您的位置:首页 > 其它

总线、设备、驱动、类

2012-12-18 21:40 183 查看


一. 总线、设备、驱动、类各自的相关结构体

    1.总线

     1.1 总线类型结构体

struct bus_type {
const char	*name;	//总线类型名
struct bus_attribute	*bus_attrs;	//总线属性
struct device_attribute	*dev_attrs;	//设备属性
struct driver_attribute	*drv_attrs;	//驱动属性
int (*match)(struct device *dev, struct device_driver *drv);	//match方法
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);	//uevent方法
int (*probe)(struct device *dev);		//总线probe方法
int (*remove)(struct device *dev);		//总线remove方法
void (*shutdown)(struct device *dev);	//总线remove方法
int (*suspend)(struct device *dev, pm_message_t state);	//总线shutdown方法
int (*resume)(struct device *dev);		//总线resume方法
const struct dev_pm_ops *pm;	//总线电源管理函数集
struct bus_type_private *p;		//总线私有数据
};

    1.2 总线私有数据结构体

struct bus_type_private {
struct kset subsys;
struct kset *drivers_kset;
struct kset *devices_kset;
struct klist klist_devices;
struct klist klist_drivers;
struct blocking_notifier_head bus_notifier;
unsigned int drivers_autoprobe:1;
struct bus_type *bus;
};

     1.3 总线类型属性结构体

struct bus_attribute {
struct attribute	attr;
ssize_t (*show)(struct bus_type *bus, char *buf);
ssize_t (*store)(struct bus_type *bus, const char *buf, size_t count);
};

     1.4 设备属性结构体

struct device_attribute {
struct attribute	attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr,char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,const char *buf, size_t count);
};

     1.5 设备驱动属性结构体

struct driver_attribute {
struct attribute attr;
ssize_t (*show)(struct device_driver *driver, char *buf);
ssize_t (*store)(struct device_driver *driver, const char *buf,size_t count);
};

 

     2.设备

     2.1 设备结构体

struct device {
struct device	*parent;	//父设备指针
struct device_private	*p;	//设备私有数据
struct kobject kobj;
const char	*init_name; /* initial name of the device */
struct device_type	*type;
struct mutex	mutex;
struct bus_type	*bus;	/* type of bus device is on */
struct device_driver *driver;	//匹配的设备驱动
void	*platform_data;	//平台数据
struct dev_pm_info	power;
#ifdef CONFIG_NUMA
int	numa_node;/* NUMA node this device is close to */
#endif
u64	*dma_mask;/* dma mask (if dma'able device) */
u64	coherent_dma_mask;
struct device_dma_parameters *dma_parms;
struct list_head	dma_pools;	/* dma pools (if dma'ble) */
struct dma_coherent_mem	*dma_mem; /* internal for coherent mem override */
/* arch specific additions */
struct dev_archdata	archdata;
#ifdef CONFIG_OF
struct device_node	*of_node;
#endif
dev_t	devt;	//设备号
spinlock_t	devres_lock;
struct list_head	devres_head;
struct klist_node	knode_class;
struct class	*class;	//对应的设备类
const struct attribute_group **groups;	/* optional groups */
void	(*release)(struct device *dev);	//release方法
};

     2.2 设备私有数据结构体

struct device_private {
struct klist klist_children;
struct klist_node knode_parent;
struct klist_node knode_driver;
struct klist_node knode_bus;
void *driver_data;
struct device *device;
};

 

     3.驱动

     3.1 设备驱动结构体

struct device_driver {
const char	*name;	//设备驱动名
struct bus_type	*bus;	//所属总线类型
struct module	*owner;	//模块所有者
const char	*mod_name;	/* used for built-in modules */
bool suppress_bind_attrs;	/* disables bind/unbind via sysfs */
#if defined(CONFIG_OF)
const struct of_device_id	*of_match_table;
#endif
int (*probe) (struct device *dev);	//probe方法
int (*remove) (struct device *dev);	//remove方法
void (*shutdown) (struct device *dev);	//shutdown方法
int (*suspend) (struct device *dev, pm_message_t state);	//suspend方法
int (*resume) (struct device *dev);	//resume方法
const struct attribute_group **groups;
const struct dev_pm_ops *pm;	//电源管理函数集
struct driver_private *p;	//设备驱动私有数据
};

     3.2 设备驱动私有数据结构体

