Consolidate simple ARM MMIO clock sources
Subsystems (13)
v2 cover Consolidate simple ARM MMIO clock sources
This is a re-posting of the clocksource patches, which includes some other updates. This includes bcmring in the update.
In a similar light to the i8253 series, this consolidates 17 ARM MMIO counter clocksources into a single common implementation. This common implementation caters for 32-bit and 16-bit register access sizes, up and down counters, and various bit sizes of those counters.
Patch 1 is already in John Stultz tree, but is included for completeness and to get rid of a build warning.
arch/arm/Kconfig | 15 ++ arch/arm/common/timer-sp.c | 80 +++++++---- arch/arm/include/asm/hardware/timer-sp.h | 4 +- arch/arm/mach-bcmring/core.c | 220 +++++++----------------------- arch/arm/mach-integrator/Kconfig | 1 + arch/arm/mach-integrator/integrator_ap.c | 21 +--- arch/arm/mach-integrator/integrator_cp.c | 11 ++- arch/arm/mach-ixp4xx/common.c | 16 +-- arch/arm/mach-lpc32xx/timer.c | 17 +-- arch/arm/mach-mxs/timer.c | 20 +-- arch/arm/mach-netx/time.c | 16 +-- arch/arm/mach-omap1/time.c | 69 +++------- arch/arm/mach-pxa/time.c | 17 +-- arch/arm/mach-realview/core.c | 13 ++- arch/arm/mach-sa1100/time.c | 24 +--- arch/arm/mach-tcc8k/time.c | 16 +-- arch/arm/mach-tegra/timer.c | 16 +-- arch/arm/mach-u300/timer.c | 18 +-- arch/arm/mach-versatile/core.c | 13 ++- arch/arm/mach-vexpress/ct-ca9x4.c | 17 ++- arch/arm/mach-vexpress/v2m.c | 17 ++- arch/arm/mach-w90x900/time.c | 17 +-- arch/arm/plat-mxc/epit.c | 18 +-- arch/arm/plat-mxc/time.c | 38 +---- arch/arm/plat-nomadik/Kconfig | 1 + arch/arm/plat-nomadik/timer.c | 31 +---- arch/arm/plat-omap/Kconfig | 1 + arch/arm/plat-orion/time.c | 21 +--- arch/arm/plat-s5p/s5p-time.c | 58 +++------ arch/arm/plat-spear/time.c | 16 +-- drivers/Kconfig | 3 + drivers/clocksource/Kconfig | 2 + drivers/clocksource/Makefile | 1 + drivers/clocksource/mmio.c | 73 ++++++++++ include/linux/clocksource.h | 10 ++- 35 files changed, 354 insertions(+), 577 deletions(-)
PATCH v2 1/19 Make clocksource name const
As nothing should be writing to the clocksource name string, make the clocksource name pointer const. Build-tested on ARM Versatile Express.
--- include/linux/clocksource.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
include/linux/clocksource.h +1 -1
@@ -161,7 +161,7 @@ struct clocksource {/* * First part of structure is read mostly */ -char *name; +const char *name;struct list_head list;int rating;cycle_t (*read)(struct clocksource *cs);
Signature · 1 line
1.7.4.4
PATCH 1/19 Make clocksource name const
Quoted 13 lines · Russell King - ARM Linux
As nothing should be writing to the clocksource name string, make the clocksource name pointer const. Build-tested on ARM Versatile Express.
Cc Alessandro Rubini <[email protected]>Cc Colin Cross <[email protected]>Cc Eric Miao <[email protected]>Cc Erik Gilling <[email protected]>Cc "Hans J. Koch" <[email protected]>Cc Imre Kaloz <[email protected]>Cc Krzysztof Halasa <[email protected]>Cc Kukjin Kim <[email protected]>Cc Lennert Buytenhek <[email protected]>Cc Linus Walleij <[email protected]>
Quoted 8 lines
Cc linux-omap at vger.kernel.orgCc Nicolas Pitre <[email protected]>Cc Olof Johansson <[email protected]>Cc Sascha Hauer <[email protected]>Cc Tony Lindgren <[email protected]>Cc Viresh Kumar <[email protected]>Cc Wan ZongShun <[email protected]>Signed-off-by Russell King <[email protected]>
Quoted 21 lines
--- include/linux/clocksource.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)include/linux/clocksource.h +1
-1@@ -161,7 +161,7 @@ struct clocksource {/* * First part of structure is read mostly */ -char *name; +const char *name;struct list_head list;int rating;cycle_t (*read)(struct clocksource *cs);Signature · 1 line
1.7.4.4
PATCH 1/19 Make clocksource name const
In reply to Russell King - ARM Linux2011/5/16 Russell King - ARM Linux <[email protected]>:
Quoted 2 lines
As nothing should be writing to the clocksource name string, make the clocksource name pointer const. ?Build-tested on ARM Versatile Express.
Yours,
Linus Walleij
PATCH v2 2/19 ARM: s5p: consolidate selection of timer register
In reply to Russell King - ARM Linuxs5p duplicates the runtime selection of the timer register three times. Move this out into a separate function.
FIXME: It is unclear whether this code needs to support true runtime selection of the timer register, or whether it can be selected once at init time.
--- arch/arm/plat-s5p/s5p-time.c | 58 ++++++++++++----------------------------- 1 files changed, 17 insertions(+), 41 deletions(-)
arch/arm/plat-s5p/s5p-time.c +17 -41
@@ -290,7 +290,7 @@ static void __init s5p_clockevent_init(void)setup_irq (irq_number, &s5p_clock_event_irq); } -static cycle_t s5p_timer_read (struct clocksource *cs) +static void __iomem *s5p_timer_reg (void ) {unsigned long offset =0 ;
@@ -308,10 +308,17 @@ static cycle_t s5p_timer_read(struct clocksource *cs)default :printk (KERN_ERR "Invalid Timer %d\n" , timer_source.source_id); -return 0 ; +return NULL ; } -return (cycle_t ) ~__raw_readl (S3C_TIMERREG (offset)); +return S3C_TIMERREG (offset); +} + +static cycle_t s5p_timer_read (struct clocksource *cs) +{ +void __iomem *reg =s5p_timer_reg (); + +return (cycle_t) (reg ? ~__raw_readl (reg) :0 ); }/*
@@ -325,53 +332,22 @@ static DEFINE_CLOCK_DATA(cd);unsigned long long notrace sched_clock (void ) { -u32 cyc; -unsigned long offset =0 ; - -switch (timer_source.source_id) { -case S5P_PWM0 : -case S5P_PWM1 : -case S5P_PWM2 : -case S5P_PWM3 : - offset = (timer_source.source_id *0x0c ) +0x14 ; -break ; - -case S5P_PWM4 : - offset =0x40 ; -break ; +void __iomem *reg =s5p_timer_reg (); -default : -printk (KERN_ERR "Invalid Timer %d\n" , timer_source.source_id); +if (!reg)return 0 ; - } - cyc = ~__raw_readl (S3C_TIMERREG (offset)); -return cyc_to_sched_clock (&cd, cyc, (u32 )~0 ); +return cyc_to_sched_clock (&cd, ~__raw_readl (reg), (u32 )~0 ); } static void notrace s5p_update_sched_clock(void) { -u32 cyc; -unsigned long offset =0 ; +void __iomem *reg =s5p_timer_reg (); -switch (timer_source.source_id) { -case S5P_PWM0 : -case S5P_PWM1 : -case S5P_PWM2 : -case S5P_PWM3 : - offset = (timer_source.source_id *0x0c ) +0x14 ; -break ; - -case S5P_PWM4 : - offset =0x40 ; -break ; - -default : -printk (KERN_ERR "Invalid Timer %d\n" , timer_source.source_id); - } +if (!reg) +return ; - cyc = ~__raw_readl (S3C_TIMERREG (offset)); -update_sched_clock (&cd, cyc, (u32 )~0 ); +update_sched_clock (&cd, ~__raw_readl (reg), (u32 )~0 ); }struct clocksource time_clocksource = {
Signature · 1 line
1.7.4.4
PATCH v2 3/19 ARM: omap1: delete useless interrupt handler
In reply to Russell King - ARM LinuxThe OMAP1 clocksource interrupt handler just increments a variable which otherwise isn't used, so this seems to be unnecessary. Tony Lindgren confirms, so lets remove it.
--- arch/arm/mach-omap1/time.c | 15 --------------- 1 files changed, 0 insertions(+), 15 deletions(-)
arch/arm/mach-omap1/time.c +0 -15
@@ -189,20 +189,6 @@ static __init void omap_init_mpu_timer(unsigned long rate)* --------------------------------------------------------------------------- */ -static unsigned long omap_mpu_timer2_overflows; - -static irqreturn_t omap_mpu_timer2_interrupt (int irq,void *dev_id) -{ - omap_mpu_timer2_overflows++; -return IRQ_HANDLED ; -} - -static struct irqaction omap_mpu_timer2_irq = { - .name ="mpu_timer2" , - .flags =IRQF_DISABLED , - .handler = omap_mpu_timer2_interrupt, -}; -static cycle_t mpu_read (struct clocksource *cs) {return ~omap_mpu_timer_read (1 );
@@ -247,7 +233,6 @@ static void __init omap_init_clocksource(unsigned long rate)static char err[]__initdata =KERN_ERR "%s: can't register clocksource!\n" ; -setup_irq (INT_TIMER2 , &omap_mpu_timer2_irq);omap_mpu_timer_start (1 , ~0 ,1 );init_sched_clock (&cd, mpu_update_sched_clock,32 , rate);
Signature · 1 line
1.7.4.4
PATCH v2 4/19 ARM: omap1: convert to using readl/writel instead of volatile struct
In reply to Russell King - ARM Linux--- arch/arm/mach-omap1/time.c | 31 ++++++++++++++++--------------- 1 files changed, 16 insertions(+), 15 deletions(-)
arch/arm/mach-omap1/time.c +16 -15
@@ -68,49 +68,50 @@ typedef struct { } omap_mpu_timer_regs_t;#define omap_mpu_timer_base (n) \ -((volatile omap_mpu_timer_regs_t*)OMAP1_IO_ADDRESS(OMAP_MPU_TIMER_BASE + \ +((omap_mpu_timer_regs_t __iomem *)OMAP1_IO_ADDRESS(OMAP_MPU_TIMER_BASE + \ (n)*OMAP_MPU_TIMER_OFFSET))static inline unsigned long notrace omap_mpu_timer_read (int nr) { -volatile omap_mpu_timer_regs_t * timer =omap_mpu_timer_base (nr); -return timer->read_tim; +omap_mpu_timer_regs_t __iomem *timer =omap_mpu_timer_base (nr); +return readl (&timer->read_tim); }static inline void omap_mpu_set_autoreset (int nr) { -volatile omap_mpu_timer_regs_t * timer =omap_mpu_timer_base (nr); +omap_mpu_timer_regs_t __iomem *timer =omap_mpu_timer_base (nr); - timer->cntl = timer->cntl |MPU_TIMER_AR ; +writel (readl (&timer->cntl) |MPU_TIMER_AR , &timer->cntl); }static inline void omap_mpu_remove_autoreset (int nr) { -volatile omap_mpu_timer_regs_t * timer =omap_mpu_timer_base (nr); +omap_mpu_timer_regs_t __iomem *timer =omap_mpu_timer_base (nr); - timer->cntl = timer->cntl & ~MPU_TIMER_AR ; +writel (readl (&timer->cntl) & ~MPU_TIMER_AR , &timer->cntl); }static inline void omap_mpu_timer_start (int nr,unsigned long load_val,int autoreset) { -volatile omap_mpu_timer_regs_t * timer =omap_mpu_timer_base (nr); -unsigned int timerflags = (MPU_TIMER_CLOCK_ENABLE |MPU_TIMER_ST ); +omap_mpu_timer_regs_t __iomem *timer =omap_mpu_timer_base (nr); +unsigned int timerflags =MPU_TIMER_CLOCK_ENABLE |MPU_TIMER_ST ; -if (autoreset) timerflags |=MPU_TIMER_AR ; +if (autoreset) + timerflags |=MPU_TIMER_AR ; - timer->cntl =MPU_TIMER_CLOCK_ENABLE ; +writel (MPU_TIMER_CLOCK_ENABLE , &timer->cntl);udelay (1 ); - timer->load_tim = load_val; +writel (load_val, &timer->load_tim);udelay (1 ); - timer->cntl = timerflags; +writel (timerflags, &timer->cntl); }static inline void omap_mpu_timer_stop (int nr) { -volatile omap_mpu_timer_regs_t * timer =omap_mpu_timer_base (nr); +omap_mpu_timer_regs_t __iomem *timer =omap_mpu_timer_base (nr); - timer->cntl &= ~MPU_TIMER_ST ; +writel (readl (&timer->cntl) & ~MPU_TIMER_ST , &timer->cntl); }/*
Signature · 1 line
1.7.4.4
PATCH 4/19 ARM: omap1: convert to using readl/writel instead of volatile struct
Quoted 2 lines · Russell King - ARM Linux
arch/arm/mach-omap1/time.c +0
-0
...
Quoted 7 lines
?static inline unsigned long notrace
omap_mpu_timer_read(int nr)?{
- ? ? ? volatile omap_mpu_timer_regs_t* timer =omap_mpu_timer_base(nr);
- ? ? ? returntimer->read_tim;
+ ? ? ?omap_mpu_timer_regs_t__iomem*timer =omap_mpu_timer_base(nr);
+ ? ? ? returnreadl(&timer->read_tim);
?}
We should start using the *_relaxed() accessors a bit more to avoid the barriers overhead in the standard I/O accessors.
Signature · 1 line
Catalin
PATCH v2 4/19 ARM: omap1: convert to using readl/writel instead of volatile struct
Quoted 12 lines · Catalin Marinas
Quoted 2 lines · Russell King - ARM Linux
arch/arm/mach-omap1/time.c +0
-0...
Quoted 7 lines
?static inline unsigned long notrace
omap_mpu_timer_read(int nr)?{
- ? ? ? volatile omap_mpu_timer_regs_t* timer =omap_mpu_timer_base(nr);
- ? ? ? returntimer->read_tim;
+ ? ? ?omap_mpu_timer_regs_t__iomem*timer =omap_mpu_timer_base(nr);
+ ? ? ? returnreadl(&timer->read_tim);
?}
Quoted 2 lines
We should start using the
*_relaxed()accessors a bit more to avoid the barriers overhead in the standard I/O accessors.
I thought about that, but when you look at patch 6, it'd change this. I wanted to use the same accessor here as it ends up with in patch 6.
PATCH 4/19 ARM: omap1: convert to using readl/writel instead of volatile struct
In reply to Catalin Marinas2011/5/17 Catalin Marinas <[email protected]>:
Quoted 12 lines · Russell King - ARM Linux
Quoted 2 lines
arch/arm/mach-omap1/time.c +0
-0...
Quoted 7 lines
?static inline unsigned long notrace
omap_mpu_timer_read(int nr)?{
- ? ? ? volatile omap_mpu_timer_regs_t* timer =omap_mpu_timer_base(nr);
- ? ? ? returntimer->read_tim;
+ ? ? ?omap_mpu_timer_regs_t__iomem*timer =omap_mpu_timer_base(nr);
+ ? ? ? returnreadl(&timer->read_tim);
?}
Quoted 2 lines
We should start using the
*_relaxed()accessors a bit more to avoid the barriers overhead in the standard I/O accessors.
Speaking of which.
The documentation for the *_relaxed calls are inDocumentation/DocBook/deviceiobook.tmpl
and reads like this:
"PCI ordering rules also guarantee that PIO read responses arrive after any outstanding DMA writes from that bus, since for some devices the result of a readb
call may signal to the driver that a DMA transaction is complete. In many cases, however, the driver may want to indicate that the next readb call has no relation to
any previous DMA writes performed by the device. The driver can use readb_relaxed for these cases, although only some platforms will honor the relaxed
semantics. Using the relaxed read functions will provide significant performance benefits on platforms that support it. The qla2xxx driver provides examples of how
to use readX_relaxed. In many cases, a majority of the driver's readX calls can safely be converted to readX_relaxed calls, since only a few will indicate or depend on DMA completion."
I guess that in the ARM case "PCI DMA" corresponds to "bus mastering" but is this strictly speaking properly describing the semantics of the ARM *_relaxed operations?
If it isn't a hint on how it should be understood would be much appreciated.
Yours,
Linus Walleij
PATCH v2 5/19 ARM: update sa1100 to reflect PXA updates
In reply to Russell King - ARM LinuxUpdate sa1100 clockevents code to reflect what its later derivative does with clockevents_calc_mult_shift(). Use OSSR_M* constants too.
--- arch/arm/mach-sa1100/time.c | 8 +++----- 1 files changed, 3 insertions(+), 5 deletions(-)
arch/arm/mach-sa1100/time.c +3 -5
@@ -92,7 +92,6 @@ sa1100_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *c)static struct clock_event_device ckevt_sa1100_osmr0 = { .name ="osmr0" , .features =CLOCK_EVT_FEAT_ONESHOT , - .shift =32 , .rating =200 , .set_next_event = sa1100_osmr0_set_next_event, .set_mode = sa1100_osmr0_set_mode,
@@ -120,14 +119,13 @@ static struct irqaction sa1100_timer_irq = {static void __init sa1100_timer_init (void ) { -OIER =0 ;/* disable any timer interrupts */ -OSSR =0xf ;/* clear status on all timers */ +OIER =0 ; +OSSR =OSSR_M0 |OSSR_M1 |OSSR_M2 |OSSR_M3 ;init_fixed_sched_clock (&cd, sa1100_update_sched_clock,32 ,3686400 ,SC_MULT ,SC_SHIFT ); - ckevt_sa1100_osmr0.mult = -div_sc (3686400 ,NSEC_PER_SEC , ckevt_sa1100_osmr0.shift); +clockevents_calc_mult_shift (&ckevt_sa1100_osmr0,3686400 ,4 ); ckevt_sa1100_osmr0.max_delta_ns =clockevent_delta2ns (0x7fffffff , &ckevt_sa1100_osmr0); ckevt_sa1100_osmr0.min_delta_ns =
Signature · 1 line
1.7.4.4
PATCH v2 6/19 clocksource: add common mmio clocksource
In reply to Russell King - ARM LinuxAdd a generic mmio clocksource, covering both 32-bit and 16-bit register access sizes, for up or down counters. This can be used to easily create clocksources for simple counter-based implementations.
--- drivers/Kconfig | 3 ++ drivers/clocksource/Kconfig | 2 + drivers/clocksource/Makefile | 1 + drivers/clocksource/mmio.c | 73 ++++++++++++++++++++++++++++++++++++++++++ include/linux/clocksource.h | 8 ++++ 5 files changed, 87 insertions(+), 0 deletions(-) create mode 100644 drivers/clocksource/Kconfig create mode 100644 drivers/clocksource/mmio.c
drivers/Kconfig +3 -0
@@ -119,4 +119,7 @@ source "drivers/platform/Kconfig" source "drivers/clk/Kconfig" source "drivers/hwspinlock/Kconfig" + +source "drivers/clocksource/Kconfig" + endmenu
drivers/clocksource/Kconfig new file +2 -0
@@ -0,0 +1,2 @@ +config CLKSRC_MMIO + bool
drivers/clocksource/Makefile +1 -0
@@ -6,3 +6,4 @@ obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += cs5535-clockevt.o obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o obj-$(CONFIG_SH_TIMER_MTU2) += sh_mtu2.o obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o +obj-$(CONFIG_CLKSRC_MMIO) += mmio.o
drivers/clocksource/mmio.c new file +73 -0
73 lines not on this page · raw message
include/linux/clocksource.h +8 -0
@@ -341,4 +341,12 @@ static inline void update_vsyscall_tz(void)extern void timekeeping_notify (struct clocksource *clock); +extern cycle_t clocksource_mmio_readl_up (struct clocksource *); +extern cycle_t clocksource_mmio_readl_down (struct clocksource *); +extern cycle_t clocksource_mmio_readw_up (struct clocksource *); +extern cycle_t clocksource_mmio_readw_down (struct clocksource *); + +extern int clocksource_mmio_init (void __iomem *,const char *, +unsigned long ,int ,unsigned ,cycle_t (*)(struct clocksource *)); +#endif /* _LINUX_CLOCKSOURCE_H */
Signature · 1 line
1.7.4.4
PATCH v2 7/19 clocksource: convert ARM 32-bit up counting clocksources
In reply to Russell King - ARM LinuxConvert ixp4xx, lpc32xx, mxc, netx, pxa, sa1100, tcc8k, tegra and u300 to use the generic mmio clocksource recently introduced.
--- arch/arm/Kconfig | 9 +++++++++ arch/arm/mach-ixp4xx/common.c | 16 ++-------------- arch/arm/mach-lpc32xx/timer.c | 17 +++-------------- arch/arm/mach-netx/time.c | 16 ++-------------- arch/arm/mach-pxa/time.c | 17 ++--------------- arch/arm/mach-sa1100/time.c | 16 ++-------------- arch/arm/mach-tcc8k/time.c | 16 ++-------------- arch/arm/mach-tegra/timer.c | 16 ++-------------- arch/arm/mach-u300/timer.c | 18 +++--------------- arch/arm/plat-mxc/time.c | 38 +++++++------------------------------- 10 files changed, 34 insertions(+), 145 deletions(-)
arch/arm/Kconfig +9 -0
@@ -366,6 +366,7 @@ config ARCH_MXC select GENERIC_CLOCKEVENTS select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP + select CLKSRC_MMIO select HAVE_SCHED_CLOCK help Support for Freescale MXC/iMX-based family of processors
@@ -390,6 +391,7 @@ config ARCH_STMP3XXX config ARCH_NETX bool "Hilscher NetX based" + select CLKSRC_MMIO select CPU_ARM926T select ARM_VIC select GENERIC_CLOCKEVENTS
@@ -457,6 +459,7 @@ config ARCH_IXP2000 config ARCH_IXP4XX bool "IXP4xx-based" depends on MMU + select CLKSRC_MMIO select CPU_XSCALE select GENERIC_GPIO select GENERIC_CLOCKEVENTS
@@ -497,6 +500,7 @@ config ARCH_LOKI config ARCH_LPC32XX bool "NXP LPC32XX" + select CLKSRC_MMIO select CPU_ARM926T select ARCH_REQUIRE_GPIOLIB select HAVE_IDE
@@ -592,6 +596,7 @@ config ARCH_NUC93X config ARCH_TEGRA bool "NVIDIA Tegra" select CLKDEV_LOOKUP + select CLKSRC_MMIO select GENERIC_TIME select GENERIC_CLOCKEVENTS select GENERIC_GPIO
@@ -617,6 +622,7 @@ config ARCH_PXA select ARCH_MTD_XIP select ARCH_HAS_CPUFREQ select CLKDEV_LOOKUP + select CLKSRC_MMIO select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS select HAVE_SCHED_CLOCK
@@ -667,6 +673,7 @@ config ARCH_RPC config ARCH_SA1100 bool "SA1100-based" + select CLKSRC_MMIO select CPU_SA1100 select ISA select ARCH_SPARSEMEM_ENABLE
@@ -803,6 +810,7 @@ config ARCH_SHARK config ARCH_TCC_926 bool "Telechips TCC ARM926-based systems" + select CLKSRC_MMIO select CPU_ARM926T select HAVE_CLK select CLKDEV_LOOKUP
@@ -813,6 +821,7 @@ config ARCH_TCC_926 config ARCH_U300 bool "ST-Ericsson U300 Series" depends on MMU + select CLKSRC_MMIO select CPU_ARM926T select HAVE_SCHED_CLOCK select HAVE_TCM
arch/arm/mach-ixp4xx/common.c +2 -14
@@ -419,26 +419,14 @@ static void notrace ixp4xx_update_sched_clock(void)/* * clocksource */ -static cycle_t ixp4xx_get_cycles (struct clocksource *cs) -{ -return *IXP4XX_OSTS ; -} - -static struct clocksource clocksource_ixp4xx = { - .name ="OSTS" , - .rating =200 , - .read = ixp4xx_get_cycles, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -unsigned long ixp4xx_timer_freq =IXP4XX_TIMER_FREQ ;EXPORT_SYMBOL (ixp4xx_timer_freq);static void __init ixp4xx_clocksource_init (void ) {init_sched_clock (&cd, ixp4xx_update_sched_clock,32 , ixp4xx_timer_freq); -clocksource_register_hz (&clocksource_ixp4xx, ixp4xx_timer_freq); +clocksource_mmio_init (&IXP4XX_OSTS ,"OSTS" , ixp4xx_timer_freq,200 ,32 , + clocksource_mmio_readl_up); }/*
arch/arm/mach-lpc32xx/timer.c +3 -14
@@ -31,19 +31,6 @@#include <mach/platform.h> #include "common.h" -static cycle_t lpc32xx_clksrc_read (struct clocksource *cs) -{ -return (cycle_t )__raw_readl (LCP32XX_TIMER_TC (LPC32XX_TIMER1_BASE )); -} - -static struct clocksource lpc32xx_clksrc = { - .name ="lpc32xx_clksrc" , - .rating =300 , - .read = lpc32xx_clksrc_read, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -static int lpc32xx_clkevt_next_event (unsigned long delta,struct clock_event_device *dev) {
@@ -170,7 +157,9 @@ static void __init lpc32xx_timer_init(void)__raw_writel (0 ,LCP32XX_TIMER_MCR (LPC32XX_TIMER1_BASE ));__raw_writel (LCP32XX_TIMER_CNTR_TCR_EN ,LCP32XX_TIMER_TCR (LPC32XX_TIMER1_BASE )); -clocksource_register_hz (&lpc32xx_clksrc, clkrate); + +clocksource_mmio_init (LCP32XX_TIMER_TC (LPC32XX_TIMER1_BASE ), +"lpc32xx_clksrc" , clkrate,300 ,32 , clocksource_mmio_readl_up); }struct sys_timer lpc32xx_timer = {
arch/arm/mach-netx/time.c +2 -14
@@ -104,19 +104,6 @@ static struct irqaction netx_timer_irq = { .handler = netx_timer_interrupt, }; -cycle_t netx_get_cycles (struct clocksource *cs) -{ -return readl (NETX_GPIO_COUNTER_CURRENT (TIMER_CLOCKSOURCE )); -} - -static struct clocksource clocksource_netx = { - .name ="netx_timer" , - .rating =200 , - .read = netx_get_cycles, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -/* * Set up timer interrupt */
@@ -150,7 +137,8 @@ static void __init netx_timer_init(void)writel (NETX_GPIO_COUNTER_CTRL_RUN ,NETX_GPIO_COUNTER_CTRL (TIMER_CLOCKSOURCE )); -clocksource_register_hz (&clocksource_netx,CLOCK_TICK_RATE ); +clocksource_mmio_init (NETX_GPIO_COUNTER_CURRENT (TIMER_CLOCKSOURCE ), +"netx_timer" ,CLOCK_TICK_RATE ,200 ,32 , clocksource_mmio_readl_up); netx_clockevent.mult =div_sc (CLOCK_TICK_RATE ,NSEC_PER_SEC , netx_clockevent.shift);
arch/arm/mach-pxa/time.c +2 -15
@@ -105,19 +105,6 @@ static struct clock_event_device ckevt_pxa_osmr0 = { .set_mode = pxa_osmr0_set_mode, }; -static cycle_t pxa_read_oscr (struct clocksource *cs) -{ -return OSCR ; -} - -static struct clocksource cksrc_pxa_oscr0 = { - .name ="oscr0" , - .rating =200 , - .read = pxa_read_oscr, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -static struct irqaction pxa_ost0_irq = { .name ="ost0" , .flags =IRQF_DISABLED |IRQF_TIMER |IRQF_IRQPOLL ,
@@ -134,7 +121,6 @@ static void __init pxa_timer_init(void)init_sched_clock (&cd, pxa_update_sched_clock,32 , clock_tick_rate); -clocksource_calc_mult_shift (&cksrc_pxa_oscr0, clock_tick_rate,4 );clockevents_calc_mult_shift (&ckevt_pxa_osmr0, clock_tick_rate,4 ); ckevt_pxa_osmr0.max_delta_ns =clockevent_delta2ns (0x7fffffff , &ckevt_pxa_osmr0);
@@ -144,7 +130,8 @@ static void __init pxa_timer_init(void)setup_irq (IRQ_OST0 , &pxa_ost0_irq); -clocksource_register_hz (&cksrc_pxa_oscr0, clock_tick_rate); +clocksource_mmio_init (&OSCR ,"oscr0" , clock_tick_rate,200 ,32 , + clocksource_mmio_readl_up);clockevents_register_device (&ckevt_pxa_osmr0); }
arch/arm/mach-sa1100/time.c +2 -14
@@ -97,19 +97,6 @@ static struct clock_event_device ckevt_sa1100_osmr0 = { .set_mode = sa1100_osmr0_set_mode, }; -static cycle_t sa1100_read_oscr (struct clocksource *s) -{ -return OSCR ; -} - -static struct clocksource cksrc_sa1100_oscr = { - .name ="oscr" , - .rating =200 , - .read = sa1100_read_oscr, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -static struct irqaction sa1100_timer_irq = { .name ="ost0" , .flags =IRQF_DISABLED |IRQF_TIMER |IRQF_IRQPOLL ,
@@ -134,7 +121,8 @@ static void __init sa1100_timer_init(void)setup_irq (IRQ_OST0 , &sa1100_timer_irq); -clocksource_register_hz (&cksrc_sa1100_oscr,CLOCK_TICK_RATE ); +clocksource_mmio_init (&OSCR ,"oscr" ,CLOCK_TICK_RATE ,200 ,32 , + clocksource_mmio_readl_up);clockevents_register_device (&ckevt_sa1100_osmr0); }
arch/arm/mach-tcc8k/time.c +2 -14
@@ -25,19 +25,6 @@static void __iomem *timer_base; -static cycle_t tcc_get_cycles (struct clocksource *cs) -{ -return __raw_readl (timer_base +TC32MCNT_OFFS ); -} - -static struct clocksource clocksource_tcc = { - .name ="tcc_tc32" , - .rating =200 , - .read = tcc_get_cycles, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -static int tcc_set_next_event (unsigned long evt,struct clock_event_device *unused) {
@@ -102,7 +89,8 @@ static int __init tcc_clockevent_init(struct clk *clock) {unsigned int c =clk_get_rate (clock); -clocksource_register_hz (&clocksource_tcc, c); +clocksource_mmio_init (timer_base +TC32MCNT_OFFS ,"tcc_tc32" , c, +200 ,32 , clocksource_mmio_readl_up); clockevent_tcc.mult =div_sc (c,NSEC_PER_SEC , clockevent_tcc.shift);
arch/arm/mach-tegra/timer.c +2 -14
@@ -98,11 +98,6 @@ static void tegra_timer_set_mode(enum clock_event_mode mode, } } -static cycle_t tegra_clocksource_read (struct clocksource *cs) -{ -return timer_readl (TIMERUS_CNTR_1US ); -} -static struct clock_event_device tegra_clockevent = { .name ="timer0" , .rating =300 ,
@@ -111,14 +106,6 @@ static struct clock_event_device tegra_clockevent = { .set_mode = tegra_timer_set_mode, }; -static struct clocksource tegra_clocksource = { - .name ="timer_us" , - .rating =300 , - .read = tegra_clocksource_read, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -static DEFINE_CLOCK_DATA (cd);/*
@@ -234,7 +221,8 @@ static void __init tegra_init_timer(void)init_fixed_sched_clock (&cd, tegra_update_sched_clock,32 ,1000000 ,SC_MULT ,SC_SHIFT ); -if (clocksource_register_hz (&tegra_clocksource,1000000 )) { +if (clocksource_mmio_init (timer_reg_base +TIMERUS_CNTR_1US , +"timer_us" ,1000000 ,300 ,32 , clocksource_mmio_readl_up)) {printk (KERN_ERR "Failed to register clocksource\n" );BUG (); }
arch/arm/mach-u300/timer.c +3 -15
@@ -333,20 +333,6 @@ static struct irqaction u300_timer_irq = { .handler = u300_timer_interrupt, }; -/* Use general purpose timer 2 as clock source */ -static cycle_t u300_get_cycles (struct clocksource *cs) -{ -return (cycles_t )readl (U300_TIMER_APP_VBASE +U300_TIMER_APP_GPT2CC ); -} - -static struct clocksource clocksource_u300_1mhz = { - .name ="GPT2" , - .rating =300 ,/* Reasonably fast and accurate clock source */ - .read = u300_get_cycles, - .mask =CLOCKSOURCE_MASK (32 ),/* 32 bits */ - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -/* * Override the global weak sched_clock symbol with this * local implementation which uses the clocksource to get some
@@ -422,7 +408,9 @@ static void __init u300_timer_init(void)writel (U300_TIMER_APP_EGPT2_TIMER_ENABLE ,U300_TIMER_APP_VBASE +U300_TIMER_APP_EGPT2 ); -if (clocksource_register_hz (&clocksource_u300_1mhz, rate)) +/* Use general purpose timer 2 as clock source */ +if (clocksource_mmio_init (U300_TIMER_APP_VBASE +U300_TIMER_APP_GPT2CC , +"GPT2" , rate,300 ,32 , clocksource_mmio_readl_up))printk (KERN_ERR "timer: failed to initialize clock " "source %s\n" , clocksource_u300_1mhz.name);
arch/arm/plat-mxc/time.c +7 -31
@@ -106,56 +106,32 @@ static void gpt_irq_acknowledge(void)__raw_writel (V2_TSTAT_OF1 , timer_base +V2_TSTAT ); } -static cycle_t dummy_get_cycles (struct clocksource *cs) -{ -return 0 ; -} - -static cycle_t mx1_2_get_cycles (struct clocksource *cs) -{ -return __raw_readl (timer_base +MX1_2_TCN ); -} - -static cycle_t v2_get_cycles (struct clocksource *cs) -{ -return __raw_readl (timer_base +V2_TCN ); -} - -static struct clocksource clocksource_mxc = { - .name ="mxc_timer1" , - .rating =200 , - .read = dummy_get_cycles, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; +static void __iomem *sched_clock_reg;static DEFINE_CLOCK_DATA (cd);unsigned long long notrace sched_clock (void ) { -cycle_t cyc = clocksource_mxc.read (&clocksource_mxc); +cycle_t cyc = sched_clock_reg ?__raw_readl (sched_clock_reg) :0 ;return cyc_to_sched_clock (&cd, cyc, (u32 )~0 ); } static void notrace mxc_update_sched_clock(void) { -cycle_t cyc = clocksource_mxc.read (&clocksource_mxc); +cycle_t cyc = sched_clock_reg ?__raw_readl (sched_clock_reg) :0 ;update_sched_clock (&cd, cyc, (u32 )~0 ); }static int __init mxc_clocksource_init (struct clk *timer_clk) {unsigned int c =clk_get_rate (timer_clk); +void __iomem *reg = timer_base + (timer_is_v2 () ?V2_TCN :MX1_2_TCN ); -if (timer_is_v2 ()) - clocksource_mxc.read = v2_get_cycles; -else - clocksource_mxc.read = mx1_2_get_cycles; + sched_clock_reg = reg;init_sched_clock (&cd, mxc_update_sched_clock,32 , c); -clocksource_register_hz (&clocksource_mxc, c); - -return 0 ; +return clocksource_mmio_init (reg,"mxc_timer1" , c,200 ,32 , + clocksource_mmio_readl_up); }/* clock event */
Signature · 1 line
1.7.4.4
PATCH 7/19 clocksource: convert ARM 32-bit up counting clocksources
Quoted 6 lines · Russell King - ARM Linux
Convert ixp4xx, lpc32xx, mxc, netx, pxa, sa1100, tcc8k, tegra and u300 to use the generic mmio clocksource recently introduced.
Cc Imre Kaloz <[email protected]>Cc Krzysztof Halasa <[email protected]>Cc Eric Miao <[email protected]>
Quoted 462 lines
Acked-by "Hans J. Koch" <[email protected]>Acked-by Colin Cross <[email protected]>Cc Erik Gilling <[email protected]>Cc Olof Johansson <[email protected]>Acked-by Linus Walleij <[email protected]>Cc Sascha Hauer <[email protected]>Signed-off-by Russell King <[email protected]>---
?arch/arm/Kconfig ? ? ? ? ? ? ?| ? ?9 +++++++++ ?arch/arm/mach-ixp4xx/common.c | ? 16 ++-------------- ?arch/arm/mach-lpc32xx/timer.c | ? 17 +++-------------- ?arch/arm/mach-netx/time.c ? ? | ? 16 ++-------------- ?arch/arm/mach-pxa/time.c ? ? ?| ? 17 ++--------------- ?arch/arm/mach-sa1100/time.c ? | ? 16 ++-------------- ?arch/arm/mach-tcc8k/time.c ? ?| ? 16 ++-------------- ?arch/arm/mach-tegra/timer.c ? | ? 16 ++-------------- ?arch/arm/mach-u300/timer.c ? ?| ? 18 +++--------------- ?arch/arm/plat-mxc/time.c ? ? ?| ? 38 +++++++-------------------------------?10 files changed, 34 insertions(+), 145 deletions(-)
arch/arm/Kconfig +0
-0@@ -366,6 +366,7 @@ config ARCH_MXC? ? ? ?select
GENERIC_CLOCKEVENTS
? ? ? ?selectARCH_REQUIRE_GPIOLIB
? ? ? ?selectCLKDEV_LOOKUP
+ ? ? ? selectCLKSRC_MMIO
? ? ? ?selectHAVE_SCHED_CLOCK
? ? ? ?help
? ? ? ? ?Support for Freescale MXC/iMX-based family of processorsarch/arm/Kconfig +0
-0@@ -390,6 +391,7 @@ config ARCH_STMP3XXX?config
ARCH_NETX
? ? ? ?bool "Hilscher NetX based"
+ ? ? ? selectCLKSRC_MMIO
? ? ? ?selectCPU_ARM926T
? ? ? ?selectARM_VIC
? ? ? ?selectGENERIC_CLOCKEVENTSarch/arm/Kconfig +0
-0@@ -457,6 +459,7 @@ config ARCH_IXP2000?config
ARCH_IXP4XX
? ? ? ?bool "IXP4xx-based"
? ? ? ?depends on MMU
+ ? ? ? selectCLKSRC_MMIO
? ? ? ?selectCPU_XSCALE
? ? ? ?selectGENERIC_GPIO
? ? ? ?selectGENERIC_CLOCKEVENTSarch/arm/Kconfig +0
-0@@ -497,6 +500,7 @@ config ARCH_LOKI?config
ARCH_LPC32XX
? ? ? ?bool "NXP LPC32XX"
+ ? ? ? selectCLKSRC_MMIO
? ? ? ?selectCPU_ARM926T
? ? ? ?selectARCH_REQUIRE_GPIOLIB
? ? ? ?selectHAVE_IDEarch/arm/Kconfig +0
-0@@ -592,6 +596,7 @@ config ARCH_NUC93X?config
ARCH_TEGRA
? ? ? ?bool "NVIDIA Tegra"
? ? ? ?selectCLKDEV_LOOKUP
+ ? ? ? selectCLKSRC_MMIO
? ? ? ?selectGENERIC_TIME
? ? ? ?selectGENERIC_CLOCKEVENTS
? ? ? ?selectGENERIC_GPIOarch/arm/Kconfig +0
-0@@ -617,6 +622,7 @@ config ARCH_PXA? ? ? ?select
ARCH_MTD_XIP
? ? ? ?selectARCH_HAS_CPUFREQ
? ? ? ?selectCLKDEV_LOOKUP
+ ? ? ? selectCLKSRC_MMIO
? ? ? ?selectARCH_REQUIRE_GPIOLIB
? ? ? ?selectGENERIC_CLOCKEVENTS
? ? ? ?selectHAVE_SCHED_CLOCKarch/arm/Kconfig +0
-0@@ -667,6 +673,7 @@ config ARCH_RPC?config
ARCH_SA1100
? ? ? ?bool "SA1100-based"
+ ? ? ? selectCLKSRC_MMIO
? ? ? ?selectCPU_SA1100
? ? ? ?select ISA
? ? ? ?selectARCH_SPARSEMEM_ENABLEarch/arm/Kconfig +0
-0@@ -803,6 +810,7 @@ config ARCH_SHARK?config
ARCH_TCC_926
? ? ? ?bool "Telechips TCC ARM926-based systems"
+ ? ? ? selectCLKSRC_MMIO
? ? ? ?selectCPU_ARM926T
? ? ? ?selectHAVE_CLK
? ? ? ?selectCLKDEV_LOOKUParch/arm/Kconfig +0
-0@@ -813,6 +821,7 @@ config ARCH_TCC_926?config
ARCH_U300
? ? ? ?bool "ST-Ericsson U300 Series"
? ? ? ?depends on MMU
+ ? ? ? selectCLKSRC_MMIO
? ? ? ?selectCPU_ARM926T
? ? ? ?selectHAVE_SCHED_CLOCK
? ? ? ?selectHAVE_TCMarch/arm/mach-ixp4xx/common.c +0
-0@@ -419,26 +419,14 @@ static void notrace ixp4xx_update_sched_clock(void)?/*
?* clocksource
?*/arch/arm/mach-ixp4xx/common.c +0
-13-static cycle_t ixp4xx_get_cycles (struct clocksource *cs) -{ - ? ? ? return *IXP4XX_OSTS; -} - -static struct clocksource clocksource_ixp4xx = { - ? ? ? .name ? ? ? ? ? = "OSTS", - ? ? ? .rating ? ? ? ? = 200, - ? ? ? .read ? ? ? ? ? = ixp4xx_get_cycles, - ? ? ? .mask ? ? ? ? ? = CLOCKSOURCE_MASK(32), - ? ? ? .flags ? ? ? ? ?= CLOCK_SOURCE_IS_CONTINUOUS, -}; -?unsigned long
ixp4xx_timer_freq=IXP4XX_TIMER_FREQ; ?EXPORT_SYMBOL(ixp4xx_timer_freq);
?static void__initixp4xx_clocksource_init(void)
?{
? ? ? ?init_sched_clock(&cd,ixp4xx_update_sched_clock, 32,ixp4xx_timer_freq);- ? ? ?
clocksource_register_hz(&clocksource_ixp4xx, ixp4xx_timer_freq);
+ ? ? ? clocksource_mmio_init(&IXP4XX_OSTS, "OSTS",ixp4xx_timer_freq, 200, 32,
+ ? ? ? ? ? ? ? ? ? ? ?clocksource_mmio_readl_up);
?}?/*
arch/arm/mach-lpc32xx/timer.c +0
-0@@ -31,19 +31,6 @@?#include <
mach/platform.h>
?#include "common.h"arch/arm/mach-lpc32xx/timer.c +0
-13-static cycle_t lpc32xx_clksrc_read (struct clocksource *cs) -{ - ? ? ? return (cycle_t)__raw_readl(LCP32XX_TIMER_TC(LPC32XX_TIMER1_BASE)); -} - -static struct clocksource lpc32xx_clksrc = { - ? ? ? .name ? = "lpc32xx_clksrc", - ? ? ? .rating = 300, - ? ? ? .read ? = lpc32xx_clksrc_read, - ? ? ? .mask ? = CLOCKSOURCE_MASK(32), - ? ? ? .flags ?= CLOCK_SOURCE_IS_CONTINUOUS, -}; -?static int
lpc32xx_clkevt_next_event(unsigned long delta, ? ? struct clock_event_device *dev)
?{arch/arm/mach-lpc32xx/timer.c +3
-1@@ -170,7 +157,9 @@ static void __init lpc32xx_timer_init(void) ? ? ? ?__raw_writel(0, LCP32XX_TIMER_MCR(LPC32XX_TIMER1_BASE)); ? ? ? ?__raw_writel(LCP32XX_TIMER_CNTR_TCR_EN, ? ? ? ? ? ? ? ?LCP32XX_TIMER_TCR(LPC32XX_TIMER1_BASE)); - ? ? ? clocksource_register_hz(&lpc32xx_clksrc, clkrate); + + ? ? ? clocksource_mmio_init(LCP32XX_TIMER_TC(LPC32XX_TIMER1_BASE), + ? ? ? ? ? ? ? "lpc32xx_clksrc", clkrate, 300, 32, clocksource_mmio_readl_up); ?} ?struct sys_timer lpc32xx_timer = {arch/arm/mach-netx/time.c +0
-13@@ -104,19 +104,6 @@ static struct irqaction netx_timer_irq = { ? ? ? ?.handler ? ? ? ?= netx_timer_interrupt, ?}; -cycle_t netx_get_cycles (struct clocksource *cs) -{ - ? ? ? return readl(NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE)); -} - -static struct clocksource clocksource_netx = { - ? ? ? .name ? ? ? ? ? = "netx_timer", - ? ? ? .rating ? ? ? ? = 200, - ? ? ? .read ? ? ? ? ? = netx_get_cycles, - ? ? ? .mask ? ? ? ? ? = CLOCKSOURCE_MASK(32), - ? ? ? .flags ? ? ? ? ?= CLOCK_SOURCE_IS_CONTINUOUS, -}; -?/*
?* Set up timer interrupt
?*/arch/arm/mach-netx/time.c +2
-1@@ -150,7 +137,8 @@ static void __init netx_timer_init(void) ? ? ? ?writel(NETX_GPIO_COUNTER_CTRL_RUN, ? ? ? ? ? ? ? ? ? ? ? ?NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKSOURCE)); - ? ? ? clocksource_register_hz(&clocksource_netx, CLOCK_TICK_RATE); + ? ? ? clocksource_mmio_init(NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE), + ? ? ? ? ? ? ? "netx_timer", CLOCK_TICK_RATE, 200, 32, clocksource_mmio_readl_up); ? ? ? ?netx_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ? ? ? ? ? ? ? ? ? ? ? ?netx_clockevent.shift);arch/arm/mach-pxa/time.c +0
-14@@ -105,19 +105,6 @@ static struct clock_event_device ckevt_pxa_osmr0 = { ? ? ? ?.set_mode ? ? ? = pxa_osmr0_set_mode, ?}; -static cycle_t pxa_read_oscr (struct clocksource *cs) -{ - ? ? ? return OSCR; -} - -static struct clocksource cksrc_pxa_oscr0 = { - ? ? ? .name ? ? ? ? ? = "oscr0", - ? ? ? .rating ? ? ? ? = 200, - ? ? ? .read ? ? ? ? ? = pxa_read_oscr, - ? ? ? .mask ? ? ? ? ? = CLOCKSOURCE_MASK(32), - ? ? ? .flags ? ? ? ? ?= CLOCK_SOURCE_IS_CONTINUOUS, -}; - ?static struct irqaction pxa_ost0_irq = { ? ? ? ?.name ? ? ? ? ? = "ost0", ? ? ? ?.flags ? ? ? ? ?= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,@@ -134,7 +121,6 @@ static void __init pxa_timer_init(void) ? ? ? ?init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate); - ? ? ? clocksource_calc_mult_shift(&cksrc_pxa_oscr0, clock_tick_rate, 4); ? ? ? ?clockevents_calc_mult_shift(&ckevt_pxa_osmr0, clock_tick_rate, 4);? ? ? ?ckevt_pxa_osmr0.max_delta_ns =
? ? ? ? ? ? ? ?clockevent_delta2ns(0x7fffffff,&ckevt_pxa_osmr0);arch/arm/mach-pxa/time.c +2
-1@@ -144,7 +130,8 @@ static void __init pxa_timer_init(void) ? ? ? ?setup_irq(IRQ_OST0, &pxa_ost0_irq); - ? ? ? clocksource_register_hz(&cksrc_pxa_oscr0, clock_tick_rate); + ? ? ? clocksource_mmio_init(&OSCR, "oscr0", clock_tick_rate, 200, 32, + ? ? ? ? ? ? ? clocksource_mmio_readl_up); ? ? ? ?clockevents_register_device(&ckevt_pxa_osmr0); ?}arch/arm/mach-sa1100/time.c +2
-14@@ -97,19 +97,6 @@ static struct clock_event_device ckevt_sa1100_osmr0 = { ? ? ? ?.set_mode ? ? ? = sa1100_osmr0_set_mode, ?}; -static cycle_t sa1100_read_oscr (struct clocksource *s) -{ - ? ? ? return OSCR; -} - -static struct clocksource cksrc_sa1100_oscr = { - ? ? ? .name ? ? ? ? ? = "oscr", - ? ? ? .rating ? ? ? ? = 200, - ? ? ? .read ? ? ? ? ? = sa1100_read_oscr, - ? ? ? .mask ? ? ? ? ? = CLOCKSOURCE_MASK(32), - ? ? ? .flags ? ? ? ? ?= CLOCK_SOURCE_IS_CONTINUOUS, -}; - ?static struct irqaction sa1100_timer_irq = { ? ? ? ?.name ? ? ? ? ? = "ost0", ? ? ? ?.flags ? ? ? ? ?= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,@@ -134,7 +121,8 @@ static void __init sa1100_timer_init(void) ? ? ? ?setup_irq(IRQ_OST0, &sa1100_timer_irq); - ? ? ? clocksource_register_hz(&cksrc_sa1100_oscr, CLOCK_TICK_RATE); + ? ? ? clocksource_mmio_init(&OSCR, "oscr", CLOCK_TICK_RATE, 200, 32, + ? ? ? ? ? ? ? clocksource_mmio_readl_up); ? ? ? ?clockevents_register_device(&ckevt_sa1100_osmr0); ?}arch/arm/mach-tcc8k/time.c +2
-14@@ -25,19 +25,6 @@ ?static void __iomem *timer_base; -static cycle_t tcc_get_cycles (struct clocksource *cs) -{ - ? ? ? return __raw_readl(timer_base + TC32MCNT_OFFS); -} - -static struct clocksource clocksource_tcc = { - ? ? ? .name ? ? ? ? ? = "tcc_tc32", - ? ? ? .rating ? ? ? ? = 200, - ? ? ? .read ? ? ? ? ? = tcc_get_cycles, - ? ? ? .mask ? ? ? ? ? = CLOCKSOURCE_MASK(32), - ? ? ? .flags ? ? ? ? ?= CLOCK_SOURCE_IS_CONTINUOUS, -}; - ?static int tcc_set_next_event(unsigned long evt, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?struct clock_event_device *unused) ?{@@ -102,7 +89,8 @@ static int __init tcc_clockevent_init(struct clk *clock) ?{ ? ? ? ?unsigned int c = clk_get_rate(clock); - ? ? ? clocksource_register_hz(&clocksource_tcc, c); + ? ? ? clocksource_mmio_init(timer_base + TC32MCNT_OFFS, "tcc_tc32", c, + ? ? ? ? ? ? ? 200, 32, clocksource_mmio_readl_up); ? ? ? ?clockevent_tcc.mult = div_sc(c, NSEC_PER_SEC, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?clockevent_tcc.shift);arch/arm/mach-tegra/timer.c +0
-13@@ -98,11 +98,6 @@ static void tegra_timer_set_mode(enum clock_event_mode mode, ? ? ? ?} ?} -static cycle_t tegra_clocksource_read (struct clocksource *cs) -{ - ? ? ? return timer_readl(TIMERUS_CNTR_1US); -} - ?static struct clock_event_device tegra_clockevent = { ? ? ? ?.name ? ? ? ? ? = "timer0", ? ? ? ?.rating ? ? ? ? = 300,@@ -111,14 +106,6 @@ static struct clock_event_device tegra_clockevent = { ? ? ? ?.set_mode ? ? ? = tegra_timer_set_mode, ?}; -static struct clocksource tegra_clocksource = { - ? ? ? .name ? = "timer_us", - ? ? ? .rating = 300, - ? ? ? .read ? = tegra_clocksource_read, - ? ? ? .mask ? = CLOCKSOURCE_MASK(32), - ? ? ? .flags ?= CLOCK_SOURCE_IS_CONTINUOUS, -}; - ?static DEFINE_CLOCK_DATA(cd);?/*
arch/arm/mach-tegra/timer.c +2
-1@@ -234,7 +221,8 @@ static void __init tegra_init_timer(void) ? ? ? ?init_fixed_sched_clock(&cd, tegra_update_sched_clock, 32, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1000000, SC_MULT, SC_SHIFT); - ? ? ? if (clocksource_register_hz(&tegra_clocksource, 1000000)) { + ? ? ? if (clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US, + ? ? ? ? ? ? ? "timer_us", 1000000, 300, 32, clocksource_mmio_readl_up)) { ? ? ? ? ? ? ? ?printk(KERN_ERR "Failed to register clocksource\n"); ? ? ? ? ? ? ? ?BUG(); ? ? ? ?}arch/arm/mach-u300/timer.c +0
-14@@ -333,20 +333,6 @@ static struct irqaction u300_timer_irq = { ? ? ? ?.handler ? ? ? ?= u300_timer_interrupt, ?}; -/* Use general purpose timer 2 as clock source */ -static cycle_t u300_get_cycles (struct clocksource *cs) -{ - ? ? ? return (cycles_t) readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); -} - -static struct clocksource clocksource_u300_1mhz = { - ? ? ? .name ? ? ? ? ? = "GPT2", - ? ? ? .rating ? ? ? ? = 300, /* Reasonably fast and accurate clock source */ - ? ? ? .read ? ? ? ? ? = u300_get_cycles, - ? ? ? .mask ? ? ? ? ? = CLOCKSOURCE_MASK(32), /* 32 bits */ - ? ? ? .flags ? ? ? ? ?= CLOCK_SOURCE_IS_CONTINUOUS, -}; -?/*
?* Override the global weaksched_clocksymbol with this ?* local implementation which uses the clocksource to get somearch/arm/mach-u300/timer.c +3
-1@@ -422,7 +408,9 @@ static void __init u300_timer_init(void) ? ? ? ?writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE, ? ? ? ? ? ? ? ?U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2); - ? ? ? if (clocksource_register_hz(&clocksource_u300_1mhz, rate)) + ? ? ? /* Use general purpose timer 2 as clock source */ + ? ? ? if (clocksource_mmio_init(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC, + ? ? ? ? ? ? ? ? ? ? ? "GPT2", rate, 300, 32, clocksource_mmio_readl_up))? ? ? ? ? ? ? ?printk(KERN_ERR "timer: failed to initialize clock " ? ? ? ? ? ? ? ? ? ? ? "source %s\n", clocksource_u300_1mhz.name);
arch/arm/plat-mxc/time.c +7
-31@@ -106,56 +106,32 @@ static void gpt_irq_acknowledge(void) ? ? ? ? ? ? ? ?__raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT); ?} -static cycle_t dummy_get_cycles(struct clocksource *cs) -{ - ? ? ? return 0; -} - -static cycle_t mx1_2_get_cycles(struct clocksource *cs) -{ - ? ? ? return __raw_readl(timer_base + MX1_2_TCN); -} - -static cycle_t v2_get_cycles(struct clocksource *cs) -{ - ? ? ? return __raw_readl(timer_base + V2_TCN); -} - -static struct clocksource clocksource_mxc = { - ? ? ? .name ? ? ? ? ? = "mxc_timer1", - ? ? ? .rating ? ? ? ? = 200, - ? ? ? .read ? ? ? ? ? = dummy_get_cycles, - ? ? ? .mask ? ? ? ? ? = CLOCKSOURCE_MASK(32), - ? ? ? .flags ? ? ? ? ?= CLOCK_SOURCE_IS_CONTINUOUS, -}; +static void __iomem *sched_clock_reg; ?static DEFINE_CLOCK_DATA(cd); ?unsigned long long notrace sched_clock(void) ?{ - ? ? ? cycle_t cyc = clocksource_mxc.read(&clocksource_mxc); + ? ? ? cycle_t cyc = sched_clock_reg ? __raw_readl(sched_clock_reg) : 0; ? ? ? ?return cyc_to_sched_clock(&cd, cyc, (u32)~0); ?} ?static void notrace mxc_update_sched_clock(void) ?{ - ? ? ? cycle_t cyc = clocksource_mxc.read(&clocksource_mxc); + ? ? ? cycle_t cyc = sched_clock_reg ? __raw_readl(sched_clock_reg) : 0; ? ? ? ?update_sched_clock(&cd, cyc, (u32)~0); ?} ?static int __init mxc_clocksource_init(struct clk *timer_clk) ?{ ? ? ? ?unsigned int c = clk_get_rate(timer_clk); + ? ? ? void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN); - ? ? ? if (timer_is_v2()) - ? ? ? ? ? ? ? clocksource_mxc.read = v2_get_cycles; - ? ? ? else - ? ? ? ? ? ? ? clocksource_mxc.read = mx1_2_get_cycles; + ? ? ? sched_clock_reg = reg; ? ? ? ?init_sched_clock(&cd, mxc_update_sched_clock, 32, c); - ? ? ? clocksource_register_hz(&clocksource_mxc, c); - - ? ? ? return 0; + ? ? ? return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32, + ? ? ? ? ? ? ? ? ? ? ? clocksource_mmio_readl_up); ?}?/* clock event */
--
1.7.4.4_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Sascha Hauer
maintainerPATCH 7/19 clocksource: convert ARM 32-bit up counting clocksources
In reply to Russell King - ARM LinuxQuoted 13 lines · Russell King - ARM Linux
Convert ixp4xx, lpc32xx, mxc, netx, pxa, sa1100, tcc8k, tegra and u300 to use the generic mmio clocksource recently introduced.
Cc Imre Kaloz <[email protected]>Cc Krzysztof Halasa <[email protected]>Cc Eric Miao <[email protected]>Acked-by "Hans J. Koch" <[email protected]>Acked-by Colin Cross <[email protected]>Cc Erik Gilling <[email protected]>Cc Olof Johansson <[email protected]>Acked-by Linus Walleij <[email protected]>Cc Sascha Hauer <[email protected]>Signed-off-by Russell King <[email protected]>
Quoted 450 lines
--- arch/arm/Kconfig | 9 +++++++++ arch/arm/mach-ixp4xx/common.c | 16 ++-------------- arch/arm/mach-lpc32xx/timer.c | 17 +++-------------- arch/arm/mach-netx/time.c | 16 ++-------------- arch/arm/mach-pxa/time.c | 17 ++--------------- arch/arm/mach-sa1100/time.c | 16 ++-------------- arch/arm/mach-tcc8k/time.c | 16 ++-------------- arch/arm/mach-tegra/timer.c | 16 ++-------------- arch/arm/mach-u300/timer.c | 18 +++--------------- arch/arm/plat-mxc/time.c | 38 +++++++------------------------------- 10 files changed, 34 insertions(+), 145 deletions(-)arch/arm/Kconfig +9
-0@@ -366,6 +366,7 @@ config ARCH_MXC select GENERIC_CLOCKEVENTS select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP + select CLKSRC_MMIO select HAVE_SCHED_CLOCK help Support for Freescale MXC/iMX-based family of processors@@ -390,6 +391,7 @@ config ARCH_STMP3XXX config ARCH_NETX bool "Hilscher NetX based" + select CLKSRC_MMIO select CPU_ARM926T select ARM_VIC select GENERIC_CLOCKEVENTS@@ -457,6 +459,7 @@ config ARCH_IXP2000 config ARCH_IXP4XX bool "IXP4xx-based" depends on MMU + select CLKSRC_MMIO select CPU_XSCALE select GENERIC_GPIO select GENERIC_CLOCKEVENTS@@ -497,6 +500,7 @@ config ARCH_LOKI config ARCH_LPC32XX bool "NXP LPC32XX" + select CLKSRC_MMIO select CPU_ARM926T select ARCH_REQUIRE_GPIOLIB select HAVE_IDE@@ -592,6 +596,7 @@ config ARCH_NUC93X config ARCH_TEGRA bool "NVIDIA Tegra" select CLKDEV_LOOKUP + select CLKSRC_MMIO select GENERIC_TIME select GENERIC_CLOCKEVENTS select GENERIC_GPIO@@ -617,6 +622,7 @@ config ARCH_PXA select ARCH_MTD_XIP select ARCH_HAS_CPUFREQ select CLKDEV_LOOKUP + select CLKSRC_MMIO select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS select HAVE_SCHED_CLOCK@@ -667,6 +673,7 @@ config ARCH_RPC config ARCH_SA1100 bool "SA1100-based" + select CLKSRC_MMIO select CPU_SA1100 select ISA select ARCH_SPARSEMEM_ENABLE@@ -803,6 +810,7 @@ config ARCH_SHARK config ARCH_TCC_926 bool "Telechips TCC ARM926-based systems" + select CLKSRC_MMIO select CPU_ARM926T select HAVE_CLK select CLKDEV_LOOKUP@@ -813,6 +821,7 @@ config ARCH_TCC_926 config ARCH_U300 bool "ST-Ericsson U300 Series" depends on MMU + select CLKSRC_MMIO select CPU_ARM926T select HAVE_SCHED_CLOCK select HAVE_TCMarch/arm/mach-ixp4xx/common.c +2
-14@@ -419,26 +419,14 @@ static void notrace ixp4xx_update_sched_clock(void)/* * clocksource */ -static cycle_t ixp4xx_get_cycles (struct clocksource *cs) -{ -return *IXP4XX_OSTS ; -} - -static struct clocksource clocksource_ixp4xx = { - .name ="OSTS" , - .rating =200 , - .read = ixp4xx_get_cycles, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -unsigned long ixp4xx_timer_freq =IXP4XX_TIMER_FREQ ;EXPORT_SYMBOL (ixp4xx_timer_freq);static void __init ixp4xx_clocksource_init (void ) {init_sched_clock (&cd, ixp4xx_update_sched_clock,32 , ixp4xx_timer_freq); -clocksource_register_hz (&clocksource_ixp4xx, ixp4xx_timer_freq); +clocksource_mmio_init (&IXP4XX_OSTS ,"OSTS" , ixp4xx_timer_freq,200 ,32 , + clocksource_mmio_readl_up); }/* arch/arm/mach-lpc32xx/timer.c +3
-14@@ -31,19 +31,6 @@#include <mach/platform.h> #include "common.h" -static cycle_t lpc32xx_clksrc_read (struct clocksource *cs) -{ -return (cycle_t )__raw_readl (LCP32XX_TIMER_TC (LPC32XX_TIMER1_BASE )); -} - -static struct clocksource lpc32xx_clksrc = { - .name ="lpc32xx_clksrc" , - .rating =300 , - .read = lpc32xx_clksrc_read, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -static int lpc32xx_clkevt_next_event (unsigned long delta,struct clock_event_device *dev) {@@ -170,7 +157,9 @@ static void __init lpc32xx_timer_init(void)__raw_writel (0 ,LCP32XX_TIMER_MCR (LPC32XX_TIMER1_BASE ));__raw_writel (LCP32XX_TIMER_CNTR_TCR_EN ,LCP32XX_TIMER_TCR (LPC32XX_TIMER1_BASE )); -clocksource_register_hz (&lpc32xx_clksrc, clkrate); + +clocksource_mmio_init (LCP32XX_TIMER_TC (LPC32XX_TIMER1_BASE ), +"lpc32xx_clksrc" , clkrate,300 ,32 , clocksource_mmio_readl_up); }struct sys_timer lpc32xx_timer = {arch/arm/mach-netx/time.c +2
-14@@ -104,19 +104,6 @@ static struct irqaction netx_timer_irq = { .handler = netx_timer_interrupt, }; -cycle_t netx_get_cycles (struct clocksource *cs) -{ -return readl (NETX_GPIO_COUNTER_CURRENT (TIMER_CLOCKSOURCE )); -} - -static struct clocksource clocksource_netx = { - .name ="netx_timer" , - .rating =200 , - .read = netx_get_cycles, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -/* * Set up timer interrupt */ @@ -150,7 +137,8 @@ static void __init netx_timer_init(void)writel (NETX_GPIO_COUNTER_CTRL_RUN ,NETX_GPIO_COUNTER_CTRL (TIMER_CLOCKSOURCE )); -clocksource_register_hz (&clocksource_netx,CLOCK_TICK_RATE ); +clocksource_mmio_init (NETX_GPIO_COUNTER_CURRENT (TIMER_CLOCKSOURCE ), +"netx_timer" ,CLOCK_TICK_RATE ,200 ,32 , clocksource_mmio_readl_up); netx_clockevent.mult =div_sc (CLOCK_TICK_RATE ,NSEC_PER_SEC , netx_clockevent.shift);arch/arm/mach-pxa/time.c +2
-15@@ -105,19 +105,6 @@ static struct clock_event_device ckevt_pxa_osmr0 = { .set_mode = pxa_osmr0_set_mode, }; -static cycle_t pxa_read_oscr (struct clocksource *cs) -{ -return OSCR ; -} - -static struct clocksource cksrc_pxa_oscr0 = { - .name ="oscr0" , - .rating =200 , - .read = pxa_read_oscr, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -static struct irqaction pxa_ost0_irq = { .name ="ost0" , .flags =IRQF_DISABLED |IRQF_TIMER |IRQF_IRQPOLL ,@@ -134,7 +121,6 @@ static void __init pxa_timer_init(void)init_sched_clock (&cd, pxa_update_sched_clock,32 , clock_tick_rate); -clocksource_calc_mult_shift (&cksrc_pxa_oscr0, clock_tick_rate,4 );clockevents_calc_mult_shift (&ckevt_pxa_osmr0, clock_tick_rate,4 ); ckevt_pxa_osmr0.max_delta_ns =clockevent_delta2ns (0x7fffffff , &ckevt_pxa_osmr0);@@ -144,7 +130,8 @@ static void __init pxa_timer_init(void)setup_irq (IRQ_OST0 , &pxa_ost0_irq); -clocksource_register_hz (&cksrc_pxa_oscr0, clock_tick_rate); +clocksource_mmio_init (&OSCR ,"oscr0" , clock_tick_rate,200 ,32 , + clocksource_mmio_readl_up);clockevents_register_device (&ckevt_pxa_osmr0); }arch/arm/mach-sa1100/time.c +2
-14@@ -97,19 +97,6 @@ static struct clock_event_device ckevt_sa1100_osmr0 = { .set_mode = sa1100_osmr0_set_mode, }; -static cycle_t sa1100_read_oscr (struct clocksource *s) -{ -return OSCR ; -} - -static struct clocksource cksrc_sa1100_oscr = { - .name ="oscr" , - .rating =200 , - .read = sa1100_read_oscr, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -static struct irqaction sa1100_timer_irq = { .name ="ost0" , .flags =IRQF_DISABLED |IRQF_TIMER |IRQF_IRQPOLL ,@@ -134,7 +121,8 @@ static void __init sa1100_timer_init(void)setup_irq (IRQ_OST0 , &sa1100_timer_irq); -clocksource_register_hz (&cksrc_sa1100_oscr,CLOCK_TICK_RATE ); +clocksource_mmio_init (&OSCR ,"oscr" ,CLOCK_TICK_RATE ,200 ,32 , + clocksource_mmio_readl_up);clockevents_register_device (&ckevt_sa1100_osmr0); }arch/arm/mach-tcc8k/time.c +2
-14@@ -25,19 +25,6 @@static void __iomem *timer_base; -static cycle_t tcc_get_cycles (struct clocksource *cs) -{ -return __raw_readl (timer_base +TC32MCNT_OFFS ); -} - -static struct clocksource clocksource_tcc = { - .name ="tcc_tc32" , - .rating =200 , - .read = tcc_get_cycles, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -static int tcc_set_next_event (unsigned long evt,struct clock_event_device *unused) {@@ -102,7 +89,8 @@ static int __init tcc_clockevent_init(struct clk *clock) {unsigned int c =clk_get_rate (clock); -clocksource_register_hz (&clocksource_tcc, c); +clocksource_mmio_init (timer_base +TC32MCNT_OFFS ,"tcc_tc32" , c, +200 ,32 , clocksource_mmio_readl_up); clockevent_tcc.mult =div_sc (c,NSEC_PER_SEC , clockevent_tcc.shift);arch/arm/mach-tegra/timer.c +2
-14@@ -98,11 +98,6 @@ static void tegra_timer_set_mode(enum clock_event_mode mode, } } -static cycle_t tegra_clocksource_read (struct clocksource *cs) -{ -return timer_readl (TIMERUS_CNTR_1US ); -} -static struct clock_event_device tegra_clockevent = { .name ="timer0" , .rating =300 ,@@ -111,14 +106,6 @@ static struct clock_event_device tegra_clockevent = { .set_mode = tegra_timer_set_mode, }; -static struct clocksource tegra_clocksource = { - .name ="timer_us" , - .rating =300 , - .read = tegra_clocksource_read, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -static DEFINE_CLOCK_DATA (cd);/* @@ -234,7 +221,8 @@ static void __init tegra_init_timer(void)init_fixed_sched_clock (&cd, tegra_update_sched_clock,32 ,1000000 ,SC_MULT ,SC_SHIFT ); -if (clocksource_register_hz (&tegra_clocksource,1000000 )) { +if (clocksource_mmio_init (timer_reg_base +TIMERUS_CNTR_1US , +"timer_us" ,1000000 ,300 ,32 , clocksource_mmio_readl_up)) {printk (KERN_ERR "Failed to register clocksource\n" );BUG (); }arch/arm/mach-u300/timer.c +3
-15@@ -333,20 +333,6 @@ static struct irqaction u300_timer_irq = { .handler = u300_timer_interrupt, }; -/* Use general purpose timer 2 as clock source */ -static cycle_t u300_get_cycles (struct clocksource *cs) -{ -return (cycles_t )readl (U300_TIMER_APP_VBASE +U300_TIMER_APP_GPT2CC ); -} - -static struct clocksource clocksource_u300_1mhz = { - .name ="GPT2" , - .rating =300 ,/* Reasonably fast and accurate clock source */ - .read = u300_get_cycles, - .mask =CLOCKSOURCE_MASK (32 ),/* 32 bits */ - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -/* * Override the global weak sched_clock symbol with this * local implementation which uses the clocksource to get some @@ -422,7 +408,9 @@ static void __init u300_timer_init(void)writel (U300_TIMER_APP_EGPT2_TIMER_ENABLE ,U300_TIMER_APP_VBASE +U300_TIMER_APP_EGPT2 ); -if (clocksource_register_hz (&clocksource_u300_1mhz, rate)) +/* Use general purpose timer 2 as clock source */ +if (clocksource_mmio_init (U300_TIMER_APP_VBASE +U300_TIMER_APP_GPT2CC , +"GPT2" , rate,300 ,32 , clocksource_mmio_readl_up))printk (KERN_ERR "timer: failed to initialize clock " "source %s\n" , clocksource_u300_1mhz.name);arch/arm/plat-mxc/time.c +7
-31@@ -106,56 +106,32 @@ static void gpt_irq_acknowledge(void)__raw_writel (V2_TSTAT_OF1 , timer_base +V2_TSTAT ); } -static cycle_t dummy_get_cycles (struct clocksource *cs) -{ -return 0 ; -} - -static cycle_t mx1_2_get_cycles (struct clocksource *cs) -{ -return __raw_readl (timer_base +MX1_2_TCN ); -} - -static cycle_t v2_get_cycles (struct clocksource *cs) -{ -return __raw_readl (timer_base +V2_TCN ); -} - -static struct clocksource clocksource_mxc = { - .name ="mxc_timer1" , - .rating =200 , - .read = dummy_get_cycles, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; +static void __iomem *sched_clock_reg;static DEFINE_CLOCK_DATA (cd);unsigned long long notrace sched_clock (void ) { -cycle_t cyc = clocksource_mxc.read (&clocksource_mxc); +cycle_t cyc = sched_clock_reg ?__raw_readl (sched_clock_reg) :0 ;return cyc_to_sched_clock (&cd, cyc, (u32 )~0 ); } static void notrace mxc_update_sched_clock(void) { -cycle_t cyc = clocksource_mxc.read (&clocksource_mxc); +cycle_t cyc = sched_clock_reg ?__raw_readl (sched_clock_reg) :0 ;update_sched_clock (&cd, cyc, (u32 )~0 ); }static int __init mxc_clocksource_init (struct clk *timer_clk) {unsigned int c =clk_get_rate (timer_clk); +void __iomem *reg = timer_base + (timer_is_v2 () ?V2_TCN :MX1_2_TCN ); -if (timer_is_v2 ()) - clocksource_mxc.read = v2_get_cycles; -else - clocksource_mxc.read = mx1_2_get_cycles; + sched_clock_reg = reg;init_sched_clock (&cd, mxc_update_sched_clock,32 , c); -clocksource_register_hz (&clocksource_mxc, c); - -return 0 ; +return clocksource_mmio_init (reg,"mxc_timer1" , c,200 ,32 , + clocksource_mmio_readl_up); }/* clock event */ Signature · 1 line
1.7.4.4
Signature · 4 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH v2 8/19 clocksource: convert ARM 32-bit down counting clocksources
In reply to Russell King - ARM LinuxConvert SP804, MXC, Nomadik and Orion 32-bit down-counting clocksources to generic mmio clocksource infrastructure.
--- arch/arm/Kconfig | 2 ++ arch/arm/common/timer-sp.c | 30 ++++++------------------------ arch/arm/plat-mxc/epit.c | 18 ++---------------- arch/arm/plat-nomadik/Kconfig | 1 + arch/arm/plat-nomadik/timer.c | 31 +++---------------------------- arch/arm/plat-orion/time.c | 21 ++------------------- 6 files changed, 16 insertions(+), 87 deletions(-)
arch/arm/Kconfig +2 -0
@@ -1042,6 +1042,7 @@ config PLAT_IOP config PLAT_ORION bool + select CLKSRC_MMIO select HAVE_SCHED_CLOCK config PLAT_PXA
@@ -1052,6 +1053,7 @@ config PLAT_VERSATILE config ARM_TIMER_SP804 bool + select CLKSRC_MMIO source arch/arm/mm/Kconfig
arch/arm/common/timer-sp.c +6 -24
@@ -32,35 +32,17 @@#define TIMER_FREQ_KHZ (1000)#define TIMER_RELOAD (TIMER_FREQ_KHZ * 1000 / HZ) -static void __iomem *clksrc_base; - -static cycle_t sp804_read (struct clocksource *cs) -{ -return ~readl (clksrc_base +TIMER_VALUE ); -} - -static struct clocksource clocksource_sp804 = { - .name ="timer3" , - .rating =200 , - .read = sp804_read, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -void __init sp804_clocksource_init (void __iomem *base) { -struct clocksource *cs = &clocksource_sp804; - - clksrc_base = base; -/* setup timer 0 as free-running clocksource */ -writel (0 , clksrc_base +TIMER_CTRL ); -writel (0xffffffff , clksrc_base +TIMER_LOAD ); -writel (0xffffffff , clksrc_base +TIMER_VALUE ); +writel (0 , base +TIMER_CTRL ); +writel (0xffffffff , base +TIMER_LOAD ); +writel (0xffffffff , base +TIMER_VALUE );writel (TIMER_CTRL_32BIT |TIMER_CTRL_ENABLE |TIMER_CTRL_PERIODIC , - clksrc_base +TIMER_CTRL ); + base +TIMER_CTRL ); -clocksource_register_khz (cs,TIMER_FREQ_KHZ ); +clocksource_mmio_init (base +TIMER_VALUE ,"timer3" , +TIMER_FREQ_KHZ *1000 ,200 ,32 , clocksource_mmio_readl_down); }
arch/arm/plat-mxc/epit.c +2 -16
@@ -83,26 +83,12 @@ static void epit_irq_acknowledge(void)__raw_writel (EPITSR_OCIF , timer_base +EPITSR ); } -static cycle_t epit_read (struct clocksource *cs) -{ -return 0 -__raw_readl (timer_base +EPITCNR ); -} - -static struct clocksource clocksource_epit = { - .name ="epit" , - .rating =200 , - .read = epit_read, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -static int __init epit_clocksource_init (struct clk *timer_clk) {unsigned int c =clk_get_rate (timer_clk); -clocksource_register_hz (&clocksource_epit, c); - -return 0 ; +return clocksource_mmio_init (timer_base +EPITCNR ,"epit" , c,200 ,32 , + clocksource_mmio_readl_down); }/* clock event */
arch/arm/plat-nomadik/Kconfig +1 -0
@@ -5,6 +5,7 @@ config PLAT_NOMADIK bool depends on ARCH_NOMADIK || ARCH_U8500 + select CLKSRC_MMIO default y help Common platform code for Nomadik and other ST-Ericsson
arch/arm/plat-nomadik/timer.c +3 -28
@@ -26,29 +26,6 @@void __iomem *mtu_base;/* Assigned by machine code */ /* -* Kernel assumes that sched_clock can be called early -* but the MTU may not yet be initialized. -*/ -static cycle_t nmdk_read_timer_dummy (struct clocksource *cs) -{ -return 0 ; -} - -/* clocksource: MTU decrements, so we negate the value being read. */ -static cycle_t nmdk_read_timer (struct clocksource *cs) -{ -return -readl (mtu_base +MTU_VAL (0 )); -} - -static struct clocksource nmdk_clksrc = { - .name ="mtu_0" , - .rating =200 , - .read = nmdk_read_timer_dummy, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; - -/* * Override the global weak sched_clock symbol with this * local implementation which uses the clocksource to get some * better resolution when scheduling the kernel.
@@ -172,12 +149,10 @@ void __init nmdk_timer_init(void)writel (0 , mtu_base +MTU_BGLR (0 ));writel (cr | MTU_CRn_ENA, mtu_base +MTU_CR (0 )); -/* Now the clock source is ready */ - nmdk_clksrc.read = nmdk_read_timer; - -if (clocksource_register_hz (&nmdk_clksrc, rate)) +if (clocksource_mmio_init (mtu_base +MTU_VAL (0 ),"mtu_0" , + rate,200 ,32 , clocksource_mmio_readl_down))pr_err ("timer: failed to initialize clock source %s\n" , - nmdk_clksrc.name); +"mtu_0" );init_sched_clock (&cd, nomadik_update_sched_clock,32 , rate);
arch/arm/plat-orion/time.c +2 -19
@@ -81,24 +81,6 @@ static void __init setup_sched_clock(unsigned long tclk) }/* -* Clocksource handling. -*/ -static cycle_t orion_clksrc_read (struct clocksource *cs) -{ -return 0xffffffff -readl (timer_base +TIMER0_VAL_OFF ); -} - -static struct clocksource orion_clksrc = { - .name ="orion_clocksource" , - .rating =300 , - .read = orion_clksrc_read, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; - - - -/* * Clockevent handling. */ static int
@@ -247,7 +229,8 @@ orion_time_init(u32 _bridge_base, u32 _bridge_timer1_clr_mask,writel (u & ~BRIDGE_INT_TIMER0 , bridge_base +BRIDGE_MASK_OFF ); u =readl (timer_base +TIMER_CTRL_OFF );writel (u |TIMER0_EN |TIMER0_RELOAD_EN , timer_base +TIMER_CTRL_OFF ); -clocksource_register_hz (&orion_clksrc, tclk); +clocksource_mmio_init (timer_base +TIMER0_VAL_OFF ,"orion_clocksource" , + tclk,300 ,32 , clocksource_mmio_readl_down);/* * Setup clockevent timer (interrupt-driven).
Signature · 1 line
1.7.4.4
PATCH v2 9/19 clocksource: convert W90x900 24-bit down counting clocksource
In reply to Russell King - ARM LinuxConvert the W90x900 24-bit down-counting clocksource to the generic mmio clocksource infrastructure
--- arch/arm/Kconfig | 1 + arch/arm/mach-w90x900/time.c | 17 ++--------------- 2 files changed, 3 insertions(+), 15 deletions(-)
arch/arm/Kconfig +1 -0
@@ -575,6 +575,7 @@ config ARCH_W90X900 select CPU_ARM926T select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP + select CLKSRC_MMIO select GENERIC_CLOCKEVENTS help Support for Nuvoton (Winbond logic dept.) ARM9 processor,
arch/arm/mach-w90x900/time.c +2 -15
@@ -43,7 +43,6 @@#define PRESCALE 0x63/* Divider = prescale + 1 */ #define TDR_SHIFT 24 -#define TDR_MASK ((1 << TDR_SHIFT) - 1)static unsigned int timer0_load;
@@ -143,19 +142,6 @@ static void __init nuc900_clockevents_init(void)clockevents_register_device (&nuc900_clockevent_device); } -static cycle_t nuc900_get_cycles (struct clocksource *cs) -{ -return (~__raw_readl (REG_TDR1 )) &TDR_MASK ; -} - -static struct clocksource clocksource_nuc900 = { - .name ="nuc900-timer1" , - .rating =200 , - .read = nuc900_get_cycles, - .mask =CLOCKSOURCE_MASK (TDR_SHIFT ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -static void __init nuc900_clocksource_init (void ) {unsigned int val;
@@ -175,7 +161,8 @@ static void __init nuc900_clocksource_init(void) val |= (COUNTEN |PERIOD |PRESCALE );__raw_writel (val,REG_TCSR1 ); -clocksource_register_hz (&clocksource_nuc900, rate); +clocksource_mmio_init (REG_TDR1 ,"nuc900-timer1" , rate,200 , +TDR_SHIFT , clocksource_mmio_readl_down); }static void __init nuc900_timer_init (void )
Signature · 1 line
1.7.4.4
PATCH v2 10/19 clocksource: convert Integrator/AP 16-bit down counting clocksource
In reply to Russell King - ARM LinuxConvert the Integrator/AP 16-bit down-counting clocksource to the generic clocksource infrastructure.
--- arch/arm/mach-integrator/Kconfig | 1 + arch/arm/mach-integrator/integrator_ap.c | 21 +++------------------ 2 files changed, 4 insertions(+), 18 deletions(-)
arch/arm/mach-integrator/Kconfig +1 -0
@@ -4,6 +4,7 @@ menu "Integrator Options" config ARCH_INTEGRATOR_AP bool "Support Integrator/AP and Integrator/PP2 platforms" + select CLKSRC_MMIO select MIGHT_HAVE_PCI help Include support for the ARM(R) Integrator/AP and
arch/arm/mach-integrator/integrator_ap.c +3 -18
@@ -343,25 +343,9 @@ static void __init ap_init(void)static unsigned long timer_reload; -static void __iomem *const clksrc_base = (void __iomem *)TIMER2_VA_BASE ; - -static cycle_t timersp_read (struct clocksource *cs) -{ -return ~(readl (clksrc_base +TIMER_VALUE ) &0xffff ); -} - -static struct clocksource clocksource_timersp = { - .name ="timer2" , - .rating =200 , - .read = timersp_read, - .mask =CLOCKSOURCE_MASK (16 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -static void integrator_clocksource_init (u32 khz) { -struct clocksource *cs = &clocksource_timersp; -void __iomem *base = clksrc_base; +void __iomem *base = (void __iomem *)TIMER2_VA_BASE ;u32 ctrl =TIMER_CTRL_ENABLE ;if (khz >=1500 ) {
@@ -372,7 +356,8 @@ static void integrator_clocksource_init(u32 khz)writel (ctrl, base +TIMER_CTRL );writel (0xffff , base +TIMER_LOAD ); -clocksource_register_khz (cs, khz); +clocksource_mmio_init (base +TIMER_VALUE ,"timer2" , + khz *1000 ,200 ,16 , clocksource_mmio_readl_down); }static void __iomem *const clkevt_base = (void __iomem *)TIMER1_VA_BASE ;
Signature · 1 line
1.7.4.4
PATCH v2 11/19 clocksource: convert SPEAr platforms 16-bit up counting clocksource
In reply to Russell King - ARM LinuxConvert SPEAr platforms 16-bit up counting clocksource, which requires a 16-bit register access read rather than 32-bit.
--- arch/arm/Kconfig | 1 + arch/arm/plat-spear/time.c | 16 ++-------------- 2 files changed, 3 insertions(+), 14 deletions(-)
arch/arm/Kconfig +1 -0
@@ -884,6 +884,7 @@ config PLAT_SPEAR select ARM_AMBA select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP + select CLKSRC_MMIO select GENERIC_CLOCKEVENTS select HAVE_CLK help
arch/arm/plat-spear/time.c +2 -14
@@ -70,19 +70,6 @@ static void clockevent_set_mode(enum clock_event_mode mode,static int clockevent_next_event (unsigned long evt,struct clock_event_device *clk_event_dev); -static cycle_t clocksource_read_cycles (struct clocksource *cs) -{ -return (cycle_t )readw (gpt_base +COUNT (CLKSRC )); -} - -static struct clocksource clksrc = { - .name ="tmr1" , - .rating =200 ,/* its a pretty decent clock */ - .read = clocksource_read_cycles, - .mask =0xFFFF ,/* 16 bits */ - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -static void spear_clocksource_init (void ) {u32 tick_rate;
@@ -103,7 +90,8 @@ static void spear_clocksource_init(void)writew (val, gpt_base +CR (CLKSRC ));/* register the clocksource */ -clocksource_register_hz (&clksrc, tick_rate); +clocksource_mmio_init (gpt_base +COUNT (CLKSRC ),"tmr1" , tick_rate, +200 ,16 , clocksource_mmio_readw_up); }static struct clock_event_device clkevt = {
Signature · 1 line
1.7.4.4
PATCH v2 12/19 clocksource: convert MXS timrotv2 to 32-bit down counting clocksource
In reply to Russell King - ARM LinuxConvert the MXS timrotv2 32-bit down counting clocksource to the generic clocksource infrastructure.
--- arch/arm/Kconfig | 1 + arch/arm/mach-mxs/timer.c | 20 +++++++------------- 2 files changed, 8 insertions(+), 13 deletions(-)
arch/arm/Kconfig +1 -0
@@ -376,6 +376,7 @@ config ARCH_MXS select GENERIC_CLOCKEVENTS select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP + select CLKSRC_MMIO help Support for Freescale MXS-based family of processors
arch/arm/mach-mxs/timer.c +7 -13
@@ -101,11 +101,6 @@ static cycle_t timrotv1_get_cycles(struct clocksource *cs) & 0xffff0000) >> 16); } -static cycle_t timrotv2_get_cycles (struct clocksource *cs) -{ -return ~__raw_readl (mxs_timrot_base +HW_TIMROT_RUNNING_COUNTn (1 )); -} -static int timrotv1_set_next_event (unsigned long evt,struct clock_event_device *dev) {
@@ -230,8 +225,8 @@ static int __init mxs_clockevent_init(struct clk *timer_clk)static struct clocksource clocksource_mxs = { .name ="mxs_timer" , .rating =200 , - .read = timrotv2_get_cycles, - .mask =CLOCKSOURCE_MASK (32 ), + .read = timrotv1_get_cycles, + .mask =CLOCKSOURCE_MASK (16 ), .flags =CLOCK_SOURCE_IS_CONTINUOUS , };
@@ -239,12 +234,11 @@ static int __init mxs_clocksource_init(struct clk *timer_clk) {unsigned int c =clk_get_rate (timer_clk); -if (timrot_is_v1 ()) { - clocksource_mxs.read = timrotv1_get_cycles; - clocksource_mxs.mask =CLOCKSOURCE_MASK (16 ); - } - -clocksource_register_hz (&clocksource_mxs, c); +if (timrot_is_v1 ()) +clocksource_register_hz (&clocksource_mxs, c); +else +clocksource_mmio_init (mxs_timrot_base +HW_TIMROT_RUNNING_COUNTn (1 ), +"mxs_timer" , c,200 ,32 , clocksource_mmio_readl_down);return 0 ; }
Signature · 1 line
1.7.4.4
PATCH v2 13/19 clocksource: convert OMAP1 to 32-bit down counting clocksource
In reply to Russell King - ARM LinuxConvert the OMAP1 32-bit down counting clocksource to the generic clocksource infrastructure.
--- arch/arm/mach-omap1/time.c | 23 ++++++----------------- arch/arm/plat-omap/Kconfig | 1 + 2 files changed, 7 insertions(+), 17 deletions(-)
arch/arm/mach-omap1/time.c +6 -17
@@ -190,24 +190,11 @@ static __init void omap_init_mpu_timer(unsigned long rate)* --------------------------------------------------------------------------- */ -static cycle_t mpu_read (struct clocksource *cs) -{ -return ~omap_mpu_timer_read (1 ); -} - -static struct clocksource clocksource_mpu = { - .name ="mpu_timer2" , - .rating =300 , - .read = mpu_read, - .mask =CLOCKSOURCE_MASK (32 ), - .flags =CLOCK_SOURCE_IS_CONTINUOUS , -}; -static DEFINE_CLOCK_DATA (cd);static inline unsigned long long notrace _omap_mpu_sched_clock (void ) { -u32 cyc =mpu_read (&clocksource_mpu); +u32 cyc = ~omap_mpu_timer_read (1 );return cyc_to_sched_clock (&cd, cyc, (u32 )~0 ); }
@@ -225,20 +212,22 @@ static unsigned long long notrace omap_mpu_sched_clock(void) static void notrace mpu_update_sched_clock(void) { -u32 cyc =mpu_read (&clocksource_mpu); +u32 cyc = ~omap_mpu_timer_read (1 );update_sched_clock (&cd, cyc, (u32 )~0 ); }static void __init omap_init_clocksource (unsigned long rate) { +omap_mpu_timer_regs_t __iomem *timer =omap_mpu_timer_base (1 );static char err[]__initdata =KERN_ERR "%s: can't register clocksource!\n" ;omap_mpu_timer_start (1 , ~0 ,1 );init_sched_clock (&cd, mpu_update_sched_clock,32 , rate); -if (clocksource_register_hz (&clocksource_mpu, rate)) -printk (err, clocksource_mpu.name); +if (clocksource_mmio_init (&timer->read_tim,"mpu_timer2" , rate, +300 ,32 , clocksource_mmio_readl_down)) +printk (err,"mpu_timer2" ); }static void __init omap_mpu_timer_init (void )
arch/arm/plat-omap/Kconfig +1 -0
@@ -12,6 +12,7 @@ choice config ARCH_OMAP1 bool "TI OMAP1" select CLKDEV_LOOKUP + select CLKSRC_MMIO help "Systems based on omap7xx, omap15xx or omap16xx"
Signature · 1 line
1.7.4.4
PATCH v2 14/19 clocksource: ARM sp804: allow clocksource name to be specified
In reply to Russell King - ARM LinuxThis allows platforms to specify the clocksource name upon registration, which is necessary should they wish to register more than one sp804 clocksource.
--- arch/arm/common/timer-sp.c | 4 ++-- arch/arm/include/asm/hardware/timer-sp.h | 2 +- arch/arm/mach-integrator/integrator_cp.c | 2 +- arch/arm/mach-realview/core.c | 2 +- arch/arm/mach-versatile/core.c | 2 +- arch/arm/mach-vexpress/ct-ca9x4.c | 2 +- arch/arm/mach-vexpress/v2m.c | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-)
arch/arm/common/timer-sp.c +2 -2
@@ -32,7 +32,7 @@#define TIMER_FREQ_KHZ (1000)#define TIMER_RELOAD (TIMER_FREQ_KHZ * 1000 / HZ) -void __init sp804_clocksource_init (void __iomem *base) +void __init sp804_clocksource_init (void __iomem *base,const char *name) {/* setup timer 0 as free-running clocksource */ writel (0 , base +TIMER_CTRL );
@@ -41,7 +41,7 @@ void __init sp804_clocksource_init(void __iomem *base)writel (TIMER_CTRL_32BIT |TIMER_CTRL_ENABLE |TIMER_CTRL_PERIODIC , base +TIMER_CTRL ); -clocksource_mmio_init (base +TIMER_VALUE ,"timer3" , +clocksource_mmio_init (base +TIMER_VALUE , name,TIMER_FREQ_KHZ *1000 ,200 ,32 , clocksource_mmio_readl_down); }
arch/arm/include/asm/hardware/timer-sp.h +1 -1
@@ -1,2 +1,2 @@ -void sp804_clocksource_init (void __iomem *); +void sp804_clocksource_init (void __iomem *,const char *);void sp804_clockevents_init (void __iomem *,unsigned int );
arch/arm/mach-integrator/integrator_cp.c +1 -1
@@ -476,7 +476,7 @@ static void __init intcp_timer_init(void)writel (0 ,TIMER1_VA_BASE +TIMER_CTRL );writel (0 ,TIMER2_VA_BASE +TIMER_CTRL ); -sp804_clocksource_init (TIMER2_VA_BASE ); +sp804_clocksource_init (TIMER2_VA_BASE ,"timer2" );sp804_clockevents_init (TIMER1_VA_BASE ,IRQ_TIMERINT1 ); }
arch/arm/mach-realview/core.c +1 -1
@@ -545,7 +545,7 @@ void __init realview_timer_init(unsigned int timer_irq)writel (0 , timer2_va_base +TIMER_CTRL );writel (0 , timer3_va_base +TIMER_CTRL ); -sp804_clocksource_init (timer3_va_base); +sp804_clocksource_init (timer3_va_base,"timer3" );sp804_clockevents_init (timer0_va_base, timer_irq); }
arch/arm/mach-versatile/core.c +1 -1
@@ -764,7 +764,7 @@ static void __init versatile_timer_init(void)writel (0 ,TIMER2_VA_BASE +TIMER_CTRL );writel (0 ,TIMER3_VA_BASE +TIMER_CTRL ); -sp804_clocksource_init (TIMER3_VA_BASE ); +sp804_clocksource_init (TIMER3_VA_BASE ,"timer3" );sp804_clockevents_init (TIMER0_VA_BASE ,IRQ_TIMERINT0_1 ); }
arch/arm/mach-vexpress/ct-ca9x4.c +1 -1
@@ -71,7 +71,7 @@ static void __init ct_ca9x4_timer_init(void)writel (0 ,MMIO_P2V (CT_CA9X4_TIMER0 ) +TIMER_CTRL );writel (0 ,MMIO_P2V (CT_CA9X4_TIMER1 ) +TIMER_CTRL ); -sp804_clocksource_init (MMIO_P2V (CT_CA9X4_TIMER1 )); +sp804_clocksource_init (MMIO_P2V (CT_CA9X4_TIMER1 ),"ct-timer1" );sp804_clockevents_init (MMIO_P2V (CT_CA9X4_TIMER0 ),IRQ_CT_CA9X4_TIMER0 ); }
arch/arm/mach-vexpress/v2m.c +1 -1
@@ -65,7 +65,7 @@ static void __init v2m_timer_init(void)writel (0 ,MMIO_P2V (V2M_TIMER0 ) +TIMER_CTRL );writel (0 ,MMIO_P2V (V2M_TIMER1 ) +TIMER_CTRL ); -sp804_clocksource_init (MMIO_P2V (V2M_TIMER1 )); +sp804_clocksource_init (MMIO_P2V (V2M_TIMER1 ),"v2m-timer1" );sp804_clockevents_init (MMIO_P2V (V2M_TIMER0 ),IRQ_V2M_TIMER0 ); }
Signature · 1 line
1.7.4.4
PATCH v2 15/19 clocksource: ARM sp804: obtain sp804 timer rate via clks
In reply to Russell King - ARM LinuxThis allows platforms to specify the rate of the SP804 clocksource via the clk subsystem. While ARM boards clock these at 1MHz, BCMRing also has SP804 timers but are clocked at different rates.
--- arch/arm/common/timer-sp.c | 39 +++++++++++++++++++++++++++++- arch/arm/mach-integrator/integrator_cp.c | 7 +++++ arch/arm/mach-realview/core.c | 9 ++++++- arch/arm/mach-versatile/core.c | 9 ++++++- arch/arm/mach-vexpress/ct-ca9x4.c | 8 ++++++ arch/arm/mach-vexpress/v2m.c | 8 ++++++ 6 files changed, 77 insertions(+), 3 deletions(-)
arch/arm/common/timer-sp.c +38 -1
@@ -18,8 +18,10 @@* along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <linux/clk.h> #include <linux/clocksource.h> #include <linux/clockchips.h> +#include <linux/err.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/io.h>
@@ -32,8 +34,43 @@#define TIMER_FREQ_KHZ (1000)#define TIMER_RELOAD (TIMER_FREQ_KHZ * 1000 / HZ) +static long __init sp804_get_clock_rate (const char *name) +{ +struct clk *clk; +long rate; +int err; + + clk =clk_get_sys ("sp804" , name); +if (IS_ERR (clk)) { +pr_err ("sp804: %s clock not found: %d\n" , name, + (int )PTR_ERR (clk)); +return PTR_ERR (clk); + } + + err =clk_enable (clk); +if (err) { +pr_err ("sp804: %s clock failed to enable: %d\n" , name, err); +clk_put (clk); +return err; + } + + rate =clk_get_rate (clk); +if (rate <0 ) { +pr_err ("sp804: %s clock failed to get rate: %ld\n" , name, err); +clk_disable (clk); +clk_put (clk); + } + +return rate; +} +void __init sp804_clocksource_init (void __iomem *base,const char *name) { +long rate =sp804_get_clock_rate (name); + +if (rate <0 ) +return ; +/* setup timer 0 as free-running clocksource */ writel (0 , base +TIMER_CTRL );writel (0xffffffff , base +TIMER_LOAD );
@@ -42,7 +79,7 @@ void __init sp804_clocksource_init(void __iomem *base, const char *name) base + TIMER_CTRL);clocksource_mmio_init (base +TIMER_VALUE , name, -TIMER_FREQ_KHZ *1000 ,200 ,32 , clocksource_mmio_readl_down); + rate,200 ,32 , clocksource_mmio_readl_down); }
arch/arm/mach-integrator/integrator_cp.c +7 -0
@@ -229,10 +229,17 @@ static struct clk cp_auxclk = { .vcoreg = CM_AUXOSC, }; +static struct clk sp804_clk = { + .rate =1000000 , +}; +static struct clk_lookup cp_lookups[] = { {/* CLCD */ .dev_id ="mb:c0" , .clk = &cp_auxclk, + }, {/* SP804 timers */ + .dev_id ="sp804" , + .clk = &sp804_clk, }, };
arch/arm/mach-realview/core.c +8 -1
@@ -315,6 +315,10 @@ static struct clk ref24_clk = { .rate = 24000000, }; +static struct clk sp804_clk = { + .rate =1000000 , +}; +static struct clk dummy_apb_pclk;static struct clk_lookup lookups[] = {
@@ -357,7 +361,10 @@ static struct clk_lookup lookups[] = { }, { /* SSP */ .dev_id = "dev:ssp0", .clk = &ref24_clk, - } + }, { /* SP804 timers */ + .dev_id = "sp804", + .clk = &sp804_clk, + }, };void __init realview_init_early (void )
arch/arm/mach-versatile/core.c +8 -1
@@ -375,6 +375,10 @@ static struct clk ref24_clk = { .rate = 24000000, }; +static struct clk sp804_clk = { + .rate =1000000 , +}; +static struct clk dummy_apb_pclk;static struct clk_lookup lookups[] = {
@@ -411,7 +415,10 @@ static struct clk_lookup lookups[] = { }, { /* CLCD */ .dev_id = "dev:20", .clk = &osc4_clk, - } + }, { /* SP804 timers */ + .dev_id = "sp804", + .clk = &sp804_clk, + }, };/*
arch/arm/mach-vexpress/ct-ca9x4.c +8 -0
@@ -141,10 +141,18 @@ static struct clk osc1_clk = { .rate = 24000000, }; +static struct clk ct_sp804_clk = { + .rate =1000000 , +}; +static struct clk_lookup lookups[] = { {/* CLCD */ .dev_id ="ct:clcd" , .clk = &osc1_clk, + }, {/* SP804 timers */ + .dev_id ="sp804" , + .con_id ="ct-timer1" , + .clk = &ct_sp804_clk, }, };
arch/arm/mach-vexpress/v2m.c +8 -0
@@ -333,6 +333,10 @@ static struct clk osc2_clk = { .rate = 24000000, }; +static struct clk v2m_sp804_clk = { + .rate =1000000 , +}; +static struct clk dummy_apb_pclk;static struct clk_lookup v2m_lookups[] = {
@@ -363,6 +367,10 @@ static struct clk_lookup v2m_lookups[] = { }, { /* CLCD */ .dev_id = "mb:clcd", .clk = &osc1_clk, + }, { /* SP804 timers */ + .dev_id = "sp804", + .con_id = "v2m-timer1", + .clk = &v2m_sp804_clk, }, };
Signature · 1 line
1.7.4.4
PATCH 15/19 clocksource: ARM sp804: obtain sp804 timer rate via clks
Quoted 47 lines · Russell King - ARM Linux
This allows platforms to specify the rate of the SP804 clocksource via the clk subsystem. While ARM boards clock these at 1MHz, BCMRing also has SP804 timers but are clocked at different rates.
Acked-by Catalin Marinas<[email protected]>Signed-off-by Russell King<[email protected]>--- arch/arm/common/timer-sp.c | 39 +++++++++++++++++++++++++++++- arch/arm/mach-integrator/integrator_cp.c | 7 +++++ arch/arm/mach-realview/core.c | 9 ++++++- arch/arm/mach-versatile/core.c | 9 ++++++- arch/arm/mach-vexpress/ct-ca9x4.c | 8 ++++++ arch/arm/mach-vexpress/v2m.c | 8 ++++++ 6 files changed, 77 insertions(+), 3 deletions(-)arch/arm/common/timer-sp.c +15
-0@@ -18,8 +18,10 @@* along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <linux/clk.h> #include <linux/clocksource.h> #include <linux/clockchips.h> +#include <linux/err.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/io.h> @@ -32,8 +34,43 @@#define TIMER_FREQ_KHZ (1000)#define TIMER_RELOAD (TIMER_FREQ_KHZ * 1000 / HZ) +static long __init sp804_get_clock_rate (const char *name) +{ +struct clk *clk; +long rate; +int err; + + clk =clk_get_sys ("sp804" , name); +if (IS_ERR (clk)) { +pr_err ("sp804: %s clock not found: %d\n" , name, + (int )PTR_ERR (clk)); +return PTR_ERR (clk); + } +
arch/arm/common/timer-sp.c line 59
Quoted 10 lines
arch/arm/common/timer-sp.c +10
-0+ err =clk_enable (clk); +if (err) { +pr_err ("sp804: %s clock failed to enable: %d\n" , name, err); +clk_put (clk); +return err; + } + + rate =clk_get_rate (clk); +if (rate<0 ) { +pr_err ("sp804: %s clock failed to get rate: %ld\n" , name, err);
err should be rate.
Rob
PATCH v2 15/19 clocksource: ARM sp804: obtain sp804 timer rate via clks
Quoted 6 lines · Rob Herring
arch/arm/common/timer-sp.c line 59
Quoted 3 lines · Russell King - ARM Linux
arch/arm/common/timer-sp.c +3
-0+ rate =clk_get_rate (clk); +if (rate<0 ) { +pr_err ("sp804: %s clock failed to get rate: %ld\n" , name, err);err should be rate.
Yup, already spotted that and fixed.
PATCH v2 16/19 clockevents: ARM sp804: allow clockevent name to be specified
In reply to Russell King - ARM LinuxThis allows platforms to specify the clcokevent name upon registration.
--- arch/arm/common/timer-sp.c | 7 ++++--- arch/arm/include/asm/hardware/timer-sp.h | 2 +- arch/arm/mach-integrator/integrator_cp.c | 2 +- arch/arm/mach-realview/core.c | 2 +- arch/arm/mach-versatile/core.c | 2 +- arch/arm/mach-vexpress/ct-ca9x4.c | 3 ++- arch/arm/mach-vexpress/v2m.c | 3 ++- 7 files changed, 12 insertions(+), 9 deletions(-)
arch/arm/common/timer-sp.c +4 -3
@@ -139,7 +139,6 @@ static int sp804_set_next_event(unsigned long next, }static struct clock_event_device sp804_clockevent = { - .name ="timer0" , .shift =32 , .features =CLOCK_EVT_FEAT_PERIODIC |CLOCK_EVT_FEAT_ONESHOT , .set_mode = sp804_set_mode,
@@ -155,13 +154,15 @@ static struct irqaction sp804_timer_irq = { .dev_id = &sp804_clockevent, }; -void __init sp804_clockevents_init (void __iomem *base,unsigned int timer_irq) +void __init sp804_clockevents_init (void __iomem *base,unsigned int irq, +const char *name) {struct clock_event_device *evt = &sp804_clockevent; clkevt_base = base; - evt->irq = timer_irq; + evt->name = name; + evt->irq = irq; evt->mult =div_sc (TIMER_FREQ_KHZ ,NSEC_PER_MSEC , evt->shift); evt->max_delta_ns =clockevent_delta2ns (0xffffffff , evt); evt->min_delta_ns =clockevent_delta2ns (0xf , evt);
arch/arm/include/asm/hardware/timer-sp.h +1 -1
@@ -1,2 +1,2 @@void sp804_clocksource_init (void __iomem *,const char *); -void sp804_clockevents_init (void __iomem *,unsigned int ); +void sp804_clockevents_init (void __iomem *,unsigned int ,const char *);
arch/arm/mach-integrator/integrator_cp.c +1 -1
@@ -484,7 +484,7 @@ static void __init intcp_timer_init(void)writel (0 ,TIMER2_VA_BASE +TIMER_CTRL );sp804_clocksource_init (TIMER2_VA_BASE ,"timer2" ); -sp804_clockevents_init (TIMER1_VA_BASE ,IRQ_TIMERINT1 ); +sp804_clockevents_init (TIMER1_VA_BASE ,IRQ_TIMERINT1 ,"timer1" ); }static struct sys_timer cp_timer = {
arch/arm/mach-realview/core.c +1 -1
@@ -553,7 +553,7 @@ void __init realview_timer_init(unsigned int timer_irq)writel (0 , timer3_va_base +TIMER_CTRL );sp804_clocksource_init (timer3_va_base,"timer3" ); -sp804_clockevents_init (timer0_va_base, timer_irq); +sp804_clockevents_init (timer0_va_base, timer_irq,"timer0" ); }/*
arch/arm/mach-versatile/core.c +1 -1
@@ -772,7 +772,7 @@ static void __init versatile_timer_init(void)writel (0 ,TIMER3_VA_BASE +TIMER_CTRL );sp804_clocksource_init (TIMER3_VA_BASE ,"timer3" ); -sp804_clockevents_init (TIMER0_VA_BASE ,IRQ_TIMERINT0_1 ); +sp804_clockevents_init (TIMER0_VA_BASE ,IRQ_TIMERINT0_1 ,"timer0" ); }struct sys_timer versatile_timer = {
arch/arm/mach-vexpress/ct-ca9x4.c +2 -1
@@ -72,7 +72,8 @@ static void __init ct_ca9x4_timer_init(void)writel (0 ,MMIO_P2V (CT_CA9X4_TIMER1 ) +TIMER_CTRL );sp804_clocksource_init (MMIO_P2V (CT_CA9X4_TIMER1 ),"ct-timer1" ); -sp804_clockevents_init (MMIO_P2V (CT_CA9X4_TIMER0 ),IRQ_CT_CA9X4_TIMER0 ); +sp804_clockevents_init (MMIO_P2V (CT_CA9X4_TIMER0 ),IRQ_CT_CA9X4_TIMER0 , +"ct-timer0" ); }static struct sys_timer ct_ca9x4_timer = {
arch/arm/mach-vexpress/v2m.c +2 -1
@@ -66,7 +66,8 @@ static void __init v2m_timer_init(void)writel (0 ,MMIO_P2V (V2M_TIMER1 ) +TIMER_CTRL );sp804_clocksource_init (MMIO_P2V (V2M_TIMER1 ),"v2m-timer1" ); -sp804_clockevents_init (MMIO_P2V (V2M_TIMER0 ),IRQ_V2M_TIMER0 ); +sp804_clockevents_init (MMIO_P2V (V2M_TIMER0 ),IRQ_V2M_TIMER0 , +"v2m-timer0" ); }static struct sys_timer v2m_timer = {
Signature · 1 line
1.7.4.4
PATCH 16/19 clockevents: ARM sp804: allow clockevent name to be specified
Quoted 31 lines · Russell King - ARM Linux
This allows platforms to specify the clcokevent name upon registration.
Cc Catalin Marinas<[email protected]>Signed-off-by Russell King<[email protected]>--- arch/arm/common/timer-sp.c | 7 ++++--- arch/arm/include/asm/hardware/timer-sp.h | 2 +- arch/arm/mach-integrator/integrator_cp.c | 2 +- arch/arm/mach-realview/core.c | 2 +- arch/arm/mach-versatile/core.c | 2 +- arch/arm/mach-vexpress/ct-ca9x4.c | 3 ++- arch/arm/mach-vexpress/v2m.c | 3 ++- 7 files changed, 12 insertions(+), 9 deletions(-)arch/arm/common/timer-sp.c +0
-2@@ -139,7 +139,6 @@ static int sp804_set_next_event(unsigned long next, }static struct clock_event_device sp804_clockevent = { - .name ="timer0" , .shift =32 , .features =CLOCK_EVT_FEAT_PERIODIC |CLOCK_EVT_FEAT_ONESHOT , .set_mode = sp804_set_mode,@@ -155,13 +154,15 @@ static struct irqaction sp804_timer_irq = { .dev_id =&sp804_clockevent, }; -void __init sp804_clockevents_init (void __iomem *base,unsigned int timer_irq)
arch/arm/common/timer-sp.c static struct irqaction sp804_timer_irq = { · line 165
Quoted 10 lines
arch/arm/common/timer-sp.c +4
-1+void __init sp804_clockevents_init (void __iomem *base,unsigned int irq, +const char *name) {struct clock_event_device *evt =&sp804_clockevent; clkevt_base = base; - evt->irq = timer_irq; + evt->name = name; + evt->irq = irq;
Also need to change timer_irq to irq in setup_irq farther down in this function.
Rob
PATCH v2 16/19 clockevents: ARM sp804: allow clockevent name to be specified
Quoted 37 lines · Rob Herring
Quoted 36 lines · Russell King - ARM Linux
This allows platforms to specify the clcokevent name upon registration.
Cc Catalin Marinas<[email protected]>Signed-off-by Russell King<[email protected]>--- arch/arm/common/timer-sp.c | 7 ++++--- arch/arm/include/asm/hardware/timer-sp.h | 2 +- arch/arm/mach-integrator/integrator_cp.c | 2 +- arch/arm/mach-realview/core.c | 2 +- arch/arm/mach-versatile/core.c | 2 +- arch/arm/mach-vexpress/ct-ca9x4.c | 3 ++- arch/arm/mach-vexpress/v2m.c | 3 ++- 7 files changed, 12 insertions(+), 9 deletions(-)arch/arm/common/timer-sp.c +2
-2@@ -139,7 +139,6 @@ static int sp804_set_next_event(unsigned long next, }static struct clock_event_device sp804_clockevent = { - .name ="timer0" , .shift =32 , .features =CLOCK_EVT_FEAT_PERIODIC |CLOCK_EVT_FEAT_ONESHOT , .set_mode = sp804_set_mode,@@ -155,13 +154,15 @@ static struct irqaction sp804_timer_irq = { .dev_id =&sp804_clockevent, }; -void __init sp804_clockevents_init (void __iomem *base,unsigned int timer_irq) +void __init sp804_clockevents_init (void __iomem *base,unsigned int irq, +const char *name) {struct clock_event_device *evt =&sp804_clockevent;
Quoted 8 lines
arch/arm/common/timer-sp.c static struct irqaction sp804_timer_irq = { · line 165
Quoted 5 lines
arch/arm/common/timer-sp.c +2
-1clkevt_base = base; - evt->irq = timer_irq; + evt->name = name; + evt->irq = irq;Also need to change
timer_irqto irq insetup_irqfarther down in this function.
Grr.
PATCH 16/19 clockevents: ARM sp804: allow clockevent name to be specified
In reply to Russell King - ARM LinuxQuoted 5 lines · Russell King - ARM Linux
This allows platforms to specify the clcokevent name upon registration.
Cc Catalin Marinas <[email protected]>Signed-off-by Russell King <[email protected]>
In case you haven't pushed these yet, after Rob's comments:
PATCH v2 17/19 clockevents: ARM sp804: obtain sp804 timer rate via clks
In reply to Russell King - ARM LinuxThis allows platforms to specify the rate of the SP804 clockevent via the clk subsystem. While ARM boards clock these at 1MHz, BCMRing also has SP804 timers but are clocked at different rates.
--- arch/arm/common/timer-sp.c | 16 ++++++++-------- arch/arm/mach-vexpress/ct-ca9x4.c | 4 ++++ arch/arm/mach-vexpress/v2m.c | 4 ++++ 3 files changed, 16 insertions(+), 8 deletions(-)
arch/arm/common/timer-sp.c +8 -8
@@ -28,12 +28,6 @@#include <asm/hardware/arm_timer.h> -/* -* These timers are currently always setup to be clocked at 1MHz. -*/ -#define TIMER_FREQ_KHZ (1000) -#define TIMER_RELOAD (TIMER_FREQ_KHZ * 1000 / HZ) -static long __init sp804_get_clock_rate (const char *name) {struct clk *clk;
@@ -84,6 +78,7 @@ void __init sp804_clocksource_init(void __iomem *base, const char *name)static void __iomem *clkevt_base; +static unsigned long clkevt_reload;/* * IRQ handler for the timer
@@ -109,7 +104,7 @@ static void sp804_set_mode(enum clock_event_mode mode,switch (mode) {case CLOCK_EVT_MODE_PERIODIC : -writel (TIMER_RELOAD , clkevt_base +TIMER_LOAD ); +writel (clkevt_reload, clkevt_base +TIMER_LOAD ); ctrl |=TIMER_CTRL_PERIODIC |TIMER_CTRL_ENABLE ;break ;
@@ -158,12 +153,17 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq, const char *name) {struct clock_event_device *evt = &sp804_clockevent; +long rate =sp804_get_clock_rate (name); + +if (rate <0 ) +return ; clkevt_base = base; + clkevt_reload =DIV_ROUND_CLOSEST (rate,HZ ); evt->name = name; evt->irq = irq; - evt->mult =div_sc (TIMER_FREQ_KHZ ,NSEC_PER_MSEC , evt->shift); + evt->mult =div_sc (rate,SEC_PER_MSEC , evt->shift); evt->max_delta_ns =clockevent_delta2ns (0xffffffff , evt); evt->min_delta_ns =clockevent_delta2ns (0xf , evt);
arch/arm/mach-vexpress/ct-ca9x4.c +4 -0
@@ -152,6 +152,10 @@ static struct clk_lookup lookups[] = { .clk = &osc1_clk, }, { /* SP804 timers */ .dev_id = "sp804", + .con_id = "ct-timer0", + .clk = &ct_sp804_clk, + }, { /* SP804 timers */ + .dev_id = "sp804", .con_id = "ct-timer1", .clk = &ct_sp804_clk, },
arch/arm/mach-vexpress/v2m.c +4 -0
@@ -370,6 +370,10 @@ static struct clk_lookup v2m_lookups[] = { .clk = &osc1_clk, }, { /* SP804 timers */ .dev_id = "sp804", + .con_id = "v2m-timer0", + .clk = &v2m_sp804_clk, + }, { /* SP804 timers */ + .dev_id = "sp804", .con_id = "v2m-timer1", .clk = &v2m_sp804_clk, },
Signature · 1 line
1.7.4.4
PATCH 17/19 clockevents: ARM sp804: obtain sp804 timer rate via clks
Quoted 52 lines · Russell King - ARM Linux
This allows platforms to specify the rate of the SP804 clockevent via the clk subsystem. While ARM boards clock these at 1MHz, BCMRing also has SP804 timers but are clocked at different rates.
Cc Catalin Marinas<[email protected]>Signed-off-by Russell King<[email protected]>--- arch/arm/common/timer-sp.c | 16 ++++++++-------- arch/arm/mach-vexpress/ct-ca9x4.c | 4 ++++ arch/arm/mach-vexpress/v2m.c | 4 ++++ 3 files changed, 16 insertions(+), 8 deletions(-)arch/arm/common/timer-sp.c +4
-7@@ -28,12 +28,6 @@#include <asm/hardware/arm_timer.h> -/* -* These timers are currently always setup to be clocked at 1MHz. -*/ -#define TIMER_FREQ_KHZ (1000) -#define TIMER_RELOAD (TIMER_FREQ_KHZ * 1000 / HZ) -static long __init sp804_get_clock_rate (const char *name) {struct clk *clk;@@ -84,6 +78,7 @@ void __init sp804_clocksource_init(void __iomem *base, const char *name)static void __iomem *clkevt_base; +static unsigned long clkevt_reload;/* * IRQ handler for the timer @@ -109,7 +104,7 @@ static void sp804_set_mode(enum clock_event_mode mode,switch (mode) {case CLOCK_EVT_MODE_PERIODIC : -writel (TIMER_RELOAD , clkevt_base +TIMER_LOAD ); +writel (clkevt_reload, clkevt_base +TIMER_LOAD ); ctrl |=TIMER_CTRL_PERIODIC |TIMER_CTRL_ENABLE ;break ;@@ -158,12 +153,17 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq, const char *name) {struct clock_event_device *evt =&sp804_clockevent; +long rate =sp804_get_clock_rate (name); +
arch/arm/common/timer-sp.c void __init sp804_clockevents_init(void __iomem *base, unsigned int irq, · line 166
Quoted 10 lines
arch/arm/common/timer-sp.c +4
-1+if (rate<0 ) +return ; clkevt_base = base; + clkevt_reload =DIV_ROUND_CLOSEST (rate,HZ ); evt->name = name; evt->irq = irq; - evt->mult =div_sc (TIMER_FREQ_KHZ ,NSEC_PER_MSEC , evt->shift); + evt->mult =div_sc (rate,SEC_PER_MSEC , evt->shift);
This doesn't compile or make sense. Should be NSEC_PER_SEC.
Rob
PATCH v2 17/19 clockevents: ARM sp804: obtain sp804 timer rate via clks
Quoted 5 lines · Rob Herring
arch/arm/common/timer-sp.c void __init sp804_clockevents_init(void __iomem *base, unsigned int irq, · line 166
Quoted 2 lines · Russell King - ARM Linux
arch/arm/common/timer-sp.c +1
-1- evt->mult =div_sc (TIMER_FREQ_KHZ ,NSEC_PER_MSEC , evt->shift); + evt->mult =div_sc (rate,SEC_PER_MSEC , evt->shift);This doesn't compile or make sense. Should be
NSEC_PER_SEC.
Grr. Fixed too. No idea how that crap happened, but thanks for catching it all.
PATCH 17/19 clockevents: ARM sp804: obtain sp804 timer rate via clks
In reply to Russell King - ARM LinuxQuoted 6 lines · Russell King - ARM Linux
This allows platforms to specify the rate of the SP804 clockevent via the clk subsystem. While ARM boards clock these at 1MHz, BCMRing also has SP804 timers but are clocked at different rates.
Cc Catalin Marinas <[email protected]>Signed-off-by Russell King <[email protected]>
After you fixed Rob's comments:
PATCH v2 18/19 ARM: bcmring: convert to sp804 clocksource
In reply to Russell King - ARM Linuxbcmring has a set of four sp804 timers incorporated, yet it has its own copy of the sp804 code. Convert its clocksource implementation to the standard sp804 support code.
--- arch/arm/Kconfig | 1 + arch/arm/mach-bcmring/core.c | 108 +++++++++++++++++------------------------- 2 files changed, 45 insertions(+), 64 deletions(-)
arch/arm/Kconfig +1 -0
@@ -297,6 +297,7 @@ config ARCH_BCMRING depends on MMU select CPU_V6 select ARM_AMBA + select ARM_TIMER_SP804 select CLKDEV_LOOKUP select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB
arch/arm/mach-bcmring/core.c +44 -64
150 lines not on this page · raw message
Signature · 1 line
1.7.4.4
PATCH v2 19/19 ARM: bcmring: convert to use sp804 clockevents
In reply to Russell King - ARM Linuxbcmring has a set of four sp804 timers incorporated, yet it has its own copy of the sp804 code. Convert its clockevent implementation to the standard sp804 support code.
--- arch/arm/mach-bcmring/core.c | 118 +++--------------------------------------- 1 files changed, 8 insertions(+), 110 deletions(-)
arch/arm/mach-bcmring/core.c +8 -110
@@ -28,8 +28,6 @@#include <linux/sysdev.h> #include <linux/interrupt.h> #include <linux/amba/bus.h> -#include <linux/clocksource.h> -#include <linux/clockchips.h> #include <linux/clkdev.h> #include <mach/csp/mm_addr.h>
@@ -113,8 +111,8 @@ static struct clk dummy_apb_pclk = {#define TIMER3_FREQUENCY_KHZ (tmrHw_HIGH_FREQUENCY_HZ / 1000)#endif -static struct clk sp804_timer1_clk = { - .name ="sp804-timer-1" , +static struct clk sp804_timer012_clk = { + .name ="sp804-timer-0,1,2" , .type =CLK_TYPE_PRIMARY , .mode =CLK_MODE_XTAL , .rate_hz =TIMER1_FREQUENCY_MHZ *1000000 ,
@@ -137,10 +135,14 @@ static struct clk_lookup lookups[] = { }, { /* UART1 */ .dev_id = "uartb", .clk = &uart_clk, + }, { /* SP804 timer 0 */ + .dev_id = "sp804", + .con_id = "timer0", + .clk = &sp804_timer012_clk, }, { /* SP804 timer 1 */ .dev_id = "sp804", .con_id = "timer1", - .clk = &sp804_timer1_clk, + .clk = &sp804_timer012_clk, }, { /* SP804 timer 3 */ .dev_id = "sp804", .con_id = "timer3",
@@ -205,100 +207,6 @@ void __init bcmring_amba_init(void)#define TIMER2_VA_BASE ((void __iomem *)(MM_IO_BASE_TMR + 0x40))#define TIMER3_VA_BASE ((void __iomem *)(MM_IO_BASE_TMR + 0x60)) -#define TICKS_PER_uSEC TIMER0_FREQUENCY_MHZ - -/* -* These are useconds NOT ticks. -* -*/ -#define mSEC_1 1000 -#define mSEC_10 (mSEC_1 * 10) - -/* -* How long is the timer interval? -*/ -#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) -#if TIMER_INTERVAL >=0x100000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 8) -#define TIMER_DIVISOR (TIMER_CTRL_DIV256) -#define TICKS2USECS (x) (256 * (x) / TICKS_PER_uSEC) -#elif TIMER_INTERVAL >=0x10000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 4)/* Divide by 16 */ -#define TIMER_DIVISOR (TIMER_CTRL_DIV16) -#define TICKS2USECS (x) (16 * (x) / TICKS_PER_uSEC) -#else -#define TIMER_RELOAD (TIMER_INTERVAL) -#define TIMER_DIVISOR (TIMER_CTRL_DIV1) -#define TICKS2USECS (x) ((x) / TICKS_PER_uSEC) -#endif - -static void timer_set_mode (enum clock_event_mode mode, -struct clock_event_device *clk) -{ -unsigned long ctrl; - -switch (mode) { -case CLOCK_EVT_MODE_PERIODIC : -writel (TIMER_RELOAD ,TIMER0_VA_BASE +TIMER_LOAD ); - - ctrl =TIMER_CTRL_PERIODIC ; - ctrl |= -TIMER_DIVISOR |TIMER_CTRL_32BIT |TIMER_CTRL_IE | -TIMER_CTRL_ENABLE ; -break ; -case CLOCK_EVT_MODE_ONESHOT : -/* period set, and timer enabled in 'next_event' hook */ - ctrl =TIMER_CTRL_ONESHOT ; - ctrl |=TIMER_DIVISOR |TIMER_CTRL_32BIT |TIMER_CTRL_IE ; -break ; -case CLOCK_EVT_MODE_UNUSED : -case CLOCK_EVT_MODE_SHUTDOWN : -default : - ctrl =0 ; - } - -writel (ctrl,TIMER0_VA_BASE +TIMER_CTRL ); -} - -static int timer_set_next_event (unsigned long evt, -struct clock_event_device *unused) -{ -unsigned long ctrl =readl (TIMER0_VA_BASE +TIMER_CTRL ); - -writel (evt,TIMER0_VA_BASE +TIMER_LOAD ); -writel (ctrl |TIMER_CTRL_ENABLE ,TIMER0_VA_BASE +TIMER_CTRL ); - -return 0 ; -} - -static struct clock_event_device timer0_clockevent = { - .name ="timer0" , - .shift =32 , - .features =CLOCK_EVT_FEAT_PERIODIC |CLOCK_EVT_FEAT_ONESHOT , - .set_mode = timer_set_mode, - .set_next_event = timer_set_next_event, -}; - -/* -* IRQ handler for the timer -*/ -static irqreturn_t bcmring_timer_interrupt (int irq,void *dev_id) -{ -struct clock_event_device *evt = &timer0_clockevent; - -writel (1 ,TIMER0_VA_BASE +TIMER_INTCLR ); - - evt->event_handler (evt); - -return IRQ_HANDLED ; -} - -static struct irqaction bcmring_timer_irq = { - .name ="bcmring Timer Tick" , - .flags =IRQF_DISABLED |IRQF_TIMER |IRQF_IRQPOLL , - .handler = bcmring_timer_interrupt, -}; -static int __init bcmring_clocksource_init (void ) {/* setup timer1 as free-running clocksource */
@@ -327,19 +235,9 @@ void __init bcmring_init_timer(void)/* * Make irqs happen for the system timer */ -setup_irq (IRQ_TIMER0 , &bcmring_timer_irq); -bcmring_clocksource_init (); - timer0_clockevent.mult = -div_sc (1000000 ,NSEC_PER_SEC , timer0_clockevent.shift); - timer0_clockevent.max_delta_ns = -clockevent_delta2ns (0xffffffff , &timer0_clockevent); - timer0_clockevent.min_delta_ns = -clockevent_delta2ns (0xf , &timer0_clockevent); - - timer0_clockevent.cpumask =cpumask_of (0 ); -clockevents_register_device (&timer0_clockevent); +sp804_clockevents_register (TIMER0_VA_BASE ,IRQ_TIMER0 ,"timer0" ); }struct sys_timer bcmring_timer = {
Signature · 1 line
1.7.4.4
PATCH 1/1 ARM: bcmring: fix patches to convert to sp804 clockevents
Fix build and boot problem with original patches to convert bcmring to use sp804 clockevents.
--- arch/arm/mach-bcmring/core.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
arch/arm/mach-bcmring/core.c +3 -3
@@ -191,8 +191,6 @@ void __init bcmring_amba_init(void)chipcHw_busInterfaceClockEnable (bus_clock); -clkdev_add_table (lookups,ARRAY_SIZE (lookups)); -for (i =0 ; i <ARRAY_SIZE (amba_devs); i++) {struct amba_device *d = amba_devs[i];amba_device_register (d, &iomem_resource);
@@ -232,12 +230,14 @@ void __init bcmring_init_timer(void)writel (0 ,TIMER2_VA_BASE +TIMER_CTRL );writel (0 ,TIMER3_VA_BASE +TIMER_CTRL ); +clkdev_add_table (lookups,ARRAY_SIZE (lookups)); +/* * Make irqs happen for the system timer */ bcmring_clocksource_init (); -sp804_clockevents_register (TIMER0_VA_BASE ,IRQ_TIMER0 ,"timer0" ); +sp804_clockevents_init (TIMER0_VA_BASE ,IRQ_TIMER0 ,"timer0" ); }struct sys_timer bcmring_timer = {
Signature · 1 line
1.7.4.1
PATCH 1/1 ARM: bcmring: fix patches to convert to sp804 clockevents
arch/arm/mach-bcmring/core.c void __init bcmring_init_timer(void) · line 234
Quoted 6 lines · Jiandong Zheng
arch/arm/mach-bcmring/core.c +2
-0@@ -232,12 +230,14 @@ void __init bcmring_init_timer(void)writel (0 ,TIMER2_VA_BASE +TIMER_CTRL );writel (0 ,TIMER3_VA_BASE +TIMER_CTRL ); +clkdev_add_table (lookups,ARRAY_SIZE (lookups)); +
As we have the init_early callback in the machine record, can this be done at that point, rather than sticking it in the timer init callback?
PATCH 1/1 ARM: bcmring: fix patches to convert to sp804 clockevents
Quoted 11 lines · Russell King - ARM Linux
arch/arm/mach-bcmring/core.c void __init bcmring_init_timer(void) · line 234
Quoted 6 lines · Jiandong Zheng
arch/arm/mach-bcmring/core.c +2
-0@@ -232,12 +230,14 @@ void __init bcmring_init_timer(void)writel (0 ,TIMER2_VA_BASE +TIMER_CTRL );writel (0 ,TIMER3_VA_BASE +TIMER_CTRL ); +clkdev_add_table (lookups,ARRAY_SIZE (lookups)); +As we have the
init_earlycallback in the machine record, can this be done at that point, rather than sticking it in the timer init callback?
It should be OK as long as the table is added early enough but leave it here make it a little easier to understand the init order.
clkdev_add_table() was called by init_machine() which is too late while some other machines still do similar thing. Should we move clkdev_add_table() to init_early for all SoC using sp804?
PATCH 1/1 ARM: bcmring: fix patches to convert to sp804 clockevents
Quoted 12 lines · Jiandong Zheng
Quoted 11 lines · Russell King - ARM Linux
arch/arm/mach-bcmring/core.c void __init bcmring_init_timer(void) · line 234
Quoted 6 lines · Jiandong Zheng
arch/arm/mach-bcmring/core.c +2
-0@@ -232,12 +230,14 @@ void __init bcmring_init_timer(void)writel (0 ,TIMER2_VA_BASE +TIMER_CTRL );writel (0 ,TIMER3_VA_BASE +TIMER_CTRL ); +clkdev_add_table (lookups,ARRAY_SIZE (lookups)); +As we have the
init_earlycallback in the machine record, can this be done at that point, rather than sticking it in the timer init callback?
Quoted 6 lines
It should be OK as long as the table is added early enough but leave it here make it a little easier to understand the init order.
clkdev_add_table()was called byinit_machine()which is too late while some other machines still do similar thing. Should we moveclkdev_add_table()toinit_earlyfor all SoC using sp804?
Yes please. The order in which things are called is as the struct is layed out:
fixup
reservemap_ioinit_earlyinit_irqtimer->initinit_machine
PATCH 1/1 ARM: bcmring: Add clkdev table in init_early
ARM: bcmring: Move adding clkdev to init_early to make sure clkevent based on sp804 is initialized properly.
--- arch/arm/mach-bcmring/arch.c | 1 + arch/arm/mach-bcmring/core.c | 7 +++++-- arch/arm/mach-bcmring/core.h | 1 + 3 files changed, 7 insertions(+), 2 deletions(-)
arch/arm/mach-bcmring/arch.c +1 -0
@@ -169,6 +169,7 @@ MACHINE_START(BCMRING, "BCMRING")/* Maintainer: Broadcom Corporation */ .fixup = bcmring_fixup, .map_io = bcmring_map_io, + .init_early = bcmring_init_early, .init_irq = bcmring_init_irq, .timer = &bcmring_timer, .init_machine = bcmring_init_machine
arch/arm/mach-bcmring/core.c +5 -2
@@ -230,8 +230,6 @@ void __init bcmring_init_timer(void)writel (0 ,TIMER2_VA_BASE +TIMER_CTRL );writel (0 ,TIMER3_VA_BASE +TIMER_CTRL ); -clkdev_add_table (lookups,ARRAY_SIZE (lookups)); -/* * Make irqs happen for the system timer */
@@ -243,3 +241,8 @@ void __init bcmring_init_timer(void)struct sys_timer bcmring_timer = { .init = bcmring_init_timer, }; + +void __init bcmring_init_early (void ) +{ +clkdev_add_table (lookups,ARRAY_SIZE (lookups)); +}
arch/arm/mach-bcmring/core.h +1 -0
@@ -25,6 +25,7 @@void __init bcmring_amba_init (void );void __init bcmring_map_io (void );void __init bcmring_init_irq (void ); +void __init bcmring_init_early (void );extern struct sys_timer bcmring_timer;#endif
Signature · 1 line
1.7.4.1
PATCH 1/1 ARM: bcmring: Add clkdev table in init_early
Quoted 2 lines · Jiandong Zheng
ARM: bcmring: Move adding clkdev to
init_earlyto make sure clkevent based on sp804 is initialized properly.
Great, can you submit this to the patch system please? Thanks.
PATCH 1/1 ARM: bcmring: Add clkdev table in init_early
Quoted 5 lines · Russell King - ARM Linux
Quoted 2 lines · Jiandong Zheng
ARM: bcmring: Move adding clkdev to
init_earlyto make sure clkevent based on sp804 is initialized properly.Great, can you submit this to the patch system please? Thanks.
Erm, actually this patch is against your previous patch (as is the one which you submitted to the patch system) so it won't apply as-is. It needs to be one which wil apply directly to mainline in this case please.
PATCH 1/1 ARM: bcmring: Add clkdev table in init_early
Quoted 11 lines · Russell King - ARM Linux
Quoted 5 lines · Russell King - ARM Linux
Quoted 2 lines · Jiandong Zheng
ARM: bcmring: Move adding clkdev to
init_earlyto make sure clkevent based on sp804 is initialized properly.Great, can you submit this to the patch system please? Thanks.
Erm, actually this patch is against your previous patch (as is the one which you submitted to the patch system) so it won't apply as-is. It needs to be one which wil apply directly to mainline in this case please.
Hi Russell,
And my previous patch is based on your set of patches to do common sp804 clock source. How should I submit mine?
Since I haven't had much experience with submitting patch so far, please allow me to ask a question which may be asked many times: when should I use patch system?
For example, I sent a couple of unrelated patches last week and seems no one has problem with them since I don't see comments regarding them. Should I submit them again through patch system or they will picked up "automatically"?
Thanks,
JD
PATCH 1/1 ARM: bcmring: Add clkdev table in init_early
Quoted 8 lines · Jiandong Zheng
Quoted 7 lines · Russell King - ARM Linux
Quoted 5 lines · Russell King - ARM Linux
Quoted 2 lines · Jiandong Zheng
ARM: bcmring: Move adding clkdev to
init_earlyto make sure clkevent based on sp804 is initialized properly.Great, can you submit this to the patch system please? Thanks.
Quoted 8 lines
Quoted 4 lines
Erm, actually this patch is against your previous patch (as is the one which you submitted to the patch system) so it won't apply as-is. It needs to be one which wil apply directly to mainline in this case please.
Hi Russell,
And my previous patch is based on your set of patches to do common sp804 clock source. How should I submit mine?
Can you provide a patch against mainline which moves the clkdev initialization to the init_early callback - and I'll then deal with fixing up my patches for that by placing it before my two bcmring patches.
Quoted 3 lines
Since I haven't had much experience with submitting patch so far, please allow me to ask a question which may be asked many times: when should I use patch system?
When the patch has been reviewed and acked by people. Note that things in this area will be changing because in the long run you should end up talking to the sub-arch group of people.
Quoted 4 lines
For example, I sent a couple of unrelated patches last week and seems no one has problem with them since I don't see comments regarding them. Should I submit them again through patch system or they will picked up "automatically"?
The debug-macros.S one seemed trivial enough, but the downside is that it impacts on our goal of showing a significant reduction of arch/arm... Since I'm fairly desperate to show as much of a reduction as possible this goes counter to my current direction.
I think the other one was a build fix (?), and that should be fine.
PATCH 1/1 ARM: bcmring: Add clkdev table in init_early
Quoted 15 lines · Russell King - ARM Linux
Quoted 14 lines · Jiandong Zheng
Quoted 11 lines · Russell King - ARM Linux
Quoted 5 lines · Russell King - ARM Linux
Quoted 2 lines · Jiandong Zheng
ARM: bcmring: Move adding clkdev to
init_earlyto make sure clkevent based on sp804 is initialized properly.Great, can you submit this to the patch system please? Thanks.
Erm, actually this patch is against your previous patch (as is the one which you submitted to the patch system) so it won't apply as-is. It needs to be one which wil apply directly to mainline in this case please.
Hi Russell,
Quoted 7 lines
Quoted 2 lines
And my previous patch is based on your set of patches to do common sp804 clock source. How should I submit mine?
Can you provide a patch against mainline which moves the clkdev initialization to the
init_earlycallback - and I'll then deal with fixing up my patches for that by placing it before my two bcmring patches.
Done.
Quoted 21 lines
Quoted 4 lines
Since I haven't had much experience with submitting patch so far, please allow me to ask a question which may be asked many times: when should I use patch system?
When the patch has been reviewed and acked by people. Note that things in this area will be changing because in the long run you should end up talking to the sub-arch group of people.
Quoted 4 lines
For example, I sent a couple of unrelated patches last week and seems no one has problem with them since I don't see comments regarding them. Should I submit them again through patch system or they will picked up "automatically"?
The
debug-macros.Sone seemed trivial enough, but the downside is that it impacts on our goal of showing a significant reduction ofarch/arm... Since I'm fairly desperate to show as much of a reduction as possible this goes counter to my current direction.I think the other one was a build fix (?), and that should be fine.