From: David Brownell <[email protected]> SDIO support in the MMC framework seems to involve no more than just being able to report SDIO irqs. Here's (untested) code to do that.
Signed-off-by: David Brownell <[email protected]> --- drivers/mmc/host/davinci_mmc.c | 48 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -174,6 +174,7 @@ struct mmc_davinci_host { void __iomem *base; struct resource *mem_res; int irq; + int sdio_irq; unsigned char bus_mode; #define DAVINCI_MMC_DATADIR_NONE 0 @@ -950,6 +951,30 @@ static irqreturn_t mmc_davinci_irq(int i return IRQ_HANDLED; } +static irqreturn_t mmc_davinci_sdio_irq(int irq, void *dev_id) +{ + struct mmc_davinci_host *host = dev_id; + u32 sdiost; + + sdiost = readl(host->base + DAVINCI_SDIOST); + if (sdiost & BIT(0)) + mmc_signal_sdio_irq(host->mmc); + return IRQ_HANDLED; +} + +static void mmc_davinci_enable_sdio_irq(struct mmc_host *mmc, int enable) +{ + struct mmc_davinci_host *host = mmc_priv(mmc); + u32 sdioen; + + sdioen = readl(host->base + DAVINCI_SDIOEN); + if (!enable) + sdioen &= ~BIT(0); + else + sdioen |= BIT(0); + writel(sdioen, host->base + DAVINCI_SDIOEN); +} + static int mmc_davinci_get_cd(struct mmc_host *mmc) { struct platform_device *pdev = to_platform_device(mmc->parent); @@ -975,6 +1000,7 @@ static struct mmc_host_ops mmc_davinci_o .set_ios = mmc_davinci_set_ios, .get_cd = mmc_davinci_get_cd, .get_ro = mmc_davinci_get_ro, + .enable_sdio_irq = mmc_davinci_enable_sdio_irq, }; static void __init init_mmcsd_host(struct mmc_davinci_host *host) @@ -995,6 +1021,8 @@ static void __init init_mmcsd_host(struc writel(0xFFFF, host->base + DAVINCI_MMCTOR); writel(0xFFFF, host->base + DAVINCI_MMCTOD); + writel(0, host->base + DAVINCI_SDIOEN); + writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_DATRST, host->base + DAVINCI_MMCCTL); writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_CMDRST, @@ -1069,9 +1097,24 @@ static int __init davinci_mmcsd_probe(st /* REVISIT: someday, support IRQ-driven card detection. */ mmc->caps |= MMC_CAP_NEEDS_POLL; - if (!pdata || pdata->wires == 4 || pdata->wires == 0) + if (!pdata || pdata->wires == 4 || pdata->wires == 0) { mmc->caps |= MMC_CAP_4_BIT_DATA; + /* for now, no support for IRQs (on DAT1) except + * when 4-wire mode is supported. + * REVISIT there's a DAT2 read-wait IRQ too ... + */ + host->sdio_irq = platform_get_irq(pdev, 1); + if (host->sdio_irq > 0) { + ret = request_irq(host->sdio_irq, + mmc_davinci_sdio_irq, 0, + mmc_hostname(mmc), host); + if (ret == 0) + mmc->caps |= MMC_CAP_SDIO_IRQ; + } + } + + mmc->ops = &mmc_davinci_ops; mmc->f_min = 312500; mmc->f_max = 52000000; /* MMCplus @52 MHz; SDHC @50 MHz */ @@ -1144,6 +1187,9 @@ static int __exit davinci_mmcsd_remove(s platform_set_drvdata(pdev, NULL); if (host) { + if (host->mmc->caps & MMC_CAP_SDIO_IRQ) + free_irq(host->sdio_irq, host); + mmc_remove_host(host->mmc); free_irq(host->irq, host); _______________________________________________ Davinci-linux-open-source mailing list [email protected] http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
