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: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
c205ef4880
commit
c47ed219ba
@ -842,6 +842,7 @@ int class_interface_register(struct class_interface *class_intf)
|
|||||||
{
|
{
|
||||||
struct class *parent;
|
struct class *parent;
|
||||||
struct class_device *class_dev;
|
struct class_device *class_dev;
|
||||||
|
struct device *dev;
|
||||||
|
|
||||||
if (!class_intf || !class_intf->class)
|
if (!class_intf || !class_intf->class)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -856,6 +857,10 @@ int class_interface_register(struct class_interface *class_intf)
|
|||||||
list_for_each_entry(class_dev, &parent->children, node)
|
list_for_each_entry(class_dev, &parent->children, node)
|
||||||
class_intf->add(class_dev, class_intf);
|
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);
|
up(&parent->sem);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -865,6 +870,7 @@ void class_interface_unregister(struct class_interface *class_intf)
|
|||||||
{
|
{
|
||||||
struct class * parent = class_intf->class;
|
struct class * parent = class_intf->class;
|
||||||
struct class_device *class_dev;
|
struct class_device *class_dev;
|
||||||
|
struct device *dev;
|
||||||
|
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return;
|
return;
|
||||||
@ -875,6 +881,10 @@ void class_interface_unregister(struct class_interface *class_intf)
|
|||||||
list_for_each_entry(class_dev, &parent->children, node)
|
list_for_each_entry(class_dev, &parent->children, node)
|
||||||
class_intf->remove(class_dev, class_intf);
|
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);
|
up(&parent->sem);
|
||||||
|
|
||||||
class_put(parent);
|
class_put(parent);
|
||||||
|
@ -372,6 +372,7 @@ int device_add(struct device *dev)
|
|||||||
{
|
{
|
||||||
struct device *parent = NULL;
|
struct device *parent = NULL;
|
||||||
char *class_name = NULL;
|
char *class_name = NULL;
|
||||||
|
struct class_interface *class_intf;
|
||||||
int error = -EINVAL;
|
int error = -EINVAL;
|
||||||
|
|
||||||
dev = get_device(dev);
|
dev = get_device(dev);
|
||||||
@ -451,9 +452,14 @@ int device_add(struct device *dev)
|
|||||||
klist_add_tail(&dev->knode_parent, &parent->klist_children);
|
klist_add_tail(&dev->knode_parent, &parent->klist_children);
|
||||||
|
|
||||||
if (dev->class) {
|
if (dev->class) {
|
||||||
/* tie the class to the device */
|
|
||||||
down(&dev->class->sem);
|
down(&dev->class->sem);
|
||||||
|
/* tie the class to the device */
|
||||||
list_add_tail(&dev->node, &dev->class->devices);
|
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);
|
up(&dev->class->sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -548,6 +554,7 @@ void device_del(struct device * dev)
|
|||||||
{
|
{
|
||||||
struct device * parent = dev->parent;
|
struct device * parent = dev->parent;
|
||||||
char *class_name = NULL;
|
char *class_name = NULL;
|
||||||
|
struct class_interface *class_intf;
|
||||||
|
|
||||||
if (parent)
|
if (parent)
|
||||||
klist_del(&dev->knode_parent);
|
klist_del(&dev->knode_parent);
|
||||||
@ -563,6 +570,11 @@ void device_del(struct device * dev)
|
|||||||
}
|
}
|
||||||
kfree(class_name);
|
kfree(class_name);
|
||||||
down(&dev->class->sem);
|
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);
|
list_del_init(&dev->node);
|
||||||
up(&dev->class->sem);
|
up(&dev->class->sem);
|
||||||
}
|
}
|
||||||
|
@ -278,6 +278,8 @@ struct class_interface {
|
|||||||
|
|
||||||
int (*add) (struct class_device *, struct class_interface *);
|
int (*add) (struct class_device *, struct class_interface *);
|
||||||
void (*remove) (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 *);
|
extern int class_interface_register(struct class_interface *);
|
||||||
|
Loading…
Reference in New Issue
Block a user