|
@@ -676,6 +676,39 @@ static inline void atkbd_disable(struct atkbd *atkbd)
|
|
|
serio_continue_rx(atkbd->ps2dev.serio);
|
|
|
}
|
|
|
|
|
|
+static int atkbd_activate(struct atkbd *atkbd)
|
|
|
+{
|
|
|
+ struct ps2dev *ps2dev = &atkbd->ps2dev;
|
|
|
+
|
|
|
+/*
|
|
|
+ * Enable the keyboard to receive keystrokes.
|
|
|
+ */
|
|
|
+
|
|
|
+ if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) {
|
|
|
+ dev_err(&ps2dev->serio->dev,
|
|
|
+ "Failed to enable keyboard on %s\n",
|
|
|
+ ps2dev->serio->phys);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * atkbd_deactivate() resets and disables the keyboard from sending
|
|
|
+ * keystrokes.
|
|
|
+ */
|
|
|
+
|
|
|
+static void atkbd_deactivate(struct atkbd *atkbd)
|
|
|
+{
|
|
|
+ struct ps2dev *ps2dev = &atkbd->ps2dev;
|
|
|
+
|
|
|
+ if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_DIS))
|
|
|
+ dev_err(&ps2dev->serio->dev,
|
|
|
+ "Failed to deactivate keyboard on %s\n",
|
|
|
+ ps2dev->serio->phys);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* atkbd_probe() probes for an AT keyboard on a serio port.
|
|
|
*/
|
|
@@ -731,6 +764,12 @@ static int atkbd_probe(struct atkbd *atkbd)
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Make sure nothing is coming from the keyboard and disturbs our
|
|
|
+ * internal state.
|
|
|
+ */
|
|
|
+ atkbd_deactivate(atkbd);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -825,24 +864,6 @@ static int atkbd_reset_state(struct atkbd *atkbd)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int atkbd_activate(struct atkbd *atkbd)
|
|
|
-{
|
|
|
- struct ps2dev *ps2dev = &atkbd->ps2dev;
|
|
|
-
|
|
|
-/*
|
|
|
- * Enable the keyboard to receive keystrokes.
|
|
|
- */
|
|
|
-
|
|
|
- if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) {
|
|
|
- dev_err(&ps2dev->serio->dev,
|
|
|
- "Failed to enable keyboard on %s\n",
|
|
|
- ps2dev->serio->phys);
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* atkbd_cleanup() restores the keyboard state so that BIOS is happy after a
|
|
|
* reboot.
|
|
@@ -1150,7 +1171,6 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
|
|
|
|
|
|
atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
|
|
|
atkbd_reset_state(atkbd);
|
|
|
- atkbd_activate(atkbd);
|
|
|
|
|
|
} else {
|
|
|
atkbd->set = 2;
|
|
@@ -1165,6 +1185,8 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
|
|
|
goto fail3;
|
|
|
|
|
|
atkbd_enable(atkbd);
|
|
|
+ if (serio->write)
|
|
|
+ atkbd_activate(atkbd);
|
|
|
|
|
|
err = input_register_device(atkbd->dev);
|
|
|
if (err)
|
|
@@ -1208,8 +1230,6 @@ static int atkbd_reconnect(struct serio *serio)
|
|
|
if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra))
|
|
|
goto out;
|
|
|
|
|
|
- atkbd_activate(atkbd);
|
|
|
-
|
|
|
/*
|
|
|
* Restore LED state and repeat rate. While input core
|
|
|
* will do this for us at resume time reconnect may happen
|
|
@@ -1223,7 +1243,17 @@ static int atkbd_reconnect(struct serio *serio)
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Reset our state machine in case reconnect happened in the middle
|
|
|
+ * of multi-byte scancode.
|
|
|
+ */
|
|
|
+ atkbd->xl_bit = 0;
|
|
|
+ atkbd->emul = 0;
|
|
|
+
|
|
|
atkbd_enable(atkbd);
|
|
|
+ if (atkbd->write)
|
|
|
+ atkbd_activate(atkbd);
|
|
|
+
|
|
|
retval = 0;
|
|
|
|
|
|
out:
|