diff options
-rw-r--r-- | net/rfkill/rfkill-input.c | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c index e4b051dbed61..9d6c9255bf2c 100644 --- a/net/rfkill/rfkill-input.c +++ b/net/rfkill/rfkill-input.c | |||
@@ -55,6 +55,22 @@ static void rfkill_task_handler(struct work_struct *work) | |||
55 | mutex_unlock(&task->mutex); | 55 | mutex_unlock(&task->mutex); |
56 | } | 56 | } |
57 | 57 | ||
58 | static void rfkill_schedule_set(struct rfkill_task *task, | ||
59 | enum rfkill_state desired_state) | ||
60 | { | ||
61 | unsigned long flags; | ||
62 | |||
63 | spin_lock_irqsave(&task->lock, flags); | ||
64 | |||
65 | if (time_after(jiffies, task->last + msecs_to_jiffies(200))) { | ||
66 | task->desired_state = desired_state; | ||
67 | task->last = jiffies; | ||
68 | schedule_work(&task->work); | ||
69 | } | ||
70 | |||
71 | spin_unlock_irqrestore(&task->lock, flags); | ||
72 | } | ||
73 | |||
58 | static void rfkill_schedule_toggle(struct rfkill_task *task) | 74 | static void rfkill_schedule_toggle(struct rfkill_task *task) |
59 | { | 75 | { |
60 | unsigned long flags; | 76 | unsigned long flags; |
@@ -87,9 +103,9 @@ static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB); | |||
87 | static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX); | 103 | static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX); |
88 | 104 | ||
89 | static void rfkill_event(struct input_handle *handle, unsigned int type, | 105 | static void rfkill_event(struct input_handle *handle, unsigned int type, |
90 | unsigned int code, int down) | 106 | unsigned int code, int data) |
91 | { | 107 | { |
92 | if (type == EV_KEY && down == 1) { | 108 | if (type == EV_KEY && data == 1) { |
93 | switch (code) { | 109 | switch (code) { |
94 | case KEY_WLAN: | 110 | case KEY_WLAN: |
95 | rfkill_schedule_toggle(&rfkill_wlan); | 111 | rfkill_schedule_toggle(&rfkill_wlan); |
@@ -106,6 +122,26 @@ static void rfkill_event(struct input_handle *handle, unsigned int type, | |||
106 | default: | 122 | default: |
107 | break; | 123 | break; |
108 | } | 124 | } |
125 | } else if (type == EV_SW) { | ||
126 | switch (code) { | ||
127 | case SW_RFKILL_ALL: | ||
128 | /* EVERY radio type. data != 0 means radios ON */ | ||
129 | rfkill_schedule_set(&rfkill_wimax, | ||
130 | (data)? RFKILL_STATE_ON: | ||
131 | RFKILL_STATE_OFF); | ||
132 | rfkill_schedule_set(&rfkill_uwb, | ||
133 | (data)? RFKILL_STATE_ON: | ||
134 | RFKILL_STATE_OFF); | ||
135 | rfkill_schedule_set(&rfkill_bt, | ||
136 | (data)? RFKILL_STATE_ON: | ||
137 | RFKILL_STATE_OFF); | ||
138 | rfkill_schedule_set(&rfkill_wlan, | ||
139 | (data)? RFKILL_STATE_ON: | ||
140 | RFKILL_STATE_OFF); | ||
141 | break; | ||
142 | default: | ||
143 | break; | ||
144 | } | ||
109 | } | 145 | } |
110 | } | 146 | } |
111 | 147 | ||
@@ -168,6 +204,11 @@ static const struct input_device_id rfkill_ids[] = { | |||
168 | .evbit = { BIT_MASK(EV_KEY) }, | 204 | .evbit = { BIT_MASK(EV_KEY) }, |
169 | .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) }, | 205 | .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) }, |
170 | }, | 206 | }, |
207 | { | ||
208 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT, | ||
209 | .evbit = { BIT(EV_SW) }, | ||
210 | .swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) }, | ||
211 | }, | ||
171 | { } | 212 | { } |
172 | }; | 213 | }; |
173 | 214 | ||