All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/7] driver core: core: move to use class_to_subsys()
@ 2023-03-31  9:33 Greg Kroah-Hartman
  2023-03-31  9:33 ` [PATCH 2/7] driver core: create class_is_registered() Greg Kroah-Hartman
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Greg Kroah-Hartman @ 2023-03-31  9:33 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

There are a number of places in core.c that need access to the private
subsystem structure of struct class, so move them to use
class_to_subsys() instead of accessing it directly.

This requires exporting class_to_subsys() out of class.c, but keeping it
local to the driver core.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/base.h  |   2 +
 drivers/base/class.c |   2 +-
 drivers/base/core.c  | 121 ++++++++++++++++++++++++++++---------------
 3 files changed, 81 insertions(+), 44 deletions(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index 2867ca4ee4ce..6296164bb7f3 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -73,6 +73,8 @@ static inline void subsys_put(struct subsys_private *sp)
 		kset_put(&sp->subsys);
 }
 
+struct subsys_private *class_to_subsys(const struct class *class);
+
 struct driver_private {
 	struct kobject kobj;
 	struct klist klist_devices;
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 1f12bd5d56d9..68a6f9b56d19 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -39,7 +39,7 @@ static struct kset *class_kset;
  * NULL.  A call to subsys_put() must be done when finished with the pointer in
  * order for it to be properly freed.
  */
-static struct subsys_private *class_to_subsys(const struct class *class)
+struct subsys_private *class_to_subsys(const struct class *class)
 {
 	struct subsys_private *sp = NULL;
 	struct kobject *kobj;
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 89249be22161..e3bc34fcf779 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -3149,8 +3149,8 @@ static const struct kobj_type class_dir_ktype = {
 	.child_ns_type	= class_dir_child_ns_type
 };
 
-static struct kobject *
-class_dir_create_and_add(const struct class *class, struct kobject *parent_kobj)
+static struct kobject *class_dir_create_and_add(struct subsys_private *sp,
+						struct kobject *parent_kobj)
 {
 	struct class_dir *dir;
 	int retval;
@@ -3159,12 +3159,12 @@ class_dir_create_and_add(const struct class *class, struct kobject *parent_kobj)
 	if (!dir)
 		return ERR_PTR(-ENOMEM);
 
-	dir->class = class;
+	dir->class = sp->class;
 	kobject_init(&dir->kobj, &class_dir_ktype);
 
-	dir->kobj.kset = &class->p->glue_dirs;
+	dir->kobj.kset = &sp->glue_dirs;
 
-	retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name);
+	retval = kobject_add(&dir->kobj, parent_kobj, "%s", sp->class->name);
 	if (retval < 0) {
 		kobject_put(&dir->kobj);
 		return ERR_PTR(retval);
@@ -3177,9 +3177,10 @@ static DEFINE_MUTEX(gdp_mutex);
 static struct kobject *get_device_parent(struct device *dev,
 					 struct device *parent)
 {
+	struct subsys_private *sp = class_to_subsys(dev->class);
 	struct kobject *kobj = NULL;
 
-	if (dev->class) {
+	if (sp) {
 		struct kobject *parent_kobj;
 		struct kobject *k;
 
@@ -3190,30 +3191,34 @@ static struct kobject *get_device_parent(struct device *dev,
 		 */
 		if (parent == NULL)
 			parent_kobj = virtual_device_parent(dev);
-		else if (parent->class && !dev->class->ns_type)
+		else if (parent->class && !dev->class->ns_type) {
+			subsys_put(sp);
 			return &parent->kobj;
-		else
+		} else {
 			parent_kobj = &parent->kobj;
+		}
 
 		mutex_lock(&gdp_mutex);
 
 		/* find our class-directory at the parent and reference it */
-		spin_lock(&dev->class->p->glue_dirs.list_lock);
-		list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry)
+		spin_lock(&sp->glue_dirs.list_lock);
+		list_for_each_entry(k, &sp->glue_dirs.list, entry)
 			if (k->parent == parent_kobj) {
 				kobj = kobject_get(k);
 				break;
 			}
-		spin_unlock(&dev->class->p->glue_dirs.list_lock);
+		spin_unlock(&sp->glue_dirs.list_lock);
 		if (kobj) {
 			mutex_unlock(&gdp_mutex);
+			subsys_put(sp);
 			return kobj;
 		}
 
 		/* or create a new class-directory at the parent device */
-		k = class_dir_create_and_add(dev->class, parent_kobj);
+		k = class_dir_create_and_add(sp, parent_kobj);
 		/* do not emit an uevent for this simple "glue" directory */
 		mutex_unlock(&gdp_mutex);
+		subsys_put(sp);
 		return k;
 	}
 
@@ -3236,10 +3241,23 @@ static struct kobject *get_device_parent(struct device *dev,
 static inline bool live_in_glue_dir(struct kobject *kobj,
 				    struct device *dev)
 {
-	if (!kobj || !dev->class ||
-	    kobj->kset != &dev->class->p->glue_dirs)
+	struct subsys_private *sp;
+	bool retval;
+
+	if (!kobj || !dev->class)
 		return false;
-	return true;
+
+	sp = class_to_subsys(dev->class);
+	if (!sp)
+		return false;
+
+	if (kobj->kset == &sp->glue_dirs)
+		retval = true;
+	else
+		retval = false;
+
+	subsys_put(sp);
+	return retval;
 }
 
 static inline struct kobject *get_glue_dir(struct device *dev)
@@ -3336,6 +3354,7 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
 static int device_add_class_symlinks(struct device *dev)
 {
 	struct device_node *of_node = dev_of_node(dev);
+	struct subsys_private *sp;
 	int error;
 
 	if (of_node) {
@@ -3345,12 +3364,11 @@ static int device_add_class_symlinks(struct device *dev)
 		/* An error here doesn't warrant bringing down the device */
 	}
 
-	if (!dev->class)
+	sp = class_to_subsys(dev->class);
+	if (!sp)
 		return 0;
 
-	error = sysfs_create_link(&dev->kobj,
-				  &dev->class->p->subsys.kobj,
-				  "subsystem");
+	error = sysfs_create_link(&dev->kobj, &sp->subsys.kobj, "subsystem");
 	if (error)
 		goto out_devnode;
 
@@ -3362,35 +3380,37 @@ static int device_add_class_symlinks(struct device *dev)
 	}
 
 	/* link in the class directory pointing to the device */
-	error = sysfs_create_link(&dev->class->p->subsys.kobj,
-				  &dev->kobj, dev_name(dev));
+	error = sysfs_create_link(&sp->subsys.kobj, &dev->kobj, dev_name(dev));
 	if (error)
 		goto out_device;
-
-	return 0;
+	goto exit;
 
 out_device:
 	sysfs_remove_link(&dev->kobj, "device");
-
 out_subsys:
 	sysfs_remove_link(&dev->kobj, "subsystem");
 out_devnode:
 	sysfs_remove_link(&dev->kobj, "of_node");
+exit:
+	subsys_put(sp);
 	return error;
 }
 
 static void device_remove_class_symlinks(struct device *dev)
 {
+	struct subsys_private *sp = class_to_subsys(dev->class);
+
 	if (dev_of_node(dev))
 		sysfs_remove_link(&dev->kobj, "of_node");
 
-	if (!dev->class)
+	if (!sp)
 		return;
 
 	if (dev->parent && device_is_not_partition(dev))
 		sysfs_remove_link(&dev->kobj, "device");
 	sysfs_remove_link(&dev->kobj, "subsystem");
-	sysfs_delete_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev));
+	sysfs_delete_link(&sp->subsys.kobj, &dev->kobj, dev_name(dev));
+	subsys_put(sp);
 }
 
 /**
@@ -3499,6 +3519,7 @@ static int device_private_init(struct device *dev)
  */
 int device_add(struct device *dev)
 {
+	struct subsys_private *sp;
 	struct device *parent;
 	struct kobject *kobj;
 	struct class_interface *class_intf;
@@ -3627,18 +3648,18 @@ int device_add(struct device *dev)
 		klist_add_tail(&dev->p->knode_parent,
 			       &parent->p->klist_children);
 
-	if (dev->class) {
-		mutex_lock(&dev->class->p->mutex);
+	sp = class_to_subsys(dev->class);
+	if (sp) {
+		mutex_lock(&sp->mutex);
 		/* tie the class to the device */
-		klist_add_tail(&dev->p->knode_class,
-			       &dev->class->p->klist_devices);
+		klist_add_tail(&dev->p->knode_class, &sp->klist_devices);
 
 		/* notify any interfaces that the device is here */
-		list_for_each_entry(class_intf,
-				    &dev->class->p->interfaces, node)
+		list_for_each_entry(class_intf, &sp->interfaces, node)
 			if (class_intf->add_dev)
 				class_intf->add_dev(dev, class_intf);
-		mutex_unlock(&dev->class->p->mutex);
+		mutex_unlock(&sp->mutex);
+		subsys_put(sp);
 	}
 done:
 	put_device(dev);
@@ -3758,6 +3779,7 @@ EXPORT_SYMBOL_GPL(kill_device);
  */
 void device_del(struct device *dev)
 {
+	struct subsys_private *sp;
 	struct device *parent = dev->parent;
 	struct kobject *glue_dir = NULL;
 	struct class_interface *class_intf;
@@ -3784,18 +3806,20 @@ void device_del(struct device *dev)
 		device_remove_sys_dev_entry(dev);
 		device_remove_file(dev, &dev_attr_dev);
 	}
-	if (dev->class) {
+
+	sp = class_to_subsys(dev->class);
+	if (sp) {
 		device_remove_class_symlinks(dev);
 
-		mutex_lock(&dev->class->p->mutex);
+		mutex_lock(&sp->mutex);
 		/* notify any interfaces that the device is now gone */
-		list_for_each_entry(class_intf,
-				    &dev->class->p->interfaces, node)
+		list_for_each_entry(class_intf, &sp->interfaces, node)
 			if (class_intf->remove_dev)
 				class_intf->remove_dev(dev, class_intf);
 		/* remove the device from the class list */
 		klist_del(&dev->p->knode_class);
-		mutex_unlock(&dev->class->p->mutex);
+		mutex_unlock(&sp->mutex);
+		subsys_put(sp);
 	}
 	device_remove_file(dev, &dev_attr_uevent);
 	device_remove_attrs(dev);
@@ -4458,9 +4482,16 @@ int device_rename(struct device *dev, const char *new_name)
 	}
 
 	if (dev->class) {
-		error = sysfs_rename_link_ns(&dev->class->p->subsys.kobj,
-					     kobj, old_device_name,
+		struct subsys_private *sp = class_to_subsys(dev->class);
+
+		if (!sp) {
+			error = -EINVAL;
+			goto out;
+		}
+
+		error = sysfs_rename_link_ns(&sp->subsys.kobj, kobj, old_device_name,
 					     new_name, kobject_namespace(kobj));
+		subsys_put(sp);
 		if (error)
 			goto out;
 	}
@@ -4643,6 +4674,7 @@ int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid)
 {
 	int error;
 	struct kobject *kobj = &dev->kobj;
+	struct subsys_private *sp;
 
 	dev = get_device(dev);
 	if (!dev)
@@ -4685,10 +4717,13 @@ int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid)
 	 * directory entry for @dev to @kuid/@kgid. This ensures that the
 	 * symlink shows the same permissions as its target.
 	 */
-	error = sysfs_link_change_owner(&dev->class->p->subsys.kobj, &dev->kobj,
-					dev_name(dev), kuid, kgid);
-	if (error)
+	sp = class_to_subsys(dev->class);
+	if (!sp) {
+		error = -EINVAL;
 		goto out;
+	}
+	error = sysfs_link_change_owner(&sp->subsys.kobj, &dev->kobj, dev_name(dev), kuid, kgid);
+	subsys_put(sp);
 
 out:
 	put_device(dev);
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/7] driver core: create class_is_registered()
  2023-03-31  9:33 [PATCH 1/7] driver core: core: move to use class_to_subsys() Greg Kroah-Hartman
@ 2023-03-31  9:33 ` Greg Kroah-Hartman
  2023-03-31 10:16   ` Rafael J. Wysocki
  2023-03-31 12:44   ` Linus Walleij
  2023-03-31  9:33 ` [PATCH 3/7] driver core: class: remove subsystem private pointer from struct class Greg Kroah-Hartman
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 16+ messages in thread
From: Greg Kroah-Hartman @ 2023-03-31  9:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: Greg Kroah-Hartman, Linus Walleij, Bartosz Golaszewski,
	Sebastian Reichel, Benjamin Tissoires, linux-gpio,
	Rafael J. Wysocki

Some classes (i.e. gpio), want to know if they have been registered or
not, and poke around in the class's internal structures to try to figure
this out.  Because this is not really a good idea, provide a function
for classes to call to try to figure this out.

Note, this is racy as the state of the class could change at any moment
in time after the call is made, but as usually a class only wants to
know if it has been registered yet or not, it should be fairly safe to
use, and is just as safe as the previous "poke at the class internals"
check was.

Move the gpiolib code to use this function as proof that it works
properly.

Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Bartosz Golaszewski <brgl@bgdev.pl>
Cc: Sebastian Reichel <sre@kernel.org>
Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Cc: linux-gpio@vger.kernel.org
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/class.c         | 25 +++++++++++++++++++++++++
 drivers/gpio/gpiolib-sysfs.c |  4 ++--
 include/linux/device/class.h |  1 +
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/base/class.c b/drivers/base/class.c
index 68a6f9b56d19..a8a1bf976290 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -634,6 +634,31 @@ void class_compat_remove_link(struct class_compat *cls, struct device *dev,
 }
 EXPORT_SYMBOL_GPL(class_compat_remove_link);
 
+/**
+ * class_is_registered - determine if at this moment in time, a class is
+ *			 registered in the driver core or not.
+ * @class: the class to check
+ *
+ * Returns a boolean to state if the class is registered in the driver core
+ * or not.  Note that the value could switch right after this call is made,
+ * so only use this in places where you "know" it is safe to do so (usually
+ * to determine if the specific class has been registered yet or not).
+ *
+ * Be careful in using this.
+ */
+bool class_is_registered(const struct class *class)
+{
+	struct subsys_private *sp = class_to_subsys(class);
+	bool is_initialized = false;
+
+	if (sp) {
+		is_initialized = true;
+		subsys_put(sp);
+	}
+	return is_initialized;
+}
+EXPORT_SYMBOL_GPL(class_is_registered);
+
 int __init classes_init(void)
 {
 	class_kset = kset_create_and_add("class", NULL, NULL);
diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index a895915affa5..1a9b21731cc9 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -554,7 +554,7 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
 	int			offset;
 
 	/* can't export until sysfs is available ... */
-	if (!gpio_class.p) {
+	if (!class_is_registered(&gpio_class)) {
 		pr_debug("%s: called too early!\n", __func__);
 		return -ENOENT;
 	}
@@ -728,7 +728,7 @@ int gpiochip_sysfs_register(struct gpio_device *gdev)
 	 * register later, in gpiolib_sysfs_init() ... here we just
 	 * verify that _some_ field of gpio_class got initialized.
 	 */
-	if (!gpio_class.p)
+	if (!class_is_registered(&gpio_class))
 		return 0;
 
 	/*
diff --git a/include/linux/device/class.h b/include/linux/device/class.h
index b53728ca56fb..9cb5db0588c8 100644
--- a/include/linux/device/class.h
+++ b/include/linux/device/class.h
@@ -84,6 +84,7 @@ extern struct kobject *sysfs_dev_block_kobj;
 
 int __must_check class_register(struct class *class);
 void class_unregister(const struct class *class);
+bool class_is_registered(const struct class *class);
 
 struct class_compat;
 struct class_compat *class_compat_register(const char *name);
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/7] driver core: class: remove subsystem private pointer from struct class
  2023-03-31  9:33 [PATCH 1/7] driver core: core: move to use class_to_subsys() Greg Kroah-Hartman
  2023-03-31  9:33 ` [PATCH 2/7] driver core: create class_is_registered() Greg Kroah-Hartman
