Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp1103457pxu; Wed, 6 Jan 2021 12:20:54 -0800 (PST) X-Google-Smtp-Source: ABdhPJx2PqDiN/cx+vWGxGFY9OwrCiryjIw1DQ2PXnHLKLS4luI67uc/070T6DYo0nqpiJDjCe72 X-Received: by 2002:aa7:cf04:: with SMTP id a4mr5141959edy.99.1609964454372; Wed, 06 Jan 2021 12:20:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609964454; cv=none; d=google.com; s=arc-20160816; b=s3+s0aR5qHUT8Nd1VyTUp9i4yT50VkEmRNgrMblUqjakA97vW72PwFmDD402m3LRn6 R6SXFSEU0T7zSna9ItSx+/nU7/hfIhMHbExhfkznJVVcvbWtmB3PWcKgCfDIbOWUm/KE zQE+BvwxokcAvGoX8nuGlwqSsqFok01lKwCM+pjLmbVWj97Czvfh+xEz7pnO6A+KN1RL KMGr1AXdEgNyTnNxYnMC/kzmXwLvE7kKVFJ9zO3A2PH6D8QrLiimPIZ2atVYB8XdfzKS Eix3m4ZVO7DB2RYSsXEa1KA4ue7/k74XdErV+58ZdGaGxSHZ6cp4HuZ+rWKBEILIy5g+ k3Pw== 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=ywJJJ4SMWBZ5nJeD+ZOU4A/H7PHB6YV5Hcn9Jp2E33w=; b=sUlMYtUCVt4+JSws+WHqelqluXTrM1NVx2Z24X4/P+yn0ad4CHH3VCzFL0yY+es9yZ R0LUjNGCjx9+Q+amWb/izfyyimsvyGoBrWZTgJtVjdPkd1ckBH0CGvq0vJ6FC2gThhxo ZMrXFcV6cgWMLAF3/RkkDy+cIrix9VAwFz16VjKluk6x8Uc8m4/XE6TVdJtSWQrF+1SW djsIkZCJ/FONSpno05g+3R82hthfVRtaVkkuf/T+emyiKHqKTwlul0m9dvnNY76vze3O 6/xLQdGyy6CZz59OGQVPmDscON/wem/AiFgEVlvJthoAmnIcOQMSa0dpNrAHdSbkv94g Y1OA== 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 hq1si1215472ejc.530.2021.01.06.12.20.30; Wed, 06 Jan 2021 12:20:54 -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 S1727433AbhAFUSX (ORCPT + 99 others); Wed, 6 Jan 2021 15:18:23 -0500 Received: from foss.arm.com ([217.140.110.172]:46940 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727200AbhAFUSW (ORCPT ); Wed, 6 Jan 2021 15:18:22 -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 A6D57139F; Wed, 6 Jan 2021 12:17:05 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 8FD213F719; Wed, 6 Jan 2021 12:17:03 -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 06/37] firmware: arm_scmi: introduce new devres notification ops Date: Wed, 6 Jan 2021 20:15:39 +0000 Message-Id: <20210106201610.26538-7-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 alternative devres managed notifications API based on protocol handles. All drivers still keep using the old API, no functional change. Signed-off-by: Cristian Marussi --- drivers/firmware/arm_scmi/notify.c | 123 +++++++++++++++++++++++++++++ include/linux/scmi_protocol.h | 15 +++- 2 files changed, 137 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c index cdaf0f962d84..70e8eb4e33c6 100644 --- a/drivers/firmware/arm_scmi/notify.c +++ b/drivers/firmware/arm_scmi/notify.c @@ -1408,6 +1408,127 @@ static int scmi_unregister_notifier(const struct scmi_handle *handle, return 0; } +struct scmi_notifier_devres { + const struct scmi_handle *handle; + u8 proto_id; + u8 evt_id; + u32 __src_id; + u32 *src_id; + struct notifier_block *nb; +}; + +static void scmi_devm_release_notifier(struct device *dev, void *res) +{ + struct scmi_notifier_devres *dres = res; + + scmi_unregister_notifier(dres->handle, dres->proto_id, dres->evt_id, + dres->src_id, dres->nb); +} + +/** + * scmi_devm_register_notifier() - Managed registration of a notifier_block + * for an event + * @sdev: A reference to an scmi_device whose embedded struct device is to + * be used for devres accounting. + * @proto_id: Protocol ID + * @evt_id: Event ID + * @src_id: Source ID, when NULL register for events coming form ALL possible + * sources + * @nb: A standard notifier block to register for the specified event + * + * Generic devres managed helper to register a notifier_block against a + * protocol event. + */ +static int scmi_devm_register_notifier(struct scmi_device *sdev, + u8 proto_id, u8 evt_id, u32 *src_id, + struct notifier_block *nb) +{ + int ret; + struct scmi_notifier_devres *dres; + + dres = devres_alloc(scmi_devm_release_notifier, + sizeof(*dres), GFP_KERNEL); + if (!dres) + return -ENOMEM; + + ret = scmi_register_notifier(sdev->handle, proto_id, + evt_id, src_id, nb); + if (ret) { + devres_free(dres); + return ret; + } + + dres->handle = sdev->handle; + dres->proto_id = proto_id; + dres->evt_id = evt_id; + dres->nb = nb; + if (src_id) { + dres->__src_id = *src_id; + dres->src_id = &dres->__src_id; + } else { + dres->src_id = NULL; + } + devres_add(&sdev->dev, dres); + + return ret; +} + +static int scmi_devm_notifier_match(struct device *dev, void *res, void *data) +{ + struct scmi_notifier_devres *dres = res; + struct scmi_notifier_devres *xres = data; + + if (WARN_ON(!dres || !xres)) + return 0; + + return dres->proto_id == xres->proto_id && + dres->evt_id == xres->evt_id && + dres->nb == xres->nb && + ((!dres->src_id && !xres->src_id) || + (dres->src_id && xres->src_id && + dres->__src_id == xres->__src_id)); +} + +/** + * scmi_devm_unregister_notifier() - Managed un-registration of a + * notifier_block for an event + * @sdev: A reference to an scmi_device whose embedded struct device is to + * be used for devres accounting. + * @proto_id: Protocol ID + * @evt_id: Event ID + * @src_id: Source ID, when NULL register for events coming form ALL possible + * sources + * @nb: A standard notifier block to register for the specified event + * + * Generic devres managed helper to explicitly un-register a notifier_block + * against a protocol event, which was previously registered using the above + * @scmi_devm_register_notifier. + */ +static int scmi_devm_unregister_notifier(struct scmi_device *sdev, + u8 proto_id, u8 evt_id, u32 *src_id, + struct notifier_block *nb) +{ + int ret; + struct scmi_notifier_devres dres; + + dres.handle = sdev->handle; + dres.proto_id = proto_id; + dres.evt_id = evt_id; + if (src_id) { + dres.__src_id = *src_id; + dres.src_id = &dres.__src_id; + } else { + dres.src_id = NULL; + } + + ret = devres_release(&sdev->dev, scmi_devm_release_notifier, + scmi_devm_notifier_match, &dres); + + WARN_ON(ret); + + return ret; +} + /** * scmi_protocols_late_init() - Worker for late initialization * @work: The work item to use associated to the proper SCMI instance @@ -1465,6 +1586,8 @@ static void scmi_protocols_late_init(struct work_struct *work) * directly from an scmi_driver to register its own notifiers. */ static const struct scmi_notify_ops notify_ops = { + .devm_register_event_notifier = scmi_devm_register_notifier, + .devm_unregister_event_notifier = scmi_devm_unregister_notifier, .register_event_notifier = scmi_register_notifier, .unregister_event_notifier = scmi_unregister_notifier, }; diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index 8a2bb723602f..88757639f790 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -544,6 +544,10 @@ struct scmi_voltage_ops { /** * struct scmi_notify_ops - represents notifications' operations provided by * SCMI core + * @devm_register_event_notifier: Managed registration of a notifier_block for + * the requested event + * @devm_unregister_event_notifier: Managed unregistration of a notifier_block + * for the requested event * @register_event_notifier: Register a notifier_block for the requested event * @unregister_event_notifier: Unregister a notifier_block for the requested * event @@ -553,7 +557,9 @@ struct scmi_voltage_ops { * tuple: (proto_id, evt_id, src_id) using the provided register/unregister * interface where: * - * @handle: The handle identifying the platform instance to use + * @sdev: The scmi_device to use when calling the devres managed ops devm_ + * @handle: The handle identifying the platform instance to use, when not + * calling the managed ops devm_ * @proto_id: The protocol ID as in SCMI Specification * @evt_id: The message ID of the desired event as in SCMI Specification * @src_id: A pointer to the desired source ID if different sources are @@ -576,6 +582,13 @@ struct scmi_voltage_ops { * @report: A custom struct describing the specific event delivered */ struct scmi_notify_ops { + int (*devm_register_event_notifier)(struct scmi_device *sdev, + u8 proto_id, u8 evt_id, u32 *src_id, + struct notifier_block *nb); + int (*devm_unregister_event_notifier)(struct scmi_device *sdev, + u8 proto_id, u8 evt_id, + u32 *src_id, + struct notifier_block *nb); int (*register_event_notifier)(const struct scmi_handle *handle, u8 proto_id, u8 evt_id, u32 *src_id, struct notifier_block *nb); -- 2.17.1