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@xxxxxxxxxxxxxx> --- v6: * New patch Ref: https://lore.kernel.org/linux-renesas-soc/OS0PR01MB5922F5494D3C0862E15F3F8486B39@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/T/#t --- drivers/pinctrl/core.c | 49 ++++++++++++++++++++++++++++++++ include/linux/pinctrl/consumer.h | 9 ++++++ 2 files changed, 58 insertions(+) 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, -- 2.25.1