diff options
Diffstat (limited to 'net/wimax/op-rfkill.c')
-rw-r--r-- | net/wimax/op-rfkill.c | 125 |
1 files changed, 27 insertions, 98 deletions
diff --git a/net/wimax/op-rfkill.c b/net/wimax/op-rfkill.c index 2b75aee04217..70ef4df863b9 100644 --- a/net/wimax/op-rfkill.c +++ b/net/wimax/op-rfkill.c | |||
@@ -29,8 +29,8 @@ | |||
29 | * A non-polled generic rfkill device is embedded into the WiMAX | 29 | * A non-polled generic rfkill device is embedded into the WiMAX |
30 | * subsystem's representation of a device. | 30 | * subsystem's representation of a device. |
31 | * | 31 | * |
32 | * FIXME: Need polled support? use a timer or add the implementation | 32 | * FIXME: Need polled support? Let drivers provide a poll routine |
33 | * to the stack. | 33 | * and hand it to rfkill ops then? |
34 | * | 34 | * |
35 | * All device drivers have to do is after wimax_dev_init(), call | 35 | * All device drivers have to do is after wimax_dev_init(), call |
36 | * wimax_report_rfkill_hw() and wimax_report_rfkill_sw() to update | 36 | * wimax_report_rfkill_hw() and wimax_report_rfkill_sw() to update |
@@ -43,7 +43,7 @@ | |||
43 | * wimax_rfkill() Kernel calling wimax_rfkill() | 43 | * wimax_rfkill() Kernel calling wimax_rfkill() |
44 | * __wimax_rf_toggle_radio() | 44 | * __wimax_rf_toggle_radio() |
45 | * | 45 | * |
46 | * wimax_rfkill_toggle_radio() RF-Kill subsytem calling | 46 | * wimax_rfkill_set_radio_block() RF-Kill subsytem calling |
47 | * __wimax_rf_toggle_radio() | 47 | * __wimax_rf_toggle_radio() |
48 | * | 48 | * |
49 | * __wimax_rf_toggle_radio() | 49 | * __wimax_rf_toggle_radio() |
@@ -65,15 +65,11 @@ | |||
65 | #include <linux/wimax.h> | 65 | #include <linux/wimax.h> |
66 | #include <linux/security.h> | 66 | #include <linux/security.h> |
67 | #include <linux/rfkill.h> | 67 | #include <linux/rfkill.h> |
68 | #include <linux/input.h> | ||
69 | #include "wimax-internal.h" | 68 | #include "wimax-internal.h" |
70 | 69 | ||
71 | #define D_SUBMODULE op_rfkill | 70 | #define D_SUBMODULE op_rfkill |
72 | #include "debug-levels.h" | 71 | #include "debug-levels.h" |
73 | 72 | ||
74 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
75 | |||
76 | |||
77 | /** | 73 | /** |
78 | * wimax_report_rfkill_hw - Reports changes in the hardware RF switch | 74 | * wimax_report_rfkill_hw - Reports changes in the hardware RF switch |
79 | * | 75 | * |
@@ -99,7 +95,6 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev, | |||
99 | int result; | 95 | int result; |
100 | struct device *dev = wimax_dev_to_dev(wimax_dev); | 96 | struct device *dev = wimax_dev_to_dev(wimax_dev); |
101 | enum wimax_st wimax_state; | 97 | enum wimax_st wimax_state; |
102 | enum rfkill_state rfkill_state; | ||
103 | 98 | ||
104 | d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); | 99 | d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); |
105 | BUG_ON(state == WIMAX_RF_QUERY); | 100 | BUG_ON(state == WIMAX_RF_QUERY); |
@@ -112,16 +107,16 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev, | |||
112 | 107 | ||
113 | if (state != wimax_dev->rf_hw) { | 108 | if (state != wimax_dev->rf_hw) { |
114 | wimax_dev->rf_hw = state; | 109 | wimax_dev->rf_hw = state; |
115 | rfkill_state = state == WIMAX_RF_ON ? | ||
116 | RFKILL_STATE_OFF : RFKILL_STATE_ON; | ||
117 | if (wimax_dev->rf_hw == WIMAX_RF_ON | 110 | if (wimax_dev->rf_hw == WIMAX_RF_ON |
118 | && wimax_dev->rf_sw == WIMAX_RF_ON) | 111 | && wimax_dev->rf_sw == WIMAX_RF_ON) |
119 | wimax_state = WIMAX_ST_READY; | 112 | wimax_state = WIMAX_ST_READY; |
120 | else | 113 | else |
121 | wimax_state = WIMAX_ST_RADIO_OFF; | 114 | wimax_state = WIMAX_ST_RADIO_OFF; |
115 | |||
116 | result = rfkill_set_hw_state(wimax_dev->rfkill, | ||
117 | state == WIMAX_RF_OFF); | ||
118 | |||
122 | __wimax_state_change(wimax_dev, wimax_state); | 119 | __wimax_state_change(wimax_dev, wimax_state); |
123 | input_report_key(wimax_dev->rfkill_input, KEY_WIMAX, | ||
124 | rfkill_state); | ||
125 | } | 120 | } |
126 | error_not_ready: | 121 | error_not_ready: |
127 | mutex_unlock(&wimax_dev->mutex); | 122 | mutex_unlock(&wimax_dev->mutex); |
@@ -174,6 +169,7 @@ void wimax_report_rfkill_sw(struct wimax_dev *wimax_dev, | |||
174 | else | 169 | else |
175 | wimax_state = WIMAX_ST_RADIO_OFF; | 170 | wimax_state = WIMAX_ST_RADIO_OFF; |
176 | __wimax_state_change(wimax_dev, wimax_state); | 171 | __wimax_state_change(wimax_dev, wimax_state); |
172 | rfkill_set_sw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF); | ||
177 | } | 173 | } |
178 | error_not_ready: | 174 | error_not_ready: |
179 | mutex_unlock(&wimax_dev->mutex); | 175 | mutex_unlock(&wimax_dev->mutex); |
@@ -249,36 +245,31 @@ out_no_change: | |||
249 | * | 245 | * |
250 | * NOTE: This call will block until the operation is completed. | 246 | * NOTE: This call will block until the operation is completed. |
251 | */ | 247 | */ |
252 | static | 248 | static int wimax_rfkill_set_radio_block(void *data, bool blocked) |
253 | int wimax_rfkill_toggle_radio(void *data, enum rfkill_state state) | ||
254 | { | 249 | { |
255 | int result; | 250 | int result; |
256 | struct wimax_dev *wimax_dev = data; | 251 | struct wimax_dev *wimax_dev = data; |
257 | struct device *dev = wimax_dev_to_dev(wimax_dev); | 252 | struct device *dev = wimax_dev_to_dev(wimax_dev); |
258 | enum wimax_rf_state rf_state; | 253 | enum wimax_rf_state rf_state; |
259 | 254 | ||
260 | d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); | 255 | d_fnstart(3, dev, "(wimax_dev %p blocked %u)\n", wimax_dev, blocked); |
261 | switch (state) { | 256 | rf_state = WIMAX_RF_ON; |
262 | case RFKILL_STATE_ON: | 257 | if (blocked) |
263 | rf_state = WIMAX_RF_OFF; | 258 | rf_state = WIMAX_RF_OFF; |
264 | break; | ||
265 | case RFKILL_STATE_OFF: | ||
266 | rf_state = WIMAX_RF_ON; | ||
267 | break; | ||
268 | default: | ||
269 | BUG(); | ||
270 | } | ||
271 | mutex_lock(&wimax_dev->mutex); | 259 | mutex_lock(&wimax_dev->mutex); |
272 | if (wimax_dev->state <= __WIMAX_ST_QUIESCING) | 260 | if (wimax_dev->state <= __WIMAX_ST_QUIESCING) |
273 | result = 0; /* just pretend it didn't happen */ | 261 | result = 0; |
274 | else | 262 | else |
275 | result = __wimax_rf_toggle_radio(wimax_dev, rf_state); | 263 | result = __wimax_rf_toggle_radio(wimax_dev, rf_state); |
276 | mutex_unlock(&wimax_dev->mutex); | 264 | mutex_unlock(&wimax_dev->mutex); |
277 | d_fnend(3, dev, "(wimax_dev %p state %u) = %d\n", | 265 | d_fnend(3, dev, "(wimax_dev %p blocked %u) = %d\n", |
278 | wimax_dev, state, result); | 266 | wimax_dev, blocked, result); |
279 | return result; | 267 | return result; |
280 | } | 268 | } |
281 | 269 | ||
270 | static const struct rfkill_ops wimax_rfkill_ops = { | ||
271 | .set_block = wimax_rfkill_set_radio_block, | ||
272 | }; | ||
282 | 273 | ||
283 | /** | 274 | /** |
284 | * wimax_rfkill - Set the software RF switch state for a WiMAX device | 275 | * wimax_rfkill - Set the software RF switch state for a WiMAX device |
@@ -322,6 +313,7 @@ int wimax_rfkill(struct wimax_dev *wimax_dev, enum wimax_rf_state state) | |||
322 | result = __wimax_rf_toggle_radio(wimax_dev, state); | 313 | result = __wimax_rf_toggle_radio(wimax_dev, state); |
323 | if (result < 0) | 314 | if (result < 0) |
324 | goto error; | 315 | goto error; |
316 | rfkill_set_sw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF); | ||
325 | break; | 317 | break; |
326 | case WIMAX_RF_QUERY: | 318 | case WIMAX_RF_QUERY: |
327 | break; | 319 | break; |
@@ -349,41 +341,20 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev) | |||
349 | { | 341 | { |
350 | int result; | 342 | int result; |
351 | struct rfkill *rfkill; | 343 | struct rfkill *rfkill; |
352 | struct input_dev *input_dev; | ||
353 | struct device *dev = wimax_dev_to_dev(wimax_dev); | 344 | struct device *dev = wimax_dev_to_dev(wimax_dev); |
354 | 345 | ||
355 | d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev); | 346 | d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev); |
356 | /* Initialize RF Kill */ | 347 | /* Initialize RF Kill */ |
357 | result = -ENOMEM; | 348 | result = -ENOMEM; |
358 | rfkill = rfkill_allocate(dev, RFKILL_TYPE_WIMAX); | 349 | rfkill = rfkill_alloc(wimax_dev->name, dev, RFKILL_TYPE_WIMAX, |
350 | &wimax_rfkill_ops, wimax_dev); | ||
359 | if (rfkill == NULL) | 351 | if (rfkill == NULL) |
360 | goto error_rfkill_allocate; | 352 | goto error_rfkill_allocate; |
353 | |||
354 | d_printf(1, dev, "rfkill %p\n", rfkill); | ||
355 | |||
361 | wimax_dev->rfkill = rfkill; | 356 | wimax_dev->rfkill = rfkill; |
362 | 357 | ||
363 | rfkill->name = wimax_dev->name; | ||
364 | rfkill->state = RFKILL_STATE_OFF; | ||
365 | rfkill->data = wimax_dev; | ||
366 | rfkill->toggle_radio = wimax_rfkill_toggle_radio; | ||
367 | rfkill->user_claim_unsupported = 1; | ||
368 | |||
369 | /* Initialize the input device for the hw key */ | ||
370 | input_dev = input_allocate_device(); | ||
371 | if (input_dev == NULL) | ||
372 | goto error_input_allocate; | ||
373 | wimax_dev->rfkill_input = input_dev; | ||
374 | d_printf(1, dev, "rfkill %p input %p\n", rfkill, input_dev); | ||
375 | |||
376 | input_dev->name = wimax_dev->name; | ||
377 | /* FIXME: get a real device bus ID and stuff? do we care? */ | ||
378 | input_dev->id.bustype = BUS_HOST; | ||
379 | input_dev->id.vendor = 0xffff; | ||
380 | input_dev->evbit[0] = BIT(EV_KEY); | ||
381 | set_bit(KEY_WIMAX, input_dev->keybit); | ||
382 | |||
383 | /* Register both */ | ||
384 | result = input_register_device(wimax_dev->rfkill_input); | ||
385 | if (result < 0) | ||
386 | goto error_input_register; | ||
387 | result = rfkill_register(wimax_dev->rfkill); | 358 | result = rfkill_register(wimax_dev->rfkill); |
388 | if (result < 0) | 359 | if (result < 0) |
389 | goto error_rfkill_register; | 360 | goto error_rfkill_register; |
@@ -395,17 +366,8 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev) | |||
395 | d_fnend(3, dev, "(wimax_dev %p) = 0\n", wimax_dev); | 366 | d_fnend(3, dev, "(wimax_dev %p) = 0\n", wimax_dev); |
396 | return 0; | 367 | return 0; |
397 | 368 | ||
398 | /* if rfkill_register() suceeds, can't use rfkill_free() any | ||
399 | * more, only rfkill_unregister() [it owns the refcount]; with | ||
400 | * the input device we have the same issue--hence the if. */ | ||
401 | error_rfkill_register: | 369 | error_rfkill_register: |
402 | input_unregister_device(wimax_dev->rfkill_input); | 370 | rfkill_destroy(wimax_dev->rfkill); |
403 | wimax_dev->rfkill_input = NULL; | ||
404 | error_input_register: | ||
405 | if (wimax_dev->rfkill_input) | ||
406 | input_free_device(wimax_dev->rfkill_input); | ||
407 | error_input_allocate: | ||
408 | rfkill_free(wimax_dev->rfkill); | ||
409 | error_rfkill_allocate: | 371 | error_rfkill_allocate: |
410 | d_fnend(3, dev, "(wimax_dev %p) = %d\n", wimax_dev, result); | 372 | d_fnend(3, dev, "(wimax_dev %p) = %d\n", wimax_dev, result); |
411 | return result; | 373 | return result; |
@@ -424,45 +386,12 @@ void wimax_rfkill_rm(struct wimax_dev *wimax_dev) | |||
424 | { | 386 | { |
425 | struct device *dev = wimax_dev_to_dev(wimax_dev); | 387 | struct device *dev = wimax_dev_to_dev(wimax_dev); |
426 | d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev); | 388 | d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev); |
427 | rfkill_unregister(wimax_dev->rfkill); /* frees */ | 389 | rfkill_unregister(wimax_dev->rfkill); |
428 | input_unregister_device(wimax_dev->rfkill_input); | 390 | rfkill_destroy(wimax_dev->rfkill); |
429 | d_fnend(3, dev, "(wimax_dev %p)\n", wimax_dev); | 391 | d_fnend(3, dev, "(wimax_dev %p)\n", wimax_dev); |
430 | } | 392 | } |
431 | 393 | ||
432 | 394 | ||
433 | #else /* #ifdef CONFIG_RFKILL */ | ||
434 | |||
435 | void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev, | ||
436 | enum wimax_rf_state state) | ||
437 | { | ||
438 | } | ||
439 | EXPORT_SYMBOL_GPL(wimax_report_rfkill_hw); | ||
440 | |||
441 | void wimax_report_rfkill_sw(struct wimax_dev *wimax_dev, | ||
442 | enum wimax_rf_state state) | ||
443 | { | ||
444 | } | ||
445 | EXPORT_SYMBOL_GPL(wimax_report_rfkill_sw); | ||
446 | |||
447 | int wimax_rfkill(struct wimax_dev *wimax_dev, | ||
448 | enum wimax_rf_state state) | ||
449 | { | ||
450 | return WIMAX_RF_ON << 1 | WIMAX_RF_ON; | ||
451 | } | ||
452 | EXPORT_SYMBOL_GPL(wimax_rfkill); | ||
453 | |||
454 | int wimax_rfkill_add(struct wimax_dev *wimax_dev) | ||
455 | { | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | void wimax_rfkill_rm(struct wimax_dev *wimax_dev) | ||
460 | { | ||
461 | } | ||
462 | |||
463 | #endif /* #ifdef CONFIG_RFKILL */ | ||
464 | |||
465 | |||
466 | /* | 395 | /* |
467 | * Exporting to user space over generic netlink | 396 | * Exporting to user space over generic netlink |
468 | * | 397 | * |