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@xxxxxxxxxxxxxx> --- 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 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox