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);

	
	if (val & MXR_INT_STATUS_VSYNC) {
		set_bit(MXR_EVENT_VSYNC, &mdev->event_flags);
		wake_up(&mdev->event_queue);
	}

	
	if (~val & MXR_INT_EN_VSYNC) {
		
		val &= ~MXR_INT_EN_VSYNC;
		val |= MXR_INT_CLEAR_VSYNC;
	}
	mxr_write(mdev, MXR_INT_STATUS, val);

	spin_unlock(&mdev->reg_slock);
	
	if (~val & MXR_INT_CLEAR_VSYNC)
		return IRQ_HANDLED;
	for (i = 0; i < MXR_MAX_LAYERS; ++i)
		mxr_irq_layer_handle(mdev->layer[i]);
	return IRQ_HANDLED;
}
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);
		/* toggle TOP field event if working in interlaced mode */
		if (~mxr_read(mdev, MXR_CFG) & MXR_CFG_SCAN_PROGRASSIVE)
			change_bit(MXR_EVENT_TOP, &mdev->event_flags);
		wake_up(&mdev->event_queue);
		/* vsync interrupt use different bit for read and clear */
		val &= ~MXR_INT_STATUS_VSYNC;
		val |= MXR_INT_CLEAR_VSYNC;
	}

	/* clear interrupts */
	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;
	/* skip layer update on bottom field */
	if (!test_bit(MXR_EVENT_TOP, &mdev->event_flags))
		return IRQ_HANDLED;
	for (i = 0; i < MXR_MAX_LAYERS; ++i)
		mxr_irq_layer_handle(mdev->layer[i]);
	return IRQ_HANDLED;
}
Example #3
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;
}