diff options
author | Simon Guinot <simon.guinot@sequanux.org> | 2013-03-24 10:45:30 -0400 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2013-03-30 16:59:19 -0400 |
commit | 8d007488731981e921346a46997dfe9f08cb8201 (patch) | |
tree | d4b5d43928600589e015e6757290e060ae05d112 /arch/arm/plat-orion | |
parent | 8bb9660418e05bb1845ac1a2428444d78e322cc7 (diff) |
ARM: Orion: add dbg_show function to gpio-orion driver
This patch adds a dedicated dbg_show function to the gpio-mvebu driver.
In addition to the generic gpiolib informations, this function displays
informations related with the specific Marvell registers (blink enable,
data in polarity, interrupt masks and cause).
Signed-off-by: Simon Guinot <simon.guinot@sequanux.org>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'arch/arm/plat-orion')
-rw-r--r-- | arch/arm/plat-orion/gpio.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c index c29ee7ea200b..e39c2ba6e2fb 100644 --- a/arch/arm/plat-orion/gpio.c +++ b/arch/arm/plat-orion/gpio.c | |||
@@ -439,6 +439,64 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
439 | } | 439 | } |
440 | } | 440 | } |
441 | 441 | ||
442 | #ifdef CONFIG_DEBUG_FS | ||
443 | #include <linux/seq_file.h> | ||
444 | |||
445 | static void orion_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | ||
446 | { | ||
447 | struct orion_gpio_chip *ochip = | ||
448 | container_of(chip, struct orion_gpio_chip, chip); | ||
449 | u32 out, io_conf, blink, in_pol, data_in, cause, edg_msk, lvl_msk; | ||
450 | int i; | ||
451 | |||
452 | out = readl_relaxed(GPIO_OUT(ochip)); | ||
453 | io_conf = readl_relaxed(GPIO_IO_CONF(ochip)); | ||
454 | blink = readl_relaxed(GPIO_BLINK_EN(ochip)); | ||
455 | in_pol = readl_relaxed(GPIO_IN_POL(ochip)); | ||
456 | data_in = readl_relaxed(GPIO_DATA_IN(ochip)); | ||
457 | cause = readl_relaxed(GPIO_EDGE_CAUSE(ochip)); | ||
458 | edg_msk = readl_relaxed(GPIO_EDGE_MASK(ochip)); | ||
459 | lvl_msk = readl_relaxed(GPIO_LEVEL_MASK(ochip)); | ||
460 | |||
461 | for (i = 0; i < chip->ngpio; i++) { | ||
462 | const char *label; | ||
463 | u32 msk; | ||
464 | bool is_out; | ||
465 | |||
466 | label = gpiochip_is_requested(chip, i); | ||
467 | if (!label) | ||
468 | continue; | ||
469 | |||
470 | msk = 1 << i; | ||
471 | is_out = !(io_conf & msk); | ||
472 | |||
473 | seq_printf(s, " gpio-%-3d (%-20.20s)", chip->base + i, label); | ||
474 | |||
475 | if (is_out) { | ||
476 | seq_printf(s, " out %s %s\n", | ||
477 | out & msk ? "hi" : "lo", | ||
478 | blink & msk ? "(blink )" : ""); | ||
479 | continue; | ||
480 | } | ||
481 | |||
482 | seq_printf(s, " in %s (act %s) - IRQ", | ||
483 | (data_in ^ in_pol) & msk ? "hi" : "lo", | ||
484 | in_pol & msk ? "lo" : "hi"); | ||
485 | if (!((edg_msk | lvl_msk) & msk)) { | ||
486 | seq_printf(s, " disabled\n"); | ||
487 | continue; | ||
488 | } | ||
489 | if (edg_msk & msk) | ||
490 | seq_printf(s, " edge "); | ||
491 | if (lvl_msk & msk) | ||
492 | seq_printf(s, " level"); | ||
493 | seq_printf(s, " (%s)\n", cause & msk ? "pending" : "clear "); | ||
494 | } | ||
495 | } | ||
496 | #else | ||
497 | #define orion_gpio_dbg_show NULL | ||
498 | #endif | ||
499 | |||
442 | void __init orion_gpio_init(struct device_node *np, | 500 | void __init orion_gpio_init(struct device_node *np, |
443 | int gpio_base, int ngpio, | 501 | int gpio_base, int ngpio, |
444 | void __iomem *base, int mask_offset, | 502 | void __iomem *base, int mask_offset, |
@@ -471,6 +529,7 @@ void __init orion_gpio_init(struct device_node *np, | |||
471 | #ifdef CONFIG_OF | 529 | #ifdef CONFIG_OF |
472 | ochip->chip.of_node = np; | 530 | ochip->chip.of_node = np; |
473 | #endif | 531 | #endif |
532 | ochip->chip.dbg_show = orion_gpio_dbg_show; | ||
474 | 533 | ||
475 | spin_lock_init(&ochip->lock); | 534 | spin_lock_init(&ochip->lock); |
476 | ochip->base = (void __iomem *)base; | 535 | ochip->base = (void __iomem *)base; |