@@ -81,7 +81,8 @@ enum clock_event_mode {
* @mode: operating mode assigned by the management code
* @features: features
* @retries: number of forced programming retries
- * @set_mode: set mode function
+ * @set_dev_mode: set dev mode function
+ * @set_mode: set mode function (deprecated, use set_dev_mode instead)
* @broadcast: function to broadcast events
* @min_delta_ticks: minimum delta value in ticks stored for reconfiguration
* @max_delta_ticks: maximum delta value in ticks stored for reconfiguration
@@ -109,6 +110,8 @@ struct clock_event_device {
unsigned long retries;
void (*broadcast)(const struct cpumask *mask);
+ int (*set_dev_mode)(enum clock_event_mode mode,
+ struct clock_event_device *);
void (*set_mode)(enum clock_event_mode mode,
struct clock_event_device *);
void (*suspend)(struct clock_event_device *);
@@ -105,7 +105,16 @@ void clockevents_set_mode(struct clock_event_device *dev,
enum clock_event_mode mode)
{
if (dev->mode != mode) {
- dev->set_mode(mode, dev);
+ if (dev->set_dev_mode) {
+ int ret = dev->set_dev_mode(mode, dev);
+
+ /* Currently available modes shouldn't fail */
+ WARN_ONCE(ret, "Requested mode: %d, error: %d\n",
+ mode, ret);
+ } else {
+ dev->set_mode(mode, dev);
+ }
+
dev->mode = mode;
/*
@@ -446,8 +455,14 @@ int __clockevents_update_freq(struct clock_event_device *dev, u32 freq)
if (dev->mode == CLOCK_EVT_MODE_ONESHOT)
return clockevents_program_event(dev, dev->next_event, false);
- if (dev->mode == CLOCK_EVT_MODE_PERIODIC)
- dev->set_mode(CLOCK_EVT_MODE_PERIODIC, dev);
+ if (dev->mode == CLOCK_EVT_MODE_PERIODIC) {
+ /* Shouldn't fail while switching to PERIODIC MODE */
+ if (dev->set_dev_mode)
+ WARN_ON_ONCE(dev->set_dev_mode(CLOCK_EVT_MODE_PERIODIC,
+ dev));
+ else
+ dev->set_mode(CLOCK_EVT_MODE_PERIODIC, dev);
+ }
return 0;
}
@@ -229,7 +229,10 @@ print_tickdevice(struct seq_file *m, struct tick_device *td, int cpu)
SEQ_printf(m, "\n");
SEQ_printf(m, " set_mode: ");
- print_name_offset(m, dev->set_mode);
+ if (dev->set_dev_mode)
+ print_name_offset(m, dev->set_dev_mode);
+ else
+ print_name_offset(m, dev->set_mode);
SEQ_printf(m, "\n");
SEQ_printf(m, " event_handler: ");