aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-05-08 11:35:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-05-08 11:35:12 -0400
commit89240c675ed12fe540093fc70c13ae8ff227e8e5 (patch)
treef2f650b0d8ead9c6da7735d68ba6fc94c529d88c
parentf142f08bf7ecc41c3e71e05b765ea654047cf0c0 (diff)
parente026646c178d8292de563fbecc247bada059c282 (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.c2
-rw-r--r--drivers/gpio/gpio-pci-idio-16.c8
-rw-r--r--drivers/gpio/gpio-pcie-idio-24.c22
-rw-r--r--drivers/gpio/gpiolib.c7
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)
628out_put_unused_fd: 629out_put_unused_fd:
629 put_unused_fd(fd); 630 put_unused_fd(fd);
630out_free_descs: 631out_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);
634out_free_lh: 635out_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