aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/serio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/serio')
-rw-r--r--drivers/input/serio/at32psif.c2
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h87
-rw-r--r--drivers/input/serio/i8042.c242
-rw-r--r--drivers/input/serio/libps2.c15
-rw-r--r--drivers/input/serio/serio.c23
5 files changed, 234 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 924e8ed7f2cf..a39bc4eb902b 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -78,6 +78,14 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = {
},
},
{
+ .ident = "ASUS G1S",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
+ DMI_MATCH(DMI_BOARD_NAME, "G1S"),
+ DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
+ },
+ },
+ {
/* AUX LOOP command does not raise AUX IRQ */
.ident = "ASUS P65UP5",
.matches = {
@@ -374,6 +382,14 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
},
},
+ {
+ .ident = "Acer Aspire 5536",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
+ },
+ },
{ }
};
@@ -441,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
/*
@@ -514,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;
@@ -604,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);
}
}
@@ -617,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) {
@@ -632,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();
@@ -664,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) &&
@@ -677,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) &&
@@ -688,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) {
@@ -696,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) {
@@ -705,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; "
@@ -719,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;
}
@@ -747,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(&param, I8042_CMD_AUX_LOOP) || param != 0xf0)
+ param = val = 0xf0;
+ if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != val)
return -1;
- param = mode ? 0x56 : 0xf6;
- if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != (mode ? 0x56 : 0xf6))
+ param = val = multiplex ? 0x56 : 0xf6;
+ if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != val)
return -1;
- param = mode ? 0xa4 : 0xa5;
- if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == (mode ? 0xa4 : 0xa5))
+ param = val = multiplex ? 0xa4 : 0xa5;
+ if (i8042_command(&param, 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(&param, 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
};