修改arch/arm/plat-s3c64xx/adc.c
首先在文件开头部分引掉mutex结构体用semaphore结构体代替:
//static DEFINE_MUTEX(adc_mutex);
DECLARE_MUTEX(ADC_LOCK);
然后在read函数中修改互斥的实现
s3c_adc_read(struct file *file, char __user * buffer,
size_t size, loff_t * pos)
{
int adc_value = 0;
printk(KERN_INFO " s3c_adc_read() entered\n");
#ifdef ADC_WITH_TOUCHSCREEN
//mutex_lock(&adc_mutex);
if (down_trylock(&ADC_LOCK) != 0)
{
goto down_error;
}
s3c_adc_save_SFR_on_ADC();
#endif
adc_value = s3c_adc_convert();
#ifdef ADC_WITH_TOUCHSCREEN
s3c_adc_restore_SFR_on_ADC();
//mutex_unlock(&adc_mutex);
up(&ADC_LOCK);
……
}
最后在文件结束部分导出信号量结构体ADC_LOCK,目的是让触摸屏驱动可以访问这个全局变量。
EXPORT_SYMBOL(ADC_LOCK);
4、 修改drivers/input/touchscreen/s3c-ts.c
首先声明信号量ADC_LOCK:
extern struct semaphore ADC_LOCK;
然后修改函数touch_timer_fire:
static void touch_timer_fire(unsigned long data)
{
……
writel(WAIT4INT(0), ts_base+S3C_ADCTSC);
#ifdef add_by_cc
if (own_adc)
{
//printk(KERN_INFO "do funtion: mutex_unlock(&adc_mutex);\n");
//mutex_unlock(&adc_mutex);
up(&ADC_LOCK);
own_adc = 0;
}
#endif
}
}
修改函数stylus_updown:
static irqreturn_t stylus_updown(int irqno, void *param)
{
unsigned long data0;
unsigned long data1;
int updown;
#ifdef add_by_cc
// bool f_lock = 0;
//if (!own_adc)
if (down_trylock(&ADC_LOCK) != 0)
{
if(ts->s3c_adc_con==ADC_TYPE_2) {
__raw_writel(0x0, ts_base+S3C_ADCCLRWK);
__raw_writel(0x0, ts_base+S3C_ADCCLRINT);
}
goto down_error;
//mutex_lock(&adc_mutex);
//own_adc = 1;
//f_lock = 1;
}
own_adc = 1;
#endif
……
#ifdef add_by_cc
if (!updown)// && f_lock)
{
//mutex_unlock(&adc_mutex);
up(&ADC_LOCK);
own_adc = 0;
}
down_error:
#endif
return IRQ_HANDLED;
}
修改stylus_action函数:
static irqreturn_t stylus_action(int irqno, void *param)
{
unsigned long data0;
unsigned long data1;
int maskdata0;
int maskdata1;
#ifdef add_by_cc
if (!own_adc) {
goto no_own_adc;
}
#endif
data0 = readl(ts_base+S3C_ADCDAT0);
……
no_own_adc:
if(ts->s3c_adc_con==ADC_TYPE_2) {
__raw_writel(0x0, ts_base+S3C_ADCCLRWK);
__raw_writel(0x0, ts_base+S3C_ADCCLRINT);
}
return IRQ_HANDLED;
}