@ 2023-03-31  9:33 ` Greg Kroah-Hartman
  2023-03-31 14:48   ` Rafael J. Wysocki
  2023-03-31  9:33 ` [PATCH 4/7] driver core: clean up the logic to determine which /sys/dev/ directory to use Greg Kroah-Hartman
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Greg Kroah-Hartman @ 2023-03-31  9:33 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

Now that the last users of the subsystem private pointer in struct class
are gone, the pointer can be removed, as no one is using it.  One step
closer to allowing struct class to be const and moved into read-only
memory.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/class.c         | 4 ----
 include/linux/device/class.h | 2 --
 2 files changed, 6 deletions(-)

diff --git a/drivers/base/class.c b/drivers/base/class.c
index a8a1bf976290..fcfb295363cc 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -97,8 +97,6 @@ static void class_release(struct kobject *kobj)
 
 	pr_debug("class '%s': release.\n", class->name);
 
-	class->p = NULL;
-
 	if (class->class_release)
 		class->class_release(class);
 	else
@@ -206,7 +204,6 @@ int class_register(struct class *cls)
 	cp->subsys.kobj.kset = class_kset;
 	cp->subsys.kobj.ktype = &class_ktype;
 	cp->class = cls;
-	cls->p = cp;
 
 	error = kset_register(&cp->subsys);
 	if (error)
@@ -222,7 +219,6 @@ int class_register(struct class *cls)
 
 err_out:
 	kfree(cp);
-	cls->p = NULL;
 	return error;
 }
 EXPORT_SYMBOL_GPL(class_register);
diff --git a/include/linux/device/class.h b/include/linux/device/class.h
index 9cb5db0588c8..f7aad64e256a 100644
--- a/include/linux/device/class.h
+++ b/include/linux/device/class.h
@@ -71,8 +71,6 @@ struct class {
 	void (*get_ownership)(const struct device *dev, kuid_t *uid, kgid_t *gid);
 
 	const struct dev_pm_ops *pm;
-
-	struct subsys_private *p;
 };
 
 struct class_dev_iter {
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/7] driver core: clean up the logic to determine which /sys/dev/ directory to use
  2023-03-31  9:33 [PATCH 1/7] driver core: core: move to use class_to_subsys() Greg Kroah-Hartman
  2023-03-31  9:33 ` [PATCH 2/7] driver core: create class_is_registered() Greg Kroah-Hartman
  2023-03-31  9:33 ` [PATCH 3/7] driver core: class: remove subsystem private pointer from struct class Greg Kroah-Hartman
@ 2023-03-31  9:33 ` Greg Kroah-Hartman
  2023-03-31 14:49   ` Rafael J. Wysocki
  2023-03-31  9:33 ` [PATCH 5/7] driver core: class: remove dev_kobj from struct class Greg Kroah-Hartman
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Greg Kroah-Hartman @ 2023-03-31  9:33 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

