aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorGrygorii Strashko <grygorii.strashko@ti.com>2014-02-13 10:58:45 -0500
committerLinus Walleij <linus.walleij@linaro.org>2014-03-04 04:20:04 -0500
commit0c6feb0796ea6407c6477994b854659311078cfa (patch)
treee582ad3d7f4c9ccfd744a32c4a41fd14ff4dc32e /drivers/gpio
parent9af4d80ba5666579944f570e113c5a87444afbde (diff)
gpio: davinci: reuse for keystone soc
The similar GPIO HW block is used by keystone SoCs as in Davinci SoCs. Hence, reuse Davinci GPIO driver for Keystone taking into account that Keystone contains ARM GIC IRQ controller which is implemented using IRQ Chip. Documentation: http://www.ti.com/lit/ug/sprugv1/sprugv1.pdf Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-davinci.c48
1 files changed, 40 insertions, 8 deletions
diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c
index 29321eea3c44..52470382a964 100644
--- a/drivers/gpio/gpio-davinci.c
+++ b/drivers/gpio/gpio-davinci.c
@@ -37,6 +37,8 @@ struct davinci_gpio_regs {
37 u32 intstat; 37 u32 intstat;
38}; 38};
39 39
40typedef struct irq_chip *(*gpio_get_irq_chip_cb_t)(unsigned int irq);
41
40#define BINTEN 0x8 /* GPIO Interrupt Per-Bank Enable Register */ 42#define BINTEN 0x8 /* GPIO Interrupt Per-Bank Enable Register */
41 43
42#define chip2controller(chip) \ 44#define chip2controller(chip) \
@@ -413,6 +415,26 @@ static const struct irq_domain_ops davinci_gpio_irq_ops = {
413 .xlate = irq_domain_xlate_onetwocell, 415 .xlate = irq_domain_xlate_onetwocell,
414}; 416};
415 417
418static struct irq_chip *davinci_gpio_get_irq_chip(unsigned int irq)
419{
420 static struct irq_chip_type gpio_unbanked;
421
422 gpio_unbanked = *container_of(irq_get_chip(irq),
423 struct irq_chip_type, chip);
424
425 return &gpio_unbanked.chip;
426};
427
428static struct irq_chip *keystone_gpio_get_irq_chip(unsigned int irq)
429{
430 static struct irq_chip gpio_unbanked;
431
432 gpio_unbanked = *irq_get_chip(irq);
433 return &gpio_unbanked;
434};
435
436static const struct of_device_id davinci_gpio_ids[];
437
416/* 438/*
417 * NOTE: for suspend/resume, probably best to make a platform_device with 439 * NOTE: for suspend/resume, probably best to make a platform_device with
418 * suspend_late/resume_resume calls hooking into results of the set_wake() 440 * suspend_late/resume_resume calls hooking into results of the set_wake()
@@ -434,6 +456,18 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
434 struct davinci_gpio_platform_data *pdata = dev->platform_data; 456 struct davinci_gpio_platform_data *pdata = dev->platform_data;
435 struct davinci_gpio_regs __iomem *g; 457 struct davinci_gpio_regs __iomem *g;
436 struct irq_domain *irq_domain = NULL; 458 struct irq_domain *irq_domain = NULL;
459 const struct of_device_id *match;
460 struct irq_chip *irq_chip;
461 gpio_get_irq_chip_cb_t gpio_get_irq_chip;
462
463 /*
464 * Use davinci_gpio_get_irq_chip by default to handle non DT cases
465 */
466 gpio_get_irq_chip = davinci_gpio_get_irq_chip;
467 match = of_match_device(of_match_ptr(davinci_gpio_ids),
468 dev);
469 if (match)
470 gpio_get_irq_chip = (gpio_get_irq_chip_cb_t)match->data;
437 471
438 ngpio = pdata->ngpio; 472 ngpio = pdata->ngpio;
439 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 473 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -490,8 +524,6 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
490 * IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs. 524 * IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs.
491 */ 525 */
492 if (pdata->gpio_unbanked) { 526 if (pdata->gpio_unbanked) {
493 static struct irq_chip_type gpio_unbanked;
494
495 /* pass "bank 0" GPIO IRQs to AINTC */ 527 /* pass "bank 0" GPIO IRQs to AINTC */
496 chips[0].chip.to_irq = gpio_to_irq_unbanked; 528 chips[0].chip.to_irq = gpio_to_irq_unbanked;
497 chips[0].gpio_irq = bank_irq; 529 chips[0].gpio_irq = bank_irq;
@@ -500,10 +532,9 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
500 532
501 /* AINTC handles mask/unmask; GPIO handles triggering */ 533 /* AINTC handles mask/unmask; GPIO handles triggering */
502 irq = bank_irq; 534 irq = bank_irq;
503 gpio_unbanked = *container_of(irq_get_chip(irq), 535 irq_chip = gpio_get_irq_chip(irq);
504 struct irq_chip_type, chip); 536 irq_chip->name = "GPIO-AINTC";
505 gpio_unbanked.chip.name = "GPIO-AINTC"; 537 irq_chip->irq_set_type = gpio_irq_type_unbanked;
506 gpio_unbanked.chip.irq_set_type = gpio_irq_type_unbanked;
507 538
508 /* default trigger: both edges */ 539 /* default trigger: both edges */
509 g = gpio2regs(0); 540 g = gpio2regs(0);
@@ -512,7 +543,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
512 543
513 /* set the direct IRQs up to use that irqchip */ 544 /* set the direct IRQs up to use that irqchip */
514 for (gpio = 0; gpio < pdata->gpio_unbanked; gpio++, irq++) { 545 for (gpio = 0; gpio < pdata->gpio_unbanked; gpio++, irq++) {
515 irq_set_chip(irq, &gpio_unbanked.chip); 546 irq_set_chip(irq, irq_chip);
516 irq_set_handler_data(irq, &chips[gpio / 32]); 547 irq_set_handler_data(irq, &chips[gpio / 32]);
517 irq_set_status_flags(irq, IRQ_TYPE_EDGE_BOTH); 548 irq_set_status_flags(irq, IRQ_TYPE_EDGE_BOTH);
518 } 549 }
@@ -555,7 +586,8 @@ done:
555 586
556#if IS_ENABLED(CONFIG_OF) 587#if IS_ENABLED(CONFIG_OF)
557static const struct of_device_id davinci_gpio_ids[] = { 588static const struct of_device_id davinci_gpio_ids[] = {
558 { .compatible = "ti,dm6441-gpio", }, 589 { .compatible = "ti,keystone-gpio", keystone_gpio_get_irq_chip},
590 { .compatible = "ti,dm6441-gpio", davinci_gpio_get_irq_chip},
559 { /* sentinel */ }, 591 { /* sentinel */ },
560}; 592};
561MODULE_DEVICE_TABLE(of, davinci_gpio_ids); 593MODULE_DEVICE_TABLE(of, davinci_gpio_ids);