gpio fixes for v6.10-rc6

- fix a race condition in i2c transfers by adding a missing i2c lock
   section in gpio-pca953x
 - validate the number of obtained interrupts in gpio-davinci
 - add missing raw_spinlock_init() in gpio-graniterapids
 - fix bad character device behavior: disallow GPIO line reconfiguration
   without set direction both in v1 and v2 uAPI
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEFp3rbAvDxGAT0sefEacuoBRx13IFAmZ+hfEACgkQEacuoBRx
 13Kl9Q//TM5RjkPzeWeVCau5zvQSpEc7CvIbrfszjl/5o/RE6+j7tD/WAFCt3EUo
 qQQuPggNCzFPCcIiHh57GakhQi2v2VFzhIFrzy78eYpYOBaQ2w5C/ceodpx1xFbb
 w3ig005hJI2uM0CsdFNoC9FFMa8XgS3c3TbfYFtMk7smNgx1LFRD3s5x8GGC1lLX
 8P2ipLeLEE4CFJsJQ/dSeK9ssM9/+owmrF4bCcFtjZZ+iZPjDZCIKl6LB3H5sK5c
 x48PllI/EglXdTOFGZ2BqQ+svFUoNAuDna0+KQMns3CiHbQ8t0KZc6oItSOyDTX8
 h1uw1GbxXShxQldrsjASs1Y9erVIoVXbC3XW/rkSD2/WYU/1V3AtsqNNuhWgY1bL
 b+WUYyoK03uS9ocpHkm64g3nhStI24POhUsDiWhD1ZYBjqRyrbOZuEbt+Efmi7dL
 yF8qz86/QubsuvRbUDbUcvYtFsSwqNAYmV8tNgtubDara7dy4UCN3Z0kp8khANeF
 q5cgJMujePGkVKMOwH3mJPWV6y4MoFiayf/BrfZgP2BxU+1Wd8f4Evuq1RCLmbV3
 aq3uwUhwXbHmL0/PCeQ1pJ6uYUvz2saC5bFJKslTqgh5VgvqrXMIUertASBXZFEW
 cIXjdyIG4rCGRZTdENmXsitQvlKI3dSTI5+FGSqL4QEMXmlfOuY=
 =+2t8
 -----END PGP SIGNATURE-----

Merge tag 'gpio-fixes-for-v6.10-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio fixes from Bartosz Golaszewski:
 "An assortment of driver fixes and two commits addressing a bad
  behavior of the GPIO uAPI when reconfiguring requested lines.

   - fix a race condition in i2c transfers by adding a missing i2c lock
     section in gpio-pca953x

   - validate the number of obtained interrupts in gpio-davinci

   - add missing raw_spinlock_init() in gpio-graniterapids

   - fix bad character device behavior: disallow GPIO line
     reconfiguration without set direction both in v1 and v2 uAPI"

* tag 'gpio-fixes-for-v6.10-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
  gpiolib: cdev: Ignore reconfiguration without direction
  gpiolib: cdev: Disallow reconfiguration without direction (uAPI v1)
  gpio: graniterapids: Add missing raw_spinlock_init()
  gpio: davinci: Validate the obtained number of IRQs
  gpio: pca953x: fix pca953x_irq_bus_sync_unlock race
This commit is contained in:
Linus Torvalds 2024-06-28 09:15:13 -07:00
commit 1cf0668466
4 changed files with 26 additions and 11 deletions

View File

@ -225,6 +225,11 @@ static int davinci_gpio_probe(struct platform_device *pdev)
else
nirq = DIV_ROUND_UP(ngpio, 16);
if (nirq > MAX_INT_PER_BANK) {
dev_err(dev, "Too many IRQs!\n");
return -EINVAL;
}
chips = devm_kzalloc(dev, sizeof(*chips), GFP_KERNEL);
if (!chips)
return -ENOMEM;

View File

@ -296,6 +296,8 @@ static int gnr_gpio_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
raw_spin_lock_init(&priv->lock);
regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(regs))
return PTR_ERR(regs);

View File

@ -758,6 +758,8 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
int level;
if (chip->driver_data & PCA_PCAL) {
guard(mutex)(&chip->i2c_lock);
/* Enable latch on interrupt-enabled inputs */
pca953x_write_regs(chip, PCAL953X_IN_LATCH, chip->irq_mask);

View File

@ -89,6 +89,10 @@ struct linehandle_state {
GPIOHANDLE_REQUEST_OPEN_DRAIN | \
GPIOHANDLE_REQUEST_OPEN_SOURCE)
#define GPIOHANDLE_REQUEST_DIRECTION_FLAGS \
(GPIOHANDLE_REQUEST_INPUT | \
GPIOHANDLE_REQUEST_OUTPUT)
static int linehandle_validate_flags(u32 flags)
{
/* Return an error if an unknown flag is set */
@ -169,21 +173,21 @@ static long linehandle_set_config(struct linehandle_state *lh,
if (ret)
return ret;
/* Lines must be reconfigured explicitly as input or output. */
if (!(lflags & GPIOHANDLE_REQUEST_DIRECTION_FLAGS))
return -EINVAL;
for (i = 0; i < lh->num_descs; i++) {
desc = lh->descs[i];
linehandle_flags_to_desc_flags(gcnf.flags, &desc->flags);
linehandle_flags_to_desc_flags(lflags, &desc->flags);
/*
* Lines have to be requested explicitly for input
* or output, else the line will be treated "as is".
*/
if (lflags & GPIOHANDLE_REQUEST_OUTPUT) {
int val = !!gcnf.default_values[i];
ret = gpiod_direction_output(desc, val);
if (ret)
return ret;
} else if (lflags & GPIOHANDLE_REQUEST_INPUT) {
} else {
ret = gpiod_direction_input(desc);
if (ret)
return ret;
@ -1530,12 +1534,14 @@ static long linereq_set_config(struct linereq *lr, void __user *ip)
line = &lr->lines[i];
desc = lr->lines[i].desc;
flags = gpio_v2_line_config_flags(&lc, i);
/*
* Lines not explicitly reconfigured as input or output
* are left unchanged.
*/
if (!(flags & GPIO_V2_LINE_DIRECTION_FLAGS))
continue;
gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags);
edflags = flags & GPIO_V2_LINE_EDGE_DETECTOR_FLAGS;
/*
* Lines have to be requested explicitly for input
* or output, else the line will be treated "as is".
*/
if (flags & GPIO_V2_LINE_FLAG_OUTPUT) {
int val = gpio_v2_line_config_output_value(&lc, i);
@ -1543,7 +1549,7 @@ static long linereq_set_config(struct linereq *lr, void __user *ip)
ret = gpiod_direction_output(desc, val);
if (ret)
return ret;
} else if (flags & GPIO_V2_LINE_FLAG_INPUT) {
} else {
ret = gpiod_direction_input(desc);
if (ret)
return ret;