Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
input.c
Go to the documentation of this file.
1 /*
2  * Input layer to RF Kill interface connector
3  *
4  * Copyright (c) 2007 Dmitry Torokhov
5  * Copyright 2009 Johannes Berg <[email protected]>
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License version 2 as published
9  * by the Free Software Foundation.
10  *
11  * If you ever run into a situation in which you have a SW_ type rfkill
12  * input device, then you can revive code that was removed in the patch
13  * "rfkill-input: remove unused code".
14  */
15 
16 #include <linux/input.h>
17 #include <linux/slab.h>
18 #include <linux/moduleparam.h>
19 #include <linux/workqueue.h>
20 #include <linux/init.h>
21 #include <linux/rfkill.h>
22 #include <linux/sched.h>
23 
24 #include "rfkill.h"
25 
31 };
32 
33 /* Delay (in ms) between consecutive switch ops */
34 #define RFKILL_OPS_DELAY 200
35 
36 static enum rfkill_input_master_mode rfkill_master_switch_mode =
38 module_param_named(master_switch_mode, rfkill_master_switch_mode, uint, 0);
39 MODULE_PARM_DESC(master_switch_mode,
40  "SW_RFKILL_ALL ON should: 0=do nothing (only unlock); 1=restore; 2=unblock all");
41 
42 static spinlock_t rfkill_op_lock;
43 static bool rfkill_op_pending;
44 static unsigned long rfkill_sw_pending[BITS_TO_LONGS(NUM_RFKILL_TYPES)];
45 static unsigned long rfkill_sw_state[BITS_TO_LONGS(NUM_RFKILL_TYPES)];
46 
52 };
53 
54 static enum rfkill_sched_op rfkill_master_switch_op;
55 static enum rfkill_sched_op rfkill_op;
56 
57 static void __rfkill_handle_global_op(enum rfkill_sched_op op)
58 {
59  unsigned int i;
60 
61  switch (op) {
63  rfkill_epo();
64  break;
67  break;
70  break;
73  for (i = 0; i < NUM_RFKILL_TYPES; i++)
74  rfkill_switch_all(i, false);
75  break;
76  default:
77  /* memory corruption or bug, fail safely */
78  rfkill_epo();
79  WARN(1, "Unknown requested operation %d! "
80  "rfkill Emergency Power Off activated\n",
81  op);
82  }
83 }
84 
85 static void __rfkill_handle_normal_op(const enum rfkill_type type,
86  const bool complement)
87 {
88  bool blocked;
89 
90  blocked = rfkill_get_global_sw_state(type);
91  if (complement)
92  blocked = !blocked;
93 
94  rfkill_switch_all(type, blocked);
95 }
96 
97 static void rfkill_op_handler(struct work_struct *work)
98 {
99  unsigned int i;
100  bool c;
101 
102  spin_lock_irq(&rfkill_op_lock);
103  do {
104  if (rfkill_op_pending) {
105  enum rfkill_sched_op op = rfkill_op;
106  rfkill_op_pending = false;
107  memset(rfkill_sw_pending, 0,
108  sizeof(rfkill_sw_pending));
109  spin_unlock_irq(&rfkill_op_lock);
110 
111  __rfkill_handle_global_op(op);
112 
113  spin_lock_irq(&rfkill_op_lock);
114 
115  /*
116  * handle global ops first -- during unlocked period
117  * we might have gotten a new global op.
118  */
119  if (rfkill_op_pending)
120  continue;
121  }
122 
124  continue;
125 
126  for (i = 0; i < NUM_RFKILL_TYPES; i++) {
127  if (__test_and_clear_bit(i, rfkill_sw_pending)) {
128  c = __test_and_clear_bit(i, rfkill_sw_state);
129  spin_unlock_irq(&rfkill_op_lock);
130 
131  __rfkill_handle_normal_op(i, c);
132 
133  spin_lock_irq(&rfkill_op_lock);
134  }
135  }
136  } while (rfkill_op_pending);
137  spin_unlock_irq(&rfkill_op_lock);
138 }
139 
140 static DECLARE_DELAYED_WORK(rfkill_op_work, rfkill_op_handler);
141 static unsigned long rfkill_last_scheduled;
142 
143 static unsigned long rfkill_ratelimit(const unsigned long last)
144 {
145  const unsigned long delay = msecs_to_jiffies(RFKILL_OPS_DELAY);
146  return time_after(jiffies, last + delay) ? 0 : delay;
147 }
148 
149 static void rfkill_schedule_ratelimited(void)
150 {
151  if (delayed_work_pending(&rfkill_op_work))
152  return;
153  schedule_delayed_work(&rfkill_op_work,
154  rfkill_ratelimit(rfkill_last_scheduled));
155  rfkill_last_scheduled = jiffies;
156 }
157 
158 static void rfkill_schedule_global_op(enum rfkill_sched_op op)
159 {
160  unsigned long flags;
161 
162  spin_lock_irqsave(&rfkill_op_lock, flags);
163  rfkill_op = op;
164  rfkill_op_pending = true;
166  /* bypass the limiter for EPO */
167  mod_delayed_work(system_wq, &rfkill_op_work, 0);
168  rfkill_last_scheduled = jiffies;
169  } else
170  rfkill_schedule_ratelimited();
171  spin_unlock_irqrestore(&rfkill_op_lock, flags);
172 }
173 
174 static void rfkill_schedule_toggle(enum rfkill_type type)
175 {
176  unsigned long flags;
177 
179  return;
180 
181  spin_lock_irqsave(&rfkill_op_lock, flags);
182  if (!rfkill_op_pending) {
183  __set_bit(type, rfkill_sw_pending);
184  __change_bit(type, rfkill_sw_state);
185  rfkill_schedule_ratelimited();
186  }
187  spin_unlock_irqrestore(&rfkill_op_lock, flags);
188 }
189 
190 static void rfkill_schedule_evsw_rfkillall(int state)
191 {
192  if (state)
193  rfkill_schedule_global_op(rfkill_master_switch_op);
194  else
195  rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO);
196 }
197 
198 static void rfkill_event(struct input_handle *handle, unsigned int type,
199  unsigned int code, int data)
200 {
201  if (type == EV_KEY && data == 1) {
202  switch (code) {
203  case KEY_WLAN:
204  rfkill_schedule_toggle(RFKILL_TYPE_WLAN);
205  break;
206  case KEY_BLUETOOTH:
207  rfkill_schedule_toggle(RFKILL_TYPE_BLUETOOTH);
208  break;
209  case KEY_UWB:
210  rfkill_schedule_toggle(RFKILL_TYPE_UWB);
211  break;
212  case KEY_WIMAX:
213  rfkill_schedule_toggle(RFKILL_TYPE_WIMAX);
214  break;
215  case KEY_RFKILL:
216  rfkill_schedule_toggle(RFKILL_TYPE_ALL);
217  break;
218  }
219  } else if (type == EV_SW && code == SW_RFKILL_ALL)
220  rfkill_schedule_evsw_rfkillall(data);
221 }
222 
223 static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
224  const struct input_device_id *id)
225 {
226  struct input_handle *handle;
227  int error;
228 
229  handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
230  if (!handle)
231  return -ENOMEM;
232 
233  handle->dev = dev;
234  handle->handler = handler;
235  handle->name = "rfkill";
236 
237  /* causes rfkill_start() to be called */
238  error = input_register_handle(handle);
239  if (error)
240  goto err_free_handle;
241 
242  error = input_open_device(handle);
243  if (error)
244  goto err_unregister_handle;
245 
246  return 0;
247 
248  err_unregister_handle:
249  input_unregister_handle(handle);
250  err_free_handle:
251  kfree(handle);
252  return error;
253 }
254 
255 static void rfkill_start(struct input_handle *handle)
256 {
257  /*
258  * Take event_lock to guard against configuration changes, we
259  * should be able to deal with concurrency with rfkill_event()
260  * just fine (which event_lock will also avoid).
261  */
262  spin_lock_irq(&handle->dev->event_lock);
263 
264  if (test_bit(EV_SW, handle->dev->evbit) &&
265  test_bit(SW_RFKILL_ALL, handle->dev->swbit))
266  rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL,
267  handle->dev->sw));
268 
269  spin_unlock_irq(&handle->dev->event_lock);
270 }
271 
272 static void rfkill_disconnect(struct input_handle *handle)
273 {
274  input_close_device(handle);
275  input_unregister_handle(handle);
276  kfree(handle);
277 }
278 
279 static const struct input_device_id rfkill_ids[] = {
280  {
282  .evbit = { BIT_MASK(EV_KEY) },
283  .keybit = { [BIT_WORD(KEY_WLAN)] = BIT_MASK(KEY_WLAN) },
284  },
285  {
287  .evbit = { BIT_MASK(EV_KEY) },
288  .keybit = { [BIT_WORD(KEY_BLUETOOTH)] = BIT_MASK(KEY_BLUETOOTH) },
289  },
290  {
292  .evbit = { BIT_MASK(EV_KEY) },
293  .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) },
294  },
295  {
297  .evbit = { BIT_MASK(EV_KEY) },
298  .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
299  },
300  {
302  .evbit = { BIT_MASK(EV_KEY) },
303  .keybit = { [BIT_WORD(KEY_RFKILL)] = BIT_MASK(KEY_RFKILL) },
304  },
305  {
307  .evbit = { BIT(EV_SW) },
308  .swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) },
309  },
310  { }
311 };
312 
313 static struct input_handler rfkill_handler = {
314  .name = "rfkill",
315  .event = rfkill_event,
316  .connect = rfkill_connect,
317  .start = rfkill_start,
318  .disconnect = rfkill_disconnect,
319  .id_table = rfkill_ids,
320 };
321 
323 {
324  switch (rfkill_master_switch_mode) {
326  rfkill_master_switch_op = RFKILL_GLOBAL_OP_UNBLOCK;
327  break;
329  rfkill_master_switch_op = RFKILL_GLOBAL_OP_RESTORE;
330  break;
332  rfkill_master_switch_op = RFKILL_GLOBAL_OP_UNLOCK;
333  break;
334  default:
335  return -EINVAL;
336  }
337 
338  spin_lock_init(&rfkill_op_lock);
339 
340  /* Avoid delay at first schedule */
341  rfkill_last_scheduled =
343  return input_register_handler(&rfkill_handler);
344 }
345 
347 {
348  input_unregister_handler(&rfkill_handler);
349  cancel_delayed_work_sync(&rfkill_op_work);
350 }