From nobody Thu Apr 9 17:58:39 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 71AB042848C for ; Fri, 6 Mar 2026 17:23:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772817818; cv=none; b=o+Jqk7kh3gQCwrOx7ZhCCvSw8hvT1yZIdztPBGCgDScZWojKso9luhsJmSQKozM6p9mQAUgr5JD9w6WXWigFOBiDcgBI9qXKipf7ldfOtf91WnNqXesu2rxEfPDZ1mDA9ZjqsTdnttAGMKJPXGOiAWNzAe7S9qwiDdyPSEIvQP8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772817818; c=relaxed/simple; bh=6FY6/NpoOq7Rdpg5gYZySEQvwKsaI6/Ar0wZmyeBw3Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=H5QUJIMWC8eOtzKX5CniMoUVu6v5tqTe3z/k/pT/A7GxKnmMimrx133uxYVEEZJqAyZfFgHOsph7eNEn/6lyz/7KH62gySEchtvwVdi8JwKcIFu5jjXhnKwM6ldZttdCWaibThD9d8YAEf4UpBLlPNdBrWjvtVJ64nI4PKzjbF0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=DhYJIfcx; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=j9NjZmTd; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="DhYJIfcx"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="j9NjZmTd" Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 626H1q7Z1898370 for ; Fri, 6 Mar 2026 17:23:36 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= gnCHGaTyIrO+/XHi40pHajxkTWJ3etB/P/3gSFJpnBk=; b=DhYJIfcxVOzcWuWg RwxVm+VBl2KvsbtLt9VbqP2xsb2bjYPbgNgkRSVffQb7q3emlUC4vBkltMSinphm AcXbMxW9eoVeUOlysHCoT9x7yANaajDiupCY/WidBp9iCVAhV1c360d382FwzeDQ J7JQzAps7WleZu59ePjHWqoeZ6gid3AgWc09+YyXuaymd3Kzy7hm2l+KTqPsHAVf /7yTBjTHwDe4BcsCrUGHmNu9vZxESQrbY6OFsLUoDDFjlfvxaCil5tAoB7MYQ1Zd fZGnxzVY1dp8fyRlyiOVHuzefrgtCU+r9IDLYrP5uP2CmUI7gmJZrZX7MlljdWqk 4JEpkA== Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4cqx14h5eg-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 06 Mar 2026 17:23:35 +0000 (GMT) Received: by mail-qk1-f200.google.com with SMTP id af79cd13be357-8c70ef98116so6168037485a.1 for ; Fri, 06 Mar 2026 09:23:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1772817815; x=1773422615; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=gnCHGaTyIrO+/XHi40pHajxkTWJ3etB/P/3gSFJpnBk=; b=j9NjZmTdOwNQPXfDNiMJhuHZhmQZiyjP7Qh/lypiGnDnhQezv9yk6jini784gXqyhE tdZ3QXEgi6wXwLeCVdRyiz98OF4M59dERSrktZ0xlmYvtuc0YJsl9W7VoePT0Um4tlH3 rmNNDa40S0YVsNjaeZb0+qgaeUidsk3fggwnAkX2fgLqahMfKG/sDkhxvDyZVStPJSN1 Z0H+Sf/XvaY6iop8aM/ZXaUdImAUSwQ1QPY16UyxBbCUSxXLGlGGbYoB7GMs7HoiUli/ AIp22iM1VpVAJJ45eC0xjASriJgEn3nSObc6f5qafz00zx8tNO8CKUjNOH5vIX2xOaAw HjcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772817815; x=1773422615; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=gnCHGaTyIrO+/XHi40pHajxkTWJ3etB/P/3gSFJpnBk=; b=LhWqwvsHQdhzm3qCc4FR53U23YAIeYKEC0NOyof6fqojsJjqFuXBS8xHgK4YtSkRZR FVwvFyo7w+IO9BNpdX1x4aCli+rpBHbtqvzRkVlCuNDVT7UwNCxtPU2geKd8FVdfQRwf g9pXkFLvPMc6GNclkeNcZxZqCvPkrV6fjZcv1So5/zTpS0cyrtX1HGHEmACw4a6A+/LS 4/Zka0OCGfTD7vARBHi4Y/bWITBRIgGyg2qAFguNwPABjWYnu0cO17yhwwMy0GYclg4A 1wvAKf/6ggnXf0z+fSvOkTQBjHxWY4rz8CRaXJ6+PZDfetb+yUhrtzV+qcMsp1caRvW/ sNag== X-Gm-Message-State: AOJu0YyHhW1y5Csehbcxv+qx1G3Dde7AT6tpIHXMgxC4XXT69qlHDhp5 eZ758DH2NHqZjAF2ofqtCR2/p5ZRi/9P10cecA3BBVgzKZgCFbi28mE8/73rBYxwbF4O1IiO75k asknyWHwAmmcvHWsihExy8ONvUdyY58Jqy+jVXjFD0Q/aSl8oOA8Hzazo07zC2NKhYQ0= X-Gm-Gg: ATEYQzxG0bZ8ffSfdIF8lgVm17SFdGukKR/3An6QhccPeX20OaOhCtTXse+lkdl6lVj wl8+oov5yP/cZFHTsiYNamvAhsUgsp/ifFq7KT4knRmtuLibMiST1JwavmqI/i81egy7hLdvzEt ODod1AmVacxrmL5s8CUfcgrqq+nxTQm8xEdFyHYQ6BoNF7m10kSexUFk7YXbv8WQJSS2XOCMbWg TjPEsTObIqZYDdN4wLa/cu2+qhJAIpdXvjv2fRKvlRUq5nJHElw5rx9NVDZU1HawFnArB0q+1c2 X+hKypk6q6ytxYnpPnN02KZDxUUuw20uV7WoPKX10F0x7pr8IRUS/mvuOhtUE+z89T88CMutrw5 Dgw3D25H//kfLw+pmic8PzvztauhaBl9gs4FjikU+N5daa+KJSpUe X-Received: by 2002:a05:620a:1925:b0:8c0:cbd8:20b0 with SMTP id af79cd13be357-8cd6d468037mr344777585a.34.1772817814525; Fri, 06 Mar 2026 09:23:34 -0800 (PST) X-Received: by 2002:a05:620a:1925:b0:8c0:cbd8:20b0 with SMTP id af79cd13be357-8cd6d468037mr344772385a.34.1772817813888; Fri, 06 Mar 2026 09:23:33 -0800 (PST) Received: from brgl-qcom.local ([2a01:cb1d:dc:7e00:28b1:4950:7702:bb20]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48527686fa9sm61488475e9.8.2026.03.06.09.23.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 Mar 2026 09:23:33 -0800 (PST) From: Bartosz Golaszewski Date: Fri, 06 Mar 2026 18:22:57 +0100 Subject: [PATCH v3 13/14] reset: convert reset core to using firmware nodes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260306-reset-core-refactor-v3-13-599349522876@oss.qualcomm.com> References: <20260306-reset-core-refactor-v3-0-599349522876@oss.qualcomm.com> In-Reply-To: <20260306-reset-core-refactor-v3-0-599349522876@oss.qualcomm.com> To: Krzysztof Kozlowski , Philipp Zabel , Jonathan Corbet , Shuah Khan Cc: linux-kernel@vger.kernel.org, brgl@kernel.org, linux-doc@vger.kernel.org, Bartosz Golaszewski X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=15703; i=bartosz.golaszewski@oss.qualcomm.com; h=from:subject:message-id; bh=6FY6/NpoOq7Rdpg5gYZySEQvwKsaI6/Ar0wZmyeBw3Q=; b=owEBbQKS/ZANAwAKAQWdLsv/NoTDAcsmYgBpqw19/45UfXqlpcldxprhPodcq9u5EhnP2HgEQ Nv7cMKFn9+JAjMEAAEKAB0WIQSR5RMt5bVGHXuiZfwFnS7L/zaEwwUCaasNfQAKCRAFnS7L/zaE ww5hD/95X1Pdm2D5Xd/3RdQPg0LQ5DXT128KonLWkljxQxPVGoSSG+602nZjuUgk4YJuxTwYMmP Be6a0i8qqeyVg7Z3EmM52doVPL2drkszQNzte0ydveE3z7S3EmlAIVBKTRml62ZVJyfKbSBBIrj y7GgL/1xpNyPgXPEBpoDAi3xOEzuiHqAitqNQZQ4lc9FdquRaBdGgxiLm8rxGRE+HN40PXrRQJw 8nifk3P6PmWNTUczXBImX3bsXmIyAoYfGESoyOC/BPgTIEkgHIPuRiJBF+4VtebBCWvjwnoeBP9 9NwDoYySsFbPbOKbmQKFeQ/HFegFvSCuDpsJiQGm//MAA/sKFVx6t8QffkvXSVO861zXHf7XFGy Vx3EpC1csSRBZSA6Ak8i9q1Wq+NpaCO2wJwyIPwpDk0amx5TQpnby6dVTigVnpA4uvGep2G4myC 76VBWyIDC5Em9GRi1BcYlqfhxSG/VS8p0WYWPDaHzl0/8QGC3HOrmuQfWQUzNkc1C5ZWkbXkzsQ Qicus+4bLSwOLBv93EJ/3y/sYC3El7DPFDAO8cw36PS03cz90HrBHnPVdr1FiFLL2+2S6Ccmhk2 j81ZrpaQapaYxhtnuAfgeF7+mhIz3+oYrUPoo21ibzwyjagSsNOaxTIwJERbpPavn0Wtm/Ijk05 UZSRgdede4TGOhQ== X-Developer-Key: i=bartosz.golaszewski@oss.qualcomm.com; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMzA2MDE2NCBTYWx0ZWRfX8Ggc3I70/XiQ MOjM/QEzYjeOIX7LtH3N7K7qzA9xJaCuc5uAM3QFeWuTSVu33GUe2VxcHHVH+jpNvc71quxpHaX tL5sCOcFN2RXmh0wd/9qGz/to1gD+ZZdGOtpeJ4bkqz2Z73LdFytimK5ktAUMiHu9bJMY4bb+1q vc8OKztP8OVVJK+1Wzqnxicx9nA8jmePLTwJhoGml6g+wH2uUNjB3aeTPeIUpgLjW+zm6ApXy0X +jVuomXt5h1kWOZ/OqJzMAdKEKA6GNadoLmKeYWQr2RswXhlcxt3Tht8Xwc/mKsYvYSE5Mgbnr4 qG7ZNT2lG+U61dlnmY/3k7Z5SacTnvbJLTIZbdWniox/ibAIXm+ktUtrEBGTnWA0q4Q+BtDkmLB P/fscY7DffQvg0IIXgqgKr+BYUfsOkhiZzhsmECwhACJLhmANMhOb3C4MxZ+GDMnkouunzKWo0N fnRPuIhdtHOsXv48UqQ== X-Proofpoint-GUID: wE9AR93btmMzjDD8U3Sr7RDEQFgzUqK0 X-Proofpoint-ORIG-GUID: wE9AR93btmMzjDD8U3Sr7RDEQFgzUqK0 X-Authority-Analysis: v=2.4 cv=e/MLiKp/ c=1 sm=1 tr=0 ts=69ab0d97 cx=c_pps a=hnmNkyzTK/kJ09Xio7VxxA==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=Yq5XynenixoA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=DJpcGTmdVt4CTyJn9g5Z:22 a=EUspDBNiAAAA:8 a=KnmVVp5zvkuUHY8ZiwgA:9 a=QEXdDO2ut3YA:10 a=PEH46H7Ffwr30OY-TuGO:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-03-06_05,2026-03-06_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 bulkscore=0 adultscore=0 clxscore=1015 spamscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0 suspectscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2602130000 definitions=main-2603060164 With everything else now in place, we can convert the remaining parts of the reset subsystem to becoming fwnode-agnostic - meaning it will work with all kinds of firmware nodes, not only devicetree. To that end: extend struct reset_controller_dev with fields taking information relevant for using firmware nodes (which mirrors what we already do for OF-nodes) and limit using of_ APIs only to where it's absolutely necessary (mostly around the of_xlate callback). For backward compatibility of existing drivers we still support OF-nodes but firmware nodes become the preferred method. Signed-off-by: Bartosz Golaszewski Reviewed-by: Philipp Zabel --- drivers/reset/core.c | 166 +++++++++++++++++++++++------------= ---- include/linux/reset-controller.h | 14 +++- 2 files changed, 112 insertions(+), 68 deletions(-) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 0817afe72de75f795d62e02451520726da7c9844..e33a9bc9f94fc6867be6efd3217= 8658d99fc088f 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -81,13 +81,13 @@ struct reset_control_array { =20 /** * struct reset_gpio_lookup - lookup key for ad-hoc created reset-gpio dev= ices - * @of_args: phandle to the reset controller with all the args like GPIO n= umber + * @ref_args: Reference to the reset controller with all the args like GPI= O number * @swnode: Software node containing the reference to the GPIO provider * @list: list entry for the reset_gpio_lookup_list * @adev: Auxiliary device representing the reset controller */ struct reset_gpio_lookup { - struct of_phandle_args of_args; + struct fwnode_reference_args ref_args; struct fwnode_handle *swnode; struct list_head list; struct auxiliary_device adev; @@ -98,24 +98,24 @@ static const char *rcdev_name(struct reset_controller_d= ev *rcdev) if (rcdev->dev) return dev_name(rcdev->dev); =20 - if (rcdev->of_node) - return rcdev->of_node->full_name; + if (rcdev->fwnode) + return fwnode_get_name(rcdev->fwnode); =20 return NULL; } =20 /** - * of_reset_simple_xlate - translate reset_spec to the reset line number + * fwnode_reset_simple_xlate - translate reset_spec to the reset line numb= er * @rcdev: a pointer to the reset controller device - * @reset_spec: reset line specifier as found in the device tree + * @reset_spec: reset line specifier as found in firmware * - * This static translation function is used by default if of_xlate in - * :c:type:`reset_controller_dev` is not set. It is useful for all reset - * controllers with 1:1 mapping, where reset lines can be indexed by number - * without gaps. + * This static translation function is used by default if neither fwnode_x= late + * not of_xlate in :c:type:`reset_controller_dev` is not set. It is useful= for + * all reset controllers with 1:1 mapping, where reset lines can be indexe= d by + * number without gaps. */ -static int of_reset_simple_xlate(struct reset_controller_dev *rcdev, - const struct of_phandle_args *reset_spec) +static int fwnode_reset_simple_xlate(struct reset_controller_dev *rcdev, + const struct fwnode_reference_args *reset_spec) { if (reset_spec->args[0] >=3D rcdev->nr_resets) return -EINVAL; @@ -129,9 +129,23 @@ static int of_reset_simple_xlate(struct reset_controll= er_dev *rcdev, */ int reset_controller_register(struct reset_controller_dev *rcdev) { - if (!rcdev->of_xlate) { - rcdev->of_reset_n_cells =3D 1; - rcdev->of_xlate =3D of_reset_simple_xlate; + if ((rcdev->of_node && rcdev->fwnode) || (rcdev->of_xlate && rcdev->fwnod= e_xlate)) + return -EINVAL; + + if (!rcdev->of_node && !rcdev->fwnode) { + rcdev->fwnode =3D dev_fwnode(rcdev->dev); + if (!rcdev->fwnode) + return -EINVAL; + } + + if (rcdev->of_node) { + rcdev->fwnode =3D of_fwnode_handle(rcdev->of_node); + rcdev->fwnode_reset_n_cells =3D rcdev->of_reset_n_cells; + } + + if (rcdev->fwnode && !rcdev->fwnode_xlate) { + rcdev->fwnode_reset_n_cells =3D 1; + rcdev->fwnode_xlate =3D fwnode_reset_simple_xlate; } =20 INIT_LIST_HEAD(&rcdev->reset_control_head); @@ -931,7 +945,7 @@ static int reset_create_gpio_aux_device(struct reset_gp= io_lookup *rgpio_dev, adev->id =3D id; adev->name =3D "gpio"; adev->dev.parent =3D parent; - adev->dev.platform_data =3D &rgpio_dev->of_args; + adev->dev.platform_data =3D &rgpio_dev->ref_args; adev->dev.release =3D reset_gpio_aux_device_release; device_set_node(&adev->dev, rgpio_dev->swnode); =20 @@ -951,18 +965,18 @@ static int reset_create_gpio_aux_device(struct reset_= gpio_lookup *rgpio_dev, return 0; } =20 -static void reset_gpio_add_devlink(struct device_node *np, +static void reset_gpio_add_devlink(struct fwnode_handle *fwnode, struct reset_gpio_lookup *rgpio_dev) { struct device *consumer; =20 /* - * We must use get_dev_from_fwnode() and not of_find_device_by_node() + * We must use get_dev_from_fwnode() and not ref_find_device_by_node() * because the latter only considers the platform bus while we want to * get consumers of any kind that can be associated with firmware * nodes: auxiliary, soundwire, etc. */ - consumer =3D get_dev_from_fwnode(of_fwnode_handle(np)); + consumer =3D get_dev_from_fwnode(fwnode); if (consumer) { if (!device_link_add(consumer, &rgpio_dev->adev.dev, DL_FLAG_AUTOREMOVE_CONSUMER)) @@ -982,15 +996,23 @@ static void reset_gpio_add_devlink(struct device_node= *np, */ } =20 +/* TODO: move it out into drivers/base/ */ +static bool fwnode_reference_args_equal(const struct fwnode_reference_args= *left, + const struct fwnode_reference_args *right) +{ + return left->fwnode =3D=3D right->fwnode && left->nargs =3D=3D right->nar= gs && + !memcmp(left->args, right->args, sizeof(left->args[0]) * left->nar= gs); +} + /* * @np: OF-node associated with the consumer - * @args: phandle to the GPIO provider with all the args like GPIO number + * @args: Reference to the GPIO provider with all the args like GPIO number */ -static int __reset_add_reset_gpio_device(struct device_node *np, - const struct of_phandle_args *args) +static int __reset_add_reset_gpio_device(struct fwnode_handle *fwnode, + const struct fwnode_reference_args *args) { struct property_entry properties[3] =3D { }; - unsigned int offset, of_flags, lflags; + unsigned int offset, flags, lflags; struct reset_gpio_lookup *rgpio_dev; struct device *parent; int ret, prop =3D 0; @@ -1001,7 +1023,7 @@ static int __reset_add_reset_gpio_device(struct devic= e_node *np, * args[1]: GPIO flags * TODO: Handle other cases. */ - if (args->args_count !=3D 2) + if (args->nargs !=3D 2) return -ENOENT; =20 /* @@ -1012,7 +1034,7 @@ static int __reset_add_reset_gpio_device(struct devic= e_node *np, lockdep_assert_not_held(&reset_list_mutex); =20 offset =3D args->args[0]; - of_flags =3D args->args[1]; + flags =3D args->args[1]; =20 /* * Later we map GPIO flags between OF and Linux, however not all @@ -1022,33 +1044,31 @@ static int __reset_add_reset_gpio_device(struct dev= ice_node *np, * FIXME: Find a better way of translating OF flags to GPIO lookup * flags. */ - if (of_flags > GPIO_ACTIVE_LOW) { + if (flags > GPIO_ACTIVE_LOW) { pr_err("reset-gpio code does not support GPIO flags %u for GPIO %u\n", - of_flags, offset); + flags, offset); return -EINVAL; } =20 struct gpio_device *gdev __free(gpio_device_put) =3D - gpio_device_find_by_fwnode(of_fwnode_handle(args->np)); + gpio_device_find_by_fwnode(args->fwnode); if (!gdev) return -EPROBE_DEFER; =20 guard(mutex)(&reset_gpio_lookup_mutex); =20 list_for_each_entry(rgpio_dev, &reset_gpio_lookup_list, list) { - if (args->np =3D=3D rgpio_dev->of_args.np) { - if (of_phandle_args_equal(args, &rgpio_dev->of_args)) { - /* - * Already on the list, create the device link - * and stop here. - */ - reset_gpio_add_devlink(np, rgpio_dev); - return 0; - } + if (fwnode_reference_args_equal(args, &rgpio_dev->ref_args)) { + /* + * Already on the list, create the device link + * and stop here. + */ + reset_gpio_add_devlink(fwnode, rgpio_dev); + return 0; } } =20 - lflags =3D GPIO_PERSISTENT | (of_flags & GPIO_ACTIVE_LOW); + lflags =3D GPIO_PERSISTENT | (flags & GPIO_ACTIVE_LOW); parent =3D gpio_device_to_device(gdev); properties[prop++] =3D PROPERTY_ENTRY_STRING("compatible", "reset-gpio"); properties[prop++] =3D PROPERTY_ENTRY_GPIO("reset-gpios", parent->fwnode,= offset, lflags); @@ -1058,43 +1078,43 @@ static int __reset_add_reset_gpio_device(struct dev= ice_node *np, if (!rgpio_dev) return -ENOMEM; =20 - rgpio_dev->of_args =3D *args; + rgpio_dev->ref_args =3D *args; /* - * We keep the device_node reference, but of_args.np is put at the end - * of __fwnode_reset_control_get(), so get it one more time. + * We keep the fwnode_handle reference, but ref_args.fwnode is put at + * the end of __fwnode_reset_control_get(), so get it one more time. * Hold reference as long as rgpio_dev memory is valid. */ - of_node_get(rgpio_dev->of_args.np); + fwnode_handle_get(rgpio_dev->ref_args.fwnode); =20 rgpio_dev->swnode =3D fwnode_create_software_node(properties, NULL); if (IS_ERR(rgpio_dev->swnode)) { ret =3D PTR_ERR(rgpio_dev->swnode); - goto err_put_of_node; + goto err_put_fwnode; } =20 ret =3D reset_create_gpio_aux_device(rgpio_dev, parent); if (ret) goto err_del_swnode; =20 - reset_gpio_add_devlink(np, rgpio_dev); + reset_gpio_add_devlink(fwnode, rgpio_dev); list_add(&rgpio_dev->list, &reset_gpio_lookup_list); =20 return 0; =20 err_del_swnode: fwnode_remove_software_node(rgpio_dev->swnode); -err_put_of_node: - of_node_put(rgpio_dev->of_args.np); +err_put_fwnode: + fwnode_handle_put(rgpio_dev->ref_args.fwnode); kfree(rgpio_dev); =20 return ret; } =20 -static struct reset_controller_dev *__reset_find_rcdev(const struct of_pha= ndle_args *args, - bool gpio_fallback) +static struct reset_controller_dev * +__reset_find_rcdev(const struct fwnode_reference_args *args, bool gpio_fal= lback) { + struct fwnode_reference_args *rc_args; struct reset_controller_dev *rcdev; - struct of_phandle_args *rc_args; =20 lockdep_assert_held(&reset_list_mutex); =20 @@ -1103,10 +1123,10 @@ static struct reset_controller_dev *__reset_find_rc= dev(const struct of_phandle_a device_is_compatible(rcdev->dev, "reset-gpio")) { rc_args =3D dev_get_platdata(rcdev->dev); =20 - if (of_phandle_args_equal(args, rc_args)) + if (fwnode_reference_args_equal(args, rc_args)) return rcdev; } else { - if (args->np =3D=3D rcdev->of_node) + if (args->fwnode =3D=3D rcdev->fwnode) return rcdev; } } @@ -1120,27 +1140,26 @@ __fwnode_reset_control_get(struct fwnode_handle *fw= node, const char *id, int ind { bool optional =3D flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL; bool gpio_fallback =3D false; - struct device_node *node =3D to_of_node(fwnode); struct reset_control *rstc =3D ERR_PTR(-EINVAL); struct reset_controller_dev *rcdev; - struct of_phandle_args args; - int rstc_id; + struct fwnode_reference_args args; + struct of_phandle_args of_args; + int rstc_id =3D -EINVAL; int ret; =20 if (!fwnode) return ERR_PTR(-EINVAL); =20 if (id) { - index =3D of_property_match_string(node, - "reset-names", id); + index =3D fwnode_property_match_string(fwnode, "reset-names", id); if (index =3D=3D -EILSEQ) return ERR_PTR(index); if (index < 0) return optional ? NULL : ERR_PTR(-ENOENT); } =20 - ret =3D of_parse_phandle_with_args(node, "resets", "#reset-cells", - index, &args); + ret =3D fwnode_property_get_reference_args(fwnode, "resets", "#reset-cell= s", + 0, index, &args); if (ret =3D=3D -EINVAL) return ERR_PTR(ret); if (ret) { @@ -1151,16 +1170,16 @@ __fwnode_reset_control_get(struct fwnode_handle *fw= node, const char *id, int ind * There can be only one reset-gpio for regular devices, so * don't bother with the "reset-gpios" phandle index. */ - ret =3D of_parse_phandle_with_args(node, "reset-gpios", "#gpio-cells", - 0, &args); + ret =3D fwnode_property_get_reference_args(fwnode, "reset-gpios", + "#gpio-cells", 0, 0, &args); if (ret) return optional ? NULL : ERR_PTR(ret); =20 gpio_fallback =3D true; =20 - ret =3D __reset_add_reset_gpio_device(node, &args); + ret =3D __reset_add_reset_gpio_device(fwnode, &args); if (ret) { - of_node_put(args.np); + fwnode_handle_put(args.fwnode); return ERR_PTR(ret); } } @@ -1173,15 +1192,30 @@ __fwnode_reset_control_get(struct fwnode_handle *fw= node, const char *id, int ind goto out_put; } =20 - if (WARN_ON(args.args_count !=3D rcdev->of_reset_n_cells)) { + if (WARN_ON(args.nargs !=3D rcdev->fwnode_reset_n_cells)) { rstc =3D ERR_PTR(-EINVAL); goto out_put; } =20 - rstc_id =3D rcdev->of_xlate(rcdev, &args); + if (rcdev->of_xlate && is_of_node(fwnode)) { + ret =3D of_parse_phandle_with_args(to_of_node(fwnode), + gpio_fallback ? "reset-gpios" : "resets", + gpio_fallback ? "#gpio-cells" : "#reset-cells", + gpio_fallback ? 0 : index, + &of_args); + if (ret) { + rstc =3D ERR_PTR(ret); + goto out_put; + } + + rstc_id =3D rcdev->of_xlate(rcdev, &of_args); + of_node_put(of_args.np); + } else if (rcdev->fwnode_xlate) { + rstc_id =3D rcdev->fwnode_xlate(rcdev, &args); + } if (rstc_id < 0) { rstc =3D ERR_PTR(rstc_id); - goto out_put; + goto out_put; } =20 flags &=3D ~RESET_CONTROL_FLAGS_BIT_OPTIONAL; @@ -1190,7 +1224,7 @@ __fwnode_reset_control_get(struct fwnode_handle *fwno= de, const char *id, int ind rstc =3D __reset_control_get_internal(rcdev, rstc_id, flags); =20 out_put: - of_node_put(args.np); + fwnode_handle_put(args.fwnode); =20 return rstc; } diff --git a/include/linux/reset-controller.h b/include/linux/reset-control= ler.h index 185d2a9bd7cd381ddc51c0f1643c4e3cb196015e..52a5a4e81f1844075210339bf7f= fa46ec5ca6edf 100644 --- a/include/linux/reset-controller.h +++ b/include/linux/reset-controller.h @@ -5,6 +5,8 @@ #include #include =20 +struct fwnode_handle; +struct fwnode_reference_args; struct reset_controller_dev; =20 /** @@ -38,8 +40,12 @@ struct of_phandle_args; * @of_node: corresponding device tree node as phandle target * @of_reset_n_cells: number of cells in reset line specifiers * @of_xlate: translation function to translate from specifier as found in= the - * device tree to id as given to the reset control ops, defaults - * to :c:func:`of_reset_simple_xlate`. + * device tree to id as given to the reset control ops + * @fwnode: firmware node associated with this device + * @fwnode_reset_n_cells: number of cells in reset line specifiers + * @fwnode_xlate: translation function to translate from firmware specifie= r to + * id as given to the reset control ops, defaults to + * :c:func:`fwnode_reset_simple_xlate` * @nr_resets: number of reset controls in this reset controller device * @lock: protects the reset control list from concurrent access */ @@ -53,6 +59,10 @@ struct reset_controller_dev { int of_reset_n_cells; int (*of_xlate)(struct reset_controller_dev *rcdev, const struct of_phandle_args *reset_spec); + struct fwnode_handle *fwnode; + int fwnode_reset_n_cells; + int (*fwnode_xlate)(struct reset_controller_dev *rcdev, + const struct fwnode_reference_args *reset_spec); unsigned int nr_resets; struct mutex lock; }; --=20 2.47.3