From nobody Wed Apr 1 09:46:28 2026 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 555B03BF69C; Tue, 31 Mar 2026 11:41:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774957297; cv=none; b=mbXuhPiqGdM/l9jaWG3lTPmWvsuYfez3ezfinZzN/R3YNmgfHJqKnpUjg0gmvcHQQp8Ctn2HxInepGNylK7/IoIopbkOtcrYV7yApEbT6Cxlp4lSH9d6e/8EMEVMk9mjkF3vwUQE5qfY/HbYebs6ViAcG51ZkY3nCol+evPuIes= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774957297; c=relaxed/simple; bh=+L/K8+O6tMPwhjokt9uI6DRjPbeTQNlOvbn7Q7JVKSk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dl6VIlwnUeKvnNEXUZZiPcN875coO39MqUtrQXGQRU+Ldws96fXK8bx7tPCRcpnuKjB8wdBHhxxzLAYkEEi2Kxc/wA4If9RZiB3UaKG2pIGk2XgtSXzgpCK132YSEnKYsJU+TvVOsGccdSsQzqqtsvERdTULaFq80EjMF7uX3Cs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b=tsHvh5lN; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b="tsHvh5lN" X-SpamFilter-By: ArmorX SpamTrap 5.80 with qID 62VBcZbgD3149080, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=realtek.com; s=dkim; t=1774957115; bh=R54LgNHSFQobFVsX7fHxSQcvp4mTFC0QLJ2acEvsUu0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=tsHvh5lNzoiQ+YHoqn6jZtfHdalvYo5kI0cm/1ZfK4UWlg1UoGjaECW6jsKQo5D54 ZO54s58KfMspsCXJFa1a/+qAhT9DywFtmu4rXkLAf/sVxINdgG4E16YCEA4w1R1s+D SOeSBT+oEL/rbC48rcfM8yorE4izp+sPgel5sYmQB4Z101+XGD7SPbWKO7ngyU88+j J1VVxoocQJvC+rYfh3YwBjj2NBzZ0J6aQsJamtb4K+7LizZqciodPuJpWSQfh9vhdc o3vymAno8Nr7rdBOrZqeSV3uibkeupVZ8vwgEVaVXPFFPCw9FgzmMnTkVpzIN7dgiq w4szu6zwXlReg== Received: from mail.realtek.com (rtkexhmbs02.realtek.com.tw[172.21.6.41]) by rtits2.realtek.com.tw (8.15.2/3.26/5.94) with ESMTPS id 62VBcZbgD3149080 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 31 Mar 2026 19:38:35 +0800 Received: from RTKEXHMBS06.realtek.com.tw (10.21.1.56) by RTKEXHMBS02.realtek.com.tw (172.21.6.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.10; Tue, 31 Mar 2026 19:38:36 +0800 Received: from RTKEXHMBS04.realtek.com.tw (10.21.1.54) by RTKEXHMBS06.realtek.com.tw (10.21.1.56) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.10; Tue, 31 Mar 2026 19:38:35 +0800 Received: from cn1dhc-k02 (172.21.252.101) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server id 15.2.1748.10 via Frontend Transport; Tue, 31 Mar 2026 19:38:35 +0800 From: Yu-Chun Lin To: , , , , , , CC: , , , , , , , , Subject: [PATCH 1/3] dt-bindings: gpio: realtek: Add realtek,rtd1625-gpio Date: Tue, 31 Mar 2026 19:38:33 +0800 Message-ID: <20260331113835.3510341-2-eleanor.lin@realtek.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260331113835.3510341-1-eleanor.lin@realtek.com> References: <20260331113835.3510341-1-eleanor.lin@realtek.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 Content-Type: text/plain; charset="utf-8" From: Tzuyi Chang Add the device tree bindings for the Realtek DHC (Digital Home Center) RTD1625 GPIO controllers. The RTD1625 GPIO controller features a per-pin register architecture that differs significantly from previous generations. It utilizes separate register blocks for GPIO configuration and interrupt control. Signed-off-by: Tzuyi Chang Signed-off-by: Yu-Chun Lin --- .../bindings/gpio/realtek,rtd1625-gpio.yaml | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/realtek,rtd1625-= gpio.yaml diff --git a/Documentation/devicetree/bindings/gpio/realtek,rtd1625-gpio.ya= ml b/Documentation/devicetree/bindings/gpio/realtek,rtd1625-gpio.yaml new file mode 100644 index 000000000000..e81d13dfefc2 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/realtek,rtd1625-gpio.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2023 Realtek Semiconductor Corporation +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpio/realtek,rtd1625-gpio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Realtek DHC RTD1625 GPIO controller + +maintainers: + - Tzuyi Chang + +description: | + GPIO controller for the Realtek RTD1625 SoC, featuring a per-pin register + architecture that differs significantly from earlier RTD series controll= ers. + Each GPIO has dedicated registers for configuration (direction, input/ou= tput + values, debounce), and interrupt control supporting edge and level detec= tion + modes. + +properties: + compatible: + enum: + - realtek,rtd1625-iso-gpio + - realtek,rtd1625-isom-gpio + + reg: + items: + - description: GPIO controller registers + - description: GPIO interrupt registers + + interrupts: + items: + - description: Interrupt number of the assert GPIO interrupt, which = is + triggered when there is a rising edge. + - description: Interrupt number of the deassert GPIO interrupt, whic= h is + triggered when there is a falling edge. + - description: Interrupt number of the level-sensitive GPIO interrup= t, + triggered by a configured logic level. + + interrupt-controller: true + + "#interrupt-cells": + const: 2 + + gpio-ranges: true + + gpio-controller: true + + "#gpio-cells": + const: 2 + +required: + - compatible + - reg + - gpio-ranges + - gpio-controller + - "#gpio-cells" + +additionalProperties: false + +examples: + - | + gpio@89120 { + compatible =3D "realtek,rtd1625-isom-gpio"; + reg =3D <0x89120 0x10>, + <0x89100 0x20>; + interrupt-parent =3D <&iso_m_irq_mux>; + interrupts =3D <0>, <1>, <2>; + interrupt-controller; + #interrupt-cells =3D <2>; + gpio-ranges =3D <&isom_pinctrl 0 0 4>; + gpio-controller; + #gpio-cells =3D <2>; + }; --=20 2.34.1 From nobody Wed Apr 1 09:46:28 2026 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B3267286D60; Tue, 31 Mar 2026 11:41:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774957294; cv=none; b=dOXGIYDjEZZO3QTtVfmHRo+AAkGU8kKSQGIHJRYGzEY2YfQj01c/7XEBV5m+Sv1HlKv9EmukglSr/24vl/JKjTzU9gq6xTDiqIFc21n1oDC9d3HtUlYesm0iw2eKCR1GhPJ88+gWmh+7XVhlxk+OwTh0IKmoqb8ottE/utDy1m4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774957294; c=relaxed/simple; bh=VIg24rCCbEtwwC1LCboJxXzmgDY6tsK45vqmFQr6OJU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=N4jTEa28D5Fz4hj3mRMhiuUyzXVkvw3kVh2wAvcrQAFSG6Ibm6ubKI52yGZKwYFCWiSssVDooiTb2JV9f4Kz21OQK0rfCMX3xZfPNREx8Yy9N5FvWjwwxcOjUIaVrvF0YMRtMn9fHFzlF8iTpcER0Atr37YwtwINv2kIflciRCE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b=mdipEE9i; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b="mdipEE9i" X-SpamFilter-By: ArmorX SpamTrap 5.80 with qID 62VBcZKj93149082, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=realtek.com; s=dkim; t=1774957115; bh=F3Td0wZotLaBngEl3nbtygM4AkeeYKfycbQUwc+pVNg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=mdipEE9ipau4+TnEm7a93c2XOTuWXIFVPMA0RjmWseac5V7/xy19G0tgjxIYdjqiI THlp+9ksq8GUUheKDxIQe7eaW7Fk8wB33Ajg3WuVwDs/QtovjJOgaasdhkD57Sl1ih VKXEX5bWeTrnAGHj/sH3U/POpopW1e+A6d12Qh/EWQQvUbPe40UHbV3nNECkfofTS8 zSgFDs70LvgRJocguUmiFE/RYQoAYMQpnzDyNOr/p2w4tviRII4A//uOdpis65yCiE tBBBvylYo1yCMvK8xnQ0n4mHjsw78jJNx22FVKhooL/zOwz4FyOZymXH6xuuiK6ZGv Oml9kaiVTZo6Q== Received: from mail.realtek.com (rtkexhmbs02.realtek.com.tw[172.21.6.41]) by rtits2.realtek.com.tw (8.15.2/3.26/5.94) with ESMTPS id 62VBcZKj93149082 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 31 Mar 2026 19:38:35 +0800 Received: from RTKEXHMBS06.realtek.com.tw (10.21.1.56) by RTKEXHMBS02.realtek.com.tw (172.21.6.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.10; Tue, 31 Mar 2026 19:38:36 +0800 Received: from RTKEXHMBS04.realtek.com.tw (10.21.1.54) by RTKEXHMBS06.realtek.com.tw (10.21.1.56) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.10; Tue, 31 Mar 2026 19:38:35 +0800 Received: from cn1dhc-k02 (172.21.252.101) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server id 15.2.1748.10 via Frontend Transport; Tue, 31 Mar 2026 19:38:35 +0800 From: Yu-Chun Lin To: , , , , , , CC: , , , , , , , , Subject: [PATCH 2/3] arm64: dts: realtek: Add GPIO support for RTD1625 Date: Tue, 31 Mar 2026 19:38:34 +0800 Message-ID: <20260331113835.3510341-3-eleanor.lin@realtek.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260331113835.3510341-1-eleanor.lin@realtek.com> References: <20260331113835.3510341-1-eleanor.lin@realtek.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 Content-Type: text/plain; charset="utf-8" Add the GPIO node for the Realtek RTD1625 SoC. Signed-off-by: Yu-Chun Lin --- arch/arm64/boot/dts/realtek/kent.dtsi | 43 ++++++++++++++++++++++++ arch/arm64/boot/dts/realtek/rtd1501.dtsi | 8 +++++ arch/arm64/boot/dts/realtek/rtd1861.dtsi | 8 +++++ arch/arm64/boot/dts/realtek/rtd1920.dtsi | 8 +++++ 4 files changed, 67 insertions(+) diff --git a/arch/arm64/boot/dts/realtek/kent.dtsi b/arch/arm64/boot/dts/re= altek/kent.dtsi index 8d4293cd4c03..746932c26724 100644 --- a/arch/arm64/boot/dts/realtek/kent.dtsi +++ b/arch/arm64/boot/dts/realtek/kent.dtsi @@ -151,6 +151,39 @@ uart0: serial@7800 { status =3D "disabled"; }; =20 + gpio: gpio@31100 { + compatible =3D "realtek,rtd1625-iso-gpio"; + reg =3D <0x31100 0x398>, + <0x31000 0x100>; + gpio-controller; + gpio-ranges =3D <&isom_pinctrl 0 0 2>, + <&ve4_pinctrl 2 0 6>, + <&iso_pinctrl 8 0 4>, + <&ve4_pinctrl 12 6 2>, + <&main2_pinctrl 14 0 2>, + <&ve4_pinctrl 16 8 4>, + <&main2_pinctrl 20 2 3>, + <&ve4_pinctrl 23 12 3>, + <&iso_pinctrl 26 4 2>, + <&isom_pinctrl 28 2 2>, + <&ve4_pinctrl 30 15 6>, + <&main2_pinctrl 36 5 6>, + <&ve4_pinctrl 42 21 3>, + <&iso_pinctrl 45 6 6>, + <&ve4_pinctrl 51 24 1>, + <&iso_pinctrl 52 12 1>, + <&ve4_pinctrl 53 25 11>, + <&main2_pinctrl 64 11 28>, + <&ve4_pinctrl 92 36 2>, + <&iso_pinctrl 94 13 19>, + <&iso_pinctrl 128 32 4>, + <&ve4_pinctrl 132 38 13>, + <&iso_pinctrl 145 36 19>, + <&ve4_pinctrl 164 51 2>; + #gpio-cells =3D <2>; + status =3D "disabled"; + }; + iso_pinctrl: pinctrl@4e000 { compatible =3D "realtek,rtd1625-iso-pinctrl"; reg =3D <0x4e000 0x1a4>; @@ -161,6 +194,16 @@ main2_pinctrl: pinctrl@4f200 { reg =3D <0x4f200 0x50>; }; =20 + iso_m_gpio: gpio@89120 { + compatible =3D "realtek,rtd1625-isom-gpio"; + reg =3D <0x89120 0x10>, + <0x89100 0x20>; + gpio-controller; + gpio-ranges =3D <&isom_pinctrl 0 0 4>; + #gpio-cells =3D <2>; + status =3D "disabled"; + }; + isom_pinctrl: pinctrl@146200 { compatible =3D "realtek,rtd1625-isom-pinctrl"; reg =3D <0x146200 0x34>; diff --git a/arch/arm64/boot/dts/realtek/rtd1501.dtsi b/arch/arm64/boot/dts= /realtek/rtd1501.dtsi index 65f7ede3df73..ae246a01f126 100644 --- a/arch/arm64/boot/dts/realtek/rtd1501.dtsi +++ b/arch/arm64/boot/dts/realtek/rtd1501.dtsi @@ -10,3 +10,11 @@ &uart0 { status =3D "okay"; }; + +&gpio { + status =3D "okay"; +}; + +&iso_m_gpio { + status =3D "okay"; +}; diff --git a/arch/arm64/boot/dts/realtek/rtd1861.dtsi b/arch/arm64/boot/dts= /realtek/rtd1861.dtsi index 44c3de8f1f48..b5f08bdd9f17 100644 --- a/arch/arm64/boot/dts/realtek/rtd1861.dtsi +++ b/arch/arm64/boot/dts/realtek/rtd1861.dtsi @@ -10,3 +10,11 @@ &uart0 { status =3D "okay"; }; + +&gpio { + status =3D "okay"; +}; + +&iso_m_gpio { + status =3D "okay"; +}; diff --git a/arch/arm64/boot/dts/realtek/rtd1920.dtsi b/arch/arm64/boot/dts= /realtek/rtd1920.dtsi index becf546216e9..94c8a43916a8 100644 --- a/arch/arm64/boot/dts/realtek/rtd1920.dtsi +++ b/arch/arm64/boot/dts/realtek/rtd1920.dtsi @@ -10,3 +10,11 @@ &uart0 { status =3D "okay"; }; + +&gpio { + status =3D "okay"; +}; + +&iso_m_gpio { + status =3D "okay"; +}; --=20 2.34.1 From nobody Wed Apr 1 09:46:28 2026 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5562C3D9027; Tue, 31 Mar 2026 11:41:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774957296; cv=none; b=YInVCanjSDYX9T2N2wBJ45i7cUy/C46ijfugvHWB1y2pnhMBg/OqeUqkWfUh1eG7EOWJwZ6q6mxGRjfDEqfvYIGN8yoOEKc1xKAOe9R8ebSimF6P6zbmpIIYBgaKrgZ8YPuJ+B/aWOugKRXNQWWiXGLBtMw6NJhM1EuhrXDGtwM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774957296; c=relaxed/simple; bh=G33wzhqL7kCwwcVllXYG5XwQw6sdRf+w3WWWqvP/sLs=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=i+wz051uhwuymP0RzXgFzrHQ9F78gSSC5+q8SJsh6A+aKeRUhUaZ3QEhhjbCIQfDF3+CkJAdRqE31UPoWqqz2wKk/63FjRZQeZeXe/fnGkoFL5fsOQRk18Lj3+W5V0qgnzPDb8OTIYVzSKd7ade/OCAYF6b7fr9aMP9ftrujHqM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b=hPuTmksP; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b="hPuTmksP" X-SpamFilter-By: ArmorX SpamTrap 5.80 with qID 62VBcZAM13149089, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=realtek.com; s=dkim; t=1774957115; bh=fp+gIfN0XfLllbGp+ZUFko52O+545pk/PSdxsFVOVHs=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=hPuTmksPEr0J53GZ5lyG3j4ln2xIbHJp2OqpmLrenSx4pEjD2WvrPqZzi/Tq5F0W/ kP4wLgMTSCMpVYLvJAwJak8n40gztWgP4Rr2AMZDIVgKdTg6pGYHNzEjbe6PAcJVQE JRR49ljFxlB9quDuJSNefAJ9M6FeSoQouBRdxOs6xxUwqlK9f3W/bm1ooC+7GEBpo6 RdMev5CdENEuB2KpiVF7X/IegAZpozvLz3UvZeE6BybsZurmoNc2eofSOYF7X0ch8o lD8NlOouSUg2wXmpo0baft8+o4lfhA+UejpomNoImTkDLGpTHqyDykYv2KLQ28h8+K OULstreHQE8/Q== Received: from mail.realtek.com (rtkexhmbs03.realtek.com.tw[10.21.1.53]) by rtits2.realtek.com.tw (8.15.2/3.26/5.94) with ESMTPS id 62VBcZAM13149089 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 31 Mar 2026 19:38:35 +0800 Received: from RTKEXHMBS06.realtek.com.tw (10.21.1.56) by RTKEXHMBS03.realtek.com.tw (10.21.1.53) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.10; Tue, 31 Mar 2026 19:38:36 +0800 Received: from RTKEXHMBS04.realtek.com.tw (10.21.1.54) by RTKEXHMBS06.realtek.com.tw (10.21.1.56) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.10; Tue, 31 Mar 2026 19:38:35 +0800 Received: from cn1dhc-k02 (172.21.252.101) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server id 15.2.1748.10 via Frontend Transport; Tue, 31 Mar 2026 19:38:35 +0800 From: Yu-Chun Lin To: , , , , , , CC: , , , , , , , , Subject: [PATCH 3/3] gpio: realtek: Add driver for Realtek DHC RTD1625 SoC Date: Tue, 31 Mar 2026 19:38:35 +0800 Message-ID: <20260331113835.3510341-4-eleanor.lin@realtek.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260331113835.3510341-1-eleanor.lin@realtek.com> References: <20260331113835.3510341-1-eleanor.lin@realtek.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 Content-Type: text/plain; charset="utf-8" From: Tzuyi Chang Add support for the GPIO controller found on Realtek DHC RTD1625 SoCs. Unlike the existing Realtek GPIO driver (drivers/gpio/gpio-rtd.c), which manages pins via shared bank registers, the RTD1625 introduces a per-pin register architecture. Each GPIO line now has its own dedicated 32-bit control register to manage configuration independently, including direction, output value, input value, interrupt enable, and debounce. Therefore, this distinct hardware design requires a separate driver. Signed-off-by: Tzuyi Chang Signed-off-by: Yu-Chun Lin --- drivers/gpio/Kconfig | 12 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-rtd1625.c | 581 ++++++++++++++++++++++++++++++++++++ 3 files changed, 594 insertions(+) create mode 100644 drivers/gpio/gpio-rtd1625.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b45fb799e36c..6ffc95e02cb9 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -639,6 +639,18 @@ config GPIO_RTD Say yes here to support GPIO functionality and GPIO interrupt on Realtek DHC SoCs. =20 +config GPIO_RTD1625 + tristate "Realtek DHC RTD1625 GPIO support" + depends on ARCH_REALTEK || COMPILE_TEST + default y + select GPIOLIB_IRQCHIP + help + This option enables support for the GPIO controller on Realtek + DHC (Digital Home Center) RTD1625 SoC. + + Say yes here to support both basic GPIO line functionality + and GPIO interrupt handling capabilities for this platform. + config GPIO_SAMA5D2_PIOBU tristate "SAMA5D2 PIOBU GPIO support" depends on MFD_SYSCON diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index c05f7d795c43..c95ba218d53a 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -159,6 +159,7 @@ obj-$(CONFIG_GPIO_REALTEK_OTTO) +=3D gpio-realtek-otto= .o obj-$(CONFIG_GPIO_REG) +=3D gpio-reg.o obj-$(CONFIG_GPIO_ROCKCHIP) +=3D gpio-rockchip.o obj-$(CONFIG_GPIO_RTD) +=3D gpio-rtd.o +obj-$(CONFIG_GPIO_RTD1625) +=3D gpio-rtd1625.o obj-$(CONFIG_ARCH_SA1100) +=3D gpio-sa1100.o obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) +=3D gpio-sama5d2-piobu.o obj-$(CONFIG_GPIO_SCH311X) +=3D gpio-sch311x.o diff --git a/drivers/gpio/gpio-rtd1625.c b/drivers/gpio/gpio-rtd1625.c new file mode 100644 index 000000000000..10559a892c06 --- /dev/null +++ b/drivers/gpio/gpio-rtd1625.c @@ -0,0 +1,581 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Realtek DHC RTD1625 gpio driver + * + * Copyright (c) 2023 Realtek Semiconductor Corp. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RTD1625_GPIO_DIR BIT(0) +#define RTD1625_GPIO_OUT BIT(2) +#define RTD1625_GPIO_IN BIT(4) +#define RTD1625_GPIO_EDGE_INT_DP BIT(6) +#define RTD1625_GPIO_EDGE_INT_EN BIT(8) +#define RTD1625_GPIO_LEVEL_INT_EN BIT(16) +#define RTD1625_GPIO_LEVEL_INT_DP BIT(18) +#define RTD1625_GPIO_DEBOUNCE GENMASK(30, 28) +#define RTD1625_GPIO_DEBOUNCE_WREN BIT(31) + +#define RTD1625_GPIO_WREN(x) ((x) << 1) + +/* Write-enable masks for all GPIO configs and reserved hardware bits */ +#define RTD1625_ISO_GPIO_WREN_ALL 0x8000aa8a +#define RTD1625_ISOM_GPIO_WREN_ALL 0x800aaa8a + +#define RTD1625_GPIO_DEBOUNCE_1US 0 +#define RTD1625_GPIO_DEBOUNCE_10US 1 +#define RTD1625_GPIO_DEBOUNCE_100US 2 +#define RTD1625_GPIO_DEBOUNCE_1MS 3 +#define RTD1625_GPIO_DEBOUNCE_10MS 4 +#define RTD1625_GPIO_DEBOUNCE_20MS 5 +#define RTD1625_GPIO_DEBOUNCE_30MS 6 +#define RTD1625_GPIO_DEBOUNCE_50MS 7 + +#define GPIO_CONTROL(gpio) ((gpio) * 4) + +/** + * struct rtd1625_gpio_info - Specific GPIO register information + * @num_gpios: The number of GPIOs + * @irq_type_support: Supported IRQ types + * @gpa_offset: Offset for GPIO assert interrupt status registers + * @gpda_offset: Offset for GPIO deassert interrupt status registers + * @level_offset: Offset of level interrupt status register + * @write_en_all: Write-enable mask for all configurable bits + */ +struct rtd1625_gpio_info { + unsigned int num_gpios; + unsigned int irq_type_support; + unsigned int gpa_offset; + unsigned int gpda_offset; + unsigned int level_offset; + unsigned int write_en_all; +}; + +struct rtd1625_gpio { + struct gpio_chip gpio_chip; + const struct rtd1625_gpio_info *info; + void __iomem *base; + void __iomem *irq_base; + unsigned int irqs[3]; + raw_spinlock_t lock; + unsigned int *save_regs; +}; + +static unsigned int rtd1625_gpio_gpa_offset(struct rtd1625_gpio *data, uns= igned int offset) +{ + return data->info->gpa_offset + ((offset / 32) * 4); +} + +static unsigned int rtd1625_gpio_gpda_offset(struct rtd1625_gpio *data, un= signed int offset) +{ + return data->info->gpda_offset + ((offset / 32) * 4); +} + +static unsigned int rtd1625_gpio_level_offset(struct rtd1625_gpio *data, u= nsigned int offset) +{ + return data->info->level_offset + ((offset / 32) * 4); +} + +static unsigned int rtd1625_gpio_set_debounce(struct gpio_chip *chip, unsi= gned int offset, + unsigned int debounce) +{ + struct rtd1625_gpio *data =3D gpiochip_get_data(chip); + u8 deb_val; + u32 val; + + switch (debounce) { + case 1: + deb_val =3D RTD1625_GPIO_DEBOUNCE_1US; + break; + case 10: + deb_val =3D RTD1625_GPIO_DEBOUNCE_10US; + break; + case 100: + deb_val =3D RTD1625_GPIO_DEBOUNCE_100US; + break; + case 1000: + deb_val =3D RTD1625_GPIO_DEBOUNCE_1MS; + break; + case 10000: + deb_val =3D RTD1625_GPIO_DEBOUNCE_10MS; + break; + case 20000: + deb_val =3D RTD1625_GPIO_DEBOUNCE_20MS; + break; + case 30000: + deb_val =3D RTD1625_GPIO_DEBOUNCE_30MS; + break; + case 50000: + deb_val =3D RTD1625_GPIO_DEBOUNCE_50MS; + break; + default: + return -ENOTSUPP; + } + + val =3D FIELD_PREP(RTD1625_GPIO_DEBOUNCE, deb_val) | RTD1625_GPIO_DEBOUNC= E_WREN; + + guard(raw_spinlock_irqsave)(&data->lock); + writel_relaxed(val, data->base + GPIO_CONTROL(offset)); + + return 0; +} + +static int rtd1625_gpio_set_config(struct gpio_chip *chip, unsigned int of= fset, + unsigned long config) +{ + int debounce; + + if (pinconf_to_config_param(config) =3D=3D PIN_CONFIG_INPUT_DEBOUNCE) { + debounce =3D pinconf_to_config_argument(config); + return rtd1625_gpio_set_debounce(chip, offset, debounce); + } + + return gpiochip_generic_config(chip, offset, config); +} + +static int rtd1625_gpio_set(struct gpio_chip *chip, unsigned int offset, i= nt value) +{ + struct rtd1625_gpio *data =3D gpiochip_get_data(chip); + u32 val =3D RTD1625_GPIO_WREN(RTD1625_GPIO_OUT); + + if (value) + val |=3D RTD1625_GPIO_OUT; + + guard(raw_spinlock_irqsave)(&data->lock); + writel_relaxed(val, data->base + GPIO_CONTROL(offset)); + + return 0; +} + +static int rtd1625_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct rtd1625_gpio *data =3D gpiochip_get_data(chip); + u32 val; + + guard(raw_spinlock_irqsave)(&data->lock); + val =3D readl_relaxed(data->base + GPIO_CONTROL(offset)); + + if (val & RTD1625_GPIO_DIR) + return !!(val & RTD1625_GPIO_OUT); + else + return !!(val & RTD1625_GPIO_IN); +} + +static int rtd1625_gpio_get_direction(struct gpio_chip *chip, unsigned int= offset) +{ + struct rtd1625_gpio *data =3D gpiochip_get_data(chip); + u32 val; + + guard(raw_spinlock_irqsave)(&data->lock); + val =3D readl_relaxed(data->base + GPIO_CONTROL(offset)); + + if (val & RTD1625_GPIO_DIR) + return GPIO_LINE_DIRECTION_OUT; + + return GPIO_LINE_DIRECTION_IN; +} + +static int rtd1625_gpio_set_direction(struct gpio_chip *chip, unsigned int= offset, bool out) +{ + struct rtd1625_gpio *data =3D gpiochip_get_data(chip); + u32 val =3D RTD1625_GPIO_WREN(RTD1625_GPIO_DIR); + + if (out) + val |=3D RTD1625_GPIO_DIR; + + guard(raw_spinlock_irqsave)(&data->lock); + writel_relaxed(val, data->base + GPIO_CONTROL(offset)); + + return 0; +} + +static int rtd1625_gpio_direction_input(struct gpio_chip *chip, unsigned i= nt offset) +{ + return rtd1625_gpio_set_direction(chip, offset, false); +} + +static int rtd1625_gpio_direction_output(struct gpio_chip *chip, unsigned = int offset, int value) +{ + rtd1625_gpio_set(chip, offset, value); + + return rtd1625_gpio_set_direction(chip, offset, true); +} + +static void rtd1625_gpio_irq_handle(struct irq_desc *desc) +{ + unsigned int (*get_reg_offset)(struct rtd1625_gpio *gpio, unsigned int of= fset); + struct rtd1625_gpio *data =3D irq_desc_get_handler_data(desc); + struct irq_domain *domain =3D data->gpio_chip.irq.domain; + struct irq_chip *chip =3D irq_desc_get_chip(desc); + unsigned int irq =3D irq_desc_get_irq(desc); + unsigned long status; + unsigned int reg_offset, i, j; + unsigned int girq; + irq_hw_number_t hwirq; + u32 irq_type; + + if (irq =3D=3D data->irqs[0]) + get_reg_offset =3D &rtd1625_gpio_gpa_offset; + else if (irq =3D=3D data->irqs[1]) + get_reg_offset =3D &rtd1625_gpio_gpda_offset; + else if (irq =3D=3D data->irqs[2]) + get_reg_offset =3D &rtd1625_gpio_level_offset; + else + return; + + chained_irq_enter(chip, desc); + + for (i =3D 0; i < data->info->num_gpios; i +=3D 32) { + reg_offset =3D get_reg_offset(data, i); + status =3D readl_relaxed(data->irq_base + reg_offset); + + /* Clear edge interrupts; level interrupts are cleared in ->irq_ack() */ + if (irq !=3D data->irqs[2]) + writel_relaxed(status, data->irq_base + reg_offset); + + for_each_set_bit(j, &status, 32) { + hwirq =3D i + j; + girq =3D irq_find_mapping(domain, hwirq); + irq_type =3D irq_get_trigger_type(girq); + + if (irq =3D=3D data->irqs[1] && irq_type !=3D IRQ_TYPE_EDGE_BOTH) + continue; + + generic_handle_domain_irq(domain, hwirq); + } + } + + chained_irq_exit(chip, desc); +} + +static void rtd1625_gpio_ack_irq(struct irq_data *d) +{ + struct rtd1625_gpio *data =3D irq_data_get_irq_chip_data(d); + irq_hw_number_t hwirq =3D irqd_to_hwirq(d); + u32 irq_type =3D irqd_get_trigger_type(d); + u32 bit_mask =3D BIT(hwirq % 32); + int reg_offset; + + if (irq_type & IRQ_TYPE_LEVEL_MASK) { + reg_offset =3D rtd1625_gpio_level_offset(data, hwirq); + writel_relaxed(bit_mask, data->irq_base + reg_offset); + } +} + +static void rtd1625_gpio_enable_edge_irq(struct rtd1625_gpio *data, irq_hw= _number_t hwirq) +{ + int gpda_reg_offset =3D rtd1625_gpio_gpda_offset(data, hwirq); + int gpa_reg_offset =3D rtd1625_gpio_gpa_offset(data, hwirq); + u32 clr_mask =3D BIT(hwirq % 32); + u32 val; + + guard(raw_spinlock_irqsave)(&data->lock); + writel_relaxed(clr_mask, data->irq_base + gpa_reg_offset); + writel_relaxed(clr_mask, data->irq_base + gpda_reg_offset); + val =3D RTD1625_GPIO_EDGE_INT_EN | RTD1625_GPIO_WREN(RTD1625_GPIO_EDGE_IN= T_EN); + writel_relaxed(val, data->base + GPIO_CONTROL(hwirq)); +} + +static void rtd1625_gpio_disable_edge_irq(struct rtd1625_gpio *data, irq_h= w_number_t hwirq) +{ + u32 val; + + guard(raw_spinlock_irqsave)(&data->lock); + val =3D RTD1625_GPIO_WREN(RTD1625_GPIO_EDGE_INT_EN); + writel_relaxed(val, data->base + GPIO_CONTROL(hwirq)); +} + +static void rtd1625_gpio_enable_level_irq(struct rtd1625_gpio *data, irq_h= w_number_t hwirq) +{ + int level_reg_offset =3D rtd1625_gpio_level_offset(data, hwirq); + u32 clr_mask =3D BIT(hwirq % 32); + u32 val; + + guard(raw_spinlock_irqsave)(&data->lock); + writel_relaxed(clr_mask, data->irq_base + level_reg_offset); + val =3D RTD1625_GPIO_LEVEL_INT_EN | RTD1625_GPIO_WREN(RTD1625_GPIO_LEVEL_= INT_EN); + writel_relaxed(val, data->base + GPIO_CONTROL(hwirq)); +} + +static void rtd1625_gpio_disable_level_irq(struct rtd1625_gpio *data, irq_= hw_number_t hwirq) +{ + u32 val; + + guard(raw_spinlock_irqsave)(&data->lock); + val =3D RTD1625_GPIO_WREN(RTD1625_GPIO_LEVEL_INT_EN); + writel_relaxed(val, data->base + GPIO_CONTROL(hwirq)); +} + +static void rtd1625_gpio_enable_irq(struct irq_data *d) +{ + struct gpio_chip *gc =3D irq_data_get_irq_chip_data(d); + struct rtd1625_gpio *data =3D gpiochip_get_data(gc); + irq_hw_number_t hwirq =3D irqd_to_hwirq(d); + u32 irq_type =3D irqd_get_trigger_type(d); + + gpiochip_enable_irq(gc, hwirq); + + if (irq_type & IRQ_TYPE_EDGE_BOTH) + rtd1625_gpio_enable_edge_irq(data, hwirq); + else if (irq_type & IRQ_TYPE_LEVEL_MASK) + rtd1625_gpio_enable_level_irq(data, hwirq); +} + +static void rtd1625_gpio_disable_irq(struct irq_data *d) +{ + struct gpio_chip *gc =3D irq_data_get_irq_chip_data(d); + struct rtd1625_gpio *data =3D gpiochip_get_data(gc); + irq_hw_number_t hwirq =3D irqd_to_hwirq(d); + u32 irq_type =3D irqd_get_trigger_type(d); + + if (irq_type & IRQ_TYPE_EDGE_BOTH) + rtd1625_gpio_disable_edge_irq(data, hwirq); + else if (irq_type & IRQ_TYPE_LEVEL_MASK) + rtd1625_gpio_disable_level_irq(data, hwirq); + + gpiochip_disable_irq(gc, hwirq); +} + +static int rtd1625_gpio_irq_set_level_type(struct irq_data *d, bool level) +{ + struct gpio_chip *gc =3D irq_data_get_irq_chip_data(d); + struct rtd1625_gpio *data =3D gpiochip_get_data(gc); + irq_hw_number_t hwirq =3D irqd_to_hwirq(d); + u32 val =3D RTD1625_GPIO_WREN(RTD1625_GPIO_LEVEL_INT_DP); + + if (!(data->info->irq_type_support & IRQ_TYPE_LEVEL_MASK)) + return -EINVAL; + + scoped_guard(raw_spinlock_irqsave, &data->lock) { + if (level) + val |=3D RTD1625_GPIO_LEVEL_INT_DP; + writel_relaxed(val, data->base + GPIO_CONTROL(hwirq)); + } + + irq_set_handler_locked(d, handle_level_irq); + + return 0; +} + +static int rtd1625_gpio_irq_set_edge_type(struct irq_data *d, bool polarit= y) +{ + struct gpio_chip *gc =3D irq_data_get_irq_chip_data(d); + struct rtd1625_gpio *data =3D gpiochip_get_data(gc); + irq_hw_number_t hwirq =3D irqd_to_hwirq(d); + u32 val =3D RTD1625_GPIO_WREN(RTD1625_GPIO_EDGE_INT_DP); + + if (!(data->info->irq_type_support & IRQ_TYPE_EDGE_BOTH)) + return -EINVAL; + + scoped_guard(raw_spinlock_irqsave, &data->lock) { + if (polarity) + val |=3D RTD1625_GPIO_EDGE_INT_DP; + writel_relaxed(val, data->base + GPIO_CONTROL(hwirq)); + } + + irq_set_handler_locked(d, handle_edge_irq); + + return 0; +} + +static int rtd1625_gpio_irq_set_type(struct irq_data *d, unsigned int type) +{ + int ret; + + switch (type & IRQ_TYPE_SENSE_MASK) { + case IRQ_TYPE_EDGE_RISING: + ret =3D rtd1625_gpio_irq_set_edge_type(d, 1); + break; + case IRQ_TYPE_EDGE_FALLING: + ret =3D rtd1625_gpio_irq_set_edge_type(d, 0); + break; + case IRQ_TYPE_EDGE_BOTH: + ret =3D rtd1625_gpio_irq_set_edge_type(d, 1); + break; + case IRQ_TYPE_LEVEL_HIGH: + ret =3D rtd1625_gpio_irq_set_level_type(d, 0); + break; + case IRQ_TYPE_LEVEL_LOW: + ret =3D rtd1625_gpio_irq_set_level_type(d, 1); + break; + default: + ret =3D -EINVAL; + } + + return ret; +} + +static struct irq_chip rtd1625_iso_gpio_irq_chip =3D { + .name =3D "rtd1625-gpio", + .irq_ack =3D rtd1625_gpio_ack_irq, + .irq_mask =3D rtd1625_gpio_disable_irq, + .irq_unmask =3D rtd1625_gpio_enable_irq, + .irq_set_type =3D rtd1625_gpio_irq_set_type, + .flags =3D IRQCHIP_IMMUTABLE | IRQCHIP_SKIP_SET_WAKE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + +static int rtd1625_gpio_setup_irq(struct platform_device *pdev, struct rtd= 1625_gpio *data) +{ + struct gpio_irq_chip *irq_chip; + int num_irqs; + int irq; + int i; + + irq =3D platform_get_irq_optional(pdev, 0); + if (irq =3D=3D -ENXIO) + return 0; + if (irq < 0) + return irq; + + num_irqs =3D (data->info->irq_type_support & IRQ_TYPE_LEVEL_MASK) ? 3 : 2; + data->irqs[0] =3D irq; + + for (i =3D 1; i < num_irqs; i++) { + irq =3D platform_get_irq(pdev, i); + if (irq < 0) + return irq; + data->irqs[i] =3D irq; + } + + irq_chip =3D &data->gpio_chip.irq; + irq_chip->handler =3D handle_bad_irq; + irq_chip->default_type =3D IRQ_TYPE_NONE; + irq_chip->parent_handler =3D rtd1625_gpio_irq_handle; + irq_chip->parent_handler_data =3D data; + irq_chip->num_parents =3D num_irqs; + irq_chip->parents =3D data->irqs; + + gpio_irq_chip_set_chip(irq_chip, &rtd1625_iso_gpio_irq_chip); + + return 0; +} + +static int rtd1625_gpio_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct rtd1625_gpio *data; + int ret; + + data =3D devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->info =3D device_get_match_data(dev); + if (!data->info) + return -EINVAL; + + raw_spin_lock_init(&data->lock); + + data->base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(data->base)) + return PTR_ERR(data->base); + + data->irq_base =3D devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(data->irq_base)) + return PTR_ERR(data->irq_base); + + data->save_regs =3D devm_kzalloc(dev, data->info->num_gpios * + sizeof(*data->save_regs), GFP_KERNEL); + if (!data->save_regs) + return -ENOMEM; + + data->gpio_chip.label =3D dev_name(dev); + data->gpio_chip.base =3D -1; + data->gpio_chip.ngpio =3D data->info->num_gpios; + data->gpio_chip.request =3D gpiochip_generic_request; + data->gpio_chip.free =3D gpiochip_generic_free; + data->gpio_chip.get_direction =3D rtd1625_gpio_get_direction; + data->gpio_chip.direction_input =3D rtd1625_gpio_direction_input; + data->gpio_chip.direction_output =3D rtd1625_gpio_direction_output; + data->gpio_chip.set =3D rtd1625_gpio_set; + data->gpio_chip.get =3D rtd1625_gpio_get; + data->gpio_chip.set_config =3D rtd1625_gpio_set_config; + data->gpio_chip.parent =3D dev; + + ret =3D rtd1625_gpio_setup_irq(pdev, data); + if (ret) + return ret; + + platform_set_drvdata(pdev, data); + + return devm_gpiochip_add_data(dev, &data->gpio_chip, data); +} + +static const struct rtd1625_gpio_info rtd1625_iso_gpio_info =3D { + .num_gpios =3D 166, + .irq_type_support =3D IRQ_TYPE_EDGE_BOTH, + .gpa_offset =3D 0x0, + .gpda_offset =3D 0x20, + .write_en_all =3D RTD1625_ISO_GPIO_WREN_ALL, +}; + +static const struct rtd1625_gpio_info rtd1625_isom_gpio_info =3D { + .num_gpios =3D 4, + .irq_type_support =3D IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_LOW | + IRQ_TYPE_LEVEL_HIGH, + .gpa_offset =3D 0x0, + .gpda_offset =3D 0x4, + .level_offset =3D 0x18, + .write_en_all =3D RTD1625_ISOM_GPIO_WREN_ALL, +}; + +static const struct of_device_id rtd1625_gpio_of_matches[] =3D { + { .compatible =3D "realtek,rtd1625-iso-gpio", .data =3D &rtd1625_iso_gpio= _info }, + { .compatible =3D "realtek,rtd1625-isom-gpio", .data =3D &rtd1625_isom_gp= io_info }, + { } +}; +MODULE_DEVICE_TABLE(of, rtd1625_gpio_of_matches); + +static int rtd1625_gpio_suspend(struct device *dev) +{ + struct rtd1625_gpio *data =3D dev_get_drvdata(dev); + const struct rtd1625_gpio_info *info =3D data->info; + int i; + + for (i =3D 0; i < info->num_gpios; i++) + data->save_regs[i] =3D readl_relaxed(data->base + GPIO_CONTROL(i)); + + return 0; +} + +static int rtd1625_gpio_resume(struct device *dev) +{ + struct rtd1625_gpio *data =3D dev_get_drvdata(dev); + const struct rtd1625_gpio_info *info =3D data->info; + int i; + + for (i =3D 0; i < info->num_gpios; i++) + writel_relaxed(data->save_regs[i] | info->write_en_all, + data->base + GPIO_CONTROL(i)); + + return 0; +} + +DEFINE_NOIRQ_DEV_PM_OPS(rtd1625_gpio_pm_ops, rtd1625_gpio_suspend, rtd1625= _gpio_resume); + +static struct platform_driver rtd1625_gpio_platform_driver =3D { + .driver =3D { + .name =3D "gpio-rtd1625", + .of_match_table =3D rtd1625_gpio_of_matches, + .pm =3D pm_sleep_ptr(&rtd1625_gpio_pm_ops), + }, + .probe =3D rtd1625_gpio_probe, +}; +module_platform_driver(rtd1625_gpio_platform_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Realtek Semiconductor Corporation"); +MODULE_DESCRIPTION("Realtek DHC SoC RTD1625 gpio driver"); --=20 2.34.1