[PATCH 1/2] console: provide best-effort clk_get_for_console helper

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Ahmad Fatoum <ahmad@xxxxxx>

clk_get will return -EPROBE_DEFER if clock provider hasn't yet been
probed. In a system with deep probe enabled, dependencies are probed
on demand, so a -EPROBE_DEFER return is final and the console probe
will never succeed.

CONFIG_DEBUG_LL is often used to debug this, but because the low-level
console is not interactive, it's a bit cumbersome. Improve upon this a
bit, by providing a clk_get_for_console helper that returns NULL if and
only if we are sure that a clock provider will not be probed.

In that case, the driver can skip code paths initialization code and
baud rate setting dependent on having access to the clock and still
register a console that reuses what was set up by CONFIG_DEBUG_LL.

Signed-off-by: Ahmad Fatoum <ahmad@xxxxxx>
---
 include/console.h   | 26 ++++++++++++++++++++++++++
 include/linux/clk.h | 21 +++++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/include/console.h b/include/console.h
index 586b68f73301..b8c901801e9f 100644
--- a/include/console.h
+++ b/include/console.h
@@ -8,6 +8,7 @@
 #define _CONSOLE_H_
 
 #include <param.h>
+#include <linux/clk.h>
 #include <linux/list.h>
 #include <driver.h>
 #include <serdev.h>
@@ -208,4 +209,29 @@ static inline void console_ctrlc_allow(void) { }
 static inline void console_ctrlc_forbid(void) { }
 #endif
 
+/**
+ * clk_get_for_console - get clock, ignoring known unavailable clock controller
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Return: a struct clk corresponding to the clock producer, a
+ * valid IS_ERR() condition containing errno or NULL if it could
+ * be determined that the clock producer will never be probed in
+ * absence of modules. The NULL return allows serial drivers to
+ * skip clock handling and rely on CONFIG_DEBUG_LL.
+ */
+static inline struct clk *clk_get_for_console(struct device *dev, const char *id)
+{
+	struct clk *clk;
+
+	if (!IS_ENABLED(CONFIG_DEBUG_LL))
+		return clk_get(dev, id);
+
+	clk = clk_get_if_available(dev, id);
+	if (clk == NULL)
+		dev_warn(dev, "couldn't get clock (ignoring)\n");
+
+	return clk;
+}
+
 #endif
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 61b4ff3127cf..f505f18a75c0 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -14,6 +14,7 @@
 #include <linux/spinlock.h>
 #include <linux/stringify.h>
 #include <linux/container_of.h>
+#include <deep-probe.h>
 #include <xfuncs.h>
 
 struct device;
@@ -982,4 +983,24 @@ static inline struct clk *clk_get_enabled(struct device *dev, const char *id)
 	return clk;
 }
 
+/**
+ * clk_get_if_available - get clock, ignoring known unavailable clock controller
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Return: a struct clk corresponding to the clock producer, a
+ * valid IS_ERR() condition containing errno or NULL if it could
+ * be determined that the clock producer will never be probed in
+ * absence of modules.
+ */
+static inline struct clk *clk_get_if_available(struct device *dev, const char *id)
+{
+	struct clk *clk = clk_get(dev, id);
+
+	if (clk == ERR_PTR(-EPROBE_DEFER) && deep_probe_is_supported())
+		return NULL;
+
+	return clk;
+}
+
 #endif
-- 
2.39.2





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux