[PATCH v8 1/9] Revert "gpio: realtek: Add driver for Realtek DHC RTD1625 SoC"

Yu-Chun Lin <[email protected]> Sun, 26 Jul 2026 20:51:52 +0800
Newsgroups org.kernel.vger.linux-gpio,org.kernel.vger.linux-iio,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
This reverts commit a57e27c43b0315ee86c6896510d69be5257e093e.

The driver will be rewritten to use the gpio-regmap infrastructure
once Andy Shevchenko's patches for gpio-regmap are applied.

Acked-by: Andy Shevchenko <[email protected]>
Acked-by: Linus Walleij <[email protected]>
Signed-off-by: Yu-Chun Lin <[email protected]>
---
Changes in v8:
- Add Acked-by tag from Linus.
---
 drivers/gpio/Kconfig        |  12 -
 drivers/gpio/Makefile       |   1 -
 drivers/gpio/gpio-rtd1625.c | 611 ------------------------------------
 3 files changed, 624 deletions(-)
 delete mode 100644 drivers/gpio/gpio-rtd1625.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index f03c05288376..ed2bc3113374 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -656,18 +656,6 @@ config GPIO_RTD
 	  Say yes here to support GPIO functionality and GPIO interrupt on
 	  Realtek DHC SoCs.
 
-config GPIO_RTD1625
-	tristate "Realtek DHC RTD1625 GPIO support"
-	depends on ARCH_REALTEK || COMPILE_TEST
-	default ARCH_REALTEK
-	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 OF
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index fa14581e3995..4d0e900402fc 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -160,7 +160,6 @@ obj-$(CONFIG_GPIO_REALTEK_OTTO)		+= gpio-realtek-otto.o
 obj-$(CONFIG_GPIO_REG)			+= gpio-reg.o
 obj-$(CONFIG_GPIO_ROCKCHIP)	+= gpio-rockchip.o
 obj-$(CONFIG_GPIO_RTD)			+= gpio-rtd.o
-obj-$(CONFIG_GPIO_RTD1625)		+= gpio-rtd1625.o
 obj-$(CONFIG_ARCH_SA1100)		+= gpio-sa1100.o
 obj-$(CONFIG_GPIO_SAMA5D2_PIOBU)	+= gpio-sama5d2-piobu.o
 obj-$(CONFIG_GPIO_SCH311X)		+= gpio-sch311x.o