When a dev_t is set in a struct device, an symlink in /sys/dev/ is
created for it either under /sys/dev/block/ or /sys/dev/char/ depending
on the device type.

The logic to determine this would trigger off of the class of the
object, and the kobj_type set in that location.  But it turns out that
this deep nesting isn't needed at all, as it's either a choice of block
or "everything else" which is a char device.  So make the logic a lot
more simple and obvious, and remove the incorrect comments in the code
that tried to document something that was not happening at all (it is
impossible to set class->dev_kobj to NULL as the class core prevented
that from happening.

This removes the only place that class->dev_kobj was being used, so
after this, it can be removed entirely.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/base.h     | 10 ++++++++++
 drivers/base/core.c     | 22 ++++------------------
 drivers/base/devtmpfs.c |  9 ---------
 3 files changed, 14 insertions(+), 27 deletions(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index 6296164bb7f3..4660e1159ee0 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -209,6 +209,16 @@ int devtmpfs_init(void);
 static inline int devtmpfs_init(void) { return 0; }
 #endif
 
+#ifdef CONFIG_BLOCK
+extern struct class block_class;
+static inline bool is_blockdev(struct device *dev)
+{
+	return dev->class == &block_class;
+}
+#else
+static inline bool is_blockdev(struct device *dev) { return false; }
+#endif
+
 /* Device links support */
 int device_links_read_lock(void);
 void device_links_read_unlock(int idx);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index e3bc34fcf779..dbc2ba6dfffc 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -3430,27 +3430,13 @@ int dev_set_name(struct device *dev, const char *fmt, ...)
 }
 EXPORT_SYMBOL_GPL(dev_set_name);
 
-/**
- * device_to_dev_kobj - select a /sys/dev/ directory for the device
- * @dev: device
- *
- * By default we select char/ for new entries.  Setting class->dev_obj
- * to NULL prevents an entry from being created.  class->dev_kobj must
- * be set (or cleared) before any devices are registered to the class
- * otherwise device_create_sys_dev_entry() and
- * device_remove_sys_dev_entry() will disagree about the presence of
- * the link.
- */
+/* select a /sys/dev/ directory for the device */
 static struct kobject *device_to_dev_kobj(struct device *dev)
 {
-	struct kobject *kobj;
-
-	if (dev->class)
-		kobj = dev->class->dev_kobj;
+	if (is_blockdev(dev))
+		return sysfs_dev_block_kobj;
 	else
-		kobj = sysfs_dev_char_kobj;
-
-	return kobj;
+		return sysfs_dev_char_kobj;
 }
 
 static int device_create_sys_dev_entry(struct device *dev)
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index ae72d4ba8547..b848764ef018 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -94,15 +94,6 @@ static struct file_system_type dev_fs_type = {
 	.mount = public_dev_mount,
 };
 
-#ifdef CONFIG_BLOCK
-static inline int is_blockdev(struct device *dev)
-{
-	return dev->class == &block_class;
-}
-#else
-static inline int is_blockdev(struct device *dev) { return 0; }
-#endif
-
 static int devtmpfs_submit_req(struct req *req, const char *tmp)
 {
 	init_completion(&req->done);
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 5/7] driver core: class: remove dev_kobj from struct class
  2023-03-31  9:33 [PATCH 1/7] driver core: core: move to use class_to_subsys() Greg Kroah-Hartman
                   ` (2 preceding siblings ...)
  2023-03-31  9:33 ` [PATCH 4/7] driver core: clean up the logic to determine which /sys/dev/ directory to use Greg Kroah-Hartman
@ 2023-03-31  9:33 ` Greg Kroah-Hartman
  2023-03-31 14:50   ` Rafael J. Wysocki
  2023-03-31  9:33 ` [PATCH 6/7] driver core: make sysfs_dev_block_kobj static Greg Kroah-Hartman
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Greg Kroah-Hartman @ 2023-03-31  9:33 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

The dev_kobj field in struct class is now only written to, but never
read from, so it can be removed as it is useless.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 block/genhd.c                | 1 -
 drivers/base/class.c         | 4 ----
 include/linux/device/class.h | 2 --
 3 files changed, 7 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index e1e1230b1b9f..af7208a37c53 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -899,7 +899,6 @@ static int __init genhd_device_init(void)
 {
 	int error;
 
-	block_class.dev_kobj = sysfs_dev_block_kobj;
 	error = class_register(&block_class);
 	if (unlikely(error))
 		return error;
diff --git a/drivers/base/class.c b/drivers/base/class.c
index fcfb295363cc..06b96d6faa19 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -197,10 +197,6 @@ int class_register(struct class *cls)
 		return error;
 	}
 
-	/* set the default /sys/dev directory for devices of this class */
-	if (!cls->dev_kobj)
-		cls->dev_kobj = sysfs_dev_char_kobj;
-
 	cp->subsys.kobj.kset = class_kset;
 	cp->subsys.kobj.ktype = &class_ktype;
 	cp->class = cls;
diff --git a/include/linux/device/class.h b/include/linux/device/class.h
index f7aad64e256a..e946642c314e 100644
--- a/include/linux/device/class.h
+++ b/include/linux/device/class.h
@@ -27,7 +27,6 @@ struct fwnode_handle;
  * @name:	Name of the class.
  * @class_groups: Default attributes of this class.
  * @dev_groups:	Default attributes of the devices that belong to the class.
- * @dev_kobj:	The kobject that represents this class and links it into the hierarchy.
  * @dev_uevent:	Called when a device is added, removed from this class, or a
  *		few other things that generate uevents to add the environment
  *		variables.
@@ -55,7 +54,6 @@ struct class {
 
 	const struct attribute_group	**class_groups;
 	const struct attribute_group	**dev_groups;
-	struct kobject			*dev_kobj;
 
 	int (*dev_uevent)(const struct device *dev, struct kobj_uevent_env *env);
 	char *(*devnode)(const struct device *dev, umode_t *mode);
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 6/7] driver core: make sysfs_dev_block_kobj static
  2023-03-31  9:33 [PATCH 1/7] driver core: core: move to use class_to_subsys() Greg Kroah-Hartman
                   ` (3 preceding siblings ...)
  2023-03-31  9:33 ` [PATCH 5/7] driver core: class: remove dev_kobj from struct class Greg Kroah-Hartman
@ 2023-03-31  9:33 ` Greg Kroah-Hartman
  2023-03-31 14:50   ` Rafael J. Wysocki
  2023-03-31  9:33 ` [PATCH 7/7] driver core: make sysfs_dev_char_kobj static Greg Kroah-Hartman
  2023-03-31 10:26 ` [PATCH 1/7] driver core: core: move to use class_to_subsys() Rafael J. Wysocki
  6 siblings, 1 reply; 16+ messages in thread
From: Greg Kroah-Hartman @ 2023-03-31  9:33 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

Nothing outside of drivers/base/core.c uses sysfs_dev_block_kobj, so
make it static and document what it is used for so we remember it the
next time we touch it 15 years from now.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/core.c          | 4 +++-
 include/linux/device/class.h | 2 --
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index dbc2ba6dfffc..cf6f41c2060c 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -2256,7 +2256,9 @@ int (*platform_notify)(struct device *dev) = NULL;
 int (*platform_notify_remove)(struct device *dev) = NULL;
 static struct kobject *dev_kobj;
 struct kobject *sysfs_dev_char_kobj;
-struct kobject *sysfs_dev_block_kobj;
+
+/* /sys/dev/block */
+static struct kobject *sysfs_dev_block_kobj;
 
 static DEFINE_MUTEX(device_hotplug_lock);
 
diff --git a/include/linux/device/class.h b/include/linux/device/class.h
index e946642c314e..7e4a1a6329f4 100644
--- a/include/linux/device/class.h
+++ b/include/linux/device/class.h
@@ -76,8 +76,6 @@ struct class_dev_iter {
 	const struct device_type	*type;
 };
 
-extern struct kobject *sysfs_dev_block_kobj;
-
 int __must_check class_register(struct class *class);
 void class_unregister(const struct class *class);
 bool class_is_registered(const struct class *class);
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 7/7] driver core: make sysfs_dev_char_kobj static
  2023-03-31  9:33 [PATCH 1/7] driver core: core: move to use class_to_subsys() Greg Kroah-Hartman
                   ` (4 preceding siblings ...)
  2023-03-31  9:33 ` [PATCH 6/7] driver core: make sysfs_dev_block_kobj static Greg Kroah-Hartman
@ 2023-03-31  9:33 ` Greg Kroah-Hartman
  2023-03-31 14:50   ` Rafael J. Wysocki
  2023-03-31 10:26 ` [PATCH 1/7] driver core: core: move to use class_to_subsys() Rafael J. Wysocki
  6 siblings, 1 reply; 16+ messages in thread
From: Greg Kroah-Hartman @ 2023-03-31  9:33 UTC (permalink / raw)
  To: linux-kernel; +Cc: Greg Kroah-Hartman, Rafael J. Wysocki

Nothing outside of drivers/base/core.c uses sysfs_dev_char_kobj, so
make it static and document what it is used for so we remember it the
next time we touch it 15 years from now.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/base/base.h | 3 ---
 drivers/base/core.c | 4 +++-
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index 4660e1159ee0..e96f3343fd7c 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -191,9 +191,6 @@ const char *device_get_devnode(const struct device *dev, umode_t *mode,
 extern struct kset *devices_kset;
 void devices_kset_move_last(struct device *dev);
 
-/* /sys/dev/char directory */
-extern struct kobject *sysfs_dev_char_kobj;
-
 #if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
 void module_add_driver(struct module *mod, struct device_driver *drv);
 void module_remove_driver(struct device_driver *drv);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index cf6f41c2060c..47e16c088e77 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -2255,7 +2255,9 @@ static void fw_devlink_link_device(struct device *dev)
 int (*platform_notify)(struct device *dev) = NULL;
 int (*platform_notify_remove)(struct device *dev) = NULL;
 static struct kobject *dev_kobj;
-struct kobject *sysfs_dev_char_kobj;
+
+/* /sys/dev/char */
+static struct kobject *sysfs_dev_char_kobj;
 
 /* /sys/dev/block */
 static struct kobject *sysfs_dev_block_kobj;
-- 
2.40.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/7] driver core: create class_is_registered()
  2023-03-31  9:33 ` [PATCH 2/7] driver core: create class_is_registered() Greg Kroah-Hartman
@ 2023-03-31 10:16   ` Rafael J. Wysocki
  2023-03-31 12:44   ` Linus Walleij
  1 sibling, 0 replies; 16+ messages in thread
From: Rafael J. Wysocki @ 2023-03-31 10:16 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, Linus Walleij, Bartosz Golaszewski,
	Sebastian Reichel, Benjamin Tissoires, linux-gpio,
	Rafael J. Wysocki

On Fri, Mar 31, 2023 at 11:33 AM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> Some classes (i.e. gpio), want to know if they have been registered or
> not, and poke around in the class's internal structures to try to figure
> this out.  Because this is not really a good idea, provide a function
> for classes to call to try to figure this out.
>
> Note, this is racy as the state of the class could change at any moment
> in time after the call is made, but as usually a class only wants to
> know if it has been registered yet or not, it should be fairly safe to
> use, and is just as safe as the previous "poke at the class internals"
> check was.
>
> Move the gpiolib code to use this function as proof that it works
> properly.
>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: Bartosz Golaszewski <brgl@bgdev.pl>
> Cc: Sebastian Reichel <sre@kernel.org>
> Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> Cc: linux-gpio@vger.kernel.org
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Reviewed-by: Rafael J. Wysocki <rafael@kernel.org>

> ---
>  drivers/base/class.c         | 25 +++++++++++++++++++++++++
>  drivers/gpio/gpiolib-sysfs.c |  4 ++--
>  include/linux/device/class.h |  1 +
>  3 files changed, 28 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/base/class.c b/drivers/base/class.c
> index 68a6f9b56d19..a8a1bf976290 100644
> --- a/drivers/base/class.c
> +++ b/drivers/base/class.c
> @@ -634,6 +634,31 @@ void class_compat_remove_link(struct class_compat *cls, struct device *dev,
>  }
>  EXPORT_SYMBOL_GPL(class_compat_remove_link);
>
> +/**
> + * class_is_registered - determine if at this moment in time, a class is
> + *                      registered in the driver core or not.
> + * @class: the class to check
> + *
> + * Returns a boolean to state if the class is registered in the driver core
> + * or not.  Note that the value could switch right after this call is made,
> + * so only use this in places where you "know" it is safe to do so (usually
> + * to determine if the specific class has been registered yet or not).
> + *
> + * Be careful in using this.
> + */
> +bool class_is_registered(const struct class *class)
> +{
> +       struct subsys_private *sp = class_to_subsys(class);
> +       bool is_initialized = false;
> +
> +       if (sp) {
> +               is_initialized = true;
> +               subsys_put(sp);
> +       }
> +       return is_initialized;
> +}
> +EXPORT_SYMBOL_GPL(class_is_registered);
> +
>  int __init classes_init(void)
>  {
>         class_kset = kset_create_and_add("class", NULL, NULL);
> diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
> index a895915affa5..1a9b21731cc9 100644
> --- a/drivers/gpio/gpiolib-sysfs.c
> +++ b/drivers/gpio/gpiolib-sysfs.c
> @@ -554,7 +554,7 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
>         int                     offset;
>
>         /* can't export until sysfs is available ... */
> -       if (!gpio_class.p) {
> +       if (!class_is_registered(&gpio_class)) {
>                 pr_debug("%s: called too early!\n", __func__);
>                 return -ENOENT;
>         }
> @@ -728,7 +728,7 @@ int gpiochip_sysfs_register(struct gpio_device *gdev)
>          * register later, in gpiolib_sysfs_init() ... here we just
>          * verify that _some_ field of gpio_class got initialized.
>          */
> -       if (!gpio_class.p)
> +       if (!class_is_registered(&gpio_class))
>                 return 0;
>
>         /*
> diff --git a/include/linux/device/class.h b/include/linux/device/class.h
> index b53728ca56fb..9cb5db0588c8 100644
> --- a/include/linux/device/class.h
> +++ b/include/linux/device/class.h
> @@ -84,6 +84,7 @@ extern struct kobject *sysfs_dev_block_kobj;
>
>  int __must_check class_register(struct class *class);
>  void class_unregister(const struct class *class);
> +bool class_is_registered(const struct class *class);
>
>  struct class_compat;
>  struct class_compat *class_compat_register(const char *name);
> --
> 2.40.0
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/7] driver core: core: move to use class_to_subsys()
  2023-03-31  9:33 [PATCH 1/7] driver core: core: move to use class_to_subsys() Greg Kroah-Hartman
                   ` (5 preceding siblings ...)
  2023-03-31  9:33 ` [PATCH 7/7] driver core: make sysfs_dev_char_kobj static Greg Kroah-Hartman
@ 2023-03-31 10:26 ` Rafael J. Wysocki
  2023-03-31 15:44   ` Greg Kroah-Hartman
  6 siblings, 1 reply; 16+ messages in thread
From: Rafael J. Wysocki @ 2023-03-31 10:26 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: linux-kernel, Rafael J. Wysocki

On Fri, Mar 31, 2023 at 11:33 AM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> There are a number of places in core.c that need access to the private
> subsystem structure of struct class, so move them to use
> class_to_subsys() instead of accessing it directly.
>
> This requires exporting class_to_subsys() out of class.c, but keeping it
> local to the driver core.
>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Reviewed-by: Rafael J. Wysocki <rafael@kernel.org>

> ---
>  drivers/base/base.h  |   2 +
>  drivers/base/class.c |   2 +-
>  drivers/base/core.c  | 121 ++++++++++++++++++++++++++++---------------
>  3 files changed, 81 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/base/base.h b/drivers/base/base.h
> index 2867ca4ee4ce..6296164bb7f3 100644
> --- a/drivers/base/base.h
> +++ b/drivers/base/base.h
> @@ -73,6 +73,8 @@ static inline void subsys_put(struct subsys_private *sp)
>                 kset_put(&sp->subsys);
>  }
>
> +struct subsys_private *class_to_subsys(const struct class *class);
> +
>  struct driver_private {
>         struct kobject kobj;
>         struct klist klist_devices;
> diff --git a/drivers/base/class.c b/drivers/base/class.c
> index 1f12bd5d56d9..68a6f9b56d19 100644
> --- a/drivers/base/class.c
> +++ b/drivers/base/class.c
> @@ -39,7 +39,7 @@ static struct kset *class_kset;
>   * NULL.  A call to subsys_put() must be done when finished with the pointer in
>   * order for it to be properly freed.
>   */
> -static struct subsys_private *class_to_subsys(const struct class *class)
> +struct subsys_private *class_to_subsys(const struct class *class)
>  {
>         struct subsys_private *sp = NULL;
>         struct kobject *kobj;
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index 89249be22161..e3bc34fcf779 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
> @@ -3149,8 +3149,8 @@ static const struct kobj_type class_dir_ktype = {
>         .child_ns_type  = class_dir_child_ns_type
>  };
>
> -static struct kobject *
> -class_dir_create_and_add(const struct class *class, struct kobject *parent_kobj)
> +static struct kobject *class_dir_create_and_add(struct subsys_private *sp,
> +                                               struct kobject *parent_kobj)
>  {
>         struct class_dir *dir;
>         int retval;
> @@ -3159,12 +3159,12 @@ class_dir_create_and_add(const struct class *class, struct kobject *parent_kobj)
>         if (!dir)
>                 return ERR_PTR(-ENOMEM);
>
> -       dir->class = class;
> +       dir->class = sp->class;
>         kobject_init(&dir->kobj, &class_dir_ktype);
>
> -       dir->kobj.kset = &class->p->glue_dirs;
> +       dir->kobj.kset = &sp->glue_dirs;
>
> -       retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name);
> +       retval = kobject_add(&dir->kobj, parent_kobj, "%s", sp->class->name);
>         if (retval < 0) {
>                 kobject_put(&dir->kobj);
>                 return ERR_PTR(retval);
> @@ -3177,9 +3177,10 @@ static DEFINE_MUTEX(gdp_mutex);
>  static struct kobject *get_device_parent(struct device *dev,
>                                          struct device *parent)
>  {
> +       struct subsys_private *sp = class_to_subsys(dev->class);
>         struct kobject *kobj = NULL;
>
> -       if (dev->class) {
> +       if (sp) {
>                 struct kobject *parent_kobj;
>                 struct kobject *k;
>
> @@ -3190,30 +3191,34 @@ static struct kobject *get_device_parent(struct device *dev,
>                  */
>                 if (parent == NULL)
>                         parent_kobj = virtual_device_parent(dev);
> -               else if (parent->class && !dev->class->ns_type)
> +               else if (parent->class && !dev->class->ns_type) {
> +                       subsys_put(sp);
>                         return &parent->kobj;
> -               else
> +               } else {
>                         parent_kobj = &parent->kobj;
> +               }
>
>                 mutex_lock(&gdp_mutex);
>
>                 /* find our class-directory at the parent and reference it */
> -               spin_lock(&dev->class->p->glue_dirs.list_lock);
> -               list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry)
> +               spin_lock(&sp->glue_dirs.list_lock);
> +               list_for_each_entry(k, &sp->glue_dirs.list, entry)
>                         if (k->parent == parent_kobj) {
>                                 kobj = kobject_get(k);
>                                 break;
>                         }
> -               spin_unlock(&dev->class->p->glue_dirs.list_lock);
> +               spin_unlock(&sp->glue_dirs.list_lock);
>                 if (kobj) {
>                         mutex_unlock(&gdp_mutex);
> +                       subsys_put(sp);
>                         return kobj;
>                 }
>
>                 /* or create a new class-directory at the parent device */
> -               k = class_dir_create_and_add(dev->class, parent_kobj);
> +               k = class_dir_create_and_add(sp, parent_kobj);
>                 /* do not emit an uevent for this simple "glue" directory */
>                 mutex_unlock(&gdp_mutex);
> +               subsys_put(sp);
>                 return k;
>         }
>
> @@ -3236,10 +3241,23 @@ static struct kobject *get_device_parent(struct device *dev,
>  static inline bool live_in_glue_dir(struct kobject *kobj,
>                                     struct device *dev)
>  {
> -       if (!kobj || !dev->class ||
> -           kobj->kset != &dev->class->p->glue_dirs)
> +       struct subsys_private *sp;
> +       bool retval;
> +
> +       if (!kobj || !dev->class)
>                 return false;
> -       return true;
> +
> +       sp = class_to_subsys(dev->class);
> +       if (!sp)
> +               return false;
> +
> +       if (kobj->kset == &sp->glue_dirs)
> +               retval = true;
> +       else
> +               retval = false;
> +
> +       subsys_put(sp);
> +       return retval;
>  }
>
>  static inline struct kobject *get_glue_dir(struct device *dev)
> @@ -3336,6 +3354,7 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
>  static int device_add_class_symlinks(struct device *dev)
>  {
>         struct device_node *of_node = dev_of_node(dev);
> +       struct subsys_private *sp;
>         int error;
>
>         if (of_node) {
> @@ -3345,12 +3364,11 @@ static int device_add_class_symlinks(struct device *dev)
>                 /* An error here doesn't warrant bringing down the device */
>         }
>
> -       if (!dev->class)
> +       sp = class_to_subsys(dev->class);
> +       if (!sp)
>                 return 0;
>
> -       error = sysfs_create_link(&dev->kobj,
> -                                 &dev->class->p->subsys.kobj,
> -                                 "subsystem");
> +       error = sysfs_create_link(&dev->kobj, &sp->subsys.kobj, "subsystem");
>         if (error)
>                 goto out_devnode;
>
> @@ -3362,35 +3380,37 @@ static int device_add_class_symlinks(struct device *dev)
>         }
>
>         /* link in the class directory pointing to the device */
> -       error = sysfs_create_link(&dev->class->p->subsys.kobj,
> -                                 &dev->kobj, dev_name(dev));
> +       error = sysfs_create_link(&sp->subsys.kobj, &dev->kobj, dev_name(dev));
>         if (error)
>                 goto out_device;
> -
> -       return 0;
> +       goto exit;
>
>  out_device:
>         sysfs_remove_link(&dev->kobj, "device");
> -
>  out_subsys:
>         sysfs_remove_link(&dev->kobj, "subsystem");
>  out_devnode:
>         sysfs_remove_link(&dev->kobj, "of_node");
> +exit:
> +       subsys_put(sp);
>         return error;
>  }
>
>  static void device_remove_class_symlinks(struct device *dev)
>  {
> +       struct subsys_private *sp = class_to_subsys(dev->class);
> +
>         if (dev_of_node(dev))
>                 sysfs_remove_link(&dev->kobj, "of_node");
>
> -       if (!dev->class)
> +       if (!sp)
>                 return;
>
>         if (dev->parent && device_is_not_partition(dev))
>                 sysfs_remove_link(&dev->kobj, "device");
>         sysfs_remove_link(&dev->kobj, "subsystem");
> -       sysfs_delete_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev));
> +       sysfs_delete_link(&sp->subsys.kobj, &dev->kobj, dev_name(dev));
> +       subsys_put(sp);
>  }
>
>  /**
> @@ -3499,6 +3519,7 @@ static int device_private_init(struct device *dev)
>   */
>  int device_add(struct device *dev)
>  {
> +       struct subsys_private *sp;
>         struct device *parent;
>         struct kobject *kobj;
>         struct class_interface *class_intf;
> @@ -3627,18 +3648,18 @@ int device_add(struct device *dev)
>                 klist_add_tail(&dev->p->knode_parent,
>                                &parent->p->klist_children);
>
> -       if (dev->class) {
> -               mutex_lock(&dev->class->p->mutex);
> +       sp = class_to_subsys(dev->class);
> +       if (sp) {
> +               mutex_lock(&sp->mutex);
>                 /* tie the class to the device */
> -               klist_add_tail(&dev->p->knode_class,
> -                              &dev->class->p->klist_devices);
> +               klist_add_tail(&dev->p->knode_class, &sp->klist_devices);
>
>                 /* notify any interfaces that the device is here */
> -               list_for_each_entry(class_intf,
> -                                   &dev->class->p->interfaces, node)
> +               list_for_each_entry(class_intf, &sp->interfaces, node)
>                         if (class_intf->add_dev)
>                                 class_intf->add_dev(dev, class_intf);
> -               mutex_unlock(&dev->class->p->mutex);
> +               mutex_unlock(&sp->mutex);
> +               subsys_put(sp);
>         }
>  done:
>         put_device(dev);
> @@ -3758,6 +3779,7 @@ EXPORT_SYMBOL_GPL(kill_device);
>   */
>  void device_del(struct device *dev)
>  {
> +       struct subsys_private *sp;
>         struct device *parent = dev->parent;
>         struct kobject *glue_dir = NULL;
>         struct class_interface *class_intf;
> @@ -3784,18 +3806,20 @@ void device_del(struct device *dev)
>                 device_remove_sys_dev_entry(dev);
>                 device_remove_file(dev, &dev_attr_dev);
>         }
> -       if (dev->class) {
> +
> +       sp = class_to_subsys(dev->class);
> +       if (sp) {
>                 device_remove_class_symlinks(dev);
>
> -               mutex_lock(&dev->class->p->mutex);
> +               mutex_lock(&sp->mutex);
>                 /* notify any interfaces that the device is now gone */
> -               list_for_each_entry(class_intf,
> -                                   &dev->class->p->interfaces, node)
> +               list_for_each_entry(class_intf, &sp->interfaces, node)
>                         if (class_intf->remove_dev)
>                                 class_intf->remove_dev(dev, class_intf);
>                 /* remove the device from the class list */
>                 klist_del(&dev->p->knode_class);
> -               mutex_unlock(&dev->class->p->mutex);
> +               mutex_unlock(&sp->mutex);
> +               subsys_put(sp);
>         }
>         device_remove_file(dev, &dev_attr_uevent);
>         device_remove_attrs(dev);
> @@ -4458,9 +4482,16 @@ int device_rename(struct device *dev, const char *new_name)
>         }
>
>         if (dev->class) {
> -               error = sysfs_rename_link_ns(&dev->class->p->subsys.kobj,
> -                                            kobj, old_device_name,
> +               struct subsys_private *sp = class_to_subsys(dev->class);
> +
> +               if (!sp) {
> +                       error = -EINVAL;
> +                       goto out;
> +               }
> +
> +               error = sysfs_rename_link_ns(&sp->subsys.kobj, kobj, old_device_name,
>                                              new_name, kobject_namespace(kobj));
> +               subsys_put(sp);
>                 if (error)
>                         goto out;
>         }
> @@ -4643,6 +4674,7 @@ int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid)
>  {
>         int error;
>         struct kobject *kobj = &dev->kobj;
> +       struct subsys_private *sp;
>
>         dev = get_device(dev);
>         if (!dev)
> @@ -4685,10 +4717,13 @@ int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid)
>          * directory entry for @dev to @kuid/@kgid. This ensures that the
>          * symlink shows the same permissions as its target.
>          */
> -       error = sysfs_link_change_owner(&dev->class->p->subsys.kobj, &dev->kobj,
> -                                       dev_name(dev), kuid, kgid);
> -       if (error)
> +       sp = class_to_subsys(dev->class);
> +       if (!sp) {
> +               error = -EINVAL;
>                 goto out;
> +       }
> +       error = sysfs_link_change_owner(&sp->subsys.kobj, &dev->kobj, dev_name(dev), kuid, kgid);
> +       subsys_put(sp);
>
>  out:
>         put_device(dev);
> --
> 2.40.0
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/7] driver core: create class_is_registered()
  2023-03-31  9:33 ` [PATCH 2/7] driver core: create class_is_registered() Greg Kroah-Hartman
  2023-03-31 10:16   ` Rafael J. Wysocki
@ 2023-03-31 12:44   ` Linus Walleij
  1 sibling, 0 replies; 16+ messages in thread
From: Linus Walleij @ 2023-03-31 12:44 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, Bartosz Golaszewski, Sebastian Reichel,
	Benjamin Tissoires, linux-gpio, Rafael J. Wysocki

On Fri, Mar 31, 2023 at 11:33 AM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:

> Some classes (i.e. gpio), want to know if they have been registered or
> not, and poke around in the class's internal structures to try to figure
> this out.  Because this is not really a good idea, provide a function
> for classes to call to try to figure this out.
>
> Note, this is racy as the state of the class could change at any moment
> in time after the call is made, but as usually a class only wants to
> know if it has been registered yet or not, it should be fairly safe to
> use, and is just as safe as the previous "poke at the class internals"
> check was.
>
> Move the gpiolib code to use this function as proof that it works
> properly.
>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Cc: Bartosz Golaszewski <brgl@bgdev.pl>
> Cc: Sebastian Reichel <sre@kernel.org>
> Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> Cc: linux-gpio@vger.kernel.org
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

This looks good to me!
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 3/7] driver core: class: remove subsystem private pointer from struct class
  2023-03-31  9:33 ` [PATCH 3/7] driver core: class: remove subsystem private pointer from struct class Greg Kroah-Hartman
@ 2023-03-31 14:48   ` Rafael J. Wysocki
  0 siblings, 0 replies; 16+ messages in thread
