Re: [PATCH v3] V4L: dynamically allocate video_device nodes in subdevices

2011-09-13 Thread Laurent Pinchart
Hi Guennadi,

On Monday 12 September 2011 12:55:46 Guennadi Liakhovetski wrote:
 Currently only very few drivers actually use video_device nodes, embedded
 in struct v4l2_subdev. Allocate these nodes dynamically for those drivers
 to save memory for the rest.
 
 Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de
 ---
 
 v3: addressed comments from Laurent Pinchart - thanks

Thanks for the patch. Just one small comment below.

 1. switch to using a device-release method, instead of freeing directly in
 v4l2_device_unregister_subdev()
 
 2. switch to using drvdata instead of a wrapper struct
 
  drivers/media/video/v4l2-device.c |   41
  include/media/v4l2-subdev.h   |  
  4 +-
  2 files changed, 38 insertions(+), 7 deletions(-)
 
 diff --git a/drivers/media/video/v4l2-device.c
 b/drivers/media/video/v4l2-device.c index c72856c..9bf3d70 100644
 --- a/drivers/media/video/v4l2-device.c
 +++ b/drivers/media/video/v4l2-device.c
 @@ -21,6 +21,7 @@
  #include linux/types.h
  #include linux/ioctl.h
  #include linux/i2c.h
 +#include linux/slab.h
  #if defined(CONFIG_SPI)
  #include linux/spi/spi.h
  #endif
 @@ -191,6 +192,13 @@ int v4l2_device_register_subdev(struct v4l2_device
 *v4l2_dev, }
  EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
 
 +void v4l2_device_release_subdev_node(struct video_device *vdev)
 +{
 + struct v4l2_subdev *sd = video_get_drvdata(vdev);
 + sd-devnode = NULL;
 + kfree(vdev);
 +}
 +
  int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
  {
   struct video_device *vdev;
 @@ -204,22 +212,42 @@ int v4l2_device_register_subdev_nodes(struct
 v4l2_device *v4l2_dev) if (!(sd-flags  V4L2_SUBDEV_FL_HAS_DEVNODE))
   continue;
 
 - vdev = sd-devnode;
 + vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
 + if (!vdev) {
 + err = -ENOMEM;
 + goto clean_up;
 + }
 +
 + video_set_drvdata(vdev, sd);
   strlcpy(vdev-name, sd-name, sizeof(vdev-name));
   vdev-v4l2_dev = v4l2_dev;
   vdev-fops = v4l2_subdev_fops;
 - vdev-release = video_device_release_empty;
 + vdev-release = v4l2_device_release_subdev_node;
   vdev-ctrl_handler = sd-ctrl_handler;
   err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
 sd-owner);
 - if (err  0)
 - return err;
 + if (err  0) {
 + kfree(vdev);
 + goto clean_up;
 + }
 + get_device(vdev-dev);

