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