diff options
Diffstat (limited to 'drivers/input/serio')
-rw-r--r-- | drivers/input/serio/Kconfig | 9 | ||||
-rw-r--r-- | drivers/input/serio/ams_delta_serio.c | 1 | ||||
-rw-r--r-- | drivers/input/serio/ct82c710.c | 16 | ||||
-rw-r--r-- | drivers/input/serio/gscps2.c | 2 | ||||
-rw-r--r-- | drivers/input/serio/hil_mlc.c | 5 | ||||
-rw-r--r-- | drivers/input/serio/hp_sdc_mlc.c | 18 | ||||
-rw-r--r-- | drivers/input/serio/i8042-x86ia64io.h | 58 | ||||
-rw-r--r-- | drivers/input/serio/i8042.c | 98 | ||||
-rw-r--r-- | drivers/input/serio/i8042.h | 14 | ||||
-rw-r--r-- | drivers/input/serio/ps2mult.c | 2 | ||||
-rw-r--r-- | drivers/input/serio/serio.c | 166 | ||||
-rw-r--r-- | drivers/input/serio/serport.c | 24 |
12 files changed, 220 insertions, 193 deletions
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 6256233d2bf..55f2c2293ec 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig @@ -2,7 +2,7 @@ # Input core configuration # config SERIO - tristate "Serial I/O support" if EMBEDDED || !X86 + tristate "Serial I/O support" if EXPERT || !X86 default y help Say Yes here if you have any input device that uses serial I/O to @@ -19,7 +19,7 @@ config SERIO if SERIO config SERIO_I8042 - tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86 + tristate "i8042 PC Keyboard controller" if EXPERT || !X86 default y depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \ (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN @@ -168,7 +168,7 @@ config SERIO_MACEPS2 module will be called maceps2. config SERIO_LIBPS2 - tristate "PS/2 driver library" if EMBEDDED + tristate "PS/2 driver library" if EXPERT depends on SERIO_I8042 || SERIO_I8042=n help Say Y here if you are using a driver for device connected @@ -214,7 +214,6 @@ config SERIO_AMS_DELTA tristate "Amstrad Delta (E3) mailboard support" depends on MACH_AMS_DELTA default y - select AMS_DELTA_FIQ ---help--- Say Y here if you have an E3 and want to use its mailboard, or any standard AT keyboard connected to the mailboard port. @@ -230,7 +229,7 @@ config SERIO_PS2MULT tristate "TQC PS/2 multiplexer" help Say Y here if you have the PS/2 line multiplexer like the one - present on TQC boads. + present on TQC boards. To compile this driver as a module, choose M here: the module will be called ps2mult. diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c index 8f1770e1e08..ebe95532567 100644 --- a/drivers/input/serio/ams_delta_serio.c +++ b/drivers/input/serio/ams_delta_serio.c @@ -172,6 +172,5 @@ static void __exit ams_delta_serio_exit(void) free_irq(OMAP_GPIO_IRQ(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), 0); gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_CLK); gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_DATA); - kfree(ams_delta_serio); } module_exit(ams_delta_serio_exit); diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index 4a3084695c0..85281656724 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c @@ -111,9 +111,11 @@ static void ct82c710_close(struct serio *serio) static int ct82c710_open(struct serio *serio) { unsigned char status; + int err; - if (request_irq(CT82C710_IRQ, ct82c710_interrupt, 0, "ct82c710", NULL)) - return -1; + err = request_irq(CT82C710_IRQ, ct82c710_interrupt, 0, "ct82c710", NULL); + if (err) + return err; status = inb_p(CT82C710_STATUS); @@ -131,7 +133,7 @@ static int ct82c710_open(struct serio *serio) status &= ~(CT82C710_ENABLE | CT82C710_INTS_ON); outb_p(status, CT82C710_STATUS); free_irq(CT82C710_IRQ, NULL); - return -1; + return -EBUSY; } return 0; @@ -191,6 +193,9 @@ static int __devinit ct82c710_probe(struct platform_device *dev) serio_register_port(ct82c710_port); + printk(KERN_INFO "serio: C&T 82c710 mouse port at %#llx irq %d\n", + (unsigned long long)CT82C710_DATA, CT82C710_IRQ); + return 0; } @@ -237,11 +242,6 @@ static int __init ct82c710_init(void) if (error) goto err_free_device; - serio_register_port(ct82c710_port); - - printk(KERN_INFO "serio: C&T 82c710 mouse port at %#llx irq %d\n", - (unsigned long long)CT82C710_DATA, CT82C710_IRQ); - return 0; err_free_device: diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index 3c287dd879d..4225f5d6b15 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c @@ -358,7 +358,7 @@ static int __devinit gscps2_probe(struct parisc_device *dev) gscps2_reset(ps2port); ps2port->id = readb(ps2port->addr + GSC_ID) & 0x0f; - snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s", + snprintf(serio->name, sizeof(serio->name), "gsc-ps2-%s", (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse"); strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys)); serio->id.type = SERIO_8042; diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index e5624d8f170..bfd3865d886 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c @@ -932,6 +932,11 @@ int hil_mlc_register(hil_mlc *mlc) hil_mlc_copy_di_scratch(mlc, i); mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL); mlc->serio[i] = mlc_serio; + if (!mlc->serio[i]) { + for (; i >= 0; i--) + kfree(mlc->serio[i]); + return -ENOMEM; + } snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i); snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i); mlc_serio->id = hil_mlc_serio_id; diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c index 7d2b820ef58..d50f0678bf4 100644 --- a/drivers/input/serio/hp_sdc_mlc.c +++ b/drivers/input/serio/hp_sdc_mlc.c @@ -305,6 +305,7 @@ static void hp_sdc_mlc_out(hil_mlc *mlc) static int __init hp_sdc_mlc_init(void) { hil_mlc *mlc = &hp_sdc_mlc; + int err; #ifdef __mc68000__ if (!MACH_IS_HP300) @@ -323,22 +324,21 @@ static int __init hp_sdc_mlc_init(void) mlc->out = &hp_sdc_mlc_out; mlc->priv = &hp_sdc_mlc_priv; - if (hil_mlc_register(mlc)) { + err = hil_mlc_register(mlc); + if (err) { printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n"); - goto err0; + return err; } if (hp_sdc_request_hil_irq(&hp_sdc_mlc_isr)) { printk(KERN_WARNING PREFIX "Request for raw HIL ISR hook denied\n"); - goto err1; + if (hil_mlc_unregister(mlc)) + printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" + "This is bad. Could cause an oops.\n"); + return -EBUSY; } + return 0; - err1: - if (hil_mlc_unregister(mlc)) - printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" - "This is bad. Could cause an oops.\n"); - err0: - return -EBUSY; } static void __exit hp_sdc_mlc_exit(void) diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index a5475b57708..bb9f5d31f0d 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -424,6 +424,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), }, }, + { + /* Dell Vostro V13 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), + }, + }, { } }; @@ -545,6 +552,17 @@ static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = { }; #endif +static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = { + { + /* Dell Vostro V13 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), + }, + }, + { } +}; + /* * Some Wistron based laptops need us to explicitly enable the 'Dritek * keyboard extension' to make their extra keys start generating scancodes. @@ -553,6 +571,13 @@ static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = { */ static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { { + /* Acer Aspire 5100 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), + }, + }, + { /* Acer Aspire 5610 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), @@ -752,7 +777,7 @@ static int __init i8042_pnp_init(void) #endif if (i8042_nopnp) { - printk(KERN_INFO "i8042: PNP detection disabled\n"); + pr_info("PNP detection disabled\n"); return 0; } @@ -769,7 +794,7 @@ static int __init i8042_pnp_init(void) #if defined(__ia64__) return -ENODEV; #else - printk(KERN_INFO "PNP: No PS/2 controller found. Probing ports directly.\n"); + pr_info("PNP: No PS/2 controller found. Probing ports directly.\n"); return 0; #endif } @@ -781,7 +806,7 @@ static int __init i8042_pnp_init(void) snprintf(aux_irq_str, sizeof(aux_irq_str), "%d", i8042_pnp_aux_irq); - printk(KERN_INFO "PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n", + pr_info("PNP: PS/2 Controller [%s%s%s] at %#x,%#x irq %s%s%s\n", i8042_pnp_kbd_name, (i8042_pnp_kbd_devices && i8042_pnp_aux_devices) ? "," : "", i8042_pnp_aux_name, i8042_pnp_data_reg, i8042_pnp_command_reg, @@ -798,9 +823,7 @@ static int __init i8042_pnp_init(void) if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && i8042_pnp_data_reg != i8042_data_reg) || !i8042_pnp_data_reg) { - printk(KERN_WARNING - "PNP: PS/2 controller has invalid data port %#x; " - "using default %#x\n", + pr_warn("PNP: PS/2 controller has invalid data port %#x; using default %#x\n", i8042_pnp_data_reg, i8042_data_reg); i8042_pnp_data_reg = i8042_data_reg; pnp_data_busted = true; @@ -809,33 +832,27 @@ static int __init i8042_pnp_init(void) if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) && i8042_pnp_command_reg != i8042_command_reg) || !i8042_pnp_command_reg) { - printk(KERN_WARNING - "PNP: PS/2 controller has invalid command port %#x; " - "using default %#x\n", + pr_warn("PNP: PS/2 controller has invalid command port %#x; using default %#x\n", i8042_pnp_command_reg, i8042_command_reg); i8042_pnp_command_reg = i8042_command_reg; pnp_data_busted = true; } if (!i8042_nokbd && !i8042_pnp_kbd_irq) { - printk(KERN_WARNING - "PNP: PS/2 controller doesn't have KBD irq; " - "using default %d\n", i8042_kbd_irq); + pr_warn("PNP: PS/2 controller doesn't have KBD irq; using default %d\n", + i8042_kbd_irq); i8042_pnp_kbd_irq = i8042_kbd_irq; pnp_data_busted = true; } if (!i8042_noaux && !i8042_pnp_aux_irq) { if (!pnp_data_busted && i8042_pnp_kbd_irq) { - printk(KERN_WARNING - "PNP: PS/2 appears to have AUX port disabled, " - "if this is incorrect please boot with " - "i8042.nopnp\n"); + pr_warn("PNP: PS/2 appears to have AUX port disabled, " + "if this is incorrect please boot with i8042.nopnp\n"); i8042_noaux = true; } else { - printk(KERN_WARNING - "PNP: PS/2 controller doesn't have AUX irq; " - "using default %d\n", i8042_aux_irq); + pr_warn("PNP: PS/2 controller doesn't have AUX irq; using default %d\n", + i8042_aux_irq); i8042_pnp_aux_irq = i8042_aux_irq; } } @@ -897,6 +914,9 @@ static int __init i8042_platform_init(void) if (dmi_check_system(i8042_dmi_nomux_table)) i8042_nomux = true; + if (dmi_check_system(i8042_dmi_notimeout_table)) + i8042_notimeout = true; + if (dmi_check_system(i8042_dmi_dritek_table)) i8042_dritek = true; #endif /* CONFIG_X86 */ diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 18db5a8c747..ac4c93689ab 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -10,6 +10,8 @@ * the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/types.h> #include <linux/delay.h> #include <linux/module.h> @@ -61,6 +63,10 @@ static bool i8042_noloop; module_param_named(noloop, i8042_noloop, bool, 0); MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); +static bool i8042_notimeout; +module_param_named(notimeout, i8042_notimeout, bool, 0); +MODULE_PARM_DESC(notimeout, "Ignore timeouts signalled by i8042"); + #ifdef CONFIG_X86 static bool i8042_dritek; module_param_named(dritek, i8042_dritek, bool, 0); @@ -225,8 +231,8 @@ static int i8042_flush(void) udelay(50); data = i8042_read_data(); i++; - dbg("%02x <- i8042 (flush, %s)", data, - str & I8042_STR_AUXDATA ? "aux" : "kbd"); + dbg("%02x <- i8042 (flush, %s)\n", + data, str & I8042_STR_AUXDATA ? "aux" : "kbd"); } spin_unlock_irqrestore(&i8042_lock, flags); @@ -253,32 +259,32 @@ static int __i8042_command(unsigned char *param, int command) if (error) return error; - dbg("%02x -> i8042 (command)", command & 0xff); + dbg("%02x -> i8042 (command)\n", command & 0xff); i8042_write_command(command & 0xff); for (i = 0; i < ((command >> 12) & 0xf); i++) { error = i8042_wait_write(); if (error) return error; - dbg("%02x -> i8042 (parameter)", param[i]); + dbg("%02x -> i8042 (parameter)\n", param[i]); i8042_write_data(param[i]); } for (i = 0; i < ((command >> 8) & 0xf); i++) { error = i8042_wait_read(); if (error) { - dbg(" -- i8042 (timeout)"); + dbg(" -- i8042 (timeout)\n"); return error; } if (command == I8042_CMD_AUX_LOOP && !(i8042_read_status() & I8042_STR_AUXDATA)) { - dbg(" -- i8042 (auxerr)"); + dbg(" -- i8042 (auxerr)\n"); return -1; } param[i] = i8042_read_data(); - dbg("%02x <- i8042 (return)", param[i]); + dbg("%02x <- i8042 (return)\n", param[i]); } return 0; @@ -309,7 +315,7 @@ static int i8042_kbd_write(struct serio *port, unsigned char c) spin_lock_irqsave(&i8042_lock, flags); if (!(retval = i8042_wait_write())) { - dbg("%02x -> i8042 (kbd-data)", c); + dbg("%02x -> i8042 (kbd-data)\n", c); i8042_write_data(c); } @@ -355,17 +361,14 @@ static void i8042_port_close(struct serio *serio) i8042_ctr &= ~irq_bit; if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) - printk(KERN_WARNING - "i8042.c: Can't write CTR while closing %s port.\n", - port_name); + pr_warn("Can't write CTR while closing %s port\n", port_name); udelay(50); i8042_ctr &= ~disable_bit; i8042_ctr |= irq_bit; if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) - printk(KERN_ERR "i8042.c: Can't reactivate %s port.\n", - port_name); + pr_err("Can't reactivate %s port\n", port_name); /* * See if there is any data appeared while we were messing with @@ -456,7 +459,8 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) str = i8042_read_status(); if (unlikely(~str & I8042_STR_OBF)) { spin_unlock_irqrestore(&i8042_lock, flags); - if (irq) dbg("Interrupt %d, without any data", irq); + if (irq) + dbg("Interrupt %d, without any data\n", irq); ret = 0; goto out; } @@ -469,7 +473,8 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) dfl = 0; if (str & I8042_STR_MUXERR) { - dbg("MUX error, status is %02x, data is %02x", str, data); + dbg("MUX error, status is %02x, data is %02x\n", + str, data); /* * When MUXERR condition is signalled the data register can only contain * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately @@ -503,7 +508,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) } else { dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) | - ((str & I8042_STR_TIMEOUT) ? SERIO_TIMEOUT : 0); + ((str & I8042_STR_TIMEOUT && !i8042_notimeout) ? SERIO_TIMEOUT : 0); port_no = (str & I8042_STR_AUXDATA) ? I8042_AUX_PORT_NO : I8042_KBD_PORT_NO; @@ -512,7 +517,7 @@ 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)", + dbg("%02x <- i8042 (interrupt, %d, %d%s%s)\n", data, port_no, irq, dfl & SERIO_PARITY ? ", bad parity" : "", dfl & SERIO_TIMEOUT ? ", timeout" : ""); @@ -540,7 +545,7 @@ static int i8042_enable_kbd_port(void) if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { i8042_ctr &= ~I8042_CTR_KBDINT; i8042_ctr |= I8042_CTR_KBDDIS; - printk(KERN_ERR "i8042.c: Failed to enable KBD port.\n"); + pr_err("Failed to enable KBD port\n"); return -EIO; } @@ -559,7 +564,7 @@ static int i8042_enable_aux_port(void) if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { i8042_ctr &= ~I8042_CTR_AUXINT; i8042_ctr |= I8042_CTR_AUXDIS; - printk(KERN_ERR "i8042.c: Failed to enable AUX port.\n"); + pr_err("Failed to enable AUX port\n"); return -EIO; } @@ -641,7 +646,7 @@ static int __init i8042_check_mux(void) if (i8042_set_mux_mode(true, &mux_version)) return -1; - printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n", + pr_info("Detected active multiplexing controller, rev %d.%d\n", (mux_version >> 4) & 0xf, mux_version & 0xf); /* @@ -651,7 +656,7 @@ static int __init i8042_check_mux(void) i8042_ctr &= ~I8042_CTR_AUXINT; if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { - printk(KERN_ERR "i8042.c: Failed to disable AUX port, can't use MUX.\n"); + pr_err("Failed to disable AUX port, can't use MUX\n"); return -EIO; } @@ -676,8 +681,8 @@ static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id) str = i8042_read_status(); if (str & I8042_STR_OBF) { data = i8042_read_data(); - dbg("%02x <- i8042 (aux_test_irq, %s)", - data, str & I8042_STR_AUXDATA ? "aux" : "kbd"); + dbg("%02x <- i8042 (aux_test_irq, %s)\n", + data, str & I8042_STR_AUXDATA ? "aux" : "kbd"); if (i8042_irq_being_tested && data == 0xa5 && (str & I8042_STR_AUXDATA)) complete(&i8042_aux_irq_delivered); @@ -770,8 +775,8 @@ static int __init i8042_check_aux(void) */ if (i8042_toggle_aux(false)) { - printk(KERN_WARNING "Failed to disable AUX port, but continuing anyway... Is this a SiS?\n"); - printk(KERN_WARNING "If AUX port is really absent please use the 'i8042.noaux' option.\n"); + pr_warn("Failed to disable AUX port, but continuing anyway... Is this a SiS?\n"); + pr_warn("If AUX port is really absent please use the 'i8042.noaux' option\n"); } if (i8042_toggle_aux(true)) @@ -819,7 +824,7 @@ static int __init i8042_check_aux(void) * AUX IRQ was never delivered so we need to flush the controller to * get rid of the byte we put there; otherwise keyboard may not work. */ - dbg(" -- i8042 (aux irq test timeout)"); + dbg(" -- i8042 (aux irq test timeout)\n"); i8042_flush(); retval = -1; } @@ -845,7 +850,7 @@ static int __init i8042_check_aux(void) static int i8042_controller_check(void) { if (i8042_flush() == I8042_BUFFER_SIZE) { - printk(KERN_ERR "i8042.c: No controller found.\n"); + pr_err("No controller found\n"); return -ENODEV; } @@ -864,15 +869,15 @@ static int i8042_controller_selftest(void) do { if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { - printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n"); + pr_err("i8042 controller self test timeout\n"); return -ENODEV; } if (param == I8042_RET_CTL_TEST) return 0; - printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n", - param, I8042_RET_CTL_TEST); + pr_err("i8042 controller selftest failed. (%#x != %#x)\n", + param, I8042_RET_CTL_TEST); msleep(50); } while (i++ < 5); @@ -883,8 +888,7 @@ static int i8042_controller_selftest(void) * and user will still get a working keyboard. This is especially * important on netbooks. On other arches we trust hardware more. */ - printk(KERN_INFO - "i8042: giving up on controller selftest, continuing anyway...\n"); + pr_info("giving up on controller selftest, continuing anyway...\n"); return 0; #else return -EIO; @@ -909,8 +913,7 @@ static int i8042_controller_init(void) do { if (n >= 10) { - printk(KERN_ERR - "i8042.c: Unable to get stable CTR read.\n"); + pr_err("Unable to get stable CTR read\n"); return -EIO; } @@ -918,8 +921,7 @@ static int i8042_controller_init(void) udelay(50); if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) { - printk(KERN_ERR - "i8042.c: Can't read CTR while initializing i8042.\n"); + pr_err("Can't read CTR while initializing i8042\n"); return -EIO; } @@ -943,7 +945,7 @@ static int i8042_controller_init(void) if (i8042_unlock) i8042_ctr |= I8042_CTR_IGNKEYLOCK; else - printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n"); + pr_warn("Warning: Keylock active\n"); } spin_unlock_irqrestore(&i8042_lock, flags); @@ -970,7 +972,7 @@ static int i8042_controller_init(void) */ if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { - printk(KERN_ERR "i8042.c: Can't write CTR while initializing i8042.\n"); + pr_err("Can't write CTR while initializing i8042\n"); return -EIO; } @@ -1000,7 +1002,7 @@ static void i8042_controller_reset(void) i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT); if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) - printk(KERN_WARNING "i8042.c: Can't write CTR while resetting.\n"); + pr_warn("Can't write CTR while resetting\n"); /* * Disable MUX mode if present. @@ -1021,7 +1023,7 @@ static void i8042_controller_reset(void) */ if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR)) - printk(KERN_WARNING "i8042.c: Can't restore CTR.\n"); + pr_warn("Can't restore CTR\n"); } @@ -1045,14 +1047,14 @@ static long i8042_panic_blink(int state) led = (state) ? 0x01 | 0x04 : 0; while (i8042_read_status() & I8042_STR_IBF) DELAY; - dbg("%02x -> i8042 (panic blink)", 0xed); + dbg("%02x -> i8042 (panic blink)\n", 0xed); i8042_suppress_kbd_ack = 2; i8042_write_data(0xed); /* set leds */ DELAY; while (i8042_read_status() & I8042_STR_IBF) DELAY; DELAY; - dbg("%02x -> i8042 (panic blink)", led); + dbg("%02x -> i8042 (panic blink)\n", led); i8042_write_data(led); DELAY; return delay; @@ -1068,9 +1070,7 @@ static void i8042_dritek_enable(void) error = i8042_command(¶m, 0x1059); if (error) - printk(KERN_WARNING - "Failed to enable DRITEK extension: %d\n", - error); + pr_warn("Failed to enable DRITEK extension: %d\n", error); } #endif @@ -1105,10 +1105,10 @@ static int i8042_controller_resume(bool force_reset) i8042_ctr |= I8042_CTR_AUXDIS | I8042_CTR_KBDDIS; i8042_ctr &= ~(I8042_CTR_AUXINT | I8042_CTR_KBDINT); if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { - printk(KERN_WARNING "i8042: Can't write CTR to resume, retrying...\n"); + pr_warn("Can't write CTR to resume, retrying...\n"); msleep(50); if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { - printk(KERN_ERR "i8042: CTR write retry failed\n"); + pr_err("CTR write retry failed\n"); return -EIO; } } @@ -1121,9 +1121,7 @@ static int i8042_controller_resume(bool force_reset) if (i8042_mux_present) { if (i8042_set_mux_mode(true, NULL) || i8042_enable_mux_ports()) - printk(KERN_WARNING - "i8042: failed to resume active multiplexor, " - "mouse won't work.\n"); + pr_warn("failed to resume active multiplexor, mouse won't work\n"); } else if (i8042_ports[I8042_AUX_PORT_NO].serio) i8042_enable_aux_port(); diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h index cbc1beb6657..ac1d759d0f5 100644 --- a/drivers/input/serio/i8042.h +++ b/drivers/input/serio/i8042.h @@ -89,15 +89,19 @@ #ifdef DEBUG static unsigned long i8042_start_time; #define dbg_init() do { i8042_start_time = jiffies; } while (0) -#define dbg(format, arg...) \ - do { \ +#define dbg(format, arg...) \ + do { \ if (i8042_debug) \ - printk(KERN_DEBUG __FILE__ ": " format " [%d]\n" , \ - ## arg, (int) (jiffies - i8042_start_time)); \ + printk(KERN_DEBUG KBUILD_MODNAME ": [%d] " format, \ + (int) (jiffies - i8042_start_time), ##arg); \ } while (0) #else #define dbg_init() do { } while (0) -#define dbg(format, arg...) do {} while (0) +#define dbg(format, arg...) \ + do { \ + if (0) \ + printk(KERN_DEBUG pr_fmt(format), ##arg); \ + } while (0) #endif #endif /* _I8042_H */ diff --git a/drivers/input/serio/ps2mult.c b/drivers/input/serio/ps2mult.c index 6bce22e4e49..15aa81c9f1f 100644 --- a/drivers/input/serio/ps2mult.c +++ b/drivers/input/serio/ps2mult.c @@ -207,7 +207,7 @@ static int ps2mult_connect(struct serio *serio, struct serio_driver *drv) err_out: while (--i >= 0) kfree(psm->ports[i].serio); - kfree(serio); + kfree(psm); return error; } diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 405bf214527..7c38d1fbabf 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -32,10 +32,9 @@ #include <linux/module.h> #include <linux/serio.h> #include <linux/errno.h> -#include <linux/wait.h> #include <linux/sched.h> #include <linux/slab.h> -#include <linux/kthread.h> +#include <linux/workqueue.h> #include <linux/mutex.h> MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); @@ -44,7 +43,7 @@ MODULE_LICENSE("GPL"); /* * serio_mutex protects entire serio subsystem and is taken every time - * serio port or driver registrered or unregistered. + * serio port or driver registered or unregistered. */ static DEFINE_MUTEX(serio_mutex); @@ -165,58 +164,22 @@ struct serio_event { static DEFINE_SPINLOCK(serio_event_lock); /* protects serio_event_list */ static LIST_HEAD(serio_event_list); -static DECLARE_WAIT_QUEUE_HEAD(serio_wait); -static struct task_struct *serio_task; -static int serio_queue_event(void *object, struct module *owner, - enum serio_event_type event_type) +static struct serio_event *serio_get_event(void) { + struct serio_event *event = NULL; unsigned long flags; - struct serio_event *event; - int retval = 0; spin_lock_irqsave(&serio_event_lock, flags); - /* - * Scan event list for the other events for the same serio port, - * starting with the most recent one. If event is the same we - * do not need add new one. If event is of different type we - * need to add this event and should not look further because - * we need to preseve sequence of distinct events. - */ - list_for_each_entry_reverse(event, &serio_event_list, node) { - if (event->object == object) { - if (event->type == event_type) - goto out; - break; - } - } - - event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); - if (!event) { - pr_err("Not enough memory to queue event %d\n", event_type); - retval = -ENOMEM; - goto out; - } - - if (!try_module_get(owner)) { - pr_warning("Can't get module reference, dropping event %d\n", - event_type); - kfree(event); - retval = -EINVAL; - goto out; + if (!list_empty(&serio_event_list)) { + event = list_first_entry(&serio_event_list, + struct serio_event, node); + list_del_init(&event->node); } - event->type = event_type; - event->object = object; - event->owner = owner; - - list_add_tail(&event->node, &serio_event_list); - wake_up(&serio_wait); - -out: spin_unlock_irqrestore(&serio_event_lock, flags); - return retval; + return event; } static void serio_free_event(struct serio_event *event) @@ -225,7 +188,8 @@ static void serio_free_event(struct serio_event *event) kfree(event); } -static void serio_remove_duplicate_events(struct serio_event *event) +static void serio_remove_duplicate_events(void *object, + enum serio_event_type type) { struct serio_event *e, *next; unsigned long flags; @@ -233,13 +197,13 @@ static void serio_remove_duplicate_events(struct serio_event *event) spin_lock_irqsave(&serio_event_lock, flags); list_for_each_entry_safe(e, next, &serio_event_list, node) { - if (event->object == e->object) { + if (object == e->object) { /* * If this event is of different type we should not * look further - we only suppress duplicate events * that were sent back-to-back. */ - if (event->type != e->type) + if (type != e->type) break; list_del_init(&e->node); @@ -250,25 +214,7 @@ static void serio_remove_duplicate_events(struct serio_event *event) spin_unlock_irqrestore(&serio_event_lock, flags); } - -static struct serio_event *serio_get_event(void) -{ - struct serio_event *event = NULL; - unsigned long flags; - - spin_lock_irqsave(&serio_event_lock, flags); - - if (!list_empty(&serio_event_list)) { - event = list_first_entry(&serio_event_list, - struct serio_event, node); - list_del_init(&event->node); - } - - spin_unlock_irqrestore(&serio_event_lock, flags); - return event; -} - -static void serio_handle_event(void) +static void serio_handle_event(struct work_struct *work) { struct serio_event *event; @@ -300,13 +246,66 @@ static void serio_handle_event(void) break; } - serio_remove_duplicate_events(event); + serio_remove_duplicate_events(event->object, event->type); serio_free_event(event); } mutex_unlock(&serio_mutex); } +static DECLARE_WORK(serio_event_work, serio_handle_event); + +static int serio_queue_event(void *object, struct module *owner, + enum serio_event_type event_type) +{ + unsigned long flags; + struct serio_event *event; + int retval = 0; + + spin_lock_irqsave(&serio_event_lock, flags); + + /* + * Scan event list for the other events for the same serio port, + * starting with the most recent one. If event is the same we + * do not need add new one. If event is of different type we + * need to add this event and should not look further because + * we need to preseve sequence of distinct events. + */ + list_for_each_entry_reverse(event, &serio_event_list, node) { + if (event->object == object) { + if (event->type == event_type) + goto out; + break; + } + } + + event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); + if (!event) { + pr_err("Not enough memory to queue event %d\n", event_type); + retval = -ENOMEM; + goto out; + } + + if (!try_module_get(owner)) { + pr_warning("Can't get module reference, dropping event %d\n", + event_type); + kfree(event); + retval = -EINVAL; + goto out; + } + + event->type = event_type; + event->object = object; + event->owner = owner; + + list_add_tail(&event->node, &serio_event_list); + schedule_work(&serio_event_work); + +out: + spin_unlock_irqrestore(&serio_event_lock, flags); + return retval; +} + /* * Remove all events that have been submitted for a given * object, be it serio port or driver. @@ -356,18 +355,6 @@ static struct serio *serio_get_pending_child(struct serio *parent) return child; } -static int serio_thread(void *nothing) -{ - do { - serio_handle_event(); - wait_event_interruptible(serio_wait, - kthread_should_stop() || !list_empty(&serio_event_list)); - } while (!kthread_should_stop()); - - return 0; -} - - /* * Serio port operations */ @@ -450,10 +437,12 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * } else if (!strncmp(buf, "rescan", count)) { serio_disconnect_port(serio); serio_find_driver(serio); + serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { serio_disconnect_port(serio); error = serio_bind_driver(serio, to_serio_driver(drv)); put_driver(drv); + serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); } else { error = -EINVAL; } @@ -1040,21 +1029,18 @@ static int __init serio_init(void) return error; } - serio_task = kthread_run(serio_thread, NULL, "kseriod"); - if (IS_ERR(serio_task)) { - bus_unregister(&serio_bus); - error = PTR_ERR(serio_task); - pr_err("Failed to start kseriod, error: %d\n", error); - return error; - } - return 0; } static void __exit serio_exit(void) { bus_unregister(&serio_bus); - kthread_stop(serio_task); + + /* + * There should not be any outstanding events but work may + * still be scheduled so simply cancel it. + */ + cancel_work_sync(&serio_event_work); } subsys_initcall(serio_init); diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 6e362de3f41..8755f5f3ad3 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -116,14 +116,15 @@ static void serport_ldisc_close(struct tty_struct *tty) /* * serport_ldisc_receive() is called by the low level tty driver when characters - * are ready for us. We forward the characters, one by one to the 'interrupt' - * routine. + * are ready for us. We forward the characters and flags, one by one to the + * 'interrupt' routine. */ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) { struct serport *serport = (struct serport*) tty->disc_data; unsigned long flags; + unsigned int ch_flags; int i; spin_lock_irqsave(&serport->lock, flags); @@ -131,8 +132,23 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c if (!test_bit(SERPORT_ACTIVE, &serport->flags)) goto out; - for (i = 0; i < count; i++) - serio_interrupt(serport->serio, cp[i], 0); + for (i = 0; i < count; i++) { + switch (fp[i]) { + case TTY_FRAME: + ch_flags = SERIO_FRAME; + break; + + case TTY_PARITY: + ch_flags = SERIO_PARITY; + break; + + default: + ch_flags = 0; + break; + } + + serio_interrupt(serport->serio, cp[i], ch_flags); + } out: spin_unlock_irqrestore(&serport->lock, flags); |