Commit 6e28fbef0f330d7c1cade345eeae003d4e5d6070
Committed by
John W. Linville
1 parent
f860ee26db
Exists in
master
and in
7 other branches
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: 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>
Showing 1 changed file with 39 additions and 15 deletions Side-by-side Diff
net/rfkill/rfkill-input.c
... | ... | @@ -109,6 +109,25 @@ |
109 | 109 | static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX); |
110 | 110 | static DEFINE_RFKILL_TASK(rfkill_wwan, RFKILL_TYPE_WWAN); |
111 | 111 | |
112 | +static void rfkill_schedule_evsw_rfkillall(int state) | |
113 | +{ | |
114 | + /* EVERY radio type. state != 0 means radios ON */ | |
115 | + /* handle EPO (emergency power off) through shortcut */ | |
116 | + if (state) { | |
117 | + rfkill_schedule_set(&rfkill_wwan, | |
118 | + RFKILL_STATE_UNBLOCKED); | |
119 | + rfkill_schedule_set(&rfkill_wimax, | |
120 | + RFKILL_STATE_UNBLOCKED); | |
121 | + rfkill_schedule_set(&rfkill_uwb, | |
122 | + RFKILL_STATE_UNBLOCKED); | |
123 | + rfkill_schedule_set(&rfkill_bt, | |
124 | + RFKILL_STATE_UNBLOCKED); | |
125 | + rfkill_schedule_set(&rfkill_wlan, | |
126 | + RFKILL_STATE_UNBLOCKED); | |
127 | + } else | |
128 | + rfkill_schedule_epo(); | |
129 | +} | |
130 | + | |
112 | 131 | static void rfkill_event(struct input_handle *handle, unsigned int type, |
113 | 132 | unsigned int code, int data) |
114 | 133 | { |
... | ... | @@ -132,21 +151,7 @@ |
132 | 151 | } else if (type == EV_SW) { |
133 | 152 | switch (code) { |
134 | 153 | case SW_RFKILL_ALL: |
135 | - /* EVERY radio type. data != 0 means radios ON */ | |
136 | - /* handle EPO (emergency power off) through shortcut */ | |
137 | - if (data) { | |
138 | - rfkill_schedule_set(&rfkill_wwan, | |
139 | - RFKILL_STATE_UNBLOCKED); | |
140 | - rfkill_schedule_set(&rfkill_wimax, | |
141 | - RFKILL_STATE_UNBLOCKED); | |
142 | - rfkill_schedule_set(&rfkill_uwb, | |
143 | - RFKILL_STATE_UNBLOCKED); | |
144 | - rfkill_schedule_set(&rfkill_bt, | |
145 | - RFKILL_STATE_UNBLOCKED); | |
146 | - rfkill_schedule_set(&rfkill_wlan, | |
147 | - RFKILL_STATE_UNBLOCKED); | |
148 | - } else | |
149 | - rfkill_schedule_epo(); | |
154 | + rfkill_schedule_evsw_rfkillall(data); | |
150 | 155 | break; |
151 | 156 | default: |
152 | 157 | break; |
... | ... | @@ -168,6 +173,7 @@ |
168 | 173 | handle->handler = handler; |
169 | 174 | handle->name = "rfkill"; |
170 | 175 | |
176 | + /* causes rfkill_start() to be called */ | |
171 | 177 | error = input_register_handle(handle); |
172 | 178 | if (error) |
173 | 179 | goto err_free_handle; |
... | ... | @@ -185,6 +191,23 @@ |
185 | 191 | return error; |
186 | 192 | } |
187 | 193 | |
194 | +static void rfkill_start(struct input_handle *handle) | |
195 | +{ | |
196 | + /* Take event_lock to guard against configuration changes, we | |
197 | + * should be able to deal with concurrency with rfkill_event() | |
198 | + * just fine (which event_lock will also avoid). */ | |
199 | + spin_lock_irq(&handle->dev->event_lock); | |
200 | + | |
201 | + if (test_bit(EV_SW, handle->dev->evbit)) { | |
202 | + if (test_bit(SW_RFKILL_ALL, handle->dev->swbit)) | |
203 | + rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL, | |
204 | + handle->dev->sw)); | |
205 | + /* add resync for further EV_SW events here */ | |
206 | + } | |
207 | + | |
208 | + spin_unlock_irq(&handle->dev->event_lock); | |
209 | +} | |
210 | + | |
188 | 211 | static void rfkill_disconnect(struct input_handle *handle) |
189 | 212 | { |
190 | 213 | input_close_device(handle); |
... | ... | @@ -225,6 +248,7 @@ |
225 | 248 | .event = rfkill_event, |
226 | 249 | .connect = rfkill_connect, |
227 | 250 | .disconnect = rfkill_disconnect, |
251 | + .start = rfkill_start, | |
228 | 252 | .name = "rfkill", |
229 | 253 | .id_table = rfkill_ids, |
230 | 254 | }; |