aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2011-09-22 16:10:30 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-11-03 16:33:46 -0400
commit9b6390bd95c65ad4a6c650955fa1e3f18f8a540c (patch)
tree3e1dcd35d28f0793dd62d1a3ff72b4831890a118 /drivers/media/video
parented33ac8e0876a3016511ea0aaf9af1d965ee2c44 (diff)
[media] omap3isp: Fix memory leaks in initialization error paths
Make sure all modules init functions clean up after themselves in case of error. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reported-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/omap3isp/ispccdc.c19
-rw-r--r--drivers/media/video/omap3isp/ispccp2.c22
-rw-r--r--drivers/media/video/omap3isp/ispcsi2.c15
-rw-r--r--drivers/media/video/omap3isp/isppreview.c27
-rw-r--r--drivers/media/video/omap3isp/ispresizer.c27
-rw-r--r--drivers/media/video/omap3isp/ispstat.c11
6 files changed, 74 insertions, 47 deletions
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c
index 3a43be2f545..6330b1d57b1 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -2224,15 +2224,21 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
2224 2224
2225 ret = omap3isp_video_init(&ccdc->video_out, "CCDC"); 2225 ret = omap3isp_video_init(&ccdc->video_out, "CCDC");
2226 if (ret < 0) 2226 if (ret < 0)
2227 return ret; 2227 goto error_video;
2228 2228
2229 /* Connect the CCDC subdev to the video node. */ 2229 /* Connect the CCDC subdev to the video node. */
2230 ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF, 2230 ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
2231 &ccdc->video_out.video.entity, 0, 0); 2231 &ccdc->video_out.video.entity, 0, 0);
2232 if (ret < 0) 2232 if (ret < 0)
2233 return ret; 2233 goto error_link;
2234 2234
2235 return 0; 2235 return 0;
2236
2237error_link:
2238 omap3isp_video_cleanup(&ccdc->video_out);
2239error_video:
2240 media_entity_cleanup(me);
2241 return ret;
2236} 2242}
2237 2243
2238/* 2244/*
@@ -2246,6 +2252,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
2246int omap3isp_ccdc_init(struct isp_device *isp) 2252int omap3isp_ccdc_init(struct isp_device *isp)
2247{ 2253{
2248 struct isp_ccdc_device *ccdc = &isp->isp_ccdc; 2254 struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
2255 int ret;
2249 2256
2250 spin_lock_init(&ccdc->lock); 2257 spin_lock_init(&ccdc->lock);
2251 init_waitqueue_head(&ccdc->wait); 2258 init_waitqueue_head(&ccdc->wait);
@@ -2274,7 +2281,13 @@ int omap3isp_ccdc_init(struct isp_device *isp)
2274 ccdc->update = OMAP3ISP_CCDC_BLCLAMP; 2281 ccdc->update = OMAP3ISP_CCDC_BLCLAMP;
2275 ccdc_apply_controls(ccdc); 2282 ccdc_apply_controls(ccdc);
2276 2283
2277 return ccdc_init_entities(ccdc); 2284 ret = ccdc_init_entities(ccdc);
2285 if (ret < 0) {
2286 mutex_destroy(&ccdc->ioctl_lock);
2287 return ret;
2288 }
2289
2290 return 0;
2278} 2291}
2279 2292
2280/* 2293/*
diff --git a/drivers/media/video/omap3isp/ispccp2.c b/drivers/media/video/omap3isp/ispccp2.c
index 883a2825cb4..904ca8c8b17 100644
--- a/drivers/media/video/omap3isp/ispccp2.c
+++ b/drivers/media/video/omap3isp/ispccp2.c
@@ -1125,15 +1125,21 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
1125 1125
1126 ret = omap3isp_video_init(&ccp2->video_in, "CCP2"); 1126 ret = omap3isp_video_init(&ccp2->video_in, "CCP2");
1127 if (ret < 0) 1127 if (ret < 0)
1128 return ret; 1128 goto error_video;
1129 1129
1130 /* Connect the video node to the ccp2 subdev. */ 1130 /* Connect the video node to the ccp2 subdev. */
1131 ret = media_entity_create_link(&ccp2->video_in.video.entity, 0, 1131 ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
1132 &ccp2->subdev.entity, CCP2_PAD_SINK, 0); 1132 &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
1133 if (ret < 0) 1133 if (ret < 0)
1134 return ret; 1134 goto error_link;
1135 1135
1136 return 0; 1136 return 0;
1137
1138error_link:
1139 omap3isp_video_cleanup(&ccp2->video_in);
1140error_video:
1141 media_entity_cleanup(&ccp2->subdev.entity);
1142 return ret;
1137} 1143}
1138 1144
1139/* 1145/*
@@ -1171,15 +1177,13 @@ int omap3isp_ccp2_init(struct isp_device *isp)
1171 } 1177 }
1172 1178
1173 ret = ccp2_init_entities(ccp2); 1179 ret = ccp2_init_entities(ccp2);
1174 if (ret < 0) 1180 if (ret < 0) {
1175 goto out; 1181 regulator_put(ccp2->vdds_csib);
1182 return ret;
1183 }
1176 1184
1177 ccp2_reset(ccp2); 1185 ccp2_reset(ccp2);
1178out: 1186 return 0;
1179 if (ret)
1180 omap3isp_ccp2_cleanup(isp);
1181
1182 return ret;
1183} 1187}
1184 1188
1185/* 1189/*
diff --git a/drivers/media/video/omap3isp/ispcsi2.c b/drivers/media/video/omap3isp/ispcsi2.c
index 2c9bffcdc5c..0c5f1cb9d99 100644
--- a/drivers/media/video/omap3isp/ispcsi2.c
+++ b/drivers/media/video/omap3isp/ispcsi2.c
@@ -1259,15 +1259,21 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
1259 1259
1260 ret = omap3isp_video_init(&csi2->video_out, "CSI2a"); 1260 ret = omap3isp_video_init(&csi2->video_out, "CSI2a");
1261 if (ret < 0) 1261 if (ret < 0)
1262 return ret; 1262 goto error_video;
1263 1263
1264 /* Connect the CSI2 subdev to the video node. */ 1264 /* Connect the CSI2 subdev to the video node. */
1265 ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE, 1265 ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
1266 &csi2->video_out.video.entity, 0, 0); 1266 &csi2->video_out.video.entity, 0, 0);
1267 if (ret < 0) 1267 if (ret < 0)
1268 return ret; 1268 goto error_link;
1269 1269
1270 return 0; 1270 return 0;
1271
1272error_link:
1273 omap3isp_video_cleanup(&csi2->video_out);
1274error_video:
1275 media_entity_cleanup(&csi2->subdev.entity);
1276 return ret;
1271} 1277}
1272 1278
1273/* 1279/*
@@ -1289,7 +1295,7 @@ int omap3isp_csi2_init(struct isp_device *isp)
1289 1295
1290 ret = csi2_init_entities(csi2a); 1296 ret = csi2_init_entities(csi2a);
1291 if (ret < 0) 1297 if (ret < 0)
1292 goto fail; 1298 return ret;
1293 1299
1294 if (isp->revision == ISP_REVISION_15_0) { 1300 if (isp->revision == ISP_REVISION_15_0) {
1295 csi2c->isp = isp; 1301 csi2c->isp = isp;
@@ -1302,9 +1308,6 @@ int omap3isp_csi2_init(struct isp_device *isp)
1302 } 1308 }
1303 1309
1304 return 0; 1310 return 0;
1305fail:
1306 omap3isp_csi2_cleanup(isp);
1307 return ret;
1308} 1311}
1309 1312
1310/* 1313/*
diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c
index b926ebbaca3..b3818356b6f 100644
--- a/drivers/media/video/omap3isp/isppreview.c
+++ b/drivers/media/video/omap3isp/isppreview.c
@@ -2060,24 +2060,32 @@ static int preview_init_entities(struct isp_prev_device *prev)
2060 2060
2061 ret = omap3isp_video_init(&prev->video_in, "preview"); 2061 ret = omap3isp_video_init(&prev->video_in, "preview");
2062 if (ret < 0) 2062 if (ret < 0)
2063 return ret; 2063 goto error_video_in;
2064 2064
2065 ret = omap3isp_video_init(&prev->video_out, "preview"); 2065 ret = omap3isp_video_init(&prev->video_out, "preview");
2066 if (ret < 0) 2066 if (ret < 0)
2067 return ret; 2067 goto error_video_out;
2068 2068
2069 /* Connect the video nodes to the previewer subdev. */ 2069 /* Connect the video nodes to the previewer subdev. */
2070 ret = media_entity_create_link(&prev->video_in.video.entity, 0, 2070 ret = media_entity_create_link(&prev->video_in.video.entity, 0,
2071 &prev->subdev.entity, PREV_PAD_SINK, 0); 2071 &prev->subdev.entity, PREV_PAD_SINK, 0);
2072 if (ret < 0) 2072 if (ret < 0)
2073 return ret; 2073 goto error_link;
2074 2074
2075 ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE, 2075 ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE,
2076 &prev->video_out.video.entity, 0, 0); 2076 &prev->video_out.video.entity, 0, 0);
2077 if (ret < 0) 2077 if (ret < 0)
2078 return ret; 2078 goto error_link;
2079 2079
2080 return 0; 2080 return 0;
2081
2082error_link:
2083 omap3isp_video_cleanup(&prev->video_out);
2084error_video_out:
2085 omap3isp_video_cleanup(&prev->video_in);
2086error_video_in:
2087 media_entity_cleanup(&prev->subdev.entity);
2088 return ret;
2081} 2089}
2082 2090
2083/* 2091/*
@@ -2088,21 +2096,12 @@ static int preview_init_entities(struct isp_prev_device *prev)
2088int omap3isp_preview_init(struct isp_device *isp) 2096int omap3isp_preview_init(struct isp_device *isp)
2089{ 2097{
2090 struct isp_prev_device *prev = &isp->isp_prev; 2098 struct isp_prev_device *prev = &isp->isp_prev;
2091 int ret;
2092 2099
2093 spin_lock_init(&prev->lock); 2100 spin_lock_init(&prev->lock);
2094 init_waitqueue_head(&prev->wait); 2101 init_waitqueue_head(&prev->wait);
2095 preview_init_params(prev); 2102 preview_init_params(prev);
2096 2103
2097 ret = preview_init_entities(prev); 2104 return preview_init_entities(prev);
2098 if (ret < 0)
2099 goto out;
2100
2101out:
2102 if (ret)
2103 omap3isp_preview_cleanup(isp);
2104
2105 return ret;
2106} 2105}
2107 2106
2108void omap3isp_preview_cleanup(struct isp_device *isp) 2107void omap3isp_preview_cleanup(struct isp_device *isp)
diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/video/omap3isp/ispresizer.c
index 224b0b90404..50e593bfcfa 100644
--- a/drivers/media/video/omap3isp/ispresizer.c
+++ b/drivers/media/video/omap3isp/ispresizer.c
@@ -1688,24 +1688,32 @@ static int resizer_init_entities(struct isp_res_device *res)
1688 1688
1689 ret = omap3isp_video_init(&res->video_in, "resizer"); 1689 ret = omap3isp_video_init(&res->video_in, "resizer");
1690 if (ret < 0) 1690 if (ret < 0)
1691 return ret; 1691 goto error_video_in;
1692 1692
1693 ret = omap3isp_video_init(&res->video_out, "resizer"); 1693 ret = omap3isp_video_init(&res->video_out, "resizer");
1694 if (ret < 0) 1694 if (ret < 0)
1695 return ret; 1695 goto error_video_out;
1696 1696
1697 /* Connect the video nodes to the resizer subdev. */ 1697 /* Connect the video nodes to the resizer subdev. */
1698 ret = media_entity_create_link(&res->video_in.video.entity, 0, 1698 ret = media_entity_create_link(&res->video_in.video.entity, 0,
1699 &res->subdev.entity, RESZ_PAD_SINK, 0); 1699 &res->subdev.entity, RESZ_PAD_SINK, 0);
1700 if (ret < 0) 1700 if (ret < 0)
1701 return ret; 1701 goto error_link;
1702 1702
1703 ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE, 1703 ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE,
1704 &res->video_out.video.entity, 0, 0); 1704 &res->video_out.video.entity, 0, 0);
1705 if (ret < 0) 1705 if (ret < 0)
1706 return ret; 1706 goto error_link;
1707 1707
1708 return 0; 1708 return 0;
1709
1710error_link:
1711 omap3isp_video_cleanup(&res->video_out);
1712error_video_out:
1713 omap3isp_video_cleanup(&res->video_in);
1714error_video_in:
1715 media_entity_cleanup(&res->subdev.entity);
1716 return ret;
1709} 1717}
1710 1718
1711/* 1719/*
@@ -1716,19 +1724,10 @@ static int resizer_init_entities(struct isp_res_device *res)
1716int omap3isp_resizer_init(struct isp_device *isp) 1724int omap3isp_resizer_init(struct isp_device *isp)
1717{ 1725{
1718 struct isp_res_device *res = &isp->isp_res; 1726 struct isp_res_device *res = &isp->isp_res;
1719 int ret;
1720 1727
1721 init_waitqueue_head(&res->wait); 1728 init_waitqueue_head(&res->wait);
1722 atomic_set(&res->stopping, 0); 1729 atomic_set(&res->stopping, 0);
1723 ret = resizer_init_entities(res); 1730 return resizer_init_entities(res);
1724 if (ret < 0)
1725 goto out;
1726
1727out:
1728 if (ret)
1729 omap3isp_resizer_cleanup(isp);
1730
1731 return ret;
1732} 1731}
1733 1732
1734void omap3isp_resizer_cleanup(struct isp_device *isp) 1733void omap3isp_resizer_cleanup(struct isp_device *isp)
diff --git a/drivers/media/video/omap3isp/ispstat.c b/drivers/media/video/omap3isp/ispstat.c
index 28b7cc61cba..68d539456c5 100644
--- a/drivers/media/video/omap3isp/ispstat.c
+++ b/drivers/media/video/omap3isp/ispstat.c
@@ -1074,14 +1074,23 @@ static int isp_stat_init_entities(struct ispstat *stat, const char *name,
1074int omap3isp_stat_init(struct ispstat *stat, const char *name, 1074int omap3isp_stat_init(struct ispstat *stat, const char *name,
1075 const struct v4l2_subdev_ops *sd_ops) 1075 const struct v4l2_subdev_ops *sd_ops)
1076{ 1076{
1077 int ret;
1078
1077 stat->buf = kcalloc(STAT_MAX_BUFS, sizeof(*stat->buf), GFP_KERNEL); 1079 stat->buf = kcalloc(STAT_MAX_BUFS, sizeof(*stat->buf), GFP_KERNEL);
1078 if (!stat->buf) 1080 if (!stat->buf)
1079 return -ENOMEM; 1081 return -ENOMEM;
1082
1080 isp_stat_buf_clear(stat); 1083 isp_stat_buf_clear(stat);
1081 mutex_init(&stat->ioctl_lock); 1084 mutex_init(&stat->ioctl_lock);
1082 atomic_set(&stat->buf_err, 0); 1085 atomic_set(&stat->buf_err, 0);
1083 1086
1084 return isp_stat_init_entities(stat, name, sd_ops); 1087 ret = isp_stat_init_entities(stat, name, sd_ops);
1088 if (ret < 0) {
1089 mutex_destroy(&stat->ioctl_lock);
1090 kfree(stat->buf);
1091 }
1092
1093 return ret;
1085} 1094}
1086 1095
1087void omap3isp_stat_cleanup(struct ispstat *stat) 1096void omap3isp_stat_cleanup(struct ispstat *stat)