diff options
Diffstat (limited to 'drivers/gpio/gpio-pxa.c')
-rw-r--r-- | drivers/gpio/gpio-pxa.c | 151 |
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 | ||
88 | enum { | 88 | enum 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 | |||
98 | struct pxa_gpio_id { | ||
99 | enum pxa_gpio_type type; | ||
100 | int gpio_nums; | ||
95 | }; | 101 | }; |
96 | 102 | ||
97 | static DEFINE_SPINLOCK(gpio_lock); | 103 | static DEFINE_SPINLOCK(gpio_lock); |
98 | static struct pxa_gpio_chip *pxa_gpio_chips; | 104 | static struct pxa_gpio_chip *pxa_gpio_chips; |
99 | static int gpio_type; | 105 | static enum pxa_gpio_type gpio_type; |
100 | static void __iomem *gpio_reg_base; | 106 | static void __iomem *gpio_reg_base; |
101 | 107 | ||
108 | static struct pxa_gpio_id pxa25x_id = { | ||
109 | .type = PXA25X_GPIO, | ||
110 | .gpio_nums = 85, | ||
111 | }; | ||
112 | |||
113 | static struct pxa_gpio_id pxa26x_id = { | ||
114 | .type = PXA26X_GPIO, | ||
115 | .gpio_nums = 90, | ||
116 | }; | ||
117 | |||
118 | static struct pxa_gpio_id pxa27x_id = { | ||
119 | .type = PXA27X_GPIO, | ||
120 | .gpio_nums = 121, | ||
121 | }; | ||
122 | |||
123 | static struct pxa_gpio_id pxa3xx_id = { | ||
124 | .type = PXA3XX_GPIO, | ||
125 | .gpio_nums = 128, | ||
126 | }; | ||
127 | |||
128 | static struct pxa_gpio_id pxa93x_id = { | ||
129 | .type = PXA93X_GPIO, | ||
130 | .gpio_nums = 192, | ||
131 | }; | ||
132 | |||
133 | static struct pxa_gpio_id mmp_id = { | ||
134 | .type = MMP_GPIO, | ||
135 | .gpio_nums = 128, | ||
136 | }; | ||
137 | |||
138 | static 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 | ||
434 | static int pxa_gpio_nums(void) | 475 | static 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 |
472 | static struct of_device_id pxa_gpio_dt_ids[] = { | 500 | static 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 | ||
492 | static int pxa_gpio_probe_dt(struct platform_device *pdev) | 525 | static 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 | ||
664 | static 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 | |||
637 | static struct platform_driver pxa_gpio_driver = { | 675 | static 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 | ||
645 | static int __init pxa_gpio_init(void) | 684 | static int __init pxa_gpio_init(void) |