|
@@ -2778,12 +2778,50 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
|
|
|
|
+static int dw_mci_init_slot_caps(struct dw_mci_slot *slot)
|
|
|
+{
|
|
|
+ struct dw_mci *host = slot->host;
|
|
|
+ const struct dw_mci_drv_data *drv_data = host->drv_data;
|
|
|
+ struct mmc_host *mmc = slot->mmc;
|
|
|
+ int ctrl_id;
|
|
|
+
|
|
|
+ if (host->pdata->caps)
|
|
|
+ mmc->caps = host->pdata->caps;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Support MMC_CAP_ERASE by default.
|
|
|
+ * It needs to use trim/discard/erase commands.
|
|
|
+ */
|
|
|
+ mmc->caps |= MMC_CAP_ERASE;
|
|
|
+
|
|
|
+ if (host->pdata->pm_caps)
|
|
|
+ mmc->pm_caps = host->pdata->pm_caps;
|
|
|
+
|
|
|
+ if (host->dev->of_node) {
|
|
|
+ ctrl_id = of_alias_get_id(host->dev->of_node, "mshc");
|
|
|
+ if (ctrl_id < 0)
|
|
|
+ ctrl_id = 0;
|
|
|
+ } else {
|
|
|
+ ctrl_id = to_platform_device(host->dev)->id;
|
|
|
+ }
|
|
|
+ if (drv_data && drv_data->caps)
|
|
|
+ mmc->caps |= drv_data->caps[ctrl_id];
|
|
|
+
|
|
|
+ if (host->pdata->caps2)
|
|
|
+ mmc->caps2 = host->pdata->caps2;
|
|
|
+
|
|
|
+ /* Process SDIO IRQs through the sdio_irq_work. */
|
|
|
+ if (mmc->caps & MMC_CAP_SDIO_IRQ)
|
|
|
+ mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int dw_mci_init_slot(struct dw_mci *host)
|
|
|
{
|
|
|
struct mmc_host *mmc;
|
|
|
struct dw_mci_slot *slot;
|
|
|
- const struct dw_mci_drv_data *drv_data = host->drv_data;
|
|
|
- int ctrl_id, ret;
|
|
|
+ int ret;
|
|
|
u32 freq[2];
|
|
|
|
|
|
mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), host->dev);
|
|
@@ -2817,38 +2855,13 @@ static int dw_mci_init_slot(struct dw_mci *host)
|
|
|
if (!mmc->ocr_avail)
|
|
|
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
|
|
|
|
|
|
- if (host->pdata->caps)
|
|
|
- mmc->caps = host->pdata->caps;
|
|
|
-
|
|
|
- /*
|
|
|
- * Support MMC_CAP_ERASE by default.
|
|
|
- * It needs to use trim/discard/erase commands.
|
|
|
- */
|
|
|
- mmc->caps |= MMC_CAP_ERASE;
|
|
|
-
|
|
|
- if (host->pdata->pm_caps)
|
|
|
- mmc->pm_caps = host->pdata->pm_caps;
|
|
|
-
|
|
|
- if (host->dev->of_node) {
|
|
|
- ctrl_id = of_alias_get_id(host->dev->of_node, "mshc");
|
|
|
- if (ctrl_id < 0)
|
|
|
- ctrl_id = 0;
|
|
|
- } else {
|
|
|
- ctrl_id = to_platform_device(host->dev)->id;
|
|
|
- }
|
|
|
- if (drv_data && drv_data->caps)
|
|
|
- mmc->caps |= drv_data->caps[ctrl_id];
|
|
|
-
|
|
|
- if (host->pdata->caps2)
|
|
|
- mmc->caps2 = host->pdata->caps2;
|
|
|
-
|
|
|
ret = mmc_of_parse(mmc);
|
|
|
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;
|
|
|
+ ret = dw_mci_init_slot_caps(slot);
|
|
|
+ if (ret)
|
|
|
+ goto err_host_allocated;
|
|
|
|
|
|
/* Useful defaults if platform data is unset. */
|
|
|
if (host->use_dma == TRANS_MODE_IDMAC) {
|