Commit 64ff9ba5 authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Mauro Carvalho Chehab

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: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent f39c1ab3
...@@ -1097,6 +1097,13 @@ static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a) ...@@ -1097,6 +1097,13 @@ static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
return v4l2_subdev_call(sd, video, s_crop, a); return v4l2_subdev_call(sd, video, s_crop, a);
} }
static void soc_camera_device_init(struct device *dev, void *pdata)
{
dev->platform_data = pdata;
dev->bus = &soc_camera_bus_type;
dev->release = dummy_release;
}
int soc_camera_host_register(struct soc_camera_host *ici) int soc_camera_host_register(struct soc_camera_host *ici)
{ {
struct soc_camera_host *ix; struct soc_camera_host *ix;
...@@ -1158,6 +1165,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici) ...@@ -1158,6 +1165,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
list_for_each_entry(icd, &devices, list) { list_for_each_entry(icd, &devices, list) {
if (icd->iface == ici->nr) { if (icd->iface == ici->nr) {
void *pdata = icd->dev.platform_data;
/* The bus->remove will be called */ /* The bus->remove will be called */
device_unregister(&icd->dev); device_unregister(&icd->dev);
/* /*
...@@ -1169,6 +1177,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici) ...@@ -1169,6 +1177,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
* device private data. * device private data.
*/ */
memset(&icd->dev, 0, sizeof(icd->dev)); memset(&icd->dev, 0, sizeof(icd->dev));
soc_camera_device_init(&icd->dev, pdata);
} }
} }
...@@ -1200,10 +1209,7 @@ static int soc_camera_device_register(struct soc_camera_device *icd) ...@@ -1200,10 +1209,7 @@ static int soc_camera_device_register(struct soc_camera_device *icd)
* man, stay reasonable... */ * man, stay reasonable... */
return -ENOMEM; return -ENOMEM;
icd->devnum = num; icd->devnum = num;
icd->dev.bus = &soc_camera_bus_type;
icd->dev.release = dummy_release;
icd->use_count = 0; icd->use_count = 0;
icd->host_priv = NULL; icd->host_priv = NULL;
mutex_init(&icd->video_lock); mutex_init(&icd->video_lock);
...@@ -1311,12 +1317,13 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) ...@@ -1311,12 +1317,13 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
icd->iface = icl->bus_id; icd->iface = icl->bus_id;
icd->pdev = &pdev->dev; icd->pdev = &pdev->dev;
platform_set_drvdata(pdev, icd); platform_set_drvdata(pdev, icd);
icd->dev.platform_data = icl;
ret = soc_camera_device_register(icd); ret = soc_camera_device_register(icd);
if (ret < 0) if (ret < 0)
goto escdevreg; goto escdevreg;
soc_camera_device_init(&icd->dev, icl);
icd->user_width = DEFAULT_WIDTH; icd->user_width = DEFAULT_WIDTH;
icd->user_height = DEFAULT_HEIGHT; icd->user_height = DEFAULT_HEIGHT;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment