TI AM335x ti am335x_tsc.c 代码跟踪

在kernel 首层目录:

先运行make ARCH=arm tags

这个作用是建立tags文件,只含有arm架构的,利用ctag即可进行跟中代码。

drivers/input/touchscreen/ti_am335x_tsc.c

看到代码最后,
module_platform_driver(ti_tsc_driver); 其实跟进入有如下定义:
#define module_platform_driver(__platform_driver) \
module_driver(__platform_driver, platform_driver_register, \
platform_driver_unregister) 其实最终有如下定义:
#define module_driver(__driver, __register, __unregister, ...) \
static int __init __driver##_init(void) \
{ \
return __register(&(__driver) , ##__VA_ARGS__); \
} \
module_init(__driver##_init); \
static void __exit __driver##_exit(void) \
{ \
__unregister(&(__driver) , ##__VA_ARGS__); \
} \
module_exit(__driver##_exit); 整合便是如下代码:
static int __init ti_tsc_driver_init(void)
{
return platform_driver_register(&(ti_tsc_driver) , ##__VA_ARGS__);
}
module_init(ti_tsc_driver_init);
static void __exit ti_tsc_driver_exit(void)
{
platform_driver_unregister(&(ti_tsc_driver) , ##__VA_ARGS__);
}
module_exit(ti_tsc_driver_exit); 相当于新版kernel将本来用做的kernel __init platform_driver_register 所有的必须做的事情通过一个module_platform_driver(driver);都做完了。
这里我们看到他注册了一个平台设备驱动,有关ti_tsc_driver。 platform_driver_register()这个函数就是将平台驱动进行了注册。
也就是说
568 int __platform_driver_register(struct platform_driver *drv,
569 struct module *owner)
570 {
571 drv->driver.owner = owner;
572 drv->driver.bus = &platform_bus_type;
573 drv->driver.probe = platform_drv_probe;
574 drv->driver.remove = platform_drv_remove;
575 drv->driver.shutdown = platform_drv_shutdown;
576
577 return driver_register(&drv->driver);
578 }
579 EXPORT_SYMBOL_GPL(__platform_driver_register); driver_register()
drivers/base/driver.c
148 int driver_register(struct device_driver *drv)
149 {
150 int ret;
151 struct device_driver *other;
152
153 BUG_ON(!drv->bus->p);
154
155 if ((drv->bus->probe && drv->probe) ||
156 (drv->bus->remove && drv->remove) ||
157 (drv->bus->shutdown && drv->shutdown))
158 printk(KERN_WARNING "Driver '%s' needs updating - please use "
159 "bus_type methods\n", drv->name);
160 /* 验证这个驱动是否重名 */
161 other = driver_find(drv->name, drv->bus);
162 if (other) {
163 printk(KERN_ERR "Error: Driver '%s' is already registered, "
164 "aborting...\n", drv->name);
165 return -EBUSY;
166 }
167 /* 将驱动添加到总线 */
168 ret = bus_add_driver(drv);
169 if (ret)
170 return ret;
171 ret = driver_add_groups(drv, drv->groups); /* 添加到所属组 */
172 if (ret) {
173 bus_remove_driver(drv);
174 return ret;
175 }
176 kobject_uevent(&drv->p->kobj, KOBJ_ADD);
177
178 return ret;
179 }
180 EXPORT_SYMBOL_GPL(driver_register); 下面看一下ti_tsc_driver 这个驱动中包含什么东西。
553 static struct platform_driver ti_tsc_driver = {
554 .probe = titsc_probe,
555 .remove = titsc_remove,
556 .driver = {
557 .name = "TI-am335x-tsc",
558 .pm = TITSC_PM_OPS,
559 .of_match_table = ti_tsc_dt_ids,
560 },
561 }; 在很早以前我写过有关平台总线相关的东西,现在想起来也记不太清了。 include/linux/platform_device.h
平台驱动结构体:
174 struct platform_driver {
175 int (*probe)(struct platform_device *);
176 int (*remove)(struct platform_device *);
177 void (*shutdown)(struct platform_device *);
178 int (*suspend)(struct platform_device *, pm_message_t state);
179 int (*resume)(struct platform_device *);
180 struct device_driver driver;
181 const struct platform_device_id *id_table;
182 bool prevent_deferred_probe;
183 };
184
185 #define to_platform_driver(drv) (container_of((drv), struct platform_driver, \
186 driver)) 上面首先将probe,remove,driver,直接定义过去。
使用module_platform_driver(ti_tsc_driver); 进行注册平台驱动。
我现在假定平台驱动与设备已经match成功。
那么,他将运行他的probe 函数。
titsc_probe:
404 static int titsc_probe(struct platform_device *pdev)
405 {
406 struct titsc *ts_dev;
407 struct input_dev *input_dev;
408 struct ti_tscadc_dev *tscadc_dev = ti_tscadc_dev_get(pdev);
409 int err;
410
411 /* Allocate memory for device */
412 ts_dev = kzalloc(sizeof(struct titsc), GFP_KERNEL);
413 input_dev = input_allocate_device();
/* 申请一个输入设备结构体 */
/* 判断ts_dev input_dev 如果有不存在就报错 */
414 if (!ts_dev || !input_dev) {
415 dev_err(&pdev->dev, "failed to allocate memory.\n");
416 err = -ENOMEM;
417 goto err_free_mem;
418 }
419 /* 赋值,初始化 */
420 tscadc_dev->tsc = ts_dev;
421 ts_dev->mfd_tscadc = tscadc_dev;
422 ts_dev->input = input_dev;
423 ts_dev->irq = tscadc_dev->irq;
424 /* 解析设备树相关信息 */
425 err = titsc_parse_dt(pdev, ts_dev);
426 if (err) {
427 dev_err(&pdev->dev, "Could not find valid DT data.\n");
428 goto err_free_mem;
429 }
430 /* 绑定中断函数, */
431 err = request_irq(ts_dev->irq, titsc_irq,
432 IRQF_SHARED, pdev->dev.driver->name, ts_dev);
433 if (err) {
434 dev_err(&pdev->dev, "failed to allocate irq.\n");
435 goto err_free_mem;
436 }
437
438 if (device_may_wakeup(tscadc_dev->dev)) {
439 err = dev_pm_set_wake_irq(tscadc_dev->dev, ts_dev->irq);
440 if (err)
441 dev_err(&pdev->dev, "irq wake enable failed.\n");
442 }
443 /* 设置中断寄存器相关状态 */
444 titsc_writel(ts_dev, REG_IRQSTATUS, IRQENB_MASK);
445 titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES);
446 titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_EOS);
447 err = titsc_config_wires(ts_dev);
448 if (err) {
449 dev_err(&pdev->dev, "wrong i/p wire configuration\n");
450 goto err_free_irq;
451 }
452 titsc_step_config(ts_dev);
453 titsc_writel(ts_dev, REG_FIFO0THR,
454 ts_dev->coordinate_readouts * 2 + 2 - 1);
455
456 input_dev->name = "ti-tsc";
457 input_dev->dev.parent = &pdev->dev;
458
459 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
460 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
461
462 input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
463 input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
464 input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
465
466 /* register to the input system */
467 err = input_register_device(input_dev);
468 if (err)
469 goto err_free_irq;
470
471 platform_set_drvdata(pdev, ts_dev);
472 return 0;
473
474 err_free_irq:
475 dev_pm_clear_wake_irq(tscadc_dev->dev);
476 free_irq(ts_dev->irq, ts_dev);
477 err_free_mem:
478 input_free_device(input_dev);
479 kfree(ts_dev);
480 return err;
481 } /* 明天着重跟踪中断请求相关信息。 */

AM335x tscadc platform driver 相关代码跟踪的更多相关文章

  1. 为AM335x移植Linux内核主线代码(35)使用platform中的GPIO

    http://www.eefocus.com/marianna/blog/15-02/310352_46e8f.html 使用GPIO,当然可以自己编写驱动,比如之前的第34节,也可以使用Kernel ...

  2. msm audio platform 驱动代码跟踪

    sound/soc/soc-core.c static int __init snd_soc_init(void) { #ifdef CONFIG_DEBUG_FS snd_soc_debugfs_r ...

  3. openstack学习笔记一 虚拟机启动过程代码跟踪

    openstack学习笔记一 虚拟机启动过程代码跟踪 本文主要通过对虚拟机创建过程的代码跟踪.观察虚拟机启动任务状态的变化,来透彻理解openstack各组件之间的作用过程. 当从horizon界面发 ...

  4. 从串口驱动的移植看linux2.6内核中的驱动模型 platform device & platform driver【转】

    转自:http://blog.csdn.net/bonnshore/article/details/7979705 写在前面的话: 博主新开了个人站点:你也可以在这里看到这篇文章,点击打开链接 本文是 ...

  5. 命令行方式使用abator.jar生成ibatis相关代码和sql语句xml文件

    最近接手一个老项目,使用的是数据库是sql server 2008,框架是springmvc + spring + ibatis,老项目是使用abator插件生成的相关代码,现在需要增加新功能,要添加 ...

  6. myBatis自动生成相关代码文件配置(Maven)

    pom.xml文件添加配置 <build> <finalName>generator</finalName> <plugins> <!-- mav ...

  7. 使用Mybatis Generator自动生成Mybatis相关代码

    本文将简要介绍怎样利用Mybatis Generator自动生成Mybatis的相关代码: 一.构建一个环境: 1. 首先创建一个表: CREATE TABLE pet (name VARCHAR(2 ...

  8. 设备驱动基础学习--platform driver简单实现

    platform是一条虚拟的总线.设备用platform_device表示,驱动用platform_driver进行注册,Linux platform driver机制和传统的device drive ...

  9. [ARM] Cortex-M Startup.s启动文件相关代码解释

    1. 定义一个段名为CSTACK, 这里: NOROOT表示如何定义的段没有被关联,那么同意会被优化掉,如果不想被优化掉就使用ROOT. 后面的括号里数字表示如下: (1):这个段是2的1次方即2字节 ...

随机推荐

  1. UDP通信

    package com.slp; import java.io.IOException; import java.net.DatagramPacket; import java.net.Datagra ...

  2. ie11的DOM管理器报错

    IE11 Windows7下F12 DOC资源管理器不能用Exception in window.onload: Error: An error has ocurredJSPlugin.3005--- ...

  3. [筆記] Ubuntu Linux 使用 apt-get 指令移除軟體並清理遺留的垃圾

    This is come from    http://blog.lyhdev.com/2013/01/ubuntu-linux-apt-get.html 在 Ubuntu 下移除某個軟體套件,使用的 ...

  4. [转]extjs grid的Ext.grid.CheckboxSelectionModel默认选中解决方法

    原文地址:http://379548695.iteye.com/blog/1167234 grid的复选框定义如下:   var sm = new Ext.grid.CheckboxSelection ...

  5. 怎么在MindManager中查看打印预览

    在MindManager2016思维导图中打印导图之前,可以先进行预览,MindManager和其他很多应用程序一样都带有打印预览功能,该功能提供了再次检查的机会,避免打印出错,MindManager ...

  6. Python3 Socket网络编程

    Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. socket起源于UNIX,在 ...

  7. iOS XCode7制作.Framework动态库和.a静态库的总结

    一.开发SDK时的支持情况: OC语言制作动态库时,支持iOS8+:OC语言制作静态库,支持iOS7+. Swift语言制作动态库时,支持iOS8+;Swift不支持静态库. 对于SDK来说,支持情况 ...

  8. 搜索框(Thinkphp5.0)

    1.普通关键词搜索框 模板部分代码: <form name='searchform' action='/index.php/module/controller/search' method='g ...

  9. SocketServer

    SocketServer是基于socket写成的一个更强大的模块. SocketServer简化了网络服务器的编写.它有4个类:TCPServer,UDPServer,UnixStreamServer ...

  10. Asp.net C# 把 Datatable转换成JSON 字符串

    First of all, we have to fetch the records from the database (MS Sqlserver) into the C# DataTable, o ...