summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-09-01 14:04:50 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-01 14:04:50 -0700
commit5e359bf2219d8622eb0931701e45af55db323228 (patch)
treee47677ae0896c66a54c65b3221050eb0e9f23b81 /arch
parent8d01b66b4f23a9fcf5c6787b27f0be5f8cbae98c (diff)
parent85e1cd6e769dfc84995270d0a4838021fcb8602d (diff)
downloadlinux-rpi3-5e359bf2219d8622eb0931701e45af55db323228.tar.gz
linux-rpi3-5e359bf2219d8622eb0931701e45af55db323228.tar.bz2
linux-rpi3-5e359bf2219d8622eb0931701e45af55db323228.zip
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer updates from Thomas Gleixner: "Rather large, but nothing exiting: - new range check for settimeofday() to prevent that boot time becomes negative. - fix for file time rounding - a few simplifications of the hrtimer code - fix for the proc/timerlist code so the output of clock realtime timers is accurate - more y2038 work - tree wide conversion of clockevent drivers to the new callbacks" * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (88 commits) hrtimer: Handle failure of tick_init_highres() gracefully hrtimer: Unconfuse switch_hrtimer_base() a bit hrtimer: Simplify get_target_base() by returning current base hrtimer: Drop return code of hrtimer_switch_to_hres() time: Introduce timespec64_to_jiffies()/jiffies_to_timespec64() time: Introduce current_kernel_time64() time: Introduce struct itimerspec64 time: Add the common weak version of update_persistent_clock() time: Always make sure wall_to_monotonic isn't positive time: Fix nanosecond file time rounding in timespec_trunc() timer_list: Add the base offset so remaining nsecs are accurate for non monotonic timers cris/time: Migrate to new 'set-state' interface kernel: broadcast-hrtimer: Migrate to new 'set-state' interface xtensa/time: Migrate to new 'set-state' interface unicore/time: Migrate to new 'set-state' interface um/time: Migrate to new 'set-state' interface sparc/time: Migrate to new 'set-state' interface sh/localtimer: Migrate to new 'set-state' interface score/time: Migrate to new 'set-state' interface s390/time: Migrate to new 'set-state' interface ...
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/kernel/time.c18
-rw-r--r--arch/blackfin/kernel/time-ts.c136
-rw-r--r--arch/c6x/platforms/timer64.c52
-rw-r--r--arch/cris/arch-v32/kernel/time.c8
-rw-r--r--arch/microblaze/kernel/timer.c46
-rw-r--r--arch/mn10300/kernel/cevt-mn10300.c7
-rw-r--r--arch/openrisc/kernel/time.c24
-rw-r--r--arch/powerpc/kernel/time.c24
-rw-r--r--arch/s390/kernel/time.c6
-rw-r--r--arch/score/kernel/time.c31
-rw-r--r--arch/sh/kernel/localtimer.c6
-rw-r--r--arch/sparc/kernel/sun4m_smp.c2
-rw-r--r--arch/sparc/kernel/time_32.c57
-rw-r--r--arch/sparc/kernel/time_64.c33
-rw-r--r--arch/um/kernel/time.c44
-rw-r--r--arch/unicore32/kernel/time.c29
-rw-r--r--arch/x86/kernel/i8253.c2
-rw-r--r--arch/xtensa/kernel/time.c53
18 files changed, 244 insertions, 334 deletions
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index 643a9dcdf093..5b6202a825ff 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -93,7 +93,7 @@ rtc_timer_interrupt(int irq, void *dev)
struct clock_event_device *ce = &per_cpu(cpu_ce, cpu);
/* Don't run the hook for UNUSED or SHUTDOWN. */
- if (likely(ce->mode == CLOCK_EVT_MODE_PERIODIC))
+ if (likely(clockevent_state_periodic(ce)))
ce->event_handler(ce);
if (test_irq_work_pending()) {
@@ -104,13 +104,6 @@ rtc_timer_interrupt(int irq, void *dev)
return IRQ_HANDLED;
}
-static void
-rtc_ce_set_mode(enum clock_event_mode mode, struct clock_event_device *ce)
-{
- /* The mode member of CE is updated in generic code.
- Since we only support periodic events, nothing to do. */
-}
-
static int
rtc_ce_set_next_event(unsigned long evt, struct clock_event_device *ce)
{
@@ -129,7 +122,6 @@ init_rtc_clockevent(void)
.features = CLOCK_EVT_FEAT_PERIODIC,
.rating = 100,
.cpumask = cpumask_of(cpu),
- .set_mode = rtc_ce_set_mode,
.set_next_event = rtc_ce_set_next_event,
};
@@ -161,12 +153,12 @@ static struct clocksource qemu_cs = {
* The QEMU alarm as a clock_event_device primitive.
*/
-static void
-qemu_ce_set_mode(enum clock_event_mode mode, struct clock_event_device *ce)
+static int qemu_ce_shutdown(struct clock_event_device *ce)
{
/* The mode member of CE is updated for us in generic code.
Just make sure that the event is disabled. */
qemu_set_alarm_abs(0);
+ return 0;
}
static int
@@ -197,7 +189,9 @@ init_qemu_clockevent(void)
.features = CLOCK_EVT_FEAT_ONESHOT,
.rating = 400,
.cpumask = cpumask_of(cpu),
- .set_mode = qemu_ce_set_mode,
+ .set_state_shutdown = qemu_ce_shutdown,
+ .set_state_oneshot = qemu_ce_shutdown,
+ .tick_resume = qemu_ce_shutdown,
.set_next_event = qemu_ce_set_next_event,
};
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c
index cb0a4845339e..fb9e95f1b719 100644
--- a/arch/blackfin/kernel/time-ts.c
+++ b/arch/blackfin/kernel/time-ts.c
@@ -136,44 +136,44 @@ static int bfin_gptmr0_set_next_event(unsigned long cycles,
return 0;
}
-static void bfin_gptmr0_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
+static int bfin_gptmr0_set_periodic(struct clock_event_device *evt)
{
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC: {
#ifndef CONFIG_BF60x
- set_gptimer_config(TIMER0_id, \
- TIMER_OUT_DIS | TIMER_IRQ_ENA | \
- TIMER_PERIOD_CNT | TIMER_MODE_PWM);
+ set_gptimer_config(TIMER0_id,
+ TIMER_OUT_DIS | TIMER_IRQ_ENA |
+ TIMER_PERIOD_CNT | TIMER_MODE_PWM);
#else
- set_gptimer_config(TIMER0_id, TIMER_OUT_DIS
- | TIMER_MODE_PWM_CONT | TIMER_PULSE_HI | TIMER_IRQ_PER);
+ set_gptimer_config(TIMER0_id,
+ TIMER_OUT_DIS | TIMER_MODE_PWM_CONT |
+ TIMER_PULSE_HI | TIMER_IRQ_PER);
#endif
- set_gptimer_period(TIMER0_id, get_sclk() / HZ);
- set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1);
- enable_gptimers(TIMER0bit);
- break;
- }
- case CLOCK_EVT_MODE_ONESHOT:
- disable_gptimers(TIMER0bit);
+ set_gptimer_period(TIMER0_id, get_sclk() / HZ);
+ set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1);
+ enable_gptimers(TIMER0bit);
+ return 0;
+}
+
+static int bfin_gptmr0_set_oneshot(struct clock_event_device *evt)
+{
+ disable_gptimers(TIMER0bit);
#ifndef CONFIG_BF60x
- set_gptimer_config(TIMER0_id, \
- TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM);
+ set_gptimer_config(TIMER0_id,
+ TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM);
#else
- set_gptimer_config(TIMER0_id, TIMER_OUT_DIS | TIMER_MODE_PWM
- | TIMER_PULSE_HI | TIMER_IRQ_WID_DLY);
+ set_gptimer_config(TIMER0_id,
+ TIMER_OUT_DIS | TIMER_MODE_PWM | TIMER_PULSE_HI |
+ TIMER_IRQ_WID_DLY);
#endif
- set_gptimer_period(TIMER0_id, 0);
- break;
- case CLOCK_EVT_MODE_UNUSED:
- case CLOCK_EVT_MODE_SHUTDOWN:
- disable_gptimers(TIMER0bit);
- break;
- case CLOCK_EVT_MODE_RESUME:
- break;
- }
+ set_gptimer_period(TIMER0_id, 0);
+ return 0;
+}
+
+static int bfin_gptmr0_shutdown(struct clock_event_device *evt)
+{
+ disable_gptimers(TIMER0bit);
+ return 0;
}
static void bfin_gptmr0_ack(void)
@@ -211,13 +211,16 @@ static struct irqaction gptmr0_irq = {
};
static struct clock_event_device clockevent_gptmr0 = {
- .name = "bfin_gptimer0",
- .rating = 300,
- .irq = IRQ_TIMER0,
- .shift = 32,
- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
- .set_next_event = bfin_gptmr0_set_next_event,
- .set_mode = bfin_gptmr0_set_mode,
+ .name = "bfin_gptimer0",
+ .rating = 300,
+ .irq = IRQ_TIMER0,
+ .shift = 32,
+ .features = CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_ONESHOT,
+ .set_next_event = bfin_gptmr0_set_next_event,
+ .set_state_shutdown = bfin_gptmr0_shutdown,
+ .set_state_periodic = bfin_gptmr0_set_periodic,
+ .set_state_oneshot = bfin_gptmr0_set_oneshot,
};
static void __init bfin_gptmr0_clockevent_init(struct clock_event_device *evt)
@@ -250,36 +253,35 @@ static int bfin_coretmr_set_next_event(unsigned long cycles,
return 0;
}
-static void bfin_coretmr_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
+static int bfin_coretmr_set_periodic(struct clock_event_device *evt)
{
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC: {
- unsigned long tcount = ((get_cclk() / (HZ * TIME_SCALE)) - 1);
- bfin_write_TCNTL(TMPWR);
- CSYNC();
- bfin_write_TSCALE(TIME_SCALE - 1);
- bfin_write_TPERIOD(tcount);
- bfin_write_TCOUNT(tcount);
- CSYNC();
- bfin_write_TCNTL(TMPWR | TMREN | TAUTORLD);
- break;
- }
- case CLOCK_EVT_MODE_ONESHOT:
- bfin_write_TCNTL(TMPWR);
- CSYNC();
- bfin_write_TSCALE(TIME_SCALE - 1);
- bfin_write_TPERIOD(0);
- bfin_write_TCOUNT(0);
- break;
- case CLOCK_EVT_MODE_UNUSED:
- case CLOCK_EVT_MODE_SHUTDOWN:
- bfin_write_TCNTL(0);
- CSYNC();
- break;
- case CLOCK_EVT_MODE_RESUME:
- break;
- }
+ unsigned long tcount = ((get_cclk() / (HZ * TIME_SCALE)) - 1);
+
+ bfin_write_TCNTL(TMPWR);
+ CSYNC();
+ bfin_write_TSCALE(TIME_SCALE - 1);
+ bfin_write_TPERIOD(tcount);
+ bfin_write_TCOUNT(tcount);
+ CSYNC();
+ bfin_write_TCNTL(TMPWR | TMREN | TAUTORLD);
+ return 0;
+}
+
+static int bfin_coretmr_set_oneshot(struct clock_event_device *evt)
+{
+ bfin_write_TCNTL(TMPWR);
+ CSYNC();
+ bfin_write_TSCALE(TIME_SCALE - 1);
+ bfin_write_TPERIOD(0);
+ bfin_write_TCOUNT(0);
+ return 0;
+}
+
+static int bfin_coretmr_shutdown(struct clock_event_device *evt)
+{
+ bfin_write_TCNTL(0);
+ CSYNC();
+ return 0;
}
void bfin_coretmr_init(void)
@@ -335,7 +337,9 @@ void bfin_coretmr_clockevent_init(void)
evt->shift = 32;
evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
evt->set_next_event = bfin_coretmr_set_next_event;
- evt->set_mode = bfin_coretmr_set_mode;
+ evt->set_state_shutdown = bfin_coretmr_shutdown;
+ evt->set_state_periodic = bfin_coretmr_set_periodic;
+ evt->set_state_oneshot = bfin_coretmr_set_oneshot;
clock_tick = get_cclk() / TIME_SCALE;
evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift);
diff --git a/arch/c6x/platforms/timer64.c b/arch/c6x/platforms/timer64.c
index 3c73d74a4674..c19901e5f055 100644
--- a/arch/c6x/platforms/timer64.c
+++ b/arch/c6x/platforms/timer64.c
@@ -126,35 +126,37 @@ static int next_event(unsigned long delta,
return 0;
}
-static void set_clock_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
+static int set_periodic(struct clock_event_device *evt)
{
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
- timer64_enable();
- timer64_mode = TIMER64_MODE_PERIODIC;
- timer64_config(TIMER64_RATE / HZ);
- break;
- case CLOCK_EVT_MODE_ONESHOT:
- timer64_enable();
- timer64_mode = TIMER64_MODE_ONE_SHOT;
- break;
- case CLOCK_EVT_MODE_UNUSED:
- case CLOCK_EVT_MODE_SHUTDOWN:
- timer64_mode = TIMER64_MODE_DISABLED;
- timer64_disable();
- break;
- case CLOCK_EVT_MODE_RESUME:
- break;
- }
+ timer64_enable();
+ timer64_mode = TIMER64_MODE_PERIODIC;
+ timer64_config(TIMER64_RATE / HZ);
+ return 0;
+}
+
+static int set_oneshot(struct clock_event_device *evt)
+{
+ timer64_enable();
+ timer64_mode = TIMER64_MODE_ONE_SHOT;
+ return 0;
+}
+
+static int shutdown(struct clock_event_device *evt)
+{
+ timer64_mode = TIMER64_MODE_DISABLED;
+ timer64_disable();
+ return 0;
}
static struct clock_event_device t64_clockevent_device = {
- .name = "TIMER64_EVT32_TIMER",
- .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
- .rating = 200,
- .set_mode = set_clock_mode,
- .set_next_event = next_event,
+ .name = "TIMER64_EVT32_TIMER",
+ .features = CLOCK_EVT_FEAT_ONESHOT |
+ CLOCK_EVT_FEAT_PERIODIC,
+ .rating = 200,
+ .set_state_shutdown = shutdown,
+ .set_state_periodic = set_periodic,
+ .set_state_oneshot = set_oneshot,
+ .set_next_event = next_event,
};
static irqreturn_t timer_interrupt(int irq, void *dev_id)
diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c
index 4fce9f1f7cc0..d2a84407654a 100644
--- a/arch/cris/arch-v32/kernel/time.c
+++ b/arch/cris/arch-v32/kernel/time.c
@@ -172,8 +172,7 @@ void handle_watchdog_bite(struct pt_regs *regs)
extern void cris_profile_sample(struct pt_regs *regs);
static void __iomem *timer_base;
-static void crisv32_clkevt_mode(enum clock_event_mode mode,
- struct clock_event_device *dev)
+static int crisv32_clkevt_switch_state(struct clock_event_device *dev)
{
reg_timer_rw_tmr0_ctrl ctrl = {
.op = regk_timer_hold,
@@ -181,6 +180,7 @@ static void crisv32_clkevt_mode(enum clock_event_mode mode,
};
REG_WR(timer, timer_base, rw_tmr0_ctrl, ctrl);
+ return 0;
}
static int crisv32_clkevt_next_event(unsigned long evt,
@@ -231,7 +231,9 @@ static struct clock_event_device crisv32_clockevent = {
.name = "crisv32-timer",
.rating = 300,
.features = CLOCK_EVT_FEAT_ONESHOT,
- .set_mode = crisv32_clkevt_mode,
+ .set_state_oneshot = crisv32_clkevt_switch_state,
+ .set_state_shutdown = crisv32_clkevt_switch_state,
+ .tick_resume = crisv32_clkevt_switch_state,
.set_next_event = crisv32_clkevt_next_event,
};
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index c8977450e28c..67e2ef48d2d0 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -122,37 +122,29 @@ static int xilinx_timer_set_next_event(unsigned long delta,
return 0;
}
-static void xilinx_timer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
+static int xilinx_timer_shutdown(struct clock_event_device *evt)
{
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
- pr_info("%s: periodic\n", __func__);
- xilinx_timer0_start_periodic(freq_div_hz);
- break;
- case CLOCK_EVT_MODE_ONESHOT:
- pr_info("%s: oneshot\n", __func__);
- break;
- case CLOCK_EVT_MODE_UNUSED:
- pr_info("%s: unused\n", __func__);
- break;
- case CLOCK_EVT_MODE_SHUTDOWN:
- pr_info("%s: shutdown\n", __func__);
- xilinx_timer0_stop();
- break;
- case CLOCK_EVT_MODE_RESUME:
- pr_info("%s: resume\n", __func__);
- break;
- }
+ pr_info("%s\n", __func__);
+ xilinx_timer0_stop();
+ return 0;
+}
+
+static int xilinx_timer_set_periodic(struct clock_event_device *evt)
+{
+ pr_info("%s\n", __func__);
+ xilinx_timer0_start_periodic(freq_div_hz);
+ return 0;
}
static struct clock_event_device clockevent_xilinx_timer = {
- .name = "xilinx_clockevent",
- .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
- .shift = 8,
- .rating = 300,
- .set_next_event = xilinx_timer_set_next_event,
- .set_mode = xilinx_timer_set_mode,
+ .name = "xilinx_clockevent",
+ .features = CLOCK_EVT_FEAT_ONESHOT |
+ CLOCK_EVT_FEAT_PERIODIC,
+ .shift = 8,
+ .rating = 300,
+ .set_next_event = xilinx_timer_set_next_event,
+ .set_state_shutdown = xilinx_timer_shutdown,
+ .set_state_periodic = xilinx_timer_set_periodic,
};
static inline void timer_ack(void)
diff --git a/arch/mn10300/kernel/cevt-mn10300.c b/arch/mn10300/kernel/cevt-mn10300.c
index 60f64ca1752a..3aae9f5a98aa 100644
--- a/arch/mn10300/kernel/cevt-mn10300.c
+++ b/arch/mn10300/kernel/cevt-mn10300.c
@@ -41,12 +41,6 @@ static int next_event(unsigned long delta,
return 0;
}
-static void set_clock_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
- /* Nothing to do ... */
-}
-
static DEFINE_PER_CPU(struct clock_event_device, mn10300_clockevent_device);
static DEFINE_PER_CPU(struct irqaction, timer_irq);
@@ -108,7 +102,6 @@ int __init init_clockevents(void)
cd->rating = 200;
cd->cpumask = cpumask_of(smp_processor_id());
- cd->set_mode = set_clock_mode;
cd->event_handler = event_handler;
cd->set_next_event = next_event;
diff --git a/arch/openrisc/kernel/time.c b/arch/openrisc/kernel/time.c
index 7c52e9494a8d..50e970183dcd 100644
--- a/arch/openrisc/kernel/time.c
+++ b/arch/openrisc/kernel/time.c
@@ -48,29 +48,6 @@ static int openrisc_timer_set_next_event(unsigned long delta,
return 0;
}
-static void openrisc_timer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
- pr_debug(KERN_INFO "%s: periodic\n", __func__);
- BUG();
- break;
- case CLOCK_EVT_MODE_ONESHOT:
- pr_debug(KERN_INFO "%s: oneshot\n", __func__);
- break;
- case CLOCK_EVT_MODE_UNUSED:
- pr_debug(KERN_INFO "%s: unused\n", __func__);
- break;
- case CLOCK_EVT_MODE_SHUTDOWN:
- pr_debug(KERN_INFO "%s: shutdown\n", __func__);
- break;
- case CLOCK_EVT_MODE_RESUME:
- pr_debug(KERN_INFO "%s: resume\n", __func__);
- break;
- }
-}
-
/* This is the clock event device based on the OR1K tick timer.
* As the timer is being used as a continuous clock-source (required for HR
* timers) we cannot enable the PERIODIC feature. The tick timer can run using
@@ -82,7 +59,6 @@ static struct clock_event_device clockevent_openrisc_timer = {
.features = CLOCK_EVT_FEAT_ONESHOT,
.rating = 300,
.set_next_event = openrisc_timer_set_next_event,
- .set_mode = openrisc_timer_set_mode,
};
static inline void timer_ack(void)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 43922509a483..1be1092c7204 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -99,16 +99,17 @@ static struct clocksource clocksource_timebase = {
static int decrementer_set_next_event(unsigned long evt,
struct clock_event_device *dev);
-static void decrementer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *dev);
+static int decrementer_shutdown(struct clock_event_device *evt);
struct clock_event_device decrementer_clockevent = {
- .name = "decrementer",
- .rating = 200,
- .irq = 0,
- .set_next_event = decrementer_set_next_event,
- .set_mode = decrementer_set_mode,
- .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP,
+ .name = "decrementer",
+ .rating = 200,
+ .irq = 0,
+ .set_next_event = decrementer_set_next_event,
+ .set_state_shutdown = decrementer_shutdown,
+ .tick_resume = decrementer_shutdown,
+ .features = CLOCK_EVT_FEAT_ONESHOT |
+ CLOCK_EVT_FEAT_C3STOP,
};
EXPORT_SYMBOL(decrementer_clockevent);
@@ -862,11 +863,10 @@ static int decrementer_set_next_event(unsigned long evt,
return 0;
}
-static void decrementer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *dev)
+static int decrementer_shutdown(struct clock_event_device *dev)
{
- if (mode != CLOCK_EVT_MODE_ONESHOT)
- decrementer_set_next_event(DECREMENTER_MAX, dev);
+ decrementer_set_next_event(DECREMENTER_MAX, dev);
+ return 0;
}
/* Interrupt handler for the timer broadcast IPI */
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 627887b075a7..52524b9083c3 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -120,11 +120,6 @@ static int s390_next_event(unsigned long delta,
return 0;
}
-static void s390_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
-}
-
/*
* Set up lowcore and control register of the current cpu to
* enable TOD clock and clock comparator interrupts.
@@ -148,7 +143,6 @@ void init_cpu_timer(void)
cd->rating = 400;
cd->cpumask = cpumask_of(cpu);
cd->set_next_event = s390_next_event;
- cd->set_mode = s390_set_mode;
clockevents_register_device(cd);
diff --git a/arch/score/kernel/time.c b/arch/score/kernel/time.c
index 24770cd9b473..679b8d7b0350 100644
--- a/arch/score/kernel/time.c
+++ b/arch/score/kernel/time.c
@@ -55,31 +55,20 @@ static int score_timer_set_next_event(unsigned long delta,
return 0;
}
-static void score_timer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evdev)
+static int score_timer_set_periodic(struct clock_event_device *evt)
{
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
- outl((TMR_M_PERIODIC | TMR_IE_ENABLE), P_TIMER0_CTRL);
- outl(SYSTEM_CLOCK/HZ, P_TIMER0_PRELOAD);
- outl(inl(P_TIMER0_CTRL) | TMR_ENABLE, P_TIMER0_CTRL);
- break;
- case CLOCK_EVT_MODE_ONESHOT:
- case CLOCK_EVT_MODE_SHUTDOWN:
- case CLOCK_EVT_MODE_RESUME:
- case CLOCK_EVT_MODE_UNUSED:
- break;
- default:
- BUG();
- }
+ outl((TMR_M_PERIODIC | TMR_IE_ENABLE), P_TIMER0_CTRL);
+ outl(SYSTEM_CLOCK / HZ, P_TIMER0_PRELOAD);
+ outl(inl(P_TIMER0_CTRL) | TMR_ENABLE, P_TIMER0_CTRL);
+ return 0;
}
static struct clock_event_device score_clockevent = {
- .name = "score_clockevent",
- .features = CLOCK_EVT_FEAT_PERIODIC,
- .shift = 16,
- .set_next_event = score_timer_set_next_event,
- .set_mode = score_timer_set_mode,
+ .name = "score_clockevent",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+ .shift = 16,
+ .set_next_event = score_timer_set_next_event,
+ .set_state_periodic = score_timer_set_periodic,
};
void __init time_init(void)
diff --git a/arch/sh/kernel/localtimer.c b/arch/sh/kernel/localtimer.c
index b880a7e2ace7..cbb7d4636ec0 100644
--- a/arch/sh/kernel/localtimer.c
+++ b/arch/sh/kernel/localtimer.c
@@ -39,11 +39,6 @@ void local_timer_interrupt(void)
irq_exit();
}
-static void dummy_timer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *clk)
-{
-}
-
void local_timer_setup(unsigned int cpu)
{
struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
@@ -54,7 +49,6 @@ void local_timer_setup(unsigned int cpu)
CLOCK_EVT_FEAT_DUMMY;
clk->rating = 400;
clk->mult = 1;
- clk->set_mode = dummy_timer_set_mode;
clk->broadcast = smp_timer_broadcast;
clk->cpumask = cpumask_of(cpu);
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index d3408e72d20c..278c40abce82 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -247,7 +247,7 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
ce = &per_cpu(sparc32_clockevent, cpu);
- if (ce->mode & CLOCK_EVT_MODE_PERIODIC)
+ if (clockevent_state_periodic(ce))
sun4m_clear_profile_irq(cpu);
else
sparc_config.load_profile_irq(cpu, 0); /* Is this needless? */
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c
index c9692f387cee..1affabc96b08 100644
--- a/arch/sparc/kernel/time_32.c
+++ b/arch/sparc/kernel/time_32.c
@@ -101,21 +101,18 @@ irqreturn_t notrace timer_interrupt(int dummy, void *dev_id)
return IRQ_HANDLED;
}
-static void timer_ce_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
+static int timer_ce_shutdown(struct clock_event_device *evt)
{
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
- case CLOCK_EVT_MODE_RESUME:
- timer_ce_enabled = 1;
- break;
- case CLOCK_EVT_MODE_SHUTDOWN:
- timer_ce_enabled = 0;
- break;
- default:
- break;
- }
+ timer_ce_enabled = 0;
+ smp_mb();
+ return 0;
+}
+
+static int timer_ce_set_periodic(struct clock_event_device *evt)
+{
+ timer_ce_enabled = 1;
smp_mb();
+ return 0;
}
static __init void setup_timer_ce(void)
@@ -127,7 +124,9 @@ static __init void setup_timer_ce(void)
ce->name = "timer_ce";
ce->rating = 100;
ce->features = CLOCK_EVT_FEAT_PERIODIC;
- ce->set_mode = timer_ce_set_mode;
+ ce->set_state_shutdown = timer_ce_shutdown;
+ ce->set_state_periodic = timer_ce_set_periodic;
+ ce->tick_resume = timer_ce_set_periodic;
ce->cpumask = cpu_possible_mask;
ce->shift = 32;
ce->mult = div_sc(sparc_config.clock_rate, NSEC_PER_SEC,
@@ -183,24 +182,20 @@ static __init int setup_timer_cs(void)
}
#ifdef CONFIG_SMP
-static void percpu_ce_setup(enum clock_event_mode mode,
- struct clock_event_device *evt)
+static int percpu_ce_shutdown(struct clock_event_device *evt)
{
int cpu = cpumask_first(evt->cpumask);
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
- sparc_config.load_profile_irq(cpu,
- SBUS_CLOCK_RATE / HZ);
- break;
- case CLOCK_EVT_MODE_ONESHOT:
- case CLOCK_EVT_MODE_SHUTDOWN:
- case CLOCK_EVT_MODE_UNUSED:
- sparc_config.load_profile_irq(cpu, 0);
- break;
- default:
- break;
- }
+ sparc_config.load_profile_irq(cpu, 0);
+ return 0;
+}
+
+static int percpu_ce_set_periodic(struct clock_event_device *evt)
+{
+ int cpu = cpumask_first(evt->cpumask);
+
+ sparc_config.load_profile_irq(cpu, SBUS_CLOCK_RATE / HZ);
+ return 0;
}
static int percpu_ce_set_next_event(unsigned long delta,
@@ -224,7 +219,9 @@ void register_percpu_ce(int cpu)
ce->name = "percpu_ce";
ce->rating = 200;
ce->features = features;
- ce->set_mode = percpu_ce_setup;
+ ce->set_state_shutdown = percpu_ce_shutdown;
+ ce->set_state_periodic = percpu_ce_set_periodic;
+ ce->set_state_oneshot = percpu_ce_shutdown;
ce->set_next_event = percpu_ce_set_next_event;
ce->cpumask = cpumask_of(cpu);
ce->shift = 32;
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c
index 2e6035c0a8ca..c69b21e51efc 100644
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -674,32 +674,19 @@ static int sparc64_next_event(unsigned long delta,
return tick_ops->add_compare(delta) ? -ETIME : 0;
}
-static void sparc64_timer_setup(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
- switch (mode) {
- case CLOCK_EVT_MODE_ONESHOT:
- case CLOCK_EVT_MODE_RESUME:
- break;
-
- case CLOCK_EVT_MODE_SHUTDOWN:
- tick_ops->disable_irq();
- break;
-
- case CLOCK_EVT_MODE_PERIODIC:
- case CLOCK_EVT_MODE_UNUSED:
- WARN_ON(1);
- break;
- }
+static int sparc64_timer_shutdown(struct clock_event_device *evt)
+{
+ tick_ops->disable_irq();
+ return 0;
}
static struct clock_event_device sparc64_clockevent = {
- .features = CLOCK_EVT_FEAT_ONESHOT,
- .set_mode = sparc64_timer_setup,
- .set_next_event = sparc64_next_event,
- .rating = 100,
- .shift = 30,
- .irq = -1,
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .set_state_shutdown = sparc64_timer_shutdown,
+ .set_next_event = sparc64_next_event,
+ .rating = 100,
+ .shift = 30,
+ .irq = -1,
};
static DEFINE_PER_CPU(struct clock_event_device, sparc64_events);
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 117568d4f64a..5af441efb377 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -22,23 +22,16 @@ void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
local_irq_restore(flags);
}
-static void itimer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
+static int itimer_shutdown(struct clock_event_device *evt)
{
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
- set_interval();
- break;
-
- case CLOCK_EVT_MODE_SHUTDOWN:
- case CLOCK_EVT_MODE_UNUSED:
- case CLOCK_EVT_MODE_ONESHOT:
- disable_timer();
- break;
-
- case CLOCK_EVT_MODE_RESUME:
- break;
- }
+ disable_timer();
+ return 0;
+}
+
+static int itimer_set_periodic(struct clock_event_device *evt)
+{
+ set_interval();
+ return 0;
}
static int itimer_next_event(unsigned long delta,
@@ -48,14 +41,17 @@ static int itimer_next_event(unsigned long delta,
}
static struct clock_event_device itimer_clockevent = {
- .name = "itimer",
- .rating = 250,
- .cpumask = cpu_all_mask,
- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
- .set_mode = itimer_set_mode,
- .set_next_event = itimer_next_event,
- .shift = 32,
- .irq = 0,
+ .name = "itimer",
+ .rating = 250,
+ .cpumask = cpu_all_mask,
+ .features = CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_ONESHOT,
+ .set_state_shutdown = itimer_shutdown,
+ .set_state_periodic = itimer_set_periodic,
+ .set_state_oneshot = itimer_shutdown,
+ .set_next_event = itimer_next_event,
+ .shift = 32,
+ .irq = 0,
};
static irqreturn_t um_timer(int irq, void *dev)
diff --git a/arch/unicore32/kernel/time.c b/arch/unicore32/kernel/time.c
index d3824b2ff644..ac4c5449bb88 100644
--- a/arch/unicore32/kernel/time.c
+++ b/arch/unicore32/kernel/time.c
@@ -46,29 +46,20 @@ puv3_osmr0_set_next_event(unsigned long delta, struct clock_event_device *c)
return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
}
-static void
-puv3_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *c)
+static int puv3_osmr0_shutdown(struct clock_event_device *evt)
{
- switch (mode) {
- case CLOCK_EVT_MODE_ONESHOT:
- case CLOCK_EVT_MODE_UNUSED:
- case CLOCK_EVT_MODE_SHUTDOWN:
- writel(readl(OST_OIER) & ~OST_OIER_E0, OST_OIER);
- writel(readl(OST_OSSR) & ~OST_OSSR_M0, OST_OSSR);
- break;
-
- case CLOCK_EVT_MODE_RESUME:
- case CLOCK_EVT_MODE_PERIODIC:
- break;
- }
+ writel(readl(OST_OIER) & ~OST_OIER_E0, OST_OIER);
+ writel(readl(OST_OSSR) & ~OST_OSSR_M0, OST_OSSR);
+ return 0;
}
static struct clock_event_device ckevt_puv3_osmr0 = {
- .name = "osmr0",
- .features = CLOCK_EVT_FEAT_ONESHOT,
- .rating = 200,
- .set_next_event = puv3_osmr0_set_next_event,
- .set_mode = puv3_osmr0_set_mode,
+ .name = "osmr0",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 200,
+ .set_next_event = puv3_osmr0_set_next_event,
+ .set_state_shutdown = puv3_osmr0_shutdown,
+ .set_state_oneshot = puv3_osmr0_shutdown,
};
static cycle_t puv3_read_oscr(struct clocksource *cs)
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c
index f2b96de3c7c1..efb82f07b29c 100644
--- a/arch/x86/kernel/i8253.c
+++ b/arch/x86/kernel/i8253.c
@@ -34,7 +34,7 @@ static int __init init_pit_clocksource(void)
* - when local APIC timer is active (PIT is switched off)
*/
if (num_possible_cpus() > 1 || is_hpet_enabled() ||
- i8253_clockevent.mode != CLOCK_EVT_MODE_PERIODIC)
+ !clockevent_state_periodic(&i8253_clockevent))
return 0;
return clocksource_i8253_init();
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index 2a1823de69cc..b97767dbc7c8 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -52,8 +52,6 @@ static struct clocksource ccount_clocksource = {
static int ccount_timer_set_next_event(unsigned long delta,
struct clock_event_device *dev);
-static void ccount_timer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt);
struct ccount_timer {
struct clock_event_device evt;
int irq_enabled;
@@ -77,35 +75,34 @@ static int ccount_timer_set_next_event(unsigned long delta,
return ret;
}
-static void ccount_timer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
+/*
+ * There is no way to disable the timer interrupt at the device level,
+ * only at the intenable register itself. Since enable_irq/disable_irq
+ * calls are nested, we need to make sure that these calls are
+ * balanced.
+ */
+static int ccount_timer_shutdown(struct clock_event_device *evt)
+{
+ struct ccount_timer *timer =
+ container_of(evt, struct ccount_timer, evt);
+
+ if (timer->irq_enabled) {
+ disable_irq(evt->irq);
+ timer->irq_enabled = 0;
+ }
+ return 0;
+}
+
+static int ccount_timer_set_oneshot(struct clock_event_device *evt)
{
struct ccount_timer *timer =
container_of(evt, struct ccount_timer, evt);
- /*
- * There is no way to disable the timer interrupt at the device level,
- * only at the intenable register itself. Since enable_irq/disable_irq
- * calls are nested, we need to make sure that these calls are
- * balanced.
- */
- switch (mode) {
- case CLOCK_EVT_MODE_SHUTDOWN:
- case CLOCK_EVT_MODE_UNUSED:
- if (timer->irq_enabled) {
- disable_irq(evt->irq);
- timer->irq_enabled = 0;
- }
- break;
- case CLOCK_EVT_MODE_RESUME:
- case CLOCK_EVT_MODE_ONESHOT:
- if (!timer->irq_enabled) {
- enable_irq(evt->irq);
- timer->irq_enabled = 1;
- }
- default:
- break;
+ if (!timer->irq_enabled) {
+ enable_irq(evt->irq);
+ timer->irq_enabled = 1;
}
+ return 0;
}
static irqreturn_t timer_interrupt(int irq, void *dev_id);
@@ -126,7 +123,9 @@ void local_timer_setup(unsigned cpu)
clockevent->features = CLOCK_EVT_FEAT_ONESHOT;
clockevent->rating = 300;
clockevent->set_next_event = ccount_timer_set_next_event;
- clockevent->set_mode = ccount_timer_set_mode;
+ clockevent->set_state_shutdown = ccount_timer_shutdown;
+ clockevent->set_state_oneshot = ccount_timer_set_oneshot;
+ clockevent->tick_resume = ccount_timer_set_oneshot;
clockevent->cpumask = cpumask_of(cpu);
clockevent->irq = irq_create_mapping(NULL, LINUX_TIMER_INT);
if (WARN(!clockevent->irq, "error: can't map timer irq"))