Commit b0f908d7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull gpio fixes from Bartosz Golaszewski:

 - fix interrupt handling in gpio-mxc

 - fix scoped_guard() usage in gpio-adnp

 - don't accept partial writes in gpio-virtuser debugfs interface as
   they can't really work correctly

 - fix resource leaks in gpio-rockchip

 - fix locking issues in remove path in shared GPIO management

 - undo the vote of a GPIO shared proxy virtual device on GPIO release

* tag 'gpio-fixes-for-v7.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
  gpio: rockchip: teardown bugs and resource leaks
  gpio: rockchip: convert bank->clk to devm_clk_get_enabled()
  gpio: virtuser: Fix uninitialized data bug in gpio_virtuser_direction_do_write()
  gpio: shared: fix lockdep false positive by removing unneeded lock
  gpio: shared: fix deadlock on shared proxy's parent removal
  gpio: adnp: fix flow control regression caused by scoped_guard()
  gpio: shared: undo the vote of the proxy on GPIO free
  gpio: mxc: fix irq_high handling
parents 43a1e374 95000776
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -237,7 +237,9 @@ static irqreturn_t adnp_irq(int irq, void *data)
		unsigned long pending;
		int err;

		scoped_guard(mutex, &adnp->i2c_lock) {
		{
			guard(mutex)(&adnp->i2c_lock);

			err = adnp_read(adnp, GPIO_PLR(adnp) + i, &level);
			if (err < 0)
				continue;
+1 −1
Original line number Diff line number Diff line
@@ -469,7 +469,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
		 * the handler is needed only once, but doing it for every port
		 * is more robust and easier.
		 */
		port->irq_high = -1;
		port->irq_high = 0;
		port->mx_irq_handler = mx2_gpio_irq_handler;
	} else
		port->mx_irq_handler = mx3_gpio_irq_handler;
+17 −6
Original line number Diff line number Diff line
@@ -638,10 +638,17 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank)
	return ret;
}

static void rockchip_clk_put(void *data)
{
	struct clk *clk = data;

	clk_put(clk);
}

static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
{
	struct resource res;
	int id = 0;
	int id = 0, ret;

	if (of_address_to_resource(bank->of_node, 0, &res)) {
		dev_err(bank->dev, "cannot find IO resource for bank\n");
@@ -656,11 +663,10 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
	if (!bank->irq)
		return -EINVAL;

	bank->clk = of_clk_get(bank->of_node, 0);
	bank->clk = devm_clk_get_enabled(bank->dev, NULL);
	if (IS_ERR(bank->clk))
		return PTR_ERR(bank->clk);

	clk_prepare_enable(bank->clk);
	id = readl(bank->reg_base + gpio_regs_v2.version_id);

	switch (id) {
@@ -672,9 +678,13 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank)
		bank->db_clk = of_clk_get(bank->of_node, 1);
		if (IS_ERR(bank->db_clk)) {
			dev_err(bank->dev, "cannot find debounce clk\n");
			clk_disable_unprepare(bank->clk);
			return -EINVAL;
		}

		ret = devm_add_action_or_reset(bank->dev, rockchip_clk_put,
					       bank->db_clk);
		if (ret)
			return ret;
		break;
	case GPIO_TYPE_V1:
		bank->gpio_regs = &gpio_regs_v1;
@@ -751,7 +761,6 @@ static int rockchip_gpio_probe(struct platform_device *pdev)

	ret = rockchip_gpiolib_register(bank);
	if (ret) {
		clk_disable_unprepare(bank->clk);
		mutex_unlock(&bank->deferred_lock);
		return ret;
	}
@@ -792,7 +801,9 @@ static void rockchip_gpio_remove(struct platform_device *pdev)
{
	struct rockchip_pin_bank *bank = platform_get_drvdata(pdev);

	clk_disable_unprepare(bank->clk);
	irq_set_chained_handler_and_data(bank->irq, NULL, NULL);
	if (bank->domain)
		irq_domain_remove(bank->domain);
	gpiochip_remove(&bank->gpio_chip);
}

+9 −0
Original line number Diff line number Diff line
@@ -103,9 +103,18 @@ static void gpio_shared_proxy_free(struct gpio_chip *gc, unsigned int offset)
{
	struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
	struct gpio_shared_desc *shared_desc = proxy->shared_desc;
	int ret;

	guard(gpio_shared_desc_lock)(shared_desc);

	if (proxy->voted_high) {
		ret = gpio_shared_proxy_set_unlocked(proxy,
			shared_desc->can_sleep ? gpiod_set_value_cansleep : gpiod_set_value, 0);
		if (ret)
			dev_err(proxy->dev,
				"Failed to unset the shared GPIO value on release: %d\n", ret);
	}

	proxy->shared_desc->usecnt--;

	dev_dbg(proxy->dev, "Shared GPIO freed, number of users: %u\n",
+2 −2
Original line number Diff line number Diff line
@@ -397,7 +397,7 @@ static ssize_t gpio_virtuser_direction_do_write(struct file *file,
	char buf[32], *trimmed;
	int ret, dir, val = 0;

	if (count >= sizeof(buf))
	if (*ppos != 0 || count >= sizeof(buf))
		return -EINVAL;

	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
@@ -622,7 +622,7 @@ static ssize_t gpio_virtuser_consumer_write(struct file *file,
	char buf[GPIO_VIRTUSER_NAME_BUF_LEN + 2];
	int ret;

	if (count >= sizeof(buf))
	if (*ppos != 0 || count >= sizeof(buf))
		return -EINVAL;

	ret = simple_write_to_buffer(buf, GPIO_VIRTUSER_NAME_BUF_LEN, ppos,
Loading