diff options
Diffstat (limited to 'net/rfkill/rfkill-input.c')
-rw-r--r-- | net/rfkill/rfkill-input.c | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c index d285f9a9d82..5d4c8b2446f 100644 --- a/net/rfkill/rfkill-input.c +++ b/net/rfkill/rfkill-input.c @@ -43,11 +43,26 @@ static void rfkill_task_handler(struct work_struct *work) mutex_unlock(&task->mutex); } +static void rfkill_task_epo_handler(struct work_struct *work) +{ + rfkill_epo(); +} + +static DECLARE_WORK(epo_work, rfkill_task_epo_handler); + +static void rfkill_schedule_epo(void) +{ + schedule_work(&epo_work); +} + static void rfkill_schedule_set(struct rfkill_task *task, enum rfkill_state desired_state) { unsigned long flags; + if (unlikely(work_pending(&epo_work))) + return; + spin_lock_irqsave(&task->lock, flags); if (time_after(jiffies, task->last + msecs_to_jiffies(200))) { @@ -63,6 +78,9 @@ static void rfkill_schedule_toggle(struct rfkill_task *task) { unsigned long flags; + if (unlikely(work_pending(&epo_work))) + return; + spin_lock_irqsave(&task->lock, flags); if (time_after(jiffies, task->last + msecs_to_jiffies(200))) { @@ -114,21 +132,20 @@ static void rfkill_event(struct input_handle *handle, unsigned int type, switch (code) { case SW_RFKILL_ALL: /* EVERY radio type. data != 0 means radios ON */ - rfkill_schedule_set(&rfkill_wwan, - (data)? RFKILL_STATE_ON: - RFKILL_STATE_OFF); - rfkill_schedule_set(&rfkill_wimax, - (data)? RFKILL_STATE_ON: - RFKILL_STATE_OFF); - rfkill_schedule_set(&rfkill_uwb, - (data)? RFKILL_STATE_ON: - RFKILL_STATE_OFF); - rfkill_schedule_set(&rfkill_bt, - (data)? RFKILL_STATE_ON: - RFKILL_STATE_OFF); - rfkill_schedule_set(&rfkill_wlan, - (data)? RFKILL_STATE_ON: - RFKILL_STATE_OFF); + /* handle EPO (emergency power off) through shortcut */ + if (data) { + rfkill_schedule_set(&rfkill_wwan, + RFKILL_STATE_ON); + rfkill_schedule_set(&rfkill_wimax, + RFKILL_STATE_ON); + rfkill_schedule_set(&rfkill_uwb, + RFKILL_STATE_ON); + rfkill_schedule_set(&rfkill_bt, + RFKILL_STATE_ON); + rfkill_schedule_set(&rfkill_wlan, + RFKILL_STATE_ON); + } else + rfkill_schedule_epo(); break; default: break; |