On Fri, 11 Aug 2017 16:22:58 +0200
Thierry Escande <thierry.esca...@collabora.com> wrote:

> From: Gwendal Grignou <gwen...@chromium.org>
> 
> If an application set a tight sampling frequency, given the interrupt
> use is a wakup source, suspend will not happen: the kernel will receive
> a wake up interrupt and will cancel the suspend process.
> 
> Given cros_ec sensors type is non wake up, this patch adds prepare and
> complete callbacks to set 1s sampling period just before suspend. This
> ensures the sensor hub will not be a source of interrupt during the
> suspend process.
> 
> Signed-off-by: Gwendal Grignou <gwen...@chromium.org>
> Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Acked-by: Jonathan Cameron <jonathan.came...@huawei.com>

Thanks,

Jonathan
> ---
>  .../iio/common/cros_ec_sensors/cros_ec_sensors.c   |  1 +
>  .../common/cros_ec_sensors/cros_ec_sensors_core.c  | 49 
> ++++++++++++++++++++++
>  .../common/cros_ec_sensors/cros_ec_sensors_core.h  |  2 +
>  drivers/iio/light/cros_ec_light_prox.c             |  1 +
>  4 files changed, 53 insertions(+)
> 
> diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c 
> b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
> index 38e8783..116da2c 100644
> --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
> +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
> @@ -292,6 +292,7 @@ MODULE_DEVICE_TABLE(platform, cros_ec_sensors_ids);
>  static struct platform_driver cros_ec_sensors_platform_driver = {
>       .driver = {
>               .name   = "cros-ec-sensors",
> +             .pm     = &cros_ec_sensors_pm_ops,
>       },
>       .probe          = cros_ec_sensors_probe,
>       .id_table       = cros_ec_sensors_ids,
> diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c 
> b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
> index 416cae5..a620eb5 100644
> --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
> +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
> @@ -446,5 +446,54 @@ int cros_ec_sensors_core_write(struct 
> cros_ec_sensors_core_state *st,
>  }
>  EXPORT_SYMBOL_GPL(cros_ec_sensors_core_write);
>  
> +static int __maybe_unused cros_ec_sensors_prepare(struct device *dev)
> +{
> +     struct platform_device *pdev = to_platform_device(dev);
> +     struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> +     struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
> +
> +     if (st->curr_sampl_freq == 0)
> +             return 0;
> +
> +     /*
> +      * If the sensors are sampled at high frequency, we will not be able to
> +      * sleep. Set sampling to a long period if necessary.
> +      */
> +     if (st->curr_sampl_freq < CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY) {
> +             mutex_lock(&st->cmd_lock);
> +             st->param.cmd = MOTIONSENSE_CMD_EC_RATE;
> +             st->param.ec_rate.data = CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY;
> +             cros_ec_motion_send_host_cmd(st, 0);
> +             mutex_unlock(&st->cmd_lock);
> +     }
> +     return 0;
> +}
> +
> +static void __maybe_unused cros_ec_sensors_complete(struct device *dev)
> +{
> +     struct platform_device *pdev = to_platform_device(dev);
> +     struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> +     struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
> +
> +     if (st->curr_sampl_freq == 0)
> +             return;
> +
> +     if (st->curr_sampl_freq < CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY) {
> +             mutex_lock(&st->cmd_lock);
> +             st->param.cmd = MOTIONSENSE_CMD_EC_RATE;
> +             st->param.ec_rate.data = st->curr_sampl_freq;
> +             cros_ec_motion_send_host_cmd(st, 0);
> +             mutex_unlock(&st->cmd_lock);
> +     }
> +}
> +
> +const struct dev_pm_ops cros_ec_sensors_pm_ops = {
> +#ifdef CONFIG_PM_SLEEP
> +     .prepare = cros_ec_sensors_prepare,
> +     .complete = cros_ec_sensors_complete
> +#endif
> +};
> +EXPORT_SYMBOL_GPL(cros_ec_sensors_pm_ops);
> +
>  MODULE_DESCRIPTION("ChromeOS EC sensor hub core functions");
>  MODULE_LICENSE("GPL v2");
> diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.h 
> b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.h
> index 8bc2ca3..2edf68d 100644
> --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.h
> +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.h
> @@ -169,6 +169,8 @@ int cros_ec_sensors_core_write(struct 
> cros_ec_sensors_core_state *st,
>                              struct iio_chan_spec const *chan,
>                              int val, int val2, long mask);
>  
> +extern const struct dev_pm_ops cros_ec_sensors_pm_ops;
> +
>  /* List of extended channel specification for all sensors */
>  extern const struct iio_chan_spec_ext_info cros_ec_sensors_ext_info[];
>  
> diff --git a/drivers/iio/light/cros_ec_light_prox.c 
> b/drivers/iio/light/cros_ec_light_prox.c
> index 7217223..f8658d4 100644
> --- a/drivers/iio/light/cros_ec_light_prox.c
> +++ b/drivers/iio/light/cros_ec_light_prox.c
> @@ -279,6 +279,7 @@ MODULE_DEVICE_TABLE(platform, cros_ec_light_prox_ids);
>  static struct platform_driver cros_ec_light_prox_platform_driver = {
>       .driver = {
>               .name   = "cros-ec-light-prox",
> +             .pm     = &cros_ec_sensors_pm_ops,
>       },
>       .probe          = cros_ec_light_prox_probe,
>       .id_table       = cros_ec_light_prox_ids,

Reply via email to