.. | .. |
---|
248 | 248 | } else { |
---|
249 | 249 | handler = td->evtdev->event_handler; |
---|
250 | 250 | next_event = td->evtdev->next_event; |
---|
251 | | - td->evtdev->event_handler = clockevents_handle_noop; |
---|
| 251 | + if (!clockevent_state_reserved(td->evtdev)) |
---|
| 252 | + td->evtdev->event_handler = clockevents_handle_noop; |
---|
252 | 253 | } |
---|
253 | 254 | |
---|
254 | 255 | td->evtdev = newdev; |
---|
.. | .. |
---|
330 | 331 | bool tick_check_replacement(struct clock_event_device *curdev, |
---|
331 | 332 | struct clock_event_device *newdev) |
---|
332 | 333 | { |
---|
| 334 | + /* |
---|
| 335 | + * Never replace an active proxy except when unregistering it. |
---|
| 336 | + */ |
---|
| 337 | + if (tick_check_is_proxy(curdev)) |
---|
| 338 | + return false; |
---|
| 339 | + |
---|
333 | 340 | if (!tick_check_percpu(curdev, newdev, smp_processor_id())) |
---|
334 | 341 | return false; |
---|
335 | 342 | |
---|
.. | .. |
---|
350 | 357 | td = &per_cpu(tick_cpu_device, cpu); |
---|
351 | 358 | curdev = td->evtdev; |
---|
352 | 359 | |
---|
| 360 | + if (tick_check_is_proxy(curdev)) |
---|
| 361 | + goto out_bc; |
---|
| 362 | + |
---|
353 | 363 | /* cpu local device ? */ |
---|
354 | 364 | if (!tick_check_percpu(curdev, newdev, cpu)) |
---|
355 | 365 | goto out_bc; |
---|
.. | .. |
---|
367 | 377 | * not give it back to the clockevents layer ! |
---|
368 | 378 | */ |
---|
369 | 379 | if (tick_is_broadcast_device(curdev)) { |
---|
370 | | - clockevents_shutdown(curdev); |
---|
| 380 | + if (tick_check_is_proxy(newdev)) { |
---|
| 381 | + list_del(&curdev->list); |
---|
| 382 | + clockevents_switch_state(curdev, CLOCK_EVT_STATE_RESERVED); |
---|
| 383 | + } else { |
---|
| 384 | + clockevents_shutdown(curdev); |
---|
| 385 | + } |
---|
371 | 386 | curdev = NULL; |
---|
372 | 387 | } |
---|
373 | 388 | clockevents_exchange_device(curdev, newdev); |
---|