Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpio: rockchip: Stop calling pinctrl for set_direction

Marking the whole controller as sleeping due to the pinctrl calls in the
.direction_{input,output} callbacks has the unfortunate side effect that
legitimate invocations of .get and .set, which cannot themselves sleep,
in atomic context now spew WARN()s from gpiolib.

However, as Heiko points out, the driver doing this is a bit silly to
begin with, as the pinctrl .gpio_set_direction hook doesn't even care
about the direction, the hook is only used to claim the mux. And sure
enough, the .gpio_request_enable hook exists to serve this very purpose,
so switch to that and remove the problematic business entirely.

Cc: stable@vger.kernel.org
Fixes: 20cf2aed89ac ("gpio: rockchip: mark the GPIO controller as sleeping")
Suggested-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Link: https://lore.kernel.org/r/bddc0469f25843ca5ae0cf578ab3671435ae98a7.1769429546.git.robin.murphy@arm.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

authored by

Robin Murphy and committed by
Bartosz Golaszewski
7ca497be 63804fed

+4 -13
-8
drivers/gpio/gpio-rockchip.c
··· 18 18 #include <linux/of.h> 19 19 #include <linux/of_address.h> 20 20 #include <linux/of_irq.h> 21 - #include <linux/pinctrl/consumer.h> 22 21 #include <linux/pinctrl/pinconf-generic.h> 23 22 #include <linux/platform_device.h> 24 23 #include <linux/regmap.h> ··· 162 163 struct rockchip_pin_bank *bank = gpiochip_get_data(chip); 163 164 unsigned long flags; 164 165 u32 data = input ? 0 : 1; 165 - 166 - 167 - if (input) 168 - pinctrl_gpio_direction_input(chip, offset); 169 - else 170 - pinctrl_gpio_direction_output(chip, offset); 171 166 172 167 raw_spin_lock_irqsave(&bank->slock, flags); 173 168 rockchip_gpio_writel_bit(bank, offset, data, bank->gpio_regs->port_ddr); ··· 586 593 gc->ngpio = bank->nr_pins; 587 594 gc->label = bank->name; 588 595 gc->parent = bank->dev; 589 - gc->can_sleep = true; 590 596 591 597 ret = gpiochip_add_data(gc, bank); 592 598 if (ret) {
+4 -5
drivers/pinctrl/pinctrl-rockchip.c
··· 3545 3545 return 0; 3546 3546 } 3547 3547 3548 - static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, 3549 - struct pinctrl_gpio_range *range, 3550 - unsigned offset, 3551 - bool input) 3548 + static int rockchip_pmx_gpio_request_enable(struct pinctrl_dev *pctldev, 3549 + struct pinctrl_gpio_range *range, 3550 + unsigned int offset) 3552 3551 { 3553 3552 struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); 3554 3553 struct rockchip_pin_bank *bank; ··· 3561 3562 .get_function_name = rockchip_pmx_get_func_name, 3562 3563 .get_function_groups = rockchip_pmx_get_groups, 3563 3564 .set_mux = rockchip_pmx_set, 3564 - .gpio_set_direction = rockchip_pmx_gpio_set_direction, 3565 + .gpio_request_enable = rockchip_pmx_gpio_request_enable, 3565 3566 }; 3566 3567 3567 3568 /*