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.
(Just a refresh of what was sent on 7-January.)
---
drivers/mmc/host/davinci_mmc.c | 53 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 52 insertions(+), 1 deletion(-)
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -166,6 +166,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
@@ -1049,6 +1050,35 @@ 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;
+
+ /* FIXME card may already be issuing (level) IRQ ... so when
+ * enabling, check DAT1 here and handle the case where we won't
+ * trigger since the edge already happened.
+ */
+
+ 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);
@@ -1074,6 +1104,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,
};
/*----------------------------------------------------------------------*/
@@ -1096,6 +1127,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,
@@ -1170,9 +1203,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 = 25000000;
@@ -1251,6 +1299,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