diff options
author | Geert Uytterhoeven <geert+renesas@glider.be> | 2015-04-03 08:50:28 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2015-04-07 09:24:15 -0400 |
commit | 7374ccc0c322a6dc55f783a1a9c816c6f308d990 (patch) | |
tree | 6a7942db78afc0a47d55ed8a7e823a65e27d8c7b /drivers/video | |
parent | 14048ffed0145a425a8d3114ce8ff48172460238 (diff) |
fbdev: sh_mobile_lcdc: Fix destruction of uninitialized mutex
If sh_mobile_lcdc_probe() fails after the allocation of driver-private
data, but before the initialization of all channels, a warning will be
printed due to the destruction of an uninitialized mutex:
WARNING: CPU: 0 PID: 1 at kernel/locking/mutex-debug.c:116 mutex_destroy+0x5c/0x7c()
DEBUG_LOCKS_WARN_ON(mutex_is_locked(lock))
...
Backtrace:
...
[<c00425b4>] (mutex_destroy) from [<c01d5858>] (sh_mobile_lcdc_remove+0x1bc/0x230)
r4:df6a4800 r3:00000000
[<c01d569c>] (sh_mobile_lcdc_remove) from [<c01d6620>] (sh_mobile_lcdc_probe+0xd54/0xe28)
Move the initialization of the mutexes from sh_mobile_lcdc_channel_init()
to immediately after the allocation of driver-private data to fix this.
Note that the interrupt number is moved to a new variable "irq", so we
can reuse the existing variable "i" for iterating over the channels.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/fbdev/sh_mobile_lcdcfb.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c index 23421ec1c4e4..82c0a8caa9b8 100644 --- a/drivers/video/fbdev/sh_mobile_lcdcfb.c +++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c | |||
@@ -2605,7 +2605,6 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch) | |||
2605 | unsigned int max_size; | 2605 | unsigned int max_size; |
2606 | unsigned int i; | 2606 | unsigned int i; |
2607 | 2607 | ||
2608 | mutex_init(&ch->open_lock); | ||
2609 | ch->notify = sh_mobile_lcdc_display_notify; | 2608 | ch->notify = sh_mobile_lcdc_display_notify; |
2610 | 2609 | ||
2611 | /* Validate the format. */ | 2610 | /* Validate the format. */ |
@@ -2704,7 +2703,7 @@ static int sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
2704 | struct resource *res; | 2703 | struct resource *res; |
2705 | int num_channels; | 2704 | int num_channels; |
2706 | int error; | 2705 | int error; |
2707 | int i; | 2706 | int irq, i; |
2708 | 2707 | ||
2709 | if (!pdata) { | 2708 | if (!pdata) { |
2710 | dev_err(&pdev->dev, "no platform data defined\n"); | 2709 | dev_err(&pdev->dev, "no platform data defined\n"); |
@@ -2712,8 +2711,8 @@ static int sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
2712 | } | 2711 | } |
2713 | 2712 | ||
2714 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2713 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2715 | i = platform_get_irq(pdev, 0); | 2714 | irq = platform_get_irq(pdev, 0); |
2716 | if (!res || i < 0) { | 2715 | if (!res || irq < 0) { |
2717 | dev_err(&pdev->dev, "cannot get platform resources\n"); | 2716 | dev_err(&pdev->dev, "cannot get platform resources\n"); |
2718 | return -ENOENT; | 2717 | return -ENOENT; |
2719 | } | 2718 | } |
@@ -2726,16 +2725,18 @@ static int sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
2726 | 2725 | ||
2727 | priv->dev = &pdev->dev; | 2726 | priv->dev = &pdev->dev; |
2728 | priv->meram_dev = pdata->meram_dev; | 2727 | priv->meram_dev = pdata->meram_dev; |
2728 | for (i = 0; i < ARRAY_SIZE(priv->ch); i++) | ||
2729 | mutex_init(&priv->ch[i].open_lock); | ||
2729 | platform_set_drvdata(pdev, priv); | 2730 | platform_set_drvdata(pdev, priv); |
2730 | 2731 | ||
2731 | error = request_irq(i, sh_mobile_lcdc_irq, 0, | 2732 | error = request_irq(irq, sh_mobile_lcdc_irq, 0, |
2732 | dev_name(&pdev->dev), priv); | 2733 | dev_name(&pdev->dev), priv); |
2733 | if (error) { | 2734 | if (error) { |
2734 | dev_err(&pdev->dev, "unable to request irq\n"); | 2735 | dev_err(&pdev->dev, "unable to request irq\n"); |
2735 | goto err1; | 2736 | goto err1; |
2736 | } | 2737 | } |
2737 | 2738 | ||
2738 | priv->irq = i; | 2739 | priv->irq = irq; |
2739 | atomic_set(&priv->hw_usecnt, -1); | 2740 | atomic_set(&priv->hw_usecnt, -1); |
2740 | 2741 | ||
2741 | for (i = 0, num_channels = 0; i < ARRAY_SIZE(pdata->ch); i++) { | 2742 | for (i = 0, num_channels = 0; i < ARRAY_SIZE(pdata->ch); i++) { |