|
@@ -2876,6 +2876,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);
|
|
|
|
|
@@ -2947,7 +2954,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;
|
|
|
}
|
|
@@ -3001,6 +3010,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);
|
|
|
|
|
@@ -3150,6 +3165,9 @@ 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:
|
|
|
clk_disable_unprepare(host->ciu_clk);
|
|
|
|
|
@@ -3180,6 +3198,9 @@ 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->pdata->rstc))
|
|
|
+ reset_control_assert(host->pdata->rstc);
|
|
|
+
|
|
|
clk_disable_unprepare(host->ciu_clk);
|
|
|
clk_disable_unprepare(host->biu_clk);
|
|
|
}
|