Re: [PATCH] Input: enable i8042-level wakeup control

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I never saw any discussion on this, and it doesn't look like it's in
any git trees (afaict). Dmitry, what are your thoughts on the patch?


On Thu, 10 Feb 2011 17:16:07 +0000 (GMT)
Daniel Drake <dsd@xxxxxxxxxx> wrote:

> The OLPC XO laptop is able to use the PS/2 controller as a wakeup
> source. When used as a wakeup source, the key press/mouse motion
> must not be lost.
> 
> Add infrastructure to allow controllers to be marked as
> wakeup-capable, and avoid doing power control/reset on the
> i8042/serio devices when running in this mode.
> 
> Signed-off-by: Daniel Drake <dsd@xxxxxxxxxx>
> ---
>  drivers/input/serio/i8042-io.h        |    4 +++
>  drivers/input/serio/i8042-ip22io.h    |    4 +++
>  drivers/input/serio/i8042-jazzio.h    |    4 +++
>  drivers/input/serio/i8042-ppcio.h     |    4 +++
>  drivers/input/serio/i8042-snirm.h     |    4 +++
>  drivers/input/serio/i8042-sparcio.h   |    4 +++
>  drivers/input/serio/i8042-x86ia64io.h |    4 +++
>  drivers/input/serio/i8042.c           |   37
> +++++++++++++++++++++++++++++---
> drivers/input/serio/serio.c           |   28 +++++++++++++++++++++---
> 9 files changed, 85 insertions(+), 8 deletions(-)
> 
> A followup patch will come soon, hooking this into OLPC's embedded
> controller:
> http://dev.laptop.org/~dsd/20110114/0015-i8042-Enable-OLPC-s-EC-based-i8042-wakeup-control.patch
> 
> diff --git a/drivers/input/serio/i8042-io.h
> b/drivers/input/serio/i8042-io.h index 5d48bb6..296633c 100644
> --- a/drivers/input/serio/i8042-io.h
> +++ b/drivers/input/serio/i8042-io.h
> @@ -92,4 +92,8 @@ static inline void i8042_platform_exit(void)
>  #endif
>  }
>  
> +static inline void i8042_platform_suspend(struct device *dev, bool
> may_wakeup) +{
> +}
> +
>  #endif /* _I8042_IO_H */
> diff --git a/drivers/input/serio/i8042-ip22io.h
> b/drivers/input/serio/i8042-ip22io.h index ee1ad27..c5b76a4 100644
> --- a/drivers/input/serio/i8042-ip22io.h
> +++ b/drivers/input/serio/i8042-ip22io.h
> @@ -73,4 +73,8 @@ static inline void i8042_platform_exit(void)
>  #endif
>  }
>  
> +static inline void i8042_platform_suspend(struct device *dev, bool
> may_wakeup) +{
> +}
> +
>  #endif /* _I8042_IP22_H */
> diff --git a/drivers/input/serio/i8042-jazzio.h
> b/drivers/input/serio/i8042-jazzio.h index 13fd710..a11913a 100644
> --- a/drivers/input/serio/i8042-jazzio.h
> +++ b/drivers/input/serio/i8042-jazzio.h
> @@ -66,4 +66,8 @@ static inline void i8042_platform_exit(void)
>  #endif
>  }
>  
> +static inline void i8042_platform_suspend(struct device *dev, bool
> may_wakeup) +{
> +}
> +
>  #endif /* _I8042_JAZZ_H */
> diff --git a/drivers/input/serio/i8042-ppcio.h
> b/drivers/input/serio/i8042-ppcio.h index f708c75..c9f4292 100644
> --- a/drivers/input/serio/i8042-ppcio.h
> +++ b/drivers/input/serio/i8042-ppcio.h
> @@ -52,6 +52,10 @@ static inline void i8042_platform_exit(void)
>  {
>  }
>  
> +static inline void i8042_platform_suspend(struct device *dev, bool
> may_wakeup) +{
> +}
> +
>  #else
>  
>  #include "i8042-io.h"
> diff --git a/drivers/input/serio/i8042-snirm.h
> b/drivers/input/serio/i8042-snirm.h index 409a934..96d034f 100644
> --- a/drivers/input/serio/i8042-snirm.h
> +++ b/drivers/input/serio/i8042-snirm.h
> @@ -72,4 +72,8 @@ static inline void i8042_platform_exit(void)
>  
>  }
>  
> +static inline void i8042_platform_suspend(struct device *dev, bool
> may_wakeup) +{
> +}
> +
>  #endif /* _I8042_SNIRM_H */
> diff --git a/drivers/input/serio/i8042-sparcio.h
> b/drivers/input/serio/i8042-sparcio.h index c5cc450..a6c1f74 100644
> --- a/drivers/input/serio/i8042-sparcio.h
> +++ b/drivers/input/serio/i8042-sparcio.h
> @@ -154,4 +154,8 @@ static inline void i8042_platform_exit(void)
>  }
>  #endif /* !CONFIG_PCI */
>  
> +static inline void i8042_platform_suspend(struct device *dev, bool
> may_wakeup) +{
> +}
> +
>  #endif /* _I8042_SPARCIO_H */
> diff --git a/drivers/input/serio/i8042-x86ia64io.h
> b/drivers/input/serio/i8042-x86ia64io.h index bb9f5d3..76b2e58 100644
> --- a/drivers/input/serio/i8042-x86ia64io.h
> +++ b/drivers/input/serio/i8042-x86ia64io.h
> @@ -875,6 +875,10 @@ static inline int i8042_pnp_init(void) { return
> 0; } static inline void i8042_pnp_exit(void) { }
>  #endif
>  
> +static inline void i8042_platform_suspend(struct device *dev, bool
> may_wakeup) +{
> +}
> +
>  static int __init i8042_platform_init(void)
>  {
>  	int retval;
> diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
> index ac4c936..fb9dee6 100644
> --- a/drivers/input/serio/i8042.c
> +++ b/drivers/input/serio/i8042.c
> @@ -79,6 +79,10 @@ module_param_named(nopnp, i8042_nopnp, bool, 0);
>  MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller
> settings"); #endif
>  
> +static bool i8042_enable_wakeup;
> +module_param_named(enable_wakeup, i8042_enable_wakeup, bool, 0);
> +MODULE_PARM_DESC(enable_wakeup, "Enable i8042 as wakeup-capable
> device"); +
>  #define DEBUG
>  #ifdef DEBUG
>  static bool i8042_debug;
> @@ -1081,10 +1085,17 @@ static void i8042_dritek_enable(void)
>   * before suspending.
>   */
>  
> -static int i8042_controller_resume(bool force_reset)
> +static int i8042_controller_resume(bool force_reset, bool
> soft_resume) {
>  	int error;
>  
> +	/*
> +	 * If device is selected as a wakeup source, it was not
> powered down
> +	 * or reset during suspend, so we have very little to do.
> +	 */
> +	if (soft_resume)
> +		goto soft;
> +
>  	error = i8042_controller_check();
>  	if (error)
>  		return error;
> @@ -1128,6 +1139,7 @@ static int i8042_controller_resume(bool
> force_reset) if (i8042_ports[I8042_KBD_PORT_NO].serio)
>  		i8042_enable_kbd_port();
>  
> +soft:
>  	i8042_interrupt(0, NULL);
>  
>  	return 0;
> @@ -1145,6 +1157,20 @@ static int i8042_pm_reset(struct device *dev)
>  	return 0;
>  }
>  
> +static int i8042_pm_suspend(struct device *dev)
> +{
> +	i8042_platform_suspend(dev, device_may_wakeup(dev));
> +
> +	/*
> +	 * If device is selected as a wakeup source, don't powerdown
> or reset
> +	 * during suspend.
> +	 */
> +	if (device_may_wakeup(dev))
> +		return 0;
> +
> +	return i8042_pm_reset(dev);
> +}
> +
>  static int i8042_pm_resume(struct device *dev)
>  {
>  	/*
> @@ -1152,7 +1178,7 @@ static int i8042_pm_resume(struct device *dev)
>  	 * to bring it in a sane state. (In case of S2D we expect
>  	 * BIOS to reset the controller for us.)
>  	 */
> -	return i8042_controller_resume(true);
> +	return i8042_controller_resume(true, device_may_wakeup(dev));
>  }
>  
>  static int i8042_pm_thaw(struct device *dev)
> @@ -1164,11 +1190,11 @@ static int i8042_pm_thaw(struct device *dev)
>  
>  static int i8042_pm_restore(struct device *dev)
>  {
> -	return i8042_controller_resume(false);
> +	return i8042_controller_resume(false, false);
>  }
>  
>  static const struct dev_pm_ops i8042_pm_ops = {
> -	.suspend	= i8042_pm_reset,
> +	.suspend	= i8042_pm_suspend,
>  	.resume		= i8042_pm_resume,
>  	.thaw		= i8042_pm_thaw,
>  	.poweroff	= i8042_pm_reset,
> @@ -1402,6 +1428,9 @@ static int __init i8042_probe(struct
> platform_device *dev) i8042_dritek_enable();
>  #endif
>  
> +	if (i8042_enable_wakeup)
> +		device_set_wakeup_capable(&dev->dev, true);
> +
>  	if (!i8042_noaux) {
>  		error = i8042_setup_aux();
>  		if (error && error != -ENODEV && error != -EBUSY)
> diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
> index db5b0bc..7480be5 100644
> --- a/drivers/input/serio/serio.c
> +++ b/drivers/input/serio/serio.c
> @@ -928,7 +928,7 @@ 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)
> +static int serio_poweroff(struct device *dev)
>  {
>  	struct serio *serio = to_serio_port(dev);
>  
> @@ -937,7 +937,17 @@ static int serio_suspend(struct device *dev)
>  	return 0;
>  }
>  
> -static int serio_resume(struct device *dev)
> +static int serio_suspend(struct device *dev)
> +{
> +	/* If parent controller is configured as a wakeup source,
> don't
> +	 * power off. */
> +	if (device_may_wakeup(dev->parent))
> +		return 0;
> +
> +	return serio_poweroff(dev);
> +}
> +
> +static int serio_restore(struct device *dev)
>  {
>  	struct serio *serio = to_serio_port(dev);
>  
> @@ -950,11 +960,21 @@ static int serio_resume(struct device *dev)
>  	return 0;
>  }
>  
> +static int serio_resume(struct device *dev)
> +{
> +	/* If parent controller is configured as a wakeup source, we
> didn't
> +	 * power off during suspend, and hence have nothing to do. */
> +	if (device_may_wakeup(dev->parent))
> +		return 0;
> +
> +	return serio_restore(dev);
> +}
> +
>  static const struct dev_pm_ops serio_pm_ops = {
>  	.suspend	= serio_suspend,
>  	.resume		= serio_resume,
> -	.poweroff	= serio_suspend,
> -	.restore	= serio_resume,
> +	.poweroff	= serio_poweroff,
> +	.restore	= serio_restore,
>  };
>  #endif /* CONFIG_PM */
>  

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux