On Mon, Sep 26, 2011 at 18:31:48, Hans Verkuil wrote:
> On Monday, September 19, 2011 07:35:27 Manjunath Hadli wrote:
> > This patch implements the core additions to the display driver, mainly 
> > controlling the VENC and other encoders for dm365.
> > This patch also includes addition of amplifier subdevice to the vpbe 
> > driver and interfacing with venc subdevice.
> > 
> > Signed-off-by: Manjunath Hadli <manjunath.ha...@ti.com>
> > ---
> >  drivers/media/video/davinci/vpbe.c |   55 
> > ++++++++++++++++++++++++++++++++++--
> >  include/media/davinci/vpbe.h       |   16 ++++++++++
> >  2 files changed, 68 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/media/video/davinci/vpbe.c 
> > b/drivers/media/video/davinci/vpbe.c
> > index d773d30..21a8645 100644
> > --- a/drivers/media/video/davinci/vpbe.c
> > +++ b/drivers/media/video/davinci/vpbe.c
> > @@ -141,11 +141,12 @@ static int vpbe_enum_outputs(struct vpbe_device 
> > *vpbe_dev,
> >     return 0;
> >  }
> >  
> > -static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char 
> > *mode)
Hans,

> > +static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode,
> > +                         int output_index)
> >  {
> >     struct vpbe_config *cfg = vpbe_dev->cfg;
> >     struct vpbe_enc_mode_info var;
> > -   int curr_output = vpbe_dev->current_out_index;
> > +   int curr_output = output_index;
> >     int i;
> >  
> >     if (NULL == mode)
> > @@ -245,6 +246,8 @@ static int vpbe_set_output(struct vpbe_device 
> > *vpbe_dev, int index)
> >     struct encoder_config_info *curr_enc_info =
> >                     vpbe_current_encoder_info(vpbe_dev);
> >     struct vpbe_config *cfg = vpbe_dev->cfg;
> > +   struct venc_platform_data *venc_device = vpbe_dev->venc_device;
> > +   enum v4l2_mbus_pixelcode if_params;
> >     int enc_out_index;
> >     int sd_index;
> >     int ret = 0;
> > @@ -274,6 +277,8 @@ static int vpbe_set_output(struct vpbe_device 
> > *vpbe_dev, int index)
> >                     goto out;
> >             }
> >  
> > +           if_params = cfg->outputs[index].if_params;
> > +           venc_device->setup_if_config(if_params);
> >             if (ret)
> >                     goto out;
> >     }
> > @@ -293,7 +298,7 @@ static int vpbe_set_output(struct vpbe_device 
> > *vpbe_dev, int index)
> >      * encoder.
> >      */
> >     ret = vpbe_get_mode_info(vpbe_dev,
> > -                            cfg->outputs[index].default_mode);
> > +                            cfg->outputs[index].default_mode, index);
> >     if (!ret) {
> >             struct osd_state *osd_device = vpbe_dev->osd_device;
> >  
> > @@ -367,6 +372,11 @@ static int vpbe_s_dv_preset(struct vpbe_device 
> > *vpbe_dev,
> >  
> >     ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
> >                                     s_dv_preset, dv_preset);
> > +   if (!ret && (vpbe_dev->amp != NULL)) {
> > +           /* Call amplifier subdevice */
> > +           ret = v4l2_subdev_call(vpbe_dev->amp, video,
> > +                           s_dv_preset, dv_preset);
> > +   }
> >     /* set the lcd controller output for the given mode */
> >     if (!ret) {
> >             struct osd_state *osd_device = vpbe_dev->osd_device; @@ -566,6 
> > +576,8 @@ static int platform_device_get(struct device *dev, void 
> > *data)
> >  
> >     if (strcmp("vpbe-osd", pdev->name) == 0)
> >             vpbe_dev->osd_device = platform_get_drvdata(pdev);
> > +   if (strcmp("vpbe-venc", pdev->name) == 0)
> > +           vpbe_dev->venc_device = dev_get_platdata(&pdev->dev);
> >  
> >     return 0;
> >  }
> > @@ -584,6 +596,7 @@ static int platform_device_get(struct device *dev, 
> > void *data)  static int vpbe_initialize(struct device *dev, struct 
> > vpbe_device *vpbe_dev)  {
> >     struct encoder_config_info *enc_info;
> > +   struct amp_config_info *amp_info;
> >     struct v4l2_subdev **enc_subdev;
> >     struct osd_state *osd_device;
> >     struct i2c_adapter *i2c_adap;
> > @@ -704,6 +717,39 @@ static int vpbe_initialize(struct device *dev, struct 
> > vpbe_device *vpbe_dev)
> >                     v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders"
> >                              " currently not supported");
> >     }
> > +   /* Add amplifier subdevice for dm365 */
> > +   if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) &&
> > +                   vpbe_dev->cfg->amp != NULL) {
> > +           vpbe_dev->amp = kmalloc(sizeof(struct v4l2_subdev *),
> > +                                   GFP_KERNEL);
> 
> Huh? Why alloc a struct v4l2_subdev pointer here?
> 
> > +           if (vpbe_dev->amp == NULL) {
> > +                   v4l2_err(&vpbe_dev->v4l2_dev,
> > +                           "unable to allocate memory for sub device");
> > +                   ret = -ENOMEM;
> > +                   goto vpbe_fail_v4l2_device;
> > +           }
> > +           amp_info = vpbe_dev->cfg->amp;
> > +           if (amp_info->is_i2c) {
> > +                   vpbe_dev->amp = v4l2_i2c_new_subdev_board(
> > +                   &vpbe_dev->v4l2_dev, i2c_adap,
> > +                   &amp_info->board_info, NULL);
> 
> Especially since it is overwritten here! And so causes a memory leak.
> The kmalloc above (and the kfree below) feels like old code that should have 
> been removed.

Thank you Hans. It was old code to be removed. Good catch. This piece of code 
is now removed and tested.
> 
> > +                   if (!vpbe_dev->amp) {
> > +                           v4l2_err(&vpbe_dev->v4l2_dev,
> > +                                    "amplifier %s failed to register",
> > +                                    amp_info->module_name);
> > +                           ret = -ENODEV;
> > +                           goto vpbe_fail_amp_register;
> > +                   }
> > +                   v4l2_info(&vpbe_dev->v4l2_dev,
> > +                                     "v4l2 sub device %s registered\n",
> > +                                     amp_info->module_name);
> > +           } else {
> > +                       vpbe_dev->amp = NULL;
> > +                       v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers"
> > +                       " currently not supported");
> > +           }
> > +   } else
> > +       vpbe_dev->amp = NULL;
> >  
> >     /* set the current encoder and output to that of venc by default */
> >     vpbe_dev->current_sd_index = 0;
> > @@ -731,6 +777,8 @@ static int vpbe_initialize(struct device *dev, struct 
> > vpbe_device *vpbe_dev)
> >     /* TBD handling of bootargs for default output and mode */
> >     return 0;
> >  
> > +vpbe_fail_amp_register:
> > +   kfree(vpbe_dev->amp);
> >  vpbe_fail_sd_register:
> >     kfree(vpbe_dev->encoders);
> >  vpbe_fail_v4l2_device:
> > @@ -757,6 +805,7 @@ static void vpbe_deinitialize(struct device *dev, 
> > struct vpbe_device *vpbe_dev)
> >     if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0)
> >             clk_put(vpbe_dev->dac_clk);
> >  
> > +   kfree(vpbe_dev->amp);
> >     kfree(vpbe_dev->encoders);
> >     vpbe_dev->initialized = 0;
> >     /* disable vpss clocks */
> > diff --git a/include/media/davinci/vpbe.h 
> > b/include/media/davinci/vpbe.h index 8b11fb0..8bc1b3c 100644
> > --- a/include/media/davinci/vpbe.h
> > +++ b/include/media/davinci/vpbe.h
> > @@ -63,6 +63,7 @@ struct vpbe_output {
> >      * output basis. If per mode is needed, we may have to move this to
> >      * mode_info structure
> >      */
> > +   enum v4l2_mbus_pixelcode if_params;
> >  };
> >  
> >  /* encoder configuration info */
> > @@ -74,6 +75,15 @@ struct encoder_config_info {
> >     struct i2c_board_info board_info;
> >  };
> >  
> > +/*amplifier configuration info */
> > +struct amp_config_info {
> > +   char module_name[32];
> > +   /* Is this an i2c device ? */
> > +   unsigned int is_i2c:1;
> > +   /* i2c subdevice board info */
> > +   struct i2c_board_info board_info;
> > +};
> > +
> >  /* structure for defining vpbe display subsystem components */  
> > struct vpbe_config {
> >     char module_name[32];
> > @@ -84,6 +94,8 @@ struct vpbe_config {
> >     /* external encoder information goes here */
> >     int num_ext_encoders;
> >     struct encoder_config_info *ext_encoders;
> > +   /* amplifier information goes here */
> > +   struct amp_config_info *amp;
> >     int num_outputs;
> >     /* Order is venc outputs followed by LCD and then external encoders */
> >     struct vpbe_output *outputs;
> > @@ -158,6 +170,8 @@ struct vpbe_device {
> >     struct v4l2_subdev **encoders;
> >     /* current encoder index */
> >     int current_sd_index;
> > +   /* external amplifier v4l2 subdevice */
> > +   struct v4l2_subdev *amp;
> >     struct mutex lock;
> >     /* device initialized */
> >     int initialized;
> > @@ -165,6 +179,8 @@ struct vpbe_device {
> >     struct clk *dac_clk;
> >     /* osd_device pointer */
> >     struct osd_state *osd_device;
> > +   /* venc device pointer */
> > +   struct venc_platform_data *venc_device;
> >     /*
> >      * fields below are accessed by users of vpbe_device. Not the
> >      * ones above
> > 
> 
> Regards,
> 
>       Hans
> 

Rgds,
Manju

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to