1356b01a9SLuo Jiaxing // SPDX-License-Identifier: GPL-2.0-only 2356b01a9SLuo Jiaxing /* Copyright (c) 2020 HiSilicon Limited. */ 3356b01a9SLuo Jiaxing #include <linux/gpio/driver.h> 4356b01a9SLuo Jiaxing #include <linux/module.h> 5356b01a9SLuo Jiaxing #include <linux/mod_devicetable.h> 6356b01a9SLuo Jiaxing #include <linux/platform_device.h> 7356b01a9SLuo Jiaxing #include <linux/property.h> 8356b01a9SLuo Jiaxing 9356b01a9SLuo Jiaxing #define HISI_GPIO_SWPORT_DR_SET_WX 0x000 10356b01a9SLuo Jiaxing #define HISI_GPIO_SWPORT_DR_CLR_WX 0x004 11356b01a9SLuo Jiaxing #define HISI_GPIO_SWPORT_DDR_SET_WX 0x010 12356b01a9SLuo Jiaxing #define HISI_GPIO_SWPORT_DDR_CLR_WX 0x014 13356b01a9SLuo Jiaxing #define HISI_GPIO_SWPORT_DDR_ST_WX 0x018 14356b01a9SLuo Jiaxing #define HISI_GPIO_INTEN_SET_WX 0x020 15356b01a9SLuo Jiaxing #define HISI_GPIO_INTEN_CLR_WX 0x024 16356b01a9SLuo Jiaxing #define HISI_GPIO_INTMASK_SET_WX 0x030 17356b01a9SLuo Jiaxing #define HISI_GPIO_INTMASK_CLR_WX 0x034 18356b01a9SLuo Jiaxing #define HISI_GPIO_INTTYPE_EDGE_SET_WX 0x040 19356b01a9SLuo Jiaxing #define HISI_GPIO_INTTYPE_EDGE_CLR_WX 0x044 20356b01a9SLuo Jiaxing #define HISI_GPIO_INT_POLARITY_SET_WX 0x050 21356b01a9SLuo Jiaxing #define HISI_GPIO_INT_POLARITY_CLR_WX 0x054 22356b01a9SLuo Jiaxing #define HISI_GPIO_DEBOUNCE_SET_WX 0x060 23356b01a9SLuo Jiaxing #define HISI_GPIO_DEBOUNCE_CLR_WX 0x064 24356b01a9SLuo Jiaxing #define HISI_GPIO_INTSTATUS_WX 0x070 25356b01a9SLuo Jiaxing #define HISI_GPIO_PORTA_EOI_WX 0x078 26356b01a9SLuo Jiaxing #define HISI_GPIO_EXT_PORT_WX 0x080 27356b01a9SLuo Jiaxing #define HISI_GPIO_INTCOMB_MASK_WX 0x0a0 28356b01a9SLuo Jiaxing #define HISI_GPIO_INT_DEDGE_SET 0x0b0 29356b01a9SLuo Jiaxing #define HISI_GPIO_INT_DEDGE_CLR 0x0b4 30356b01a9SLuo Jiaxing #define HISI_GPIO_INT_DEDGE_ST 0x0b8 31356b01a9SLuo Jiaxing 32356b01a9SLuo Jiaxing #define HISI_GPIO_LINE_NUM_MAX 32 33356b01a9SLuo Jiaxing #define HISI_GPIO_DRIVER_NAME "gpio-hisi" 34356b01a9SLuo Jiaxing 35356b01a9SLuo Jiaxing struct hisi_gpio { 36356b01a9SLuo Jiaxing struct gpio_chip chip; 37356b01a9SLuo Jiaxing struct device *dev; 38356b01a9SLuo Jiaxing void __iomem *reg_base; 39356b01a9SLuo Jiaxing unsigned int line_num; 40356b01a9SLuo Jiaxing struct irq_chip irq_chip; 41356b01a9SLuo Jiaxing int irq; 42356b01a9SLuo Jiaxing }; 43356b01a9SLuo Jiaxing 44356b01a9SLuo Jiaxing static inline u32 hisi_gpio_read_reg(struct gpio_chip *chip, 45356b01a9SLuo Jiaxing unsigned int off) 46356b01a9SLuo Jiaxing { 47356b01a9SLuo Jiaxing struct hisi_gpio *hisi_gpio = 48356b01a9SLuo Jiaxing container_of(chip, struct hisi_gpio, chip); 49356b01a9SLuo Jiaxing void __iomem *reg = hisi_gpio->reg_base + off; 50356b01a9SLuo Jiaxing 51356b01a9SLuo Jiaxing return readl(reg); 52356b01a9SLuo Jiaxing } 53356b01a9SLuo Jiaxing 54356b01a9SLuo Jiaxing static inline void hisi_gpio_write_reg(struct gpio_chip *chip, 55356b01a9SLuo Jiaxing unsigned int off, u32 val) 56356b01a9SLuo Jiaxing { 57356b01a9SLuo Jiaxing struct hisi_gpio *hisi_gpio = 58356b01a9SLuo Jiaxing container_of(chip, struct hisi_gpio, chip); 59356b01a9SLuo Jiaxing void __iomem *reg = hisi_gpio->reg_base + off; 60356b01a9SLuo Jiaxing 61356b01a9SLuo Jiaxing writel(val, reg); 62356b01a9SLuo Jiaxing } 63356b01a9SLuo Jiaxing 64356b01a9SLuo Jiaxing static void hisi_gpio_set_debounce(struct gpio_chip *chip, unsigned int off, 65356b01a9SLuo Jiaxing u32 debounce) 66356b01a9SLuo Jiaxing { 67356b01a9SLuo Jiaxing if (debounce) 68356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_DEBOUNCE_SET_WX, BIT(off)); 69356b01a9SLuo Jiaxing else 70356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_DEBOUNCE_CLR_WX, BIT(off)); 71356b01a9SLuo Jiaxing } 72356b01a9SLuo Jiaxing 73356b01a9SLuo Jiaxing static int hisi_gpio_set_config(struct gpio_chip *chip, unsigned int offset, 74356b01a9SLuo Jiaxing unsigned long config) 75356b01a9SLuo Jiaxing { 76356b01a9SLuo Jiaxing u32 config_para = pinconf_to_config_param(config); 77356b01a9SLuo Jiaxing u32 config_arg; 78356b01a9SLuo Jiaxing 79356b01a9SLuo Jiaxing switch (config_para) { 80356b01a9SLuo Jiaxing case PIN_CONFIG_INPUT_DEBOUNCE: 81356b01a9SLuo Jiaxing config_arg = pinconf_to_config_argument(config); 82356b01a9SLuo Jiaxing hisi_gpio_set_debounce(chip, offset, config_arg); 83356b01a9SLuo Jiaxing break; 84356b01a9SLuo Jiaxing default: 85356b01a9SLuo Jiaxing return -ENOTSUPP; 86356b01a9SLuo Jiaxing } 87356b01a9SLuo Jiaxing 88356b01a9SLuo Jiaxing return 0; 89356b01a9SLuo Jiaxing } 90356b01a9SLuo Jiaxing 91356b01a9SLuo Jiaxing static void hisi_gpio_set_ack(struct irq_data *d) 92356b01a9SLuo Jiaxing { 93356b01a9SLuo Jiaxing struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 94356b01a9SLuo Jiaxing 95356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_PORTA_EOI_WX, BIT(irqd_to_hwirq(d))); 96356b01a9SLuo Jiaxing } 97356b01a9SLuo Jiaxing 98356b01a9SLuo Jiaxing static void hisi_gpio_irq_set_mask(struct irq_data *d) 99356b01a9SLuo Jiaxing { 100356b01a9SLuo Jiaxing struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 101356b01a9SLuo Jiaxing 102356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTMASK_SET_WX, BIT(irqd_to_hwirq(d))); 103356b01a9SLuo Jiaxing } 104356b01a9SLuo Jiaxing 105356b01a9SLuo Jiaxing static void hisi_gpio_irq_clr_mask(struct irq_data *d) 106356b01a9SLuo Jiaxing { 107356b01a9SLuo Jiaxing struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 108356b01a9SLuo Jiaxing 109356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTMASK_CLR_WX, BIT(irqd_to_hwirq(d))); 110356b01a9SLuo Jiaxing } 111356b01a9SLuo Jiaxing 112356b01a9SLuo Jiaxing static int hisi_gpio_irq_set_type(struct irq_data *d, u32 type) 113356b01a9SLuo Jiaxing { 114356b01a9SLuo Jiaxing struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 115356b01a9SLuo Jiaxing unsigned int mask = BIT(irqd_to_hwirq(d)); 116356b01a9SLuo Jiaxing 117356b01a9SLuo Jiaxing switch (type) { 118356b01a9SLuo Jiaxing case IRQ_TYPE_EDGE_BOTH: 119356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INT_DEDGE_SET, mask); 120356b01a9SLuo Jiaxing break; 121356b01a9SLuo Jiaxing case IRQ_TYPE_EDGE_RISING: 122356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTTYPE_EDGE_SET_WX, mask); 123356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INT_POLARITY_SET_WX, mask); 124356b01a9SLuo Jiaxing break; 125356b01a9SLuo Jiaxing case IRQ_TYPE_EDGE_FALLING: 126356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTTYPE_EDGE_SET_WX, mask); 127356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INT_POLARITY_CLR_WX, mask); 128356b01a9SLuo Jiaxing break; 129356b01a9SLuo Jiaxing case IRQ_TYPE_LEVEL_HIGH: 130356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTTYPE_EDGE_CLR_WX, mask); 131356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INT_POLARITY_SET_WX, mask); 132356b01a9SLuo Jiaxing break; 133356b01a9SLuo Jiaxing case IRQ_TYPE_LEVEL_LOW: 134356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTTYPE_EDGE_CLR_WX, mask); 135356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INT_POLARITY_CLR_WX, mask); 136356b01a9SLuo Jiaxing break; 137356b01a9SLuo Jiaxing default: 138356b01a9SLuo Jiaxing return -EINVAL; 139356b01a9SLuo Jiaxing } 140356b01a9SLuo Jiaxing 141356b01a9SLuo Jiaxing /* 142356b01a9SLuo Jiaxing * The dual-edge interrupt and other interrupt's registers do not 143356b01a9SLuo Jiaxing * take effect at the same time. The registers of the two-edge 144356b01a9SLuo Jiaxing * interrupts have higher priorities, the configuration of 145356b01a9SLuo Jiaxing * the dual-edge interrupts must be disabled before the configuration 146356b01a9SLuo Jiaxing * of other kind of interrupts. 147356b01a9SLuo Jiaxing */ 148356b01a9SLuo Jiaxing if (type != IRQ_TYPE_EDGE_BOTH) { 149356b01a9SLuo Jiaxing unsigned int both = hisi_gpio_read_reg(chip, HISI_GPIO_INT_DEDGE_ST); 150356b01a9SLuo Jiaxing 151356b01a9SLuo Jiaxing if (both & mask) 152356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INT_DEDGE_CLR, mask); 153356b01a9SLuo Jiaxing } 154356b01a9SLuo Jiaxing 155356b01a9SLuo Jiaxing if (type & IRQ_TYPE_LEVEL_MASK) 156356b01a9SLuo Jiaxing irq_set_handler_locked(d, handle_level_irq); 157356b01a9SLuo Jiaxing else if (type & IRQ_TYPE_EDGE_BOTH) 158356b01a9SLuo Jiaxing irq_set_handler_locked(d, handle_edge_irq); 159356b01a9SLuo Jiaxing 160356b01a9SLuo Jiaxing return 0; 161356b01a9SLuo Jiaxing } 162356b01a9SLuo Jiaxing 163356b01a9SLuo Jiaxing static void hisi_gpio_irq_enable(struct irq_data *d) 164356b01a9SLuo Jiaxing { 165356b01a9SLuo Jiaxing struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 166356b01a9SLuo Jiaxing 167356b01a9SLuo Jiaxing hisi_gpio_irq_clr_mask(d); 168356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTEN_SET_WX, BIT(irqd_to_hwirq(d))); 169356b01a9SLuo Jiaxing } 170356b01a9SLuo Jiaxing 171356b01a9SLuo Jiaxing static void hisi_gpio_irq_disable(struct irq_data *d) 172356b01a9SLuo Jiaxing { 173356b01a9SLuo Jiaxing struct gpio_chip *chip = irq_data_get_irq_chip_data(d); 174356b01a9SLuo Jiaxing 175356b01a9SLuo Jiaxing hisi_gpio_irq_set_mask(d); 176356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTEN_CLR_WX, BIT(irqd_to_hwirq(d))); 177356b01a9SLuo Jiaxing } 178356b01a9SLuo Jiaxing 179356b01a9SLuo Jiaxing static void hisi_gpio_irq_handler(struct irq_desc *desc) 180356b01a9SLuo Jiaxing { 181356b01a9SLuo Jiaxing struct hisi_gpio *hisi_gpio = irq_desc_get_handler_data(desc); 182356b01a9SLuo Jiaxing unsigned long irq_msk = hisi_gpio_read_reg(&hisi_gpio->chip, 183356b01a9SLuo Jiaxing HISI_GPIO_INTSTATUS_WX); 184356b01a9SLuo Jiaxing struct irq_chip *irq_c = irq_desc_get_chip(desc); 185356b01a9SLuo Jiaxing int hwirq; 186356b01a9SLuo Jiaxing 187356b01a9SLuo Jiaxing chained_irq_enter(irq_c, desc); 188356b01a9SLuo Jiaxing for_each_set_bit(hwirq, &irq_msk, HISI_GPIO_LINE_NUM_MAX) 189dbd1c54fSMarc Zyngier generic_handle_domain_irq(hisi_gpio->chip.irq.domain, 190dbd1c54fSMarc Zyngier hwirq); 191356b01a9SLuo Jiaxing chained_irq_exit(irq_c, desc); 192356b01a9SLuo Jiaxing } 193356b01a9SLuo Jiaxing 194356b01a9SLuo Jiaxing static void hisi_gpio_init_irq(struct hisi_gpio *hisi_gpio) 195356b01a9SLuo Jiaxing { 196356b01a9SLuo Jiaxing struct gpio_chip *chip = &hisi_gpio->chip; 197356b01a9SLuo Jiaxing struct gpio_irq_chip *girq_chip = &chip->irq; 198356b01a9SLuo Jiaxing 199356b01a9SLuo Jiaxing /* Set hooks for irq_chip */ 200356b01a9SLuo Jiaxing hisi_gpio->irq_chip.irq_ack = hisi_gpio_set_ack; 201356b01a9SLuo Jiaxing hisi_gpio->irq_chip.irq_mask = hisi_gpio_irq_set_mask; 202356b01a9SLuo Jiaxing hisi_gpio->irq_chip.irq_unmask = hisi_gpio_irq_clr_mask; 203356b01a9SLuo Jiaxing hisi_gpio->irq_chip.irq_set_type = hisi_gpio_irq_set_type; 204356b01a9SLuo Jiaxing hisi_gpio->irq_chip.irq_enable = hisi_gpio_irq_enable; 205356b01a9SLuo Jiaxing hisi_gpio->irq_chip.irq_disable = hisi_gpio_irq_disable; 206356b01a9SLuo Jiaxing 207356b01a9SLuo Jiaxing girq_chip->chip = &hisi_gpio->irq_chip; 208356b01a9SLuo Jiaxing girq_chip->default_type = IRQ_TYPE_NONE; 209356b01a9SLuo Jiaxing girq_chip->num_parents = 1; 210356b01a9SLuo Jiaxing girq_chip->parents = &hisi_gpio->irq; 211356b01a9SLuo Jiaxing girq_chip->parent_handler = hisi_gpio_irq_handler; 212356b01a9SLuo Jiaxing girq_chip->parent_handler_data = hisi_gpio; 213356b01a9SLuo Jiaxing 214356b01a9SLuo Jiaxing /* Clear Mask of GPIO controller combine IRQ */ 215356b01a9SLuo Jiaxing hisi_gpio_write_reg(chip, HISI_GPIO_INTCOMB_MASK_WX, 1); 216356b01a9SLuo Jiaxing } 217356b01a9SLuo Jiaxing 218356b01a9SLuo Jiaxing static const struct acpi_device_id hisi_gpio_acpi_match[] = { 219356b01a9SLuo Jiaxing {"HISI0184", 0}, 220356b01a9SLuo Jiaxing {} 221356b01a9SLuo Jiaxing }; 222356b01a9SLuo Jiaxing MODULE_DEVICE_TABLE(acpi, hisi_gpio_acpi_match); 223356b01a9SLuo Jiaxing 224*80280df7SWeilong Chen static const struct of_device_id hisi_gpio_dts_match[] = { 225*80280df7SWeilong Chen { .compatible = "hisilicon,ascend910-gpio", }, 226*80280df7SWeilong Chen { } 227*80280df7SWeilong Chen }; 228*80280df7SWeilong Chen MODULE_DEVICE_TABLE(of, hisi_gpio_dts_match); 229*80280df7SWeilong Chen 230356b01a9SLuo Jiaxing static void hisi_gpio_get_pdata(struct device *dev, 231356b01a9SLuo Jiaxing struct hisi_gpio *hisi_gpio) 232356b01a9SLuo Jiaxing { 233356b01a9SLuo Jiaxing struct platform_device *pdev = to_platform_device(dev); 234356b01a9SLuo Jiaxing struct fwnode_handle *fwnode; 235356b01a9SLuo Jiaxing int idx = 0; 236356b01a9SLuo Jiaxing 237356b01a9SLuo Jiaxing device_for_each_child_node(dev, fwnode) { 238356b01a9SLuo Jiaxing /* Cycle for once, no need for an array to save line_num */ 239356b01a9SLuo Jiaxing if (fwnode_property_read_u32(fwnode, "ngpios", 240356b01a9SLuo Jiaxing &hisi_gpio->line_num)) { 241356b01a9SLuo Jiaxing dev_err(dev, 242356b01a9SLuo Jiaxing "failed to get number of lines for port%d and use default value instead\n", 243356b01a9SLuo Jiaxing idx); 244356b01a9SLuo Jiaxing hisi_gpio->line_num = HISI_GPIO_LINE_NUM_MAX; 245356b01a9SLuo Jiaxing } 246356b01a9SLuo Jiaxing 247356b01a9SLuo Jiaxing if (WARN_ON(hisi_gpio->line_num > HISI_GPIO_LINE_NUM_MAX)) 248356b01a9SLuo Jiaxing hisi_gpio->line_num = HISI_GPIO_LINE_NUM_MAX; 249356b01a9SLuo Jiaxing 250356b01a9SLuo Jiaxing hisi_gpio->irq = platform_get_irq(pdev, idx); 251356b01a9SLuo Jiaxing 252356b01a9SLuo Jiaxing dev_info(dev, 253356b01a9SLuo Jiaxing "get hisi_gpio[%d] with %d lines\n", idx, 254356b01a9SLuo Jiaxing hisi_gpio->line_num); 255356b01a9SLuo Jiaxing 256356b01a9SLuo Jiaxing idx++; 257356b01a9SLuo Jiaxing } 258356b01a9SLuo Jiaxing } 259356b01a9SLuo Jiaxing 260356b01a9SLuo Jiaxing static int hisi_gpio_probe(struct platform_device *pdev) 261356b01a9SLuo Jiaxing { 262356b01a9SLuo Jiaxing struct device *dev = &pdev->dev; 263356b01a9SLuo Jiaxing struct hisi_gpio *hisi_gpio; 264356b01a9SLuo Jiaxing int port_num; 265356b01a9SLuo Jiaxing int ret; 266356b01a9SLuo Jiaxing 267356b01a9SLuo Jiaxing /* 268356b01a9SLuo Jiaxing * One GPIO controller own one port currently, 269356b01a9SLuo Jiaxing * if we get more from ACPI table, return error. 270356b01a9SLuo Jiaxing */ 271356b01a9SLuo Jiaxing port_num = device_get_child_node_count(dev); 272356b01a9SLuo Jiaxing if (WARN_ON(port_num != 1)) 273356b01a9SLuo Jiaxing return -ENODEV; 274356b01a9SLuo Jiaxing 275356b01a9SLuo Jiaxing hisi_gpio = devm_kzalloc(dev, sizeof(*hisi_gpio), GFP_KERNEL); 276356b01a9SLuo Jiaxing if (!hisi_gpio) 277356b01a9SLuo Jiaxing return -ENOMEM; 278356b01a9SLuo Jiaxing 279356b01a9SLuo Jiaxing hisi_gpio->reg_base = devm_platform_ioremap_resource(pdev, 0); 280356b01a9SLuo Jiaxing if (IS_ERR(hisi_gpio->reg_base)) 281356b01a9SLuo Jiaxing return PTR_ERR(hisi_gpio->reg_base); 282356b01a9SLuo Jiaxing 283356b01a9SLuo Jiaxing hisi_gpio_get_pdata(dev, hisi_gpio); 284356b01a9SLuo Jiaxing 285356b01a9SLuo Jiaxing hisi_gpio->dev = dev; 286356b01a9SLuo Jiaxing 287356b01a9SLuo Jiaxing ret = bgpio_init(&hisi_gpio->chip, hisi_gpio->dev, 0x4, 288356b01a9SLuo Jiaxing hisi_gpio->reg_base + HISI_GPIO_EXT_PORT_WX, 289356b01a9SLuo Jiaxing hisi_gpio->reg_base + HISI_GPIO_SWPORT_DR_SET_WX, 290356b01a9SLuo Jiaxing hisi_gpio->reg_base + HISI_GPIO_SWPORT_DR_CLR_WX, 291356b01a9SLuo Jiaxing hisi_gpio->reg_base + HISI_GPIO_SWPORT_DDR_SET_WX, 292356b01a9SLuo Jiaxing hisi_gpio->reg_base + HISI_GPIO_SWPORT_DDR_CLR_WX, 293356b01a9SLuo Jiaxing BGPIOF_NO_SET_ON_INPUT); 294356b01a9SLuo Jiaxing if (ret) { 295356b01a9SLuo Jiaxing dev_err(dev, "failed to init, ret = %d\n", ret); 296356b01a9SLuo Jiaxing return ret; 297356b01a9SLuo Jiaxing } 298356b01a9SLuo Jiaxing 299356b01a9SLuo Jiaxing hisi_gpio->chip.set_config = hisi_gpio_set_config; 300356b01a9SLuo Jiaxing hisi_gpio->chip.ngpio = hisi_gpio->line_num; 301356b01a9SLuo Jiaxing hisi_gpio->chip.bgpio_dir_unreadable = 1; 302356b01a9SLuo Jiaxing hisi_gpio->chip.base = -1; 303356b01a9SLuo Jiaxing 304356b01a9SLuo Jiaxing if (hisi_gpio->irq > 0) 305356b01a9SLuo Jiaxing hisi_gpio_init_irq(hisi_gpio); 306356b01a9SLuo Jiaxing 307356b01a9SLuo Jiaxing ret = devm_gpiochip_add_data(dev, &hisi_gpio->chip, hisi_gpio); 308356b01a9SLuo Jiaxing if (ret) { 309356b01a9SLuo Jiaxing dev_err(dev, "failed to register gpiochip, ret = %d\n", ret); 310356b01a9SLuo Jiaxing return ret; 311356b01a9SLuo Jiaxing } 312356b01a9SLuo Jiaxing 313356b01a9SLuo Jiaxing return 0; 314356b01a9SLuo Jiaxing } 315356b01a9SLuo Jiaxing 316356b01a9SLuo Jiaxing static struct platform_driver hisi_gpio_driver = { 317356b01a9SLuo Jiaxing .driver = { 318356b01a9SLuo Jiaxing .name = HISI_GPIO_DRIVER_NAME, 319356b01a9SLuo Jiaxing .acpi_match_table = hisi_gpio_acpi_match, 320*80280df7SWeilong Chen .of_match_table = hisi_gpio_dts_match, 321356b01a9SLuo Jiaxing }, 322356b01a9SLuo Jiaxing .probe = hisi_gpio_probe, 323356b01a9SLuo Jiaxing }; 324356b01a9SLuo Jiaxing 325356b01a9SLuo Jiaxing module_platform_driver(hisi_gpio_driver); 326356b01a9SLuo Jiaxing 327356b01a9SLuo Jiaxing MODULE_LICENSE("GPL"); 328356b01a9SLuo Jiaxing MODULE_AUTHOR("Luo Jiaxing <luojiaxing@huawei.com>"); 329356b01a9SLuo Jiaxing MODULE_DESCRIPTION("HiSilicon GPIO controller driver"); 330356b01a9SLuo Jiaxing MODULE_ALIAS("platform:" HISI_GPIO_DRIVER_NAME); 331