1*356b01a9SLuo Jiaxing // SPDX-License-Identifier: GPL-2.0-only 2*356b01a9SLuo Jiaxing /* Copyright (c) 2020 HiSilicon Limited. */ 3*356b01a9SLuo Jiaxing #include <linux/gpio/driver.h> 4*356b01a9SLuo Jiaxing #include <linux/module.h> 5*356b01a9SLuo Jiaxing #include <linux/mod_devicetable.h> 6*356b01a9SLuo Jiaxing #include <linux/platform_device.h> 7*356b01a9SLuo Jiaxing #include <linux/property.h> 8*356b01a9SLuo Jiaxing 9*356b01a9SLuo Jiaxing #define HISI_GPIO_SWPORT_DR_SET_WX 0x000 10*356b01a9SLuo Jiaxing #define HISI_GPIO_SWPORT_DR_CLR_WX 0x004 11*356b01a9SLuo Jiaxing #define HISI_GPIO_SWPORT_DDR_SET_WX 0x010 12*356b01a9SLuo Jiaxing #define HISI_GPIO_SWPORT_DDR_CLR_WX 0x014 13*356b01a9SLuo Jiaxing #define HISI_GPIO_SWPORT_DDR_ST_WX 0x018 14*356b01a9SLuo Jiaxing #define HISI_GPIO_INTEN_SET_WX 0x020 15*356b01a9SLuo Jiaxing #define HISI_GPIO_INTEN_CLR_WX 0x024 16*356b01a9SLuo Jiaxing #define HISI_GPIO_INTMASK_SET_WX 0x030 17*356b01a9SLuo Jiaxing #define HISI_GPIO_INTMASK_CLR_WX 0x034 18*356b01a9SLuo Jiaxing #define HISI_GPIO_INTTYPE_EDGE_SET_WX 0x040 19*356b01a9SLuo Jiaxing #define HISI_GPIO_INTTYPE_EDGE_CLR_WX 0x044 20*356b01a9SLuo Jiaxing #define HISI_GPIO_INT_POLARITY_SET_WX 0x050 21*356b01a9SLuo Jiaxing #define HISI_GPIO_INT_POLARITY_CLR_WX 0x054 22*356b01a9SLuo Jiaxing #define HISI_GPIO_DEBOUNCE_SET_WX 0x060 23*356b01a9SLuo Jiaxing #define HISI_GPIO_DEBOUNCE_CLR_WX 0x064 24*356b01a9SLuo Jiaxing #define HISI_GPIO_INTSTATUS_WX 0x070 25*356b01a9SLuo Jiaxing #define HISI_GPIO_PORTA_EOI_WX 0x078 26*356b01a9SLuo Jiaxing #define HISI_GPIO_EXT_PORT_WX 0x080 27*356b01a9SLuo Jiaxing #define HISI_GPIO_INTCOMB_MASK_WX 0x0a0 28*356b01a9SLuo Jiaxing #define HISI_GPIO_INT_DEDGE_SET 0x0b0 29*356b01a9SLuo Jiaxing #define HISI_GPIO_INT_DEDGE_CLR 0x0b4 30*356b01a9SLuo Jiaxing #define HISI_GPIO_INT_DEDGE_ST 0x0b8 31*356b01a9SLuo Jiaxing 32*356b01a9SLuo Jiaxing #define HISI_GPIO_LINE_NUM_MAX 32 33*356b01a9SLuo Jiaxing #define HISI_GPIO_DRIVER_NAME "gpio-hisi" 34*356b01a9SLuo Jiaxing 35*356b01a9SLuo Jiaxing struct hisi_gpio { 36*356b01a9SLuo Jiaxing struct gpio_chip chip; 37*356b01a9SLuo Jiaxing struct device *dev; 38*356b01a9SLuo Jiaxing void __iomem *reg_base; 39*356b01a9SLuo Jiaxing unsigned int line_num; 40*356b01a9SLuo Jiaxing struct irq_chip irq_chip; 41*356b01a9SLuo Jiaxing int irq; 42*356b01a9SLuo Jiaxing }; 43*356b01a9SLuo Jiaxing 44*356b01a9SLuo Jiaxing static inline u32 hisi_gpio_read_reg(struct gpio_chip *chip, 45*356b01a9SLuo Jiaxing unsigned int off) 46*356b01a9SLuo Jiaxing { 47*356b01a9SLuo Jiaxing struct hisi_gpio *hisi_gpio = 48*356b01a9SLuo Jiaxing container_of(chip, struct hisi_gpio, chip); 49*356b01a9SLuo Jiaxing void __iomem *reg = hisi_gpio->reg_base + off; 50*356b01a9SLuo Jiaxing 51*356b01a9SLuo Jiaxing return readl(reg); 52*356b01a9SLuo Jiaxing } 53*356b01a9SLuo Jiaxing 54*356b01a9SLuo Jiaxing static inline void hisi_gpio_write_reg(struct gpio_chip *chip, 55*356b01a9SLuo Jiaxing unsigned int off, u32 val) 56*356b01a9SLuo Jiaxing { 57*356b01a9SLuo Jiaxing struct hisi_gpio *hisi_gpio = 58*356b01a9SLuo Jiaxing container_of(chip, struct hisi_gpio, chip); 59*356b01a9SLuo Jiaxing void __iomem *reg = hisi_gpio->reg_base + off; 60*356b01a9SLuo Jiaxing 61*356b01a9SLuo Jiaxing writel(val, reg); 62*356b01a9SLuo Jiaxing } 63*356b01a9SLuo Jiaxing 64*356b01a9SLuo Jiaxing static void hisi_gpio_set_debounce(struct gpio_chip *chip, unsigned int off, 65*356b01a9SLuo Jiaxing u32 debounce) 66*356b01a9SLuo Jiaxing { 67*356b01a9SLuo Jiaxing if (debounce) 68*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_DEBOUNCE_SET_WX, BIT(off)); 69*356b01a9SLuo Jiaxing else 70*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_DEBOUNCE_CLR_WX, BIT(off)); 71*356b01a9SLuo Jiaxing } 72*356b01a9SLuo Jiaxing 73*356b01a9SLuo Jiaxing static int hisi_gpio_set_config(struct gpio_chip *chip, unsigned int offset, 74*356b01a9SLuo Jiaxing unsigned long config) 75*356b01a9SLuo Jiaxing { 76*356b01a9SLuo Jiaxing u32 config_para = pinconf_to_config_param(config); 77*356b01a9SLuo Jiaxing u32 config_arg; 78*356b01a9SLuo Jiaxing 79*356b01a9SLuo Jiaxing switch (config_para) { 80*356b01a9SLuo Jiaxing case PIN_CONFIG_INPUT_DEBOUNCE: 81*356b01a9SLuo Jiaxing config_arg = pinconf_to_config_argument(config); 82*356b01a9SLuo Jiaxing hisi_gpio_set_debounce(chip, offset, config_arg); 83*356b01a9SLuo Jiaxing break; 84*356b01a9SLuo Jiaxing default: 85*356b01a9SLuo Jiaxing return -ENOTSUPP; 86*356b01a9SLuo Jiaxing } 87*356b01a9SLuo Jiaxing 88*356b01a9SLuo Jiaxing return 0; 89*356b01a9SLuo Jiaxing } 90*356b01a9SLuo Jiaxing 91*356b01a9SLuo Jiaxing static void hisi_gpio_set_ack(struct irq_data *d) 92*356b01a9SLuo Jiaxing { 93*356b01a9SLuo Jiaxing struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 94*356b01a9SLuo Jiaxing 95*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_PORTA_EOI_WX, BIT(irqd_to_hwirq(d))); 96*356b01a9SLuo Jiaxing } 97*356b01a9SLuo Jiaxing 98*356b01a9SLuo Jiaxing static void hisi_gpio_irq_set_mask(struct irq_data *d) 99*356b01a9SLuo Jiaxing { 100*356b01a9SLuo Jiaxing struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 101*356b01a9SLuo Jiaxing 102*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTMASK_SET_WX, BIT(irqd_to_hwirq(d))); 103*356b01a9SLuo Jiaxing } 104*356b01a9SLuo Jiaxing 105*356b01a9SLuo Jiaxing static void hisi_gpio_irq_clr_mask(struct irq_data *d) 106*356b01a9SLuo Jiaxing { 107*356b01a9SLuo Jiaxing struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 108*356b01a9SLuo Jiaxing 109*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTMASK_CLR_WX, BIT(irqd_to_hwirq(d))); 110*356b01a9SLuo Jiaxing } 111*356b01a9SLuo Jiaxing 112*356b01a9SLuo Jiaxing static int hisi_gpio_irq_set_type(struct irq_data *d, u32 type) 113*356b01a9SLuo Jiaxing { 114*356b01a9SLuo Jiaxing struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 115*356b01a9SLuo Jiaxing unsigned int mask = BIT(irqd_to_hwirq(d)); 116*356b01a9SLuo Jiaxing 117*356b01a9SLuo Jiaxing switch (type) { 118*356b01a9SLuo Jiaxing case IRQ_TYPE_EDGE_BOTH: 119*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INT_DEDGE_SET, mask); 120*356b01a9SLuo Jiaxing break; 121*356b01a9SLuo Jiaxing case IRQ_TYPE_EDGE_RISING: 122*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTTYPE_EDGE_SET_WX, mask); 123*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INT_POLARITY_SET_WX, mask); 124*356b01a9SLuo Jiaxing break; 125*356b01a9SLuo Jiaxing case IRQ_TYPE_EDGE_FALLING: 126*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTTYPE_EDGE_SET_WX, mask); 127*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INT_POLARITY_CLR_WX, mask); 128*356b01a9SLuo Jiaxing break; 129*356b01a9SLuo Jiaxing case IRQ_TYPE_LEVEL_HIGH: 130*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTTYPE_EDGE_CLR_WX, mask); 131*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INT_POLARITY_SET_WX, mask); 132*356b01a9SLuo Jiaxing break; 133*356b01a9SLuo Jiaxing case IRQ_TYPE_LEVEL_LOW: 134*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTTYPE_EDGE_CLR_WX, mask); 135*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INT_POLARITY_CLR_WX, mask); 136*356b01a9SLuo Jiaxing break; 137*356b01a9SLuo Jiaxing default: 138*356b01a9SLuo Jiaxing return -EINVAL; 139*356b01a9SLuo Jiaxing } 140*356b01a9SLuo Jiaxing 141*356b01a9SLuo Jiaxing /* 142*356b01a9SLuo Jiaxing * The dual-edge interrupt and other interrupt's registers do not 143*356b01a9SLuo Jiaxing * take effect at the same time. The registers of the two-edge 144*356b01a9SLuo Jiaxing * interrupts have higher priorities, the configuration of 145*356b01a9SLuo Jiaxing * the dual-edge interrupts must be disabled before the configuration 146*356b01a9SLuo Jiaxing * of other kind of interrupts. 147*356b01a9SLuo Jiaxing */ 148*356b01a9SLuo Jiaxing if (type != IRQ_TYPE_EDGE_BOTH) { 149*356b01a9SLuo Jiaxing unsigned int both = hisi_gpio_read_reg(chip, HISI_GPIO_INT_DEDGE_ST); 150*356b01a9SLuo Jiaxing 151*356b01a9SLuo Jiaxing if (both & mask) 152*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INT_DEDGE_CLR, mask); 153*356b01a9SLuo Jiaxing } 154*356b01a9SLuo Jiaxing 155*356b01a9SLuo Jiaxing if (type & IRQ_TYPE_LEVEL_MASK) 156*356b01a9SLuo Jiaxing irq_set_handler_locked(d, handle_level_irq); 157*356b01a9SLuo Jiaxing else if (type & IRQ_TYPE_EDGE_BOTH) 158*356b01a9SLuo Jiaxing irq_set_handler_locked(d, handle_edge_irq); 159*356b01a9SLuo Jiaxing 160*356b01a9SLuo Jiaxing return 0; 161*356b01a9SLuo Jiaxing } 162*356b01a9SLuo Jiaxing 163*356b01a9SLuo Jiaxing static void hisi_gpio_irq_enable(struct irq_data *d) 164*356b01a9SLuo Jiaxing { 165*356b01a9SLuo Jiaxing struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 166*356b01a9SLuo Jiaxing 167*356b01a9SLuo Jiaxing hisi_gpio_irq_clr_mask(d); 168*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTEN_SET_WX, BIT(irqd_to_hwirq(d))); 169*356b01a9SLuo Jiaxing } 170*356b01a9SLuo Jiaxing 171*356b01a9SLuo Jiaxing static void hisi_gpio_irq_disable(struct irq_data *d) 172*356b01a9SLuo Jiaxing { 173*356b01a9SLuo Jiaxing struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 174*356b01a9SLuo Jiaxing 175*356b01a9SLuo Jiaxing hisi_gpio_irq_set_mask(d); 176*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTEN_CLR_WX, BIT(irqd_to_hwirq(d))); 177*356b01a9SLuo Jiaxing } 178*356b01a9SLuo Jiaxing 179*356b01a9SLuo Jiaxing static void hisi_gpio_irq_handler(struct irq_desc *desc) 180*356b01a9SLuo Jiaxing { 181*356b01a9SLuo Jiaxing struct hisi_gpio *hisi_gpio = irq_desc_get_handler_data(desc); 182*356b01a9SLuo Jiaxing unsigned long irq_msk = hisi_gpio_read_reg(&hisi_gpio->chip, 183*356b01a9SLuo Jiaxing HISI_GPIO_INTSTATUS_WX); 184*356b01a9SLuo Jiaxing struct irq_chip *irq_c = irq_desc_get_chip(desc); 185*356b01a9SLuo Jiaxing int hwirq; 186*356b01a9SLuo Jiaxing 187*356b01a9SLuo Jiaxing chained_irq_enter(irq_c, desc); 188*356b01a9SLuo Jiaxing for_each_set_bit(hwirq, &irq_msk, HISI_GPIO_LINE_NUM_MAX) 189*356b01a9SLuo Jiaxing generic_handle_irq(irq_find_mapping(hisi_gpio->chip.irq.domain, 190*356b01a9SLuo Jiaxing hwirq)); 191*356b01a9SLuo Jiaxing chained_irq_exit(irq_c, desc); 192*356b01a9SLuo Jiaxing } 193*356b01a9SLuo Jiaxing 194*356b01a9SLuo Jiaxing static void hisi_gpio_init_irq(struct hisi_gpio *hisi_gpio) 195*356b01a9SLuo Jiaxing { 196*356b01a9SLuo Jiaxing struct gpio_chip *chip = &hisi_gpio->chip; 197*356b01a9SLuo Jiaxing struct gpio_irq_chip *girq_chip = &chip->irq; 198*356b01a9SLuo Jiaxing 199*356b01a9SLuo Jiaxing /* Set hooks for irq_chip */ 200*356b01a9SLuo Jiaxing hisi_gpio->irq_chip.irq_ack = hisi_gpio_set_ack; 201*356b01a9SLuo Jiaxing hisi_gpio->irq_chip.irq_mask = hisi_gpio_irq_set_mask; 202*356b01a9SLuo Jiaxing hisi_gpio->irq_chip.irq_unmask = hisi_gpio_irq_clr_mask; 203*356b01a9SLuo Jiaxing hisi_gpio->irq_chip.irq_set_type = hisi_gpio_irq_set_type; 204*356b01a9SLuo Jiaxing hisi_gpio->irq_chip.irq_enable = hisi_gpio_irq_enable; 205*356b01a9SLuo Jiaxing hisi_gpio->irq_chip.irq_disable = hisi_gpio_irq_disable; 206*356b01a9SLuo Jiaxing 207*356b01a9SLuo Jiaxing girq_chip->chip = &hisi_gpio->irq_chip; 208*356b01a9SLuo Jiaxing girq_chip->default_type = IRQ_TYPE_NONE; 209*356b01a9SLuo Jiaxing girq_chip->num_parents = 1; 210*356b01a9SLuo Jiaxing girq_chip->parents = &hisi_gpio->irq; 211*356b01a9SLuo Jiaxing girq_chip->parent_handler = hisi_gpio_irq_handler; 212*356b01a9SLuo Jiaxing girq_chip->parent_handler_data = hisi_gpio; 213*356b01a9SLuo Jiaxing 214*356b01a9SLuo Jiaxing /* Clear Mask of GPIO controller combine IRQ */ 215*356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTCOMB_MASK_WX, 1); 216*356b01a9SLuo Jiaxing } 217*356b01a9SLuo Jiaxing 218*356b01a9SLuo Jiaxing static const struct acpi_device_id hisi_gpio_acpi_match[] = { 219*356b01a9SLuo Jiaxing {"HISI0184", 0}, 220*356b01a9SLuo Jiaxing {} 221*356b01a9SLuo Jiaxing }; 222*356b01a9SLuo Jiaxing MODULE_DEVICE_TABLE(acpi, hisi_gpio_acpi_match); 223*356b01a9SLuo Jiaxing 224*356b01a9SLuo Jiaxing static void hisi_gpio_get_pdata(struct device *dev, 225*356b01a9SLuo Jiaxing struct hisi_gpio *hisi_gpio) 226*356b01a9SLuo Jiaxing { 227*356b01a9SLuo Jiaxing struct platform_device *pdev = to_platform_device(dev); 228*356b01a9SLuo Jiaxing struct fwnode_handle *fwnode; 229*356b01a9SLuo Jiaxing int idx = 0; 230*356b01a9SLuo Jiaxing 231*356b01a9SLuo Jiaxing device_for_each_child_node(dev, fwnode) { 232*356b01a9SLuo Jiaxing /* Cycle for once, no need for an array to save line_num */ 233*356b01a9SLuo Jiaxing if (fwnode_property_read_u32(fwnode, "ngpios", 234*356b01a9SLuo Jiaxing &hisi_gpio->line_num)) { 235*356b01a9SLuo Jiaxing dev_err(dev, 236*356b01a9SLuo Jiaxing "failed to get number of lines for port%d and use default value instead\n", 237*356b01a9SLuo Jiaxing idx); 238*356b01a9SLuo Jiaxing hisi_gpio->line_num = HISI_GPIO_LINE_NUM_MAX; 239*356b01a9SLuo Jiaxing } 240*356b01a9SLuo Jiaxing 241*356b01a9SLuo Jiaxing if (WARN_ON(hisi_gpio->line_num > HISI_GPIO_LINE_NUM_MAX)) 242*356b01a9SLuo Jiaxing hisi_gpio->line_num = HISI_GPIO_LINE_NUM_MAX; 243*356b01a9SLuo Jiaxing 244*356b01a9SLuo Jiaxing hisi_gpio->irq = platform_get_irq(pdev, idx); 245*356b01a9SLuo Jiaxing 246*356b01a9SLuo Jiaxing dev_info(dev, 247*356b01a9SLuo Jiaxing "get hisi_gpio[%d] with %d lines\n", idx, 248*356b01a9SLuo Jiaxing hisi_gpio->line_num); 249*356b01a9SLuo Jiaxing 250*356b01a9SLuo Jiaxing idx++; 251*356b01a9SLuo Jiaxing } 252*356b01a9SLuo Jiaxing } 253*356b01a9SLuo Jiaxing 254*356b01a9SLuo Jiaxing static int hisi_gpio_probe(struct platform_device *pdev) 255*356b01a9SLuo Jiaxing { 256*356b01a9SLuo Jiaxing struct device *dev = &pdev->dev; 257*356b01a9SLuo Jiaxing void __iomem *dat, *set, *clr; 258*356b01a9SLuo Jiaxing struct hisi_gpio *hisi_gpio; 259*356b01a9SLuo Jiaxing int port_num; 260*356b01a9SLuo Jiaxing int ret; 261*356b01a9SLuo Jiaxing 262*356b01a9SLuo Jiaxing /* 263*356b01a9SLuo Jiaxing * One GPIO controller own one port currently, 264*356b01a9SLuo Jiaxing * if we get more from ACPI table, return error. 265*356b01a9SLuo Jiaxing */ 266*356b01a9SLuo Jiaxing port_num = device_get_child_node_count(dev); 267*356b01a9SLuo Jiaxing if (WARN_ON(port_num != 1)) 268*356b01a9SLuo Jiaxing return -ENODEV; 269*356b01a9SLuo Jiaxing 270*356b01a9SLuo Jiaxing hisi_gpio = devm_kzalloc(dev, sizeof(*hisi_gpio), GFP_KERNEL); 271*356b01a9SLuo Jiaxing if (!hisi_gpio) 272*356b01a9SLuo Jiaxing return -ENOMEM; 273*356b01a9SLuo Jiaxing 274*356b01a9SLuo Jiaxing hisi_gpio->reg_base = devm_platform_ioremap_resource(pdev, 0); 275*356b01a9SLuo Jiaxing if (IS_ERR(hisi_gpio->reg_base)) 276*356b01a9SLuo Jiaxing return PTR_ERR(hisi_gpio->reg_base); 277*356b01a9SLuo Jiaxing 278*356b01a9SLuo Jiaxing hisi_gpio_get_pdata(dev, hisi_gpio); 279*356b01a9SLuo Jiaxing 280*356b01a9SLuo Jiaxing hisi_gpio->dev = dev; 281*356b01a9SLuo Jiaxing 282*356b01a9SLuo Jiaxing dat = hisi_gpio->reg_base + HISI_GPIO_EXT_PORT_WX; 283*356b01a9SLuo Jiaxing set = hisi_gpio->reg_base + HISI_GPIO_SWPORT_DR_SET_WX; 284*356b01a9SLuo Jiaxing clr = hisi_gpio->reg_base + HISI_GPIO_SWPORT_DR_CLR_WX; 285*356b01a9SLuo Jiaxing 286*356b01a9SLuo Jiaxing ret = bgpio_init(&hisi_gpio->chip, hisi_gpio->dev, 0x4, 287*356b01a9SLuo Jiaxing hisi_gpio->reg_base + HISI_GPIO_EXT_PORT_WX, 288*356b01a9SLuo Jiaxing hisi_gpio->reg_base + HISI_GPIO_SWPORT_DR_SET_WX, 289*356b01a9SLuo Jiaxing hisi_gpio->reg_base + HISI_GPIO_SWPORT_DR_CLR_WX, 290*356b01a9SLuo Jiaxing hisi_gpio->reg_base + HISI_GPIO_SWPORT_DDR_SET_WX, 291*356b01a9SLuo Jiaxing hisi_gpio->reg_base + HISI_GPIO_SWPORT_DDR_CLR_WX, 292*356b01a9SLuo Jiaxing BGPIOF_NO_SET_ON_INPUT); 293*356b01a9SLuo Jiaxing if (ret) { 294*356b01a9SLuo Jiaxing dev_err(dev, "failed to init, ret = %d\n", ret); 295*356b01a9SLuo Jiaxing return ret; 296*356b01a9SLuo Jiaxing } 297*356b01a9SLuo Jiaxing 298*356b01a9SLuo Jiaxing hisi_gpio->chip.set_config = hisi_gpio_set_config; 299*356b01a9SLuo Jiaxing hisi_gpio->chip.ngpio = hisi_gpio->line_num; 300*356b01a9SLuo Jiaxing hisi_gpio->chip.bgpio_dir_unreadable = 1; 301*356b01a9SLuo Jiaxing hisi_gpio->chip.base = -1; 302*356b01a9SLuo Jiaxing 303*356b01a9SLuo Jiaxing if (hisi_gpio->irq > 0) 304*356b01a9SLuo Jiaxing hisi_gpio_init_irq(hisi_gpio); 305*356b01a9SLuo Jiaxing 306*356b01a9SLuo Jiaxing ret = devm_gpiochip_add_data(dev, &hisi_gpio->chip, hisi_gpio); 307*356b01a9SLuo Jiaxing if (ret) { 308*356b01a9SLuo Jiaxing dev_err(dev, "failed to register gpiochip, ret = %d\n", ret); 309*356b01a9SLuo Jiaxing return ret; 310*356b01a9SLuo Jiaxing } 311*356b01a9SLuo Jiaxing 312*356b01a9SLuo Jiaxing return 0; 313*356b01a9SLuo Jiaxing } 314*356b01a9SLuo Jiaxing 315*356b01a9SLuo Jiaxing static struct platform_driver hisi_gpio_driver = { 316*356b01a9SLuo Jiaxing .driver = { 317*356b01a9SLuo Jiaxing .name = HISI_GPIO_DRIVER_NAME, 318*356b01a9SLuo Jiaxing .acpi_match_table = hisi_gpio_acpi_match, 319*356b01a9SLuo Jiaxing }, 320*356b01a9SLuo Jiaxing .probe = hisi_gpio_probe, 321*356b01a9SLuo Jiaxing }; 322*356b01a9SLuo Jiaxing 323*356b01a9SLuo Jiaxing module_platform_driver(hisi_gpio_driver); 324*356b01a9SLuo Jiaxing 325*356b01a9SLuo Jiaxing MODULE_LICENSE("GPL"); 326*356b01a9SLuo Jiaxing MODULE_AUTHOR("Luo Jiaxing <luojiaxing@huawei.com>"); 327*356b01a9SLuo Jiaxing MODULE_DESCRIPTION("HiSilicon GPIO controller driver"); 328*356b01a9SLuo Jiaxing MODULE_ALIAS("platform:" HISI_GPIO_DRIVER_NAME); 329