diff mbox series

[v6,01/13] pinctrl: core: Add pinctrl_get_device()

Message ID 20230306090014.128732-2-biju.das.jz@bp.renesas.com
State New
Headers show
Series Add pinctrl sysfs and RZ/G2L POEG support | expand

Commit Message

Biju Das March 6, 2023, 9 a.m. UTC
Add pinctrl_get_device() to find a device handle associated with
a pincontrol group(i.e. by matching function name and group name for a
device). This device handle can then be used for finding match for the
pin output disable device that protects device against short circuits
on the pins.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
---
v6:
 * New patch
Ref:
 https://lore.kernel.org/linux-renesas-soc/OS0PR01MB5922F5494D3C0862E15F3F8486B39@OS0PR01MB5922.jpnprd01.prod.outlook.com/T/#t
---
 drivers/pinctrl/core.c           | 49 ++++++++++++++++++++++++++++++++
 include/linux/pinctrl/consumer.h |  9 ++++++
 2 files changed, 58 insertions(+)
diff mbox series

Patch

diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index d6e6c751255f..2ba222026db4 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -27,6 +27,7 @@ 
 #include <linux/pinctrl/devinfo.h>
 #include <linux/pinctrl/machine.h>
 #include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
 
 #ifdef CONFIG_GPIOLIB
 #include "../gpio/gpiolib.h"
@@ -1584,6 +1585,54 @@  int pinctrl_select_default_state(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(pinctrl_select_default_state);
 
+static bool pinctrl_get_device_match(struct pinctrl_setting *setting,
+				     const char *fname, const char *gname)
+{
+	struct pinctrl_dev *pctldev = setting->pctldev;
+	const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
+	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
+	const char *function = pmxops->get_function_name(pctldev,
+							 setting->data.mux.func);
+	const char *group = pctlops->get_group_name(pctldev,
+						    setting->data.mux.group);
+
+	if ((!strcmp(function, fname)) && (!strcmp(group, gname)))
+		return true;
+
+	return false;
+}
+
+/**
+ * pinctrl_get_device() - returns device associated with a pincontrol group
+ * @fname: function name
+ * @gname: group name
+ */
+struct device *pinctrl_get_device(const char *fname, const char *gname)
+{
+	struct pinctrl *p;
+	struct pinctrl_state *state;
+	struct pinctrl_setting *setting;
+
+	mutex_lock(&pinctrl_list_mutex);
+
+	list_for_each_entry(p, &pinctrl_list, node) {
+		list_for_each_entry(state, &p->states, node) {
+			list_for_each_entry(setting, &state->settings, node) {
+				if (setting->type == PIN_MAP_TYPE_MUX_GROUP &&
+				    pinctrl_get_device_match(setting, fname, gname)) {
+					mutex_unlock(&pinctrl_list_mutex);
+					return p->dev;
+				}
+			}
+		}
+	}
+
+	mutex_unlock(&pinctrl_list_mutex);
+
+	return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL_GPL(pinctrl_get_device);
+
 #ifdef CONFIG_PM
 
 /**
diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h
index 4729d54e8995..6ff8857c0a9c 100644
--- a/include/linux/pinctrl/consumer.h
+++ b/include/linux/pinctrl/consumer.h
@@ -42,6 +42,9 @@  extern struct pinctrl * __must_check devm_pinctrl_get(struct device *dev);
 extern void devm_pinctrl_put(struct pinctrl *p);
 extern int pinctrl_select_default_state(struct device *dev);
 
+extern struct device * __must_check pinctrl_get_device(const char *fname,
+						       const char *gname);
+
 #ifdef CONFIG_PM
 extern int pinctrl_pm_select_default_state(struct device *dev);
 extern int pinctrl_pm_select_sleep_state(struct device *dev);
@@ -142,6 +145,12 @@  static inline int pinctrl_pm_select_idle_state(struct device *dev)
 	return 0;
 }
 
+static inline struct device * __must_check pinctrl_get_device(const char *fname,
+							      const char *gname)
+{
+	return NULL;
+}
+
 #endif /* CONFIG_PINCTRL */
 
 static inline struct pinctrl * __must_check pinctrl_get_select(struct device *dev,