aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/mmci.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@stericsson.com>2010-10-19 07:39:48 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-11-10 08:10:01 -0500
commit2686b4b408c25349aee7b35558722d5730d67224 (patch)
tree4ad3778ff46e209237c7695395c7e4b174598ec0 /drivers/mmc/host/mmci.c
parentf6614b7bb405a9b35dd28baea989a749492c46b2 (diff)
ARM: 6311/2: mmci: work with only one irq
The DBx500 variants have only one IRQ line hooked up. Allow these (and any other implementations which choose to use only one irq) to work by directing the PIO interrupts also to the first IRQ line. Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@stericsson.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/mmc/host/mmci.c')
-rw-r--r--drivers/mmc/host/mmci.c50
1 files changed, 41 insertions, 9 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 87b4fc6c98c2..ed700a5b03ae 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -129,10 +129,26 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
129 spin_lock(&host->lock); 129 spin_lock(&host->lock);
130} 130}
131 131
132static void mmci_set_mask1(struct mmci_host *host, unsigned int mask)
133{
134 void __iomem *base = host->base;
135
136 if (host->singleirq) {
137 unsigned int mask0 = readl(base + MMCIMASK0);
138
139 mask0 &= ~MCI_IRQ1MASK;
140 mask0 |= mask;
141
142 writel(mask0, base + MMCIMASK0);
143 }
144
145 writel(mask, base + MMCIMASK1);
146}
147
132static void mmci_stop_data(struct mmci_host *host) 148static void mmci_stop_data(struct mmci_host *host)
133{ 149{
134 writel(0, host->base + MMCIDATACTRL); 150 writel(0, host->base + MMCIDATACTRL);
135 writel(0, host->base + MMCIMASK1); 151 mmci_set_mask1(host, 0);
136 host->data = NULL; 152 host->data = NULL;
137} 153}
138 154
@@ -198,7 +214,7 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
198 214
199 writel(datactrl, base + MMCIDATACTRL); 215 writel(datactrl, base + MMCIDATACTRL);
200 writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); 216 writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0);
201 writel(irqmask, base + MMCIMASK1); 217 mmci_set_mask1(host, irqmask);
202} 218}
203 219
204static void 220static void
@@ -437,7 +453,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
437 * "any data available" mode. 453 * "any data available" mode.
438 */ 454 */
439 if (status & MCI_RXACTIVE && host->size < variant->fifosize) 455 if (status & MCI_RXACTIVE && host->size < variant->fifosize)
440 writel(MCI_RXDATAAVLBLMASK, base + MMCIMASK1); 456 mmci_set_mask1(host, MCI_RXDATAAVLBLMASK);
441 457
442 /* 458 /*
443 * If we run out of data, disable the data IRQs; this 459 * If we run out of data, disable the data IRQs; this
@@ -446,7 +462,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
446 * stops us racing with our data end IRQ. 462 * stops us racing with our data end IRQ.
447 */ 463 */
448 if (host->size == 0) { 464 if (host->size == 0) {
449 writel(0, base + MMCIMASK1); 465 mmci_set_mask1(host, 0);
450 writel(readl(base + MMCIMASK0) | MCI_DATAENDMASK, base + MMCIMASK0); 466 writel(readl(base + MMCIMASK0) | MCI_DATAENDMASK, base + MMCIMASK0);
451 } 467 }
452 468
@@ -469,6 +485,14 @@ static irqreturn_t mmci_irq(int irq, void *dev_id)
469 struct mmc_data *data; 485 struct mmc_data *data;
470 486
471 status = readl(host->base + MMCISTATUS); 487 status = readl(host->base + MMCISTATUS);
488
489 if (host->singleirq) {
490 if (status & readl(host->base + MMCIMASK1))
491 mmci_pio_irq(irq, dev_id);
492
493 status &= ~MCI_IRQ1MASK;
494 }
495
472 status &= readl(host->base + MMCIMASK0); 496 status &= readl(host->base + MMCIMASK0);
473 writel(status, host->base + MMCICLEAR); 497 writel(status, host->base + MMCICLEAR);
474 498
@@ -635,6 +659,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
635 struct variant_data *variant = id->data; 659 struct variant_data *variant = id->data;
636 struct mmci_host *host; 660 struct mmci_host *host;
637 struct mmc_host *mmc; 661 struct mmc_host *mmc;
662 unsigned int mask;
638 int ret; 663 int ret;
639 664
640 /* must have platform data */ 665 /* must have platform data */
@@ -806,11 +831,17 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
806 if (ret) 831 if (ret)
807 goto unmap; 832 goto unmap;
808 833
809 ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED, DRIVER_NAME " (pio)", host); 834 if (dev->irq[1] == NO_IRQ)
810 if (ret) 835 host->singleirq = true;
811 goto irq0_free; 836 else {
837 ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED,
838 DRIVER_NAME " (pio)", host);
839 if (ret)
840 goto irq0_free;
841 }
812 842
813 writel(MCI_IRQENABLE, host->base + MMCIMASK0); 843 mask = MCI_IRQENABLE;
844 writel(mask, host->base + MMCIMASK0);
814 845
815 amba_set_drvdata(dev, mmc); 846 amba_set_drvdata(dev, mmc);
816 847
@@ -864,7 +895,8 @@ static int __devexit mmci_remove(struct amba_device *dev)
864 writel(0, host->base + MMCIDATACTRL); 895 writel(0, host->base + MMCIDATACTRL);
865 896
866 free_irq(dev->irq[0], host); 897 free_irq(dev->irq[0], host);
867 free_irq(dev->irq[1], host); 898 if (!host->singleirq)
899 free_irq(dev->irq[1], host);
868 900
869 if (host->gpio_wp != -ENOSYS) 901 if (host->gpio_wp != -ENOSYS)
870 gpio_free(host->gpio_wp); 902 gpio_free(host->gpio_wp);