]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ENGR00263304-3 IPUv3:Check NULL irq handler in ipu_request_irq()
authorLiu Ying <Ying.Liu@freescale.com>
Tue, 21 May 2013 09:02:46 +0000 (17:02 +0800)
committerOliver Wendt <ow@karo-electronics.de>
Mon, 30 Sep 2013 12:14:04 +0000 (14:14 +0200)
To avoid NULL interrupt handler being called potentially in the
IPU sync interrupt source handler, this patch adds sanity check
on NULL interrupt handler in the function ipu_request_irq() for
sync interrupts because the callers are likely to request a sync
interrupt without specifying a handler. The error interrupts can
still be enabled by this function without this kind of sanity
check since we simply print out the relevant error interrupt
register values in the IPU error interrupt source's handler.
This patch also corrects _ipu_get() and _ipu_put() function call
in the function ipu_request_irq() to make them be called in pair
when handler has already been registered.

Signed-off-by: Liu Ying <Ying.Liu@freescale.com>
drivers/mxc/ipu3/ipu_common.c

index 95ff05e115ea374bf6cf4bd9de7b7189fb0f1263..ca9f66ce233ba18651d78ecabf6924ab68704f1c 100644 (file)
@@ -2620,6 +2620,7 @@ int ipu_request_irq(struct ipu_soc *ipu, uint32_t irq,
 {
        uint32_t reg;
        unsigned long lock_flags;
+       int ret = 0;
 
        BUG_ON(irq >= IPU_IRQ_COUNT);
 
@@ -2630,8 +2631,19 @@ int ipu_request_irq(struct ipu_soc *ipu, uint32_t irq,
        if (ipu->irq_list[irq].handler != NULL) {
                dev_err(ipu->dev,
                        "handler already installed on irq %d\n", irq);
-               spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /*
+        * Check sync interrupt handler only, since we do nothing for
+        * error interrupts but than print out register values in the
+        * error interrupt source handler.
+        */
+       if (_ipu_is_sync_irq(irq) && (handler == NULL)) {
+               dev_err(ipu->dev, "handler is NULL for sync irq %d\n", irq);
+               ret = -EINVAL;
+               goto out;
        }
 
        ipu->irq_list[irq].handler = handler;
@@ -2645,12 +2657,12 @@ int ipu_request_irq(struct ipu_soc *ipu, uint32_t irq,
        reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq));
        reg |= IPUIRQ_2_MASK(irq);
        ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq));
-
+out:
        spin_unlock_irqrestore(&ipu->int_reg_spin_lock, lock_flags);
 
        _ipu_put(ipu);
 
-       return 0;
+       return ret;
 }
 EXPORT_SYMBOL(ipu_request_irq);