platform 总线
linux设备通常需要挂载在一种总线上,SoC系统中集成了独立的外设控制器,挂接在Soc内存空间的外设不依赖此类总线。
linux_platform_driver 机制和传统的device_driver机制(即:通过 driver_register 函数进行注册)相比,一个十分明显的优势在于platform机制将设备本身的资源注册进内核,由内核统一管理,在驱动程序中用使用这些资源时,通过platform device提供的标准接口进行申请并使用。
platform 设备开发步骤
数据结构
struct platform_device {
const char * name;/* 设备名 */
u32 id;//设备id,用于给插入给该总线并且具有相同name的设备编号,如果只有一个设备的话填-1。
struct device dev;//结构体中内嵌的device结构体。
u32 num_resources;/* 设备所使用各类资源数量 */
struct resource * resource;/* //定义平台设备的资源*/
};
//平台资源结构
struct resource {
resource_size_t start; //定义资源的起始地址
resource_size_t end; //定义资源的结束地址
const char *name; //定义资源的名称
unsigned long flags; //定义资源的类型,比如MEM,IO,IRQ,DMA类型
struct resource *parent, *sibling, *child;
};
//设备的驱动:platform_driver这个结构体中包含probe()、remove()、shutdown()、suspend()、 resume()函数,通常也需要由驱动实现。
struct platform_driver {
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
int (*suspend_late)(struct platform_device *, pm_message_t state);
int (*resume_early)(struct platform_device *);
int (*resume)(struct platform_device *);
struct pm_ext_ops *pm;
struct device_driver driver;
};
//系统中为platform总线定义了一个bus_type的实例platform_bus_type,
struct bus_type platform_bus_type = {
.name = “platform”,
.dev_attrs = platform_dev_attrs,
.match = platform_match,
.uevent = platform_uevent,
.pm = PLATFORM_PM_OPS_PTR,
};
EXPORT_SYMBOL_GPL(platform_bus_type);
注册
1、实现platform_driver结构体
static struct platform_driver globalfifo_driver = {
.driver = {
.name = "globalfifo",
.owner = THIS_MODULE,
},
.probe = globalfifo_probe,
.remove = globalfifo_remove,
};
2、在module_init 模块加载函数里调用
platform_device_register(&globalfifo_driver)
网友评论