Is get_device() (and the corresponding put_device() calls below) required ? I 
thought device_register() initialized the reference count to 1 (don't take my 
word for it though).

  #if defined(CONFIG_MEDIA_CONTROLLER)
   sd-entity.v4l.major = VIDEO_MAJOR;
   sd-entity.v4l.minor = vdev-minor;
  #endif
 + sd-devnode = vdev;
   }
   return 0;
 +
 +clean_up:
 + list_for_each_entry(sd, v4l2_dev-subdevs, list) {
 + if (!sd-devnode)
 + break;
 + video_unregister_device(sd-devnode);
 + put_device(sd-devnode-dev);
 + }
 +
 + return err;
  }
  EXPORT_SYMBOL_GPL(v4l2_device_register_subdev_nodes);
 
 @@ -245,7 +273,10 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev
 *sd) if (v4l2_dev-mdev)
   media_device_unregister_entity(sd-entity);
  #endif
 - video_unregister_device(sd-devnode);
 + if (sd-devnode) {
 + video_unregister_device(sd-devnode);
 + put_device(sd-devnode-dev);
 + }
   module_put(sd-owner);
  }
  EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev);
 diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
 index 257da1a..5dd049a 100644
 --- a/include/media/v4l2-subdev.h
 +++ b/include/media/v4l2-subdev.h
 @@ -534,13 +534,13 @@ struct v4l2_subdev {
   void *dev_priv;
   void *host_priv;
   /* subdev device node */
 - struct video_device devnode;
 + struct video_device *devnode;
  };
 
  #define media_entity_to_v4l2_subdev(ent) \
   container_of(ent, struct v4l2_subdev, entity)
  #define vdev_to_v4l2_subdev(vdev) \
 - container_of(vdev, struct v4l2_subdev, devnode)
 + video_get_drvdata(vdev)
 
  /*
   * Used for storing subdev information per file handle

-- 
Regards,

Laurent Pinchart
--
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


Re: [PATCH v3] V4L: dynamically allocate video_device nodes in subdevices

2011-09-13 Thread Guennadi Liakhovetski
On Tue, 13 Sep 2011, Laurent Pinchart wrote:

 Hi Guennadi,
 
 On Monday 12 September 2011 12:55:46 Guennadi Liakhovetski wrote:
  Currently only very few drivers actually use video_device nodes, embedded
  in struct v4l2_subdev. Allocate these nodes dynamically for those drivers
  to save memory for the rest.
  
  Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de
  ---
  
  v3: addressed comments from Laurent Pinchart - thanks
 
 Thanks for the patch. Just one small comment below.
 
  1. switch to using a device-release method, instead of freeing directly in
  v4l2_device_unregister_subdev()
  
  2. switch to using drvdata instead of a wrapper struct
  
   drivers/media/video/v4l2-device.c |   41
   include/media/v4l2-subdev.h   |  
   4 +-
   2 files changed, 38 insertions(+), 7 deletions(-)
  
  diff --git a/drivers/media/video/v4l2-device.c
  b/drivers/media/video/v4l2-device.c index c72856c..9bf3d70 100644
  --- a/drivers/media/video/v4l2-device.c
  +++ b/drivers/media/video/v4l2-device.c
  @@ -21,6 +21,7 @@
   #include linux/types.h
   #include linux/ioctl.h
   #include linux/i2c.h
  +#include linux/slab.h
   #if defined(CONFIG_SPI)
   #include linux/spi/spi.h
   #endif
  @@ -191,6 +192,13 @@ int v4l2_device_register_subdev(struct v4l2_device
  *v4l2_dev, }
   EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
  
  +void v4l2_device_release_subdev_node(struct video_device *vdev)
  +{
  +   struct v4l2_subdev *sd = video_get_drvdata(vdev);
  +   sd-devnode = NULL;
  +   kfree(vdev);
  +}
  +
   int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
   {
  struct video_device *vdev;
  @@ -204,22 +212,42 @@ int v4l2_device_register_subdev_nodes(struct
  v4l2_device *v4l2_dev) if (!(sd-flags  V4L2_SUBDEV_FL_HAS_DEVNODE))
  continue;
  
  -   vdev = sd-devnode;
  +   vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
  +   if (!vdev) {
  +   err = -ENOMEM;
  +   goto clean_up;
  +   }
  +
  +   video_set_drvdata(vdev, sd);
  strlcpy(vdev-name, sd-name, sizeof(vdev-name));
  vdev-v4l2_dev = v4l2_dev;
  vdev-fops = v4l2_subdev_fops;
  -   vdev-release = video_device_release_empty;
  +   vdev-release = v4l2_device_release_subdev_node;
  vdev-ctrl_handler = sd-ctrl_handler;
  err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
sd-owner);
  -   if (err  0)
  -   return err;
  +   if (err  0) {
  +   kfree(vdev);
  +   goto clean_up;
  +   }
  +   get_device(vdev-dev);
 
 Is get_device() (and the corresponding put_device() calls below) required ? I 
 thought device_register() initialized the reference count to 1 (don't take my 
 word for it though).

Indeed, I think, you're right. Will update.

Thanks
Guennadi

 
   #if defined(CONFIG_MEDIA_CONTROLLER)
  sd-entity.v4l.major = VIDEO_MAJOR;
  sd-entity.v4l.minor = vdev-minor;
   #endif
  +   sd-devnode = vdev;
  }
  return 0;
  +
  +clean_up:
  +   list_for_each_entry(sd, v4l2_dev-subdevs, list) {
  +   if (!sd-devnode)
  +   break;
  +   video_unregister_device(sd-devnode);
  +   put_device(sd-devnode-dev);
  +   }
  +
  +   return err;
   }
   EXPORT_SYMBOL_GPL(v4l2_device_register_subdev_nodes);
  
  @@ -245,7 +273,10 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev
  *sd) if (v4l2_dev-mdev)
  media_device_unregister_entity(sd-entity);
   #endif
  -   video_unregister_device(sd-devnode);
  +   if (sd-devnode) {
  +   video_unregister_device(sd-devnode);
  +   put_device(sd-devnode-dev);
  +   }
  module_put(sd-owner);
   }
   EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev);
  diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
  index 257da1a..5dd049a 100644
  --- a/include/media/v4l2-subdev.h
  +++ b/include/media/v4l2-subdev.h
  @@ -534,13 +534,13 @@ struct v4l2_subdev {
  void *dev_priv;
  void *host_priv;
  /* subdev device node */
  -   struct video_device devnode;
  +   struct video_device *devnode;
   };
  
   #define media_entity_to_v4l2_subdev(ent) \
  container_of(ent, struct v4l2_subdev, entity)
   #define vdev_to_v4l2_subdev(vdev) \
  -   container_of(vdev, struct v4l2_subdev, devnode)
  +   video_get_drvdata(vdev)
  
   /*
* Used for storing subdev information per file handle
 
 -- 
 Regards,
 
 Laurent Pinchart
 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
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


Re: [PATCH v3] V4L: dynamically allocate video_device nodes in subdevices

2011-09-13 Thread Laurent Pinchart
Hi Guennadi,

On Tuesday 13 September 2011 11:26:23 Guennadi Liakhovetski wrote:
 On Tue, 13 Sep 2011, Laurent Pinchart wrote:
  On Monday 12 September 2011 12:55:46 Guennadi Liakhovetski wrote:
   Currently only very few drivers actually use video_device nodes,
   embedded in struct v4l2_subdev. Allocate these nodes dynamically for
   those drivers to save memory for the rest.
   
   Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de
   ---
   
   v3: addressed comments from Laurent Pinchart - thanks
  
  Thanks for the patch. Just one small comment below.
  
   1. switch to using a device-release method, instead of freeing directly
   in v4l2_device_unregister_subdev()
   
   2. switch to using drvdata instead of a wrapper struct
   
drivers/media/video/v4l2-device.c |   41
   
    include/media/v4l2-subdev.h  
   |
   
4 +-
2 files changed, 38 insertions(+), 7 deletions(-)
   
   diff --git a/drivers/media/video/v4l2-device.c
   b/drivers/media/video/v4l2-device.c index c72856c..9bf3d70 100644
   --- a/drivers/media/video/v4l2-device.c
   +++ b/drivers/media/video/v4l2-device.c
   @@ -21,6 +21,7 @@
   
#include linux/types.h
#include linux/ioctl.h
#include linux/i2c.h
   
   +#include linux/slab.h
   
#if defined(CONFIG_SPI)
#include linux/spi/spi.h
#endif
   
   @@ -191,6 +192,13 @@ int v4l2_device_register_subdev(struct v4l2_device
   *v4l2_dev, }
   
EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
   
   +void v4l2_device_release_subdev_node(struct video_device *vdev)
   +{
   + struct v4l2_subdev *sd = video_get_drvdata(vdev);
   + sd-devnode = NULL;
   + kfree(vdev);
   +}
   +
   
int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
{

 struct video_device *vdev;
   
   @@ -204,22 +212,42 @@ int v4l2_device_register_subdev_nodes(struct
   v4l2_device *v4l2_dev) if (!(sd-flags  V4L2_SUBDEV_FL_HAS_DEVNODE))
   
 continue;
   
   - vdev = sd-devnode;
   + vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
   + if (!vdev) {
   + err = -ENOMEM;
   + goto clean_up;
   + }
   +
   + video_set_drvdata(vdev, sd);
   
 strlcpy(vdev-name, sd-name, sizeof(vdev-name));
 vdev-v4l2_dev = v4l2_dev;
 vdev-fops = v4l2_subdev_fops;
   
   - vdev-release = video_device_release_empty;
   + vdev-release = v4l2_device_release_subdev_node;
   
 vdev-ctrl_handler = sd-ctrl_handler;
 err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
 
   sd-owner);
   
   - if (err  0)
   - return err;
   + if (err  0) {
   + kfree(vdev);
   + goto clean_up;
   + }
   + get_device(vdev-dev);
  
  Is get_device() (and the corresponding put_device() calls below) required
  ? I thought device_register() initialized the reference count to 1
  (don't take my word for it though).
 
 Indeed, I think, you're right. Will update.

Please test it as well :-)

-- 
Regards,

Laurent Pinchart
--
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


Re: [PATCH v3] V4L: dynamically allocate video_device nodes in subdevices

2011-09-13 Thread Guennadi Liakhovetski
On Tue, 13 Sep 2011, Laurent Pinchart wrote:

 Hi Guennadi,
 
 On Tuesday 13 September 2011 11:26:23 Guennadi Liakhovetski wrote:
  On Tue, 13 Sep 2011, Laurent Pinchart wrote:
   On Monday 12 September 2011 12:55:46 Guennadi Liakhovetski wrote:
Currently only very few drivers actually use video_device nodes,
embedded in struct v4l2_subdev. Allocate these nodes dynamically for
those drivers to save memory for the rest.

Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de
---

v3: addressed comments from Laurent Pinchart - thanks
   
   Thanks for the patch. Just one small comment below.
   
1. switch to using a device-release method, instead of freeing directly
in v4l2_device_unregister_subdev()

2. switch to using drvdata instead of a wrapper struct

 drivers/media/video/v4l2-device.c |   41

 include/media/v4l2-subdev.h  
|

 4 +-
 2 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/drivers/media/video/v4l2-device.c
b/drivers/media/video/v4l2-device.c index c72856c..9bf3d70 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -21,6 +21,7 @@

 #include linux/types.h
 #include linux/ioctl.h
 #include linux/i2c.h

+#include linux/slab.h

 #if defined(CONFIG_SPI)
 #include linux/spi/spi.h
 #endif

@@ -191,6 +192,13 @@ int v4l2_device_register_subdev(struct v4l2_device
*v4l2_dev, }

 EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);

+void v4l2_device_release_subdev_node(struct video_device *vdev)
+{
+   struct v4l2_subdev *sd = video_get_drvdata(vdev);
+   sd-devnode = NULL;
+   kfree(vdev);
+}
+

 int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
 {
 
struct video_device *vdev;

@@ -204,22 +212,42 @@ int v4l2_device_register_subdev_nodes(struct
v4l2_device *v4l2_dev) if (!(sd-flags  V4L2_SUBDEV_FL_HAS_DEVNODE))

continue;

-   vdev = sd-devnode;
+   vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
+   if (!vdev) {
+   err = -ENOMEM;
+   goto clean_up;
+   }
+
+   video_set_drvdata(vdev, sd);

strlcpy(vdev-name, sd-name, sizeof(vdev-name));
vdev-v4l2_dev = v4l2_dev;
vdev-fops = v4l2_subdev_fops;

-   vdev-release = video_device_release_empty;
+   vdev-release = v4l2_device_release_subdev_node;

vdev-ctrl_handler = sd-ctrl_handler;
err = __video_register_device(vdev, VFL_TYPE_SUBDEV, 
-1, 1,

  sd-owner);

-   if (err  0)
-   return err;
+   if (err  0) {
+   kfree(vdev);
+   goto clean_up;
+   }
+   get_device(vdev-dev);
   
   Is get_device() (and the corresponding put_device() calls below) required
   ? I thought device_register() initialized the reference count to 1
   (don't take my word for it though).
  
  Indeed, I think, you're right. Will update.
 
 Please test it as well :-)

I'm afraid, testing it wouldn't be very easy for me: I only have one 
system here, on which MC is used - the beagle-board. And it is not an easy 
nor a quick exersize to bring it up and run a test on it;-) But if noone 
else finds time to test it and if we're not confident enough in its 
correctness, well, we'll have to wait until I find time to do that...

BTW, there's one more improvement to be made for this patch:

-void v4l2_device_release_subdev_node(struct video_device *vdev)
+static void v4l2_device_release_subdev_node(struct video_device *vdev)

My copy-paste from video_device_release_empty() was too precise:-(

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
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