linux platform设备与驱动
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;
};
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 */
enum probe_type probe_type;
const struct of_device_id *of_match_table; //device tree通过这个去匹配
const struct acpi_device_id *acpi_match_table;
int (*probe) (struct device *dev);
int (*remove) (struct device *dev);
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_t state);
int (*resume) (struct device *dev);
const struct attribute_group **groups;
const struct dev_pm_ops *pm;
struct driver_private *p;
};
struct platform_device {
const char *name;
int id;
bool id_auto;
struct device dev;
u32 num_resources;
struct resource *resource;
const struct platform_device_id *id_entry;
char *driver_override; /* Driver name to force a match */
/* MFD cell pointer */
struct mfd_cell *mfd_cell;
/* arch specific additions */
struct pdev_archdata archdata;
};
以上是头文件的结构体定义
static const struct of_device_id dw_spi_mmio_of_match[] = {
{ .compatible = "snps,dw-apb-ssi", },
{ /* end of table */}
};
MODULE_DEVICE_TABLE(of, dw_spi_mmio_of_match);
static struct platform_driver dw_spi_mmio_driver = {
.probe = dw_spi_mmio_probe,
.remove = dw_spi_mmio_remove,
.driver = {
.name = DRIVER_NAME,
.of_match_table = dw_spi_mmio_of_match,
},
};
module_platform_driver(dw_spi_mmio_driver);
MODULE_AUTHOR("Jean-Hugues Deschenes <jean-hugues.deschenes@octasic.com>");
MODULE_DESCRIPTION("Memory-mapped I/O interface driver for DW SPI Core");
MODULE_LICENSE("GPL v2");
以前的写法 :
struct platform_device s3c_device_usb = {
.name = "s3c2410-ohci", //s3c6410-usb
.id = -,
.num_resources = ARRAY_SIZE(s3c_usb_resource),
.resource = s3c_usb_resource,
.dev = {
.dma_mask = &s3c_device_usb_dmamask,
.coherent_dma_mask = 0xffffffffUL
}
};
有了platform_device就可以调用函数platform_add_devices向系统中添加该设备了。系统中的设备资源都可以采用这种方式列举在一起,然后成一个指针数组,如:
static struct platform_device *smdk6410_devices[] __initdata = {
......
&s3c_device_usbgadget,
&s3c_device_usb, //jeff add.
......
}
static struct platform_driver ohci_hcd_s3c2410_driver = {
.probe = ohci_hcd_s3c2410_drv_probe,
.remove = ohci_hcd_s3c2410_drv_remove,
.shutdown = usb_hcd_platform_shutdown,
/*.suspend = ohci_hcd_s3c2410_drv_suspend, */
/*.resume = ohci_hcd_s3c2410_drv_resume, */
.driver = {
.owner = THIS_MODULE,
.name = "s3c2410-ohci",
},
};
()在内核初始化时kernel_init()->do_basic_setup()->driver_init()->platform_bus_init()初始化platform_bus(虚拟总线);
(2)设备注册的时候platform_device_register()->platform_device_add()->(pdev->dev.bus = &platform_bus_type)把设备挂在虚拟的platform bus下;
()驱动注册的时候platform_driver_register()->driver_register()->bus_add_driver()->driver_attach()->bus_for_each_dev(),对每个挂在虚拟的
platform bus的设备作__driver_attach()->driver_probe_device(),判断drv->bus->match()是否存在并且是否执行成功,此时通过指针执行platform_match,
比较strncmp(pdev->name, drv->name, BUS_ID_SIZE),如果相符就调用really_probe(实际就是执行的相应设备的platform_driver->probe(platform_device),
注意platform_drv_probe的_dev参数是由bus_for_each_dev的next_device获得)开始真正的探测加载,如果probe成功则绑定该设备到该驱动。
当进入probe函数后,需要获取设备的资源信息,根据参数type所指定类型,例如IORESOURCE_MEM,来分别获取指定的资源。
struct resource * platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);当然,也可以固定资源类型,
如获取资源中的中断号:struct int platform_get_irq(struct platform_device *dev, unsigned int num);
probe函数一般完成硬件设备使能,struct resource的获取以及虚拟地址的动态映射和具体类型设备的注册(因为平台设备只是一种虚拟的设备类型);
remove函数完成硬件设备的关闭,struct resource以及虚拟地址的动态映射的释放和具体类型设备的注销。只要和内核本身运行依赖性不大的外围设备
( 换句话说只要不在内核运行所需的一个最小系统之内的设备 ), 相对独立的拥有各自独自的资源 (addresses and IRQs) ,都可以用platform_driver 实现。
如:lcd,usb,uart 等,都可以用platfrom_driver 写,而timer,irq等最小系统之内的设备则最好不用platfrom_driver 机制,实际上内核实现也是这样的。
http://blog.csdn.net/zhandoushi1982/article/details/5130207
http://blog.csdn.net/lichengtongxiazai/article/details/38941997 DT书写规范
http://www.right.com.cn/forum/thread-146260-1-1.html DT(2)
http://blog.csdn.net/zengxianyang/article/details/50732929 DT驱动写法
http://blog.csdn.net/21cnbao/article/details/8457546 DT宋宝华
http://www.cnblogs.com/dyllove98/archive/2013/07/03/3170178.html 获取DT资源
http://blog.csdn.net/zqixiao_09/article/details/50888795 platform_device字符驱动
linux platform设备与驱动的更多相关文章
- Linux下platform设备以及platform设备和驱动注册的先后顺序
platform是Linux系统提供的一种管理设备的手段,所有SOC系统中集成的独立的外设控制器.挂接在SOC内存空间的外设等都属Platform设备.如ARM S3C6410处理器中,把内部集成的I ...
- Linux platform设备简介
Technorati 标签: Linux platform Linux在2.6内核中,针对一系列设备驱动,提供新的管理框架,成为platform机制,推出的目的,在于隔离驱动的资源和实现,使得 ...
- Linux内核驱动学习(四)Platform设备驱动模型
Linux platform设备驱动模型 文章目录 Linux platform设备驱动模型 前言 框架 设备与驱动的分离 设备(device) 驱动(driver) 匹配(match) 参考 前言 ...
- linux设备驱动归纳总结(九):1.platform总线的设备和驱动【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-111745.html linux设备驱动归纳总结(九):1.platform总线的设备和驱动 xxxx ...
- 【linux设备模型】之platform设备驱动
一.platform总线.设备和驱动 platform是一种虚拟总线,对应的设备称为platform_device,对应的驱动称为platform_driver. platform_devic ...
- Linux Platform驱动模型(一)-设备信息
我在Linux字符设备驱动框架一文中简单介绍了Linux字符设备编程模型,在那个模型中,只要应用程序open()了相应的设备文件,就可以使用ioctl通过驱动程序来控制我们的硬件,这种模型直观,但是从 ...
- Linux platform平台总线、平台设备、平台驱动
平台总线(platform_bus)的需求来源? 随着soc的升级,S3C2440->S3C6410->S5PV210->4412,以前的程序就得重新写一遍,做着大量的重复工作, 人 ...
- Linux Platform驱动模型(一) _设备信息
我在Linux字符设备驱动框架一文中简单介绍了Linux字符设备编程模型,在那个模型中,只要应用程序open()了相应的设备文件,就可以使用ioctl通过驱动程序来控制我们的硬件,这种模型直观,但是从 ...
- Linux Platform devices 平台设备驱动
设备总线驱动模型:http://blog.csdn.net/lizuobin2/article/details/51570196 本文主要参考:http://www.wowotech.net/devi ...
随机推荐
- Android中锁定文件的方法
androidSDK中并没有锁定文件相关的api. 但是android是基于linux操作系统的,linux比较底层,灵活性也更大,为了实现锁定文件的效果,大概有以下几种办法: 用chmod命令修改文 ...
- HTML 接收本地文件
HTML代码请把文件拖到下面的框里触发drop事件读取拖放的文件常用情况:结合XMLHttpRequest和拖放文件实现上传查看和管理本地文件和图片 <!DOCTYPE HTML> < ...
- python3的编码问题
Python3对文本(str)和二进制数据(bytes)作了更为清晰的区分. 文本默认是以Unicode编码(python2默认是ascii),由str类型表示,二进制数据则由bytes类型表示. s ...
- apache如何解决跨域资源访问
很多时候,大中型网站为了静态资源分布式部署,加快访问速度,减轻主站压力,会把静态资源(例如字体文件.图片等)放在独立服务器或者CDN上,并且使用独立的资源域名(例如res.test.com) 但是在实 ...
- c/c++ 缓冲区的刷新
利用string 对象查看缓冲区的变化,因为每个string对象在输入时会以空格作为分界. #include<iostream> #include<string> using ...
- jquery 替换文本内容
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...
- iOS 之各种Crash
1.*** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position ...
- JS中获得当前时间的年月
//获取完整的日期 var date=new Date; var year=date.getFullYear(); var month=date.getMonth()+1; month =(month ...
- Docker上ubuntu新建用户的网络访问不通问题
背景 作为一个生命不息,折腾不止的码农.各种操作系统被我不知道搞崩了多少次,无数个夜晚连夜抢修数据,重装系统,那个累啊!! Option 1:备份.数据可以备份,配置可以备份,安装包可以备份.但是安装 ...
- 给钛度产品的一些建议(Note)
背景:上一只鼠标坏了,今天299从京东如了一只钛度鼠标,核心用料据说都很高端,设计也不错.但是实际用起来发现了很多码农常识问题和产品建议,遂反馈给钛度客服,并记录于此. 传送门: http://bbs ...