From: Rafael J. Wysocki @ 2023-03-31 14:48 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: linux-kernel, Rafael J. Wysocki

On Fri, Mar 31, 2023 at 11:33 AM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> Now that the last users of the subsystem private pointer in struct class
> are gone, the pointer can be removed, as no one is using it.  One step
> closer to allowing struct class to be const and moved into read-only
> memory.
>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Acked-by: Rafael J. Wysocki <rafael@kernel.org>

> ---
>  drivers/base/class.c         | 4 ----
>  include/linux/device/class.h | 2 --
>  2 files changed, 6 deletions(-)
>
> diff --git a/drivers/base/class.c b/drivers/base/class.c
> index a8a1bf976290..fcfb295363cc 100644
> --- a/drivers/base/class.c
> +++ b/drivers/base/class.c
> @@ -97,8 +97,6 @@ static void class_release(struct kobject *kobj)
>
>         pr_debug("class '%s': release.\n", class->name);
>
> -       class->p = NULL;
> -
>         if (class->class_release)
>                 class->class_release(class);
>         else
> @@ -206,7 +204,6 @@ int class_register(struct class *cls)
>         cp->subsys.kobj.kset = class_kset;
>         cp->subsys.kobj.ktype = &class_ktype;
>         cp->class = cls;
> -       cls->p = cp;
>
>         error = kset_register(&cp->subsys);
>         if (error)
> @@ -222,7 +219,6 @@ int class_register(struct class *cls)
>
>  err_out:
>         kfree(cp);
> -       cls->p = NULL;
>         return error;
>  }
>  EXPORT_SYMBOL_GPL(class_register);
> diff --git a/include/linux/device/class.h b/include/linux/device/class.h
> index 9cb5db0588c8..f7aad64e256a 100644
> --- a/include/linux/device/class.h
> +++ b/include/linux/device/class.h
> @@ -71,8 +71,6 @@ struct class {
>         void (*get_ownership)(const struct device *dev, kuid_t *uid, kgid_t *gid);
>
>         const struct dev_pm_ops *pm;
> -
> -       struct subsys_private *p;
>  };
>
>  struct class_dev_iter {
> --
> 2.40.0
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 4/7] driver core: clean up the logic to determine which /sys/dev/ directory to use
  2023-03-31  9:33 ` [PATCH 4/7] driver core: clean up the logic to determine which /sys/dev/ directory to use Greg Kroah-Hartman
@ 2023-03-31 14:49   ` Rafael J. Wysocki
  0 siblings, 0 replies; 16+ messages in thread
