diff mbox series

[08/30,v2] ARM: ixp4xx: Switch to use new timer driver

Message ID 20190221154458.23763-9-linus.walleij@linaro.org (mailing list archive)
State New, archived
Headers show
Series ARM: ixp4xx: Modernize and DT support | expand

Commit Message

Linus Walleij Feb. 21, 2019, 3:44 p.m. UTC
This augments the IXP4xx to select and use the new
timer driver in drivers/clocksource and removes the old
code in the machine.

Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Clocksource/timer maintainers: here you see how I activate
this new driver. Intended to be merged through ARM SoC.
---
 arch/arm/Kconfig              |   2 +-
 arch/arm/mach-ixp4xx/common.c | 153 +---------------------------------
 2 files changed, 5 insertions(+), 150 deletions(-)

Comments

Daniel Lezcano Feb. 22, 2019, 8:38 a.m. UTC | #1
On 21/02/2019 16:44, Linus Walleij wrote:
> This augments the IXP4xx to select and use the new
> timer driver in drivers/clocksource and removes the old
> code in the machine.
> 
> Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> Clocksource/timer maintainers: here you see how I activate
> this new driver. Intended to be merged through ARM SoC.
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>



>  arch/arm/Kconfig              |   2 +-
>  arch/arm/mach-ixp4xx/common.c | 153 +---------------------------------
>  2 files changed, 5 insertions(+), 150 deletions(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index f6345594cef0..9f70d7e032d6 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -427,7 +427,6 @@ config ARCH_IXP4XX
>  	depends on MMU
>  	select ARCH_HAS_DMA_SET_COHERENT_MASK
>  	select ARCH_SUPPORTS_BIG_ENDIAN
> -	select CLKSRC_MMIO
>  	select CPU_XSCALE
>  	select DMABOUNCE if PCI
>  	select GENERIC_CLOCKEVENTS
> @@ -436,6 +435,7 @@ config ARCH_IXP4XX
>  	select GPIOLIB
>  	select HAVE_PCI
>  	select IXP4XX_IRQ
> +	select IXP4XX_TIMER
>  	select NEED_MACH_IO_H
>  	select USB_EHCI_BIG_ENDIAN_DESC
>  	select USB_EHCI_BIG_ENDIAN_MMIO
> diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
> index 71683dfc48f9..fc4c9b21ca96 100644
> --- a/arch/arm/mach-ixp4xx/common.c
> +++ b/arch/arm/mach-ixp4xx/common.c
> @@ -22,9 +22,6 @@
>  #include <linux/serial_core.h>
>  #include <linux/interrupt.h>
>  #include <linux/bitops.h>
> -#include <linux/time.h>
> -#include <linux/clocksource.h>
> -#include <linux/clockchips.h>
>  #include <linux/io.h>
>  #include <linux/export.h>
>  #include <linux/cpu.h>
> @@ -32,6 +29,7 @@
>  #include <linux/sched_clock.h>
>  #include <linux/bitops.h>
>  #include <linux/irqchip/irq-ixp4xx.h>
> +#include <linux/platform_data/timer-ixp4xx.h>
>  #include <mach/udc.h>
>  #include <mach/hardware.h>
>  #include <mach/io.h>
> @@ -49,19 +47,6 @@
>  
>  #define IXP4XX_TIMER_FREQ 66666000
>  
> -/*
> - * The timer register doesn't allow to specify the two least significant bits of
> - * the timeout value and assumes them being zero. So make sure IXP4XX_LATCH is
> - * the best value with the two least significant bits unset.
> - */
> -#define IXP4XX_LATCH DIV_ROUND_CLOSEST(IXP4XX_TIMER_FREQ, \
> -				       (IXP4XX_OST_RELOAD_MASK + 1) * HZ) * \
> -			(IXP4XX_OST_RELOAD_MASK + 1)
> -
> -static void __init ixp4xx_clocksource_init(void);
> -static void __init ixp4xx_clockevent_init(void);
> -static struct clock_event_device clockevent_ixp4xx;
> -
>  /*************************************************************************
>   * IXP4xx chipset I/O mapping
>   *************************************************************************/
> @@ -106,37 +91,11 @@ void __init ixp4xx_init_irq(void)
>  			(cpu_is_ixp46x() || cpu_is_ixp43x()));
>  }
>  
> -/*************************************************************************
> - * IXP4xx timer tick
> - * We use OS timer1 on the CPU for the timer tick and the timestamp 
> - * counter as a source of real clock ticks to account for missed jiffies.
> - *************************************************************************/
> -
> -static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
> -{
> -	struct clock_event_device *evt = dev_id;
> -
> -	/* Clear Pending Interrupt by writing '1' to it */
> -	*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
> -
> -	evt->event_handler(evt);
> -
> -	return IRQ_HANDLED;
> -}
> -
>  void __init ixp4xx_timer_init(void)
>  {
> -	/* Reset/disable counter */
> -	*IXP4XX_OSRT1 = 0;
> -
> -	/* Clear Pending Interrupt by writing '1' to it */
> -	*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
> -
> -	/* Reset time-stamp counter */
> -	*IXP4XX_OSTS = 0;
> -
> -	ixp4xx_clocksource_init();
> -	ixp4xx_clockevent_init();
> +	return ixp4xx_timer_setup(IXP4XX_TIMER_BASE_PHYS,
> +				  IRQ_IXP4XX_TIMER1,
> +				  IXP4XX_TIMER_FREQ);
>  }
>  
>  static struct pxa2xx_udc_mach_info ixp4xx_udc_info;
> @@ -251,112 +210,8 @@ void __init ixp4xx_sys_init(void)
>  			ixp4xx_exp_bus_size >> 20);
>  }
>  
> -/*
> - * sched_clock()
> - */
> -static u64 notrace ixp4xx_read_sched_clock(void)
> -{
> -	return *IXP4XX_OSTS;
> -}
> -
> -/*
> - * clocksource
> - */
> -
> -static u64 ixp4xx_clocksource_read(struct clocksource *c)
> -{
> -	return *IXP4XX_OSTS;
> -}
> -
>  unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ;
>  EXPORT_SYMBOL(ixp4xx_timer_freq);
> -static void __init ixp4xx_clocksource_init(void)
> -{
> -	sched_clock_register(ixp4xx_read_sched_clock, 32, ixp4xx_timer_freq);
> -
> -	clocksource_mmio_init(NULL, "OSTS", ixp4xx_timer_freq, 200, 32,
> -			ixp4xx_clocksource_read);
> -}
> -
> -/*
> - * clockevents
> - */
> -static int ixp4xx_set_next_event(unsigned long evt,
> -				 struct clock_event_device *unused)
> -{
> -	unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
> -
> -	*IXP4XX_OSRT1 = (evt & ~IXP4XX_OST_RELOAD_MASK) | opts;
> -
> -	return 0;
> -}
> -
> -static int ixp4xx_shutdown(struct clock_event_device *evt)
> -{
> -	unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
> -	unsigned long osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK;
> -
> -	opts &= ~IXP4XX_OST_ENABLE;
> -	*IXP4XX_OSRT1 = osrt | opts;
> -	return 0;
> -}
> -
> -static int ixp4xx_set_oneshot(struct clock_event_device *evt)
> -{
> -	unsigned long opts = IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT;
> -	unsigned long osrt = 0;
> -
> -	/* period set by 'set next_event' */
> -	*IXP4XX_OSRT1 = osrt | opts;
> -	return 0;
> -}
> -
> -static int ixp4xx_set_periodic(struct clock_event_device *evt)
> -{
> -	unsigned long opts = IXP4XX_OST_ENABLE;
> -	unsigned long osrt = IXP4XX_LATCH & ~IXP4XX_OST_RELOAD_MASK;
> -
> -	*IXP4XX_OSRT1 = osrt | opts;
> -	return 0;
> -}
> -
> -static int ixp4xx_resume(struct clock_event_device *evt)
> -{
> -	unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
> -	unsigned long osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK;
> -
> -	opts |= IXP4XX_OST_ENABLE;
> -	*IXP4XX_OSRT1 = osrt | opts;
> -	return 0;
> -}
> -
> -static struct clock_event_device clockevent_ixp4xx = {
> -	.name			= "ixp4xx timer1",
> -	.features		= CLOCK_EVT_FEAT_PERIODIC |
> -				  CLOCK_EVT_FEAT_ONESHOT,
> -	.rating			= 200,
> -	.set_state_shutdown	= ixp4xx_shutdown,
> -	.set_state_periodic	= ixp4xx_set_periodic,
> -	.set_state_oneshot	= ixp4xx_set_oneshot,
> -	.tick_resume		= ixp4xx_resume,
> -	.set_next_event		= ixp4xx_set_next_event,
> -};
> -
> -static void __init ixp4xx_clockevent_init(void)
> -{
> -	int ret;
> -
> -	clockevent_ixp4xx.cpumask = cpumask_of(0);
> -	clockevent_ixp4xx.irq = IRQ_IXP4XX_TIMER1;
> -	ret = request_irq(IRQ_IXP4XX_TIMER1, ixp4xx_timer_interrupt,
> -			  IRQF_TIMER, "IXP4XX-TIMER1", &clockevent_ixp4xx);
> -	if (ret) {
> -		pr_crit("no timer IRQ\n");
> -		return;
> -	}
> -	clockevents_config_and_register(&clockevent_ixp4xx, IXP4XX_TIMER_FREQ,
> -					0xf, 0xfffffffe);
> -}
>  
>  void ixp4xx_restart(enum reboot_mode mode, const char *cmd)
>  {
>
diff mbox series

Patch

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f6345594cef0..9f70d7e032d6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -427,7 +427,6 @@  config ARCH_IXP4XX
 	depends on MMU
 	select ARCH_HAS_DMA_SET_COHERENT_MASK
 	select ARCH_SUPPORTS_BIG_ENDIAN
-	select CLKSRC_MMIO
 	select CPU_XSCALE
 	select DMABOUNCE if PCI
 	select GENERIC_CLOCKEVENTS
@@ -436,6 +435,7 @@  config ARCH_IXP4XX
 	select GPIOLIB
 	select HAVE_PCI
 	select IXP4XX_IRQ
+	select IXP4XX_TIMER
 	select NEED_MACH_IO_H
 	select USB_EHCI_BIG_ENDIAN_DESC
 	select USB_EHCI_BIG_ENDIAN_MMIO
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 71683dfc48f9..fc4c9b21ca96 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -22,9 +22,6 @@ 
 #include <linux/serial_core.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
-#include <linux/time.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
 #include <linux/io.h>
 #include <linux/export.h>
 #include <linux/cpu.h>
@@ -32,6 +29,7 @@ 
 #include <linux/sched_clock.h>
 #include <linux/bitops.h>
 #include <linux/irqchip/irq-ixp4xx.h>
+#include <linux/platform_data/timer-ixp4xx.h>
 #include <mach/udc.h>
 #include <mach/hardware.h>
 #include <mach/io.h>
@@ -49,19 +47,6 @@ 
 
 #define IXP4XX_TIMER_FREQ 66666000
 
-/*
- * The timer register doesn't allow to specify the two least significant bits of
- * the timeout value and assumes them being zero. So make sure IXP4XX_LATCH is
- * the best value with the two least significant bits unset.
- */
-#define IXP4XX_LATCH DIV_ROUND_CLOSEST(IXP4XX_TIMER_FREQ, \
-				       (IXP4XX_OST_RELOAD_MASK + 1) * HZ) * \
-			(IXP4XX_OST_RELOAD_MASK + 1)
-
-static void __init ixp4xx_clocksource_init(void);
-static void __init ixp4xx_clockevent_init(void);
-static struct clock_event_device clockevent_ixp4xx;
-
 /*************************************************************************
  * IXP4xx chipset I/O mapping
  *************************************************************************/
