aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-pxa.c
diff options
context:
space:
mode:
authorHaojian Zhuang <haojian.zhuang@gmail.com>2012-04-13 03:15:45 -0400
committerHaojian Zhuang <haojian.zhuang@gmail.com>2012-05-05 04:36:47 -0400
commit7a4d5079baf205f39efa0d9a1b273812c15a93aa (patch)
tree25cb94c3b212f83f3bcafc85e7ca87152baa7fb8 /drivers/gpio/gpio-pxa.c
parentc68ef2b5921cf26225533c8ed109386578060a98 (diff)
gpio: pxa: parse gpio from DTS file
Parse GPIO numbers from DTS file. Allocate interrupt according to GPIO numbers. Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/gpio/gpio-pxa.c')
-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