1*6435d21cSTzuyi Chang // SPDX-License-Identifier: GPL-2.0-or-later 2*6435d21cSTzuyi Chang /* 3*6435d21cSTzuyi Chang * Realtek DHC RTD1625 gpio driver 4*6435d21cSTzuyi Chang * 5*6435d21cSTzuyi Chang * Copyright (c) 2023-2026 Realtek Semiconductor Corp. 6*6435d21cSTzuyi Chang */ 7*6435d21cSTzuyi Chang 8*6435d21cSTzuyi Chang #include <linux/bitfield.h> 9*6435d21cSTzuyi Chang #include <linux/bitops.h> 10*6435d21cSTzuyi Chang #include <linux/cleanup.h> 11*6435d21cSTzuyi Chang #include <linux/gpio/driver.h> 12*6435d21cSTzuyi Chang #include <linux/gpio/regmap.h> 13*6435d21cSTzuyi Chang #include <linux/interrupt.h> 14*6435d21cSTzuyi Chang #include <linux/irqchip.h> 15*6435d21cSTzuyi Chang #include <linux/irqchip/chained_irq.h> 16*6435d21cSTzuyi Chang #include <linux/irqdomain.h> 17*6435d21cSTzuyi Chang #include <linux/module.h> 18*6435d21cSTzuyi Chang #include <linux/platform_device.h> 19*6435d21cSTzuyi Chang #include <linux/property.h> 20*6435d21cSTzuyi Chang #include <linux/regmap.h> 21*6435d21cSTzuyi Chang #include <linux/spinlock.h> 22*6435d21cSTzuyi Chang #include <linux/types.h> 23*6435d21cSTzuyi Chang 24*6435d21cSTzuyi Chang #define RTD1625_GPIO_DIR BIT(0) 25*6435d21cSTzuyi Chang #define RTD1625_GPIO_OUT BIT(2) 26*6435d21cSTzuyi Chang #define RTD1625_GPIO_IN BIT(4) 27*6435d21cSTzuyi Chang #define RTD1625_GPIO_EDGE_INT_DP BIT(6) 28*6435d21cSTzuyi Chang #define RTD1625_GPIO_EDGE_INT_EN BIT(8) 29*6435d21cSTzuyi Chang #define RTD1625_GPIO_LEVEL_INT_EN BIT(16) 30*6435d21cSTzuyi Chang #define RTD1625_GPIO_LEVEL_INT_DP BIT(18) 31*6435d21cSTzuyi Chang #define RTD1625_GPIO_DEBOUNCE GENMASK(30, 28) 32*6435d21cSTzuyi Chang #define RTD1625_GPIO_DEBOUNCE_WREN BIT(31) 33*6435d21cSTzuyi Chang 34*6435d21cSTzuyi Chang #define RTD1625_GPIO_WREN(x) ((x) << 1) 35*6435d21cSTzuyi Chang 36*6435d21cSTzuyi Chang /* Write-enable masks for all GPIO configs and reserved hardware bits */ 37*6435d21cSTzuyi Chang #define RTD1625_ISO_GPIO_WREN_ALL 0x8000aa8a 38*6435d21cSTzuyi Chang #define RTD1625_ISOM_GPIO_WREN_ALL 0x800aaa8a 39*6435d21cSTzuyi Chang 40*6435d21cSTzuyi Chang #define RTD1625_GPIO_DEBOUNCE_1US 0 41*6435d21cSTzuyi Chang #define RTD1625_GPIO_DEBOUNCE_10US 1 42*6435d21cSTzuyi Chang #define RTD1625_GPIO_DEBOUNCE_100US 2 43*6435d21cSTzuyi Chang #define RTD1625_GPIO_DEBOUNCE_1MS 3 44*6435d21cSTzuyi Chang #define RTD1625_GPIO_DEBOUNCE_10MS 4 45*6435d21cSTzuyi Chang #define RTD1625_GPIO_DEBOUNCE_20MS 5 46*6435d21cSTzuyi Chang #define RTD1625_GPIO_DEBOUNCE_30MS 6 47*6435d21cSTzuyi Chang #define RTD1625_GPIO_DEBOUNCE_50MS 7 48*6435d21cSTzuyi Chang 49*6435d21cSTzuyi Chang #define GPIO_CONTROL(gpio) ((gpio) * 4) 50*6435d21cSTzuyi Chang 51*6435d21cSTzuyi Chang static struct lock_class_key rtd1625_gpio_irq_lock_class; 52*6435d21cSTzuyi Chang static struct lock_class_key rtd1625_gpio_irq_request_class; 53*6435d21cSTzuyi Chang 54*6435d21cSTzuyi Chang enum rtd1625_irq_index { 55*6435d21cSTzuyi Chang RTD1625_IRQ_ASSERT, 56*6435d21cSTzuyi Chang RTD1625_IRQ_DEASSERT, 57*6435d21cSTzuyi Chang RTD1625_IRQ_LEVEL, 58*6435d21cSTzuyi Chang RTD1625_MAX_IRQS 59*6435d21cSTzuyi Chang }; 60*6435d21cSTzuyi Chang 61*6435d21cSTzuyi Chang /** 62*6435d21cSTzuyi Chang * struct rtd1625_gpio_info - Specific GPIO register information 63*6435d21cSTzuyi Chang * @num_gpios: The number of GPIOs 64*6435d21cSTzuyi Chang * @irq_type_support: Supported IRQ types 65*6435d21cSTzuyi Chang * @base_offset: Offset for GPIO controller register 66*6435d21cSTzuyi Chang * @gpa_offset: Offset for GPIO assert interrupt status register 67*6435d21cSTzuyi Chang * @gpda_offset: Offset for GPIO deassert interrupt status register 68*6435d21cSTzuyi Chang * @level_offset: Offset of level interrupt status register 69*6435d21cSTzuyi Chang * @write_en_all: Write-enable mask for all configurable bits 70*6435d21cSTzuyi Chang */ 71*6435d21cSTzuyi Chang struct rtd1625_gpio_info { 72*6435d21cSTzuyi Chang unsigned int num_gpios; 73*6435d21cSTzuyi Chang unsigned int irq_type_support; 74*6435d21cSTzuyi Chang unsigned int base_offset; 75*6435d21cSTzuyi Chang unsigned int gpa_offset; 76*6435d21cSTzuyi Chang unsigned int gpda_offset; 77*6435d21cSTzuyi Chang unsigned int level_offset; 78*6435d21cSTzuyi Chang unsigned int write_en_all; 79*6435d21cSTzuyi Chang }; 80*6435d21cSTzuyi Chang 81*6435d21cSTzuyi Chang struct rtd1625_gpio { 82*6435d21cSTzuyi Chang struct gpio_regmap *gpio_reg; 83*6435d21cSTzuyi Chang const struct rtd1625_gpio_info *info; 84*6435d21cSTzuyi Chang struct regmap *regmap; 85*6435d21cSTzuyi Chang unsigned int irqs[RTD1625_MAX_IRQS]; 86*6435d21cSTzuyi Chang raw_spinlock_t lock; 87*6435d21cSTzuyi Chang struct irq_domain *domain; 88*6435d21cSTzuyi Chang unsigned int *save_regs; 89*6435d21cSTzuyi Chang }; 90*6435d21cSTzuyi Chang 91*6435d21cSTzuyi Chang static unsigned int rtd1625_gpio_gpa_offset(struct rtd1625_gpio *data, unsigned int offset) 92*6435d21cSTzuyi Chang { 93*6435d21cSTzuyi Chang return data->info->gpa_offset + ((offset / 32) * 4); 94*6435d21cSTzuyi Chang } 95*6435d21cSTzuyi Chang 96*6435d21cSTzuyi Chang static unsigned int rtd1625_gpio_gpda_offset(struct rtd1625_gpio *data, unsigned int offset) 97*6435d21cSTzuyi Chang { 98*6435d21cSTzuyi Chang return data->info->gpda_offset + ((offset / 32) * 4); 99*6435d21cSTzuyi Chang } 100*6435d21cSTzuyi Chang 101*6435d21cSTzuyi Chang static unsigned int rtd1625_gpio_level_offset(struct rtd1625_gpio *data, unsigned int offset) 102*6435d21cSTzuyi Chang { 103*6435d21cSTzuyi Chang return data->info->level_offset + ((offset / 32) * 4); 104*6435d21cSTzuyi Chang } 105*6435d21cSTzuyi Chang 106*6435d21cSTzuyi Chang static int rtd1625_reg_mask_xlate(struct gpio_regmap *gpio, enum gpio_regmap_operation op, 107*6435d21cSTzuyi Chang unsigned int base, unsigned int offset, unsigned int *reg, 108*6435d21cSTzuyi Chang unsigned int *mask) 109*6435d21cSTzuyi Chang { 110*6435d21cSTzuyi Chang /* Each GPIO has its own dedicated 32-bit register */ 111*6435d21cSTzuyi Chang struct rtd1625_gpio *data = gpio_regmap_get_drvdata(gpio); 112*6435d21cSTzuyi Chang int val = 0, ret = 0; 113*6435d21cSTzuyi Chang *reg = base + offset * 4; 114*6435d21cSTzuyi Chang 115*6435d21cSTzuyi Chang switch (op) { 116*6435d21cSTzuyi Chang case GPIO_REGMAP_SET_OP: 117*6435d21cSTzuyi Chang *mask = RTD1625_GPIO_OUT; 118*6435d21cSTzuyi Chang return 0; 119*6435d21cSTzuyi Chang 120*6435d21cSTzuyi Chang case GPIO_REGMAP_GET_OP: 121*6435d21cSTzuyi Chang ret = regmap_read(data->regmap, *reg, &val); 122*6435d21cSTzuyi Chang if (ret) 123*6435d21cSTzuyi Chang return ret; 124*6435d21cSTzuyi Chang 125*6435d21cSTzuyi Chang if (val & RTD1625_GPIO_DIR) 126*6435d21cSTzuyi Chang *mask = RTD1625_GPIO_OUT; 127*6435d21cSTzuyi Chang else 128*6435d21cSTzuyi Chang *mask = RTD1625_GPIO_IN; 129*6435d21cSTzuyi Chang return 0; 130*6435d21cSTzuyi Chang 131*6435d21cSTzuyi Chang case GPIO_REGMAP_GET_DIR_OP: 132*6435d21cSTzuyi Chang case GPIO_REGMAP_SET_DIR_OP: 133*6435d21cSTzuyi Chang *mask = RTD1625_GPIO_DIR; 134*6435d21cSTzuyi Chang return 0; 135*6435d21cSTzuyi Chang 136*6435d21cSTzuyi Chang default: 137*6435d21cSTzuyi Chang return -ENOTSUPP; 138*6435d21cSTzuyi Chang } 139*6435d21cSTzuyi Chang } 140*6435d21cSTzuyi Chang 141*6435d21cSTzuyi Chang static int rtd1625_value_xlate(struct gpio_regmap *gpio, 142*6435d21cSTzuyi Chang enum gpio_regmap_operation op, 143*6435d21cSTzuyi Chang unsigned int base, unsigned int offset, 144*6435d21cSTzuyi Chang unsigned int reg, unsigned int *mask, 145*6435d21cSTzuyi Chang unsigned int *val) 146*6435d21cSTzuyi Chang { 147*6435d21cSTzuyi Chang switch (op) { 148*6435d21cSTzuyi Chang case GPIO_REGMAP_SET_OP: 149*6435d21cSTzuyi Chang *val |= RTD1625_GPIO_WREN(RTD1625_GPIO_OUT); 150*6435d21cSTzuyi Chang *mask |= RTD1625_GPIO_WREN(RTD1625_GPIO_OUT); 151*6435d21cSTzuyi Chang return 0; 152*6435d21cSTzuyi Chang 153*6435d21cSTzuyi Chang case GPIO_REGMAP_SET_DIR_OP: 154*6435d21cSTzuyi Chang *val |= RTD1625_GPIO_WREN(RTD1625_GPIO_DIR); 155*6435d21cSTzuyi Chang *mask |= RTD1625_GPIO_WREN(RTD1625_GPIO_DIR); 156*6435d21cSTzuyi Chang return 0; 157*6435d21cSTzuyi Chang 158*6435d21cSTzuyi Chang default: 159*6435d21cSTzuyi Chang return -ENOTSUPP; 160*6435d21cSTzuyi Chang } 161*6435d21cSTzuyi Chang } 162*6435d21cSTzuyi Chang 163*6435d21cSTzuyi Chang static int rtd1625_gpio_set_debounce(struct rtd1625_gpio *data, unsigned int offset, 164*6435d21cSTzuyi Chang unsigned int debounce) 165*6435d21cSTzuyi Chang { 166*6435d21cSTzuyi Chang u8 deb_val; 167*6435d21cSTzuyi Chang u32 val; 168*6435d21cSTzuyi Chang 169*6435d21cSTzuyi Chang switch (debounce) { 170*6435d21cSTzuyi Chang case 1: 171*6435d21cSTzuyi Chang deb_val = RTD1625_GPIO_DEBOUNCE_1US; 172*6435d21cSTzuyi Chang break; 173*6435d21cSTzuyi Chang case 10: 174*6435d21cSTzuyi Chang deb_val = RTD1625_GPIO_DEBOUNCE_10US; 175*6435d21cSTzuyi Chang break; 176*6435d21cSTzuyi Chang case 100: 177*6435d21cSTzuyi Chang deb_val = RTD1625_GPIO_DEBOUNCE_100US; 178*6435d21cSTzuyi Chang break; 179*6435d21cSTzuyi Chang case 1000: 180*6435d21cSTzuyi Chang deb_val = RTD1625_GPIO_DEBOUNCE_1MS; 181*6435d21cSTzuyi Chang break; 182*6435d21cSTzuyi Chang case 10000: 183*6435d21cSTzuyi Chang deb_val = RTD1625_GPIO_DEBOUNCE_10MS; 184*6435d21cSTzuyi Chang break; 185*6435d21cSTzuyi Chang case 20000: 186*6435d21cSTzuyi Chang deb_val = RTD1625_GPIO_DEBOUNCE_20MS; 187*6435d21cSTzuyi Chang break; 188*6435d21cSTzuyi Chang case 30000: 189*6435d21cSTzuyi Chang deb_val = RTD1625_GPIO_DEBOUNCE_30MS; 190*6435d21cSTzuyi Chang break; 191*6435d21cSTzuyi Chang case 50000: 192*6435d21cSTzuyi Chang deb_val = RTD1625_GPIO_DEBOUNCE_50MS; 193*6435d21cSTzuyi Chang break; 194*6435d21cSTzuyi Chang default: 195*6435d21cSTzuyi Chang return -ENOTSUPP; 196*6435d21cSTzuyi Chang } 197*6435d21cSTzuyi Chang 198*6435d21cSTzuyi Chang val = FIELD_PREP(RTD1625_GPIO_DEBOUNCE, deb_val) | RTD1625_GPIO_DEBOUNCE_WREN; 199*6435d21cSTzuyi Chang 200*6435d21cSTzuyi Chang guard(raw_spinlock_irqsave)(&data->lock); 201*6435d21cSTzuyi Chang 202*6435d21cSTzuyi Chang return regmap_write(data->regmap, data->info->base_offset + GPIO_CONTROL(offset), val); 203*6435d21cSTzuyi Chang } 204*6435d21cSTzuyi Chang 205*6435d21cSTzuyi Chang static int rtd1625_gpio_set_config(struct gpio_regmap *gpio, struct gpio_chip *chip, 206*6435d21cSTzuyi Chang unsigned int offset, unsigned long config) 207*6435d21cSTzuyi Chang { 208*6435d21cSTzuyi Chang struct rtd1625_gpio *data = gpio_regmap_get_drvdata(gpio); 209*6435d21cSTzuyi Chang u32 debounce; 210*6435d21cSTzuyi Chang 211*6435d21cSTzuyi Chang if (pinconf_to_config_param(config) == PIN_CONFIG_INPUT_DEBOUNCE) { 212*6435d21cSTzuyi Chang debounce = pinconf_to_config_argument(config); 213*6435d21cSTzuyi Chang return rtd1625_gpio_set_debounce(data, offset, debounce); 214*6435d21cSTzuyi Chang } 215*6435d21cSTzuyi Chang 216*6435d21cSTzuyi Chang return gpiochip_generic_config(chip, offset, config); 217*6435d21cSTzuyi Chang } 218*6435d21cSTzuyi Chang 219*6435d21cSTzuyi Chang static void rtd1625_gpio_irq_handle(struct irq_desc *desc) 220*6435d21cSTzuyi Chang { 221*6435d21cSTzuyi Chang unsigned int (*get_reg_offset)(struct rtd1625_gpio *gpio, unsigned int offset); 222*6435d21cSTzuyi Chang struct rtd1625_gpio *data = irq_desc_get_handler_data(desc); 223*6435d21cSTzuyi Chang struct irq_chip *chip = irq_desc_get_chip(desc); 224*6435d21cSTzuyi Chang unsigned int irq = irq_desc_get_irq(desc); 225*6435d21cSTzuyi Chang struct irq_domain *domain = data->domain; 226*6435d21cSTzuyi Chang unsigned int reg_offset, i, j, val; 227*6435d21cSTzuyi Chang irq_hw_number_t hwirq; 228*6435d21cSTzuyi Chang unsigned long status; 229*6435d21cSTzuyi Chang u32 irq_type; 230*6435d21cSTzuyi Chang int ret; 231*6435d21cSTzuyi Chang 232*6435d21cSTzuyi Chang if (irq == data->irqs[RTD1625_IRQ_ASSERT]) 233*6435d21cSTzuyi Chang get_reg_offset = &rtd1625_gpio_gpa_offset; 234*6435d21cSTzuyi Chang else if (irq == data->irqs[RTD1625_IRQ_DEASSERT]) 235*6435d21cSTzuyi Chang get_reg_offset = &rtd1625_gpio_gpda_offset; 236*6435d21cSTzuyi Chang else if (irq == data->irqs[RTD1625_IRQ_LEVEL]) 237*6435d21cSTzuyi Chang get_reg_offset = &rtd1625_gpio_level_offset; 238*6435d21cSTzuyi Chang else 239*6435d21cSTzuyi Chang return; 240*6435d21cSTzuyi Chang 241*6435d21cSTzuyi Chang chained_irq_enter(chip, desc); 242*6435d21cSTzuyi Chang 243*6435d21cSTzuyi Chang for (i = 0; i < data->info->num_gpios; i += 32) { 244*6435d21cSTzuyi Chang reg_offset = get_reg_offset(data, i); 245*6435d21cSTzuyi Chang ret = regmap_read(data->regmap, reg_offset, &val); 246*6435d21cSTzuyi Chang if (ret) { 247*6435d21cSTzuyi Chang pr_err_ratelimited("Failed to read IRQ status for GPIO %u: %d\n", i, ret); 248*6435d21cSTzuyi Chang continue; 249*6435d21cSTzuyi Chang } 250*6435d21cSTzuyi Chang 251*6435d21cSTzuyi Chang status = val; 252*6435d21cSTzuyi Chang 253*6435d21cSTzuyi Chang /* 254*6435d21cSTzuyi Chang * Hardware quirk: The controller fires both "assert" and "de-assert" 255*6435d21cSTzuyi Chang * interrupts simultaneously on any edge toggle. 256*6435d21cSTzuyi Chang * We must pre-clear edge interrupts here. If we drop an unwanted 257*6435d21cSTzuyi Chang * de-assert interrupt below, it will never reach the IRQ core 258*6435d21cSTzuyi Chang * (generic_handle_domain_irq), meaning ->irq_ack() won't be called. 259*6435d21cSTzuyi Chang * Failing to clear it here leads to an interrupt storm. 260*6435d21cSTzuyi Chang */ 261*6435d21cSTzuyi Chang if (irq != data->irqs[RTD1625_IRQ_LEVEL]) { 262*6435d21cSTzuyi Chang ret = regmap_write(data->regmap, reg_offset, status); 263*6435d21cSTzuyi Chang if (ret) 264*6435d21cSTzuyi Chang pr_err_ratelimited("Failed to clear edge IRQ for GPIO %u: %d\n", 265*6435d21cSTzuyi Chang i, ret); 266*6435d21cSTzuyi Chang } 267*6435d21cSTzuyi Chang 268*6435d21cSTzuyi Chang for_each_set_bit(j, &status, 32) { 269*6435d21cSTzuyi Chang hwirq = i + j; 270*6435d21cSTzuyi Chang irq_type = irq_get_trigger_type(irq_find_mapping(domain, hwirq)); 271*6435d21cSTzuyi Chang 272*6435d21cSTzuyi Chang /* 273*6435d21cSTzuyi Chang * Filter out the hardware-forced de-assert interrupt unless 274*6435d21cSTzuyi Chang * the user explicitly requested IRQ_TYPE_EDGE_BOTH. 275*6435d21cSTzuyi Chang */ 276*6435d21cSTzuyi Chang if (irq == data->irqs[RTD1625_IRQ_DEASSERT] && 277*6435d21cSTzuyi Chang irq_type != IRQ_TYPE_EDGE_BOTH) 278*6435d21cSTzuyi Chang continue; 279*6435d21cSTzuyi Chang 280*6435d21cSTzuyi Chang generic_handle_domain_irq(domain, hwirq); 281*6435d21cSTzuyi Chang } 282*6435d21cSTzuyi Chang } 283*6435d21cSTzuyi Chang 284*6435d21cSTzuyi Chang chained_irq_exit(chip, desc); 285*6435d21cSTzuyi Chang } 286*6435d21cSTzuyi Chang 287*6435d21cSTzuyi Chang static void rtd1625_gpio_ack_irq(struct irq_data *d) 288*6435d21cSTzuyi Chang { 289*6435d21cSTzuyi Chang struct rtd1625_gpio *data = irq_data_get_irq_chip_data(d); 290*6435d21cSTzuyi Chang irq_hw_number_t hwirq = irqd_to_hwirq(d); 291*6435d21cSTzuyi Chang u32 irq_type = irqd_get_trigger_type(d); 292*6435d21cSTzuyi Chang u32 bit_mask = BIT(hwirq % 32); 293*6435d21cSTzuyi Chang int reg_offset; 294*6435d21cSTzuyi Chang 295*6435d21cSTzuyi Chang if (irq_type & IRQ_TYPE_LEVEL_MASK) { 296*6435d21cSTzuyi Chang reg_offset = rtd1625_gpio_level_offset(data, hwirq); 297*6435d21cSTzuyi Chang regmap_write(data->regmap, reg_offset, bit_mask); 298*6435d21cSTzuyi Chang } 299*6435d21cSTzuyi Chang } 300*6435d21cSTzuyi Chang 301*6435d21cSTzuyi Chang static void rtd1625_gpio_enable_edge_irq(struct rtd1625_gpio *data, irq_hw_number_t hwirq) 302*6435d21cSTzuyi Chang { 303*6435d21cSTzuyi Chang int gpda_reg_offset = rtd1625_gpio_gpda_offset(data, hwirq); 304*6435d21cSTzuyi Chang int gpa_reg_offset = rtd1625_gpio_gpa_offset(data, hwirq); 305*6435d21cSTzuyi Chang u32 clr_mask = BIT(hwirq % 32); 306*6435d21cSTzuyi Chang u32 val; 307*6435d21cSTzuyi Chang 308*6435d21cSTzuyi Chang guard(raw_spinlock_irqsave)(&data->lock); 309*6435d21cSTzuyi Chang 310*6435d21cSTzuyi Chang regmap_write(data->regmap, gpa_reg_offset, clr_mask); 311*6435d21cSTzuyi Chang regmap_write(data->regmap, gpda_reg_offset, clr_mask); 312*6435d21cSTzuyi Chang val = RTD1625_GPIO_EDGE_INT_EN | RTD1625_GPIO_WREN(RTD1625_GPIO_EDGE_INT_EN); 313*6435d21cSTzuyi Chang regmap_write(data->regmap, data->info->base_offset + GPIO_CONTROL(hwirq), val); 314*6435d21cSTzuyi Chang } 315*6435d21cSTzuyi Chang 316*6435d21cSTzuyi Chang static void rtd1625_gpio_disable_edge_irq(struct rtd1625_gpio *data, irq_hw_number_t hwirq) 317*6435d21cSTzuyi Chang { 318*6435d21cSTzuyi Chang u32 val; 319*6435d21cSTzuyi Chang 320*6435d21cSTzuyi Chang guard(raw_spinlock_irqsave)(&data->lock); 321*6435d21cSTzuyi Chang 322*6435d21cSTzuyi Chang val = RTD1625_GPIO_WREN(RTD1625_GPIO_EDGE_INT_EN); 323*6435d21cSTzuyi Chang regmap_write(data->regmap, data->info->base_offset + GPIO_CONTROL(hwirq), val); 324*6435d21cSTzuyi Chang } 325*6435d21cSTzuyi Chang 326*6435d21cSTzuyi Chang static void rtd1625_gpio_enable_level_irq(struct rtd1625_gpio *data, irq_hw_number_t hwirq) 327*6435d21cSTzuyi Chang { 328*6435d21cSTzuyi Chang int level_reg_offset = rtd1625_gpio_level_offset(data, hwirq); 329*6435d21cSTzuyi Chang u32 clr_mask = BIT(hwirq % 32); 330*6435d21cSTzuyi Chang u32 val; 331*6435d21cSTzuyi Chang 332*6435d21cSTzuyi Chang guard(raw_spinlock_irqsave)(&data->lock); 333*6435d21cSTzuyi Chang 334*6435d21cSTzuyi Chang regmap_write(data->regmap, level_reg_offset, clr_mask); 335*6435d21cSTzuyi Chang val = RTD1625_GPIO_LEVEL_INT_EN | RTD1625_GPIO_WREN(RTD1625_GPIO_LEVEL_INT_EN); 336*6435d21cSTzuyi Chang regmap_write(data->regmap, data->info->base_offset + GPIO_CONTROL(hwirq), val); 337*6435d21cSTzuyi Chang } 338*6435d21cSTzuyi Chang 339*6435d21cSTzuyi Chang static void rtd1625_gpio_disable_level_irq(struct rtd1625_gpio *data, irq_hw_number_t hwirq) 340*6435d21cSTzuyi Chang { 341*6435d21cSTzuyi Chang u32 val; 342*6435d21cSTzuyi Chang 343*6435d21cSTzuyi Chang guard(raw_spinlock_irqsave)(&data->lock); 344*6435d21cSTzuyi Chang 345*6435d21cSTzuyi Chang val = RTD1625_GPIO_WREN(RTD1625_GPIO_LEVEL_INT_EN); 346*6435d21cSTzuyi Chang regmap_write(data->regmap, data->info->base_offset + GPIO_CONTROL(hwirq), val); 347*6435d21cSTzuyi Chang } 348*6435d21cSTzuyi Chang 349*6435d21cSTzuyi Chang static void rtd1625_gpio_enable_irq(struct irq_data *d) 350*6435d21cSTzuyi Chang { 351*6435d21cSTzuyi Chang struct rtd1625_gpio *data = irq_data_get_irq_chip_data(d); 352*6435d21cSTzuyi Chang irq_hw_number_t hwirq = irqd_to_hwirq(d); 353*6435d21cSTzuyi Chang u32 irq_type = irqd_get_trigger_type(d); 354*6435d21cSTzuyi Chang 355*6435d21cSTzuyi Chang gpio_regmap_enable_irq(data->gpio_reg, hwirq); 356*6435d21cSTzuyi Chang 357*6435d21cSTzuyi Chang if (irq_type & IRQ_TYPE_EDGE_BOTH) 358*6435d21cSTzuyi Chang rtd1625_gpio_enable_edge_irq(data, hwirq); 359*6435d21cSTzuyi Chang else if (irq_type & IRQ_TYPE_LEVEL_MASK) 360*6435d21cSTzuyi Chang rtd1625_gpio_enable_level_irq(data, hwirq); 361*6435d21cSTzuyi Chang } 362*6435d21cSTzuyi Chang 363*6435d21cSTzuyi Chang static void rtd1625_gpio_disable_irq(struct irq_data *d) 364*6435d21cSTzuyi Chang { 365*6435d21cSTzuyi Chang struct rtd1625_gpio *data = irq_data_get_irq_chip_data(d); 366*6435d21cSTzuyi Chang irq_hw_number_t hwirq = irqd_to_hwirq(d); 367*6435d21cSTzuyi Chang u32 irq_type = irqd_get_trigger_type(d); 368*6435d21cSTzuyi Chang 369*6435d21cSTzuyi Chang if (irq_type & IRQ_TYPE_EDGE_BOTH) 370*6435d21cSTzuyi Chang rtd1625_gpio_disable_edge_irq(data, hwirq); 371*6435d21cSTzuyi Chang else if (irq_type & IRQ_TYPE_LEVEL_MASK) 372*6435d21cSTzuyi Chang rtd1625_gpio_disable_level_irq(data, hwirq); 373*6435d21cSTzuyi Chang 374*6435d21cSTzuyi Chang gpio_regmap_disable_irq(data->gpio_reg, hwirq); 375*6435d21cSTzuyi Chang } 376*6435d21cSTzuyi Chang 377*6435d21cSTzuyi Chang static int rtd1625_gpio_irq_set_level_type(struct irq_data *d, bool level) 378*6435d21cSTzuyi Chang { 379*6435d21cSTzuyi Chang u32 val = RTD1625_GPIO_WREN(RTD1625_GPIO_LEVEL_INT_DP); 380*6435d21cSTzuyi Chang irq_hw_number_t hwirq = irqd_to_hwirq(d); 381*6435d21cSTzuyi Chang struct rtd1625_gpio *data; 382*6435d21cSTzuyi Chang int ret; 383*6435d21cSTzuyi Chang 384*6435d21cSTzuyi Chang data = irq_data_get_irq_chip_data(d); 385*6435d21cSTzuyi Chang if (!(data->info->irq_type_support & IRQ_TYPE_LEVEL_MASK)) 386*6435d21cSTzuyi Chang return -EINVAL; 387*6435d21cSTzuyi Chang 388*6435d21cSTzuyi Chang if (level) 389*6435d21cSTzuyi Chang val |= RTD1625_GPIO_LEVEL_INT_DP; 390*6435d21cSTzuyi Chang 391*6435d21cSTzuyi Chang scoped_guard(raw_spinlock_irqsave, &data->lock) { 392*6435d21cSTzuyi Chang ret = regmap_write(data->regmap, data->info->base_offset + GPIO_CONTROL(hwirq), 393*6435d21cSTzuyi Chang val); 394*6435d21cSTzuyi Chang if (ret) 395*6435d21cSTzuyi Chang return ret; 396*6435d21cSTzuyi Chang } 397*6435d21cSTzuyi Chang 398*6435d21cSTzuyi Chang irq_set_handler_locked(d, handle_level_irq); 399*6435d21cSTzuyi Chang 400*6435d21cSTzuyi Chang return 0; 401*6435d21cSTzuyi Chang } 402*6435d21cSTzuyi Chang 403*6435d21cSTzuyi Chang static int rtd1625_gpio_irq_set_edge_type(struct irq_data *d, bool polarity) 404*6435d21cSTzuyi Chang { 405*6435d21cSTzuyi Chang struct rtd1625_gpio *data = irq_data_get_irq_chip_data(d); 406*6435d21cSTzuyi Chang u32 val = RTD1625_GPIO_WREN(RTD1625_GPIO_EDGE_INT_DP); 407*6435d21cSTzuyi Chang irq_hw_number_t hwirq = irqd_to_hwirq(d); 408*6435d21cSTzuyi Chang int ret; 409*6435d21cSTzuyi Chang 410*6435d21cSTzuyi Chang if (!(data->info->irq_type_support & IRQ_TYPE_EDGE_BOTH)) 411*6435d21cSTzuyi Chang return -EINVAL; 412*6435d21cSTzuyi Chang 413*6435d21cSTzuyi Chang if (polarity) 414*6435d21cSTzuyi Chang val |= RTD1625_GPIO_EDGE_INT_DP; 415*6435d21cSTzuyi Chang 416*6435d21cSTzuyi Chang scoped_guard(raw_spinlock_irqsave, &data->lock) { 417*6435d21cSTzuyi Chang ret = regmap_write(data->regmap, data->info->base_offset + GPIO_CONTROL(hwirq), 418*6435d21cSTzuyi Chang val); 419*6435d21cSTzuyi Chang if (ret) 420*6435d21cSTzuyi Chang return ret; 421*6435d21cSTzuyi Chang } 422*6435d21cSTzuyi Chang 423*6435d21cSTzuyi Chang irq_set_handler_locked(d, handle_edge_irq); 424*6435d21cSTzuyi Chang 425*6435d21cSTzuyi Chang return 0; 426*6435d21cSTzuyi Chang } 427*6435d21cSTzuyi Chang 428*6435d21cSTzuyi Chang static int rtd1625_gpio_irq_set_type(struct irq_data *d, unsigned int type) 429*6435d21cSTzuyi Chang { 430*6435d21cSTzuyi Chang switch (type & IRQ_TYPE_SENSE_MASK) { 431*6435d21cSTzuyi Chang case IRQ_TYPE_EDGE_RISING: 432*6435d21cSTzuyi Chang return rtd1625_gpio_irq_set_edge_type(d, 1); 433*6435d21cSTzuyi Chang 434*6435d21cSTzuyi Chang case IRQ_TYPE_EDGE_FALLING: 435*6435d21cSTzuyi Chang return rtd1625_gpio_irq_set_edge_type(d, 0); 436*6435d21cSTzuyi Chang 437*6435d21cSTzuyi Chang case IRQ_TYPE_EDGE_BOTH: 438*6435d21cSTzuyi Chang return rtd1625_gpio_irq_set_edge_type(d, 1); 439*6435d21cSTzuyi Chang 440*6435d21cSTzuyi Chang case IRQ_TYPE_LEVEL_HIGH: 441*6435d21cSTzuyi Chang return rtd1625_gpio_irq_set_level_type(d, 0); 442*6435d21cSTzuyi Chang 443*6435d21cSTzuyi Chang case IRQ_TYPE_LEVEL_LOW: 444*6435d21cSTzuyi Chang return rtd1625_gpio_irq_set_level_type(d, 1); 445*6435d21cSTzuyi Chang 446*6435d21cSTzuyi Chang default: 447*6435d21cSTzuyi Chang return -EINVAL; 448*6435d21cSTzuyi Chang } 449*6435d21cSTzuyi Chang } 450*6435d21cSTzuyi Chang 451*6435d21cSTzuyi Chang static int rtd1625_gpio_irq_request_resources(struct irq_data *d) 452*6435d21cSTzuyi Chang { 453*6435d21cSTzuyi Chang struct rtd1625_gpio *data = irq_data_get_irq_chip_data(d); 454*6435d21cSTzuyi Chang 455*6435d21cSTzuyi Chang return gpio_regmap_reqres_irq(data->gpio_reg, d->hwirq); 456*6435d21cSTzuyi Chang } 457*6435d21cSTzuyi Chang 458*6435d21cSTzuyi Chang static void rtd1625_gpio_irq_release_resources(struct irq_data *d) 459*6435d21cSTzuyi Chang { 460*6435d21cSTzuyi Chang struct rtd1625_gpio *data = irq_data_get_irq_chip_data(d); 461*6435d21cSTzuyi Chang 462*6435d21cSTzuyi Chang gpio_regmap_relres_irq(data->gpio_reg, d->hwirq); 463*6435d21cSTzuyi Chang } 464*6435d21cSTzuyi Chang 465*6435d21cSTzuyi Chang static struct irq_chip rtd1625_iso_gpio_irq_chip = { 466*6435d21cSTzuyi Chang .name = "rtd1625-gpio", 467*6435d21cSTzuyi Chang .irq_ack = rtd1625_gpio_ack_irq, 468*6435d21cSTzuyi Chang .irq_mask = rtd1625_gpio_disable_irq, 469*6435d21cSTzuyi Chang .irq_unmask = rtd1625_gpio_enable_irq, 470*6435d21cSTzuyi Chang .irq_set_type = rtd1625_gpio_irq_set_type, 471*6435d21cSTzuyi Chang .flags = IRQCHIP_IMMUTABLE | IRQCHIP_SKIP_SET_WAKE, 472*6435d21cSTzuyi Chang .irq_request_resources = rtd1625_gpio_irq_request_resources, 473*6435d21cSTzuyi Chang .irq_release_resources = rtd1625_gpio_irq_release_resources, 474*6435d21cSTzuyi Chang }; 475*6435d21cSTzuyi Chang 476*6435d21cSTzuyi Chang static int rtd1625_gpio_setup_irq(struct platform_device *pdev, struct rtd1625_gpio *data) 477*6435d21cSTzuyi Chang { 478*6435d21cSTzuyi Chang unsigned int num_irqs; 479*6435d21cSTzuyi Chang int irq; 480*6435d21cSTzuyi Chang 481*6435d21cSTzuyi Chang /* IRQ is optional; operate as basic GPIO if absent */ 482*6435d21cSTzuyi Chang irq = platform_get_irq_optional(pdev, 0); 483*6435d21cSTzuyi Chang if (irq == -ENXIO) 484*6435d21cSTzuyi Chang return 0; 485*6435d21cSTzuyi Chang if (irq < 0) 486*6435d21cSTzuyi Chang return irq; 487*6435d21cSTzuyi Chang 488*6435d21cSTzuyi Chang num_irqs = (data->info->irq_type_support & IRQ_TYPE_LEVEL_MASK) ? 3 : 2; 489*6435d21cSTzuyi Chang 490*6435d21cSTzuyi Chang for (unsigned int i = 0; i < num_irqs; i++) { 491*6435d21cSTzuyi Chang irq = platform_get_irq(pdev, i); 492*6435d21cSTzuyi Chang if (irq < 0) 493*6435d21cSTzuyi Chang return irq; 494*6435d21cSTzuyi Chang 495*6435d21cSTzuyi Chang data->irqs[i] = irq; 496*6435d21cSTzuyi Chang irq_set_chained_handler_and_data(data->irqs[i], rtd1625_gpio_irq_handle, data); 497*6435d21cSTzuyi Chang } 498*6435d21cSTzuyi Chang 499*6435d21cSTzuyi Chang return 0; 500*6435d21cSTzuyi Chang } 501*6435d21cSTzuyi Chang 502*6435d21cSTzuyi Chang static int rtd1625_gpio_irq_map(struct irq_domain *domain, unsigned int irq, 503*6435d21cSTzuyi Chang irq_hw_number_t hwirq) 504*6435d21cSTzuyi Chang { 505*6435d21cSTzuyi Chang struct rtd1625_gpio *data = domain->host_data; 506*6435d21cSTzuyi Chang 507*6435d21cSTzuyi Chang irq_set_chip_data(irq, data); 508*6435d21cSTzuyi Chang 509*6435d21cSTzuyi Chang irq_set_chip_and_handler(irq, &rtd1625_iso_gpio_irq_chip, handle_bad_irq); 510*6435d21cSTzuyi Chang 511*6435d21cSTzuyi Chang irq_set_noprobe(irq); 512*6435d21cSTzuyi Chang 513*6435d21cSTzuyi Chang irq_set_lockdep_class(irq, &rtd1625_gpio_irq_lock_class, 514*6435d21cSTzuyi Chang &rtd1625_gpio_irq_request_class); 515*6435d21cSTzuyi Chang 516*6435d21cSTzuyi Chang return 0; 517*6435d21cSTzuyi Chang } 518*6435d21cSTzuyi Chang 519*6435d21cSTzuyi Chang static const struct irq_domain_ops rtd1625_gpio_irq_domain_ops = { 520*6435d21cSTzuyi Chang .map = rtd1625_gpio_irq_map, 521*6435d21cSTzuyi Chang .xlate = irq_domain_xlate_twocell, 522*6435d21cSTzuyi Chang }; 523*6435d21cSTzuyi Chang 524*6435d21cSTzuyi Chang static const struct regmap_config rtd1625_gpio_regmap_config = { 525*6435d21cSTzuyi Chang .reg_bits = 32, 526*6435d21cSTzuyi Chang .reg_stride = 4, 527*6435d21cSTzuyi Chang .val_bits = 32, 528*6435d21cSTzuyi Chang #ifndef CONFIG_DEBUG_GPIO 529*6435d21cSTzuyi Chang .disable_locking = true, 530*6435d21cSTzuyi Chang #endif 531*6435d21cSTzuyi Chang }; 532*6435d21cSTzuyi Chang 533*6435d21cSTzuyi Chang static int rtd1625_gpio_probe(struct platform_device *pdev) 534*6435d21cSTzuyi Chang { 535*6435d21cSTzuyi Chang struct gpio_regmap_config config = {}; 536*6435d21cSTzuyi Chang struct irq_domain_info d_info = {}; 537*6435d21cSTzuyi Chang struct device *dev = &pdev->dev; 538*6435d21cSTzuyi Chang struct gpio_regmap *gpio_reg; 539*6435d21cSTzuyi Chang struct rtd1625_gpio *data; 540*6435d21cSTzuyi Chang void __iomem *irq_base; 541*6435d21cSTzuyi Chang int ret; 542*6435d21cSTzuyi Chang 543*6435d21cSTzuyi Chang data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 544*6435d21cSTzuyi Chang if (!data) 545*6435d21cSTzuyi Chang return -ENOMEM; 546*6435d21cSTzuyi Chang 547*6435d21cSTzuyi Chang data->info = device_get_match_data(dev); 548*6435d21cSTzuyi Chang if (!data->info) 549*6435d21cSTzuyi Chang return -ENODATA; 550*6435d21cSTzuyi Chang 551*6435d21cSTzuyi Chang irq_base = devm_platform_ioremap_resource(pdev, 0); 552*6435d21cSTzuyi Chang if (IS_ERR(irq_base)) 553*6435d21cSTzuyi Chang return PTR_ERR(irq_base); 554*6435d21cSTzuyi Chang 555*6435d21cSTzuyi Chang data->regmap = devm_regmap_init_mmio(dev, irq_base, &rtd1625_gpio_regmap_config); 556*6435d21cSTzuyi Chang if (IS_ERR(data->regmap)) 557*6435d21cSTzuyi Chang return PTR_ERR(data->regmap); 558*6435d21cSTzuyi Chang 559*6435d21cSTzuyi Chang raw_spin_lock_init(&data->lock); 560*6435d21cSTzuyi Chang platform_set_drvdata(pdev, data); 561*6435d21cSTzuyi Chang 562*6435d21cSTzuyi Chang data->save_regs = devm_kcalloc(dev, data->info->num_gpios, sizeof(*data->save_regs), 563*6435d21cSTzuyi Chang GFP_KERNEL); 564*6435d21cSTzuyi Chang if (!data->save_regs) 565*6435d21cSTzuyi Chang return -ENOMEM; 566*6435d21cSTzuyi Chang 567*6435d21cSTzuyi Chang config.parent = dev; 568*6435d21cSTzuyi Chang config.regmap = data->regmap; 569*6435d21cSTzuyi Chang config.ngpio = data->info->num_gpios; 570*6435d21cSTzuyi Chang config.reg_dat_base = data->info->base_offset; 571*6435d21cSTzuyi Chang config.reg_set_base = data->info->base_offset; 572*6435d21cSTzuyi Chang config.reg_dir_out_base = data->info->base_offset; 573*6435d21cSTzuyi Chang 574*6435d21cSTzuyi Chang config.reg_mask_xlate = rtd1625_reg_mask_xlate; 575*6435d21cSTzuyi Chang config.set_config = rtd1625_gpio_set_config; 576*6435d21cSTzuyi Chang config.value_xlate = rtd1625_value_xlate; 577*6435d21cSTzuyi Chang 578*6435d21cSTzuyi Chang d_info.fwnode = dev_fwnode(&pdev->dev); 579*6435d21cSTzuyi Chang d_info.size = data->info->num_gpios; 580*6435d21cSTzuyi Chang d_info.hwirq_max = data->info->num_gpios; 581*6435d21cSTzuyi Chang d_info.ops = &rtd1625_gpio_irq_domain_ops; 582*6435d21cSTzuyi Chang d_info.host_data = data; 583*6435d21cSTzuyi Chang 584*6435d21cSTzuyi Chang data->domain = devm_irq_domain_instantiate(dev, &d_info); 585*6435d21cSTzuyi Chang if (IS_ERR(data->domain)) 586*6435d21cSTzuyi Chang return PTR_ERR(data->domain); 587*6435d21cSTzuyi Chang 588*6435d21cSTzuyi Chang ret = rtd1625_gpio_setup_irq(pdev, data); 589*6435d21cSTzuyi Chang if (ret) 590*6435d21cSTzuyi Chang return ret; 591*6435d21cSTzuyi Chang 592*6435d21cSTzuyi Chang config.irq_domain = data->domain; 593*6435d21cSTzuyi Chang config.drvdata = data; 594*6435d21cSTzuyi Chang 595*6435d21cSTzuyi Chang gpio_reg = devm_gpio_regmap_register(dev, &config); 596*6435d21cSTzuyi Chang if (IS_ERR(gpio_reg)) 597*6435d21cSTzuyi Chang return PTR_ERR(gpio_reg); 598*6435d21cSTzuyi Chang 599*6435d21cSTzuyi Chang data->gpio_reg = gpio_reg; 600*6435d21cSTzuyi Chang 601*6435d21cSTzuyi Chang return 0; 602*6435d21cSTzuyi Chang } 603*6435d21cSTzuyi Chang 604*6435d21cSTzuyi Chang static const struct rtd1625_gpio_info rtd1625_iso_gpio_info = { 605*6435d21cSTzuyi Chang .num_gpios = 166, 606*6435d21cSTzuyi Chang .irq_type_support = IRQ_TYPE_EDGE_BOTH, 607*6435d21cSTzuyi Chang .base_offset = 0x100, 608*6435d21cSTzuyi Chang .gpa_offset = 0x000, 609*6435d21cSTzuyi Chang .gpda_offset = 0x020, 610*6435d21cSTzuyi Chang .write_en_all = RTD1625_ISO_GPIO_WREN_ALL, 611*6435d21cSTzuyi Chang }; 612*6435d21cSTzuyi Chang 613*6435d21cSTzuyi Chang static const struct rtd1625_gpio_info rtd1625_isom_gpio_info = { 614*6435d21cSTzuyi Chang .num_gpios = 4, 615*6435d21cSTzuyi Chang .irq_type_support = IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_LOW | 616*6435d21cSTzuyi Chang IRQ_TYPE_LEVEL_HIGH, 617*6435d21cSTzuyi Chang .base_offset = 0x20, 618*6435d21cSTzuyi Chang .gpa_offset = 0x00, 619*6435d21cSTzuyi Chang .gpda_offset = 0x04, 620*6435d21cSTzuyi Chang .level_offset = 0x18, 621*6435d21cSTzuyi Chang .write_en_all = RTD1625_ISOM_GPIO_WREN_ALL, 622*6435d21cSTzuyi Chang }; 623*6435d21cSTzuyi Chang 624*6435d21cSTzuyi Chang static int rtd1625_gpio_suspend(struct device *dev) 625*6435d21cSTzuyi Chang { 626*6435d21cSTzuyi Chang struct rtd1625_gpio *data = dev_get_drvdata(dev); 627*6435d21cSTzuyi Chang const struct rtd1625_gpio_info *info = data->info; 628*6435d21cSTzuyi Chang int ret; 629*6435d21cSTzuyi Chang 630*6435d21cSTzuyi Chang for (unsigned int i = 0; i < info->num_gpios; i++) { 631*6435d21cSTzuyi Chang ret = regmap_read(data->regmap, data->info->base_offset + GPIO_CONTROL(i), 632*6435d21cSTzuyi Chang &data->save_regs[i]); 633*6435d21cSTzuyi Chang if (ret) 634*6435d21cSTzuyi Chang return ret; 635*6435d21cSTzuyi Chang } 636*6435d21cSTzuyi Chang 637*6435d21cSTzuyi Chang return 0; 638*6435d21cSTzuyi Chang } 639*6435d21cSTzuyi Chang 640*6435d21cSTzuyi Chang static int rtd1625_gpio_resume(struct device *dev) 641*6435d21cSTzuyi Chang { 642*6435d21cSTzuyi Chang struct rtd1625_gpio *data = dev_get_drvdata(dev); 643*6435d21cSTzuyi Chang const struct rtd1625_gpio_info *info = data->info; 644*6435d21cSTzuyi Chang int ret; 645*6435d21cSTzuyi Chang 646*6435d21cSTzuyi Chang for (unsigned int i = 0; i < info->num_gpios; i++) { 647*6435d21cSTzuyi Chang ret = regmap_write(data->regmap, data->info->base_offset + GPIO_CONTROL(i), 648*6435d21cSTzuyi Chang data->save_regs[i] | info->write_en_all); 649*6435d21cSTzuyi Chang if (ret) 650*6435d21cSTzuyi Chang return ret; 651*6435d21cSTzuyi Chang } 652*6435d21cSTzuyi Chang 653*6435d21cSTzuyi Chang return 0; 654*6435d21cSTzuyi Chang } 655*6435d21cSTzuyi Chang 656*6435d21cSTzuyi Chang static DEFINE_NOIRQ_DEV_PM_OPS(rtd1625_gpio_pm_ops, rtd1625_gpio_suspend, rtd1625_gpio_resume); 657*6435d21cSTzuyi Chang 658*6435d21cSTzuyi Chang static const struct of_device_id rtd1625_gpio_of_matches[] = { 659*6435d21cSTzuyi Chang { .compatible = "realtek,rtd1625-iso-gpio", .data = &rtd1625_iso_gpio_info }, 660*6435d21cSTzuyi Chang { .compatible = "realtek,rtd1625-isom-gpio", .data = &rtd1625_isom_gpio_info }, 661*6435d21cSTzuyi Chang { } 662*6435d21cSTzuyi Chang }; 663*6435d21cSTzuyi Chang MODULE_DEVICE_TABLE(of, rtd1625_gpio_of_matches); 664*6435d21cSTzuyi Chang 665*6435d21cSTzuyi Chang static struct platform_driver rtd1625_gpio_platform_driver = { 666*6435d21cSTzuyi Chang .driver = { 667*6435d21cSTzuyi Chang .name = "gpio-rtd1625", 668*6435d21cSTzuyi Chang .of_match_table = rtd1625_gpio_of_matches, 669*6435d21cSTzuyi Chang .pm = pm_sleep_ptr(&rtd1625_gpio_pm_ops), 670*6435d21cSTzuyi Chang }, 671*6435d21cSTzuyi Chang .probe = rtd1625_gpio_probe, 672*6435d21cSTzuyi Chang }; 673*6435d21cSTzuyi Chang module_platform_driver(rtd1625_gpio_platform_driver); 674*6435d21cSTzuyi Chang 675*6435d21cSTzuyi Chang MODULE_LICENSE("GPL"); 676*6435d21cSTzuyi Chang MODULE_AUTHOR("Realtek Semiconductor Corporation"); 677*6435d21cSTzuyi Chang MODULE_DESCRIPTION("Realtek DHC SoC RTD1625 gpio driver"); 678