On Thu, Nov 19, 2020 at 1:31 PM Juan Antonio Aldea-Armenteros <juant.aldea@xxxxxxxxx> wrote: > > This patch fixes the following warnings reported by sparse, by adding > missing __force annotations. > > drivers/staging/hikey9xx/hisi-spmi-controller.c:164:24: warning: cast to restricted __be32 > drivers/staging/hikey9xx/hisi-spmi-controller.c:164:24: warning: cast to restricted __be32 > drivers/staging/hikey9xx/hisi-spmi-controller.c:164:24: warning: cast to restricted __be32 > drivers/staging/hikey9xx/hisi-spmi-controller.c:164:24: warning: cast to restricted __be32 > drivers/staging/hikey9xx/hisi-spmi-controller.c:164:24: warning: cast to restricted __be32 > drivers/staging/hikey9xx/hisi-spmi-controller.c:164:24: warning: cast to restricted __be32 > > drivers/staging/hikey9xx/hisi-spmi-controller.c:239:25: warning: cast from restricted __be32 > > Rationale for #164: > data is declared as u32, and it is read and then converted by means of > be32_to_cpu(). Said function expects a __be32 but data is u32, therefore > there's a type missmatch here. > > Rationale for #239: > Is the dual of #164. This time data going to be written so it > needs to be converted from cpu to __be32, but writel() expects u32 and the > output of cpu_to_be32 returns a __be32. Both of the casts look very suspicious, I'd leave these in unless someone can confirm what the actual desired behavior is. > SPMI_SLAVE_OFFSET * slave_id + > SPMI_APB_SPMI_RDATA0_BASE_ADDR + > i * SPMI_PER_DATAREG_BYTE); > - data = be32_to_cpu((__be32)data); > + data = be32_to_cpu((__be32 __force)data); > if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) { > memcpy(buf, &data, sizeof(data)); > buf += sizeof(data); The data comes from a readl(), which contains an endian conversion on architectures that need it, such as when running the board in big-endian arm64 mode. Having a second endian-conversion on little-endian architectures means that the data is always swapped when it gets written to the register. In the original code before Mauro's commit 8788a30c12c7 ("staging: spmi: hisi-spmi-controller: use le32 macros where needed"), the data was byteswapped, and then written into the fifo register, which produced no warning but would do a double-swap on a big-endian kernel, and change the behavior from what it was before. My guess is that Mauro inadvertently fixed this driver for big-endian mode, without noticing that it was broken to start with, and that he did not actually try it with CONFIG_CPU_BIG_ENDIAN. I think the best way would be to go back to to using swab32p() (not the open-coded version) and then use writesl() or iowrite32_rep() with count=1 to write the byteswapped FIFO register without swapping it again. Arnd _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel