Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'gpio-updates-for-v6.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio updates from Bartosz Golaszewski:
"Thanks to little activity in December, this is really tiny. Just a few
updates to drivers and device-tree bindings.

Driver improvements:
- support a new model in gpio-mpc8xxx
- refactor gpio-tqmx86 and add support for direction setting
- allow building gpio-omap with COMPILE_TEST=y
- use gpiochip_get_data() instead of dev_get_drvdata() in
gpio-twl6040
- drop unued field from driver data in gpio-altera
- use generic request/free callbacks in gpio-regmap for better
integration with pinctrl
- use dev_err_probe() where applicable in gpio-pca953x
- use existing dedicated GPIO defines in gpio-tps65219 instead of
custom ones

DT bindings:
- document a new model in fsl,qoriq-gpio
- explain the chip's latch clock pin and how it works like
chip-select in fairchild,74hc595
- enable the gpio-line-names property for gpio-brcmstb"

* tag 'gpio-updates-for-v6.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
gpio: regmap: Use generic request/free ops
gpio: altera: Drop .mapped_irq from driver data
gpio: mpc8xxx: Add MPC8314 support
dt-bindings: gpio: fsl,qoriq-gpio: Add compatible string fsl,mpc8314-gpio
dt-bindings: gpio: fairchild,74hc595: Document chip select vs. latch clock
gpio: tps65219: Use existing kernel gpio macros
gpio: pca953x: log an error when failing to get the reset GPIO
dt-bindings: gpio: brcmstb: permit gpio-line-names property
gpio: tqmx86: add support for changing GPIO directions
gpio: tqmx86: introduce tqmx86_gpio_clrsetbits() helper
gpio: tqmx86: use cleanup guards for spinlock
gpio: tqmx86: consistently refer to IRQs by hwirq numbers
gpio: tqmx86: add macros for interrupt configuration
gpio: omap: allow building the module with COMPILE_TEST=y
gpio: twl4030: use gpiochip_get_data

