diff options
Diffstat (limited to 'drivers/mmc/host/cqhci.c')
-rw-r--r-- | drivers/mmc/host/cqhci.c | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/drivers/mmc/host/cqhci.c b/drivers/mmc/host/cqhci.c index 5047f7343ffc..75934f3c117e 100644 --- a/drivers/mmc/host/cqhci.c +++ b/drivers/mmc/host/cqhci.c @@ -5,6 +5,7 @@ #include <linux/delay.h> #include <linux/highmem.h> #include <linux/io.h> +#include <linux/iopoll.h> #include <linux/module.h> #include <linux/dma-mapping.h> #include <linux/slab.h> @@ -298,16 +299,16 @@ static void __cqhci_disable(struct cqhci_host *cq_host) cq_host->activated = false; } -int cqhci_suspend(struct mmc_host *mmc) +int cqhci_deactivate(struct mmc_host *mmc) { struct cqhci_host *cq_host = mmc->cqe_private; - if (cq_host->enabled) + if (cq_host->enabled && cq_host->activated) __cqhci_disable(cq_host); return 0; } -EXPORT_SYMBOL(cqhci_suspend); +EXPORT_SYMBOL(cqhci_deactivate); int cqhci_resume(struct mmc_host *mmc) { @@ -321,14 +322,20 @@ static int cqhci_enable(struct mmc_host *mmc, struct mmc_card *card) struct cqhci_host *cq_host = mmc->cqe_private; int err; + if (!card->ext_csd.cmdq_en) + return -EINVAL; + if (cq_host->enabled) return 0; cq_host->rca = card->rca; err = cqhci_host_alloc_tdl(cq_host); - if (err) + if (err) { + pr_err("%s: Failed to enable CQE, error %d\n", + mmc_hostname(mmc), err); return err; + } __cqhci_enable(cq_host); @@ -343,12 +350,16 @@ static int cqhci_enable(struct mmc_host *mmc, struct mmc_card *card) /* CQHCI is idle and should halt immediately, so set a small timeout */ #define CQHCI_OFF_TIMEOUT 100 +static u32 cqhci_read_ctl(struct cqhci_host *cq_host) +{ + return cqhci_readl(cq_host, CQHCI_CTL); +} + static void cqhci_off(struct mmc_host *mmc) { struct cqhci_host *cq_host = mmc->cqe_private; - ktime_t timeout; - bool timed_out; u32 reg; + int err; if (!cq_host->enabled || !mmc->cqe_on || cq_host->recovery_halt) return; @@ -358,15 +369,9 @@ static void cqhci_off(struct mmc_host *mmc) cqhci_writel(cq_host, CQHCI_HALT, CQHCI_CTL); - timeout = ktime_add_us(ktime_get(), CQHCI_OFF_TIMEOUT); - while (1) { - timed_out = ktime_compare(ktime_get(), timeout) > 0; - reg = cqhci_readl(cq_host, CQHCI_CTL); - if ((reg & CQHCI_HALT) || timed_out) - break; - } - - if (timed_out) + err = readx_poll_timeout(cqhci_read_ctl, cq_host, reg, + reg & CQHCI_HALT, 0, CQHCI_OFF_TIMEOUT); + if (err < 0) pr_err("%s: cqhci: CQE stuck on\n", mmc_hostname(mmc)); else pr_debug("%s: cqhci: CQE off\n", mmc_hostname(mmc)); @@ -1071,7 +1076,7 @@ struct cqhci_host *cqhci_pltfm_init(struct platform_device *pdev) /* check and setup CMDQ interface */ cqhci_memres = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "cqhci_mem"); + "cqhci"); if (!cqhci_memres) { dev_dbg(&pdev->dev, "CMDQ not supported\n"); return ERR_PTR(-EINVAL); |