From 594bb46dbc63934bc65fa95743f83204bd26a641 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 24 Apr 2009 12:53:51 -0300 Subject: V4L/DVB (11607): soc-camera: add a free_bus method to struct soc_camera_link Currently pcm990 camera bus-width management functions request a GPIO and never free it again. With this approach the GPIO extender driver cannot be unloaded once camera drivers have been loaded, also unloading theb i2c-pxa bus driver produces errors, because the GPIO extender driver cannot unregister properly. Another problem is, that if camera drivers are once loaded before the GPIO extender driver, the platform code marks the GPIO unavailable and only a reboot helps to recover. Adding an explicit free_bus method and using it in mt9m001 and mt9v022 drivers fixes these problems. Signed-off-by: Guennadi Liakhovetski Acked-by: Eric Miao Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mt9m001.c | 3 +++ drivers/media/video/mt9v022.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index 684f62fa789..3838ff77381 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c @@ -604,10 +604,13 @@ ei2c: static void mt9m001_video_remove(struct soc_camera_device *icd) { struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + struct soc_camera_link *icl = mt9m001->client->dev.platform_data; dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr, icd->dev.parent, icd->vdev); soc_camera_video_stop(icd); + if (icl->free_bus) + icl->free_bus(icl); } static int mt9m001_probe(struct i2c_client *client, diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index 4d3b4813c32..412b399baca 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c @@ -735,10 +735,13 @@ ei2c: static void mt9v022_video_remove(struct soc_camera_device *icd) { struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + struct soc_camera_link *icl = mt9v022->client->dev.platform_data; dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, icd->dev.parent, icd->vdev); soc_camera_video_stop(icd); + if (icl->free_bus) + icl->free_bus(icl); } static int mt9v022_probe(struct i2c_client *client, -- cgit v1.2.3-70-g09d2