summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinmux.h
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2026-09-02 09:55:01 -0400
committerSteven Rostedt <rostedt@goodmis.org>2026-09-02 11:08:21 -0400
commit4617721c502b2ddaa4e324e86da4997edf738fa5 (patch)
tree350aa83b47da0b574a814795392b20b0bed83cbc /drivers/pinctrl/pinmux.h
downloadlinux-stable-4617721c502b2ddaa4e324e86da4997edf738fa5.tar.gz
linux-stable-4617721c502b2ddaa4e324e86da4997edf738fa5.zip
ftrace: Synchronize the initialization of ftrace_opsgrafted
There's some internal state that ftrace_ops needs to have set, but since it can be declared outside of the ftrace.c code, it calls ftrace_ops_init() on the ops in every global function. The issue is that if two tasks call it on the same ops at the same time it is possible to have the initialization of one corrupt the initialization of the other call. Create a ops_mutex to use to synchronize every initialization of the ftrace_ops. The mutex is taken within checking the ftrace_ops flag that states it was initializied but the flag is checked again after the mutex has been taken. Checking first outside the mutex allows it to shortcut having to take the mutex. But then the check needs to be done again after the mute is taken in case of races. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260902095501.6b59af20@gandalf.local.home Fixes: f04f24fb7e48d ("ftrace, kprobes: Fix a deadlock on ftrace_regex_lock") Reported-by: sashiko-bot@kernel.org Close: https://lore.kernel.org/all/20260829025528.49A831F000E9@smtp.kernel.org/ Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'drivers/pinctrl/pinmux.h')
-rw-r--r--drivers/pinctrl/pinmux.h181
1 files changed, 181 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h
new file mode 100644
index 000000000..4e826c1a5
--- /dev/null
+++ b/drivers/pinctrl/pinmux.h
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Internal interface between the core pin control system and the
+ * pinmux portions
+ *
+ * Copyright (C) 2011 ST-Ericsson SA
+ * Written on behalf of Linaro for ST-Ericsson
+ * Based on bits of regulator core, gpio core and clk core
+ *
+ * Author: Linus Walleij <linus.walleij@linaro.org>
+ */
+
+#include <linux/types.h>
+
+struct dentry;
+struct seq_file;
+
+struct pinctrl_dev;
+struct pinctrl_gpio_range;
+struct pinctrl_map;
+struct pinctrl_setting;
+
+#ifdef CONFIG_PINMUX
+
+int pinmux_check_ops(struct pinctrl_dev *pctldev);
+
+int pinmux_validate_map(const struct pinctrl_map *map, int i);
+
+bool pinmux_can_be_used_for_gpio(struct pinctrl_dev *pctldev, unsigned int pin);
+
+int pinmux_request_gpio(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int pin, unsigned int gpio);
+void pinmux_free_gpio(struct pinctrl_dev *pctldev, unsigned int pin,
+ struct pinctrl_gpio_range *range);
+int pinmux_gpio_direction(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int pin, bool input);
+
+int pinmux_map_to_setting(const struct pinctrl_map *map,
+ struct pinctrl_setting *setting);
+void pinmux_free_setting(const struct pinctrl_setting *setting);
+int pinmux_enable_setting(const struct pinctrl_setting *setting);
+void pinmux_disable_setting(const struct pinctrl_setting *setting);
+
+#else
+
+static inline int pinmux_check_ops(struct pinctrl_dev *pctldev)
+{
+ return 0;
+}
+
+static inline int pinmux_validate_map(const struct pinctrl_map *map, int i)
+{
+ return 0;
+}
+
+static inline bool pinmux_can_be_used_for_gpio(struct pinctrl_dev *pctldev,
+ unsigned int pin)
+{
+ return true;
+}
+
+static inline int pinmux_request_gpio(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int pin, unsigned int gpio)
+{
+ return 0;
+}
+
+static inline void pinmux_free_gpio(struct pinctrl_dev *pctldev,
+ unsigned int pin,
+ struct pinctrl_gpio_range *range)
+{
+}
+
+static inline int pinmux_gpio_direction(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int pin, bool input)
+{
+ return 0;
+}
+
+static inline int pinmux_map_to_setting(const struct pinctrl_map *map,
+ struct pinctrl_setting *setting)
+{
+ return 0;
+}
+
+static inline void pinmux_free_setting(const struct pinctrl_setting *setting)
+{
+}
+
+static inline int pinmux_enable_setting(const struct pinctrl_setting *setting)
+{
+ return 0;
+}
+
+static inline void pinmux_disable_setting(const struct pinctrl_setting *setting)
+{
+}
+
+#endif
+
+#if defined(CONFIG_PINMUX) && defined(CONFIG_DEBUG_FS)
+
+void pinmux_show_map(struct seq_file *s, const struct pinctrl_map *map);
+void pinmux_show_setting(struct seq_file *s,
+ const struct pinctrl_setting *setting);
+void pinmux_init_device_debugfs(struct dentry *devroot,
+ struct pinctrl_dev *pctldev);
+
+#else
+
+static inline void pinmux_show_map(struct seq_file *s,
+ const struct pinctrl_map *map)
+{
+}
+
+static inline void pinmux_show_setting(struct seq_file *s,
+ const struct pinctrl_setting *setting)
+{
+}
+
+static inline void pinmux_init_device_debugfs(struct dentry *devroot,
+ struct pinctrl_dev *pctldev)
+{
+}
+
+#endif
+
+#ifdef CONFIG_GENERIC_PINMUX_FUNCTIONS
+
+/**
+ * struct function_desc - generic function descriptor
+ * @func: generic data of the pin function (name and groups of pins)
+ * @data: pin controller driver specific data
+ */
+struct function_desc {
+ const struct pinfunction *func;
+ void *data;
+};
+
+int pinmux_generic_get_function_count(struct pinctrl_dev *pctldev);
+
+const char *
+pinmux_generic_get_function_name(struct pinctrl_dev *pctldev,
+ unsigned int selector);
+
+int pinmux_generic_get_function_groups(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ const char * const **groups,
+ unsigned int * const ngroups);
+
+const struct function_desc *
+pinmux_generic_get_function(struct pinctrl_dev *pctldev, unsigned int selector);
+
+int pinmux_generic_add_function(struct pinctrl_dev *pctldev,
+ const char *name,
+ const char * const *groups,
+ unsigned int const ngroups,
+ void *data);
+
+int pinmux_generic_add_pinfunction(struct pinctrl_dev *pctldev,
+ const struct pinfunction *func, void *data);
+
+int pinmux_generic_remove_function(struct pinctrl_dev *pctldev,
+ unsigned int selector);
+
+void pinmux_generic_free_functions(struct pinctrl_dev *pctldev);
+
+bool pinmux_generic_function_is_gpio(struct pinctrl_dev *pctldev,
+ unsigned int selector);
+
+#else
+
+static inline void pinmux_generic_free_functions(struct pinctrl_dev *pctldev)
+{
+}
+
+#endif /* CONFIG_GENERIC_PINMUX_FUNCTIONS */