Skip to content
Snippets Groups Projects
Commit 5e359bf2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
  ...
parents 8d01b66b 85e1cd6e
No related branches found
No related tags found
No related merge requests found
Showing
with 267 additions and 365 deletions
......@@ -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,
};
......
......@@ -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);
......
......@@ -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)
......
......@@ -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,
};
......
......@@ -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)
......
......@@ -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;
......
......@@ -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)
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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)
......
......@@ -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);
......
......@@ -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? */
......
......@@ -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;
......
......@@ -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);
......
......@@ -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)
......
......@@ -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)
......
......@@ -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();
......
......@@ -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"))
......
......@@ -277,7 +277,7 @@ config CLKSRC_MIPS_GIC
config CLKSRC_PXA
def_bool y if ARCH_PXA || ARCH_SA1100
select CLKSRC_OF if USE_OF
select CLKSRC_OF if OF
help
This enables OST0 support available on PXA and SA-11x0
platforms.
......
......@@ -181,44 +181,36 @@ static irqreturn_t arch_timer_handler_virt_mem(int irq, void *dev_id)
return timer_handler(ARCH_TIMER_MEM_VIRT_ACCESS, evt);
}
static __always_inline void timer_set_mode(const int access, int mode,
struct clock_event_device *clk)
static __always_inline int timer_shutdown(const int access,
struct clock_event_device *clk)
{
unsigned long ctrl;
switch (mode) {
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
break;
default:
break;
}
ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk);
ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
return 0;
}
static void arch_timer_set_mode_virt(enum clock_event_mode mode,
struct clock_event_device *clk)
static int arch_timer_shutdown_virt(struct clock_event_device *clk)
{
timer_set_mode(ARCH_TIMER_VIRT_ACCESS, mode, clk);
return timer_shutdown(ARCH_TIMER_VIRT_ACCESS, clk);
}
static void arch_timer_set_mode_phys(enum clock_event_mode mode,
struct clock_event_device *clk)
static int arch_timer_shutdown_phys(struct clock_event_device *clk)
{
timer_set_mode(ARCH_TIMER_PHYS_ACCESS, mode, clk);
return timer_shutdown(ARCH_TIMER_PHYS_ACCESS, clk);
}
static void arch_timer_set_mode_virt_mem(enum clock_event_mode mode,
struct clock_event_device *clk)
static int arch_timer_shutdown_virt_mem(struct clock_event_device *clk)
{
timer_set_mode(ARCH_TIMER_MEM_VIRT_ACCESS, mode, clk);
return timer_shutdown(ARCH_TIMER_MEM_VIRT_ACCESS, clk);
}
static void arch_timer_set_mode_phys_mem(enum clock_event_mode mode,
struct clock_event_device *clk)
static int arch_timer_shutdown_phys_mem(struct clock_event_device *clk)
{
timer_set_mode(ARCH_TIMER_MEM_PHYS_ACCESS, mode, clk);
return timer_shutdown(ARCH_TIMER_MEM_PHYS_ACCESS, clk);
}
static __always_inline void set_next_event(const int access, unsigned long evt,
......@@ -273,11 +265,11 @@ static void __arch_timer_setup(unsigned type,
clk->cpumask = cpumask_of(smp_processor_id());
if (arch_timer_use_virtual) {
clk->irq = arch_timer_ppi[VIRT_PPI];
clk->set_mode = arch_timer_set_mode_virt;
clk->set_state_shutdown = arch_timer_shutdown_virt;
clk->set_next_event = arch_timer_set_next_event_virt;
} else {
clk->irq = arch_timer_ppi[PHYS_SECURE_PPI];
clk->set_mode = arch_timer_set_mode_phys;
clk->set_state_shutdown = arch_timer_shutdown_phys;
clk->set_next_event = arch_timer_set_next_event_phys;
}
} else {
......@@ -286,17 +278,17 @@ static void __arch_timer_setup(unsigned type,
clk->rating = 400;
clk->cpumask = cpu_all_mask;
if (arch_timer_mem_use_virtual) {
clk->set_mode = arch_timer_set_mode_virt_mem;
clk->set_state_shutdown = arch_timer_shutdown_virt_mem;
clk->set_next_event =
arch_timer_set_next_event_virt_mem;
} else {
clk->set_mode = arch_timer_set_mode_phys_mem;
clk->set_state_shutdown = arch_timer_shutdown_phys_mem;
clk->set_next_event =
arch_timer_set_next_event_phys_mem;
}
}
clk->set_mode(CLOCK_EVT_MODE_SHUTDOWN, clk);
clk->set_state_shutdown(clk);
clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff);
}
......@@ -506,7 +498,7 @@ static void arch_timer_stop(struct clock_event_device *clk)
disable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI]);
}
clk->set_mode(CLOCK_EVT_MODE_UNUSED, clk);
clk->set_state_shutdown(clk);
}
static int arch_timer_cpu_notify(struct notifier_block *self,
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment