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>
u32 dtran_mode = DTRAN_MODE_BUS_WID_TH | DTRAN_MODE_ADDR_MODE;
enum dma_data_direction dir;
int ret;
u32 dtran_mode = DTRAN_MODE_BUS_WID_TH | DTRAN_MODE_ADDR_MODE;
enum dma_data_direction dir;
int ret;
/* This DMAC cannot handle if sg_len is not 1 */
WARN_ON(host->sg_len > 1);
/* This DMAC cannot handle if sg_len is not 1 */
WARN_ON(host->sg_len > 1);
if (data->flags & MMC_DATA_READ) {
dtran_mode |= DTRAN_MODE_CH_NUM_CH1;
dir = DMA_FROM_DEVICE;
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;
} 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);
}
ret = dma_map_sg(&host->pdev->dev, sg, host->sg_len, dir);
renesas_sdhi_internal_dmac_enable_dma(host, true);
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);
/* set dma parameters */
renesas_sdhi_internal_dmac_dm_write(host, DM_CM_DTRAN_MODE,
dtran_mode);
- 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);
/* 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);
- 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;
/* The only sg element can be unaligned, use our bounce buffer then */
if (!aligned) {
unsigned long flags;
*/
if (host->data && (!cmd->error || cmd->error == -EILSEQ)) {
if (host->data->flags & MMC_DATA_READ) {
*/
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);
tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_READOP);
+ } else {
+ tmio_mmc_disable_mmc_irqs(host,
+ TMIO_MASK_READOP);
tasklet_schedule(&host->dma_issue);
tasklet_schedule(&host->dma_issue);
- if (host->force_pio || !host->chan_tx)
+ if (host->force_pio || !host->chan_tx) {
tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_WRITEOP);
tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_WRITEOP);
+ } else {
+ tmio_mmc_disable_mmc_irqs(host,
+ TMIO_MASK_WRITEOP);
tasklet_schedule(&host->dma_issue);
tasklet_schedule(&host->dma_issue);
}
} else {
schedule_work(&host->done);
}
} else {
schedule_work(&host->done);
_host->sdcard_irq_mask = sd_ctrl_read16_and_16_as_32(_host, CTL_IRQ_MASK);
tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);
_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)
_host->sdcard_irq_mask &= ~irq_mask;
if (_host->native_hotplug)