From nobody Mon Feb 9 08:29:17 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 DCB322E7179 for ; Mon, 5 Jan 2026 14:16:21 +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=1767622585; cv=none; b=D2paZJ2ebluY2KvHkE6R9CAr4UkT7A0gGw2Q++Ojuoj9eJ3JkjIodrrdCJgM0ZDGwkjDJJYMRqmTogdu73x6/GeglqGbn4tgaXqumuwCO8jUTNYmjuNZoRuzSFv8E61In9GSSWS70yNcSTJkQPvHVhC0umFnQ1OFyMwWfPVAIfE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767622585; c=relaxed/simple; bh=XpQOedqiqilgQAGLdUIy5qGWiwRiz0JVfLqf9eSpIzI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fNTqtHWaokWCNz+fipkHj1lL6kV+zG6VeX5vdqomsK0ZVFRduhqtkKKFAdqjtf0anPGep/w4AOdOzkyuiDINAoRD35gPRCtgyl0v9GrhthQ8FZjO0sTJ1cKz1SIgYPJIm13GItFiSInmTWevLKJfJUdSD45pQ+754k1SI0b4IFc= 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=KtB1dMds; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=gUsv5aCa; 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="KtB1dMds"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="gUsv5aCa" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 6059co3u610507 for ; Mon, 5 Jan 2026 14:16:21 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= 97i8zO0OGZluEWL25+YjUnEjd3xeNV0RVa8LxVTiEhQ=; b=KtB1dMdsum2nQCpy W71/BfeUU5il/wQ9D6ewTr/OcpILC40BoiLutfhsKPNGFzSrxPzZvpCUOzVk17FQ wTAifTFIClKHiaFducQ8my1GMgnfSbQD73w4e33u12TocKCOjrx2Owal2RhuxXDo u7LdFOzwQPpfQuCE/ARWoNyZAfJmyLizbSTHj+s439HMROZ2SQ5gi7HGBVTkEMgw Aj2Vu+e229M4Lr0pBAaiBxkN6AAytSSYpk3ZiKW32Onpquse3uPlZsQJO6C1Xhzc iQRStEbGSk/ubA42eR7EZnsV1uRjsu9IRtqimWZ249CiFzJMIee0Ss4bWLyI8vSv CHUHOw== Received: from mail-vk1-f197.google.com (mail-vk1-f197.google.com [209.85.221.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4bgaus0p1x-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Mon, 05 Jan 2026 14:16:20 +0000 (GMT) Received: by mail-vk1-f197.google.com with SMTP id 71dfb90a1353d-5602cf6f011so12909084e0c.0 for ; Mon, 05 Jan 2026 06:16:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1767622580; x=1768227380; 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=97i8zO0OGZluEWL25+YjUnEjd3xeNV0RVa8LxVTiEhQ=; b=gUsv5aCamxHEZjoJ+9WJhavGY/Ev/2rUiaa6iuTpZDoj3gARpbX23Ys57NKFCbkY7K qQPlfaLDigfboRMWTqO8nm7HPHar7/eD9MAbKZdYo+AI2Sca2xb7F7UYYGH6q9k9WSEi Y941rk5h8d2lT9j27Tp/PUv+3DCn/XFhUSLVpLh2E+oC73KN7MNr/ZX9TF9C/UiEVj2U a4YJv7lJl5EKEHUeBGrGBErd7rtY6npmMx7J6x784QWnspf9FD8aJpFMRddyGiHT/W6j zKOqecb9E2wnUdZtWzeGTl+hNn7w/eR3nfqrnKZ1Gz8uUEN21kT51hbtCThHf8H7WhUJ A5fA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767622580; x=1768227380; 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=97i8zO0OGZluEWL25+YjUnEjd3xeNV0RVa8LxVTiEhQ=; b=CjmNQ1QJ0tW9eJwIs2XFMiZkiPf32YjWp7Am5L79iHlkZStShcQWjAIeUHCexHGNsW uPY2zDn303cg71p+ALE0Q2rSdKYDWizpteQ8J+5cxAbzDNxGYNdot1ZVyIpO0k5tntVN dBGu8a0/XU7D3bgJN0Sz30DHHqMYklGHdd+3pPhpqNCfjxE8qSE2k2Nc8xUSpye9/JAb gLVx5t6DXidOuMAtwngfIgpKMdOLrctFBw7xIyV53gx09mXwc20gqGJlpHbEn+/jJd9/ eL4Qubnfovc7Z7mkX3DwOpNnONJphVRjvoXPu532eqzuTQYDTYx9dvJESXyf/BKhvsBB pwqA== X-Gm-Message-State: AOJu0YwUn5W+eokJZKQ3uXJMZWCPrABztKemy+yd3HOJHhPY6teoKS+R O9ivcawo6nf2rwb44EXn1+mNxFEr0QXYQcKMzsDtSbz5hRNHa3LuG4k/yCoFSVmgnSc7NZ1JpRz SviEN7BvjdxrMfJBsAe45aWJWRp8dpoLpsieFhKW1u1YMhgD4qHy9L0HACrUB/rgALdw= X-Gm-Gg: AY/fxX7Ig3IOTFgAf26P6GlmGuYNhLRFOzQ7aN3s6dZTYZzlWqlChJVA6ELDiwrPD7j Ue3rR88HNmSOqEo9OHxZct8axLS7+3OdrsgHnZXlLsCes+yf7lnkECe2XVOJi8ceFRY3ZTw4GhM dCZw79L0VVJVXWrZxNRBK4QMQ/YGlzai0ksxDPakCs9OkVzsyqReSC/4SlGAiJeQtk3wIqK6NWL 8FlEevzoqbaMXVHe8gPzk1KvCeDARI02xn8iibpkJwWtM/27hQCYSRFZYokFy1ILKPJRGv6cDBx T5RKILFUriu+03A2JPBqgq/kwa4jX2PrcXzOiQ0sXvuC5+o+Vk4F3I8TutzwU4qxxCtDGE7NkfT YmlJnfLP0/lisred5SGB3mbxc21hOoDvnq+xrlsA= X-Received: by 2002:a05:6122:2509:b0:54a:a178:3c9f with SMTP id 71dfb90a1353d-5615be82111mr12125181e0c.15.1767622578306; Mon, 05 Jan 2026 06:16:18 -0800 (PST) X-Google-Smtp-Source: AGHT+IGAIQKbta252zaXvoz7jKCpA/SvfITdNs4kmnMVjsvtq3vZEo+X+Pey3kOqwk9FFSutOObqXg== X-Received: by 2002:a05:6122:2509:b0:54a:a178:3c9f with SMTP id 71dfb90a1353d-5615be82111mr12125154e0c.15.1767622577742; Mon, 05 Jan 2026 06:16:17 -0800 (PST) Received: from brgl-qcom.local ([2a01:cb1d:dc:7e00:dd3b:c635:dd06:9574]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4324ea1aef7sm100774703f8f.7.2026.01.05.06.16.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Jan 2026 06:16:17 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 05 Jan 2026 15:15:33 +0100 Subject: [PATCH 14/15] 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: <20260105-reset-core-refactor-v1-14-ac443103498d@oss.qualcomm.com> References: <20260105-reset-core-refactor-v1-0-ac443103498d@oss.qualcomm.com> In-Reply-To: <20260105-reset-core-refactor-v1-0-ac443103498d@oss.qualcomm.com> To: Krzysztof Kozlowski , Philipp Zabel Cc: linux-kernel@vger.kernel.org, Bartosz Golaszewski X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=15260; i=bartosz.golaszewski@oss.qualcomm.com; h=from:subject:message-id; bh=XpQOedqiqilgQAGLdUIy5qGWiwRiz0JVfLqf9eSpIzI=; b=owEBbQKS/ZANAwAKAQWdLsv/NoTDAcsmYgBpW8eg11qNMKTpA/TqqeBAzpodXIFMVk1SO97Fb j4lCAVg3KaJAjMEAAEKAB0WIQSR5RMt5bVGHXuiZfwFnS7L/zaEwwUCaVvHoAAKCRAFnS7L/zaE w5ooD/0Y3Gnw59jYUHUb2Byzl+G30FqNOTeKnTTt6k40F27MtlTtX+E6ljtK4Zgtop0ilZUdY8D Si4B3laXFcimteJDX2b+yTxXHWwgiw1B4UBeXYBUOzg8RJhpqN3FCIYJkfV+MPUX0V3h4LEy+94 6PLKXBlAFuk319fIIbjVC4Hv7UquK3atcMHV4E0xCFJQTf0xiUA03Vdux2mJW5BqsIKo8Uw25uG X0A9vMt4QI8NsA7s/cG+fJWO1UYFRd4okAV5Ef337bQ2mP+M8j09q+y937NZ8KknQ0XIeDAVPME cVxT0zmLg/trPjNBvAdIUKzokUh9SBpaEv7HW0kW9dhCXp8k8iEJ2RZrwEcp7M4MzLXWmvmGe5s L89F4jKnziUcOUQSEvk01exEe3YN8xCBNGkOYgrZHc0swCoYuCNRcDsh9f6GE28KIeods5iija+ D1D/sEVaoUFeZ57NuqkGuId6ldIogHw1WeA7uuj9WCU55v7yYxyz2bUuqGxMxEzm+VsH15qr+J3 Qufm0GLaarsfcMl3GrPHkIUt1G1ZG7N3rT+y0PhzayaZf0Yw9Ce4F3ANLFTy4XuVlYD3I8MsjUl 2//QOgqj/sUrP8fIdniXlp5ZODH07OlvDN8iFdlIQogIsAcDB/iV/oxFpv4ObPXhuVMSNbm95V0 arpUnhLEb1hJqYQ== X-Developer-Key: i=bartosz.golaszewski@oss.qualcomm.com; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 X-Proofpoint-ORIG-GUID: FP3PJm3o_9yoxlkp_4beMlvtkkx4rgfi X-Authority-Analysis: v=2.4 cv=DP6CIiNb c=1 sm=1 tr=0 ts=695bc7b4 cx=c_pps a=JIY1xp/sjQ9K5JH4t62bdg==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=vUbySO9Y5rIA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=EUspDBNiAAAA:8 a=EAxQ06SQvwH9g5cYwaQA:9 a=QEXdDO2ut3YA:10 a=tNoRWFLymzeba-QzToBc:22 X-Proofpoint-GUID: FP3PJm3o_9yoxlkp_4beMlvtkkx4rgfi X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwMTA1MDEyNSBTYWx0ZWRfX+Mf5Jb/HLSSX d/XM2VQ6uxb0gWHunHF+ZnxItVrLex47VTlGRg1zpNajLrDoaqlCe2eiQ5SSM3jxLZSv/q6rYz6 15w07i5u7YVjPhZ3QYIydl97rFhfi2wopkDCThvrSez/D7i47tUAvPj4y4IJ+tY3TygTub04OzD VMHiysQaZZZ0iJHVhLDRcvohoNeFr4rAA+C7W/2kFAjwgSQOkGl9UFvHL57OJ1rB/WDQknPeOdW 0oOzY7qLbhFcNQII7hVimC2vdBl7YGEXf+K7IFalbA5txap+XnmRAgHGPp8O1Pc+5c4QpVi5dnq dMlumgirzVDutvhVw1QqUep0psxUFYVys9S8zMeRGFtQmKWACjAIK2xJY6W1icOze25XdKIwYkX ruOkPcoGmUc9a3rU7YmZ8jDHQyzuiepwR0XhjdSFQ5XmVNUB+/INTujgdwkid/H2wkw1yb9Qi6m lAVT7Oz5ChTOKyk+bTg== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2026-01-05_01,2026-01-05_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 priorityscore=1501 clxscore=1015 impostorscore=0 malwarescore=0 phishscore=0 adultscore=0 spamscore=0 suspectscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2512120000 definitions=main-2601050125 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 --- drivers/reset/core.c | 150 +++++++++++++++++++++++------------= ---- include/linux/reset-controller.h | 14 +++- 2 files changed, 101 insertions(+), 63 deletions(-) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 11c5bd0fe2b23e76db0b4739c5e34e478d83608b..310434ba5caae716a21e4f8ea70= 62dd201fb1f2c 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 + * This static translation function is used by default if fwnode_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. */ -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,17 @@ 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 =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); @@ -917,7 +925,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 @@ -937,18 +945,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)) @@ -968,15 +976,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; @@ -987,7 +1003,7 @@ static int __reset_add_reset_gpio_device(struct device= _node *np, * args[1]: GPIO flags * TODO: Handle other cases. */ - if (args->args_count !=3D 2) + if (args->nargs !=3D 2) return -ENOENT; =20 /* @@ -998,7 +1014,7 @@ static int __reset_add_reset_gpio_device(struct device= _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 @@ -1008,33 +1024,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); @@ -1044,43 +1058,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 reset_controller_dev *rcdev; - struct of_phandle_args *rc_args; + struct fwnode_reference_args *rc_args; =20 lockdep_assert_held(&reset_list_mutex); =20 @@ -1088,10 +1102,10 @@ static struct reset_controller_dev *__reset_find_rc= dev(const struct of_phandle_a if (gpio_fallback && 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; } } @@ -1105,27 +1119,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) { @@ -1136,14 +1149,14 @@ __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) { rstc =3D ERR_PTR(ret); goto out_put; @@ -1158,12 +1171,27 @@ __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; @@ -1175,7 +1203,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 2fecb4edeba1a2b1f5f5db2b34c867362c5f9c18..2f7a1217d0ec6dba4f8831fb8c6= 6308188f7a339 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: synchronizes concurrent access to the structure's fields */ @@ -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