ze550kl-关于mutex_lock的bug

本文分析了一起触摸屏手势识别过程中的bug,涉及到mutex_lock的使用和设备唤醒状态的检查。主要关注了在fts_read_Gestruedata函数中锁的异常情况及其对后续操作的影响,以及在设备唤醒状态检查函数proximity_check_status中的mutex_enable_mutex初始化失败导致的问题。通过对比日志文件,详细解释了问题发生的上下文和解决思路。
摘要由CSDN通过智能技术生成
遇到一个bug:
    bug的lastshutdowm的log如下:
task: ffffffc0a7591300 ti: ffffffc0a715c000 task.ti: ffffffc0a715c000
PC is at __mutex_lock_slowpath+0x124/0x21c
LR is at __mutex_lock_slowpath+0x114/0x21c
看起来的mutex_lock出问题了
往前看log,发现是在
[Focal][Touch] ftxxxx_ts_interrupt: tpd fts_read_Gestruedata state=1
[Focal][Touch] fts_read_Gestruedata : tpd read FTS_GESTRUE_POINTS_HEADER.
fts_read_Gestruedata这个函数里
而在这个函数往下追看到了这个锁
static void check_gesture(struct ftxxxx_ts_data *data, int gesture_id)
{
bool Ps_status = false;


// printk(KERN_EMERG "[Focal][Touch] %s :  gesture_id = 0x%x\n ", __func__, gesture_id);
if(!ftxxxx_ts->cover_mode_states)
Ps_status = proximity_check_status();//这个函数里的
if (!Ps_status) {
switch (gesture_id) {
/* ++++ touch gesture mode support part in ZE500CL ++++ */

case GESTURE_DOUBLECLICK:
if(dclick_flags==true)
{
input_report_key(data->input_dev, KEY_GESTURE_U, 1);
input_sync(data->input_dev);
input_report_key(data->input_dev, KEY_GESTURE_U, 0);
input_sync(data->input_dev);
printk(KERN_EMERG "[Focal][Touch] double click\n");
dclick_flags=false;
}
break;
case GESTURE_V:
input_report_key(data->input_dev, KEY_GESTURE_V, 1);
input_sync(data->input_dev);
input_report_key(data->input_dev, KEY_GESTURE_V, 0);
input_sync(data->input_dev);
printk(KERN_EMERG"[Focal][Touch] click GESTURE_V\n");

break;


case GESTURE_Z:
input_report_key(data->input_dev, KEY_GESTURE_Z, 1);
input_sync(data->input_dev);
input_report_key(data->input_dev, KEY_GESTURE_Z, 0);
input_sync(data->input_dev);
printk(KERN_EMERG "[Focal][Touch] click GESTURE_Z\n");

break;
case GESTURE_E:
input_report_key(data->input_dev, KEY_GESTURE_E, 1);
input_sync(data->input_dev);
input_report_key(data->input_dev, KEY_GESTURE_E, 0);
input_sync(data->input_dev);
printk(KERN_EMERG "[Focal][Touch] click GESTURE_E\n");

break;
case GESTURE_C:
input_report_key(data->input_dev, KEY_GESTURE_C, 1);
input_sync(data->input_dev);
input_report_key(data->input_dev, KEY_GESTURE_C, 0);
input_sync(data->input_dev);
printk(KERN_EMERG "[Focal][Touch] click GESTURE_C\n");

break;
case GESTURE_S:
input_report_key(data->input_dev, KEY_GESTURE_S, 1);
input_sync(data->input_dev);
input_report_key(data->input_dev, KEY_GESTURE_S, 0);
input_sync(data->input_dev);
printk(KERN_EMERG "[Focal][Touch] click GESTURE_S\n");

break;


case GESTURE_W:
input_report_key(data->input_dev, KEY_GESTURE_W, 1);
input_sync(data->input_dev);
input_report_key(data->input_dev, KEY_GESTURE_W, 0);
input_sync(data->input_dev);
printk(KERN_EMERG "[Focal][Touch] click GESTURE_W\n");

break;
default:

break;
}
} else {
printk(KERN_EMERG "[Focal][Touch] %s :  Skip wake up devices !\n ", __func__);
}
}


往下
bool proximity_check_status(void){
    struct CM36283_info *lpi;
uint16_t ps_adc_value_init = 0 , data =0, data1= 0;
    int ret = 0;
int p_value; //<asus-wx20150814+>


pr_err("anna proximity_check_status default \n");
if (cm36283_is_no_present) {                                      //这边加入了对probe的check防止出现ps的probe函数失败
pr_err("[PS][ap3426]  is ap3426\n"); 
return proximityap3426_check_status();
}  
//<asus-wx20150805>+>>
if (cm36283_probe_fail) {                                         //这边加入了对probe的check防止出现ps的probe函数失败
pr_err("proximity_check_status default return FAR\n");
goto error_return_far;
}


mutex_lock(&ps_enable_mutex);                                     //这里出现了锁,当时真正的问题在于这个ps_enable_mutex在ps的probe函数里初始化失败了   mutex_init(&ps_enable_mutex);


lpi = lp_info_cm36283;
ret = _CM36283_I2C_Read_Word(lpi->slave_addr, PS_CONF1, &data);
if (ret < 0) goto error_return_far;
//<asus-wx20150805>+<<


if ( data & CM36283_PS_SD ) {
        data1 = data & CM36283_PS_SD_MASK; //disable = 0
//<asus-wx20150805>+>>
       ret = _CM36283_I2C_Write_Word(lpi->slave_addr, PS_CONF1, data1);  
       if (ret < 0) goto error_return_far;
//<asus-wx20150805>+<<
}

msleep(50); //need some delay


        ret = get_ps_adc_value(&ps_adc_value_init);
        if(!ret){      
             if(ps_adc_value_init > lpi->ps_close_thd_set){
      D("[PS][CM36283] proximity initial NEAR\n");
p_value = 1; //<asus-wx20150814>
}else{
      D("[PS][CM36283] proximity initial FAR\n");  
p_value = 0; //<asus-wx20150814>
}
        }
//<asus-wx20150814>+>>
else {
goto error_return_far;
}
//<asus-wx20150814>+<<


if ( data & CM36283_PS_SD) {
data1 = data | CM36283_PS_SD; //disable = 1
//<asus-wx20150805>+>>
       ret = _CM36283_I2C_Write_Word(lpi->slave_addr, PS_CONF1, data1);   
       if (ret < 0) goto error_return_far;
//<asus-wx20150805>+<<
}


mutex_unlock(&ps_enable_mutex);
return p_value;
error_return_far: //<asus-wx20150805+>
return 0;
}


之后在logcat.txt.0里也找到了相应的fail:
04-16 00:24:15.189   381     0 I Kernel  : <3>[    1.384055] [PS_ERR][CM36283 error]CM36283_probe: CM36283 is not present!


所以log得对照起来看,不能光看一份



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值