diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-06 18:40:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-06 18:40:55 -0400 |
commit | 30c67e93c526639aaac90fa873800104b7c16d16 (patch) | |
tree | 6d8d0fd248d4e60bdc175dacbd196fc44f23ce11 /drivers/gpio/gpio-mvebu.c | |
parent | f87bb9ee62700fa11713c630ac5671f253233b94 (diff) | |
parent | 08ffb2229fafc2c3a696b325a74bf4198d6b91d7 (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.c | 85 |
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 | |||
476 | static 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 | |||
473 | static struct of_device_id mvebu_gpio_of_match[] = { | 531 | static 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 | } |