From patchwork Fri Feb 23 16:23:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 129447 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp791061lja; Fri, 23 Feb 2018 08:26:20 -0800 (PST) X-Google-Smtp-Source: AH8x22783Q/LhBFZ3n0V4w1P6ewJo6nZ2ympRRqmv3OuDXBs7dag+Yp8pXXMSJQTr3yw5v8X36Hr X-Received: by 10.99.166.10 with SMTP id t10mr1873066pge.198.1519403179893; Fri, 23 Feb 2018 08:26:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519403179; cv=none; d=google.com; s=arc-20160816; b=IgOPr8kZjJHIOcuhiltClObHxspKlgxCIHLHfXbCdQ7+sApqzBGXy56yb0bZHIGX06 UFJgP5GVKzph62HXCOrUztmSBGRGIoURfV810aVDN69LgNpx/VyPw40EI3OuucINzs+Q iQdRoxRJ2FSIKpvElNkoAXKA0FRyaGKiMHci2/ETIj5OPDG7U7phLhqcfmRdI6QgO+L7 FtHdECNzWGaw7u6RRNvSSb37L6gaVZQq+1ZzOYcByQW/s1NSJpYuCx3HZJ5OK60L/IE/ fa2pDuwry5agDvgyCAf0OIs2g1HVXVwKbkIUQeavq99YEzmlpAw4oYhD6NlQY/sWqO5D W0eA== 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=ZhBe09h/6asjYp5imNYh+hB7zrgpDB+J82tOGJrTZA4=; b=ss085xdG0az7XvIwxel4J8d+WEyjJmEsYhmOf5qOfP1DLP6gCCdAtclYqiMRZYmaMU 0SfhHH7tjaQh6xbaq/pKcCFMZ0qf1gyssifguxktJHiuEUVWy4Ex6RltyswJo4DBflbq CCU2Z9xZvoKG3KhyiKc1/av4O5mUHegHx0uEczdrrbI2b0GAg07XKBEsmIdX0jAKrROJ aUQbexgj9mpIy8H9d1AQqSamRlFJXuORhQDFqO8Brwu+fnSoon3KKzHRq1eDpJEBNMUp iLKVV/f7CUyJekZOfZgNzE8rxH2Wc/PDZM6c/VkTEaZBvZWGFYPNlBt/n6jyJbQjBhX7 RUeQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-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 r22si1710580pgn.104.2018.02.23.08.26.19; Fri, 23 Feb 2018 08:26:19 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of devicetree-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 devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751580AbeBWQ0S (ORCPT + 6 others); Fri, 23 Feb 2018 11:26:18 -0500 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70]:57356 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751970AbeBWQYa (ORCPT ); Fri, 23 Feb 2018 11:24:30 -0500 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 A839516A0; Fri, 23 Feb 2018 08:24:30 -0800 (PST) Received: from e107155-lin.cambridge.arm.com (unknown [10.1.210.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 52E043F25C; Fri, 23 Feb 2018 08:24:29 -0800 (PST) From: Sudeep Holla To: ALKML , LKML , DTML Cc: Sudeep Holla , Alexey Klimov , Arnd Bergmann , Greg Kroah-Hartman Subject: [PATCH v6 14/20] firmware: arm_scmi: add per-protocol channels support using idr objects Date: Fri, 23 Feb 2018 16:23:44 +0000 Message-Id: <1519403030-21189-15-git-send-email-sudeep.holla@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1519403030-21189-1-git-send-email-sudeep.holla@arm.com> References: <1519403030-21189-1-git-send-email-sudeep.holla@arm.com> Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@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 Cc: Greg Kroah-Hartman Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/driver.c | 54 +++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 12 deletions(-) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index a9e3f4c46b78..527157f55e27 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -115,6 +115,7 @@ struct scmi_chan_info { struct mbox_chan *chan; void __iomem *payload; struct device *dev; + struct scmi_handle *handle; }; /** @@ -126,7 +127,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 @@ -138,7 +139,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; @@ -229,7 +230,7 @@ static void scmi_rx_callback(struct mbox_client *cl, void *m) struct scmi_xfer *xfer; struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl); struct device *dev = cinfo->dev; - struct scmi_info *info = dev_get_drvdata(dev); + struct scmi_info *info = handle_to_scmi_info(cinfo->handle); struct scmi_xfers_info *minfo = &info->minfo; struct scmi_shared_mem __iomem *mem = cinfo->payload; @@ -401,7 +402,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) { @@ -668,13 +673,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; } @@ -682,6 +692,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; mutex_lock(&scmi_list_mutex); if (info->users) @@ -690,28 +701,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; @@ -745,6 +762,14 @@ 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; + } + + cinfo->handle = &info->handle; return 0; } @@ -761,6 +786,11 @@ scmi_create_protocol_device(struct device_node *np, struct scmi_info *info, return; } + if (scmi_mbox_chan_setup(info, &sdev->dev, prot_id)) { + dev_err(&sdev->dev, "failed to setup transport\n"); + scmi_device_destroy(sdev); + } + /* setup handle now as the transport is ready */ scmi_set_handle(sdev); } @@ -795,19 +825,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; }