diff options
author | JiebingLi <jiebing.li@intel.com> | 2010-08-05 09:18:21 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-10-22 13:21:19 -0400 |
commit | 3211cbc20b406799423385cf62e1f1879b1ca8cc (patch) | |
tree | 9d7d76ca45841b1fc0df123b5c14f5a3cf567b19 /drivers | |
parent | 513b91b688f527766bfe335d1ffd145257ad1624 (diff) |
USB: langwell: USB Client Remote Wakeup Support
Remote wakeup support in client driver. Made non-debug only this time.
Signed-off-by: JiebingLi <jiebing.li@intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/gadget/langwell_udc.c | 67 | ||||
-rw-r--r-- | drivers/usb/gadget/langwell_udc.h | 3 |
2 files changed, 65 insertions, 5 deletions
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index 8b92e2208dad..4b134abb1dbe 100644 --- a/drivers/usb/gadget/langwell_udc.c +++ b/drivers/usb/gadget/langwell_udc.c | |||
@@ -1815,6 +1815,36 @@ static ssize_t show_langwell_udc(struct device *_dev, | |||
1815 | static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL); | 1815 | static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL); |
1816 | 1816 | ||
1817 | 1817 | ||
1818 | /* device "remote_wakeup" sysfs attribute file */ | ||
1819 | static ssize_t store_remote_wakeup(struct device *_dev, | ||
1820 | struct device_attribute *attr, const char *buf, size_t count) | ||
1821 | { | ||
1822 | struct langwell_udc *dev = the_controller; | ||
1823 | unsigned long flags; | ||
1824 | ssize_t rc = count; | ||
1825 | |||
1826 | if (count > 2) | ||
1827 | return -EINVAL; | ||
1828 | |||
1829 | if (count > 0 && buf[count-1] == '\n') | ||
1830 | ((char *) buf)[count-1] = 0; | ||
1831 | |||
1832 | if (buf[0] != '1') | ||
1833 | return -EINVAL; | ||
1834 | |||
1835 | /* force remote wakeup enabled in case gadget driver doesn't support */ | ||
1836 | spin_lock_irqsave(&dev->lock, flags); | ||
1837 | dev->remote_wakeup = 1; | ||
1838 | dev->dev_status |= (1 << USB_DEVICE_REMOTE_WAKEUP); | ||
1839 | spin_unlock_irqrestore(&dev->lock, flags); | ||
1840 | |||
1841 | langwell_wakeup(&dev->gadget); | ||
1842 | |||
1843 | return rc; | ||
1844 | } | ||
1845 | static DEVICE_ATTR(remote_wakeup, S_IWUSR, NULL, store_remote_wakeup); | ||
1846 | |||
1847 | |||
1818 | /*-------------------------------------------------------------------------*/ | 1848 | /*-------------------------------------------------------------------------*/ |
1819 | 1849 | ||
1820 | /* | 1850 | /* |
@@ -2136,8 +2166,7 @@ static void get_status(struct langwell_udc *dev, u8 request_type, u16 value, | |||
2136 | 2166 | ||
2137 | if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) { | 2167 | if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) { |
2138 | /* get device status */ | 2168 | /* get device status */ |
2139 | status_data = 1 << USB_DEVICE_SELF_POWERED; | 2169 | status_data = dev->dev_status; |
2140 | status_data |= dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP; | ||
2141 | } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) { | 2170 | } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) { |
2142 | /* get interface status */ | 2171 | /* get interface status */ |
2143 | status_data = 0; | 2172 | status_data = 0; |
@@ -2275,6 +2304,22 @@ static void handle_setup_packet(struct langwell_udc *dev, | |||
2275 | } else if ((setup->bRequestType & (USB_RECIP_MASK | 2304 | } else if ((setup->bRequestType & (USB_RECIP_MASK |
2276 | | USB_TYPE_MASK)) == (USB_RECIP_DEVICE | 2305 | | USB_TYPE_MASK)) == (USB_RECIP_DEVICE |
2277 | | USB_TYPE_STANDARD)) { | 2306 | | USB_TYPE_STANDARD)) { |
2307 | rc = 0; | ||
2308 | switch (wValue) { | ||
2309 | case USB_DEVICE_REMOTE_WAKEUP: | ||
2310 | if (setup->bRequest == USB_REQ_SET_FEATURE) { | ||
2311 | dev->remote_wakeup = 1; | ||
2312 | dev->dev_status |= (1 << wValue); | ||
2313 | } else { | ||
2314 | dev->remote_wakeup = 0; | ||
2315 | dev->dev_status &= ~(1 << wValue); | ||
2316 | } | ||
2317 | break; | ||
2318 | default: | ||
2319 | rc = -EOPNOTSUPP; | ||
2320 | break; | ||
2321 | } | ||
2322 | |||
2278 | if (!gadget_is_otg(&dev->gadget)) | 2323 | if (!gadget_is_otg(&dev->gadget)) |
2279 | break; | 2324 | break; |
2280 | else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) { | 2325 | else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) { |
@@ -2290,7 +2335,6 @@ static void handle_setup_packet(struct langwell_udc *dev, | |||
2290 | dev->gadget.a_alt_hnp_support = 1; | 2335 | dev->gadget.a_alt_hnp_support = 1; |
2291 | else | 2336 | else |
2292 | break; | 2337 | break; |
2293 | rc = 0; | ||
2294 | } else | 2338 | } else |
2295 | break; | 2339 | break; |
2296 | 2340 | ||
@@ -2678,7 +2722,10 @@ static void handle_usb_reset(struct langwell_udc *dev) | |||
2678 | 2722 | ||
2679 | dev->ep0_dir = USB_DIR_OUT; | 2723 | dev->ep0_dir = USB_DIR_OUT; |
2680 | dev->ep0_state = WAIT_FOR_SETUP; | 2724 | dev->ep0_state = WAIT_FOR_SETUP; |
2681 | dev->remote_wakeup = 0; /* default to 0 on reset */ | 2725 | |
2726 | /* remote wakeup reset to 0 when the device is reset */ | ||
2727 | dev->remote_wakeup = 0; | ||
2728 | dev->dev_status = 1 << USB_DEVICE_SELF_POWERED; | ||
2682 | dev->gadget.b_hnp_enable = 0; | 2729 | dev->gadget.b_hnp_enable = 0; |
2683 | dev->gadget.a_hnp_support = 0; | 2730 | dev->gadget.a_hnp_support = 0; |
2684 | dev->gadget.a_alt_hnp_support = 0; | 2731 | dev->gadget.a_alt_hnp_support = 0; |
@@ -2997,6 +3044,7 @@ static void langwell_udc_remove(struct pci_dev *pdev) | |||
2997 | 3044 | ||
2998 | device_unregister(&dev->gadget.dev); | 3045 | device_unregister(&dev->gadget.dev); |
2999 | device_remove_file(&pdev->dev, &dev_attr_langwell_udc); | 3046 | device_remove_file(&pdev->dev, &dev_attr_langwell_udc); |
3047 | device_remove_file(&pdev->dev, &dev_attr_remote_wakeup); | ||
3000 | 3048 | ||
3001 | #ifndef OTG_TRANSCEIVER | 3049 | #ifndef OTG_TRANSCEIVER |
3002 | pci_set_drvdata(pdev, NULL); | 3050 | pci_set_drvdata(pdev, NULL); |
@@ -3177,7 +3225,10 @@ static int langwell_udc_probe(struct pci_dev *pdev, | |||
3177 | dev->resume_state = USB_STATE_NOTATTACHED; | 3225 | dev->resume_state = USB_STATE_NOTATTACHED; |
3178 | dev->usb_state = USB_STATE_POWERED; | 3226 | dev->usb_state = USB_STATE_POWERED; |
3179 | dev->ep0_dir = USB_DIR_OUT; | 3227 | dev->ep0_dir = USB_DIR_OUT; |
3180 | dev->remote_wakeup = 0; /* default to 0 on reset */ | 3228 | |
3229 | /* remote wakeup reset to 0 when the device is reset */ | ||
3230 | dev->remote_wakeup = 0; | ||
3231 | dev->dev_status = 1 << USB_DEVICE_SELF_POWERED; | ||
3181 | 3232 | ||
3182 | #ifndef OTG_TRANSCEIVER | 3233 | #ifndef OTG_TRANSCEIVER |
3183 | /* reset device controller */ | 3234 | /* reset device controller */ |
@@ -3247,9 +3298,15 @@ static int langwell_udc_probe(struct pci_dev *pdev, | |||
3247 | if (retval) | 3298 | if (retval) |
3248 | goto error; | 3299 | goto error; |
3249 | 3300 | ||
3301 | retval = device_create_file(&pdev->dev, &dev_attr_remote_wakeup); | ||
3302 | if (retval) | ||
3303 | goto error_attr1; | ||
3304 | |||
3250 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | 3305 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); |
3251 | return 0; | 3306 | return 0; |
3252 | 3307 | ||
3308 | error_attr1: | ||
3309 | device_remove_file(&pdev->dev, &dev_attr_langwell_udc); | ||
3253 | error: | 3310 | error: |
3254 | if (dev) { | 3311 | if (dev) { |
3255 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | 3312 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); |
diff --git a/drivers/usb/gadget/langwell_udc.h b/drivers/usb/gadget/langwell_udc.h index 9719934e1c08..3d3206eec544 100644 --- a/drivers/usb/gadget/langwell_udc.h +++ b/drivers/usb/gadget/langwell_udc.h | |||
@@ -224,5 +224,8 @@ struct langwell_udc { | |||
224 | 224 | ||
225 | /* make sure release() is done */ | 225 | /* make sure release() is done */ |
226 | struct completion *done; | 226 | struct completion *done; |
227 | |||
228 | /* device status data for get_status request */ | ||
229 | u16 dev_status; | ||
227 | }; | 230 | }; |
228 | 231 | ||