diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-01-15 19:09:22 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-02-09 10:34:49 -0500 |
commit | f03ecaa0aa3a3b74b9b9e8341cf7919516c902d5 (patch) | |
tree | 600449a48766ceb7387035229a0a4e7db338c96d /arch/arm/common | |
parent | 1ebcd7654e4e391a36945c937c125995c737c446 (diff) |
ARM: sa1111: finish "allow cascaded IRQs to be used by platforms"
Commit 19851c58e680 (sa1111: allow cascaded IRQs to be used by platforms)
moved the IRQ definitions to the .c file, and added an irq_base member
to the private data structure.
The inerrupt demultiplexer uses irq_base, but the interrupt setup code
does not. Also, although the commit adds a private data structure to
pass this data, it isn't even referenced, resulting in irq_base being
zero.
We also copied the IRQ numbers from the device info array into the actual
devices, resulting in wrong interrupt numbers passed to the sub-devices.
The net effect of this is that we always overwrite IRQs 0-54, even if
they are allocated elsewhere in the system.
Add the code necessary to setup the private irq_base, and use it in the
IRQ setup code. Make the SA-1111 probe fail with -EINVAL if there is no
platform data provided.
Acked-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/common')
-rw-r--r-- | arch/arm/common/sa1111.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 957f6e3c4280..d3a8f5e26487 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c | |||
@@ -438,7 +438,7 @@ static struct irq_chip sa1111_high_chip = { | |||
438 | static void sa1111_setup_irq(struct sa1111 *sachip) | 438 | static void sa1111_setup_irq(struct sa1111 *sachip) |
439 | { | 439 | { |
440 | void __iomem *irqbase = sachip->base + SA1111_INTC; | 440 | void __iomem *irqbase = sachip->base + SA1111_INTC; |
441 | unsigned int irq; | 441 | unsigned i, irq; |
442 | 442 | ||
443 | /* | 443 | /* |
444 | * We're guaranteed that this region hasn't been taken. | 444 | * We're guaranteed that this region hasn't been taken. |
@@ -464,14 +464,16 @@ static void sa1111_setup_irq(struct sa1111 *sachip) | |||
464 | sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0); | 464 | sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0); |
465 | sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1); | 465 | sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1); |
466 | 466 | ||
467 | for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) { | 467 | for (i = IRQ_GPAIN0; i <= SSPROR; i++) { |
468 | irq = sachip->irq_base + i; | ||
468 | irq_set_chip_and_handler(irq, &sa1111_low_chip, | 469 | irq_set_chip_and_handler(irq, &sa1111_low_chip, |
469 | handle_edge_irq); | 470 | handle_edge_irq); |
470 | irq_set_chip_data(irq, sachip); | 471 | irq_set_chip_data(irq, sachip); |
471 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 472 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
472 | } | 473 | } |
473 | 474 | ||
474 | for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) { | 475 | for (i = AUDXMTDMADONEA; i <= IRQ_S1_BVD1_STSCHG; i++) { |
476 | irq = sachip->irq_base + i; | ||
475 | irq_set_chip_and_handler(irq, &sa1111_high_chip, | 477 | irq_set_chip_and_handler(irq, &sa1111_high_chip, |
476 | handle_edge_irq); | 478 | handle_edge_irq); |
477 | irq_set_chip_data(irq, sachip); | 479 | irq_set_chip_data(irq, sachip); |
@@ -625,6 +627,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, | |||
625 | struct sa1111_dev_info *info) | 627 | struct sa1111_dev_info *info) |
626 | { | 628 | { |
627 | struct sa1111_dev *dev; | 629 | struct sa1111_dev *dev; |
630 | unsigned i; | ||
628 | int ret; | 631 | int ret; |
629 | 632 | ||
630 | dev = kzalloc(sizeof(struct sa1111_dev), GFP_KERNEL); | 633 | dev = kzalloc(sizeof(struct sa1111_dev), GFP_KERNEL); |
@@ -645,7 +648,9 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, | |||
645 | dev->res.flags = IORESOURCE_MEM; | 648 | dev->res.flags = IORESOURCE_MEM; |
646 | dev->mapbase = sachip->base + info->offset; | 649 | dev->mapbase = sachip->base + info->offset; |
647 | dev->skpcr_mask = info->skpcr_mask; | 650 | dev->skpcr_mask = info->skpcr_mask; |
648 | memmove(dev->irq, info->irq, sizeof(dev->irq)); | 651 | |
652 | for (i = 0; i < ARRAY_SIZE(info->irq); i++) | ||
653 | dev->irq[i] = sachip->irq_base + info->irq[i]; | ||
649 | 654 | ||
650 | ret = request_resource(parent, &dev->res); | 655 | ret = request_resource(parent, &dev->res); |
651 | if (ret) { | 656 | if (ret) { |
@@ -699,16 +704,21 @@ out: | |||
699 | * Returns: | 704 | * Returns: |
700 | * %-ENODEV device not found. | 705 | * %-ENODEV device not found. |
701 | * %-EBUSY physical address already marked in-use. | 706 | * %-EBUSY physical address already marked in-use. |
707 | * %-EINVAL no platform data passed | ||
702 | * %0 successful. | 708 | * %0 successful. |
703 | */ | 709 | */ |
704 | static int __devinit | 710 | static int __devinit |
705 | __sa1111_probe(struct device *me, struct resource *mem, int irq) | 711 | __sa1111_probe(struct device *me, struct resource *mem, int irq) |
706 | { | 712 | { |
713 | struct sa1111_platform_data *pd = me->platform_data; | ||
707 | struct sa1111 *sachip; | 714 | struct sa1111 *sachip; |
708 | unsigned long id; | 715 | unsigned long id; |
709 | unsigned int has_devs; | 716 | unsigned int has_devs; |
710 | int i, ret = -ENODEV; | 717 | int i, ret = -ENODEV; |
711 | 718 | ||
719 | if (!pd) | ||
720 | return -EINVAL; | ||
721 | |||
712 | sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL); | 722 | sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL); |
713 | if (!sachip) | 723 | if (!sachip) |
714 | return -ENOMEM; | 724 | return -ENOMEM; |
@@ -730,6 +740,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) | |||
730 | 740 | ||
731 | sachip->phys = mem->start; | 741 | sachip->phys = mem->start; |
732 | sachip->irq = irq; | 742 | sachip->irq = irq; |
743 | sachip->irq_base = pd->irq_base; | ||
733 | 744 | ||
734 | /* | 745 | /* |
735 | * Map the whole region. This also maps the | 746 | * Map the whole region. This also maps the |