static irqreturn_t vpe_parse_irq(int irq_num, void *data) { vpe_ctrl->irq_status = msm_io_r_mb(vpe_ctrl->vpebase + VPE_INTR_STATUS_OFFSET); msm_io_w_mb(vpe_ctrl->irq_status, vpe_ctrl->vpebase + VPE_INTR_CLEAR_OFFSET); msm_io_w(0, vpe_ctrl->vpebase + VPE_INTR_ENABLE_OFFSET); CDBG("%s: vpe_parse_irq =0x%x.\n", __func__, vpe_ctrl->irq_status); tasklet_schedule(&vpe_tasklet); return IRQ_HANDLED; }
static irqreturn_t vpe_parse_irq(int irq_num, void *data) { unsigned long flags; uint32_t irq_status = 0; struct vpe_isr_queue_cmd_type *qcmd; CDBG("vpe_parse_irq.\n"); /* read and clear back-to-back. */ irq_status = msm_io_r_mb(vpe_device->vpebase + VPE_INTR_STATUS_OFFSET); msm_io_w_mb(irq_status, vpe_device->vpebase + VPE_INTR_CLEAR_OFFSET); msm_io_w(0, vpe_device->vpebase + VPE_INTR_ENABLE_OFFSET); if (irq_status == 0) { printk(KERN_ERR "vpe_parse_irq: irq_status = 0" "!!!! Something is wrong!\n"); return IRQ_HANDLED; } irq_status &= 0x1; /* apply mask. only interested in bit 0. */ if (irq_status) { qcmd = kzalloc(sizeof(struct vpe_isr_queue_cmd_type), GFP_ATOMIC); if (!qcmd) { CDBG("vpe_parse_irq: qcmd malloc failed!\n"); return IRQ_HANDLED; } /* must be 0x1 now. so in bottom half we don't really need to check. */ qcmd->irq_status = irq_status & 0x1; spin_lock_irqsave(&vpe_ctrl->tasklet_lock, flags); list_add_tail(&qcmd->list, &vpe_ctrl->tasklet_q); spin_unlock_irqrestore(&vpe_ctrl->tasklet_lock, flags); tasklet_schedule(&vpe_tasklet); } return IRQ_HANDLED; }