* [PATCH v3] irqchip/irq-realtek-rtl: change to readl_be and writel_be
@ 2026-08-20 16:20 Rustam Adilov
2026-08-20 16:36 ` [tip: irq/urgent] irqchip/irq-realtek-rtl: Use readl_be()/writel_be() instead of readl()/writel() tip-bot2 for Rustam Adilov
0 siblings, 1 reply; 2+ messages in thread
From: Rustam Adilov @ 2026-08-20 16:20 UTC (permalink / raw)
To: Thomas Gleixner, Birger Koblitz, Bert Vermeulen, John Crispin,
linux-kernel
Cc: Rustam Adilov, Carlo Szelinsky
When CONFIG_SWAP_IO_SPACE is enabled, readl() is changed to perform
a swap from little endian device to big endian CPU and vice versa
for writel(). This is incorrect because the Realtek Interrupt
controller is a big endian device and so the LE to BE conversions
are unwanted.
Fix this by converting the MMIO accesses to readl_be() and writel_be().
Tested-by: Carlo Szelinsky <github@szelinsky.de>
Signed-off-by: Rustam Adilov <adilov@disroot.org>
---
Changes in v3:
- Make the commit message more sensible, hopefully.
- Change the __raw variants to readl_be and writel_be.
- Add the note in the driver that the controller is big endian.
Changes in v2:
- Make the commit message clearer.
drivers/irqchip/irq-realtek-rtl.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/irqchip/irq-realtek-rtl.c b/drivers/irqchip/irq-realtek-rtl.c
index c8becb458da2..26e52c3f8c68 100644
--- a/drivers/irqchip/irq-realtek-rtl.c
+++ b/drivers/irqchip/irq-realtek-rtl.c
@@ -1,5 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
+ * Realtek Interrupt controller.
+ *
+ * The Realtek Interrupt controller is a big endian device found in the
+ * Realtek MIPS SoCs.
+ *
* Copyright (C) 2020 Birger Koblitz <mail@birger-koblitz.de>
* Copyright (C) 2020 Bert Vermeulen <bert@biot.com>
* Copyright (C) 2020 John Crispin <john@phrozen.org>
@@ -50,18 +55,18 @@ static inline void enable_gimr(unsigned int cpu, unsigned int hw_irq)
{
u32 gimr;
- gimr = readl(REG(cpu, RTL_ICTL_GIMR));
+ gimr = readl_be(REG(cpu, RTL_ICTL_GIMR));
gimr |= BIT(hw_irq);
- writel(gimr, REG(cpu, RTL_ICTL_GIMR));
+ writel_be(gimr, REG(cpu, RTL_ICTL_GIMR));
}
static inline void disable_gimr(unsigned int cpu, unsigned int hw_irq)
{
u32 gimr;
- gimr = readl(REG(cpu, RTL_ICTL_GIMR));
+ gimr = readl_be(REG(cpu, RTL_ICTL_GIMR));
gimr &= ~BIT(hw_irq);
- writel(gimr, REG(cpu, RTL_ICTL_GIMR));
+ writel_be(gimr, REG(cpu, RTL_ICTL_GIMR));
}
static void write_irr(unsigned int cpu, int hw_irq, u32 value)
@@ -71,9 +76,9 @@ static void write_irr(unsigned int cpu, int hw_irq, u32 value)
unsigned int shift = IRR_SHIFT(hw_irq);
u32 irr;
- irr = readl(irr0 + offset) & ~(0xf << shift);
+ irr = readl_be(irr0 + offset) & ~(0xf << shift);
irr |= (value & 0xf) << shift;
- writel(irr, irr0 + offset);
+ writel_be(irr, irr0 + offset);
}
static void realtek_ictl_unmask_irq(struct irq_data *i)
@@ -159,7 +164,8 @@ static void realtek_irq_dispatch(struct irq_desc *desc)
unsigned int hw_irq;
chained_irq_enter(chip, desc);
- pending = readl(REG(cpu, RTL_ICTL_GIMR)) & readl(REG(cpu, RTL_ICTL_GISR)) & output->mask;
+ pending = readl_be(REG(cpu, RTL_ICTL_GIMR)) &
+ readl_be(REG(cpu, RTL_ICTL_GISR)) & output->mask;
if (unlikely(!pending)) {
spurious_interrupt();
--
2.55.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [tip: irq/urgent] irqchip/irq-realtek-rtl: Use readl_be()/writel_be() instead of readl()/writel()
2026-08-20 16:20 [PATCH v3] irqchip/irq-realtek-rtl: change to readl_be and writel_be Rustam Adilov
@ 2026-08-20 16:36 ` tip-bot2 for Rustam Adilov
0 siblings, 0 replies; 2+ messages in thread
From: tip-bot2 for Rustam Adilov @ 2026-08-20 16:36 UTC (permalink / raw)
To: linux-tip-commits
Cc: Rustam Adilov, Thomas Gleixner, Carlo Szelinsky, x86,
linux-kernel, maz
The following commit has been merged into the irq/urgent branch of tip:
Commit-ID: 58b34b72b64bfbfc5f8ad4d8f229942aff76597e
Gitweb: https://git.kernel.org/tip/58b34b72b64bfbfc5f8ad4d8f229942aff76597e
Author: Rustam Adilov <adilov@disroot.org>
AuthorDate: Thu, 20 Aug 2026 21:20:17 +05:00
Committer: Thomas Gleixner <tglx@kernel.org>
CommitterDate: Thu, 20 Aug 2026 18:34:59 +02:00
irqchip/irq-realtek-rtl: Use readl_be()/writel_be() instead of readl()/writel()
When CONFIG_SWAP_IO_SPACE is enabled, readl() performs a swap from little
endian device to big endian CPU and vice versa for writel().
This is incorrect for Realtek Interrupt controller as that is a big endian
device and so the LE to BE conversions are unwanted.
Fix this by converting the MMIO accesses to readl_be() and writel_be().
Fixes: 9f3a0f34b84a ("irqchip: Add support for Realtek RTL838x/RTL839x interrupt controller")
Signed-off-by: Rustam Adilov <adilov@disroot.org>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Tested-by: Carlo Szelinsky <github@szelinsky.de>
Link: https://patch.msgid.link/20260820162017.28507-1-adilov@disroot.org
---
drivers/irqchip/irq-realtek-rtl.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/irqchip/irq-realtek-rtl.c b/drivers/irqchip/irq-realtek-rtl.c
index c8becb4..26e52c3 100644
--- a/drivers/irqchip/irq-realtek-rtl.c
+++ b/drivers/irqchip/irq-realtek-rtl.c
@@ -1,5 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
+ * Realtek Interrupt controller.
+ *
+ * The Realtek Interrupt controller is a big endian device found in the
+ * Realtek MIPS SoCs.
+ *
* Copyright (C) 2020 Birger Koblitz <mail@birger-koblitz.de>
* Copyright (C) 2020 Bert Vermeulen <bert@biot.com>
* Copyright (C) 2020 John Crispin <john@phrozen.org>
@@ -50,18 +55,18 @@ static inline void enable_gimr(unsigned int cpu, unsigned int hw_irq)
{
u32 gimr;
- gimr = readl(REG(cpu, RTL_ICTL_GIMR));
+ gimr = readl_be(REG(cpu, RTL_ICTL_GIMR));
gimr |= BIT(hw_irq);
- writel(gimr, REG(cpu, RTL_ICTL_GIMR));
+ writel_be(gimr, REG(cpu, RTL_ICTL_GIMR));
}
static inline void disable_gimr(unsigned int cpu, unsigned int hw_irq)
{
u32 gimr;
- gimr = readl(REG(cpu, RTL_ICTL_GIMR));
+ gimr = readl_be(REG(cpu, RTL_ICTL_GIMR));
gimr &= ~BIT(hw_irq);
- writel(gimr, REG(cpu, RTL_ICTL_GIMR));
+ writel_be(gimr, REG(cpu, RTL_ICTL_GIMR));
}
static void write_irr(unsigned int cpu, int hw_irq, u32 value)
@@ -71,9 +76,9 @@ static void write_irr(unsigned int cpu, int hw_irq, u32 value)
unsigned int shift = IRR_SHIFT(hw_irq);
u32 irr;
- irr = readl(irr0 + offset) & ~(0xf << shift);
+ irr = readl_be(irr0 + offset) & ~(0xf << shift);
irr |= (value & 0xf) << shift;
- writel(irr, irr0 + offset);
+ writel_be(irr, irr0 + offset);
}
static void realtek_ictl_unmask_irq(struct irq_data *i)
@@ -159,7 +164,8 @@ static void realtek_irq_dispatch(struct irq_desc *desc)
unsigned int hw_irq;
chained_irq_enter(chip, desc);
- pending = readl(REG(cpu, RTL_ICTL_GIMR)) & readl(REG(cpu, RTL_ICTL_GISR)) & output->mask;
+ pending = readl_be(REG(cpu, RTL_ICTL_GIMR)) &
+ readl_be(REG(cpu, RTL_ICTL_GISR)) & output->mask;
if (unlikely(!pending)) {
spurious_interrupt();
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-08-20 16:36 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-20 16:20 [PATCH v3] irqchip/irq-realtek-rtl: change to readl_be and writel_be Rustam Adilov
2026-08-20 16:36 ` [tip: irq/urgent] irqchip/irq-realtek-rtl: Use readl_be()/writel_be() instead of readl()/writel() tip-bot2 for Rustam Adilov
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.