mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
[media] V4L: dynamically allocate video_device nodes in subdevices
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 <[email protected]> Tested-by: Sylwester Nawrocki <[email protected]> Acked-by: Laurent Pinchart <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
This commit is contained in:
parent
2fbdc9bd42
commit
3e0ec41c5c
2 changed files with 33 additions and 7 deletions
|
|
@ -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
|
||||
|
|
@ -193,6 +194,13 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
|
||||
|
||||
static 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;
|
||||
|
|
@ -206,22 +214,40 @@ 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;
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(v4l2_device_register_subdev_nodes);
|
||||
|
||||
|
|
@ -247,7 +273,7 @@ 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);
|
||||
video_unregister_device(sd->devnode);
|
||||
module_put(sd->owner);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev);
|
||||
|
|
|
|||
Loading…
Reference in a new issue