@@ -106,37 +91,11 @@  void __init ixp4xx_init_irq(void)
 			(cpu_is_ixp46x() || cpu_is_ixp43x()));
 }
 
-/*************************************************************************
- * IXP4xx timer tick
- * We use OS timer1 on the CPU for the timer tick and the timestamp 
- * counter as a source of real clock ticks to account for missed jiffies.
- *************************************************************************/
-
-static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = dev_id;
-
-	/* Clear Pending Interrupt by writing '1' to it */
-	*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
-
-	evt->event_handler(evt);
-
-	return IRQ_HANDLED;
-}
-
 void __init ixp4xx_timer_init(void)
 {
-	/* Reset/disable counter */
-	*IXP4XX_OSRT1 = 0;
-
-	/* Clear Pending Interrupt by writing '1' to it */
-	*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
-
-	/* Reset time-stamp counter */
-	*IXP4XX_OSTS = 0;
-
-	ixp4xx_clocksource_init();
-	ixp4xx_clockevent_init();
+	return ixp4xx_timer_setup(IXP4XX_TIMER_BASE_PHYS,
+				  IRQ_IXP4XX_TIMER1,
+				  IXP4XX_TIMER_FREQ);
 }
 
 static struct pxa2xx_udc_mach_info ixp4xx_udc_info;
