Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp1102173pxu; Wed, 6 Jan 2021 12:18:42 -0800 (PST) X-Google-Smtp-Source: ABdhPJzPFZWqiM9tzu0PFQkk0ui5t1Mylfg1OyoLEwqA0c7njXs3tFv4ypgz8ubfC3ak/59JFH/O X-Received: by 2002:a17:906:f949:: with SMTP id ld9mr4078267ejb.401.1609964321995; Wed, 06 Jan 2021 12:18:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609964321; cv=none; d=google.com; s=arc-20160816; b=L78pfaVnz8akPrZ4rXmPkEFdH6cL1lYjuWxhlNgl9BSM3cJRGuhpdVQdCgey/KIUYd hrwJuSNN9NJYv2uucNDQaIoPHMZwPbKhfFamKraiNUmnnPxmJZq+grGNUQwHetJ/yYZQ OIm/+863zWn2tnH5X4/bcdqTz6e75g7ATXQrBMTFk5wm39HcnXLAFme0hWBRy7vq1i3M 6A3ffhv9MP0iDpCMN6btOYdea3UpCV7m9OmTDODxKJgfb/a2GZpjccM8vdbdM8IrVgVZ z6O9fpVix84qKqeTHF0XrfUSyknJbfh3/K3IK1WsM4Q8GUmwkevQN+uHiEP6VkoSIp3n QCOg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from; bh=LdAUlCyi2TpcFjJkNiuBrIxHcDunszIi3eAaJXPybAY=; b=WyB6BwQry6/0PFxCRyKizUewkCZ43KY8US4wXZDNuAk/+zzSHrJEhZikeIwuPaNfqn UfUe+CGDwTkgnUlScYY50fofIohlc+gbFEvHImwDqaFofJPngG0gsHMiZxljhohxtoLk 47OVU2l0DmWvSGL67yO5nFNyTfX69ayXd0ZkzIartOp2U4cC0s+ZUpOfgbYWNrBmBb7b YKkPpR2T/DONzKbNtOjmcQNllnn0L6QDxIKjdFCLo3xel5NoIR59PUz+x4x+Df1bgexu /WkGFyN3P5hxEtORomn//Oa8AGK9IxIQ3wW22WOQSyb/ye0cmbxBdK90X2DdYpvOHxOW UhJQ== ARC-Authentication-Results: i=1; mx.google.com; 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=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id l18si1240385eje.178.2021.01.06.12.18.18; Wed, 06 Jan 2021 12:18:41 -0800 (PST) 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; 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=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727227AbhAFURn (ORCPT + 99 others); Wed, 6 Jan 2021 15:17:43 -0500 Received: from foss.arm.com ([217.140.110.172]:46764 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726773AbhAFURn (ORCPT ); Wed, 6 Jan 2021 15:17:43 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 67EC711D4; Wed, 6 Jan 2021 12:16:57 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 6B1543F719; Wed, 6 Jan 2021 12:16:55 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, lukasz.luba@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, etienne.carriere@linaro.org, thara.gopinath@linaro.org, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, cristian.marussi@arm.com Subject: [PATCH v4 03/37] firmware: arm_scmi: introduce devres get/put protocols operations Date: Wed, 6 Jan 2021 20:15:36 +0000 Message-Id: <20210106201610.26538-4-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210106201610.26538-1-cristian.marussi@arm.com> References: <20210106201610.26538-1-cristian.marussi@arm.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Expose to the SCMI drivers a new devres managed common protocols API based on generic get/put methods and protocol handles. All drivers still keep using the old API, no functional change. Signed-off-by: Cristian Marussi --- drivers/firmware/arm_scmi/driver.c | 92 ++++++++++++++++++++++++++++++ include/linux/scmi_protocol.h | 11 ++++ 2 files changed, 103 insertions(+) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 10fe9aacae1b..fbc3ba1b69f6 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -732,6 +733,95 @@ scmi_is_protocol_implemented(const struct scmi_handle *handle, u8 prot_id) return false; } +struct scmi_protocol_devres { + struct scmi_handle *handle; + u8 protocol_id; +}; + +static void scmi_devm_release_protocol(struct device *dev, void *res) +{ + struct scmi_protocol_devres *dres = res; + + scmi_release_protocol(dres->handle, dres->protocol_id); +} + +/** + * scmi_devm_get_protocol_ops - Devres managed get protocol operations + * @sdev: A reference to an scmi_device whose embedded struct device is to + * be used for devres accounting. + * @protocol_id: The protocol being requested. + * @ph: A pointer reference used to pass back the associated protocol handle. + * + * Get hold of a protocol accounting for its usage, eventually triggering its + * initialization, and returning the protocol specific operations and related + * protocol handle which will be used as first argument in most of the + * protocols operations methods. + * Being a devres based managed method, protocol hold will be automatically + * released, and possibly de-initialized on last user, once the SCMI driver + * owning the scmi_device is unbound from it. + * + * Return: A reference to the requested protocol operations or error. + * Must be checked for errors by caller. + */ +static const void __must_check * +scmi_devm_get_protocol_ops(struct scmi_device *sdev, u8 protocol_id, + struct scmi_protocol_handle **ph) +{ + struct scmi_protocol_instance *pi; + struct scmi_protocol_devres *dres; + struct scmi_handle *handle = sdev->handle; + + if (!ph) + return ERR_PTR(-EINVAL); + + dres = devres_alloc(scmi_devm_release_protocol, + sizeof(*dres), GFP_KERNEL); + if (!dres) + return ERR_PTR(-ENOMEM); + + pi = scmi_get_protocol_instance(handle, protocol_id); + if (IS_ERR(pi)) { + devres_free(dres); + return pi; + } + + dres->handle = handle; + dres->protocol_id = protocol_id; + devres_add(&sdev->dev, dres); + + *ph = &pi->ph; + + return pi->proto->ops; +} + +static int scmi_devm_protocol_match(struct device *dev, void *res, void *data) +{ + struct scmi_protocol_devres *dres = res; + + if (WARN_ON(!dres || !data)) + return 0; + + return dres->protocol_id == *((u8 *)data); +} + +/** + * scmi_devm_put_protocol_ops - Devres managed put protocol operations + * @sdev: A reference to an scmi_device whose embedded struct device is to + * be used for devres accounting. + * @protocol_id: The protocol being requested. + * + * Explicitly release a protocol hold previously obtained calling the above + * @scmi_devm_get_protocol_ops. + */ +static void scmi_devm_put_protocol_ops(struct scmi_device *sdev, u8 protocol_id) +{ + int ret; + + ret = devres_release(&sdev->dev, scmi_devm_release_protocol, + scmi_devm_protocol_match, &protocol_id); + WARN_ON(ret); +} + /** * scmi_handle_get() - Get the SCMI handle for a device * @@ -986,6 +1076,8 @@ static int scmi_probe(struct platform_device *pdev) handle = &info->handle; handle->dev = info->dev; handle->version = &info->version; + handle->devm_get_ops = scmi_devm_get_protocol_ops; + handle->devm_put_ops = scmi_devm_put_protocol_ops; ret = scmi_txrx_setup(info, dev, SCMI_PROTOCOL_BASE); if (ret) diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index 757a826e3cef..2fd2fffb4024 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -57,6 +57,8 @@ struct scmi_clock_info { }; struct scmi_handle; +struct scmi_device; +struct scmi_protocol_handle; /** * struct scmi_clk_ops - represents the various operations provided @@ -593,6 +595,9 @@ struct scmi_notify_ops { * @sensor_ops: pointer to set of sensor protocol operations * @reset_ops: pointer to set of reset protocol operations * @voltage_ops: pointer to set of voltage protocol operations + * @devm_get_ops: devres managed method to acquire a protocol and get specific + * operations and a dedicated protocol handler + * @devm_put_ops: devres managed method to release a protocol * @notify_ops: pointer to set of notifications related operations * @perf_priv: pointer to private data structure specific to performance * protocol(for internal use only) @@ -618,6 +623,12 @@ struct scmi_handle { const struct scmi_sensor_ops *sensor_ops; const struct scmi_reset_ops *reset_ops; const struct scmi_voltage_ops *voltage_ops; + + const void __must_check * + (*devm_get_ops)(struct scmi_device *sdev, u8 proto, + struct scmi_protocol_handle **ph); + void (*devm_put_ops)(struct scmi_device *sdev, u8 proto); + const struct scmi_notify_ops *notify_ops; /* for protocol internal use */ void *perf_priv; -- 2.17.1