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 }                                                                               

/* 明天着重跟踪中断请求相关信息。   */
原文地址:https://www.cnblogs.com/chenfulin5/p/6195809.html