|
|
@@ -2635,6 +2635,34 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
|
|
|
}
|
|
|
#endif /* CONFIG_OF */
|
|
|
|
|
|
+static void dw_mci_enable_cd(struct dw_mci *host)
|
|
|
+{
|
|
|
+ struct dw_mci_board *brd = host->pdata;
|
|
|
+ unsigned long irqflags;
|
|
|
+ u32 temp;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ /* No need for CD if broken card detection */
|
|
|
+ if (brd->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION)
|
|
|
+ return;
|
|
|
+
|
|
|
+ /* No need for CD if all slots have a non-error GPIO */
|
|
|
+ for (i = 0; i < host->num_slots; i++) {
|
|
|
+ struct dw_mci_slot *slot = host->slot[i];
|
|
|
+
|
|
|
+ if (IS_ERR_VALUE(mmc_gpio_get_cd(slot->mmc)))
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (i == host->num_slots)
|
|
|
+ return;
|
|
|
+
|
|
|
+ spin_lock_irqsave(&host->irq_lock, irqflags);
|
|
|
+ temp = mci_readl(host, INTMASK);
|
|
|
+ temp |= SDMMC_INT_CD;
|
|
|
+ mci_writel(host, INTMASK, temp);
|
|
|
+ spin_unlock_irqrestore(&host->irq_lock, irqflags);
|
|
|
+}
|
|
|
+
|
|
|
int dw_mci_probe(struct dw_mci *host)
|
|
|
{
|
|
|
const struct dw_mci_drv_data *drv_data = host->drv_data;
|
|
|
@@ -2808,13 +2836,13 @@ int dw_mci_probe(struct dw_mci *host)
|
|
|
host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1;
|
|
|
|
|
|
/*
|
|
|
- * Enable interrupts for command done, data over, data empty, card det,
|
|
|
+ * Enable interrupts for command done, data over, data empty,
|
|
|
* receive ready and error such as transmit, receive timeout, crc error
|
|
|
*/
|
|
|
mci_writel(host, RINTSTS, 0xFFFFFFFF);
|
|
|
mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER |
|
|
|
SDMMC_INT_TXDR | SDMMC_INT_RXDR |
|
|
|
- DW_MCI_ERROR_FLAGS | SDMMC_INT_CD);
|
|
|
+ DW_MCI_ERROR_FLAGS);
|
|
|
mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */
|
|
|
|
|
|
dev_info(host->dev, "DW MMC controller at irq %d, "
|
|
|
@@ -2831,6 +2859,9 @@ int dw_mci_probe(struct dw_mci *host)
|
|
|
init_slots++;
|
|
|
}
|
|
|
|
|
|
+ /* Now that slots are all setup, we can enable card detect */
|
|
|
+ dw_mci_enable_cd(host);
|
|
|
+
|
|
|
if (init_slots) {
|
|
|
dev_info(host->dev, "%d slots initialized\n", init_slots);
|
|
|
} else {
|
|
|
@@ -2925,7 +2956,7 @@ int dw_mci_resume(struct dw_mci *host)
|
|
|
mci_writel(host, RINTSTS, 0xFFFFFFFF);
|
|
|
mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER |
|
|
|
SDMMC_INT_TXDR | SDMMC_INT_RXDR |
|
|
|
- DW_MCI_ERROR_FLAGS | SDMMC_INT_CD);
|
|
|
+ DW_MCI_ERROR_FLAGS);
|
|
|
mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE);
|
|
|
|
|
|
for (i = 0; i < host->num_slots; i++) {
|
|
|
@@ -2937,6 +2968,10 @@ int dw_mci_resume(struct dw_mci *host)
|
|
|
dw_mci_setup_bus(slot, true);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /* Now that slots are all setup, we can enable card detect */
|
|
|
+ dw_mci_enable_cd(host);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
EXPORT_SYMBOL(dw_mci_resume);
|