aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/common
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-01-15 19:09:22 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-02-09 10:34:49 -0500
commitf03ecaa0aa3a3b74b9b9e8341cf7919516c902d5 (patch)
tree600449a48766ceb7387035229a0a4e7db338c96d /arch/arm/common
parent1ebcd7654e4e391a36945c937c125995c737c446 (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.c19
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 = {
438static void sa1111_setup_irq(struct sa1111 *sachip) 438static 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 */
704static int __devinit 710static 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