lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20170113132406.GD6864@dell>
Date:   Fri, 13 Jan 2017 13:24:06 +0000
From:   Lee Jones <lee.jones@...aro.org>
To:     Enric Balletbo i Serra <enric.balletbo@...labora.com>
Cc:     bleung@...omium.org, linux-kernel@...r.kernel.org, olof@...om.net,
        Eric Caruso <ejcaruso@...omium.org>,
        Guenter Roeck <groeck@...omium.org>
Subject: Re: [PATCH v2 2/4] platform/chrome: cros_ec_lightbar - Control of
 suspend/resume lightbar sequence

On Wed, 11 Jan 2017, Enric Balletbo i Serra wrote:

> From: Eric Caruso <ejcaruso@...omium.org>
> 
> Don't let EC control suspend/resume sequence. If the EC controls the
> lightbar and sets the sequence when it notices the chipset transitioning
> between states, we can't make exceptions for cases where we don't want
> to activate the lightbar. Instead, let's move the suspend/resume
> notifications into the kernel so we can selectively play the sequences.
> 
> Signed-off-by: Eric Caruso <ejcaruso@...omium.org>
> Signed-off-by: Guenter Roeck <groeck@...omium.org>
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@...labora.com>
> ---
>  drivers/platform/chrome/cros_ec_dev.c      | 38 +++++++++++++
>  drivers/platform/chrome/cros_ec_dev.h      |  6 +++
>  drivers/platform/chrome/cros_ec_lightbar.c | 85 ++++++++++++++++++++++++++++--

>  include/linux/mfd/cros_ec_commands.h       | 11 +++-

Acked-by: Lee Jones <lee.jones@...aro.org>
  
