Re: [RFC 4/4] m68k: coldfire: fix non-standard readX()/writeX() functions

From: Arnd Bergmann

Date: Sun May 17 2026 - 16:08:52 EST


On Sun, May 17, 2026, at 21:43, Angelo Dureghello wrote:
> On Thu, May 07, 2026 at 10:43:01PM +1000, Greg Ungerer wrote:
>> On 7/5/26 05:12, Arnd Bergmann wrote:
>> > On Wed, May 6, 2026, at 16:26, Greg Ungerer wrote:
>
> [ 2.270000] fsl-dspi fsl-dspi.0: Not able to get desc for DMA xfer
> [ 2.280000] fsl-dspi fsl-dspi.0: DMA transfer failed
> [ 2.280000] spi_master spi0: failed to transfer one message from queue
> [ 2.290000] spi_master spi0: noqueue transfer failed
> [ 2.290000] spi-nor spi0.1: probe with driver spi-nor failed with error -5
>
> DSPI is using edma, i will try to understand where the issue is asap.
>
> About how it works:
> - for accesses to edma module (IP) mmio registers, must be native
> big_endian, so using the "be" suffix in "mcf"_edma looks ok for me.

The twist here is that with the way that readl() is defined on
coldfire as a non-swapping operation, and the generic
definition assuming the opposite in

static inline u32 ioread32be(const void __iomem *addr)
{
return swab32(readl(addr));
}

the function called ioread32be() actually tries to access
the registers as little-endian. I can see two possible ways
we got here, but don't know which one is currect:

a) the device actually has little-endian registers (like it
does on i.MX, but unlike all other coldfire devices), and
you just never noticed because using ioread32be() worked
as you expected.

b) you tested the driver using an ioread32be() definition that
did not have a byteswap and it correctly accessed big-endian
registers at the time, but the version in mainline today does
not.

> - for accessing the "tcd" memory structure, that must be, from what i
> remember, anyway in little endian, independently from the cpu core
> endiannes, this is the reason that big_endian flag is needed, it is
> used for tcd area accesses, so the IP module was built.
> The tcd area may be similar to pci accesses (see mcf54415 RM 19.4.16).

edma_read_tcdreg() calls into edma_readl(), which is the same function
that is used for normal register access, so from what I can tell,
they always use the same endianess here.

Arnd