diff options
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r-- | drivers/mmc/host/sdhci.c | 103 |
1 files changed, 33 insertions, 70 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index acd8c620ec43..cbaf3df3ebd9 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -55,8 +55,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); static void sdhci_tuning_timer(unsigned long data); static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable); static int sdhci_pre_dma_transfer(struct sdhci_host *host, - struct mmc_data *data, - struct sdhci_host_next *next); + struct mmc_data *data); static int sdhci_do_get_cd(struct sdhci_host *host); #ifdef CONFIG_PM @@ -510,7 +509,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, goto fail; BUG_ON(host->align_addr & host->align_mask); - host->sg_count = sdhci_pre_dma_transfer(host, data, NULL); + host->sg_count = sdhci_pre_dma_transfer(host, data); if (host->sg_count < 0) goto unmap_align; @@ -649,9 +648,11 @@ static void sdhci_adma_table_post(struct sdhci_host *host, } } - if (!data->host_cookie) + if (data->host_cookie == COOKIE_MAPPED) { dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, direction); + data->host_cookie = COOKIE_UNMAPPED; + } } static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) @@ -847,7 +848,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) } else { int sg_cnt; - sg_cnt = sdhci_pre_dma_transfer(host, data, NULL); + sg_cnt = sdhci_pre_dma_transfer(host, data); if (sg_cnt <= 0) { /* * This only happens when someone fed @@ -963,11 +964,13 @@ static void sdhci_finish_data(struct sdhci_host *host) if (host->flags & SDHCI_USE_ADMA) sdhci_adma_table_post(host, data); else { - if (!data->host_cookie) + if (data->host_cookie == COOKIE_MAPPED) { dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, (data->flags & MMC_DATA_READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); + data->host_cookie = COOKIE_UNMAPPED; + } } } @@ -1146,6 +1149,7 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host) preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR104); break; case MMC_TIMING_UHS_DDR50: + case MMC_TIMING_MMC_DDR52: preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50); break; case MMC_TIMING_MMC_HS400: @@ -1598,7 +1602,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) (ios->timing == MMC_TIMING_UHS_SDR25) || (ios->timing == MMC_TIMING_UHS_SDR50) || (ios->timing == MMC_TIMING_UHS_SDR104) || - (ios->timing == MMC_TIMING_UHS_DDR50))) { + (ios->timing == MMC_TIMING_UHS_DDR50) || + (ios->timing == MMC_TIMING_MMC_DDR52))) { u16 preset; sdhci_enable_preset_value(host, true); @@ -2129,49 +2134,36 @@ static void sdhci_post_req(struct mmc_host *mmc, struct mmc_request *mrq, struct mmc_data *data = mrq->data; if (host->flags & SDHCI_REQ_USE_DMA) { - if (data->host_cookie) + if (data->host_cookie == COOKIE_GIVEN || + data->host_cookie == COOKIE_MAPPED) dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, data->flags & MMC_DATA_WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - mrq->data->host_cookie = 0; + data->host_cookie = COOKIE_UNMAPPED; } } static int sdhci_pre_dma_transfer(struct sdhci_host *host, - struct mmc_data *data, - struct sdhci_host_next *next) + struct mmc_data *data) { int sg_count; - if (!next && data->host_cookie && - data->host_cookie != host->next_data.cookie) { - pr_debug(DRIVER_NAME "[%s] invalid cookie: %d, next-cookie %d\n", - __func__, data->host_cookie, host->next_data.cookie); - data->host_cookie = 0; + if (data->host_cookie == COOKIE_MAPPED) { + data->host_cookie = COOKIE_GIVEN; + return data->sg_count; } - /* Check if next job is already prepared */ - if (next || - (!next && data->host_cookie != host->next_data.cookie)) { - sg_count = dma_map_sg(mmc_dev(host->mmc), data->sg, - data->sg_len, - data->flags & MMC_DATA_WRITE ? - DMA_TO_DEVICE : DMA_FROM_DEVICE); - - } else { - sg_count = host->next_data.sg_count; - host->next_data.sg_count = 0; - } + WARN_ON(data->host_cookie == COOKIE_GIVEN); + sg_count = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + data->flags & MMC_DATA_WRITE ? + DMA_TO_DEVICE : DMA_FROM_DEVICE); if (sg_count == 0) - return -EINVAL; + return -ENOSPC; - if (next) { - next->sg_count = sg_count; - data->host_cookie = ++next->cookie < 0 ? 1 : next->cookie; - } else - host->sg_count = sg_count; + data->sg_count = sg_count; + data->host_cookie = COOKIE_MAPPED; return sg_count; } @@ -2181,16 +2173,10 @@ static void sdhci_pre_req(struct mmc_host *mmc, struct mmc_request *mrq, { struct sdhci_host *host = mmc_priv(mmc); - if (mrq->data->host_cookie) { - mrq->data->host_cookie = 0; - return; - } + mrq->data->host_cookie = COOKIE_UNMAPPED; if (host->flags & SDHCI_REQ_USE_DMA) - if (sdhci_pre_dma_transfer(host, - mrq->data, - &host->next_data) < 0) - mrq->data->host_cookie = 0; + sdhci_pre_dma_transfer(host, mrq->data); } static void sdhci_card_event(struct mmc_host *mmc) @@ -2691,31 +2677,6 @@ static irqreturn_t sdhci_thread_irq(int irq, void *dev_id) return isr ? IRQ_HANDLED : IRQ_NONE; } -#ifdef CONFIG_PREEMPT_RT_BASE -static irqreturn_t sdhci_rt_irq(int irq, void *dev_id) -{ - irqreturn_t ret; - - local_bh_disable(); - ret = sdhci_irq(irq, dev_id); - local_bh_enable(); - if (ret == IRQ_WAKE_THREAD) - ret = sdhci_thread_irq(irq, dev_id); - return ret; -} -#endif - -static int sdhci_req_irq(struct sdhci_host *host) -{ -#ifdef CONFIG_PREEMPT_RT_BASE - return request_threaded_irq(host->irq, NULL, sdhci_rt_irq, - IRQF_SHARED, mmc_hostname(host->mmc), host); -#else - return request_threaded_irq(host->irq, sdhci_irq, sdhci_thread_irq, - IRQF_SHARED, mmc_hostname(host->mmc), host); -#endif -} - /*****************************************************************************\ * * * Suspend/resume * @@ -2783,7 +2744,9 @@ int sdhci_resume_host(struct sdhci_host *host) } if (!device_may_wakeup(mmc_dev(host->mmc))) { - ret = sdhci_req_irq(host); + ret = request_threaded_irq(host->irq, sdhci_irq, + sdhci_thread_irq, IRQF_SHARED, + mmc_hostname(host->mmc), host); if (ret) return ret; } else { @@ -3111,7 +3074,6 @@ int sdhci_add_host(struct sdhci_host *host) host->max_clk = host->ops->get_max_clock(host); } - host->next_data.cookie = 1; /* * In case of Host Controller v3.00, find out whether clock * multiplier is supported. @@ -3444,7 +3406,8 @@ int sdhci_add_host(struct sdhci_host *host) sdhci_init(host, 0); - ret = sdhci_req_irq(host); + ret = request_threaded_irq(host->irq, sdhci_irq, sdhci_thread_irq, + IRQF_SHARED, mmc_hostname(mmc), host); if (ret) { pr_err("%s: Failed to request IRQ %d: %d\n", mmc_hostname(mmc), host->irq, ret); |