From patchwork Thu Sep 28 13:11:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 114429 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp727913qgf; Thu, 28 Sep 2017 06:14:44 -0700 (PDT) X-Google-Smtp-Source: AOwi7QApTCbnIRic0JbyqNZj4vBWzj+RKFZgBCFuRFoVgPywAYlSNH3MdBBdzpKztYatUufb1hPn X-Received: by 10.98.86.28 with SMTP id k28mr4336351pfb.89.1506604484568; Thu, 28 Sep 2017 06:14:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506604484; cv=none; d=google.com; s=arc-20160816; b=D1wIhJ2ePkor80hGcM8vOtPpF5h8clWSq7P/6x3IljbhVdcWVKgBGtBUaVL4Va+K2P QQW0bg6Nli/2QcqVQyjuvHL05jDvK+1y7sH9zB59+IzEQcTGXLYAs8SrLHkG2L0nBbUA valfExdhCHdcQrf1LB7bD20ZJ7KvBstvElvlUpgOVRfYatXIn0GUI9glhnLWVu5Y90uZ uAym7W3NC0/b8ZknLJZ7ZYcwgpXgRwSRdK8YCXkhvQd3J7n/rUaia679xHU1b4xtRlRi ImxSnmGIV0UNMNSV4Lzx12hlk8yNRo2zhrmOB+gQxqT5g63b/h7Yy14gr2FDMpTuktdK t0gA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=L645vZwFlZfDHUyry2YYzrDBjrm/tf94M8nj2Yy20co=; b=Cpai2wn75eiEqmMgDKWiez80Uu2K2YMIx56d0Erzpl8lRGQokLbiOQyc+y6AKj97QD 7lD9uGUQ2TRSGrqNuQQTElhu/y3IePG9OGm0llGB139s/k2z2mB4KDh69r7yHYLRb42z K9oIR6KK2k2Q+bAIplxfIlmrV3jdv5Dwwjk4s5IPqSjtBRwchIYDpBHjAn3O/NNrw7sa wwFjCUVAXjSajfkzFXNOhOQhWcaNBc1M3cFM399TJGTeGxif3lodDRUhQSG3ymkMouEv U9bjWTjBZQeF3NK6EHJD1AbYHvDENKwFHKMBrkvCFz7saFed4TxIdjliXjSlllMTsBc6 GvRA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q11si1378625pli.749.2017.09.28.06.14.43; Thu, 28 Sep 2017 06:14:44 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753376AbdI1NOl (ORCPT + 26 others); Thu, 28 Sep 2017 09:14:41 -0400 Received: from foss.arm.com ([217.140.101.70]:57158 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753317AbdI1NOh (ORCPT ); Thu, 28 Sep 2017 09:14:37 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 954F5164F; Thu, 28 Sep 2017 06:14:37 -0700 (PDT) Received: from e107155-lin.cambridge.arm.com (unknown [10.1.210.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 82E153F483; Thu, 28 Sep 2017 06:14:35 -0700 (PDT) From: Sudeep Holla To: ALKML , LKML , DTML Cc: Sudeep Holla , Roy Franz , Harb Abdulhamid , Nishanth Menon , Arnd Bergmann , Loc Ho , Alexey Klimov , Ryan Harkin , Jassi Brar Subject: [PATCH v3 14/22] firmware: arm_scmi: add per-protocol channels support using idr objects Date: Thu, 28 Sep 2017 14:11:38 +0100 Message-Id: <1506604306-20739-15-git-send-email-sudeep.holla@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1506604306-20739-1-git-send-email-sudeep.holla@arm.com> References: <1506604306-20739-1-git-send-email-sudeep.holla@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In order to maintain the channel information per protocol, we need some sort of list or hashtable to hold all this information. IDR provides sparse array mapping of small integer ID numbers onto arbitrary pointers. In this case the arbitrary pointers can be pointers to the channel information. This patch adds support for per-protocol channels using those idr objects. Cc: Arnd Bergmann Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/driver.c | 47 +++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 11 deletions(-) -- 2.7.4 diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 93b3bd8d437f..92ef21d6aa5a 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -128,7 +128,7 @@ struct scmi_chan_info { * @version: SCMI revision information containing protocol version, * implementation version and (sub-)vendor identification. * @minfo: Message info - * @tx_cinfo: Reference to SCMI channel information + * @tx_idr: IDR object to map protocol id to channel info pointer * @protocols_imp: list of protocols implemented, currently maximum of * MAX_PROTOCOLS_IMP elements allocated by the base protocol * @node: list head @@ -140,7 +140,7 @@ struct scmi_info { struct scmi_revision_info version; struct scmi_handle handle; struct scmi_xfers_info minfo; - struct scmi_chan_info *tx_cinfo; + struct idr tx_idr; u8 *protocols_imp; struct list_head node; int users; @@ -413,7 +413,11 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer) int timeout; struct scmi_info *info = handle_to_scmi_info(handle); struct device *dev = info->dev; - struct scmi_chan_info *cinfo = info->tx_cinfo; + struct scmi_chan_info *cinfo; + + cinfo = idr_find(&info->tx_idr, xfer->hdr.protocol_id); + if (unlikely(!cinfo)) + return -EINVAL; ret = mbox_send_message(cinfo->chan, xfer); if (ret < 0) { @@ -771,13 +775,18 @@ static int scmi_mailbox_check(struct device_node *np) return of_parse_phandle_with_args(np, "mboxes", "#mbox-cells", 0, &arg); } -static int scmi_mbox_free_channel(struct scmi_chan_info *cinfo) +static int scmi_mbox_free_channel(int id, void *p, void *data) { + struct scmi_chan_info *cinfo = p; + struct idr *idr = data; + if (!IS_ERR_OR_NULL(cinfo->chan)) { mbox_free_channel(cinfo->chan); cinfo->chan = NULL; } + idr_remove(idr, id); + return 0; } @@ -785,6 +794,7 @@ static int scmi_remove(struct platform_device *pdev) { int ret = 0; struct scmi_info *info = platform_get_drvdata(pdev); + struct idr *idr = &info->tx_idr; of_platform_depopulate(&pdev->dev); @@ -795,28 +805,34 @@ static int scmi_remove(struct platform_device *pdev) list_del(&info->node); mutex_unlock(&scmi_list_mutex); - if (!ret) + if (!ret) { /* Safe to free channels since no more users */ - return scmi_mbox_free_channel(info->tx_cinfo); + ret = idr_for_each(idr, scmi_mbox_free_channel, idr); + idr_destroy(&info->tx_idr); + } return ret; } -static inline int scmi_mbox_chan_setup(struct scmi_info *info) +static inline int +scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev, int prot_id) { int ret; struct resource res; resource_size_t size; - struct device *dev = info->dev; struct device_node *shmem, *np = dev->of_node; struct scmi_chan_info *cinfo; struct mbox_client *cl; + if (scmi_mailbox_check(np)) { + cinfo = idr_find(&info->tx_idr, SCMI_PROTOCOL_BASE); + goto idr_alloc; + } + cinfo = devm_kzalloc(info->dev, sizeof(*cinfo), GFP_KERNEL); if (!cinfo) return -ENOMEM; - info->tx_cinfo = cinfo; cinfo->dev = dev; cl = &cinfo->cl; @@ -850,6 +866,13 @@ static inline int scmi_mbox_chan_setup(struct scmi_info *info) return ret; } +idr_alloc: + ret = idr_alloc(&info->tx_idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL); + if (ret != prot_id) { + dev_err(dev, "unable to allocate SCMI idr slot err %d\n", ret); + return ret; + } + return 0; } @@ -868,6 +891,8 @@ scmi_create_protocol_device(struct device_node *np, struct scmi_info *info, platform_set_drvdata(cdev, info); + scmi_mbox_chan_setup(info, &cdev->dev, match->protocol_id); + init_ret = match->fn(&info->handle); if (init_ret) { dev_err(info->dev, "SCMI protocol %d init error %d\n", @@ -906,19 +931,19 @@ static int scmi_probe(struct platform_device *pdev) return ret; platform_set_drvdata(pdev, info); + idr_init(&info->tx_idr); handle = &info->handle; handle->dev = info->dev; handle->version = &info->version; - ret = scmi_mbox_chan_setup(info); + ret = scmi_mbox_chan_setup(info, dev, SCMI_PROTOCOL_BASE); if (ret) return ret; ret = scmi_base_protocol_init(handle); if (ret) { dev_err(dev, "unable to communicate with SCMI(%d)\n", ret); - scmi_mbox_free_channel(info->tx_cinfo); return ret; }