summaryrefslogtreecommitdiff
path: root/drivers/input/serio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/serio')
-rw-r--r--drivers/input/serio/ambakmi.c8
-rw-r--r--drivers/input/serio/i8042.c45
-rw-r--r--drivers/input/serio/i8042.h13
-rw-r--r--drivers/input/serio/libps2.c22
-rw-r--r--drivers/input/serio/parkbd.c1
-rw-r--r--drivers/input/serio/serio.c5
6 files changed, 75 insertions, 19 deletions
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
index 8b748d99b..c6606cacb 100644
--- a/drivers/input/serio/ambakmi.c
+++ b/drivers/input/serio/ambakmi.c
@@ -175,9 +175,9 @@ static int amba_kmi_remove(struct amba_device *dev)
return 0;
}
-static int amba_kmi_resume(struct amba_device *dev)
+static int __maybe_unused amba_kmi_resume(struct device *dev)
{
- struct amba_kmi_port *kmi = amba_get_drvdata(dev);
+ struct amba_kmi_port *kmi = dev_get_drvdata(dev);
/* kick the serio layer to rescan this port */
serio_reconnect(kmi->io);
@@ -185,6 +185,8 @@ static int amba_kmi_resume(struct amba_device *dev)
return 0;
}
+static SIMPLE_DEV_PM_OPS(amba_kmi_dev_pm_ops, NULL, amba_kmi_resume);
+
static struct amba_id amba_kmi_idtable[] = {
{
.id = 0x00041050,
@@ -199,11 +201,11 @@ static struct amba_driver ambakmi_driver = {
.drv = {
.name = "kmi-pl050",
.owner = THIS_MODULE,
+ .pm = &amba_kmi_dev_pm_ops,
},
.id_table = amba_kmi_idtable,
.probe = amba_kmi_probe,
.remove = amba_kmi_remove,
- .resume = amba_kmi_resume,
};
module_amba_driver(ambakmi_driver);
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index cb5ece77f..db91de539 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -88,6 +88,10 @@ MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings");
static bool i8042_debug;
module_param_named(debug, i8042_debug, bool, 0600);
MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off");
+
+static bool i8042_unmask_kbd_data;
+module_param_named(unmask_kbd_data, i8042_unmask_kbd_data, bool, 0600);
+MODULE_PARM_DESC(unmask_kbd_data, "Unconditional enable (may reveal sensitive data) of normally sanitize-filtered kbd data traffic debug log [pre-condition: i8042.debug=1 enabled]");
#endif
static bool i8042_bypass_aux_irq_test;
@@ -116,6 +120,7 @@ struct i8042_port {
struct serio *serio;
int irq;
bool exists;
+ bool driver_bound;
signed char mux;
};
@@ -133,6 +138,7 @@ static bool i8042_kbd_irq_registered;
static bool i8042_aux_irq_registered;
static unsigned char i8042_suppress_kbd_ack;
static struct platform_device *i8042_platform_device;
+static struct notifier_block i8042_kbd_bind_notifier_block;
static irqreturn_t i8042_interrupt(int irq, void *dev_id);
static bool (*i8042_platform_filter)(unsigned char data, unsigned char str,
@@ -528,10 +534,10 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
port = &i8042_ports[port_no];
serio = port->exists ? port->serio : NULL;
- dbg("%02x <- i8042 (interrupt, %d, %d%s%s)\n",
- data, port_no, irq,
- dfl & SERIO_PARITY ? ", bad parity" : "",
- dfl & SERIO_TIMEOUT ? ", timeout" : "");
+ filter_dbg(port->driver_bound, data, "<- i8042 (interrupt, %d, %d%s%s)\n",
+ port_no, irq,
+ dfl & SERIO_PARITY ? ", bad parity" : "",
+ dfl & SERIO_TIMEOUT ? ", timeout" : "");
filtered = i8042_filter(data, str, serio);
@@ -871,7 +877,7 @@ static int __init i8042_check_aux(void)
static int i8042_controller_check(void)
{
if (i8042_flush()) {
- pr_err("No controller found\n");
+ pr_info("No controller found\n");
return -ENODEV;
}
@@ -1438,6 +1444,29 @@ static int __init i8042_setup_kbd(void)
return error;
}
+static int i8042_kbd_bind_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct device *dev = data;
+ struct serio *serio = to_serio_port(dev);
+ struct i8042_port *port = serio->port_data;
+
+ if (serio != i8042_ports[I8042_KBD_PORT_NO].serio)
+ return 0;
+
+ switch (action) {
+ case BUS_NOTIFY_BOUND_DRIVER:
+ port->driver_bound = true;
+ break;
+
+ case BUS_NOTIFY_UNBIND_DRIVER:
+ port->driver_bound = false;
+ break;
+ }
+
+ return 0;
+}
+
static int __init i8042_probe(struct platform_device *dev)
{
int error;
@@ -1507,6 +1536,10 @@ static struct platform_driver i8042_driver = {
.shutdown = i8042_shutdown,
};
+static struct notifier_block i8042_kbd_bind_notifier_block = {
+ .notifier_call = i8042_kbd_bind_notifier,
+};
+
static int __init i8042_init(void)
{
struct platform_device *pdev;
@@ -1528,6 +1561,7 @@ static int __init i8042_init(void)
goto err_platform_exit;
}
+ bus_register_notifier(&serio_bus, &i8042_kbd_bind_notifier_block);
panic_blink = i8042_panic_blink;
return 0;
@@ -1543,6 +1577,7 @@ static void __exit i8042_exit(void)
platform_driver_unregister(&i8042_driver);
i8042_platform_exit();
+ bus_unregister_notifier(&serio_bus, &i8042_kbd_bind_notifier_block);
panic_blink = NULL;
}
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
index fc080beff..1db0a40c9 100644
--- a/drivers/input/serio/i8042.h
+++ b/drivers/input/serio/i8042.h
@@ -73,6 +73,17 @@ static unsigned long i8042_start_time;
printk(KERN_DEBUG KBUILD_MODNAME ": [%d] " format, \
(int) (jiffies - i8042_start_time), ##arg); \
} while (0)
+
+#define filter_dbg(filter, data, format, args...) \
+ do { \
+ if (!i8042_debug) \
+ break; \
+ \
+ if (!filter || i8042_unmask_kbd_data) \
+ dbg("%02x " format, data, ##args); \
+ else \
+ dbg("** " format, ##args); \
+ } while (0)
#else
#define dbg_init() do { } while (0)
#define dbg(format, arg...) \
@@ -80,6 +91,8 @@ static unsigned long i8042_start_time;
if (0) \
printk(KERN_DEBUG pr_fmt(format), ##arg); \
} while (0)
+
+#define filter_dbg(filter, data, format, args...) do { } while (0)
#endif
#endif /* _I8042_H */
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index 75516996d..316f2c897 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -212,12 +212,17 @@ int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
* time before the ACK arrives.
*/
if (ps2_sendbyte(ps2dev, command & 0xff,
- command == PS2_CMD_RESET_BAT ? 1000 : 200))
- goto out;
+ command == PS2_CMD_RESET_BAT ? 1000 : 200)) {
+ serio_pause_rx(ps2dev->serio);
+ goto out_reset_flags;
+ }
- for (i = 0; i < send; i++)
- if (ps2_sendbyte(ps2dev, param[i], 200))
- goto out;
+ for (i = 0; i < send; i++) {
+ if (ps2_sendbyte(ps2dev, param[i], 200)) {
+ serio_pause_rx(ps2dev->serio);
+ goto out_reset_flags;
+ }
+ }
/*
* The reset command takes a long time to execute.
@@ -234,17 +239,18 @@ int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
!(ps2dev->flags & PS2_FLAG_CMD), timeout);
}
+ serio_pause_rx(ps2dev->serio);
+
if (param)
for (i = 0; i < receive; i++)
param[i] = ps2dev->cmdbuf[(receive - 1) - i];
if (ps2dev->cmdcnt && (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1))
- goto out;
+ goto out_reset_flags;
rc = 0;
- out:
- serio_pause_rx(ps2dev->serio);
+ out_reset_flags:
ps2dev->flags = 0;
serio_continue_rx(ps2dev->serio);
diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c
index 26b45936f..1e8cd6f1f 100644
--- a/drivers/input/serio/parkbd.c
+++ b/drivers/input/serio/parkbd.c
@@ -194,6 +194,7 @@ static int __init parkbd_init(void)
parkbd_port = parkbd_allocate_serio();
if (!parkbd_port) {
parport_release(parkbd_dev);
+ parport_unregister_device(parkbd_dev);
return -ENOMEM;
}
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index a05a5179d..8f828975a 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -49,8 +49,6 @@ static DEFINE_MUTEX(serio_mutex);
static LIST_HEAD(serio_list);
-static struct bus_type serio_bus;
-
static void serio_add_port(struct serio *serio);
static int serio_reconnect_port(struct serio *serio);
static void serio_disconnect_port(struct serio *serio);
@@ -1017,7 +1015,7 @@ irqreturn_t serio_interrupt(struct serio *serio,
}
EXPORT_SYMBOL(serio_interrupt);
-static struct bus_type serio_bus = {
+struct bus_type serio_bus = {
.name = "serio",
.drv_groups = serio_driver_groups,
.match = serio_bus_match,
@@ -1029,6 +1027,7 @@ static struct bus_type serio_bus = {
.pm = &serio_pm_ops,
#endif
};
+EXPORT_SYMBOL(serio_bus);
static int __init serio_init(void)
{