summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-11-24 16:32:11 +0900
committerPaul Mundt <lethal@linux-sh.org>2009-11-24 16:32:11 +0900
commit49fb2cd2571e0134e5a12c5abab227696e4940c7 (patch)
tree9a77364e988ef3f3af24feee3f5bb91bd0c34129 /drivers/video
parentdfc349402de8e95f6a42e8341e9ea193b718eee3 (diff)
parent260af56271f79da0e37faa5a99b1786b221297e5 (diff)
Merge branch 'master' into sh/st-integration
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 3ad5157f9899..b4b5de930cf5 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -281,18 +281,34 @@ static void sh_mobile_lcdc_deferred_io(struct fb_info *info,
struct list_head *pagelist)
{
struct sh_mobile_lcdc_chan *ch = info->par;
- unsigned int nr_pages;
/* enable clocks before accessing hardware */
sh_mobile_lcdc_clk_on(ch->lcdc);
- nr_pages = sh_mobile_lcdc_sginit(info, pagelist);
- dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
-
- /* trigger panel update */
- lcdc_write_chan(ch, LDSM2R, 1);
-
- dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
+ /*
+ * It's possible to get here without anything on the pagelist via
+ * sh_mobile_lcdc_deferred_io_touch() or via a userspace fsync()
+ * invocation. In the former case, the acceleration routines are
+ * stepped in to when using the framebuffer console causing the
+ * workqueue to be scheduled without any dirty pages on the list.
+ *
+ * Despite this, a panel update is still needed given that the
+ * acceleration routines have their own methods for writing in
+ * that still need to be updated.
+ *
+ * The fsync() and empty pagelist case could be optimized for,
+ * but we don't bother, as any application exhibiting such
+ * behaviour is fundamentally broken anyways.
+ */
+ if (!list_empty(pagelist)) {
+ unsigned int nr_pages = sh_mobile_lcdc_sginit(info, pagelist);
+
+ /* trigger panel update */
+ dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
+ lcdc_write_chan(ch, LDSM2R, 1);
+ dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
+ } else
+ lcdc_write_chan(ch, LDSM2R, 1);
}
static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)