[PATCH v2 2/5] bcma: scan: support big-endian backplanes
From: Alessio Ferri
Date: Sun Oct 11 2026 - 18:48:57 EST
On some SoCs the bcma backplane is a big-endian peripheral, so the
ChipCommon ID/EROM pointer registers and the EROM itself read wrong
with readl().
Add a big_endian flag to struct bcma_bus, set by the host driver
before bcma_init_bus(), and use ioread32be() for scan-time accesses
when it is set. Core register accesses after the scan already go
through the host ops, which the host driver provides with the right
endianness.
Nothing changes for other devices.
Assisted-by: LLM sparse
Signed-off-by: Alessio Ferri <alessio.ferri@xxxxxxxxxxx>
---
drivers/bcma/scan.c | 4 +++-
include/linux/bcma/bcma.h | 3 +++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 84742408a59c..983a62ddeebb 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -143,6 +143,8 @@ static const char *bcma_device_name(const struct bcma_device_id *id)
static u32 bcma_scan_read32(struct bcma_bus *bus, u16 offset)
{
+ if (bus->big_endian)
+ return ioread32be(bus->mmio + offset);
return readl(bus->mmio + offset);
}
@@ -155,7 +157,7 @@ static void bcma_scan_switch_core(struct bcma_bus *bus, u32 addr)
static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 __iomem **eromptr)
{
- u32 ent = readl(*eromptr);
+ u32 ent = bus->big_endian ? ioread32be(*eromptr) : readl(*eromptr);
(*eromptr)++;
return ent;
}
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 17fc50190014..7ab2b21e7238 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -362,6 +362,9 @@ struct bcma_bus {
/* We decided to share SPROM struct with SSB as long as we do not need
* any hacks for BCMA. This simplifies drivers code. */
struct ssb_sprom sprom;
+
+ /* Backplane registers, EROM included, are big-endian */
+ bool big_endian;
};
static inline u32 bcma_read8(struct bcma_device *core, u16 offset)
--
2.56.0