aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2010-09-03 03:19:57 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-09-14 04:22:25 -0400
commit5ef6b505d9df45558402bdb823a078840a6a26c4 (patch)
tree9ce7965f1aff5195822962369ee2a2c671fcfdcf /drivers/video
parent6ee4845270d9b1e7ea348f9e3b6347f54f986abb (diff)
fbdev: sh_mobile_lcdcfb: fix more error paths
This patch fixes the following two erroneous error paths: hw_usecnt is allocated with a value of 0, therefore in an early error case, calling sh_mobile_lcdc_clk_off() will wrongly conclude, that hw_usecnt has already been incremented. Then sh_mobile_lcdc_runtime_suspend() will be called, which will access uninitialised data fields and crash the kernel. sh_mobile_lcdc_stop() can be called before framebuffer has been allocated, then ch->info is NULL and dereferencing it will Oops too. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 43132de38822..295bf4ba1849 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -614,7 +614,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
614 * flush frame, and wait for frame end interrupt 614 * flush frame, and wait for frame end interrupt
615 * clean up deferred io and enable clock 615 * clean up deferred io and enable clock
616 */ 616 */
617 if (ch->info->fbdefio) { 617 if (ch->info && ch->info->fbdefio) {
618 ch->frame_end = 0; 618 ch->frame_end = 0;
619 schedule_delayed_work(&ch->info->deferred_work, 0); 619 schedule_delayed_work(&ch->info->deferred_work, 0);
620 wait_event(ch->frame_end_wait, ch->frame_end); 620 wait_event(ch->frame_end_wait, ch->frame_end);
@@ -704,7 +704,6 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
704 return PTR_ERR(priv->dot_clk); 704 return PTR_ERR(priv->dot_clk);
705 } 705 }
706 } 706 }
707 atomic_set(&priv->hw_usecnt, -1);
708 707
709 /* Runtime PM support involves two step for this driver: 708 /* Runtime PM support involves two step for this driver:
710 * 1) Enable Runtime PM 709 * 1) Enable Runtime PM
@@ -1055,6 +1054,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1055 1054
1056 priv->irq = i; 1055 priv->irq = i;
1057 pdata = pdev->dev.platform_data; 1056 pdata = pdev->dev.platform_data;
1057 atomic_set(&priv->hw_usecnt, -1);
1058 1058
1059 j = 0; 1059 j = 0;
1060 for (i = 0; i < ARRAY_SIZE(pdata->ch); i++) { 1060 for (i = 0; i < ARRAY_SIZE(pdata->ch); i++) {