From 5a59bc544d00923ff715e2fe68ea537153f52dda Mon Sep 17 00:00:00 2001
From: Robert Jarzmik <rjarzmik@free.fr>
Date: Mon, 12 May 2008 10:47:56 -0700
Subject: [PATCH] USB: pxa27x_udc: minor fixes

Minor fixes to pxa27x udc driver :
 - don't clobber driver model bus_id field
 - wrong endianess fix (no functional change; cpu is little-endian)
 - double udc disable fix
 - resume/suspend fix (OTG hold bit)
 - make driver pxa27x dependant (check cpu at runtime)

Signed-off-by: Robert Jarzmik <rjarzmik@free.fr>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/usb/gadget/pxa27x_udc.c | 17 ++++++++---------
 drivers/usb/gadget/pxa27x_udc.h |  8 ++++++++
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 75eba202f737..499b7a23f351 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -1546,7 +1546,6 @@ static __init void udc_init_data(struct pxa_udc *dev)
 	INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);
 	dev->udc_usb_ep[0].pxa_ep = &dev->pxa_ep[0];
 	ep0_idle(dev);
-	strcpy(dev->dev->bus_id, "");
 
 	/* PXA endpoints init */
 	for (i = 0; i < NR_PXA_ENDPOINTS; i++) {
@@ -1746,13 +1745,10 @@ static void handle_ep0_ctrl_req(struct pxa_udc *udc,
 		ep_err(ep, "wrong to have extra bytes for setup : 0x%08x\n", i);
 	}
 
-	le16_to_cpus(&u.r.wValue);
-	le16_to_cpus(&u.r.wIndex);
-	le16_to_cpus(&u.r.wLength);
-
 	ep_dbg(ep, "SETUP %02x.%02x v%04x i%04x l%04x\n",
 		u.r.bRequestType, u.r.bRequest,
-		u.r.wValue, u.r.wIndex, u.r.wLength);
+		le16_to_cpu(u.r.wValue), le16_to_cpu(u.r.wIndex),
+		le16_to_cpu(u.r.wLength));
 	if (unlikely(have_extrabytes))
 		goto stall;
 
@@ -2296,7 +2292,8 @@ static void pxa_udc_shutdown(struct platform_device *_dev)
 {
 	struct pxa_udc *udc = platform_get_drvdata(_dev);
 
-	udc_disable(udc);
+	if (udc_readl(udc, UDCCR) & UDCCR_UDE)
+		udc_disable(udc);
 }
 
 #ifdef CONFIG_PM
@@ -2361,9 +2358,8 @@ static int pxa_udc_resume(struct platform_device *_dev)
 	 * Upon exit from sleep mode and before clearing OTGPH,
 	 * Software must configure the USB OTG pad, UDC, and UHC
 	 * to the state they were in before entering sleep mode.
-	 *
-	 * Should be : PSSR |= PSSR_OTGPH;
 	 */
+	PSSR |= PSSR_OTGPH;
 
 	return 0;
 }
@@ -2387,6 +2383,9 @@ static struct platform_driver udc_driver = {
 
 static int __init udc_init(void)
 {
+	if (!cpu_is_pxa27x())
+		return -ENODEV;
+
 	printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION);
 	return platform_driver_probe(&udc_driver, pxa_udc_probe);
 }
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h
index 1d1b7936ee11..97453db924ff 100644
--- a/drivers/usb/gadget/pxa27x_udc.h
+++ b/drivers/usb/gadget/pxa27x_udc.h
@@ -484,4 +484,12 @@ static inline struct pxa_udc *to_gadget_udc(struct usb_gadget *gadget)
 #define ep_warn(ep, fmt, arg...) \
 	dev_warn(ep->dev->dev, "%s:%s:" fmt, EPNAME(ep), __func__, ## arg)
 
+/*
+ * Cannot include pxa-regs.h, as register names are similar.
+ * So PSSR is redefined here. This should be removed once UDC registers will
+ * be gone from pxa-regs.h.
+ */
+#define PSSR		__REG(0x40F00004)	/* Power Manager Sleep Status */
+#define PSSR_OTGPH	(1 << 6)		/* OTG Peripheral Hold */
+
 #endif /* __LINUX_USB_GADGET_PXA27X_H */