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.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index fdf87d2ab25e..e348eab756f3 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -51,6 +51,7 @@ struct rfkill_gsw_state {
51 51
52static struct rfkill_gsw_state rfkill_global_states[RFKILL_TYPE_MAX]; 52static struct rfkill_gsw_state rfkill_global_states[RFKILL_TYPE_MAX];
53static unsigned long rfkill_states_lockdflt[BITS_TO_LONGS(RFKILL_TYPE_MAX)]; 53static unsigned long rfkill_states_lockdflt[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
54static bool rfkill_epo_lock_active;
54 55
55static BLOCKING_NOTIFIER_HEAD(rfkill_notifier_list); 56static BLOCKING_NOTIFIER_HEAD(rfkill_notifier_list);
56 57
@@ -264,11 +265,14 @@ static void __rfkill_switch_all(const enum rfkill_type type,
264 * 265 *
265 * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state). 266 * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state).
266 * Please refer to __rfkill_switch_all() for details. 267 * Please refer to __rfkill_switch_all() for details.
268 *
269 * Does nothing if the EPO lock is active.
267 */ 270 */
268void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) 271void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
269{ 272{
270 mutex_lock(&rfkill_global_mutex); 273 mutex_lock(&rfkill_global_mutex);
271 __rfkill_switch_all(type, state); 274 if (!rfkill_epo_lock_active)
275 __rfkill_switch_all(type, state);
272 mutex_unlock(&rfkill_global_mutex); 276 mutex_unlock(&rfkill_global_mutex);
273} 277}
274EXPORT_SYMBOL(rfkill_switch_all); 278EXPORT_SYMBOL(rfkill_switch_all);
@@ -289,6 +293,7 @@ void rfkill_epo(void)
289 293
290 mutex_lock(&rfkill_global_mutex); 294 mutex_lock(&rfkill_global_mutex);
291 295
296 rfkill_epo_lock_active = true;
292 list_for_each_entry(rfkill, &rfkill_list, node) { 297 list_for_each_entry(rfkill, &rfkill_list, node) {
293 mutex_lock(&rfkill->mutex); 298 mutex_lock(&rfkill->mutex);
294 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); 299 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
@@ -317,6 +322,7 @@ void rfkill_restore_states(void)
317 322
318 mutex_lock(&rfkill_global_mutex); 323 mutex_lock(&rfkill_global_mutex);
319 324
325 rfkill_epo_lock_active = false;
320 for (i = 0; i < RFKILL_TYPE_MAX; i++) 326 for (i = 0; i < RFKILL_TYPE_MAX; i++)
321 __rfkill_switch_all(i, rfkill_global_states[i].default_state); 327 __rfkill_switch_all(i, rfkill_global_states[i].default_state);
322 mutex_unlock(&rfkill_global_mutex); 328 mutex_unlock(&rfkill_global_mutex);
@@ -324,6 +330,35 @@ void rfkill_restore_states(void)
324EXPORT_SYMBOL_GPL(rfkill_restore_states); 330EXPORT_SYMBOL_GPL(rfkill_restore_states);
325 331
326/** 332/**
333 * rfkill_remove_epo_lock - unlock state changes
334 *
335 * Used by rfkill-input manually unlock state changes, when
336 * the EPO switch is deactivated.
337 */
338void rfkill_remove_epo_lock(void)
339{
340 mutex_lock(&rfkill_global_mutex);
341 rfkill_epo_lock_active = false;
342 mutex_unlock(&rfkill_global_mutex);
343}
344EXPORT_SYMBOL_GPL(rfkill_remove_epo_lock);
345
346/**
347 * rfkill_is_epo_lock_active - returns true EPO is active
348 *
349 * Returns 0 (false) if there is NOT an active EPO contidion,
350 * and 1 (true) if there is an active EPO contition, which
351 * locks all radios in one of the BLOCKED states.
352 *
353 * Can be called in atomic context.
354 */
355bool rfkill_is_epo_lock_active(void)
356{
357 return rfkill_epo_lock_active;
358}
359EXPORT_SYMBOL_GPL(rfkill_is_epo_lock_active);
360
361/**
327 * rfkill_get_global_state - returns global state for a type 362 * rfkill_get_global_state - returns global state for a type
328 * @type: the type to get the global state of 363 * @type: the type to get the global state of
329 * 364 *
@@ -447,7 +482,12 @@ static ssize_t rfkill_state_store(struct device *dev,
447 error = mutex_lock_killable(&rfkill->mutex); 482 error = mutex_lock_killable(&rfkill->mutex);
448 if (error) 483 if (error)
449 return error; 484 return error;
450 error = rfkill_toggle_radio(rfkill, state, 0); 485
486 if (!rfkill_epo_lock_active)
487 error = rfkill_toggle_radio(rfkill, state, 0);
488 else
489 error = -EPERM;
490
451 mutex_unlock(&rfkill->mutex); 491 mutex_unlock(&rfkill->mutex);
452 492
453 return error ? error : count; 493 return error ? error : count;
@@ -491,7 +531,7 @@ static ssize_t rfkill_claim_store(struct device *dev,
491 return error; 531 return error;
492 532
493 if (rfkill->user_claim != claim) { 533 if (rfkill->user_claim != claim) {
494 if (!claim) { 534 if (!claim && !rfkill_epo_lock_active) {
495 mutex_lock(&rfkill->mutex); 535 mutex_lock(&rfkill->mutex);
496 rfkill_toggle_radio(rfkill, 536 rfkill_toggle_radio(rfkill,
497 rfkill_global_states[rfkill->type].current_state, 537 rfkill_global_states[rfkill->type].current_state,