struct driver_private {
struct kobject kobj;
struct klist klist_devices;
struct klist_node knode_bus;
struct module_kobject *mkobj;
struct device_driver *driver;
};

 

     4.类

     4.1 设备类结构体

struct class {
const char	*name;	//类名
struct module	*owner;	//模块所有者
struct class_attribute	*class_attrs;	//类属性
struct device_attribute	*dev_attrs;	//设备属性
struct kobject	*dev_kobj;
int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
char *(*devnode)(struct device *dev, mode_t *mode);
void (*class_release)(struct class *class);
void (*dev_release)(struct device *dev);
int (*suspend)(struct device *dev, pm_message_t state);
int (*resume)(struct device *dev);
const struct kobj_ns_type_operations *ns_type;
const void *(*namespace)(struct device *dev);
const struct dev_pm_ops *pm;	//电源管理函数集
struct class_private *p;	//类私有数据结构
};

     4.2 类属私有数据结构体

struct class_private {
struct kset class_subsys;
struct klist class_devices;
struct list_head class_interfaces;
struct kset class_dirs;
struct mutex class_mutex;
struct class *class;
};

     4.3 类属性结构体

struct class_attribute {
struct attribute attr;
ssize_t (*show)(struct class *class, struct class_attribute *attr,char *buf);
ssize_t (*store)(struct class *class, struct class_attribute *attr,const char *buf, size_t count);
};


二. 初始化过程

     1 系统启动过程中调用start_kernel函数->rest_init()->创建kernel_init线程->do_basic_setup()->driver_init()

     2.driver_init

void __init driver_init(void)
{
devtmpfs_init();		//初始化devtmpfs文件系统
devices_init();		//设备初始化
buses_init();		//总线初始化
classes_init();		//设备类初始化
firmware_init();
hypervisor_init();
platform_bus_init();
system_bus_init();
cpu_dev_init();
memory_dev_init();
}

     3. devices_init

int __init devices_init(void)
{
devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);	//创建"/sys/devices"
if (!devices_kset)
return -ENOMEM;
dev_kobj = kobject_create_and_add("dev", NULL);	//创建"/sys/dev"
if (!dev_kobj)
goto dev_kobj_err;
sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj);	//创建"/sys/dev/block"
if (!sysfs_dev_block_kobj)
goto block_kobj_err;
sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj);		//创建"/sys/dev/char"
if (!sysfs_dev_char_kobj)
goto char_kobj_err;
return 0;

char_kobj_err:
kobject_put(sysfs_dev_block_kobj);
block_kobj_err:
kobject_put(dev_kobj);
dev_kobj_err:
kset_unregister(devices_kset);
return -ENOMEM;
}

     4. buses_init

int __init buses_init(void)
{
bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);	//创建"/sys/bus"
if (!bus_kset)
return -ENOMEM;
return 0;
}

    5. classes_init

int __init classes_init(void)
{
class_kset = kset_create_and_add("class", NULL, NULL);		//创建"/sys/class"
if (!class_kset)
return -ENOMEM;
return 0;
}

 

     6.经过上面的初始化得到一些全局的变量

bus_kset --> /sys/bus
class_kset --> /sys/class
devices_kset --> /sys/devices
dev_kobj--> /sys/dev
sysfs_dev_block_kobj --> /sys/dev/block
sysfs_dev_char_kobj --> /sys/dev/char


三. 总线 设备 驱动 类 的注册与注销

     1. 总线注册与注销

     1.1 注册

int bus_register(struct bus_type *bus)
{
int retval;
struct bus_type_private *priv;

priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);	//分配总线类型私有数据结构体
if (!priv)
return -ENOMEM;

priv->bus = bus;		//私有数据结构体的总线指针指向总线
bus->p = priv;		//总线的私有数据指针指向私有数据结构体

BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);	//初始化通知链表头

retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);
if (retval)
goto out;

priv->subsys.kobj.kset = bus_kset;		//bus_kset --> /sys/bus
priv->subsys.kobj.ktype = &bus_ktype;
priv->drivers_autoprobe = 1;

