Mark, Andy, On Thu, May 21, 2020 at 04:21:51AM +0300, Serge Semin wrote: > [nip] > +static void dw_spi_dma_calc_delay(struct dw_spi *dws, u32 nents, > + struct spi_delay *delay) > +{ > + unsigned long ns, us; > + > + ns = (NSEC_PER_SEC / spi_get_clk(dws)) * nents * dws->n_bytes * > + BITS_PER_BYTE; > + > + if (ns <= NSEC_PER_USEC) { > + delay->unit = SPI_DELAY_UNIT_NSECS; > + delay->value = ns; > + } else { > + us = DIV_ROUND_UP(ns, NSEC_PER_USEC); > + delay->unit = SPI_DELAY_UNIT_USECS; > + delay->value = clamp_val(us, 0, USHRT_MAX); > + } > +} > + > +static inline bool dw_spi_dma_tx_busy(struct dw_spi *dws) > +{ > + return !(dw_readl(dws, DW_SPI_SR) & SR_TF_EMPT); > +} > + > +static void dw_spi_dma_wait_tx_done(struct dw_spi *dws) > +{ > + int retry = WAIT_RETRIES; > + struct spi_delay delay; > + u32 nents; > + > + nents = dw_readl(dws, DW_SPI_TXFLR); > + dw_spi_dma_calc_delay(dws, nents, &delay); > + > + while (dw_spi_dma_tx_busy(dws) && retry--) > + spi_delay_exec(&delay, NULL); I've just discovered using spi_delay_exec() wasn't a good idea here. Look at the call stack: dw_dma_tasklet() -> dwc_scan_descriptors() -> dwc_descriptor_complete() -> dw_spi_dma_tx_done() -> spi_delay_exec() -> usleep_range() -> ... So tasklet is calling a sleeping function.((( I've absolutely forgotten to check the context the DMA completion function is called with. We'll have to manually select either ndelay or udelay here and nothing else. Since basically both functions represent an atomic context and most of the platforms ndelay fallsback to udelay, I'll get the ndelay back to the wait functions. I'll resend a patchset shortly. -Sergey