On Mon, Feb 03, 2025 at 03:25:17PM +0100, Greg Kroah-Hartman wrote: > Many drivers abuse the platform driver/bus system as it provides a > simple way to create and bind a device to a driver-specific set of > probe/release functions. Instead of doing that, and wasting all of the > memory associated with a platform device, here is a "faux" bus that > can be used instead. ... > +#include <linux/device/faux.h> I would rather think that this goes after generic inclusions... > +#include <linux/err.h> > +#include <linux/init.h> > +#include <linux/slab.h> > +#include <linux/string.h> ...somewhere here. But looking into organisation of device.h and device/*.h, I would rather think of the linux/faux_device.h. > +#include "base.h" I don't remember by heart what it does include, I would go with IWYU principle and list above all what we use. container_of.h device.h export.h printk.h types.h ... > +static int faux_match(struct device *dev, const struct device_driver *drv) > +{ > + struct faux_object *faux_obj = to_faux_object(dev); > + > + /* Match is simple, strcmp()! */ > + return (strcmp(faux_obj->name, drv->name) == 0); Outer parentheses are not needed. > +} ... > +/** > + * __faux_device_create - create and register a faux device and driver > + * @name: name of the device and driver we are adding > + * @faux_ops: struct faux_driver_ops that the new device will call back into, can be NULL > + * @owner: module owner of the device/driver > + * > + * Create a new faux device and driver, both with the same name, and register > + * them in the driver core properly. The probe() callback of @faux_ops will be > + * called with the new device that is created for the caller to do something > + * with. The kernel-doc will complain on missing Return: section. > + */ > +struct faux_device *__faux_device_create(const char *name, > + struct faux_driver_ops *faux_ops, > + struct module *owner) > +{ > + struct device_driver *drv; > + struct device *dev; > + struct faux_object *faux_obj; > + struct faux_device *faux_dev; > + int ret; > + faux_obj = kzalloc(sizeof(*faux_obj) + strlen(name) + 1, GFP_KERNEL); Potential overflow. To avoid one may use struct_size() from overflow.h. > + if (!faux_obj) > + return NULL; > + > + /* Save off the name of the object into local memory */ > + strcpy(faux_obj->name, name); > + > + /* Initialize the driver portion and register it with the driver core */ > + faux_obj->faux_ops = faux_ops; > + drv = &faux_obj->driver; > + > + drv->owner = owner; > + drv->name = faux_obj->name; > + drv->bus = &faux_bus_type; > + drv->probe_type = PROBE_PREFER_ASYNCHRONOUS; > + > + ret = driver_register(drv); > + if (ret) { > + pr_err("%s: driver_register for %s faux driver failed with %d\n", > + __func__, name, ret); > + kfree(faux_obj); > + return NULL; > + } > + > + /* Initialize the device portion and register it with the driver core */ > + faux_dev = &faux_obj->faux_dev; > + dev = &faux_dev->dev; > + > + device_initialize(dev); > + dev->release = faux_device_release; > + dev->parent = &faux_bus_root; > + dev->bus = &faux_bus_type; > + dev_set_name(dev, "%s", name); > + > + ret = device_add(dev); > + if (ret) { > + pr_err("%s: device_add for %s faux device failed with %d\n", > + __func__, name, ret); > + put_device(dev); > + return NULL; > + } > + > + return faux_dev; > +} > +EXPORT_SYMBOL_GPL(__faux_device_create); ... > +#ifndef _FAUX_DEVICE_H_ > +#define _FAUX_DEVICE_H_ > +#include <linux/module.h> + container_of.h > +#include <linux/device.h> > +struct faux_device { > + struct device dev; > +}; > +#define to_faux_device(x) container_of_const((x), struct faux_device, dev) > + > +struct faux_driver_ops { > + int (*probe)(struct faux_device *faux_dev); > + void (*remove)(struct faux_device *faux_dev); > +}; > + > +#define faux_device_create(name, faux_ops) __faux_device_create(name, faux_ops, THIS_MODULE) > +struct faux_device *__faux_device_create(const char *name, > + struct faux_driver_ops *faux_ops, > + struct module *module); > +void faux_device_destroy(struct faux_device *faux_dev); > + > +#endif /* _FAUX_DEVICE_H_ */ -- With Best Regards, Andy Shevchenko