aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2015-02-27 06:51:32 -0500
committerIngo Molnar <mingo@kernel.org>2015-03-27 05:26:19 -0400
commit554ef3876c6acdff1331feab10275e9e9e0adb84 (patch)
treee01d4c83d5f177e814e5cd749206ef9801081b2b
parentfe5fba05b46c791c95a9f34228ac495f81f72fc0 (diff)
clockevents: Handle tick device's resume separately
Upcoming patch will redefine possible states of a clockevent device. The RESUME mode is a special case only for tick's clockevent devices. In future it can be replaced by ->resume() callback already available for clockevent devices. Lets handle it separately so that clockevents_set_mode() only handles states valid across all devices. This also renames set_mode_resume() to tick_resume() to make it more explicit. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Kevin Hilman <khilman@linaro.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Preeti U Murthy <preeti@linux.vnet.ibm.com> Cc: linaro-kernel@lists.linaro.org Cc: linaro-networking@linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/c1b0112410870f49e7bf06958e1483eac6c15e20.1425037853.git.viresh.kumar@linaro.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--include/linux/clockchips.h4
-rw-r--r--kernel/time/clockevents.c30
-rw-r--r--kernel/time/tick-broadcast.c2
-rw-r--r--kernel/time/tick-common.c2
-rw-r--r--kernel/time/tick-internal.h1
-rw-r--r--kernel/time/timer_list.c4
6 files changed, 28 insertions, 15 deletions
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 59af26b54d15..a41749543d48 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -87,7 +87,7 @@ enum clock_event_mode {
87 * @set_mode_periodic: switch mode to periodic, if !set_mode 87 * @set_mode_periodic: switch mode to periodic, if !set_mode
88 * @set_mode_oneshot: switch mode to oneshot, if !set_mode 88 * @set_mode_oneshot: switch mode to oneshot, if !set_mode
89 * @set_mode_shutdown: switch mode to shutdown, if !set_mode 89 * @set_mode_shutdown: switch mode to shutdown, if !set_mode
90 * @set_mode_resume: resume clkevt device, if !set_mode 90 * @tick_resume: resume clkevt device, if !set_mode
91 * @broadcast: function to broadcast events 91 * @broadcast: function to broadcast events
92 * @min_delta_ticks: minimum delta value in ticks stored for reconfiguration 92 * @min_delta_ticks: minimum delta value in ticks stored for reconfiguration
93 * @max_delta_ticks: maximum delta value in ticks stored for reconfiguration 93 * @max_delta_ticks: maximum delta value in ticks stored for reconfiguration
@@ -125,7 +125,7 @@ struct clock_event_device {
125 int (*set_mode_periodic)(struct clock_event_device *); 125 int (*set_mode_periodic)(struct clock_event_device *);
126 int (*set_mode_oneshot)(struct clock_event_device *); 126 int (*set_mode_oneshot)(struct clock_event_device *);
127 int (*set_mode_shutdown)(struct clock_event_device *); 127 int (*set_mode_shutdown)(struct clock_event_device *);
128 int (*set_mode_resume)(struct clock_event_device *); 128 int (*tick_resume)(struct clock_event_device *);
129 129
130 void (*broadcast)(const struct cpumask *mask); 130 void (*broadcast)(const struct cpumask *mask);
131 void (*suspend)(struct clock_event_device *); 131 void (*suspend)(struct clock_event_device *);
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 489642b08d64..1b0ea63de69c 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -100,7 +100,7 @@ static int __clockevents_set_mode(struct clock_event_device *dev,
100 /* Transition with legacy set_mode() callback */ 100 /* Transition with legacy set_mode() callback */
101 if (dev->set_mode) { 101 if (dev->set_mode) {
102 /* Legacy callback doesn't support new modes */ 102 /* Legacy callback doesn't support new modes */
103 if (mode > CLOCK_EVT_MODE_RESUME) 103 if (mode > CLOCK_EVT_MODE_ONESHOT)
104 return -ENOSYS; 104 return -ENOSYS;
105 dev->set_mode(mode, dev); 105 dev->set_mode(mode, dev);
106 return 0; 106 return 0;
@@ -133,13 +133,6 @@ static int __clockevents_set_mode(struct clock_event_device *dev,
133 return -ENOSYS; 133 return -ENOSYS;
134 return dev->set_mode_oneshot(dev); 134 return dev->set_mode_oneshot(dev);
135 135
136 case CLOCK_EVT_MODE_RESUME:
137 /* Optional callback */
138 if (dev->set_mode_resume)
139 return dev->set_mode_resume(dev);
140 else
141 return 0;
142
143 default: 136 default:
144 return -ENOSYS; 137 return -ENOSYS;
145 } 138 }
@@ -184,6 +177,25 @@ void clockevents_shutdown(struct clock_event_device *dev)
184 dev->next_event.tv64 = KTIME_MAX; 177 dev->next_event.tv64 = KTIME_MAX;
185} 178}
186 179
180/**
181 * clockevents_tick_resume - Resume the tick device before using it again
182 * @dev: device to resume
183 */
184int clockevents_tick_resume(struct clock_event_device *dev)
185{
186 int ret = 0;
187
188 if (dev->set_mode)
189 dev->set_mode(CLOCK_EVT_MODE_RESUME, dev);
190 else if (dev->tick_resume)
191 ret = dev->tick_resume(dev);
192
193 if (likely(!ret))
194 dev->mode = CLOCK_EVT_MODE_RESUME;
195
196 return ret;
197}
198
187#ifdef CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST 199#ifdef CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST
188 200
189/* Limit min_delta to a jiffie */ 201/* Limit min_delta to a jiffie */
@@ -433,7 +445,7 @@ static int clockevents_sanity_check(struct clock_event_device *dev)
433 if (dev->set_mode) { 445 if (dev->set_mode) {
434 /* We shouldn't be supporting new modes now */ 446 /* We shouldn't be supporting new modes now */
435 WARN_ON(dev->set_mode_periodic || dev->set_mode_oneshot || 447 WARN_ON(dev->set_mode_periodic || dev->set_mode_oneshot ||
436 dev->set_mode_shutdown || dev->set_mode_resume); 448 dev->set_mode_shutdown || dev->tick_resume);
437 return 0; 449 return 0;
438 } 450 }
439 451
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 066f0ec05e48..542d5bb5c13d 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -464,7 +464,7 @@ int tick_resume_broadcast(void)
464 bc = tick_broadcast_device.evtdev; 464 bc = tick_broadcast_device.evtdev;
465 465
466 if (bc) { 466 if (bc) {
467 clockevents_set_mode(bc, CLOCK_EVT_MODE_RESUME); 467 clockevents_tick_resume(bc);
468 468
469 switch (tick_broadcast_device.mode) { 469 switch (tick_broadcast_device.mode) {
470 case TICKDEV_MODE_PERIODIC: 470 case TICKDEV_MODE_PERIODIC:
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index f7c515595b42..5c50664c21d7 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -384,7 +384,7 @@ void tick_resume(void)
384 struct tick_device *td = this_cpu_ptr(&tick_cpu_device); 384 struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
385 int broadcast = tick_resume_broadcast(); 385 int broadcast = tick_resume_broadcast();
386 386
387 clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_RESUME); 387 clockevents_tick_resume(td->evtdev);
388 388
389 if (!broadcast) { 389 if (!broadcast) {
390 if (td->mode == TICKDEV_MODE_PERIODIC) 390 if (td->mode == TICKDEV_MODE_PERIODIC)
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index 366aeb4f2c66..98700e4a2000 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -32,6 +32,7 @@ extern bool tick_check_replacement(struct clock_event_device *curdev,
32extern void tick_install_replacement(struct clock_event_device *dev); 32extern void tick_install_replacement(struct clock_event_device *dev);
33 33
34extern void clockevents_shutdown(struct clock_event_device *dev); 34extern void clockevents_shutdown(struct clock_event_device *dev);
35extern int clockevents_tick_resume(struct clock_event_device *dev);
35 36
36extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt); 37extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt);
37 38
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index 2cfd19485824..2b3e9393034d 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -251,9 +251,9 @@ print_tickdevice(struct seq_file *m, struct tick_device *td, int cpu)
251 SEQ_printf(m, "\n"); 251 SEQ_printf(m, "\n");
252 } 252 }
253 253
254 if (dev->set_mode_resume) { 254 if (dev->tick_resume) {
255 SEQ_printf(m, " resume: "); 255 SEQ_printf(m, " resume: ");
256 print_name_offset(m, dev->set_mode_resume); 256 print_name_offset(m, dev->tick_resume);
257 SEQ_printf(m, "\n"); 257 SEQ_printf(m, "\n");
258 } 258 }
259 } 259 }