summaryrefslogtreecommitdiffstats
path: root/drivers/regulator/internal.h
diff options
context:
space:
mode:
authorMiguel Ojeda <ojeda@kernel.org>2026-08-16 15:32:33 +0200
committerMiguel Ojeda <ojeda@kernel.org>2026-08-23 21:27:17 +0200
commit5febf432df1cfa5b25d99b54c32103fafbdd0eb9 (patch)
tree93a1ed1d337bc53adf1e572c2586d347703b286e /drivers/regulator/internal.h
downloadlinux-stable-5febf432df1cfa5b25d99b54c32103fafbdd0eb9.tar.gz
linux-stable-5febf432df1cfa5b25d99b54c32103fafbdd0eb9.zip
kbuild: rust: keep Rust objects out of Clang LTO with inline helpersgrafted
Under `CONFIG_LTO_CLANG` + `CONFIG_RUST_INLINE_HELPERS`, one may hit `objtool` errors such as: vmlinux.o: error: objtool: _R..._3Gsp4boot+0xd6a: can't find jump dest instruction at .text._R..._3Gsp4boot+0x1dfd The reason is that in such builds, the Clang invocation that compiles the combined Rust plus helpers bitcode emits LLVM bitcode (again) -- the final code generation happens in the linker's LTO step, which the `-mllvm` trap options passed to Clang do not reach. This, in turn, means that unreachable traps are missing, and the impossible paths do not merely fallthrough to the next symbol, but past the end of their own section, since LTO builds place each function in its own section. Thus filter `CC_FLAGS_LTO` out of the Clang invocation, so that it always emits machine code directly, with the traps in place. Assisted-by: LLM Cc: Gary Guo <gary@garyguo.net> Cc: Boqun Feng <boqun@kernel.org> Cc: Alice Ryhl <aliceryhl@google.com> Cc: Matthew Maurer <mmaurer@google.com> Cc: Josh Poimboeuf <jpoimboe@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: stable@vger.kernel.org Fixes: 3a2486cc1da5 ("kbuild: rust: provide an option to inline C helpers into Rust") Acked-by: Gary Guo <gary@garyguo.net> Link: https://patch.msgid.link/20260816133233.197500-2-ojeda@kernel.org Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'drivers/regulator/internal.h')
-rw-r--r--drivers/regulator/internal.h138
1 files changed, 138 insertions, 0 deletions
diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h
new file mode 100644
index 000000000..b3d48dc38
--- /dev/null
+++ b/drivers/regulator/internal.h
@@ -0,0 +1,138 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * internal.h -- Voltage/Current Regulator framework internal code
+ *
+ * Copyright 2007, 2008 Wolfson Microelectronics PLC.
+ * Copyright 2008 SlimLogic Ltd.
+ *
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
+ */
+
+#ifndef __REGULATOR_INTERNAL_H
+#define __REGULATOR_INTERNAL_H
+
+#include <linux/suspend.h>
+
+#define REGULATOR_STATES_NUM (PM_SUSPEND_MAX + 1)
+
+#define rdev_crit(rdev, fmt, ...) \
+ pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
+#define rdev_err(rdev, fmt, ...) \
+ pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
+#define rdev_warn(rdev, fmt, ...) \
+ pr_warn("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
+#define rdev_info(rdev, fmt, ...) \
+ pr_info("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
+#define rdev_dbg(rdev, fmt, ...) \
+ pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
+
+struct regulator_voltage {
+ int min_uV;
+ int max_uV;
+};
+
+/*
+ * struct regulator
+ *
+ * One for each consumer device.
+ * @voltage - a voltage array for each state of runtime, i.e.:
+ * PM_SUSPEND_ON
+ * PM_SUSPEND_TO_IDLE
+ * PM_SUSPEND_STANDBY
+ * PM_SUSPEND_MEM
+ * PM_SUSPEND_MAX
+ */
+struct regulator {
+ struct device *dev;
+ struct list_head list;
+ unsigned int always_on:1;
+ unsigned int bypass:1;
+ unsigned int device_link:1;
+ int uA_load;
+ unsigned int enable_count;
+ unsigned int deferred_disables;
+ struct regulator_voltage voltage[REGULATOR_STATES_NUM];
+ const char *supply_name;
+ struct device_attribute dev_attr;
+ struct regulator_dev *rdev;
+ struct dentry *debugfs;
+};
+
+extern const struct class regulator_class;
+
+static inline struct regulator_dev *dev_to_rdev(struct device *dev)
+{
+ return container_of(dev, struct regulator_dev, dev);
+}
+
+enum regulator_get_type {
+ NORMAL_GET,
+ EXCLUSIVE_GET,
+ OPTIONAL_GET,
+ MAX_GET_TYPE
+};
+
+#ifdef CONFIG_OF
+struct regulator_dev *of_regulator_dev_lookup(struct device *dev,
+ struct device_node *np,
+ const char *supply);
+struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
+ const struct regulator_desc *desc,
+ struct regulator_config *config,
+ struct device_node **node);
+
+struct regulator *_of_regulator_get(struct device *dev, struct device_node *node,
+ const char *id, enum regulator_get_type get_type);
+
+struct regulator_dev *of_parse_coupled_regulator(struct regulator_dev *rdev,
+ int index);
+
+int of_get_n_coupled(struct regulator_dev *rdev);
+
+bool of_check_coupling_data(struct regulator_dev *rdev);
+
+#else
+static inline struct regulator_dev *of_regulator_dev_lookup(struct device *dev,
+ struct device_node *np,
+ const char *supply)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline struct regulator_init_data *
+regulator_of_get_init_data(struct device *dev,
+ const struct regulator_desc *desc,
+ struct regulator_config *config,
+ struct device_node **node)
+{
+ return NULL;
+}
+
+static inline struct regulator_dev *
+of_parse_coupled_regulator(struct regulator_dev *rdev,
+ int index)
+{
+ return NULL;
+}
+
+static inline int of_get_n_coupled(struct regulator_dev *rdev)
+{
+ return 0;
+}
+
+static inline bool of_check_coupling_data(struct regulator_dev *rdev)
+{
+ return false;
+}
+
+#endif
+
+int _regulator_get_common_check(struct device *dev, const char *id,
+ enum regulator_get_type get_type);
+struct regulator *_regulator_get_common(struct regulator_dev *rdev, struct device *dev,
+ const char *id, enum regulator_get_type get_type);
+struct regulator *_regulator_get(struct device *dev, const char *id,
+ enum regulator_get_type get_type);
+int _regulator_bulk_get(struct device *dev, int num_consumers,
+ struct regulator_bulk_data *consumers, enum regulator_get_type get_type);
+#endif