Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp595169pxk; Wed, 9 Sep 2020 13:29:53 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz7aslwiwLec5yAF3kcJHdurGNTIXz7dezEycN3ABJ6Dq7Oai+k+xeVuFs3qa3YEotFrwJc X-Received: by 2002:aa7:cb83:: with SMTP id r3mr5805653edt.35.1599683393125; Wed, 09 Sep 2020 13:29:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599683393; cv=none; d=google.com; s=arc-20160816; b=akYZ3HSpzQg9h3lb+c719emmbTlpa1R+XGPxsnF3uRvtLEHnlHkv0NnzbvkSppNW5g 6gPLlYpTOq2HKZ3naIXlneVZGW4Edb+y2f5XCNyIYX2ock7sudReN3UfXYRYBA1fixuW yzRnjnfelQFD9BXUaJ3YsL6IkrUCpZ3vEs5yBn7tR6tAif18LVTUtkheb3r54yDmPFSW 3vkHgdOHMxUbLcUm0s759+Fzb6tixhs6ma/ghohFxzc4zjj09sKxY+ogFjqkZXaNsVPK oo2Eco7qete74kTUfZvBU8aHbE48SE3BULfYdU3j1tWw6N5NNWRb7+7G1mZuiIqHPPFK WWJg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=gUUWGVHgE8tUqZT0ApldnnFwJzUOwJCiB7CzBUujVEc=; b=Lzenr5S6sMo/Ro3pxRmNyTt5lIC+fgEJDItmC7yTBR2jfYQyTO7ImjFiQaeWIqA/LH hINSFusVLsp2nEiQUIWZP/imSNAkt74ct4t3DLao416YiTYzCTEyv0rQ+JQ//6lNx4HU EytW3/u3L3qUxX30E6vPa1BevWSgjZLgtI7MjaszJTWg1kV82qKt58AcaGKuPhxQMtmq ccImoxqkqb4eX01kwwMicYKC2AjM2O+RVDIKBMxHVy4WuaoFMQZSrCCGVwXrk37V+ina Y/Cx0MvJ69ROYStSuj/NmdhSWOwJnOFmEHEzGcIxcc5Sky5VI4Jcp6vztthuh8TDQ5+t q7Cw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=F5ht1xAp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k14si2318294ejx.254.2020.09.09.13.29.29; Wed, 09 Sep 2020 13:29:53 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=F5ht1xAp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729129AbgIIU0X (ORCPT + 99 others); Wed, 9 Sep 2020 16:26:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36932 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725975AbgIIU0L (ORCPT ); Wed, 9 Sep 2020 16:26:11 -0400 Received: from mail-pf1-x441.google.com (mail-pf1-x441.google.com [IPv6:2607:f8b0:4864:20::441]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5C8CBC061573 for ; Wed, 9 Sep 2020 13:26:11 -0700 (PDT) Received: by mail-pf1-x441.google.com with SMTP id c196so3312369pfc.0 for ; Wed, 09 Sep 2020 13:26:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=gUUWGVHgE8tUqZT0ApldnnFwJzUOwJCiB7CzBUujVEc=; b=F5ht1xAppMd8ZHuBZN1o+o82AHLYb0FQqW84OTqLNQE1APpnkIMuqvkgIUL4R61EFr L6ATLAvTyi0CqKBwyPxJGUSjSUNMwK0lDUCghku38xGiQFuUEitgbshPF7slDawLLKq7 qys3ohJ+KCqriyiEr5DVmF2WeQskR6cOXcpJE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=gUUWGVHgE8tUqZT0ApldnnFwJzUOwJCiB7CzBUujVEc=; b=M65+eXsWoXuXqlvUjubBtWy3NJFgpqlSxEDMDgkGddp3t5wVpxM5Bo6dNvHTK2sane fTm29eoBJsYDV1WJe58gCHgE6QIz+hnFZIf0kOTvcwhv6JqcyoQZx0Ez49JthdbKIAT1 YLai3nTT3CiXMB1JYE2Wkhft+wvTRmcgvOgGcDe09OLYysJ16eY8jzGzIz7BqSP5mWGY taABlRt8V9T6BSEnznUk+FjreU2QI2IuP/Bnw8l8GQ9UQ00UQROhRnYF8SA+vzkN2dx/ PUSxZPE8gYJm/B8JHimYk689T2pm2uCZuawSFs+36S+F+UPX1TFaon0M+jSVBFIxHz+I zDVg== X-Gm-Message-State: AOAM530C5EIsr7IBRN2eI7zNNdGI+qRG1JincDX70c5Y9cPTA9SkL16W QVZVHmsVMvaenoSj8kngithpBA== X-Received: by 2002:a62:1b56:: with SMTP id b83mr2261862pfb.15.1599683170797; Wed, 09 Sep 2020 13:26:10 -0700 (PDT) Received: from smtp.gmail.com ([2620:15c:202:1:3e52:82ff:fe6c:83ab]) by smtp.gmail.com with ESMTPSA id a74sm3503946pfa.16.2020.09.09.13.26.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Sep 2020 13:26:10 -0700 (PDT) From: Stephen Boyd To: Benson Leung , Enric Balletbo i Serra Cc: linux-kernel@vger.kernel.org, Gwendal Grignou , Guenter Roeck , Lee Jones Subject: [PATCH] platform/chrome: Don't populate lightbar device if it isn't there Date: Wed, 9 Sep 2020 13:26:09 -0700 Message-Id: <20200909202609.1630698-1-swboyd@chromium.org> X-Mailer: git-send-email 2.28.0.526.ge36021eeef-goog MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The cros ec lightbar driver has a check in probe to fail early if the ec device isn't the cros_ec one or if it can't read the lightbar version from the EC. Let's move this check to the place where the lightbar device is registered. This way we don't expose devices that aren't actually there on devices that don't have a lightbar. This should improve memory and possibly performance too because struct devices don't exactly have a small memory footprint and they contribute to suspend/resume regardless of driver attachment. Cc: Gwendal Grignou Cc: Guenter Roeck Cc: Lee Jones Signed-off-by: Stephen Boyd --- drivers/mfd/cros_ec_dev.c | 16 +++- drivers/platform/chrome/cros_ec_lightbar.c | 100 ++------------------ drivers/platform/chrome/cros_ec_proto.c | 82 ++++++++++++++++ include/linux/platform_data/cros_ec_proto.h | 4 + 4 files changed, 109 insertions(+), 93 deletions(-) diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index d07b43d7c761..9e98b2ec5d92 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -74,6 +74,10 @@ static const struct mfd_cell cros_ec_cec_cells[] = { { .name = "cros-ec-cec", }, }; +static const struct mfd_cell cros_ec_lightbar_cells[] = { + { .name = "cros-ec-lightbar", }, +}; + static const struct mfd_cell cros_ec_rtc_cells[] = { { .name = "cros-ec-rtc", }, }; @@ -112,7 +116,6 @@ static const struct cros_feature_to_cells cros_subdevices[] = { static const struct mfd_cell cros_ec_platform_cells[] = { { .name = "cros-ec-chardev", }, { .name = "cros-ec-debugfs", }, - { .name = "cros-ec-lightbar", }, { .name = "cros-ec-sysfs", }, }; @@ -206,6 +209,17 @@ static int ec_device_probe(struct platform_device *pdev) } } + if (!strcmp(ec_platform->ec_name, CROS_EC_DEV_NAME) && + !cros_ec_get_lightbar_version(ec, NULL, NULL)) { + retval = mfd_add_hotplug_devices(ec->dev, + cros_ec_lightbar_cells, + ARRAY_SIZE(cros_ec_lightbar_cells)); + if (retval) + dev_err(ec->dev, + "failed to add lightbar device: %d\n", + retval); + } + /* * The PD notifier driver cell is separate since it only needs to be * explicitly added on platforms that don't have the PD notifier ACPI diff --git a/drivers/platform/chrome/cros_ec_lightbar.c b/drivers/platform/chrome/cros_ec_lightbar.c index b59180bff5a3..95e2e62bea9b 100644 --- a/drivers/platform/chrome/cros_ec_lightbar.c +++ b/drivers/platform/chrome/cros_ec_lightbar.c @@ -82,75 +82,6 @@ static int lb_throttle(void) return ret; } -static struct cros_ec_command *alloc_lightbar_cmd_msg(struct cros_ec_dev *ec) -{ - struct cros_ec_command *msg; - int len; - - len = max(sizeof(struct ec_params_lightbar), - sizeof(struct ec_response_lightbar)); - - msg = kmalloc(sizeof(*msg) + len, GFP_KERNEL); - if (!msg) - return NULL; - - msg->version = 0; - msg->command = EC_CMD_LIGHTBAR_CMD + ec->cmd_offset; - msg->outsize = sizeof(struct ec_params_lightbar); - msg->insize = sizeof(struct ec_response_lightbar); - - return msg; -} - -static int get_lightbar_version(struct cros_ec_dev *ec, - uint32_t *ver_ptr, uint32_t *flg_ptr) -{ - struct ec_params_lightbar *param; - struct ec_response_lightbar *resp; - struct cros_ec_command *msg; - int ret; - - msg = alloc_lightbar_cmd_msg(ec); - if (!msg) - return 0; - - param = (struct ec_params_lightbar *)msg->data; - param->cmd = LIGHTBAR_CMD_VERSION; - ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); - if (ret < 0) { - ret = 0; - goto exit; - } - - switch (msg->result) { - case EC_RES_INVALID_PARAM: - /* Pixel had no version command. */ - if (ver_ptr) - *ver_ptr = 0; - if (flg_ptr) - *flg_ptr = 0; - ret = 1; - goto exit; - - case EC_RES_SUCCESS: - resp = (struct ec_response_lightbar *)msg->data; - - /* Future devices w/lightbars should implement this command */ - if (ver_ptr) - *ver_ptr = resp->version.num; - if (flg_ptr) - *flg_ptr = resp->version.flags; - ret = 1; - goto exit; - } - - /* Anything else (ie, EC_RES_INVALID_COMMAND) - no lightbar */ - ret = 0; -exit: - kfree(msg); - return ret; -} - static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -163,7 +94,7 @@ static ssize_t version_show(struct device *dev, return ret; /* This should always succeed, because we check during init. */ - if (!get_lightbar_version(ec, &version, &flags)) + if (cros_ec_get_lightbar_version(ec, &version, &flags)) return -EIO; return scnprintf(buf, PAGE_SIZE, "%d %d\n", version, flags); @@ -182,7 +113,7 @@ static ssize_t brightness_store(struct device *dev, if (kstrtouint(buf, 0, &val)) return -EINVAL; - msg = alloc_lightbar_cmd_msg(ec); + msg = cros_ec_alloc_lightbar_cmd_msg(ec); if (!msg) return -ENOMEM; @@ -220,7 +151,7 @@ static ssize_t led_rgb_store(struct device *dev, struct device_attribute *attr, unsigned int val[4]; int ret, i = 0, j = 0, ok = 0; - msg = alloc_lightbar_cmd_msg(ec); + msg = cros_ec_alloc_lightbar_cmd_msg(ec); if (!msg) return -ENOMEM; @@ -287,7 +218,7 @@ static ssize_t sequence_show(struct device *dev, int ret; struct cros_ec_dev *ec = to_cros_ec_dev(dev); - msg = alloc_lightbar_cmd_msg(ec); + msg = cros_ec_alloc_lightbar_cmd_msg(ec); if (!msg) return -ENOMEM; @@ -324,7 +255,7 @@ static int lb_send_empty_cmd(struct cros_ec_dev *ec, uint8_t cmd) struct cros_ec_command *msg; int ret; - msg = alloc_lightbar_cmd_msg(ec); + msg = cros_ec_alloc_lightbar_cmd_msg(ec); if (!msg) return -ENOMEM; @@ -352,7 +283,7 @@ static int lb_manual_suspend_ctrl(struct cros_ec_dev *ec, uint8_t enable) struct cros_ec_command *msg; int ret; - msg = alloc_lightbar_cmd_msg(ec); + msg = cros_ec_alloc_lightbar_cmd_msg(ec); if (!msg) return -ENOMEM; @@ -399,7 +330,7 @@ static ssize_t sequence_store(struct device *dev, struct device_attribute *attr, return ret; } - msg = alloc_lightbar_cmd_msg(ec); + msg = cros_ec_alloc_lightbar_cmd_msg(ec); if (!msg) return -ENOMEM; @@ -444,7 +375,7 @@ static ssize_t program_store(struct device *dev, struct device_attribute *attr, return -EINVAL; } - msg = alloc_lightbar_cmd_msg(ec); + msg = cros_ec_alloc_lightbar_cmd_msg(ec); if (!msg) return -ENOMEM; @@ -531,24 +462,9 @@ static struct attribute_group cros_ec_lightbar_attr_group = { static int cros_ec_lightbar_probe(struct platform_device *pd) { struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent); - struct cros_ec_platform *pdata = dev_get_platdata(ec_dev->dev); struct device *dev = &pd->dev; int ret; - /* - * Only instantiate the lightbar if the EC name is 'cros_ec'. Other EC - * devices like 'cros_pd' doesn't have a lightbar. - */ - if (strcmp(pdata->ec_name, CROS_EC_DEV_NAME) != 0) - return -ENODEV; - - /* - * Ask then for the lightbar version, if it's 0 then the 'cros_ec' - * doesn't have a lightbar. - */ - if (!get_lightbar_version(ec_dev, NULL, NULL)) - return -ENODEV; - /* Take control of the lightbar from the EC. */ lb_manual_suspend_ctrl(ec_dev, 1); diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index 8d52b3b4bd4e..7a297a527f8d 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -887,3 +887,85 @@ int cros_ec_get_sensor_count(struct cros_ec_dev *ec) return sensor_count; } EXPORT_SYMBOL_GPL(cros_ec_get_sensor_count); + +struct cros_ec_command *cros_ec_alloc_lightbar_cmd_msg(struct cros_ec_dev *ec) +{ + struct cros_ec_command *msg; + int len; + + len = max(sizeof(struct ec_params_lightbar), + sizeof(struct ec_response_lightbar)); + + msg = kmalloc(sizeof(*msg) + len, GFP_KERNEL); + if (!msg) + return NULL; + + msg->version = 0; + msg->command = EC_CMD_LIGHTBAR_CMD + ec->cmd_offset; + msg->outsize = sizeof(struct ec_params_lightbar); + msg->insize = sizeof(struct ec_response_lightbar); + + return msg; +} +EXPORT_SYMBOL_GPL(cros_ec_alloc_lightbar_cmd_msg); + +/** + * cros_ec_get_lightbar_version() - Get the EC lightbar version + * + * @ec: EC device, does not have to be connected directly to the AP, + * can be daisy chained through another device. + * @ver_ptr: Detected lightbar version number + * @flag_ptr: Detected lightbar flags + * + * Call this function to determine the EC's lightbar version and flags + * information. If it doesn't exist then this function returns a negative + * error value. + * + * Return: 0 on success, negative errno on failure to detect a lightbar. + */ +int cros_ec_get_lightbar_version(struct cros_ec_dev *ec, uint32_t *ver_ptr, + uint32_t *flg_ptr) +{ + struct ec_params_lightbar *param; + struct ec_response_lightbar *resp; + struct cros_ec_command *msg; + int ret; + + msg = cros_ec_alloc_lightbar_cmd_msg(ec); + if (!msg) + return -ENOMEM; + + param = (struct ec_params_lightbar *)msg->data; + param->cmd = LIGHTBAR_CMD_VERSION; + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); + if (ret < 0) + goto exit; + + switch (msg->result) { + case EC_RES_INVALID_PARAM: + /* Pixel had no version command. */ + if (ver_ptr) + *ver_ptr = 0; + if (flg_ptr) + *flg_ptr = 0; + ret = 0; + break; + case EC_RES_SUCCESS: + resp = (struct ec_response_lightbar *)msg->data; + + /* Future devices w/lightbars should implement this command */ + if (ver_ptr) + *ver_ptr = resp->version.num; + if (flg_ptr) + *flg_ptr = resp->version.flags; + ret = 0; + break; + default: + /* Anything else (ie, EC_RES_INVALID_COMMAND) - no lightbar */ + ret = -ENODEV; + } +exit: + kfree(msg); + return ret; +} +EXPORT_SYMBOL_GPL(cros_ec_get_lightbar_version); diff --git a/include/linux/platform_data/cros_ec_proto.h b/include/linux/platform_data/cros_ec_proto.h index 4a415ae851ef..50221254956c 100644 --- a/include/linux/platform_data/cros_ec_proto.h +++ b/include/linux/platform_data/cros_ec_proto.h @@ -229,6 +229,10 @@ u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev); int cros_ec_check_features(struct cros_ec_dev *ec, int feature); +struct cros_ec_command *cros_ec_alloc_lightbar_cmd_msg(struct cros_ec_dev *ec); +int cros_ec_get_lightbar_version(struct cros_ec_dev *ec, uint32_t *ver_ptr, + uint32_t *flg_ptr); + int cros_ec_get_sensor_count(struct cros_ec_dev *ec); /** -- Sent by a computer, using git, on the internet