diff options
author | Liu Ying <Ying.Liu@freescale.com> | 2013-05-21 17:02:46 +0800 |
---|---|---|
committer | Liu Ying <Ying.Liu@freescale.com> | 2013-05-22 09:17:12 +0800 |
commit | d72bb22ba2f382cebfe6e275e6c1a1c68d076281 (patch) | |
tree | 8d2f075283aede48c485b8a29debc166a258aa07 /drivers/mxc | |
parent | cc43424a36f57829d4e621208178807afd5b8781 (diff) |
ENGR00263304-3 IPUv3:Check NULL irq handler in ipu_request_irq()
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>
Diffstat (limited to 'drivers/mxc')
-rw-r--r-- | drivers/mxc/ipu3/ipu_common.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c index 95ff05e115ea..ca9f66ce233b 100644 --- a/drivers/mxc/ipu3/ipu_common.c +++ b/drivers/mxc/ipu3/ipu_common.c @@ -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); |