>  4 files changed, 135 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/platform/chrome/cros_ec_dev.c b/drivers/platform/chrome/cros_ec_dev.c
> index ebe029d..ef04523 100644
> --- a/drivers/platform/chrome/cros_ec_dev.c
> +++ b/drivers/platform/chrome/cros_ec_dev.c
> @@ -21,6 +21,7 @@
>  #include <linux/mfd/core.h>
>  #include <linux/module.h>
>  #include <linux/platform_device.h>
> +#include <linux/pm.h>
>  #include <linux/slab.h>
>  #include <linux/uaccess.h>
>  
> @@ -463,6 +464,10 @@ static int ec_device_probe(struct platform_device *pdev)
>  	if (cros_ec_check_features(ec, EC_FEATURE_RTC))
>  		cros_ec_rtc_register(ec);
>  
> +	/* Take control of the lightbar from the EC. */
> +	if (ec_has_lightbar(ec))
> +		lb_manual_suspend_ctrl(ec, 1);
> +
>  	return 0;
>  
>  dev_reg_failed:
> @@ -477,6 +482,11 @@ static int ec_device_probe(struct platform_device *pdev)
>  static int ec_device_remove(struct platform_device *pdev)
>  {
>  	struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev);
> +
> +	/* Let the EC take over the lightbar again. */
> +	if (ec_has_lightbar(ec))
> +		lb_manual_suspend_ctrl(ec, 0);
> +
>  	cdev_del(&ec->cdev);
>  	device_unregister(&ec->class_dev);
>  	return 0;
> @@ -488,9 +498,37 @@ static const struct platform_device_id cros_ec_id[] = {
>  };
>  MODULE_DEVICE_TABLE(platform, cros_ec_id);
>  
> +static int ec_device_suspend(struct device *dev)
> +{
> +	struct cros_ec_dev *ec = dev_get_drvdata(dev);
> +
> +	if (ec_has_lightbar(ec))
> +		lb_suspend(ec);
> +
> +	return 0;
> +}
> +
> +static int ec_device_resume(struct device *dev)
> +{
> +	struct cros_ec_dev *ec = dev_get_drvdata(dev);
> +
> +	if (ec_has_lightbar(ec))
> +		lb_resume(ec);
> +
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops cros_ec_dev_pm_ops = {
> +#ifdef CONFIG_PM_SLEEP
> +	.suspend = ec_device_suspend,
> +	.resume = ec_device_resume,
> +#endif
> +};
> +
>  static struct platform_driver cros_ec_dev_driver = {
>  	.driver = {
>  		.name = "cros-ec-ctl",
> +		.pm = &cros_ec_dev_pm_ops,
>  	},
>  	.probe = ec_device_probe,
>  	.remove = ec_device_remove,
> diff --git a/drivers/platform/chrome/cros_ec_dev.h b/drivers/platform/chrome/cros_ec_dev.h
> index bfd2c84..45e9453 100644
> --- a/drivers/platform/chrome/cros_ec_dev.h
> +++ b/drivers/platform/chrome/cros_ec_dev.h
> @@ -43,4 +43,10 @@ struct cros_ec_readmem {
>  #define CROS_EC_DEV_IOCXCMD   _IOWR(CROS_EC_DEV_IOC, 0, struct cros_ec_command)
>  #define CROS_EC_DEV_IOCRDMEM  _IOWR(CROS_EC_DEV_IOC, 1, struct cros_ec_readmem)
>  
> +/* Lightbar utilities */
> +extern bool ec_has_lightbar(struct cros_ec_dev *ec);
> +extern int lb_manual_suspend_ctrl(struct cros_ec_dev *ec, uint8_t enable);
> +extern int lb_suspend(struct cros_ec_dev *ec);
> +extern int lb_resume(struct cros_ec_dev *ec);
> +
>  #endif /* _CROS_EC_DEV_H_ */
> diff --git a/drivers/platform/chrome/cros_ec_lightbar.c b/drivers/platform/chrome/cros_ec_lightbar.c
> index 2667505..4df379d 100644
> --- a/drivers/platform/chrome/cros_ec_lightbar.c
> +++ b/drivers/platform/chrome/cros_ec_lightbar.c
> @@ -341,6 +341,80 @@ static ssize_t sequence_show(struct device *dev,
>  	return ret;
>  }
>  
> +static int lb_send_empty_cmd(struct cros_ec_dev *ec, uint8_t cmd)
> +{
> +	struct ec_params_lightbar *param;
> +	struct cros_ec_command *msg;
> +	int ret;
> +
> +	msg = alloc_lightbar_cmd_msg(ec);
> +	if (!msg)
> +		return -ENOMEM;
> +
> +	param = (struct ec_params_lightbar *)msg->data;
> +	param->cmd = cmd;
> +
> +	ret = lb_throttle();
> +	if (ret)
> +		goto error;
> +
> +	ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
> +	if (ret < 0)
> +		goto error;
> +	if (msg->result != EC_RES_SUCCESS) {
> +		ret = -EINVAL;
> +		goto error;
> +	}
> +	ret = 0;
> +error:
> +	kfree(msg);
> +
> +	return ret;
> +}
> +
> +int lb_manual_suspend_ctrl(struct cros_ec_dev *ec, uint8_t enable)
> +{
> +	struct ec_params_lightbar *param;
> +	struct cros_ec_command *msg;
> +	int ret;
> +
> +	msg = alloc_lightbar_cmd_msg(ec);
> +	if (!msg)
> +		return -ENOMEM;
> +
> +	param = (struct ec_params_lightbar *)msg->data;
> +
> +	param->cmd = LIGHTBAR_CMD_MANUAL_SUSPEND_CTRL;
> +	param->manual_suspend_ctrl.enable = enable;
> +
> +	ret = lb_throttle();
> +	if (ret)
> +		goto error;
> +
> +	ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
> +	if (ret < 0)
> +		goto error;
> +	if (msg->result != EC_RES_SUCCESS) {
> +		ret = -EINVAL;
> +		goto error;
> +	}
> +	ret = 0;
> +error:
> +	kfree(msg);
> +
> +	return ret;
> +}
> +
> +int lb_suspend(struct cros_ec_dev *ec)
> +{
> +	return lb_send_empty_cmd(ec, LIGHTBAR_CMD_SUSPEND);
> +}
> +
> +int lb_resume(struct cros_ec_dev *ec)
> +{
> +	return lb_send_empty_cmd(ec, LIGHTBAR_CMD_RESUME);
> +}
> +
>  static ssize_t sequence_store(struct device *dev, struct device_attribute *attr,
>  			      const char *buf, size_t count)
>  {
> @@ -473,6 +547,11 @@ static struct attribute *__lb_cmds_attrs[] = {
>  	NULL,
>  };
>  
> +bool ec_has_lightbar(struct cros_ec_dev *ec)
> +{
> +	return !!get_lightbar_version(ec, NULL, NULL);
> +}
> +
>  static umode_t cros_ec_lightbar_attrs_are_visible(struct kobject *kobj,
>  						  struct attribute *a, int n)
>  {
> @@ -489,10 +568,10 @@ static umode_t cros_ec_lightbar_attrs_are_visible(struct kobject *kobj,
>  		return 0;
>  
>  	/* Only instantiate this stuff if the EC has a lightbar */
> -	if (get_lightbar_version(ec, NULL, NULL))
> +	if (ec_has_lightbar(ec))
>  		return a->mode;
> -	else
> -		return 0;
> +
> +	return 0;
>  }
>  
>  struct attribute_group cros_ec_lightbar_attr_group = {
> diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h
> index efc78bd..64138fd 100644
> --- a/include/linux/mfd/cros_ec_commands.h
> +++ b/include/linux/mfd/cros_ec_commands.h
> @@ -1176,7 +1176,7 @@ struct ec_params_lightbar {
>  		struct {
>  			/* no args */
>  		} dump, off, on, init, get_seq, get_params_v0, get_params_v1,
> -			version, get_brightness, get_demo;
> +			version, get_brightness, get_demo, suspend, resume;
>  
>  		struct {
>  			uint8_t num;
> @@ -1194,6 +1194,10 @@ struct ec_params_lightbar {
>  			uint8_t led;
>  		} get_rgb;
>  
> +		struct {
> +			uint8_t enable;
> +		} manual_suspend_ctrl;
> +
>  		struct lightbar_params_v0 set_params_v0;
>  		struct lightbar_params_v1 set_params_v1;
>  		struct lightbar_program set_program;
> @@ -1230,7 +1234,7 @@ struct ec_response_lightbar {
>  			/* no return params */
>  		} off, on, init, set_brightness, seq, reg, set_rgb,
>  			demo, set_params_v0, set_params_v1,
> -			set_program;
> +			set_program, manual_suspend_ctrl, suspend, resume;
>  	};
>  } __packed;
>  
> @@ -1255,6 +1259,9 @@ enum lightbar_command {
>  	LIGHTBAR_CMD_GET_PARAMS_V1 = 16,
>  	LIGHTBAR_CMD_SET_PARAMS_V1 = 17,
>  	LIGHTBAR_CMD_SET_PROGRAM = 18,
> +	LIGHTBAR_CMD_MANUAL_SUSPEND_CTRL = 19,
> +	LIGHTBAR_CMD_SUSPEND = 20,
> +	LIGHTBAR_CMD_RESUME = 21,
>  	LIGHTBAR_NUM_CMDS
>  };
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