aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-03-26 11:17:39 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-26 11:17:39 -0700
commit61a091827e273650b39eb87c799a6d260913fa0b (patch)
tree19f0a4840fc90da6ca3787ee7efacb5bb0c6c7a2 /drivers/usb/gadget
parent0c93ea4064a209cdc36de8a9a3003d43d08f46f7 (diff)
parentfd8345f8dea93691b0ceba55146088d8c05415f6 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (97 commits) USB: qcserial: add device id for HP devices USB: isp1760: Add a delay before reading the SKIPMAP registers in isp1760-hcd.c USB: allow malformed LANGID descriptors USB: pxa27x_udc: typo fixes and code cleanups USB: gadget: gadget zero uses new suspend/resume hooks USB: gadget: composite device-level suspend/resume hooks USB: r8a66597-hcd: suspend/resume support USB: more u32 conversion after transfer_buffer_length and actual_length USB: Fix cp2101 USB serial device driver termios functions for console use USB: CP2101 New Device ID USB: ipaq: handle 4 endpoint devices USB: S3C: Move usb-control.h to platform include USB: ohci-hcd: Add ARCH_S3C24XX to the ohci-s3c2410.c glue USB: pedantic: spelling correction in comment for ch9.h USB: host: fix sparse warning: Using plain integer as NULL pointer USB: ohci-s3c2410: fix name of bus clock USB: ohci-s3c2410: remove <mach/hardware.h> include USB: serial: rename cp2101 driver to cp210x USB: CP2101 Reduce Error Logging USB: CP2101 Support AN205 baud rates ...
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/Kconfig1
-rw-r--r--drivers/usb/gadget/amd5536udc.c2
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c20
-rw-r--r--drivers/usb/gadget/cdc2.c8
-rw-r--r--drivers/usb/gadget/ci13xxx_udc.c1
-rw-r--r--drivers/usb/gadget/composite.c13
-rw-r--r--drivers/usb/gadget/dummy_hcd.c4
-rw-r--r--drivers/usb/gadget/epautoconf.c2
-rw-r--r--drivers/usb/gadget/ether.c8
-rw-r--r--drivers/usb/gadget/f_acm.c10
-rw-r--r--drivers/usb/gadget/f_ecm.c16
-rw-r--r--drivers/usb/gadget/f_loopback.c10
-rw-r--r--drivers/usb/gadget/f_obex.c8
-rw-r--r--drivers/usb/gadget/f_phonet.c8
-rw-r--r--drivers/usb/gadget/f_rndis.c12
-rw-r--r--drivers/usb/gadget/f_serial.c4
-rw-r--r--drivers/usb/gadget/f_sourcesink.c56
-rw-r--r--drivers/usb/gadget/f_subset.c14
-rw-r--r--drivers/usb/gadget/file_storage.c22
-rw-r--r--drivers/usb/gadget/fsl_usb2_udc.c8
-rw-r--r--drivers/usb/gadget/g_zero.h4
-rw-r--r--drivers/usb/gadget/gmidi.c16
-rw-r--r--drivers/usb/gadget/goku_udc.c8
-rw-r--r--drivers/usb/gadget/imx_udc.c244
-rw-r--r--drivers/usb/gadget/imx_udc.h49
-rw-r--r--drivers/usb/gadget/inode.c4
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c16
-rw-r--r--drivers/usb/gadget/net2280.c16
-rw-r--r--drivers/usb/gadget/printer.c18
-rw-r--r--drivers/usb/gadget/pxa27x_udc.c272
-rw-r--r--drivers/usb/gadget/pxa27x_udc.h10
-rw-r--r--drivers/usb/gadget/serial.c12
-rw-r--r--drivers/usb/gadget/u_serial.c2
-rw-r--r--drivers/usb/gadget/zero.c78
34 files changed, 634 insertions, 342 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index e55fef52a5d..770b3eaa918 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -254,6 +254,7 @@ config USB_PXA25X_SMALL
config USB_GADGET_PXA27X
boolean "PXA 27x"
depends on ARCH_PXA && PXA27x
+ select USB_OTG_UTILS
help
Intel's PXA 27x series XScale ARM v5TE processors include
an integrated full speed USB 1.1 device controller.
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c
index abf8192f89e..826f3adde5d 100644
--- a/drivers/usb/gadget/amd5536udc.c
+++ b/drivers/usb/gadget/amd5536udc.c
@@ -551,7 +551,7 @@ udc_alloc_request(struct usb_ep *usbep, gfp_t gfp)
dma_desc->status = AMD_ADDBITS(dma_desc->status,
UDC_DMA_STP_STS_BS_HOST_BUSY,
UDC_DMA_STP_STS_BS);
- dma_desc->bufptr = __constant_cpu_to_le32(DMA_DONT_USE);
+ dma_desc->bufptr = cpu_to_le32(DMA_DONT_USE);
req->td_data = dma_desc;
req->td_data_last = NULL;
req->chain_len = 1;
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index 65b03e3445a..c22fab16411 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -1017,7 +1017,7 @@ static struct usb_endpoint_descriptor usba_ep0_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 0,
.bmAttributes = USB_ENDPOINT_XFER_CONTROL,
- .wMaxPacketSize = __constant_cpu_to_le16(64),
+ .wMaxPacketSize = cpu_to_le16(64),
/* FIXME: I have no idea what to put here */
.bInterval = 1,
};
@@ -1207,21 +1207,21 @@ static int do_test_mode(struct usba_udc *udc)
/* Avoid overly long expressions */
static inline bool feature_is_dev_remote_wakeup(struct usb_ctrlrequest *crq)
{
- if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP))
+ if (crq->wValue == cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP))
return true;
return false;
}
static inline bool feature_is_dev_test_mode(struct usb_ctrlrequest *crq)
{
- if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_TEST_MODE))
+ if (crq->wValue == cpu_to_le16(USB_DEVICE_TEST_MODE))
return true;
return false;
}
static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq)
{
- if (crq->wValue == __constant_cpu_to_le16(USB_ENDPOINT_HALT))
+ if (crq->wValue == cpu_to_le16(USB_ENDPOINT_HALT))
return true;
return false;
}
@@ -1239,7 +1239,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
status = cpu_to_le16(udc->devstatus);
} else if (crq->bRequestType
== (USB_DIR_IN | USB_RECIP_INTERFACE)) {
- status = __constant_cpu_to_le16(0);
+ status = cpu_to_le16(0);
} else if (crq->bRequestType
== (USB_DIR_IN | USB_RECIP_ENDPOINT)) {
struct usba_ep *target;
@@ -1250,12 +1250,12 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
status = 0;
if (is_stalled(udc, target))
- status |= __constant_cpu_to_le16(1);
+ status |= cpu_to_le16(1);
} else
goto delegate;
/* Write directly to the FIFO. No queueing is done. */
- if (crq->wLength != __constant_cpu_to_le16(sizeof(status)))
+ if (crq->wLength != cpu_to_le16(sizeof(status)))
goto stall;
ep->state = DATA_STAGE_IN;
__raw_writew(status, ep->fifo);
@@ -1274,7 +1274,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
} else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
struct usba_ep *target;
- if (crq->wLength != __constant_cpu_to_le16(0)
+ if (crq->wLength != cpu_to_le16(0)
|| !feature_is_ep_halt(crq))
goto stall;
target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex));
@@ -1308,7 +1308,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep,
} else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
struct usba_ep *target;
- if (crq->wLength != __constant_cpu_to_le16(0)
+ if (crq->wLength != cpu_to_le16(0)
|| !feature_is_ep_halt(crq))
goto stall;
@@ -1514,7 +1514,7 @@ restart:
*/
ep->state = DATA_STAGE_IN;
} else {
- if (crq.crq.wLength != __constant_cpu_to_le16(0))
+ if (crq.crq.wLength != cpu_to_le16(0))
ep->state = DATA_STAGE_OUT;
else
ep->state = STATUS_STAGE_IN;
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
index 5495b171cf2..928137d3dbd 100644
--- a/drivers/usb/gadget/cdc2.c
+++ b/drivers/usb/gadget/cdc2.c
@@ -66,7 +66,7 @@ static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_COMM,
.bDeviceSubClass = 0,
@@ -74,8 +74,8 @@ static struct usb_device_descriptor device_desc = {
/* .bMaxPacketSize0 = f(hardware) */
/* Vendor and product id can be overridden by module parameters. */
- .idVendor = __constant_cpu_to_le16(CDC_VENDOR_NUM),
- .idProduct = __constant_cpu_to_le16(CDC_PRODUCT_NUM),
+ .idVendor = cpu_to_le16(CDC_VENDOR_NUM),
+ .idProduct = cpu_to_le16(CDC_PRODUCT_NUM),
/* .bcdDevice = f(hardware) */
/* .iManufacturer = DYNAMIC */
/* .iProduct = DYNAMIC */
@@ -193,7 +193,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
gadget->name,
cdc_config_driver.label);
device_desc.bcdDevice =
- __constant_cpu_to_le16(0x0300 | 0x0099);
+ cpu_to_le16(0x0300 | 0x0099);
}
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 7f4e5eb1dc8..22c65960c42 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -56,7 +56,6 @@
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/kernel.h>
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 5d11c291f1a..59e85234fa0 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -149,16 +149,17 @@ done:
int usb_function_deactivate(struct usb_function *function)
{
struct usb_composite_dev *cdev = function->config->cdev;
+ unsigned long flags;
int status = 0;
- spin_lock(&cdev->lock);
+ spin_lock_irqsave(&cdev->lock, flags);
if (cdev->deactivations == 0)
status = usb_gadget_disconnect(cdev->gadget);
if (status == 0)
cdev->deactivations++;
- spin_unlock(&cdev->lock);
+ spin_unlock_irqrestore(&cdev->lock, flags);
return status;
}
@@ -1013,7 +1014,7 @@ composite_suspend(struct usb_gadget *gadget)
struct usb_composite_dev *cdev = get_gadget_data(gadget);
struct usb_function *f;
- /* REVISIT: should we have config and device level
+ /* REVISIT: should we have config level
* suspend/resume callbacks?
*/
DBG(cdev, "suspend\n");
@@ -1023,6 +1024,8 @@ composite_suspend(struct usb_gadget *gadget)
f->suspend(f);
}
}
+ if (composite->suspend)
+ composite->suspend(cdev);
}
static void
@@ -1031,10 +1034,12 @@ composite_resume(struct usb_gadget *gadget)
struct usb_composite_dev *cdev = get_gadget_data(gadget);
struct usb_function *f;
- /* REVISIT: should we have config and device level
+ /* REVISIT: should we have config level
* suspend/resume callbacks?
*/
DBG(cdev, "resume\n");
+ if (composite->resume)
+ composite->resume(cdev);
if (cdev->config) {
list_for_each_entry(f, &cdev->config->functions, list) {
if (f->resume)
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 9064696636a..a56b24d305f 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -1437,7 +1437,7 @@ restart:
}
if (urb->transfer_buffer_length > 1)
buf [1] = 0;
- urb->actual_length = min (2,
+ urb->actual_length = min_t(u32, 2,
urb->transfer_buffer_length);
value = 0;
status = 0;
@@ -1626,7 +1626,7 @@ static int dummy_hub_control (
hub_descriptor ((struct usb_hub_descriptor *) buf);
break;
case GetHubStatus:
- *(__le32 *) buf = __constant_cpu_to_le32 (0);
+ *(__le32 *) buf = cpu_to_le32 (0);
break;
case GetPortStatus:
if (wIndex != 1)
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index a36b1175b18..cd0914ec898 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -148,7 +148,7 @@ ep_matches (
return 0;
/* BOTH: "high bandwidth" works only at high speed */
- if ((desc->wMaxPacketSize & __constant_cpu_to_le16(3<<11))) {
+ if ((desc->wMaxPacketSize & cpu_to_le16(3<<11))) {
if (!gadget->is_dualspeed)
return 0;
/* configure your hardware with enough buffering!! */
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 37252d0012a..d006dc652e0 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -156,7 +156,7 @@ static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16 (0x0200),
+ .bcdUSB = cpu_to_le16 (0x0200),
.bDeviceClass = USB_CLASS_COMM,
.bDeviceSubClass = 0,
@@ -167,8 +167,8 @@ static struct usb_device_descriptor device_desc = {
* we support. (As does bNumConfigurations.) These values can
* also be overridden by module parameters.
*/
- .idVendor = __constant_cpu_to_le16 (CDC_VENDOR_NUM),
- .idProduct = __constant_cpu_to_le16 (CDC_PRODUCT_NUM),
+ .idVendor = cpu_to_le16 (CDC_VENDOR_NUM),
+ .idProduct = cpu_to_le16 (CDC_PRODUCT_NUM),
/* .bcdDevice = f(hardware) */
/* .iManufacturer = DYNAMIC */
/* .iProduct = DYNAMIC */
@@ -318,7 +318,7 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
gadget->name,
eth_config_driver.label);
device_desc.bcdDevice =
- __constant_cpu_to_le16(0x0300 | 0x0099);
+ cpu_to_le16(0x0300 | 0x0099);
}
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index c1d34df0b15..7953948bfe4 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -125,7 +125,7 @@ static struct usb_cdc_header_desc acm_header_desc __initdata = {
.bLength = sizeof(acm_header_desc),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0110),
+ .bcdCDC = cpu_to_le16(0x0110),
};
static struct usb_cdc_call_mgmt_descriptor
@@ -159,7 +159,7 @@ static struct usb_endpoint_descriptor acm_fs_notify_desc __initdata = {
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
+ .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET),
.bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL,
};
@@ -197,7 +197,7 @@ static struct usb_endpoint_descriptor acm_hs_notify_desc __initdata = {
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET),
+ .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET),
.bInterval = GS_LOG2_NOTIFY_INTERVAL+4,
};
@@ -205,14 +205,14 @@ static struct usb_endpoint_descriptor acm_hs_in_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor acm_hs_out_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *acm_hs_function[] __initdata = {
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
index 4ae579948e5..ecf5bdd0ae0 100644
--- a/drivers/usb/gadget/f_ecm.c
+++ b/drivers/usb/gadget/f_ecm.c
@@ -130,7 +130,7 @@ static struct usb_cdc_header_desc ecm_header_desc __initdata = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0110),
+ .bcdCDC = cpu_to_le16(0x0110),
};
static struct usb_cdc_union_desc ecm_union_desc __initdata = {
@@ -148,9 +148,9 @@ static struct usb_cdc_ether_desc ecm_desc __initdata = {
/* this descriptor actually adds value, surprise! */
/* .iMACAddress = DYNAMIC */
- .bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */
- .wMaxSegmentSize = __constant_cpu_to_le16(ETH_FRAME_LEN),
- .wNumberMCFilters = __constant_cpu_to_le16(0),
+ .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */
+ .wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN),
+ .wNumberMCFilters = cpu_to_le16(0),
.bNumberPowerFilters = 0,
};
@@ -192,7 +192,7 @@ static struct usb_endpoint_descriptor fs_ecm_notify_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
+ .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
.bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
};
@@ -236,7 +236,7 @@ static struct usb_endpoint_descriptor hs_ecm_notify_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
+ .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
.bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
};
static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = {
@@ -245,7 +245,7 @@ static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = {
@@ -254,7 +254,7 @@ static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = {
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *ecm_hs_function[] __initdata = {
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index 8affe1dfc2c..eb6ddfc2085 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -100,7 +100,7 @@ static struct usb_endpoint_descriptor hs_loop_source_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor hs_loop_sink_desc = {
@@ -108,7 +108,7 @@ static struct usb_endpoint_descriptor hs_loop_sink_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *hs_loopback_descs[] = {
@@ -359,7 +359,7 @@ static struct usb_configuration loopback_driver = {
* loopback_add - add a loopback testing configuration to a device
* @cdev: the device to support the loopback configuration
*/
-int __init loopback_add(struct usb_composite_dev *cdev)
+int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume)
{
int id;
@@ -372,6 +372,10 @@ int __init loopback_add(struct usb_composite_dev *cdev)
loopback_intf.iInterface = id;
loopback_driver.iConfiguration = id;
+ /* support autoresume for remote wakeup testing */
+ if (autoresume)
+ sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+
/* support OTG systems */
if (gadget_is_otg(cdev->gadget)) {
loopback_driver.descriptors = otg_desc;
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c
index 38aa896cc5d..46d6266f30e 100644
--- a/drivers/usb/gadget/f_obex.c
+++ b/drivers/usb/gadget/f_obex.c
@@ -123,7 +123,7 @@ static struct usb_cdc_header_desc obex_cdc_header_desc __initdata = {
.bLength = sizeof(obex_cdc_header_desc),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0120),
+ .bcdCDC = cpu_to_le16(0x0120),
};
static struct usb_cdc_union_desc obex_cdc_union_desc __initdata = {
@@ -138,7 +138,7 @@ static struct usb_cdc_obex_desc obex_desc __initdata = {
.bLength = sizeof(obex_desc),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_OBEX_TYPE,
- .bcdVersion = __constant_cpu_to_le16(0x0100),
+ .bcdVersion = cpu_to_le16(0x0100),
};
/* High-Speed Support */
@@ -149,7 +149,7 @@ static struct usb_endpoint_descriptor obex_hs_ep_out_desc __initdata = {
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = {
@@ -158,7 +158,7 @@ static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *hs_function[] __initdata = {
diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
index c0916c7b217..c1abeb89b41 100644
--- a/drivers/usb/gadget/f_phonet.c
+++ b/drivers/usb/gadget/f_phonet.c
@@ -79,7 +79,7 @@ pn_header_desc = {
.bLength = sizeof pn_header_desc,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0110),
+ .bcdCDC = cpu_to_le16(0x0110),
};
static const struct usb_cdc_header_desc
@@ -87,7 +87,7 @@ pn_phonet_desc = {
.bLength = sizeof pn_phonet_desc,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_PHONET_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x1505), /* ??? */
+ .bcdCDC = cpu_to_le16(0x1505), /* ??? */
};
static struct usb_cdc_union_desc
@@ -138,7 +138,7 @@ pn_hs_sink_desc = {
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor
@@ -157,7 +157,7 @@ pn_hs_source_desc = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *fs_pn_function[] = {
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 3a8bb53fc47..3279a472604 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -137,7 +137,7 @@ static struct usb_cdc_header_desc header_desc __initdata = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0110),
+ .bcdCDC = cpu_to_le16(0x0110),
};
static struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor __initdata = {
@@ -187,7 +187,7 @@ static struct usb_endpoint_descriptor fs_notify_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT),
+ .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
.bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
};
@@ -230,7 +230,7 @@ static struct usb_endpoint_descriptor hs_notify_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT),
+ .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
.bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
};
static struct usb_endpoint_descriptor hs_in_desc __initdata = {
@@ -239,7 +239,7 @@ static struct usb_endpoint_descriptor hs_in_desc __initdata = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor hs_out_desc __initdata = {
@@ -248,7 +248,7 @@ static struct usb_endpoint_descriptor hs_out_desc __initdata = {
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *eth_hs_function[] __initdata = {
@@ -437,7 +437,7 @@ invalid:
DBG(cdev, "rndis req%02x.%02x v%04x i%04x l%d\n",
ctrl->bRequestType, ctrl->bRequest,
w_value, w_index, w_length);
- req->zero = 0;
+ req->zero = (value < w_length);
req->length = value;
value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
if (value < 0)
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index fe5674db344..db0aa93606e 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -89,14 +89,14 @@ static struct usb_endpoint_descriptor gser_hs_in_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor gser_hs_out_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *gser_hs_function[] __initdata = {
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index dc84d26d283..bffe91d525f 100644
--- a/drivers/usb/gadget/f_sourcesink.c
+++ b/drivers/usb/gadget/f_sourcesink.c
@@ -59,7 +59,6 @@ struct f_sourcesink {
struct usb_ep *in_ep;
struct usb_ep *out_ep;
- struct timer_list resume;
};
static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
@@ -67,10 +66,6 @@ static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
return container_of(f, struct f_sourcesink, function);
}
-static unsigned autoresume;
-module_param(autoresume, uint, 0);
-MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
-
static unsigned pattern;
module_param(pattern, uint, 0);
MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63 ");
@@ -118,7 +113,7 @@ static struct usb_endpoint_descriptor hs_source_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor hs_sink_desc = {
@@ -126,7 +121,7 @@ static struct usb_endpoint_descriptor hs_sink_desc = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *hs_source_sink_descs[] = {
@@ -155,21 +150,6 @@ static struct usb_gadget_strings *sourcesink_strings[] = {
/*-------------------------------------------------------------------------*/
-static void sourcesink_autoresume(unsigned long _c)
-{
- struct usb_composite_dev *cdev = (void *)_c;
- struct usb_gadget *g = cdev->gadget;
-
- /* Normally the host would be woken up for something
- * more significant than just a timer firing; likely
- * because of some direct user request.
- */
- if (g->speed != USB_SPEED_UNKNOWN) {
- int status = usb_gadget_wakeup(g);
- DBG(cdev, "%s --> %d\n", __func__, status);
- }
-}
-
static int __init
sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
{
@@ -198,9 +178,6 @@ autoconf_fail:
goto autoconf_fail;
ss->out_ep->driver_data = cdev; /* claim */
- setup_timer(&ss->resume, sourcesink_autoresume,
- (unsigned long) c->cdev);
-
/* support high speed hardware */
if (gadget_is_dualspeed(c->cdev->gadget)) {
hs_source_desc.bEndpointAddress =
@@ -359,7 +336,6 @@ static void disable_source_sink(struct f_sourcesink *ss)
cdev = ss->function.config->cdev;
disable_endpoints(cdev, ss->in_ep, ss->out_ep);
- del_timer(&ss->resume);
VDBG(cdev, "%s disabled\n", ss->function.name);
}
@@ -426,30 +402,6 @@ static void sourcesink_disable(struct usb_function *f)
disable_source_sink(ss);
}
-static void sourcesink_suspend(struct usb_function *f)
-{
- struct f_sourcesink *ss = func_to_ss(f);
- struct usb_composite_dev *cdev = f->config->cdev;
-
- if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
- return;
-
- if (autoresume) {
- mod_timer(&ss->resume, jiffies + (HZ * autoresume));
- DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
- } else
- DBG(cdev, "%s\n", __func__);
-}
-
-static void sourcesink_resume(struct usb_function *f)
-{
- struct f_sourcesink *ss = func_to_ss(f);
- struct usb_composite_dev *cdev = f->config->cdev;
-
- DBG(cdev, "%s\n", __func__);
- del_timer(&ss->resume);
-}
-
/*-------------------------------------------------------------------------*/
static int __init sourcesink_bind_config(struct usb_configuration *c)
@@ -467,8 +419,6 @@ static int __init sourcesink_bind_config(struct usb_configuration *c)
ss->function.unbind = sourcesink_unbind;
ss->function.set_alt = sourcesink_set_alt;
ss->function.disable = sourcesink_disable;
- ss->function.suspend = sourcesink_suspend;
- ss->function.resume = sourcesink_resume;
status = usb_add_function(c, &ss->function);
if (status)
@@ -559,7 +509,7 @@ static struct usb_configuration sourcesink_driver = {
* sourcesink_add - add a source/sink testing configuration to a device
* @cdev: the device to support the configuration
*/
-int __init sourcesink_add(struct usb_composite_dev *cdev)
+int __init sourcesink_add(struct usb_composite_dev *cdev, bool autoresume)
{
int id;
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
index fe183287577..a9c98fdb626 100644
--- a/drivers/usb/gadget/f_subset.c
+++ b/drivers/usb/gadget/f_subset.c
@@ -108,7 +108,7 @@ static struct usb_cdc_header_desc mdlm_header_desc __initdata = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
- .bcdCDC = __constant_cpu_to_le16(0x0110),
+ .bcdCDC = cpu_to_le16(0x0110),
};
static struct usb_cdc_mdlm_desc mdlm_desc __initdata = {
@@ -116,7 +116,7 @@ static struct usb_cdc_mdlm_desc mdlm_desc __initdata = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_MDLM_TYPE,
- .bcdVersion = __constant_cpu_to_le16(0x0100),
+ .bcdVersion = cpu_to_le16(0x0100),
.bGUID = {
0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6,
0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f,
@@ -144,9 +144,9 @@ static struct usb_cdc_ether_desc ether_desc __initdata = {
/* this descriptor actually adds value, surprise! */
/* .iMACAddress = DYNAMIC */
- .bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */
- .wMaxSegmentSize = __constant_cpu_to_le16(ETH_FRAME_LEN),
- .wNumberMCFilters = __constant_cpu_to_le16(0),
+ .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */
+ .wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN),
+ .wNumberMCFilters = cpu_to_le16(0),
.bNumberPowerFilters = 0,
};
@@ -186,7 +186,7 @@ static struct usb_endpoint_descriptor hs_subset_in_desc __initdata = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = {
@@ -194,7 +194,7 @@ static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = {
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_descriptor_header *hs_eth_function[] __initdata = {
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 1ab9dac7e12..d3c2464dee8 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -847,13 +847,13 @@ device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
/* The next three values can be overridden by module parameters */
- .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_ID),
- .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_ID),
- .bcdDevice = __constant_cpu_to_le16(0xffff),
+ .idVendor = cpu_to_le16(DRIVER_VENDOR_ID),
+ .idProduct = cpu_to_le16(DRIVER_PRODUCT_ID),
+ .bcdDevice = cpu_to_le16(0xffff),
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
@@ -926,7 +926,7 @@ fs_intr_in_desc = {
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(2),
+ .wMaxPacketSize = cpu_to_le16(2),
.bInterval = 32, // frames -> 32 ms
};
@@ -954,7 +954,7 @@ dev_qualifier = {
.bLength = sizeof dev_qualifier,
.bDescriptorType = USB_DT_DEVICE_QUALIFIER,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
.bNumConfigurations = 1,
@@ -967,7 +967,7 @@ hs_bulk_in_desc = {
/* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
};
static struct usb_endpoint_descriptor
@@ -977,7 +977,7 @@ hs_bulk_out_desc = {
/* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
+ .wMaxPacketSize = cpu_to_le16(512),
.bInterval = 1, // NAK every 1 uframe
};
@@ -988,7 +988,7 @@ hs_intr_in_desc = {
/* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(2),
+ .wMaxPacketSize = cpu_to_le16(2),
.bInterval = 9, // 2**(9-1) = 256 uframes -> 32 ms
};
@@ -2646,7 +2646,7 @@ static int send_status(struct fsg_dev *fsg)
struct bulk_cs_wrap *csw = bh->buf;
/* Store and send the Bulk-only CSW */
- csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG);
+ csw->Signature = cpu_to_le32(USB_BULK_CS_SIG);
csw->Tag = fsg->tag;
csw->Residue = cpu_to_le32(fsg->residue);
csw->Status = status;
@@ -3089,7 +3089,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
/* Is the CBW valid? */
if (req->actual != USB_BULK_CB_WRAP_LEN ||
- cbw->Signature != __constant_cpu_to_le32(
+ cbw->Signature != cpu_to_le32(
USB_BULK_CB_SIG)) {
DBG(fsg, "invalid CBW: len %u sig 0x%x\n",
req->actual,
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c
index d8d9a52a44b..9d7b95d4e3d 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.c
+++ b/drivers/usb/gadget/fsl_usb2_udc.c
@@ -1802,7 +1802,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
out:
if (retval)
- printk("gadget driver register failed %d\n", retval);
+ printk(KERN_WARNING "gadget driver register failed %d\n",
+ retval);
return retval;
}
EXPORT_SYMBOL(usb_gadget_register_driver);
@@ -1847,7 +1848,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
udc_controller->gadget.dev.driver = NULL;
udc_controller->driver = NULL;
- printk("unregistered gadget driver '%s'\n", driver->driver.name);
+ printk(KERN_WARNING "unregistered gadget driver '%s'\n",
+ driver->driver.name);
return 0;
}
EXPORT_SYMBOL(usb_gadget_unregister_driver);
@@ -2455,7 +2457,7 @@ module_init(udc_init);
static void __exit udc_exit(void)
{
platform_driver_unregister(&udc_driver);
- printk("%s unregistered\n", driver_desc);
+ printk(KERN_WARNING "%s unregistered\n", driver_desc);
}
module_exit(udc_exit);
diff --git a/drivers/usb/gadget/g_zero.h b/drivers/usb/gadget/g_zero.h
index dd2f16ad5a8..e84b3c47ed3 100644
--- a/drivers/usb/gadget/g_zero.h
+++ b/drivers/usb/gadget/g_zero.h
@@ -19,7 +19,7 @@ void disable_endpoints(struct usb_composite_dev *cdev,
struct usb_ep *in, struct usb_ep *out);
/* configuration-specific linkup */
-int sourcesink_add(struct usb_composite_dev *cdev);
-int loopback_add(struct usb_composite_dev *cdev);
+int sourcesink_add(struct usb_composite_dev *cdev, bool autoresume);
+int loopback_add(struct usb_composite_dev *cdev, bool autoresume);
#endif /* __G_ZERO_H */
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index 14e09abbddf..b9312dc6e04 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -199,10 +199,10 @@ DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(1);
static struct usb_device_descriptor device_desc = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
- .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM),
- .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM),
+ .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM),
+ .idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM),
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
.bNumConfigurations = 1,
@@ -241,8 +241,8 @@ static const struct usb_ac_header_descriptor_1 ac_header_desc = {
.bLength = USB_DT_AC_HEADER_SIZE(1),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = USB_MS_HEADER,
- .bcdADC = __constant_cpu_to_le16(0x0100),
- .wTotalLength = __constant_cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)),
+ .bcdADC = cpu_to_le16(0x0100),
+ .wTotalLength = cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)),
.bInCollection = 1,
.baInterfaceNr = {
[0] = GMIDI_MS_INTERFACE,
@@ -265,8 +265,8 @@ static const struct usb_ms_header_descriptor ms_header_desc = {
.bLength = USB_DT_MS_HEADER_SIZE,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = USB_MS_HEADER,
- .bcdMSC = __constant_cpu_to_le16(0x0100),
- .wTotalLength = __constant_cpu_to_le16(USB_DT_MS_HEADER_SIZE
+ .bcdMSC = cpu_to_le16(0x0100),
+ .wTotalLength = cpu_to_le16(USB_DT_MS_HEADER_SIZE
+ 2*USB_DT_MIDI_IN_SIZE
+ 2*USB_DT_MIDI_OUT_SIZE(1)),
};
@@ -1226,7 +1226,7 @@ autoconf_fail:
*/
pr_warning("%s: controller '%s' not recognized\n",
shortname, gadget->name);
- device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
+ device_desc.bcdDevice = cpu_to_le16(0x9999);
}
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 63419c4d503..de010c939db 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -1472,7 +1472,7 @@ static void ep0_setup(struct goku_udc *dev)
/* active endpoint */
if (tmp > 3 || (!dev->ep[tmp].desc && tmp != 0))
goto stall;
- if (ctrl.wIndex & __constant_cpu_to_le16(
+ if (ctrl.wIndex & cpu_to_le16(
USB_DIR_IN)) {
if (!dev->ep[tmp].is_in)
goto stall;
@@ -1480,7 +1480,7 @@ static void ep0_setup(struct goku_udc *dev)
if (dev->ep[tmp].is_in)
goto stall;
}
- if (ctrl.wValue != __constant_cpu_to_le16(
+ if (ctrl.wValue != cpu_to_le16(
USB_ENDPOINT_HALT))
goto stall;
if (tmp)
@@ -1493,7 +1493,7 @@ succeed:
return;
case USB_RECIP_DEVICE:
/* device remote wakeup: always clear */
- if (ctrl.wValue != __constant_cpu_to_le16(1))
+ if (ctrl.wValue != cpu_to_le16(1))
goto stall;
VDBG(dev, "clear dev remote wakeup\n");
goto succeed;
@@ -1519,7 +1519,7 @@ succeed:
dev->req_config = (ctrl.bRequest == USB_REQ_SET_CONFIGURATION
&& ctrl.bRequestType == USB_RECIP_DEVICE);
if (unlikely(dev->req_config))
- dev->configured = (ctrl.wValue != __constant_cpu_to_le16(0));
+ dev->configured = (ctrl.wValue != cpu_to_le16(0));
/* delegate everything to the gadget driver.
* it may respond after this irq handler returns.
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c
index cd67ac75e62..168658b4b4e 100644
--- a/drivers/usb/gadget/imx_udc.c
+++ b/drivers/usb/gadget/imx_udc.c
@@ -1,7 +1,7 @@
/*
* driver/usb/gadget/imx_udc.c
*
- * Copyright (C) 2005 Mike Lee(eemike@gmail.com)
+ * Copyright (C) 2005 Mike Lee <eemike@gmail.com>
* Copyright (C) 2008 Darius Augulis <augulis.darius@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -28,6 +28,7 @@
#include <linux/dma-mapping.h>
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/timer.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
@@ -51,7 +52,8 @@ void ep0_chg_stat(const char *label, struct imx_udc_struct *imx_usb,
void imx_udc_enable(struct imx_udc_struct *imx_usb)
{
int temp = __raw_readl(imx_usb->base + USB_CTRL);
- __raw_writel(temp | CTRL_FE_ENA | CTRL_AFE_ENA, imx_usb->base + USB_CTRL);
+ __raw_writel(temp | CTRL_FE_ENA | CTRL_AFE_ENA,
+ imx_usb->base + USB_CTRL);
imx_usb->gadget.speed = USB_SPEED_FULL;
}
@@ -126,7 +128,8 @@ void imx_udc_config(struct imx_udc_struct *imx_usb)
for (j = 0; j < 5; j++) {
__raw_writeb(ep_conf[j],
imx_usb->base + USB_DDAT);
- do {} while (__raw_readl(imx_usb->base + USB_DADR)
+ do {} while (__raw_readl(imx_usb->base
+ + USB_DADR)
& DADR_BSY);
}
}
@@ -183,7 +186,8 @@ void imx_udc_init_ep(struct imx_udc_struct *imx_usb)
temp = (EP_DIR(imx_ep) << 7) | (max << 5)
| (imx_ep->bmAttributes << 3);
__raw_writel(temp, imx_usb->base + USB_EP_STAT(i));
- __raw_writel(temp | EPSTAT_FLUSH, imx_usb->base + USB_EP_STAT(i));
+ __raw_writel(temp | EPSTAT_FLUSH,
+ imx_usb->base + USB_EP_STAT(i));
D_INI(imx_usb->dev, "<%s> ep%d_stat %08x\n", __func__, i,
__raw_readl(imx_usb->base + USB_EP_STAT(i)));
}
@@ -278,15 +282,18 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep)
struct imx_udc_struct *imx_usb = imx_ep->imx_usb;
int temp, i;
- D_ERR(imx_usb->dev, "<%s> Forced stall on %s\n", __func__, imx_ep->ep.name);
+ D_ERR(imx_usb->dev,
+ "<%s> Forced stall on %s\n", __func__, imx_ep->ep.name);
imx_flush(imx_ep);
/* Special care for ep0 */
- if (EP_NO(imx_ep)) {
+ if (!EP_NO(imx_ep)) {
temp = __raw_readl(imx_usb->base + USB_CTRL);
- __raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, imx_usb->base + USB_CTRL);
- do { } while (__raw_readl(imx_usb->base + USB_CTRL) & CTRL_CMDOVER);
+ __raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR,
+ imx_usb->base + USB_CTRL);
+ do { } while (__raw_readl(imx_usb->base + USB_CTRL)
+ & CTRL_CMDOVER);
temp = __raw_readl(imx_usb->base + USB_CTRL);
__raw_writel(temp & ~CTRL_CMDERROR, imx_usb->base + USB_CTRL);
}
@@ -296,12 +303,13 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep)
imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
for (i = 0; i < 100; i ++) {
- temp = __raw_readl(imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
+ temp = __raw_readl(imx_usb->base
+ + USB_EP_STAT(EP_NO(imx_ep)));
if (!(temp & EPSTAT_STALL))
break;
udelay(20);
}
- if (i == 50)
+ if (i == 100)
D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n",
__func__, imx_ep->ep.name);
}
@@ -325,7 +333,8 @@ static int imx_udc_wakeup(struct usb_gadget *_gadget)
*******************************************************************************
*/
-static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req)
+static void ep_add_request(struct imx_ep_struct *imx_ep,
+ struct imx_request *req)
{
if (unlikely(!req))
return;
@@ -334,7 +343,8 @@ static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req
list_add_tail(&req->queue, &imx_ep->queue);
}
-static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req)
+static void ep_del_request(struct imx_ep_struct *imx_ep,
+ struct imx_request *req)
{
if (unlikely(!req))
return;
@@ -343,7 +353,8 @@ static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req
req->in_use = 0;
}
-static void done(struct imx_ep_struct *imx_ep, struct imx_request *req, int status)
+static void done(struct imx_ep_struct *imx_ep,
+ struct imx_request *req, int status)
{
ep_del_request(imx_ep, req);
@@ -494,7 +505,8 @@ static int write_fifo(struct imx_ep_struct *imx_ep, struct imx_request *req)
__func__, imx_ep->ep.name, req,
completed ? "completed" : "not completed");
if (!EP_NO(imx_ep))
- ep0_chg_stat(__func__, imx_ep->imx_usb, EP0_IDLE);
+ ep0_chg_stat(__func__,
+ imx_ep->imx_usb, EP0_IDLE);
}
}
@@ -539,10 +551,9 @@ static int handle_ep0(struct imx_ep_struct *imx_ep)
struct imx_request *req = NULL;
int ret = 0;
- if (!list_empty(&imx_ep->queue))
+ if (!list_empty(&imx_ep->queue)) {
req = list_entry(imx_ep->queue.next, struct imx_request, queue);
- if (req) {
switch (imx_ep->imx_usb->ep0state) {
case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR */
@@ -561,6 +572,10 @@ static int handle_ep0(struct imx_ep_struct *imx_ep)
}
}
+ else
+ D_ERR(imx_ep->imx_usb->dev, "<%s> no request on %s\n",
+ __func__, imx_ep->ep.name);
+
return ret;
}
@@ -583,7 +598,8 @@ static void handle_ep0_devreq(struct imx_udc_struct *imx_usb)
"<%s> no setup packet received\n", __func__);
goto stall;
}
- u.word[i] = __raw_readl(imx_usb->base + USB_EP_FDAT(EP_NO(imx_ep)));
+ u.word[i] = __raw_readl(imx_usb->base
+ + USB_EP_FDAT(EP_NO(imx_ep)));
}
temp = imx_ep_empty(imx_ep);
@@ -759,7 +775,7 @@ static int imx_ep_queue
*/
if (imx_usb->set_config && !EP_NO(imx_ep)) {
imx_usb->set_config = 0;
- D_EPX(imx_usb->dev,
+ D_ERR(imx_usb->dev,
"<%s> gadget reply set config\n", __func__);
return 0;
}
@@ -779,28 +795,29 @@ static int imx_ep_queue
return -ESHUTDOWN;
}
- local_irq_save(flags);
-
/* Debug */
D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n",
__func__, EP_NO(imx_ep),
- ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE)
- || (EP_NO(imx_ep) && EP_DIR(imx_ep))) ? "IN" : "OUT", usb_req->length);
+ ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state
+ == EP0_IN_DATA_PHASE)
+ || (EP_NO(imx_ep) && EP_DIR(imx_ep)))
+ ? "IN" : "OUT", usb_req->length);
dump_req(__func__, imx_ep, usb_req);
if (imx_ep->stopped) {
usb_req->status = -ESHUTDOWN;
- ret = -ESHUTDOWN;
- goto out;
+ return -ESHUTDOWN;
}
if (req->in_use) {
D_ERR(imx_usb->dev,
"<%s> refusing to queue req %p (already queued)\n",
__func__, req);
- goto out;
+ return 0;
}
+ local_irq_save(flags);
+
usb_req->status = -EINPROGRESS;
usb_req->actual = 0;
@@ -810,7 +827,7 @@ static int imx_ep_queue
ret = handle_ep0(imx_ep);
else
ret = handle_ep(imx_ep);
-out:
+
local_irq_restore(flags);
return ret;
}
@@ -997,71 +1014,32 @@ static void udc_stop_activity(struct imx_udc_struct *imx_usb,
*******************************************************************************
*/
-static irqreturn_t imx_udc_irq(int irq, void *dev)
+/*
+ * Called when timer expires.
+ * Timer is started when CFG_CHG is received.
+ */
+static void handle_config(unsigned long data)
{
- struct imx_udc_struct *imx_usb = dev;
+ struct imx_udc_struct *imx_usb = (void *)data;
struct usb_ctrlrequest u;
int temp, cfg, intf, alt;
- int intr = __raw_readl(imx_usb->base + USB_INTR);
-
- if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START
- | INTR_RESET_STOP | INTR_CFG_CHG)) {
- dump_intr(__func__, intr, imx_usb->dev);
- dump_usb_stat(__func__, imx_usb);
- }
-
- if (!imx_usb->driver) {
- /*imx_udc_disable(imx_usb);*/
- goto end_irq;
- }
-
- if (intr & INTR_WAKEUP) {
- if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN
- && imx_usb->driver && imx_usb->driver->resume)
- imx_usb->driver->resume(&imx_usb->gadget);
- imx_usb->set_config = 0;
- imx_usb->gadget.speed = USB_SPEED_FULL;
- }
-
- if (intr & INTR_SUSPEND) {
- if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN
- && imx_usb->driver && imx_usb->driver->suspend)
- imx_usb->driver->suspend(&imx_usb->gadget);
- imx_usb->set_config = 0;
- imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
- }
- if (intr & INTR_RESET_START) {
- __raw_writel(intr, imx_usb->base + USB_INTR);
- udc_stop_activity(imx_usb, imx_usb->driver);
- imx_usb->set_config = 0;
- imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
- }
-
- if (intr & INTR_RESET_STOP)
- imx_usb->gadget.speed = USB_SPEED_FULL;
+ local_irq_disable();
- if (intr & INTR_CFG_CHG) {
- __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR);
- temp = __raw_readl(imx_usb->base + USB_STAT);
- cfg = (temp & STAT_CFG) >> 5;
- intf = (temp & STAT_INTF) >> 3;
- alt = temp & STAT_ALTSET;
+ temp = __raw_readl(imx_usb->base + USB_STAT);
+ cfg = (temp & STAT_CFG) >> 5;
+ intf = (temp & STAT_INTF) >> 3;
+ alt = temp & STAT_ALTSET;
- D_REQ(imx_usb->dev,
- "<%s> orig config C=%d, I=%d, A=%d / "
- "req config C=%d, I=%d, A=%d\n",
- __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt,
- cfg, intf, alt);
+ D_REQ(imx_usb->dev,
+ "<%s> orig config C=%d, I=%d, A=%d / "
+ "req config C=%d, I=%d, A=%d\n",
+ __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt,
+ cfg, intf, alt);
- if (cfg != 1 && cfg != 2)
- goto end_irq;
+ if (cfg == 1 || cfg == 2) {
- imx_usb->set_config = 0;
-
- /* Config setup */
if (imx_usb->cfg != cfg) {
- D_REQ(imx_usb->dev, "<%s> Change config start\n",__func__);
u.bRequest = USB_REQ_SET_CONFIGURATION;
u.bRequestType = USB_DIR_OUT |
USB_TYPE_STANDARD |
@@ -1070,14 +1048,10 @@ static irqreturn_t imx_udc_irq(int irq, void *dev)
u.wIndex = 0;
u.wLength = 0;
imx_usb->cfg = cfg;
- imx_usb->set_config = 1;
imx_usb->driver->setup(&imx_usb->gadget, &u);
- imx_usb->set_config = 0;
- D_REQ(imx_usb->dev, "<%s> Change config done\n",__func__);
}
if (imx_usb->intf != intf || imx_usb->alt != alt) {
- D_REQ(imx_usb->dev, "<%s> Change interface start\n",__func__);
u.bRequest = USB_REQ_SET_INTERFACE;
u.bRequestType = USB_DIR_OUT |
USB_TYPE_STANDARD |
@@ -1087,20 +1061,92 @@ static irqreturn_t imx_udc_irq(int irq, void *dev)
u.wLength = 0;
imx_usb->intf = intf;
imx_usb->alt = alt;
- imx_usb->set_config = 1;
imx_usb->driver->setup(&imx_usb->gadget, &u);
- imx_usb->set_config = 0;
- D_REQ(imx_usb->dev, "<%s> Change interface done\n",__func__);
}
}
+ imx_usb->set_config = 0;
+
+ local_irq_enable();
+}
+
+static irqreturn_t imx_udc_irq(int irq, void *dev)
+{
+ struct imx_udc_struct *imx_usb = dev;
+ int intr = __raw_readl(imx_usb->base + USB_INTR);
+ int temp;
+
+ if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START
+ | INTR_RESET_STOP | INTR_CFG_CHG)) {
+ dump_intr(__func__, intr, imx_usb->dev);
+ dump_usb_stat(__func__, imx_usb);
+ }
+
+ if (!imx_usb->driver)
+ goto end_irq;
+
if (intr & INTR_SOF) {
+ /* Copy from Freescale BSP.
+ We must enable SOF intr and set CMDOVER.
+ Datasheet don't specifiy this action, but it
+ is done in Freescale BSP, so just copy it.
+ */
if (imx_usb->ep0state == EP0_IDLE) {
temp = __raw_readl(imx_usb->base + USB_CTRL);
- __raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL);
+ __raw_writel(temp | CTRL_CMDOVER,
+ imx_usb->base + USB_CTRL);
}
}
+ if (intr & INTR_CFG_CHG) {
+ /* A workaround of serious IMX UDC bug.
+ Handling of CFG_CHG should be delayed for some time, because
+ IMX does not NACK the host when CFG_CHG interrupt is pending.
+ There is no time to handle current CFG_CHG
+ if next CFG_CHG or SETUP packed is send immediately.
+ We have to clear CFG_CHG, start the timer and
+ NACK the host by setting CTRL_CMDOVER
+ if it sends any SETUP packet.
+ When timer expires, handler is called to handle configuration
+ changes. While CFG_CHG is not handled (set_config=1),
+ we must NACK the host to every SETUP packed.
+ This delay prevents from going out of sync with host.
+ */
+ __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR);
+ imx_usb->set_config = 1;
+ mod_timer(&imx_usb->timer, jiffies + 5);
+ goto end_irq;
+ }
+
+ if (intr & INTR_WAKEUP) {
+ if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN
+ && imx_usb->driver && imx_usb->driver->resume)
+ imx_usb->driver->resume(&imx_usb->gadget);
+ imx_usb->set_config = 0;
+ del_timer(&imx_usb->timer);
+ imx_usb->gadget.speed = USB_SPEED_FULL;
+ }
+
+ if (intr & INTR_SUSPEND) {
+ if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN
+ && imx_usb->driver && imx_usb->driver->suspend)
+ imx_usb->driver->suspend(&imx_usb->gadget);
+ imx_usb->set_config = 0;
+ del_timer(&imx_usb->timer);
+ imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
+ }
+
+ if (intr & INTR_RESET_START) {
+ __raw_writel(intr, imx_usb->base + USB_INTR);
+ udc_stop_activity(imx_usb, imx_usb->driver);
+ imx_usb->set_config = 0;
+ del_timer(&imx_usb->timer);
+ imx_usb->gadget.speed = USB_SPEED_UNKNOWN;
+ }
+
+ if (intr & INTR_RESET_STOP)
+ imx_usb->gadget.speed = USB_SPEED_FULL;
+
end_irq:
__raw_writel(intr, imx_usb->base + USB_INTR);
return IRQ_HANDLED;
@@ -1109,6 +1155,7 @@ end_irq:
static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev)
{
struct imx_udc_struct *imx_usb = dev;
+ struct imx_ep_struct *imx_ep = &imx_usb->imx_ep[0];
int intr = __raw_readl(imx_usb->base + USB_EP_INTR(0));
dump_ep_intr(__func__, 0, intr, imx_usb->dev);
@@ -1118,16 +1165,15 @@ static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev)
return IRQ_HANDLED;
}
- /* DEVREQ IRQ has highest priority */
+ /* DEVREQ has highest priority */
if (intr & (EPINTR_DEVREQ | EPINTR_MDEVREQ))
handle_ep0_devreq(imx_usb);
/* Seem i.MX is missing EOF interrupt sometimes.
- * Therefore we monitor both EOF and FIFO_EMPTY interrups
- * when transmiting, and both EOF and FIFO_FULL when
- * receiving data.
+ * Therefore we don't monitor EOF.
+ * We call handle_ep0() only if a request is queued for ep0.
*/
- else if (intr & (EPINTR_EOF | EPINTR_FIFO_EMPTY | EPINTR_FIFO_FULL))
- handle_ep0(&imx_usb->imx_ep[0]);
+ else if (!list_empty(&imx_ep->queue))
+ handle_ep0(imx_ep);
__raw_writel(intr, imx_usb->base + USB_EP_INTR(0));
@@ -1318,6 +1364,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
udc_stop_activity(imx_usb, driver);
imx_udc_disable(imx_usb);
+ del_timer(&imx_usb->timer);
driver->unbind(&imx_usb->gadget);
imx_usb->gadget.dev.driver = NULL;
@@ -1435,6 +1482,10 @@ static int __init imx_udc_probe(struct platform_device *pdev)
usb_init_data(imx_usb);
imx_udc_init(imx_usb);
+ init_timer(&imx_usb->timer);
+ imx_usb->timer.function = handle_config;
+ imx_usb->timer.data = (unsigned long)imx_usb;
+
return 0;
fail3:
@@ -1457,6 +1508,7 @@ static int __exit imx_udc_remove(struct platform_device *pdev)
int i;
imx_udc_disable(imx_usb);
+ del_timer(&imx_usb->timer);
for (i = 0; i < IMX_USB_NB_EP + 1; i++)
free_irq(imx_usb->usbd_int[i], imx_usb);
diff --git a/drivers/usb/gadget/imx_udc.h b/drivers/usb/gadget/imx_udc.h
index 850076937d8..b48ad59603d 100644
--- a/drivers/usb/gadget/imx_udc.h
+++ b/drivers/usb/gadget/imx_udc.h
@@ -23,7 +23,8 @@
/* Helper macros */
#define EP_NO(ep) ((ep->bEndpointAddress) & ~USB_DIR_IN) /* IN:1, OUT:0 */
#define EP_DIR(ep) ((ep->bEndpointAddress) & USB_DIR_IN ? 1 : 0)
-#define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/
+#define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) \
+ ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/
#define ep_to_irq(ep) (EP_NO((ep)) + USBD_INT0)
#define IMX_USB_NB_EP 6
@@ -58,6 +59,7 @@ struct imx_udc_struct {
struct device *dev;
struct imx_ep_struct imx_ep[IMX_USB_NB_EP];
struct clk *clk;
+ struct timer_list timer;
enum ep0_state ep0state;
struct resource *res;
void __iomem *base;
@@ -88,8 +90,8 @@ struct imx_udc_struct {
#define USB_EP_FDAT3(x) (0x3F + (x*0x30)) /* USB FIFO data */
#define USB_EP_FSTAT(x) (0x40 + (x*0x30)) /* USB FIFO status */
#define USB_EP_FCTRL(x) (0x44 + (x*0x30)) /* USB FIFO control */
-#define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last read frame pointer */
-#define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last write frame pointer */
+#define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last rd f. pointer */
+#define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last wr f. pointer */
#define USB_EP_FALRM(x) (0x50 + (x*0x30)) /* USB FIFO alarm */
#define USB_EP_FRDP(x) (0x54 + (x*0x30)) /* USB FIFO read pointer */
#define USB_EP_FWRP(x) (0x58 + (x*0x30)) /* USB FIFO write pointer */
@@ -170,7 +172,7 @@ struct imx_udc_struct {
/* #define DEBUG_IRQ */
/* #define DEBUG_EPIRQ */
/* #define DEBUG_DUMP */
-#define DEBUG_ERR
+/* #define DEBUG_ERR */
#ifdef DEBUG_REQ
#define D_REQ(dev, args...) dev_dbg(dev, ## args)
@@ -228,7 +230,8 @@ struct imx_udc_struct {
#endif /* DEBUG_IRQ */
#ifdef DEBUG_EPIRQ
- static void dump_ep_intr(const char *label, int nr, int irqreg, struct device *dev)
+ static void dump_ep_intr(const char *label, int nr, int irqreg,
+ struct device *dev)
{
dev_dbg(dev, "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, nr,
(irqreg & EPINTR_FIFO_FULL) ? " full" : "",
@@ -246,7 +249,8 @@ struct imx_udc_struct {
#endif /* DEBUG_IRQ */
#ifdef DEBUG_DUMP
- static void dump_usb_stat(const char *label, struct imx_udc_struct *imx_usb)
+ static void dump_usb_stat(const char *label,
+ struct imx_udc_struct *imx_usb)
{
int temp = __raw_readl(imx_usb->base + USB_STAT);
@@ -259,12 +263,15 @@ struct imx_udc_struct {
(temp & STAT_ALTSET));
}
- static void dump_ep_stat(const char *label, struct imx_ep_struct *imx_ep)
+ static void dump_ep_stat(const char *label,
+ struct imx_ep_struct *imx_ep)
{
- int temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_INTR(EP_NO(imx_ep)));
+ int temp = __raw_readl(imx_ep->imx_usb->base
+ + USB_EP_INTR(EP_NO(imx_ep)));
dev_dbg(imx_ep->imx_usb->dev,
- "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep),
+ "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n",
+ label, EP_NO(imx_ep),
(temp & EPINTR_FIFO_FULL) ? " full" : "",
(temp & EPINTR_FIFO_EMPTY) ? " fempty" : "",
(temp & EPINTR_FIFO_ERROR) ? " ferr" : "",
@@ -275,18 +282,22 @@ struct imx_udc_struct {
(temp & EPINTR_DEVREQ) ? " devreq" : "",
(temp & EPINTR_EOT) ? " eot" : "");
- temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_STAT(EP_NO(imx_ep)));
+ temp = __raw_readl(imx_ep->imx_usb->base
+ + USB_EP_STAT(EP_NO(imx_ep)));
dev_dbg(imx_ep->imx_usb->dev,
- "<%s> EP%d_STAT=[%s%s bcount=%d]\n", label, EP_NO(imx_ep),
+ "<%s> EP%d_STAT=[%s%s bcount=%d]\n",
+ label, EP_NO(imx_ep),
(temp & EPSTAT_SIP) ? " sip" : "",
(temp & EPSTAT_STALL) ? " stall" : "",
(temp & EPSTAT_BCOUNT) >> 16);
- temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_FSTAT(EP_NO(imx_ep)));
+ temp = __raw_readl(imx_ep->imx_usb->base
+ + USB_EP_FSTAT(EP_NO(imx_ep)));
dev_dbg(imx_ep->imx_usb->dev,
- "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep),
+ "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n",
+ label, EP_NO(imx_ep),
(temp & FSTAT_ERR) ? " ferr" : "",
(temp & FSTAT_UF) ? " funder" : "",
(temp & FSTAT_OF) ? " fover" : "",
@@ -296,19 +307,23 @@ struct imx_udc_struct {
(temp & FSTAT_EMPTY) ? " fempty" : "");
}
- static void dump_req(const char *label, struct imx_ep_struct *imx_ep, struct usb_request *req)
+ static void dump_req(const char *label, struct imx_ep_struct *imx_ep,
+ struct usb_request *req)
{
int i;
if (!req || !req->buf) {
- dev_dbg(imx_ep->imx_usb->dev, "<%s> req or req buf is free\n", label);
+ dev_dbg(imx_ep->imx_usb->dev,
+ "<%s> req or req buf is free\n", label);
return;
}
- if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE)
+ if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state
+ == EP0_IN_DATA_PHASE)
|| (EP_NO(imx_ep) && EP_DIR(imx_ep))) {
- dev_dbg(imx_ep->imx_usb->dev, "<%s> request dump <", label);
+ dev_dbg(imx_ep->imx_usb->dev,
+ "<%s> request dump <", label);
for (i = 0; i < req->length; i++)
printk("%02x-", *((u8 *)req->buf + i));
printk(">\n");
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 317b48fdbf0..d20937f28a1 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -1334,7 +1334,7 @@ static void make_qualifier (struct dev_data *dev)
qual.bLength = sizeof qual;
qual.bDescriptorType = USB_DT_DEVICE_QUALIFIER;
- qual.bcdUSB = __constant_cpu_to_le16 (0x0200);
+ qual.bcdUSB = cpu_to_le16 (0x0200);
desc = dev->dev;
qual.bDeviceClass = desc->bDeviceClass;
@@ -1908,7 +1908,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|| dev->dev->bNumConfigurations != 1)
goto fail;
dev->dev->bNumConfigurations = 1;
- dev->dev->bcdUSB = __constant_cpu_to_le16 (0x0200);
+ dev->dev->bcdUSB = cpu_to_le16 (0x0200);
/* triggers gadgetfs_bind(); then we can enumerate. */
spin_unlock_irq (&dev->lock);
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index d554b089560..6cd3d54f564 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -432,8 +432,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
device_add(&dev->gadget.dev);
retval = driver->bind(&dev->gadget);
if (retval) {
- printk("%s: bind to driver %s --> error %d\n", dev->gadget.name,
- driver->driver.name, retval);
+ printk(KERN_WARNING "%s: bind to driver %s --> error %d\n",
+ dev->gadget.name, driver->driver.name, retval);
device_del(&dev->gadget.dev);
dev->driver = 0;
@@ -445,8 +445,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
* for set_configuration as well as eventual disconnect.
* NOTE: this shouldn't power up until later.
*/
- printk("%s: registered gadget driver '%s'\n", dev->gadget.name,
- driver->driver.name);
+ printk(KERN_WARNING "%s: registered gadget driver '%s'\n",
+ dev->gadget.name, driver->driver.name);
udc_enable(dev);
@@ -581,7 +581,8 @@ static int read_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req)
* discard the extra data.
*/
if (req->req.status != -EOVERFLOW)
- printk("%s overflow %d\n", ep->ep.name, count);
+ printk(KERN_WARNING "%s overflow %d\n",
+ ep->ep.name, count);
req->req.status = -EOVERFLOW;
} else {
*buf++ = byte;
@@ -831,7 +832,8 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
queue);
if (!req) {
- printk("%s: NULL REQ %d\n",
+ printk(KERN_WARNING
+ "%s: NULL REQ %d\n",
__func__, ep_idx);
flush(ep);
break;
@@ -844,7 +846,7 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr)
} else {
/* Throw packet away.. */
- printk("%s: No descriptor?!?\n", __func__);
+ printk(KERN_WARNING "%s: No descriptor?!?\n", __func__);
flush(ep);
}
}
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 12c6d83b218..9498be87a72 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -142,8 +142,8 @@ static char *type_string (u8 bmAttributes)
#include "net2280.h"
-#define valid_bit __constant_cpu_to_le32 (1 << VALID_BIT)
-#define dma_done_ie __constant_cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE)
+#define valid_bit cpu_to_le32 (1 << VALID_BIT)
+#define dma_done_ie cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE)
/*-------------------------------------------------------------------------*/
@@ -425,7 +425,7 @@ net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags)
return NULL;
}
td->dmacount = 0; /* not VALID */
- td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID);
+ td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID);
td->dmadesc = td->dmaaddr;
req->td = td;
}
@@ -775,7 +775,7 @@ static void start_dma (struct net2280_ep *ep, struct net2280_request *req)
fill_dma_desc (ep, req, 1);
if (!use_dma_chaining)
- req->td->dmacount |= __constant_cpu_to_le32 (1 << END_OF_CHAIN);
+ req->td->dmacount |= cpu_to_le32 (1 << END_OF_CHAIN);
start_queue (ep, tmp, req->td_dma);
}
@@ -2407,9 +2407,9 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
if (readl (&e->regs->ep_rsp)
& (1 << SET_ENDPOINT_HALT))
- status = __constant_cpu_to_le32 (1);
+ status = cpu_to_le32 (1);
else
- status = __constant_cpu_to_le32 (0);
+ status = cpu_to_le32 (0);
/* don't bother with a request object! */
writel (0, &dev->epregs [0].ep_irqenb);
@@ -2667,7 +2667,7 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat)
req = list_entry (ep->queue.next,
struct net2280_request, queue);
dmacount = req->td->dmacount;
- dmacount &= __constant_cpu_to_le32 (
+ dmacount &= cpu_to_le32 (
(1 << VALID_BIT)
| DMA_BYTE_COUNT_MASK);
if (dmacount && (dmacount & valid_bit) == 0)
@@ -2881,7 +2881,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
goto done;
}
td->dmacount = 0; /* not VALID */
- td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID);
+ td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID);
td->dmadesc = td->dmaaddr;
dev->ep [i].dummy = td;
}
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index 5a3034fdfe4..29500154d00 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -225,12 +225,12 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR);
static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
- .idVendor = __constant_cpu_to_le16(PRINTER_VENDOR_NUM),
- .idProduct = __constant_cpu_to_le16(PRINTER_PRODUCT_NUM),
+ .idVendor = cpu_to_le16(PRINTER_VENDOR_NUM),
+ .idProduct = cpu_to_le16(PRINTER_PRODUCT_NUM),
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
.iSerialNumber = STRING_SERIALNUM,
@@ -299,20 +299,20 @@ static struct usb_endpoint_descriptor hs_ep_in_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512)
+ .wMaxPacketSize = cpu_to_le16(512)
};
static struct usb_endpoint_descriptor hs_ep_out_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512)
+ .wMaxPacketSize = cpu_to_le16(512)
};
static struct usb_qualifier_descriptor dev_qualifier = {
.bLength = sizeof dev_qualifier,
.bDescriptorType = USB_DT_DEVICE_QUALIFIER,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PRINTER,
.bNumConfigurations = 1
};
@@ -1406,16 +1406,16 @@ printer_bind(struct usb_gadget *gadget)
gadget->name);
/* unrecognized, but safe unless bulk is REALLY quirky */
device_desc.bcdDevice =
- __constant_cpu_to_le16(0xFFFF);
+ cpu_to_le16(0xFFFF);
}
snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s",
init_utsname()->sysname, init_utsname()->release,
gadget->name);
device_desc.idVendor =
- __constant_cpu_to_le16(PRINTER_VENDOR_NUM);
+ cpu_to_le16(PRINTER_VENDOR_NUM);
device_desc.idProduct =
- __constant_cpu_to_le16(PRINTER_PRODUCT_NUM);
+ cpu_to_le16(PRINTER_PRODUCT_NUM);
/* support optional vendor/distro customization */
if (idVendor) {
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 990f40f988d..8cc676ecbb2 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -30,6 +30,7 @@
#include <linux/proc_fs.h>
#include <linux/clk.h>
#include <linux/irq.h>
+#include <linux/gpio.h>
#include <asm/byteorder.h>
#include <mach/hardware.h>
@@ -278,7 +279,7 @@ static void pxa_init_debugfs(struct pxa_udc *udc)
goto err_queues;
eps = debugfs_create_file("epstate", 0400, root, udc,
&eps_dbg_fops);
- if (!queues)
+ if (!eps)
goto err_eps;
udc->debugfs_root = root;
@@ -747,13 +748,13 @@ static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status)
}
/**
- * ep_end_out_req - Ends control endpoint in request
+ * ep_end_out_req - Ends endpoint OUT request
* @ep: physical endpoint
* @req: pxa request
*
* Context: ep->lock held
*
- * Ends endpoint in request (completes usb request).
+ * Ends endpoint OUT request (completes usb request).
*/
static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
{
@@ -762,13 +763,13 @@ static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
}
/**
- * ep0_end_out_req - Ends control endpoint in request (ends data stage)
+ * ep0_end_out_req - Ends control endpoint OUT request (ends data stage)
* @ep: physical endpoint
* @req: pxa request
*
* Context: ep->lock held
*
- * Ends control endpoint in request (completes usb request), and puts
+ * Ends control endpoint OUT request (completes usb request), and puts
* control endpoint into idle state
*/
static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
@@ -779,13 +780,13 @@ static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
}
/**
- * ep_end_in_req - Ends endpoint out request
+ * ep_end_in_req - Ends endpoint IN request
* @ep: physical endpoint
* @req: pxa request
*
* Context: ep->lock held
*
- * Ends endpoint out request (completes usb request).
+ * Ends endpoint IN request (completes usb request).
*/
static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
{
@@ -794,20 +795,18 @@ static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
}
/**
- * ep0_end_in_req - Ends control endpoint out request (ends data stage)
+ * ep0_end_in_req - Ends control endpoint IN request (ends data stage)
* @ep: physical endpoint
* @req: pxa request
*
* Context: ep->lock held
*
- * Ends control endpoint out request (completes usb request), and puts
+ * Ends control endpoint IN request (completes usb request), and puts
* control endpoint into status state
*/
static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
{
- struct pxa_udc *udc = ep->dev;
-
- set_ep0state(udc, IN_STATUS_STAGE);
+ set_ep0state(ep->dev, IN_STATUS_STAGE);
ep_end_in_req(ep, req);
}
@@ -1167,7 +1166,7 @@ static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
ep_end_in_req(ep, req);
} else {
ep_err(ep, "got a request of %d bytes while"
- "in state WATI_ACK_SET_CONF_INTERF\n",
+ "in state WAIT_ACK_SET_CONF_INTERF\n",
length);
ep_del_request(ep, req);
rc = -EL2HLT;
@@ -1213,30 +1212,26 @@ static int pxa_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
struct udc_usb_ep *udc_usb_ep;
struct pxa27x_request *req;
unsigned long flags;
- int rc;
+ int rc = -EINVAL;
if (!_ep)
- return -EINVAL;
+ return rc;
udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
ep = udc_usb_ep->pxa_ep;
if (!ep || is_ep0(ep))
- return -EINVAL;
+ return rc;
spin_lock_irqsave(&ep->lock, flags);
/* make sure it's actually queued on this endpoint */
list_for_each_entry(req, &ep->queue, queue) {
- if (&req->req == _req)
+ if (&req->req == _req) {
+ req_done(ep, req, -ECONNRESET);
+ rc = 0;
break;
+ }
}
- rc = -EINVAL;
- if (&req->req != _req)
- goto out;
-
- rc = 0;
- req_done(ep, req, -ECONNRESET);
-out:
spin_unlock_irqrestore(&ep->lock, flags);
return rc;
}
@@ -1471,6 +1466,32 @@ static struct usb_ep_ops pxa_ep_ops = {
.fifo_flush = pxa_ep_fifo_flush,
};
+/**
+ * dplus_pullup - Connect or disconnect pullup resistor to D+ pin
+ * @udc: udc device
+ * @on: 0 if disconnect pullup resistor, 1 otherwise
+ * Context: any
+ *
+ * Handle D+ pullup resistor, make the device visible to the usb bus, and
+ * declare it as a full speed usb device
+ */
+static void dplus_pullup(struct pxa_udc *udc, int on)
+{
+ if (on) {
+ if (gpio_is_valid(udc->mach->gpio_pullup))
+ gpio_set_value(udc->mach->gpio_pullup,
+ !udc->mach->gpio_pullup_inverted);
+ if (udc->mach->udc_command)
+ udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
+ } else {
+ if (gpio_is_valid(udc->mach->gpio_pullup))
+ gpio_set_value(udc->mach->gpio_pullup,
+ udc->mach->gpio_pullup_inverted);
+ if (udc->mach->udc_command)
+ udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
+ }
+ udc->pullup_on = on;
+}
/**
* pxa_udc_get_frame - Returns usb frame number
@@ -1500,21 +1521,145 @@ static int pxa_udc_wakeup(struct usb_gadget *_gadget)
return 0;
}
+static void udc_enable(struct pxa_udc *udc);
+static void udc_disable(struct pxa_udc *udc);
+
+/**
+ * should_enable_udc - Tells if UDC should be enabled
+ * @udc: udc device
+ * Context: any
+ *
+ * The UDC should be enabled if :
+
+ * - the pullup resistor is connected
+ * - and a gadget driver is bound
+ * - and vbus is sensed (or no vbus sense is available)
+ *
+ * Returns 1 if UDC should be enabled, 0 otherwise
+ */
+static int should_enable_udc(struct pxa_udc *udc)
+{
+ int put_on;
+
+ put_on = ((udc->pullup_on) && (udc->driver));
+ put_on &= ((udc->vbus_sensed) || (!udc->transceiver));
+ return put_on;
+}
+
+/**
+ * should_disable_udc - Tells if UDC should be disabled
+ * @udc: udc device
+ * Context: any
+ *
+ * The UDC should be disabled if :
+ * - the pullup resistor is not connected
+ * - or no gadget driver is bound
+ * - or no vbus is sensed (when vbus sesing is available)
+ *
+ * Returns 1 if UDC should be disabled
+ */
+static int should_disable_udc(struct pxa_udc *udc)
+{
+ int put_off;
+
+ put_off = ((!udc->pullup_on) || (!udc->driver));
+ put_off |= ((!udc->vbus_sensed) && (udc->transceiver));
+ return put_off;
+}
+
+/**
+ * pxa_udc_pullup - Offer manual D+ pullup control
+ * @_gadget: usb gadget using the control
+ * @is_active: 0 if disconnect, else connect D+ pullup resistor
+ * Context: !in_interrupt()
+ *
+ * Returns 0 if OK, -EOPNOTSUPP if udc driver doesn't handle D+ pullup
+ */
+static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active)
+{
+ struct pxa_udc *udc = to_gadget_udc(_gadget);
+
+ if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command)
+ return -EOPNOTSUPP;
+
+ dplus_pullup(udc, is_active);
+
+ if (should_enable_udc(udc))
+ udc_enable(udc);
+ if (should_disable_udc(udc))
+ udc_disable(udc);
+ return 0;
+}
+
+static void udc_enable(struct pxa_udc *udc);
+static void udc_disable(struct pxa_udc *udc);
+
+/**
+ * pxa_udc_vbus_session - Called by external transceiver to enable/disable udc
+ * @_gadget: usb gadget
+ * @is_active: 0 if should disable the udc, 1 if should enable
+ *
+ * Enables the udc, and optionnaly activates D+ pullup resistor. Or disables the
+ * udc, and deactivates D+ pullup resistor.
+ *
+ * Returns 0
+ */
+static int pxa_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
+{
+ struct pxa_udc *udc = to_gadget_udc(_gadget);
+
+ udc->vbus_sensed = is_active;
+ if (should_enable_udc(udc))
+ udc_enable(udc);
+ if (should_disable_udc(udc))
+ udc_disable(udc);
+
+ return 0;
+}
+
+/**
+ * pxa_udc_vbus_draw - Called by gadget driver after SET_CONFIGURATION completed
+ * @_gadget: usb gadget
+ * @mA: current drawn
+ *
+ * Context: !in_interrupt()
+ *
+ * Called after a configuration was chosen by a USB host, to inform how much
+ * current can be drawn by the device from VBus line.
+ *
+ * Returns 0 or -EOPNOTSUPP if no transceiver is handling the udc
+ */
+static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
+{
+ struct pxa_udc *udc;
+
+ udc = to_gadget_udc(_gadget);
+ if (udc->transceiver)
+ return otg_set_power(udc->transceiver, mA);
+ return -EOPNOTSUPP;
+}
+
static const struct usb_gadget_ops pxa_udc_ops = {
.get_frame = pxa_udc_get_frame,
.wakeup = pxa_udc_wakeup,
- /* current versions must always be self-powered */
+ .pullup = pxa_udc_pullup,
+ .vbus_session = pxa_udc_vbus_session,
+ .vbus_draw = pxa_udc_vbus_draw,
};
/**
* udc_disable - disable udc device controller
* @udc: udc device
+ * Context: any
*
* Disables the udc device : disables clocks, udc interrupts, control endpoint
* interrupts.
*/
static void udc_disable(struct pxa_udc *udc)
{
+ if (!udc->enabled)
+ return;
+
udc_writel(udc, UDCICR0, 0);
udc_writel(udc, UDCICR1, 0);
@@ -1523,8 +1668,8 @@ static void udc_disable(struct pxa_udc *udc)
ep0_idle(udc);
udc->gadget.speed = USB_SPEED_UNKNOWN;
- if (udc->mach->udc_command)
- udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
+
+ udc->enabled = 0;
}
/**
@@ -1555,10 +1700,9 @@ static __init void udc_init_data(struct pxa_udc *dev)
}
/* USB endpoints init */
- for (i = 0; i < NR_USB_ENDPOINTS; i++)
- if (i != 0)
- list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list,
- &dev->gadget.ep_list);
+ for (i = 1; i < NR_USB_ENDPOINTS; i++)
+ list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list,
+ &dev->gadget.ep_list);
}
/**
@@ -1570,6 +1714,9 @@ static __init void udc_init_data(struct pxa_udc *dev)
*/
static void udc_enable(struct pxa_udc *udc)
{
+ if (udc->enabled)
+ return;
+
udc_writel(udc, UDCICR0, 0);
udc_writel(udc, UDCICR1, 0);
udc_clear_mask_UDCCR(udc, UDCCR_UDE);
@@ -1598,9 +1745,7 @@ static void udc_enable(struct pxa_udc *udc)
/* enable ep0 irqs */
pio_irq_enable(&udc->pxa_ep[0]);
- dev_info(udc->dev, "UDC connecting\n");
- if (udc->mach->udc_command)
- udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
+ udc->enabled = 1;
}
/**
@@ -1612,6 +1757,9 @@ static void udc_enable(struct pxa_udc *udc)
* usb traffic follows until a disconnect is reported. Then a host may connect
* again, or the driver might get unbound.
*
+ * Note that the udc is not automatically enabled. Check function
+ * should_enable_udc().
+ *
* Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise
*/
int usb_gadget_register_driver(struct usb_gadget_driver *driver)
@@ -1630,6 +1778,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
/* first hook up the driver ... */
udc->driver = driver;
udc->gadget.dev.driver = &driver->driver;
+ dplus_pullup(udc, 1);
retval = device_add(&udc->gadget.dev);
if (retval) {
@@ -1645,9 +1794,21 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
dev_dbg(udc->dev, "registered gadget driver '%s'\n",
driver->driver.name);
- udc_enable(udc);
+ if (udc->transceiver) {
+ retval = otg_set_peripheral(udc->transceiver, &udc->gadget);
+ if (retval) {
+ dev_err(udc->dev, "can't bind to transceiver\n");
+ goto transceiver_fail;
+ }
+ }
+
+ if (should_enable_udc(udc))
+ udc_enable(udc);
return 0;
+transceiver_fail:
+ if (driver->unbind)
+ driver->unbind(&udc->gadget);
bind_fail:
device_del(&udc->gadget.dev);
add_fail:
@@ -1699,14 +1860,17 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
stop_activity(udc, driver);
udc_disable(udc);
+ dplus_pullup(udc, 0);
driver->unbind(&udc->gadget);
udc->driver = NULL;
device_del(&udc->gadget.dev);
-
dev_info(udc->dev, "unregistered gadget driver '%s'\n",
driver->driver.name);
+
+ if (udc->transceiver)
+ return otg_set_peripheral(udc->transceiver, NULL);
return 0;
}
EXPORT_SYMBOL(usb_gadget_unregister_driver);
@@ -1823,14 +1987,14 @@ static void handle_ep0(struct pxa_udc *udc, int fifo_irq, int opc_irq)
struct pxa27x_request *req = NULL;
int completed = 0;
+ if (!list_empty(&ep->queue))
+ req = list_entry(ep->queue.next, struct pxa27x_request, queue);
+
udccsr0 = udc_ep_readl(ep, UDCCSR);
ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n",
EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR),
(fifo_irq << 1 | opc_irq));
- if (!list_empty(&ep->queue))
- req = list_entry(ep->queue.next, struct pxa27x_request, queue);
-
if (udccsr0 & UDCCSR0_SST) {
ep_dbg(ep, "clearing stall status\n");
nuke(ep, -EPIPE);
@@ -2212,7 +2376,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
{
struct resource *regs;
struct pxa_udc *udc = &memory;
- int retval;
+ int retval = 0, gpio;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs)
@@ -2223,6 +2387,20 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
udc->dev = &pdev->dev;
udc->mach = pdev->dev.platform_data;
+ udc->transceiver = otg_get_transceiver();
+
+ gpio = udc->mach->gpio_pullup;
+ if (gpio_is_valid(gpio)) {
+ retval = gpio_request(gpio, "USB D+ pullup");
+ if (retval == 0)
+ gpio_direction_output(gpio,
+ udc->mach->gpio_pullup_inverted);
+ }
+ if (retval) {
+ dev_err(&pdev->dev, "Couldn't request gpio %d : %d\n",
+ gpio, retval);
+ return retval;
+ }
udc->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(udc->clk)) {
@@ -2240,6 +2418,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
device_initialize(&udc->gadget.dev);
udc->gadget.dev.parent = &pdev->dev;
udc->gadget.dev.dma_mask = NULL;
+ udc->vbus_sensed = 0;
the_controller = udc;
platform_set_drvdata(pdev, udc);
@@ -2273,14 +2452,21 @@ err_clk:
static int __exit pxa_udc_remove(struct platform_device *_dev)
{
struct pxa_udc *udc = platform_get_drvdata(_dev);
+ int gpio = udc->mach->gpio_pullup;
usb_gadget_unregister_driver(udc->driver);
free_irq(udc->irq, udc);
pxa_cleanup_debugfs(udc);
+ if (gpio_is_valid(gpio))
+ gpio_free(gpio);
+
+ otg_put_transceiver(udc->transceiver);
+ udc->transceiver = NULL;
platform_set_drvdata(_dev, NULL);
the_controller = NULL;
clk_put(udc->clk);
+ iounmap(udc->regs);
return 0;
}
@@ -2319,6 +2505,8 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state)
}
udc_disable(udc);
+ udc->pullup_resume = udc->pullup_on;
+ dplus_pullup(udc, 0);
return 0;
}
@@ -2346,7 +2534,9 @@ static int pxa_udc_resume(struct platform_device *_dev)
ep->udccsr_value, ep->udccr_value);
}
- udc_enable(udc);
+ dplus_pullup(udc, udc->pullup_resume);
+ if (should_enable_udc(udc))
+ udc_enable(udc);
/*
* We do not handle OTG yet.
*
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h
index 1d1b7936ee1..db58125331d 100644
--- a/drivers/usb/gadget/pxa27x_udc.h
+++ b/drivers/usb/gadget/pxa27x_udc.h
@@ -26,6 +26,7 @@
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/io.h>
+#include <linux/usb/otg.h>
/*
* Register definitions
@@ -421,10 +422,14 @@ struct udc_stats {
* @driver: bound gadget (zero, g_ether, g_file_storage, ...)
* @dev: device
* @mach: machine info, used to activate specific GPIO
+ * @transceiver: external transceiver to handle vbus sense and D+ pullup
* @ep0state: control endpoint state machine state
* @stats: statistics on udc usage
* @udc_usb_ep: array of usb endpoints offered by the gadget
* @pxa_ep: array of pxa available endpoints
+ * @enabled: UDC was enabled by a previous udc_enable()
+ * @pullup_on: if pullup resistor connected to D+ pin
+ * @pullup_resume: if pullup resistor should be connected to D+ pin on resume
* @config: UDC active configuration
* @last_interface: UDC interface of the last SET_INTERFACE host request
* @last_alternate: UDC altsetting of the last SET_INTERFACE host request
@@ -443,6 +448,7 @@ struct pxa_udc {
struct usb_gadget_driver *driver;
struct device *dev;
struct pxa2xx_udc_mach_info *mach;
+ struct otg_transceiver *transceiver;
enum ep0_state ep0state;
struct udc_stats stats;
@@ -450,6 +456,10 @@ struct pxa_udc {
struct udc_usb_ep udc_usb_ep[NR_USB_ENDPOINTS];
struct pxa_ep pxa_ep[NR_PXA_ENDPOINTS];
+ unsigned enabled:1;
+ unsigned pullup_on:1;
+ unsigned pullup_resume:1;
+ unsigned vbus_sensed:1;
unsigned config:2;
unsigned last_interface:3;
unsigned last_alternate:3;
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 37879af1c43..f46a60962da 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -87,12 +87,12 @@ static struct usb_gadget_strings *dev_strings[] = {
static struct usb_device_descriptor device_desc = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
/* .bDeviceClass = f(use_acm) */
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
/* .bMaxPacketSize0 = f(hardware) */
- .idVendor = __constant_cpu_to_le16(GS_VENDOR_ID),
+ .idVendor = cpu_to_le16(GS_VENDOR_ID),
/* .idProduct = f(use_acm) */
/* .bcdDevice = f(hardware) */
/* .iManufacturer = DYNAMIC */
@@ -216,7 +216,7 @@ static int __init gs_bind(struct usb_composite_dev *cdev)
pr_warning("gs_bind: controller '%s' not recognized\n",
gadget->name);
device_desc.bcdDevice =
- __constant_cpu_to_le16(GS_VERSION_NUM | 0x0099);
+ cpu_to_le16(GS_VERSION_NUM | 0x0099);
}
if (gadget_is_otg(cdev->gadget)) {
@@ -255,19 +255,19 @@ static int __init init(void)
serial_config_driver.bConfigurationValue = 2;
device_desc.bDeviceClass = USB_CLASS_COMM;
device_desc.idProduct =
- __constant_cpu_to_le16(GS_CDC_PRODUCT_ID);
+ cpu_to_le16(GS_CDC_PRODUCT_ID);
} else if (use_obex) {
serial_config_driver.label = "CDC OBEX config";
serial_config_driver.bConfigurationValue = 3;
device_desc.bDeviceClass = USB_CLASS_COMM;
device_desc.idProduct =
- __constant_cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
+ cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
} else {
serial_config_driver.label = "Generic Serial config";
serial_config_driver.bConfigurationValue = 1;
device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
device_desc.idProduct =
- __constant_cpu_to_le16(GS_PRODUCT_ID);
+ cpu_to_le16(GS_PRODUCT_ID);
}
strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label;
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index 53d59287f2b..0a4d99ab40d 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -1092,7 +1092,7 @@ int __init gserial_setup(struct usb_gadget *g, unsigned count)
gs_tty_driver->init_termios.c_ispeed = 9600;
gs_tty_driver->init_termios.c_ospeed = 9600;
- coding.dwDTERate = __constant_cpu_to_le32(9600);
+ coding.dwDTERate = cpu_to_le32(9600);
coding.bCharFormat = 8;
coding.bParityType = USB_CDC_NO_PARITY;
coding.bDataBits = USB_CDC_1_STOP_BITS;
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 361d9659ac4..2d772401b7a 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -102,22 +102,32 @@ module_param(loopdefault, bool, S_IRUGO|S_IWUSR);
#ifndef CONFIG_USB_ZERO_HNPTEST
#define DRIVER_VENDOR_NUM 0x0525 /* NetChip */
#define DRIVER_PRODUCT_NUM 0xa4a0 /* Linux-USB "Gadget Zero" */
+#define DEFAULT_AUTORESUME 0
#else
#define DRIVER_VENDOR_NUM 0x1a0a /* OTG test device IDs */
#define DRIVER_PRODUCT_NUM 0xbadd
+#define DEFAULT_AUTORESUME 5
#endif
+/* If the optional "autoresume" mode is enabled, it provides good
+ * functional coverage for the "USBCV" test harness from USB-IF.
+ * It's always set if OTG mode is enabled.
+ */
+unsigned autoresume = DEFAULT_AUTORESUME;
+module_param(autoresume, uint, S_IRUGO);
+MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
+
/*-------------------------------------------------------------------------*/
static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
- .bcdUSB = __constant_cpu_to_le16(0x0200),
+ .bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_VENDOR_SPEC,
- .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM),
- .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM),
+ .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM),
+ .idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM),
.bNumConfigurations = 2,
};
@@ -212,6 +222,47 @@ void disable_endpoints(struct usb_composite_dev *cdev,
/*-------------------------------------------------------------------------*/
+static struct timer_list autoresume_timer;
+
+static void zero_autoresume(unsigned long _c)
+{
+ struct usb_composite_dev *cdev = (void *)_c;
+ struct usb_gadget *g = cdev->gadget;
+
+ /* unconfigured devices can't issue wakeups */
+ if (!cdev->config)
+ return;
+
+ /* Normally the host would be woken up for something
+ * more significant than just a timer firing; likely
+ * because of some direct user request.
+ */
+ if (g->speed != USB_SPEED_UNKNOWN) {
+ int status = usb_gadget_wakeup(g);
+ INFO(cdev, "%s --> %d\n", __func__, status);
+ }
+}
+
+static void zero_suspend(struct usb_composite_dev *cdev)
+{
+ if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
+ return;
+
+ if (autoresume) {
+ mod_timer(&autoresume_timer, jiffies + (HZ * autoresume));
+ DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
+ } else
+ DBG(cdev, "%s\n", __func__);
+}
+
+static void zero_resume(struct usb_composite_dev *cdev)
+{
+ DBG(cdev, "%s\n", __func__);
+ del_timer(&autoresume_timer);
+}
+
+/*-------------------------------------------------------------------------*/
+
static int __init zero_bind(struct usb_composite_dev *cdev)
{
int gcnum;
@@ -239,17 +290,19 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
strings_dev[STRING_SERIAL_IDX].id = id;
device_desc.iSerialNumber = id;
+ setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev);
+
/* Register primary, then secondary configuration. Note that
* SH3 only allows one config...
*/
if (loopdefault) {
- loopback_add(cdev);
+ loopback_add(cdev, autoresume != 0);
if (!gadget_is_sh(gadget))
- sourcesink_add(cdev);
+ sourcesink_add(cdev, autoresume != 0);
} else {
- sourcesink_add(cdev);
+ sourcesink_add(cdev, autoresume != 0);
if (!gadget_is_sh(gadget))
- loopback_add(cdev);
+ loopback_add(cdev, autoresume != 0);
}
gcnum = usb_gadget_controller_number(gadget);
@@ -265,7 +318,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
*/
pr_warning("%s: controller '%s' not recognized\n",
longname, gadget->name);
- device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
+ device_desc.bcdDevice = cpu_to_le16(0x9999);
}
@@ -278,11 +331,20 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
return 0;
}
+static int zero_unbind(struct usb_composite_dev *cdev)
+{
+ del_timer_sync(&autoresume_timer);
+ return 0;
+}
+
static struct usb_composite_driver zero_driver = {
.name = "zero",
.dev = &device_desc,
.strings = dev_strings,
.bind = zero_bind,
+ .unbind = zero_unbind,
+ .suspend = zero_suspend,
+ .resume = zero_resume,
};
MODULE_AUTHOR("David Brownell");