retval = kset_register(&priv->subsys);	//创建"/sys/bus/xxx"
if (retval)
goto out;

retval = bus_create_file(bus, &bus_attr_uevent);
if (retval)
goto bus_uevent_fail;

priv->devices_kset = kset_create_and_add("devices", NULL,&priv->subsys.kobj);	//创建"/sys/bus/xxx/devices"
if (!priv->devices_kset) {
retval = -ENOMEM;
goto bus_devices_fail;
}

priv->drivers_kset = kset_create_and_add("drivers", NULL,&priv->subsys.kobj);	//创建"/sys/bus/xxx/drivers"
if (!priv->drivers_kset) {
retval = -ENOMEM;
goto bus_drivers_fail;
}

klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
klist_init(&priv->klist_drivers, NULL, NULL);

retval = add_probe_files(bus);
if (retval)
goto bus_probe_files_fail;

retval = bus_add_attrs(bus);
if (retval)
goto bus_attrs_fail;

pr_debug("bus: '%s': registered\n", bus->name);
return 0;

bus_attrs_fail:
remove_probe_files(bus);
bus_probe_files_fail:
kset_unregister(bus->p->drivers_kset);
bus_drivers_fail:
kset_unregister(bus->p->devices_kset);
bus_devices_fail:
bus_remove_file(bus, &bus_attr_uevent);
bus_uevent_fail:
kset_unregister(&bus->p->subsys);
out:
kfree(bus->p);
bus->p = NULL;
return retval;
}


     1.2 注销

void bus_unregister(struct bus_type *bus)
{
pr_debug("bus: '%s': unregistering\n", bus->name);
bus_remove_attrs(bus);
remove_probe_files(bus);
kset_unregister(bus->p->drivers_kset);
kset_unregister(bus->p->devices_kset);
bus_remove_file(bus, &bus_attr_uevent);
kset_unregister(&bus->p->subsys);
kfree(bus->p);
bus->p = NULL;
}

 

     2.设备注册与注销

     2.1 注册

int device_register(struct device *dev)
{
device_initialize(dev);
return device_add(dev);
}

     2.1.1 device_initialize

void device_initialize(struct device *dev)
{
dev->kobj.kset = devices_kset;    //devices_kset --> /sys/devices
kobject_init(&dev->kobj, &device_ktype);
INIT_LIST_HEAD(&dev->dma_pools);
mutex_init(&dev->mutex);
lockdep_set_novalidate_class(&dev->mutex);
spin_lock_init(&dev->devres_lock);
INIT_LIST_HEAD(&dev->devres_head);
device_pm_init(dev);
set_dev_node(dev, -1);
}

     2.1.2 device_add

int device_add(struct device *dev)
{
struct device *parent = NULL;
struct class_interface *class_intf;
int error = -EINVAL;
dev = get_device(dev);
if (!dev)
goto done;

if (!dev->p) {
error = device_private_init(dev);
if (error)
goto done;
}

if (dev->init_name) {
dev_set_name(dev, "%s", dev->init_name);
dev->init_name = NULL;
}

if (!dev_name(dev)) {
error = -EINVAL;
goto name_error;
}

pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
parent = get_device(dev->parent);
setup_parent(dev, parent);
if (parent)
set_dev_node(dev, dev_to_node(parent));
error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);
if (error)
goto Error;
if (platform_notify)
platform_notify(dev);
error = device_create_file(dev, &uevent_attr);
if (error)
goto attrError;
if (MAJOR(dev->devt)) {
error = device_create_file(dev, &devt_attr);
if (error)
goto ueventattrError;
error = device_create_sys_dev_entry(dev);	//创建"/sys/dev/char/xxx"或"/sys/dev/block/xxx"
if (error)
goto devtattrError;
devtmpfs_create_node(dev);	//创建节点文件
}
error = device_add_class_symlinks(dev);
if (error)
goto SymlinkError;
error = device_add_attrs(dev);
if (error)
goto AttrsError;
error = bus_add_device(dev);	//将设备添加进总线
if (error)
goto BusError;
error = dpm_sysfs_add(dev);
if (error)
goto DPMError;
device_pm_add(dev);
if (dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,BUS_NOTIFY_ADD_DEVICE, dev);	//通知链发送通知

