GPIO fixes for the v5.4 series:

- Don't clear FLAG_IS_OUT when emulating open drain/source in
   gpiolib.
 - Fix up the usage of nonexclusive GPIO descriptors from device
   trees.
 - Fix the incorrect IEC offset when toggling trigger edge in
   the Spreadtrum driver.
 - Use the correct unit for debounce settings in the MAX77620
   driver.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEElDRnuGcz/wPCXQWMQRCzN7AZXXMFAl2cT2cACgkQQRCzN7AZ
 XXPCIhAAieKjIfW+adcV9+EZUybw35R9QCn27TTowK3YZfNi4cXyOi9f39gw8Kby
 ZptY9lE5w6P142z8qLmtYWZ1F639sjeo4dZ2tXIzo0PhqG36rUP2hPOCffrhvMHb
 iDby2IIgKTbR4i1YxZk75h8s0oWG542JGs39Uu+UyYTNAwJdA/4jKjIHK4XosqdD
 YbhGNP4J4rmeNLwpK7RObg2NwWsfB0P15TEywnVNEDyOSsjmm65gKYSQn+frDlOz
 sSdLy/J2+suRCu2KwHlgclF2dKcm2wyBAHItyTFwLTlYOENUC/cAGDlc6/2Nqhh+
 CR9blbf5Jns0aTWoPDRHaAXy5qkKTfcI4osDJOP8yRVziz0vW0+Xq1PxmifrFl4d
 zFIN5MPwJ3kTjNlfOaR4txuqvZX8JCDAjMfHMY0e/fqG5Ofm4OvGfsk1Xdwq7wbs
 qV5Fewv6XybdHmIuDOHvJ9iPMuMEZbgs3jNRCxnLj0NYXDMXyHR9tJoTq71v8GHg
 KvyCNwKXACrRQvE/zkEYgSgY3IXS/3Dhv3RhmpzIpP/Ey55o57CmaqG3oh2C3C0V
 OyCXXYQ8ZvFrIAwLYZwq/l1f2knP0D+uJrT/puxvFUXJQpLqD72mfr20/G1tcyrf
 8lxwf2MHmqjLV79E+lTxykfTFi0AEbSBHy2FPDYewfdPQG7h6xo=
 =J0x0
 -----END PGP SIGNATURE-----

Merge tag 'gpio-v5.4-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio

Pull GPIO fixes from Linus Walleij:

 - don't clear FLAG_IS_OUT when emulating open drain/source in gpiolib

 - fix up the usage of nonexclusive GPIO descriptors from device trees

 - fix the incorrect IEC offset when toggling trigger edge in the
   Spreadtrum driver

 - use the correct unit for debounce settings in the MAX77620 driver

* tag 'gpio-v5.4-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio:
  gpio: max77620: Use correct unit for debounce times
  gpio: eic: sprd: Fix the incorrect EIC offset when toggling
  gpio: fix getting nonexclusive gpiods from DT
  gpiolib: don't clear FLAG_IS_OUT when emulating open-drain/open-source
This commit is contained in:
Linus Torvalds 2019-10-08 10:55:22 -07:00
commit d5001955c2
4 changed files with 27 additions and 15 deletions

View File

@ -530,11 +530,12 @@ static void sprd_eic_handle_one_type(struct gpio_chip *chip)
} }
for_each_set_bit(n, &reg, SPRD_EIC_PER_BANK_NR) { for_each_set_bit(n, &reg, SPRD_EIC_PER_BANK_NR) {
girq = irq_find_mapping(chip->irq.domain, u32 offset = bank * SPRD_EIC_PER_BANK_NR + n;
bank * SPRD_EIC_PER_BANK_NR + n);
girq = irq_find_mapping(chip->irq.domain, offset);
generic_handle_irq(girq); generic_handle_irq(girq);
sprd_eic_toggle_trigger(chip, girq, n); sprd_eic_toggle_trigger(chip, girq, offset);
} }
} }
} }

View File

