aboutsummaryrefslogtreecommitdiffstats
path: root/net/rfkill/rfkill.c
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2008-06-23 16:23:02 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-26 14:21:20 -0400
commit526324b61a9667ed9a71f0a8a8899cf675346c76 (patch)
tree4a7697c0987ab4869f2760f06e1ba8e487a91af8 /net/rfkill/rfkill.c
parent477576a073699783abb53ae14993d5d41c66301d (diff)
rfkill: rework suspend and resume handlers
The resume handler should reset the wireless transmitter rfkill state to exactly what it was when the system was suspended. Do it, and do it using the normal routines for state change while at it. The suspend handler should force-switch the transmitter to blocked state, ignoring caches. Do it. Also take an opportunity shot to rfkill_remove_switch() and also force the transmitter to blocked state there, bypassing caches. Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Acked-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/rfkill/rfkill.c')
-rw-r--r--net/rfkill/rfkill.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 79f3bbb027ff..fb566902030a 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -75,24 +75,25 @@ static void update_rfkill_state(struct rfkill *rfkill)
75} 75}
76 76
77static int rfkill_toggle_radio(struct rfkill *rfkill, 77static int rfkill_toggle_radio(struct rfkill *rfkill,
78 enum rfkill_state state) 78 enum rfkill_state state,
79 int force)
79{ 80{
80 int retval = 0; 81 int retval = 0;
81 enum rfkill_state oldstate, newstate; 82 enum rfkill_state oldstate, newstate;
82 83
83 oldstate = rfkill->state; 84 oldstate = rfkill->state;
84 85
85 if (rfkill->get_state && 86 if (rfkill->get_state && !force &&
86 !rfkill->get_state(rfkill->data, &newstate)) 87 !rfkill->get_state(rfkill->data, &newstate))
87 rfkill->state = newstate; 88 rfkill->state = newstate;
88 89
89 if (state != rfkill->state) { 90 if (force || state != rfkill->state) {
90 retval = rfkill->toggle_radio(rfkill->data, state); 91 retval = rfkill->toggle_radio(rfkill->data, state);
91 if (!retval) 92 if (!retval)
92 rfkill->state = state; 93 rfkill->state = state;
93 } 94 }
94 95
95 if (rfkill->state != oldstate) 96 if (force || rfkill->state != oldstate)
96 rfkill_led_trigger(rfkill, rfkill->state); 97 rfkill_led_trigger(rfkill, rfkill->state);
97 98
98 return retval; 99 return retval;
@@ -107,7 +108,6 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
107 * a specific switch is claimed by userspace in which case it is 108 * a specific switch is claimed by userspace in which case it is
108 * left alone. 109 * left alone.
109 */ 110 */
110
111void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) 111void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
112{ 112{
113 struct rfkill *rfkill; 113 struct rfkill *rfkill;
@@ -118,7 +118,7 @@ void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
118 118
119 list_for_each_entry(rfkill, &rfkill_list, node) { 119 list_for_each_entry(rfkill, &rfkill_list, node) {
120 if ((!rfkill->user_claim) && (rfkill->type == type)) 120 if ((!rfkill->user_claim) && (rfkill->type == type))
121 rfkill_toggle_radio(rfkill, state); 121 rfkill_toggle_radio(rfkill, state, 0);
122 } 122 }
123 123
124 mutex_unlock(&rfkill_mutex); 124 mutex_unlock(&rfkill_mutex);
@@ -214,7 +214,8 @@ static ssize_t rfkill_state_store(struct device *dev,
214 if (mutex_lock_interruptible(&rfkill->mutex)) 214 if (mutex_lock_interruptible(&rfkill->mutex))
215 return -ERESTARTSYS; 215 return -ERESTARTSYS;
216 error = rfkill_toggle_radio(rfkill, 216 error = rfkill_toggle_radio(rfkill,
217 state ? RFKILL_STATE_ON : RFKILL_STATE_OFF); 217 state ? RFKILL_STATE_ON : RFKILL_STATE_OFF,
218 0);
218 mutex_unlock(&rfkill->mutex); 219 mutex_unlock(&rfkill->mutex);
219 220
220 return error ? error : count; 221 return error ? error : count;
@@ -255,7 +256,8 @@ static ssize_t rfkill_claim_store(struct device *dev,
255 if (rfkill->user_claim != claim) { 256 if (rfkill->user_claim != claim) {
256 if (!claim) 257 if (!claim)
257 rfkill_toggle_radio(rfkill, 258 rfkill_toggle_radio(rfkill,
258 rfkill_states[rfkill->type]); 259 rfkill_states[rfkill->type],
260 0);
259 rfkill->user_claim = claim; 261 rfkill->user_claim = claim;
260 } 262 }
261 263
@@ -288,12 +290,11 @@ static int rfkill_suspend(struct device *dev, pm_message_t state)
288 290
289 if (dev->power.power_state.event != state.event) { 291 if (dev->power.power_state.event != state.event) {
290 if (state.event & PM_EVENT_SLEEP) { 292 if (state.event & PM_EVENT_SLEEP) {
291 mutex_lock(&rfkill->mutex); 293 /* Stop transmitter, keep state, no notifies */
292 294 update_rfkill_state(rfkill);
293 if (rfkill->state == RFKILL_STATE_ON)
294 rfkill->toggle_radio(rfkill->data,
295 RFKILL_STATE_OFF);
296 295
296 mutex_lock(&rfkill->mutex);
297 rfkill->toggle_radio(rfkill->data, RFKILL_STATE_OFF);
297 mutex_unlock(&rfkill->mutex); 298 mutex_unlock(&rfkill->mutex);
298 } 299 }
299 300
@@ -310,8 +311,8 @@ static int rfkill_resume(struct device *dev)
310 if (dev->power.power_state.event != PM_EVENT_ON) { 311 if (dev->power.power_state.event != PM_EVENT_ON) {
311 mutex_lock(&rfkill->mutex); 312 mutex_lock(&rfkill->mutex);
312 313
313 if (rfkill->state == RFKILL_STATE_ON) 314 /* restore radio state AND notify everybody */
314 rfkill->toggle_radio(rfkill->data, RFKILL_STATE_ON); 315 rfkill_toggle_radio(rfkill, rfkill->state, 1);
315 316
316 mutex_unlock(&rfkill->mutex); 317 mutex_unlock(&rfkill->mutex);
317 } 318 }
@@ -338,7 +339,7 @@ static int rfkill_add_switch(struct rfkill *rfkill)
338 339
339 mutex_lock(&rfkill_mutex); 340 mutex_lock(&rfkill_mutex);
340 341
341 error = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]); 342 error = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type], 0);
342 if (!error) 343 if (!error)
343 list_add_tail(&rfkill->node, &rfkill_list); 344 list_add_tail(&rfkill->node, &rfkill_list);
344 345
@@ -351,7 +352,7 @@ static void rfkill_remove_switch(struct rfkill *rfkill)
351{ 352{
352 mutex_lock(&rfkill_mutex); 353 mutex_lock(&rfkill_mutex);
353 list_del_init(&rfkill->node); 354 list_del_init(&rfkill->node);
354 rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF); 355 rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF, 1);
355 mutex_unlock(&rfkill_mutex); 356 mutex_unlock(&rfkill_mutex);
356} 357}
357 358