什么是平台总线模型: 是linux系统虚拟出来的总线, 没有对应的硬件接口
平台总线模型将一个驱动分成了两个部分
device.c
: 描述硬件资源代码, 描述寄存器的地址, 中断号
driver.c
: 控制硬件的驱动代码, 操作寄存器, 处理中断
这两个部分通过相同的name
进行匹配
为什么要使用平台总线, 平台总线的优点
不同的处理器的相同功能的寄存器不在一个位置, 但是使用驱动可以是同一套
device.c描述的硬件资源是
硬件的寄存器的地址, 中断号, 和其他硬件资源
使用下面的结构体描述
struct platform_device {
// 名字, 和driver匹配, 可以在sys目录下看到
const char *name;
// 区分不同的设备, sys目录下的设备文件的后缀(-1无后缀)
int id;
bool id_auto; // 自动设置id, 一般不用
// 设备的通用属性部分, 必须实现里面的release函数
struct device dev;
u64 platform_dma_mask;
struct device_dma_parameters dma_parms;
// 存储资源的个数
u32 num_resources;
// 存放硬件资源的结构体
struct resource *resource;
const struct platform_device_id *id_entry;
const char *driver_override;
/* MFD cell pointer */
struct mfd_cell *mfd_cell;
/* arch specific additions */
struct pdev_archdata archdata;
};
描述硬件资源的结构体
// linux-master/include/linux/ioport.h
struct resource {
resource_size_t start;
resource_size_t end;
const char *name;
unsigned long flags;
unsigned long desc;
struct resource *parent, *sibling, *child;
};
include/linux/ioport.h
路径下列举硬件资源举例
static struct resource my_device_resources[] = {
[0] = {
.start = 0xFDD60000,
.end = 0xFDD60004,
.flags = IORESOURCE_MEM, // 内存类型或寄存器
},
[1] = {
.start = 13,
.end = 13,
.flags= IORESOURCE_IRQ, // 中断类型
},
};
platform设备加卸载函数: 把设备加载到总线上
int platform_device_register(struct platform_device *pdev)
void platform_device_unregister(struct platform_device *pdev)
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 (*resume)(struct platform_device *);
struct device_driver driver;
const struct platform_device_id *id_table;
bool prevent_deferred_probe;
bool driver_managed_dma;
};
platform驱动加卸载函数
const struct platform_device_id mydriver_id_table = {
.name = "mydevice",
};
struct platform driver platform driver test ={
.probe = mydriver_probe,
.remove =mydriver_remove,
.driver = {
.name ="mydevice",
.owner = THIS_MODULE,
}
// id_table的优先级大于drive中的name
.id_table = &mydriver_id_table,
}
int platform_driver_register(struct platform_driver *drv, struct module *owner)
void platform_driver_unregister(struct platform_driver *drv);
平台设备和驱动的匹配方法
static int platform_match(struct device *dev, struct device_driver *drv)
{
...
/* Then try to match against the id table */
if (pdrv->id_table)
return platform_match_id(pdrv->id_table, pdev) != NULL;
/* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0);
}
获取设备资源的函数
platform_get_resource: 返回设备指定类型的第num个资源
struct resource *platform_get_resource(struct platform_device *dev,
unsigned int type, unsigned int num)
{
u32 i;
for (i = 0; i num_resources; i++) {
struct resource *r = &dev->resource[i];
if (type == resource_type(r) && num-- == 0)
return r;
}
return NULL;
}
参与评论
手机查看
返回顶部