summary refs log tree commit diff
path: root/net/rfkill
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2008-11-21 20:40:09 -0200
committerJohn W. Linville <linville@tuxdriver.com>2008-11-26 09:47:43 -0500
commitf80b5e99c7dac5a9a0d72496cec5075a12cd1476 (patch)
tree493b11de9639655fbf2a9431f9def759ab3f6a27 /net/rfkill
parent5925d976fbe99859d636e7075e5304625503c5fe (diff)
downloadlinux-f80b5e99c7dac5a9a0d72496cec5075a12cd1476.tar.gz
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.c7
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)
 #ifdef CONFIG_PM
 static int rfkill_suspend(struct device *dev, pm_message_t state)
 {
+	struct rfkill *rfkill = to_rfkill(dev);
+
 	/* mark class device as suspended */
 	if (dev->power.power_state.event != state.event)
 		dev->power.power_state = state;
 
+	/* store state for the resume handler */
+	rfkill->state_for_resume = rfkill->state;
+
 	return 0;
 }
 
@@ -590,7 +595,7 @@ static int rfkill_resume(struct device *dev)
 		rfkill_toggle_radio(rfkill,
 				rfkill_epo_lock_active ?
 					RFKILL_STATE_SOFT_BLOCKED :
-					rfkill->state,
+					rfkill->state_for_resume,
 				1);
 
 		mutex_unlock(&rfkill->mutex);