From 92f2ac7f06eaf2008455661845168ba34bd193bc Mon Sep 17 00:00:00 2001 From: ddl Date: Thu, 2 Sep 2010 10:59:22 +0800 Subject: [PATCH] camera:fix memory leak, the struct videobuf_buffer which malloced videobuf_alloc isn't free after camera exit --- drivers/media/video/rk2818_camera.c | 64 +++++++++++++++++++---------- drivers/media/video/soc_camera.c | 5 +-- 2 files changed, 43 insertions(+), 26 deletions(-) mode change 100755 => 100644 drivers/media/video/rk2818_camera.c diff --git a/drivers/media/video/rk2818_camera.c b/drivers/media/video/rk2818_camera.c old mode 100755 new mode 100644 index a7fb7858bc7b..3f4afa335f33 --- a/drivers/media/video/rk2818_camera.c +++ b/drivers/media/video/rk2818_camera.c @@ -97,11 +97,16 @@ #define VIPREGPAL 0x00000400 //-------------------------- #define CONFIG_RK28CAMERA_TR 1 - +#define CONFIG_RK28CAMERA_DEBUG 0 #if (CONFIG_RK28CAMERA_TR) -#define RK28CAMERA_TR(format, ...) printk(format, ## __VA_ARGS__) + #define RK28CAMERA_TR(format, ...) printk(format, ## __VA_ARGS__) + #if (CONFIG_RK28CAMERA_DEBUG) + #define RK28CAMERA_DG(format, ...) printk(format, ## __VA_ARGS__) + #else + #define RK28CAMERA_DG(format, ...) + #endif #else -#define RK28CAMERA_TR(format, ...) + #define RK28CAMERA_TR(format, ...) #endif #define MIN(x,y) ((xuser_width * icd->user_height * bytes_per_pixel); /* Y pages UV pages, yuv422*/ - RK28CAMERA_TR("\n%s..%d.. size = %d ******** ddl *********\n",__FUNCTION__,__LINE__, *size); + RK28CAMERA_DG("\n%s..%d.. size = %d ******** ddl *********\n",__FUNCTION__,__LINE__, *size); return 0; } @@ -210,6 +215,10 @@ static void rk28_videobuf_free(struct videobuf_queue *vq, struct rk28_buffer *bu dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, &buf->vb, buf->vb.baddr, buf->vb.bsize); + /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/ + if (buf->vb.state == VIDEOBUF_NEEDS_INIT) + return; + if (in_interrupt()) BUG(); @@ -398,13 +407,14 @@ static void rk28_camera_init_videobuf(struct videobuf_queue *q, V4L2_FIELD_NONE, sizeof(struct rk28_buffer), icd); + pcdev->vb_vidq_ptr = q; /* ddl@rock-chips.com */ } static int rk28_camera_activate(struct rk28_camera_dev *pcdev, struct soc_camera_device *icd) { unsigned long sensor_bus_flags = SOCAM_MCLK_24MHZ; struct clk *parent; - RK28CAMERA_TR("\n%s..%d.. ******** ddl *********\n",__FUNCTION__,__LINE__); + RK28CAMERA_DG("\n%s..%d.. ******** ddl *********\n",__FUNCTION__,__LINE__); if (!pcdev->clk || IS_ERR(pcdev->clk)) RK28CAMERA_TR(KERN_ERR "failed to get vip_clk source\n"); @@ -434,7 +444,7 @@ static int rk28_camera_activate(struct rk28_camera_dev *pcdev, struct soc_camera write_vip_reg(RK28_VIP_RESET, 0x76543210); /* ddl@rock-chips.com : vip software reset */ udelay(10); - write_vip_reg(RK28_VIP_AHBR_CTRL, 0x05); //only 8 or 4 will be the actual length. + write_vip_reg(RK28_VIP_AHBR_CTRL, 0x07); /* ddl@rock-chips.com : vip ahb burst 16 */ write_vip_reg(RK28_VIP_INT_MASK, 0x01); //capture complete interrupt enable write_vip_reg(RK28_VIP_CRM, 0x00000000); //Y/CB/CR color modification @@ -507,6 +517,13 @@ static void rk28_camera_remove_device(struct soc_camera_device *icd) dev_info(&icd->dev, "RK28 Camera driver detached from camera %d\n", icd->devnum); + /* ddl@rock-chips.com: Call videobuf_mmap_free here for free the struct video_buffer which malloc in videobuf_alloc */ + if (pcdev->vb_vidq_ptr) { + videobuf_mmap_free(pcdev->vb_vidq_ptr); + pcdev->vb_vidq_ptr = NULL; + } + + rk28_camera_deactivate(pcdev); pcdev->icd = NULL; @@ -518,7 +535,7 @@ static int rk28_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt unsigned int vip_ctrl_val = 0; int ret = 0; - RK28CAMERA_TR("\n%s..%d.. ******** ddl *********\n",__FUNCTION__,__LINE__); + RK28CAMERA_DG("\n%s..%d.. ******** ddl *********\n",__FUNCTION__,__LINE__); bus_flags = RK28_CAM_BUS_PARAM; @@ -546,11 +563,12 @@ static int rk28_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt vip_ctrl_val |= ENABLE_CAPTURE; write_vip_reg(RK28_VIP_CTRL, vip_ctrl_val); - RK28CAMERA_TR("\n%s..CtrReg=%x ******** ddl *********\n",__FUNCTION__,read_vip_reg(RK28_VIP_CTRL)); - + RK28CAMERA_DG("\n%s..CtrReg=%x ******** ddl *********\n",__FUNCTION__,read_vip_reg(RK28_VIP_CTRL)); + RK28_CAMERA_SET_BUS_PARAM_END: - RK28CAMERA_TR("\n%s..%d.. ret = %d ^^^^^^^^^ ddl^^^^^^^^^^\n",__FUNCTION__,__LINE__, ret); - return ret; + if (ret) + RK28CAMERA_TR("\n%s..%d.. ret = %d ^^^^^^^^^ ddl^^^^^^^^^^\n",__FUNCTION__,__LINE__, ret); + return ret; } static int rk28_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt) @@ -630,7 +648,7 @@ static void rk28_camera_setup_format(struct soc_camera_device *icd, __u32 host_p write_vip_reg(RK28_VIP_FB_SR, 0x00000003); - RK28CAMERA_TR("\n%s.. crop:%x .. fs : %x *** ddl ***\n",__FUNCTION__,vip_crop,vip_fs); + RK28CAMERA_DG("\n%s.. crop:%x .. fs : %x *** ddl ***\n",__FUNCTION__,vip_crop,vip_fs); } static int rk28_camera_get_formats(struct soc_camera_device *icd, int idx, @@ -729,7 +747,7 @@ static int rk28_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_rect rect; int ret; - RK28CAMERA_TR("\n%s..%d.. ******** ddl *********\n",__FUNCTION__,__LINE__); + RK28CAMERA_DG("\n%s..%d.. ******** ddl *********\n",__FUNCTION__,__LINE__); xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); if (!xlate) { @@ -753,7 +771,7 @@ static int rk28_camera_set_fmt(struct soc_camera_device *icd, rect.width = pix->width; rect.height = pix->height; - RK28CAMERA_TR("\n%s..%s..%s ^^^^^^^^^ ddl^^^^^^^^^^\n",__FUNCTION__,xlate->host_fmt->name, cam_fmt->name); + RK28CAMERA_DG("\n%s..%s..%s ^^^^^^^^^ ddl^^^^^^^^^^\n",__FUNCTION__,xlate->host_fmt->name, cam_fmt->name); rk28_camera_setup_format(icd, pix->pixelformat, cam_fmt->fourcc, &rect); icd->buswidth = xlate->buswidth; @@ -761,8 +779,9 @@ static int rk28_camera_set_fmt(struct soc_camera_device *icd, } RK28_CAMERA_SET_FMT_END: - RK28CAMERA_TR("\n%s..%d.. ret = %d ^^^^^^^^^ ddl^^^^^^^^^^\n",__FUNCTION__,__LINE__, ret); - return ret; + if (ret) + RK28CAMERA_TR("\n%s..%d.. ret = %d ^^^^^^^^^ ddl^^^^^^^^^^\n",__FUNCTION__,__LINE__, ret); + return ret; } static int rk28_camera_try_fmt(struct soc_camera_device *icd, @@ -776,7 +795,7 @@ static int rk28_camera_try_fmt(struct soc_camera_device *icd, enum v4l2_field field; int ret,i; - RK28CAMERA_TR("\n%s..%d.. ******** ddl *********\n",__FUNCTION__,__LINE__); + RK28CAMERA_DG("\n%s..%d.. ******** ddl *********\n",__FUNCTION__,__LINE__); xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (!xlate) { @@ -810,7 +829,8 @@ static int rk28_camera_try_fmt(struct soc_camera_device *icd, } RK28_CAMERA_TRY_FMT_END: - RK28CAMERA_TR("\n%s..%d.. ret = %d ^^^^^^^^^ ddl^^^^^^^^^^\n",__FUNCTION__,__LINE__, ret); + if (ret) + RK28CAMERA_TR("\n%s..%d.. ret = %d ^^^^^^^^^ ddl^^^^^^^^^^\n",__FUNCTION__,__LINE__, ret); return ret; } @@ -912,7 +932,7 @@ static int rk28_camera_probe(struct platform_device *pdev) int irq; int err = 0; - RK28CAMERA_TR("\n%s..%s..%d ******** ddl *********\n",__FUNCTION__,__FILE__,__LINE__); + RK28CAMERA_DG("\n%s..%s..%d ******** ddl *********\n",__FUNCTION__,__FILE__,__LINE__); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); if (!res || irq < 0) { @@ -985,7 +1005,7 @@ static int rk28_camera_probe(struct platform_device *pdev) if (err) goto exit_free_irq; - RK28CAMERA_TR("\n%s..%s..%d ^^^^^^^^ ddl^^^^^^^^\n",__FUNCTION__,__FILE__,__LINE__); + RK28CAMERA_DG("\n%s..%s..%d ^^^^^^^^ ddl^^^^^^^^\n",__FUNCTION__,__FILE__,__LINE__); return 0; exit_free_irq: @@ -1039,7 +1059,7 @@ static struct platform_driver rk28_camera_driver = static int __devinit rk28_camera_init(void) { - RK28CAMERA_TR("\n%s..%s..%d ******** ddl *********\n",__FUNCTION__,__FILE__,__LINE__); + RK28CAMERA_DG("\n%s..%s..%d ******** ddl *********\n",__FUNCTION__,__FILE__,__LINE__); return platform_driver_register(&rk28_camera_driver); } diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 141d81ab1cbb..0ecbf6b4f36e 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -292,8 +292,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf, dev_dbg(&icd->dev, "S_FMT(%c%c%c%c, %ux%u)\n", pixfmtstr(pix->pixelformat), pix->width, pix->height); - - printk("%s..%d.. ********ddl*******\n",__FUNCTION__, __LINE__); + /* We always call try_fmt() before set_fmt() or set_crop() */ ret = ici->ops->try_fmt(icd, f); if (ret < 0) @@ -444,8 +443,6 @@ static int soc_camera_close(struct file *file) module_put(ici->ops->owner); - printk("icf->vb_vidq.bufs[0] = 0x%x\n",(int)(icf->vb_vidq.bufs[0])); - vfree(icf); dev_dbg(&icd->dev, "camera device close\n"); -- 2.34.1