[meta-freescale] imx6 DCIC driver stops after 2hrs
Cv, Sijil
sijil.cv at aptiv.com
Fri Dec 21 04:12:08 PST 2018
Hi All,
I have seen an issue with imx6 DCIC driver when I tried to read the CRC results from userspace via DCIC_IOC_GET_RESULT iocl call. After 2hr I could see the following stack trace and the driver stops working.
[17506.062623] irq 56: nobody cared (try booting with the "irqpoll" option)
[17506.069338] CPU: 0 PID: 19824 Comm: QSGRenderThread Not tainted 4.9.88-6QuadPlus+g5e23f9d #1
[17506.077778] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
[17506.084314] Function entered at [<8010ddc8>] from [<8010b0c0>]
[17506.090150] Function entered at [<8010b0c0>] from [<802e143c>]
[17506.095988] Function entered at [<802e143c>] from [<8016acb4>]
[17506.101825] Function entered at [<8016acb4>] from [<8016b034>]
[17506.107661] Function entered at [<8016b034>] from [<80168948>]
[17506.113497] Function entered at [<80168948>] from [<8016898c>]
[17506.119332] Function entered at [<8016898c>] from [<8016bc84>]
[17506.125167] Function entered at [<8016bc84>] from [<80167fcc>]
[17506.131002] Function entered at [<80167fcc>] from [<8016805c>]
[17506.136837] Function entered at [<8016805c>] from [<80101448>]
[17506.142673] Function entered at [<80101448>] from [<8010be70>]
[17506.148509] Exception stack(0x947cbfb0 to 0x947cbff8)
[17506.153566] bfa0: 0216cb48 7603d000 76f35a54 9a110bb5
[17506.161749] bfc0: 02173524 00000001 02175e88 021746d8 0217352c 02173370 00000000 02173940
[17506.169931] bfe0: 75b0400c 6df61be8 75aeb3d0 75fdf790 200f0010 ffffffff
[17506.176548] handlers:
[17506.178824] [<803252b4>] 0x803252b4
[17506.182328] Disabling IRQ #56
1162778008
The root cause of the issue is due to a bug in imx6 dcic driver. The return value of dcic_irq_handler is always zero ( IRQ_NONE interrupt was not from this device or was not handled ). Because of this invalid return kernel assumes this as spurious interrupt and stops the IRQ after 100,0000 attempts . The fix for this issue is to correct the irq return type to IRQ_HANDLED
/**
* enum irqreturn
* @IRQ_NONE interrupt was not from this device or was not handled
* @IRQ_HANDLED interrupt was handled by this device
* @IRQ_WAKE_THREAD handler requests to wake the handler thread
*/
enum irqreturn {
IRQ_NONE = (0 << 0),
IRQ_HANDLED = (1 << 0),
IRQ_WAKE_THREAD = (1 << 1),
};
File: drivers/video/fbdev/mxc/mxc_dcic.c
static irqreturn_t dcic_irq_handler(int irq, void *data)
{
u32 i;
struct dcic_data *dcic = data;
u32 dcics = readl(&dcic->regs->dcics);
dcic->result = dcics & 0xffff;
dcic_int_disable(dcic);
/* clean dcic interrupt state */
writel(DCICS_FI_STAT_PENDING, &dcic->regs->dcics);
writel(dcics, &dcic->regs->dcics);
/*for (i = 0; i < 16; i++) {
printk(KERN_INFO "ROI=%d,crcRS=0x%x, crcCS=0x%x\n", i,
readl(&dcic->regs->ROI[i].dcicrrs),
readl(&dcic->regs->ROI[i].dcicrcs));
}
*/
complete(&dcic->roi_crc_comp);
return 0; /* Fix (return IRQ_HANDLED; ) */
}
/*
* If 99,900 of the previous 100,000 interrupts have not been handled
* then assume that the IRQ is stuck in some manner. Drop a diagnostic
* and try to turn the IRQ off.
*
* (The other 100-of-100,000 interrupts may have been a correctly
* functioning device sharing an IRQ with the failing one)
*/
static void __report_bad_irq(struct irq_desc *desc, irqreturn_t action_ret)
{
unsigned int irq = irq_desc_get_irq(desc);
struct irqaction *action;
unsigned long flags;
if (bad_action_ret(action_ret)) {
printk(KERN_ERR "irq event %d: bogus return value %x\n",
irq, action_ret);
} else {
printk(KERN_ERR "irq %d: nobody cared (try booting with "
"the \"irqpoll\" option)\n", irq);
}
dump_stack();
/Sijil
More information about the meta-freescale
mailing list