[PATCH 2/3] realtek: use DT provided address for timers

Sander Vanheule sander at svanheule.net
Sun Feb 20 08:17:17 PST 2022


The I/O base address for the timers was hardcoded into the driver,
or derived from the HW IRQ number as an even more horrible hack. All
supported SoC families have these timers, but with hardcoded addresses
the code cannot be reused right now.

Request the timer's base address from the DT specification, and store it
in a private struct for future reference.

Matching the second interrupt specifier, the address range for the
second timer is added to the DT specification.

Signed-off-by: Sander Vanheule <sander at svanheule.net>
---
 target/linux/realtek/dts-5.10/rtl930x.dtsi    |  2 +-
 .../arch/mips/kernel/cevt-rtl9300.c           | 46 +++++++++----------
 2 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/target/linux/realtek/dts-5.10/rtl930x.dtsi b/target/linux/realtek/dts-5.10/rtl930x.dtsi
index 0ac613454f58..bfde5e6ff6ae 100644
--- a/target/linux/realtek/dts-5.10/rtl930x.dtsi
+++ b/target/linux/realtek/dts-5.10/rtl930x.dtsi
@@ -59,7 +59,7 @@
 
 		rtl9300clock: rtl9300clock at 3200 {
 			compatible = "realtek,rtl9300clock";
-			reg = <0x3200 0x10>;
+			reg = <0x3200 0x10>, <0x3210 0x10>;
 
 			interrupt-parent = <&intc>;
 			interrupts = <7 5>, <8 5>;
diff --git a/target/linux/realtek/files-5.10/arch/mips/kernel/cevt-rtl9300.c b/target/linux/realtek/files-5.10/arch/mips/kernel/cevt-rtl9300.c
index cf3a4fe437d8..cbbea7d68605 100644
--- a/target/linux/realtek/files-5.10/arch/mips/kernel/cevt-rtl9300.c
+++ b/target/linux/realtek/files-5.10/arch/mips/kernel/cevt-rtl9300.c
@@ -24,11 +24,6 @@
 #define RTL9300_TC_INT_IP	BIT(16)
 #define RTL9300_TC_INT_IE	BIT(20)
 
-// Clocksource is using timer 0, clock event uses timer 1
-#define TIMER_CLK_SRC		0
-#define TIMER_CLK_EVT		0
-#define TIMER_BLK_EVT		(TIMER_CLK_EVT << 4)
-
 // Timer modes
 #define TIMER_MODE_REPEAT	1
 #define TIMER_MODE_ONCE		0
@@ -38,37 +33,35 @@
 
 #define N_BITS			28
 
-#define RTL9300_TC1_IRQ		8
 #define RTL9300_CLOCK_RATE	87500000
-#define RTL9300_TC0_BASE	(void *)0xb8003200
 
-int irq_tc0 = 7;
+struct rtl9300_clk_dev {
+	struct clock_event_device clkdev;
+	void __iomem *base;
+};
 
 static void __iomem *rtl9300_tc_base(struct clock_event_device *clk)
 {
-	struct irq_desc *desc = irq_to_desc(clk->irq);
-	int tc = desc->irq_data.hwirq - irq_tc0;
+	struct rtl9300_clk_dev *rtl_clk = container_of(clk, struct rtl9300_clk_dev, clkdev);
 
-	return RTL9300_TC0_BASE + (tc << 4);
+	return rtl_clk->base;
 }
 
 static irqreturn_t rtl9300_timer_interrupt(int irq, void *dev_id)
 {
-	struct clock_event_device *clk = dev_id;
+	struct rtl9300_clk_dev *rtl_clk = dev_id;
+	struct clock_event_device *clk = &rtl_clk->clkdev;
 //	int cpu = smp_processor_id();
-	struct irq_desc *desc = irq_to_desc(irq);
-	int tc = desc->irq_data.hwirq - irq_tc0;
-	void __iomem *base = RTL9300_TC0_BASE + (tc << 4);
 	static atomic_t count = ATOMIC_INIT(0);
 	unsigned int c;
-	u32 v = readl(base + RTL9300_TC_INT);
+	u32 v = readl(rtl_clk->base + RTL9300_TC_INT);
 
 	c = (unsigned int)atomic_inc_return(&count);
 
 	// Acknowledge the IRQ
 	v |= RTL9300_TC_INT_IP;
-	writel(v, base + RTL9300_TC_INT);
-	if (readl(base + RTL9300_TC_INT) & RTL9300_TC_INT_IP)
+	writel(v, rtl_clk->base + RTL9300_TC_INT);
+	if (readl(rtl_clk->base + RTL9300_TC_INT) & RTL9300_TC_INT_IP)
 		dump_stack();
 
 	clk->event_handler(clk);
@@ -158,14 +151,15 @@ static void rtl9300_clock_setup(void __iomem *base)
 	writel(0x0fffffff, base + RTL9300_TC_DATA);
 }
 
-static DEFINE_PER_CPU(struct clock_event_device, rtl9300_clockevent);
+static DEFINE_PER_CPU(struct rtl9300_clk_dev, rtl9300_clockevent);
 static DEFINE_PER_CPU(char [18], rtl9300_clock_name);
 
 void rtl9300_clockevent_init(void)
 {
 	int cpu = smp_processor_id();
 	int irq;
-	struct clock_event_device *cd = &per_cpu(rtl9300_clockevent, cpu);
+	struct rtl9300_clk_dev *rtl_clk = &per_cpu(rtl9300_clockevent, cpu);
+	struct clock_event_device *cd = &rtl_clk->clkdev;
 	unsigned char *name = per_cpu(rtl9300_clock_name, cpu);
 	unsigned long flags =  IRQF_PERCPU | IRQF_TIMER;
 	struct device_node *node;
@@ -182,7 +176,13 @@ void rtl9300_clockevent_init(void)
 	irq = irq_of_parse_and_map(node, cpu);
 	pr_info("%s using IRQ %d\n", __func__, irq);
 
-	rtl9300_clock_setup(RTL9300_TC0_BASE + TIMER_BLK_EVT + (cpu << 4));
+	rtl_clk->base = of_iomap(node, cpu);
+	if (!rtl_clk->base) {
+		pr_err("cannot map timer for cpu %d", cpu);
+		return;
+	}
+
+	rtl9300_clock_setup(rtl_clk->base);
 
 	sprintf(name, "rtl9300-counter-%d", cpu);
 	cd->name		= name;
@@ -205,8 +205,8 @@ void rtl9300_clockevent_init(void)
 
 	irq_set_affinity(irq, cd->cpumask);
 
-	if (request_irq(irq, rtl9300_timer_interrupt, flags, name, cd))
+	if (request_irq(irq, rtl9300_timer_interrupt, flags, name, rtl_clk))
 		pr_err("Failed to request irq %d (%s)\n", irq, name);
 
-	writel(RTL9300_TC_INT_IE, RTL9300_TC0_BASE + TIMER_BLK_EVT + (cpu << 4) + RTL9300_TC_INT);
+	writel(RTL9300_TC_INT_IE, rtl_clk->base + RTL9300_TC_INT);
 }
-- 
2.35.1




More information about the openwrt-devel mailing list