一. 总线、设备、驱动、类各自的相关结构体
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");