I2C--中断

前些天在中断响应(handle)函数中操作I2C的时候,发现内核会抱怨:

 

BUG: scheduling while atomic: samtest/0x00010000/57

Call Trace:[<c009a30>][<c009a30>][<c010f7f0>][<c010ed08>][<c010f7f0>][<c002e664>]

...

 

但是后面的操作依然正常,经过高手指点后发现原来通过I2C传输的时候,总线会休眠,英文说明:

 

* we can't acknowledge from interrupt context since the i2c  

* bus controller may sleep, so we just disable the interrupt  

* here and handle the acknowledge using delayed work.  

 

查看如下代码中的说明:

http://linux.sourcearchive.com/documentation/2.6.27-1.2/migor__ts_8c-source.html

 

00086 static irqreturn_t migor_ts_isr(int irq, void *dev_id) 00087 { 00088 struct migor_ts_priv *priv = dev_id; 00089 00090 /* the touch screen controller chip is hooked up to the cpu 00091 * using i2c and a single interrupt line. the interrupt line 00092 * is pulled low whenever someone taps the screen. to deassert 00093 * the interrupt line we need to acknowledge the interrupt by 00094 * communicating with the controller over the slow i2c bus. 00095 * 00096 * we can't acknowledge from interrupt context since the i2c 00097 * bus controller may sleep, so we just disable the interrupt 00098 * here and handle the acknowledge using delayed work. 00099 */ 00100 00101 disable_irq_nosync(irq); 00102 schedule_delayed_work(&priv->work, HZ / 20); 00103 00104 return IRQ_HANDLED; 00105 }  

 所以采用先注册

/* Init the workqueue used for interrupt that have to sleep */ INIT_WORK(&dev->wq, wq_handler); void wq_handler(struct work_struct *work);

然后在中断中调用

schedule_work(&dev->wq);

你可能感兴趣的:(I2C--中断)