diff mbox series

[RFC,1/3] pinctrl/core: check that can_sleep is true in pinctrl_gpio_direction()

Message ID 20211206131648.1521868-2-hverkuil-cisco@xs4all.nl
State New
Headers show
Series pinctrl: can_sleep and pinctrl_gpio_direction | expand

Commit Message

Hans Verkuil Dec. 6, 2021, 1:16 p.m. UTC
Since pinctrl_gpio_direction() takes a mutex, the gpio driver must
have can_sleep set to true. If not, then this function will call
WARN_ON (only once per pin controller) to tell the developer that
something must be done: either set can_sleep to true, or set the
direction in the combine gpio/pinctrl driver itself without calling
pinctrl_gpio_direction_input/output.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
---
 drivers/pinctrl/core.c | 11 +++++++++++
 drivers/pinctrl/core.h |  4 ++++
 2 files changed, 15 insertions(+)
diff mbox series

Patch

diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index ffe39336fcac..886242d08dcf 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -845,6 +845,17 @@  static int pinctrl_gpio_direction(unsigned gpio, bool input)
 
 	mutex_lock(&pctldev->mutex);
 
+	if (!pctldev->checked_can_sleep) {
+		struct gpio_chip *chip = gpio_to_chip(gpio);
+
+		pctldev->checked_can_sleep = true;
+		/*
+		 * This pin controller can sleep, so check that the gpio
+		 * controller sets can_sleep to true.
+		 */
+		WARN_ON(chip && !chip->can_sleep);
+	}
+
 	/* Convert to the pin controllers number space */
 	pin = gpio_to_pin(range, gpio);
 	ret = pinmux_gpio_direction(pctldev, range, pin, input);
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h
index 840103c40c14..ae14b4e69b7b 100644
--- a/drivers/pinctrl/core.h
+++ b/drivers/pinctrl/core.h
@@ -38,6 +38,9 @@  struct pinctrl_gpio_range;
  * @hog_sleep: sleep state for pins hogged by this device
  * @mutex: mutex taken on each pin controller specific action
  * @device_root: debugfs root for this device
+ * @checked_can_sleep: used internally to warn once if pinctrl_gpio_direction()
+ *	is called from a gpio driver that didn't set @can_sleep to true.
+ *	pinctrl_gpio_direction() uses mutexes, so it can sleep.
  */
 struct pinctrl_dev {
 	struct list_head node;
@@ -62,6 +65,7 @@  struct pinctrl_dev {
 #ifdef CONFIG_DEBUG_FS
 	struct dentry *device_root;
 #endif
+	bool checked_can_sleep;
 };
 
 /**