From nobody Thu Apr 2 20:09:44 2026 Received: from BYAPR05CU005.outbound.protection.outlook.com (mail-westusazon11010014.outbound.protection.outlook.com [52.101.85.14]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4CDE333D6FC; Wed, 18 Feb 2026 09:53:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.85.14 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771408421; cv=fail; b=no/xngEM7U/0oJN+3Ck0vdlm+xAN5K3PkaB8b+7l99HxhAolNQpUucg4BfKPT6TWBqvxzhM2hPIXZ2EkFWrONuA8PVmOjWGAwvm1Ki+mIQanqVVYHl7S3K4zghcK6bQeKrqWETZhRB+ZrSJELJ5km0W7+uqr7n7ytU34Bp2Gsxc= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771408421; c=relaxed/simple; bh=ulQg8zKLcnr1Rx+5Ls04WEcQeqlmARZKq9hIFYz+C+4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=hu1roY9hZxeVSpgPMWAtScBvAAizLjUKhmCqrkCs1n+RzWCDrxleL9yNdq8wstgYwn7fa1FNd+C3LZl2jBQnWff27yEcLv+nHjkRGKYvn/2WGMQILR/gzsiH/spdM3MK7g9JyKUSXwcT9uEyuqpx4Agu59fJ4BW6ZPy/Vf5++mA= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=PhwQH8Wa; arc=fail smtp.client-ip=52.101.85.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="PhwQH8Wa" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=IkhoJdxDjz6y2BhGbKDQcTdh2WkeZJg9mgJ6p5auS7cNq5D2p9BBehVYyWqNBpmUeXegVbg/m6wxT2P/1FPQAUkUVteywC3CMZs0fpxTkBU2Mllu4peALUPBCEkl7vej0dVuSCvVMpXgved8SJu7caBu8Qs1EcfjgIYFHWHsVlz2uUP4JvqfZCTcSgYR9I16Yj4YnvcMqBpfNzN6QP0hAwCSKNv+zrv0tbTHr41HUvRr8ktfoako5V8KkNCWM0w74dWNwt16WDTblALJuD34yFkdymsLVcVlShP/JQyJeEEGqN877n5HRsmeYq+ChmQbWAWDoccNmLiEkvTGOBjYyA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=SIhn/ET+peJ51tOt95GX6r6kIliGQI614WduJl3z2wQ=; b=UycKpcITWzpBYAZi/D02FWalkK5Kdfb+YxgbB04cQY6pjQJKy0ybOUqpzOLtFSgTLx9JIsFiHbmsEi2Oz22jWiuO+BTMgth9PjAucvWmoeKPRZPSTWjNSm/EfuQcEo/N146SYBgI0yWn9owTxEK7eVdhbgTgh06x+OYseUg4uXGb/H1K1UQRbP0CZHwCUVasMDV5RP3V2e29BsRMwVyCRxFypSZDqaM0AgSolA154mFSikD5hG5+q+ExVEznDdA45rUMRh//dS80PpK2/OFx/BVJChXAbjo4WVeuGdP1lJUmlVbHSuuO5yIbzo19GaymL3PjjX19L+/O4TXYTgKy7w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 198.47.21.195) smtp.rcpttodomain=nxp.com smtp.mailfrom=ti.com; dmarc=pass (p=quarantine sp=none pct=100) action=none header.from=ti.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=SIhn/ET+peJ51tOt95GX6r6kIliGQI614WduJl3z2wQ=; b=PhwQH8Waiud8rE211IiQ+yAylGbwZmgqofHhuWwimuYnhc56oW5gCULmv8pcLK2LrAjZ4PU1T1lkEFLDw3KvSU4Ur0Cfvw5acS9dCqhfp7RN0YG+7UeAxKPiiqWWTA2wQ9QDL1qreQ6E6WWghhLedTx14Yqxf3qa/VA8GzdPKck= Received: from MN2PR15CA0056.namprd15.prod.outlook.com (2603:10b6:208:237::25) by CH4PR10MB8170.namprd10.prod.outlook.com (2603:10b6:610:247::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9632.13; Wed, 18 Feb 2026 09:53:37 +0000 Received: from BN2PEPF000055DF.namprd21.prod.outlook.com (2603:10b6:208:237:cafe::5) by MN2PR15CA0056.outlook.office365.com (2603:10b6:208:237::25) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9632.14 via Frontend Transport; Wed, 18 Feb 2026 09:53:34 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 198.47.21.195) smtp.mailfrom=ti.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=ti.com; Received-SPF: Pass (protection.outlook.com: domain of ti.com designates 198.47.21.195 as permitted sender) receiver=protection.outlook.com; client-ip=198.47.21.195; helo=flwvzet201.ext.ti.com; pr=C Received: from flwvzet201.ext.ti.com (198.47.21.195) by BN2PEPF000055DF.mail.protection.outlook.com (10.167.245.9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9654.0 via Frontend Transport; Wed, 18 Feb 2026 09:53:35 +0000 Received: from DFLE215.ent.ti.com (10.64.6.73) by flwvzet201.ext.ti.com (10.248.192.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20; Wed, 18 Feb 2026 03:53:35 -0600 Received: from DFLE202.ent.ti.com (10.64.6.60) by DFLE215.ent.ti.com (10.64.6.73) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20; Wed, 18 Feb 2026 03:53:35 -0600 Received: from lelvem-mr06.itg.ti.com (10.180.75.8) by DFLE202.ent.ti.com (10.64.6.60) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.20 via Frontend Transport; Wed, 18 Feb 2026 03:53:35 -0600 Received: from uda0498651.dhcp.ti.com (uda0498651.dhcp.ti.com [172.24.233.239]) by lelvem-mr06.itg.ti.com (8.18.1/8.18.1) with ESMTP id 61I9qpIF200561; Wed, 18 Feb 2026 03:53:30 -0600 From: Sai Sree Kartheek Adivi To: , , , , , , , , , , , , , CC: , Subject: [PATCH v5 08/18] dmaengine: ti: k3-udma: move resource management functions to k3-udma-common.c Date: Wed, 18 Feb 2026 15:22:33 +0530 Message-ID: <20260218095243.2832115-9-s-adivi@ti.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260218095243.2832115-1-s-adivi@ti.com> References: <20260218095243.2832115-1-s-adivi@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BN2PEPF000055DF:EE_|CH4PR10MB8170:EE_ X-MS-Office365-Filtering-Correlation-Id: 588c0c87-6f25-4a94-a789-08de6ed3959f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|36860700013|82310400026|376014|7416014|921020; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?mRoE27LLad586KYONjHamimJD9TNiYXofsYMursDmAlz8Z6/7MJOj7ej7/5v?= =?us-ascii?Q?LWmF86drnUzMkhdQlOUQfg0Dc3C5rU6fTgxV4hcwGtLKzFfokwUVwsXxXv6p?= =?us-ascii?Q?TGo5s2o2aUbyjElR9lC5FbC+foMNkhey/lUwCMHBzfQHE5y969v4ya2Bv6lt?= =?us-ascii?Q?w7WMDS0SfaUpRl7D0iHOq7mavtYR2rTqChEENVRegX6VIZSssQdUtHOD/DqK?= =?us-ascii?Q?Yw7FsT8Jw/ERBmoI08gD9US3xmrVNlJLWyK22zXZHMkY8EhOxgYcf0W6bxot?= =?us-ascii?Q?uTIHAROHf5wsWEcQZ4Yd1ij2FA6senRdTkA8Dx0arQrkxeJg9iWHkFdq85Kn?= =?us-ascii?Q?AOnbIFJlsR4Br4PX0eJUncCpYmG/OY9aLBk+8JXufC7pyN5hZ25u2VNaTfdj?= =?us-ascii?Q?OIRAfYqM34kEt+lQWkEq21SSK51XwplFHgMs9lO9q+2B7o+hXNJJyAg1wJbv?= =?us-ascii?Q?JB5RV4Ctu7Q/TxGP9PUj9xPZ87Mqg5rw+pzBAskTrjZhZ5ZG0GKFnxWWizl+?= =?us-ascii?Q?vsppE0zs6+FOUBT+frwEzwwz0t+BC+hMGRvS/v4EggCcNL5mJchkiGKM3e9L?= =?us-ascii?Q?vwua1eZlYA06fv8IoN2KGhAWwFlacKJrTpQfLGI5Rmi27cYwdHZsdImiqt31?= =?us-ascii?Q?COnawe6thijds+uyoZL4MSHbGIRKwDk28ob6LEgD3ZYgAKAlHU1bby53zHLP?= =?us-ascii?Q?AEEgo5/mJToWvK9FYqefhdrUpnkvmnqu8OQBB6AL9g7s5sZq3+NxeqM3FTGT?= =?us-ascii?Q?3qTVf75ePgtChwHKBxthS0Z4s1AOGSjvgUz6TWIABegHNl4YFlVdKBVm0xHl?= =?us-ascii?Q?ah7DQah2XcCMzThJnmQqId3jSuVPnglGzheOkJswxgQoEzMU5DXq6FNdtIta?= =?us-ascii?Q?DAPg1wb2vSnhxl+oOr+0ANRMZZxD7UOjWvmVvEvN+N0Lxq7IfwGKvFrGsauk?= =?us-ascii?Q?RIWtraLAFxrE3A2yiQNduF5rAznO5v2MRVd4ma4N97BrFBBmkhJr0Q5QZfJ4?= =?us-ascii?Q?7iabRZRKoahf3b2MNgnrfzUGzSWAUqOBBf5uz8cZfwLGvTMvRA9GFt2ufYPT?= =?us-ascii?Q?smcU3HCjlSJ9tjJXClhvzc6qKK6hlUfD5FGEfcag2W9K0glqP5Q55lK49Xwc?= =?us-ascii?Q?J+j76MFsMYuCFWSXXO/46q9ZtqtBcDrlmzpYP6nd9ZSf46liMsGmuoB0xhp6?= =?us-ascii?Q?lW1LbS/oaQ15Y1DGVXopW6Xur1T2j1P7hMUjE28RnOGWtYGHMvN5FUxVuNJa?= =?us-ascii?Q?U4GAMexU9tMxJFkWUWs6ewfjLXbOmwogx5V4tzDCC9X70ts0kvKFQnlCBYJA?= =?us-ascii?Q?HHHvoIkFFb3zJeHPPy9oGNPS+YwwTPwLWD08yy+4Uqh+0yS8T8WxObN7j4LQ?= =?us-ascii?Q?mx8XNzBnJUoQHN4b0wH1GIRxt9rdw0kpm9Qs/StnoKQl6FABk+m+pqOgntEE?= =?us-ascii?Q?IhpdwYKAH/0DsJu0b6mZ2VjybVMK79qF8LQdvU4Xeh5u2bBOI9Kh9J2S5Ek2?= =?us-ascii?Q?dGMM7iH5tu1hUVTL2n6HVJW2wQAU1uK6Kr/sAL7rOLlO3/Ti0XhnY0vRd8E9?= =?us-ascii?Q?nnSE82sOu+rHpfRcWEF6HaR7r3dxDFDrHr+vIYG7nopZjOi13pNdhZ/kix9m?= =?us-ascii?Q?3R0SbEFlh5h4K69qbgg/xjg93t9bW4Vxu+kSy8s51BKdYjcCuxZvzkaEY2cI?= =?us-ascii?Q?cpC+9Q=3D=3D?= X-Forefront-Antispam-Report: CIP:198.47.21.195;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:flwvzet201.ext.ti.com;PTR:ErrorRetry;CAT:NONE;SFS:(13230040)(1800799024)(36860700013)(82310400026)(376014)(7416014)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: IpztKcgKlvqOIyN94agUGewRBHovynbR3eEJco+s5CCE4sgAogKfSeD6PBJpAifyE8mnoSl8vUIlk5e8nZzTixdGiCVo3cas9g1zLqdfeFaFgmdZfEE6MUxKBJ4Gh3+TC1N0XsgTBDGkuwK3NGM9R/J18Ot+HKt4VRndIALmK256amQ2smoqk9FaIP/uttUT/mQe3odbBHGPBPHVmRBnjQKR8ub33JADfW8QcEph0q2I0LWXTH+Yxj//mrY8KkmFEEW+WGjQM6M0F1Im5dZ7qgqBBPLnDmb+llu0O6ZBVQU2G8G1TcFC6zZfOYot3jXhJBopHD4lmz2YNoDAER+jbwdGEuiChA3ssdWI8k0xPevw3QA+ERRr/hQAlNTVe+msx5njtzzN5hbVVzZlsSLpoELbnOpJYI3M6scDPXKiaThsdZS8kcah5CxARKynj3z8 X-OriginatorOrg: ti.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Feb 2026 09:53:35.9122 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 588c0c87-6f25-4a94-a789-08de6ed3959f X-MS-Exchange-CrossTenant-Id: e5b49634-450b-4709-8abb-1e2b19b982b7 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=e5b49634-450b-4709-8abb-1e2b19b982b7;Ip=[198.47.21.195];Helo=[flwvzet201.ext.ti.com] X-MS-Exchange-CrossTenant-AuthSource: BN2PEPF000055DF.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH4PR10MB8170 Content-Type: text/plain; charset="utf-8" Move functions responsible for allocation and release of udma resources such as channels, rings and flows from k3-udma.c to the common k3-udma-common.c file. The implementation of these functions is largely shared between K3 UDMA and K3 UDMA v2. This refactor improves code reuse and maintainability across multiple variants. No functional changes intended. Signed-off-by: Sai Sree Kartheek Adivi --- drivers/dma/ti/k3-udma-common.c | 442 ++++++++++++++++++++++++++++++++ drivers/dma/ti/k3-udma.c | 423 ------------------------------ drivers/dma/ti/k3-udma.h | 21 ++ 3 files changed, 463 insertions(+), 423 deletions(-) diff --git a/drivers/dma/ti/k3-udma-common.c b/drivers/dma/ti/k3-udma-commo= n.c index 472eedc4663a9..882d27b3c9ee5 100644 --- a/drivers/dma/ti/k3-udma-common.c +++ b/drivers/dma/ti/k3-udma-common.c @@ -1891,5 +1891,447 @@ enum dmaengine_alignment udma_get_copy_align(struct= udma_dev *ud) } EXPORT_SYMBOL_GPL(udma_get_copy_align); =20 +/** + * __udma_alloc_gp_rflow_range - alloc range of GP RX flows + * @ud: UDMA device + * @from: Start the search from this flow id number + * @cnt: Number of consecutive flow ids to allocate + * + * Allocate range of RX flow ids for future use, those flows can be reques= ted + * only using explicit flow id number. if @from is set to -1 it will try t= o find + * first free range. if @from is positive value it will force allocation o= nly + * of the specified range of flows. + * + * Returns -ENOMEM if can't find free range. + * -EEXIST if requested range is busy. + * -EINVAL if wrong input values passed. + * Returns flow id on success. + */ +int __udma_alloc_gp_rflow_range(struct udma_dev *ud, int from, int cnt) +{ + int start, tmp_from; + DECLARE_BITMAP(tmp, K3_UDMA_MAX_RFLOWS); + + tmp_from =3D from; + if (tmp_from < 0) + tmp_from =3D ud->rchan_cnt; + /* default flows can't be allocated and accessible only by id */ + if (tmp_from < ud->rchan_cnt) + return -EINVAL; + + if (tmp_from + cnt > ud->rflow_cnt) + return -EINVAL; + + bitmap_or(tmp, ud->rflow_gp_map, ud->rflow_gp_map_allocated, + ud->rflow_cnt); + + start =3D bitmap_find_next_zero_area(tmp, + ud->rflow_cnt, + tmp_from, cnt, 0); + if (start >=3D ud->rflow_cnt) + return -ENOMEM; + + if (from >=3D 0 && start !=3D from) + return -EEXIST; + + bitmap_set(ud->rflow_gp_map_allocated, start, cnt); + return start; +} +EXPORT_SYMBOL_GPL(__udma_alloc_gp_rflow_range); + +int __udma_free_gp_rflow_range(struct udma_dev *ud, int from, int cnt) +{ + if (from < ud->rchan_cnt) + return -EINVAL; + if (from + cnt > ud->rflow_cnt) + return -EINVAL; + + bitmap_clear(ud->rflow_gp_map_allocated, from, cnt); + return 0; +} +EXPORT_SYMBOL_GPL(__udma_free_gp_rflow_range); + +struct udma_rflow *__udma_get_rflow(struct udma_dev *ud, int id) +{ + /* + * Attempt to request rflow by ID can be made for any rflow + * if not in use with assumption that caller knows what's doing. + * TI-SCI FW will perform additional permission check ant way, it's + * safe + */ + + if (id < 0 || id >=3D ud->rflow_cnt) + return ERR_PTR(-ENOENT); + + if (test_bit(id, ud->rflow_in_use)) + return ERR_PTR(-ENOENT); + + if (ud->rflow_gp_map) { + /* GP rflow has to be allocated first */ + if (!test_bit(id, ud->rflow_gp_map) && + !test_bit(id, ud->rflow_gp_map_allocated)) + return ERR_PTR(-EINVAL); + } + + dev_dbg(ud->dev, "get rflow%d\n", id); + set_bit(id, ud->rflow_in_use); + return &ud->rflows[id]; +} +EXPORT_SYMBOL_GPL(__udma_get_rflow); + +void __udma_put_rflow(struct udma_dev *ud, struct udma_rflow *rflow) +{ + if (!test_bit(rflow->id, ud->rflow_in_use)) { + dev_err(ud->dev, "attempt to put unused rflow%d\n", rflow->id); + return; + } + + dev_dbg(ud->dev, "put rflow%d\n", rflow->id); + clear_bit(rflow->id, ud->rflow_in_use); +} +EXPORT_SYMBOL_GPL(__udma_put_rflow); + +#define UDMA_RESERVE_RESOURCE(res) \ +struct udma_##res *__udma_reserve_##res(struct udma_dev *ud, \ + enum udma_tp_level tpl, \ + int id) \ +{ \ + if (id >=3D 0) { \ + if (test_bit(id, ud->res##_map)) { \ + dev_err(ud->dev, "res##%d is in use\n", id); \ + return ERR_PTR(-ENOENT); \ + } \ + } else { \ + int start; \ + \ + if (tpl >=3D ud->res##_tpl.levels) \ + tpl =3D ud->res##_tpl.levels - 1; \ + \ + start =3D ud->res##_tpl.start_idx[tpl]; \ + \ + id =3D find_next_zero_bit(ud->res##_map, ud->res##_cnt, \ + start); \ + if (id =3D=3D ud->res##_cnt) { \ + return ERR_PTR(-ENOENT); \ + } \ + } \ + \ + set_bit(id, ud->res##_map); \ + return &ud->res##s[id]; \ +} + +UDMA_RESERVE_RESOURCE(bchan); +EXPORT_SYMBOL_GPL(__udma_reserve_bchan); +UDMA_RESERVE_RESOURCE(tchan); +EXPORT_SYMBOL_GPL(__udma_reserve_tchan); +UDMA_RESERVE_RESOURCE(rchan); +EXPORT_SYMBOL_GPL(__udma_reserve_rchan); + +int udma_get_tchan(struct udma_chan *uc) +{ + struct udma_dev *ud =3D uc->ud; + int ret; + + if (uc->tchan) { + dev_dbg(ud->dev, "chan%d: already have tchan%d allocated\n", + uc->id, uc->tchan->id); + return 0; + } + + /* + * mapped_channel_id is -1 for UDMA, BCDMA and PKTDMA unmapped channels. + * For PKTDMA mapped channels it is configured to a channel which must + * be used to service the peripheral. + */ + uc->tchan =3D __udma_reserve_tchan(ud, uc->config.channel_tpl, + uc->config.mapped_channel_id); + if (IS_ERR(uc->tchan)) { + ret =3D PTR_ERR(uc->tchan); + uc->tchan =3D NULL; + return ret; + } + + if (ud->tflow_cnt) { + int tflow_id; + + /* Only PKTDMA have support for tx flows */ + if (uc->config.default_flow_id >=3D 0) + tflow_id =3D uc->config.default_flow_id; + else + tflow_id =3D uc->tchan->id; + + if (test_bit(tflow_id, ud->tflow_map)) { + dev_err(ud->dev, "tflow%d is in use\n", tflow_id); + clear_bit(uc->tchan->id, ud->tchan_map); + uc->tchan =3D NULL; + return -ENOENT; + } + + uc->tchan->tflow_id =3D tflow_id; + set_bit(tflow_id, ud->tflow_map); + } else { + uc->tchan->tflow_id =3D -1; + } + + return 0; +} +EXPORT_SYMBOL_GPL(udma_get_tchan); + +int udma_get_rchan(struct udma_chan *uc) +{ + struct udma_dev *ud =3D uc->ud; + int ret; + + if (uc->rchan) { + dev_dbg(ud->dev, "chan%d: already have rchan%d allocated\n", + uc->id, uc->rchan->id); + return 0; + } + + /* + * mapped_channel_id is -1 for UDMA, BCDMA and PKTDMA unmapped channels. + * For PKTDMA mapped channels it is configured to a channel which must + * be used to service the peripheral. + */ + uc->rchan =3D __udma_reserve_rchan(ud, uc->config.channel_tpl, + uc->config.mapped_channel_id); + if (IS_ERR(uc->rchan)) { + ret =3D PTR_ERR(uc->rchan); + uc->rchan =3D NULL; + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(udma_get_rchan); + +int udma_get_chan_pair(struct udma_chan *uc) +{ + struct udma_dev *ud =3D uc->ud; + int chan_id, end; + + if ((uc->tchan && uc->rchan) && uc->tchan->id =3D=3D uc->rchan->id) { + dev_info(ud->dev, "chan%d: already have %d pair allocated\n", + uc->id, uc->tchan->id); + return 0; + } + + if (uc->tchan) { + dev_err(ud->dev, "chan%d: already have tchan%d allocated\n", + uc->id, uc->tchan->id); + return -EBUSY; + } else if (uc->rchan) { + dev_err(ud->dev, "chan%d: already have rchan%d allocated\n", + uc->id, uc->rchan->id); + return -EBUSY; + } + + /* Can be optimized, but let's have it like this for now */ + end =3D min(ud->tchan_cnt, ud->rchan_cnt); + /* + * Try to use the highest TPL channel pair for MEM_TO_MEM channels + * Note: in UDMAP the channel TPL is symmetric between tchan and rchan + */ + chan_id =3D ud->tchan_tpl.start_idx[ud->tchan_tpl.levels - 1]; + for (; chan_id < end; chan_id++) { + if (!test_bit(chan_id, ud->tchan_map) && + !test_bit(chan_id, ud->rchan_map)) + break; + } + + if (chan_id =3D=3D end) + return -ENOENT; + + set_bit(chan_id, ud->tchan_map); + set_bit(chan_id, ud->rchan_map); + uc->tchan =3D &ud->tchans[chan_id]; + uc->rchan =3D &ud->rchans[chan_id]; + + /* UDMA does not use tx flows */ + uc->tchan->tflow_id =3D -1; + + return 0; +} +EXPORT_SYMBOL_GPL(udma_get_chan_pair); + +int udma_get_rflow(struct udma_chan *uc, int flow_id) +{ + struct udma_dev *ud =3D uc->ud; + int ret; + + if (!uc->rchan) { + dev_err(ud->dev, "chan%d: does not have rchan??\n", uc->id); + return -EINVAL; + } + + if (uc->rflow) { + dev_dbg(ud->dev, "chan%d: already have rflow%d allocated\n", + uc->id, uc->rflow->id); + return 0; + } + + uc->rflow =3D __udma_get_rflow(ud, flow_id); + if (IS_ERR(uc->rflow)) { + ret =3D PTR_ERR(uc->rflow); + uc->rflow =3D NULL; + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(udma_get_rflow); + +void udma_put_rchan(struct udma_chan *uc) +{ + struct udma_dev *ud =3D uc->ud; + + if (uc->rchan) { + dev_dbg(ud->dev, "chan%d: put rchan%d\n", uc->id, + uc->rchan->id); + clear_bit(uc->rchan->id, ud->rchan_map); + uc->rchan =3D NULL; + } +} +EXPORT_SYMBOL_GPL(udma_put_rchan); + +void udma_put_tchan(struct udma_chan *uc) +{ + struct udma_dev *ud =3D uc->ud; + + if (uc->tchan) { + dev_dbg(ud->dev, "chan%d: put tchan%d\n", uc->id, + uc->tchan->id); + clear_bit(uc->tchan->id, ud->tchan_map); + + if (uc->tchan->tflow_id >=3D 0) + clear_bit(uc->tchan->tflow_id, ud->tflow_map); + + uc->tchan =3D NULL; + } +} +EXPORT_SYMBOL_GPL(udma_put_tchan); + +void udma_put_rflow(struct udma_chan *uc) +{ + struct udma_dev *ud =3D uc->ud; + + if (uc->rflow) { + dev_dbg(ud->dev, "chan%d: put rflow%d\n", uc->id, + uc->rflow->id); + __udma_put_rflow(ud, uc->rflow); + uc->rflow =3D NULL; + } +} +EXPORT_SYMBOL_GPL(udma_put_rflow); + +void udma_free_tx_resources(struct udma_chan *uc) +{ + if (!uc->tchan) + return; + + k3_ringacc_ring_free(uc->tchan->t_ring); + k3_ringacc_ring_free(uc->tchan->tc_ring); + uc->tchan->t_ring =3D NULL; + uc->tchan->tc_ring =3D NULL; + + udma_put_tchan(uc); +} +EXPORT_SYMBOL_GPL(udma_free_tx_resources); + +void udma_free_rx_resources(struct udma_chan *uc) +{ + if (!uc->rchan) + return; + + if (uc->rflow) { + struct udma_rflow *rflow =3D uc->rflow; + + k3_ringacc_ring_free(rflow->fd_ring); + k3_ringacc_ring_free(rflow->r_ring); + rflow->fd_ring =3D NULL; + rflow->r_ring =3D NULL; + + udma_put_rflow(uc); + } + + udma_put_rchan(uc); +} +EXPORT_SYMBOL_GPL(udma_free_rx_resources); + +void udma_free_chan_resources(struct dma_chan *chan) +{ + struct udma_chan *uc =3D to_udma_chan(chan); + struct udma_dev *ud =3D to_udma_dev(chan->device); + + udma_terminate_all(chan); + if (uc->terminated_desc) { + ud->reset_chan(uc, false); + udma_reset_rings(uc); + } + + cancel_delayed_work_sync(&uc->tx_drain.work); + + if (uc->irq_num_ring > 0) { + free_irq(uc->irq_num_ring, uc); + + uc->irq_num_ring =3D 0; + } + if (uc->irq_num_udma > 0) { + free_irq(uc->irq_num_udma, uc); + + uc->irq_num_udma =3D 0; + } + + /* Release PSI-L pairing */ + if (uc->psil_paired && ud->psil_unpair) { + ud->psil_unpair(ud, uc->config.src_thread, + uc->config.dst_thread); + uc->psil_paired =3D false; + } + + vchan_free_chan_resources(&uc->vc); + tasklet_kill(&uc->vc.task); + + bcdma_free_bchan_resources(uc); + udma_free_tx_resources(uc); + udma_free_rx_resources(uc); + udma_reset_uchan(uc); + + if (uc->use_dma_pool) { + dma_pool_destroy(uc->hdesc_pool); + uc->use_dma_pool =3D false; + } +} +EXPORT_SYMBOL_GPL(udma_free_chan_resources); + +void bcdma_put_bchan(struct udma_chan *uc) +{ + struct udma_dev *ud =3D uc->ud; + + if (uc->bchan) { + dev_dbg(ud->dev, "chan%d: put bchan%d\n", uc->id, + uc->bchan->id); + clear_bit(uc->bchan->id, ud->bchan_map); + uc->bchan =3D NULL; + uc->tchan =3D NULL; + } +} +EXPORT_SYMBOL_GPL(bcdma_put_bchan); + +void bcdma_free_bchan_resources(struct udma_chan *uc) +{ + if (!uc->bchan) + return; + + k3_ringacc_ring_free(uc->bchan->tc_ring); + k3_ringacc_ring_free(uc->bchan->t_ring); + uc->bchan->tc_ring =3D NULL; + uc->bchan->t_ring =3D NULL; + k3_configure_chan_coherency(&uc->vc.chan, 0); + + bcdma_put_bchan(uc); +} +EXPORT_SYMBOL_GPL(bcdma_free_bchan_resources); + MODULE_DESCRIPTION("Texas Instruments K3 UDMA Common Library"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index e86c811a15eb9..fa9a464f4b953 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -423,135 +423,6 @@ static irqreturn_t udma_udma_irq_handler(int irq, voi= d *data) return IRQ_HANDLED; } =20 -/** - * __udma_alloc_gp_rflow_range - alloc range of GP RX flows - * @ud: UDMA device - * @from: Start the search from this flow id number - * @cnt: Number of consecutive flow ids to allocate - * - * Allocate range of RX flow ids for future use, those flows can be reques= ted - * only using explicit flow id number. if @from is set to -1 it will try t= o find - * first free range. if @from is positive value it will force allocation o= nly - * of the specified range of flows. - * - * Returns -ENOMEM if can't find free range. - * -EEXIST if requested range is busy. - * -EINVAL if wrong input values passed. - * Returns flow id on success. - */ -static int __udma_alloc_gp_rflow_range(struct udma_dev *ud, int from, int = cnt) -{ - int start, tmp_from; - DECLARE_BITMAP(tmp, K3_UDMA_MAX_RFLOWS); - - tmp_from =3D from; - if (tmp_from < 0) - tmp_from =3D ud->rchan_cnt; - /* default flows can't be allocated and accessible only by id */ - if (tmp_from < ud->rchan_cnt) - return -EINVAL; - - if (tmp_from + cnt > ud->rflow_cnt) - return -EINVAL; - - bitmap_or(tmp, ud->rflow_gp_map, ud->rflow_gp_map_allocated, - ud->rflow_cnt); - - start =3D bitmap_find_next_zero_area(tmp, - ud->rflow_cnt, - tmp_from, cnt, 0); - if (start >=3D ud->rflow_cnt) - return -ENOMEM; - - if (from >=3D 0 && start !=3D from) - return -EEXIST; - - bitmap_set(ud->rflow_gp_map_allocated, start, cnt); - return start; -} - -static int __udma_free_gp_rflow_range(struct udma_dev *ud, int from, int c= nt) -{ - if (from < ud->rchan_cnt) - return -EINVAL; - if (from + cnt > ud->rflow_cnt) - return -EINVAL; - - bitmap_clear(ud->rflow_gp_map_allocated, from, cnt); - return 0; -} - -static struct udma_rflow *__udma_get_rflow(struct udma_dev *ud, int id) -{ - /* - * Attempt to request rflow by ID can be made for any rflow - * if not in use with assumption that caller knows what's doing. - * TI-SCI FW will perform additional permission check ant way, it's - * safe - */ - - if (id < 0 || id >=3D ud->rflow_cnt) - return ERR_PTR(-ENOENT); - - if (test_bit(id, ud->rflow_in_use)) - return ERR_PTR(-ENOENT); - - if (ud->rflow_gp_map) { - /* GP rflow has to be allocated first */ - if (!test_bit(id, ud->rflow_gp_map) && - !test_bit(id, ud->rflow_gp_map_allocated)) - return ERR_PTR(-EINVAL); - } - - dev_dbg(ud->dev, "get rflow%d\n", id); - set_bit(id, ud->rflow_in_use); - return &ud->rflows[id]; -} - -static void __udma_put_rflow(struct udma_dev *ud, struct udma_rflow *rflow) -{ - if (!test_bit(rflow->id, ud->rflow_in_use)) { - dev_err(ud->dev, "attempt to put unused rflow%d\n", rflow->id); - return; - } - - dev_dbg(ud->dev, "put rflow%d\n", rflow->id); - clear_bit(rflow->id, ud->rflow_in_use); -} - -#define UDMA_RESERVE_RESOURCE(res) \ -static struct udma_##res *__udma_reserve_##res(struct udma_dev *ud, \ - enum udma_tp_level tpl, \ - int id) \ -{ \ - if (id >=3D 0) { \ - if (test_bit(id, ud->res##_map)) { \ - dev_err(ud->dev, "res##%d is in use\n", id); \ - return ERR_PTR(-ENOENT); \ - } \ - } else { \ - int start; \ - \ - if (tpl >=3D ud->res##_tpl.levels) \ - tpl =3D ud->res##_tpl.levels - 1; \ - \ - start =3D ud->res##_tpl.start_idx[tpl]; \ - \ - id =3D find_next_zero_bit(ud->res##_map, ud->res##_cnt, \ - start); \ - if (id =3D=3D ud->res##_cnt) { \ - return ERR_PTR(-ENOENT); \ - } \ - } \ - \ - set_bit(id, ud->res##_map); \ - return &ud->res##s[id]; \ -} - -UDMA_RESERVE_RESOURCE(bchan); -UDMA_RESERVE_RESOURCE(tchan); -UDMA_RESERVE_RESOURCE(rchan); - static int bcdma_get_bchan(struct udma_chan *uc) { struct udma_dev *ud =3D uc->ud; @@ -585,223 +456,6 @@ static int bcdma_get_bchan(struct udma_chan *uc) return 0; } =20 -static int udma_get_tchan(struct udma_chan *uc) -{ - struct udma_dev *ud =3D uc->ud; - int ret; - - if (uc->tchan) { - dev_dbg(ud->dev, "chan%d: already have tchan%d allocated\n", - uc->id, uc->tchan->id); - return 0; - } - - /* - * mapped_channel_id is -1 for UDMA, BCDMA and PKTDMA unmapped channels. - * For PKTDMA mapped channels it is configured to a channel which must - * be used to service the peripheral. - */ - uc->tchan =3D __udma_reserve_tchan(ud, uc->config.channel_tpl, - uc->config.mapped_channel_id); - if (IS_ERR(uc->tchan)) { - ret =3D PTR_ERR(uc->tchan); - uc->tchan =3D NULL; - return ret; - } - - if (ud->tflow_cnt) { - int tflow_id; - - /* Only PKTDMA have support for tx flows */ - if (uc->config.default_flow_id >=3D 0) - tflow_id =3D uc->config.default_flow_id; - else - tflow_id =3D uc->tchan->id; - - if (test_bit(tflow_id, ud->tflow_map)) { - dev_err(ud->dev, "tflow%d is in use\n", tflow_id); - clear_bit(uc->tchan->id, ud->tchan_map); - uc->tchan =3D NULL; - return -ENOENT; - } - - uc->tchan->tflow_id =3D tflow_id; - set_bit(tflow_id, ud->tflow_map); - } else { - uc->tchan->tflow_id =3D -1; - } - - return 0; -} - -static int udma_get_rchan(struct udma_chan *uc) -{ - struct udma_dev *ud =3D uc->ud; - int ret; - - if (uc->rchan) { - dev_dbg(ud->dev, "chan%d: already have rchan%d allocated\n", - uc->id, uc->rchan->id); - return 0; - } - - /* - * mapped_channel_id is -1 for UDMA, BCDMA and PKTDMA unmapped channels. - * For PKTDMA mapped channels it is configured to a channel which must - * be used to service the peripheral. - */ - uc->rchan =3D __udma_reserve_rchan(ud, uc->config.channel_tpl, - uc->config.mapped_channel_id); - if (IS_ERR(uc->rchan)) { - ret =3D PTR_ERR(uc->rchan); - uc->rchan =3D NULL; - return ret; - } - - return 0; -} - -static int udma_get_chan_pair(struct udma_chan *uc) -{ - struct udma_dev *ud =3D uc->ud; - int chan_id, end; - - if ((uc->tchan && uc->rchan) && uc->tchan->id =3D=3D uc->rchan->id) { - dev_info(ud->dev, "chan%d: already have %d pair allocated\n", - uc->id, uc->tchan->id); - return 0; - } - - if (uc->tchan) { - dev_err(ud->dev, "chan%d: already have tchan%d allocated\n", - uc->id, uc->tchan->id); - return -EBUSY; - } else if (uc->rchan) { - dev_err(ud->dev, "chan%d: already have rchan%d allocated\n", - uc->id, uc->rchan->id); - return -EBUSY; - } - - /* Can be optimized, but let's have it like this for now */ - end =3D min(ud->tchan_cnt, ud->rchan_cnt); - /* - * Try to use the highest TPL channel pair for MEM_TO_MEM channels - * Note: in UDMAP the channel TPL is symmetric between tchan and rchan - */ - chan_id =3D ud->tchan_tpl.start_idx[ud->tchan_tpl.levels - 1]; - for (; chan_id < end; chan_id++) { - if (!test_bit(chan_id, ud->tchan_map) && - !test_bit(chan_id, ud->rchan_map)) - break; - } - - if (chan_id =3D=3D end) - return -ENOENT; - - set_bit(chan_id, ud->tchan_map); - set_bit(chan_id, ud->rchan_map); - uc->tchan =3D &ud->tchans[chan_id]; - uc->rchan =3D &ud->rchans[chan_id]; - - /* UDMA does not use tx flows */ - uc->tchan->tflow_id =3D -1; - - return 0; -} - -static int udma_get_rflow(struct udma_chan *uc, int flow_id) -{ - struct udma_dev *ud =3D uc->ud; - int ret; - - if (!uc->rchan) { - dev_err(ud->dev, "chan%d: does not have rchan??\n", uc->id); - return -EINVAL; - } - - if (uc->rflow) { - dev_dbg(ud->dev, "chan%d: already have rflow%d allocated\n", - uc->id, uc->rflow->id); - return 0; - } - - uc->rflow =3D __udma_get_rflow(ud, flow_id); - if (IS_ERR(uc->rflow)) { - ret =3D PTR_ERR(uc->rflow); - uc->rflow =3D NULL; - return ret; - } - - return 0; -} - -static void bcdma_put_bchan(struct udma_chan *uc) -{ - struct udma_dev *ud =3D uc->ud; - - if (uc->bchan) { - dev_dbg(ud->dev, "chan%d: put bchan%d\n", uc->id, - uc->bchan->id); - clear_bit(uc->bchan->id, ud->bchan_map); - uc->bchan =3D NULL; - uc->tchan =3D NULL; - } -} - -static void udma_put_rchan(struct udma_chan *uc) -{ - struct udma_dev *ud =3D uc->ud; - - if (uc->rchan) { - dev_dbg(ud->dev, "chan%d: put rchan%d\n", uc->id, - uc->rchan->id); - clear_bit(uc->rchan->id, ud->rchan_map); - uc->rchan =3D NULL; - } -} - -static void udma_put_tchan(struct udma_chan *uc) -{ - struct udma_dev *ud =3D uc->ud; - - if (uc->tchan) { - dev_dbg(ud->dev, "chan%d: put tchan%d\n", uc->id, - uc->tchan->id); - clear_bit(uc->tchan->id, ud->tchan_map); - - if (uc->tchan->tflow_id >=3D 0) - clear_bit(uc->tchan->tflow_id, ud->tflow_map); - - uc->tchan =3D NULL; - } -} - -static void udma_put_rflow(struct udma_chan *uc) -{ - struct udma_dev *ud =3D uc->ud; - - if (uc->rflow) { - dev_dbg(ud->dev, "chan%d: put rflow%d\n", uc->id, - uc->rflow->id); - __udma_put_rflow(ud, uc->rflow); - uc->rflow =3D NULL; - } -} - -static void bcdma_free_bchan_resources(struct udma_chan *uc) -{ - if (!uc->bchan) - return; - - k3_ringacc_ring_free(uc->bchan->tc_ring); - k3_ringacc_ring_free(uc->bchan->t_ring); - uc->bchan->tc_ring =3D NULL; - uc->bchan->t_ring =3D NULL; - k3_configure_chan_coherency(&uc->vc.chan, 0); - - bcdma_put_bchan(uc); -} - static int bcdma_alloc_bchan_resources(struct udma_chan *uc) { struct k3_ring_cfg ring_cfg; @@ -847,19 +501,6 @@ static int bcdma_alloc_bchan_resources(struct udma_cha= n *uc) return ret; } =20 -static void udma_free_tx_resources(struct udma_chan *uc) -{ - if (!uc->tchan) - return; - - k3_ringacc_ring_free(uc->tchan->t_ring); - k3_ringacc_ring_free(uc->tchan->tc_ring); - uc->tchan->t_ring =3D NULL; - uc->tchan->tc_ring =3D NULL; - - udma_put_tchan(uc); -} - static int udma_alloc_tx_resources(struct udma_chan *uc) { struct k3_ring_cfg ring_cfg; @@ -917,25 +558,6 @@ static int udma_alloc_tx_resources(struct udma_chan *u= c) return ret; } =20 -static void udma_free_rx_resources(struct udma_chan *uc) -{ - if (!uc->rchan) - return; - - if (uc->rflow) { - struct udma_rflow *rflow =3D uc->rflow; - - k3_ringacc_ring_free(rflow->fd_ring); - k3_ringacc_ring_free(rflow->r_ring); - rflow->fd_ring =3D NULL; - rflow->r_ring =3D NULL; - - udma_put_rflow(uc); - } - - udma_put_rchan(uc); -} - static int udma_alloc_rx_resources(struct udma_chan *uc) { struct udma_dev *ud =3D uc->ud; @@ -2024,51 +1646,6 @@ static int udma_resume(struct dma_chan *chan) return 0; } =20 -static void udma_free_chan_resources(struct dma_chan *chan) -{ - struct udma_chan *uc =3D to_udma_chan(chan); - struct udma_dev *ud =3D to_udma_dev(chan->device); - - udma_terminate_all(chan); - if (uc->terminated_desc) { - ud->reset_chan(uc, false); - udma_reset_rings(uc); - } - - cancel_delayed_work_sync(&uc->tx_drain.work); - - if (uc->irq_num_ring > 0) { - free_irq(uc->irq_num_ring, uc); - - uc->irq_num_ring =3D 0; - } - if (uc->irq_num_udma > 0) { - free_irq(uc->irq_num_udma, uc); - - uc->irq_num_udma =3D 0; - } - - /* Release PSI-L pairing */ - if (uc->psil_paired) { - navss_psil_unpair(ud, uc->config.src_thread, - uc->config.dst_thread); - uc->psil_paired =3D false; - } - - vchan_free_chan_resources(&uc->vc); - tasklet_kill(&uc->vc.task); - - bcdma_free_bchan_resources(uc); - udma_free_tx_resources(uc); - udma_free_rx_resources(uc); - udma_reset_uchan(uc); - - if (uc->use_dma_pool) { - dma_pool_destroy(uc->hdesc_pool); - uc->use_dma_pool =3D false; - } -} - static struct platform_driver udma_driver; static struct platform_driver bcdma_driver; static struct platform_driver pktdma_driver; diff --git a/drivers/dma/ti/k3-udma.h b/drivers/dma/ti/k3-udma.h index 797e8b0c5b85e..e4b512d9ffb2e 100644 --- a/drivers/dma/ti/k3-udma.h +++ b/drivers/dma/ti/k3-udma.h @@ -654,6 +654,27 @@ void udma_dbg_summary_show(struct seq_file *s, struct dma_device *dma_dev); #endif /* CONFIG_DEBUG_FS */ =20 +int __udma_alloc_gp_rflow_range(struct udma_dev *ud, int from, int cnt); +int __udma_free_gp_rflow_range(struct udma_dev *ud, int from, int cnt); +struct udma_rflow *__udma_get_rflow(struct udma_dev *ud, int id); +void __udma_put_rflow(struct udma_dev *ud, struct udma_rflow *rflow); +int udma_get_tchan(struct udma_chan *uc); +int udma_get_rchan(struct udma_chan *uc); +int udma_get_chan_pair(struct udma_chan *uc); +int udma_get_rflow(struct udma_chan *uc, int flow_id); +void udma_put_rchan(struct udma_chan *uc); +void udma_put_tchan(struct udma_chan *uc); +void udma_put_rflow(struct udma_chan *uc); +void udma_free_tx_resources(struct udma_chan *uc); +void udma_free_rx_resources(struct udma_chan *uc); +void udma_free_chan_resources(struct dma_chan *chan); +void bcdma_put_bchan(struct udma_chan *uc); +void bcdma_free_bchan_resources(struct udma_chan *uc); + +struct udma_bchan *__udma_reserve_bchan(struct udma_dev *ud, enum udma_tp_= level tpl, int id); +struct udma_tchan *__udma_reserve_tchan(struct udma_dev *ud, enum udma_tp_= level tpl, int id); +struct udma_rchan *__udma_reserve_rchan(struct udma_dev *ud, enum udma_tp_= level tpl, int id); + /* Direct access to UDMA low lever resources for the glue layer */ int xudma_navss_psil_pair(struct udma_dev *ud, u32 src_thread, u32 dst_thr= ead); int xudma_navss_psil_unpair(struct udma_dev *ud, u32 src_thread, --=20 2.34.1