• AM335x tscadc platform driver 相关代码跟踪


    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
    ", 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...
    ", 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.
    ");                    
    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.
    ");                 
    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.
    ");                       
    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.
    ");                   
    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
    ");                  
    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 }                                                                               
    
    /* 明天着重跟踪中断请求相关信息。   */
  • 相关阅读:
    硅谷独角兽公司的监控系统长啥样?
    通过jQuery设置全局Ajax加载时呈现Loading
    Jquery遮罩插件,想罩哪就罩哪!
    jquery 读取textarea内容
    easy ui layout 高度 宽度自适应浏览器
    css调节样式
    ORACLE数据库的连接
    spring cloud API网关
    嵌套查询与连接查询的性能
    对于where 1=1 这种条件传入需要'%s'
  • 原文地址:https://www.cnblogs.com/chenfulin5/p/6195809.html
Copyright © 2020-2023  润新知