| From a4cd588eee924157183daa6174d04d4433260cf4 Mon Sep 17 00:00:00 2001 |
| From: Masahiro Yamada <yamada.masahiro@socionext.com> |
| Date: Thu, 18 Jan 2018 01:28:14 +0900 |
| Subject: [PATCH 0829/1795] mmc: tmio: move TMIO_MASK_{READOP, WRITEOP} |
| handling to correct place |
| |
| As far as I tested the IP on UniPhier SoCs, TMIO_STAT_{RXRDY,TXRQ} |
| are asserted for DMA mode as well as for PIO. I need to disable the |
| those IRQs in dma_ops->start hook, otherwise the DMA transfer fails |
| with the following error message: |
| PIO IRQ in DMA mode! |
| |
| Renesas chips are the same cases since I see their dma_ops->start |
| hooks explicitly clear TMIO_STAT_{RXRDY,TXRQ} (with nice comment!). |
| |
| If we do this sanity check in TMIO MMC core, RXRDY/TXRQ handling |
| should be entirely moved to the core. tmio_mmc_cmd_irq() will |
| be a suitable place to disable them. |
| |
| The probe function sets TMIO_MASK_{READOP,WRITEOP} but this is odd. |
| |
| /* Unmask the IRQs we want to know about */ |
| if (!_host->chan_rx) |
| irq_mask |= TMIO_MASK_READOP; |
| if (!_host->chan_tx) |
| irq_mask |= TMIO_MASK_WRITEOP; |
| |
| At this point, _host->{chan_rx,chan_tx} are _always_ NULL because |
| tmio_mmc_request_dma() is called after this code. Consequently, |
| TMIO_MASK_{READOP,WRITEOP} are set here whether DMA is used or not. |
| Remove this pointless code. |
| |
| Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com> |
| Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> |
| Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> |
| Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com> |
| (cherry picked from commit b12a7a28f860c3ab078ae306e13a659ec70b3c33) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> |
| --- |
| drivers/mmc/host/renesas_sdhi_internal_dmac.c | 6 ------ |
| drivers/mmc/host/renesas_sdhi_sys_dmac.c | 4 ---- |
| drivers/mmc/host/tmio_mmc_core.c | 20 +++++++++---------- |
| 3 files changed, 10 insertions(+), 20 deletions(-) |
| |
| diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c |
| index 1d4d2dcc4f32..9f66baaded94 100644 |
| --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c |
| +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c |
| @@ -145,7 +145,6 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host, |
| u32 dtran_mode = DTRAN_MODE_BUS_WID_TH | DTRAN_MODE_ADDR_MODE; |
| enum dma_data_direction dir; |
| int ret; |
| - u32 irq_mask; |
| |
| /* This DMAC cannot handle if sg_len is not 1 */ |
| WARN_ON(host->sg_len > 1); |
| @@ -157,11 +156,9 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host, |
| if (data->flags & MMC_DATA_READ) { |
| dtran_mode |= DTRAN_MODE_CH_NUM_CH1; |
| dir = DMA_FROM_DEVICE; |
| - irq_mask = TMIO_STAT_RXRDY; |
| } else { |
| dtran_mode |= DTRAN_MODE_CH_NUM_CH0; |
| dir = DMA_TO_DEVICE; |
| - irq_mask = TMIO_STAT_TXRQ; |
| } |
| |
| ret = dma_map_sg(&host->pdev->dev, sg, host->sg_len, dir); |
| @@ -170,9 +167,6 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host, |
| |
| renesas_sdhi_internal_dmac_enable_dma(host, true); |
| |
| - /* disable PIO irqs to avoid "PIO IRQ in DMA mode!" */ |
| - tmio_mmc_disable_mmc_irqs(host, irq_mask); |
| - |
| /* set dma parameters */ |
| renesas_sdhi_internal_dmac_dm_write(host, DM_CM_DTRAN_MODE, |
| dtran_mode); |
| diff --git a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c |
| index 434afa9dd9a1..4bb46c489d71 100644 |
| --- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c |
| +++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c |
| @@ -205,8 +205,6 @@ static void renesas_sdhi_sys_dmac_start_dma_rx(struct tmio_mmc_host *host) |
| return; |
| } |
| |
| - tmio_mmc_disable_mmc_irqs(host, TMIO_STAT_RXRDY); |
| - |
| /* The only sg element can be unaligned, use our bounce buffer then */ |
| if (!aligned) { |
| sg_init_one(&host->bounce_sg, host->bounce_buf, sg->length); |
| @@ -280,8 +278,6 @@ static void renesas_sdhi_sys_dmac_start_dma_tx(struct tmio_mmc_host *host) |
| return; |
| } |
| |
| - tmio_mmc_disable_mmc_irqs(host, TMIO_STAT_TXRQ); |
| - |
| /* The only sg element can be unaligned, use our bounce buffer then */ |
| if (!aligned) { |
| unsigned long flags; |
| diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c |
| index 63767fd1da24..477fafa3094f 100644 |
| --- a/drivers/mmc/host/tmio_mmc_core.c |
| +++ b/drivers/mmc/host/tmio_mmc_core.c |
| @@ -621,15 +621,21 @@ static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, unsigned int stat) |
| */ |
| if (host->data && (!cmd->error || cmd->error == -EILSEQ)) { |
| if (host->data->flags & MMC_DATA_READ) { |
| - if (host->force_pio || !host->chan_rx) |
| + if (host->force_pio || !host->chan_rx) { |
| tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_READOP); |
| - else |
| + } else { |
| + tmio_mmc_disable_mmc_irqs(host, |
| + TMIO_MASK_READOP); |
| tasklet_schedule(&host->dma_issue); |
| + } |
| } else { |
| - if (host->force_pio || !host->chan_tx) |
| + if (host->force_pio || !host->chan_tx) { |
| tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_WRITEOP); |
| - else |
| + } else { |
| + tmio_mmc_disable_mmc_irqs(host, |
| + TMIO_MASK_WRITEOP); |
| tasklet_schedule(&host->dma_issue); |
| + } |
| } |
| } else { |
| schedule_work(&host->done); |
| @@ -1273,12 +1279,6 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host) |
| _host->sdcard_irq_mask = sd_ctrl_read16_and_16_as_32(_host, CTL_IRQ_MASK); |
| tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL); |
| |
| - /* Unmask the IRQs we want to know about */ |
| - if (!_host->chan_rx) |
| - irq_mask |= TMIO_MASK_READOP; |
| - if (!_host->chan_tx) |
| - irq_mask |= TMIO_MASK_WRITEOP; |
| - |
| _host->sdcard_irq_mask &= ~irq_mask; |
| |
| if (_host->native_hotplug) |
| -- |
| 2.19.0 |
| |