diff options
Diffstat (limited to 'drivers/input/serio')
-rw-r--r-- | drivers/input/serio/at32psif.c | 2 | ||||
-rw-r--r-- | drivers/input/serio/i8042-x86ia64io.h | 71 | ||||
-rw-r--r-- | drivers/input/serio/i8042.c | 242 | ||||
-rw-r--r-- | drivers/input/serio/libps2.c | 15 | ||||
-rw-r--r-- | drivers/input/serio/serio.c | 23 |
5 files changed, 218 insertions, 135 deletions
diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c index 41fda8c67b1e..a6fb7a3dcc46 100644 --- a/drivers/input/serio/at32psif.c +++ b/drivers/input/serio/at32psif.c @@ -231,7 +231,7 @@ static int __init psif_probe(struct platform_device *pdev) goto out_free_io; } - psif->regs = ioremap(regs->start, regs->end - regs->start + 1); + psif->regs = ioremap(regs->start, resource_size(regs)); if (!psif->regs) { ret = -ENOMEM; dev_dbg(&pdev->dev, "could not map I/O memory\n"); diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index ccbf23ece8e3..a39bc4eb902b 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -457,6 +457,34 @@ static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = { }, { } }; + +static struct dmi_system_id __initdata i8042_dmi_laptop_table[] = { + { + .ident = "Portable", + .matches = { + DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ + }, + }, + { + .ident = "Laptop", + .matches = { + DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */ + }, + }, + { + .ident = "Notebook", + .matches = { + DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ + }, + }, + { + .ident = "Sub-Notebook", + .matches = { + DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */ + }, + }, + { } +}; #endif /* @@ -530,9 +558,9 @@ static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = { #ifdef CONFIG_PNP #include <linux/pnp.h> -static int i8042_pnp_kbd_registered; +static bool i8042_pnp_kbd_registered; static unsigned int i8042_pnp_kbd_devices; -static int i8042_pnp_aux_registered; +static bool i8042_pnp_aux_registered; static unsigned int i8042_pnp_aux_devices; static int i8042_pnp_command_reg; @@ -620,12 +648,12 @@ static struct pnp_driver i8042_pnp_aux_driver = { static void i8042_pnp_exit(void) { if (i8042_pnp_kbd_registered) { - i8042_pnp_kbd_registered = 0; + i8042_pnp_kbd_registered = false; pnp_unregister_driver(&i8042_pnp_kbd_driver); } if (i8042_pnp_aux_registered) { - i8042_pnp_aux_registered = 0; + i8042_pnp_aux_registered = false; pnp_unregister_driver(&i8042_pnp_aux_driver); } } @@ -633,12 +661,12 @@ static void i8042_pnp_exit(void) static int __init i8042_pnp_init(void) { char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 }; - int pnp_data_busted = 0; + int pnp_data_busted = false; int err; #ifdef CONFIG_X86 if (dmi_check_system(i8042_dmi_nopnp_table)) - i8042_nopnp = 1; + i8042_nopnp = true; #endif if (i8042_nopnp) { @@ -648,11 +676,11 @@ static int __init i8042_pnp_init(void) err = pnp_register_driver(&i8042_pnp_kbd_driver); if (!err) - i8042_pnp_kbd_registered = 1; + i8042_pnp_kbd_registered = true; err = pnp_register_driver(&i8042_pnp_aux_driver); if (!err) - i8042_pnp_aux_registered = 1; + i8042_pnp_aux_registered = true; if (!i8042_pnp_kbd_devices && !i8042_pnp_aux_devices) { i8042_pnp_exit(); @@ -680,9 +708,9 @@ static int __init i8042_pnp_init(void) #if defined(__ia64__) if (!i8042_pnp_kbd_devices) - i8042_nokbd = 1; + i8042_nokbd = true; if (!i8042_pnp_aux_devices) - i8042_noaux = 1; + i8042_noaux = true; #endif if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) && @@ -693,7 +721,7 @@ static int __init i8042_pnp_init(void) "using default %#x\n", i8042_pnp_data_reg, i8042_data_reg); i8042_pnp_data_reg = i8042_data_reg; - pnp_data_busted = 1; + pnp_data_busted = true; } if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) && @@ -704,7 +732,7 @@ static int __init i8042_pnp_init(void) "using default %#x\n", i8042_pnp_command_reg, i8042_command_reg); i8042_pnp_command_reg = i8042_command_reg; - pnp_data_busted = 1; + pnp_data_busted = true; } if (!i8042_nokbd && !i8042_pnp_kbd_irq) { @@ -712,7 +740,7 @@ static int __init i8042_pnp_init(void) "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 = 1; + pnp_data_busted = true; } if (!i8042_noaux && !i8042_pnp_aux_irq) { @@ -721,7 +749,7 @@ static int __init i8042_pnp_init(void) "PNP: PS/2 appears to have AUX port disabled, " "if this is incorrect please boot with " "i8042.nopnp\n"); - i8042_noaux = 1; + i8042_noaux = true; } else { printk(KERN_WARNING "PNP: PS/2 controller doesn't have AUX irq; " @@ -735,6 +763,11 @@ static int __init i8042_pnp_init(void) i8042_kbd_irq = i8042_pnp_kbd_irq; i8042_aux_irq = i8042_pnp_aux_irq; +#ifdef CONFIG_X86 + i8042_bypass_aux_irq_test = !pnp_data_busted && + dmi_check_system(i8042_dmi_laptop_table); +#endif + return 0; } @@ -763,21 +796,21 @@ static int __init i8042_platform_init(void) return retval; #if defined(__ia64__) - i8042_reset = 1; + i8042_reset = true; #endif #ifdef CONFIG_X86 if (dmi_check_system(i8042_dmi_reset_table)) - i8042_reset = 1; + i8042_reset = true; if (dmi_check_system(i8042_dmi_noloop_table)) - i8042_noloop = 1; + i8042_noloop = true; if (dmi_check_system(i8042_dmi_nomux_table)) - i8042_nomux = 1; + i8042_nomux = true; if (dmi_check_system(i8042_dmi_dritek_table)) - i8042_dritek = 1; + i8042_dritek = true; #endif /* CONFIG_X86 */ return retval; diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 582245c497eb..eb3ff94af58c 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -28,35 +28,35 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); MODULE_DESCRIPTION("i8042 keyboard and mouse controller driver"); MODULE_LICENSE("GPL"); -static unsigned int i8042_nokbd; +static bool i8042_nokbd; module_param_named(nokbd, i8042_nokbd, bool, 0); MODULE_PARM_DESC(nokbd, "Do not probe or use KBD port."); -static unsigned int i8042_noaux; +static bool i8042_noaux; module_param_named(noaux, i8042_noaux, bool, 0); MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port."); -static unsigned int i8042_nomux; +static bool i8042_nomux; module_param_named(nomux, i8042_nomux, bool, 0); MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present."); -static unsigned int i8042_unlock; +static bool i8042_unlock; module_param_named(unlock, i8042_unlock, bool, 0); MODULE_PARM_DESC(unlock, "Ignore keyboard lock."); -static unsigned int i8042_reset; +static bool i8042_reset; module_param_named(reset, i8042_reset, bool, 0); MODULE_PARM_DESC(reset, "Reset controller during init and cleanup."); -static unsigned int i8042_direct; +static bool i8042_direct; module_param_named(direct, i8042_direct, bool, 0); MODULE_PARM_DESC(direct, "Put keyboard port into non-translated mode."); -static unsigned int i8042_dumbkbd; +static bool i8042_dumbkbd; module_param_named(dumbkbd, i8042_dumbkbd, bool, 0); MODULE_PARM_DESC(dumbkbd, "Pretend that controller can only read data from keyboard"); -static unsigned int i8042_noloop; +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"); @@ -65,24 +65,26 @@ module_param_named(panicblink, i8042_blink_frequency, uint, 0600); MODULE_PARM_DESC(panicblink, "Frequency with which keyboard LEDs should blink when kernel panics"); #ifdef CONFIG_X86 -static unsigned int i8042_dritek; +static bool i8042_dritek; module_param_named(dritek, i8042_dritek, bool, 0); MODULE_PARM_DESC(dritek, "Force enable the Dritek keyboard extension"); #endif #ifdef CONFIG_PNP -static int i8042_nopnp; +static bool i8042_nopnp; module_param_named(nopnp, i8042_nopnp, bool, 0); MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings"); #endif #define DEBUG #ifdef DEBUG -static int i8042_debug; +static bool i8042_debug; module_param_named(debug, i8042_debug, bool, 0600); MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off"); #endif +static bool i8042_bypass_aux_irq_test; + #include "i8042.h" static DEFINE_SPINLOCK(i8042_lock); @@ -90,7 +92,7 @@ static DEFINE_SPINLOCK(i8042_lock); struct i8042_port { struct serio *serio; int irq; - unsigned char exists; + bool exists; signed char mux; }; @@ -103,9 +105,9 @@ static struct i8042_port i8042_ports[I8042_NUM_PORTS]; static unsigned char i8042_initial_ctr; static unsigned char i8042_ctr; -static unsigned char i8042_mux_present; -static unsigned char i8042_kbd_irq_registered; -static unsigned char i8042_aux_irq_registered; +static bool i8042_mux_present; +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; @@ -262,6 +264,49 @@ static int i8042_aux_write(struct serio *serio, unsigned char c) I8042_CMD_MUX_SEND + port->mux); } + +/* + * i8042_aux_close attempts to clear AUX or KBD port state by disabling + * and then re-enabling it. + */ + +static void i8042_port_close(struct serio *serio) +{ + int irq_bit; + int disable_bit; + const char *port_name; + + if (serio == i8042_ports[I8042_AUX_PORT_NO].serio) { + irq_bit = I8042_CTR_AUXINT; + disable_bit = I8042_CTR_AUXDIS; + port_name = "AUX"; + } else { + irq_bit = I8042_CTR_KBDINT; + disable_bit = I8042_CTR_KBDDIS; + port_name = "KBD"; + } + + 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); + + 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); + + /* + * See if there is any data appeared while we were messing with + * port state. + */ + i8042_interrupt(0, NULL); +} + /* * i8042_start() is called by serio core when port is about to finish * registering. It will mark port as existing so i8042_interrupt can @@ -271,7 +316,7 @@ static int i8042_start(struct serio *serio) { struct i8042_port *port = serio->port_data; - port->exists = 1; + port->exists = true; mb(); return 0; } @@ -285,7 +330,7 @@ static void i8042_stop(struct serio *serio) { struct i8042_port *port = serio->port_data; - port->exists = 0; + port->exists = false; /* * We synchronize with both AUX and KBD IRQs because there is @@ -391,7 +436,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) } /* - * i8042_enable_kbd_port enables keybaord port on chip + * i8042_enable_kbd_port enables keyboard port on chip */ static int i8042_enable_kbd_port(void) @@ -447,14 +492,15 @@ static int i8042_enable_mux_ports(void) } /* - * i8042_set_mux_mode checks whether the controller has an active - * multiplexor and puts the chip into Multiplexed (1) or Legacy (0) mode. + * i8042_set_mux_mode checks whether the controller has an + * active multiplexor and puts the chip into Multiplexed (true) + * or Legacy (false) mode. */ -static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version) +static int i8042_set_mux_mode(bool multiplex, unsigned char *mux_version) { - unsigned char param; + unsigned char param, val; /* * Get rid of bytes in the queue. */ @@ -466,14 +512,21 @@ static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version) * mouse interface, the last should be version. */ - param = 0xf0; - if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0xf0) + param = val = 0xf0; + if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != val) return -1; - param = mode ? 0x56 : 0xf6; - if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != (mode ? 0x56 : 0xf6)) + param = val = multiplex ? 0x56 : 0xf6; + if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != val) return -1; - param = mode ? 0xa4 : 0xa5; - if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param == (mode ? 0xa4 : 0xa5)) + param = val = multiplex ? 0xa4 : 0xa5; + if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param == val) + return -1; + +/* + * Workaround for interference with USB Legacy emulation + * that causes a v10.12 MUX to be found. + */ + if (param == 0xac) return -1; if (mux_version) @@ -488,18 +541,11 @@ static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version) * LCS/Telegraphics. */ -static int __devinit i8042_check_mux(void) +static int __init i8042_check_mux(void) { unsigned char mux_version; - if (i8042_set_mux_mode(1, &mux_version)) - return -1; - -/* - * Workaround for interference with USB Legacy emulation - * that causes a v10.12 MUX to be found. - */ - if (mux_version == 0xAC) + if (i8042_set_mux_mode(true, &mux_version)) return -1; printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n", @@ -516,7 +562,7 @@ static int __devinit i8042_check_mux(void) return -EIO; } - i8042_mux_present = 1; + i8042_mux_present = true; return 0; } @@ -524,10 +570,10 @@ static int __devinit i8042_check_mux(void) /* * The following is used to test AUX IRQ delivery. */ -static struct completion i8042_aux_irq_delivered __devinitdata; -static int i8042_irq_being_tested __devinitdata; +static struct completion i8042_aux_irq_delivered __initdata; +static bool i8042_irq_being_tested __initdata; -static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id) +static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id) { unsigned long flags; unsigned char str, data; @@ -552,7 +598,7 @@ static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id) * verifies success by readinng CTR. Used when testing for presence of AUX * port. */ -static int __devinit i8042_toggle_aux(int on) +static int __init i8042_toggle_aux(bool on) { unsigned char param; int i; @@ -580,11 +626,11 @@ static int __devinit i8042_toggle_aux(int on) * the presence of an AUX interface. */ -static int __devinit i8042_check_aux(void) +static int __init i8042_check_aux(void) { int retval = -1; - int irq_registered = 0; - int aux_loop_broken = 0; + bool irq_registered = false; + bool aux_loop_broken = false; unsigned long flags; unsigned char param; @@ -621,19 +667,19 @@ static int __devinit i8042_check_aux(void) * mark it as broken */ if (!retval) - aux_loop_broken = 1; + aux_loop_broken = true; } /* * Bit assignment test - filters out PS/2 i8042's in AT mode */ - if (i8042_toggle_aux(0)) { + 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"); } - if (i8042_toggle_aux(1)) + if (i8042_toggle_aux(true)) return -1; /* @@ -641,7 +687,7 @@ static int __devinit i8042_check_aux(void) * used it for a PCI card or somethig else. */ - if (i8042_noloop || aux_loop_broken) { + if (i8042_noloop || i8042_bypass_aux_irq_test || aux_loop_broken) { /* * Without LOOP command we can't test AUX IRQ delivery. Assume the port * is working and hope we are right. @@ -654,7 +700,7 @@ static int __devinit i8042_check_aux(void) "i8042", i8042_platform_device)) goto out; - irq_registered = 1; + irq_registered = true; if (i8042_enable_aux_port()) goto out; @@ -662,7 +708,7 @@ static int __devinit i8042_check_aux(void) spin_lock_irqsave(&i8042_lock, flags); init_completion(&i8042_aux_irq_delivered); - i8042_irq_being_tested = 1; + i8042_irq_being_tested = true; param = 0xa5; retval = __i8042_command(¶m, I8042_CMD_AUX_LOOP & 0xf0ff); @@ -799,7 +845,7 @@ static int i8042_controller_init(void) */ if (~i8042_ctr & I8042_CTR_XLATE) - i8042_direct = 1; + i8042_direct = true; /* * Set nontranslated mode for the kbd interface if requested by an option. @@ -839,12 +885,15 @@ static void i8042_controller_reset(void) i8042_ctr |= I8042_CTR_KBDDIS | I8042_CTR_AUXDIS; i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT); + if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR)) + printk(KERN_WARNING "i8042.c: Can't write CTR while resetting.\n"); + /* * Disable MUX mode if present. */ if (i8042_mux_present) - i8042_set_mux_mode(0, NULL); + i8042_set_mux_mode(false, NULL); /* * Reset the controller if requested. @@ -923,41 +972,27 @@ static void i8042_dritek_enable(void) #ifdef CONFIG_PM -static bool i8042_suspended; - /* - * Here we try to restore the original BIOS settings. We only want to - * do that once, when we really suspend, not when we taking memory - * snapshot for swsusp (in this case we'll perform required cleanup - * as part of shutdown process). + * Here we try to restore the original BIOS settings to avoid + * upsetting it. */ -static int i8042_suspend(struct platform_device *dev, pm_message_t state) +static int i8042_pm_reset(struct device *dev) { - if (!i8042_suspended && state.event == PM_EVENT_SUSPEND) - i8042_controller_reset(); - - i8042_suspended = state.event == PM_EVENT_SUSPEND || - state.event == PM_EVENT_FREEZE; + i8042_controller_reset(); return 0; } - /* - * Here we try to reset everything back to a state in which suspended + * Here we try to reset everything back to a state we had + * before suspending. */ -static int i8042_resume(struct platform_device *dev) +static int i8042_pm_restore(struct device *dev) { int error; -/* - * Do not bother with restoring state if we haven't suspened yet - */ - if (!i8042_suspended) - return 0; - error = i8042_controller_check(); if (error) return error; @@ -991,7 +1026,7 @@ static int i8042_resume(struct platform_device *dev) #endif if (i8042_mux_present) { - if (i8042_set_mux_mode(1, NULL) || i8042_enable_mux_ports()) + 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"); @@ -1001,11 +1036,18 @@ static int i8042_resume(struct platform_device *dev) if (i8042_ports[I8042_KBD_PORT_NO].serio) i8042_enable_kbd_port(); - i8042_suspended = false; i8042_interrupt(0, NULL); return 0; } + +static const struct dev_pm_ops i8042_pm_ops = { + .suspend = i8042_pm_reset, + .resume = i8042_pm_restore, + .poweroff = i8042_pm_reset, + .restore = i8042_pm_restore, +}; + #endif /* CONFIG_PM */ /* @@ -1018,7 +1060,7 @@ static void i8042_shutdown(struct platform_device *dev) i8042_controller_reset(); } -static int __devinit i8042_create_kbd_port(void) +static int __init i8042_create_kbd_port(void) { struct serio *serio; struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO]; @@ -1031,6 +1073,7 @@ static int __devinit i8042_create_kbd_port(void) serio->write = i8042_dumbkbd ? NULL : i8042_kbd_write; serio->start = i8042_start; serio->stop = i8042_stop; + serio->close = i8042_port_close; serio->port_data = port; serio->dev.parent = &i8042_platform_device->dev; strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name)); @@ -1042,7 +1085,7 @@ static int __devinit i8042_create_kbd_port(void) return 0; } -static int __devinit i8042_create_aux_port(int idx) +static int __init i8042_create_aux_port(int idx) { struct serio *serio; int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx; @@ -1061,6 +1104,7 @@ static int __devinit i8042_create_aux_port(int idx) if (idx < 0) { strlcpy(serio->name, "i8042 AUX port", sizeof(serio->name)); strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys)); + serio->close = i8042_port_close; } else { snprintf(serio->name, sizeof(serio->name), "i8042 AUX%d port", idx); snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, idx + 1); @@ -1073,13 +1117,13 @@ static int __devinit i8042_create_aux_port(int idx) return 0; } -static void __devinit i8042_free_kbd_port(void) +static void __init i8042_free_kbd_port(void) { kfree(i8042_ports[I8042_KBD_PORT_NO].serio); i8042_ports[I8042_KBD_PORT_NO].serio = NULL; } -static void __devinit i8042_free_aux_ports(void) +static void __init i8042_free_aux_ports(void) { int i; @@ -1089,7 +1133,7 @@ static void __devinit i8042_free_aux_ports(void) } } -static void __devinit i8042_register_ports(void) +static void __init i8042_register_ports(void) { int i; @@ -1124,10 +1168,10 @@ static void i8042_free_irqs(void) if (i8042_kbd_irq_registered) free_irq(I8042_KBD_IRQ, i8042_platform_device); - i8042_aux_irq_registered = i8042_kbd_irq_registered = 0; + i8042_aux_irq_registered = i8042_kbd_irq_registered = false; } -static int __devinit i8042_setup_aux(void) +static int __init i8042_setup_aux(void) { int (*aux_enable)(void); int error; @@ -1158,7 +1202,7 @@ static int __devinit i8042_setup_aux(void) if (aux_enable()) goto err_free_irq; - i8042_aux_irq_registered = 1; + i8042_aux_irq_registered = true; return 0; err_free_irq: @@ -1168,7 +1212,7 @@ static int __devinit i8042_setup_aux(void) return error; } -static int __devinit i8042_setup_kbd(void) +static int __init i8042_setup_kbd(void) { int error; @@ -1185,7 +1229,7 @@ static int __devinit i8042_setup_kbd(void) if (error) goto err_free_irq; - i8042_kbd_irq_registered = 1; + i8042_kbd_irq_registered = true; return 0; err_free_irq: @@ -1195,7 +1239,7 @@ static int __devinit i8042_setup_kbd(void) return error; } -static int __devinit i8042_probe(struct platform_device *dev) +static int __init i8042_probe(struct platform_device *dev) { int error; @@ -1251,14 +1295,12 @@ static struct platform_driver i8042_driver = { .driver = { .name = "i8042", .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &i8042_pm_ops, +#endif }, - .probe = i8042_probe, .remove = __devexit_p(i8042_remove), .shutdown = i8042_shutdown, -#ifdef CONFIG_PM - .suspend = i8042_suspend, - .resume = i8042_resume, -#endif }; static int __init i8042_init(void) @@ -1275,28 +1317,28 @@ static int __init i8042_init(void) if (err) goto err_platform_exit; - err = platform_driver_register(&i8042_driver); - if (err) - goto err_platform_exit; - i8042_platform_device = platform_device_alloc("i8042", -1); if (!i8042_platform_device) { err = -ENOMEM; - goto err_unregister_driver; + goto err_platform_exit; } err = platform_device_add(i8042_platform_device); if (err) goto err_free_device; + err = platform_driver_probe(&i8042_driver, i8042_probe); + if (err) + goto err_del_device; + panic_blink = i8042_panic_blink; return 0; + err_del_device: + platform_device_del(i8042_platform_device); err_free_device: platform_device_put(i8042_platform_device); - err_unregister_driver: - platform_driver_unregister(&i8042_driver); err_platform_exit: i8042_platform_exit(); @@ -1305,8 +1347,8 @@ static int __init i8042_init(void) static void __exit i8042_exit(void) { - platform_device_unregister(i8042_platform_device); platform_driver_unregister(&i8042_driver); + platform_device_unregister(i8042_platform_device); i8042_platform_exit(); panic_blink = NULL; diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index be5bbbb8ae4e..3a95b508bf27 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c @@ -161,7 +161,7 @@ static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout) * ps2_command() can only be called from a process context */ -int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) +int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) { int timeout; int send = (command >> 12) & 0xf; @@ -179,8 +179,6 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) return -1; } - mutex_lock(&ps2dev->cmd_mutex); - serio_pause_rx(ps2dev->serio); ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; ps2dev->cmdcnt = receive; @@ -231,7 +229,18 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) ps2dev->flags = 0; serio_continue_rx(ps2dev->serio); + return rc; +} +EXPORT_SYMBOL(__ps2_command); + +int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) +{ + int rc; + + mutex_lock(&ps2dev->cmd_mutex); + rc = __ps2_command(ps2dev, param, command); mutex_unlock(&ps2dev->cmd_mutex); + return rc; } EXPORT_SYMBOL(ps2_command); diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index d66f4944f2a0..0236f0d5fd91 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -931,15 +931,11 @@ static int serio_uevent(struct device *dev, struct kobj_uevent_env *env) #endif /* CONFIG_HOTPLUG */ #ifdef CONFIG_PM -static int serio_suspend(struct device *dev, pm_message_t state) +static int serio_suspend(struct device *dev) { struct serio *serio = to_serio_port(dev); - if (!serio->suspended && state.event == PM_EVENT_SUSPEND) - serio_cleanup(serio); - - serio->suspended = state.event == PM_EVENT_SUSPEND || - state.event == PM_EVENT_FREEZE; + serio_cleanup(serio); return 0; } @@ -952,13 +948,17 @@ static int serio_resume(struct device *dev) * Driver reconnect can take a while, so better let kseriod * deal with it. */ - if (serio->suspended) { - serio->suspended = false; - serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT); - } + serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT); return 0; } + +static const struct dev_pm_ops serio_pm_ops = { + .suspend = serio_suspend, + .resume = serio_resume, + .poweroff = serio_suspend, + .restore = serio_resume, +}; #endif /* CONFIG_PM */ /* called from serio_driver->connect/disconnect methods under serio_mutex */ @@ -1015,8 +1015,7 @@ static struct bus_type serio_bus = { .remove = serio_driver_remove, .shutdown = serio_shutdown, #ifdef CONFIG_PM - .suspend = serio_suspend, - .resume = serio_resume, + .pm = &serio_pm_ops, #endif }; |