Merge remote-tracking branch 'keys/keys-next'
[deliverable/linux.git] / drivers / mmc / host / dw_mmc.c
index 32380d5d4f6b15440497b952b035cfe3b76b74ea..22dacae42f84e22b502421b6a3e94f70be96dc5d 100644 (file)
@@ -1691,11 +1691,11 @@ static int dw_mci_data_complete(struct dw_mci *host, struct mmc_data *data)
                                data->error = -ETIMEDOUT;
                        } else if (host->dir_status ==
                                        DW_MCI_RECV_STATUS) {
-                               data->error = -EIO;
+                               data->error = -EILSEQ;
                        }
                } else {
                        /* SDMMC_INT_SBE is included */
-                       data->error = -EIO;
+                       data->error = -EILSEQ;
                }
 
                dev_dbg(host->dev, "data error, status 0x%08x\n", status);
@@ -2523,47 +2523,6 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-#ifdef CONFIG_OF
-/* given a slot, find out the device node representing that slot */
-static struct device_node *dw_mci_of_find_slot_node(struct dw_mci_slot *slot)
-{
-       struct device *dev = slot->mmc->parent;
-       struct device_node *np;
-       const __be32 *addr;
-       int len;
-
-       if (!dev || !dev->of_node)
-               return NULL;
-
-       for_each_child_of_node(dev->of_node, np) {
-               addr = of_get_property(np, "reg", &len);
-               if (!addr || (len < sizeof(int)))
-                       continue;
-               if (be32_to_cpup(addr) == slot->id)
-                       return np;
-       }
-       return NULL;
-}
-
-static void dw_mci_slot_of_parse(struct dw_mci_slot *slot)
-{
-       struct device_node *np = dw_mci_of_find_slot_node(slot);
-
-       if (!np)
-               return;
-
-       if (of_property_read_bool(np, "disable-wp")) {
-               slot->mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT;
-               dev_warn(slot->mmc->parent,
-                       "Slot quirk 'disable-wp' is deprecated\n");
-       }
-}
-#else /* CONFIG_OF */
-static void dw_mci_slot_of_parse(struct dw_mci_slot *slot)
-{
-}
-#endif /* CONFIG_OF */
-
 static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
 {
        struct mmc_host *mmc;
@@ -2626,8 +2585,6 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
        if (host->pdata->caps2)
                mmc->caps2 = host->pdata->caps2;
 
-       dw_mci_slot_of_parse(slot);
-
        ret = mmc_of_parse(mmc);
        if (ret)
                goto err_host_allocated;
@@ -2915,6 +2872,13 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
        if (!pdata)
                return ERR_PTR(-ENOMEM);
 
+       /* find reset controller when exist */
+       pdata->rstc = devm_reset_control_get_optional(dev, NULL);
+       if (IS_ERR(pdata->rstc)) {
+               if (PTR_ERR(pdata->rstc) == -EPROBE_DEFER)
+                       return ERR_PTR(-EPROBE_DEFER);
+       }
+
        /* find out number of slots supported */
        of_property_read_u32(np, "num-slots", &pdata->num_slots);
 
@@ -2986,7 +2950,9 @@ int dw_mci_probe(struct dw_mci *host)
 
        if (!host->pdata) {
                host->pdata = dw_mci_parse_dt(host);
-               if (IS_ERR(host->pdata)) {
+               if (PTR_ERR(host->pdata) == -EPROBE_DEFER) {
+                       return -EPROBE_DEFER;
+               } else if (IS_ERR(host->pdata)) {
                        dev_err(host->dev, "platform data not available\n");
                        return -EINVAL;
                }
@@ -3040,6 +3006,12 @@ int dw_mci_probe(struct dw_mci *host)
                }
        }
 
+       if (!IS_ERR(host->pdata->rstc)) {
+               reset_control_assert(host->pdata->rstc);
+               usleep_range(10, 50);
+               reset_control_deassert(host->pdata->rstc);
+       }
+
        setup_timer(&host->cmd11_timer,
                    dw_mci_cmd11_timer, (unsigned long)host);
 
@@ -3189,13 +3161,14 @@ err_dmaunmap:
        if (host->use_dma && host->dma_ops->exit)
                host->dma_ops->exit(host);
 
+       if (!IS_ERR(host->pdata->rstc))
+               reset_control_assert(host->pdata->rstc);
+
 err_clk_ciu:
-       if (!IS_ERR(host->ciu_clk))
-               clk_disable_unprepare(host->ciu_clk);
+       clk_disable_unprepare(host->ciu_clk);
 
 err_clk_biu:
-       if (!IS_ERR(host->biu_clk))
-               clk_disable_unprepare(host->biu_clk);
+       clk_disable_unprepare(host->biu_clk);
 
        return ret;
 }
@@ -3221,11 +3194,11 @@ void dw_mci_remove(struct dw_mci *host)
        if (host->use_dma && host->dma_ops->exit)
                host->dma_ops->exit(host);
 
-       if (!IS_ERR(host->ciu_clk))
-               clk_disable_unprepare(host->ciu_clk);
+       if (!IS_ERR(host->pdata->rstc))
+               reset_control_assert(host->pdata->rstc);
 
-       if (!IS_ERR(host->biu_clk))
-               clk_disable_unprepare(host->biu_clk);
+       clk_disable_unprepare(host->ciu_clk);
+       clk_disable_unprepare(host->biu_clk);
 }
 EXPORT_SYMBOL(dw_mci_remove);
 
This page took 0.039557 seconds and 5 git commands to generate.