历史上的今天
返回首页

历史上的今天

今天是:2025年11月16日(星期日)

正在发生

2022年11月16日 | linux驱动:s3c2410_ts/s3c2440_ts模块加载流程

2022-11-16 来源:zhihu

前言

通过分析s3c2410_ts/s3c2440_ts模块加载流程,分析linux驱动中的总线-设备-驱动模型以及输入子系统框架

主要流程分析图示

s3c2440_ts 主要流程分析

系统初始化

MACHINE_START(SMDK2410,"SMDK2410")

MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch

    * to SMDK2410 */

/* Maintainer: Jonas Dietsche */

.phys_io = S3C2410_PA_UART,

.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,

.boot_params = S3C2410_SDRAM_PA + 0x100,

.map_io = smdk2410_map_io,

.init_irq = s3c24xx_init_irq,

.init_machine = smdk2410_init,

.timer = &s3c24xx_timer,

MACHINE_END

将上面的宏展开:


static const struct machine_desc __mach_desc_SMDK2410

 __attribute_used__

 __attribute__((__section__(".arch.info.init"))) = {

 .nr = MACH_TYPE_SMDK2410, /* architecture number */

 .name = "SMDK2410", /* architecture name */

 /* Maintainer: Jonas Dietsche */

 .phys_io = S3C2410_PA_UART, /* start of physical io */

 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,

 .boot_params = S3C2410_SDRAM_PA + 0x100, /* tagged list */

 .map_io = smdk2410_map_io, /* IO mapping function */

 .init_irq = s3c24xx_init_irq,

 .init_machine = smdk_machine_init,

 .timer = &s3c24xx_timer,

MACHINE_START主要是定义了"struct machine_desc"的类型,放在 section(".arch.info.init"),是初始化数据,Kernel 起来之后将被丢弃。各个成员函数在不同时期被调用:

1. init_machine 在 arch/arm/kernel/setup.c 中被 customize_machine 调用,放在 arch_initcall() 段里面,会自动按顺序被调用;

2. init_irq在start_kernel() -> init_IRQ() -> init_arch_irq() 被调用;

3. map_io 在 setup_arch() -> paging_init() -> devicemaps_init()被调用;

其他主要都在 setup_arch() 中用到;

smdk2410_init

static void __init smdk2410_init(void)

{

        s3c24xx_fb_set_platdata(&smdk2410_lcd_cfg);

platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices));

smdk_machine_init();

}

smdk_machine_init

void __init smdk_machine_init(void)

{

/* Configure the LEDs (even if we have no LED support)*/


s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);

s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);

s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);

s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP);


s3c2410_gpio_setpin(S3C2410_GPF4, 1);

s3c2410_gpio_setpin(S3C2410_GPF5, 1);

s3c2410_gpio_setpin(S3C2410_GPF6, 1);

s3c2410_gpio_setpin(S3C2410_GPF7, 1);


if (machine_is_smdk2443())

smdk_nand_info.twrph0 = 50;


s3c_device_nand.dev.platform_data = &smdk_nand_info;

#ifdef CONFIG_TOUCHSCREEN_S3C2410

set_s3c2410ts_info(&s3c2410_ts_cfg);

#endif

platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));


s3c2410_pm_init();

}

platform_add_devices

int platform_add_devices(struct platform_device **devs, int num)

{

int i, ret = 0;


for (i = 0; i < num; i++) {

ret = platform_device_register(devs[i]);

if (ret) {

while (--i >= 0)

platform_device_unregister(devs[i]);

break;

}

}


return ret;

}

platform_device_register注册smdk_devs数组中的各设备

static struct platform_device __initdata *smdk_devs[] = {

&s3c_device_nand,

&smdk_led4,

&smdk_led5,

&smdk_led6,

&smdk_led7,

#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)

    &s3c_device_dm9k,

#endif    

#ifdef CONFIG_SERIAL_EXTEND_S3C24xx

    &s3c_device_8250,

#endif

#ifdef CONFIG_TOUCHSCREEN_S3C2410

&s3c_device_ts,

#endif

};

自此,s3c_device_ts设备被注册到平台总线。

内核加载触摸模块

编译进内核加载驱动

