]> Pileus Git - ~andy/linux/blobdiff - drivers/gpio/gpio-mvebu.c
Merge tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux
[~andy/linux] / drivers / gpio / gpio-mvebu.c
index 61a6fde6c089b28a76f3ca5012309c101ebcf2b2..bf69a7eff370cbabc72ba01591727ba20c81338c 100644 (file)
@@ -117,7 +117,7 @@ static inline void __iomem *mvebu_gpioreg_edge_cause(struct mvebu_gpio_chip *mvc
 {
        int cpu;
 
-       switch(mvchip->soc_variant) {
+       switch (mvchip->soc_variant) {
        case MVEBU_GPIO_SOC_VARIANT_ORION:
        case MVEBU_GPIO_SOC_VARIANT_MV78200:
                return mvchip->membase + GPIO_EDGE_CAUSE_OFF;
@@ -133,7 +133,7 @@ static inline void __iomem *mvebu_gpioreg_edge_mask(struct mvebu_gpio_chip *mvch
 {
        int cpu;
 
-       switch(mvchip->soc_variant) {
+       switch (mvchip->soc_variant) {
        case MVEBU_GPIO_SOC_VARIANT_ORION:
                return mvchip->membase + GPIO_EDGE_MASK_OFF;
        case MVEBU_GPIO_SOC_VARIANT_MV78200:
@@ -151,7 +151,7 @@ static void __iomem *mvebu_gpioreg_level_mask(struct mvebu_gpio_chip *mvchip)
 {
        int cpu;
 
-       switch(mvchip->soc_variant) {
+       switch (mvchip->soc_variant) {
        case MVEBU_GPIO_SOC_VARIANT_ORION:
                return mvchip->membase + GPIO_LEVEL_MASK_OFF;
        case MVEBU_GPIO_SOC_VARIANT_MV78200:
@@ -401,7 +401,7 @@ static int mvebu_gpio_irq_set_type(struct irq_data *d, unsigned int type)
        /*
         * Configure interrupt polarity.
         */
-       switch(type) {
+       switch (type) {
        case IRQ_TYPE_EDGE_RISING:
        case IRQ_TYPE_LEVEL_HIGH:
                u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip));
@@ -470,18 +470,76 @@ static void mvebu_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
        }
 }
 
+#ifdef CONFIG_DEBUG_FS
+#include <linux/seq_file.h>
+
+static void mvebu_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+       struct mvebu_gpio_chip *mvchip =
+               container_of(chip, struct mvebu_gpio_chip, chip);
+       u32 out, io_conf, blink, in_pol, data_in, cause, edg_msk, lvl_msk;
+       int i;
+
+       out     = readl_relaxed(mvebu_gpioreg_out(mvchip));
+       io_conf = readl_relaxed(mvebu_gpioreg_io_conf(mvchip));
+       blink   = readl_relaxed(mvebu_gpioreg_blink(mvchip));
+       in_pol  = readl_relaxed(mvebu_gpioreg_in_pol(mvchip));
+       data_in = readl_relaxed(mvebu_gpioreg_data_in(mvchip));
+       cause   = readl_relaxed(mvebu_gpioreg_edge_cause(mvchip));
+       edg_msk = readl_relaxed(mvebu_gpioreg_edge_mask(mvchip));
+       lvl_msk = readl_relaxed(mvebu_gpioreg_level_mask(mvchip));
+
+       for (i = 0; i < chip->ngpio; i++) {
+               const char *label;
+               u32 msk;
+               bool is_out;
+
+               label = gpiochip_is_requested(chip, i);
+               if (!label)
+                       continue;
+
+               msk = 1 << i;
+               is_out = !(io_conf & msk);
+
+               seq_printf(s, " gpio-%-3d (%-20.20s)", chip->base + i, label);
+
+               if (is_out) {
+                       seq_printf(s, " out %s %s\n",
+                                  out & msk ? "hi" : "lo",
+                                  blink & msk ? "(blink )" : "");
+                       continue;
+               }
+
+               seq_printf(s, " in  %s (act %s) - IRQ",
+                          (data_in ^ in_pol) & msk  ? "hi" : "lo",
+                          in_pol & msk ? "lo" : "hi");
+               if (!((edg_msk | lvl_msk) & msk)) {
+                       seq_printf(s, " disabled\n");
+                       continue;
+               }
+               if (edg_msk & msk)
+                       seq_printf(s, " edge ");
+               if (lvl_msk & msk)
+                       seq_printf(s, " level");
+               seq_printf(s, " (%s)\n", cause & msk ? "pending" : "clear  ");
+       }
+}
+#else
+#define mvebu_gpio_dbg_show NULL
+#endif
+
 static struct of_device_id mvebu_gpio_of_match[] = {
        {
                .compatible = "marvell,orion-gpio",
-               .data       = (void*) MVEBU_GPIO_SOC_VARIANT_ORION,
+               .data       = (void *) MVEBU_GPIO_SOC_VARIANT_ORION,
        },
        {
                .compatible = "marvell,mv78200-gpio",
-               .data       = (void*) MVEBU_GPIO_SOC_VARIANT_MV78200,
+               .data       = (void *) MVEBU_GPIO_SOC_VARIANT_MV78200,
        },
        {
                .compatible = "marvell,armadaxp-gpio",
-               .data       = (void*) MVEBU_GPIO_SOC_VARIANT_ARMADAXP,
+               .data       = (void *) MVEBU_GPIO_SOC_VARIANT_ARMADAXP,
        },
        {
                /* sentinel */
@@ -509,13 +567,13 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
                soc_variant = MVEBU_GPIO_SOC_VARIANT_ORION;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (! res) {
+       if (!res) {
                dev_err(&pdev->dev, "Cannot get memory resource\n");
                return -ENODEV;
        }
 
        mvchip = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_gpio_chip), GFP_KERNEL);
-       if (! mvchip){
+       if (!mvchip) {
                dev_err(&pdev->dev, "Cannot allocate memory\n");
                return -ENOMEM;
        }
@@ -550,6 +608,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
        mvchip->chip.ngpio = ngpios;
        mvchip->chip.can_sleep = 0;
        mvchip->chip.of_node = np;
+       mvchip->chip.dbg_show = mvebu_gpio_dbg_show;
 
        spin_lock_init(&mvchip->lock);
        mvchip->membase = devm_ioremap_resource(&pdev->dev, res);
@@ -560,21 +619,21 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
         * per-CPU registers */
        if (soc_variant == MVEBU_GPIO_SOC_VARIANT_ARMADAXP) {
                res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-               if (! res) {
+               if (!res) {
                        dev_err(&pdev->dev, "Cannot get memory resource\n");
                        return -ENODEV;
                }
 
                mvchip->percpu_membase = devm_ioremap_resource(&pdev->dev,
                                                               res);
-               if (IS_ERR(mvchip->percpu_membase)) 
+               if (IS_ERR(mvchip->percpu_membase))
                        return PTR_ERR(mvchip->percpu_membase);
        }
 
        /*
         * Mask and clear GPIO interrupts.
         */
-       switch(soc_variant) {
+       switch (soc_variant) {
        case MVEBU_GPIO_SOC_VARIANT_ORION:
                writel_relaxed(0, mvchip->membase + GPIO_EDGE_CAUSE_OFF);
                writel_relaxed(0, mvchip->membase + GPIO_EDGE_MASK_OFF);
@@ -632,7 +691,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
 
        gc = irq_alloc_generic_chip("mvebu_gpio_irq", 2, mvchip->irqbase,
                                    mvchip->membase, handle_level_irq);
-       if (! gc) {
+       if (!gc) {
                dev_err(&pdev->dev, "Cannot allocate generic irq_chip\n");
                return -ENOMEM;
        }