从工作队列调用enable_irq()
是否有任何副作用?我通过工作队列看到了异常。
static void mmxx_irq_worker(struct work_struct *work)
{
struct mmxx_data *mma = container_of(work, struct mmxx_data, accel_work);
if (unlikely(read_and_report_abs(mmxx) != 0))
dev_err(&mmxx_i2c_client->dev, "read_and_report failed\n");
enable_irq(mmxx->irq);
}
[ 2029.755981] Exception stack(0xd51fbe70 to 0xd51fbeb8)
[ 2029.761718] be60: c09cee10 600b0113 00000001 00000000
[ 2029.771057] be80: c09cedc0 00000001 000002bf d508bb4c 000002d6 c09b3ac0 fffffffe d51fbec4
[ 2029.780426] bea0: d51fbec8 d51fbeb8 c00b6458 c06e5b28 400b0113 ffffffff
[ 2029.787841] r6:ffffffff r5:400b0113 r4:c06e5b28 r3:c00b6458
[ 2029.795379] [<c06e5b04>] (_raw_spin_unlock_irqrestore+0x0/0x50) from [<c00b6458>] (__irq_put_desc_unlock+0x1c/0x40)
[ 2029.807189] [<c00b643c>] (__irq_put_desc_unlock+0x0/0x40) from [<c00b7c2c>] (enable_irq+0x54/0x7c)
[ 2029.817352] r5:000001e5 r4:c09cedc0
[ 2029.821990] [<c00b7bd8>] (enable_irq+0x0/0x7c) from [<c0357394>] (mmxx_irq_worker+0x1b8/0x238)
[ 2029.832061] r5:c0a1d8b4 r4:c0abb340
[ 2029.836700] [<c03571dc>] (mmxx_irq_worker+0x0/0x238) from [<c0063e70>] (process_one_work+0x134/0x4ac)
[ 2029.847442] [<c0063d3c>] (process_one_work+0x0/0x4ac) from [<c0064374>] (worker_thread+0x18c/0x3d8)
[ 2029.857757] [<c00641e8>] (worker_thread+0x0/0x3d8) from [<c0068df8>] (kthread+0x90/0x9c)
[ 2029.866790] [<c0068d68>] (kthread+0x0/0x9c) from [<c004c9f4>] (do_exit+0x0/0x81c)
[ 2029.875366] r6:c004c9f4 r5:c0068d68 r4:d699dec4
答案 0 :(得分:1)
Workqueue在启用了IRQ的进程上下文中运行。所以你应该不在workqueue处理程序中执行enable_irq()
,除非你之前禁用了这个IRQ。
但你也不应该得到那个错误。可能mmxx->irq
号码错误或未被请求。在你的回溯中注意这一行:
(__irq_put_desc_unlock) from (enable_irq)
它发生在enable_irq()函数:
void enable_irq(unsigned int irq)
{
unsigned long flags;
struct irq_desc *desc = irq_get_desc_buslock(irq, &flags,
IRQ_GET_DESC_CHECK_GLOBAL);
if (!desc)
return;
if (WARN(!desc->irq_data.chip,
KERN_ERR "enable_irq before setup/request_irq: irq %u\n", irq))
goto out;
__enable_irq(desc, irq);
out:
irq_put_desc_busunlock(desc, flags);
}
irq_put_desc_busunlock()
基本上是__irq_put_desc_unlock()
。
现在,您可以看到执行此链的唯一方法是desc->irq_data.chip
为NULL
。你也应该在你的回溯中观察这样的输出:
"enable_irq before setup/request_irq: irq %u\n"
从这里我会说你传递给mmxx->irq
的{{1}}号码是错误的(enable_irq()
?)或者之前没有要求此IRQ。尝试检查0
中具有的确切值,并确保在第一次调用workqueue处理程序之前已请求它。
无论如何,从代码中删除mmxx->irq
行应该可以解决问题(因为您可能并非真的需要这样做)。