diff --git a/drivers/gpio/gpio-rtd1625.c b/drivers/gpio/gpio-rtd1625.c
deleted file mode 100644
index 409e540bf40b..000000000000
--- a/drivers/gpio/gpio-rtd1625.c
+++ /dev/null
@@ -1,611 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Realtek DHC RTD1625 gpio driver
- *
- * Copyright (c) 2023-2026 Realtek Semiconductor Corp.
- */
-
-#include <linux/bitfield.h>
-#include <linux/bitops.h>
-#include <linux/cleanup.h>
-#include <linux/gpio/driver.h>
-#include <linux/interrupt.h>
-#include <linux/irqchip.h>
-#include <linux/irqchip/chained_irq.h>
-#include <linux/irqdomain.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/property.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-
-#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)
-
-enum rtd1625_irq_index {
-	RTD1625_IRQ_ASSERT,
-	RTD1625_IRQ_DEASSERT,
-	RTD1625_IRQ_LEVEL,
-	RTD1625_MAX_IRQS
-};
-
-/**
- * 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	base_offset;
-	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[RTD1625_MAX_IRQS];
-	raw_spinlock_t			lock;
-	unsigned int			*save_regs;
-};
-
-static unsigned int rtd1625_gpio_gpa_offset(struct rtd1625_gpio *data, unsigned int offset)
-{
-	return data->info->gpa_offset + ((offset / 32) * 4);
-}
-
-static unsigned int rtd1625_gpio_gpda_offset(struct rtd1625_gpio *data, unsigned int offset)
-{
-	return data->info->gpda_offset + ((offset / 32) * 4);
-}
-
-static unsigned int rtd1625_gpio_level_offset(struct rtd1625_gpio *data, unsigned int offset)
-{
-	return data->info->level_offset + ((offset / 32) * 4);
-}
-
-static int rtd1625_gpio_set_debounce(struct gpio_chip *chip, unsigned int offset,
-				     unsigned int debounce)
-{
-	struct rtd1625_gpio *data = gpiochip_get_data(chip);
-	u8 deb_val;
-	u32 val;
-
-	switch (debounce) {
-	case 1:
-		deb_val = RTD1625_GPIO_DEBOUNCE_1US;
-		break;
-	case 10:
-		deb_val = RTD1625_GPIO_DEBOUNCE_10US;
-		break;
-	case 100:
-		deb_val = RTD1625_GPIO_DEBOUNCE_100US;
-		break;
-	case 1000:
-		deb_val = RTD1625_GPIO_DEBOUNCE_1MS;
-		break;
-	case 10000:
-		deb_val = RTD1625_GPIO_DEBOUNCE_10MS;
-		break;
-	case 20000:
-		deb_val = RTD1625_GPIO_DEBOUNCE_20MS;
-		break;
-	case 30000:
-		deb_val = RTD1625_GPIO_DEBOUNCE_30MS;
-		break;
-	case 50000:
-		deb_val = RTD1625_GPIO_DEBOUNCE_50MS;
-		break;
-	default:
-		return -ENOTSUPP;
-	}
-
-	val = FIELD_PREP(RTD1625_GPIO_DEBOUNCE, deb_val) | RTD1625_GPIO_DEBOUNCE_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 offset,
-				   unsigned long config)
-{
-	u32 debounce;
-
-	if (pinconf_to_config_param(config) == PIN_CONFIG_INPUT_DEBOUNCE) {
-		debounce = 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, int value)
-{
-	struct rtd1625_gpio *data = gpiochip_get_data(chip);
-	u32 val = RTD1625_GPIO_WREN(RTD1625_GPIO_OUT);
-
-	if (value)
-		val |= 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 = gpiochip_get_data(chip);
-	u32 val;
-
-	guard(raw_spinlock_irqsave)(&data->lock);
-
-	val = 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 = gpiochip_get_data(chip);
-	u32 val;
-
-	guard(raw_spinlock_irqsave)(&data->lock);
-
-	val = 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 = gpiochip_get_data(chip);
-	u32 val = RTD1625_GPIO_WREN(RTD1625_GPIO_DIR);
-
-	if (out)
-		val |= 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 int 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 offset);
-	struct rtd1625_gpio *data = irq_desc_get_handler_data(desc);
-	struct irq_domain *domain = data->gpio_chip.irq.domain;
-	struct irq_chip *chip = irq_desc_get_chip(desc);
-	unsigned int irq = 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 == data->irqs[RTD1625_IRQ_ASSERT])
-		get_reg_offset = &rtd1625_gpio_gpa_offset;
-	else if (irq == data->irqs[RTD1625_IRQ_DEASSERT])
-		get_reg_offset = &rtd1625_gpio_gpda_offset;
-	else if (irq == data->irqs[2])
-		get_reg_offset = &rtd1625_gpio_level_offset;
-	else
-		return;
-
-	chained_irq_enter(chip, desc);
-
-	for (i = 0; i < data->info->num_gpios; i += 32) {
-		reg_offset = get_reg_offset(data, i);
-		status = readl_relaxed(data->irq_base + reg_offset);
-
-		/*
-		 * Hardware quirk: The controller fires both "assert" and "de-assert"
-		 * interrupts simultaneously on any edge toggle.
-		 * We must pre-clear edge interrupts here. If we drop an unwanted
-		 * de-assert interrupt below, it will never reach the IRQ core
-		 * (generic_handle_domain_irq), meaning ->irq_ack() won't be called.
-		 * Failing to clear it here leads to an interrupt storm.
-		 */
-		if (irq != data->irqs[RTD1625_IRQ_LEVEL])
-			writel_relaxed(status, data->irq_base + reg_offset);
-
-		for_each_set_bit(j, &status, 32) {
-			hwirq = i + j;
-			girq = irq_find_mapping(domain, hwirq);
-			irq_type = irq_get_trigger_type(girq);
-
-			/*
-			 * Filter out the hardware-forced de-assert interrupt unless
-			 * the user explicitly requested IRQ_TYPE_EDGE_BOTH.
-			 */
-			if (irq == data->irqs[RTD1625_IRQ_DEASSERT] &&
-			    irq_type != 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 = irq_data_get_irq_chip_data(d);
-	irq_hw_number_t hwirq = irqd_to_hwirq(d);
-	u32 irq_type = irqd_get_trigger_type(d);
-	u32 bit_mask = BIT(hwirq % 32);
-	int reg_offset;
-
-	if (irq_type & IRQ_TYPE_LEVEL_MASK) {
-		reg_offset = 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 = rtd1625_gpio_gpda_offset(data, hwirq);
-	int gpa_reg_offset = rtd1625_gpio_gpa_offset(data, hwirq);
-	u32 clr_mask = 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 = RTD1625_GPIO_EDGE_INT_EN | RTD1625_GPIO_WREN(RTD1625_GPIO_EDGE_INT_EN);
-	writel_relaxed(val, data->base + GPIO_CONTROL(hwirq));
-}
-
-static void rtd1625_gpio_disable_edge_irq(struct rtd1625_gpio *data, irq_hw_number_t hwirq)
-{
-	u32 val;
-
-	guard(raw_spinlock_irqsave)(&data->lock);
-
-	val = 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_hw_number_t hwirq)
-{
-	int level_reg_offset = rtd1625_gpio_level_offset(data, hwirq);
-	u32 clr_mask = BIT(hwirq % 32);
-	u32 val;
-
-	guard(raw_spinlock_irqsave)(&data->lock);
-
-	writel_relaxed(clr_mask, data->irq_base + level_reg_offset);
-	val = 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 = 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 = irq_data_get_irq_chip_data(d);
-	struct rtd1625_gpio *data = gpiochip_get_data(gc);
-	irq_hw_number_t hwirq = irqd_to_hwirq(d);
-	u32 irq_type = 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 = irq_data_get_irq_chip_data(d);
-	struct rtd1625_gpio *data = gpiochip_get_data(gc);
-	irq_hw_number_t hwirq = irqd_to_hwirq(d);
-	u32 irq_type = 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 = irq_data_get_irq_chip_data(d);
-	struct rtd1625_gpio *data = gpiochip_get_data(gc);
-	irq_hw_number_t hwirq = irqd_to_hwirq(d);
-	u32 val = RTD1625_GPIO_WREN(RTD1625_GPIO_LEVEL_INT_DP);
-
-	if (!(data->info->irq_type_support & IRQ_TYPE_LEVEL_MASK))
-		return -EINVAL;
-
-	if (level)
-		val |= RTD1625_GPIO_LEVEL_INT_DP;
-
-	scoped_guard(raw_spinlock_irqsave, &data->lock)
-		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 polarity)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	struct rtd1625_gpio *data = gpiochip_get_data(gc);
-	irq_hw_number_t hwirq = irqd_to_hwirq(d);
-	u32 val = RTD1625_GPIO_WREN(RTD1625_GPIO_EDGE_INT_DP);
-
-	if (!(data->info->irq_type_support & IRQ_TYPE_EDGE_BOTH))
-		return -EINVAL;
-
-	if (polarity)
-		val |= RTD1625_GPIO_EDGE_INT_DP;
-
-	scoped_guard(raw_spinlock_irqsave, &data->lock)
-		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)
-{
-	switch (type & IRQ_TYPE_SENSE_MASK) {
-	case IRQ_TYPE_EDGE_RISING:
-		return rtd1625_gpio_irq_set_edge_type(d, 1);
-
-	case IRQ_TYPE_EDGE_FALLING:
-		return rtd1625_gpio_irq_set_edge_type(d, 0);
-
-	case IRQ_TYPE_EDGE_BOTH:
-		return rtd1625_gpio_irq_set_edge_type(d, 1);
-
-	case IRQ_TYPE_LEVEL_HIGH:
-		return rtd1625_gpio_irq_set_level_type(d, 0);
-
-	case IRQ_TYPE_LEVEL_LOW:
-		return rtd1625_gpio_irq_set_level_type(d, 1);
-
-	default:
-		return -EINVAL;
-	}
-}
-
-static struct irq_chip rtd1625_iso_gpio_irq_chip = {
-	.name = "rtd1625-gpio",
-	.irq_ack = rtd1625_gpio_ack_irq,
-	.irq_mask = rtd1625_gpio_disable_irq,
-	.irq_unmask = rtd1625_gpio_enable_irq,
-	.irq_set_type = rtd1625_gpio_irq_set_type,
-	.flags = IRQCHIP_IMMUTABLE | IRQCHIP_SKIP_SET_WAKE,
-	GPIOCHIP_IRQ_RESOURCE_HELPERS,
-};
-
-static int rtd1625_gpio_setup_irq(struct platform_device *pdev, struct rtd1625_gpio *data)
-{
-	struct gpio_irq_chip *irq_chip;
-	unsigned int num_irqs;
-	int irq;
-
-	/*
-	 * Interrupt support is optional. All IRQs must be provided together.
-	 * If index 0 is missing, we assume no interrupts are configured in DT
-	 * and fall back to basic GPIO operation.
-	 */
-	irq = platform_get_irq_optional(pdev, 0);
-	if (irq == -ENXIO)
-		return 0;
-	if (irq < 0)
-		return irq;
-
-	num_irqs = (data->info->irq_type_support & IRQ_TYPE_LEVEL_MASK) ? 3 : 2;
-	data->irqs[RTD1625_IRQ_ASSERT] = irq;
-
-	for (unsigned int i = 1; i < num_irqs; i++) {
-		irq = platform_get_irq(pdev, i);
-		if (irq < 0)
-			return irq;
-		data->irqs[i] = irq;
-	}
-
-	irq_chip = &data->gpio_chip.irq;
-	irq_chip->handler = handle_bad_irq;
-	irq_chip->default_type = IRQ_TYPE_NONE;
-	irq_chip->parent_handler = rtd1625_gpio_irq_handle;
-	irq_chip->parent_handler_data = data;
-	irq_chip->num_parents = num_irqs;
-	irq_chip->parents = 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 = &pdev->dev;
-	struct rtd1625_gpio *data;
-	void __iomem *irq_base;
-	int ret;
-
-	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	data->info = device_get_match_data(dev);
-	if (!data->info)
-		return -EINVAL;
-
-	raw_spin_lock_init(&data->lock);
-
-	irq_base = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(irq_base))
-		return PTR_ERR(irq_base);
-
-	data->irq_base = irq_base;
-	data->base = irq_base + data->info->base_offset;
-
-	data->save_regs = devm_kcalloc(dev, data->info->num_gpios, sizeof(*data->save_regs),
-				       GFP_KERNEL);
-	if (!data->save_regs)
-		return -ENOMEM;
-
-	data->gpio_chip.label = dev_name(dev);
-	data->gpio_chip.base = -1;
-	data->gpio_chip.ngpio = data->info->num_gpios;
-	data->gpio_chip.request = gpiochip_generic_request;
-	data->gpio_chip.free = gpiochip_generic_free;
-	data->gpio_chip.get_direction = rtd1625_gpio_get_direction;
-	data->gpio_chip.direction_input = rtd1625_gpio_direction_input;
-	data->gpio_chip.direction_output = rtd1625_gpio_direction_output;
-	data->gpio_chip.set = rtd1625_gpio_set;
-	data->gpio_chip.get = rtd1625_gpio_get;
-	data->gpio_chip.set_config = rtd1625_gpio_set_config;
-	data->gpio_chip.parent = dev;
-
-	ret = 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 = {
-	.num_gpios        = 166,
-	.irq_type_support = IRQ_TYPE_EDGE_BOTH,
-	.base_offset      = 0x100,
-	.gpa_offset       = 0x000,
-	.gpda_offset      = 0x020,
-	.write_en_all     = RTD1625_ISO_GPIO_WREN_ALL,
-};
-
-static const struct rtd1625_gpio_info rtd1625_isom_gpio_info = {
-	.num_gpios        = 4,
-	.irq_type_support = IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_LOW |
-			    IRQ_TYPE_LEVEL_HIGH,
-	.base_offset      = 0x20,
-	.gpa_offset       = 0x00,
-	.gpda_offset      = 0x04,
-	.level_offset     = 0x18,
-	.write_en_all     = RTD1625_ISOM_GPIO_WREN_ALL,
-};
-
-static int rtd1625_gpio_suspend(struct device *dev)
-{
-	struct rtd1625_gpio *data = dev_get_drvdata(dev);
-	const struct rtd1625_gpio_info *info = data->info;
-
-	for (unsigned int i = 0; i < info->num_gpios; i++)
-		data->save_regs[i] = readl_relaxed(data->base + GPIO_CONTROL(i));
-
-	return 0;
-}
-
-static int rtd1625_gpio_resume(struct device *dev)
-{
-	struct rtd1625_gpio *data = dev_get_drvdata(dev);
-	const struct rtd1625_gpio_info *info = data->info;
-
-	for (unsigned int i = 0; i < info->num_gpios; i++)
-		writel_relaxed(data->save_regs[i] | info->write_en_all,
-			       data->base + GPIO_CONTROL(i));
-
-	return 0;
-}
-
-static DEFINE_NOIRQ_DEV_PM_OPS(rtd1625_gpio_pm_ops, rtd1625_gpio_suspend, rtd1625_gpio_resume);
-
-static const struct of_device_id rtd1625_gpio_of_matches[] = {
-	{ .compatible = "realtek,rtd1625-iso-gpio", .data = &rtd1625_iso_gpio_info },
-	{ .compatible = "realtek,rtd1625-isom-gpio", .data = &rtd1625_isom_gpio_info },
-	{ }
-};
-MODULE_DEVICE_TABLE(of, rtd1625_gpio_of_matches);
-
-static struct platform_driver rtd1625_gpio_platform_driver = {
-	.driver = {
-		.name = "gpio-rtd1625",
-		.of_match_table = rtd1625_gpio_of_matches,
-		.pm = pm_sleep_ptr(&rtd1625_gpio_pm_ops),
-	},
-	.probe = 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");
-- 
2.43.0