@ -192,13 +192,13 @@ static int max77620_gpio_set_debounce(struct max77620_gpio *mgpio,
case 0: case 0:
val = MAX77620_CNFG_GPIO_DBNC_None; val = MAX77620_CNFG_GPIO_DBNC_None;
break; break;
case 1 ... 8: case 1000 ... 8000:
val = MAX77620_CNFG_GPIO_DBNC_8ms; val = MAX77620_CNFG_GPIO_DBNC_8ms;
break; break;
case 9 ... 16: case 9000 ... 16000:
val = MAX77620_CNFG_GPIO_DBNC_16ms; val = MAX77620_CNFG_GPIO_DBNC_16ms;
break; break;
case 17 ... 32: case 17000 ... 32000:
val = MAX77620_CNFG_GPIO_DBNC_32ms; val = MAX77620_CNFG_GPIO_DBNC_32ms;
break; break;
default: default:

View File

@ -317,7 +317,7 @@ struct gpio_desc *gpiod_get_from_of_node(struct device_node *node,
transitory = flags & OF_GPIO_TRANSITORY; transitory = flags & OF_GPIO_TRANSITORY;
ret = gpiod_request(desc, label); ret = gpiod_request(desc, label);
if (ret == -EBUSY && (flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE)) if (ret == -EBUSY && (dflags & GPIOD_FLAGS_BIT_NONEXCLUSIVE))
return desc; return desc;
if (ret) if (ret)
return ERR_PTR(ret); return ERR_PTR(ret);

View File

@ -3070,8 +3070,10 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
if (!ret) if (!ret)
goto set_output_value; goto set_output_value;
/* Emulate open drain by not actively driving the line high */ /* Emulate open drain by not actively driving the line high */
if (value) if (value) {
return gpiod_direction_input(desc); ret = gpiod_direction_input(desc);
goto set_output_flag;
}
} }
else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) { else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) {
ret = gpio_set_config(gc, gpio_chip_hwgpio(desc), ret = gpio_set_config(gc, gpio_chip_hwgpio(desc),
@ -3079,8 +3081,10 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
if (!ret) if (!ret)
goto set_output_value; goto set_output_value;
/* Emulate open source by not actively driving the line low */ /* Emulate open source by not actively driving the line low */
if (!value) if (!value) {
return gpiod_direction_input(desc); ret = gpiod_direction_input(desc);
goto set_output_flag;
}
} else { } else {
gpio_set_config(gc, gpio_chip_hwgpio(desc), gpio_set_config(gc, gpio_chip_hwgpio(desc),
PIN_CONFIG_DRIVE_PUSH_PULL); PIN_CONFIG_DRIVE_PUSH_PULL);
@ -3088,6 +3092,17 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
set_output_value: set_output_value:
return gpiod_direction_output_raw_commit(desc, value); return gpiod_direction_output_raw_commit(desc, value);
set_output_flag:
/*
* When emulating open-source or open-drain functionalities by not
* actively driving the line (setting mode to input) we still need to
* set the IS_OUT flag or otherwise we won't be able to set the line
* value anymore.
*/
if (ret == 0)
set_bit(FLAG_IS_OUT, &desc->flags);
return ret;
} }
EXPORT_SYMBOL_GPL(gpiod_direction_output); EXPORT_SYMBOL_GPL(gpiod_direction_output);
@ -3448,8 +3463,6 @@ static void gpio_set_open_drain_value_commit(struct gpio_desc *desc, bool value)
if (value) { if (value) {
ret = chip->direction_input(chip, offset); ret = chip->direction_input(chip, offset);
if (!ret)
clear_bit(FLAG_IS_OUT, &desc->flags);
} else { } else {
ret = chip->direction_output(chip, offset, 0); ret = chip->direction_output(chip, offset, 0);
if (!ret) if (!ret)
@ -3479,8 +3492,6 @@ static void gpio_set_open_source_value_commit(struct gpio_desc *desc, bool value
set_bit(FLAG_IS_OUT, &desc->flags); set_bit(FLAG_IS_OUT, &desc->flags);
} else { } else {
ret = chip->direction_input(chip, offset); ret = chip->direction_input(chip, offset);
if (!ret)
clear_bit(FLAG_IS_OUT, &desc->flags);
} }
trace_gpio_direction(desc_to_gpio(desc), !value, ret); trace_gpio_direction(desc_to_gpio(desc), !value, ret);
if (ret < 0) if (ret < 0)