diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2009-11-09 14:12:37 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-11-26 16:38:02 -0500 |
commit | 64ff9ba5f1d771e8405ec766c31f6b32c9708285 (patch) | |
tree | cda19375ecf8e742b7aae674fd3692c09d6155a5 | |
parent | f39c1ab3c3878f1a50ca129e55d17ae63215fcbe (diff) |
V4L/DVB (13344): soc-camera: properly initialise the device object when reusing
Commit ef373189f62413803b7b816c972fc154c488cdc0 "fix use-after-free Oops,
resulting from a driver-core API change" fixed the Oops, but didn't correct
missing device object initialisation. This patch makes unloading and reloading
of soc-camera host- and client-drivers possible again.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/soc_camera.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 36e617bd13c7..95fdeb23c2c1 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -1097,6 +1097,13 @@ static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a) | |||
1097 | return v4l2_subdev_call(sd, video, s_crop, a); | 1097 | return v4l2_subdev_call(sd, video, s_crop, a); |
1098 | } | 1098 | } |
1099 | 1099 | ||
1100 | static void soc_camera_device_init(struct device *dev, void *pdata) | ||
1101 | { | ||
1102 | dev->platform_data = pdata; | ||
1103 | dev->bus = &soc_camera_bus_type; | ||
1104 | dev->release = dummy_release; | ||
1105 | } | ||
1106 | |||
1100 | int soc_camera_host_register(struct soc_camera_host *ici) | 1107 | int soc_camera_host_register(struct soc_camera_host *ici) |
1101 | { | 1108 | { |
1102 | struct soc_camera_host *ix; | 1109 | struct soc_camera_host *ix; |
@@ -1158,6 +1165,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici) | |||
1158 | 1165 | ||
1159 | list_for_each_entry(icd, &devices, list) { | 1166 | list_for_each_entry(icd, &devices, list) { |
1160 | if (icd->iface == ici->nr) { | 1167 | if (icd->iface == ici->nr) { |
1168 | void *pdata = icd->dev.platform_data; | ||
1161 | /* The bus->remove will be called */ | 1169 | /* The bus->remove will be called */ |
1162 | device_unregister(&icd->dev); | 1170 | device_unregister(&icd->dev); |
1163 | /* | 1171 | /* |
@@ -1169,6 +1177,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici) | |||
1169 | * device private data. | 1177 | * device private data. |
1170 | */ | 1178 | */ |
1171 | memset(&icd->dev, 0, sizeof(icd->dev)); | 1179 | memset(&icd->dev, 0, sizeof(icd->dev)); |
1180 | soc_camera_device_init(&icd->dev, pdata); | ||
1172 | } | 1181 | } |
1173 | } | 1182 | } |
1174 | 1183 | ||
@@ -1200,10 +1209,7 @@ static int soc_camera_device_register(struct soc_camera_device *icd) | |||
1200 | * man, stay reasonable... */ | 1209 | * man, stay reasonable... */ |
1201 | return -ENOMEM; | 1210 | return -ENOMEM; |
1202 | 1211 | ||
1203 | icd->devnum = num; | 1212 | icd->devnum = num; |
1204 | icd->dev.bus = &soc_camera_bus_type; | ||
1205 | |||
1206 | icd->dev.release = dummy_release; | ||
1207 | icd->use_count = 0; | 1213 | icd->use_count = 0; |
1208 | icd->host_priv = NULL; | 1214 | icd->host_priv = NULL; |
1209 | mutex_init(&icd->video_lock); | 1215 | mutex_init(&icd->video_lock); |
@@ -1311,12 +1317,13 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) | |||
1311 | icd->iface = icl->bus_id; | 1317 | icd->iface = icl->bus_id; |
1312 | icd->pdev = &pdev->dev; | 1318 | icd->pdev = &pdev->dev; |
1313 | platform_set_drvdata(pdev, icd); | 1319 | platform_set_drvdata(pdev, icd); |
1314 | icd->dev.platform_data = icl; | ||
1315 | 1320 | ||
1316 | ret = soc_camera_device_register(icd); | 1321 | ret = soc_camera_device_register(icd); |
1317 | if (ret < 0) | 1322 | if (ret < 0) |
1318 | goto escdevreg; | 1323 | goto escdevreg; |
1319 | 1324 | ||
1325 | soc_camera_device_init(&icd->dev, icl); | ||
1326 | |||
1320 | icd->user_width = DEFAULT_WIDTH; | 1327 | icd->user_width = DEFAULT_WIDTH; |
1321 | icd->user_height = DEFAULT_HEIGHT; | 1328 | icd->user_height = DEFAULT_HEIGHT; |
1322 | 1329 | ||