From: Rafael J. Wysocki @ 2023-03-31 14:49 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: linux-kernel, Rafael J. Wysocki

On Fri, Mar 31, 2023 at 11:33 AM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> When a dev_t is set in a struct device, an symlink in /sys/dev/ is
> created for it either under /sys/dev/block/ or /sys/dev/char/ depending
> on the device type.
>
> The logic to determine this would trigger off of the class of the
> object, and the kobj_type set in that location.  But it turns out that
> this deep nesting isn't needed at all, as it's either a choice of block
> or "everything else" which is a char device.  So make the logic a lot
> more simple and obvious, and remove the incorrect comments in the code
> that tried to document something that was not happening at all (it is
> impossible to set class->dev_kobj to NULL as the class core prevented
> that from happening.
>
> This removes the only place that class->dev_kobj was being used, so
> after this, it can be removed entirely.
>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

I like this.

Acked-by: Rafael J. Wysocki <rafael@kernel.org>

> ---
>  drivers/base/base.h     | 10 ++++++++++
>  drivers/base/core.c     | 22 ++++------------------
>  drivers/base/devtmpfs.c |  9 ---------
>  3 files changed, 14 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/base/base.h b/drivers/base/base.h
> index 6296164bb7f3..4660e1159ee0 100644
> --- a/drivers/base/base.h
> +++ b/drivers/base/base.h
> @@ -209,6 +209,16 @@ int devtmpfs_init(void);
>  static inline int devtmpfs_init(void) { return 0; }
>  #endif
>
> +#ifdef CONFIG_BLOCK
> +extern struct class block_class;
> +static inline bool is_blockdev(struct device *dev)
> +{
> +       return dev->class == &block_class;
> +}
> +#else
> +static inline bool is_blockdev(struct device *dev) { return false; }
> +#endif
> +
>  /* Device links support */
>  int device_links_read_lock(void);
>  void device_links_read_unlock(int idx);
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index e3bc34fcf779..dbc2ba6dfffc 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
> @@ -3430,27 +3430,13 @@ int dev_set_name(struct device *dev, const char *fmt, ...)
>  }
>  EXPORT_SYMBOL_GPL(dev_set_name);
>
> -/**
> - * device_to_dev_kobj - select a /sys/dev/ directory for the device
> - * @dev: device
> - *
> - * By default we select char/ for new entries.  Setting class->dev_obj
> - * to NULL prevents an entry from being created.  class->dev_kobj must
> - * be set (or cleared) before any devices are registered to the class
> - * otherwise device_create_sys_dev_entry() and
> - * device_remove_sys_dev_entry() will disagree about the presence of
> - * the link.
> - */
> +/* select a /sys/dev/ directory for the device */
>  static struct kobject *device_to_dev_kobj(struct device *dev)
>  {
> -       struct kobject *kobj;
> -
> -       if (dev->class)
> -               kobj = dev->class->dev_kobj;
> +       if (is_blockdev(dev))
> +               return sysfs_dev_block_kobj;
>         else
> -               kobj = sysfs_dev_char_kobj;
> -
> -       return kobj;
> +               return sysfs_dev_char_kobj;
>  }
>
>  static int device_create_sys_dev_entry(struct device *dev)
> diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
> index ae72d4ba8547..b848764ef018 100644
> --- a/drivers/base/devtmpfs.c
> +++ b/drivers/base/devtmpfs.c
> @@ -94,15 +94,6 @@ static struct file_system_type dev_fs_type = {
>         .mount = public_dev_mount,
>  };
>
> -#ifdef CONFIG_BLOCK
> -static inline int is_blockdev(struct device *dev)
> -{
> -       return dev->class == &block_class;
> -}
> -#else
> -static inline int is_blockdev(struct device *dev) { return 0; }
> -#endif
> -
>  static int devtmpfs_submit_req(struct req *req, const char *tmp)
>  {
>         init_completion(&req->done);
> --
> 2.40.0
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 5/7] driver core: class: remove dev_kobj from struct class
  2023-03-31  9:33 ` [PATCH 5/7] driver core: class: remove dev_kobj from struct class Greg Kroah-Hartman
@ 2023-03-31 14:50   ` Rafael J. Wysocki
  0 siblings, 0 replies; 16+ messages in thread
