diff options
| author | Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 2008-11-21 17:40:09 -0500 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2008-11-26 09:47:43 -0500 |
| commit | f80b5e99c7dac5a9a0d72496cec5075a12cd1476 (patch) | |
| tree | 493b11de9639655fbf2a9431f9def759ab3f6a27 /net/rfkill | |
| parent | 5925d976fbe99859d636e7075e5304625503c5fe (diff) | |
rfkill: preserve state across suspend
The rfkill class API requires that the driver connected to a class
call rfkill_force_state() on resume to update the real state of the
rfkill controller, OR that it provides a get_state() hook.
This means there is potentially a hidden call in the resume code flow
that changes rfkill->state (i.e. rfkill_force_state()), so the
previous state of the transmitter was being lost.
The simplest and most future-proof way to fix this is to explicitly
store the pre-sleep state on the rfkill structure, and restore from
that on resume.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
Cc: Matthew Garrett <mjg59@srcf.ucam.org>
Cc: Alan Jenkins <alan-jenkins@tuffmail.co.uk>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/rfkill')
| -rw-r--r-- | net/rfkill/rfkill.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index ec26eae8004d..5ad411d3e8f8 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c | |||
| @@ -565,10 +565,15 @@ static void rfkill_release(struct device *dev) | |||
| 565 | #ifdef CONFIG_PM | 565 | #ifdef CONFIG_PM |
| 566 | static int rfkill_suspend(struct device *dev, pm_message_t state) | 566 | static int rfkill_suspend(struct device *dev, pm_message_t state) |
| 567 | { | 567 | { |
| 568 | struct rfkill *rfkill = to_rfkill(dev); | ||
| 569 | |||
| 568 | /* mark class device as suspended */ | 570 | /* mark class device as suspended */ |
| 569 | if (dev->power.power_state.event != state.event) | 571 | if (dev->power.power_state.event != state.event) |
| 570 | dev->power.power_state = state; | 572 | dev->power.power_state = state; |
| 571 | 573 | ||
| 574 | /* store state for the resume handler */ | ||
| 575 | rfkill->state_for_resume = rfkill->state; | ||
| 576 | |||
| 572 | return 0; | 577 | return 0; |
| 573 | } | 578 | } |
| 574 | 579 | ||
| @@ -590,7 +595,7 @@ static int rfkill_resume(struct device *dev) | |||
| 590 | rfkill_toggle_radio(rfkill, | 595 | rfkill_toggle_radio(rfkill, |
| 591 | rfkill_epo_lock_active ? | 596 | rfkill_epo_lock_active ? |
| 592 | RFKILL_STATE_SOFT_BLOCKED : | 597 | RFKILL_STATE_SOFT_BLOCKED : |
| 593 | rfkill->state, | 598 | rfkill->state_for_resume, |
| 594 | 1); | 599 | 1); |
| 595 | 600 | ||
| 596 | mutex_unlock(&rfkill->mutex); | 601 | mutex_unlock(&rfkill->mutex); |
