diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-08 11:35:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-08 11:35:12 -0400 |
commit | 89240c675ed12fe540093fc70c13ae8ff227e8e5 (patch) | |
tree | f2f650b0d8ead9c6da7735d68ba6fc94c529d88c | |
parent | f142f08bf7ecc41c3e71e05b765ea654047cf0c0 (diff) | |
parent | e026646c178d8292de563fbecc247bada059c282 (diff) |
Merge tag 'gpio-v4.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio
Pull GPIO fixes from Linus Walleij:
"Sorry for lagging behind on sending the first batch of GPIO fixes for
this cycle. Just too busy conferencing and the weather was too nice.
Here it is anyway: some real important polishing on the error path
facing userspace (tagged for stable as well) and some normal driver
fixes.
- Fix proper IRQ unmasking in the Aspeed driver.
- Do not free unrequested descriptors on the errorpath when creating
line handles from the userspace chardev requested GPIO lines.
- Also fix the errorpath in the linehandle creation function.
- Fix the get/set multiple GPIO lines for a few of the funky
industrial GPIO cards on the ISA bus"
* tag 'gpio-v4.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio:
gpio: pcie-idio-24: Fix off-by-one error in get_multiple loop
gpio: pcie-idio-24: Fix port memory offset for get_multiple/set_multiple callbacks
gpio: pci-idio-16: Fix port memory offset for get_multiple callback
gpio: fix error path in lineevent_create
gpioib: do not free unrequested descriptors
gpio: fix aspeed_gpio unmask irq
-rw-r--r-- | drivers/gpio/gpio-aspeed.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-pci-idio-16.c | 8 | ||||
-rw-r--r-- | drivers/gpio/gpio-pcie-idio-24.c | 22 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 7 |
4 files changed, 20 insertions, 19 deletions
diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c index 77e485557498..6f693b7d5220 100644 --- a/drivers/gpio/gpio-aspeed.c +++ b/drivers/gpio/gpio-aspeed.c | |||
@@ -384,7 +384,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set) | |||
384 | if (set) | 384 | if (set) |
385 | reg |= bit; | 385 | reg |= bit; |
386 | else | 386 | else |
387 | reg &= bit; | 387 | reg &= ~bit; |
388 | iowrite32(reg, addr); | 388 | iowrite32(reg, addr); |
389 | 389 | ||
390 | spin_unlock_irqrestore(&gpio->lock, flags); | 390 | spin_unlock_irqrestore(&gpio->lock, flags); |
diff --git a/drivers/gpio/gpio-pci-idio-16.c b/drivers/gpio/gpio-pci-idio-16.c index 1948724d8c36..25d16b2af1c3 100644 --- a/drivers/gpio/gpio-pci-idio-16.c +++ b/drivers/gpio/gpio-pci-idio-16.c | |||
@@ -116,9 +116,9 @@ static int idio_16_gpio_get_multiple(struct gpio_chip *chip, | |||
116 | unsigned long word_mask; | 116 | unsigned long word_mask; |
117 | const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0); | 117 | const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0); |
118 | unsigned long port_state; | 118 | unsigned long port_state; |
119 | u8 __iomem ports[] = { | 119 | void __iomem *ports[] = { |
120 | idio16gpio->reg->out0_7, idio16gpio->reg->out8_15, | 120 | &idio16gpio->reg->out0_7, &idio16gpio->reg->out8_15, |
121 | idio16gpio->reg->in0_7, idio16gpio->reg->in8_15, | 121 | &idio16gpio->reg->in0_7, &idio16gpio->reg->in8_15, |
122 | }; | 122 | }; |
123 | 123 | ||
124 | /* clear bits array to a clean slate */ | 124 | /* clear bits array to a clean slate */ |
@@ -143,7 +143,7 @@ static int idio_16_gpio_get_multiple(struct gpio_chip *chip, | |||
143 | } | 143 | } |
144 | 144 | ||
145 | /* read bits from current gpio port */ | 145 | /* read bits from current gpio port */ |
146 | port_state = ioread8(ports + i); | 146 | port_state = ioread8(ports[i]); |
147 | 147 | ||
148 | /* store acquired bits at respective bits array offset */ | 148 | /* store acquired bits at respective bits array offset */ |
149 | bits[word_index] |= port_state << word_offset; | 149 | bits[word_index] |= port_state << word_offset; |
diff --git a/drivers/gpio/gpio-pcie-idio-24.c b/drivers/gpio/gpio-pcie-idio-24.c index 835607ecf658..f953541e7890 100644 --- a/drivers/gpio/gpio-pcie-idio-24.c +++ b/drivers/gpio/gpio-pcie-idio-24.c | |||
@@ -206,10 +206,10 @@ static int idio_24_gpio_get_multiple(struct gpio_chip *chip, | |||
206 | unsigned long word_mask; | 206 | unsigned long word_mask; |
207 | const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0); | 207 | const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0); |
208 | unsigned long port_state; | 208 | unsigned long port_state; |
209 | u8 __iomem ports[] = { | 209 | void __iomem *ports[] = { |
210 | idio24gpio->reg->out0_7, idio24gpio->reg->out8_15, | 210 | &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15, |
211 | idio24gpio->reg->out16_23, idio24gpio->reg->in0_7, | 211 | &idio24gpio->reg->out16_23, &idio24gpio->reg->in0_7, |
212 | idio24gpio->reg->in8_15, idio24gpio->reg->in16_23, | 212 | &idio24gpio->reg->in8_15, &idio24gpio->reg->in16_23, |
213 | }; | 213 | }; |
214 | const unsigned long out_mode_mask = BIT(1); | 214 | const unsigned long out_mode_mask = BIT(1); |
215 | 215 | ||
@@ -217,7 +217,7 @@ static int idio_24_gpio_get_multiple(struct gpio_chip *chip, | |||
217 | bitmap_zero(bits, chip->ngpio); | 217 | bitmap_zero(bits, chip->ngpio); |
218 | 218 | ||
219 | /* get bits are evaluated a gpio port register at a time */ | 219 | /* get bits are evaluated a gpio port register at a time */ |
220 | for (i = 0; i < ARRAY_SIZE(ports); i++) { | 220 | for (i = 0; i < ARRAY_SIZE(ports) + 1; i++) { |
221 | /* gpio offset in bits array */ | 221 | /* gpio offset in bits array */ |
222 | bits_offset = i * gpio_reg_size; | 222 | bits_offset = i * gpio_reg_size; |
223 | 223 | ||
@@ -236,7 +236,7 @@ static int idio_24_gpio_get_multiple(struct gpio_chip *chip, | |||
236 | 236 | ||
237 | /* read bits from current gpio port (port 6 is TTL GPIO) */ | 237 | /* read bits from current gpio port (port 6 is TTL GPIO) */ |
238 | if (i < 6) | 238 | if (i < 6) |
239 | port_state = ioread8(ports + i); | 239 | port_state = ioread8(ports[i]); |
240 | else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) | 240 | else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) |
241 | port_state = ioread8(&idio24gpio->reg->ttl_out0_7); | 241 | port_state = ioread8(&idio24gpio->reg->ttl_out0_7); |
242 | else | 242 | else |
@@ -301,9 +301,9 @@ static void idio_24_gpio_set_multiple(struct gpio_chip *chip, | |||
301 | const unsigned long port_mask = GENMASK(gpio_reg_size, 0); | 301 | const unsigned long port_mask = GENMASK(gpio_reg_size, 0); |
302 | unsigned long flags; | 302 | unsigned long flags; |
303 | unsigned int out_state; | 303 | unsigned int out_state; |
304 | u8 __iomem ports[] = { | 304 | void __iomem *ports[] = { |
305 | idio24gpio->reg->out0_7, idio24gpio->reg->out8_15, | 305 | &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15, |
306 | idio24gpio->reg->out16_23 | 306 | &idio24gpio->reg->out16_23 |
307 | }; | 307 | }; |
308 | const unsigned long out_mode_mask = BIT(1); | 308 | const unsigned long out_mode_mask = BIT(1); |
309 | const unsigned int ttl_offset = 48; | 309 | const unsigned int ttl_offset = 48; |
@@ -327,9 +327,9 @@ static void idio_24_gpio_set_multiple(struct gpio_chip *chip, | |||
327 | raw_spin_lock_irqsave(&idio24gpio->lock, flags); | 327 | raw_spin_lock_irqsave(&idio24gpio->lock, flags); |
328 | 328 | ||
329 | /* process output lines */ | 329 | /* process output lines */ |
330 | out_state = ioread8(ports + i) & ~gpio_mask; | 330 | out_state = ioread8(ports[i]) & ~gpio_mask; |
331 | out_state |= (*bits >> bits_offset) & gpio_mask; | 331 | out_state |= (*bits >> bits_offset) & gpio_mask; |
332 | iowrite8(out_state, ports + i); | 332 | iowrite8(out_state, ports[i]); |
333 | 333 | ||
334 | raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); | 334 | raw_spin_unlock_irqrestore(&idio24gpio->lock, flags); |
335 | } | 335 | } |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 43aeb07343ec..d8ccb500872f 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -497,7 +497,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) | |||
497 | struct gpiohandle_request handlereq; | 497 | struct gpiohandle_request handlereq; |
498 | struct linehandle_state *lh; | 498 | struct linehandle_state *lh; |
499 | struct file *file; | 499 | struct file *file; |
500 | int fd, i, ret; | 500 | int fd, i, count = 0, ret; |
501 | u32 lflags; | 501 | u32 lflags; |
502 | 502 | ||
503 | if (copy_from_user(&handlereq, ip, sizeof(handlereq))) | 503 | if (copy_from_user(&handlereq, ip, sizeof(handlereq))) |
@@ -558,6 +558,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) | |||
558 | if (ret) | 558 | if (ret) |
559 | goto out_free_descs; | 559 | goto out_free_descs; |
560 | lh->descs[i] = desc; | 560 | lh->descs[i] = desc; |
561 | count = i; | ||
561 | 562 | ||
562 | if (lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW) | 563 | if (lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW) |
563 | set_bit(FLAG_ACTIVE_LOW, &desc->flags); | 564 | set_bit(FLAG_ACTIVE_LOW, &desc->flags); |
@@ -628,7 +629,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) | |||
628 | out_put_unused_fd: | 629 | out_put_unused_fd: |
629 | put_unused_fd(fd); | 630 | put_unused_fd(fd); |
630 | out_free_descs: | 631 | out_free_descs: |
631 | for (; i >= 0; i--) | 632 | for (i = 0; i < count; i++) |
632 | gpiod_free(lh->descs[i]); | 633 | gpiod_free(lh->descs[i]); |
633 | kfree(lh->label); | 634 | kfree(lh->label); |
634 | out_free_lh: | 635 | out_free_lh: |
@@ -902,7 +903,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) | |||
902 | desc = &gdev->descs[offset]; | 903 | desc = &gdev->descs[offset]; |
903 | ret = gpiod_request(desc, le->label); | 904 | ret = gpiod_request(desc, le->label); |
904 | if (ret) | 905 | if (ret) |
905 | goto out_free_desc; | 906 | goto out_free_label; |
906 | le->desc = desc; | 907 | le->desc = desc; |
907 | le->eflags = eflags; | 908 | le->eflags = eflags; |
908 | 909 | ||