aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEnric Balletbo i Serra <enric.balletbo@collabora.com>2018-12-12 12:34:02 -0500
committerLee Jones <lee.jones@linaro.org>2019-02-01 03:09:27 -0500
commitfd68bd0f5d4c2090c95f84e27b05d0836bcd6c0c (patch)
tree2da97f30022aaaf7397236ee87935532945e86d0
parent0545625baa5981bb0a583e6a6045155936d3ea95 (diff)
platform/chrome: cros_ec_lightbar: Instantiate only if the EC has a lightbar
Due to the way attribute groups visibility work, the function cros_ec_lightbar_attrs_are_visible is called multiple times, once per attribute, and each of these calls makes an EC transaction. For what is worth the EC log reports multiple errors on boot when the lightbar is not available. Instead, check if the EC has a lightbar in the probe function and only instantiate the device. Ideally we should have instantiate the driver only if the EC_FEATURE_LIGHTBAR is defined, but that's not possible because that flag is not in the very first Pixel Chromebook (Link), only on Samus. So, the driver is instantiated by his parent always. This patch changes a bit the actual behaviour. Before the patch if an EC doesn't have a lightbar an empty lightbar folder is created in /sys/class/chromeos/<ec-device-name>, after the patch the empty folder is not created, so, the folder is only created if the lightbar exists. Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> Reviewed-by: Guenter Roeck <groeck@chromium.org> Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r--drivers/platform/chrome/cros_ec_lightbar.c53
1 files changed, 18 insertions, 35 deletions
diff --git a/drivers/platform/chrome/cros_ec_lightbar.c b/drivers/platform/chrome/cros_ec_lightbar.c
index c22318ba93aa..c3e4e6e5211d 100644
--- a/drivers/platform/chrome/cros_ec_lightbar.c
+++ b/drivers/platform/chrome/cros_ec_lightbar.c
@@ -43,7 +43,6 @@ static unsigned long lb_interval_jiffies = 50 * HZ / 1000;
43 * If this is true, we won't do anything during suspend/resume. 43 * If this is true, we won't do anything during suspend/resume.
44 */ 44 */
45static bool userspace_control; 45static bool userspace_control;
46static struct cros_ec_dev *ec_with_lightbar;
47 46
48static ssize_t interval_msec_show(struct device *dev, 47static ssize_t interval_msec_show(struct device *dev,
49 struct device_attribute *attr, char *buf) 48 struct device_attribute *attr, char *buf)
@@ -381,9 +380,6 @@ static int lb_manual_suspend_ctrl(struct cros_ec_dev *ec, uint8_t enable)
381 struct cros_ec_command *msg; 380 struct cros_ec_command *msg;
382 int ret; 381 int ret;
383 382
384 if (ec != ec_with_lightbar)
385 return 0;
386
387 msg = alloc_lightbar_cmd_msg(ec); 383 msg = alloc_lightbar_cmd_msg(ec);
388 if (!msg) 384 if (!msg)
389 return -ENOMEM; 385 return -ENOMEM;
@@ -567,45 +563,32 @@ static struct attribute *__lb_cmds_attrs[] = {
567 NULL, 563 NULL,
568}; 564};
569 565
570static bool ec_has_lightbar(struct cros_ec_dev *ec) 566struct attribute_group cros_ec_lightbar_attr_group = {
571{
572 return !!get_lightbar_version(ec, NULL, NULL);
573}
574
575static umode_t cros_ec_lightbar_attrs_are_visible(struct kobject *kobj,
576 struct attribute *a, int n)
577{
578 struct device *dev = container_of(kobj, struct device, kobj);
579 struct cros_ec_dev *ec = to_cros_ec_dev(dev);
580 struct platform_device *pdev = to_platform_device(ec->dev);
581 struct cros_ec_platform *pdata = pdev->dev.platform_data;
582 int is_cros_ec;
583
584 is_cros_ec = strcmp(pdata->ec_name, CROS_EC_DEV_NAME);
585
586 if (is_cros_ec != 0)
587 return 0;
588
589 /* Only instantiate this stuff if the EC has a lightbar */
590 if (ec_has_lightbar(ec)) {
591 ec_with_lightbar = ec;
592 return a->mode;
593 }
594 return 0;
595}
596
597static struct attribute_group cros_ec_lightbar_attr_group = {
598 .name = "lightbar", 567 .name = "lightbar",
599 .attrs = __lb_cmds_attrs, 568 .attrs = __lb_cmds_attrs,
600 .is_visible = cros_ec_lightbar_attrs_are_visible,
601}; 569};
602 570
603static int cros_ec_lightbar_probe(struct platform_device *pd) 571static int cros_ec_lightbar_probe(struct platform_device *pd)
604{ 572{
605 struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent); 573 struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent);
574 struct cros_ec_platform *pdata = dev_get_platdata(ec_dev->dev);
606 struct device *dev = &pd->dev; 575 struct device *dev = &pd->dev;
607 int ret; 576 int ret;
608 577
578 /*
579 * Only instantiate the lightbar if the EC name is 'cros_ec'. Other EC
580 * devices like 'cros_pd' doesn't have a lightbar.
581 */
582 if (strcmp(pdata->ec_name, CROS_EC_DEV_NAME) != 0)
583 return -ENODEV;
584
585 /*
586 * Ask then for the lightbar version, if it's 0 then the 'cros_ec'
587 * doesn't have a lightbar.
588 */
589 if (!get_lightbar_version(ec_dev, NULL, NULL))
590 return -ENODEV;
591
609 /* Take control of the lightbar from the EC. */ 592 /* Take control of the lightbar from the EC. */
610 lb_manual_suspend_ctrl(ec_dev, 1); 593 lb_manual_suspend_ctrl(ec_dev, 1);
611 594
@@ -635,7 +618,7 @@ static int __maybe_unused cros_ec_lightbar_resume(struct device *dev)
635{ 618{
636 struct cros_ec_dev *ec_dev = dev_get_drvdata(dev); 619 struct cros_ec_dev *ec_dev = dev_get_drvdata(dev);
637 620
638 if (userspace_control || ec_dev != ec_with_lightbar) 621 if (userspace_control)
639 return 0; 622 return 0;
640 623
641 return lb_send_empty_cmd(ec_dev, LIGHTBAR_CMD_RESUME); 624 return lb_send_empty_cmd(ec_dev, LIGHTBAR_CMD_RESUME);
@@ -645,7 +628,7 @@ static int __maybe_unused cros_ec_lightbar_suspend(struct device *dev)
645{ 628{
646 struct cros_ec_dev *ec_dev = dev_get_drvdata(dev); 629 struct cros_ec_dev *ec_dev = dev_get_drvdata(dev);
647 630
648 if (userspace_control || ec_dev != ec_with_lightbar) 631 if (userspace_control)
649 return 0; 632 return 0;
650 633
651 return lb_send_empty_cmd(ec_dev, LIGHTBAR_CMD_SUSPEND); 634 return lb_send_empty_cmd(ec_dev, LIGHTBAR_CMD_SUSPEND);