Messages in this thread Patch in this message | | | From | Magnus Damm <> | Date | Wed, 11 Mar 2009 21:59:28 +0900 | Subject | [PATCH 05/05] tmio_mmc: Support multiple interrupts |
| |
From: Magnus Damm <damm@opensource.se>
Add support for tmio_mmc hardware configurations with multiple interrupts. With this patch applied all interrupts passed as platform data will be used by the driver.
Signed-off-by: Magnus Damm <damm@opensource.se> ---
drivers/mmc/host/tmio_mmc.c | 58 ++++++++++++++++++++++++++++++++----------- drivers/mmc/host/tmio_mmc.h | 1 2 files changed, 44 insertions(+), 15 deletions(-)
--- 0013/drivers/mmc/host/tmio_mmc.c +++ work/drivers/mmc/host/tmio_mmc.c 2009-03-11 19:38:59.000000000 +0900 @@ -537,6 +537,45 @@ static struct mmc_host_ops tmio_mmc_ops .get_ro = tmio_mmc_get_ro, }; +static int tmio_mmc_hook_irqs(struct platform_device *dev, int hook) +{ + struct mmc_host *mmc = platform_get_drvdata(dev); + struct tmio_mmc_host *host = mmc_priv(mmc); + struct resource *res; + int ret = -ENXIO; + int q, m; + int k = 0; + int n = 0; + + while ((res = platform_get_resource(dev, IORESOURCE_IRQ, k))) { + for (n = res->start; hook && n <= res->end; n++) { + if (request_irq(n, tmio_mmc_irq, IRQF_DISABLED, + dev_name(&dev->dev), host)) + goto rollback; + + set_irq_type(n, IRQ_TYPE_EDGE_FALLING); + } + k++; + } + + if (hook) + return k > 0 ? 0 : -ENOENT; + + k--; + ret = 0; + + rollback: + for (q = k; k >= 0; k--) { + for (m = n; m >= res->start; m--) + free_irq(m, host); + + res = platform_get_resource(dev, IORESOURCE_IRQ, k - 1); + m = res->end; + } + + return ret; +} + #ifdef CONFIG_PM static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state) { @@ -636,25 +675,16 @@ static int __devinit tmio_mmc_probe(stru tmio_mmc_clk_stop(host); reset(host); - ret = platform_get_irq(dev, 0); - if (ret >= 0) - host->irq = ret; - else - goto unmap_cnf; - - disable_mmc_irqs(host->ctl, TMIO_MASK_ALL); - - ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED, "tmio-mmc", - host); + ret = tmio_mmc_hook_irqs(dev, 1); if (ret) goto unmap_cnf; - set_irq_type(host->irq, IRQ_TYPE_EDGE_FALLING); + disable_mmc_irqs(host->ctl, TMIO_MASK_ALL); mmc_add_host(mmc); - printk(KERN_INFO "%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc), - (unsigned long)host->ctl, host->irq); + printk(KERN_INFO "%s at 0x%08lx\n", mmc_hostname(host->mmc), + (unsigned long)host->ctl); /* Unmask the IRQs we want to know about */ enable_mmc_irqs(host->ctl, TMIO_MASK_IRQ); @@ -681,7 +711,7 @@ static int __devexit tmio_mmc_remove(str if (mmc) { struct tmio_mmc_host *host = mmc_priv(mmc); mmc_remove_host(mmc); - free_irq(host->irq, host); + tmio_mmc_hook_irqs(dev, 0); if (host->cnf) iounmap(host->cnf); iounmap(host->ctl); --- 0001/drivers/mmc/host/tmio_mmc.h +++ work/drivers/mmc/host/tmio_mmc.h 2009-03-11 19:38:03.000000000 +0900 @@ -112,7 +112,6 @@ struct tmio_mmc_host { struct mmc_request *mrq; struct mmc_data *data; struct mmc_host *mmc; - int irq; /* pio related stuff */ struct scatterlist *sg_ptr;
| |