11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 21ceacea2SWilliam Breathitt Gray /* 31ceacea2SWilliam Breathitt Gray * GPIO driver for the ACCES 104-IDIO-16 family 41ceacea2SWilliam Breathitt Gray * Copyright (C) 2015 William Breathitt Gray 51ceacea2SWilliam Breathitt Gray * 686ea8a95SWilliam Breathitt Gray * This driver supports the following ACCES devices: 104-IDIO-16, 786ea8a95SWilliam Breathitt Gray * 104-IDIO-16E, 104-IDO-16, 104-IDIO-8, 104-IDIO-8E, and 104-IDO-8. 81ceacea2SWilliam Breathitt Gray */ 9cc442e4dSWilliam Breathitt Gray #include <linux/bits.h> 101ceacea2SWilliam Breathitt Gray #include <linux/device.h> 111ceacea2SWilliam Breathitt Gray #include <linux/errno.h> 121ceacea2SWilliam Breathitt Gray #include <linux/gpio/driver.h> 131ceacea2SWilliam Breathitt Gray #include <linux/io.h> 141ceacea2SWilliam Breathitt Gray #include <linux/ioport.h> 15a1184147SWilliam Breathitt Gray #include <linux/interrupt.h> 16a1184147SWilliam Breathitt Gray #include <linux/irqdesc.h> 1786ea8a95SWilliam Breathitt Gray #include <linux/isa.h> 181ceacea2SWilliam Breathitt Gray #include <linux/kernel.h> 191ceacea2SWilliam Breathitt Gray #include <linux/module.h> 201ceacea2SWilliam Breathitt Gray #include <linux/moduleparam.h> 211ceacea2SWilliam Breathitt Gray #include <linux/spinlock.h> 22cc442e4dSWilliam Breathitt Gray #include <linux/types.h> 231ceacea2SWilliam Breathitt Gray 2486ea8a95SWilliam Breathitt Gray #define IDIO_16_EXTENT 8 2586ea8a95SWilliam Breathitt Gray #define MAX_NUM_IDIO_16 max_num_isa_dev(IDIO_16_EXTENT) 2686ea8a95SWilliam Breathitt Gray 2786ea8a95SWilliam Breathitt Gray static unsigned int base[MAX_NUM_IDIO_16]; 2886ea8a95SWilliam Breathitt Gray static unsigned int num_idio_16; 29d759f906SDavid Howells module_param_hw_array(base, uint, ioport, &num_idio_16, 0); 3086ea8a95SWilliam Breathitt Gray MODULE_PARM_DESC(base, "ACCES 104-IDIO-16 base addresses"); 3186ea8a95SWilliam Breathitt Gray 3286ea8a95SWilliam Breathitt Gray static unsigned int irq[MAX_NUM_IDIO_16]; 33*c6074f3fSWilliam Breathitt Gray static unsigned int num_irq; 34*c6074f3fSWilliam Breathitt Gray module_param_hw_array(irq, uint, irq, &num_irq, 0); 3586ea8a95SWilliam Breathitt Gray MODULE_PARM_DESC(irq, "ACCES 104-IDIO-16 interrupt line numbers"); 361ceacea2SWilliam Breathitt Gray 371ceacea2SWilliam Breathitt Gray /** 38cc442e4dSWilliam Breathitt Gray * struct idio_16_reg - device registers structure 39cc442e4dSWilliam Breathitt Gray * @out0_7: Read: N/A 40cc442e4dSWilliam Breathitt Gray * Write: FET Drive Outputs 0-7 41cc442e4dSWilliam Breathitt Gray * @in0_7: Read: Isolated Inputs 0-7 42cc442e4dSWilliam Breathitt Gray * Write: Clear Interrupt 43cc442e4dSWilliam Breathitt Gray * @irq_ctl: Read: Enable IRQ 44cc442e4dSWilliam Breathitt Gray * Write: Disable IRQ 45cc442e4dSWilliam Breathitt Gray * @unused: N/A 46cc442e4dSWilliam Breathitt Gray * @out8_15: Read: N/A 47cc442e4dSWilliam Breathitt Gray * Write: FET Drive Outputs 8-15 48cc442e4dSWilliam Breathitt Gray * @in8_15: Read: Isolated Inputs 8-15 49cc442e4dSWilliam Breathitt Gray * Write: N/A 50cc442e4dSWilliam Breathitt Gray */ 51cc442e4dSWilliam Breathitt Gray struct idio_16_reg { 52cc442e4dSWilliam Breathitt Gray u8 out0_7; 53cc442e4dSWilliam Breathitt Gray u8 in0_7; 54cc442e4dSWilliam Breathitt Gray u8 irq_ctl; 55cc442e4dSWilliam Breathitt Gray u8 unused; 56cc442e4dSWilliam Breathitt Gray u8 out8_15; 57cc442e4dSWilliam Breathitt Gray u8 in8_15; 58cc442e4dSWilliam Breathitt Gray }; 59cc442e4dSWilliam Breathitt Gray 60cc442e4dSWilliam Breathitt Gray /** 611ceacea2SWilliam Breathitt Gray * struct idio_16_gpio - GPIO device private data structure 621ceacea2SWilliam Breathitt Gray * @chip: instance of the gpio_chip 63a1184147SWilliam Breathitt Gray * @lock: synchronization lock to prevent I/O race conditions 64a1184147SWilliam Breathitt Gray * @irq_mask: I/O bits affected by interrupts 65cc442e4dSWilliam Breathitt Gray * @reg: I/O address offset for the device registers 661ceacea2SWilliam Breathitt Gray * @out_state: output bits state 671ceacea2SWilliam Breathitt Gray */ 681ceacea2SWilliam Breathitt Gray struct idio_16_gpio { 691ceacea2SWilliam Breathitt Gray struct gpio_chip chip; 703906e808SJulia Cartwright raw_spinlock_t lock; 71a1184147SWilliam Breathitt Gray unsigned long irq_mask; 72cc442e4dSWilliam Breathitt Gray struct idio_16_reg __iomem *reg; 73cc0f53d2SNavin Sankar Velliangiri unsigned int out_state; 741ceacea2SWilliam Breathitt Gray }; 751ceacea2SWilliam Breathitt Gray 76cc0f53d2SNavin Sankar Velliangiri static int idio_16_gpio_get_direction(struct gpio_chip *chip, 77cc0f53d2SNavin Sankar Velliangiri unsigned int offset) 781ceacea2SWilliam Breathitt Gray { 791ceacea2SWilliam Breathitt Gray if (offset > 15) 80e42615ecSMatti Vaittinen return GPIO_LINE_DIRECTION_IN; 811ceacea2SWilliam Breathitt Gray 82e42615ecSMatti Vaittinen return GPIO_LINE_DIRECTION_OUT; 831ceacea2SWilliam Breathitt Gray } 841ceacea2SWilliam Breathitt Gray 85cc0f53d2SNavin Sankar Velliangiri static int idio_16_gpio_direction_input(struct gpio_chip *chip, 86cc0f53d2SNavin Sankar Velliangiri unsigned int offset) 871ceacea2SWilliam Breathitt Gray { 881ceacea2SWilliam Breathitt Gray return 0; 891ceacea2SWilliam Breathitt Gray } 901ceacea2SWilliam Breathitt Gray 911ceacea2SWilliam Breathitt Gray static int idio_16_gpio_direction_output(struct gpio_chip *chip, 92cc0f53d2SNavin Sankar Velliangiri unsigned int offset, int value) 931ceacea2SWilliam Breathitt Gray { 941ceacea2SWilliam Breathitt Gray chip->set(chip, offset, value); 951ceacea2SWilliam Breathitt Gray return 0; 961ceacea2SWilliam Breathitt Gray } 971ceacea2SWilliam Breathitt Gray 98cc0f53d2SNavin Sankar Velliangiri static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset) 991ceacea2SWilliam Breathitt Gray { 100d602ae90SLinus Walleij struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 101cc0f53d2SNavin Sankar Velliangiri const unsigned int mask = BIT(offset-16); 1021ceacea2SWilliam Breathitt Gray 1031ceacea2SWilliam Breathitt Gray if (offset < 16) 1041ceacea2SWilliam Breathitt Gray return -EINVAL; 1051ceacea2SWilliam Breathitt Gray 1061ceacea2SWilliam Breathitt Gray if (offset < 24) 107cc442e4dSWilliam Breathitt Gray return !!(ioread8(&idio16gpio->reg->in0_7) & mask); 1081ceacea2SWilliam Breathitt Gray 109cc442e4dSWilliam Breathitt Gray return !!(ioread8(&idio16gpio->reg->in8_15) & (mask>>8)); 1101ceacea2SWilliam Breathitt Gray } 1111ceacea2SWilliam Breathitt Gray 11215f59cffSWilliam Breathitt Gray static int idio_16_gpio_get_multiple(struct gpio_chip *chip, 11315f59cffSWilliam Breathitt Gray unsigned long *mask, unsigned long *bits) 11415f59cffSWilliam Breathitt Gray { 11515f59cffSWilliam Breathitt Gray struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 11615f59cffSWilliam Breathitt Gray 11715f59cffSWilliam Breathitt Gray *bits = 0; 11815f59cffSWilliam Breathitt Gray if (*mask & GENMASK(23, 16)) 119cc442e4dSWilliam Breathitt Gray *bits |= (unsigned long)ioread8(&idio16gpio->reg->in0_7) << 16; 12015f59cffSWilliam Breathitt Gray if (*mask & GENMASK(31, 24)) 121cc442e4dSWilliam Breathitt Gray *bits |= (unsigned long)ioread8(&idio16gpio->reg->in8_15) << 24; 12215f59cffSWilliam Breathitt Gray 12315f59cffSWilliam Breathitt Gray return 0; 12415f59cffSWilliam Breathitt Gray } 12515f59cffSWilliam Breathitt Gray 126cc0f53d2SNavin Sankar Velliangiri static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset, 127cc0f53d2SNavin Sankar Velliangiri int value) 1281ceacea2SWilliam Breathitt Gray { 129d602ae90SLinus Walleij struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 130cc0f53d2SNavin Sankar Velliangiri const unsigned int mask = BIT(offset); 1311ceacea2SWilliam Breathitt Gray unsigned long flags; 1321ceacea2SWilliam Breathitt Gray 1331ceacea2SWilliam Breathitt Gray if (offset > 15) 1341ceacea2SWilliam Breathitt Gray return; 1351ceacea2SWilliam Breathitt Gray 1363906e808SJulia Cartwright raw_spin_lock_irqsave(&idio16gpio->lock, flags); 1371ceacea2SWilliam Breathitt Gray 1381ceacea2SWilliam Breathitt Gray if (value) 1396e0171b4SWilliam Breathitt Gray idio16gpio->out_state |= mask; 1401ceacea2SWilliam Breathitt Gray else 1416e0171b4SWilliam Breathitt Gray idio16gpio->out_state &= ~mask; 1421ceacea2SWilliam Breathitt Gray 1431ceacea2SWilliam Breathitt Gray if (offset > 7) 144cc442e4dSWilliam Breathitt Gray iowrite8(idio16gpio->out_state >> 8, &idio16gpio->reg->out8_15); 1451ceacea2SWilliam Breathitt Gray else 146cc442e4dSWilliam Breathitt Gray iowrite8(idio16gpio->out_state, &idio16gpio->reg->out0_7); 1471ceacea2SWilliam Breathitt Gray 1483906e808SJulia Cartwright raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); 1491ceacea2SWilliam Breathitt Gray } 1501ceacea2SWilliam Breathitt Gray 1519d7ae812SWilliam Breathitt Gray static void idio_16_gpio_set_multiple(struct gpio_chip *chip, 1529d7ae812SWilliam Breathitt Gray unsigned long *mask, unsigned long *bits) 1539d7ae812SWilliam Breathitt Gray { 1549d7ae812SWilliam Breathitt Gray struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 1559d7ae812SWilliam Breathitt Gray unsigned long flags; 1569d7ae812SWilliam Breathitt Gray 1573906e808SJulia Cartwright raw_spin_lock_irqsave(&idio16gpio->lock, flags); 1589d7ae812SWilliam Breathitt Gray 1599d7ae812SWilliam Breathitt Gray idio16gpio->out_state &= ~*mask; 1609d7ae812SWilliam Breathitt Gray idio16gpio->out_state |= *mask & *bits; 1619d7ae812SWilliam Breathitt Gray 1629d7ae812SWilliam Breathitt Gray if (*mask & 0xFF) 163cc442e4dSWilliam Breathitt Gray iowrite8(idio16gpio->out_state, &idio16gpio->reg->out0_7); 1649d7ae812SWilliam Breathitt Gray if ((*mask >> 8) & 0xFF) 165cc442e4dSWilliam Breathitt Gray iowrite8(idio16gpio->out_state >> 8, &idio16gpio->reg->out8_15); 1669d7ae812SWilliam Breathitt Gray 1673906e808SJulia Cartwright raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); 1689d7ae812SWilliam Breathitt Gray } 1699d7ae812SWilliam Breathitt Gray 170a1184147SWilliam Breathitt Gray static void idio_16_irq_ack(struct irq_data *data) 171a1184147SWilliam Breathitt Gray { 172a1184147SWilliam Breathitt Gray } 173a1184147SWilliam Breathitt Gray 174a1184147SWilliam Breathitt Gray static void idio_16_irq_mask(struct irq_data *data) 175a1184147SWilliam Breathitt Gray { 176a1184147SWilliam Breathitt Gray struct gpio_chip *chip = irq_data_get_irq_chip_data(data); 177d602ae90SLinus Walleij struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 178a1184147SWilliam Breathitt Gray const unsigned long mask = BIT(irqd_to_hwirq(data)); 179a1184147SWilliam Breathitt Gray unsigned long flags; 180a1184147SWilliam Breathitt Gray 181a1184147SWilliam Breathitt Gray idio16gpio->irq_mask &= ~mask; 182a1184147SWilliam Breathitt Gray 183a1184147SWilliam Breathitt Gray if (!idio16gpio->irq_mask) { 1843906e808SJulia Cartwright raw_spin_lock_irqsave(&idio16gpio->lock, flags); 185a1184147SWilliam Breathitt Gray 186cc442e4dSWilliam Breathitt Gray iowrite8(0, &idio16gpio->reg->irq_ctl); 187a1184147SWilliam Breathitt Gray 1883906e808SJulia Cartwright raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); 189a1184147SWilliam Breathitt Gray } 190a1184147SWilliam Breathitt Gray } 191a1184147SWilliam Breathitt Gray 192a1184147SWilliam Breathitt Gray static void idio_16_irq_unmask(struct irq_data *data) 193a1184147SWilliam Breathitt Gray { 194a1184147SWilliam Breathitt Gray struct gpio_chip *chip = irq_data_get_irq_chip_data(data); 195d602ae90SLinus Walleij struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 196a1184147SWilliam Breathitt Gray const unsigned long mask = BIT(irqd_to_hwirq(data)); 197a1184147SWilliam Breathitt Gray const unsigned long prev_irq_mask = idio16gpio->irq_mask; 198a1184147SWilliam Breathitt Gray unsigned long flags; 199a1184147SWilliam Breathitt Gray 200a1184147SWilliam Breathitt Gray idio16gpio->irq_mask |= mask; 201a1184147SWilliam Breathitt Gray 202a1184147SWilliam Breathitt Gray if (!prev_irq_mask) { 2033906e808SJulia Cartwright raw_spin_lock_irqsave(&idio16gpio->lock, flags); 204a1184147SWilliam Breathitt Gray 205cc442e4dSWilliam Breathitt Gray ioread8(&idio16gpio->reg->irq_ctl); 206a1184147SWilliam Breathitt Gray 2073906e808SJulia Cartwright raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); 208a1184147SWilliam Breathitt Gray } 209a1184147SWilliam Breathitt Gray } 210a1184147SWilliam Breathitt Gray 211cc0f53d2SNavin Sankar Velliangiri static int idio_16_irq_set_type(struct irq_data *data, unsigned int flow_type) 212a1184147SWilliam Breathitt Gray { 213a1184147SWilliam Breathitt Gray /* The only valid irq types are none and both-edges */ 214a1184147SWilliam Breathitt Gray if (flow_type != IRQ_TYPE_NONE && 215a1184147SWilliam Breathitt Gray (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH) 216a1184147SWilliam Breathitt Gray return -EINVAL; 217a1184147SWilliam Breathitt Gray 218a1184147SWilliam Breathitt Gray return 0; 219a1184147SWilliam Breathitt Gray } 220a1184147SWilliam Breathitt Gray 221a1184147SWilliam Breathitt Gray static struct irq_chip idio_16_irqchip = { 222a1184147SWilliam Breathitt Gray .name = "104-idio-16", 223a1184147SWilliam Breathitt Gray .irq_ack = idio_16_irq_ack, 224a1184147SWilliam Breathitt Gray .irq_mask = idio_16_irq_mask, 225a1184147SWilliam Breathitt Gray .irq_unmask = idio_16_irq_unmask, 226a1184147SWilliam Breathitt Gray .irq_set_type = idio_16_irq_set_type 227a1184147SWilliam Breathitt Gray }; 228a1184147SWilliam Breathitt Gray 229a1184147SWilliam Breathitt Gray static irqreturn_t idio_16_irq_handler(int irq, void *dev_id) 230a1184147SWilliam Breathitt Gray { 231a1184147SWilliam Breathitt Gray struct idio_16_gpio *const idio16gpio = dev_id; 232a1184147SWilliam Breathitt Gray struct gpio_chip *const chip = &idio16gpio->chip; 233a1184147SWilliam Breathitt Gray int gpio; 234a1184147SWilliam Breathitt Gray 235a1184147SWilliam Breathitt Gray for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio) 236dbd1c54fSMarc Zyngier generic_handle_domain_irq(chip->irq.domain, gpio); 237a1184147SWilliam Breathitt Gray 2383906e808SJulia Cartwright raw_spin_lock(&idio16gpio->lock); 23912b61c9dSWilliam Breathitt Gray 240cc442e4dSWilliam Breathitt Gray iowrite8(0, &idio16gpio->reg->in0_7); 24112b61c9dSWilliam Breathitt Gray 2423906e808SJulia Cartwright raw_spin_unlock(&idio16gpio->lock); 24312b61c9dSWilliam Breathitt Gray 244a1184147SWilliam Breathitt Gray return IRQ_HANDLED; 245a1184147SWilliam Breathitt Gray } 246a1184147SWilliam Breathitt Gray 247e0af4b5eSWilliam Breathitt Gray #define IDIO_16_NGPIO 32 248e0af4b5eSWilliam Breathitt Gray static const char *idio_16_names[IDIO_16_NGPIO] = { 249e0af4b5eSWilliam Breathitt Gray "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7", 250e0af4b5eSWilliam Breathitt Gray "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15", 251e0af4b5eSWilliam Breathitt Gray "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7", 252e0af4b5eSWilliam Breathitt Gray "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15" 253e0af4b5eSWilliam Breathitt Gray }; 254e0af4b5eSWilliam Breathitt Gray 25582e4613dSLinus Walleij static int idio_16_irq_init_hw(struct gpio_chip *gc) 25682e4613dSLinus Walleij { 25782e4613dSLinus Walleij struct idio_16_gpio *const idio16gpio = gpiochip_get_data(gc); 25882e4613dSLinus Walleij 25982e4613dSLinus Walleij /* Disable IRQ by default */ 260cc442e4dSWilliam Breathitt Gray iowrite8(0, &idio16gpio->reg->irq_ctl); 261cc442e4dSWilliam Breathitt Gray iowrite8(0, &idio16gpio->reg->in0_7); 26282e4613dSLinus Walleij 26382e4613dSLinus Walleij return 0; 26482e4613dSLinus Walleij } 26582e4613dSLinus Walleij 26686ea8a95SWilliam Breathitt Gray static int idio_16_probe(struct device *dev, unsigned int id) 2671ceacea2SWilliam Breathitt Gray { 2681ceacea2SWilliam Breathitt Gray struct idio_16_gpio *idio16gpio; 2696e0171b4SWilliam Breathitt Gray const char *const name = dev_name(dev); 27082e4613dSLinus Walleij struct gpio_irq_chip *girq; 2711ceacea2SWilliam Breathitt Gray int err; 2721ceacea2SWilliam Breathitt Gray 2731ceacea2SWilliam Breathitt Gray idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL); 2741ceacea2SWilliam Breathitt Gray if (!idio16gpio) 2751ceacea2SWilliam Breathitt Gray return -ENOMEM; 2761ceacea2SWilliam Breathitt Gray 27786ea8a95SWilliam Breathitt Gray if (!devm_request_region(dev, base[id], IDIO_16_EXTENT, name)) { 278cb32389cSWilliam Breathitt Gray dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", 27986ea8a95SWilliam Breathitt Gray base[id], base[id] + IDIO_16_EXTENT); 280cb32389cSWilliam Breathitt Gray return -EBUSY; 2811ceacea2SWilliam Breathitt Gray } 2821ceacea2SWilliam Breathitt Gray 283cc442e4dSWilliam Breathitt Gray idio16gpio->reg = devm_ioport_map(dev, base[id], IDIO_16_EXTENT); 284cc442e4dSWilliam Breathitt Gray if (!idio16gpio->reg) 285e0a574efSWilliam Breathitt Gray return -ENOMEM; 286e0a574efSWilliam Breathitt Gray 2876e0171b4SWilliam Breathitt Gray idio16gpio->chip.label = name; 28858383c78SLinus Walleij idio16gpio->chip.parent = dev; 2891ceacea2SWilliam Breathitt Gray idio16gpio->chip.owner = THIS_MODULE; 2901ceacea2SWilliam Breathitt Gray idio16gpio->chip.base = -1; 291e0af4b5eSWilliam Breathitt Gray idio16gpio->chip.ngpio = IDIO_16_NGPIO; 292e0af4b5eSWilliam Breathitt Gray idio16gpio->chip.names = idio_16_names; 2931ceacea2SWilliam Breathitt Gray idio16gpio->chip.get_direction = idio_16_gpio_get_direction; 2941ceacea2SWilliam Breathitt Gray idio16gpio->chip.direction_input = idio_16_gpio_direction_input; 2951ceacea2SWilliam Breathitt Gray idio16gpio->chip.direction_output = idio_16_gpio_direction_output; 2961ceacea2SWilliam Breathitt Gray idio16gpio->chip.get = idio_16_gpio_get; 29715f59cffSWilliam Breathitt Gray idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple; 2981ceacea2SWilliam Breathitt Gray idio16gpio->chip.set = idio_16_gpio_set; 2999d7ae812SWilliam Breathitt Gray idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple; 3001ceacea2SWilliam Breathitt Gray idio16gpio->out_state = 0xFFFF; 3011ceacea2SWilliam Breathitt Gray 30282e4613dSLinus Walleij girq = &idio16gpio->chip.irq; 30382e4613dSLinus Walleij girq->chip = &idio_16_irqchip; 30482e4613dSLinus Walleij /* This will let us handle the parent IRQ in the driver */ 30582e4613dSLinus Walleij girq->parent_handler = NULL; 30682e4613dSLinus Walleij girq->num_parents = 0; 30782e4613dSLinus Walleij girq->parents = NULL; 30882e4613dSLinus Walleij girq->default_type = IRQ_TYPE_NONE; 30982e4613dSLinus Walleij girq->handler = handle_edge_irq; 31082e4613dSLinus Walleij girq->init_hw = idio_16_irq_init_hw; 31182e4613dSLinus Walleij 3123906e808SJulia Cartwright raw_spin_lock_init(&idio16gpio->lock); 3131ceacea2SWilliam Breathitt Gray 314837143d3SWilliam Breathitt Gray err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio); 3151ceacea2SWilliam Breathitt Gray if (err) { 3161ceacea2SWilliam Breathitt Gray dev_err(dev, "GPIO registering failed (%d)\n", err); 317cb32389cSWilliam Breathitt Gray return err; 3181ceacea2SWilliam Breathitt Gray } 3191ceacea2SWilliam Breathitt Gray 320837143d3SWilliam Breathitt Gray err = devm_request_irq(dev, irq[id], idio_16_irq_handler, 0, name, 321837143d3SWilliam Breathitt Gray idio16gpio); 322837143d3SWilliam Breathitt Gray if (err) { 323837143d3SWilliam Breathitt Gray dev_err(dev, "IRQ handler registering failed (%d)\n", err); 324837143d3SWilliam Breathitt Gray return err; 325837143d3SWilliam Breathitt Gray } 3261ceacea2SWilliam Breathitt Gray 3271ceacea2SWilliam Breathitt Gray return 0; 3281ceacea2SWilliam Breathitt Gray } 3291ceacea2SWilliam Breathitt Gray 33086ea8a95SWilliam Breathitt Gray static struct isa_driver idio_16_driver = { 33186ea8a95SWilliam Breathitt Gray .probe = idio_16_probe, 3321ceacea2SWilliam Breathitt Gray .driver = { 3331ceacea2SWilliam Breathitt Gray .name = "104-idio-16" 3341ceacea2SWilliam Breathitt Gray }, 3351ceacea2SWilliam Breathitt Gray }; 3361ceacea2SWilliam Breathitt Gray 337*c6074f3fSWilliam Breathitt Gray module_isa_driver_with_irq(idio_16_driver, num_idio_16, num_irq); 3381ceacea2SWilliam Breathitt Gray 3391ceacea2SWilliam Breathitt Gray MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); 3401ceacea2SWilliam Breathitt Gray MODULE_DESCRIPTION("ACCES 104-IDIO-16 GPIO driver"); 34122aeddb5SWilliam Breathitt Gray MODULE_LICENSE("GPL v2"); 342