Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

driver core: Add device_show_string() helper for sysfs attributes

For drivers wishing to expose an unsigned long, int or bool at a static
memory location in sysfs, the driver core provides ready-made helpers
such as device_show_ulong() to be used as ->show() callback.

Some drivers need to expose a string and so far they all provide their
own ->show() implementation. arch/powerpc/perf/hv-24x7.c went so far
as to create a device_show_string() helper but kept it private.

Make it public for reuse by other drivers. The pattern seems to be
sufficiently frequent to merit a public helper.

Add a DEVICE_STRING_ATTR_RO() macro in line with the existing
DEVICE_ULONG_ATTR() and similar macros to ease declaration of string
attributes.

Signed-off-by: Lukas Wunner <lukas@wunner.de>
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/2e3eaaf2600bb55c0415c23ba301e809403a7aa2.1713608122.git.lukas@wunner.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Lukas Wunner and committed by
Greg Kroah-Hartman
3cc50d07 e5019b14

+24 -10
-10
arch/powerpc/perf/hv-24x7.c
··· 425 425 return kasprintf(gfp, "%.*s", max_len, maybe_str); 426 426 } 427 427 428 - static ssize_t device_show_string(struct device *dev, 429 - struct device_attribute *attr, char *buf) 430 - { 431 - struct dev_ext_attribute *d; 432 - 433 - d = container_of(attr, struct dev_ext_attribute, attr); 434 - 435 - return sprintf(buf, "%s\n", (char *)d->var); 436 - } 437 - 438 428 static ssize_t cpumask_show(struct device *dev, 439 429 struct device_attribute *attr, char *buf) 440 430 {
+9
drivers/base/core.c
··· 2538 2538 } 2539 2539 EXPORT_SYMBOL_GPL(device_show_bool); 2540 2540 2541 + ssize_t device_show_string(struct device *dev, 2542 + struct device_attribute *attr, char *buf) 2543 + { 2544 + struct dev_ext_attribute *ea = to_ext_attr(attr); 2545 + 2546 + return sysfs_emit(buf, "%s\n", (char *)ea->var); 2547 + } 2548 + EXPORT_SYMBOL_GPL(device_show_string); 2549 + 2541 2550 /** 2542 2551 * device_release - free device structure. 2543 2552 * @kobj: device's kobject.
+15
include/linux/device.h
··· 132 132 char *buf); 133 133 ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, 134 134 const char *buf, size_t count); 135 + ssize_t device_show_string(struct device *dev, struct device_attribute *attr, 136 + char *buf); 135 137 136 138 /** 137 139 * DEVICE_ATTR - Define a device attribute. ··· 252 250 #define DEVICE_BOOL_ATTR(_name, _mode, _var) \ 253 251 struct dev_ext_attribute dev_attr_##_name = \ 254 252 { __ATTR(_name, _mode, device_show_bool, device_store_bool), &(_var) } 253 + 254 + /** 255 + * DEVICE_STRING_ATTR_RO - Define a device attribute backed by a r/o string. 256 + * @_name: Attribute name. 257 + * @_mode: File mode. 258 + * @_var: Identifier of string. 259 + * 260 + * Like DEVICE_ULONG_ATTR(), but @_var is a string. Because the length of the 261 + * string allocation is unknown, the attribute must be read-only. 262 + */ 263 + #define DEVICE_STRING_ATTR_RO(_name, _mode, _var) \ 264 + struct dev_ext_attribute dev_attr_##_name = \ 265 + { __ATTR(_name, (_mode) & ~0222, device_show_string, NULL), (_var) } 255 266 256 267 #define DEVICE_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \ 257 268 struct device_attribute dev_attr_##_name = \