[soc:broadcom/drivers 2/4] drivers/soc/bcm/bcm63xx/bcm-pmb.c:103:45: sparse: sparse: cast to restricted __le32

Arnd Bergmann arnd at kernel.org
Thu Feb 11 06:05:12 EST 2021


On Thu, Feb 11, 2021 at 7:44 AM Rafał Miłecki <rafal at milecki.pl> wrote:
> On 10.02.2021 22:48, kernel test robot wrote:
>
> Florian: can you review above code & verify my logic is correct there?
> That I need to use le32_to_cpu() / be32_to_cpu() on the readl() value?

I'm fairly sure the logic is incorrect.

> Assuming my logic is correct, above code doesn't use __le32 / __be32 as
> that would require extra variables and code paths. Current code is quite
> simple & clear.

The problem is that readl() assumes that a register is little-endian in
hardware, and it performs a byteswap when running on a big-endian
machine (on most architectures).

The usual way to encode this is to use

      if (device->big_endian)
                 return ioread32be(device->reg + offset);
     else
                 return ioread32(device->reg + offset);

You can treat ioread32() as an alias for readl() in practice, while
ioread32be() produces the byte-reversed result of that.

If you however also need to run this on big-endian mips, you
might need to wrap this in another #ifdef that accounts for
the different behavior on that architecture, where readl()
sometimes sometimes assumes the register is cpu-endian
rather than little-endian.

        Arnd



More information about the linux-arm-kernel mailing list