Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b12a7a28 authored by Masahiro Yamada's avatar Masahiro Yamada Committed by Ulf Hansson
Browse files

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: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Reviewed-by: default avatarWolfram Sang <wsa+renesas@sang-engineering.com>
Tested-by: default avatarWolfram Sang <wsa+renesas@sang-engineering.com>
parent c7cd630a
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -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);
+0 −4
Original line number Diff line number Diff line
@@ -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;
+10 −10
Original line number Diff line number Diff line
@@ -621,16 +621,22 @@ 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)