err = request_threaded_irq(ftxxxx_ts->client->irq, NULL, ftxxxx_ts_interrupt,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->dev.driver->name,
ftxxxx_ts);
int request_threaded_irq(unsigned int irq, irq_handler_t handler,
irq_handler_t thread_fn, unsigned long irqflags,
const char *devname, void *dev_id)
第二个参数是中断的上半部分,也就是硬中断部分,第三个参数是中断的下半部分,可以被调度也可以被打断,通过irqflags得知
/*
* These flags used only by the kernel as part of the
* irq handling routines.
*
* IRQF_DISABLED - keep irqs disabled when calling the action handler.
* DEPRECATED. This flag is a NOOP and scheduled to be removed
* IRQF_SHARED - allow sharing the irq among several devices
* IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur
* IRQF_TIMER - Flag to mark this interrupt as timer interrupt
* IRQF_PERCPU - Interrupt is per cpu
* IRQF_NOBALANCING - Flag to exclude this interrupt from irq balancing
* IRQF_IRQPOLL - Interrupt is used for polling (only the interrupt that is
* registered first in an shared interrupt is considered for
* performance reasons)
* IRQF_ONESHOT - Interrupt is not reenabled after the hardirq handler finished.
* Used by threaded interrupts which need to keep the
* irq line disabled until the threaded handler has been run.
* IRQF_NO_SUSPEND - Do not disable this IRQ during suspend
* IRQF_FORCE_RESUME - Force enable it on resume even if IRQF_NO_SUSPEND is set
* IRQF_NO_THREAD - Interrupt cannot be threaded
* IRQF_EARLY_RESUME - Resume IRQ early during syscore instead of at device
* resume time.
*/
#define IRQF_DISABLED 0x00000020
#define IRQF_SHARED 0x00000080
#define IRQF_PROBE_SHARED 0x00000100
#define __IRQF_TIMER 0x00000200
#define IRQF_PERCPU 0x00000400
#define IRQF_NOBALANCING 0x00000800
#define IRQF_IRQPOLL 0x00001000
#define IRQF_ONESHOT 0x00002000
#define IRQF_NO_SUSPEND 0x00004000
#define IRQF_FORCE_RESUME 0x00008000
#define IRQF_NO_THREAD 0x00010000
#define IRQF_EARLY_RESUME 0x00020000
#define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)
/*这里的
IRQF_ONESHOT - Interrupt is not reenabled after the hardirq handler finished.
* Used by threaded interrupts which need to keep the
* irq line disabled until the threaded handler has been run.
这里说这个中断的上半部分如果没执行完的话,中断是被禁止的,但是下半部分可以中断重入也就是嵌套中断,如果想在下半部分禁止中断就必须
像下面这个函数一样
static irqreturn_t ftxxxx_ts_interrupt(int irq, void *dev_id)
{
/* struct ftxxxx_ts_data *ftxxxx_ts = dev_id; ASUS jacob use globle ftxxxx_ts data*/
int ret = 0;
#ifdef FTS_GESTRUE/*zax 20140922*/
u8 state;
#endif
if(selftestflag==1)
{
printk(KERN_WARNING "[Focal][Touch] in selftest mode\n");
return IRQ_HANDLED;
}
if (suspend_resume_process == true) {
printk("[Focal][Touch] interrupt suspend_resume in process skip !\n");
return IRQ_HANDLED;
}
wake_lock(&ftxxxx_ts->wake_lock);
mutex_lock(&ftxxxx_ts->g_device_mutex);
if(!FOCAL_IRQ_DISABLE)
{
ftxxxx_nosync_irq_disable(ftxxxx_ts->client);//禁止了中断
#ifdef FTS_GESTRUE/*zax 20140922*/
i2c_smbus_read_i2c_block_data(ftxxxx_ts->client, 0xd0, 1, &state);
if(Gesture_flag==1)
{
printk("[Focal][Touch] %s: tpd fts_read_Gestruedata state=%d\n",__func__, state);
}
if (state == 1) {
fts_read_Gestruedata(ftxxxx_ts);
/*continue;*/
} else {
#endif
ret = ftxxxx_read_Touchdata(ftxxxx_ts);
if ((ret == 0)&&(suspend_resume_process==false)&&(!disable_tp_flag))
ftxxxx_report_value(ftxxxx_ts);
#ifdef FTS_GESTRUE/*zax 20140922*/
}
#endif
ftxxxx_irq_enable(ftxxxx_ts->client);//重新开启中断
msleep(500);//这边加了delay之后就可以看到两次进入irq
}
else
{
printk(KERN_EMERG"[Focal][Touch] newcode---disable touch\n");
}
mutex_unlock(&ftxxxx_ts->g_device_mutex);
wake_unlock(&ftxxxx_ts->wake_lock);
return IRQ_HANDLED;
}
IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->dev.driver->name,
ftxxxx_ts);
int request_threaded_irq(unsigned int irq, irq_handler_t handler,
irq_handler_t thread_fn, unsigned long irqflags,
const char *devname, void *dev_id)
第二个参数是中断的上半部分,也就是硬中断部分,第三个参数是中断的下半部分,可以被调度也可以被打断,通过irqflags得知
/*
* These flags used only by the kernel as part of the
* irq handling routines.
*
* IRQF_DISABLED - keep irqs disabled when calling the action handler.
* DEPRECATED. This flag is a NOOP and scheduled to be removed
* IRQF_SHARED - allow sharing the irq among several devices
* IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur
* IRQF_TIMER - Flag to mark this interrupt as timer interrupt
* IRQF_PERCPU - Interrupt is per cpu
* IRQF_NOBALANCING - Flag to exclude this interrupt from irq balancing
* IRQF_IRQPOLL - Interrupt is used for polling (only the interrupt that is
* registered first in an shared interrupt is considered for
* performance reasons)
* IRQF_ONESHOT - Interrupt is not reenabled after the hardirq handler finished.
* Used by threaded interrupts which need to keep the
* irq line disabled until the threaded handler has been run.
* IRQF_NO_SUSPEND - Do not disable this IRQ during suspend
* IRQF_FORCE_RESUME - Force enable it on resume even if IRQF_NO_SUSPEND is set
* IRQF_NO_THREAD - Interrupt cannot be threaded
* IRQF_EARLY_RESUME - Resume IRQ early during syscore instead of at device
* resume time.
*/
#define IRQF_DISABLED 0x00000020
#define IRQF_SHARED 0x00000080
#define IRQF_PROBE_SHARED 0x00000100
#define __IRQF_TIMER 0x00000200
#define IRQF_PERCPU 0x00000400
#define IRQF_NOBALANCING 0x00000800
#define IRQF_IRQPOLL 0x00001000
#define IRQF_ONESHOT 0x00002000
#define IRQF_NO_SUSPEND 0x00004000
#define IRQF_FORCE_RESUME 0x00008000
#define IRQF_NO_THREAD 0x00010000
#define IRQF_EARLY_RESUME 0x00020000
#define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)
/*这里的
IRQF_ONESHOT - Interrupt is not reenabled after the hardirq handler finished.
* Used by threaded interrupts which need to keep the
* irq line disabled until the threaded handler has been run.
这里说这个中断的上半部分如果没执行完的话,中断是被禁止的,但是下半部分可以中断重入也就是嵌套中断,如果想在下半部分禁止中断就必须
像下面这个函数一样
static irqreturn_t ftxxxx_ts_interrupt(int irq, void *dev_id)
{
/* struct ftxxxx_ts_data *ftxxxx_ts = dev_id; ASUS jacob use globle ftxxxx_ts data*/
int ret = 0;
#ifdef FTS_GESTRUE/*zax 20140922*/
u8 state;
#endif
if(selftestflag==1)
{
printk(KERN_WARNING "[Focal][Touch] in selftest mode\n");
return IRQ_HANDLED;
}
if (suspend_resume_process == true) {
printk("[Focal][Touch] interrupt suspend_resume in process skip !\n");
return IRQ_HANDLED;
}
wake_lock(&ftxxxx_ts->wake_lock);
mutex_lock(&ftxxxx_ts->g_device_mutex);
if(!FOCAL_IRQ_DISABLE)
{
ftxxxx_nosync_irq_disable(ftxxxx_ts->client);//禁止了中断
#ifdef FTS_GESTRUE/*zax 20140922*/
i2c_smbus_read_i2c_block_data(ftxxxx_ts->client, 0xd0, 1, &state);
if(Gesture_flag==1)
{
printk("[Focal][Touch] %s: tpd fts_read_Gestruedata state=%d\n",__func__, state);
}
if (state == 1) {
fts_read_Gestruedata(ftxxxx_ts);
/*continue;*/
} else {
#endif
ret = ftxxxx_read_Touchdata(ftxxxx_ts);
if ((ret == 0)&&(suspend_resume_process==false)&&(!disable_tp_flag))
ftxxxx_report_value(ftxxxx_ts);
#ifdef FTS_GESTRUE/*zax 20140922*/
}
#endif
ftxxxx_irq_enable(ftxxxx_ts->client);//重新开启中断
msleep(500);//这边加了delay之后就可以看到两次进入irq
}
else
{
printk(KERN_EMERG"[Focal][Touch] newcode---disable touch\n");
}
mutex_unlock(&ftxxxx_ts->g_device_mutex);
wake_unlock(&ftxxxx_ts->wake_lock);
return IRQ_HANDLED;
}