Yuhang Zheng

第十四节、平台总线模型——注册platform驱动

N 人看过

本节用于介绍平台总线模型——注册platform驱动

编写driver.c的思路

首先定义一个platform_driver结构体变量,然后去实现结构体中的各个成员变量,那么当我们的driver 和device匹配成功的时候,就会执行probe函数,所以匹配成功以后的重点就在于probe函数的编写。

1、平台总线注册一个platform_driver

文件位置路径:include/linux/platform_device.h

struct platform_driver {
        int (*probe)(struct platform_device *);            //当driver和device匹配成功的时候,就会执行probe 函数
        int (*remove)(struct platform_device *);        //当driver和device任意一个remove的时候,就会执行这个函数
        void (*shutdown)(struct platform_device *);        //当设备收到shutdown命令的时候,就会执行这个函数
        int (*suspend)(struct platform_device *, pm_message_t state);    //当设备收到suspend休眠命令的时候,就会执行这个函数
        int (*resume)(struct platform_device *);                        ////当设备收到resume唤醒命令的时候,就会执行这个函数
        struct device_driver driver;
        const struct platform_device_id *id_table;        //这个里面的name优先级比device_driver结构体里面的name的优先级比较高
        bool prevent_deferred_probe;
};

在struct platform_device_id结构体内还有一个name成员

文件位置路径:include/linux/mod_devicetable.h

struct platform_device_id {
        char name[PLATFORM_NAME_SIZE];
        kernel_ulong_t driver_data;
};

这个里面的name的匹配优先级比较高,

2、填写platform_driver里面的device_driver结构体

文件位置路径:include/linux/device.h

struct device_driver {
    ...
        const char              *name;        //常用,用于平台设备与平台驱动的匹配,会在/sys/bus/platform/driver/下生成name的节点
        struct module           *owner;        //模块的所有者,一般是THIS_MODULE
    ...
};

示例:

int beep_probe(struct platform_device *pdev)
{
        printk("beep_probe\n");
        return 0;
}

int beep_remove(struct platform_device *pdev)
{
        printk("beep_remove\n");
        return 0;
}

struct platform_device_id beep_idtable = {
        .name = "beep_test"
};

struct platform_driver beep_driver = {
        .probe = beep_probe,
        .remove = beep_remove,
        .driver = {
                .owner = THIS_MODULE,
                .name = "beep_test"
        },
        .id_table = &beep_idtable
};

3、注册和注销平台驱动函数

当使用上节的函数创建完成一个platform_driver后,使用platform_driver_register函数进行平台设备的注册

文件位置路径:include/linux/platform_device.h

实际函数位置路径:drivers/base/platform.c

#define platform_driver_register(drv) \
        __platform_driver_register(drv, THIS_MODULE)
extern int __platform_driver_register(struct platform_driver *,
                                        struct module *);

//参数
//pdev:要注册的平台驱动
extern void platform_driver_unregister(struct platform_driver *);
void platform_driver_unregister(struct platform_driver *drv)
{
        driver_unregister(&drv->driver);
}
EXPORT_SYMBOL_GPL(platform_driver_unregister);
//参数
//pdev:要注销的平台驱动