]> err.no Git - linux-2.6/blobdiff - net/rfkill/rfkill-input.c
rfkill: handle SW_RFKILL_ALL events
[linux-2.6] / net / rfkill / rfkill-input.c
index eaabf087c59b53e1dcf05af11647fdd2288d136a..9d6c9255bf2cfe9ebd8dfc125a37091d4bb4cda0 100644 (file)
@@ -55,6 +55,22 @@ static void rfkill_task_handler(struct work_struct *work)
        mutex_unlock(&task->mutex);
 }
 
+static void rfkill_schedule_set(struct rfkill_task *task,
+                               enum rfkill_state desired_state)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&task->lock, flags);
+
+       if (time_after(jiffies, task->last + msecs_to_jiffies(200))) {
+               task->desired_state = desired_state;
+               task->last = jiffies;
+               schedule_work(&task->work);
+       }
+
+       spin_unlock_irqrestore(&task->lock, flags);
+}
+
 static void rfkill_schedule_toggle(struct rfkill_task *task)
 {
        unsigned long flags;
@@ -84,11 +100,12 @@ static void rfkill_schedule_toggle(struct rfkill_task *task)
 static DEFINE_RFKILL_TASK(rfkill_wlan, RFKILL_TYPE_WLAN);
 static DEFINE_RFKILL_TASK(rfkill_bt, RFKILL_TYPE_BLUETOOTH);
 static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB);
+static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX);
 
 static void rfkill_event(struct input_handle *handle, unsigned int type,
-                       unsigned int code, int down)
+                       unsigned int code, int data)
 {
-       if (type == EV_KEY && down == 1) {
+       if (type == EV_KEY && data == 1) {
                switch (code) {
                case KEY_WLAN:
                        rfkill_schedule_toggle(&rfkill_wlan);
@@ -99,6 +116,29 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
                case KEY_UWB:
                        rfkill_schedule_toggle(&rfkill_uwb);
                        break;
+               case KEY_WIMAX:
+                       rfkill_schedule_toggle(&rfkill_wimax);
+                       break;
+               default:
+                       break;
+               }
+       } else if (type == EV_SW) {
+               switch (code) {
+               case SW_RFKILL_ALL:
+                       /* EVERY radio type. data != 0 means radios ON */
+                       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);
+                       break;
                default:
                        break;
                }
@@ -146,18 +186,28 @@ static void rfkill_disconnect(struct input_handle *handle)
 static const struct input_device_id rfkill_ids[] = {
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
-               .evbit = { BIT(EV_KEY) },
-               .keybit = { [LONG(KEY_WLAN)] = BIT(KEY_WLAN) },
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(KEY_WLAN)] = BIT_MASK(KEY_WLAN) },
+       },
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(KEY_BLUETOOTH)] = BIT_MASK(KEY_BLUETOOTH) },
        },
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
-               .evbit = { BIT(EV_KEY) },
-               .keybit = { [LONG(KEY_BLUETOOTH)] = BIT(KEY_BLUETOOTH) },
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) },
        },
        {
                .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
-               .evbit = { BIT(EV_KEY) },
-               .keybit = { [LONG(KEY_UWB)] = BIT(KEY_UWB) },
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
+       },
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT,
+               .evbit = { BIT(EV_SW) },
+               .swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) },
        },
        { }
 };