Skip to content

Commit

Permalink
Merge tag 'gpio-v4.17-2' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
Linus Torvalds committed May 8, 2018
2 parents f142f08 + e026646 commit 89240c6
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 19 deletions.
2 changes: 1 addition & 1 deletion drivers/gpio/gpio-aspeed.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
if (set)
reg |= bit;
else
reg &= bit;
reg &= ~bit;
iowrite32(reg, addr);

spin_unlock_irqrestore(&gpio->lock, flags);
Expand Down
8 changes: 4 additions & 4 deletions drivers/gpio/gpio-pci-idio-16.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
unsigned long word_mask;
const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
unsigned long port_state;
u8 __iomem ports[] = {
idio16gpio->reg->out0_7, idio16gpio->reg->out8_15,
idio16gpio->reg->in0_7, idio16gpio->reg->in8_15,
void __iomem *ports[] = {
&idio16gpio->reg->out0_7, &idio16gpio->reg->out8_15,
&idio16gpio->reg->in0_7, &idio16gpio->reg->in8_15,
};

/* clear bits array to a clean slate */
Expand All @@ -143,7 +143,7 @@ static int idio_16_gpio_get_multiple(struct gpio_chip *chip,
}

/* read bits from current gpio port */
port_state = ioread8(ports + i);
port_state = ioread8(ports[i]);

/* store acquired bits at respective bits array offset */
bits[word_index] |= port_state << word_offset;
Expand Down
22 changes: 11 additions & 11 deletions drivers/gpio/gpio-pcie-idio-24.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,18 +206,18 @@ static int idio_24_gpio_get_multiple(struct gpio_chip *chip,
unsigned long word_mask;
const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
unsigned long port_state;
u8 __iomem ports[] = {
idio24gpio->reg->out0_7, idio24gpio->reg->out8_15,
idio24gpio->reg->out16_23, idio24gpio->reg->in0_7,
idio24gpio->reg->in8_15, idio24gpio->reg->in16_23,
void __iomem *ports[] = {
&idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
&idio24gpio->reg->out16_23, &idio24gpio->reg->in0_7,
&idio24gpio->reg->in8_15, &idio24gpio->reg->in16_23,
};
const unsigned long out_mode_mask = BIT(1);

/* clear bits array to a clean slate */
bitmap_zero(bits, chip->ngpio);

/* get bits are evaluated a gpio port register at a time */
for (i = 0; i < ARRAY_SIZE(ports); i++) {
for (i = 0; i < ARRAY_SIZE(ports) + 1; i++) {
/* gpio offset in bits array */
bits_offset = i * gpio_reg_size;

Expand All @@ -236,7 +236,7 @@ static int idio_24_gpio_get_multiple(struct gpio_chip *chip,

/* read bits from current gpio port (port 6 is TTL GPIO) */
if (i < 6)
port_state = ioread8(ports + i);
port_state = ioread8(ports[i]);
else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
port_state = ioread8(&idio24gpio->reg->ttl_out0_7);
else
Expand Down Expand Up @@ -301,9 +301,9 @@ static void idio_24_gpio_set_multiple(struct gpio_chip *chip,
const unsigned long port_mask = GENMASK(gpio_reg_size, 0);
unsigned long flags;
unsigned int out_state;
u8 __iomem ports[] = {
idio24gpio->reg->out0_7, idio24gpio->reg->out8_15,
idio24gpio->reg->out16_23
void __iomem *ports[] = {
&idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
&idio24gpio->reg->out16_23
};
const unsigned long out_mode_mask = BIT(1);
const unsigned int ttl_offset = 48;
Expand All @@ -327,9 +327,9 @@ static void idio_24_gpio_set_multiple(struct gpio_chip *chip,
raw_spin_lock_irqsave(&idio24gpio->lock, flags);

/* process output lines */
out_state = ioread8(ports + i) & ~gpio_mask;
out_state = ioread8(ports[i]) & ~gpio_mask;
out_state |= (*bits >> bits_offset) & gpio_mask;
iowrite8(out_state, ports + i);
iowrite8(out_state, ports[i]);

raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
}
Expand Down
7 changes: 4 additions & 3 deletions drivers/gpio/gpiolib.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
struct gpiohandle_request handlereq;
struct linehandle_state *lh;
struct file *file;
int fd, i, ret;
int fd, i, count = 0, ret;
u32 lflags;

if (copy_from_user(&handlereq, ip, sizeof(handlereq)))
Expand Down Expand Up @@ -558,6 +558,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
if (ret)
goto out_free_descs;
lh->descs[i] = desc;
count = i;

if (lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW)
set_bit(FLAG_ACTIVE_LOW, &desc->flags);
Expand Down Expand Up @@ -628,7 +629,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
out_put_unused_fd:
put_unused_fd(fd);
out_free_descs:
for (; i >= 0; i--)
for (i = 0; i < count; i++)
gpiod_free(lh->descs[i]);
kfree(lh->label);
out_free_lh:
Expand Down Expand Up @@ -902,7 +903,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
desc = &gdev->descs[offset];
ret = gpiod_request(desc, le->label);
if (ret)
goto out_free_desc;
goto out_free_label;
le->desc = desc;
le->eflags = eflags;

Expand Down

0 comments on commit 89240c6

Please sign in to comment.