* [RFC 4/4] m68k: coldfire: fix non-standard readX()/writeX() functions
[not found] <20260506142644.3234270-2-gerg@kernel.org>
@ 2026-05-06 14:26 ` Greg Ungerer
2026-05-06 16:14 ` Frank Li
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Greg Ungerer @ 2026-05-06 14:26 UTC (permalink / raw)
To: linux-m68k
Cc: linux-kernel, arnd, Greg Ungerer, dmaengine, linux-can, linux-spi,
olteanv, adureghello
From: Greg Ungerer <gerg@linux-m68k.org>
Remove the local ColdFire definitions of readb()/readw()/readl() and
writeb()/writew()/writel() and use the asm-generic versions of them.
The implementation of the readX()/writeX() family of IO access functions
is non-standard on ColdFire platforms. They either return big-endian (that
is native endian) data, or on platforms with PCI bus support check the
supplied address and return either big or little endian data based on that
check. This is non-standard, they are expected to always return
little-endian byte ordered data. Unfortunately this behavior also means
that ioreadX()/iowroteX() and their big-endian counter parts
ioreadXbe()/iowriteXbe() are currently broken because they are implemented
using the readX()/writeX() functions.
The change to use the asm-generic versions of readX()/writeX() itself is
quite strait forward, just remove the ColdFire local versions of them. But
this of course has implications for any remaining drivers that use any of
these IO access functions. A number of drivers can be independently fixed,
before this final fix to readX()/writeX() for ColdFire. A small number of
drivers cannot easily be independently fixed and remain in a working
state. Those drivers are fixed here as well:
drivers/dma/mcf-edma-main.c
Supports big-endian access by setting the big-endian flag of
the drivers struct fsl_edma_engine. But locally should be using
ioread32be() and iowrite32be() instead of ioread32() and iowrite32().
drivers/net/can/flexcan/flexcan-core.c
Setting the driver quirks flag for big-endian access will force
driver to use correct access functions.
drivers/spi/spi-fsl-dspi.c
Setting the regmap format_endian flags to use native endian will
force driver to use appropriate big or little endian access on
whatever platform it is built for.
These drivers have only been compile tested.
Signed-off-by: Greg Ungerer <gerg@linux-m68k.org>
---
arch/m68k/include/asm/io_no.h | 68 +++-----------------------
drivers/dma/mcf-edma-main.c | 14 +++---
drivers/net/can/flexcan/flexcan-core.c | 1 +
drivers/spi/spi-fsl-dspi.c | 2 +
4 files changed, 16 insertions(+), 69 deletions(-)
diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h
index 4f0f34b06e37..2f12f4ed0da5 100644
--- a/arch/m68k/include/asm/io_no.h
+++ b/arch/m68k/include/asm/io_no.h
@@ -3,15 +3,10 @@
#define _M68KNOMMU_IO_H
/*
- * Convert a physical memory address into a IO memory address.
- * For us this is trivially a type cast.
- */
-#define iomem(a) ((void __iomem *) (a))
-
-/*
- * The non-MMU m68k and ColdFire IO and memory mapped hardware access
- * functions have always worked in CPU native endian. We need to define
- * that behavior here first before we include asm-generic/io.h.
+ * Historically the raw native endian IO access macros for non-MMU m68k and
+ * ColdFire have accepted any integral value as the address argument.
+ * The asm-generic versions of these expect "void __iomem *" for the address,
+ * so define local permissive versions here.
*/
#define __raw_readb(addr) \
({ u8 __v = (*(__force volatile u8 *) (addr)); __v; })
@@ -45,66 +40,15 @@
* applies just the same of there is no MMU but something like a PCI bus
* is present.
*/
-static int __cf_internalio(unsigned long addr)
+static inline int __cf_internalio(unsigned long addr)
{
return (addr >= IOMEMBASE) && (addr <= IOMEMBASE + IOMEMSIZE - 1);
}
-static int cf_internalio(const volatile void __iomem *addr)
+static inline int cf_internalio(const volatile void __iomem *addr)
{
return __cf_internalio((unsigned long) addr);
}
-
-/*
- * We need to treat built-in peripherals and bus based address ranges
- * differently. Local built-in peripherals (and the ColdFire SoC parts
- * have quite a lot of them) are always native endian - which is big
- * endian on m68k/ColdFire. Bus based address ranges, like the PCI bus,
- * are accessed little endian - so we need to byte swap those.
- */
-#define readw readw
-static inline u16 readw(const volatile void __iomem *addr)
-{
- if (cf_internalio(addr))
- return __raw_readw(addr);
- return swab16(__raw_readw(addr));
-}
-
-#define readl readl
-static inline u32 readl(const volatile void __iomem *addr)
-{
- if (cf_internalio(addr))
- return __raw_readl(addr);
- return swab32(__raw_readl(addr));
-}
-
-#define writew writew
-static inline void writew(u16 value, volatile void __iomem *addr)
-{
- if (cf_internalio(addr))
- __raw_writew(value, addr);
- else
- __raw_writew(swab16(value), addr);
-}
-
-#define writel writel
-static inline void writel(u32 value, volatile void __iomem *addr)
-{
- if (cf_internalio(addr))
- __raw_writel(value, addr);
- else
- __raw_writel(swab32(value), addr);
-}
-
-#else
-
-#define readb __raw_readb
-#define readw __raw_readw
-#define readl __raw_readl
-#define writeb __raw_writeb
-#define writew __raw_writew
-#define writel __raw_writel
-
#endif /* IOMEMBASE */
#if defined(CONFIG_COLDFIRE)
diff --git a/drivers/dma/mcf-edma-main.c b/drivers/dma/mcf-edma-main.c
index 9e1c6400c77b..4ed0ce644e37 100644
--- a/drivers/dma/mcf-edma-main.c
+++ b/drivers/dma/mcf-edma-main.c
@@ -21,9 +21,9 @@ static irqreturn_t mcf_edma_tx_handler(int irq, void *dev_id)
unsigned int ch;
u64 intmap;
- intmap = ioread32(regs->inth);
+ intmap = ioread32be(regs->inth);
intmap <<= 32;
- intmap |= ioread32(regs->intl);
+ intmap |= ioread32be(regs->intl);
if (!intmap)
return IRQ_NONE;
@@ -43,7 +43,7 @@ static irqreturn_t mcf_edma_err_handler(int irq, void *dev_id)
struct edma_regs *regs = &mcf_edma->regs;
unsigned int err, ch;
- err = ioread32(regs->errl);
+ err = ioread32be(regs->errl);
if (!err)
return IRQ_NONE;
@@ -55,7 +55,7 @@ static irqreturn_t mcf_edma_err_handler(int irq, void *dev_id)
}
}
- err = ioread32(regs->errh);
+ err = ioread32be(regs->errh);
if (!err)
return IRQ_NONE;
@@ -203,8 +203,8 @@ static int mcf_edma_probe(struct platform_device *pdev)
edma_write_tcdreg(mcf_chan, cpu_to_le32(0), csr);
}
- iowrite32(~0, regs->inth);
- iowrite32(~0, regs->intl);
+ iowrite32be(~0, regs->inth);
+ iowrite32be(~0, regs->intl);
ret = mcf_edma->drvdata->setup_irq(pdev, mcf_edma);
if (ret)
@@ -248,7 +248,7 @@ static int mcf_edma_probe(struct platform_device *pdev)
}
/* Enable round robin arbitration */
- iowrite32(EDMA_CR_ERGA | EDMA_CR_ERCA, regs->cr);
+ iowrite32be(EDMA_CR_ERGA | EDMA_CR_ERCA, regs->cr);
return 0;
}
diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c
index f5d22c61503f..a682f02d2c43 100644
--- a/drivers/net/can/flexcan/flexcan-core.c
+++ b/drivers/net/can/flexcan/flexcan-core.c
@@ -296,6 +296,7 @@ static_assert(sizeof(struct flexcan_regs) == 0x4 * 18 + 0xfb8);
static const struct flexcan_devtype_data fsl_mcf5441x_devtype_data = {
.quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE |
FLEXCAN_QUIRK_NR_IRQ_3 | FLEXCAN_QUIRK_NR_MB_16 |
+ FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN |
FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX |
FLEXCAN_QUIRK_SUPPORT_RX_FIFO,
};
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 9f2a7b8163b1..964ca6baf32f 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -203,6 +203,8 @@ static const struct regmap_config dspi_regmap_config[] = {
.volatile_table = &dspi_volatile_table,
.rd_table = &dspi_access_table,
.wr_table = &dspi_access_table,
+ .reg_format_endian = REGMAP_ENDIAN_NATIVE,
+ .val_format_endian = REGMAP_ENDIAN_NATIVE,
},
[S32G_DSPI_REGMAP] = {
.reg_bits = 32,
--
2.54.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [RFC 4/4] m68k: coldfire: fix non-standard readX()/writeX() functions
2026-05-06 14:26 ` [RFC 4/4] m68k: coldfire: fix non-standard readX()/writeX() functions Greg Ungerer
@ 2026-05-06 16:14 ` Frank Li
2026-05-06 19:12 ` Arnd Bergmann
2026-05-07 13:30 ` Marc Kleine-Budde
2 siblings, 0 replies; 7+ messages in thread
From: Frank Li @ 2026-05-06 16:14 UTC (permalink / raw)
To: Greg Ungerer
Cc: linux-m68k, linux-kernel, arnd, Greg Ungerer, dmaengine,
linux-can, linux-spi, olteanv, adureghello
On Thu, May 07, 2026 at 12:26:48AM +1000, Greg Ungerer wrote:
> From: Greg Ungerer <gerg@linux-m68k.org>
>
> Remove the local ColdFire definitions of readb()/readw()/readl() and
> writeb()/writew()/writel() and use the asm-generic versions of them.
>
> The implementation of the readX()/writeX() family of IO access functions
> is non-standard on ColdFire platforms. They either return big-endian (that
> is native endian) data, or on platforms with PCI bus support check the
> supplied address and return either big or little endian data based on that
> check. This is non-standard, they are expected to always return
> little-endian byte ordered data. Unfortunately this behavior also means
> that ioreadX()/iowroteX() and their big-endian counter parts
> ioreadXbe()/iowriteXbe() are currently broken because they are implemented
> using the readX()/writeX() functions.
>
> The change to use the asm-generic versions of readX()/writeX() itself is
> quite strait forward, just remove the ColdFire local versions of them. But
> this of course has implications for any remaining drivers that use any of
> these IO access functions. A number of drivers can be independently fixed,
> before this final fix to readX()/writeX() for ColdFire. A small number of
> drivers cannot easily be independently fixed and remain in a working
> state. Those drivers are fixed here as well:
>
> drivers/dma/mcf-edma-main.c
> Supports big-endian access by setting the big-endian flag of
> the drivers struct fsl_edma_engine. But locally should be using
> ioread32be() and iowrite32be() instead of ioread32() and iowrite32().
>
> drivers/net/can/flexcan/flexcan-core.c
> Setting the driver quirks flag for big-endian access will force
> driver to use correct access functions.
>
> drivers/spi/spi-fsl-dspi.c
> Setting the regmap format_endian flags to use native endian will
> force driver to use appropriate big or little endian access on
> whatever platform it is built for.
>
> These drivers have only been compile tested.
>
> Signed-off-by: Greg Ungerer <gerg@linux-m68k.org>
> ---
> arch/m68k/include/asm/io_no.h | 68 +++-----------------------
> drivers/dma/mcf-edma-main.c | 14 +++---
Suppose it is correct, but I have not such platform to test it. it should
be correct if disassembly code is the same at access register.
Frank
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC 4/4] m68k: coldfire: fix non-standard readX()/writeX() functions
2026-05-06 14:26 ` [RFC 4/4] m68k: coldfire: fix non-standard readX()/writeX() functions Greg Ungerer
2026-05-06 16:14 ` Frank Li
@ 2026-05-06 19:12 ` Arnd Bergmann
2026-05-07 12:43 ` Greg Ungerer
2026-05-07 13:30 ` Marc Kleine-Budde
2 siblings, 1 reply; 7+ messages in thread
From: Arnd Bergmann @ 2026-05-06 19:12 UTC (permalink / raw)
To: Greg Ungerer, linux-m68k
Cc: linux-kernel, Greg Ungerer, dmaengine, linux-can, linux-spi,
Vladimir Oltean, Angelo Dureghello
On Wed, May 6, 2026, at 16:26, Greg Ungerer wrote:
> drivers/dma/mcf-edma-main.c
> Supports big-endian access by setting the big-endian flag of
> the drivers struct fsl_edma_engine. But locally should be using
> ioread32be() and iowrite32be() instead of ioread32() and iowrite32().
I'm still a bit confused about how this works at the moment,
since the drivers/dma/fsl-edma-common.h file already contains
checks for the edma->big_endian flag, which is set in
mcf_edma_probe(). The version after your patch makes sense
to me, but it looks like the existing code cannot work.
> drivers/spi/spi-fsl-dspi.c
> Setting the regmap format_endian flags to use native endian will
> force driver to use appropriate big or little endian access on
> whatever platform it is built for.
>
> These drivers have only been compile tested.
I would suggest marking these as explicit BIG_ENDIAN rather than
NATIVE_ENDIAN. The effect should be the same since coldfire CPUs
cannot run little-endian code, but the way that hardware usually
works is that the endianess is fixed at the bus level to one way
or the other. NATIVE_ENDIAN to me implies that the registers
have configurable endianess that is switched along with the CPU
mode.
Arnd
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC 4/4] m68k: coldfire: fix non-standard readX()/writeX() functions
2026-05-06 19:12 ` Arnd Bergmann
@ 2026-05-07 12:43 ` Greg Ungerer
2026-05-07 12:59 ` Arnd Bergmann
0 siblings, 1 reply; 7+ messages in thread
From: Greg Ungerer @ 2026-05-07 12:43 UTC (permalink / raw)
To: Arnd Bergmann, linux-m68k
Cc: linux-kernel, dmaengine, linux-can, linux-spi, Vladimir Oltean,
Angelo Dureghello
Hi Arnd,
On 7/5/26 05:12, Arnd Bergmann wrote:
> On Wed, May 6, 2026, at 16:26, Greg Ungerer wrote:
>
>> drivers/dma/mcf-edma-main.c
>> Supports big-endian access by setting the big-endian flag of
>> the drivers struct fsl_edma_engine. But locally should be using
>> ioread32be() and iowrite32be() instead of ioread32() and iowrite32().
>
> I'm still a bit confused about how this works at the moment,
> since the drivers/dma/fsl-edma-common.h file already contains
> checks for the edma->big_endian flag, which is set in
> mcf_edma_probe(). The version after your patch makes sense
> to me, but it looks like the existing code cannot work.
Yes, it certainly doesn't look right to me either.
Angelo: you look to be the original author of this driver, can you shed any
light on its working status in mainline currently?
>> drivers/spi/spi-fsl-dspi.c
>> Setting the regmap format_endian flags to use native endian will
>> force driver to use appropriate big or little endian access on
>> whatever platform it is built for.
>>
>> These drivers have only been compile tested.
>
> I would suggest marking these as explicit BIG_ENDIAN rather than
> NATIVE_ENDIAN. The effect should be the same since coldfire CPUs
> cannot run little-endian code, but the way that hardware usually
> works is that the endianess is fixed at the bus level to one way
> or the other. NATIVE_ENDIAN to me implies that the registers
> have configurable endianess that is switched along with the CPU
> mode.
Ok, will change. I chose native endian in this case since the regmap config
entry used for the m5441x family is also used by the vf610 devce (which looks
to be an ARM imx SoC). So it will need a duplicate setup with those endian
flags set to BIG_ENDIAN. But that is no problem.
Thanks
Greg
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC 4/4] m68k: coldfire: fix non-standard readX()/writeX() functions
2026-05-07 12:43 ` Greg Ungerer
@ 2026-05-07 12:59 ` Arnd Bergmann
0 siblings, 0 replies; 7+ messages in thread
From: Arnd Bergmann @ 2026-05-07 12:59 UTC (permalink / raw)
To: Greg Ungerer, linux-m68k
Cc: linux-kernel, dmaengine, linux-can, linux-spi, Vladimir Oltean,
Angelo Dureghello
On Thu, May 7, 2026, at 14:43, Greg Ungerer wrote:
> On 7/5/26 05:12, Arnd Bergmann wrote:
>> On Wed, May 6, 2026, at 16:26, Greg Ungerer wrote:
>>
>> I would suggest marking these as explicit BIG_ENDIAN rather than
>> NATIVE_ENDIAN. The effect should be the same since coldfire CPUs
>> cannot run little-endian code, but the way that hardware usually
>> works is that the endianess is fixed at the bus level to one way
>> or the other. NATIVE_ENDIAN to me implies that the registers
>> have configurable endianess that is switched along with the CPU
>> mode.
>
> Ok, will change. I chose native endian in this case since the regmap config
> entry used for the m5441x family is also used by the vf610 devce (which looks
> to be an ARM imx SoC). So it will need a duplicate setup with those endian
> flags set to BIG_ENDIAN. But that is no problem.
Sounds good. In this case, splitting it up is technically even required,
because you can run a big-endian ARMv7 kernel on vf610, so the vf610
entry has to use little-endian registers rather than native.
I don't think anyone has run big-endian kernels on vf610, though I have
heard of users testing them successfully on i.MX6.
Arnd
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC 4/4] m68k: coldfire: fix non-standard readX()/writeX() functions
2026-05-06 14:26 ` [RFC 4/4] m68k: coldfire: fix non-standard readX()/writeX() functions Greg Ungerer
2026-05-06 16:14 ` Frank Li
2026-05-06 19:12 ` Arnd Bergmann
@ 2026-05-07 13:30 ` Marc Kleine-Budde
2026-05-07 14:33 ` Greg Ungerer
2 siblings, 1 reply; 7+ messages in thread
From: Marc Kleine-Budde @ 2026-05-07 13:30 UTC (permalink / raw)
To: Greg Ungerer
Cc: linux-m68k, linux-kernel, arnd, Greg Ungerer, dmaengine,
linux-can, linux-spi, olteanv, adureghello
[-- Attachment #1: Type: text/plain, Size: 1172 bytes --]
On 07.05.2026 00:26:48, Greg Ungerer wrote:
> diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c
> index f5d22c61503f..a682f02d2c43 100644
> --- a/drivers/net/can/flexcan/flexcan-core.c
> +++ b/drivers/net/can/flexcan/flexcan-core.c
> @@ -296,6 +296,7 @@ static_assert(sizeof(struct flexcan_regs) == 0x4 * 18 + 0xfb8);
> static const struct flexcan_devtype_data fsl_mcf5441x_devtype_data = {
> .quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE |
Nitpick:
Can you move it here, so that the quirks stay sorted?
FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN |
> FLEXCAN_QUIRK_NR_IRQ_3 | FLEXCAN_QUIRK_NR_MB_16 |
> + FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN |
> FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX |
> FLEXCAN_QUIRK_SUPPORT_RX_FIFO,
> };
With that change:
Acked-by: Marc Kleine-Budde <mkl@pengutronix.de> # for drivers/net/can/flexcan
regards,
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung Nürnberg | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC 4/4] m68k: coldfire: fix non-standard readX()/writeX() functions
2026-05-07 13:30 ` Marc Kleine-Budde
@ 2026-05-07 14:33 ` Greg Ungerer
0 siblings, 0 replies; 7+ messages in thread
From: Greg Ungerer @ 2026-05-07 14:33 UTC (permalink / raw)
To: Marc Kleine-Budde
Cc: linux-m68k, linux-kernel, arnd, Greg Ungerer, dmaengine,
linux-can, linux-spi, olteanv, adureghello
On 7/5/26 23:30, Marc Kleine-Budde wrote:
> On 07.05.2026 00:26:48, Greg Ungerer wrote:
>> diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c
>> index f5d22c61503f..a682f02d2c43 100644
>> --- a/drivers/net/can/flexcan/flexcan-core.c
>> +++ b/drivers/net/can/flexcan/flexcan-core.c
>> @@ -296,6 +296,7 @@ static_assert(sizeof(struct flexcan_regs) == 0x4 * 18 + 0xfb8);
>> static const struct flexcan_devtype_data fsl_mcf5441x_devtype_data = {
>> .quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE |
>
> Nitpick:
> Can you move it here, so that the quirks stay sorted?
Yep, sure thing.
> FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN |
>
>> FLEXCAN_QUIRK_NR_IRQ_3 | FLEXCAN_QUIRK_NR_MB_16 |
>> + FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN |
>> FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX |
>> FLEXCAN_QUIRK_SUPPORT_RX_FIFO,
>> };
>
> With that change:
>
> Acked-by: Marc Kleine-Budde <mkl@pengutronix.de> # for drivers/net/can/flexcan
Thanks
Greg
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-05-07 14:33 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260506142644.3234270-2-gerg@kernel.org>
2026-05-06 14:26 ` [RFC 4/4] m68k: coldfire: fix non-standard readX()/writeX() functions Greg Ungerer
2026-05-06 16:14 ` Frank Li
2026-05-06 19:12 ` Arnd Bergmann
2026-05-07 12:43 ` Greg Ungerer
2026-05-07 12:59 ` Arnd Bergmann
2026-05-07 13:30 ` Marc Kleine-Budde
2026-05-07 14:33 ` Greg Ungerer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox