diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2010-04-30 12:07:00 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-05-06 00:24:56 -0400 |
commit | 8bed90557d2600d25e58de30df48b244980164ec (patch) | |
tree | ce833bf30b8783a0c34068222779c83ba3400234 /drivers | |
parent | 83515bc7df812555e20cda48614674e2f346f9f5 (diff) |
sh: fix a number of Oopses and leaks in SH framebuffer driver
Fix a number of Oopses, memory leaks and unbalanced calls on error paths in
sh_mobile_lcdcfb.c.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/sh_mobile_lcdcfb.c | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index e14bd0749129..e8c769944812 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
@@ -695,6 +695,7 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev, | |||
695 | * 1) Enable Runtime PM | 695 | * 1) Enable Runtime PM |
696 | * 2) Force Runtime PM Resume since hardware is accessed from probe() | 696 | * 2) Force Runtime PM Resume since hardware is accessed from probe() |
697 | */ | 697 | */ |
698 | priv->dev = &pdev->dev; | ||
698 | pm_runtime_enable(priv->dev); | 699 | pm_runtime_enable(priv->dev); |
699 | pm_runtime_resume(priv->dev); | 700 | pm_runtime_resume(priv->dev); |
700 | return 0; | 701 | return 0; |
@@ -957,25 +958,24 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
957 | 958 | ||
958 | if (!pdev->dev.platform_data) { | 959 | if (!pdev->dev.platform_data) { |
959 | dev_err(&pdev->dev, "no platform data defined\n"); | 960 | dev_err(&pdev->dev, "no platform data defined\n"); |
960 | error = -EINVAL; | 961 | return -EINVAL; |
961 | goto err0; | ||
962 | } | 962 | } |
963 | 963 | ||
964 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 964 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
965 | i = platform_get_irq(pdev, 0); | 965 | i = platform_get_irq(pdev, 0); |
966 | if (!res || i < 0) { | 966 | if (!res || i < 0) { |
967 | dev_err(&pdev->dev, "cannot get platform resources\n"); | 967 | dev_err(&pdev->dev, "cannot get platform resources\n"); |
968 | error = -ENOENT; | 968 | return -ENOENT; |
969 | goto err0; | ||
970 | } | 969 | } |
971 | 970 | ||
972 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 971 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
973 | if (!priv) { | 972 | if (!priv) { |
974 | dev_err(&pdev->dev, "cannot allocate device data\n"); | 973 | dev_err(&pdev->dev, "cannot allocate device data\n"); |
975 | error = -ENOMEM; | 974 | return -ENOMEM; |
976 | goto err0; | ||
977 | } | 975 | } |
978 | 976 | ||
977 | platform_set_drvdata(pdev, priv); | ||
978 | |||
979 | error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED, | 979 | error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED, |
980 | dev_name(&pdev->dev), priv); | 980 | dev_name(&pdev->dev), priv); |
981 | if (error) { | 981 | if (error) { |
@@ -984,8 +984,6 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
984 | } | 984 | } |
985 | 985 | ||
986 | priv->irq = i; | 986 | priv->irq = i; |
987 | priv->dev = &pdev->dev; | ||
988 | platform_set_drvdata(pdev, priv); | ||
989 | pdata = pdev->dev.platform_data; | 987 | pdata = pdev->dev.platform_data; |
990 | 988 | ||
991 | j = 0; | 989 | j = 0; |
@@ -1099,9 +1097,9 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
1099 | info = ch->info; | 1097 | info = ch->info; |
1100 | 1098 | ||
1101 | if (info->fbdefio) { | 1099 | if (info->fbdefio) { |
1102 | priv->ch->sglist = vmalloc(sizeof(struct scatterlist) * | 1100 | ch->sglist = vmalloc(sizeof(struct scatterlist) * |
1103 | info->fix.smem_len >> PAGE_SHIFT); | 1101 | info->fix.smem_len >> PAGE_SHIFT); |
1104 | if (!priv->ch->sglist) { | 1102 | if (!ch->sglist) { |
1105 | dev_err(&pdev->dev, "cannot allocate sglist\n"); | 1103 | dev_err(&pdev->dev, "cannot allocate sglist\n"); |
1106 | goto err1; | 1104 | goto err1; |
1107 | } | 1105 | } |
@@ -1126,9 +1124,9 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
1126 | } | 1124 | } |
1127 | 1125 | ||
1128 | return 0; | 1126 | return 0; |
1129 | err1: | 1127 | err1: |
1130 | sh_mobile_lcdc_remove(pdev); | 1128 | sh_mobile_lcdc_remove(pdev); |
1131 | err0: | 1129 | |
1132 | return error; | 1130 | return error; |
1133 | } | 1131 | } |
1134 | 1132 | ||
@@ -1139,7 +1137,7 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) | |||
1139 | int i; | 1137 | int i; |
1140 | 1138 | ||
1141 | for (i = 0; i < ARRAY_SIZE(priv->ch); i++) | 1139 | for (i = 0; i < ARRAY_SIZE(priv->ch); i++) |
1142 | if (priv->ch[i].info->dev) | 1140 | if (priv->ch[i].info && priv->ch[i].info->dev) |
1143 | unregister_framebuffer(priv->ch[i].info); | 1141 | unregister_framebuffer(priv->ch[i].info); |
1144 | 1142 | ||
1145 | sh_mobile_lcdc_stop(priv); | 1143 | sh_mobile_lcdc_stop(priv); |
@@ -1162,7 +1160,8 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) | |||
1162 | if (priv->dot_clk) | 1160 | if (priv->dot_clk) |
1163 | clk_put(priv->dot_clk); | 1161 | clk_put(priv->dot_clk); |
1164 | 1162 | ||
1165 | pm_runtime_disable(priv->dev); | 1163 | if (priv->dev) |
1164 | pm_runtime_disable(priv->dev); | ||
1166 | 1165 | ||
1167 | if (priv->base) | 1166 | if (priv->base) |
1168 | iounmap(priv->base); | 1167 | iounmap(priv->base); |