From 6d79468dd8537530f4150e76ed9b4b63f80571c6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 5 Jan 2008 09:57:31 -0300 Subject: V4L/DVB (6951): Integrates em28xx-audio.c into em28xx kernel module Also fixes the remaining CodingStyle issues that Lindent didn't fix. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-video.c | 63 +++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 4 deletions(-) (limited to 'drivers/media/video/em28xx/em28xx-video.c') diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 1a284cb18c2..caa4757b7eb 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1599,9 +1599,48 @@ static const struct video_device em28xx_video_template = { .current_norm = V4L2_STD_PAL, }; - /******************************** usb interface *****************************************/ + +static LIST_HEAD(em28xx_extension_devlist); +static DEFINE_MUTEX(em28xx_extension_devlist_lock); + +int em28xx_register_extension(struct em28xx_ops *ops) +{ + struct em28xx *h, *dev = NULL; + + list_for_each_entry(h, &em28xx_devlist, devlist) + dev = h; + + mutex_lock(&em28xx_extension_devlist_lock); + list_add_tail(&ops->next, &em28xx_extension_devlist); + if (dev) + ops->init(dev); + + printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); + mutex_unlock(&em28xx_extension_devlist_lock); + + return 0; +} +EXPORT_SYMBOL(em28xx_register_extension); + +void em28xx_unregister_extension(struct em28xx_ops *ops) +{ + struct em28xx *h, *dev = NULL; + + list_for_each_entry(h, &em28xx_devlist, devlist) + dev = h; + + if (dev) + ops->fini(dev); + + mutex_lock(&em28xx_extension_devlist_lock); + printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); + list_del(&ops->next); + mutex_unlock(&em28xx_extension_devlist_lock); +} +EXPORT_SYMBOL(em28xx_unregister_extension); + /* * em28xx_init_dev() * allocates and inits the device structs, registers i2c bus and v4l device @@ -1609,6 +1648,7 @@ static const struct video_device em28xx_video_template = { static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, int minor) { + struct em28xx_ops *ops = NULL; struct em28xx *dev = *devhandle; int retval = -ENOMEM; int errCode; @@ -1742,6 +1782,15 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); + mutex_lock(&em28xx_extension_devlist_lock); + if (!list_empty(&em28xx_extension_devlist)) { + list_for_each_entry(ops, &em28xx_extension_devlist, next) { + if (ops->id) + ops->init(dev); + } + } + mutex_unlock(&em28xx_extension_devlist_lock); + return 0; } @@ -1862,6 +1911,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, static void em28xx_usb_disconnect(struct usb_interface *interface) { struct em28xx *dev; + struct em28xx_ops *ops = NULL; dev = usb_get_intfdata(interface); usb_set_intfdata(interface, NULL); @@ -1891,15 +1941,20 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) dev->state |= DEV_DISCONNECTED; em28xx_release_resources(dev); } - - mutex_unlock(&dev->lock); + mutex_lock(&em28xx_extension_devlist_lock); + if (!list_empty(&em28xx_extension_devlist)) { + list_for_each_entry(ops, &em28xx_extension_devlist, next) { + ops->fini(dev); + } + } + mutex_unlock(&em28xx_extension_devlist_lock); + if (!dev->users) { kfree(dev->alt_max_pkt_size); kfree(dev); } - } static struct usb_driver em28xx_usb_driver = { -- cgit v1.2.3