kobject_uevent(&dev->kobj, KOBJ_ADD);
bus_probe_device(dev);	//设备尝试匹配驱动并调用其probe方法
if (parent)
klist_add_tail(&dev->p->knode_parent,&parent->p->klist_children);

if (dev->class) {
mutex_lock(&dev->class->p->class_mutex);
/* tie the class to the device */
klist_add_tail(&dev->knode_class,&dev->class->p->class_devices);

/* notify any interfaces that the device is here */
list_for_each_entry(class_intf,&dev->class->p->class_interfaces, node)
if (class_intf->add_dev)
class_intf->add_dev(dev, class_intf);
mutex_unlock(&dev->class->p->class_mutex);
}
done:
put_device(dev);
return error;
DPMError:
bus_remove_device(dev);
BusError:
device_remove_attrs(dev);
AttrsError:
device_remove_class_symlinks(dev);
SymlinkError:
if (MAJOR(dev->devt))
devtmpfs_delete_node(dev);
if (MAJOR(dev->devt))
device_remove_sys_dev_entry(dev);
devtattrError:
if (MAJOR(dev->devt))
device_remove_file(dev, &devt_attr);
ueventattrError:
device_remove_file(dev, &uevent_attr);
attrError:
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
kobject_del(&dev->kobj);
Error:
cleanup_device_parent(dev);
if (parent)
put_device(parent);
name_error:
kfree(dev->p);
dev->p = NULL;
goto done;
}

     2.1.2.1 device_create_sys_dev_entry 创建设备入口

static int device_create_sys_dev_entry(struct device *dev)
{
struct kobject *kobj = device_to_dev_kobj(dev);
int error = 0;
char devt_str[15];
if (kobj) {
format_dev_t(devt_str, dev->devt);	//devt_srt=主设备号:次设备号
error = sysfs_create_link(kobj, &dev->kobj, devt_str);
}
return error;
}

创建"/sys/dev/char[block]/主设备号:次设备号"

     2.1.2.2 bus_add_device

int bus_add_device(struct device *dev)
{
struct bus_type *bus = bus_get(dev->bus);
int error = 0;

if (bus) {
pr_debug("bus: '%s': add device %s\n", bus->name, dev_name(dev));
error = device_add_attrs(bus, dev);
if (error)
goto out_put;
error = sysfs_create_link(&bus->p->devices_kset->kobj,&dev->kobj, dev_name(dev));
if (error)
goto out_id;
error = sysfs_create_link(&dev->kobj,&dev->bus->p->subsys.kobj, "subsystem");
if (error)
goto out_subsys;
klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);	//将设备添加至总线的设备链表
}
return 0;

out_subsys:
sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev));
out_id:
device_remove_attrs(bus, dev);
out_put:
bus_put(dev->bus);
return error;
}

    2,2 注销

void device_unregister(struct device *dev)
{
pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
device_del(dev);
put_device(dev);
}

 

     3. 驱动注册与注销

     3.1 注册

int driver_register(struct device_driver *drv)
{
int ret;
struct device_driver *other;

BUG_ON(!drv->bus->p);
//判断驱动的方法与总线是否匹配
if ((drv->bus->probe && drv->probe) ||(drv->bus->remove && drv->remove) ||(drv->bus->shutdown && drv->shutdown))
printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name);
other = driver_find(drv->name, drv->bus);	//根据总线类型和驱动设备名查找设备
if (other) {
put_driver(other);
printk(KERN_ERR "Error: Driver '%s' is already registered,aborting...\n", drv->name);
return -EBUSY;
}
ret = bus_add_driver(drv);		//总线添加设备驱动
if (ret)
return ret;
ret = driver_add_groups(drv, drv->groups);
if (ret)
bus_remove_driver(drv);
return ret;
}

     3.1.1 bus_add_driver

int bus_add_driver(struct device_driver *drv)
{
struct bus_type *bus;
struct driver_private *priv;
int error = 0;

bus = bus_get(drv->bus);	//获取驱动总线类型
if (!bus)
return -EINVAL;

pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);

