Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b8cd253a authored by Linus Walleij's avatar Linus Walleij
Browse files

Merge tag 'gpio-v5.4-rc2-fixes-for-linus' of...

Merge tag 'gpio-v5.4-rc2-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux into fixes

gpio: fixes for v5.4-rc2

- fix a bug with emulated open-drain/source where lines' values can no longer
  be changed
- fix getting nonexclusive gpiods from DT
- fix an incorrect offset for the level trigger in gpio-eic-sprd
parents 54ecb8f7 e91aafcb
Loading
Loading
Loading
Loading
+4 −3
Original line number Original line Diff line number Diff line
@@ -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);
		}
		}
	}
	}
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -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);
+19 −8
Original line number Original line Diff line number Diff line
@@ -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)