X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Frfkill%2Frfkill-input.c;h=8aa82273014516a14a8184bd44cdcdff70f972af;hb=2aec609fb45e84d65bc8eabc7b650bbecb1cc179;hp=d285f9a9d8299b82342b34a21c558cc3c9b508d0;hpb=fbc6af2f3c46df4722f5161d0ad20dd87cd7dfa9;p=linux-2.6 diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c index d285f9a9d8..8aa8227301 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,10 +78,14 @@ 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))) { - task->desired_state = !task->desired_state; + task->desired_state = + rfkill_state_complement(task->desired_state); task->last = jiffies; schedule_work(&task->work); } @@ -74,14 +93,14 @@ static void rfkill_schedule_toggle(struct rfkill_task *task) spin_unlock_irqrestore(&task->lock, flags); } -#define DEFINE_RFKILL_TASK(n, t) \ - struct rfkill_task n = { \ - .work = __WORK_INITIALIZER(n.work, \ - rfkill_task_handler), \ - .type = t, \ - .mutex = __MUTEX_INITIALIZER(n.mutex), \ - .lock = __SPIN_LOCK_UNLOCKED(n.lock), \ - .desired_state = RFKILL_STATE_ON, \ +#define DEFINE_RFKILL_TASK(n, t) \ + struct rfkill_task n = { \ + .work = __WORK_INITIALIZER(n.work, \ + rfkill_task_handler), \ + .type = t, \ + .mutex = __MUTEX_INITIALIZER(n.mutex), \ + .lock = __SPIN_LOCK_UNLOCKED(n.lock), \ + .desired_state = RFKILL_STATE_UNBLOCKED, \ } static DEFINE_RFKILL_TASK(rfkill_wlan, RFKILL_TYPE_WLAN); @@ -114,21 +133,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_UNBLOCKED); + rfkill_schedule_set(&rfkill_wimax, + RFKILL_STATE_UNBLOCKED); + rfkill_schedule_set(&rfkill_uwb, + RFKILL_STATE_UNBLOCKED); + rfkill_schedule_set(&rfkill_bt, + RFKILL_STATE_UNBLOCKED); + rfkill_schedule_set(&rfkill_wlan, + RFKILL_STATE_UNBLOCKED); + } else + rfkill_schedule_epo(); break; default: break;