Commit 1cf06684 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 90384559 b4403963
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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;
+2 −0
Original line number Diff line number Diff line
@@ -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);
+2 −0
Original line number Diff line number Diff line
@@ -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);

+17 −11
Original line number Diff line number Diff line
@@ -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);
		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".
		 * 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;
		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;