priv = kzalloc(sizeof(*priv), GFP_KERNEL);	//分配设备驱动私有数据结构体
if (!priv) {
error = -ENOMEM;
goto out_put_bus;
}
klist_init(&priv->klist_devices, NULL, NULL);
priv->driver = drv;
drv->p = priv;
priv->kobj.kset = bus->p->drivers_kset;
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,"%s", drv->name);	//创建"/sys/bus/xxx/drivers"
if (error)
goto out_unregister;

if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv);		//驱动匹配设备,并调用probe方法
if (error)
goto out_unregister;
}
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);	//添加设备驱动到总线驱动链表
module_add_driver(drv->owner, drv);
error = driver_create_file(drv, &driver_attr_uevent);
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",__func__, drv->name);
}
error = driver_add_attrs(bus, drv);
if (error) {
printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",__func__, drv->name);
}

if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",__func__, drv->name);
}
}
kobject_uevent(&priv->kobj, KOBJ_ADD);
return 0;
out_unregister:
kobject_put(&priv->kobj);
kfree(drv->p);
drv->p = NULL;
out_put_bus:
bus_put(bus);
return error;
}

     3.1.1.1 driver_attach 设备驱动匹配

int driver_attach(struct device_driver *drv)
{
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}

    3.1.1.1.1 __driver_attach

static int __driver_attach(struct device *dev, void *data)
{
struct device_driver *drv = data;
if (!driver_match_device(drv, dev))	//设备与设备驱动的匹配
return 0;
if (dev->parent)	/* Needed for USB */
device_lock(dev->parent);
device_lock(dev);
if (!dev->driver)	//存在设备驱动
driver_probe_device(drv, dev);
device_unlock(dev);
if (dev->parent)
device_unlock(dev->parent);
return 0;
}

    3.1.1.1.1.1driver_match_device

static inline int driver_match_device(struct device_driver *drv,struct device *dev)
{
return drv->bus->match ? drv->bus->match(dev, drv) : 1;	//若总线存在match方法调用总线的match方法
}

   3.1.1.1.1.2 driver_probe_device

int driver_probe_device(struct device_driver *drv, struct device *dev)
{
int ret = 0;

if (!device_is_registered(dev))
return -ENODEV;

pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
drv->bus->name, __func__, dev_name(dev), drv->name);

pm_runtime_get_noresume(dev);
pm_runtime_barrier(dev);
ret = really_probe(dev, drv);
pm_runtime_put_sync(dev);

return ret;
}

    3.1.1.1.1.2.1  really_probe函数

static int really_probe(struct device *dev, struct device_driver *drv)
{
int ret = 0;
atomic_inc(&probe_count);
pr_debug("bus: '%s': %s: probing driver %s with device %s\n",drv->bus->name, __func__, drv->name, dev_name(dev));
WARN_ON(!list_empty(&dev->devres_head));
dev->driver = drv;
if (driver_sysfs_add(dev)) {
printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",__func__, dev_name(dev));
goto probe_failed;
}
if (dev->bus->probe) {	//总线存在probe方法
ret = dev->bus->probe(dev);	//则调用去probe方法
if (ret)
goto probe_failed;
} else if (drv->probe) {	//驱动存在probe方法
ret = drv->probe(dev);	//则调用设备驱动的probe方法
if (ret)
goto probe_failed;
}
driver_bound(dev);	//捆绑设备文件,会调用总线的通知链回调函数
ret = 1;
pr_debug("bus: '%s': %s: bound device %s to driver %s\n",drv->bus->name, __func__, dev_name(dev), drv->name);
goto done;

probe_failed:
devres_release_all(dev);
driver_sysfs_remove(dev);
dev->driver = NULL;
if (ret != -ENODEV && ret != -ENXIO) {
printk(KERN_WARNING"%s: probe of %s failed with error %d\n",drv->name, dev_name(dev), ret);
}
ret = 0;
done:
atomic_dec(&probe_count);
wake_up(&probe_waitqueue);
return ret;
}

   3.2 注销

void driver_unregister(struct device_driver *drv)
{
if (!drv || !drv->p) {
WARN(1, "Unexpected driver unregister!\n");
return;
}
driver_remove_groups(drv, drv->groups);
bus_remove_driver(drv);
}

 

     4. 类的注册与注销

     4.1 注册

