| .. | .. |
|---|
| 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); |
|---|