[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