From patchwork Fri Dec 16 05:33:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: MD Danish Anwar X-Patchwork-Id: 13074784 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 45EA2C4332F for ; Fri, 16 Dec 2022 05:35:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version: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=XlhiIkaydzWkBOLMLy7fJXTyG45D7eGr1qiJqHZYklc=; b=IigAMyvo0oMA2A 7apxfQs3lecF/xra/l2D6xVzjCVIkZ4Hv3SXwskok2r/N/0NbOUvGQ14uBPOjRrSuubM1ZNduaikP ou/ayGJvTcIbuklYb1lLvx2Sp50xVnqSv+ANz1I3jadRZh9jlimsFe41i+fGIDj35BI4gSPKGCP5d ksoFkQeUA+f+8KlDk0BxJFwpzO6THRcq0wctsXJLvP0RSSAD4yZyGUfeH5GMcvdcjYFFgiQHGdPkI TwNXt8wz3D7gQZSjQUcfLdtVBHfo294mMoWyWfmQq6mYxZsG76wVqMd59ruamdWQxjaid+Q5lmB2W T8v3yBmzM8ntGWt9nOmg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1p63MY-00Cxnr-Ot; Fri, 16 Dec 2022 05:34:27 +0000 Received: from fllv0016.ext.ti.com ([198.47.19.142]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1p63Lk-00CxX4-G7 for linux-arm-kernel@lists.infradead.org; Fri, 16 Dec 2022 05:33:42 +0000 Received: from fllv0034.itg.ti.com ([10.64.40.246]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 2BG5XMQ1019007; Thu, 15 Dec 2022 23:33:22 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1671168802; bh=3X5iSQjkrEbpAD21Eif8EZYEj4D7VaACi1Irdy+JHNM=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=fycCWC8JatByVJQicylG1pjiAXOXUGmIO5QR/pswtgpQsTnneNplUKyrlfltDMKlG v8GIIxT6LdHx5AVomNPtMs6LgnEvN/7k48aOXzMcCcfBcF66PpTjkS0vPD5zUZzGzF aBqPbr7z+MUinMsVUldYpRgXY6F4Dj+kXLzGrNjY= Received: from DLEE108.ent.ti.com (dlee108.ent.ti.com [157.170.170.38]) by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 2BG5XM2C113129 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 15 Dec 2022 23:33:22 -0600 Received: from DLEE115.ent.ti.com (157.170.170.26) by DLEE108.ent.ti.com (157.170.170.38) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.16; Thu, 15 Dec 2022 23:33:22 -0600 Received: from fllv0039.itg.ti.com (10.64.41.19) by DLEE115.ent.ti.com (157.170.170.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.16 via Frontend Transport; Thu, 15 Dec 2022 23:33:22 -0600 Received: from lelv0854.itg.ti.com (lelv0854.itg.ti.com [10.181.64.140]) by fllv0039.itg.ti.com (8.15.2/8.15.2) with ESMTP id 2BG5XMhq042489; Thu, 15 Dec 2022 23:33:22 -0600 Received: from localhost (a0501179-pc.dhcp.ti.com [10.24.69.114]) by lelv0854.itg.ti.com (8.14.7/8.14.7) with ESMTP id 2BG5XKJ4008928; Thu, 15 Dec 2022 23:33:21 -0600 From: MD Danish Anwar To: Mathieu Poirier , Krzysztof Kozlowski , Rob Herring Subject: [PATCH v12 3/6] remoteproc: pru: Add APIs to get and put the PRU cores Date: Fri, 16 Dec 2022 11:03:10 +0530 Message-ID: <20221216053313.2974826-4-danishanwar@ti.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221216053313.2974826-1-danishanwar@ti.com> References: <20221216053313.2974826-1-danishanwar@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221215_213336_805649_5F870A18 X-CRM114-Status: GOOD ( 25.80 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nm@ti.com, srk@ti.com, vigneshr@ti.com, devicetree@vger.kernel.org, linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org, MD Danish Anwar , "Andrew F . Davis" , Roger Quadros , linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add two new APIs, pru_rproc_get() and pru_rproc_put(), to the PRU driver to allow client drivers to acquire and release the remoteproc device associated with a PRU core. The PRU cores are treated as resources with only one client owning it at a time. The pru_rproc_get() function returns the rproc handle corresponding to a PRU core identified by the device tree "ti,prus" property under the client node. The pru_rproc_put() is the complementary function to pru_rproc_get(). Signed-off-by: Suman Anna Signed-off-by: Tero Kristo Signed-off-by: Grzegorz Jaszczyk Signed-off-by: MD Danish Anwar Reviewed-by: Roger Quadros --- drivers/remoteproc/pru_rproc.c | 128 ++++++++++++++++++++++++++++++++- include/linux/pruss.h | 29 ++++++++ 2 files changed, 155 insertions(+), 2 deletions(-) diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index a1a208b31846..fe4ca1584e91 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -2,12 +2,14 @@ /* * PRU-ICSS remoteproc driver for various TI SoCs * - * Copyright (C) 2014-2020 Texas Instruments Incorporated - https://www.ti.com/ + * Copyright (C) 2014-2022 Texas Instruments Incorporated - https://www.ti.com/ * * Author(s): * Suman Anna * Andrew F. Davis * Grzegorz Jaszczyk for Texas Instruments + * Puranjay Mohan + * Md Danish Anwar */ #include @@ -112,6 +114,8 @@ struct pru_private_data { * @rproc: remoteproc pointer for this PRU core * @data: PRU core specific data * @mem_regions: data for each of the PRU memory regions + * @client_np: client device node + * @lock: mutex to protect client usage * @fw_name: name of firmware image used during loading * @mapped_irq: virtual interrupt numbers of created fw specific mapping * @pru_interrupt_map: pointer to interrupt mapping description (firmware) @@ -127,6 +131,8 @@ struct pru_rproc { struct rproc *rproc; const struct pru_private_data *data; struct pruss_mem_region mem_regions[PRU_IOMEM_MAX]; + struct device_node *client_np; + struct mutex lock; const char *fw_name; unsigned int *mapped_irq; struct pru_irq_rsc *pru_interrupt_map; @@ -147,6 +153,120 @@ void pru_control_write_reg(struct pru_rproc *pru, unsigned int reg, u32 val) writel_relaxed(val, pru->mem_regions[PRU_IOMEM_CTRL].va + reg); } +static struct rproc *__pru_rproc_get(struct device_node *np, int index) +{ + struct rproc *rproc; + phandle rproc_phandle; + int ret; + + ret = of_property_read_u32_index(np, "ti,prus", index, &rproc_phandle); + if (ret) + return ERR_PTR(ret); + + rproc = rproc_get_by_phandle(rproc_phandle); + if (!rproc) { + ret = -EPROBE_DEFER; + return ERR_PTR(ret); + } + + /* make sure it is PRU rproc */ + if (!is_pru_rproc(rproc->dev.parent)) { + rproc_put(rproc); + return ERR_PTR(-ENODEV); + } + + return rproc; +} + +/** + * pru_rproc_get() - get the PRU rproc instance from a device node + * @np: the user/client device node + * @index: index to use for the ti,prus property + * @pru_id: optional pointer to return the PRU remoteproc processor id + * + * This function looks through a client device node's "ti,prus" property at + * index @index and returns the rproc handle for a valid PRU remote processor if + * found. The function allows only one user to own the PRU rproc resource at a + * time. Caller must call pru_rproc_put() when done with using the rproc, not + * required if the function returns a failure. + * + * When optional @pru_id pointer is passed the PRU remoteproc processor id is + * returned. + * + * Return: rproc handle on success, and an ERR_PTR on failure using one + * of the following error values + * -ENODEV if device is not found + * -EBUSY if PRU is already acquired by anyone + * -EPROBE_DEFER is PRU device is not probed yet + */ +struct rproc *pru_rproc_get(struct device_node *np, int index, + enum pruss_pru_id *pru_id) +{ + struct rproc *rproc; + struct pru_rproc *pru; + struct device *dev; + int ret; + + rproc = __pru_rproc_get(np, index); + if (IS_ERR(rproc)) + return rproc; + + pru = rproc->priv; + dev = &rproc->dev; + + mutex_lock(&pru->lock); + + if (pru->client_np) { + mutex_unlock(&pru->lock); + ret = -EBUSY; + goto err_no_rproc_handle; + } + + pru->client_np = np; + + mutex_unlock(&pru->lock); + + if (pru_id) + *pru_id = pru->id; + + return rproc; + +err_no_rproc_handle: + rproc_put(rproc); + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(pru_rproc_get); + +/** + * pru_rproc_put() - release the PRU rproc resource + * @rproc: the rproc resource to release + * + * Releases the PRU rproc resource and makes it available to other + * users. + */ +void pru_rproc_put(struct rproc *rproc) +{ + struct pru_rproc *pru; + + if (IS_ERR_OR_NULL(rproc) || !is_pru_rproc(rproc->dev.parent)) + return; + + pru = rproc->priv; + + mutex_lock(&pru->lock); + + if (!pru->client_np) { + mutex_unlock(&pru->lock); + return; + } + + pru->client_np = NULL; + mutex_unlock(&pru->lock); + + rproc_put(rproc); +} +EXPORT_SYMBOL_GPL(pru_rproc_put); + static inline u32 pru_debug_read_reg(struct pru_rproc *pru, unsigned int reg) { return readl_relaxed(pru->mem_regions[PRU_IOMEM_DEBUG].va + reg); @@ -817,6 +937,8 @@ static int pru_rproc_probe(struct platform_device *pdev) pru->pruss = platform_get_drvdata(ppdev); pru->rproc = rproc; pru->fw_name = fw_name; + pru->client_np = NULL; + mutex_init(&pru->lock); for (i = 0; i < ARRAY_SIZE(mem_names); i++) { res = platform_get_resource_byname(pdev, IORESOURCE_MEM, @@ -905,7 +1027,7 @@ MODULE_DEVICE_TABLE(of, pru_rproc_match); static struct platform_driver pru_rproc_driver = { .driver = { - .name = "pru-rproc", + .name = PRU_RPROC_DRVNAME, .of_match_table = pru_rproc_match, .suppress_bind_attrs = true, }, @@ -917,5 +1039,7 @@ module_platform_driver(pru_rproc_driver); MODULE_AUTHOR("Suman Anna "); MODULE_AUTHOR("Andrew F. Davis "); MODULE_AUTHOR("Grzegorz Jaszczyk "); +MODULE_AUTHOR("Puranjay Mohan "); +MODULE_AUTHOR("Md Danish Anwar "); MODULE_DESCRIPTION("PRU-ICSS Remote Processor Driver"); MODULE_LICENSE("GPL v2"); diff --git a/include/linux/pruss.h b/include/linux/pruss.h index fbe4fbb45807..6ea737e995e9 100644 --- a/include/linux/pruss.h +++ b/include/linux/pruss.h @@ -28,5 +28,34 @@ enum pruss_pru_id { PRUSS_NUM_PRUS, }; +struct device_node; + +#if IS_ENABLED(CONFIG_PRU_REMOTEPROC) + +struct rproc *pru_rproc_get(struct device_node *np, int index, + enum pruss_pru_id *pru_id); +void pru_rproc_put(struct rproc *rproc); + +#else + +static inline struct rproc * +pru_rproc_get(struct device_node *np, int index, enum pruss_pru_id *pru_id) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static inline void pru_rproc_put(struct rproc *rproc) { } + +#endif /* CONFIG_PRU_REMOTEPROC */ + +static inline bool is_pru_rproc(struct device *dev) +{ + const char *drv_name = dev_driver_string(dev); + + if (strncmp(drv_name, PRU_RPROC_DRVNAME, sizeof(PRU_RPROC_DRVNAME))) + return false; + + return true; +} #endif /* __LINUX_PRUSS_H */ \ No newline at end of file