+160 -105
+4
Documentation/devicetree/bindings/gpio/brcm,brcmstb-gpio.yaml
··· 64 64 65 65 gpio-ranges: true 66 66 67 + gpio-line-names: 68 + minItems: 1 69 + maxItems: 128 70 + 67 71 wakeup-source: 68 72 type: boolean 69 73 description: >
+17
Documentation/devicetree/bindings/gpio/fairchild,74hc595.yaml
··· 6 6 7 7 title: Generic 8-bit shift register 8 8 9 + description: | 10 + NOTE: These chips nominally don't have a chip select pin. They do however 11 + have a rising-edge triggered latch clock (or storage register clock) pin, 12 + which behaves like an active-low chip select. 13 + 14 + After the bits are shifted into the shift register, CS# is driven high, which 15 + the 74HC595 sees as a rising edge on the latch clock that results in a 16 + transfer of the bits from the shift register to the storage register and thus 17 + to the output pins. 18 + _ _ _ _ 19 + shift clock ____| |_| |_..._| |_| |_________ 20 + 21 + latch clock * trigger 22 + ___ ________ 23 + chip select# |___________________| 24 + 25 + 9 26 maintainers: 10 27 - Maxime Ripard <mripard@kernel.org> 11 28
+1
Documentation/devicetree/bindings/gpio/fsl,qoriq-gpio.yaml
··· 15 15 - enum: 16 16 - fsl,mpc5121-gpio 17 17 - fsl,mpc5125-gpio 18 + - fsl,mpc8314-gpio 18 19 - fsl,mpc8349-gpio 19 20 - fsl,mpc8572-gpio 20 21 - fsl,mpc8610-gpio
+2 -2
drivers/gpio/Kconfig
··· 529 529 family of SOCs. 530 530 531 531 config GPIO_OMAP 532 - tristate "TI OMAP GPIO support" if ARCH_OMAP2PLUS || COMPILE_TEST 532 + tristate "TI OMAP GPIO support" 533 + depends on ARCH_OMAP || COMPILE_TEST 533 534 default y if ARCH_OMAP 534 - depends on ARM 535 535 select GENERIC_IRQ_CHIP 536 536 select GPIOLIB_IRQCHIP 537 537 help
+4 -5
drivers/gpio/gpio-altera.c
··· 32 32 * will be blocked until the current one completes. 33 33 * @interrupt_trigger : specifies the hardware configured IRQ trigger type 34 34 * (rising, falling, both, high) 35 - * @mapped_irq : kernel mapped irq number. 36 35 */ 37 36 struct altera_gpio_chip { 38 37 struct gpio_chip gc; 39 38 void __iomem *regs; 40 39 raw_spinlock_t gpio_lock; 41 40 int interrupt_trigger; 42 - int mapped_irq; 43 41 }; 44 42 45 43 static void altera_gpio_irq_unmask(struct irq_data *d) ··· 233 235 int reg, ret; 234 236 struct altera_gpio_chip *altera_gc; 235 237 struct gpio_irq_chip *girq; 238 + int mapped_irq; 236 239 237 240 altera_gc = devm_kzalloc(&pdev->dev, sizeof(*altera_gc), GFP_KERNEL); 238 241 if (!altera_gc) ··· 270 271 if (IS_ERR(altera_gc->regs)) 271 272 return dev_err_probe(dev, PTR_ERR(altera_gc->regs), "failed to ioremap memory resource\n"); 272 273 273 - altera_gc->mapped_irq = platform_get_irq_optional(pdev, 0); 274 - if (altera_gc->mapped_irq < 0) 274 + mapped_irq = platform_get_irq_optional(pdev, 0); 275 + if (mapped_irq < 0) 275 276 goto skip_irq; 276 277 277 278 if (device_property_read_u32(dev, "altr,interrupt-type", &reg)) { ··· 295 296 return -ENOMEM; 296 297 girq->default_type = IRQ_TYPE_NONE; 297 298 girq->handler = handle_bad_irq; 298 - girq->parents[0] = altera_gc->mapped_irq; 299 + girq->parents[0] = mapped_irq; 299 300 300 301 skip_irq: 301 302 ret = devm_gpiochip_add_data(dev, &altera_gc->gc, altera_gc);
+1
drivers/gpio/gpio-mpc8xxx.c
··· 285 285 }; 286 286 287 287 static const struct of_device_id mpc8xxx_gpio_ids[] = { 288 + { .compatible = "fsl,mpc8314-gpio", }, 288 289 { .compatible = "fsl,mpc8349-gpio", }, 289 290 { .compatible = "fsl,mpc8572-gpio", .data = &mpc8572_gpio_devtype, }, 290 291 { .compatible = "fsl,mpc8610-gpio", },
+2 -1
drivers/gpio/gpio-pca953x.c
··· 1088 1088 */ 1089 1089 reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); 1090 1090 if (IS_ERR(reset_gpio)) 1091 - return PTR_ERR(reset_gpio); 1091 + return dev_err_probe(dev, PTR_ERR(reset_gpio), 1092 + "Failed to get reset gpio\n"); 1092 1093 } 1093 1094 1094 1095 chip->client = client;
+2
drivers/gpio/gpio-regmap.c
··· 262 262 chip->label = config->label ?: dev_name(config->parent); 263 263 chip->can_sleep = regmap_might_sleep(config->regmap); 264 264 265 + chip->request = gpiochip_generic_request; 266 + chip->free = gpiochip_generic_free; 265 267 chip->get = gpio_regmap_get; 266 268 if (gpio->reg_set_base && gpio->reg_clr_base) 267 269 chip->set = gpio_regmap_set_with_clear;
+5 -7
drivers/gpio/gpio-tps65219.c
··· 15 15 #define TPS65219_GPIO0_DIR_MASK BIT(3) 16 16 #define TPS65219_GPIO0_OFFSET 2 17 17 #define TPS65219_GPIO0_IDX 0 18 - #define TPS65219_GPIO_DIR_IN 1 19 - #define TPS65219_GPIO_DIR_OUT 0 20 18 21 19 struct tps65219_gpio { 22 20 struct gpio_chip gpio_chip; ··· 59 61 * status bit. 60 62 */ 61 63 62 - if (tps65219_gpio_get_direction(gc, offset) == TPS65219_GPIO_DIR_OUT) 64 + if (tps65219_gpio_get_direction(gc, offset) == GPIO_LINE_DIRECTION_OUT) 63 65 return -ENOTSUPP; 64 66 65 67 return ret; ··· 122 124 return -ENOTSUPP; 123 125 } 124 126 125 - if (tps65219_gpio_get_direction(gc, offset) == TPS65219_GPIO_DIR_IN) 127 + if (tps65219_gpio_get_direction(gc, offset) == GPIO_LINE_DIRECTION_IN) 126 128 return 0; 127 129 128 - return tps65219_gpio_change_direction(gc, offset, TPS65219_GPIO_DIR_IN); 130 + return tps65219_gpio_change_direction(gc, offset, GPIO_LINE_DIRECTION_IN); 129 131 } 130 132 131 133 static int tps65219_gpio_direction_output(struct gpio_chip *gc, unsigned int offset, int value) ··· 134 136 if (offset != TPS65219_GPIO0_IDX) 135 137 return 0; 136 138 137 - if (tps65219_gpio_get_direction(gc, offset) == TPS65219_GPIO_DIR_OUT) 139 + if (tps65219_gpio_get_direction(gc, offset) == GPIO_LINE_DIRECTION_OUT) 138 140 return 0; 139 141 140 - return tps65219_gpio_change_direction(gc, offset, TPS65219_GPIO_DIR_OUT); 142 + return tps65219_gpio_change_direction(gc, offset, GPIO_LINE_DIRECTION_OUT); 141 143 } 142 144 143 145 static const struct gpio_chip tps65219_template_chip = {
+119 -87
drivers/gpio/gpio-tqmx86.c
··· 29 29 #define TQMX86_GPIIC 3 /* GPI Interrupt Configuration Register */ 30 30 #define TQMX86_GPIIS 4 /* GPI Interrupt Status Register */ 31 31 32 - #define TQMX86_GPII_NONE 0 33 - #define TQMX86_GPII_FALLING BIT(0) 34 - #define TQMX86_GPII_RISING BIT(1) 35 - /* Stored in irq_type as a trigger type, but not actually valid as a register 36 - * value, so the name doesn't use "GPII" 32 + /* 33 + * NONE, FALLING and RISING use the same bit patterns that can be programmed to 34 + * the GPII register (after passing them to the TQMX86_GPII_ macros to shift 35 + * them to the right position) 37 36 */ 38 - #define TQMX86_INT_BOTH (BIT(0) | BIT(1)) 39 - #define TQMX86_GPII_MASK (BIT(0) | BIT(1)) 40 - #define TQMX86_GPII_BITS 2 37 + #define TQMX86_INT_TRIG_NONE 0 38 + #define TQMX86_INT_TRIG_FALLING BIT(0) 39 + #define TQMX86_INT_TRIG_RISING BIT(1) 40 + #define TQMX86_INT_TRIG_BOTH (BIT(0) | BIT(1)) 41 + #define TQMX86_INT_TRIG_MASK (BIT(0) | BIT(1)) 41 42 /* Stored in irq_type with GPII bits */ 42 43 #define TQMX86_INT_UNMASKED BIT(2) 44 + 45 + #define TQMX86_GPIIC_CONFIG(i, v) ((v) << (2 * (i))) 46 + #define TQMX86_GPIIC_MASK(i) TQMX86_GPIIC_CONFIG(i, TQMX86_INT_TRIG_MASK) 43 47 44 48 struct tqmx86_gpio_data { 45 49 struct gpio_chip chip; ··· 52 48 /* Lock must be held for accessing output and irq_type fields */ 53 49 raw_spinlock_t spinlock; 54 50 DECLARE_BITMAP(output, TQMX86_NGPIO); 55 - u8 irq_type[TQMX86_NGPI]; 51 + u8 irq_type[TQMX86_NGPIO]; 56 52 }; 57 53 58 54 static u8 tqmx86_gpio_read(struct tqmx86_gpio_data *gd, unsigned int reg) ··· 66 62 iowrite8(val, gd->io_base + reg); 67 63 } 68 64 65 + static void tqmx86_gpio_clrsetbits(struct tqmx86_gpio_data *gpio, 66 + u8 clr, u8 set, unsigned int reg) 67 + __must_hold(&gpio->spinlock) 68 + { 69 + u8 val = tqmx86_gpio_read(gpio, reg); 70 + 71 + val &= ~clr; 72 + val |= set; 73 + 74 + tqmx86_gpio_write(gpio, val, reg); 75 + } 76 + 69 77 static int tqmx86_gpio_get(struct gpio_chip *chip, unsigned int offset) 70 78 { 71 79 struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); ··· 85 69 return !!(tqmx86_gpio_read(gpio, TQMX86_GPIOD) & BIT(offset)); 86 70 } 87 71 72 + static void _tqmx86_gpio_set(struct tqmx86_gpio_data *gpio, unsigned int offset, 73 + int value) 74 + __must_hold(&gpio->spinlock) 75 + { 76 + __assign_bit(offset, gpio->output, value); 77 + tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD); 78 + } 79 + 88 80 static void tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset, 89 81 int value) 90 82 { 91 83 struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); 92 - unsigned long flags; 93 84 94 - raw_spin_lock_irqsave(&gpio->spinlock, flags); 95 - __assign_bit(offset, gpio->output, value); 96 - tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD); 97 - raw_spin_unlock_irqrestore(&gpio->spinlock, flags); 85 + guard(raw_spinlock_irqsave)(&gpio->spinlock); 86 + 87 + _tqmx86_gpio_set(gpio, offset, value); 98 88 } 99 89 100 90 static int tqmx86_gpio_direction_input(struct gpio_chip *chip, 101 91 unsigned int offset) 102 92 { 103 - /* Direction cannot be changed. Validate is an input. */ 104 - if (BIT(offset) & TQMX86_DIR_INPUT_MASK) 105 - return 0; 106 - else 107 - return -EINVAL; 93 + struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); 94 + 95 + guard(raw_spinlock_irqsave)(&gpio->spinlock); 96 + 97 + tqmx86_gpio_clrsetbits(gpio, BIT(offset), 0, TQMX86_GPIODD); 98 + 99 + return 0; 108 100 } 109 101 110 102 static int tqmx86_gpio_direction_output(struct gpio_chip *chip, 111 103 unsigned int offset, 112 104 int value) 113 105 { 114 - /* Direction cannot be changed, validate is an output */ 115 - if (BIT(offset) & TQMX86_DIR_INPUT_MASK) 116 - return -EINVAL; 106 + struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); 117 107 118 - tqmx86_gpio_set(chip, offset, value); 108 + guard(raw_spinlock_irqsave)(&gpio->spinlock); 109 + 110 + _tqmx86_gpio_set(gpio, offset, value); 111 + tqmx86_gpio_clrsetbits(gpio, 0, BIT(offset), TQMX86_GPIODD); 112 + 119 113 return 0; 120 114 } 121 115 122 116 static int tqmx86_gpio_get_direction(struct gpio_chip *chip, 123 117 unsigned int offset) 124 118 { 125 - if (TQMX86_DIR_INPUT_MASK & BIT(offset)) 126 - return GPIO_LINE_DIRECTION_IN; 119 + struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); 120 + u8 val; 127 121 128 - return GPIO_LINE_DIRECTION_OUT; 122 + val = tqmx86_gpio_read(gpio, TQMX86_GPIODD); 123 + 124 + if (val & BIT(offset)) 125 + return GPIO_LINE_DIRECTION_OUT; 126 + 127 + return GPIO_LINE_DIRECTION_IN; 129 128 } 130 129 131 - static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int offset) 130 + static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int hwirq) 132 131 __must_hold(&gpio->spinlock) 133 132 { 134 - u8 type = TQMX86_GPII_NONE, gpiic; 133 + u8 type = TQMX86_INT_TRIG_NONE; 134 + int gpiic_irq = hwirq - TQMX86_NGPO; 135 135 136 - if (gpio->irq_type[offset] & TQMX86_INT_UNMASKED) { 137 - type = gpio->irq_type[offset] & TQMX86_GPII_MASK; 136 + if (gpio->irq_type[hwirq] & TQMX86_INT_UNMASKED) { 137 + type = gpio->irq_type[hwirq] & TQMX86_INT_TRIG_MASK; 138 138 139 - if (type == TQMX86_INT_BOTH) 140 - type = tqmx86_gpio_get(&gpio->chip, offset + TQMX86_NGPO) 141 - ? TQMX86_GPII_FALLING 142 - : TQMX86_GPII_RISING; 139 + if (type == TQMX86_INT_TRIG_BOTH) 140 + type = tqmx86_gpio_get(&gpio->chip, hwirq) 141 + ? TQMX86_INT_TRIG_FALLING 142 + : TQMX86_INT_TRIG_RISING; 143 143 } 144 144 145 - gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC); 146 - gpiic &= ~(TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS)); 147 - gpiic |= type << (offset * TQMX86_GPII_BITS); 148 - tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC); 145 + tqmx86_gpio_clrsetbits(gpio, 146 + TQMX86_GPIIC_MASK(gpiic_irq), 147 + TQMX86_GPIIC_CONFIG(gpiic_irq, type), 148 + TQMX86_GPIIC); 149 149 } 150 150 151 151 static void tqmx86_gpio_irq_mask(struct irq_data *data) 152 152 { 153 - unsigned int offset = (data->hwirq - TQMX86_NGPO); 154 153 struct tqmx86_gpio_data *gpio = gpiochip_get_data( 155 154 irq_data_get_irq_chip_data(data)); 156 - unsigned long flags; 157 155 158 - raw_spin_lock_irqsave(&gpio->spinlock, flags); 159 - gpio->irq_type[offset] &= ~TQMX86_INT_UNMASKED; 160 - tqmx86_gpio_irq_config(gpio, offset); 161 - raw_spin_unlock_irqrestore(&gpio->spinlock, flags); 156 + scoped_guard(raw_spinlock_irqsave, &gpio->spinlock) { 157 + gpio->irq_type[data->hwirq] &= ~TQMX86_INT_UNMASKED; 158 + tqmx86_gpio_irq_config(gpio, data->hwirq); 159 + } 162 160 163 161 gpiochip_disable_irq(&gpio->chip, irqd_to_hwirq(data)); 164 162 } 165 163 166 164 static void tqmx86_gpio_irq_unmask(struct irq_data *data) 167 165 { 168 - unsigned int offset = (data->hwirq - TQMX86_NGPO); 169 166 struct tqmx86_gpio_data *gpio = gpiochip_get_data( 170 167 irq_data_get_irq_chip_data(data)); 171 - unsigned long flags; 172 168 173 169 gpiochip_enable_irq(&gpio->chip, irqd_to_hwirq(data)); 174 170 175 - raw_spin_lock_irqsave(&gpio->spinlock, flags); 176 - gpio->irq_type[offset] |= TQMX86_INT_UNMASKED; 177 - tqmx86_gpio_irq_config(gpio, offset); 178 - raw_spin_unlock_irqrestore(&gpio->spinlock, flags); 171 + guard(raw_spinlock_irqsave)(&gpio->spinlock); 172 + 173 + gpio->irq_type[data->hwirq] |= TQMX86_INT_UNMASKED; 174 + tqmx86_gpio_irq_config(gpio, data->hwirq); 179 175 } 180 176 181 177 static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type) 182 178 { 183 179 struct tqmx86_gpio_data *gpio = gpiochip_get_data( 184 180 irq_data_get_irq_chip_data(data)); 185 - unsigned int offset = (data->hwirq - TQMX86_NGPO); 186 181 unsigned int edge_type = type & IRQF_TRIGGER_MASK; 187 - unsigned long flags; 188 182 u8 new_type; 189 183 190 184 switch (edge_type) { 191 185 case IRQ_TYPE_EDGE_RISING: 192 - new_type = TQMX86_GPII_RISING; 186 + new_type = TQMX86_INT_TRIG_RISING; 193 187 break; 194 188 case IRQ_TYPE_EDGE_FALLING: 195 - new_type = TQMX86_GPII_FALLING; 189 + new_type = TQMX86_INT_TRIG_FALLING; 196 190 break; 197 191 case IRQ_TYPE_EDGE_BOTH: 198 - new_type = TQMX86_INT_BOTH; 192 + new_type = TQMX86_INT_TRIG_BOTH; 199 193 break; 200 194 default: 201 195 return -EINVAL; /* not supported */ 202 196 } 203 197 204 - raw_spin_lock_irqsave(&gpio->spinlock, flags); 205 - gpio->irq_type[offset] &= ~TQMX86_GPII_MASK; 206 - gpio->irq_type[offset] |= new_type; 207 - tqmx86_gpio_irq_config(gpio, offset); 208 - raw_spin_unlock_irqrestore(&gpio->spinlock, flags); 198 + guard(raw_spinlock_irqsave)(&gpio->spinlock); 199 + 200 + gpio->irq_type[data->hwirq] &= ~TQMX86_INT_TRIG_MASK; 201 + gpio->irq_type[data->hwirq] |= new_type; 202 + tqmx86_gpio_irq_config(gpio, data->hwirq); 209 203 210 204 return 0; 211 205 } ··· 225 199 struct gpio_chip *chip = irq_desc_get_handler_data(desc); 226 200 struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); 227 201 struct irq_chip *irq_chip = irq_desc_get_chip(desc); 228 - unsigned long irq_bits, flags; 229 - int i; 202 + unsigned long irq_bits; 203 + int i, hwirq; 230 204 u8 irq_status; 231 205 232 206 chained_irq_enter(irq_chip, desc); ··· 236 210 237 211 irq_bits = irq_status; 238 212 239 - raw_spin_lock_irqsave(&gpio->spinlock, flags); 240 - for_each_set_bit(i, &irq_bits, TQMX86_NGPI) { 241 - /* 242 - * Edge-both triggers are implemented by flipping the edge 243 - * trigger after each interrupt, as the controller only supports 244 - * either rising or falling edge triggers, but not both. 245 - * 246 - * Internally, the TQMx86 GPIO controller has separate status 247 - * registers for rising and falling edge interrupts. GPIIC 248 - * configures which bits from which register are visible in the 249 - * interrupt status register GPIIS and defines what triggers the 250 - * parent IRQ line. Writing to GPIIS always clears both rising 251 - * and falling interrupt flags internally, regardless of the 252 - * currently configured trigger. 253 - * 254 - * In consequence, we can cleanly implement the edge-both 255 - * trigger in software by first clearing the interrupt and then 256 - * setting the new trigger based on the current GPIO input in 257 - * tqmx86_gpio_irq_config() - even if an edge arrives between 258 - * reading the input and setting the trigger, we will have a new 259 - * interrupt pending. 260 - */ 261 - if ((gpio->irq_type[i] & TQMX86_GPII_MASK) == TQMX86_INT_BOTH) 262 - tqmx86_gpio_irq_config(gpio, i); 213 + scoped_guard(raw_spinlock_irqsave, &gpio->spinlock) { 214 + for_each_set_bit(i, &irq_bits, TQMX86_NGPI) { 215 + hwirq = i + TQMX86_NGPO; 216 + 217 + /* 218 + * Edge-both triggers are implemented by flipping the 219 + * edge trigger after each interrupt, as the controller 220 + * only supports either rising or falling edge triggers, 221 + * but not both. 222 + * 223 + * Internally, the TQMx86 GPIO controller has separate 224 + * status registers for rising and falling edge 225 + * interrupts. GPIIC configures which bits from which 226 + * register are visible in the interrupt status register 227 + * GPIIS and defines what triggers the parent IRQ line. 228 + * Writing to GPIIS always clears both rising and 229 + * falling interrupt flags internally, regardless of the 230 + * currently configured trigger. 231 + * 232 + * In consequence, we can cleanly implement the 233 + * edge-both trigger in software by first clearing the 234 + * interrupt and then setting the new trigger based on 235 + * the current GPIO input in tqmx86_gpio_irq_config() - 236 + * even if an edge arrives between reading the input and 237 + * setting the trigger, we will have a new interrupt 238 + * pending. 239 + */ 240 + if ((gpio->irq_type[hwirq] & TQMX86_INT_TRIG_MASK) == 241 + TQMX86_INT_TRIG_BOTH) 242 + tqmx86_gpio_irq_config(gpio, hwirq); 243 + } 263 244 } 264 - raw_spin_unlock_irqrestore(&gpio->spinlock, flags); 265 245 266 246 for_each_set_bit(i, &irq_bits, TQMX86_NGPI) 267 247 generic_handle_domain_irq(gpio->chip.irq.domain,
+3 -3
drivers/gpio/gpio-twl6040.c
··· 22 22 23 23 static int twl6040gpo_get(struct gpio_chip *chip, unsigned offset) 24 24 { 25 - struct twl6040 *twl6040 = dev_get_drvdata(chip->parent->parent); 25 + struct twl6040 *twl6040 = gpiochip_get_data(chip); 26 26 int ret = 0; 27 27 28 28 ret = twl6040_reg_read(twl6040, TWL6040_REG_GPOCTL); ··· 46 46 47 47 static void twl6040gpo_set(struct gpio_chip *chip, unsigned offset, int value) 48 48 { 49 - struct twl6040 *twl6040 = dev_get_drvdata(chip->parent->parent); 49 + struct twl6040 *twl6040 = gpiochip_get_data(chip); 50 50 int ret; 51 51 u8 gpoctl; 52 52 ··· 91 91 92 92 twl6040gpo_chip.parent = &pdev->dev; 93 93 94 - ret = devm_gpiochip_add_data(&pdev->dev, &twl6040gpo_chip, NULL); 94 + ret = devm_gpiochip_add_data(&pdev->dev, &twl6040gpo_chip, twl6040); 95 95 if (ret < 0) { 96 96 dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret); 97 97 twl6040gpo_chip.ngpio = 0;