@@ -1304,6 +1304,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
<bus_id>,<clkrate>
i8042.debug [HW] Toggle i8042 debug mode
+ i8042.debug_kbd [HW] Enable printing of interrupt data from the KBD port
+ (disabled by default, requires that i8042.debug=1
+ be enabled)
i8042.direct [HW] Put keyboard port into non-translated mode
i8042.dumbkbd [HW] Pretend that controller can only read data from
keyboard and cannot control its state
@@ -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_debug_kbd;
+module_param_named(debug_kbd, i8042_debug_kbd, bool, 0600);
+MODULE_PARM_DESC(i8042_kbd, "Turn i8042 kbd debugging output on or off (requires i8042.debug=1)");
#endif
static bool i8042_bypass_aux_irq_test;
@@ -116,6 +120,9 @@ struct i8042_port {
struct serio *serio;
int irq;
bool exists;
+#ifdef DEBUG
+ bool filter_dbg;
+#endif
signed char mux;
};
@@ -133,6 +140,9 @@ 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;
+#ifdef DEBUG
+static struct notifier_block i8042_kbd_bind_notifier_block;
+#endif
static irqreturn_t i8042_interrupt(int irq, void *dev_id);
static bool (*i8042_platform_filter)(unsigned char data, unsigned char str,
@@ -528,10 +538,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->filter_dbg, 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);
@@ -1329,6 +1339,13 @@ static void __init i8042_register_ports(void)
i8042_ports[i].irq);
serio_register_port(serio);
device_set_wakeup_capable(&serio->dev, true);
+#ifdef DEBUG
+ if (i8042_ports[i].irq == I8042_KBD_IRQ) {
+ bus_register_notifier(
+ serio->dev.bus,
+ &i8042_kbd_bind_notifier_block);
+ }
+#endif
}
}
}
@@ -1338,8 +1355,17 @@ static void i8042_unregister_ports(void)
int i;
for (i = 0; i < I8042_NUM_PORTS; i++) {
- if (i8042_ports[i].serio) {
- serio_unregister_port(i8042_ports[i].serio);
+ struct serio *serio = i8042_ports[i].serio;
+
+ if (serio) {
+#ifdef DEBUG
+ if (i8042_ports[i].irq == I8042_KBD_IRQ) {
+ bus_unregister_notifier(
+ serio->dev.bus,
+ &i8042_kbd_bind_notifier_block);
+ }
+#endif
+ serio_unregister_port(serio);
i8042_ports[i].serio = NULL;
}
}
@@ -1438,6 +1464,22 @@ static int __init i8042_setup_kbd(void)
return error;
}
+#ifdef DEBUG
+static int i8042_kbd_bind_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct device *dev = data;
+ struct i8042_port *port = to_serio_port(dev)->port_data;
+
+ if (action == BUS_NOTIFY_BOUND_DRIVER)
+ port->filter_dbg = true;
+ else if (action == BUS_NOTIFY_UNBOUND_DRIVER)
+ port->filter_dbg = false;
+
+ return 0;
+}
+#endif
+
static int __init i8042_probe(struct platform_device *dev)
{
int error;
@@ -1507,6 +1549,12 @@ static struct platform_driver i8042_driver = {
.shutdown = i8042_shutdown,
};
+#ifdef DEBUG
+static struct notifier_block i8042_kbd_bind_notifier_block = {
+ .notifier_call = i8042_kbd_bind_notifier,
+};
+#endif
+
static int __init i8042_init(void)
{
struct platform_device *pdev;
@@ -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_debug_kbd) \
+ 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 */