@@ -251,112 +210,8 @@  void __init ixp4xx_sys_init(void)
 			ixp4xx_exp_bus_size >> 20);
 }
 
-/*
- * sched_clock()
- */
-static u64 notrace ixp4xx_read_sched_clock(void)
-{
-	return *IXP4XX_OSTS;
-}
-
-/*
- * clocksource
- */
-
-static u64 ixp4xx_clocksource_read(struct clocksource *c)
-{
-	return *IXP4XX_OSTS;
-}
-
 unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ;
 EXPORT_SYMBOL(ixp4xx_timer_freq);
-static void __init ixp4xx_clocksource_init(void)
-{
-	sched_clock_register(ixp4xx_read_sched_clock, 32, ixp4xx_timer_freq);
-
-	clocksource_mmio_init(NULL, "OSTS", ixp4xx_timer_freq, 200, 32,
-			ixp4xx_clocksource_read);
-}
-
-/*
- * clockevents
- */
-static int ixp4xx_set_next_event(unsigned long evt,
-				 struct clock_event_device *unused)
-{
-	unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
-
-	*IXP4XX_OSRT1 = (evt & ~IXP4XX_OST_RELOAD_MASK) | opts;
-
-	return 0;
-}
-
-static int ixp4xx_shutdown(struct clock_event_device *evt)
-{
-	unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
-	unsigned long osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK;
-
-	opts &= ~IXP4XX_OST_ENABLE;
-	*IXP4XX_OSRT1 = osrt | opts;
-	return 0;
-}
-
-static int ixp4xx_set_oneshot(struct clock_event_device *evt)
-{
-	unsigned long opts = IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT;
-	unsigned long osrt = 0;
-
-	/* period set by 'set next_event' */
-	*IXP4XX_OSRT1 = osrt | opts;
-	return 0;
-}
-
-static int ixp4xx_set_periodic(struct clock_event_device *evt)
-{
-	unsigned long opts = IXP4XX_OST_ENABLE;
-	unsigned long osrt = IXP4XX_LATCH & ~IXP4XX_OST_RELOAD_MASK;
-
-	*IXP4XX_OSRT1 = osrt | opts;
-	return 0;
-}
-
-static int ixp4xx_resume(struct clock_event_device *evt)
-{
-	unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
-	unsigned long osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK;
-
-	opts |= IXP4XX_OST_ENABLE;
-	*IXP4XX_OSRT1 = osrt | opts;
-	return 0;
-}
-
-static struct clock_event_device clockevent_ixp4xx = {
-	.name			= "ixp4xx timer1",
-	.features		= CLOCK_EVT_FEAT_PERIODIC |
-				  CLOCK_EVT_FEAT_ONESHOT,
-	.rating			= 200,
-	.set_state_shutdown	= ixp4xx_shutdown,
-	.set_state_periodic	= ixp4xx_set_periodic,
-	.set_state_oneshot	= ixp4xx_set_oneshot,
-	.tick_resume		= ixp4xx_resume,
-	.set_next_event		= ixp4xx_set_next_event,
-};
-
-static void __init ixp4xx_clockevent_init(void)
-{
-	int ret;
-
-	clockevent_ixp4xx.cpumask = cpumask_of(0);
-	clockevent_ixp4xx.irq = IRQ_IXP4XX_TIMER1;
-	ret = request_irq(IRQ_IXP4XX_TIMER1, ixp4xx_timer_interrupt,
-			  IRQF_TIMER, "IXP4XX-TIMER1", &clockevent_ixp4xx);
-	if (ret) {
-		pr_crit("no timer IRQ\n");
-		return;
-	}
-	clockevents_config_and_register(&clockevent_ixp4xx, IXP4XX_TIMER_FREQ,
-					0xf, 0xfffffffe);
-}
 
 void ixp4xx_restart(enum reboot_mode mode, const char *cmd)
 {