Platform 概述
1、概述:
通常在Linux中,把SoC系统中集成的独立外设单元(如:I2C、IIS、RTC、看门狗等)都被当作平台设备来处理。
从Linux2.6起,引入了一套新的驱动管理和注册机制:Platform_device和Platform_driver,来管理相应设备。
Linux中大部分的设备驱动,都可以使用这套机制,设备用platform_device表示,驱动用platform_driver进行注册。
Linux platform driver机制和传统的device_driver机制相比,一个十分明显的优势在于platform机制将本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时通过platform_device提供的标准接口进行申请并使用。
这样提高了驱动和资源管理的独立性,并且拥有较好的可移植性和安全性。
对在每个挂在虚拟的platform bus的设备作__driver_attach() ->driver_probe_device()
开始真正的探测,如果probe成功,则绑定设备到该驱动。
定义 platform_device
struct platform_device
{
const char * name;
u32 id;
struct device dev;
u32 num_resources;
struct resource * resource;
};
每个具体的驱动都对应一个这样的结构体。
(注意,这个名字一定要和后面platform_driver.driver->name相同,因为在注册具体的设备驱动时会遍历这个结构体查找相应的数据结构,后面会详细讲解)
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; //资源链表指针
};
主要用于定义具体设备占用的硬件资源(如:地址空间、中断号等;
static void __init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_fb_info);
s3c_i2c0_set_platdata(NULL);
platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
smdk_machine_init();
}
此函数中调用了platform_add_devices() -> platform_device_register()注册platform设备
注册顺序根据同文件夹下的
{
&s3c_device_ohci,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_dm9k,
&s3c24xx_uda134x,
&s3c_device_sdi,
};
结构体进行
这些设备的初始化一般都在arch/arm/plat-s3c24xx/devs.c下
我们以s3c_device_wdt为例进行观察:
/* Watchdog */
//看门狗资源结构体
static struct resource s3c_wdt_resource[] = {
[0] = {
.start = S3C24XX_PA_WATCHDOG,
.end = S3C24XX_PA_WATCHDOG + S3C24XX_SZ_WATCHDOG - 1,
.flags = IORESOURCE_MEM, //看门狗所使用的IO口范围
},
[1] = {
.start = IRQ_WDT,
.end = IRQ_WDT,
.flags = IORESOURCE_IRQ, //看门狗所使用的中断资源
}
};
//定义了一个看门狗结构体
struct platform_device s3c_device_wdt = {
.name = "s3c2410-wdt", //驱动名称
.id = -1, //id号,-1代表自动分配
.num_resources = ARRAY_SIZE(s3c_wdt_resource),
//指定资源数量
.resource = s3c_wdt_resource, //指定资源结构体
};
platform_driver在具体的硬件设备驱动编写中完成:
同plartform_device相似,需要定义并实现以下结构体
{
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 device_driver driver;
};
其中除了一些函数指针外,还有一个一般驱动的device_driver结构。
/*Watchdog平台驱动结构体,平台驱动结构体定义在platform_device.h中,该结构体内的接口函数需要单独实现*/
static struct platform_driver watchdog_driver =
{
.probe = watchdog_probe, /*Watchdog探测函数*/
.remove = __devexit_p(watchdog_remove),/*Watchdog移除函数*/
.shutdown = watchdog_shutdown, /*Watchdog关闭函数*/
.suspend = watchdog_suspend, /*Watchdog挂起函数*/
.resume = watchdog_resume, /*Watchdog恢复函数*/
.driver =
{
/*注意这里的名称一定要和系统中定义平台设备的地方一致,这样才能把平台设备与该平台设备的驱动关联起来*/
.name = "s3c2410-wdt",
.owner = THIS_MODULE,
},
};
static int __init watchdog_init(void)
{
/*将Watchdog注册成平台设备驱动*/
return platform_driver_register(&watchdog_driver);
}
static void __exit watchdog_exit(void)
{
/*注销Watchdog平台设备驱动*/
platform_driver_unregister(&watchdog_driver);
}
module_init(watchdog_init);
module_exit(watchdog_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("linux");
MODULE_DESCRIPTION("S3C2440 Watchdog Driver");
static int __devinit watchdog_probe(struct platform_device *pdev)
{
int ret;
int started = 0;
struct resource *res;/*定义一个资源,用来保存获取的watchdog的IO资源*/
wdt_irqno = platform_get_irq(pdev, 0);
/*申请Watchdog中断服务,这里使用的是快速中断:IRQF_DISABLED。中断服务程序为:wdt_irq,将Watchdog平台设备pdev做参数传递过去了*/
ret = request_irq(wdt_irqno, wdt_irq, IRQF_DISABLED, pdev->name, pdev);
/*获取watchdog平台设备所使用的IO端口资源,注意这个IORESOURCE_MEM标志和watchdog平台设备定义中的一致*/
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
/*申请watchdog的IO端口资源所占用的IO空间(要注意理解IO空间和内存空间的区别),request_mem_region定义在ioport.h中*/
wdt_mem = request_mem_region(res->start, res->end - res->start + 1, pdev->name);
/*将watchdog的IO端口占用的这段IO空间映射到内存的虚拟地址,ioremap定义在io.h中。
注意:IO空间要映射后才能使用,以后对虚拟地址的操作就是对IO空间的操作,*/
wdt_base = ioremap(res->start, res->end - res->start + 1);
return ret;
}
/*Watchdog平台驱动的设备移除接口函数的实现*/
static int __devexit wdt_remove(struct platform_device *dev)
{
/*释放获取的Watchdog平台设备的IO资源*/
release_resource(wdt_mem);
kfree(wdt_mem);
wdt_mem = NULL;
/*同watchdog_probe中中断的申请相对应,在那里申请中断,这里就释放中断*/
free_irq(wdt_irqno, dev);
wdt_irq = NULL;
/*释放获取的Watchdog平台设备的时钟*/
clk_disable(wdt_clock);
clk_put(wdt_clock);
wdt_clock = NULL;
/*释放Watchdog设备虚拟地址映射空间*/
iounmap(wdt_base);
return 0;
}
#ifdef CONFIG_PM
/*定义两个变量来分别保存挂起时的WTCON和WTDAT值,到恢复的时候使用*/
static unsigned long wtcon_save;
static unsigned long wtdat_save;
/*Watchdog平台驱动的设备挂起接口函数的实现*/
static int wdt_suspend(struct platform_device *dev, pm_message_t state)
{
/*保存挂起时的WTCON和WTDAT值*/
wtcon_save = readl(wdt_base + S3C2410_WTCON);
wtdat_save = readl(wdt_base + S3C2410_WTDAT);
/*停止看门狗定时器*/
wdt_start_or_stop(0);
return 0;
}
/*Watchdog平台驱动的设备恢复接口函数的实现*/
static int wdt_resume(struct platform_device *dev)
{
/*恢复挂起时的WTCON和WTDAT值,注意这个顺序*/
writel(wtdat_save, wdt_base + S3C2410_WTDAT);
writel(wtdat_save, wdt_base + S3C2410_WTCNT);
writel(wtcon_save, wdt_base + S3C2410_WTCON);
return 0;
}
#else /*配置内核时没选上电源管理,Watchdog平台驱动的设备挂起和恢复功能均无效,这两个函数也就无需实现了*/
#define wdt_suspend NULL
#define wdt_resume NULL
#endif
Platform 概述相关推荐
- Linux ALSA驱动之Platform源码分析(wm8350.c)
1.Platform概述 ASoC被分为Machine,Platform和Codec三大部件,Platform驱动的主要作用是完成音频数据的管理,最终通过CPU的数字音频接口(DA〉把音频数据传送给C ...
- Linux ALSA 音频系统:物理链路篇
原址 1. Overview 硬件平台及软件版本: Kernel - 3.4.5 SoC - Samsung exynos CODEC - WM8994 Machine - goni_wm8994 U ...
- ALSA-ASOC音频驱动框架简述
##ALSA-ASOC音频驱动框架简述 注意:本文只限于讲解ALSA-ASOC音频驱动框架,不深入到寄存器.时序等配置,文章有不足之处,日后逐渐完善补充 另外多谢两位前辈的博客,学到了很多,多谢. h ...
- knime 大数据_如何使用Knime进行数据科学
knime 大数据 Knime(K是无声的,因此发音为nīm )是一个高度评价的数据分析平台,具有广泛的适用性,并且与其他产品(例如与数据库,语言,机器学习框架和深度学习框架)进行了许多集成. Kni ...
- knime 大数据_如何将KNIME用于数据科学
knime 大数据 . KNIME(K是无声的,因此发音为nīm )是一个高度评价的数据分析平台,具有广泛的适用性,并且与其他产品(例如与数据库,语言,机器学习框架和深度学习框架)进行了许多集成. K ...
- 微软power bi_Microsoft Power Platform快速概述
微软power bi In this article, I am going to explain the various products offered by the Microsoft Powe ...
- BEA WebLogic Platform 8.1 Single Sign-On Enablement:概述
BEA WebLogic Platform 8.1 Single Sign-On Enablement:概述 时间:2004-03-10 作者: 浏览次数: 4162 本文关键字:SSO, 单点登录 ...
- 【Azure Services Platform Step by Step-第5篇】.NET Services 概述
在云端运行应用程序.存储和处理数据只是云计算的一部分.我们还想搭建云端服务(cloud-based services).云端服务当然和普通的服务不同了,需要更多的管理和约束..NET Services ...
- MIT Graph实践概述
MIT Graph实践概述 Features功能 • iCloud Support • Multi Local & Cloud Graphs • Thread Safe • Store Any ...
最新文章
- CNN如何用于NLP任务?一文简述文本分类任务的7个模型(附代码)
- HIve分组查询返回每组的一条记录
- 13.执行外部命令subprocess
- python中数组的维度_Python数组维度问题
- es6 --- Promise封装读取文件操作
- 开着开着,Model S天窗飞了!特斯拉回应...
- 弱引用WeakReference
- 当下大数据体系的4个热点,4个趋势和3个问题
- 学计算机辐射,离散数学对计算机专业系统知识辐射作用.doc
- asp.net core3.0 mvc 用 autofac
- Android Google Map –两点之间的绘图路线
- Python库的下载及导入使用教程
- flash 10 android,adobe flash 10.0.0
- python 查询ip工具
- 32 Pin和 8 Pin(引脚 )flash烧录操作指导
- 使用python对微信好友进行数据分析
- yolov5s.pt下载
- Doc2Vec 模型参数
- 文件怎么复制到虚拟机中的linux系统吗,Windows下的文件如何复制到虚拟机的Linux中...
- 计算机辅助翻译政府工作报告,Trados辅助翻译软件在科技英语翻译中的应用