Merge branch 'topic/pcm-drain-nonblock' into for-linus
[pandora-kernel.git] / drivers / media / video / uvc / uvc_status.c
index c705f24..1ca6dff 100644 (file)
 #ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV
 static int uvc_input_init(struct uvc_device *dev)
 {
-       struct usb_device *udev = dev->udev;
        struct input_dev *input;
-       char *phys = NULL;
        int ret;
 
        input = input_allocate_device();
        if (input == NULL)
                return -ENOMEM;
 
-       phys = kmalloc(6 + strlen(udev->bus->bus_name) + strlen(udev->devpath),
-                       GFP_KERNEL);
-       if (phys == NULL) {
-               ret = -ENOMEM;
-               goto error;
-       }
-       sprintf(phys, "usb-%s-%s", udev->bus->bus_name, udev->devpath);
+       usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys));
+       strlcat(dev->input_phys, "/button", sizeof(dev->input_phys));
 
        input->name = dev->name;
-       input->phys = phys;
-       usb_to_input_id(udev, &input->id);
+       input->phys = dev->input_phys;
+       usb_to_input_id(dev->udev, &input->id);
        input->dev.parent = &dev->intf->dev;
 
        __set_bit(EV_KEY, input->evbit);
@@ -57,7 +50,6 @@ static int uvc_input_init(struct uvc_device *dev)
 
 error:
        input_free_device(input);
-       kfree(phys);
        return ret;
 }
 
@@ -153,8 +145,8 @@ static void uvc_status_complete(struct urb *urb)
                        break;
 
                default:
-                       uvc_printk(KERN_INFO, "unknown event type %u.\n",
-                               dev->status[0]);
+                       uvc_trace(UVC_TRACE_STATUS, "Unknown status event "
+                               "type %u.\n", dev->status[0]);
                        break;
                }
        }
@@ -202,7 +194,7 @@ int uvc_status_init(struct uvc_device *dev)
                dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete,
                dev, interval);
 
-       return usb_submit_urb(dev->int_urb, GFP_KERNEL);
+       return 0;
 }
 
 void uvc_status_cleanup(struct uvc_device *dev)
@@ -213,15 +205,30 @@ void uvc_status_cleanup(struct uvc_device *dev)
        uvc_input_cleanup(dev);
 }
 
-int uvc_status_suspend(struct uvc_device *dev)
+int uvc_status_start(struct uvc_device *dev)
+{
+       if (dev->int_urb == NULL)
+               return 0;
+
+       return usb_submit_urb(dev->int_urb, GFP_KERNEL);
+}
+
+void uvc_status_stop(struct uvc_device *dev)
 {
        usb_kill_urb(dev->int_urb);
+}
+
+int uvc_status_suspend(struct uvc_device *dev)
+{
+       if (atomic_read(&dev->users))
+               usb_kill_urb(dev->int_urb);
+
        return 0;
 }
 
 int uvc_status_resume(struct uvc_device *dev)
 {
-       if (dev->int_urb == NULL)
+       if (dev->int_urb == NULL || atomic_read(&dev->users) == 0)
                return 0;
 
        return usb_submit_urb(dev->int_urb, GFP_NOIO);