The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH v2] irqchip/irq-realtek-rtl: change to __raw reads and writes
@ 2026-07-25 10:14 Rustam Adilov
  2026-08-19 19:02 ` Thomas Gleixner
  0 siblings, 1 reply; 3+ messages in thread
From: Rustam Adilov @ 2026-07-25 10:14 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() and writel() are
changed to perform a byte swap to little endian type. This is
incorrect because the devices that use the irq-realtek-rtl driver
are all big endian MIPS chips.

Fix this by converting the MMIO accesses to __raw_readl() and
__raw_writel(), which do not byte swap the data.

Tested-by: Carlo Szelinsky <github@szelinsky.de>
Signed-off-by: Rustam Adilov <adilov@disroot.org>
---
Changes in v2:
 - Make the commit message clearer.

 drivers/irqchip/irq-realtek-rtl.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/irqchip/irq-realtek-rtl.c b/drivers/irqchip/irq-realtek-rtl.c
index 4b59e0cd86bf..3077f4efb4e2 100644
--- a/drivers/irqchip/irq-realtek-rtl.c
+++ b/drivers/irqchip/irq-realtek-rtl.c
@@ -50,18 +50,18 @@ static inline void enable_gimr(unsigned int cpu, unsigned int hw_irq)
 {
 	u32 gimr;
 
-	gimr = readl(REG(cpu, RTL_ICTL_GIMR));
+	gimr = __raw_readl(REG(cpu, RTL_ICTL_GIMR));
 	gimr |= BIT(hw_irq);
-	writel(gimr, REG(cpu, RTL_ICTL_GIMR));
+	__raw_writel(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 = __raw_readl(REG(cpu, RTL_ICTL_GIMR));
 	gimr &= ~BIT(hw_irq);
-	writel(gimr, REG(cpu, RTL_ICTL_GIMR));
+	__raw_writel(gimr, REG(cpu, RTL_ICTL_GIMR));
 }
 
 static void write_irr(unsigned int cpu, int hw_irq, u32 value)
@@ -71,9 +71,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 = __raw_readl(irr0 + offset) & ~(0xf << shift);
 	irr |= (value & 0xf) << shift;
-	writel(irr, irr0 + offset);
+	__raw_writel(irr, irr0 + offset);
 }
 
 static void realtek_ictl_unmask_irq(struct irq_data *i)
@@ -159,7 +159,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 = __raw_readl(REG(cpu, RTL_ICTL_GIMR)) &
+		  __raw_readl(REG(cpu, RTL_ICTL_GISR)) & output->mask;
 
 	if (unlikely(!pending)) {
 		spurious_interrupt();
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] irqchip/irq-realtek-rtl: change to __raw reads and writes
  2026-07-25 10:14 [PATCH v2] irqchip/irq-realtek-rtl: change to __raw reads and writes Rustam Adilov
@ 2026-08-19 19:02 ` Thomas Gleixner
  2026-08-20 14:56   ` Rustam Adilov
  0 siblings, 1 reply; 3+ messages in thread
From: Thomas Gleixner @ 2026-08-19 19:02 UTC (permalink / raw)
  To: Rustam Adilov, Birger Koblitz, Bert Vermeulen, John Crispin,
	linux-kernel
  Cc: Rustam Adilov, Carlo Szelinsky

On Sat, Jul 25 2026 at 15:14, Rustam Adilov wrote:
> When CONFIG_SWAP_IO_SPACE is enabled, readl() and writel() are
> changed to perform a byte swap to little endian type. This is
> incorrect because the devices that use the irq-realtek-rtl driver
> are all big endian MIPS chips.

That still does not make sense. With CONFIG_SWAP_IO_SPACE() enabled
readl() performs a address swizzle to convert from BE (CPU) to LE
(device). readl() swaps the read data from LE (device) to BE (CPU)
and writel() the other way round.

You need that change not because your CPU is big endian. You need it
because the device is BE, so you don't want to have the LE -> BE
conversion, right?

Btw, please use readl_be() and writel_be() as those are the proper
generic interfaces for this.

And please put a comment into the driver explaining that the device is
BE.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] irqchip/irq-realtek-rtl: change to __raw reads and writes
  2026-08-19 19:02 ` Thomas Gleixner
@ 2026-08-20 14:56   ` Rustam Adilov
  0 siblings, 0 replies; 3+ messages in thread
From: Rustam Adilov @ 2026-08-20 14:56 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Birger Koblitz, Bert Vermeulen, John Crispin, linux-kernel,
	Carlo Szelinsky

On 2026-08-19 19:02, Thomas Gleixner wrote:
> On Sat, Jul 25 2026 at 15:14, Rustam Adilov wrote:
>> When CONFIG_SWAP_IO_SPACE is enabled, readl() and writel() are
>> changed to perform a byte swap to little endian type. This is
>> incorrect because the devices that use the irq-realtek-rtl driver
>> are all big endian MIPS chips.
> 
> That still does not make sense. With CONFIG_SWAP_IO_SPACE() enabled
> readl() performs a address swizzle to convert from BE (CPU) to LE
> (device). readl() swaps the read data from LE (device) to BE (CPU)
> and writel() the other way round.
> 
> You need that change not because your CPU is big endian. You need it
> because the device is BE, so you don't want to have the LE -> BE
> conversion, right?

Right, yes. Still getting the grasp of the SWAP_IO_SPACE it seems.

> Btw, please use readl_be() and writel_be() as those are the proper
> generic interfaces for this.
> 
> And please put a comment into the driver explaining that the device is
> BE.

Okay, will do that in the next version.

Best,
Rustam

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-08-20 14:57 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-25 10:14 [PATCH v2] irqchip/irq-realtek-rtl: change to __raw reads and writes Rustam Adilov
2026-08-19 19:02 ` Thomas Gleixner
2026-08-20 14:56   ` Rustam Adilov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox