USB: Composite framework: Add suspended sysfs entry
authorFabien Chouteau <fabien.chouteau@barco.com>
Fri, 23 Apr 2010 12:21:26 +0000 (14:21 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 20 May 2010 20:21:39 +0000 (13:21 -0700)
This patch adds a sysfs entry (/sys/devices/platform/_UDC_/gadget/suspended) to
show the suspend state of an USB composite gadget.

Signed-off-by: Fabien Chouteau <fabien.chouteau@barco.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Documentation/ABI/testing/sysfs-devices-platform-_UDC_-gadget [new file with mode: 0644]
drivers/usb/gadget/composite.c
include/linux/usb/composite.h
include/linux/usb/gadget.h

diff --git a/Documentation/ABI/testing/sysfs-devices-platform-_UDC_-gadget b/Documentation/ABI/testing/sysfs-devices-platform-_UDC_-gadget
new file mode 100644 (file)
index 0000000..3403402
--- /dev/null
@@ -0,0 +1,9 @@
+What:          /sys/devices/platform/_UDC_/gadget/suspended
+Date:          April 2010
+Contact:       Fabien Chouteau <fabien.chouteau@barco.com>
+Description:
+               Show the suspend state of an USB composite gadget.
+               1 -> suspended
+               0 -> resumed
+
+               (_UDC_ is the name of the USB Device Controller driver)
index 5465d87..f9aff1b 100644 (file)
@@ -898,6 +898,18 @@ static void composite_disconnect(struct usb_gadget *gadget)
 
 /*-------------------------------------------------------------------------*/
 
+static ssize_t composite_show_suspended(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       struct usb_gadget *gadget = dev_to_usb_gadget(dev);
+       struct usb_composite_dev *cdev = get_gadget_data(gadget);
+
+       return sprintf(buf, "%d\n", cdev->suspended);
+}
+
+static DEVICE_ATTR(suspended, 0444, composite_show_suspended, NULL);
+
 static void /* __init_or_exit */
 composite_unbind(struct usb_gadget *gadget)
 {
@@ -944,6 +956,7 @@ composite_unbind(struct usb_gadget *gadget)
        }
        kfree(cdev);
        set_gadget_data(gadget, NULL);
+       device_remove_file(&gadget->dev, &dev_attr_suspended);
        composite = NULL;
 }
 
@@ -1036,6 +1049,10 @@ static int __init composite_bind(struct usb_gadget *gadget)
                string_override(composite->strings,
                        cdev->desc.iSerialNumber, iSerialNumber);
 
+       status = device_create_file(&gadget->dev, &dev_attr_suspended);
+       if (status)
+               goto fail;
+
        INFO(cdev, "%s ready\n", composite->name);
        return 0;
 
@@ -1064,6 +1081,8 @@ composite_suspend(struct usb_gadget *gadget)
        }
        if (composite->suspend)
                composite->suspend(cdev);
+
+       cdev->suspended = 1;
 }
 
 static void
@@ -1084,6 +1103,8 @@ composite_resume(struct usb_gadget *gadget)
                                f->resume(f);
                }
        }
+
+       cdev->suspended = 0;
 }
 
 /*-------------------------------------------------------------------------*/
index 738ea1a..139353e 100644 (file)
@@ -326,6 +326,7 @@ struct usb_composite_dev {
 
        /* private: */
        /* internals */
+       unsigned int                    suspended:1;
        struct usb_device_descriptor    desc;
        struct list_head                configs;
        struct usb_composite_driver     *driver;
index f4b7ca5..db6141c 100644 (file)
@@ -494,6 +494,10 @@ static inline void set_gadget_data(struct usb_gadget *gadget, void *data)
        { dev_set_drvdata(&gadget->dev, data); }
 static inline void *get_gadget_data(struct usb_gadget *gadget)
        { return dev_get_drvdata(&gadget->dev); }
+static inline struct usb_gadget *dev_to_usb_gadget(struct device *dev)
+{
+       return container_of(dev, struct usb_gadget, dev);
+}
 
 /* iterates the non-control endpoints; 'tmp' is a struct usb_ep pointer */
 #define gadget_for_each_ep(tmp,gadget) \