|
@@ -1642,9 +1642,8 @@ static void dw_mci_init_card(struct mmc_host *mmc, struct mmc_card *card)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
|
|
|
+static void __dw_mci_enable_sdio_irq(struct dw_mci_slot *slot, int enb)
|
|
|
{
|
|
|
- struct dw_mci_slot *slot = mmc_priv(mmc);
|
|
|
struct dw_mci *host = slot->host;
|
|
|
unsigned long irqflags;
|
|
|
u32 int_mask;
|
|
@@ -1662,6 +1661,20 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
|
|
|
spin_unlock_irqrestore(&host->irq_lock, irqflags);
|
|
|
}
|
|
|
|
|
|
+static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
|
|
|
+{
|
|
|
+ struct dw_mci_slot *slot = mmc_priv(mmc);
|
|
|
+
|
|
|
+ __dw_mci_enable_sdio_irq(slot, enb);
|
|
|
+}
|
|
|
+
|
|
|
+static void dw_mci_ack_sdio_irq(struct mmc_host *mmc)
|
|
|
+{
|
|
|
+ struct dw_mci_slot *slot = mmc_priv(mmc);
|
|
|
+
|
|
|
+ __dw_mci_enable_sdio_irq(slot, 1);
|
|
|
+}
|
|
|
+
|
|
|
static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
|
|
|
{
|
|
|
struct dw_mci_slot *slot = mmc_priv(mmc);
|
|
@@ -1763,6 +1776,7 @@ static const struct mmc_host_ops dw_mci_ops = {
|
|
|
.get_cd = dw_mci_get_cd,
|
|
|
.hw_reset = dw_mci_hw_reset,
|
|
|
.enable_sdio_irq = dw_mci_enable_sdio_irq,
|
|
|
+ .ack_sdio_irq = dw_mci_ack_sdio_irq,
|
|
|
.execute_tuning = dw_mci_execute_tuning,
|
|
|
.card_busy = dw_mci_card_busy,
|
|
|
.start_signal_voltage_switch = dw_mci_switch_voltage,
|
|
@@ -2654,7 +2668,8 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
|
|
|
if (pending & SDMMC_INT_SDIO(slot->sdio_id)) {
|
|
|
mci_writel(host, RINTSTS,
|
|
|
SDMMC_INT_SDIO(slot->sdio_id));
|
|
|
- mmc_signal_sdio_irq(slot->mmc);
|
|
|
+ __dw_mci_enable_sdio_irq(slot, 0);
|
|
|
+ sdio_signal_irq(slot->mmc);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2755,6 +2770,10 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
|
|
|
if (ret)
|
|
|
goto err_host_allocated;
|
|
|
|
|
|
+ /* Process SDIO IRQs through the sdio_irq_work. */
|
|
|
+ if (mmc->caps & MMC_CAP_SDIO_IRQ)
|
|
|
+ mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
|
|
|
+
|
|
|
/* Useful defaults if platform data is unset. */
|
|
|
if (host->use_dma == TRANS_MODE_IDMAC) {
|
|
|
mmc->max_segs = host->ring_size;
|