irqreturn_t mxr_irq_handler(int irq, void *dev_data)
{
	struct mxr_device *mdev = dev_data;
	u32 val;

	spin_lock(&mdev->reg_slock);
	val = mxr_read(mdev, MXR_INT_STATUS);

	/* wake up process waiting for VSYNC */
	if (val & MXR_INT_STATUS_VSYNC) {
		mdev->vsync_timestamp = ktime_get();
		wake_up_interruptible_all(&mdev->vsync_wait);
	}

	/* clear interrupts.
	   vsync is updated after write MXR_CFG_LAYER_UPDATE bit */
	if (val & MXR_INT_CLEAR_VSYNC)
		mxr_write_mask(mdev, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);

	val = mxr_irq_underrun_handle(mdev, val);
	mxr_write(mdev, MXR_INT_STATUS, val);

	spin_unlock(&mdev->reg_slock);
	return IRQ_HANDLED;
}
Exemple #2
0
irqreturn_t mxr_irq_handler(int irq, void *dev_data)
{
	struct mxr_device *mdev = dev_data;
	u32 i, val;

	spin_lock(&mdev->reg_slock);
	val = mxr_read(mdev, MXR_INT_STATUS);

	/* wake up process waiting for VSYNC */
	if (val & MXR_INT_STATUS_VSYNC) {
		set_bit(MXR_EVENT_VSYNC, &mdev->event_flags);
		wake_up(&mdev->event_queue);
	}

	/* clear interrupts */
	if (~val & MXR_INT_EN_VSYNC) {
		/* vsync interrupt use different bit for read and clear */
		val &= ~MXR_INT_EN_VSYNC;
		val |= MXR_INT_CLEAR_VSYNC;
	}
	val = mxr_irq_underrun_handle(mdev, val);
	mxr_write(mdev, MXR_INT_STATUS, val);

	spin_unlock(&mdev->reg_slock);
	/* leave on non-vsync event */
	if (~val & MXR_INT_CLEAR_VSYNC)
		return IRQ_HANDLED;

	for (i = 0; i < MXR_MAX_SUB_MIXERS; ++i) {
#if defined(CONFIG_ARCH_EXYNOS4)
		mxr_irq_layer_handle(mdev->sub_mxr[i].layer[MXR_LAYER_VIDEO]);
#endif
		mxr_irq_layer_handle(mdev->sub_mxr[i].layer[MXR_LAYER_GRP0]);
		mxr_irq_layer_handle(mdev->sub_mxr[i].layer[MXR_LAYER_GRP1]);
	}

	return IRQ_HANDLED;
}