ARM clockevent patches
Subsystems (5)
cover ARM clockevent patches
Thomas, Ingo,
Here are some updates to get a couple ARM platforms working with the latest -rt. The platforms tested are OMAP and XScale IXP4xx.
Patches against 2.6.20-rc6-rt6
Kevin
PATCH 1/6 ARM build fixups
kernel/time/tick-sched.c +2 -0
@@ -21,6 +21,8 @@#include <linux/sched.h> #include <linux/tick.h> +#include <asm/irq_regs.h> +#include "tick-internal.h" /*
--
PATCH 2/6 ARM NO_HZ idle loop fixup
In reply to Kevin Hilmanarch/arm/kernel/process.c +3 -2
@@ -28,6 +28,7 @@#include <linux/cpu.h> #include <linux/elfcore.h> #include <linux/pm.h> +#include <linux/tick.h> #include <asm/leds.h> #include <asm/processor.h>
@@ -154,12 +155,12 @@ void cpu_idle(void)if (!idle) idle = default_idle;leds_event (led_idle_start); -hrtimer_stop_sched_tick (); +tick_nohz_stop_sched_tick ();while (!need_resched () && !need_resched_delayed ())idle ();leds_event (led_idle_end); -hrtimer_restart_sched_tick ();local_irq_disable (); +tick_nohz_restart_sched_tick ();__preempt_enable_no_resched ();__schedule ();preempt_disable ();
--
PATCH 3/6 ARM Kconfig support for GENERIC_CLOCKEVENTS
In reply to Kevin Hilmanarch/arm/Kconfig +4 -0
@@ -25,6 +25,10 @@ config GENERIC_CLOCKEVENTS bool default n +config GENERIC_CLOCKEVENTS + bool + default n + config MMU bool default y
--
PATCH 4/6 ARM: LEDS_TIMER hackery for clockevents
In reply to Kevin HilmanThe clockevent layer now handles everything done by the ARM timer_tick() call, except the LED stuff. Here we add an arch_tick_leds() to handle LED toggling which is called by do_timer().
arch/arm/kernel/time.c +7 -0
@@ -244,6 +244,13 @@ static inline void do_leds(void)#define do_leds ()#endif +void arch_tick_leds (void ) +{ +#ifdef CONFIG_LEDS_TIMER +do_leds (); +#endif +} +#ifndef CONFIG_GENERIC_TIME void do_gettimeofday (struct timeval *tv) {
kernel/timer.c +3 -0
@@ -1471,6 +1471,9 @@ static void run_timer_softirq(struct sofvoid do_timer (unsigned long ticks) { jiffies_64 += ticks; +#ifdef CONFIG_LEDS_TIMER +arch_tick_leds (); +#endif }#ifdef __ARCH_WANT_SYS_ALARM
--
PATCH 5/6 ARM: clockevent support for ixp4xx platform
In reply to Kevin Hilmanarch/arm/mach-ixp4xx/common.c +74 -19
@@ -27,6 +27,7 @@#include <linux/time.h> #include <linux/timex.h> #include <linux/clocksource.h> +#include <linux/clockchips.h> #include <asm/arch/udc.h> #include <asm/hardware.h>
@@ -41,6 +42,8 @@#include <asm/mach/time.h> static int __init ixp4xx_clocksource_init (void ); +static int __init ixp4xx_clockevent_init (void ); +static struct clock_event_device clockevent_ixp4xx;/************************************************************************* * IXP4xx chipset I/O mapping
@@ -239,52 +242,40 @@ void __init ixp4xx_init_irq(void)* counter as a source of real clock ticks to account for missed jiffies. *************************************************************************/ -static unsigned volatile last_jiffy_time; - -#define CLOCK_TICKS_PER_USEC ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC) -static irqreturn_t ixp4xx_timer_interrupt (int irq,void *dev_id) { -write_seqlock (&xtime_lock); +struct clock_event_device *evt = &clockevent_ixp4xx;/* Clear Pending Interrupt by writing '1' to it */ *IXP4XX_OSST =IXP4XX_OSST_TIMER_1_PEND ; -/* -* Catch up with the real idea of time -*/ -while ((signed long )(*IXP4XX_OSTS - last_jiffy_time) >=LATCH ) { -timer_tick (); - last_jiffy_time +=LATCH ; - } - -write_sequnlock (&xtime_lock); + evt->event_handler (evt);return IRQ_HANDLED ; }static struct irqaction ixp4xx_timer_irq = { - .name ="IXP4xx Timer Tick" , + .name ="timer1" , .flags =IRQF_DISABLED |IRQF_TIMER , .handler = ixp4xx_timer_interrupt, };static void __init ixp4xx_timer_init (void ) { +/* Reset/disable counter */ + *IXP4XX_OSRT1 =0 ; +/* Clear Pending Interrupt by writing '1' to it */ *IXP4XX_OSST =IXP4XX_OSST_TIMER_1_PEND ; -/* Setup the Timer counter value */ - *IXP4XX_OSRT1 = (LATCH & ~IXP4XX_OST_RELOAD_MASK ) |IXP4XX_OST_ENABLE ; -/* Reset time-stamp counter */ *IXP4XX_OSTS =0 ; - last_jiffy_time =0 ;/* Connect the interrupt handler and enable the interrupt */ setup_irq (IRQ_IXP4XX_TIMER1 , &ixp4xx_timer_irq);ixp4xx_clocksource_init (); +ixp4xx_clockevent_init (); }struct sys_timer ixp4xx_timer = {
@@ -384,6 +375,9 @@ void __init ixp4xx_sys_init(void) ixp4xx_exp_bus_size >> 20); } +/* +* clocksource +*/ cycle_t ixp4xx_get_cycles (void ) {return *IXP4XX_OSTS ;
@@ -408,3 +402,64 @@ static int __init ixp4xx_clocksource_inireturn 0 ; } + +/* +* clockevents +*/ +static int ixp4xx_set_next_event (unsigned long evt, +struct clock_event_device *unused) +{ +unsigned long opts = *IXP4XX_OSRT1 &IXP4XX_OST_RELOAD_MASK ; + + *IXP4XX_OSRT1 = (evt & ~IXP4XX_OST_RELOAD_MASK ) | opts; + +return 0 ; +} + +static void ixp4xx_set_mode (enum clock_event_mode mode, +struct clock_event_device *evt) +{ +unsigned long opts, osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK ; + +switch (mode) { +case CLOCK_EVT_MODE_PERIODIC : + osrt =LATCH & ~IXP4XX_OST_RELOAD_MASK ; + opts =IXP4XX_OST_ENABLE ; +break ; +case CLOCK_EVT_MODE_ONESHOT : +/* period set by 'set next_event' */ + osrt =0 ; + opts =IXP4XX_OST_ENABLE |IXP4XX_OST_ONE_SHOT ; +break ; +case CLOCK_EVT_MODE_SHUTDOWN : +case CLOCK_EVT_MODE_UNUSED : +default : + osrt = opts =0 ; +break ; + } + + *IXP4XX_OSRT1 = osrt | opts; +} + +static struct clock_event_device clockevent_ixp4xx = { + .name ="ixp4xx timer1" , + .features =CLOCK_EVT_FEAT_PERIODIC |CLOCK_EVT_FEAT_ONESHOT , + .rating =200 , + .shift =24 , + .set_mode = ixp4xx_set_mode, + .set_next_event = ixp4xx_set_next_event, +}; + +static int __init ixp4xx_clockevent_init (void ) +{ + clockevent_ixp4xx.mult =div_sc (FREQ ,NSEC_PER_SEC , + clockevent_ixp4xx.shift); + clockevent_ixp4xx.max_delta_ns = +clockevent_delta2ns (0xfffffffe , &clockevent_ixp4xx); + clockevent_ixp4xx.min_delta_ns = +clockevent_delta2ns (0xf , &clockevent_ixp4xx); + clockevent_ixp4xx.cpumask =cpumask_of_cpu (0 ); + +clockevents_register_device (&clockevent_ixp4xx); +return 0 ; +}
arch/arm/Kconfig +1 -0
@@ -255,6 +255,7 @@ config ARCH_IXP4XX bool "IXP4xx-based" depends on MMU select GENERIC_TIME + select GENERIC_CLOCKEVENTS help Support for Intel's IXP4XX (XScale) family of processors.
--
PATCH 6/6 ARM: clockevent support for OMAP1 platform
In reply to Kevin HilmanThese are minor fixups to the clockevent support which is already in 2.6.20-rc6-rt6 for OMAP.
arch/arm/plat-omap/common.c +1 -1
@@ -186,7 +186,7 @@ static struct clocksource clocksource_32 .read = omap_32k_read, .mask = CLOCKSOURCE_MASK(32), .shift = 10, - .is_continuous = 1, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, };static int __init omap_init_clocksource_32k (void )
arch/arm/plat-omap/timer32k.c +11 -32
80 lines not on this page · raw message
arch/arm/mach-omap1/time.c +13 -9
@@ -137,31 +137,32 @@ static inline void omap_mpu_timer_start(* MPU timer 1 ... count down to zero, interrupt, reload * --------------------------------------------------------------------------- */ -static void omap_mpu_set_next_event (unsigned long cycles, +static int omap_mpu_set_next_event (unsigned long cycles,struct clock_event_device *evt) {omap_mpu_timer_start (0 , cycles,0 ); +return 0 ; }static void omap_mpu_set_mode (enum clock_event_mode mode,struct clock_event_device *evt) {switch (mode) { -case CLOCK_EVT_PERIODIC : +case CLOCK_EVT_MODE_PERIODIC :omap_mpu_set_autoreset (0 );break ; -case CLOCK_EVT_ONESHOT : +case CLOCK_EVT_MODE_ONESHOT :omap_mpu_remove_autoreset (0 );break ; -case CLOCK_EVT_SHUTDOWN : +case CLOCK_EVT_MODE_UNUSED : +case CLOCK_EVT_MODE_SHUTDOWN :break ; } }static struct clock_event_device clockevent_mpu_timer1 = { .name ="mpu_timer1" , - .capabilities =CLOCK_CAP_NEXTEVT |CLOCK_CAP_TICK | -CLOCK_CAP_UPDATE , + .features =CLOCK_EVT_FEAT_PERIODIC ,CLOCK_EVT_FEAT_ONESHOT , .shift =32 , .set_next_event = omap_mpu_set_next_event, .set_mode = omap_mpu_set_mode,
@@ -169,7 +170,9 @@ static struct clock_event_device clockevstatic irqreturn_t omap_mpu_timer1_interrupt (int irq,void *dev_id) { - clockevent_mpu_timer1.event_handler (); +struct clock_event_device *evt = &clockevent_mpu_timer1; + + evt->event_handler (evt);return IRQ_HANDLED ; }
@@ -194,7 +197,8 @@ static __init void omap_init_mpu_timer(u clockevent_mpu_timer1.min_delta_ns =clockevent_delta2ns (1 , &clockevent_mpu_timer1); -register_global_clockevent (&clockevent_mpu_timer1); + clockevent_mpu_timer1.cpumask =cpumask_of_cpu (0 ); +clockevents_register_device (&clockevent_mpu_timer1); }
@@ -229,7 +233,7 @@ static struct clocksource clocksource_mp .read = mpu_read, .mask = CLOCKSOURCE_MASK(32), .shift = 24, - .is_continuous = 1, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, };static void __init omap_init_clocksource (unsigned long rate)
--
Quoted 6 lines · Kevin Hilman
Thomas, Ingo,
Here are some updates to get a couple ARM platforms working with the latest -rt. The platforms tested are OMAP and XScale IXP4xx.
Patches against 2.6.20-rc6-rt6
thanks, i've applied all of them, they'll show up in -rc7-rt1.
Ingo
-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php