aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-pxa.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-04 15:34:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-04 15:34:30 -0400
commit150a8dcf109f68f322bf112c7604f2d950303f00 (patch)
treed2219f3de4facbcd34625c733b6fae85ea3b7b8c /drivers/gpio/gpio-pxa.c
parente3d98847ded1d183111ff7c4d1ef56b161c7f13e (diff)
parent21bdcc1a2ffce8c9bc7caad711401fff47f99c00 (diff)
Merge tag 'boards-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC board specific changes (part 1) from Olof Johansson: "These changes are all for board specific files. These used to make up a large portion of the ARM changes in the past, but as we are generalizing the support and moving to device tree probing, this has gotten significantly smaller. The only platform actually adding new code here at the moment is Renesas shmobile, as they are still busy converting their code to device tree and have not come far enough to not need it." * tag 'boards-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (43 commits) ARM: msm: USB_MSM_OTG needs USB_PHY ARM: davinci: da850 evm: fix const qualifier placement ARM: davinci: da850 board: add remoteproc support ARM: pxa: move debug uart code ARM: pxa: select PXA935 on saar & tavorevb ARM: mmp: add more compatible names in gpio driver ARM: pxa: move PXA_GPIO_TO_IRQ macro ARM: pxa: remove cpu_is_xxx in gpio driver ARM: Kirkwood: update Network Space Mini v2 description ARM: Kirkwood: DT board setup for CloudBox ARM: Kirkwood: sort board entries by ASCII-code order ARM: OMAP: board-4430sdp: Provide regulator to pwm-backlight ARM: OMAP: zoom: Use pwm stack for lcd and keyboard backlight ARM: OMAP2+: omap2plus_defconfig: Add support for BMP085 pressure sensor omap2+: Remove useless Makefile line omap2+: Remove useless Makefile line ARM: OMAP: RX-51: add missing regulator supply definitions for lis3lv02d ARM: OMAP1: fix omap_udc registration ARM: davinci: use is IS_ENABLED macro ARM: kirkwood: add MACH_GURUPLUG_DT to defconfig ...
Diffstat (limited to 'drivers/gpio/gpio-pxa.c')
-rw-r--r--drivers/gpio/gpio-pxa.c151
1 files changed, 95 insertions, 56 deletions
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 2d3af981641e..d7a5c9d75525 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -85,20 +85,61 @@ struct pxa_gpio_chip {
85#endif 85#endif
86}; 86};
87 87
88enum { 88enum pxa_gpio_type {
89 PXA25X_GPIO = 0, 89 PXA25X_GPIO = 0,
90 PXA26X_GPIO, 90 PXA26X_GPIO,
91 PXA27X_GPIO, 91 PXA27X_GPIO,
92 PXA3XX_GPIO, 92 PXA3XX_GPIO,
93 PXA93X_GPIO, 93 PXA93X_GPIO,
94 MMP_GPIO = 0x10, 94 MMP_GPIO = 0x10,
95 MMP2_GPIO,
96};
97
98struct pxa_gpio_id {
99 enum pxa_gpio_type type;
100 int gpio_nums;
95}; 101};
96 102
97static DEFINE_SPINLOCK(gpio_lock); 103static DEFINE_SPINLOCK(gpio_lock);
98static struct pxa_gpio_chip *pxa_gpio_chips; 104static struct pxa_gpio_chip *pxa_gpio_chips;
99static int gpio_type; 105static enum pxa_gpio_type gpio_type;
100static void __iomem *gpio_reg_base; 106static void __iomem *gpio_reg_base;
101 107
108static struct pxa_gpio_id pxa25x_id = {
109 .type = PXA25X_GPIO,
110 .gpio_nums = 85,
111};
112
113static struct pxa_gpio_id pxa26x_id = {
114 .type = PXA26X_GPIO,
115 .gpio_nums = 90,
116};
117
118static struct pxa_gpio_id pxa27x_id = {
119 .type = PXA27X_GPIO,
120 .gpio_nums = 121,
121};
122
123static struct pxa_gpio_id pxa3xx_id = {
124 .type = PXA3XX_GPIO,
125 .gpio_nums = 128,
126};
127
128static struct pxa_gpio_id pxa93x_id = {
129 .type = PXA93X_GPIO,
130 .gpio_nums = 192,
131};
132
133static struct pxa_gpio_id mmp_id = {
134 .type = MMP_GPIO,
135 .gpio_nums = 128,
136};
137
138static struct pxa_gpio_id mmp2_id = {
139 .type = MMP2_GPIO,
140 .gpio_nums = 192,
141};
142
102#define for_each_gpio_chip(i, c) \ 143#define for_each_gpio_chip(i, c) \
103 for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++) 144 for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++)
104 145
@@ -431,47 +472,39 @@ static struct irq_chip pxa_muxed_gpio_chip = {
431 .irq_set_wake = pxa_gpio_set_wake, 472 .irq_set_wake = pxa_gpio_set_wake,
432}; 473};
433 474
434static int pxa_gpio_nums(void) 475static int pxa_gpio_nums(struct platform_device *pdev)
435{ 476{
477 const struct platform_device_id *id = platform_get_device_id(pdev);
478 struct pxa_gpio_id *pxa_id = (struct pxa_gpio_id *)id->driver_data;
436 int count = 0; 479 int count = 0;
437 480
438#ifdef CONFIG_ARCH_PXA 481 switch (pxa_id->type) {
439 if (cpu_is_pxa25x()) { 482 case PXA25X_GPIO:
440#ifdef CONFIG_CPU_PXA26x 483 case PXA26X_GPIO:
441 count = 89; 484 case PXA27X_GPIO:
442 gpio_type = PXA26X_GPIO; 485 case PXA3XX_GPIO:
443#elif defined(CONFIG_PXA25x) 486 case PXA93X_GPIO:
444 count = 84; 487 case MMP_GPIO:
445 gpio_type = PXA26X_GPIO; 488 case MMP2_GPIO:
446#endif /* CONFIG_CPU_PXA26x */ 489 gpio_type = pxa_id->type;
447 } else if (cpu_is_pxa27x()) { 490 count = pxa_id->gpio_nums - 1;
448 count = 120; 491 break;
449 gpio_type = PXA27X_GPIO; 492 default:
450 } else if (cpu_is_pxa93x()) { 493 count = -EINVAL;
451 count = 191; 494 break;
452 gpio_type = PXA93X_GPIO;
453 } else if (cpu_is_pxa3xx()) {
454 count = 127;
455 gpio_type = PXA3XX_GPIO;
456 }
457#endif /* CONFIG_ARCH_PXA */
458
459#ifdef CONFIG_ARCH_MMP
460 if (cpu_is_pxa168() || cpu_is_pxa910()) {
461 count = 127;
462 gpio_type = MMP_GPIO;
463 } else if (cpu_is_mmp2()) {
464 count = 191;
465 gpio_type = MMP_GPIO;
466 } 495 }
467#endif /* CONFIG_ARCH_MMP */
468 return count; 496 return count;
469} 497}
470 498
471#ifdef CONFIG_OF 499#ifdef CONFIG_OF
472static struct of_device_id pxa_gpio_dt_ids[] = { 500static struct of_device_id pxa_gpio_dt_ids[] = {
473 { .compatible = "mrvl,pxa-gpio" }, 501 { .compatible = "intel,pxa25x-gpio", .data = &pxa25x_id, },
474 { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO }, 502 { .compatible = "intel,pxa26x-gpio", .data = &pxa26x_id, },
503 { .compatible = "intel,pxa27x-gpio", .data = &pxa27x_id, },
504 { .compatible = "intel,pxa3xx-gpio", .data = &pxa3xx_id, },
505 { .compatible = "marvell,pxa93x-gpio", .data = &pxa93x_id, },
506 { .compatible = "marvell,mmp-gpio", .data = &mmp_id, },
507 { .compatible = "marvell,mmp2-gpio", .data = &mmp2_id, },
475 {} 508 {}
476}; 509};
477 510
@@ -491,16 +524,18 @@ const struct irq_domain_ops pxa_irq_domain_ops = {
491 524
492static int pxa_gpio_probe_dt(struct platform_device *pdev) 525static int pxa_gpio_probe_dt(struct platform_device *pdev)
493{ 526{
494 int ret, nr_banks, nr_gpios; 527 int ret, nr_gpios;
495 struct device_node *prev, *next, *np = pdev->dev.of_node; 528 struct device_node *prev, *next, *np = pdev->dev.of_node;
496 const struct of_device_id *of_id = 529 const struct of_device_id *of_id =
497 of_match_device(pxa_gpio_dt_ids, &pdev->dev); 530 of_match_device(pxa_gpio_dt_ids, &pdev->dev);
531 const struct pxa_gpio_id *gpio_id;
498 532
499 if (!of_id) { 533 if (!of_id || !of_id->data) {
500 dev_err(&pdev->dev, "Failed to find gpio controller\n"); 534 dev_err(&pdev->dev, "Failed to find gpio controller\n");
501 return -EFAULT; 535 return -EFAULT;
502 } 536 }
503 gpio_type = (int)of_id->data; 537 gpio_id = of_id->data;
538 gpio_type = gpio_id->type;
504 539
505 next = of_get_next_child(np, NULL); 540 next = of_get_next_child(np, NULL);
506 prev = next; 541 prev = next;
@@ -509,14 +544,8 @@ static int pxa_gpio_probe_dt(struct platform_device *pdev)
509 ret = -EINVAL; 544 ret = -EINVAL;
510 goto err; 545 goto err;
511 } 546 }
512 for (nr_banks = 1; ; nr_banks++) {
513 next = of_get_next_child(np, prev);
514 if (!next)
515 break;
516 prev = next;
517 }
518 of_node_put(prev); 547 of_node_put(prev);
519 nr_gpios = nr_banks << 5; 548 nr_gpios = gpio_id->gpio_nums;
520 pxa_last_gpio = nr_gpios - 1; 549 pxa_last_gpio = nr_gpios - 1;
521 550
522 irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0); 551 irq_base = irq_alloc_descs(-1, 0, nr_gpios, 0);
@@ -545,19 +574,18 @@ static int pxa_gpio_probe(struct platform_device *pdev)
545 int gpio, irq, ret, use_of = 0; 574 int gpio, irq, ret, use_of = 0;
546 int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; 575 int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0;
547 576
548 ret = pxa_gpio_probe_dt(pdev); 577 info = dev_get_platdata(&pdev->dev);
549 if (ret < 0) { 578 if (info) {
550 pxa_last_gpio = pxa_gpio_nums(); 579 irq_base = info->irq_base;
551#ifdef CONFIG_ARCH_PXA 580 if (irq_base <= 0)
552 if (gpio_is_pxa_type(gpio_type)) 581 return -EINVAL;
553 irq_base = PXA_GPIO_TO_IRQ(0); 582 pxa_last_gpio = pxa_gpio_nums(pdev);
554#endif
555#ifdef CONFIG_ARCH_MMP
556 if (gpio_is_mmp_type(gpio_type))
557 irq_base = MMP_GPIO_TO_IRQ(0);
558#endif
559 } else { 583 } else {
584 irq_base = 0;
560 use_of = 1; 585 use_of = 1;
586 ret = pxa_gpio_probe_dt(pdev);
587 if (ret < 0)
588 return -EINVAL;
561 } 589 }
562 590
563 if (!pxa_last_gpio) 591 if (!pxa_last_gpio)
@@ -594,7 +622,6 @@ static int pxa_gpio_probe(struct platform_device *pdev)
594 } 622 }
595 623
596 /* Initialize GPIO chips */ 624 /* Initialize GPIO chips */
597 info = dev_get_platdata(&pdev->dev);
598 pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL); 625 pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL);
599 626
600 /* clear all GPIO edge detects */ 627 /* clear all GPIO edge detects */
@@ -634,12 +661,24 @@ static int pxa_gpio_probe(struct platform_device *pdev)
634 return 0; 661 return 0;
635} 662}
636 663
664static const struct platform_device_id gpio_id_table[] = {
665 { "pxa25x-gpio", (unsigned long)&pxa25x_id },
666 { "pxa26x-gpio", (unsigned long)&pxa26x_id },
667 { "pxa27x-gpio", (unsigned long)&pxa27x_id },
668 { "pxa3xx-gpio", (unsigned long)&pxa3xx_id },
669 { "pxa93x-gpio", (unsigned long)&pxa93x_id },
670 { "mmp-gpio", (unsigned long)&mmp_id },
671 { "mmp2-gpio", (unsigned long)&mmp2_id },
672 { },
673};
674
637static struct platform_driver pxa_gpio_driver = { 675static struct platform_driver pxa_gpio_driver = {
638 .probe = pxa_gpio_probe, 676 .probe = pxa_gpio_probe,
639 .driver = { 677 .driver = {
640 .name = "pxa-gpio", 678 .name = "pxa-gpio",
641 .of_match_table = of_match_ptr(pxa_gpio_dt_ids), 679 .of_match_table = of_match_ptr(pxa_gpio_dt_ids),
642 }, 680 },
681 .id_table = gpio_id_table,
643}; 682};
644 683
645static int __init pxa_gpio_init(void) 684static int __init pxa_gpio_init(void)