Commit f75979b7 authored by Pierre Ossman's avatar Pierre Ossman

sdhci: sdio interrupt support

Add support for relaying the sdio interrupt signal from the card.
Signed-off-by: default avatarPierre Ossman <drzeus@drzeus.cx>
parent 15b82b46
...@@ -800,10 +800,35 @@ static int sdhci_get_ro(struct mmc_host *mmc) ...@@ -800,10 +800,35 @@ static int sdhci_get_ro(struct mmc_host *mmc)
return !(present & SDHCI_WRITE_PROTECT); return !(present & SDHCI_WRITE_PROTECT);
} }
static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
struct sdhci_host *host;
unsigned long flags;
u32 ier;
host = mmc_priv(mmc);
spin_lock_irqsave(&host->lock, flags);
ier = readl(host->ioaddr + SDHCI_INT_ENABLE);
ier &= ~SDHCI_INT_CARD_INT;
if (enable)
ier |= SDHCI_INT_CARD_INT;
writel(ier, host->ioaddr + SDHCI_INT_ENABLE);
writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
mmiowb();
spin_unlock_irqrestore(&host->lock, flags);
}
static const struct mmc_host_ops sdhci_ops = { static const struct mmc_host_ops sdhci_ops = {
.request = sdhci_request, .request = sdhci_request,
.set_ios = sdhci_set_ios, .set_ios = sdhci_set_ios,
.get_ro = sdhci_get_ro, .get_ro = sdhci_get_ro,
.enable_sdio_irq = sdhci_enable_sdio_irq,
}; };
/*****************************************************************************\ /*****************************************************************************\
...@@ -1012,6 +1037,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) ...@@ -1012,6 +1037,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
irqreturn_t result; irqreturn_t result;
struct sdhci_host* host = dev_id; struct sdhci_host* host = dev_id;
u32 intmask; u32 intmask;
int cardint = 0;
spin_lock(&host->lock); spin_lock(&host->lock);
...@@ -1056,6 +1082,11 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) ...@@ -1056,6 +1082,11 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
intmask &= ~SDHCI_INT_BUS_POWER; intmask &= ~SDHCI_INT_BUS_POWER;
if (intmask & SDHCI_INT_CARD_INT)
cardint = 1;
intmask &= ~SDHCI_INT_CARD_INT;
if (intmask) { if (intmask) {
printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n", printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
mmc_hostname(host->mmc), intmask); mmc_hostname(host->mmc), intmask);
...@@ -1070,6 +1101,12 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) ...@@ -1070,6 +1101,12 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
out: out:
spin_unlock(&host->lock); spin_unlock(&host->lock);
/*
* We have to delay this as it calls back into the driver.
*/
if (cardint)
mmc_signal_sdio_irq(host->mmc);
return result; return result;
} }
...@@ -1309,7 +1346,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) ...@@ -1309,7 +1346,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
mmc->ops = &sdhci_ops; mmc->ops = &sdhci_ops;
mmc->f_min = host->max_clk / 256; mmc->f_min = host->max_clk / 256;
mmc->f_max = host->max_clk; mmc->f_max = host->max_clk;
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE; mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_SDIO_IRQ;
if (caps & SDHCI_CAN_DO_HISPD) if (caps & SDHCI_CAN_DO_HISPD)
mmc->caps |= MMC_CAP_SD_HIGHSPEED; mmc->caps |= MMC_CAP_SD_HIGHSPEED;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment