Input: i8042 - let serio bus suspend ports
Let serio subsystem take care of suspending the ports; concentrate
on suspending/resuming the controller itself.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index c3fdfc1..b90a2cd 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -724,7 +724,7 @@
if (~i8042_read_status() & I8042_STR_KEYLOCK) {
if (i8042_unlock)
i8042_ctr |= I8042_CTR_IGNKEYLOCK;
- else
+ else
printk(KERN_WARNING "i8042.c: Warning: Keylock active.\n");
}
spin_unlock_irqrestore(&i8042_lock, flags);
@@ -791,27 +791,6 @@
/*
- * Here we try to reset everything back to a state in which the BIOS will be
- * able to talk to the hardware when rebooting.
- */
-
-static void i8042_controller_cleanup(void)
-{
- int i;
-
-/*
- * Reset anything that is connected to the ports.
- */
-
- for (i = 0; i < I8042_NUM_PORTS; i++)
- if (i8042_ports[i].serio)
- serio_cleanup(i8042_ports[i].serio);
-
- i8042_controller_reset();
-}
-
-
-/*
* i8042_panic_blink() will flash the keyboard LEDs and is called when
* kernel panics. Flashing LEDs is useful for users running X who may
* not see the console and will help distingushing panics from "real"
@@ -857,13 +836,22 @@
#undef DELAY
+#ifdef CONFIG_PM
/*
- * Here we try to restore the original BIOS settings
+ * 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).
*/
static int i8042_suspend(struct platform_device *dev, pm_message_t state)
{
- i8042_controller_cleanup();
+ if (dev->dev.power.power_state.event != state.event) {
+ if (state.event == PM_EVENT_SUSPEND)
+ i8042_controller_reset();
+
+ dev->dev.power.power_state = state;
+ }
return 0;
}
@@ -877,6 +865,12 @@
{
int error;
+/*
+ * Do not bother with restoring state if we haven't suspened yet
+ */
+ if (dev->dev.power.power_state.event == PM_EVENT_ON)
+ return 0;
+
error = i8042_controller_check();
if (error)
return error;
@@ -886,9 +880,12 @@
return error;
/*
- * Restore pre-resume CTR value and disable all ports
+ * Restore original CTR value and disable all ports
*/
+ i8042_ctr = i8042_initial_ctr;
+ if (i8042_direct)
+ i8042_ctr &= ~I8042_CTR_XLATE;
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)) {
@@ -909,8 +906,11 @@
i8042_interrupt(0, NULL);
+ dev->dev.power.power_state = PMSG_ON;
+
return 0;
}
+#endif /* CONFIG_PM */
/*
* We need to reset the 8042 back to original mode on system shutdown,
@@ -919,7 +919,7 @@
static void i8042_shutdown(struct platform_device *dev)
{
- i8042_controller_cleanup();
+ i8042_controller_reset();
}
static int __devinit i8042_create_kbd_port(void)
@@ -1154,9 +1154,11 @@
},
.probe = i8042_probe,
.remove = __devexit_p(i8042_remove),
+ .shutdown = i8042_shutdown,
+#ifdef CONFIG_PM
.suspend = i8042_suspend,
.resume = i8042_resume,
- .shutdown = i8042_shutdown,
+#endif
};
static int __init i8042_init(void)