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