From patchwork Fri Nov 3 14:47:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 10040647 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D68DB602D8 for ; Fri, 3 Nov 2017 15:49:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C6EA329769 for ; Fri, 3 Nov 2017 15:49:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BBBAA2976F; Fri, 3 Nov 2017 15:49:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4F1BD2976C for ; Fri, 3 Nov 2017 15:49:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=ppQQyDbNKpZ/okyTwguw3PhZ/5OjOKUohDbaIX5HHAI=; b=Wuv799Q9d0Ouk+eHBzidDbCGU5 uGIOLl7vQIR6isyW+mCAINRRGgd78GeQJCrrkSTfrYvP0Ps2xUTHbUI28Fd58AR6ZCBSgYvBuk8fh s3oPX8QpF9XINukLVZy/VKI56c32Zqo7erEFxgwL0+5E1xeDKFc7q9XB/mSgbLrKNOeIXQCVm6wyJ o83rloRfNWA2aRXx3Fg2C87m/W2iNSfMgIXo9h7Brwrdp3eO7aN1I1y27Yt3fX4sQN5C8YEikGMZH 78hYMkCrIwHMD0KkxkJCuYuKqvuEkJce4Bd2P7y9rp7jmSbz4I5RQ/DOCXjySTUw3gy5/w2crWFul FRX8hPdw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1eAeDb-0000ef-Pi; Fri, 03 Nov 2017 15:49:15 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1eAeDa-0000eH-2U for linux-arm-kernel@bombadil.infradead.org; Fri, 03 Nov 2017 15:49:14 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=0Uv7xnx3zZ2ryCwtsBM4zccad+H83YfxUQDoIr6R9Nw=; b=g8KvgV7EfRxsR/okcGwG+M4rP yg5X6QWgrJgdoZqCCu3LRhGnmE6NSyKINMpnv6UDKiScUlrua/i1HKYFHQje/nDgE5196mzdeMWVP Dqhgflfmqpe3u6TjcWCe+JdZFEyDhjSxGHqHipUbtoX2DAwmH7vDCIhcoVrcsK7/hcupA+s1cgS9F JnXiKyKFkqgmHwLZ14jPO0vgAm1slryDj098TazRq17+AKYdw5V66oNzZ5XpH685bXCvDh+bFltOJ J3LyorTpnwuBZL/V/UIxfsPyzEFG/xN6AQ/hvNbGl7GuBOmfnNwTUPSVCFQgpnyoS6vst+xzynwBm eHN7Fhdtg==; Received: from foss.arm.com ([217.140.101.70]) by merlin.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1eAdID-0003PJ-Ni for linux-arm-kernel@lists.infradead.org; Fri, 03 Nov 2017 14:49:59 +0000 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 4278A19CC; Fri, 3 Nov 2017 07:49:21 -0700 (PDT) Received: from e107155-lin.cambridge.arm.com (e107155-lin.cambridge.arm.com [10.1.210.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 537563F3DF; Fri, 3 Nov 2017 07:49:19 -0700 (PDT) From: Sudeep Holla To: ALKML , LKML , DTML Subject: [PATCH v4 14/20] firmware: arm_scmi: add per-protocol channels support using idr objects Date: Fri, 3 Nov 2017 14:47:51 +0000 Message-Id: <1509720477-18936-15-git-send-email-sudeep.holla@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1509720477-18936-1-git-send-email-sudeep.holla@arm.com> References: <1509720477-18936-1-git-send-email-sudeep.holla@arm.com> X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Nishanth Menon , Harb Abdulhamid , Arnd Bergmann , Jassi Brar , Ryan Harkin , Roy Franz , Loc Ho , Sudeep Holla MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP 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 | 54 +++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 24acb421208c..6734a035bcc6 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -118,6 +118,7 @@ struct scmi_chan_info { struct mbox_chan *chan; void __iomem *payload; struct device *dev; + struct scmi_handle *handle; }; /** @@ -129,7 +130,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 @@ -141,7 +142,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; @@ -232,7 +233,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; @@ -409,7 +410,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) { @@ -681,13 +686,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; } @@ -695,6 +705,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) @@ -703,28 +714,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; @@ -758,6 +775,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; } @@ -774,6 +799,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); } @@ -808,19 +838,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; }