[PATCH] driver: implement dev_err_probe()

Ahmad Fatoum a.fatoum at pengutronix.de
Sat Oct 30 10:59:26 PDT 2021


The function like it's Linux equivalent is meant to be used during
driver probe whenever an error occurs that would lead to aborting the
probe. This allows moving EPROBE_DEFER checks out of drivers and
in future could allow selectively compiling out only error probe
messages, as they are mainly interesting during bring up.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 drivers/base/driver.c  | 49 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/printk.h | 12 +++++++++++
 2 files changed, 61 insertions(+)

diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 3b22a95e174c..e3615fcd0630 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -10,6 +10,8 @@
  * @brief barebox's driver model, and devinfo command
  */
 
+#define dev_err_probe dev_err_probe
+
 #include <common.h>
 #include <command.h>
 #include <deep-probe.h>
@@ -535,3 +537,50 @@ const void *device_get_match_data(struct device_d *dev)
 
 	return NULL;
 }
+
+/**
+ * dev_err_probe - probe error check and log helper
+ * @loglevel: log level configured in source file
+ * @dev: the pointer to the struct device
+ * @err: error value to test
+ * @fmt: printf-style format string
+ * @...: arguments as specified in the format string
+ *
+ * This helper implements common pattern present in probe functions for error
+ * checking: print debug or error message depending if the error value is
+ * -EPROBE_DEFER and propagate error upwards.
+ * In case of -EPROBE_DEFER it sets also defer probe reason, which can be
+ * checked later by reading devices_deferred debugfs attribute.
+ * It replaces code sequence::
+ *
+ * 	if (err != -EPROBE_DEFER)
+ * 		dev_err(dev, ...);
+ * 	else
+ * 		dev_dbg(dev, ...);
+ * 	return err;
+ *
+ * with::
+ *
+ * 	return dev_err_probe(dev, err, ...);
+ *
+ * Returns @err.
+ *
+ */
+int dev_err_probe(const struct device_d *dev, int err, const char *fmt, ...);
+int dev_err_probe(const struct device_d *dev, int err, const char *fmt, ...)
+{
+	struct va_format vaf;
+	va_list args;
+
+	va_start(args, fmt);
+	vaf.fmt = fmt;
+	vaf.va = &args;
+
+	dev_printf(err == -EPROBE_DEFER ? MSG_DEBUG : MSG_ERR,
+		   dev, "error %pe: %pV", ERR_PTR(err), &vaf);
+
+	va_end(args);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(dev_err_probe);
diff --git a/include/linux/printk.h b/include/linux/printk.h
index 3f370adb90ec..212041927251 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -74,6 +74,18 @@ static inline int pr_print(int level, const char *format, ...)
 #define dev_vdbg(dev, format, arg...)		\
 	__dev_printf(8, (dev) , format , ## arg)
 
+#if LOGLEVEL >= MSG_ERR
+int dev_err_probe(const struct device_d *dev, int err, const char *fmt, ...)
+	__attribute__ ((format(__printf__, 3, 4)));
+#elif !defined(dev_err_probe)
+static int dev_err_probe(const struct device_d *dev, int err, const char *fmt, ...)
+	__attribute__ ((format(__printf__, 3, 4)));
+static inline int dev_err_probe(const struct device_d *dev, int err, const char *fmt, ...)
+{
+	return err;
+}
+#endif
+
 #define __pr_printk(level, format, args...) \
 	({	\
 		(level) <= LOGLEVEL ? pr_print((level), (format), ##args) : 0; \
-- 
2.30.2




More information about the barebox mailing list