diff options
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/sh_mobile_lcdcfb.c | 32 |
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, | |||
281 | struct list_head *pagelist) | 281 | struct list_head *pagelist) |
282 | { | 282 | { |
283 | struct sh_mobile_lcdc_chan *ch = info->par; | 283 | struct sh_mobile_lcdc_chan *ch = info->par; |
284 | unsigned int nr_pages; | ||
285 | 284 | ||
286 | /* enable clocks before accessing hardware */ | 285 | /* enable clocks before accessing hardware */ |
287 | sh_mobile_lcdc_clk_on(ch->lcdc); | 286 | sh_mobile_lcdc_clk_on(ch->lcdc); |
288 | 287 | ||
289 | nr_pages = sh_mobile_lcdc_sginit(info, pagelist); | 288 | /* |
290 | dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); | 289 | * It's possible to get here without anything on the pagelist via |
291 | 290 | * sh_mobile_lcdc_deferred_io_touch() or via a userspace fsync() | |
292 | /* trigger panel update */ | 291 | * invocation. In the former case, the acceleration routines are |
293 | lcdc_write_chan(ch, LDSM2R, 1); | 292 | * stepped in to when using the framebuffer console causing the |
294 | 293 | * workqueue to be scheduled without any dirty pages on the list. | |
295 | dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); | 294 | * |
295 | * Despite this, a panel update is still needed given that the | ||
296 | * acceleration routines have their own methods for writing in | ||
297 | * that still need to be updated. | ||
298 | * | ||
299 | * The fsync() and empty pagelist case could be optimized for, | ||
300 | * but we don't bother, as any application exhibiting such | ||
301 | * behaviour is fundamentally broken anyways. | ||
302 | */ | ||
303 | if (!list_empty(pagelist)) { | ||
304 | unsigned int nr_pages = sh_mobile_lcdc_sginit(info, pagelist); | ||
305 | |||
306 | /* trigger panel update */ | ||
307 | dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); | ||
308 | lcdc_write_chan(ch, LDSM2R, 1); | ||
309 | dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE); | ||
310 | } else | ||
311 | lcdc_write_chan(ch, LDSM2R, 1); | ||
296 | } | 312 | } |
297 | 313 | ||
298 | static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info) | 314 | static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info) |