aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2008-06-23 16:22:58 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-26 14:21:19 -0400
commit28f089c18464810ec9e91ee10a89adbb02ad7765 (patch)
tree5addf4b36d545258759d6aba8e825c79aa00698d
parentc8fcd905a59a535bff93a120ac44b09ce24e13e6 (diff)
rfkill: handle SW_RFKILL_ALL events
Teach rfkill-input how to handle SW_RFKILL_ALL events (new name for the SW_RADIO event). SW_RFKILL_ALL is an absolute enable-or-disable command that is tied to all radios in a system. Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Acked-by: Ivo van Doorn <IvDoorn@gmail.com> Cc: Dmitry Torokhov <dtor@mail.ru> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/rfkill/rfkill-input.c45
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
58static 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
58static void rfkill_schedule_toggle(struct rfkill_task *task) 74static 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);
87static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX); 103static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX);
88 104
89static void rfkill_event(struct input_handle *handle, unsigned int type, 105static 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