aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-22 12:30:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-22 12:30:52 -0400
commitb324c67d4800e59171f48d9ddab6cbfb59110482 (patch)
treea16509a710e76fa24c01514b60aed06b7db13716 /drivers/gpio
parent8dca6010d44cc722a94dc6da96560f9083dac782 (diff)
parent396d81cd0fe12ce5d1f6d159f093f9315d2837bc (diff)
Merge tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull device tree conversions for arm-soc, part 1, from Olof Johansson: "The spear3xx, lpc32xx, shmobile and mmp platforms are joining the game of booting using device trees, which is a great step forward for them. at91 and spear have pretty much completed this process with a huge amount of work being put into at91. The other platforms are continuing the process. We finally start to see the payback on this investment, as new machines are getting supported purely by adding a .dts source file that can be completely independent of the kernel source." Fix up trivial conflict in arch/arm/Kconfig * tag 'dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (83 commits) ARM: at91: Add ADC driver to at91sam9260/at91sam9g20 dtsi files arm/dts: omap4-panda: Add LEDs support arm/dts: omap4-sdp: Add LEDs support arm/dts: twl4030: Add twl4030-gpio node OMAP4: devices: Do not create mcpdm device if the dtb has been provided OMAP4: devices: Do not create dmic device if the dtb has been provided Documentation: update docs for mmp dt ARM: dts: refresh dts file for arch mmp ARM: mmp: support pxa910 with device tree ARM: mmp: support mmp2 with device tree gpio: pxa: parse gpio from DTS file ARM: mmp: support DT in timer ARM: mmp: support DT in irq ARM: mmp: append CONFIG_MACH_MMP2_DT ARM: mmp: fix build issue on mmp with device tree ARM: ux500: Enable PRCMU Timer 4 (clocksource) for Device Tree ARM: ux500: Disable SMSC911x platform code registration when DT is enabled ARM: ux500: Fork cpu-db8500 platform_devs for sequential DT enablement ARM: ux500: Do not attempt to register non-existent i2c devices on Snowball ARM: SPEAr3xx: Correct keyboard data passed from DT ...
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-pxa.c116
1 files changed, 98 insertions, 18 deletions
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index fc3ace3fd4cb..58a6a63a6ece 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -11,13 +11,17 @@
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14#include <linux/module.h>
14#include <linux/clk.h> 15#include <linux/clk.h>
15#include <linux/err.h> 16#include <linux/err.h>
16#include <linux/gpio.h> 17#include <linux/gpio.h>
17#include <linux/gpio-pxa.h> 18#include <linux/gpio-pxa.h>
18#include <linux/init.h> 19#include <linux/init.h>
19#include <linux/irq.h> 20#include <linux/irq.h>
21#include <linux/irqdomain.h>
20#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/of.h>
24#include <linux/of_device.h>
21#include <linux/platform_device.h> 25#include <linux/platform_device.h>
22#include <linux/syscore_ops.h> 26#include <linux/syscore_ops.h>
23#include <linux/slab.h> 27#include <linux/slab.h>
@@ -56,6 +60,10 @@
56 60
57int pxa_last_gpio; 61int pxa_last_gpio;
58 62
63#ifdef CONFIG_OF
64static struct irq_domain *domain;
65#endif
66
59struct pxa_gpio_chip { 67struct pxa_gpio_chip {
60 struct gpio_chip chip; 68 struct gpio_chip chip;
61 void __iomem *regbase; 69 void __iomem *regbase;
@@ -81,7 +89,6 @@ enum {
81 PXA3XX_GPIO, 89 PXA3XX_GPIO,
82 PXA93X_GPIO, 90 PXA93X_GPIO,
83 MMP_GPIO = 0x10, 91 MMP_GPIO = 0x10,
84 MMP2_GPIO,
85}; 92};
86 93
87static DEFINE_SPINLOCK(gpio_lock); 94static DEFINE_SPINLOCK(gpio_lock);
@@ -475,22 +482,92 @@ static int pxa_gpio_nums(void)
475 gpio_type = MMP_GPIO; 482 gpio_type = MMP_GPIO;
476 } else if (cpu_is_mmp2()) { 483 } else if (cpu_is_mmp2()) {
477 count = 191; 484 count = 191;
478 gpio_type = MMP2_GPIO; 485 gpio_type = MMP_GPIO;
479 } 486 }
480#endif /* CONFIG_ARCH_MMP */ 487#endif /* CONFIG_ARCH_MMP */
481 return count; 488 return count;
482} 489}
483 490
491static struct of_device_id pxa_gpio_dt_ids[] = {
492 { .compatible = "mrvl,pxa-gpio" },
493 { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO },
494 {}
495};
496
497static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq,
498 irq_hw_number_t hw)
499{
500 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
501 handle_edge_irq);
502 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
503 return 0;
504}
505
506const struct irq_domain_ops pxa_irq_domain_ops = {
507 .map = pxa_irq_domain_map,
508};
509
510#ifdef CONFIG_OF
511static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev)
512{
513 int ret, nr_banks, nr_gpios, irq_base;
514 struct device_node *prev, *next, *np = pdev->dev.of_node;
515 const struct of_device_id *of_id =
516 of_match_device(pxa_gpio_dt_ids, &pdev->dev);
517
518 if (!of_id) {
519 dev_err(&pdev->dev, "Failed to find gpio controller\n");
520 return -EFAULT;
521 }
522 gpio_type = (int)of_id->data;
523
524 next = of_get_next_child(np, NULL);
525 prev = next;
526 if (!next) {
527 dev_err(&pdev->dev, "Failed to find child gpio node\n");
528 ret = -EINVAL;
529 goto err;
530 }
531 for (nr_banks = 1; ; nr_banks++) {
532 next = of_get_next_child(np, prev);
533 if (!next)
534 break;
535 prev = next;
536 }
537 of_node_put(prev);
538 nr_gpios = nr_banks << 5;
539 pxa_last_gpio = nr_gpios - 1;
540
541 irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0);
542 if (irq_base < 0) {
543 dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n");
544 goto err;
545 }
546 domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0,
547 &pxa_irq_domain_ops, NULL);
548 return 0;
549err:
550 iounmap(gpio_reg_base);
551 return ret;
552}
553#else
554#define pxa_gpio_probe_dt(pdev) (-1)
555#endif
556
484static int __devinit pxa_gpio_probe(struct platform_device *pdev) 557static int __devinit pxa_gpio_probe(struct platform_device *pdev)
485{ 558{
486 struct pxa_gpio_chip *c; 559 struct pxa_gpio_chip *c;
487 struct resource *res; 560 struct resource *res;
488 struct clk *clk; 561 struct clk *clk;
489 struct pxa_gpio_platform_data *info; 562 struct pxa_gpio_platform_data *info;
490 int gpio, irq, ret; 563 int gpio, irq, ret, use_of = 0;
491 int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; 564 int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
492 565
493 pxa_last_gpio = pxa_gpio_nums(); 566 ret = pxa_gpio_probe_dt(pdev);
567 if (ret < 0)
568 pxa_last_gpio = pxa_gpio_nums();
569 else
570 use_of = 1;
494 if (!pxa_last_gpio) 571 if (!pxa_last_gpio)
495 return -EINVAL; 572 return -EINVAL;
496 573
@@ -545,25 +622,27 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev)
545 writel_relaxed(~0, c->regbase + ED_MASK_OFFSET); 622 writel_relaxed(~0, c->regbase + ED_MASK_OFFSET);
546 } 623 }
547 624
625 if (!use_of) {
548#ifdef CONFIG_ARCH_PXA 626#ifdef CONFIG_ARCH_PXA
549 irq = gpio_to_irq(0); 627 irq = gpio_to_irq(0);
550 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, 628 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
551 handle_edge_irq); 629 handle_edge_irq);
552 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 630 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
553 irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler); 631 irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler);
554
555 irq = gpio_to_irq(1);
556 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
557 handle_edge_irq);
558 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
559 irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler);
560#endif
561 632
562 for (irq = gpio_to_irq(gpio_offset); 633 irq = gpio_to_irq(1);
563 irq <= gpio_to_irq(pxa_last_gpio); irq++) {
564 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, 634 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
565 handle_edge_irq); 635 handle_edge_irq);
566 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 636 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
637 irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler);
638#endif
639
640 for (irq = gpio_to_irq(gpio_offset);
641 irq <= gpio_to_irq(pxa_last_gpio); irq++) {
642 irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
643 handle_edge_irq);
644 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
645 }
567 } 646 }
568 647
569 irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler); 648 irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler);
@@ -574,6 +653,7 @@ static struct platform_driver pxa_gpio_driver = {
574 .probe = pxa_gpio_probe, 653 .probe = pxa_gpio_probe,
575 .driver = { 654 .driver = {
576 .name = "pxa-gpio", 655 .name = "pxa-gpio",
656 .of_match_table = pxa_gpio_dt_ids,
577 }, 657 },
578}; 658};
579 659