summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/sdhci-msm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/sdhci-msm.c')
-rw-r--r--drivers/mmc/host/sdhci-msm.c70
1 files changed, 40 insertions, 30 deletions
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index ca72ebfd55a3..7aefeb037ef4 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -1823,7 +1823,7 @@ struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev,
}
pdata->status_gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, &flags);
- if (gpio_is_valid(pdata->status_gpio) & !(flags & OF_GPIO_ACTIVE_LOW))
+ if (gpio_is_valid(pdata->status_gpio) && !(flags & OF_GPIO_ACTIVE_LOW))
pdata->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
of_property_read_u32(np, "qcom,bus-width", &bus_width);
@@ -1837,13 +1837,13 @@ struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev,
}
if (sdhci_msm_dt_get_array(dev, "qcom,devfreq,freq-table",
- &msm_host->mmc->clk_scaling.freq_table,
- &msm_host->mmc->clk_scaling.freq_table_sz, 0))
+ &msm_host->mmc->clk_scaling.pltfm_freq_table,
+ &msm_host->mmc->clk_scaling.pltfm_freq_table_sz, 0))
pr_debug("%s: no clock scaling frequencies were supplied\n",
dev_name(dev));
- else if (!msm_host->mmc->clk_scaling.freq_table ||
- !msm_host->mmc->clk_scaling.freq_table_sz)
- dev_err(dev, "bad dts clock scaling frequencies\n");
+ else if (!msm_host->mmc->clk_scaling.pltfm_freq_table ||
+ !msm_host->mmc->clk_scaling.pltfm_freq_table_sz)
+ dev_err(dev, "bad dts clock scaling frequencies\n");
/*
* Few hosts can support DDR52 mode at the same lower
@@ -1958,7 +1958,7 @@ struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev,
sdhci_msm_pm_qos_parse(dev, pdata);
if (of_get_property(np, "qcom,core_3_0v_support", NULL))
- pdata->core_3_0v_support = true;
+ msm_host->core_3_0v_support = true;
pdata->sdr104_wa = of_property_read_bool(np, "qcom,sdr104-wa");
@@ -2366,21 +2366,6 @@ out:
return ret;
}
-/*
- * Reset vreg by ensuring it is off during probe. A call
- * to enable vreg is needed to balance disable vreg
- */
-static int sdhci_msm_vreg_reset(struct sdhci_msm_pltfm_data *pdata)
-{
- int ret;
-
- ret = sdhci_msm_setup_vreg(pdata, 1, true);
- if (ret)
- return ret;
- ret = sdhci_msm_setup_vreg(pdata, 0, true);
- return ret;
-}
-
/* This init function should be called only once for each SDHC slot */
static int sdhci_msm_vreg_init(struct device *dev,
struct sdhci_msm_pltfm_data *pdata,
@@ -2415,7 +2400,7 @@ static int sdhci_msm_vreg_init(struct device *dev,
if (ret)
goto vdd_reg_deinit;
}
- ret = sdhci_msm_vreg_reset(pdata);
+
if (ret)
dev_err(dev, "vreg reset failed (%d)\n", ret);
goto out;
@@ -2509,15 +2494,30 @@ void sdhci_msm_dump_pwr_ctrl_regs(struct sdhci_host *host)
struct sdhci_msm_host *msm_host = pltfm_host->priv;
const struct sdhci_msm_offset *msm_host_offset =
msm_host->offset;
+ unsigned int irq_flags = 0;
+ struct irq_desc *pwr_irq_desc = irq_to_desc(msm_host->pwr_irq);
+
+ if (pwr_irq_desc)
+ irq_flags = pwr_irq_desc->irq_data.common->state_use_accessors;
- pr_err("%s: PWRCTL_STATUS: 0x%08x | PWRCTL_MASK: 0x%08x | PWRCTL_CTL: 0x%08x\n",
+ pr_err("%s: PWRCTL_STATUS: 0x%08x | PWRCTL_MASK: 0x%08x | PWRCTL_CTL: 0x%08x, pwr isr state=0x%x\n",
mmc_hostname(host->mmc),
sdhci_msm_readl_relaxed(host,
msm_host_offset->CORE_PWRCTL_STATUS),
sdhci_msm_readl_relaxed(host,
msm_host_offset->CORE_PWRCTL_MASK),
sdhci_msm_readl_relaxed(host,
- msm_host_offset->CORE_PWRCTL_CTL));
+ msm_host_offset->CORE_PWRCTL_CTL), irq_flags);
+
+ MMC_TRACE(host->mmc,
+ "%s: Sts: 0x%08x | Mask: 0x%08x | Ctrl: 0x%08x, pwr isr state=0x%x\n",
+ __func__,
+ sdhci_msm_readb_relaxed(host,
+ msm_host_offset->CORE_PWRCTL_STATUS),
+ sdhci_msm_readb_relaxed(host,
+ msm_host_offset->CORE_PWRCTL_MASK),
+ sdhci_msm_readb_relaxed(host,
+ msm_host_offset->CORE_PWRCTL_CTL), irq_flags);
}
static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data)
@@ -2592,7 +2592,9 @@ static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data)
io_level = REQ_IO_HIGH;
}
if (irq_status & CORE_PWRCTL_BUS_OFF) {
- ret = sdhci_msm_setup_vreg(msm_host->pdata, false, false);
+ if (msm_host->pltfm_init_done)
+ ret = sdhci_msm_setup_vreg(msm_host->pdata,
+ false, false);
if (!ret) {
ret = sdhci_msm_setup_pins(msm_host->pdata, false);
ret |= sdhci_msm_set_vdd_io_vol(msm_host->pdata,
@@ -2639,7 +2641,9 @@ static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data)
*/
mb();
- if ((io_level & REQ_IO_HIGH) && (msm_host->caps_0 & CORE_3_0V_SUPPORT))
+ if ((io_level & REQ_IO_HIGH) &&
+ (msm_host->caps_0 & CORE_3_0V_SUPPORT) &&
+ !msm_host->core_3_0v_support)
writel_relaxed((readl_relaxed(host->ioaddr +
msm_host_offset->CORE_VENDOR_SPEC) &
~CORE_IO_PAD_PWR_SWITCH), host->ioaddr +
@@ -2786,10 +2790,14 @@ static void sdhci_msm_check_power_status(struct sdhci_host *host, u32 req_type)
if (done)
init_completion(&msm_host->pwr_irq_completion);
else if (!wait_for_completion_timeout(&msm_host->pwr_irq_completion,
- msecs_to_jiffies(MSM_PWR_IRQ_TIMEOUT_MS)))
+ msecs_to_jiffies(MSM_PWR_IRQ_TIMEOUT_MS))) {
__WARN_printf("%s: request(%d) timed out waiting for pwr_irq\n",
mmc_hostname(host->mmc), req_type);
-
+ MMC_TRACE(host->mmc,
+ "%s: request(%d) timed out waiting for pwr_irq\n",
+ __func__, req_type);
+ sdhci_msm_dump_pwr_ctrl_regs(host);
+ }
pr_debug("%s: %s: request %d done\n", mmc_hostname(host->mmc),
__func__, req_type);
}
@@ -4133,7 +4141,7 @@ static void sdhci_set_default_hw_caps(struct sdhci_msm_host *msm_host,
msm_host->use_14lpp_dll = true;
/* Fake 3.0V support for SDIO devices which requires such voltage */
- if (msm_host->pdata->core_3_0v_support) {
+ if (msm_host->core_3_0v_support) {
caps |= CORE_3_0V_SUPPORT;
writel_relaxed((readl_relaxed(host->ioaddr +
SDHCI_CAPABILITIES) | caps), host->ioaddr +
@@ -4666,6 +4674,8 @@ static int sdhci_msm_probe(struct platform_device *pdev)
goto vreg_deinit;
}
+ msm_host->pltfm_init_done = true;
+
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, MSM_AUTOSUSPEND_DELAY_MS);