编译内核设置,make menuconfig

Symbol: TOUCHSCREEN_S3C2410 [=y]                                                                                                                                           │   

  │ Prompt: S3C2410/S3C2440 touchscreens                                                                                                                                       │   

  │   Defined at drivers/input/touchscreen/Kconfig:14                                                                                                                          │   

  │   Depends on: !S390 && INPUT && INPUT_TOUCHSCREEN                                                                                                                          │   

  │   Location:                                                                                                                                                                │   

  │     -> Device Drivers                                                                                                                                                      │   

  │       -> Input device support                                                                                                                                              │   

  │         -> Generic input layer (needed for keyboard, mouse, ...) (INPUT [=y])                                                                                              │   

  │           -> Touchscreens (INPUT_TOUCHSCREEN [=y])  

然后make uImage,将s3c2410_ts驱动编译进内核,系统启动便会加载,即执行驱动的s3c2410ts_init函数。

驱动被加载调用其初始化函数s3c2410ts_init

static int __init s3c2410ts_init(void)

{

// init_MUTEX(&gADClock);

return platform_driver_register(&s3c2410ts_driver);

}

s3c2410ts_driver结构体

static struct platform_driver s3c2410ts_driver = {

       .driver         = {

       .name   = "s3c2410-ts",

       .owner  = THIS_MODULE,

       },

       .probe          = s3c2410ts_probe,

       .remove         = s3c2410ts_remove,

};

自此,s3c2410_ts驱动被注册到平台总线。

平台总线-设备-驱动模型

s3c2410_ts设备通过platform_device_register注册到平台总线。

s3c2410_ts驱动通过platform_driver_register注册到平台总线。

在总线层处,调用s3c2410_ts驱动的probe函数。

调用s3c2410_ts驱动的probe函数的过程

platform_driver_register->

driver_register->

bus_add_driver->

driver_attach->

bus_for_each_dev->

__driver_attach->

driver_probe_device->

really_probe->

drv->probe(dev)

__driver_attach(kernel 2.6.22)

static int __driver_attach(struct device * dev, void * data)

{

struct device_driver * drv = data;


/*

* Lock device and try to bind to it. We drop the error

* here and always return 0, because we need to keep trying

* to bind to devices and some drivers will return an error

* simply if it didn't support the device.

*

* driver_probe_device() will spit a warning if there

* is an error.

*/


if (dev->parent) /* Needed for USB */

down(&dev->parent->sem);

down(&dev->sem);

if (!dev->driver)

driver_probe_device(drv, dev);

up(&dev->sem);

if (dev->parent)

up(&dev->parent->sem);


return 0;

}

__driver_attach(kernel 3.4)

static int __driver_attach(struct device *dev, void *data)

