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]; 33d759f906SDavid Howells module_param_hw_array(irq, uint, irq, NULL, 0); 3486ea8a95SWilliam Breathitt Gray MODULE_PARM_DESC(irq, "ACCES 104-IDIO-16 interrupt line numbers"); 351ceacea2SWilliam Breathitt Gray 361ceacea2SWilliam Breathitt Gray /** 37cc442e4dSWilliam Breathitt Gray * struct idio_16_reg - device registers structure 38cc442e4dSWilliam Breathitt Gray * @out0_7: Read: N/A 39cc442e4dSWilliam Breathitt Gray * Write: FET Drive Outputs 0-7 40cc442e4dSWilliam Breathitt Gray * @in0_7: Read: Isolated Inputs 0-7 41cc442e4dSWilliam Breathitt Gray * Write: Clear Interrupt 42cc442e4dSWilliam Breathitt Gray * @irq_ctl: Read: Enable IRQ 43cc442e4dSWilliam Breathitt Gray * Write: Disable IRQ 44cc442e4dSWilliam Breathitt Gray * @unused: N/A 45cc442e4dSWilliam Breathitt Gray * @out8_15: Read: N/A 46cc442e4dSWilliam Breathitt Gray * Write: FET Drive Outputs 8-15 47cc442e4dSWilliam Breathitt Gray * @in8_15: Read: Isolated Inputs 8-15 48cc442e4dSWilliam Breathitt Gray * Write: N/A 49cc442e4dSWilliam Breathitt Gray */ 50cc442e4dSWilliam Breathitt Gray struct idio_16_reg { 51cc442e4dSWilliam Breathitt Gray u8 out0_7; 52cc442e4dSWilliam Breathitt Gray u8 in0_7; 53cc442e4dSWilliam Breathitt Gray u8 irq_ctl; 54cc442e4dSWilliam Breathitt Gray u8 unused; 55cc442e4dSWilliam Breathitt Gray u8 out8_15; 56cc442e4dSWilliam Breathitt Gray u8 in8_15; 57cc442e4dSWilliam Breathitt Gray }; 58cc442e4dSWilliam Breathitt Gray 59cc442e4dSWilliam Breathitt Gray /** 601ceacea2SWilliam Breathitt Gray * struct idio_16_gpio - GPIO device private data structure 611ceacea2SWilliam Breathitt Gray * @chip: instance of the gpio_chip 62a1184147SWilliam Breathitt Gray * @lock: synchronization lock to prevent I/O race conditions 63a1184147SWilliam Breathitt Gray * @irq_mask: I/O bits affected by interrupts 64cc442e4dSWilliam Breathitt Gray * @reg: I/O address offset for the device registers 651ceacea2SWilliam Breathitt Gray * @out_state: output bits state 661ceacea2SWilliam Breathitt Gray */ 671ceacea2SWilliam Breathitt Gray struct idio_16_gpio { 681ceacea2SWilliam Breathitt Gray struct gpio_chip chip; 693906e808SJulia Cartwright raw_spinlock_t lock; 70a1184147SWilliam Breathitt Gray unsigned long irq_mask; 71cc442e4dSWilliam Breathitt Gray struct idio_16_reg __iomem *reg; 72cc0f53d2SNavin Sankar Velliangiri unsigned int out_state; 731ceacea2SWilliam Breathitt Gray }; 741ceacea2SWilliam Breathitt Gray 75cc0f53d2SNavin Sankar Velliangiri static int idio_16_gpio_get_direction(struct gpio_chip *chip, 76cc0f53d2SNavin Sankar Velliangiri unsigned int offset) 771ceacea2SWilliam Breathitt Gray { 781ceacea2SWilliam Breathitt Gray if (offset > 15) 79e42615ecSMatti Vaittinen return GPIO_LINE_DIRECTION_IN; 801ceacea2SWilliam Breathitt Gray 81e42615ecSMatti Vaittinen return GPIO_LINE_DIRECTION_OUT; 821ceacea2SWilliam Breathitt Gray } 831ceacea2SWilliam Breathitt Gray 84cc0f53d2SNavin Sankar Velliangiri static int idio_16_gpio_direction_input(struct gpio_chip *chip, 85cc0f53d2SNavin Sankar Velliangiri unsigned int offset) 861ceacea2SWilliam Breathitt Gray { 871ceacea2SWilliam Breathitt Gray return 0; 881ceacea2SWilliam Breathitt Gray } 891ceacea2SWilliam Breathitt Gray 901ceacea2SWilliam Breathitt Gray static int idio_16_gpio_direction_output(struct gpio_chip *chip, 91cc0f53d2SNavin Sankar Velliangiri unsigned int offset, int value) 921ceacea2SWilliam Breathitt Gray { 931ceacea2SWilliam Breathitt Gray chip->set(chip, offset, value); 941ceacea2SWilliam Breathitt Gray return 0; 951ceacea2SWilliam Breathitt Gray } 961ceacea2SWilliam Breathitt Gray 97cc0f53d2SNavin Sankar Velliangiri static int idio_16_gpio_get(struct gpio_chip *chip, unsigned int offset) 981ceacea2SWilliam Breathitt Gray { 99d602ae90SLinus Walleij struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 100cc0f53d2SNavin Sankar Velliangiri const unsigned int mask = BIT(offset-16); 1011ceacea2SWilliam Breathitt Gray 1021ceacea2SWilliam Breathitt Gray if (offset < 16) 1031ceacea2SWilliam Breathitt Gray return -EINVAL; 1041ceacea2SWilliam Breathitt Gray 1051ceacea2SWilliam Breathitt Gray if (offset < 24) 106cc442e4dSWilliam Breathitt Gray return !!(ioread8(&idio16gpio->reg->in0_7) & mask); 1071ceacea2SWilliam Breathitt Gray 108cc442e4dSWilliam Breathitt Gray return !!(ioread8(&idio16gpio->reg->in8_15) & (mask>>8)); 1091ceacea2SWilliam Breathitt Gray } 1101ceacea2SWilliam Breathitt Gray 11115f59cffSWilliam Breathitt Gray static int idio_16_gpio_get_multiple(struct gpio_chip *chip, 11215f59cffSWilliam Breathitt Gray unsigned long *mask, unsigned long *bits) 11315f59cffSWilliam Breathitt Gray { 11415f59cffSWilliam Breathitt Gray struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 11515f59cffSWilliam Breathitt Gray 11615f59cffSWilliam Breathitt Gray *bits = 0; 11715f59cffSWilliam Breathitt Gray if (*mask & GENMASK(23, 16)) 118cc442e4dSWilliam Breathitt Gray *bits |= (unsigned long)ioread8(&idio16gpio->reg->in0_7) << 16; 11915f59cffSWilliam Breathitt Gray if (*mask & GENMASK(31, 24)) 120cc442e4dSWilliam Breathitt Gray *bits |= (unsigned long)ioread8(&idio16gpio->reg->in8_15) << 24; 12115f59cffSWilliam Breathitt Gray 12215f59cffSWilliam Breathitt Gray return 0; 12315f59cffSWilliam Breathitt Gray } 12415f59cffSWilliam Breathitt Gray 125cc0f53d2SNavin Sankar Velliangiri static void idio_16_gpio_set(struct gpio_chip *chip, unsigned int offset, 126cc0f53d2SNavin Sankar Velliangiri int value) 1271ceacea2SWilliam Breathitt Gray { 128d602ae90SLinus Walleij struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 129cc0f53d2SNavin Sankar Velliangiri const unsigned int mask = BIT(offset); 1301ceacea2SWilliam Breathitt Gray unsigned long flags; 1311ceacea2SWilliam Breathitt Gray 1321ceacea2SWilliam Breathitt Gray if (offset > 15) 1331ceacea2SWilliam Breathitt Gray return; 1341ceacea2SWilliam Breathitt Gray 1353906e808SJulia Cartwright raw_spin_lock_irqsave(&idio16gpio->lock, flags); 1361ceacea2SWilliam Breathitt Gray 1371ceacea2SWilliam Breathitt Gray if (value) 1386e0171b4SWilliam Breathitt Gray idio16gpio->out_state |= mask; 1391ceacea2SWilliam Breathitt Gray else 1406e0171b4SWilliam Breathitt Gray idio16gpio->out_state &= ~mask; 1411ceacea2SWilliam Breathitt Gray 1421ceacea2SWilliam Breathitt Gray if (offset > 7) 143cc442e4dSWilliam Breathitt Gray iowrite8(idio16gpio->out_state >> 8, &idio16gpio->reg->out8_15); 1441ceacea2SWilliam Breathitt Gray else 145cc442e4dSWilliam Breathitt Gray iowrite8(idio16gpio->out_state, &idio16gpio->reg->out0_7); 1461ceacea2SWilliam Breathitt Gray 1473906e808SJulia Cartwright raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); 1481ceacea2SWilliam Breathitt Gray } 1491ceacea2SWilliam Breathitt Gray 1509d7ae812SWilliam Breathitt Gray static void idio_16_gpio_set_multiple(struct gpio_chip *chip, 1519d7ae812SWilliam Breathitt Gray unsigned long *mask, unsigned long *bits) 1529d7ae812SWilliam Breathitt Gray { 1539d7ae812SWilliam Breathitt Gray struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 1549d7ae812SWilliam Breathitt Gray unsigned long flags; 1559d7ae812SWilliam Breathitt Gray 1563906e808SJulia Cartwright raw_spin_lock_irqsave(&idio16gpio->lock, flags); 1579d7ae812SWilliam Breathitt Gray 1589d7ae812SWilliam Breathitt Gray idio16gpio->out_state &= ~*mask; 1599d7ae812SWilliam Breathitt Gray idio16gpio->out_state |= *mask & *bits; 1609d7ae812SWilliam Breathitt Gray 1619d7ae812SWilliam Breathitt Gray if (*mask & 0xFF) 162cc442e4dSWilliam Breathitt Gray iowrite8(idio16gpio->out_state, &idio16gpio->reg->out0_7); 1639d7ae812SWilliam Breathitt Gray if ((*mask >> 8) & 0xFF) 164cc442e4dSWilliam Breathitt Gray iowrite8(idio16gpio->out_state >> 8, &idio16gpio->reg->out8_15); 1659d7ae812SWilliam Breathitt Gray 1663906e808SJulia Cartwright raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); 1679d7ae812SWilliam Breathitt Gray } 1689d7ae812SWilliam Breathitt Gray 169a1184147SWilliam Breathitt Gray static void idio_16_irq_ack(struct irq_data *data) 170a1184147SWilliam Breathitt Gray { 171a1184147SWilliam Breathitt Gray } 172a1184147SWilliam Breathitt Gray 173a1184147SWilliam Breathitt Gray static void idio_16_irq_mask(struct irq_data *data) 174a1184147SWilliam Breathitt Gray { 175a1184147SWilliam Breathitt Gray struct gpio_chip *chip = irq_data_get_irq_chip_data(data); 176d602ae90SLinus Walleij struct idio_16_gpio *const idio16gpio = gpiochip_get_data(chip); 177*410a5041SWilliam Breathitt Gray const unsigned long offset = irqd_to_hwirq(data); 178a1184147SWilliam Breathitt Gray unsigned long flags; 179a1184147SWilliam Breathitt Gray 180*410a5041SWilliam Breathitt Gray idio16gpio->irq_mask &= ~BIT(offset); 181*410a5041SWilliam Breathitt Gray gpiochip_disable_irq(chip, offset); 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); 196*410a5041SWilliam Breathitt Gray const unsigned long offset = 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 200*410a5041SWilliam Breathitt Gray gpiochip_enable_irq(chip, offset); 201*410a5041SWilliam Breathitt Gray idio16gpio->irq_mask |= BIT(offset); 202a1184147SWilliam Breathitt Gray 203a1184147SWilliam Breathitt Gray if (!prev_irq_mask) { 2043906e808SJulia Cartwright raw_spin_lock_irqsave(&idio16gpio->lock, flags); 205a1184147SWilliam Breathitt Gray 206cc442e4dSWilliam Breathitt Gray ioread8(&idio16gpio->reg->irq_ctl); 207a1184147SWilliam Breathitt Gray 2083906e808SJulia Cartwright raw_spin_unlock_irqrestore(&idio16gpio->lock, flags); 209a1184147SWilliam Breathitt Gray } 210a1184147SWilliam Breathitt Gray } 211a1184147SWilliam Breathitt Gray 212cc0f53d2SNavin Sankar Velliangiri static int idio_16_irq_set_type(struct irq_data *data, unsigned int flow_type) 213a1184147SWilliam Breathitt Gray { 214a1184147SWilliam Breathitt Gray /* The only valid irq types are none and both-edges */ 215a1184147SWilliam Breathitt Gray if (flow_type != IRQ_TYPE_NONE && 216a1184147SWilliam Breathitt Gray (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH) 217a1184147SWilliam Breathitt Gray return -EINVAL; 218a1184147SWilliam Breathitt Gray 219a1184147SWilliam Breathitt Gray return 0; 220a1184147SWilliam Breathitt Gray } 221a1184147SWilliam Breathitt Gray 222*410a5041SWilliam Breathitt Gray static const struct irq_chip idio_16_irqchip = { 223a1184147SWilliam Breathitt Gray .name = "104-idio-16", 224a1184147SWilliam Breathitt Gray .irq_ack = idio_16_irq_ack, 225a1184147SWilliam Breathitt Gray .irq_mask = idio_16_irq_mask, 226a1184147SWilliam Breathitt Gray .irq_unmask = idio_16_irq_unmask, 227*410a5041SWilliam Breathitt Gray .irq_set_type = idio_16_irq_set_type, 228*410a5041SWilliam Breathitt Gray .flags = IRQCHIP_IMMUTABLE, 229*410a5041SWilliam Breathitt Gray GPIOCHIP_IRQ_RESOURCE_HELPERS, 230a1184147SWilliam Breathitt Gray }; 231a1184147SWilliam Breathitt Gray 232a1184147SWilliam Breathitt Gray static irqreturn_t idio_16_irq_handler(int irq, void *dev_id) 233a1184147SWilliam Breathitt Gray { 234a1184147SWilliam Breathitt Gray struct idio_16_gpio *const idio16gpio = dev_id; 235a1184147SWilliam Breathitt Gray struct gpio_chip *const chip = &idio16gpio->chip; 236a1184147SWilliam Breathitt Gray int gpio; 237a1184147SWilliam Breathitt Gray 238a1184147SWilliam Breathitt Gray for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio) 239dbd1c54fSMarc Zyngier generic_handle_domain_irq(chip->irq.domain, gpio); 240a1184147SWilliam Breathitt Gray 2413906e808SJulia Cartwright raw_spin_lock(&idio16gpio->lock); 24212b61c9dSWilliam Breathitt Gray 243cc442e4dSWilliam Breathitt Gray iowrite8(0, &idio16gpio->reg->in0_7); 24412b61c9dSWilliam Breathitt Gray 2453906e808SJulia Cartwright raw_spin_unlock(&idio16gpio->lock); 24612b61c9dSWilliam Breathitt Gray 247a1184147SWilliam Breathitt Gray return IRQ_HANDLED; 248a1184147SWilliam Breathitt Gray } 249a1184147SWilliam Breathitt Gray 250e0af4b5eSWilliam Breathitt Gray #define IDIO_16_NGPIO 32 251e0af4b5eSWilliam Breathitt Gray static const char *idio_16_names[IDIO_16_NGPIO] = { 252e0af4b5eSWilliam Breathitt Gray "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7", 253e0af4b5eSWilliam Breathitt Gray "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15", 254e0af4b5eSWilliam Breathitt Gray "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7", 255e0af4b5eSWilliam Breathitt Gray "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15" 256e0af4b5eSWilliam Breathitt Gray }; 257e0af4b5eSWilliam Breathitt Gray 25882e4613dSLinus Walleij static int idio_16_irq_init_hw(struct gpio_chip *gc) 25982e4613dSLinus Walleij { 26082e4613dSLinus Walleij struct idio_16_gpio *const idio16gpio = gpiochip_get_data(gc); 26182e4613dSLinus Walleij 26282e4613dSLinus Walleij /* Disable IRQ by default */ 263cc442e4dSWilliam Breathitt Gray iowrite8(0, &idio16gpio->reg->irq_ctl); 264cc442e4dSWilliam Breathitt Gray iowrite8(0, &idio16gpio->reg->in0_7); 26582e4613dSLinus Walleij 26682e4613dSLinus Walleij return 0; 26782e4613dSLinus Walleij } 26882e4613dSLinus Walleij 26986ea8a95SWilliam Breathitt Gray static int idio_16_probe(struct device *dev, unsigned int id) 2701ceacea2SWilliam Breathitt Gray { 2711ceacea2SWilliam Breathitt Gray struct idio_16_gpio *idio16gpio; 2726e0171b4SWilliam Breathitt Gray const char *const name = dev_name(dev); 27382e4613dSLinus Walleij struct gpio_irq_chip *girq; 2741ceacea2SWilliam Breathitt Gray int err; 2751ceacea2SWilliam Breathitt Gray 2761ceacea2SWilliam Breathitt Gray idio16gpio = devm_kzalloc(dev, sizeof(*idio16gpio), GFP_KERNEL); 2771ceacea2SWilliam Breathitt Gray if (!idio16gpio) 2781ceacea2SWilliam Breathitt Gray return -ENOMEM; 2791ceacea2SWilliam Breathitt Gray 28086ea8a95SWilliam Breathitt Gray if (!devm_request_region(dev, base[id], IDIO_16_EXTENT, name)) { 281cb32389cSWilliam Breathitt Gray dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", 28286ea8a95SWilliam Breathitt Gray base[id], base[id] + IDIO_16_EXTENT); 283cb32389cSWilliam Breathitt Gray return -EBUSY; 2841ceacea2SWilliam Breathitt Gray } 2851ceacea2SWilliam Breathitt Gray 286cc442e4dSWilliam Breathitt Gray idio16gpio->reg = devm_ioport_map(dev, base[id], IDIO_16_EXTENT); 287cc442e4dSWilliam Breathitt Gray if (!idio16gpio->reg) 288e0a574efSWilliam Breathitt Gray return -ENOMEM; 289e0a574efSWilliam Breathitt Gray 2906e0171b4SWilliam Breathitt Gray idio16gpio->chip.label = name; 29158383c78SLinus Walleij idio16gpio->chip.parent = dev; 2921ceacea2SWilliam Breathitt Gray idio16gpio->chip.owner = THIS_MODULE; 2931ceacea2SWilliam Breathitt Gray idio16gpio->chip.base = -1; 294e0af4b5eSWilliam Breathitt Gray idio16gpio->chip.ngpio = IDIO_16_NGPIO; 295e0af4b5eSWilliam Breathitt Gray idio16gpio->chip.names = idio_16_names; 2961ceacea2SWilliam Breathitt Gray idio16gpio->chip.get_direction = idio_16_gpio_get_direction; 2971ceacea2SWilliam Breathitt Gray idio16gpio->chip.direction_input = idio_16_gpio_direction_input; 2981ceacea2SWilliam Breathitt Gray idio16gpio->chip.direction_output = idio_16_gpio_direction_output; 2991ceacea2SWilliam Breathitt Gray idio16gpio->chip.get = idio_16_gpio_get; 30015f59cffSWilliam Breathitt Gray idio16gpio->chip.get_multiple = idio_16_gpio_get_multiple; 3011ceacea2SWilliam Breathitt Gray idio16gpio->chip.set = idio_16_gpio_set; 3029d7ae812SWilliam Breathitt Gray idio16gpio->chip.set_multiple = idio_16_gpio_set_multiple; 3031ceacea2SWilliam Breathitt Gray idio16gpio->out_state = 0xFFFF; 3041ceacea2SWilliam Breathitt Gray 30582e4613dSLinus Walleij girq = &idio16gpio->chip.irq; 306*410a5041SWilliam Breathitt Gray gpio_irq_chip_set_chip(girq, &idio_16_irqchip); 30782e4613dSLinus Walleij /* This will let us handle the parent IRQ in the driver */ 30882e4613dSLinus Walleij girq->parent_handler = NULL; 30982e4613dSLinus Walleij girq->num_parents = 0; 31082e4613dSLinus Walleij girq->parents = NULL; 31182e4613dSLinus Walleij girq->default_type = IRQ_TYPE_NONE; 31282e4613dSLinus Walleij girq->handler = handle_edge_irq; 31382e4613dSLinus Walleij girq->init_hw = idio_16_irq_init_hw; 31482e4613dSLinus Walleij 3153906e808SJulia Cartwright raw_spin_lock_init(&idio16gpio->lock); 3161ceacea2SWilliam Breathitt Gray 317837143d3SWilliam Breathitt Gray err = devm_gpiochip_add_data(dev, &idio16gpio->chip, idio16gpio); 3181ceacea2SWilliam Breathitt Gray if (err) { 3191ceacea2SWilliam Breathitt Gray dev_err(dev, "GPIO registering failed (%d)\n", err); 320cb32389cSWilliam Breathitt Gray return err; 3211ceacea2SWilliam Breathitt Gray } 3221ceacea2SWilliam Breathitt Gray 323837143d3SWilliam Breathitt Gray err = devm_request_irq(dev, irq[id], idio_16_irq_handler, 0, name, 324837143d3SWilliam Breathitt Gray idio16gpio); 325837143d3SWilliam Breathitt Gray if (err) { 326837143d3SWilliam Breathitt Gray dev_err(dev, "IRQ handler registering failed (%d)\n", err); 327837143d3SWilliam Breathitt Gray return err; 328837143d3SWilliam Breathitt Gray } 3291ceacea2SWilliam Breathitt Gray 3301ceacea2SWilliam Breathitt Gray return 0; 3311ceacea2SWilliam Breathitt Gray } 3321ceacea2SWilliam Breathitt Gray 33386ea8a95SWilliam Breathitt Gray static struct isa_driver idio_16_driver = { 33486ea8a95SWilliam Breathitt Gray .probe = idio_16_probe, 3351ceacea2SWilliam Breathitt Gray .driver = { 3361ceacea2SWilliam Breathitt Gray .name = "104-idio-16" 3371ceacea2SWilliam Breathitt Gray }, 3381ceacea2SWilliam Breathitt Gray }; 3391ceacea2SWilliam Breathitt Gray 34086ea8a95SWilliam Breathitt Gray module_isa_driver(idio_16_driver, num_idio_16); 3411ceacea2SWilliam Breathitt Gray 3421ceacea2SWilliam Breathitt Gray MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); 3431ceacea2SWilliam Breathitt Gray MODULE_DESCRIPTION("ACCES 104-IDIO-16 GPIO driver"); 34422aeddb5SWilliam Breathitt Gray MODULE_LICENSE("GPL v2"); 345