diff options
-rw-r--r-- | drivers/video/mxsfb.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index 3fb54350a182..84f62a47d843 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -4,7 +4,7 @@ * This code is based on: * Author: Vitaly Wool <vital@embeddedalley.com> * - * Copyright 2008-2014 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008-2015 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -115,6 +115,16 @@ #define CTRL1_UNDERFLOW_IRQ (1 << 10) #define CTRL1_CUR_FRAME_DONE_IRQ (1 << 9) #define CTRL1_VSYNC_EDGE_IRQ (1 << 8) +#define CTRL1_IRQ_ENABLE_MASK (CTRL1_OVERFLOW_IRQ_EN | \ + CTRL1_UNDERFLOW_IRQ_EN | \ + CTRL1_CUR_FRAME_DONE_IRQ_EN | \ + CTRL1_VSYNC_EDGE_IRQ_EN) +#define CTRL1_IRQ_ENABLE_SHIFT 12 +#define CTRL1_IRQ_STATUS_MASK (CTRL1_OVERFLOW_IRQ | \ + CTRL1_UNDERFLOW_IRQ | \ + CTRL1_CUR_FRAME_DONE_IRQ | \ + CTRL1_VSYNC_EDGE_IRQ) +#define CTRL1_IRQ_STATUS_SHIFT 8 #define CTRL2_OUTSTANDING_REQS__REQ_16 (3 << 21) @@ -368,31 +378,32 @@ static inline unsigned chan_to_field(unsigned chan, struct fb_bitfield *bf) static irqreturn_t mxsfb_irq_handler(int irq, void *dev_id) { struct mxsfb_info *host = dev_id; - u32 status_lcd = readl(host->base + LCDC_CTRL1); + u32 ctrl1, enable, status, acked_status; - if ((status_lcd & CTRL1_VSYNC_EDGE_IRQ) && - host->wait4vsync) { + ctrl1 = readl(host->base + LCDC_CTRL1); + enable = (ctrl1 & CTRL1_IRQ_ENABLE_MASK) >> CTRL1_IRQ_ENABLE_SHIFT; + status = (ctrl1 & CTRL1_IRQ_STATUS_MASK) >> CTRL1_IRQ_STATUS_SHIFT; + acked_status = (enable & status) << CTRL1_IRQ_STATUS_SHIFT; + + if ((acked_status & CTRL1_VSYNC_EDGE_IRQ) && host->wait4vsync) { writel(CTRL1_VSYNC_EDGE_IRQ_EN, host->base + LCDC_CTRL1 + REG_CLR); host->wait4vsync = 0; complete(&host->vsync_complete); } - if (status_lcd & CTRL1_CUR_FRAME_DONE_IRQ) { + if (acked_status & CTRL1_CUR_FRAME_DONE_IRQ) { writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, host->base + LCDC_CTRL1 + REG_CLR); up(&host->flip_sem); } - if (status_lcd & CTRL1_UNDERFLOW_IRQ) { - writel(CTRL1_UNDERFLOW_IRQ, - host->base + LCDC_CTRL1 + REG_CLR); - } + if (acked_status & CTRL1_UNDERFLOW_IRQ) + writel(CTRL1_UNDERFLOW_IRQ, host->base + LCDC_CTRL1 + REG_CLR); + + if (acked_status & CTRL1_OVERFLOW_IRQ) + writel(CTRL1_OVERFLOW_IRQ, host->base + LCDC_CTRL1 + REG_CLR); - if (status_lcd & CTRL1_OVERFLOW_IRQ) { - writel(CTRL1_OVERFLOW_IRQ, - host->base + LCDC_CTRL1 + REG_CLR); - } return IRQ_HANDLED; } |