Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
clockevents: make device shutdown robust
clocksource, acpi_pm.c: fix check for monotonicity
clockevents: remove WARN_ON which was used to gather information

+29 -19
+10 -11
drivers/clocksource/acpi_pm.c
··· 178 179 /* Number of monotonicity checks to perform during initialization */ 180 #define ACPI_PM_MONOTONICITY_CHECKS 10 181 182 static int __init init_acpi_pm_clocksource(void) 183 { 184 cycle_t value1, value2; 185 - unsigned int i, j, good = 0; 186 187 if (!pmtmr_ioport) 188 return -ENODEV; ··· 194 195 /* "verify" this timing source: */ 196 for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) { 197 value1 = clocksource_acpi_pm.read(); 198 - for (i = 0; i < 10000; i++) { 199 value2 = clocksource_acpi_pm.read(); 200 if (value2 == value1) 201 continue; 202 if (value2 > value1) 203 - good++; 204 break; 205 if ((value2 < value1) && ((value2) < 0xFFF)) 206 - good++; 207 break; 208 printk(KERN_INFO "PM-Timer had inconsistent results:" 209 " 0x%#llx, 0x%#llx - aborting.\n", 210 value1, value2); 211 return -EINVAL; 212 } 213 - udelay(300 * i); 214 - } 215 - 216 - if (good != ACPI_PM_MONOTONICITY_CHECKS) { 217 - printk(KERN_INFO "PM-Timer failed consistency check " 218 - " (0x%#llx) - aborting.\n", value1); 219 - return -ENODEV; 220 } 221 222 if (verify_pmtmr_rate() != 0)
··· 178 179 /* Number of monotonicity checks to perform during initialization */ 180 #define ACPI_PM_MONOTONICITY_CHECKS 10 181 + /* Number of reads we try to get two different values */ 182 + #define ACPI_PM_READ_CHECKS 10000 183 184 static int __init init_acpi_pm_clocksource(void) 185 { 186 cycle_t value1, value2; 187 + unsigned int i, j = 0; 188 189 if (!pmtmr_ioport) 190 return -ENODEV; ··· 192 193 /* "verify" this timing source: */ 194 for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) { 195 + udelay(100 * j); 196 value1 = clocksource_acpi_pm.read(); 197 + for (i = 0; i < ACPI_PM_READ_CHECKS; i++) { 198 value2 = clocksource_acpi_pm.read(); 199 if (value2 == value1) 200 continue; 201 if (value2 > value1) 202 break; 203 if ((value2 < value1) && ((value2) < 0xFFF)) 204 break; 205 printk(KERN_INFO "PM-Timer had inconsistent results:" 206 " 0x%#llx, 0x%#llx - aborting.\n", 207 value1, value2); 208 return -EINVAL; 209 } 210 + if (i == ACPI_PM_READ_CHECKS) { 211 + printk(KERN_INFO "PM-Timer failed consistency check " 212 + " (0x%#llx) - aborting.\n", value1); 213 + return -ENODEV; 214 + } 215 } 216 217 if (verify_pmtmr_rate() != 0)
+11 -1
kernel/time/clockevents.c
··· 72 } 73 74 /** 75 * clockevents_program_event - Reprogram the clock event device. 76 * @expires: absolute expiry time (monotonic clock) 77 * ··· 216 217 if (new) { 218 BUG_ON(new->mode != CLOCK_EVT_MODE_UNUSED); 219 - clockevents_set_mode(new, CLOCK_EVT_MODE_SHUTDOWN); 220 } 221 local_irq_restore(flags); 222 }
··· 72 } 73 74 /** 75 + * clockevents_shutdown - shutdown the device and clear next_event 76 + * @dev: device to shutdown 77 + */ 78 + void clockevents_shutdown(struct clock_event_device *dev) 79 + { 80 + clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN); 81 + dev->next_event.tv64 = KTIME_MAX; 82 + } 83 + 84 + /** 85 * clockevents_program_event - Reprogram the clock event device. 86 * @expires: absolute expiry time (monotonic clock) 87 * ··· 206 207 if (new) { 208 BUG_ON(new->mode != CLOCK_EVT_MODE_UNUSED); 209 + clockevents_shutdown(new); 210 } 211 local_irq_restore(flags); 212 }
+4 -5
kernel/time/tick-broadcast.c
··· 236 if (!cpu_isset(cpu, tick_broadcast_mask)) { 237 cpu_set(cpu, tick_broadcast_mask); 238 if (td->mode == TICKDEV_MODE_PERIODIC) 239 - clockevents_set_mode(dev, 240 - CLOCK_EVT_MODE_SHUTDOWN); 241 } 242 if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE) 243 tick_broadcast_force = 1; ··· 253 254 if (cpus_empty(tick_broadcast_mask)) { 255 if (!bc_stopped) 256 - clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); 257 } else if (bc_stopped) { 258 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) 259 tick_broadcast_start_periodic(bc); ··· 305 306 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) { 307 if (bc && cpus_empty(tick_broadcast_mask)) 308 - clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); 309 } 310 311 spin_unlock_irqrestore(&tick_broadcast_lock, flags); ··· 320 321 bc = tick_broadcast_device.evtdev; 322 if (bc) 323 - clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN); 324 325 spin_unlock_irqrestore(&tick_broadcast_lock, flags); 326 }
··· 236 if (!cpu_isset(cpu, tick_broadcast_mask)) { 237 cpu_set(cpu, tick_broadcast_mask); 238 if (td->mode == TICKDEV_MODE_PERIODIC) 239 + clockevents_shutdown(dev); 240 } 241 if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE) 242 tick_broadcast_force = 1; ··· 254 255 if (cpus_empty(tick_broadcast_mask)) { 256 if (!bc_stopped) 257 + clockevents_shutdown(bc); 258 } else if (bc_stopped) { 259 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) 260 tick_broadcast_start_periodic(bc); ··· 306 307 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) { 308 if (bc && cpus_empty(tick_broadcast_mask)) 309 + clockevents_shutdown(bc); 310 } 311 312 spin_unlock_irqrestore(&tick_broadcast_lock, flags); ··· 321 322 bc = tick_broadcast_device.evtdev; 323 if (bc) 324 + clockevents_shutdown(bc); 325 326 spin_unlock_irqrestore(&tick_broadcast_lock, flags); 327 }
+2 -2
kernel/time/tick-common.c
··· 249 * not give it back to the clockevents layer ! 250 */ 251 if (tick_is_broadcast_device(curdev)) { 252 - clockevents_set_mode(curdev, CLOCK_EVT_MODE_SHUTDOWN); 253 curdev = NULL; 254 } 255 clockevents_exchange_device(curdev, newdev); ··· 311 unsigned long flags; 312 313 spin_lock_irqsave(&tick_device_lock, flags); 314 - clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_SHUTDOWN); 315 spin_unlock_irqrestore(&tick_device_lock, flags); 316 } 317
··· 249 * not give it back to the clockevents layer ! 250 */ 251 if (tick_is_broadcast_device(curdev)) { 252 + clockevents_shutdown(curdev); 253 curdev = NULL; 254 } 255 clockevents_exchange_device(curdev, newdev); ··· 311 unsigned long flags; 312 313 spin_lock_irqsave(&tick_device_lock, flags); 314 + clockevents_shutdown(td->evtdev); 315 spin_unlock_irqrestore(&tick_device_lock, flags); 316 } 317
+2
kernel/time/tick-internal.h
··· 10 extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast); 11 extern void tick_handle_periodic(struct clock_event_device *dev); 12 13 /* 14 * NO_HZ / high resolution timer shared code 15 */
··· 10 extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast); 11 extern void tick_handle_periodic(struct clock_event_device *dev); 12 13 + extern void clockevents_shutdown(struct clock_event_device *dev); 14 + 15 /* 16 * NO_HZ / high resolution timer shared code 17 */