CLOCK_EVT_NOTIFY_ADD,
CLOCK_EVT_NOTIFY_BROADCAST_ON,
CLOCK_EVT_NOTIFY_BROADCAST_OFF,
+ CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
CLOCK_EVT_NOTIFY_SUSPEND,
bc = tick_broadcast_device.evtdev;
/*
- * Is the device in broadcast mode forever or is it not
- * affected by the powerstate ?
+ * Is the device not affected by the powerstate ?
*/
- if (!dev || !tick_device_is_functional(dev) ||
- !(dev->features & CLOCK_EVT_FEAT_C3STOP))
+ if (!dev || !(dev->features & CLOCK_EVT_FEAT_C3STOP))
goto out;
- if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_ON) {
+ /*
+ * Defect device ?
+ */
+ if (!tick_device_is_functional(dev)) {
+ /*
+ * AMD C1E wreckage fixup:
+ *
+ * Device was registered functional in the first
+ * place. Now the secondary CPU detected the C1E
+ * misfeature and notifies us to fix it up
+ */
+ if (*reason != CLOCK_EVT_NOTIFY_BROADCAST_FORCE)
+ goto out;
+ }
+
+ switch (*reason) {
+ case CLOCK_EVT_NOTIFY_BROADCAST_ON:
+ case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
if (!cpu_isset(cpu, tick_broadcast_mask)) {
cpu_set(cpu, tick_broadcast_mask);
if (td->mode == TICKDEV_MODE_PERIODIC)
clockevents_set_mode(dev,
CLOCK_EVT_MODE_SHUTDOWN);
}
- } else {
+ break;
+ case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
if (cpu_isset(cpu, tick_broadcast_mask)) {
cpu_clear(cpu, tick_broadcast_mask);
if (td->mode == TICKDEV_MODE_PERIODIC)
tick_setup_periodic(dev, 0);
}
+ break;
}
if (cpus_empty(tick_broadcast_mask))