[PATCH v2 3/5] drivers/core: simplify variadic args handling

Andrzej Hajda
2025-12-01T09:33:40Z

Changing argument type from va_list to struct va_format * allows
to simplify variadic argument handling with va_format_call helper.

Signed-off-by: Andrzej Hajda <andrzej.hajda@intel.com>
---
drivers/base/core.c | 50 +++++++-------------------------------------------
1 file changed, 7 insertions(+), 43 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 513e5ef8a6da..4d76b67a87e3 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -4965,30 +4965,12 @@ define_dev_printk_level(_dev_info, KERN_INFO);
#endif

static void __dev_probe_failed(const struct device *dev, int err, bool fatal,
- const char *fmt, va_list vargsp)
+ const char *fmt, struct va_format *vaf)
{
- struct va_format vaf;
- va_list vargs;
-
- /*
- * On x86_64 and possibly on other architectures, va_list is actually a
- * size-1 array containing a structure. As a result, function parameter
- * vargsp decays from T[1] to T*, and &vargsp has type T** rather than
- * T(*)[1], which is expected by its assignment to vaf.va below.
- *
- * One standard way to solve this mess is by creating a copy in a local
- * variable of type va_list and then using a pointer to that local copy
- * instead, which is the approach employed here.
- */
- va_copy(vargs, vargsp);
-
- vaf.fmt = fmt;
- vaf.va = &vargs;
-
switch (err) {
case -EPROBE_DEFER:
- device_set_deferred_probe_reason(dev, &vaf);
- dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
+ device_set_deferred_probe_reason(dev, vaf);
+ dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), vaf);
break;

case -ENOMEM:
@@ -4998,13 +4980,11 @@ static void __dev_probe_failed(const struct device *dev, int err, bool fatal,
default:
/* Log fatal final failures as errors, otherwise produce warnings */
if (fatal)
- dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
+ dev_err(dev, "error %pe: %pV", ERR_PTR(err), vaf);
else
- dev_warn(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
+ dev_warn(dev, "error %pe: %pV", ERR_PTR(err), vaf);
break;
}
-
- va_end(vargs);
}

/**
@@ -5042,15 +5022,7 @@ static void __dev_probe_failed(const struct device *dev, int err, bool fatal,
*/
int dev_err_probe(const struct device *dev, int err, const char *fmt, ...)
{
- va_list vargs;
-
- va_start(vargs, fmt);
-
- /* Use dev_err() for logging when err doesn't equal -EPROBE_DEFER */
- __dev_probe_failed(dev, err, true, fmt, vargs);
-
- va_end(vargs);
-
+ va_format_call(fmt, __dev_probe_failed, dev, err, true, fmt, va_format_arg);
return err;
}
EXPORT_SYMBOL_GPL(dev_err_probe);
@@ -5090,15 +5062,7 @@ EXPORT_SYMBOL_GPL(dev_err_probe);
*/
int dev_warn_probe(const struct device *dev, int err, const char *fmt, ...)
{
- va_list vargs;
-
- va_start(vargs, fmt);
-
- /* Use dev_warn() for logging when err doesn't equal -EPROBE_DEFER */
- __dev_probe_failed(dev, err, false, fmt, vargs);
-
- va_end(vargs);
-
+ va_format_call(fmt, __dev_probe_failed, dev, err, false, fmt, va_format_arg);
return err;
}
EXPORT_SYMBOL_GPL(dev_warn_probe);

--
2.43.0