[RFC 13/13] m68k: mac: convert to generic clockevent

Arnd Bergmann arnd at arndb.de
Thu Oct 8 11:46:51 EDT 2020


Now that the infrastructure allows kernels to have both legacy timer
ticks and clockevent drivers in the same image, start by moving one
platform to generic clockevents.

As qemu only supports the q800 platform among the classic m68k, use
that as an example.

I also tried adding oneshot mode, which was successful but broke
the clocksource. It's probably not hard to make it work properly,
but this is where I've stopped.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
I have never tried implementing a clockevent or clocksource
driver in the past, so this is really just an experiment and
I expect I got something wrong.


 arch/m68k/Kconfig.machine |  2 +-
 arch/m68k/mac/via.c       | 44 ++++++++++++++++++++++++++++++++-------
 2 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine
index 8a4e8bd8aade..cccabdad618e 100644
--- a/arch/m68k/Kconfig.machine
+++ b/arch/m68k/Kconfig.machine
@@ -30,7 +30,7 @@ config MAC
 	depends on MMU
 	select MMU_MOTOROLA if MMU
 	select HAVE_ARCH_NVRAM_OPS
-	select LEGACY_TIMER_TICK
+	select GENERIC_CLOCKEVENTS
 	help
 	  This option enables support for the Apple Macintosh series of
 	  computers (yes, there is experimental support now, at least for part
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index 8ad734e3c934..dd4c13c318b6 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -24,6 +24,7 @@
  */
 
 #include <linux/clocksource.h>
+#include <linux/clockchips.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -602,27 +603,54 @@ static u32 clk_total, clk_offset;
 
 static irqreturn_t via_timer_handler(int irq, void *dev_id)
 {
+	struct clock_event_device *evt = dev_id;
+
 	clk_total += VIA_TIMER_CYCLES;
 	clk_offset = 0;
-	legacy_timer_tick(1);
+	evt->event_handler(evt);
 
 	return IRQ_HANDLED;
 }
 
-void __init via_init_clock(void)
+static int via_set_periodic(struct clock_event_device *evt)
 {
-	if (request_irq(IRQ_MAC_TIMER_1, via_timer_handler, IRQF_TIMER, "timer",
-			NULL)) {
-		pr_err("Couldn't register %s interrupt\n", "timer");
-		return;
-	}
-
 	via1[vT1LL] = VIA_TC_LOW;
 	via1[vT1LH] = VIA_TC_HIGH;
 	via1[vT1CL] = VIA_TC_LOW;
 	via1[vT1CH] = VIA_TC_HIGH;
 	via1[vACR] |= 0x40;
 
+	return 0;
+}
+
+static int via_set_shutdown(struct clock_event_device *evt)
+{
+	via1[vACR] &= ~0x40;
+
+	return 0;
+}
+
+static struct clock_event_device via_clk_event = {
+	.name	= "via1",
+	.rating = 250,
+	.irq	= IRQ_MAC_TIMER_1,
+	.owner	= THIS_MODULE,
+
+	.features		= CLOCK_EVT_FEAT_PERIODIC,
+	.set_state_shutdown	= via_set_shutdown,
+	.set_state_periodic	= via_set_periodic,
+};
+
+void __init via_init_clock(void)
+{
+	clockevents_config_and_register(&via_clk_event, VIA_CLOCK_FREQ, 1, 0xffff);
+
+	if (request_irq(IRQ_MAC_TIMER_1, via_timer_handler, IRQF_TIMER, "timer",
+			&via_clk_event)) {
+		pr_err("Couldn't register %s interrupt\n", "timer");
+		return;
+	}
+
 	clocksource_register_hz(&mac_clk, VIA_CLOCK_FREQ);
 }
 
-- 
2.27.0




More information about the linux-arm-kernel mailing list