Re: [PATCH v5 3/5] drivers/soc/litex: add LiteX SoC Controller driver

From: Benjamin Herrenschmidt
Date: Tue Apr 28 2020 - 23:23:13 EST


On Mon, 2020-04-27 at 11:13 +0200, Mateusz Holenko wrote:
> As Gabriel Somlo <gsomlo@xxxxxxxxx> suggested to me, I could still use
> readl/writel/ioread/iowrite() standard functions providing memory
> barriers *and* have values in CPU native endianness by using the
> following constructs:
>
> `le32_to_cpu(readl(addr))`
>
> and
>
> `writel(cpu_to_le32(value), addr)`
>
> as le32_to_cpu/cpu_to_le32():
> - does nothing on LE CPUs and
> - reorders bytes on BE CPUs which in turn reverts swapping made by
> readl() resulting in returning the original value.

It's a bit sad... I don't understand why you need this. The HW has a
fied endian has you have mentioned earlier (and that is a good design).

The fact that you are trying to shove things into a "smaller pipe" than
the actual register shouldn't affect at what address the MSB and LSB
reside. And readl/writel (or ioread32/iowrite32) will always be LE as
well, so will match the HW layout. Thus I don't see why you need to
play swapping games here.

This however would be avoided completely if the HW was a tiny bit
smarter and would do the multi-beat access for you which shouldn't be
terribly hard to implement.

That said, it would be even clearer if you just open coded the 2 or 3
useful cases: 32/8, 32/16 and 32/32. The loop with calculated shifts
(and no masks) makes the code hard to understand.

Cheers,
Ben.