@@ -99,7 +99,8 @@ static irqreturn_t sunkbd_interrupt(struct serio *serio,
99
99
switch (data ) {
100
100
101
101
case SUNKBD_RET_RESET :
102
- schedule_work (& sunkbd -> tq );
102
+ if (sunkbd -> enabled )
103
+ schedule_work (& sunkbd -> tq );
103
104
sunkbd -> reset = -1 ;
104
105
break ;
105
106
@@ -200,16 +201,12 @@ static int sunkbd_initialize(struct sunkbd *sunkbd)
200
201
}
201
202
202
203
/*
203
- * sunkbd_reinit () sets leds and beeps to a state the computer remembers they
204
- * were in.
204
+ * sunkbd_set_leds_beeps () sets leds and beeps to a state the computer remembers
205
+ * they were in.
205
206
*/
206
207
207
- static void sunkbd_reinit (struct work_struct * work )
208
+ static void sunkbd_set_leds_beeps (struct sunkbd * sunkbd )
208
209
{
209
- struct sunkbd * sunkbd = container_of (work , struct sunkbd , tq );
210
-
211
- wait_event_interruptible_timeout (sunkbd -> wait , sunkbd -> reset >= 0 , HZ );
212
-
213
210
serio_write (sunkbd -> serio , SUNKBD_CMD_SETLED );
214
211
serio_write (sunkbd -> serio ,
215
212
(!!test_bit (LED_CAPSL , sunkbd -> dev -> led ) << 3 ) |
@@ -222,11 +219,39 @@ static void sunkbd_reinit(struct work_struct *work)
222
219
SUNKBD_CMD_BELLOFF - !!test_bit (SND_BELL , sunkbd -> dev -> snd ));
223
220
}
224
221
222
+
223
+ /*
224
+ * sunkbd_reinit() wait for the keyboard reset to complete and restores state
225
+ * of leds and beeps.
226
+ */
227
+
228
+ static void sunkbd_reinit (struct work_struct * work )
229
+ {
230
+ struct sunkbd * sunkbd = container_of (work , struct sunkbd , tq );
231
+
232
+ /*
233
+ * It is OK that we check sunkbd->enabled without pausing serio,
234
+ * as we only want to catch true->false transition that will
235
+ * happen once and we will be woken up for it.
236
+ */
237
+ wait_event_interruptible_timeout (sunkbd -> wait ,
238
+ sunkbd -> reset >= 0 || !sunkbd -> enabled ,
239
+ HZ );
240
+
241
+ if (sunkbd -> reset >= 0 && sunkbd -> enabled )
242
+ sunkbd_set_leds_beeps (sunkbd );
243
+ }
244
+
225
245
static void sunkbd_enable (struct sunkbd * sunkbd , bool enable )
226
246
{
227
247
serio_pause_rx (sunkbd -> serio );
228
248
sunkbd -> enabled = enable ;
229
249
serio_continue_rx (sunkbd -> serio );
250
+
251
+ if (!enable ) {
252
+ wake_up_interruptible (& sunkbd -> wait );
253
+ cancel_work_sync (& sunkbd -> tq );
254
+ }
230
255
}
231
256
232
257
/*
0 commit comments