lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20241210-aux-device-create-helper-v1-1-5887f4d89308@baylibre.com>
Date: Tue, 10 Dec 2024 14:43:12 +0100
From: Jerome Brunet <jbrunet@...libre.com>
To: Greg Kroah-Hartman <gregkh@...uxfoundation.org>, 
 Dave Ertman <david.m.ertman@...el.com>, Ira Weiny <ira.weiny@...el.com>, 
 "Rafael J. Wysocki" <rafael@...nel.org>, Stephen Boyd <sboyd@...nel.org>, 
 Arnd Bergmann <arnd@...db.de>
Cc: linux-kernel@...r.kernel.org, Jerome Brunet <jbrunet@...libre.com>
Subject: [PATCH] driver core: auxiliary bus: add device creation helper

Add an function helper to create a device on the auxiliary bus.
This should avoid having the same code repeated in the different drivers
registering auxiliary devices.

Suggested-by: Stephen Boyd <sboyd@...nel.org>
Cc: Arnd Bergmann <arnd@...db.de>
Signed-off-by: Jerome Brunet <jbrunet@...libre.com>
---
The suggestion for this change was initially discussed here: [1]

I was not sure if the managed variant should return the auxiliary device or
just the error. This initial version returns the auxiliary device, allowing
it to be further (ab)used. Please let me know if you prefer to just return
the error code instead.

Also the non managed variant of the helper is not exported but it could
easily be, if necessary.

[1]: https://lore.kernel.org/linux-clk/df0a53ee859e450d84e81547099f5f36.sboyd@kernel.org
---
 drivers/base/auxiliary.c      | 89 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/auxiliary_bus.h |  4 ++
 2 files changed, 93 insertions(+)

diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c
index afa4df4c5a3f371b91d8dd8c4325495d32ad1291..60ca3f0da329fb7f8e69ecdf703b505e7cf5085c 100644
--- a/drivers/base/auxiliary.c
+++ b/drivers/base/auxiliary.c
@@ -385,6 +385,95 @@ void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv)
 }
 EXPORT_SYMBOL_GPL(auxiliary_driver_unregister);
 
+static DEFINE_IDA(auxiliary_device_ida);
+
+static void auxiliary_device_release(struct device *dev)
+{
+	struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
+
+	ida_free(&auxiliary_device_ida, auxdev->id);
+	kfree(auxdev);
+}
+
+static struct auxiliary_device *auxiliary_device_create(struct device *dev,
+							const char *name,
+							void *platform_data)
+{
+	struct auxiliary_device *auxdev;
+	int ret;
+
+	auxdev = kzalloc(sizeof(*auxdev), GFP_KERNEL);
+	if (!auxdev)
+		return ERR_PTR(-ENOMEM);
+
+	ret = ida_alloc(&auxiliary_device_ida, GFP_KERNEL);
+	if (ret < 0)
+		goto auxdev_free;
+
+	auxdev->id = ret;
+	auxdev->name = name;
+	auxdev->dev.parent = dev;
+	auxdev->dev.platform_data = platform_data;
+	auxdev->dev.release = auxiliary_device_release;
+	device_set_of_node_from_dev(&auxdev->dev, dev);
+
+	ret = auxiliary_device_init(auxdev);
+	if (ret)
+		goto ida_free;
+
+	ret = __auxiliary_device_add(auxdev, dev->driver->name);
+	if (ret) {
+		auxiliary_device_uninit(auxdev);
+		return ERR_PTR(ret);
+	}
+
+	return auxdev;
+
+ida_free:
+	ida_free(&auxiliary_device_ida, auxdev->id);
+auxdev_free:
+	kfree(auxdev);
+	return ERR_PTR(ret);
+}
+
+static void auxiliary_device_destroy(void *_auxdev)
+{
+	struct auxiliary_device *auxdev = _auxdev;
+
+	auxiliary_device_delete(auxdev);
+	auxiliary_device_uninit(auxdev);
+}
+
+/**
+ * devm_auxiliary_device_create - create a device on the auxiliary bus
+ * @dev: parent device
+ * @name: auxiliary bus driver name
+ * @platform_data: auxiliary bus device platform data
+ *
+ * Device managed helper to create an auxiliary bus device.
+ * The parent device KBUILD_MODNAME is automatically inserted before the
+ * provided name for the modname parameter of the auxiliary device created.
+ */
+struct auxiliary_device *devm_auxiliary_device_create(struct device *dev,
+						      const char *name,
+						      void *platform_data)
+{
+	struct auxiliary_device *auxdev;
+	int ret;
+
+	auxdev = auxiliary_device_create(dev, name, platform_data);
+	if (IS_ERR(auxdev))
+		return auxdev;
+
+	ret = devm_add_action_or_reset(dev, auxiliary_device_destroy,
+				       auxdev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return auxdev;
+}
+EXPORT_SYMBOL_GPL(devm_auxiliary_device_create);
+
 void __init auxiliary_bus_init(void)
 {
 	WARN_ON(bus_register(&auxiliary_bus_type));
diff --git a/include/linux/auxiliary_bus.h b/include/linux/auxiliary_bus.h
index 65dd7f15437474468acf0e28f6932a7ff2cfff2c..3ba11b3658833917a225916a508bddbd291bb545 100644
--- a/include/linux/auxiliary_bus.h
+++ b/include/linux/auxiliary_bus.h
@@ -254,6 +254,10 @@ int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *
 
 void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv);
 
+struct auxiliary_device *devm_auxiliary_device_create(struct device *dev,
+						      const char *name,
+						      void *platform_data);
+
 /**
  * module_auxiliary_driver() - Helper macro for registering an auxiliary driver
  * @__auxiliary_driver: auxiliary driver struct

---
base-commit: 40384c840ea1944d7c5a392e8975ed088ecf0b37
change-id: 20241210-aux-device-create-helper-93141524e523

Best regards,
-- 
Jerome


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