Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e28fbef authored by Henrique de Moraes Holschuh's avatar Henrique de Moraes Holschuh Committed by John W. Linville
Browse files

rfkill: query EV_SW states when rfkill-input (re)?connects to a input device



Every time a new input device that is capable of one of the
rfkill EV_SW events (currently only SW_RFKILL_ALL) is connected to
rfkill-input, we must check the states of the input EV_SW switches
and take action.  Otherwise, we will ignore the initial switch state.

We also need to re-check the states of the EV_SW switches after
a device that was under an exclusive grab is released back to us,
since we got no input events from that device while it was grabbed.

Signed-off-by: default avatarHenrique de Moraes Holschuh <hmh@hmh.eng.br>
Acked-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
Cc: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent f860ee26
Loading
Loading
Loading
Loading
+39 −15
Original line number Original line Diff line number Diff line
@@ -109,6 +109,25 @@ 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 DEFINE_RFKILL_TASK(rfkill_wwan, RFKILL_TYPE_WWAN);
static DEFINE_RFKILL_TASK(rfkill_wwan, RFKILL_TYPE_WWAN);


static void rfkill_schedule_evsw_rfkillall(int state)
{
	/* EVERY radio type. state != 0 means radios ON */
	/* handle EPO (emergency power off) through shortcut */
	if (state) {
		rfkill_schedule_set(&rfkill_wwan,
				    RFKILL_STATE_UNBLOCKED);
		rfkill_schedule_set(&rfkill_wimax,
				    RFKILL_STATE_UNBLOCKED);
		rfkill_schedule_set(&rfkill_uwb,
				    RFKILL_STATE_UNBLOCKED);
		rfkill_schedule_set(&rfkill_bt,
				    RFKILL_STATE_UNBLOCKED);
		rfkill_schedule_set(&rfkill_wlan,
				    RFKILL_STATE_UNBLOCKED);
	} else
		rfkill_schedule_epo();
}

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 data)
			unsigned int code, int data)
{
{
@@ -132,21 +151,7 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
	} else if (type == EV_SW) {
	} else if (type == EV_SW) {
		switch (code) {
		switch (code) {
		case SW_RFKILL_ALL:
		case SW_RFKILL_ALL:
			/* EVERY radio type. data != 0 means radios ON */
			rfkill_schedule_evsw_rfkillall(data);
			/* handle EPO (emergency power off) through shortcut */
			if (data) {
				rfkill_schedule_set(&rfkill_wwan,
						    RFKILL_STATE_UNBLOCKED);
				rfkill_schedule_set(&rfkill_wimax,
						    RFKILL_STATE_UNBLOCKED);
				rfkill_schedule_set(&rfkill_uwb,
						    RFKILL_STATE_UNBLOCKED);
				rfkill_schedule_set(&rfkill_bt,
						    RFKILL_STATE_UNBLOCKED);
				rfkill_schedule_set(&rfkill_wlan,
						    RFKILL_STATE_UNBLOCKED);
			} else
				rfkill_schedule_epo();
			break;
			break;
		default:
		default:
			break;
			break;
@@ -168,6 +173,7 @@ static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
	handle->handler = handler;
	handle->handler = handler;
	handle->name = "rfkill";
	handle->name = "rfkill";


	/* causes rfkill_start() to be called */
	error = input_register_handle(handle);
	error = input_register_handle(handle);
	if (error)
	if (error)
		goto err_free_handle;
		goto err_free_handle;
@@ -185,6 +191,23 @@ static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
	return error;
	return error;
}
}


static void rfkill_start(struct input_handle *handle)
{
	/* Take event_lock to guard against configuration changes, we
	 * should be able to deal with concurrency with rfkill_event()
	 * just fine (which event_lock will also avoid). */
	spin_lock_irq(&handle->dev->event_lock);

	if (test_bit(EV_SW, handle->dev->evbit)) {
		if (test_bit(SW_RFKILL_ALL, handle->dev->swbit))
			rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL,
							handle->dev->sw));
		/* add resync for further EV_SW events here */
	}

	spin_unlock_irq(&handle->dev->event_lock);
}

static void rfkill_disconnect(struct input_handle *handle)
static void rfkill_disconnect(struct input_handle *handle)
{
{
	input_close_device(handle);
	input_close_device(handle);
@@ -225,6 +248,7 @@ static struct input_handler rfkill_handler = {
	.event =	rfkill_event,
	.event =	rfkill_event,
	.connect =	rfkill_connect,
	.connect =	rfkill_connect,
	.disconnect =	rfkill_disconnect,
	.disconnect =	rfkill_disconnect,
	.start =	rfkill_start,
	.name =		"rfkill",
	.name =		"rfkill",
	.id_table =	rfkill_ids,
	.id_table =	rfkill_ids,
};
};