^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * GPIO driver for the WinSystems WS16C48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2016 William Breathitt Gray
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/bitmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/irqdesc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/isa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define WS16C48_EXTENT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define MAX_NUM_WS16C48 max_num_isa_dev(WS16C48_EXTENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static unsigned int base[MAX_NUM_WS16C48];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static unsigned int num_ws16c48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) module_param_hw_array(base, uint, ioport, &num_ws16c48, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) MODULE_PARM_DESC(base, "WinSystems WS16C48 base addresses");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static unsigned int irq[MAX_NUM_WS16C48];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) module_param_hw_array(irq, uint, irq, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) MODULE_PARM_DESC(irq, "WinSystems WS16C48 interrupt line numbers");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * struct ws16c48_gpio - GPIO device private data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * @chip: instance of the gpio_chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * @io_state: bit I/O state (whether bit is set to input or output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * @out_state: output bits state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * @lock: synchronization lock to prevent I/O race conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * @irq_mask: I/O bits affected by interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * @flow_mask: IRQ flow type mask for the respective I/O bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * @base: base port address of the GPIO device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct ws16c48_gpio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct gpio_chip chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned char io_state[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned char out_state[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) raw_spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) unsigned long irq_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) unsigned long flow_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) unsigned base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static int ws16c48_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) const unsigned port = offset / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) const unsigned mask = BIT(offset % 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (ws16c48gpio->io_state[port] & mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return GPIO_LINE_DIRECTION_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return GPIO_LINE_DIRECTION_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static int ws16c48_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) const unsigned port = offset / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) const unsigned mask = BIT(offset % 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ws16c48gpio->io_state[port] |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ws16c48gpio->out_state[port] &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static int ws16c48_gpio_direction_output(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) unsigned offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) const unsigned port = offset / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) const unsigned mask = BIT(offset % 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ws16c48gpio->io_state[port] &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ws16c48gpio->out_state[port] |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ws16c48gpio->out_state[port] &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) const unsigned port = offset / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) const unsigned mask = BIT(offset % 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) unsigned port_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* ensure that GPIO is set for input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (!(ws16c48gpio->io_state[port] & mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) port_state = inb(ws16c48gpio->base + port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return !!(port_state & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static int ws16c48_gpio_get_multiple(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) unsigned long *mask, unsigned long *bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) unsigned long gpio_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) unsigned int port_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) unsigned long port_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* clear bits array to a clean slate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) bitmap_zero(bits, chip->ngpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) for_each_set_clump8(offset, gpio_mask, mask, chip->ngpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) port_addr = ws16c48gpio->base + offset / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) port_state = inb(port_addr) & gpio_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) bitmap_set_value8(bits, port_state, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) const unsigned port = offset / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) const unsigned mask = BIT(offset % 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* ensure that GPIO is set for output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (ws16c48gpio->io_state[port] & mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ws16c48gpio->out_state[port] |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ws16c48gpio->out_state[port] &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static void ws16c48_gpio_set_multiple(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) unsigned long *mask, unsigned long *bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) unsigned long gpio_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) size_t index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) unsigned int port_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) unsigned long bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) for_each_set_clump8(offset, gpio_mask, mask, chip->ngpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) index = offset / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) port_addr = ws16c48gpio->base + index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* mask out GPIO configured for input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) gpio_mask &= ~ws16c48gpio->io_state[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* update output state data and set device gpio register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) ws16c48gpio->out_state[index] &= ~gpio_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ws16c48gpio->out_state[index] |= bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) outb(ws16c48gpio->out_state[index], port_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static void ws16c48_irq_ack(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) const unsigned long offset = irqd_to_hwirq(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) const unsigned port = offset / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) const unsigned mask = BIT(offset % 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) unsigned port_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* only the first 3 ports support interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (port > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) port_state = ws16c48gpio->irq_mask >> (8*port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) outb(0x80, ws16c48gpio->base + 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) outb(port_state & ~mask, ws16c48gpio->base + 8 + port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) outb(port_state | mask, ws16c48gpio->base + 8 + port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) outb(0xC0, ws16c48gpio->base + 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static void ws16c48_irq_mask(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) const unsigned long offset = irqd_to_hwirq(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) const unsigned long mask = BIT(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) const unsigned port = offset / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* only the first 3 ports support interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (port > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ws16c48gpio->irq_mask &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) outb(0x80, ws16c48gpio->base + 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) outb(0xC0, ws16c48gpio->base + 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static void ws16c48_irq_unmask(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) const unsigned long offset = irqd_to_hwirq(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) const unsigned long mask = BIT(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) const unsigned port = offset / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* only the first 3 ports support interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (port > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ws16c48gpio->irq_mask |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) outb(0x80, ws16c48gpio->base + 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) outb(ws16c48gpio->irq_mask >> (8*port), ws16c48gpio->base + 8 + port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) outb(0xC0, ws16c48gpio->base + 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) const unsigned long offset = irqd_to_hwirq(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) const unsigned long mask = BIT(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) const unsigned port = offset / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* only the first 3 ports support interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (port > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) raw_spin_lock_irqsave(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) switch (flow_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) case IRQ_TYPE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) case IRQ_TYPE_EDGE_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ws16c48gpio->flow_mask |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) case IRQ_TYPE_EDGE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) ws16c48gpio->flow_mask &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) outb(0x40, ws16c48gpio->base + 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) outb(ws16c48gpio->flow_mask >> (8*port), ws16c48gpio->base + 8 + port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) outb(0xC0, ws16c48gpio->base + 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) raw_spin_unlock_irqrestore(&ws16c48gpio->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static struct irq_chip ws16c48_irqchip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) .name = "ws16c48",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) .irq_ack = ws16c48_irq_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) .irq_mask = ws16c48_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) .irq_unmask = ws16c48_irq_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) .irq_set_type = ws16c48_irq_set_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static irqreturn_t ws16c48_irq_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct ws16c48_gpio *const ws16c48gpio = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct gpio_chip *const chip = &ws16c48gpio->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) unsigned long int_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) unsigned long port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) unsigned long int_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) unsigned long gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) int_pending = inb(ws16c48gpio->base + 6) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (!int_pending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* loop until all pending interrupts are handled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) for_each_set_bit(port, &int_pending, 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) int_id = inb(ws16c48gpio->base + 8 + port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) for_each_set_bit(gpio, &int_id, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) generic_handle_irq(irq_find_mapping(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) chip->irq.domain, gpio + 8*port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int_pending = inb(ws16c48gpio->base + 6) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) } while (int_pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) #define WS16C48_NGPIO 48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static const char *ws16c48_names[WS16C48_NGPIO] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) "Port 0 Bit 0", "Port 0 Bit 1", "Port 0 Bit 2", "Port 0 Bit 3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) "Port 0 Bit 4", "Port 0 Bit 5", "Port 0 Bit 6", "Port 0 Bit 7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) "Port 1 Bit 0", "Port 1 Bit 1", "Port 1 Bit 2", "Port 1 Bit 3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) "Port 1 Bit 4", "Port 1 Bit 5", "Port 1 Bit 6", "Port 1 Bit 7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) "Port 2 Bit 0", "Port 2 Bit 1", "Port 2 Bit 2", "Port 2 Bit 3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) "Port 2 Bit 4", "Port 2 Bit 5", "Port 2 Bit 6", "Port 2 Bit 7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) "Port 3 Bit 0", "Port 3 Bit 1", "Port 3 Bit 2", "Port 3 Bit 3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) "Port 3 Bit 4", "Port 3 Bit 5", "Port 3 Bit 6", "Port 3 Bit 7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) "Port 4 Bit 0", "Port 4 Bit 1", "Port 4 Bit 2", "Port 4 Bit 3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) "Port 4 Bit 4", "Port 4 Bit 5", "Port 4 Bit 6", "Port 4 Bit 7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) "Port 5 Bit 0", "Port 5 Bit 1", "Port 5 Bit 2", "Port 5 Bit 3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) "Port 5 Bit 4", "Port 5 Bit 5", "Port 5 Bit 6", "Port 5 Bit 7"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static int ws16c48_irq_init_hw(struct gpio_chip *gc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* Disable IRQ by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) outb(0x80, ws16c48gpio->base + 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) outb(0, ws16c48gpio->base + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) outb(0, ws16c48gpio->base + 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) outb(0, ws16c48gpio->base + 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) outb(0xC0, ws16c48gpio->base + 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static int ws16c48_probe(struct device *dev, unsigned int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct ws16c48_gpio *ws16c48gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) const char *const name = dev_name(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct gpio_irq_chip *girq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) ws16c48gpio = devm_kzalloc(dev, sizeof(*ws16c48gpio), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (!ws16c48gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (!devm_request_region(dev, base[id], WS16C48_EXTENT, name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) base[id], base[id] + WS16C48_EXTENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ws16c48gpio->chip.label = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ws16c48gpio->chip.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) ws16c48gpio->chip.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ws16c48gpio->chip.base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) ws16c48gpio->chip.ngpio = WS16C48_NGPIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) ws16c48gpio->chip.names = ws16c48_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) ws16c48gpio->chip.get_direction = ws16c48_gpio_get_direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ws16c48gpio->chip.direction_input = ws16c48_gpio_direction_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) ws16c48gpio->chip.direction_output = ws16c48_gpio_direction_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) ws16c48gpio->chip.get = ws16c48_gpio_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ws16c48gpio->chip.get_multiple = ws16c48_gpio_get_multiple;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ws16c48gpio->chip.set = ws16c48_gpio_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) ws16c48gpio->chip.set_multiple = ws16c48_gpio_set_multiple;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) ws16c48gpio->base = base[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) girq = &ws16c48gpio->chip.irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) girq->chip = &ws16c48_irqchip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* This will let us handle the parent IRQ in the driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) girq->parent_handler = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) girq->num_parents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) girq->parents = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) girq->default_type = IRQ_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) girq->handler = handle_edge_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) girq->init_hw = ws16c48_irq_init_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) raw_spin_lock_init(&ws16c48gpio->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) err = devm_gpiochip_add_data(dev, &ws16c48gpio->chip, ws16c48gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) dev_err(dev, "GPIO registering failed (%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) err = devm_request_irq(dev, irq[id], ws16c48_irq_handler, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) name, ws16c48gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) dev_err(dev, "IRQ handler registering failed (%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static struct isa_driver ws16c48_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .probe = ws16c48_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) .name = "ws16c48"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) module_isa_driver(ws16c48_driver, num_ws16c48);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) MODULE_DESCRIPTION("WinSystems WS16C48 GPIO driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) MODULE_LICENSE("GPL v2");