From: Rafael J. Wysocki @ 2023-03-31 14:50 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: linux-kernel, Rafael J. Wysocki

On Fri, Mar 31, 2023 at 11:33 AM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> The dev_kobj field in struct class is now only written to, but never
> read from, so it can be removed as it is useless.
>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Acked-by: Rafael J. Wysocki <rafael@kernel.org>

> ---
>  block/genhd.c                | 1 -
>  drivers/base/class.c         | 4 ----
>  include/linux/device/class.h | 2 --
>  3 files changed, 7 deletions(-)
>
> diff --git a/block/genhd.c b/block/genhd.c
> index e1e1230b1b9f..af7208a37c53 100644
> --- a/block/genhd.c
> +++ b/block/genhd.c
> @@ -899,7 +899,6 @@ static int __init genhd_device_init(void)
>  {
>         int error;
>
> -       block_class.dev_kobj = sysfs_dev_block_kobj;
>         error = class_register(&block_class);
>         if (unlikely(error))
>                 return error;
> diff --git a/drivers/base/class.c b/drivers/base/class.c
> index fcfb295363cc..06b96d6faa19 100644
> --- a/drivers/base/class.c
> +++ b/drivers/base/class.c
> @@ -197,10 +197,6 @@ int class_register(struct class *cls)
>                 return error;
>         }
>
> -       /* set the default /sys/dev directory for devices of this class */
> -       if (!cls->dev_kobj)
> -               cls->dev_kobj = sysfs_dev_char_kobj;
> -
>         cp->subsys.kobj.kset = class_kset;
>         cp->subsys.kobj.ktype = &class_ktype;
>         cp->class = cls;
> diff --git a/include/linux/device/class.h b/include/linux/device/class.h
> index f7aad64e256a..e946642c314e 100644
> --- a/include/linux/device/class.h
> +++ b/include/linux/device/class.h
> @@ -27,7 +27,6 @@ struct fwnode_handle;
>   * @name:      Name of the class.
>   * @class_groups: Default attributes of this class.
>   * @dev_groups:        Default attributes of the devices that belong to the class.
> - * @dev_kobj:  The kobject that represents this class and links it into the hierarchy.
>   * @dev_uevent:        Called when a device is added, removed from this class, or a
>   *             few other things that generate uevents to add the environment
>   *             variables.
> @@ -55,7 +54,6 @@ struct class {
>
>         const struct attribute_group    **class_groups;
>         const struct attribute_group    **dev_groups;
> -       struct kobject                  *dev_kobj;
>
>         int (*dev_uevent)(const struct device *dev, struct kobj_uevent_env *env);
>         char *(*devnode)(const struct device *dev, umode_t *mode);
> --
> 2.40.0
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 6/7] driver core: make sysfs_dev_block_kobj static
  2023-03-31  9:33 ` [PATCH 6/7] driver core: make sysfs_dev_block_kobj static Greg Kroah-Hartman
@ 2023-03-31 14:50   ` Rafael J. Wysocki
  0 siblings, 0 replies; 16+ messages in thread
