aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-mvebu.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-06 18:40:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-06 18:40:55 -0400
commit30c67e93c526639aaac90fa873800104b7c16d16 (patch)
tree6d8d0fd248d4e60bdc175dacbd196fc44f23ce11 /drivers/gpio/gpio-mvebu.c
parentf87bb9ee62700fa11713c630ac5671f253233b94 (diff)
parent08ffb2229fafc2c3a696b325a74bf4198d6b91d7 (diff)
Merge tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux
Pull GPIO changes from Grant Likely: "The usual selection of bug fixes and driver updates for GPIO. Nothing really stands out except the addition of the GRGPIO driver and some enhacements to ACPI support" I'm pulling this despite the earlier mess. Let's hope it compiles these days. * tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux: (46 commits) gpio: grgpio: Add irq support gpio: grgpio: Add device driver for GRGPIO cores gpiolib-acpi: introduce acpi_get_gpio_by_index() helper GPIO: gpio-generic: remove kfree() from bgpio_remove call gpio / ACPI: Handle ACPI events in accordance with the spec gpio: lpc32xx: Fix off-by-one valid range checking for bank gpio: mcp23s08: convert driver to DT gpio/omap: force restore if context loss is not detectable gpio/omap: optimise interrupt service routine gpio/omap: remove extra context restores in *_runtime_resume() gpio/omap: free irq domain in probe() failure paths gpio: gpio-generic: Add 16 and 32 bit big endian byte order support gpio: samsung: Add terminating entry for exynos_pinctrl_ids gpio: mvebu: add dbg_show function MAX7301 GPIO: Do not force SPI speed when using OF Platform gpio: gpio-tps65910.c: fix checkpatch error gpio: gpio-timberdale.c: fix checkpatch error gpio: gpio-tc3589x.c: fix checkpatch errors gpio: gpio-stp-xway.c: fix checkpatch error gpio: gpio-sch.c: fix checkpatch error ...
Diffstat (limited to 'drivers/gpio/gpio-mvebu.c')
-rw-r--r--drivers/gpio/gpio-mvebu.c85
1 files changed, 72 insertions, 13 deletions
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index 61a6fde6c089..bf69a7eff370 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -117,7 +117,7 @@ static inline void __iomem *mvebu_gpioreg_edge_cause(struct mvebu_gpio_chip *mvc
117{ 117{
118 int cpu; 118 int cpu;
119 119
120 switch(mvchip->soc_variant) { 120 switch (mvchip->soc_variant) {
121 case MVEBU_GPIO_SOC_VARIANT_ORION: 121 case MVEBU_GPIO_SOC_VARIANT_ORION:
122 case MVEBU_GPIO_SOC_VARIANT_MV78200: 122 case MVEBU_GPIO_SOC_VARIANT_MV78200:
123 return mvchip->membase + GPIO_EDGE_CAUSE_OFF; 123 return mvchip->membase + GPIO_EDGE_CAUSE_OFF;
@@ -133,7 +133,7 @@ static inline void __iomem *mvebu_gpioreg_edge_mask(struct mvebu_gpio_chip *mvch
133{ 133{
134 int cpu; 134 int cpu;
135 135
136 switch(mvchip->soc_variant) { 136 switch (mvchip->soc_variant) {
137 case MVEBU_GPIO_SOC_VARIANT_ORION: 137 case MVEBU_GPIO_SOC_VARIANT_ORION:
138 return mvchip->membase + GPIO_EDGE_MASK_OFF; 138 return mvchip->membase + GPIO_EDGE_MASK_OFF;
139 case MVEBU_GPIO_SOC_VARIANT_MV78200: 139 case MVEBU_GPIO_SOC_VARIANT_MV78200:
@@ -151,7 +151,7 @@ static void __iomem *mvebu_gpioreg_level_mask(struct mvebu_gpio_chip *mvchip)
151{ 151{
152 int cpu; 152 int cpu;
153 153
154 switch(mvchip->soc_variant) { 154 switch (mvchip->soc_variant) {
155 case MVEBU_GPIO_SOC_VARIANT_ORION: 155 case MVEBU_GPIO_SOC_VARIANT_ORION:
156 return mvchip->membase + GPIO_LEVEL_MASK_OFF; 156 return mvchip->membase + GPIO_LEVEL_MASK_OFF;
157 case MVEBU_GPIO_SOC_VARIANT_MV78200: 157 case MVEBU_GPIO_SOC_VARIANT_MV78200:
@@ -401,7 +401,7 @@ static int mvebu_gpio_irq_set_type(struct irq_data *d, unsigned int type)
401 /* 401 /*
402 * Configure interrupt polarity. 402 * Configure interrupt polarity.
403 */ 403 */
404 switch(type) { 404 switch (type) {
405 case IRQ_TYPE_EDGE_RISING: 405 case IRQ_TYPE_EDGE_RISING:
406 case IRQ_TYPE_LEVEL_HIGH: 406 case IRQ_TYPE_LEVEL_HIGH:
407 u = readl_relaxed(mvebu_gpioreg_in_pol(mvchip)); 407 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)
470 } 470 }
471} 471}
472 472
473#ifdef CONFIG_DEBUG_FS
474#include <linux/seq_file.h>
475
476static void mvebu_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
477{
478 struct mvebu_gpio_chip *mvchip =
479 container_of(chip, struct mvebu_gpio_chip, chip);
480 u32 out, io_conf, blink, in_pol, data_in, cause, edg_msk, lvl_msk;
481 int i;
482
483 out = readl_relaxed(mvebu_gpioreg_out(mvchip));
484 io_conf = readl_relaxed(mvebu_gpioreg_io_conf(mvchip));
485 blink = readl_relaxed(mvebu_gpioreg_blink(mvchip));
486 in_pol = readl_relaxed(mvebu_gpioreg_in_pol(mvchip));
487 data_in = readl_relaxed(mvebu_gpioreg_data_in(mvchip));
488 cause = readl_relaxed(mvebu_gpioreg_edge_cause(mvchip));
489 edg_msk = readl_relaxed(mvebu_gpioreg_edge_mask(mvchip));
490 lvl_msk = readl_relaxed(mvebu_gpioreg_level_mask(mvchip));
491
492 for (i = 0; i < chip->ngpio; i++) {
493 const char *label;
494 u32 msk;
495 bool is_out;
496
497 label = gpiochip_is_requested(chip, i);
498 if (!label)
499 continue;
500
501 msk = 1 << i;
502 is_out = !(io_conf & msk);
503
504 seq_printf(s, " gpio-%-3d (%-20.20s)", chip->base + i, label);
505
506 if (is_out) {
507 seq_printf(s, " out %s %s\n",
508 out & msk ? "hi" : "lo",
509 blink & msk ? "(blink )" : "");
510 continue;
511 }
512
513 seq_printf(s, " in %s (act %s) - IRQ",
514 (data_in ^ in_pol) & msk ? "hi" : "lo",
515 in_pol & msk ? "lo" : "hi");
516 if (!((edg_msk | lvl_msk) & msk)) {
517 seq_printf(s, " disabled\n");
518 continue;
519 }
520 if (edg_msk & msk)
521 seq_printf(s, " edge ");
522 if (lvl_msk & msk)
523 seq_printf(s, " level");
524 seq_printf(s, " (%s)\n", cause & msk ? "pending" : "clear ");
525 }
526}
527#else
528#define mvebu_gpio_dbg_show NULL
529#endif
530
473static struct of_device_id mvebu_gpio_of_match[] = { 531static struct of_device_id mvebu_gpio_of_match[] = {
474 { 532 {
475 .compatible = "marvell,orion-gpio", 533 .compatible = "marvell,orion-gpio",
476 .data = (void*) MVEBU_GPIO_SOC_VARIANT_ORION, 534 .data = (void *) MVEBU_GPIO_SOC_VARIANT_ORION,
477 }, 535 },
478 { 536 {
479 .compatible = "marvell,mv78200-gpio", 537 .compatible = "marvell,mv78200-gpio",
480 .data = (void*) MVEBU_GPIO_SOC_VARIANT_MV78200, 538 .data = (void *) MVEBU_GPIO_SOC_VARIANT_MV78200,
481 }, 539 },
482 { 540 {
483 .compatible = "marvell,armadaxp-gpio", 541 .compatible = "marvell,armadaxp-gpio",
484 .data = (void*) MVEBU_GPIO_SOC_VARIANT_ARMADAXP, 542 .data = (void *) MVEBU_GPIO_SOC_VARIANT_ARMADAXP,
485 }, 543 },
486 { 544 {
487 /* sentinel */ 545 /* sentinel */
@@ -509,13 +567,13 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
509 soc_variant = MVEBU_GPIO_SOC_VARIANT_ORION; 567 soc_variant = MVEBU_GPIO_SOC_VARIANT_ORION;
510 568
511 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 569 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
512 if (! res) { 570 if (!res) {
513 dev_err(&pdev->dev, "Cannot get memory resource\n"); 571 dev_err(&pdev->dev, "Cannot get memory resource\n");
514 return -ENODEV; 572 return -ENODEV;
515 } 573 }
516 574
517 mvchip = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_gpio_chip), GFP_KERNEL); 575 mvchip = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_gpio_chip), GFP_KERNEL);
518 if (! mvchip){ 576 if (!mvchip) {
519 dev_err(&pdev->dev, "Cannot allocate memory\n"); 577 dev_err(&pdev->dev, "Cannot allocate memory\n");
520 return -ENOMEM; 578 return -ENOMEM;
521 } 579 }
@@ -550,6 +608,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
550 mvchip->chip.ngpio = ngpios; 608 mvchip->chip.ngpio = ngpios;
551 mvchip->chip.can_sleep = 0; 609 mvchip->chip.can_sleep = 0;
552 mvchip->chip.of_node = np; 610 mvchip->chip.of_node = np;
611 mvchip->chip.dbg_show = mvebu_gpio_dbg_show;
553 612
554 spin_lock_init(&mvchip->lock); 613 spin_lock_init(&mvchip->lock);
555 mvchip->membase = devm_ioremap_resource(&pdev->dev, res); 614 mvchip->membase = devm_ioremap_resource(&pdev->dev, res);
@@ -560,21 +619,21 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
560 * per-CPU registers */ 619 * per-CPU registers */
561 if (soc_variant == MVEBU_GPIO_SOC_VARIANT_ARMADAXP) { 620 if (soc_variant == MVEBU_GPIO_SOC_VARIANT_ARMADAXP) {
562 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 621 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
563 if (! res) { 622 if (!res) {
564 dev_err(&pdev->dev, "Cannot get memory resource\n"); 623 dev_err(&pdev->dev, "Cannot get memory resource\n");
565 return -ENODEV; 624 return -ENODEV;
566 } 625 }
567 626
568 mvchip->percpu_membase = devm_ioremap_resource(&pdev->dev, 627 mvchip->percpu_membase = devm_ioremap_resource(&pdev->dev,
569 res); 628 res);
570 if (IS_ERR(mvchip->percpu_membase)) 629 if (IS_ERR(mvchip->percpu_membase))
571 return PTR_ERR(mvchip->percpu_membase); 630 return PTR_ERR(mvchip->percpu_membase);
572 } 631 }
573 632
574 /* 633 /*
575 * Mask and clear GPIO interrupts. 634 * Mask and clear GPIO interrupts.
576 */ 635 */
577 switch(soc_variant) { 636 switch (soc_variant) {
578 case MVEBU_GPIO_SOC_VARIANT_ORION: 637 case MVEBU_GPIO_SOC_VARIANT_ORION:
579 writel_relaxed(0, mvchip->membase + GPIO_EDGE_CAUSE_OFF); 638 writel_relaxed(0, mvchip->membase + GPIO_EDGE_CAUSE_OFF);
580 writel_relaxed(0, mvchip->membase + GPIO_EDGE_MASK_OFF); 639 writel_relaxed(0, mvchip->membase + GPIO_EDGE_MASK_OFF);
@@ -632,7 +691,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
632 691
633 gc = irq_alloc_generic_chip("mvebu_gpio_irq", 2, mvchip->irqbase, 692 gc = irq_alloc_generic_chip("mvebu_gpio_irq", 2, mvchip->irqbase,
634 mvchip->membase, handle_level_irq); 693 mvchip->membase, handle_level_irq);
635 if (! gc) { 694 if (!gc) {
636 dev_err(&pdev->dev, "Cannot allocate generic irq_chip\n"); 695 dev_err(&pdev->dev, "Cannot allocate generic irq_chip\n");
637 return -ENOMEM; 696 return -ENOMEM;
638 } 697 }