Skip to content

Commit f75979b

Browse files
author
Pierre Ossman
committed
sdhci: sdio interrupt support
Add support for relaying the sdio interrupt signal from the card. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
1 parent 15b82b4 commit f75979b

File tree

1 file changed

+38
-1
lines changed

1 file changed

+38
-1
lines changed

drivers/mmc/host/sdhci.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -800,10 +800,35 @@ static int sdhci_get_ro(struct mmc_host *mmc)
800800
return !(present & SDHCI_WRITE_PROTECT);
801801
}
802802

803+
static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
804+
{
805+
struct sdhci_host *host;
806+
unsigned long flags;
807+
u32 ier;
808+
809+
host = mmc_priv(mmc);
810+
811+
spin_lock_irqsave(&host->lock, flags);
812+
813+
ier = readl(host->ioaddr + SDHCI_INT_ENABLE);
814+
815+
ier &= ~SDHCI_INT_CARD_INT;
816+
if (enable)
817+
ier |= SDHCI_INT_CARD_INT;
818+
819+
writel(ier, host->ioaddr + SDHCI_INT_ENABLE);
820+
writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
821+
822+
mmiowb();
823+
824+
spin_unlock_irqrestore(&host->lock, flags);
825+
}
826+
803827
static const struct mmc_host_ops sdhci_ops = {
804828
.request = sdhci_request,
805829
.set_ios = sdhci_set_ios,
806830
.get_ro = sdhci_get_ro,
831+
.enable_sdio_irq = sdhci_enable_sdio_irq,
807832
};
808833

809834
/*****************************************************************************\
@@ -1012,6 +1037,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
10121037
irqreturn_t result;
10131038
struct sdhci_host* host = dev_id;
10141039
u32 intmask;
1040+
int cardint = 0;
10151041

10161042
spin_lock(&host->lock);
10171043

@@ -1056,6 +1082,11 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
10561082

10571083
intmask &= ~SDHCI_INT_BUS_POWER;
10581084

1085+
if (intmask & SDHCI_INT_CARD_INT)
1086+
cardint = 1;
1087+
1088+
intmask &= ~SDHCI_INT_CARD_INT;
1089+
10591090
if (intmask) {
10601091
printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
10611092
mmc_hostname(host->mmc), intmask);
@@ -1070,6 +1101,12 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
10701101
out:
10711102
spin_unlock(&host->lock);
10721103

1104+
/*
1105+
* We have to delay this as it calls back into the driver.
1106+
*/
1107+
if (cardint)
1108+
mmc_signal_sdio_irq(host->mmc);
1109+
10731110
return result;
10741111
}
10751112

@@ -1309,7 +1346,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
13091346
mmc->ops = &sdhci_ops;
13101347
mmc->f_min = host->max_clk / 256;
13111348
mmc->f_max = host->max_clk;
1312-
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE;
1349+
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_SDIO_IRQ;
13131350

13141351
if (caps & SDHCI_CAN_DO_HISPD)
13151352
mmc->caps |= MMC_CAP_SD_HIGHSPEED;

0 commit comments

Comments
 (0)