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>
This commit is contained in:
committed by
John W. Linville
parent
c8fcd905a5
commit
28f089c184
@@ -55,6 +55,22 @@ static void rfkill_task_handler(struct work_struct *work)
|
|||||||
mutex_unlock(&task->mutex);
|
mutex_unlock(&task->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rfkill_schedule_set(struct rfkill_task *task,
|
||||||
|
enum rfkill_state desired_state)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&task->lock, flags);
|
||||||
|
|
||||||
|
if (time_after(jiffies, task->last + msecs_to_jiffies(200))) {
|
||||||
|
task->desired_state = desired_state;
|
||||||
|
task->last = jiffies;
|
||||||
|
schedule_work(&task->work);
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&task->lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
static void rfkill_schedule_toggle(struct rfkill_task *task)
|
static void rfkill_schedule_toggle(struct rfkill_task *task)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@@ -87,9 +103,9 @@ static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB);
|
|||||||
static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX);
|
static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX);
|
||||||
|
|
||||||
static void rfkill_event(struct input_handle *handle, unsigned int type,
|
static void rfkill_event(struct input_handle *handle, unsigned int type,
|
||||||
unsigned int code, int down)
|
unsigned int code, int data)
|
||||||
{
|
{
|
||||||
if (type == EV_KEY && down == 1) {
|
if (type == EV_KEY && data == 1) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case KEY_WLAN:
|
case KEY_WLAN:
|
||||||
rfkill_schedule_toggle(&rfkill_wlan);
|
rfkill_schedule_toggle(&rfkill_wlan);
|
||||||
@@ -106,6 +122,26 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else if (type == EV_SW) {
|
||||||
|
switch (code) {
|
||||||
|
case SW_RFKILL_ALL:
|
||||||
|
/* EVERY radio type. data != 0 means radios ON */
|
||||||
|
rfkill_schedule_set(&rfkill_wimax,
|
||||||
|
(data)? RFKILL_STATE_ON:
|
||||||
|
RFKILL_STATE_OFF);
|
||||||
|
rfkill_schedule_set(&rfkill_uwb,
|
||||||
|
(data)? RFKILL_STATE_ON:
|
||||||
|
RFKILL_STATE_OFF);
|
||||||
|
rfkill_schedule_set(&rfkill_bt,
|
||||||
|
(data)? RFKILL_STATE_ON:
|
||||||
|
RFKILL_STATE_OFF);
|
||||||
|
rfkill_schedule_set(&rfkill_wlan,
|
||||||
|
(data)? RFKILL_STATE_ON:
|
||||||
|
RFKILL_STATE_OFF);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,6 +204,11 @@ static const struct input_device_id rfkill_ids[] = {
|
|||||||
.evbit = { BIT_MASK(EV_KEY) },
|
.evbit = { BIT_MASK(EV_KEY) },
|
||||||
.keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
|
.keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT,
|
||||||
|
.evbit = { BIT(EV_SW) },
|
||||||
|
.swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) },
|
||||||
|
},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user