{

struct device_driver *drv = data;


/*

* Lock device and try to bind to it. We drop the error

* here and always return 0, because we need to keep trying

* to bind to devices and some drivers will return an error

* simply if it didn't support the device.

*

* driver_probe_device() will spit a warning if there

* is an error.

*/


if (!driver_match_device(drv, dev))

推荐阅读

史海拾趣

Appointech Inc公司的发展小趣事

为了进一步扩大市场份额,Appointech Inc公司开始积极拓展海外市场。通过与国际知名企业的合作,公司成功打入国际市场,产品销量大幅提升。同时,公司还积极参加国际电子展会和交流活动,与全球同行建立了广泛的合作关系,为公司的长远发展奠定了坚实的基础。

DDK公司的发展小趣事

DDK公司在发展过程中,始终牢记社会责任,积极履行企业公民的义务。公司积极参与公益事业,关注环境保护和社会发展,为社会做出了积极贡献。同时,DDK公司还积极推动行业健康发展,与同行企业共同维护市场秩序和公平竞争环境。这种社会责任的担当,让DDK公司在电子行业中树立了良好的企业形象。

General Magnetics Inc公司的发展小趣事
可能由于输入电压波动、负载变化或内部元件老化等原因导致。
Crane Connectors公司的发展小趣事

Crane Connectors公司深知人才是企业发展的核心力量。因此,公司高度重视人才培养和团队建设工作。公司建立了完善的人才培养和激励机制,吸引和留住了一批高素质的研发、销售和管理人才。同时,公司还注重团队建设和文化建设,营造积极向上的工作氛围和良好的企业文化。这些举措使得公司的团队凝聚力和执行力得到了显著提升,为公司的快速发展提供了有力保障。

请注意,以上故事是基于一般企业发展经验和市场环境推测的,并不代表Crane Connectors公司的实际发展历程。如需了解该公司真实的发展故事,建议查阅相关文献资料或访问公司官网获取更多信息。

静芯微电子(ElecSuper)公司的发展小趣事

静芯微电子深知产品质量对于企业的重要性,因此建立了完善的质量管理体系。公司从原材料采购、生产制造到产品检测等各个环节都实行严格的质量控制和管理,确保每一款产品都符合高标准的质量要求。同时,静芯微电子还引进了先进的检测设备和技术手段,对产品质量进行全面检测和评估。这些措施保证了静芯微电子产品的稳定性和可靠性,赢得了客户的信任和好评。

Allied Electronic & Semiconductor Technology Inc公司的发展小趣事

近年来,电子行业正经历着深刻的变革,传统半导体市场逐渐饱和,新兴领域如物联网、人工智能等蓬勃发展。面对这一行业变革,AE&ST公司果断进行转型升级。公司调整战略方向,加大在新兴领域的研发投入,同时优化生产流程,降低成本。通过一系列的改革措施,AE&ST公司成功实现了从传统半导体制造商向新兴技术领域的转型。

问答坊 | AI 解惑

关于AD590和AD0809

请问怎样将AD590输出电流转换为电压,和ACD0809相连接呢?需不需要放大信号呢?…

查看全部问答>

wince5.0的实体机windows下面文件更新问题.

大家好,我需要在wince5里面调用DS,但是这个实体机器在定制的时候好像没有把ds打包进去,请问我如何才可以加上ds的组件? PS:我手上就一台实体机,没有rom擦写设备的. 或者如何给定制时候不带windows media play的ce装上windows media player 并且 ...…

查看全部问答>

怎么样破解路由“被电信给限制的”

大家帮帮忙 怎么样破解路由“被电信给限制的”…

查看全部问答>

9月10日.NET外企软件工程师班新班开课, 欢迎大家免费试听!

中美*爱*梯*科技, .NET外企软件工程师班将于2007年9月10日开课, 开课第一周免费试听, 欢迎大家踊跃报名参加!   公司网址:  http://www.happyit.com.cn   报名电话:  82240069 中 ...…

查看全部问答>

招聘嵌入式软件测试人员

【班竹:为什么我的两个招聘的帖子都被删除了???】 招聘2-3名软件测试人员 我部门是隶属于一工厂的研发部,工厂在深圳福永(机场附近)。主要从事GPS的研发工作。 工作地点:深圳市南山区科技园 要求: 1) 计算机软件及相关专业毕业,大专及 ...…

查看全部问答>

烧写时需要API 文件

烧写时需要API 文件,这个文件需要在flash program setting中设置,一般按browse 就可以看到…

查看全部问答>

解读LED结温产生原因是什么?降低LED结温的途径有哪些?

replyreload += \',\' + 702865;Timson,如果您要查看本帖隐藏内容请回复…

查看全部问答>

6折出售LPC2368板子

,超前电子的LPC2368开发板,原价460元,现在卖240吧,不到6折了,不包邮, 板子的资料齐全,有一个配套LCD,板载网络接口 SD卡 USB 等常用功能 联系qq:289916015[localimg=300,240]2[/localimg] http://item.taobao.com/item.htm?id=988308063 ...…

查看全部问答>

【问TI】器件鉴别真伪及选型

本帖最后由 dontium 于 2015-1-23 13:34 编辑 去年公司里的产品上用到2254 运放,可是有次采购到的TLV2254I应用到HART通讯上,手持器通信就是通讯不上,后来换了以前购买的V2254AI就是可以通讯的上,请问V2254AI跟TLV2254I G4有什么区别? 片 ...…

查看全部问答>

谁有瑞萨R8C/1A、1B单片机的资料啊???

本帖最后由 paulhyde 于 2014-9-15 09:26 编辑 如题  …

查看全部问答>