From patchwork Fri Oct 5 14:30:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 10628231 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2AF6813BB for ; Fri, 5 Oct 2018 14:31:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 19F13293C0 for ; Fri, 5 Oct 2018 14:31:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0E266293CB; Fri, 5 Oct 2018 14:31: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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.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 89F25293C0 for ; Fri, 5 Oct 2018 14:31:15 +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: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=hzeP3oXTcdEuQdNCNCdSnNX4eVwS1n+3tNP6VjDE59U=; b=SBw09wV+/BYZnj /rCGMZvIUx2TTjwt6ykxpFPP007HJW5jc7c0g0F8M6aYsyLo77s3NTvHCmhAxQEDLtYFK2du8FPK5 UsQlRf3AAlIs5keE1Bs6nJUenMh0XiWpXmmxKDge9o5JVYvNQ3nqoUye/F4hA1sYvqL5xluK8z+ls W+TgjTj0MlPJ+30rq6vDZvlHh/Akm8oaL4KQmGP2fzu5Pf66l5+/ZMXw7e2ZUMvhhQpdyEb/ts5h9 jJWZV15zmgeoULex/DvwyOYExZOTgrQI7+kGMSDHhSf+Wmg4vyq0Xb/q33B+TamdtIkqBxROTQM75 P7p2zJpVkgDRR88+Y1vg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g8R8B-0002k3-Ox; Fri, 05 Oct 2018 14:31:03 +0000 Received: from lelv0142.ext.ti.com ([198.47.23.249]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g8R7Z-0002Ud-O7 for linux-arm-kernel@lists.infradead.org; Fri, 05 Oct 2018 14:30:27 +0000 Received: from dflxv15.itg.ti.com ([128.247.5.124]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id w95EUFPF001583; Fri, 5 Oct 2018 09:30:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1538749815; bh=z81S8Q0YDAhO4Y0kfvATeBRiSzSLu3SGlTtzHyIV3OE=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=AidO0KBGfWi8CZiWbbVd4COECIfdRVBFEGvlFjhM62s07siBjTHxLF9IyrjgF7v7Z qYcmKIO1CSu05dhhsit1ppsFFjP8x+vQW2EQDTot51/BAMxMdO23IN21XijSmGIoyq VgWgBFHddNb3+SW5M07u8avVNtWDY5mFsIGLZjmM= Received: from DFLE114.ent.ti.com (dfle114.ent.ti.com [10.64.6.35]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id w95EUFvw003385; Fri, 5 Oct 2018 09:30:15 -0500 Received: from DFLE106.ent.ti.com (10.64.6.27) by DFLE114.ent.ti.com (10.64.6.35) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Fri, 5 Oct 2018 09:30:15 -0500 Received: from dlep32.itg.ti.com (157.170.170.100) by DFLE106.ent.ti.com (10.64.6.27) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Fri, 5 Oct 2018 09:30:14 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id w95EU9Zk023568; Fri, 5 Oct 2018 09:30:12 -0500 From: Lokesh Vutla To: Nishanth Menon , Tero Kristo , Santosh Shilimkar Subject: [PATCH 1/4] firmware: ti_sci: Add support to get TISCI handle using of_phandle Date: Fri, 5 Oct 2018 20:00:03 +0530 Message-ID: <20181005143006.18284-2-lokeshvutla@ti.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181005143006.18284-1-lokeshvutla@ti.com> References: <20181005143006.18284-1-lokeshvutla@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-20181005_073025_902209_37B2DD96 X-CRM114-Status: GOOD ( 18.28 ) 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: Lokesh Vutla , Grygorii Strashko , Sekhar Nori , Linux ARM Mailing List 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 From: Grygorii Strashko TISCI has been updated to have support for Resource management(likes interrupts etc..). And there can be multiple device instances of a resource type in a SoC. So every driver corresponding to a resource type should get a TISCI handle so that it can make TISCI calls. And each DT node corresponding to a device should exist under its corresponding bus node as per the SoC architecture. But existing apis in TISCI library assumes that all TISCI users are child nodes of TISCI. Which is not true in the above case. So introduce (devm_)ti_sci_get_by_phandle() apis that can be used by TISCI users to get TISCI handle using of phandle property. Signed-off-by: Grygorii Strashko Signed-off-by: Lokesh Vutla --- drivers/firmware/ti_sci.c | 83 ++++++++++++++++++++++++++ include/linux/soc/ti/ti_sci_protocol.h | 17 ++++++ 2 files changed, 100 insertions(+) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 69ed1464175c..f0cafa8a2ee9 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -1781,6 +1781,89 @@ const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev) } EXPORT_SYMBOL_GPL(devm_ti_sci_get_handle); +/** + * ti_sci_get_by_phandle() - Get the TI SCI handle using DT phandle + * @np: device node + * @propname: property name containing phandle on TISCI node + * + * NOTE: The function does not track individual clients of the framework + * and is expected to be maintained by caller of TI SCI protocol library. + * ti_sci_put_handle must be balanced with successful ti_sci_get_by_phandle + * Return: pointer to handle if successful, else: + * -EPROBE_DEFER if the instance is not ready + * -ENODEV if the required node handler is missing + * -EINVAL if invalid conditions are encountered. + */ +const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np, + const char *property) +{ + struct ti_sci_handle *handle = NULL; + struct device_node *ti_sci_np; + struct ti_sci_info *info; + struct list_head *p; + + if (!np) { + pr_err("I need a device pointer\n"); + return ERR_PTR(-EINVAL); + } + + ti_sci_np = of_parse_phandle(np, property, 0); + if (!ti_sci_np) + return ERR_PTR(-ENODEV); + + mutex_lock(&ti_sci_list_mutex); + list_for_each(p, &ti_sci_list) { + info = list_entry(p, struct ti_sci_info, node); + if (ti_sci_np == info->dev->of_node) { + handle = &info->handle; + info->users++; + break; + } + } + mutex_unlock(&ti_sci_list_mutex); + of_node_put(ti_sci_np); + + if (!handle) + return ERR_PTR(-EPROBE_DEFER); + + return handle; +} +EXPORT_SYMBOL_GPL(ti_sci_get_by_phandle); + +/** + * devm_ti_sci_get_by_phandle() - Managed get handle using phandle + * @dev: Device pointer requesting TISCI handle + * @propname: property name containing phandle on TISCI node + * + * NOTE: This releases the handle once the device resources are + * no longer needed. MUST NOT BE released with ti_sci_put_handle. + * The function does not track individual clients of the framework + * and is expected to be maintained by caller of TI SCI protocol library. + * + * Return: 0 if all went fine, else corresponding error. + */ +const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev, + const char *property) +{ + const struct ti_sci_handle *handle; + const struct ti_sci_handle **ptr; + + ptr = devres_alloc(devm_ti_sci_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + handle = ti_sci_get_by_phandle(dev_of_node(dev), property); + + if (!IS_ERR(handle)) { + *ptr = handle; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return handle; +} +EXPORT_SYMBOL_GPL(devm_ti_sci_get_by_phandle); + static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode, void *cmd) { diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index 18435e5c6364..515587e9d373 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -217,6 +217,10 @@ struct ti_sci_handle { const struct ti_sci_handle *ti_sci_get_handle(struct device *dev); int ti_sci_put_handle(const struct ti_sci_handle *handle); const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev); +const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np, + const char *property); +const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev, + const char *property); #else /* CONFIG_TI_SCI_PROTOCOL */ @@ -236,6 +240,19 @@ const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev) return ERR_PTR(-EINVAL); } +static inline +const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np, + const char *property) +{ + return ERR_PTR(-EINVAL); +} + +static inline +const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev, + const char *property) +{ + return ERR_PTR(-EINVAL); +} #endif /* CONFIG_TI_SCI_PROTOCOL */ #endif /* __TISCI_PROTOCOL_H */ From patchwork Fri Oct 5 14:30:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 10628235 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 970BF13BB for ; Fri, 5 Oct 2018 14:32:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 83616293E4 for ; Fri, 5 Oct 2018 14:32:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 756DB2940A; Fri, 5 Oct 2018 14:32:49 +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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.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 AEC3C293E4 for ; Fri, 5 Oct 2018 14:32:48 +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: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=JjWcxHEf2N6wWg5n9XV0lofu5q/kM7ln1DxZfIhfp9U=; b=WComU84fWJlKmO u8+EkKgoG+KGscqzLO1tUScMRqnBcMb5bVyhasrw9ez9/Eb+uAaxa8Z5yVhjqZrI46JjnJa/BPEzu rE8PVCQREoLBuhpKcGZ6DJjP6gyaQwtY+DQpk0x2FuyFjeBxHYLC4HMiv3/blfgpA2QwsA1yRDJsT sMfzGeMt4QnGq/Qn3jvIZMuJKmbuUcqj85eCZ222ZYeOGBPryf+5DyaQPS8fJ8Mb0C5YZgydAojYG nICMuS2dX006zxM2Fn8NwCYM1DwLN8oX3vN9Ij+Uy9RpmnnJzMFTVr+Kt1SkGgbDmI4W6qvWcKmpG iPDS2ZKq9vqj8rCWG41A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g8R9f-0003P1-Gs; Fri, 05 Oct 2018 14:32:35 +0000 Received: from lelv0143.ext.ti.com ([198.47.23.248]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g8R7d-0002Un-32 for linux-arm-kernel@lists.infradead.org; Fri, 05 Oct 2018 14:30:45 +0000 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id w95EUHWt081200; Fri, 5 Oct 2018 09:30:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1538749817; bh=zXVIwOCS+n6yatJGAgo0NYzzg/sp8RrT5zFguKNTSIc=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=W/dTanR1LZhMAL56JNRHQCYKJLq4nrRIRxlCIflxkDWN1Zz/EZNd6QTuvx9AatlQz 55sXeL8aVX9+FF/JecqPw7OkofLDTs0V0/YPZhvdV7sk4Ps1WPcmskDs9bkjqQhpa+ wBBn0tcT0knbWSnUNw27fu/5ViXRFimDVs9k1ZKQ= Received: from DLEE102.ent.ti.com (dlee102.ent.ti.com [157.170.170.32]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w95EUHs7027194; Fri, 5 Oct 2018 09:30:17 -0500 Received: from DLEE106.ent.ti.com (157.170.170.36) by DLEE102.ent.ti.com (157.170.170.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Fri, 5 Oct 2018 09:30:17 -0500 Received: from dlep32.itg.ti.com (157.170.170.100) by DLEE106.ent.ti.com (157.170.170.36) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Fri, 5 Oct 2018 09:30:17 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id w95EU9Zl023568; Fri, 5 Oct 2018 09:30:15 -0500 From: Lokesh Vutla To: Nishanth Menon , Tero Kristo , Santosh Shilimkar Subject: [PATCH 2/4] firmware: ti_sci: Add support for RM core ops Date: Fri, 5 Oct 2018 20:00:04 +0530 Message-ID: <20181005143006.18284-3-lokeshvutla@ti.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181005143006.18284-1-lokeshvutla@ti.com> References: <20181005143006.18284-1-lokeshvutla@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-20181005_073029_241595_31885196 X-CRM114-Status: GOOD ( 19.13 ) 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: Lokesh Vutla , Sekhar Nori , Linux ARM Mailing List 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 TISCI provides support for getting the resources(IRQ, RING etc..) assigned to a specific device. These resources can be handled by the client and in turn sends TISCI cmd to configure the resources. It is very important that client should keep track on usage of these resources. Add support for TISCI commands to get resource ranges. Signed-off-by: Lokesh Vutla --- drivers/firmware/ti_sci.c | 114 +++++++++++++++++++++++++ drivers/firmware/ti_sci.h | 42 +++++++++ include/linux/soc/ti/ti_sci_protocol.h | 26 ++++++ 3 files changed, 182 insertions(+) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index f0cafa8a2ee9..978cdf3e0986 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -1617,6 +1617,115 @@ static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle) return ret; } +/** + * ti_sci_get_resource_range - Helper to get a range of resources assigned + * to a host. Resource is uniquely identified by + * type and subtype. + * @handle: Pointer to TISCI handle. + * @type: Resource assignment type that is being requested for + * @subtype: Resource assignment subtype that is being requested for + * @s_host: Host processor ID to which the resources are allocated + * @range_start: Start index of the resource range + * @range_num: Number of resources in the range + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_get_resource_range(const struct ti_sci_handle *handle, + u16 type, u8 subtype, u8 s_host, + u16 *range_start, u16 *range_num) +{ + struct ti_sci_msg_resp_get_resource_range *resp; + struct ti_sci_msg_req_get_resource_range *req; + struct ti_sci_xfer *xfer; + struct ti_sci_info *info; + struct device *dev; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + dev = info->dev; + + xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_RESOURCE_RANGE, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + sizeof(*req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req = (struct ti_sci_msg_req_get_resource_range *)xfer->xfer_buf; + req->secondary_host = s_host; + req->type = type & MSG_RM_RESOURCE_TYPE_MASK; + req->subtype = subtype & MSG_RM_RESOURCE_SUBTYPE_MASK; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(dev, "Mbox send fail %d\n", ret); + goto fail; + } + + resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->xfer_buf; + + if (!ti_sci_is_response_ack(resp)) { + ret = -ENODEV; + } else if (!resp->range_start && !resp->range_num) { + ret = -ENODEV; + } else { + *range_start = resp->range_start; + *range_num = resp->range_num; + }; + +fail: + ti_sci_put_one_xfer(&info->minfo, xfer); + + return ret; +} + +/** + * ti_sci_cmd_get_resource_range - Get a range of resources assigned to host + * that is same as ti sci interface host. + * @handle: Pointer to TISCI handle. + * @type: Resource assignment type that is being requested for + * @subtype: Resource assignment subtype that is being requested for + * @range_start: Start index of the resource range + * @range_num: Number of resources in the range + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_get_resource_range(const struct ti_sci_handle *handle, + u16 type, u8 subtype, + u16 *range_start, u16 *range_num) +{ + return ti_sci_get_resource_range(handle, type, subtype, + TI_SCI_IRQ_SECONDARY_HOST_INVALID, + range_start, range_num); +} + +/** + * ti_sci_cmd_get_resource_range_from_shost - Get a range of resources + * assigned to a specified host. + * @handle: Pointer to TISCI handle. + * @type: Resource assignment type that is being requested for + * @subtype: Resource assignment subtype that is being requested for + * @s_host: Host processor ID to which the resources are allocated + * @range_start: Start index of the resource range + * @range_num: Number of resources in the range + * + * Return: 0 if all went fine, else return appropriate error. + */ +static +int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle, + u16 type, u8 subtype, u8 s_host, + u16 *range_start, u16 *range_num) +{ + return ti_sci_get_resource_range(handle, type, subtype, s_host, + range_start, range_num); +} + /* * ti_sci_setup_ops() - Setup the operations structures * @info: pointer to TISCI pointer @@ -1627,6 +1736,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) struct ti_sci_core_ops *core_ops = &ops->core_ops; struct ti_sci_dev_ops *dops = &ops->dev_ops; struct ti_sci_clk_ops *cops = &ops->clk_ops; + struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops; core_ops->reboot_device = ti_sci_cmd_core_reboot; @@ -1657,6 +1767,10 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq; cops->set_freq = ti_sci_cmd_clk_set_freq; cops->get_freq = ti_sci_cmd_clk_get_freq; + + rm_core_ops->get_range = ti_sci_cmd_get_resource_range; + rm_core_ops->get_range_from_shost = + ti_sci_cmd_get_resource_range_from_shost; } /** diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index 12bf316b68df..a043c4762791 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -35,6 +35,9 @@ #define TI_SCI_MSG_QUERY_CLOCK_FREQ 0x010d #define TI_SCI_MSG_GET_CLOCK_FREQ 0x010e +/* Resource Management Requests */ +#define TI_SCI_MSG_GET_RESOURCE_RANGE 0x1500 + /** * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses * @type: Type of messages: One of TI_SCI_MSG* values @@ -461,4 +464,43 @@ struct ti_sci_msg_resp_get_clock_freq { u64 freq_hz; } __packed; +#define TI_SCI_IRQ_SECONDARY_HOST_INVALID 0xff + +/** + * struct ti_sci_msg_req_get_resource_range - Request to get a host's assigned + * range of resources. + * @hdr: Generic Header + * @type: Unique resource assignment type + * @subtype: Resource assignment subtype within the resource type. + * @secondary_host: Host processing entity to which the resources are + * allocated. This is required only when the destination + * host id id different from ti sci interface host id, + * else TI_SCI_IRQ_SECONDARY_HOST_INVALID can be passed. + * + * Request type is TI_SCI_MSG_GET_RESOURCE_RANGE. Responded with requested + * resource range which is of type TI_SCI_MSG_GET_RESOURCE_RANGE. + */ +struct ti_sci_msg_req_get_resource_range { + struct ti_sci_msg_hdr hdr; +#define MSG_RM_RESOURCE_TYPE_MASK GENMASK(9, 0) +#define MSG_RM_RESOURCE_SUBTYPE_MASK GENMASK(5, 0) + u16 type; + u8 subtype; + u8 secondary_host; +} __packed; + +/** + * struct ti_sci_msg_resp_get_resource_range - Response to resource get range. + * @hdr: Generic Header + * @range_start: Start index of the resource range. + * @range_num: Number of resources in the range. + * + * Response to request TI_SCI_MSG_GET_RESOURCE_RANGE. + */ +struct ti_sci_msg_resp_get_resource_range { + struct ti_sci_msg_hdr hdr; + u16 range_start; + u16 range_num; +} __packed; + #endif /* __TI_SCI_H */ diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index 515587e9d373..c009a1f92c14 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -192,15 +192,41 @@ struct ti_sci_clk_ops { u64 *current_freq); }; +/** + * struct ti_sci_rm_core_ops - Resource management core operations + * @get_range: Get a range of resources belonging to ti sci host. + * @get_rage_from_shost: Get a range of resources belonging to + * specified host id. + * - s_host: Host processing entity to which the + * resources are allocated + * + * NOTE: for these functions, all the parameters are consolidated and defined + * as below: + * - handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle + * - type: resource assignment type that is being requested for + * - subtype: resource assignment subtype that is being requested for + * - range_start: Start index of the resource range + * - range_end: Number of resources in the range + */ +struct ti_sci_rm_core_ops { + int (*get_range)(const struct ti_sci_handle *handle, u16 type, + u8 subtype, u16 *range_start, u16 *range_num); + int (*get_range_from_shost)(const struct ti_sci_handle *handle, + u16 type, u8 subtype, u8 s_host, + u16 *range_start, u16 *range_num); +}; + /** * struct ti_sci_ops - Function support for TI SCI * @dev_ops: Device specific operations * @clk_ops: Clock specific operations + * @rm_core_ops: Resource management core operations. */ struct ti_sci_ops { struct ti_sci_core_ops core_ops; struct ti_sci_dev_ops dev_ops; struct ti_sci_clk_ops clk_ops; + struct ti_sci_rm_core_ops rm_core_ops; }; /** From patchwork Fri Oct 5 14:30:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 10628233 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 91BCD16B1 for ; Fri, 5 Oct 2018 14:31:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7C152293CD for ; Fri, 5 Oct 2018 14:31:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6DFCB293D1; Fri, 5 Oct 2018 14:31:50 +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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.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 148A4293CD for ; Fri, 5 Oct 2018 14:31:49 +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: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=zKZJhZX0xgrQ5sdZOayGEKCPG3alT4Wp/zQgB1Wd5uw=; b=Zzg0QsNv7g+j3a jyIOBbFm+odMFiQ8kNRC96Y8THZJ07i/RYp9ZDwWpEf1BDQMNaH37RhCGWxEGJCrr2PxXOn4sTNki 0jCRbKopXSpPzQmY7OvggKxPTfVEWKLEJ9LyZYaiI9qeDXJEdlRk5F14Y4K1gRM1vhw+ndmePjl55 sm6H5ItRypMu912CW8Qy4jxppvXSnnsFNCAyGnFLTRzAGVKszgDBi9nfZO/lnBtIB51V5PoBoIlwd 0PR+n1oDeljhaDZMNx4Ki4Jw952J5JsH8zeVYwXxA4+/mQorxqcNhTSzO+jlFsAUbgF4JiRcUi+bz S/LT6e4Ul3wXtjiKKZWg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g8R8p-00030e-TG; Fri, 05 Oct 2018 14:31:44 +0000 Received: from lelv0142.ext.ti.com ([198.47.23.249]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g8R7Z-0002Up-O5 for linux-arm-kernel@lists.infradead.org; Fri, 05 Oct 2018 14:30:40 +0000 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id w95EUKll001605; Fri, 5 Oct 2018 09:30:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1538749820; bh=momRREYxU4u5WR4D3C7uB9tcWu4/YNQR6iyHwlwtyR0=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=Qi3NNnwi0VglPPpEybBTto+C+vrtwNYd6RbigBDhvyVipGu8u2HUZdYio1WoTq6wH pgKRz0umbSjK62Q118X7Wr1HNSC4stS3NTw6vsxTZXaEcZylFJwz74RUtx57RSibVr aLpyGkr+CgBF9GAsP8Cax1GN0U0vPosEu2TFPAzQ= Received: from DFLE106.ent.ti.com (dfle106.ent.ti.com [10.64.6.27]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w95EUK3M027218; Fri, 5 Oct 2018 09:30:20 -0500 Received: from DFLE107.ent.ti.com (10.64.6.28) by DFLE106.ent.ti.com (10.64.6.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Fri, 5 Oct 2018 09:30:19 -0500 Received: from dlep32.itg.ti.com (157.170.170.100) by DFLE107.ent.ti.com (10.64.6.28) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Fri, 5 Oct 2018 09:30:19 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id w95EU9Zm023568; Fri, 5 Oct 2018 09:30:17 -0500 From: Lokesh Vutla To: Nishanth Menon , Tero Kristo , Santosh Shilimkar Subject: [PATCH 3/4] firmware: ti_sci: Add support for IRQ management Date: Fri, 5 Oct 2018 20:00:05 +0530 Message-ID: <20181005143006.18284-4-lokeshvutla@ti.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181005143006.18284-1-lokeshvutla@ti.com> References: <20181005143006.18284-1-lokeshvutla@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-20181005_073025_898173_64E815C8 X-CRM114-Status: GOOD ( 17.20 ) 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: Lokesh Vutla , Sekhar Nori , Linux ARM Mailing List 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 TISCI abstracts the handling of IRQ routes where interrupt sources are not directly connected to interrupt controller. Add support for the set of TISCI commands for requesting and releasing IRQs. Signed-off-by: Lokesh Vutla --- drivers/firmware/ti_sci.c | 436 +++++++++++++++++++++++++ drivers/firmware/ti_sci.h | 60 ++++ include/linux/soc/ti/ti_sci_protocol.h | 77 +++++ 3 files changed, 573 insertions(+) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 978cdf3e0986..5184ff38804f 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -1726,6 +1726,429 @@ int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle, range_start, range_num); } +/** + * ti_sci_manage_irq() - Helper api to configure/release the irq route between + * the requested source and destination + * @handle: Pointer to TISCI handle. + * @valid_params: Bit fields defining the validity of certain params + * @src_id: Device ID of the IRQ source + * @src_index: IRQ source index within the source device + * @dst_id: Device ID of the IRQ destination + * @dt_host_irq: IRQ number of the destination device + * @ia_id: Device ID of the IA, if the IRQ flows through this IA + * @vint: Virtual interrupt to be used within the IA + * @global_event: Global event number to be used for the requesting event + * @vint_status_bit: Virtual interrupt status bit to be used for the event + * @s_host: Secondary host ID to which the irq/event is being + * requested for. + * @type: Request type irq set or release. + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_manage_irq(const struct ti_sci_handle *handle, + u32 valid_params, u16 src_id, u16 src_index, + u16 dst_id, u16 dst_host_irq, u16 ia_id, u16 vint, + u16 global_event, u8 vint_status_bit, u8 s_host, + u16 type) +{ + struct ti_sci_msg_req_manage_irq *req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_xfer *xfer; + struct ti_sci_info *info; + struct device *dev; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + dev = info->dev; + + xfer = ti_sci_get_one_xfer(info, type, TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + sizeof(*req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req = (struct ti_sci_msg_req_manage_irq *)xfer->xfer_buf; + req->valid_params = valid_params; + req->src_id = src_id; + req->src_index = src_index; + req->dst_id = dst_id; + req->dst_host_irq = dst_host_irq; + req->ia_id = ia_id; + req->vint = vint; + req->global_event = global_event; + req->vint_status_bit = vint_status_bit; + req->secondary_host = s_host; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(dev, "Mbox send fail %d\n", ret); + goto fail; + } + + resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; + + ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; + +fail: + ti_sci_put_one_xfer(&info->minfo, xfer); + + return ret; +} + +/** + * ti_sci_set_irq() - Helper api to configure the irq route between the + * requested source and destination + * @handle: Pointer to TISCI handle. + * @valid_params: Bit fields defining the validity of certain params + * @src_id: Device ID of the IRQ source + * @src_index: IRQ source index within the source device + * @dst_id: Device ID of the IRQ destination + * @dt_host_irq: IRQ number of the destination device + * @ia_id: Device ID of the IA, if the IRQ flows through this IA + * @vint: Virtual interrupt to be used within the IA + * @global_event: Global event number to be used for the requesting event + * @vint_status_bit: Virtual interrupt status bit to be used for the event + * @s_host: Secondary host ID to which the irq/event is being + * requested for. + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_set_irq(const struct ti_sci_handle *handle, u32 valid_params, + u16 src_id, u16 src_index, u16 dst_id, + u16 dst_host_irq, u16 ia_id, u16 vint, + u16 global_event, u8 vint_status_bit, u8 s_host) +{ + return ti_sci_manage_irq(handle, valid_params, src_id, src_index, + dst_id, dst_host_irq, ia_id, vint, + global_event, vint_status_bit, s_host, + TI_SCI_MSG_SET_IRQ); +} + +/** + * ti_sci_free_irq() - Helper api to free the irq route between the + * requested source and destination + * @handle: Pointer to TISCI handle. + * @valid_params: Bit fields defining the validity of certain params + * @src_id: Device ID of the IRQ source + * @src_index: IRQ source index within the source device + * @dst_id: Device ID of the IRQ destination + * @dt_host_irq: IRQ number of the destination device + * @ia_id: Device ID of the IA, if the IRQ flows through this IA + * @vint: Virtual interrupt to be used within the IA + * @global_event: Global event number to be used for the requesting event + * @vint_status_bit: Virtual interrupt status bit to be used for the event + * @s_host: Secondary host ID to which the irq/event is being + * requested for. + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_free_irq(const struct ti_sci_handle *handle, u32 valid_params, + u16 src_id, u16 src_index, u16 dst_id, + u16 dst_host_irq, u16 ia_id, u16 vint, + u16 global_event, u8 vint_status_bit, u8 s_host) +{ + return ti_sci_manage_irq(handle, valid_params, src_id, src_index, + dst_id, dst_host_irq, ia_id, vint, + global_event, vint_status_bit, s_host, + TI_SCI_MSG_FREE_IRQ); +} + +/** + * ti_sci_cmd_set_direct_irq() - Configure a non-event based direct irq route + * between the requested source and destination. + * @handle: Pointer to TISCI handle. + * @src_id: Device ID of the IRQ source + * @src_index: IRQ source index within the source device + * @dst_id: Device ID of the IRQ destination + * @dt_host_irq: IRQ number of the destination device + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_set_direct_irq(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, u16 dst_id, + u16 dst_host_irq) +{ + u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID; + + return ti_sci_set_irq(handle, valid_params, src_id, src_index, + dst_id, dst_host_irq, 0, 0, 0, 0, 0); +} + +/** + * ti_sci_cmd_set_event_irq() - Configure an event based irq route between the + * requested source and destination + * @handle: Pointer to TISCI handle. + * @src_id: Device ID of the IRQ source + * @src_index: IRQ source index within the source device + * @dst_id: Device ID of the IRQ destination + * @dt_host_irq: IRQ number of the destination device + * @ia_id: Device ID of the IA, if the IRQ flows through this IA + * @vint: Virtual interrupt to be used within the IA + * @global_event: Global event number to be used for the requesting event + * @vint_status_bit: Virtual interrupt status bit to be used for the event + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_set_event_irq(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, u16 dst_id, + u16 dst_host_irq, u16 ia_id, u16 vint, + u16 global_event, u8 vint_status_bit) +{ + u32 valid_params = MSG_FLAG_DST_ID_VALID | + MSG_FLAG_DST_HOST_IRQ_VALID | MSG_FLAG_IA_ID_VALID | + MSG_FLAG_VINT_VALID | MSG_FLAG_GLB_EVNT_VALID | + MSG_FLAG_VINT_STS_BIT_VALID; + + return ti_sci_set_irq(handle, valid_params, src_id, src_index, dst_id, + dst_host_irq, ia_id, vint, global_event, + vint_status_bit, 0); +} + +/** + * ti_sci_cmd_set_direct_irq_from_shost() - Configure a non-event based direct + * irq route between the source and + * destination belonging to a + * specified host. + * @handle: Pointer to TISCI handle. + * @src_id: Device ID of the IRQ source + * @src_index: IRQ source index within the source device + * @dst_id: Device ID of the IRQ destination + * @dt_host_irq: IRQ number of the destination device + * @s_host: Secondary host ID to which the irq/event is being + * requested for. + * + * Return: 0 if all went fine, else return appropriate error. + */ +static +int ti_sci_cmd_set_direct_irq_from_shost(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, u16 dst_id, + u16 dst_host_irq, u8 s_host) +{ + u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID | + MSG_FLAG_SHOST_VALID; + + return ti_sci_set_irq(handle, valid_params, src_id, src_index, + dst_id, dst_host_irq, 0, 0, 0, 0, s_host); +} + +/** + * ti_sci_cmd_set_event_irq_from_shost() - Configure an event based irq + * route between the source and + * destination belonging to a + * specified host. + * @handle: Pointer to TISCI handle. + * @src_id: Device ID of the IRQ source + * @src_index: IRQ source index within the source device + * @dst_id: Device ID of the IRQ destination + * @dt_host_irq: IRQ number of the destination device + * @ia_id: Device ID of the IA, if the IRQ flows through this IA + * @vint: Virtual interrupt to be used within the IA + * @global_event: Global event number to be used for the requesting event + * @vint_status_bit: Virtual interrupt status bit to be used for the event + * @s_host: Secondary host ID to which the irq/event is being + * requested for. + * + * Return: 0 if all went fine, else return appropriate error. + */ +static +int ti_sci_cmd_set_event_irq_from_shost(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, u16 dst_id, + u16 dst_host_irq, u16 ia_id, u16 vint, + u16 global_event, u8 vint_status_bit, + u8 s_host) +{ + u32 valid_params = MSG_FLAG_DST_ID_VALID | + MSG_FLAG_DST_HOST_IRQ_VALID | MSG_FLAG_IA_ID_VALID | + MSG_FLAG_VINT_VALID | MSG_FLAG_GLB_EVNT_VALID | + MSG_FLAG_VINT_STS_BIT_VALID | MSG_FLAG_SHOST_VALID; + + return ti_sci_set_irq(handle, valid_params, src_id, src_index, + dst_id, dst_host_irq, ia_id, vint, + global_event, vint_status_bit, s_host); +} + +/** + * ti_sci_cmd_set_event_irq_to_poll() - Configure an event based irq + * in polling mode + * @handle: Pointer to TISCI handle. + * @src_id: Device ID of the IRQ source + * @src_index: IRQ source index within the source device + * @dst_id: Device ID of the IRQ destination + * @dt_host_irq: IRQ number of the destination device + * @ia_id: Device ID of the IA, if the IRQ flows through this IA + * @vint: Virtual interrupt to be used within the IA + * @global_event: Global event number to be used for the requesting event + * @vint_status_bit: Virtual interrupt status bit to be used for the event + * @s_host: Secondary host ID to which the irq/event is being + * requested for. + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_set_event_irq_to_poll(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, + u16 ia_id, u16 vint, + u16 global_event, + u8 vint_status_bit) +{ + u32 valid_params = MSG_FLAG_IA_ID_VALID | MSG_FLAG_VINT_VALID | + MSG_FLAG_GLB_EVNT_VALID | + MSG_FLAG_VINT_STS_BIT_VALID; + + return ti_sci_set_irq(handle, valid_params, src_id, src_index, 0, 0, + ia_id, vint, global_event, vint_status_bit, 0); +} + +/** + * ti_sci_cmd_free_direct_irq() - Free a non-event based direct irq route + * between the requested source and destination. + * @handle: Pointer to TISCI handle. + * @src_id: Device ID of the IRQ source + * @src_index: IRQ source index within the source device + * @dst_id: Device ID of the IRQ destination + * @dt_host_irq: IRQ number of the destination device + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_free_direct_irq(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, u16 dst_id, + u16 dst_host_irq) +{ + u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID; + + return ti_sci_free_irq(handle, valid_params, src_id, src_index, + dst_id, dst_host_irq, 0, 0, 0, 0, 0); +} + +/** + * ti_sci_cmd_free_event_irq() - Free an event based irq route between the + * requested source and destination + * @handle: Pointer to TISCI handle. + * @src_id: Device ID of the IRQ source + * @src_index: IRQ source index within the source device + * @dst_id: Device ID of the IRQ destination + * @dt_host_irq: IRQ number of the destination device + * @ia_id: Device ID of the IA, if the IRQ flows through this IA + * @vint: Virtual interrupt to be used within the IA + * @global_event: Global event number to be used for the requesting event + * @vint_status_bit: Virtual interrupt status bit to be used for the event + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_free_event_irq(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, u16 dst_id, + u16 dst_host_irq, u16 ia_id, u16 vint, + u16 global_event, u8 vint_status_bit) +{ + u32 valid_params = MSG_FLAG_DST_ID_VALID | + MSG_FLAG_DST_HOST_IRQ_VALID | MSG_FLAG_IA_ID_VALID | + MSG_FLAG_VINT_VALID | MSG_FLAG_GLB_EVNT_VALID | + MSG_FLAG_VINT_STS_BIT_VALID; + + return ti_sci_free_irq(handle, valid_params, src_id, src_index, + dst_id, dst_host_irq, ia_id, vint, + global_event, vint_status_bit, 0); +} + +/** + * ti_sci_cmd_free_direct_irq_from_shost() - Free a non-event based direct irq + * route between the source and + * destination belonging to a + * specified host. + * @handle: Pointer to TISCI handle. + * @src_id: Device ID of the IRQ source + * @src_index: IRQ source index within the source device + * @dst_id: Device ID of the IRQ destination + * @dt_host_irq: IRQ number of the destination device + * @s_host: Secondary host ID to which the irq/event is being + * requested for. + * + * Return: 0 if all went fine, else return appropriate error. + */ +static +int ti_sci_cmd_free_direct_irq_from_shost(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, u16 dst_id, + u16 dst_host_irq, u8 s_host) +{ + u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID | + MSG_FLAG_SHOST_VALID; + + return ti_sci_free_irq(handle, valid_params, src_id, src_index, + dst_id, dst_host_irq, 0, 0, 0, 0, s_host); +} + +/** + * ti_sci_cmd_free_event_irq_from_shost() - Free an event based irq + * route between the source and + * destination belonging to a + * specified host. + * @handle: Pointer to TISCI handle. + * @src_id: Device ID of the IRQ source + * @src_index: IRQ source index within the source device + * @dst_id: Device ID of the IRQ destination + * @dt_host_irq: IRQ number of the destination device + * @ia_id: Device ID of the IA, if the IRQ flows through this IA + * @vint: Virtual interrupt to be used within the IA + * @global_event: Global event number to be used for the requesting event + * @vint_status_bit: Virtual interrupt status bit to be used for the event + * @s_host: Secondary host ID to which the irq/event is being + * requested for. + * + * Return: 0 if all went fine, else return appropriate error. + */ +static +int ti_sci_cmd_free_event_irq_from_shost(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, u16 dst_id, + u16 dst_host_irq, u16 ia_id, u16 vint, + u16 global_event, u8 vint_status_bit, + u8 s_host) +{ + u32 valid_params = MSG_FLAG_DST_ID_VALID | + MSG_FLAG_DST_HOST_IRQ_VALID | MSG_FLAG_IA_ID_VALID | + MSG_FLAG_VINT_VALID | MSG_FLAG_GLB_EVNT_VALID | + MSG_FLAG_VINT_STS_BIT_VALID | MSG_FLAG_SHOST_VALID; + + return ti_sci_free_irq(handle, valid_params, src_id, src_index, + dst_id, dst_host_irq, ia_id, vint, + global_event, vint_status_bit, s_host); +} + +/** + * ti_sci_cmd_free_event_irq_to_poll() - Free an event based irq + * in polling mode + * @handle: Pointer to TISCI handle. + * @src_id: Device ID of the IRQ source + * @src_index: IRQ source index within the source device + * @dst_id: Device ID of the IRQ destination + * @dt_host_irq: IRQ number of the destination device + * @ia_id: Device ID of the IA, if the IRQ flows through this IA + * @vint: Virtual interrupt to be used within the IA + * @global_event: Global event number to be used for the requesting event + * @vint_status_bit: Virtual interrupt status bit to be used for the event + * @s_host: Secondary host ID to which the irq/event is being + * requested for. + * + * Return: 0 if all went fine, else return appropriate error. + */ +static int ti_sci_cmd_free_event_irq_to_poll(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, + u16 ia_id, u16 vint, + u16 global_event, + u8 vint_status_bit) +{ + u32 valid_params = MSG_FLAG_IA_ID_VALID | MSG_FLAG_VINT_VALID | + MSG_FLAG_GLB_EVNT_VALID | + MSG_FLAG_VINT_STS_BIT_VALID; + + return ti_sci_free_irq(handle, valid_params, src_id, src_index, 0, 0, + ia_id, vint, global_event, vint_status_bit, 0); +} + /* * ti_sci_setup_ops() - Setup the operations structures * @info: pointer to TISCI pointer @@ -1737,6 +2160,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) struct ti_sci_dev_ops *dops = &ops->dev_ops; struct ti_sci_clk_ops *cops = &ops->clk_ops; struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops; + struct ti_sci_rm_irq_ops *iops = &ops->rm_irq_ops; core_ops->reboot_device = ti_sci_cmd_core_reboot; @@ -1771,6 +2195,18 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) rm_core_ops->get_range = ti_sci_cmd_get_resource_range; rm_core_ops->get_range_from_shost = ti_sci_cmd_get_resource_range_from_shost; + + iops->set_direct_irq = ti_sci_cmd_set_direct_irq; + iops->set_event_irq = ti_sci_cmd_set_event_irq; + iops->set_direct_irq_from_shost = ti_sci_cmd_set_direct_irq_from_shost; + iops->set_event_irq_from_shost = ti_sci_cmd_set_event_irq_from_shost; + iops->set_event_irq_to_poll = ti_sci_cmd_set_event_irq_to_poll; + iops->free_direct_irq = ti_sci_cmd_free_direct_irq; + iops->free_event_irq = ti_sci_cmd_free_event_irq; + iops->free_direct_irq_from_shost = + ti_sci_cmd_free_direct_irq_from_shost; + iops->free_event_irq_from_shost = ti_sci_cmd_free_event_irq_from_shost; + iops->free_event_irq_to_poll = ti_sci_cmd_free_event_irq_to_poll; } /** diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index a043c4762791..4983827151bf 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -38,6 +38,10 @@ /* Resource Management Requests */ #define TI_SCI_MSG_GET_RESOURCE_RANGE 0x1500 +/* IRQ requests */ +#define TI_SCI_MSG_SET_IRQ 0x1000 +#define TI_SCI_MSG_FREE_IRQ 0x1001 + /** * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses * @type: Type of messages: One of TI_SCI_MSG* values @@ -503,4 +507,60 @@ struct ti_sci_msg_resp_get_resource_range { u16 range_num; } __packed; +/** + * struct ti_sci_msg_req_manage_irq - Request to configure/release the route + * between the dev and the host. + * @hdr: Generic Header + * @valid_params: Bit fields defining the validity of interrupt source + * parameters. If a bit is not set, then corresponding + * field is not valid and will not be used for route set. + * Bit field definitions: + * 0 - Valid bit for @dst_id + * 1 - Valid bit for @dst_host_irq + * 2 - Valid bit for @ia_id + * 3 - Valid bit for @vint + * 4 - Valid bit for @global_event + * 5 - Valid bit for @vint_status_bit_index + * 31 - Valid bit for @secondary_host + * @src_id: IRQ source peripheral ID. + * @src_index: IRQ source index within the peripheral + * @dst_id: IRQ Destination ID. Based on the architecture it can be + * IRQ controller or host processor ID. + * @dst_host_irq: IRQ number of the destination host IRQ controller + * @ia_id: Device ID of the interrupt aggregator in which the + * vint resides. + * @vint: Virtual interrupt number if the interrupt route + * is through an interrupt aggregator. + * @global_event: Global event that is to be mapped to interrupt + * aggregator virtual interrupt status bit. + * @vint_status_bit: Virtual interrupt status bit if the interrupt route + * utilizes an interrupt aggregator status bit. + * @secondary_host: Host ID of the IRQ destination computing entity. This is + * required only when destination host id is different + * from ti sci interface host id. + * + * Request type is TI_SCI_MSG_SET/RELEASE_IRQ. + * Response is generic ACK / NACK message. + */ +struct ti_sci_msg_req_manage_irq { + struct ti_sci_msg_hdr hdr; +#define MSG_FLAG_DST_ID_VALID TI_SCI_MSG_FLAG(0) +#define MSG_FLAG_DST_HOST_IRQ_VALID TI_SCI_MSG_FLAG(1) +#define MSG_FLAG_IA_ID_VALID TI_SCI_MSG_FLAG(2) +#define MSG_FLAG_VINT_VALID TI_SCI_MSG_FLAG(3) +#define MSG_FLAG_GLB_EVNT_VALID TI_SCI_MSG_FLAG(4) +#define MSG_FLAG_VINT_STS_BIT_VALID TI_SCI_MSG_FLAG(5) +#define MSG_FLAG_SHOST_VALID TI_SCI_MSG_FLAG(31) + u32 valid_params; + u16 src_id; + u16 src_index; + u16 dst_id; + u16 dst_host_irq; + u16 ia_id; + u16 vint; + u16 global_event; + u8 vint_status_bit; + u8 secondary_host; +} __packed; + #endif /* __TI_SCI_H */ diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index c009a1f92c14..837f4b25171c 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -216,17 +216,94 @@ struct ti_sci_rm_core_ops { u16 *range_start, u16 *range_num); }; +/** + * struct ti_sci_rm_irq_ops: IRQ management operations + * @set_direct_irq: Set Non-event Sourced direct irq to destination + * host(same host as ti sci interface id). + * @set_event_irq: Set Event based peripheral irq to destination + * host(same host as ti sci interface id). + * @set_direct_irq_from_shost: Set Non-event Sourced direct irq to a + * specified destination host. + * @set_event_irq_from_shost: Set Event based peripheral irq to a + * specified destination host. + * @set_event_irq_to_poll: Set Event based peripheral irq to polling mode. + * vint_status_bit is used for polling. + * @free_direct_irq: Free a non-event sourced direct irq to + * destination host(same as ti sci interface id) + * @free_event_irq: Free an event based peripheral irq to + * destination host(same as ti sci interface id) + * @free_direct_irq_from_shost: Free non-event based direct irq from a + * specified destination host. + * @free_event_irq_from_shost: Free event based peripheral irq from a + * specified destination host. + * @free_event_irq_to_poll: Free an event based peripheral irq that is + * configured in polling mode. + * + * NOTE: for these functions, all the parameters are consolidated and defined + * as below: + * - handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle + * - src_id: Device ID of the IRQ source + * - src_index: IRQ source index within the source device + * - dst_id: Device ID of the IRQ destination. + * - dst_host_irq: IRQ number of the destination device. + * - ia_id: Device ID of the IA, if the IRQ flows through this IA + * - vint: Virtual interrupt to be used within the IA + * - global_event: Global event number to be used for the requesting event. + * - vint_status_bit: Virtual interrupt status bit to be used for the event. + * - s_host: Secondary host ID to which the irq/event is being requested. + */ +struct ti_sci_rm_irq_ops { + int (*set_direct_irq)(const struct ti_sci_handle *handle, u16 src_id, + u16 src_index, u16 dst_id, u16 dst_host_irq); + int (*set_event_irq)(const struct ti_sci_handle *handle, u16 src_id, + u16 src_index, u16 dst_id, u16 dst_host_irq, + u16 ia_id, u16 vint, u16 global_event, + u8 vint_status_bit); + int (*set_direct_irq_from_shost)(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, u16 dst_id, + u16 dst_host_irq, u8 s_host); + int (*set_event_irq_from_shost)(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, u16 dst_id, + u16 dst_host_irq, u16 ia_id, u16 vint, + u16 global_event, u8 vint_status_bit, + u8 s_host); + int (*set_event_irq_to_poll)(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, u16 ia_id, + u16 vint, u16 global_event, + u8 vint_status_bit); + int (*free_direct_irq)(const struct ti_sci_handle *handle, u16 src_id, + u16 src_index, u16 dst_id, u16 dst_host_irq); + int (*free_event_irq)(const struct ti_sci_handle *handle, u16 src_id, + u16 src_index, u16 dst_id, u16 dst_host_irq, + u16 ia_id, u16 vint, u16 global_event, + u8 vint_status_bit); + int (*free_direct_irq_from_shost)(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, u16 dst_id, + u16 dst_host_irq, u8 s_host); + int (*free_event_irq_from_shost)(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, u16 dst_id, + u16 dst_host_irq, u16 ia_id, u16 vint, + u16 global_event, u8 vint_status_bit, + u8 s_host); + int (*free_event_irq_to_poll)(const struct ti_sci_handle *handle, + u16 src_id, u16 src_index, u16 ia_id, + u16 vint, u16 global_event, + u8 vint_status_bit); +}; + /** * struct ti_sci_ops - Function support for TI SCI * @dev_ops: Device specific operations * @clk_ops: Clock specific operations * @rm_core_ops: Resource management core operations. + * @rm_irq_ops: IRQ management specific operations */ struct ti_sci_ops { struct ti_sci_core_ops core_ops; struct ti_sci_dev_ops dev_ops; struct ti_sci_clk_ops clk_ops; struct ti_sci_rm_core_ops rm_core_ops; + struct ti_sci_rm_irq_ops rm_irq_ops; }; /** From patchwork Fri Oct 5 14:30:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lokesh Vutla X-Patchwork-Id: 10628237 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 43CEA13BB for ; Fri, 5 Oct 2018 14:33:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 319D4292F3 for ; Fri, 5 Oct 2018 14:33:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 222A92930D; Fri, 5 Oct 2018 14:33:20 +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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.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 7CD54292F3 for ; Fri, 5 Oct 2018 14:33:19 +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: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=hwTtM6ne18b/4MenJuutG7DX3XNGVyzce4ojyrinczo=; b=c4bJwg/SNstpTu 6iFAkRHwrm7u6RCg6BOJGWa6Hxo6cV45zPOc58EjoEEWoD8m1F9sZSoV+14CIAae5g7u7cJYKu2hr 6fZnHGup2ln0vCWZ+V+aEzKRDJyz5rq5T/11Ud/Uh4YpvXr6EIt/HyagO9RImnguTfn30oWD+csbh nxPla4JfECF80ngllYqWKuYeX5lbgPHHhnWTk36ob7uD0f0ByFobdaSlsCnKywBY48GI4xQ3rJF91 lEdaZNVrk7LhuI7kx0G4lxvx4/AGHN5EcWwrnmHFrWmcUX/mrxya3rmZTDSaAMj35ye+lp4IciAI8 +ZdH3dUwLCKjoETT0Jog==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1g8RAJ-0003gA-7d; Fri, 05 Oct 2018 14:33:15 +0000 Received: from lelv0143.ext.ti.com ([198.47.23.248]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1g8R7d-0002Ux-31 for linux-arm-kernel@lists.infradead.org; Fri, 05 Oct 2018 14:30:59 +0000 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id w95EUMAA081233; Fri, 5 Oct 2018 09:30:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1538749822; bh=8+1AUsXlmgUZy34mFv5h3P4LO19oSfNfagH0DAyV0xQ=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=NKVNtk8AnbT43S8TpdoyBx66Mx4oLLE/kkMYKoOcgYB+PffPyjbtnxOMlHTyozrLT MdiNYITfQX5sUm/WpWMt4JqTfMJ4PQeH2/PnxXc0Pk/EpWPLMNZMhqPYNFbUWKLaCq +jMB3dDupxZWDf3WDyLudIrqJp5AHUhjh8KDR13g= Received: from DFLE104.ent.ti.com (dfle104.ent.ti.com [10.64.6.25]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w95EUM6j027273; Fri, 5 Oct 2018 09:30:22 -0500 Received: from DFLE104.ent.ti.com (10.64.6.25) by DFLE104.ent.ti.com (10.64.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1466.3; Fri, 5 Oct 2018 09:30:22 -0500 Received: from dlep32.itg.ti.com (157.170.170.100) by DFLE104.ent.ti.com (10.64.6.25) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1466.3 via Frontend Transport; Fri, 5 Oct 2018 09:30:22 -0500 Received: from uda0131933.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id w95EU9Zn023568; Fri, 5 Oct 2018 09:30:20 -0500 From: Lokesh Vutla To: Nishanth Menon , Tero Kristo , Santosh Shilimkar Subject: [PATCH 4/4] firmware: ti_sci: Add helper apis to mange resources Date: Fri, 5 Oct 2018 20:00:06 +0530 Message-ID: <20181005143006.18284-5-lokeshvutla@ti.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181005143006.18284-1-lokeshvutla@ti.com> References: <20181005143006.18284-1-lokeshvutla@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-20181005_073029_258977_1392937A X-CRM114-Status: GOOD ( 17.60 ) 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: Lokesh Vutla , Sekhar Nori , Linux ARM Mailing List 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 Each resource with in the device can be uniquely identified by a type and subtype as defined by TISCI. Since this is generic across the devices, resource allocation also can be made generic instead of each client driver handling the resource. So add helper apis to manage the resource. devm_ti_sci_get_of_resource() expects resource from dt in form of tuples . Signed-off-by: Lokesh Vutla --- drivers/firmware/ti_sci.c | 126 +++++++++++++++++++++++++ include/linux/soc/ti/ti_sci_protocol.h | 48 ++++++++++ 2 files changed, 174 insertions(+) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 5184ff38804f..53443bd093fb 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -2414,6 +2414,132 @@ const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev, } EXPORT_SYMBOL_GPL(devm_ti_sci_get_by_phandle); +/* + * ti_sci_get_free_resource() - Get a free resource from TISCI resource. + * @res: Pointer to the TISCI resource + * + * Return: resource num if all went ok else TI_SCI_RESOURCE_NULL. + */ +u16 ti_sci_get_free_resource(struct ti_sci_resource *res) +{ + unsigned long flags; + u16 set, free_bit; + + raw_spin_lock_irqsave(&res->lock, flags); + for (set = 0; set < res->sets; set++) { + free_bit = find_first_zero_bit(res->desc[set].res_map, + res->desc[set].num); + if (free_bit != res->desc[set].num) { + set_bit(free_bit, res->desc[set].res_map); + raw_spin_unlock_irqrestore(&res->lock, flags); + return res->desc[set].start + free_bit; + } + } + raw_spin_unlock_irqrestore(&res->lock, flags); + + return TI_SCI_RESOURCE_NULL; +} +EXPORT_SYMBOL_GPL(ti_sci_get_free_resource); + +/** + * ti_sci_release_resource() - Release a resource from TISCI resource. + * @res: Pointer to the TISCI resource + */ +void ti_sci_release_resource(struct ti_sci_resource *res, u16 id) +{ + unsigned long flags; + u16 set; + + raw_spin_lock_irqsave(&res->lock, flags); + for (set = 0; set < res->sets; set++) { + if (res->desc[set].start <= id && + (res->desc[set].num + res->desc[set].start) > id) + clear_bit(id - res->desc[set].start, + res->desc[set].res_map); + } + raw_spin_unlock_irqrestore(&res->lock, flags); +} +EXPORT_SYMBOL_GPL(ti_sci_release_resource); + +/** + * devm_ti_sci_get_of_resource() - Get a TISCI resource assigned to a device + * @handle: TISCI handle + * @dev: Device pointer to which the resource is assigned + * @of_prop: property name by which the resource are represented + * + * Note: This function expects of_prop to be in the form of tuples + * . Allocates and initializes ti_sci_resource structure + * for each of_prop. Client driver can directly call + * ti_sci_(get_free, release)_resource apis for handling the resource. + * + * Return: Pointer to ti_sci_resource if all went well else appropriate + * error pointer. + */ +struct ti_sci_resource * +devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle, + struct device *dev, char *of_prop) +{ + u32 resource_type, resource_subtype; + struct ti_sci_resource *res; + int sets, i, ret; + + res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL); + if (!res) + return ERR_PTR(-ENOMEM); + + sets = of_property_count_elems_of_size(dev_of_node(dev), of_prop, + sizeof(u32)); + if (sets < 0) { + dev_err(dev, "%s resource type ids not available\n", of_prop); + return ERR_PTR(sets); + } + + res->sets = sets / 2; + + res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc), + GFP_KERNEL); + if (!res->desc) + return ERR_PTR(-ENOMEM); + + for (i = 0; i < res->sets; i++) { + ret = of_property_read_u32_index(dev_of_node(dev), of_prop, + i * 2, &resource_type); + if (ret) + return ERR_PTR(-EINVAL); + + ret = of_property_read_u32_index(dev_of_node(dev), of_prop, + (i * 2) + 1, + &resource_subtype); + if (ret) + return ERR_PTR(-EINVAL); + + ret = handle->ops.rm_core_ops.get_range(handle, resource_type, + resource_subtype, + &res->desc[i].start, + &res->desc[i].num); + if (ret) { + dev_err(dev, "type %d subtype %d not allocated for host %d\n", + resource_type, resource_subtype, + handle_to_ti_sci_info(handle)->host_id); + return ERR_PTR(ret); + } + + dev_dbg(dev, "res type = %d, subtype = %d, start = %d, num = %d\n", + resource_type, resource_subtype, res->desc[i].start, + res->desc[i].num); + + res->desc[i].res_map = + devm_kzalloc(dev, BITS_TO_LONGS(res->desc[i].num) * + sizeof(*res->desc[i].res_map), GFP_KERNEL); + if (!res->desc[i].res_map) + return ERR_PTR(-ENOMEM); + } + raw_spin_lock_init(&res->lock); + + return res; +} +EXPORT_SYMBOL_GPL(devm_ti_sci_get_of_resource); + static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode, void *cmd) { diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index 837f4b25171c..ff897900b347 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -316,6 +316,33 @@ struct ti_sci_handle { struct ti_sci_ops ops; }; +#define TI_SCI_RESOURCE_NULL 0xffff + +/** + * struct ti_sci_resource_desc - Description of TI SCI resource instance range. + * @start: Start index of the resource. + * @num: Number of resources. + * @res_map: Bitmap to manage the allocation of these resources. + */ +struct ti_sci_resource_desc { + u16 start; + u16 num; + unsigned long *res_map; +}; + +/** + * struct ti_sci_resource - Structure representing a resource assigned + * to a device. + * @sets: Number of sets available from this resource type + * @lock: Lock to guard the res map in each set. + * @desc: Array of resource descriptors. + */ +struct ti_sci_resource { + u16 sets; + raw_spinlock_t lock; + struct ti_sci_resource_desc *desc; +}; + #if IS_ENABLED(CONFIG_TI_SCI_PROTOCOL) const struct ti_sci_handle *ti_sci_get_handle(struct device *dev); int ti_sci_put_handle(const struct ti_sci_handle *handle); @@ -324,6 +351,11 @@ const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np, const char *property); const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev, const char *property); +u16 ti_sci_get_free_resource(struct ti_sci_resource *res); +void ti_sci_release_resource(struct ti_sci_resource *res, u16 id); +struct ti_sci_resource * +devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle, + struct device *dev, char *of_prop); #else /* CONFIG_TI_SCI_PROTOCOL */ @@ -356,6 +388,22 @@ const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev, { return ERR_PTR(-EINVAL); } + +static inline u16 ti_sci_get_free_resource(struct ti_sci_resource *res) +{ + return TI_SCI_RESOURCE_NULL; +} + +static inline void ti_sci_release_resource(struct ti_sci_resource *res, u16 id) +{ +} + +static inline struct ti_sci_resource * +devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle, + struct device *dev, char *of_prop) +{ + return ERR_PTR(-EINVAL); +} #endif /* CONFIG_TI_SCI_PROTOCOL */ #endif /* __TISCI_PROTOCOL_H */