diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2010-09-03 03:19:57 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-09-14 04:22:25 -0400 |
commit | 5ef6b505d9df45558402bdb823a078840a6a26c4 (patch) | |
tree | 9ce7965f1aff5195822962369ee2a2c671fcfdcf /drivers/video | |
parent | 6ee4845270d9b1e7ea348f9e3b6347f54f986abb (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.c | 4 |
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++) { |