From: Rafael J. Wysocki @ 2023-03-31 14:50 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: linux-kernel, Rafael J. Wysocki

On Fri, Mar 31, 2023 at 11:33 AM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> Nothing outside of drivers/base/core.c uses sysfs_dev_block_kobj, so
> make it static and document what it is used for so we remember it the
> next time we touch it 15 years from now.
>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Acked-by: Rafael J. Wysocki <rafael@kernel.org>

> ---
>  drivers/base/core.c          | 4 +++-
>  include/linux/device/class.h | 2 --
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index dbc2ba6dfffc..cf6f41c2060c 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
> @@ -2256,7 +2256,9 @@ int (*platform_notify)(struct device *dev) = NULL;
>  int (*platform_notify_remove)(struct device *dev) = NULL;
>  static struct kobject *dev_kobj;
>  struct kobject *sysfs_dev_char_kobj;
> -struct kobject *sysfs_dev_block_kobj;
> +
> +/* /sys/dev/block */
> +static struct kobject *sysfs_dev_block_kobj;
>
>  static DEFINE_MUTEX(device_hotplug_lock);
>
> diff --git a/include/linux/device/class.h b/include/linux/device/class.h
> index e946642c314e..7e4a1a6329f4 100644
> --- a/include/linux/device/class.h
> +++ b/include/linux/device/class.h
> @@ -76,8 +76,6 @@ struct class_dev_iter {
>         const struct device_type        *type;
>  };
>
> -extern struct kobject *sysfs_dev_block_kobj;
> -
>  int __must_check class_register(struct class *class);
>  void class_unregister(const struct class *class);
>  bool class_is_registered(const struct class *class);
> --
> 2.40.0
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 7/7] driver core: make sysfs_dev_char_kobj static
  2023-03-31  9:33 ` [PATCH 7/7] driver core: make sysfs_dev_char_kobj static Greg Kroah-Hartman
@ 2023-03-31 14:50   ` Rafael J. Wysocki
  0 siblings, 0 replies; 16+ messages in thread
From: Rafael J. Wysocki @ 2023-03-31 14:50 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: linux-kernel, Rafael J. Wysocki

On Fri, Mar 31, 2023 at 11:33 AM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> Nothing outside of drivers/base/core.c uses sysfs_dev_char_kobj, so
> make it static and document what it is used for so we remember it the
> next time we touch it 15 years from now.
>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Acked-by: Rafael J. Wysocki <rafael@kernel.org>

> ---
>  drivers/base/base.h | 3 ---
>  drivers/base/core.c | 4 +++-
>  2 files changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/base/base.h b/drivers/base/base.h
> index 4660e1159ee0..e96f3343fd7c 100644
> --- a/drivers/base/base.h
> +++ b/drivers/base/base.h
> @@ -191,9 +191,6 @@ const char *device_get_devnode(const struct device *dev, umode_t *mode,
>  extern struct kset *devices_kset;
>  void devices_kset_move_last(struct device *dev);
>
> -/* /sys/dev/char directory */
> -extern struct kobject *sysfs_dev_char_kobj;
> -
>  #if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
>  void module_add_driver(struct module *mod, struct device_driver *drv);
>  void module_remove_driver(struct device_driver *drv);
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index cf6f41c2060c..47e16c088e77 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
> @@ -2255,7 +2255,9 @@ static void fw_devlink_link_device(struct device *dev)
>  int (*platform_notify)(struct device *dev) = NULL;
>  int (*platform_notify_remove)(struct device *dev) = NULL;
>  static struct kobject *dev_kobj;
> -struct kobject *sysfs_dev_char_kobj;
> +
> +/* /sys/dev/char */
> +static struct kobject *sysfs_dev_char_kobj;
>
>  /* /sys/dev/block */
>  static struct kobject *sysfs_dev_block_kobj;
> --
> 2.40.0
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/7] driver core: core: move to use class_to_subsys()
  2023-03-31 10:26 ` [PATCH 1/7] driver core: core: move to use class_to_subsys() Rafael J. Wysocki
@ 2023-03-31 15:44   ` Greg Kroah-Hartman
  0 siblings, 0 replies; 16+ messages in thread
From: Greg Kroah-Hartman @ 2023-03-31 15:44 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: linux-kernel

On Fri, Mar 31, 2023 at 12:26:34PM +0200, Rafael J. Wysocki wrote:
> On Fri, Mar 31, 2023 at 11:33 AM Greg Kroah-Hartman
> <gregkh@linuxfoundation.org> wrote:
> >
> > There are a number of places in core.c that need access to the private
> > subsystem structure of struct class, so move them to use
> > class_to_subsys() instead of accessing it directly.
> >
> > This requires exporting class_to_subsys() out of class.c, but keeping it
> > local to the driver core.
> >
> > Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> 
> Reviewed-by: Rafael J. Wysocki <rafael@kernel.org>

Thanks for the quick review!

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2023-03-31 15:44 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-31  9:33 [PATCH 1/7] driver core: core: move to use class_to_subsys() Greg Kroah-Hartman
2023-03-31  9:33 ` [PATCH 2/7] driver core: create class_is_registered() Greg Kroah-Hartman
2023-03-31 10:16   ` Rafael J. Wysocki
2023-03-31 12:44   ` Linus Walleij
2023-03-31  9:33 ` [PATCH 3/7] driver core: class: remove subsystem private pointer from struct class Greg Kroah-Hartman
2023-03-31 14:48   ` Rafael J. Wysocki
2023-03-31  9:33 ` [PATCH 4/7] driver core: clean up the logic to determine which /sys/dev/ directory to use Greg Kroah-Hartman
2023-03-31 14:49   ` Rafael J. Wysocki
2023-03-31  9:33 ` [PATCH 5/7] driver core: class: remove dev_kobj from struct class Greg Kroah-Hartman
2023-03-31 14:50   ` Rafael J. Wysocki
2023-03-31  9:33 ` [PATCH 6/7] driver core: make sysfs_dev_block_kobj static Greg Kroah-Hartman
2023-03-31 14:50   ` Rafael J. Wysocki
2023-03-31  9:33 ` [PATCH 7/7] driver core: make sysfs_dev_char_kobj static Greg Kroah-Hartman
2023-03-31 14:50   ` Rafael J. Wysocki
2023-03-31 10:26 ` [PATCH 1/7] driver core: core: move to use class_to_subsys() Rafael J. Wysocki
2023-03-31 15:44   ` Greg Kroah-Hartman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.