diff options
Diffstat (limited to 'drivers/platform/chrome/cros_ec.c')
| -rw-r--r-- | drivers/platform/chrome/cros_ec.c | 117 | 
1 files changed, 95 insertions, 22 deletions
| diff --git a/drivers/platform/chrome/cros_ec.c b/drivers/platform/chrome/cros_ec.c index 8b7949220382..badc68bbae8c 100644 --- a/drivers/platform/chrome/cros_ec.c +++ b/drivers/platform/chrome/cros_ec.c @@ -12,6 +12,7 @@  #include <linux/interrupt.h>  #include <linux/module.h>  #include <linux/of_platform.h> +#include <linux/platform_device.h>  #include <linux/platform_data/cros_ec_commands.h>  #include <linux/platform_data/cros_ec_proto.h>  #include <linux/slab.h> @@ -320,17 +321,8 @@ void cros_ec_unregister(struct cros_ec_device *ec_dev)  EXPORT_SYMBOL(cros_ec_unregister);  #ifdef CONFIG_PM_SLEEP -/** - * cros_ec_suspend() - Handle a suspend operation for the ChromeOS EC device. - * @ec_dev: Device to suspend. - * - * This can be called by drivers to handle a suspend event. - * - * Return: 0 on success or negative error code. - */ -int cros_ec_suspend(struct cros_ec_device *ec_dev) +static void cros_ec_send_suspend_event(struct cros_ec_device *ec_dev)  { -	struct device *dev = ec_dev->dev;  	int ret;  	u8 sleep_event; @@ -342,7 +334,26 @@ int cros_ec_suspend(struct cros_ec_device *ec_dev)  	if (ret < 0)  		dev_dbg(ec_dev->dev, "Error %d sending suspend event to ec\n",  			ret); +} +/** + * cros_ec_suspend_prepare() - Handle a suspend prepare operation for the ChromeOS EC device. + * @ec_dev: Device to suspend. + * + * This can be called by drivers to handle a suspend prepare stage of suspend. + * + * Return: 0 always. + */ +int cros_ec_suspend_prepare(struct cros_ec_device *ec_dev) +{ +	cros_ec_send_suspend_event(ec_dev); +	return 0; +} +EXPORT_SYMBOL(cros_ec_suspend_prepare); + +static void cros_ec_disable_irq(struct cros_ec_device *ec_dev) +{ +	struct device *dev = ec_dev->dev;  	if (device_may_wakeup(dev))  		ec_dev->wake_enabled = !enable_irq_wake(ec_dev->irq);  	else @@ -350,7 +361,35 @@ int cros_ec_suspend(struct cros_ec_device *ec_dev)  	disable_irq(ec_dev->irq);  	ec_dev->suspended = true; +} +/** + * cros_ec_suspend_late() - Handle a suspend late operation for the ChromeOS EC device. + * @ec_dev: Device to suspend. + * + * This can be called by drivers to handle a suspend late stage of suspend. + * + * Return: 0 always. + */ +int cros_ec_suspend_late(struct cros_ec_device *ec_dev) +{ +	cros_ec_disable_irq(ec_dev); +	return 0; +} +EXPORT_SYMBOL(cros_ec_suspend_late); + +/** + * cros_ec_suspend() - Handle a suspend operation for the ChromeOS EC device. + * @ec_dev: Device to suspend. + * + * This can be called by drivers to handle a suspend event. + * + * Return: 0 always. + */ +int cros_ec_suspend(struct cros_ec_device *ec_dev) +{ +	cros_ec_send_suspend_event(ec_dev); +	cros_ec_disable_irq(ec_dev);  	return 0;  }  EXPORT_SYMBOL(cros_ec_suspend); @@ -369,22 +408,11 @@ static void cros_ec_report_events_during_suspend(struct cros_ec_device *ec_dev)  	}  } -/** - * cros_ec_resume() - Handle a resume operation for the ChromeOS EC device. - * @ec_dev: Device to resume. - * - * This can be called by drivers to handle a resume event. - * - * Return: 0 on success or negative error code. - */ -int cros_ec_resume(struct cros_ec_device *ec_dev) +static void cros_ec_send_resume_event(struct cros_ec_device *ec_dev)  {  	int ret;  	u8 sleep_event; -	ec_dev->suspended = false; -	enable_irq(ec_dev->irq); -  	sleep_event = (!IS_ENABLED(CONFIG_ACPI) || pm_suspend_via_firmware()) ?  		      HOST_SLEEP_EVENT_S3_RESUME :  		      HOST_SLEEP_EVENT_S0IX_RESUME; @@ -393,6 +421,24 @@ int cros_ec_resume(struct cros_ec_device *ec_dev)  	if (ret < 0)  		dev_dbg(ec_dev->dev, "Error %d sending resume event to ec\n",  			ret); +} + +/** + * cros_ec_resume_complete() - Handle a resume complete operation for the ChromeOS EC device. + * @ec_dev: Device to resume. + * + * This can be called by drivers to handle a resume complete stage of resume. + */ +void cros_ec_resume_complete(struct cros_ec_device *ec_dev) +{ +	cros_ec_send_resume_event(ec_dev); +} +EXPORT_SYMBOL(cros_ec_resume_complete); + +static void cros_ec_enable_irq(struct cros_ec_device *ec_dev) +{ +	ec_dev->suspended = false; +	enable_irq(ec_dev->irq);  	if (ec_dev->wake_enabled)  		disable_irq_wake(ec_dev->irq); @@ -402,8 +448,35 @@ int cros_ec_resume(struct cros_ec_device *ec_dev)  	 * suspend. This way the clients know what to do with them.  	 */  	cros_ec_report_events_during_suspend(ec_dev); +} +/** + * cros_ec_resume_early() - Handle a resume early operation for the ChromeOS EC device. + * @ec_dev: Device to resume. + * + * This can be called by drivers to handle a resume early stage of resume. + * + * Return: 0 always. + */ +int cros_ec_resume_early(struct cros_ec_device *ec_dev) +{ +	cros_ec_enable_irq(ec_dev); +	return 0; +} +EXPORT_SYMBOL(cros_ec_resume_early); +/** + * cros_ec_resume() - Handle a resume operation for the ChromeOS EC device. + * @ec_dev: Device to resume. + * + * This can be called by drivers to handle a resume event. + * + * Return: 0 always. + */ +int cros_ec_resume(struct cros_ec_device *ec_dev) +{ +	cros_ec_enable_irq(ec_dev); +	cros_ec_send_resume_event(ec_dev);  	return 0;  }  EXPORT_SYMBOL(cros_ec_resume); |