aboutsummaryrefslogtreecommitdiffstats
path: root/net/rfkill/rfkill.c
diff options
context:
space:
mode:
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