#define class_register(class)			\
({						\
static struct lock_class_key __key;	\
__class_register(class, &__key);	\
})
int __class_register(struct class *cls, struct lock_class_key *key)
{
struct class_private *cp;
int error;

pr_debug("device class '%s': registering\n", cls->name);

cp = kzalloc(sizeof(*cp), GFP_KERNEL);
if (!cp)
return -ENOMEM;
klist_init(&cp->class_devices, klist_class_dev_get, klist_class_dev_put);
INIT_LIST_HEAD(&cp->class_interfaces);
kset_init(&cp->class_dirs);
__mutex_init(&cp->class_mutex, "struct class mutex", key);
error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name);
if (error) {
kfree(cp);
return error;
}

/* set the default /sys/dev directory for devices of this class */
if (!cls->dev_kobj)
cls->dev_kobj = sysfs_dev_char_kobj;		//sysfs_dev_char_kobj --> /sys/dev/char
#if defined(CONFIG_BLOCK)
/* let the block class directory show up in the root of sysfs */
if (!sysfs_deprecated || cls != &block_class)		//创建"/sys/block"
cp->class_subsys.kobj.kset = class_kset;
#else
cp->class_subsys.kobj.kset = class_kset;	//class_kset --> /sys/class
#endif
cp->class_subsys.kobj.ktype = &class_ktype;
cp->class = cls;
cls->p = cp;

error = kset_register(&cp->class_subsys);
if (error) {
kfree(cp);
return error;
}
error = add_class_attrs(class_get(cls));
class_put(cls);
return error;
}

     4.2 注销

void class_unregister(struct class *cls)
{
pr_debug("device class '%s': unregistering\n", cls->name);
remove_class_attrs(cls);
kset_unregister(&cls->p->class_subsys);
}

    4.3 驱动中注册与注销类的另一种方式

    4.3.1 注册类 class_create

#define class_create(owner, name)		\	//创建"/sys/(name)"
({					\
static struct lock_class_key __key;	\
__class_create(owner, name, &__key);	\
})
struct class *__class_create(struct module *owner, const char *name,struct lock_class_key *key)
{
struct class *cls;
int retval;

cls = kzalloc(sizeof(*cls), GFP_KERNEL);
if (!cls) {
retval = -ENOMEM;
goto error;
}

cls->name = name;
cls->owner = owner;
cls->class_release = class_create_release;

retval = __class_register(cls, key);		//实质上也是调用了__class_register函数
if (retval)
goto error;

return cls;

error:
kfree(cls);
return ERR_PTR(retval);
}

    4.3.2 注销类 class_destroy

void class_destroy(struct class *cls)
{
if ((cls == NULL) || (IS_ERR(cls)))
return;

class_unregister(cls);
}

四. 总线设备驱动类框架的搭建(eg:platform)

     1.定义总线类型结构体

struct bus_type platform_bus_type = {
.name       = "platform",       //总线名
.dev_attrs  = platform_dev_attrs,   //设备属性
.match      = platform_match,       //匹配函数
.uevent     = platform_uevent,      //事件函数
.pm     = &platform_dev_pm_ops, //电源管理函数集
};

      2.定义总线作为设备的设备结构体--总线本身也是一个设备

struct device platform_bus = {
.init_name	= "platform",
};

     3.注册作为设备的总线设备

platform_bus_init()-->device_register(&platform_bus)

     4.注册总线

platform_bus_init()-->bus_register(&platform_bus_type)

     5.这里可以是设备注册或者设备驱动注册(以设备注册先为例)

     5.1 定义总线下的设备结构体

static struct platform_device platform_device_1 = {
.name   = "paltform_1",
.id = -1,               //设备id一般都设置为-1
};

      5.1.1 注册设备

platform_device_register(&platform_device_1); //-->platform_device_add-->device_add(&pdev->dev)

      6.定义设备驱动

static struct platform_driver platform_1_driver = {
.driver = {
.name = "platform_1",
.owner = THIS_MODULE,
},
.probe = platform_1_probe,
.remove = platform_1_remove,
};

     7.注册设备驱动

platform_driver_register(&platform_1_driver);	//-->driver_register(&drv->driver)

    8. 至于类的添加

class_create(THIS_MODULES,"platfrom_1");

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: