Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c47ed219 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Class: add support for class interfaces for devices



When moving class_device usage over to device, we need to handle
class_interfaces properly with devices.  This patch adds that support.


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent c205ef48
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -842,6 +842,7 @@ int class_interface_register(struct class_interface *class_intf)
{
	struct class *parent;
	struct class_device *class_dev;
	struct device *dev;

	if (!class_intf || !class_intf->class)
		return -ENODEV;
@@ -856,6 +857,10 @@ int class_interface_register(struct class_interface *class_intf)
		list_for_each_entry(class_dev, &parent->children, node)
			class_intf->add(class_dev, class_intf);
	}
	if (class_intf->add_dev) {
		list_for_each_entry(dev, &parent->devices, node)
			class_intf->add_dev(dev, class_intf);
	}
	up(&parent->sem);

	return 0;
@@ -865,6 +870,7 @@ void class_interface_unregister(struct class_interface *class_intf)
{
	struct class * parent = class_intf->class;
	struct class_device *class_dev;
	struct device *dev;

	if (!parent)
		return;
@@ -875,6 +881,10 @@ void class_interface_unregister(struct class_interface *class_intf)
		list_for_each_entry(class_dev, &parent->children, node)
			class_intf->remove(class_dev, class_intf);
	}
	if (class_intf->remove_dev) {
		list_for_each_entry(dev, &parent->devices, node)
			class_intf->remove_dev(dev, class_intf);
	}
	up(&parent->sem);

	class_put(parent);
+13 −1
Original line number Diff line number Diff line
@@ -372,6 +372,7 @@ int device_add(struct device *dev)
{
	struct device *parent = NULL;
	char *class_name = NULL;
	struct class_interface *class_intf;
	int error = -EINVAL;

	dev = get_device(dev);
@@ -451,9 +452,14 @@ int device_add(struct device *dev)
		klist_add_tail(&dev->knode_parent, &parent->klist_children);

	if (dev->class) {
		/* tie the class to the device */
		down(&dev->class->sem);
		/* tie the class to the device */
		list_add_tail(&dev->node, &dev->class->devices);

		/* notify any interfaces that the device is here */
		list_for_each_entry(class_intf, &dev->class->interfaces, node)
			if (class_intf->add_dev)
				class_intf->add_dev(dev, class_intf);
		up(&dev->class->sem);
	}

@@ -548,6 +554,7 @@ void device_del(struct device * dev)
{
	struct device * parent = dev->parent;
	char *class_name = NULL;
	struct class_interface *class_intf;

	if (parent)
		klist_del(&dev->knode_parent);
@@ -563,6 +570,11 @@ void device_del(struct device * dev)
		}
		kfree(class_name);
		down(&dev->class->sem);
		/* notify any interfaces that the device is now gone */
		list_for_each_entry(class_intf, &dev->class->interfaces, node)
			if (class_intf->remove_dev)
				class_intf->remove_dev(dev, class_intf);
		/* remove the device from the class list */
		list_del_init(&dev->node);
		up(&dev->class->sem);
	}
+2 −0
Original line number Diff line number Diff line
@@ -278,6 +278,8 @@ struct class_interface {

	int (*add)	(struct class_device *, struct class_interface *);
	void (*remove)	(struct class_device *, struct class_interface *);
	int (*add_dev)		(struct device *, struct class_interface *);
	void (*remove_dev)	(struct device *, struct class_interface *);
};

extern int class_interface_register(struct class_interface *);