summaryrefslogtreecommitdiffstats
path: root/drivers/platform/chrome/cros_ec_dev.c
diff options
context:
space:
mode:
authorEric Caruso2017-05-16 17:46:48 +0200
committerBenson Leung2017-06-24 01:12:18 +0200
commit405c84308c4335ee7cb58b9304b77b85e61f7129 (patch)
tree1b487ce422a157890aed2ddacbb9cd5ecb18a83e /drivers/platform/chrome/cros_ec_dev.c
parentplatform/chrome: cros_ec_lightbar - Add lightbar program feature to sysfs (diff)
downloadkernel-qcow2-linux-405c84308c4335ee7cb58b9304b77b85e61f7129.tar.gz
kernel-qcow2-linux-405c84308c4335ee7cb58b9304b77b85e61f7129.tar.xz
kernel-qcow2-linux-405c84308c4335ee7cb58b9304b77b85e61f7129.zip
platform/chrome: cros_ec_lightbar - Control of suspend/resume lightbar sequence
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@chromium.org> Signed-off-by: Guenter Roeck <groeck@chromium.org> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> Acked-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Benson Leung <bleung@chromium.org>
Diffstat (limited to 'drivers/platform/chrome/cros_ec_dev.c')
-rw-r--r--drivers/platform/chrome/cros_ec_dev.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/platform/chrome/cros_ec_dev.c b/drivers/platform/chrome/cros_ec_dev.c
index 20ce1c23fb5c..7c2622319211 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>
@@ -435,6 +436,10 @@ static int ec_device_probe(struct platform_device *pdev)
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE))
cros_ec_sensors_register(ec);
+ /* Take control of the lightbar from the EC. */
+ if (ec_has_lightbar(ec))
+ lb_manual_suspend_ctrl(ec, 1);
+
return 0;
failed:
@@ -446,6 +451,10 @@ 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);
+
cros_ec_debugfs_remove(ec);
cdev_del(&ec->cdev);
@@ -459,9 +468,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,