All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <201103011807.01828.heiko@sntech.de>

diff --git a/a/1.txt b/N1/1.txt
index 4467c2a..2ca6cfc 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -22,3 +22,31 @@ Heiko
 [1] http://gitorious.org/oyo-hack/kernel/commits/s3c-hsudc
 [2] http://gitorious.org/oyo-
 hack/kernel/commit/c063317869d11c3b8f906061319f8a075de06b5c
+-------------- next part --------------
+A non-text attachment was scrubbed...
+Name: 0001-ARM-S3C2416-Add-USB-Phy-register-definitions.patch
+Type: text/x-patch
+Size: 2146 bytes
+Desc: not available
+URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110301/11ab6ee5/attachment-0004.bin>
+-------------- next part --------------
+A non-text attachment was scrubbed...
+Name: 0002-ARM-S3C24XX-Add-plaform-device-definition-for-USB-Hi.patch
+Type: text/x-patch
+Size: 4593 bytes
+Desc: not available
+URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110301/11ab6ee5/attachment-0005.bin>
+-------------- next part --------------
+A non-text attachment was scrubbed...
+Name: 0004-ARM-S3C2416-Add-support-for-USB-2.0-High-Speed-gadge.patch
+Type: text/x-patch
+Size: 2728 bytes
+Desc: not available
+URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110301/11ab6ee5/attachment-0006.bin>
+-------------- next part --------------
+A non-text attachment was scrubbed...
+Name: 0003-USB-Gadget-Add-Samsung-S3C24XX-USB-High-Speed-contro.patch
+Type: text/x-patch
+Size: 40485 bytes
+Desc: not available
+URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110301/11ab6ee5/attachment-0007.bin>
diff --git a/a/2.hdr b/a/2.hdr
deleted file mode 100644
index 4baf7b4..0000000
--- a/a/2.hdr
+++ /dev/null
@@ -1,6 +0,0 @@
-Content-Type: text/x-patch;
-  charset="UTF-8";
-  name="0001-ARM-S3C2416-Add-USB-Phy-register-definitions.patch"
-Content-Transfer-Encoding: quoted-printable
-Content-Disposition: attachment;
-	filename="0001-ARM-S3C2416-Add-USB-Phy-register-definitions.patch"
diff --git a/a/2.txt b/a/2.txt
deleted file mode 100644
index 9aefd6d..0000000
--- a/a/2.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-From 92a488ff6afa7d33ed04d476c4f1704899be9da1 Mon Sep 17 00:00:00 2001
-From: Thomas Abraham <thomas.ab@samsung.com>
-Date: Wed, 13 Oct 2010 09:10:24 +0900
-Subject: [PATCH 1/4] ARM: S3C2416: Add USB Phy register definitions
-
-Add register definitions required to configure the USB Phy. The definitions
-for PHYCTRL, PHYPWR, URSTCON and UCLKCON registers and corresponding bit
-field definitions are added.
-
-Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
-Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
----
- .../mach-s3c2410/include/mach/regs-s3c2443-clock.h |   25 ++++++++++++++++++++
- 1 files changed, 25 insertions(+), 0 deletions(-)
-
-diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
-index 44494a5..5e06c72 100644
---- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
-+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
-@@ -37,6 +37,10 @@
- #define S3C2443_SYSID			S3C2443_CLKREG(0x5C)
- #define S3C2443_PWRCFG			S3C2443_CLKREG(0x60)
- #define S3C2443_RSTCON			S3C2443_CLKREG(0x64)
-+#define S3C2443_PHYCTRL			S3C2443_CLKREG(0x80)
-+#define S3C2443_PHYPWR			S3C2443_CLKREG(0x84)
-+#define S3C2443_URSTCON			S3C2443_CLKREG(0x88)
-+#define S3C2443_UCLKCON			S3C2443_CLKREG(0x8C)
- 
- #define S3C2443_SWRST_RESET		(0x533c2443)
- 
-@@ -121,6 +125,27 @@
- 
- #define S3C2443_PWRCFG_SLEEP		(1<<15)
- 
-+#define S3C2443_PWRCFG_USBPHY		(1 << 4)
-+
-+#define S3C2443_URSTCON_FUNCRST		(1 << 2)
-+#define S3C2443_URSTCON_PHYRST		(1 << 0)
-+
-+#define S3C2443_PHYCTRL_CLKSEL		(1 << 3)
-+#define S3C2443_PHYCTRL_EXTCLK		(1 << 2)
-+#define S3C2443_PHYCTRL_PLLSEL		(1 << 1)
-+#define S3C2443_PHYCTRL_DSPORT		(1 << 0)
-+
-+#define S3C2443_PHYPWR_COMMON_ON	(1 << 31)
-+#define S3C2443_PHYPWR_ANALOG_PD	(1 << 4)
-+#define S3C2443_PHYPWR_PLL_REFCLK	(1 << 3)
-+#define S3C2443_PHYPWR_XO_ON		(1 << 2)
-+#define S3C2443_PHYPWR_PLL_PWRDN	(1 << 1)
-+#define S3C2443_PHYPWR_FSUSPEND		(1 << 0)
-+
-+#define S3C2443_UCLKCON_DETECT_VBUS	(1 << 31)
-+#define S3C2443_UCLKCON_FUNC_CLKEN	(1 << 2)
-+#define S3C2443_UCLKCON_TCLKEN		(1 << 0)
-+
- #include <asm/div64.h>
- 
- static inline unsigned int
--- 
-1.7.2.3
diff --git a/a/3.hdr b/a/3.hdr
deleted file mode 100644
index 321c83a..0000000
--- a/a/3.hdr
+++ /dev/null
@@ -1,6 +0,0 @@
-Content-Type: text/x-patch;
-  charset="UTF-8";
-  name="0002-ARM-S3C24XX-Add-plaform-device-definition-for-USB-Hi.patch"
-Content-Transfer-Encoding: quoted-printable
-Content-Disposition: attachment;
-	filename="0002-ARM-S3C24XX-Add-plaform-device-definition-for-USB-Hi.patch"
diff --git a/a/3.txt b/a/3.txt
deleted file mode 100644
index 6294353..0000000
--- a/a/3.txt
+++ /dev/null
@@ -1,136 +0,0 @@
-From 0e89d462593eeb69a168ed1712c3e27039c2af78 Mon Sep 17 00:00:00 2001
-From: Thomas Abraham <thomas.ab@samsung.com>
-Date: Wed, 13 Oct 2010 09:10:25 +0900
-Subject: [PATCH 2/4] ARM: S3C24XX: Add plaform device definition for USB High-Speed gadget controller.
-
-S3C2416, S3C2443 and S3C2450 includes a USB High-Speed Gadget controller module.
-This patch adds the following for supporting this controller.
-
-1. Definition for USB High-Speed controller base address.
-2. Platform device instantiation.
-3. Declaration for platform data structure.
-4. Functionality to setup platform data for the controller.
-
-Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
-Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
----
- arch/arm/mach-s3c2410/include/mach/map.h  |    4 +++
- arch/arm/plat-s3c24xx/devs.c              |   41 +++++++++++++++++++++++++++++
- arch/arm/plat-s3c24xx/include/plat/udc.h  |   17 ++++++++++++
- arch/arm/plat-samsung/include/plat/devs.h |    1 +
- 4 files changed, 63 insertions(+), 0 deletions(-)
-
-diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h
-index 25bbf5a..425552d 100644
---- a/arch/arm/mach-s3c2410/include/mach/map.h
-+++ b/arch/arm/mach-s3c2410/include/mach/map.h
-@@ -21,6 +21,10 @@
- /* USB host controller */
- #define S3C2410_PA_USBHOST (0x49000000)
- 
-+/* S3C2416/S3C2443/S3C2450 High-Speed USB Gadget */
-+#define S3C2416_PA_HSUDC	(0x49800000)
-+#define S3C2416_SZ_HSUDC	(SZ_4K)
-+
- /* DMA controller */
- #define S3C2410_PA_DMA	   (0x4B000000)
- #define S3C24XX_SZ_DMA	   SZ_1M
-diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
-index 268f3ed..7366799 100644
---- a/arch/arm/plat-s3c24xx/devs.c
-+++ b/arch/arm/plat-s3c24xx/devs.c
-@@ -22,6 +22,7 @@
- #include <linux/io.h>
- #include <linux/slab.h>
- #include <linux/string.h>
-+#include <linux/dma-mapping.h>
- 
- #include <asm/mach/arch.h>
- #include <asm/mach/map.h>
-@@ -233,6 +234,46 @@ void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
- 	}
- }
- 
-+/* USB High Speed 2.0 Device (Gadget) */
-+static struct resource s3c_hsudc_resource[] = {
-+	[0] = {
-+		.start	= S3C2416_PA_HSUDC,
-+		.end	= S3C2416_PA_HSUDC + S3C2416_SZ_HSUDC - 1,
-+		.flags	= IORESOURCE_MEM,
-+	},
-+	[1] = {
-+		.start	= IRQ_USBD,
-+		.end	= IRQ_USBD,
-+		.flags	= IORESOURCE_IRQ,
-+	}
-+};
-+
-+static u64 s3c_hsudc_dmamask = DMA_BIT_MASK(32);
-+
-+struct platform_device s3c_device_usb_hsudc = {
-+	.name		= "s3c-hsudc",
-+	.id		= -1,
-+	.num_resources	= ARRAY_SIZE(s3c_hsudc_resource),
-+	.resource	= s3c_hsudc_resource,
-+	.dev		= {
-+		.dma_mask		= &s3c_hsudc_dmamask,
-+		.coherent_dma_mask	= DMA_BIT_MASK(32),
-+	},
-+};
-+
-+void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd)
-+{
-+	struct s3c24xx_hsudc_platdata *npd;
-+
-+	npd = kmalloc(sizeof(*npd), GFP_KERNEL);
-+	if (npd) {
-+		memcpy(npd, pd, sizeof(*npd));
-+		s3c_device_usb_hsudc.dev.platform_data = npd;
-+	} else {
-+		printk(KERN_ERR "no memory for udc platform data\n");
-+	}
-+}
-+
- /* IIS */
- 
- static struct resource s3c_iis_resource[] = {
-diff --git a/arch/arm/plat-s3c24xx/include/plat/udc.h b/arch/arm/plat-s3c24xx/include/plat/udc.h
-index 546bb40..a3fc1be 100644
---- a/arch/arm/plat-s3c24xx/include/plat/udc.h
-+++ b/arch/arm/plat-s3c24xx/include/plat/udc.h
-@@ -33,4 +33,21 @@ struct s3c2410_udc_mach_info {
- 
- extern void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *);
- 
-+/**
-+ * s3c24xx_hsudc_platdata - Platform data for USB High-Speed gadget controller.
-+ * @epnum: Number of endpoints to be instantiated by the controller driver.
-+ * @gpio_init: Platform specific USB related GPIO initialization.
-+ * @gpio_uninit: Platform specific USB releted GPIO uninitialzation.
-+ *
-+ * Representation of platform data for the S3C24XX USB 2.0 High Speed gadget
-+ * controllers.
-+ */
-+struct s3c24xx_hsudc_platdata {
-+	unsigned int	epnum;
-+	void		(*gpio_init)(void);
-+	void		(*gpio_uninit)(void);
-+};
-+
-+extern void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd);
-+
- #endif /* __ASM_ARM_ARCH_UDC_H */
-diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
-index b4d208b..fcb6e30 100644
---- a/arch/arm/plat-samsung/include/plat/devs.h
-+++ b/arch/arm/plat-samsung/include/plat/devs.h
-@@ -85,6 +85,7 @@ extern struct platform_device s3c64xx_device_onenand1;
- extern struct platform_device s5p_device_onenand;
- 
- extern struct platform_device s3c_device_usbgadget;
-+extern struct platform_device s3c_device_usb_hsudc;
- extern struct platform_device s3c_device_usb_hsotg;
- 
- extern struct platform_device s5pv210_device_ac97;
--- 
-1.7.2.3
diff --git a/a/4.hdr b/a/4.hdr
deleted file mode 100644
index 93fa208..0000000
--- a/a/4.hdr
+++ /dev/null
@@ -1,6 +0,0 @@
-Content-Type: text/x-patch;
-  charset="UTF-8";
-  name="0004-ARM-S3C2416-Add-support-for-USB-2.0-High-Speed-gadge.patch"
-Content-Transfer-Encoding: quoted-printable
-Content-Disposition: attachment;
-	filename="0004-ARM-S3C2416-Add-support-for-USB-2.0-High-Speed-gadge.patch"
diff --git a/a/4.txt b/a/4.txt
deleted file mode 100644
index 5e8732e..0000000
--- a/a/4.txt
+++ /dev/null
@@ -1,89 +0,0 @@
-From 80eed2079d7aed5013e3d3c89e7b4b12f3ee6bd6 Mon Sep 17 00:00:00 2001
-From: Thomas Abraham <thomas.ab@samsung.com>
-Date: Wed, 13 Oct 2010 09:10:27 +0900
-Subject: [PATCH 4/4] ARM: S3C2416: Add support for USB 2.0 High-Speed gadget controller
-
-Add support for USB 2.0 High-Speed gadget controller driver for Samsung's
-S3C2416 processor.
-
-Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
-Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
----
- arch/arm/mach-s3c2416/mach-smdk2416.c |   27 +++++++++++++++++++++++++++
- 1 files changed, 27 insertions(+), 0 deletions(-)
-
-diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c
-index 3f83177..ac27ebb 100644
---- a/arch/arm/mach-s3c2416/mach-smdk2416.c
-+++ b/arch/arm/mach-s3c2416/mach-smdk2416.c
-@@ -23,6 +23,7 @@
- #include <linux/mtd/partitions.h>
- #include <linux/gpio.h>
- #include <linux/fb.h>
-+#include <linux/delay.h>
- 
- #include <asm/mach/arch.h>
- #include <asm/mach/map.h>
-@@ -35,6 +36,7 @@
- #include <plat/regs-serial.h>
- #include <mach/regs-gpio.h>
- #include <mach/regs-lcd.h>
-+#include <mach/regs-s3c2443-clock.h>
- 
- #include <mach/idle.h>
- #include <mach/leds-gpio.h>
-@@ -47,6 +49,7 @@
- #include <plat/cpu.h>
- #include <plat/nand.h>
- #include <plat/sdhci.h>
-+#include <plat/udc.h>
- 
- #include <plat/regs-fb-v4.h>
- #include <plat/fb.h>
-@@ -121,6 +124,27 @@ static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = {
- 	}
- };
- 
-+void smdk2416_hsudc_gpio_init(void)
-+{
-+	s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_UP);
-+	s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_NONE);
-+	s3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(1));
-+	s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 0);
-+}
-+
-+void smdk2416_hsudc_gpio_uninit(void)
-+{
-+	s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 1);
-+	s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_NONE);
-+	s3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(0));
-+}
-+
-+struct s3c24xx_hsudc_platdata smdk2416_hsudc_platdata = {
-+	.epnum = 9,
-+	.gpio_init = smdk2416_hsudc_gpio_init,
-+	.gpio_uninit = smdk2416_hsudc_gpio_uninit,
-+};
-+
- struct s3c_fb_pd_win smdk2416_fb_win[] = {
- 	[0] = {
- 		/* think this is the same as the smdk6410 */
-@@ -186,6 +210,7 @@ static struct platform_device *smdk2416_devices[] __initdata = {
- 	&s3c_device_i2c0,
- 	&s3c_device_hsmmc0,
- 	&s3c_device_hsmmc1,
-+	&s3c_device_usb_hsudc,
- };
- 
- static void __init smdk2416_map_io(void)
-@@ -203,6 +228,8 @@ static void __init smdk2416_machine_init(void)
- 	s3c_sdhci0_set_platdata(&smdk2416_hsmmc0_pdata);
- 	s3c_sdhci1_set_platdata(&smdk2416_hsmmc1_pdata);
- 
-+	s3c24xx_hsudc_set_platdata(&smdk2416_hsudc_platdata);
-+
- 	gpio_request(S3C2410_GPB(4), "USBHost Power");
- 	gpio_direction_output(S3C2410_GPB(4), 1);
- 
--- 
-1.7.2.3
diff --git a/a/5.hdr b/a/5.hdr
deleted file mode 100644
index a31d599..0000000
--- a/a/5.hdr
+++ /dev/null
@@ -1,6 +0,0 @@
-Content-Type: text/x-patch;
-  charset="UTF-8";
-  name="0003-USB-Gadget-Add-Samsung-S3C24XX-USB-High-Speed-contro.patch"
-Content-Transfer-Encoding: quoted-printable
-Content-Disposition: attachment;
-	filename="0003-USB-Gadget-Add-Samsung-S3C24XX-USB-High-Speed-contro.patch"
diff --git a/a/5.txt b/a/5.txt
deleted file mode 100644
index 315840a..0000000
--- a/a/5.txt
+++ /dev/null
@@ -1,1424 +0,0 @@
-From c063317869d11c3b8f906061319f8a075de06b5c Mon Sep 17 00:00:00 2001
-From: Thomas Abraham <thomas.ab@samsung.com>
-Date: Sat, 23 Oct 2010 07:51:55 +0900
-Subject: [PATCH 3/4] USB: Gadget: Add Samsung S3C24XX USB High-Speed controller driver
-
-The Samsung's S3C2416, S3C2443 and S3C2450 includes a USB High-Speed
-device controller module. This driver enables support for USB high-speed
-gadget functionality for the Samsung S3C24xx SoC's that include this
-controller.
-
-Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
-Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
-Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
----
- drivers/usb/gadget/Kconfig        |   17 +
- drivers/usb/gadget/Makefile       |    1 +
- drivers/usb/gadget/gadget_chips.h |    8 +
- drivers/usb/gadget/s3c-hsudc.c    | 1329 +++++++++++++++++++++++++++++++++++++
- 4 files changed, 1355 insertions(+), 0 deletions(-)
- create mode 100644 drivers/usb/gadget/s3c-hsudc.c
-
-diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
-index d500996..d836756 100644
---- a/drivers/usb/gadget/Kconfig
-+++ b/drivers/usb/gadget/Kconfig
-@@ -338,6 +338,23 @@ config USB_S3C2410_DEBUG
- 	boolean "S3C2410 udc debug messages"
- 	depends on USB_GADGET_S3C2410
- 
-+config USB_GADGET_S3C_HSUDC
-+	boolean "S3C2416, S3C2443 and S3C2450 USB Device Controller"
-+	depends on ARCH_S3C2410
-+	select USB_GADGET_DUALSPEED
-+	help
-+	  Samsung's S3C2416, S3C2443 and S3C2450 is an ARM9 based SoC
-+	  integrated with dual speed USB 2.0 device controller. It has
-+	  8 endpoints, as well as endpoint zero.
-+
-+	  This driver has been tested on S3C2416 and S3C2450 processors.
-+
-+config USB_S3C_HSUDC
-+	tristate
-+	depends on USB_GADGET_S3C_HSUDC
-+	default USB_GADGET
-+	select USB_GADGET_SELECTED
-+
- config USB_GADGET_PXA_U2O
- 	boolean "PXA9xx Processor USB2.0 controller"
- 	select USB_GADGET_DUALSPEED
-diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
-index 55f5e8a..540783c 100644
---- a/drivers/usb/gadget/Makefile
-+++ b/drivers/usb/gadget/Makefile
-@@ -23,6 +23,7 @@ obj-$(CONFIG_USB_R8A66597)	+= r8a66597-udc.o
- obj-$(CONFIG_USB_FSL_QE)	+= fsl_qe_udc.o
- obj-$(CONFIG_USB_CI13XXX_PCI)	+= ci13xxx_pci.o
- obj-$(CONFIG_USB_S3C_HSOTG)	+= s3c-hsotg.o
-+obj-$(CONFIG_USB_S3C_HSUDC)	+= s3c-hsudc.o
- obj-$(CONFIG_USB_LANGWELL)	+= langwell_udc.o
- obj-$(CONFIG_USB_EG20T)		+= pch_udc.o
- obj-$(CONFIG_USB_PXA_U2O)	+= mv_udc.o
-diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
-index 5c2720d..836a08e 100644
---- a/drivers/usb/gadget/gadget_chips.h
-+++ b/drivers/usb/gadget/gadget_chips.h
-@@ -142,6 +142,12 @@
- #define gadget_is_s3c_hsotg(g)    0
- #endif
- 
-+#ifdef CONFIG_USB_S3C_HSUDC
-+#define gadget_is_s3c_hsudc(g) (!strcmp("s3c-hsudc", (g)->name))
-+#else
-+#define gadget_is_s3c_hsudc(g) 0
-+#endif
-+
- #ifdef CONFIG_USB_GADGET_EG20T
- #define	gadget_is_pch(g)	(!strcmp("pch_udc", (g)->name))
- #else
-@@ -215,6 +221,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
- 		return 0x27;
- 	else if (gadget_is_ci13xxx_msm(gadget))
- 		return 0x28;
-+	else if (gadget_is_s3c_hsudc(gadget))
-+		return 0x29;
- 	return -ENOENT;
- }
- 
-diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c
-new file mode 100644
-index 0000000..b98d8a1
---- /dev/null
-+++ b/drivers/usb/gadget/s3c-hsudc.c
-@@ -0,0 +1,1329 @@
-+/* linux/drivers/usb/gadget/s3c-hsudc.c
-+ *
-+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
-+ *		http://www.samsung.com/
-+ *
-+ * S3C24XX USB 2.0 High-speed USB controller gadget driver
-+ *
-+ * The S3C24XX USB 2.0 high-speed USB controller supports upto 9 endpoints.
-+ * Each endpoint can be configured as either in or out endpoint. Endpoints
-+ * can be configured for Bulk or Interrupt transfer mode.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+*/
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/spinlock.h>
-+#include <linux/interrupt.h>
-+#include <linux/platform_device.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/delay.h>
-+#include <linux/io.h>
-+#include <linux/slab.h>
-+#include <linux/clk.h>
-+#include <linux/usb/ch9.h>
-+#include <linux/usb/gadget.h>
-+
-+#include <mach/regs-s3c2443-clock.h>
-+#include <plat/udc.h>
-+
-+#define S3C_HSUDC_REG(x)	(x)
-+
-+/* Non-Indexed Registers */
-+#define S3C_IR				S3C_HSUDC_REG(0x00) /* Index Register */
-+#define S3C_EIR				S3C_HSUDC_REG(0x04) /* EP Intr Status */
-+#define S3C_EIR_EP0			(1<<0)
-+#define S3C_EIER			S3C_HSUDC_REG(0x08) /* EP Intr Enable */
-+#define S3C_FAR				S3C_HSUDC_REG(0x0c) /* Gadget Address */
-+#define S3C_FNR				S3C_HSUDC_REG(0x10) /* Frame Number */
-+#define S3C_EDR				S3C_HSUDC_REG(0x14) /* EP Direction */
-+#define S3C_TR				S3C_HSUDC_REG(0x18) /* Test Register */
-+#define S3C_SSR				S3C_HSUDC_REG(0x1c) /* System Status */
-+#define S3C_SSR_DTZIEN_EN		(0xff8f)
-+#define S3C_SSR_ERR			(0xff80)
-+#define S3C_SSR_VBUSON			(1 << 8)
-+#define S3C_SSR_HSP			(1 << 4)
-+#define S3C_SSR_SDE			(1 << 3)
-+#define S3C_SSR_RESUME			(1 << 2)
-+#define S3C_SSR_SUSPEND			(1 << 1)
-+#define S3C_SSR_RESET			(1 << 0)
-+#define S3C_SCR				S3C_HSUDC_REG(0x20) /* System Control */
-+#define S3C_SCR_DTZIEN_EN		(1 << 14)
-+#define S3C_SCR_RRD_EN			(1 << 5)
-+#define S3C_SCR_SUS_EN			(1 << 1)
-+#define S3C_SCR_RST_EN			(1 << 0)
-+#define S3C_EP0SR			S3C_HSUDC_REG(0x24) /* EP0 Status */
-+#define S3C_EP0SR_EP0_LWO		(1 << 6)
-+#define S3C_EP0SR_STALL			(1 << 4)
-+#define S3C_EP0SR_TX_SUCCESS		(1 << 1)
-+#define S3C_EP0SR_RX_SUCCESS		(1 << 0)
-+#define S3C_EP0CR			S3C_HSUDC_REG(0x28) /* EP0 Control */
-+#define S3C_BR(_x)			S3C_HSUDC_REG(0x60 + (_x * 4))
-+
-+/* Indexed Registers */
-+#define S3C_ESR				S3C_HSUDC_REG(0x2c) /* EPn Status */
-+#define S3C_ESR_FLUSH			(1 << 6)
-+#define S3C_ESR_STALL			(1 << 5)
-+#define S3C_ESR_LWO			(1 << 4)
-+#define S3C_ESR_PSIF_ONE		(1 << 2)
-+#define S3C_ESR_PSIF_TWO		(2 << 2)
-+#define S3C_ESR_TX_SUCCESS		(1 << 1)
-+#define S3C_ESR_RX_SUCCESS		(1 << 0)
-+#define S3C_ECR				S3C_HSUDC_REG(0x30) /* EPn Control */
-+#define S3C_ECR_DUEN			(1 << 7)
-+#define S3C_ECR_FLUSH			(1 << 6)
-+#define S3C_ECR_STALL			(1 << 1)
-+#define S3C_ECR_IEMS			(1 << 0)
-+#define S3C_BRCR			S3C_HSUDC_REG(0x34) /* Read Count */
-+#define S3C_BWCR			S3C_HSUDC_REG(0x38) /* Write Count */
-+#define S3C_MPR				S3C_HSUDC_REG(0x3c) /* Max Pkt Size */
-+
-+#define WAIT_FOR_SETUP			(0)
-+#define DATA_STATE_XMIT			(1)
-+#define DATA_STATE_RECV			(2)
-+
-+/**
-+ * struct s3c_hsudc_ep - Endpoint representation used by driver.
-+ * @ep: USB gadget layer representation of device endpoint.
-+ * @name: Endpoint name (as required by ep autoconfiguration).
-+ * @dev: Reference to the device controller to which this EP belongs.
-+ * @desc: Endpoint descriptor obtained from the gadget driver.
-+ * @queue: Transfer request queue for the endpoint.
-+ * @stopped: Maintains state of endpoint, set if EP is halted.
-+ * @bEndpointAddress: EP address (including direction bit).
-+ * @fifo: Base address of EP FIFO.
-+ */
-+struct s3c_hsudc_ep {
-+	struct usb_ep ep;
-+	char name[20];
-+	struct s3c_hsudc *dev;
-+	const struct usb_endpoint_descriptor *desc;
-+	struct list_head queue;
-+	u8 stopped;
-+	u8 bEndpointAddress;
-+	void __iomem *fifo;
-+};
-+
-+/**
-+ * struct s3c_hsudc_req - Driver encapsulation of USB gadget transfer request.
-+ * @req: Reference to USB gadget transfer request.
-+ * @queue: Used for inserting this request to the endpoint request queue.
-+ */
-+struct s3c_hsudc_req {
-+	struct usb_request req;
-+	struct list_head queue;
-+};
-+
-+/**
-+ * struct s3c_hsudc - Driver's abstraction of the device controller.
-+ * @gadget: Instance of usb_gadget which is referenced by gadget driver.
-+ * @driver: Reference to currenty active gadget driver.
-+ * @dev: The device reference used by probe function.
-+ * @lock: Lock to synchronize the usage of Endpoints (EP's are indexed).
-+ * @regs: Remapped base address of controller's register space.
-+ * @mem_rsrc: Device memory resource used for remapping device register space.
-+ * irq: IRQ number used by the controller.
-+ * uclk: Reference to the controller clock.
-+ * ep0state: Current state of EP0.
-+ * ep: List of endpoints supported by the controller.
-+ */
-+struct s3c_hsudc {
-+	struct usb_gadget gadget;
-+	struct usb_gadget_driver *driver;
-+	struct device *dev;
-+	struct s3c24xx_hsudc_platdata *pd;
-+	spinlock_t lock;
-+	void __iomem *regs;
-+	struct resource *mem_rsrc;
-+	int irq;
-+	struct clk *uclk;
-+	int ep0state;
-+	struct s3c_hsudc_ep ep[];
-+};
-+
-+#define ep_maxpacket(_ep)	((_ep)->ep.maxpacket)
-+#define ep_is_in(_ep)		((_ep)->bEndpointAddress & USB_DIR_IN)
-+#define ep_index(_ep)		((_ep)->bEndpointAddress & \
-+					USB_ENDPOINT_NUMBER_MASK)
-+
-+static struct s3c_hsudc *the_controller;
-+static const char driver_name[] = "s3c-udc";
-+static const char ep0name[] = "ep0-control";
-+
-+static inline struct s3c_hsudc_req *our_req(struct usb_request *req)
-+{
-+	return container_of(req, struct s3c_hsudc_req, req);
-+}
-+
-+static inline struct s3c_hsudc_ep *our_ep(struct usb_ep *ep)
-+{
-+	return container_of(ep, struct s3c_hsudc_ep, ep);
-+}
-+
-+static inline struct s3c_hsudc *to_hsudc(struct usb_gadget *gadget)
-+{
-+	return container_of(gadget, struct s3c_hsudc, gadget);
-+}
-+
-+static inline void set_index(struct s3c_hsudc *hsudc, int ep_addr)
-+{
-+	ep_addr &= USB_ENDPOINT_NUMBER_MASK;
-+	writel(ep_addr, hsudc->regs + S3C_IR);
-+}
-+
-+static inline void __orr32(void __iomem *ptr, u32 val)
-+{
-+	writel(readl(ptr) | val, ptr);
-+}
-+
-+static void s3c_hsudc_init_phy(void)
-+{
-+	u32 cfg;
-+
-+	cfg = readl(S3C2443_PWRCFG) | S3C2443_PWRCFG_USBPHY;
-+	writel(cfg, S3C2443_PWRCFG);
-+
-+	cfg = readl(S3C2443_URSTCON);
-+	cfg |= (S3C2443_URSTCON_FUNCRST | S3C2443_URSTCON_PHYRST);
-+	writel(cfg, S3C2443_URSTCON);
-+	mdelay(1);
-+
-+	cfg = readl(S3C2443_URSTCON);
-+	cfg &= ~(S3C2443_URSTCON_FUNCRST | S3C2443_URSTCON_PHYRST);
-+	writel(cfg, S3C2443_URSTCON);
-+
-+	cfg = readl(S3C2443_PHYCTRL);
-+	cfg &= ~(S3C2443_PHYCTRL_CLKSEL | S3C2443_PHYCTRL_DSPORT);
-+	cfg |= (S3C2443_PHYCTRL_EXTCLK | S3C2443_PHYCTRL_PLLSEL);
-+	writel(cfg, S3C2443_PHYCTRL);
-+
-+	cfg = readl(S3C2443_PHYPWR);
-+	cfg &= ~(S3C2443_PHYPWR_FSUSPEND | S3C2443_PHYPWR_PLL_PWRDN |
-+		S3C2443_PHYPWR_XO_ON | S3C2443_PHYPWR_PLL_REFCLK |
-+		S3C2443_PHYPWR_ANALOG_PD);
-+	cfg |= S3C2443_PHYPWR_COMMON_ON;
-+	writel(cfg, S3C2443_PHYPWR);
-+
-+	cfg = readl(S3C2443_UCLKCON);
-+	cfg |= (S3C2443_UCLKCON_DETECT_VBUS | S3C2443_UCLKCON_FUNC_CLKEN |
-+		S3C2443_UCLKCON_TCLKEN);
-+	writel(cfg, S3C2443_UCLKCON);
-+}
-+
-+static void s3c_hsudc_uninit_phy(void)
-+{
-+	u32 cfg;
-+
-+	cfg = readl(S3C2443_PWRCFG) & ~S3C2443_PWRCFG_USBPHY;
-+	writel(cfg, S3C2443_PWRCFG);
-+
-+	writel(S3C2443_PHYPWR_FSUSPEND, S3C2443_PHYPWR);
-+
-+	cfg = readl(S3C2443_UCLKCON) & ~S3C2443_UCLKCON_FUNC_CLKEN;
-+	writel(cfg, S3C2443_UCLKCON);
-+}
-+
-+/**
-+ * s3c_hsudc_complete_request - Complete a transfer request.
-+ * @hsep: Endpoint to which the request belongs.
-+ * @hsreq: Transfer request to be completed.
-+ * @status: Transfer completion status for the transfer request.
-+ */
-+static void s3c_hsudc_complete_request(struct s3c_hsudc_ep *hsep,
-+				struct s3c_hsudc_req *hsreq, int status)
-+{
-+	unsigned int stopped = hsep->stopped;
-+	struct s3c_hsudc *hsudc = hsep->dev;
-+
-+	list_del_init(&hsreq->queue);
-+	hsreq->req.status = status;
-+
-+	if (!ep_index(hsep)) {
-+		hsudc->ep0state = WAIT_FOR_SETUP;
-+		hsep->bEndpointAddress &= ~USB_DIR_IN;
-+	}
-+
-+	hsep->stopped = 1;
-+	spin_unlock(&hsudc->lock);
-+	if (hsreq->req.complete != NULL)
-+		hsreq->req.complete(&hsep->ep, &hsreq->req);
-+	spin_lock(&hsudc->lock);
-+	hsep->stopped = stopped;
-+}
-+
-+/**
-+ * s3c_hsudc_nuke_ep - Terminate all requests queued for a endpoint.
-+ * @hsep: Endpoint for which queued requests have to be terminated.
-+ * @status: Transfer completion status for the transfer request.
-+ */
-+static void s3c_hsudc_nuke_ep(struct s3c_hsudc_ep *hsep, int status)
-+{
-+	struct s3c_hsudc_req *hsreq;
-+
-+	while (!list_empty(&hsep->queue)) {
-+		hsreq = list_entry(hsep->queue.next,
-+				struct s3c_hsudc_req, queue);
-+		s3c_hsudc_complete_request(hsep, hsreq, status);
-+	}
-+}
-+
-+/**
-+ * s3c_hsudc_stop_activity - Stop activity on all endpoints.
-+ * @hsudc: Device controller for which EP activity is to be stopped.
-+ * @driver: Reference to the gadget driver which is currently active.
-+ *
-+ * All the endpoints are stopped and any pending transfer requests if any on
-+ * the endpoint are terminated.
-+ */
-+static void s3c_hsudc_stop_activity(struct s3c_hsudc *hsudc,
-+			  struct usb_gadget_driver *driver)
-+{
-+	struct s3c_hsudc_ep *hsep;
-+	int epnum;
-+
-+	hsudc->gadget.speed = USB_SPEED_UNKNOWN;
-+
-+	for (epnum = 0; epnum < hsudc->pd->epnum; epnum++) {
-+		hsep = &hsudc->ep[epnum];
-+		hsep->stopped = 1;
-+		s3c_hsudc_nuke_ep(hsep, -ESHUTDOWN);
-+	}
-+
-+	spin_unlock(&hsudc->lock);
-+	driver->disconnect(&hsudc->gadget);
-+	spin_lock(&hsudc->lock);
-+}
-+
-+/**
-+ * s3c_hsudc_read_setup_pkt - Read the received setup packet from EP0 fifo.
-+ * @hsudc: Device controller from which setup packet is to be read.
-+ * @buf: The buffer into which the setup packet is read.
-+ *
-+ * The setup packet received in the EP0 fifo is read and stored into a
-+ * given buffer address.
-+ */
-+
-+static void s3c_hsudc_read_setup_pkt(struct s3c_hsudc *hsudc, u16 *buf)
-+{
-+	int count;
-+
-+	count = readl(hsudc->regs + S3C_BRCR);
-+	while (count--)
-+		*buf++ = (u16)readl(hsudc->regs + S3C_BR(0));
-+
-+	writel(S3C_EP0SR_RX_SUCCESS, hsudc->regs + S3C_EP0SR);
-+}
-+
-+/**
-+ * s3c_hsudc_write_fifo - Write next chunk of transfer data to EP fifo.
-+ * @hsep: Endpoint to which the data is to be written.
-+ * @hsreq: Transfer request from which the next chunk of data is written.
-+ *
-+ * Write the next chunk of data from a transfer request to the endpoint FIFO.
-+ * If the transfer request completes, 1 is returned, otherwise 0 is returned.
-+ */
-+static int s3c_hsudc_write_fifo(struct s3c_hsudc_ep *hsep,
-+				struct s3c_hsudc_req *hsreq)
-+{
-+	u16 *buf;
-+	u32 max = ep_maxpacket(hsep);
-+	u32 count, length;
-+	bool is_last;
-+	void __iomem *fifo = hsep->fifo;
-+
-+	buf = hsreq->req.buf + hsreq->req.actual;
-+	prefetch(buf);
-+
-+	length = hsreq->req.length - hsreq->req.actual;
-+	length = min(length, max);
-+	hsreq->req.actual += length;
-+
-+	writel(length, hsep->dev->regs + S3C_BWCR);
-+	for (count = 0; count < length; count += 2)
-+		writel(*buf++, fifo);
-+
-+	if (count != max) {
-+		is_last = true;
-+	} else {
-+		if (hsreq->req.length != hsreq->req.actual || hsreq->req.zero)
-+			is_last = false;
-+		else
-+			is_last = true;
-+	}
-+
-+	if (is_last) {
-+		s3c_hsudc_complete_request(hsep, hsreq, 0);
-+		return 1;
-+	}
-+
-+	return 0;
-+}
-+
-+/**
-+ * s3c_hsudc_read_fifo - Read the next chunk of data from EP fifo.
-+ * @hsep: Endpoint from which the data is to be read.
-+ * @hsreq: Transfer request to which the next chunk of data read is written.
-+ *
-+ * Read the next chunk of data from the endpoint FIFO and a write it to the
-+ * transfer request buffer. If the transfer request completes, 1 is returned,
-+ * otherwise 0 is returned.
-+ */
-+static int s3c_hsudc_read_fifo(struct s3c_hsudc_ep *hsep,
-+				struct s3c_hsudc_req *hsreq)
-+{
-+	struct s3c_hsudc *hsudc = hsep->dev;
-+	u32 csr, offset;
-+	u16 *buf, word;
-+	u32 buflen, rcnt, rlen;
-+	void __iomem *fifo = hsep->fifo;
-+	u32 is_short = 0;
-+
-+	offset = (ep_index(hsep)) ? S3C_ESR : S3C_EP0SR;
-+	csr = readl(hsudc->regs + offset);
-+	if (!(csr & S3C_ESR_RX_SUCCESS))
-+		return -EINVAL;
-+
-+	buf = hsreq->req.buf + hsreq->req.actual;
-+	prefetchw(buf);
-+	buflen = hsreq->req.length - hsreq->req.actual;
-+
-+	rcnt = readl(hsudc->regs + S3C_BRCR);
-+	rlen = (csr & S3C_ESR_LWO) ? (rcnt * 2 - 1) : (rcnt * 2);
-+
-+	hsreq->req.actual += min(rlen, buflen);
-+	is_short = (rlen < hsep->ep.maxpacket);
-+
-+	while (rcnt-- != 0) {
-+		word = (u16)readl(fifo);
-+		if (buflen) {
-+			*buf++ = word;
-+			buflen--;
-+		} else {
-+			hsreq->req.status = -EOVERFLOW;
-+		}
-+	}
-+
-+	writel(S3C_ESR_RX_SUCCESS, hsudc->regs + offset);
-+
-+	if (is_short || hsreq->req.actual == hsreq->req.length) {
-+		s3c_hsudc_complete_request(hsep, hsreq, 0);
-+		return 1;
-+	}
-+
-+	return 0;
-+}
-+
-+/**
-+ * s3c_hsudc_epin_intr - Handle in-endpoint interrupt.
-+ * @hsudc - Device controller for which the interrupt is to be handled.
-+ * @ep_idx - Endpoint number on which an interrupt is pending.
-+ *
-+ * Handles interrupt for a in-endpoint. The interrupts that are handled are
-+ * stall and data transmit complete interrupt.
-+ */
-+static void s3c_hsudc_epin_intr(struct s3c_hsudc *hsudc, u32 ep_idx)
-+{
-+	struct s3c_hsudc_ep *hsep = &hsudc->ep[ep_idx];
-+	struct s3c_hsudc_req *hsreq;
-+	u32 csr;
-+
-+	csr = readl((u32)hsudc->regs + S3C_ESR);
-+	if (csr & S3C_ESR_STALL) {
-+		writel(S3C_ESR_STALL, hsudc->regs + S3C_ESR);
-+		return;
-+	}
-+
-+	if (csr & S3C_ESR_TX_SUCCESS) {
-+		writel(S3C_ESR_TX_SUCCESS, hsudc->regs + S3C_ESR);
-+		if (list_empty(&hsep->queue))
-+			return;
-+
-+		hsreq = list_entry(hsep->queue.next,
-+				struct s3c_hsudc_req, queue);
-+		if ((s3c_hsudc_write_fifo(hsep, hsreq) == 0) &&
-+				(csr & S3C_ESR_PSIF_TWO))
-+			s3c_hsudc_write_fifo(hsep, hsreq);
-+	}
-+}
-+
-+/**
-+ * s3c_hsudc_epout_intr - Handle out-endpoint interrupt.
-+ * @hsudc - Device controller for which the interrupt is to be handled.
-+ * @ep_idx - Endpoint number on which an interrupt is pending.
-+ *
-+ * Handles interrupt for a out-endpoint. The interrupts that are handled are
-+ * stall, flush and data ready interrupt.
-+ */
-+static void s3c_hsudc_epout_intr(struct s3c_hsudc *hsudc, u32 ep_idx)
-+{
-+	struct s3c_hsudc_ep *hsep = &hsudc->ep[ep_idx];
-+	struct s3c_hsudc_req *hsreq;
-+	u32 csr;
-+
-+	csr = readl((u32)hsudc->regs + S3C_ESR);
-+	if (csr & S3C_ESR_STALL) {
-+		writel(S3C_ESR_STALL, hsudc->regs + S3C_ESR);
-+		return;
-+	}
-+
-+	if (csr & S3C_ESR_FLUSH) {
-+		__orr32(hsudc->regs + S3C_ECR, S3C_ECR_FLUSH);
-+		return;
-+	}
-+
-+	if (csr & S3C_ESR_RX_SUCCESS) {
-+		if (list_empty(&hsep->queue))
-+			return;
-+
-+		hsreq = list_entry(hsep->queue.next,
-+				struct s3c_hsudc_req, queue);
-+		if (((s3c_hsudc_read_fifo(hsep, hsreq)) == 0) &&
-+				(csr & S3C_ESR_PSIF_TWO))
-+			s3c_hsudc_read_fifo(hsep, hsreq);
-+	}
-+}
-+
-+/** s3c_hsudc_set_halt - Set or clear a endpoint halt.
-+ * @_ep: Endpoint on which halt has to be set or cleared.
-+ * @value: 1 for setting halt on endpoint, 0 to clear halt.
-+ *
-+ * Set or clear endpoint halt. If halt is set, the endpoint is stopped.
-+ * If halt is cleared, for in-endpoints, if there are any pending
-+ * transfer requests, transfers are started.
-+ */
-+static int s3c_hsudc_set_halt(struct usb_ep *_ep, int value)
-+{
-+	struct s3c_hsudc_ep *hsep = our_ep(_ep);
-+	struct s3c_hsudc *hsudc = hsep->dev;
-+	struct s3c_hsudc_req *hsreq;
-+	unsigned long irqflags;
-+	u32 ecr;
-+	u32 offset;
-+
-+	if (value && ep_is_in(hsep) && !list_empty(&hsep->queue))
-+		return -EAGAIN;
-+
-+	spin_lock_irqsave(&hsudc->lock, irqflags);
-+	set_index(hsudc, ep_index(hsep));
-+	offset = (ep_index(hsep)) ? S3C_ECR : S3C_EP0CR;
-+	ecr = readl(hsudc->regs + offset);
-+
-+	if (value) {
-+		ecr |= S3C_ECR_STALL;
-+		if (ep_index(hsep))
-+			ecr |= S3C_ECR_FLUSH;
-+		hsep->stopped = 1;
-+	} else {
-+		ecr &= ~S3C_ECR_STALL;
-+		hsep->stopped = 0;
-+	}
-+	writel(ecr, hsudc->regs + offset);
-+
-+	if (ep_is_in(hsep) && !list_empty(&hsep->queue) && !value) {
-+		hsreq = list_entry(hsep->queue.next,
-+			struct s3c_hsudc_req, queue);
-+		if (hsreq)
-+			s3c_hsudc_write_fifo(hsep, hsreq);
-+	}
-+
-+	spin_unlock_irqrestore(&hsudc->lock, irqflags);
-+	return 0;
-+}
-+
-+/** s3c_hsudc_handle_reqfeat - Handle set feature or clear feature requests.
-+ * @_ep: Device controller on which the set/clear feature needs to be handled.
-+ * @ctrl: Control request as received on the endpoint 0.
-+ *
-+ * Handle set feature or clear feature control requests on the control endpoint.
-+ */
-+static int s3c_hsudc_handle_reqfeat(struct s3c_hsudc *hsudc,
-+					struct usb_ctrlrequest *ctrl)
-+{
-+	struct s3c_hsudc_ep *hsep;
-+	bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE);
-+	u8 ep_num = ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK;
-+
-+	if (ctrl->bRequestType == USB_RECIP_ENDPOINT) {
-+		hsep = &hsudc->ep[ep_num];
-+		switch (le16_to_cpu(ctrl->wValue)) {
-+		case USB_ENDPOINT_HALT:
-+			s3c_hsudc_set_halt(&hsep->ep, set);
-+			return 0;
-+		}
-+	}
-+
-+	return -ENOENT;
-+}
-+
-+/**
-+ * s3c_hsudc_process_req_status - Handle get status control request.
-+ * @hsudc: Device controller on which get status request has be handled.
-+ * @ctrl: Control request as received on the endpoint 0.
-+ *
-+ * Handle get status control request received on control endpoint.
-+ */
-+static void s3c_hsudc_process_req_status(struct s3c_hsudc *hsudc,
-+					struct usb_ctrlrequest *ctrl)
-+{
-+	struct s3c_hsudc_ep *hsep0 = &hsudc->ep[0];
-+	struct s3c_hsudc_req hsreq;
-+	struct s3c_hsudc_ep *hsep;
-+	__le16 reply;
-+	u8 epnum;
-+
-+	switch (ctrl->bRequestType & USB_RECIP_MASK) {
-+	case USB_RECIP_DEVICE:
-+		reply = cpu_to_le16(0);
-+		break;
-+
-+	case USB_RECIP_INTERFACE:
-+		reply = cpu_to_le16(0);
-+		break;
-+
-+	case USB_RECIP_ENDPOINT:
-+		epnum = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK;
-+		hsep = &hsudc->ep[epnum];
-+		reply = cpu_to_le16(hsep->stopped ? 1 : 0);
-+		break;
-+	}
-+
-+	INIT_LIST_HEAD(&hsreq.queue);
-+	hsreq.req.length = 2;
-+	hsreq.req.buf = &reply;
-+	hsreq.req.actual = 0;
-+	hsreq.req.complete = NULL;
-+	s3c_hsudc_write_fifo(hsep0, &hsreq);
-+}
-+
-+/**
-+ * s3c_hsudc_process_setup - Process control request received on endpoint 0.
-+ * @hsudc: Device controller on which control request has been received.
-+ *
-+ * Read the control request received on endpoint 0, decode it and handle
-+ * the request.
-+ */
-+static void s3c_hsudc_process_setup(struct s3c_hsudc *hsudc)
-+{
-+	struct s3c_hsudc_ep *hsep = &hsudc->ep[0];
-+	struct usb_ctrlrequest ctrl = {0};
-+	int ret;
-+
-+	s3c_hsudc_nuke_ep(hsep, -EPROTO);
-+	s3c_hsudc_read_setup_pkt(hsudc, (u16 *)&ctrl);
-+
-+	if (ctrl.bRequestType & USB_DIR_IN) {
-+		hsep->bEndpointAddress |= USB_DIR_IN;
-+		hsudc->ep0state = DATA_STATE_XMIT;
-+	} else {
-+		hsep->bEndpointAddress &= ~USB_DIR_IN;
-+		hsudc->ep0state = DATA_STATE_RECV;
-+	}
-+
-+	switch (ctrl.bRequest) {
-+	case USB_REQ_SET_ADDRESS:
-+		if (ctrl.bRequestType != (USB_TYPE_STANDARD | USB_RECIP_DEVICE))
-+			break;
-+		hsudc->ep0state = WAIT_FOR_SETUP;
-+		return;
-+
-+	case USB_REQ_GET_STATUS:
-+		if ((ctrl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD)
-+			break;
-+		s3c_hsudc_process_req_status(hsudc, &ctrl);
-+		return;
-+
-+	case USB_REQ_SET_FEATURE:
-+	case USB_REQ_CLEAR_FEATURE:
-+		if ((ctrl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD)
-+			break;
-+		s3c_hsudc_handle_reqfeat(hsudc, &ctrl);
-+		hsudc->ep0state = WAIT_FOR_SETUP;
-+		return;
-+	}
-+
-+	if (hsudc->driver) {
-+		spin_unlock(&hsudc->lock);
-+		ret = hsudc->driver->setup(&hsudc->gadget, &ctrl);
-+		spin_lock(&hsudc->lock);
-+
-+		if (ctrl.bRequest == USB_REQ_SET_CONFIGURATION) {
-+			hsep->bEndpointAddress &= ~USB_DIR_IN;
-+			hsudc->ep0state = WAIT_FOR_SETUP;
-+		}
-+
-+		if (ret < 0) {
-+			dev_err(hsudc->dev, "setup failed, returned %d\n",
-+						ret);
-+			s3c_hsudc_set_halt(&hsep->ep, 1);
-+			hsudc->ep0state = WAIT_FOR_SETUP;
-+			hsep->bEndpointAddress &= ~USB_DIR_IN;
-+		}
-+	}
-+}
-+
-+/** s3c_hsudc_handle_ep0_intr - Handle endpoint 0 interrupt.
-+ * @hsudc: Device controller on which endpoint 0 interrupt has occured.
-+ *
-+ * Handle endpoint 0 interrupt when it occurs. EP0 interrupt could occur
-+ * when a stall handshake is sent to host or data is sent/received on
-+ * endpoint 0.
-+ */
-+static void s3c_hsudc_handle_ep0_intr(struct s3c_hsudc *hsudc)
-+{
-+	struct s3c_hsudc_ep *hsep = &hsudc->ep[0];
-+	struct s3c_hsudc_req *hsreq;
-+	u32 csr = readl(hsudc->regs + S3C_EP0SR);
-+	u32 ecr;
-+
-+	if (csr & S3C_EP0SR_STALL) {
-+		ecr = readl(hsudc->regs + S3C_EP0CR);
-+		ecr &= ~(S3C_ECR_STALL | S3C_ECR_FLUSH);
-+		writel(ecr, hsudc->regs + S3C_EP0CR);
-+
-+		writel(S3C_EP0SR_STALL, hsudc->regs + S3C_EP0SR);
-+		hsep->stopped = 0;
-+
-+		s3c_hsudc_nuke_ep(hsep, -ECONNABORTED);
-+		hsudc->ep0state = WAIT_FOR_SETUP;
-+		hsep->bEndpointAddress &= ~USB_DIR_IN;
-+		return;
-+	}
-+
-+	if (csr & S3C_EP0SR_TX_SUCCESS) {
-+		writel(S3C_EP0SR_TX_SUCCESS, hsudc->regs + S3C_EP0SR);
-+		if (ep_is_in(hsep)) {
-+			if (list_empty(&hsep->queue))
-+				return;
-+
-+			hsreq = list_entry(hsep->queue.next,
-+					struct s3c_hsudc_req, queue);
-+			s3c_hsudc_write_fifo(hsep, hsreq);
-+		}
-+	}
-+
-+	if (csr & S3C_EP0SR_RX_SUCCESS) {
-+		if (hsudc->ep0state == WAIT_FOR_SETUP)
-+			s3c_hsudc_process_setup(hsudc);
-+		else {
-+			if (!ep_is_in(hsep)) {
-+				if (list_empty(&hsep->queue))
-+					return;
-+				hsreq = list_entry(hsep->queue.next,
-+					struct s3c_hsudc_req, queue);
-+				s3c_hsudc_read_fifo(hsep, hsreq);
-+			}
-+		}
-+	}
-+}
-+
-+/**
-+ * s3c_hsudc_ep_enable - Enable a endpoint.
-+ * @_ep: The endpoint to be enabled.
-+ * @desc: Endpoint descriptor.
-+ *
-+ * Enables a endpoint when called from the gadget driver. Endpoint stall if
-+ * any is cleared, transfer type is configured and endpoint interrupt is
-+ * enabled.
-+ */
-+static int s3c_hsudc_ep_enable(struct usb_ep *_ep,
-+				const struct usb_endpoint_descriptor *desc)
-+{
-+	struct s3c_hsudc_ep *hsep;
-+	struct s3c_hsudc *hsudc;
-+	unsigned long flags;
-+	u32 ecr = 0;
-+
-+	hsep = container_of(_ep, struct s3c_hsudc_ep, ep);
-+	if (!_ep || !desc || hsep->desc || _ep->name == ep0name
-+		|| desc->bDescriptorType != USB_DT_ENDPOINT
-+		|| hsep->bEndpointAddress != desc->bEndpointAddress
-+		|| ep_maxpacket(hsep) < le16_to_cpu(desc->wMaxPacketSize))
-+		return -EINVAL;
-+
-+	if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
-+		&& le16_to_cpu(desc->wMaxPacketSize) != ep_maxpacket(hsep))
-+		|| !desc->wMaxPacketSize)
-+		return -ERANGE;
-+
-+	hsudc = hsep->dev;
-+	if (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN)
-+		return -ESHUTDOWN;
-+
-+	spin_lock_irqsave(&hsudc->lock, flags);
-+
-+	set_index(hsudc, hsep->bEndpointAddress);
-+	ecr |= ((usb_endpoint_xfer_int(desc)) ? S3C_ECR_IEMS : S3C_ECR_DUEN);
-+	writel(ecr, hsudc->regs + S3C_ECR);
-+
-+	hsep->stopped = 0;
-+	hsep->desc = desc;
-+	hsep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize);
-+
-+	s3c_hsudc_set_halt(_ep, 0);
-+	__set_bit(ep_index(hsep), hsudc->regs + S3C_EIER);
-+
-+	spin_unlock_irqrestore(&hsudc->lock, flags);
-+	return 0;
-+}
-+
-+/**
-+ * s3c_hsudc_ep_disable - Disable a endpoint.
-+ * @_ep: The endpoint to be disabled.
-+ * @desc: Endpoint descriptor.
-+ *
-+ * Disables a endpoint when called from the gadget driver.
-+ */
-+static int s3c_hsudc_ep_disable(struct usb_ep *_ep)
-+{
-+	struct s3c_hsudc_ep *hsep = our_ep(_ep);
-+	struct s3c_hsudc *hsudc = hsep->dev;
-+	unsigned long flags;
-+
-+	if (!_ep || !hsep->desc)
-+		return -EINVAL;
-+
-+	spin_lock_irqsave(&hsudc->lock, flags);
-+
-+	set_index(hsudc, hsep->bEndpointAddress);
-+	__clear_bit(ep_index(hsep), hsudc->regs + S3C_EIER);
-+
-+	s3c_hsudc_nuke_ep(hsep, -ESHUTDOWN);
-+
-+	hsep->desc = 0;
-+	hsep->stopped = 1;
-+
-+	spin_unlock_irqrestore(&hsudc->lock, flags);
-+	return 0;
-+}
-+
-+/**
-+ * s3c_hsudc_alloc_request - Allocate a new request.
-+ * @_ep: Endpoint for which request is allocated (not used).
-+ * @gfp_flags: Flags used for the allocation.
-+ *
-+ * Allocates a single transfer request structure when called from gadget driver.
-+ */
-+static struct usb_request *s3c_hsudc_alloc_request(struct usb_ep *_ep,
-+						gfp_t gfp_flags)
-+{
-+	struct s3c_hsudc_req *hsreq;
-+
-+	hsreq = kzalloc(sizeof *hsreq, gfp_flags);
-+	if (!hsreq)
-+		return 0;
-+
-+	INIT_LIST_HEAD(&hsreq->queue);
-+	return &hsreq->req;
-+}
-+
-+/**
-+ * s3c_hsudc_free_request - Deallocate a request.
-+ * @ep: Endpoint for which request is deallocated (not used).
-+ * @_req: Request to be deallocated.
-+ *
-+ * Allocates a single transfer request structure when called from gadget driver.
-+ */
-+static void s3c_hsudc_free_request(struct usb_ep *ep, struct usb_request *_req)
-+{
-+	struct s3c_hsudc_req *hsreq;
-+
-+	hsreq = container_of(_req, struct s3c_hsudc_req, req);
-+	WARN_ON(!list_empty(&hsreq->queue));
-+	kfree(hsreq);
-+}
-+
-+/**
-+ * s3c_hsudc_queue - Queue a transfer request for the endpoint.
-+ * @_ep: Endpoint for which the request is queued.
-+ * @_req: Request to be queued.
-+ * @gfp_flags: Not used.
-+ *
-+ * Start or enqueue a request for a endpoint when called from gadget driver.
-+ */
-+static int s3c_hsudc_queue(struct usb_ep *_ep, struct usb_request *_req,
-+			gfp_t gfp_flags)
-+{
-+	struct s3c_hsudc_req *hsreq;
-+	struct s3c_hsudc_ep *hsep;
-+	struct s3c_hsudc *hsudc;
-+	unsigned long flags;
-+	u32 offset;
-+	u32 csr;
-+
-+	hsreq = container_of(_req, struct s3c_hsudc_req, req);
-+	if ((!_req || !_req->complete || !_req->buf ||
-+		!list_empty(&hsreq->queue)))
-+		return -EINVAL;
-+
-+	hsep = container_of(_ep, struct s3c_hsudc_ep, ep);
-+	hsudc = hsep->dev;
-+	if (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN)
-+		return -ESHUTDOWN;
-+
-+	spin_lock_irqsave(&hsudc->lock, flags);
-+	set_index(hsudc, hsep->bEndpointAddress);
-+
-+	_req->status = -EINPROGRESS;
-+	_req->actual = 0;
-+
-+	if (!ep_index(hsep) && _req->length == 0) {
-+		hsudc->ep0state = WAIT_FOR_SETUP;
-+		s3c_hsudc_complete_request(hsep, hsreq, 0);
-+		spin_unlock_irqrestore(&hsudc->lock, flags);
-+		return 0;
-+	}
-+
-+	if (list_empty(&hsep->queue) && !hsep->stopped) {
-+		offset = (ep_index(hsep)) ? S3C_ESR : S3C_EP0SR;
-+		if (ep_is_in(hsep)) {
-+			csr = readl((u32)hsudc->regs + offset);
-+			if (!(csr & S3C_ESR_TX_SUCCESS) &&
-+				(s3c_hsudc_write_fifo(hsep, hsreq) == 1))
-+				hsreq = 0;
-+		} else {
-+			csr = readl((u32)hsudc->regs + offset);
-+			if ((csr & S3C_ESR_RX_SUCCESS)
-+				   && (s3c_hsudc_read_fifo(hsep, hsreq) == 1))
-+				hsreq = 0;
-+		}
-+	}
-+
-+	if (hsreq != 0)
-+		list_add_tail(&hsreq->queue, &hsep->queue);
-+
-+	spin_unlock_irqrestore(&hsudc->lock, flags);
-+	return 0;
-+}
-+
-+/**
-+ * s3c_hsudc_dequeue - Dequeue a transfer request from an endpoint.
-+ * @_ep: Endpoint from which the request is dequeued.
-+ * @_req: Request to be dequeued.
-+ *
-+ * Dequeue a request from a endpoint when called from gadget driver.
-+ */
-+static int s3c_hsudc_dequeue(struct usb_ep *_ep, struct usb_request *_req)
-+{
-+	struct s3c_hsudc_ep *hsep = our_ep(_ep);
-+	struct s3c_hsudc *hsudc = hsep->dev;
-+	struct s3c_hsudc_req *hsreq;
-+	unsigned long flags;
-+
-+	hsep = container_of(_ep, struct s3c_hsudc_ep, ep);
-+	if (!_ep || hsep->ep.name == ep0name)
-+		return -EINVAL;
-+
-+	spin_lock_irqsave(&hsudc->lock, flags);
-+
-+	list_for_each_entry(hsreq, &hsep->queue, queue) {
-+		if (&hsreq->req == _req)
-+			break;
-+	}
-+	if (&hsreq->req != _req) {
-+		spin_unlock_irqrestore(&hsudc->lock, flags);
-+		return -EINVAL;
-+	}
-+
-+	set_index(hsudc, hsep->bEndpointAddress);
-+	s3c_hsudc_complete_request(hsep, hsreq, -ECONNRESET);
-+
-+	spin_unlock_irqrestore(&hsudc->lock, flags);
-+	return 0;
-+}
-+
-+static struct usb_ep_ops s3c_hsudc_ep_ops = {
-+	.enable = s3c_hsudc_ep_enable,
-+	.disable = s3c_hsudc_ep_disable,
-+	.alloc_request = s3c_hsudc_alloc_request,
-+	.free_request = s3c_hsudc_free_request,
-+	.queue = s3c_hsudc_queue,
-+	.dequeue = s3c_hsudc_dequeue,
-+	.set_halt = s3c_hsudc_set_halt,
-+};
-+
-+/**
-+ * s3c_hsudc_initep - Initialize a endpoint to default state.
-+ * @hsudc - Reference to the device controller.
-+ * @hsep - Endpoint to be initialized.
-+ * @epnum - Address to be assigned to the endpoint.
-+ *
-+ * Initialize a endpoint with default configuration.
-+ */
-+static void s3c_hsudc_initep(struct s3c_hsudc *hsudc,
-+				struct s3c_hsudc_ep *hsep, int epnum)
-+{
-+	char *dir;
-+
-+	if ((epnum % 2) == 0) {
-+		dir = "out";
-+	} else {
-+		dir = "in";
-+		hsep->bEndpointAddress = USB_DIR_IN;
-+	}
-+
-+	hsep->bEndpointAddress |= epnum;
-+	if (epnum)
-+		snprintf(hsep->name, sizeof(hsep->name), "ep%d%s", epnum, dir);
-+	else
-+		snprintf(hsep->name, sizeof(hsep->name), "%s", ep0name);
-+
-+	INIT_LIST_HEAD(&hsep->queue);
-+	INIT_LIST_HEAD(&hsep->ep.ep_list);
-+	if (epnum)
-+		list_add_tail(&hsep->ep.ep_list, &hsudc->gadget.ep_list);
-+
-+	hsep->dev = hsudc;
-+	hsep->ep.name = hsep->name;
-+	hsep->ep.maxpacket = epnum ? 512 : 64;
-+	hsep->ep.ops = &s3c_hsudc_ep_ops;
-+	hsep->fifo = hsudc->regs + S3C_BR(epnum);
-+	hsep->desc = 0;
-+	hsep->stopped = 0;
-+
-+	set_index(hsudc, epnum);
-+	writel(hsep->ep.maxpacket, hsudc->regs + S3C_MPR);
-+}
-+
-+/**
-+ * s3c_hsudc_setup_ep - Configure all endpoints to default state.
-+ * @hsudc: Reference to device controller.
-+ *
-+ * Configures all endpoints to default state.
-+ */
-+static void s3c_hsudc_setup_ep(struct s3c_hsudc *hsudc)
-+{
-+	int epnum;
-+
-+	hsudc->ep0state = WAIT_FOR_SETUP;
-+	INIT_LIST_HEAD(&hsudc->gadget.ep_list);
-+	for (epnum = 0; epnum < hsudc->pd->epnum; epnum++)
-+		s3c_hsudc_initep(hsudc, &hsudc->ep[epnum], epnum);
-+}
-+
-+/**
-+ * s3c_hsudc_reconfig - Reconfigure the device controller to default state.
-+ * @hsudc: Reference to device controller.
-+ *
-+ * Reconfigures the device controller registers to a default state.
-+ */
-+static void s3c_hsudc_reconfig(struct s3c_hsudc *hsudc)
-+{
-+	writel(0xAA, hsudc->regs + S3C_EDR);
-+	writel(1, hsudc->regs + S3C_EIER);
-+	writel(0, hsudc->regs + S3C_TR);
-+	writel(S3C_SCR_DTZIEN_EN | S3C_SCR_RRD_EN | S3C_SCR_SUS_EN |
-+			S3C_SCR_RST_EN, hsudc->regs + S3C_SCR);
-+	writel(0, hsudc->regs + S3C_EP0CR);
-+
-+	s3c_hsudc_setup_ep(hsudc);
-+}
-+
-+/**
-+ * s3c_hsudc_irq - Interrupt handler for device controller.
-+ * @irq: Not used.
-+ * @_dev: Reference to the device controller.
-+ *
-+ * Interrupt handler for the device controller. This handler handles controller
-+ * interrupts and endpoint interrupts.
-+ */
-+static irqreturn_t s3c_hsudc_irq(int irq, void *_dev)
-+{
-+	struct s3c_hsudc *hsudc = _dev;
-+	struct s3c_hsudc_ep *hsep;
-+	u32 ep_intr;
-+	u32 sys_status;
-+	u32 ep_idx;
-+
-+	spin_lock(&hsudc->lock);
-+
-+	sys_status = readl(hsudc->regs + S3C_SSR);
-+	ep_intr = readl(hsudc->regs + S3C_EIR) & 0x3FF;
-+
-+	if (!ep_intr && !(sys_status & S3C_SSR_DTZIEN_EN)) {
-+		spin_unlock(&hsudc->lock);
-+		return IRQ_HANDLED;
-+	}
-+
-+	if (sys_status) {
-+		if (sys_status & S3C_SSR_VBUSON)
-+			writel(S3C_SSR_VBUSON, hsudc->regs + S3C_SSR);
-+
-+		if (sys_status & S3C_SSR_ERR)
-+			writel(S3C_SSR_ERR, hsudc->regs + S3C_SSR);
-+
-+		if (sys_status & S3C_SSR_SDE) {
-+			writel(S3C_SSR_SDE, hsudc->regs + S3C_SSR);
-+			hsudc->gadget.speed = (sys_status & S3C_SSR_HSP) ?
-+				USB_SPEED_HIGH : USB_SPEED_FULL;
-+		}
-+
-+		if (sys_status & S3C_SSR_SUSPEND) {
-+			writel(S3C_SSR_SUSPEND, hsudc->regs + S3C_SSR);
-+			if (hsudc->gadget.speed != USB_SPEED_UNKNOWN
-+				&& hsudc->driver && hsudc->driver->suspend)
-+				hsudc->driver->suspend(&hsudc->gadget);
-+		}
-+
-+		if (sys_status & S3C_SSR_RESUME) {
-+			writel(S3C_SSR_RESUME, hsudc->regs + S3C_SSR);
-+			if (hsudc->gadget.speed != USB_SPEED_UNKNOWN
-+				&& hsudc->driver && hsudc->driver->resume)
-+				hsudc->driver->resume(&hsudc->gadget);
-+		}
-+
-+		if (sys_status & S3C_SSR_RESET) {
-+			writel(S3C_SSR_RESET, hsudc->regs + S3C_SSR);
-+			for (ep_idx = 0; ep_idx < hsudc->pd->epnum; ep_idx++) {
-+				hsep = &hsudc->ep[ep_idx];
-+				hsep->stopped = 1;
-+				s3c_hsudc_nuke_ep(hsep, -ECONNRESET);
-+			}
-+			s3c_hsudc_reconfig(hsudc);
-+			hsudc->ep0state = WAIT_FOR_SETUP;
-+		}
-+	}
-+
-+	if (ep_intr & S3C_EIR_EP0) {
-+		writel(S3C_EIR_EP0, hsudc->regs + S3C_EIR);
-+		set_index(hsudc, 0);
-+		s3c_hsudc_handle_ep0_intr(hsudc);
-+	}
-+
-+	ep_intr >>= 1;
-+	ep_idx = 1;
-+	while (ep_intr) {
-+		if (ep_intr & 1)  {
-+			hsep = &hsudc->ep[ep_idx];
-+			set_index(hsudc, ep_idx);
-+			writel(1 << ep_idx, hsudc->regs + S3C_EIR);
-+			if (ep_is_in(hsep))
-+				s3c_hsudc_epin_intr(hsudc, ep_idx);
-+			else
-+				s3c_hsudc_epout_intr(hsudc, ep_idx);
-+		}
-+		ep_intr >>= 1;
-+		ep_idx++;
-+	}
-+
-+	spin_unlock(&hsudc->lock);
-+	return IRQ_HANDLED;
-+}
-+
-+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
-+               int (*bind)(struct usb_gadget *))
-+{
-+	struct s3c_hsudc *hsudc = the_controller;
-+	int ret;
-+
-+	if (!driver
-+		|| (driver->speed != USB_SPEED_FULL &&
-+			driver->speed != USB_SPEED_HIGH)
-+		|| !bind
-+		|| !driver->unbind || !driver->disconnect || !driver->setup)
-+		return -EINVAL;
-+
-+	if (!hsudc)
-+		return -ENODEV;
-+
-+	if (hsudc->driver)
-+		return -EBUSY;
-+
-+	hsudc->driver = driver;
-+	hsudc->gadget.dev.driver = &driver->driver;
-+	hsudc->gadget.speed = USB_SPEED_UNKNOWN;
-+	ret = device_add(&hsudc->gadget.dev);
-+	if (ret) {
-+		dev_err(hsudc->dev, "failed to probe gadget device");
-+		return ret;
-+	}
-+
-+	ret = bind(&hsudc->gadget);
-+	if (ret) {
-+		dev_err(hsudc->dev, "%s: bind failed\n", hsudc->gadget.name);
-+		device_del(&hsudc->gadget.dev);
-+
-+		hsudc->driver = NULL;
-+		hsudc->gadget.dev.driver = NULL;
-+		return ret;
-+	}
-+
-+	enable_irq(hsudc->irq);
-+	dev_info(hsudc->dev, "bound driver %s\n", driver->driver.name);
-+
-+	s3c_hsudc_reconfig(hsudc);
-+	s3c_hsudc_init_phy();
-+	if (hsudc->pd->gpio_init)
-+		hsudc->pd->gpio_init();
-+
-+	return 0;
-+}
-+EXPORT_SYMBOL(usb_gadget_probe_driver);
-+
-+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
-+{
-+	struct s3c_hsudc *hsudc = the_controller;
-+	unsigned long flags;
-+
-+	if (!hsudc)
-+		return -ENODEV;
-+
-+	if (!driver || driver != hsudc->driver || !driver->unbind)
-+		return -EINVAL;
-+
-+	spin_lock_irqsave(&hsudc->lock, flags);
-+	hsudc->driver = 0;
-+	s3c_hsudc_uninit_phy();
-+	if (hsudc->pd->gpio_uninit)
-+		hsudc->pd->gpio_uninit();
-+	s3c_hsudc_stop_activity(hsudc, driver);
-+	spin_unlock_irqrestore(&hsudc->lock, flags);
-+
-+	driver->unbind(&hsudc->gadget);
-+	device_del(&hsudc->gadget.dev);
-+	disable_irq(hsudc->irq);
-+
-+	dev_info(hsudc->dev, "unregistered gadget driver '%s'\n",
-+			driver->driver.name);
-+	return 0;
-+}
-+EXPORT_SYMBOL(usb_gadget_unregister_driver);
-+
-+static inline u32 s3c_hsudc_read_frameno(struct s3c_hsudc *hsudc)
-+{
-+	return readl(hsudc->regs + S3C_FNR) & 0x3FF;
-+}
-+
-+static int s3c_hsudc_gadget_getframe(struct usb_gadget *gadget)
-+{
-+	return s3c_hsudc_read_frameno(to_hsudc(gadget));
-+}
-+
-+static struct usb_gadget_ops s3c_hsudc_gadget_ops = {
-+	.get_frame	= s3c_hsudc_gadget_getframe,
-+};
-+
-+static int s3c_hsudc_probe(struct platform_device *pdev)
-+{
-+	struct device *dev = &pdev->dev;
-+	struct resource *res;
-+	struct s3c_hsudc *hsudc;
-+	struct s3c24xx_hsudc_platdata *pd = pdev->dev.platform_data;
-+	int ret;
-+
-+	hsudc = kzalloc(sizeof(struct s3c_hsudc) +
-+			sizeof(struct s3c_hsudc_ep) * pd->epnum,
-+			GFP_KERNEL);
-+	if (!hsudc) {
-+		dev_err(dev, "cannot allocate memory\n");
-+		return -ENOMEM;
-+	}
-+
-+	the_controller = hsudc;
-+	platform_set_drvdata(pdev, dev);
-+	hsudc->dev = dev;
-+	hsudc->pd = pdev->dev.platform_data;
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	if (!res) {
-+		dev_err(dev, "unable to obtain driver resource data\n");
-+		ret = -ENODEV;
-+		goto err_res;
-+	}
-+
-+	hsudc->mem_rsrc = request_mem_region(res->start, resource_size(res),
-+				dev_name(&pdev->dev));
-+	if (!hsudc->mem_rsrc) {
-+		dev_err(dev, "failed to reserve register area\n");
-+		ret = -ENODEV;
-+		goto err_res;
-+	}
-+
-+	hsudc->regs = ioremap(res->start, resource_size(res));
-+	if (!hsudc->regs) {
-+		dev_err(dev, "error mapping device register area\n");
-+		ret = -EBUSY;
-+		goto err_remap;
-+	}
-+
-+	ret = platform_get_irq(pdev, 0);
-+	if (ret < 0) {
-+		dev_err(dev, "unable to obtain IRQ number\n");
-+		goto err_irq;
-+	}
-+	hsudc->irq = ret;
-+
-+	ret = request_irq(hsudc->irq, s3c_hsudc_irq, 0, driver_name, hsudc);
-+	if (ret < 0) {
-+		dev_err(dev, "irq request failed\n");
-+		goto err_irq;
-+	}
-+
-+	spin_lock_init(&hsudc->lock);
-+
-+	device_initialize(&hsudc->gadget.dev);
-+	dev_set_name(&hsudc->gadget.dev, "gadget");
-+
-+	hsudc->gadget.is_dualspeed = 1;
-+	hsudc->gadget.ops = &s3c_hsudc_gadget_ops;
-+	hsudc->gadget.name = dev_name(dev);
-+	hsudc->gadget.dev.parent = dev;
-+	hsudc->gadget.dev.dma_mask = dev->dma_mask;
-+	hsudc->gadget.ep0 = &hsudc->ep[0].ep;
-+
-+	hsudc->gadget.is_otg = 0;
-+	hsudc->gadget.is_a_peripheral = 0;
-+
-+	s3c_hsudc_setup_ep(hsudc);
-+
-+	hsudc->uclk = clk_get(&pdev->dev, "usb-device");
-+	if (hsudc->uclk == NULL) {
-+		dev_err(dev, "failed to find usb-device clock source\n");
-+		return -ENOENT;
-+	}
-+	clk_enable(hsudc->uclk);
-+
-+	local_irq_disable();
-+
-+	disable_irq(hsudc->irq);
-+	local_irq_enable();
-+	return 0;
-+
-+err_irq:
-+	iounmap(hsudc->regs);
-+
-+err_remap:
-+	release_resource(hsudc->mem_rsrc);
-+	kfree(hsudc->mem_rsrc);
-+
-+err_res:
-+	kfree(hsudc);
-+	return ret;
-+}
-+
-+static struct platform_driver s3c_hsudc_driver = {
-+	.driver		= {
-+		.owner	= THIS_MODULE,
-+		.name	= "s3c-hsudc",
-+	},
-+	.probe		= s3c_hsudc_probe,
-+};
-+
-+static int __init s3c_hsudc_modinit(void)
-+{
-+	return platform_driver_register(&s3c_hsudc_driver);
-+}
-+
-+static void __exit s3c_hsudc_modexit(void)
-+{
-+	platform_driver_unregister(&s3c_hsudc_driver);
-+}
-+
-+module_init(s3c_hsudc_modinit);
-+module_exit(s3c_hsudc_modexit);
-+
-+MODULE_DESCRIPTION("Samsung S3C24XX USB high-speed controller driver");
-+MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
-+MODULE_LICENSE("GPL");
--- 
-1.7.2.3
diff --git a/a/6.hdr b/a/6.hdr
deleted file mode 100644
index 4b86001..0000000
--- a/a/6.hdr
+++ /dev/null
@@ -1,4 +0,0 @@
-Content-Type: text/plain; charset="us-ascii"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Content-Disposition: inline
diff --git a/a/6.txt b/a/6.txt
deleted file mode 100644
index 8133cf0..0000000
--- a/a/6.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-_______________________________________________
-linux-arm-kernel mailing list
-linux-arm-kernel@lists.infradead.org
-http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
diff --git a/a/content_digest b/N1/content_digest
index f8e13d8..7166d35 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -1,13 +1,8 @@
- "From\0Heiko St\303\274bner <heiko@sntech.de>\0"
+ "From\0heiko@sntech.de (Heiko St\303\274bner)\0"
  "Subject\0resend hsudc patches for s3c24xx?\0"
  "Date\0Tue, 1 Mar 2011 18:07:01 +0100\0"
- "To\0Kukjin Kim <kgene.kim@samsung.com>"
-  Sangbeom Kim <sbkim73@samsung.com>
- " Thomas Abraham <thomas.ab@samsung.com>\0"
- "Cc\0Alexander Neumann <fd0@lochraster.org>"
-  linux-samsung-soc@vger.kernel.org
- " linux-arm-kernel@lists.infradead.org\0"
- "\01:1\0"
+ "To\0linux-arm-kernel@lists.infradead.org\0"
+ "\00:1\0"
  "b\0"
  "Hi,\n"
  "\n"
@@ -32,1733 +27,34 @@
  "\n"
  "[1] http://gitorious.org/oyo-hack/kernel/commits/s3c-hsudc\n"
  "[2] http://gitorious.org/oyo-\n"
- hack/kernel/commit/c063317869d11c3b8f906061319f8a075de06b5c
- "\01:2\0"
- "fn\00001-ARM-S3C2416-Add-USB-Phy-register-definitions.patch\0"
- "b\0"
- "From 92a488ff6afa7d33ed04d476c4f1704899be9da1 Mon Sep 17 00:00:00 2001\n"
- "From: Thomas Abraham <thomas.ab@samsung.com>\n"
- "Date: Wed, 13 Oct 2010 09:10:24 +0900\n"
- "Subject: [PATCH 1/4] ARM: S3C2416: Add USB Phy register definitions\n"
- "\n"
- "Add register definitions required to configure the USB Phy. The definitions\n"
- "for PHYCTRL, PHYPWR, URSTCON and UCLKCON registers and corresponding bit\n"
- "field definitions are added.\n"
- "\n"
- "Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>\n"
- "Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>\n"
- "---\n"
- " .../mach-s3c2410/include/mach/regs-s3c2443-clock.h |   25 ++++++++++++++++++++\n"
- " 1 files changed, 25 insertions(+), 0 deletions(-)\n"
- "\n"
- "diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h\n"
- "index 44494a5..5e06c72 100644\n"
- "--- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h\n"
- "+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h\n"
- "@@ -37,6 +37,10 @@\n"
- " #define S3C2443_SYSID\t\t\tS3C2443_CLKREG(0x5C)\n"
- " #define S3C2443_PWRCFG\t\t\tS3C2443_CLKREG(0x60)\n"
- " #define S3C2443_RSTCON\t\t\tS3C2443_CLKREG(0x64)\n"
- "+#define S3C2443_PHYCTRL\t\t\tS3C2443_CLKREG(0x80)\n"
- "+#define S3C2443_PHYPWR\t\t\tS3C2443_CLKREG(0x84)\n"
- "+#define S3C2443_URSTCON\t\t\tS3C2443_CLKREG(0x88)\n"
- "+#define S3C2443_UCLKCON\t\t\tS3C2443_CLKREG(0x8C)\n"
- " \n"
- " #define S3C2443_SWRST_RESET\t\t(0x533c2443)\n"
- " \n"
- "@@ -121,6 +125,27 @@\n"
- " \n"
- " #define S3C2443_PWRCFG_SLEEP\t\t(1<<15)\n"
- " \n"
- "+#define S3C2443_PWRCFG_USBPHY\t\t(1 << 4)\n"
- "+\n"
- "+#define S3C2443_URSTCON_FUNCRST\t\t(1 << 2)\n"
- "+#define S3C2443_URSTCON_PHYRST\t\t(1 << 0)\n"
- "+\n"
- "+#define S3C2443_PHYCTRL_CLKSEL\t\t(1 << 3)\n"
- "+#define S3C2443_PHYCTRL_EXTCLK\t\t(1 << 2)\n"
- "+#define S3C2443_PHYCTRL_PLLSEL\t\t(1 << 1)\n"
- "+#define S3C2443_PHYCTRL_DSPORT\t\t(1 << 0)\n"
- "+\n"
- "+#define S3C2443_PHYPWR_COMMON_ON\t(1 << 31)\n"
- "+#define S3C2443_PHYPWR_ANALOG_PD\t(1 << 4)\n"
- "+#define S3C2443_PHYPWR_PLL_REFCLK\t(1 << 3)\n"
- "+#define S3C2443_PHYPWR_XO_ON\t\t(1 << 2)\n"
- "+#define S3C2443_PHYPWR_PLL_PWRDN\t(1 << 1)\n"
- "+#define S3C2443_PHYPWR_FSUSPEND\t\t(1 << 0)\n"
- "+\n"
- "+#define S3C2443_UCLKCON_DETECT_VBUS\t(1 << 31)\n"
- "+#define S3C2443_UCLKCON_FUNC_CLKEN\t(1 << 2)\n"
- "+#define S3C2443_UCLKCON_TCLKEN\t\t(1 << 0)\n"
- "+\n"
- " #include <asm/div64.h>\n"
- " \n"
- " static inline unsigned int\n"
- "-- \n"
- 1.7.2.3
- "\01:3\0"
- "fn\00002-ARM-S3C24XX-Add-plaform-device-definition-for-USB-Hi.patch\0"
- "b\0"
- "From 0e89d462593eeb69a168ed1712c3e27039c2af78 Mon Sep 17 00:00:00 2001\n"
- "From: Thomas Abraham <thomas.ab@samsung.com>\n"
- "Date: Wed, 13 Oct 2010 09:10:25 +0900\n"
- "Subject: [PATCH 2/4] ARM: S3C24XX: Add plaform device definition for USB High-Speed gadget controller.\n"
- "\n"
- "S3C2416, S3C2443 and S3C2450 includes a USB High-Speed Gadget controller module.\n"
- "This patch adds the following for supporting this controller.\n"
- "\n"
- "1. Definition for USB High-Speed controller base address.\n"
- "2. Platform device instantiation.\n"
- "3. Declaration for platform data structure.\n"
- "4. Functionality to setup platform data for the controller.\n"
- "\n"
- "Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>\n"
- "Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>\n"
- "---\n"
- " arch/arm/mach-s3c2410/include/mach/map.h  |    4 +++\n"
- " arch/arm/plat-s3c24xx/devs.c              |   41 +++++++++++++++++++++++++++++\n"
- " arch/arm/plat-s3c24xx/include/plat/udc.h  |   17 ++++++++++++\n"
- " arch/arm/plat-samsung/include/plat/devs.h |    1 +\n"
- " 4 files changed, 63 insertions(+), 0 deletions(-)\n"
- "\n"
- "diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h\n"
- "index 25bbf5a..425552d 100644\n"
- "--- a/arch/arm/mach-s3c2410/include/mach/map.h\n"
- "+++ b/arch/arm/mach-s3c2410/include/mach/map.h\n"
- "@@ -21,6 +21,10 @@\n"
- " /* USB host controller */\n"
- " #define S3C2410_PA_USBHOST (0x49000000)\n"
- " \n"
- "+/* S3C2416/S3C2443/S3C2450 High-Speed USB Gadget */\n"
- "+#define S3C2416_PA_HSUDC\t(0x49800000)\n"
- "+#define S3C2416_SZ_HSUDC\t(SZ_4K)\n"
- "+\n"
- " /* DMA controller */\n"
- " #define S3C2410_PA_DMA\t   (0x4B000000)\n"
- " #define S3C24XX_SZ_DMA\t   SZ_1M\n"
- "diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c\n"
- "index 268f3ed..7366799 100644\n"
- "--- a/arch/arm/plat-s3c24xx/devs.c\n"
- "+++ b/arch/arm/plat-s3c24xx/devs.c\n"
- "@@ -22,6 +22,7 @@\n"
- " #include <linux/io.h>\n"
- " #include <linux/slab.h>\n"
- " #include <linux/string.h>\n"
- "+#include <linux/dma-mapping.h>\n"
- " \n"
- " #include <asm/mach/arch.h>\n"
- " #include <asm/mach/map.h>\n"
- "@@ -233,6 +234,46 @@ void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)\n"
- " \t}\n"
- " }\n"
- " \n"
- "+/* USB High Speed 2.0 Device (Gadget) */\n"
- "+static struct resource s3c_hsudc_resource[] = {\n"
- "+\t[0] = {\n"
- "+\t\t.start\t= S3C2416_PA_HSUDC,\n"
- "+\t\t.end\t= S3C2416_PA_HSUDC + S3C2416_SZ_HSUDC - 1,\n"
- "+\t\t.flags\t= IORESOURCE_MEM,\n"
- "+\t},\n"
- "+\t[1] = {\n"
- "+\t\t.start\t= IRQ_USBD,\n"
- "+\t\t.end\t= IRQ_USBD,\n"
- "+\t\t.flags\t= IORESOURCE_IRQ,\n"
- "+\t}\n"
- "+};\n"
- "+\n"
- "+static u64 s3c_hsudc_dmamask = DMA_BIT_MASK(32);\n"
- "+\n"
- "+struct platform_device s3c_device_usb_hsudc = {\n"
- "+\t.name\t\t= \"s3c-hsudc\",\n"
- "+\t.id\t\t= -1,\n"
- "+\t.num_resources\t= ARRAY_SIZE(s3c_hsudc_resource),\n"
- "+\t.resource\t= s3c_hsudc_resource,\n"
- "+\t.dev\t\t= {\n"
- "+\t\t.dma_mask\t\t= &s3c_hsudc_dmamask,\n"
- "+\t\t.coherent_dma_mask\t= DMA_BIT_MASK(32),\n"
- "+\t},\n"
- "+};\n"
- "+\n"
- "+void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd)\n"
- "+{\n"
- "+\tstruct s3c24xx_hsudc_platdata *npd;\n"
- "+\n"
- "+\tnpd = kmalloc(sizeof(*npd), GFP_KERNEL);\n"
- "+\tif (npd) {\n"
- "+\t\tmemcpy(npd, pd, sizeof(*npd));\n"
- "+\t\ts3c_device_usb_hsudc.dev.platform_data = npd;\n"
- "+\t} else {\n"
- "+\t\tprintk(KERN_ERR \"no memory for udc platform data\\n\");\n"
- "+\t}\n"
- "+}\n"
- "+\n"
- " /* IIS */\n"
- " \n"
- " static struct resource s3c_iis_resource[] = {\n"
- "diff --git a/arch/arm/plat-s3c24xx/include/plat/udc.h b/arch/arm/plat-s3c24xx/include/plat/udc.h\n"
- "index 546bb40..a3fc1be 100644\n"
- "--- a/arch/arm/plat-s3c24xx/include/plat/udc.h\n"
- "+++ b/arch/arm/plat-s3c24xx/include/plat/udc.h\n"
- "@@ -33,4 +33,21 @@ struct s3c2410_udc_mach_info {\n"
- " \n"
- " extern void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *);\n"
- " \n"
- "+/**\n"
- "+ * s3c24xx_hsudc_platdata - Platform data for USB High-Speed gadget controller.\n"
- "+ * @epnum: Number of endpoints to be instantiated by the controller driver.\n"
- "+ * @gpio_init: Platform specific USB related GPIO initialization.\n"
- "+ * @gpio_uninit: Platform specific USB releted GPIO uninitialzation.\n"
- "+ *\n"
- "+ * Representation of platform data for the S3C24XX USB 2.0 High Speed gadget\n"
- "+ * controllers.\n"
- "+ */\n"
- "+struct s3c24xx_hsudc_platdata {\n"
- "+\tunsigned int\tepnum;\n"
- "+\tvoid\t\t(*gpio_init)(void);\n"
- "+\tvoid\t\t(*gpio_uninit)(void);\n"
- "+};\n"
- "+\n"
- "+extern void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd);\n"
- "+\n"
- " #endif /* __ASM_ARM_ARCH_UDC_H */\n"
- "diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h\n"
- "index b4d208b..fcb6e30 100644\n"
- "--- a/arch/arm/plat-samsung/include/plat/devs.h\n"
- "+++ b/arch/arm/plat-samsung/include/plat/devs.h\n"
- "@@ -85,6 +85,7 @@ extern struct platform_device s3c64xx_device_onenand1;\n"
- " extern struct platform_device s5p_device_onenand;\n"
- " \n"
- " extern struct platform_device s3c_device_usbgadget;\n"
- "+extern struct platform_device s3c_device_usb_hsudc;\n"
- " extern struct platform_device s3c_device_usb_hsotg;\n"
- " \n"
- " extern struct platform_device s5pv210_device_ac97;\n"
- "-- \n"
- 1.7.2.3
- "\01:4\0"
- "fn\00004-ARM-S3C2416-Add-support-for-USB-2.0-High-Speed-gadge.patch\0"
- "b\0"
- "From 80eed2079d7aed5013e3d3c89e7b4b12f3ee6bd6 Mon Sep 17 00:00:00 2001\n"
- "From: Thomas Abraham <thomas.ab@samsung.com>\n"
- "Date: Wed, 13 Oct 2010 09:10:27 +0900\n"
- "Subject: [PATCH 4/4] ARM: S3C2416: Add support for USB 2.0 High-Speed gadget controller\n"
- "\n"
- "Add support for USB 2.0 High-Speed gadget controller driver for Samsung's\n"
- "S3C2416 processor.\n"
- "\n"
- "Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>\n"
- "Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>\n"
- "---\n"
- " arch/arm/mach-s3c2416/mach-smdk2416.c |   27 +++++++++++++++++++++++++++\n"
- " 1 files changed, 27 insertions(+), 0 deletions(-)\n"
- "\n"
- "diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c\n"
- "index 3f83177..ac27ebb 100644\n"
- "--- a/arch/arm/mach-s3c2416/mach-smdk2416.c\n"
- "+++ b/arch/arm/mach-s3c2416/mach-smdk2416.c\n"
- "@@ -23,6 +23,7 @@\n"
- " #include <linux/mtd/partitions.h>\n"
- " #include <linux/gpio.h>\n"
- " #include <linux/fb.h>\n"
- "+#include <linux/delay.h>\n"
- " \n"
- " #include <asm/mach/arch.h>\n"
- " #include <asm/mach/map.h>\n"
- "@@ -35,6 +36,7 @@\n"
- " #include <plat/regs-serial.h>\n"
- " #include <mach/regs-gpio.h>\n"
- " #include <mach/regs-lcd.h>\n"
- "+#include <mach/regs-s3c2443-clock.h>\n"
- " \n"
- " #include <mach/idle.h>\n"
- " #include <mach/leds-gpio.h>\n"
- "@@ -47,6 +49,7 @@\n"
- " #include <plat/cpu.h>\n"
- " #include <plat/nand.h>\n"
- " #include <plat/sdhci.h>\n"
- "+#include <plat/udc.h>\n"
- " \n"
- " #include <plat/regs-fb-v4.h>\n"
- " #include <plat/fb.h>\n"
- "@@ -121,6 +124,27 @@ static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = {\n"
- " \t}\n"
- " };\n"
- " \n"
- "+void smdk2416_hsudc_gpio_init(void)\n"
- "+{\n"
- "+\ts3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_UP);\n"
- "+\ts3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_NONE);\n"
- "+\ts3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(1));\n"
- "+\ts3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 0);\n"
- "+}\n"
- "+\n"
- "+void smdk2416_hsudc_gpio_uninit(void)\n"
- "+{\n"
- "+\ts3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 1);\n"
- "+\ts3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_NONE);\n"
- "+\ts3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(0));\n"
- "+}\n"
- "+\n"
- "+struct s3c24xx_hsudc_platdata smdk2416_hsudc_platdata = {\n"
- "+\t.epnum = 9,\n"
- "+\t.gpio_init = smdk2416_hsudc_gpio_init,\n"
- "+\t.gpio_uninit = smdk2416_hsudc_gpio_uninit,\n"
- "+};\n"
- "+\n"
- " struct s3c_fb_pd_win smdk2416_fb_win[] = {\n"
- " \t[0] = {\n"
- " \t\t/* think this is the same as the smdk6410 */\n"
- "@@ -186,6 +210,7 @@ static struct platform_device *smdk2416_devices[] __initdata = {\n"
- " \t&s3c_device_i2c0,\n"
- " \t&s3c_device_hsmmc0,\n"
- " \t&s3c_device_hsmmc1,\n"
- "+\t&s3c_device_usb_hsudc,\n"
- " };\n"
- " \n"
- " static void __init smdk2416_map_io(void)\n"
- "@@ -203,6 +228,8 @@ static void __init smdk2416_machine_init(void)\n"
- " \ts3c_sdhci0_set_platdata(&smdk2416_hsmmc0_pdata);\n"
- " \ts3c_sdhci1_set_platdata(&smdk2416_hsmmc1_pdata);\n"
- " \n"
- "+\ts3c24xx_hsudc_set_platdata(&smdk2416_hsudc_platdata);\n"
- "+\n"
- " \tgpio_request(S3C2410_GPB(4), \"USBHost Power\");\n"
- " \tgpio_direction_output(S3C2410_GPB(4), 1);\n"
- " \n"
- "-- \n"
- 1.7.2.3
- "\01:5\0"
- "fn\00003-USB-Gadget-Add-Samsung-S3C24XX-USB-High-Speed-contro.patch\0"
- "b\0"
- "From c063317869d11c3b8f906061319f8a075de06b5c Mon Sep 17 00:00:00 2001\n"
- "From: Thomas Abraham <thomas.ab@samsung.com>\n"
- "Date: Sat, 23 Oct 2010 07:51:55 +0900\n"
- "Subject: [PATCH 3/4] USB: Gadget: Add Samsung S3C24XX USB High-Speed controller driver\n"
- "\n"
- "The Samsung's S3C2416, S3C2443 and S3C2450 includes a USB High-Speed\n"
- "device controller module. This driver enables support for USB high-speed\n"
- "gadget functionality for the Samsung S3C24xx SoC's that include this\n"
- "controller.\n"
- "\n"
- "Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>\n"
- "Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>\n"
- "Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>\n"
- "---\n"
- " drivers/usb/gadget/Kconfig        |   17 +\n"
- " drivers/usb/gadget/Makefile       |    1 +\n"
- " drivers/usb/gadget/gadget_chips.h |    8 +\n"
- " drivers/usb/gadget/s3c-hsudc.c    | 1329 +++++++++++++++++++++++++++++++++++++\n"
- " 4 files changed, 1355 insertions(+), 0 deletions(-)\n"
- " create mode 100644 drivers/usb/gadget/s3c-hsudc.c\n"
- "\n"
- "diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig\n"
- "index d500996..d836756 100644\n"
- "--- a/drivers/usb/gadget/Kconfig\n"
- "+++ b/drivers/usb/gadget/Kconfig\n"
- "@@ -338,6 +338,23 @@ config USB_S3C2410_DEBUG\n"
- " \tboolean \"S3C2410 udc debug messages\"\n"
- " \tdepends on USB_GADGET_S3C2410\n"
- " \n"
- "+config USB_GADGET_S3C_HSUDC\n"
- "+\tboolean \"S3C2416, S3C2443 and S3C2450 USB Device Controller\"\n"
- "+\tdepends on ARCH_S3C2410\n"
- "+\tselect USB_GADGET_DUALSPEED\n"
- "+\thelp\n"
- "+\t  Samsung's S3C2416, S3C2443 and S3C2450 is an ARM9 based SoC\n"
- "+\t  integrated with dual speed USB 2.0 device controller. It has\n"
- "+\t  8 endpoints, as well as endpoint zero.\n"
- "+\n"
- "+\t  This driver has been tested on S3C2416 and S3C2450 processors.\n"
- "+\n"
- "+config USB_S3C_HSUDC\n"
- "+\ttristate\n"
- "+\tdepends on USB_GADGET_S3C_HSUDC\n"
- "+\tdefault USB_GADGET\n"
- "+\tselect USB_GADGET_SELECTED\n"
- "+\n"
- " config USB_GADGET_PXA_U2O\n"
- " \tboolean \"PXA9xx Processor USB2.0 controller\"\n"
- " \tselect USB_GADGET_DUALSPEED\n"
- "diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile\n"
- "index 55f5e8a..540783c 100644\n"
- "--- a/drivers/usb/gadget/Makefile\n"
- "+++ b/drivers/usb/gadget/Makefile\n"
- "@@ -23,6 +23,7 @@ obj-$(CONFIG_USB_R8A66597)\t+= r8a66597-udc.o\n"
- " obj-$(CONFIG_USB_FSL_QE)\t+= fsl_qe_udc.o\n"
- " obj-$(CONFIG_USB_CI13XXX_PCI)\t+= ci13xxx_pci.o\n"
- " obj-$(CONFIG_USB_S3C_HSOTG)\t+= s3c-hsotg.o\n"
- "+obj-$(CONFIG_USB_S3C_HSUDC)\t+= s3c-hsudc.o\n"
- " obj-$(CONFIG_USB_LANGWELL)\t+= langwell_udc.o\n"
- " obj-$(CONFIG_USB_EG20T)\t\t+= pch_udc.o\n"
- " obj-$(CONFIG_USB_PXA_U2O)\t+= mv_udc.o\n"
- "diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h\n"
- "index 5c2720d..836a08e 100644\n"
- "--- a/drivers/usb/gadget/gadget_chips.h\n"
- "+++ b/drivers/usb/gadget/gadget_chips.h\n"
- "@@ -142,6 +142,12 @@\n"
- " #define gadget_is_s3c_hsotg(g)    0\n"
- " #endif\n"
- " \n"
- "+#ifdef CONFIG_USB_S3C_HSUDC\n"
- "+#define gadget_is_s3c_hsudc(g) (!strcmp(\"s3c-hsudc\", (g)->name))\n"
- "+#else\n"
- "+#define gadget_is_s3c_hsudc(g) 0\n"
- "+#endif\n"
- "+\n"
- " #ifdef CONFIG_USB_GADGET_EG20T\n"
- " #define\tgadget_is_pch(g)\t(!strcmp(\"pch_udc\", (g)->name))\n"
- " #else\n"
- "@@ -215,6 +221,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)\n"
- " \t\treturn 0x27;\n"
- " \telse if (gadget_is_ci13xxx_msm(gadget))\n"
- " \t\treturn 0x28;\n"
- "+\telse if (gadget_is_s3c_hsudc(gadget))\n"
- "+\t\treturn 0x29;\n"
- " \treturn -ENOENT;\n"
- " }\n"
- " \n"
- "diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c\n"
- "new file mode 100644\n"
- "index 0000000..b98d8a1\n"
- "--- /dev/null\n"
- "+++ b/drivers/usb/gadget/s3c-hsudc.c\n"
- "@@ -0,0 +1,1329 @@\n"
- "+/* linux/drivers/usb/gadget/s3c-hsudc.c\n"
- "+ *\n"
- "+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.\n"
- "+ *\t\thttp://www.samsung.com/\n"
- "+ *\n"
- "+ * S3C24XX USB 2.0 High-speed USB controller gadget driver\n"
- "+ *\n"
- "+ * The S3C24XX USB 2.0 high-speed USB controller supports upto 9 endpoints.\n"
- "+ * Each endpoint can be configured as either in or out endpoint. Endpoints\n"
- "+ * can be configured for Bulk or Interrupt transfer mode.\n"
- "+ *\n"
- "+ * This program is free software; you can redistribute it and/or modify\n"
- "+ * it under the terms of the GNU General Public License version 2 as\n"
- "+ * published by the Free Software Foundation.\n"
- "+*/\n"
- "+\n"
- "+#include <linux/kernel.h>\n"
- "+#include <linux/module.h>\n"
- "+#include <linux/spinlock.h>\n"
- "+#include <linux/interrupt.h>\n"
- "+#include <linux/platform_device.h>\n"
- "+#include <linux/dma-mapping.h>\n"
- "+#include <linux/delay.h>\n"
- "+#include <linux/io.h>\n"
- "+#include <linux/slab.h>\n"
- "+#include <linux/clk.h>\n"
- "+#include <linux/usb/ch9.h>\n"
- "+#include <linux/usb/gadget.h>\n"
- "+\n"
- "+#include <mach/regs-s3c2443-clock.h>\n"
- "+#include <plat/udc.h>\n"
- "+\n"
- "+#define S3C_HSUDC_REG(x)\t(x)\n"
- "+\n"
- "+/* Non-Indexed Registers */\n"
- "+#define S3C_IR\t\t\t\tS3C_HSUDC_REG(0x00) /* Index Register */\n"
- "+#define S3C_EIR\t\t\t\tS3C_HSUDC_REG(0x04) /* EP Intr Status */\n"
- "+#define S3C_EIR_EP0\t\t\t(1<<0)\n"
- "+#define S3C_EIER\t\t\tS3C_HSUDC_REG(0x08) /* EP Intr Enable */\n"
- "+#define S3C_FAR\t\t\t\tS3C_HSUDC_REG(0x0c) /* Gadget Address */\n"
- "+#define S3C_FNR\t\t\t\tS3C_HSUDC_REG(0x10) /* Frame Number */\n"
- "+#define S3C_EDR\t\t\t\tS3C_HSUDC_REG(0x14) /* EP Direction */\n"
- "+#define S3C_TR\t\t\t\tS3C_HSUDC_REG(0x18) /* Test Register */\n"
- "+#define S3C_SSR\t\t\t\tS3C_HSUDC_REG(0x1c) /* System Status */\n"
- "+#define S3C_SSR_DTZIEN_EN\t\t(0xff8f)\n"
- "+#define S3C_SSR_ERR\t\t\t(0xff80)\n"
- "+#define S3C_SSR_VBUSON\t\t\t(1 << 8)\n"
- "+#define S3C_SSR_HSP\t\t\t(1 << 4)\n"
- "+#define S3C_SSR_SDE\t\t\t(1 << 3)\n"
- "+#define S3C_SSR_RESUME\t\t\t(1 << 2)\n"
- "+#define S3C_SSR_SUSPEND\t\t\t(1 << 1)\n"
- "+#define S3C_SSR_RESET\t\t\t(1 << 0)\n"
- "+#define S3C_SCR\t\t\t\tS3C_HSUDC_REG(0x20) /* System Control */\n"
- "+#define S3C_SCR_DTZIEN_EN\t\t(1 << 14)\n"
- "+#define S3C_SCR_RRD_EN\t\t\t(1 << 5)\n"
- "+#define S3C_SCR_SUS_EN\t\t\t(1 << 1)\n"
- "+#define S3C_SCR_RST_EN\t\t\t(1 << 0)\n"
- "+#define S3C_EP0SR\t\t\tS3C_HSUDC_REG(0x24) /* EP0 Status */\n"
- "+#define S3C_EP0SR_EP0_LWO\t\t(1 << 6)\n"
- "+#define S3C_EP0SR_STALL\t\t\t(1 << 4)\n"
- "+#define S3C_EP0SR_TX_SUCCESS\t\t(1 << 1)\n"
- "+#define S3C_EP0SR_RX_SUCCESS\t\t(1 << 0)\n"
- "+#define S3C_EP0CR\t\t\tS3C_HSUDC_REG(0x28) /* EP0 Control */\n"
- "+#define S3C_BR(_x)\t\t\tS3C_HSUDC_REG(0x60 + (_x * 4))\n"
- "+\n"
- "+/* Indexed Registers */\n"
- "+#define S3C_ESR\t\t\t\tS3C_HSUDC_REG(0x2c) /* EPn Status */\n"
- "+#define S3C_ESR_FLUSH\t\t\t(1 << 6)\n"
- "+#define S3C_ESR_STALL\t\t\t(1 << 5)\n"
- "+#define S3C_ESR_LWO\t\t\t(1 << 4)\n"
- "+#define S3C_ESR_PSIF_ONE\t\t(1 << 2)\n"
- "+#define S3C_ESR_PSIF_TWO\t\t(2 << 2)\n"
- "+#define S3C_ESR_TX_SUCCESS\t\t(1 << 1)\n"
- "+#define S3C_ESR_RX_SUCCESS\t\t(1 << 0)\n"
- "+#define S3C_ECR\t\t\t\tS3C_HSUDC_REG(0x30) /* EPn Control */\n"
- "+#define S3C_ECR_DUEN\t\t\t(1 << 7)\n"
- "+#define S3C_ECR_FLUSH\t\t\t(1 << 6)\n"
- "+#define S3C_ECR_STALL\t\t\t(1 << 1)\n"
- "+#define S3C_ECR_IEMS\t\t\t(1 << 0)\n"
- "+#define S3C_BRCR\t\t\tS3C_HSUDC_REG(0x34) /* Read Count */\n"
- "+#define S3C_BWCR\t\t\tS3C_HSUDC_REG(0x38) /* Write Count */\n"
- "+#define S3C_MPR\t\t\t\tS3C_HSUDC_REG(0x3c) /* Max Pkt Size */\n"
- "+\n"
- "+#define WAIT_FOR_SETUP\t\t\t(0)\n"
- "+#define DATA_STATE_XMIT\t\t\t(1)\n"
- "+#define DATA_STATE_RECV\t\t\t(2)\n"
- "+\n"
- "+/**\n"
- "+ * struct s3c_hsudc_ep - Endpoint representation used by driver.\n"
- "+ * @ep: USB gadget layer representation of device endpoint.\n"
- "+ * @name: Endpoint name (as required by ep autoconfiguration).\n"
- "+ * @dev: Reference to the device controller to which this EP belongs.\n"
- "+ * @desc: Endpoint descriptor obtained from the gadget driver.\n"
- "+ * @queue: Transfer request queue for the endpoint.\n"
- "+ * @stopped: Maintains state of endpoint, set if EP is halted.\n"
- "+ * @bEndpointAddress: EP address (including direction bit).\n"
- "+ * @fifo: Base address of EP FIFO.\n"
- "+ */\n"
- "+struct s3c_hsudc_ep {\n"
- "+\tstruct usb_ep ep;\n"
- "+\tchar name[20];\n"
- "+\tstruct s3c_hsudc *dev;\n"
- "+\tconst struct usb_endpoint_descriptor *desc;\n"
- "+\tstruct list_head queue;\n"
- "+\tu8 stopped;\n"
- "+\tu8 bEndpointAddress;\n"
- "+\tvoid __iomem *fifo;\n"
- "+};\n"
- "+\n"
- "+/**\n"
- "+ * struct s3c_hsudc_req - Driver encapsulation of USB gadget transfer request.\n"
- "+ * @req: Reference to USB gadget transfer request.\n"
- "+ * @queue: Used for inserting this request to the endpoint request queue.\n"
- "+ */\n"
- "+struct s3c_hsudc_req {\n"
- "+\tstruct usb_request req;\n"
- "+\tstruct list_head queue;\n"
- "+};\n"
- "+\n"
- "+/**\n"
- "+ * struct s3c_hsudc - Driver's abstraction of the device controller.\n"
- "+ * @gadget: Instance of usb_gadget which is referenced by gadget driver.\n"
- "+ * @driver: Reference to currenty active gadget driver.\n"
- "+ * @dev: The device reference used by probe function.\n"
- "+ * @lock: Lock to synchronize the usage of Endpoints (EP's are indexed).\n"
- "+ * @regs: Remapped base address of controller's register space.\n"
- "+ * @mem_rsrc: Device memory resource used for remapping device register space.\n"
- "+ * irq: IRQ number used by the controller.\n"
- "+ * uclk: Reference to the controller clock.\n"
- "+ * ep0state: Current state of EP0.\n"
- "+ * ep: List of endpoints supported by the controller.\n"
- "+ */\n"
- "+struct s3c_hsudc {\n"
- "+\tstruct usb_gadget gadget;\n"
- "+\tstruct usb_gadget_driver *driver;\n"
- "+\tstruct device *dev;\n"
- "+\tstruct s3c24xx_hsudc_platdata *pd;\n"
- "+\tspinlock_t lock;\n"
- "+\tvoid __iomem *regs;\n"
- "+\tstruct resource *mem_rsrc;\n"
- "+\tint irq;\n"
- "+\tstruct clk *uclk;\n"
- "+\tint ep0state;\n"
- "+\tstruct s3c_hsudc_ep ep[];\n"
- "+};\n"
- "+\n"
- "+#define ep_maxpacket(_ep)\t((_ep)->ep.maxpacket)\n"
- "+#define ep_is_in(_ep)\t\t((_ep)->bEndpointAddress & USB_DIR_IN)\n"
- "+#define ep_index(_ep)\t\t((_ep)->bEndpointAddress & \\\n"
- "+\t\t\t\t\tUSB_ENDPOINT_NUMBER_MASK)\n"
- "+\n"
- "+static struct s3c_hsudc *the_controller;\n"
- "+static const char driver_name[] = \"s3c-udc\";\n"
- "+static const char ep0name[] = \"ep0-control\";\n"
- "+\n"
- "+static inline struct s3c_hsudc_req *our_req(struct usb_request *req)\n"
- "+{\n"
- "+\treturn container_of(req, struct s3c_hsudc_req, req);\n"
- "+}\n"
- "+\n"
- "+static inline struct s3c_hsudc_ep *our_ep(struct usb_ep *ep)\n"
- "+{\n"
- "+\treturn container_of(ep, struct s3c_hsudc_ep, ep);\n"
- "+}\n"
- "+\n"
- "+static inline struct s3c_hsudc *to_hsudc(struct usb_gadget *gadget)\n"
- "+{\n"
- "+\treturn container_of(gadget, struct s3c_hsudc, gadget);\n"
- "+}\n"
- "+\n"
- "+static inline void set_index(struct s3c_hsudc *hsudc, int ep_addr)\n"
- "+{\n"
- "+\tep_addr &= USB_ENDPOINT_NUMBER_MASK;\n"
- "+\twritel(ep_addr, hsudc->regs + S3C_IR);\n"
- "+}\n"
- "+\n"
- "+static inline void __orr32(void __iomem *ptr, u32 val)\n"
- "+{\n"
- "+\twritel(readl(ptr) | val, ptr);\n"
- "+}\n"
- "+\n"
- "+static void s3c_hsudc_init_phy(void)\n"
- "+{\n"
- "+\tu32 cfg;\n"
- "+\n"
- "+\tcfg = readl(S3C2443_PWRCFG) | S3C2443_PWRCFG_USBPHY;\n"
- "+\twritel(cfg, S3C2443_PWRCFG);\n"
- "+\n"
- "+\tcfg = readl(S3C2443_URSTCON);\n"
- "+\tcfg |= (S3C2443_URSTCON_FUNCRST | S3C2443_URSTCON_PHYRST);\n"
- "+\twritel(cfg, S3C2443_URSTCON);\n"
- "+\tmdelay(1);\n"
- "+\n"
- "+\tcfg = readl(S3C2443_URSTCON);\n"
- "+\tcfg &= ~(S3C2443_URSTCON_FUNCRST | S3C2443_URSTCON_PHYRST);\n"
- "+\twritel(cfg, S3C2443_URSTCON);\n"
- "+\n"
- "+\tcfg = readl(S3C2443_PHYCTRL);\n"
- "+\tcfg &= ~(S3C2443_PHYCTRL_CLKSEL | S3C2443_PHYCTRL_DSPORT);\n"
- "+\tcfg |= (S3C2443_PHYCTRL_EXTCLK | S3C2443_PHYCTRL_PLLSEL);\n"
- "+\twritel(cfg, S3C2443_PHYCTRL);\n"
- "+\n"
- "+\tcfg = readl(S3C2443_PHYPWR);\n"
- "+\tcfg &= ~(S3C2443_PHYPWR_FSUSPEND | S3C2443_PHYPWR_PLL_PWRDN |\n"
- "+\t\tS3C2443_PHYPWR_XO_ON | S3C2443_PHYPWR_PLL_REFCLK |\n"
- "+\t\tS3C2443_PHYPWR_ANALOG_PD);\n"
- "+\tcfg |= S3C2443_PHYPWR_COMMON_ON;\n"
- "+\twritel(cfg, S3C2443_PHYPWR);\n"
- "+\n"
- "+\tcfg = readl(S3C2443_UCLKCON);\n"
- "+\tcfg |= (S3C2443_UCLKCON_DETECT_VBUS | S3C2443_UCLKCON_FUNC_CLKEN |\n"
- "+\t\tS3C2443_UCLKCON_TCLKEN);\n"
- "+\twritel(cfg, S3C2443_UCLKCON);\n"
- "+}\n"
- "+\n"
- "+static void s3c_hsudc_uninit_phy(void)\n"
- "+{\n"
- "+\tu32 cfg;\n"
- "+\n"
- "+\tcfg = readl(S3C2443_PWRCFG) & ~S3C2443_PWRCFG_USBPHY;\n"
- "+\twritel(cfg, S3C2443_PWRCFG);\n"
- "+\n"
- "+\twritel(S3C2443_PHYPWR_FSUSPEND, S3C2443_PHYPWR);\n"
- "+\n"
- "+\tcfg = readl(S3C2443_UCLKCON) & ~S3C2443_UCLKCON_FUNC_CLKEN;\n"
- "+\twritel(cfg, S3C2443_UCLKCON);\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_complete_request - Complete a transfer request.\n"
- "+ * @hsep: Endpoint to which the request belongs.\n"
- "+ * @hsreq: Transfer request to be completed.\n"
- "+ * @status: Transfer completion status for the transfer request.\n"
- "+ */\n"
- "+static void s3c_hsudc_complete_request(struct s3c_hsudc_ep *hsep,\n"
- "+\t\t\t\tstruct s3c_hsudc_req *hsreq, int status)\n"
- "+{\n"
- "+\tunsigned int stopped = hsep->stopped;\n"
- "+\tstruct s3c_hsudc *hsudc = hsep->dev;\n"
- "+\n"
- "+\tlist_del_init(&hsreq->queue);\n"
- "+\thsreq->req.status = status;\n"
- "+\n"
- "+\tif (!ep_index(hsep)) {\n"
- "+\t\thsudc->ep0state = WAIT_FOR_SETUP;\n"
- "+\t\thsep->bEndpointAddress &= ~USB_DIR_IN;\n"
- "+\t}\n"
- "+\n"
- "+\thsep->stopped = 1;\n"
- "+\tspin_unlock(&hsudc->lock);\n"
- "+\tif (hsreq->req.complete != NULL)\n"
- "+\t\thsreq->req.complete(&hsep->ep, &hsreq->req);\n"
- "+\tspin_lock(&hsudc->lock);\n"
- "+\thsep->stopped = stopped;\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_nuke_ep - Terminate all requests queued for a endpoint.\n"
- "+ * @hsep: Endpoint for which queued requests have to be terminated.\n"
- "+ * @status: Transfer completion status for the transfer request.\n"
- "+ */\n"
- "+static void s3c_hsudc_nuke_ep(struct s3c_hsudc_ep *hsep, int status)\n"
- "+{\n"
- "+\tstruct s3c_hsudc_req *hsreq;\n"
- "+\n"
- "+\twhile (!list_empty(&hsep->queue)) {\n"
- "+\t\thsreq = list_entry(hsep->queue.next,\n"
- "+\t\t\t\tstruct s3c_hsudc_req, queue);\n"
- "+\t\ts3c_hsudc_complete_request(hsep, hsreq, status);\n"
- "+\t}\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_stop_activity - Stop activity on all endpoints.\n"
- "+ * @hsudc: Device controller for which EP activity is to be stopped.\n"
- "+ * @driver: Reference to the gadget driver which is currently active.\n"
- "+ *\n"
- "+ * All the endpoints are stopped and any pending transfer requests if any on\n"
- "+ * the endpoint are terminated.\n"
- "+ */\n"
- "+static void s3c_hsudc_stop_activity(struct s3c_hsudc *hsudc,\n"
- "+\t\t\t  struct usb_gadget_driver *driver)\n"
- "+{\n"
- "+\tstruct s3c_hsudc_ep *hsep;\n"
- "+\tint epnum;\n"
- "+\n"
- "+\thsudc->gadget.speed = USB_SPEED_UNKNOWN;\n"
- "+\n"
- "+\tfor (epnum = 0; epnum < hsudc->pd->epnum; epnum++) {\n"
- "+\t\thsep = &hsudc->ep[epnum];\n"
- "+\t\thsep->stopped = 1;\n"
- "+\t\ts3c_hsudc_nuke_ep(hsep, -ESHUTDOWN);\n"
- "+\t}\n"
- "+\n"
- "+\tspin_unlock(&hsudc->lock);\n"
- "+\tdriver->disconnect(&hsudc->gadget);\n"
- "+\tspin_lock(&hsudc->lock);\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_read_setup_pkt - Read the received setup packet from EP0 fifo.\n"
- "+ * @hsudc: Device controller from which setup packet is to be read.\n"
- "+ * @buf: The buffer into which the setup packet is read.\n"
- "+ *\n"
- "+ * The setup packet received in the EP0 fifo is read and stored into a\n"
- "+ * given buffer address.\n"
- "+ */\n"
- "+\n"
- "+static void s3c_hsudc_read_setup_pkt(struct s3c_hsudc *hsudc, u16 *buf)\n"
- "+{\n"
- "+\tint count;\n"
- "+\n"
- "+\tcount = readl(hsudc->regs + S3C_BRCR);\n"
- "+\twhile (count--)\n"
- "+\t\t*buf++ = (u16)readl(hsudc->regs + S3C_BR(0));\n"
- "+\n"
- "+\twritel(S3C_EP0SR_RX_SUCCESS, hsudc->regs + S3C_EP0SR);\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_write_fifo - Write next chunk of transfer data to EP fifo.\n"
- "+ * @hsep: Endpoint to which the data is to be written.\n"
- "+ * @hsreq: Transfer request from which the next chunk of data is written.\n"
- "+ *\n"
- "+ * Write the next chunk of data from a transfer request to the endpoint FIFO.\n"
- "+ * If the transfer request completes, 1 is returned, otherwise 0 is returned.\n"
- "+ */\n"
- "+static int s3c_hsudc_write_fifo(struct s3c_hsudc_ep *hsep,\n"
- "+\t\t\t\tstruct s3c_hsudc_req *hsreq)\n"
- "+{\n"
- "+\tu16 *buf;\n"
- "+\tu32 max = ep_maxpacket(hsep);\n"
- "+\tu32 count, length;\n"
- "+\tbool is_last;\n"
- "+\tvoid __iomem *fifo = hsep->fifo;\n"
- "+\n"
- "+\tbuf = hsreq->req.buf + hsreq->req.actual;\n"
- "+\tprefetch(buf);\n"
- "+\n"
- "+\tlength = hsreq->req.length - hsreq->req.actual;\n"
- "+\tlength = min(length, max);\n"
- "+\thsreq->req.actual += length;\n"
- "+\n"
- "+\twritel(length, hsep->dev->regs + S3C_BWCR);\n"
- "+\tfor (count = 0; count < length; count += 2)\n"
- "+\t\twritel(*buf++, fifo);\n"
- "+\n"
- "+\tif (count != max) {\n"
- "+\t\tis_last = true;\n"
- "+\t} else {\n"
- "+\t\tif (hsreq->req.length != hsreq->req.actual || hsreq->req.zero)\n"
- "+\t\t\tis_last = false;\n"
- "+\t\telse\n"
- "+\t\t\tis_last = true;\n"
- "+\t}\n"
- "+\n"
- "+\tif (is_last) {\n"
- "+\t\ts3c_hsudc_complete_request(hsep, hsreq, 0);\n"
- "+\t\treturn 1;\n"
- "+\t}\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_read_fifo - Read the next chunk of data from EP fifo.\n"
- "+ * @hsep: Endpoint from which the data is to be read.\n"
- "+ * @hsreq: Transfer request to which the next chunk of data read is written.\n"
- "+ *\n"
- "+ * Read the next chunk of data from the endpoint FIFO and a write it to the\n"
- "+ * transfer request buffer. If the transfer request completes, 1 is returned,\n"
- "+ * otherwise 0 is returned.\n"
- "+ */\n"
- "+static int s3c_hsudc_read_fifo(struct s3c_hsudc_ep *hsep,\n"
- "+\t\t\t\tstruct s3c_hsudc_req *hsreq)\n"
- "+{\n"
- "+\tstruct s3c_hsudc *hsudc = hsep->dev;\n"
- "+\tu32 csr, offset;\n"
- "+\tu16 *buf, word;\n"
- "+\tu32 buflen, rcnt, rlen;\n"
- "+\tvoid __iomem *fifo = hsep->fifo;\n"
- "+\tu32 is_short = 0;\n"
- "+\n"
- "+\toffset = (ep_index(hsep)) ? S3C_ESR : S3C_EP0SR;\n"
- "+\tcsr = readl(hsudc->regs + offset);\n"
- "+\tif (!(csr & S3C_ESR_RX_SUCCESS))\n"
- "+\t\treturn -EINVAL;\n"
- "+\n"
- "+\tbuf = hsreq->req.buf + hsreq->req.actual;\n"
- "+\tprefetchw(buf);\n"
- "+\tbuflen = hsreq->req.length - hsreq->req.actual;\n"
- "+\n"
- "+\trcnt = readl(hsudc->regs + S3C_BRCR);\n"
- "+\trlen = (csr & S3C_ESR_LWO) ? (rcnt * 2 - 1) : (rcnt * 2);\n"
- "+\n"
- "+\thsreq->req.actual += min(rlen, buflen);\n"
- "+\tis_short = (rlen < hsep->ep.maxpacket);\n"
- "+\n"
- "+\twhile (rcnt-- != 0) {\n"
- "+\t\tword = (u16)readl(fifo);\n"
- "+\t\tif (buflen) {\n"
- "+\t\t\t*buf++ = word;\n"
- "+\t\t\tbuflen--;\n"
- "+\t\t} else {\n"
- "+\t\t\thsreq->req.status = -EOVERFLOW;\n"
- "+\t\t}\n"
- "+\t}\n"
- "+\n"
- "+\twritel(S3C_ESR_RX_SUCCESS, hsudc->regs + offset);\n"
- "+\n"
- "+\tif (is_short || hsreq->req.actual == hsreq->req.length) {\n"
- "+\t\ts3c_hsudc_complete_request(hsep, hsreq, 0);\n"
- "+\t\treturn 1;\n"
- "+\t}\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_epin_intr - Handle in-endpoint interrupt.\n"
- "+ * @hsudc - Device controller for which the interrupt is to be handled.\n"
- "+ * @ep_idx - Endpoint number on which an interrupt is pending.\n"
- "+ *\n"
- "+ * Handles interrupt for a in-endpoint. The interrupts that are handled are\n"
- "+ * stall and data transmit complete interrupt.\n"
- "+ */\n"
- "+static void s3c_hsudc_epin_intr(struct s3c_hsudc *hsudc, u32 ep_idx)\n"
- "+{\n"
- "+\tstruct s3c_hsudc_ep *hsep = &hsudc->ep[ep_idx];\n"
- "+\tstruct s3c_hsudc_req *hsreq;\n"
- "+\tu32 csr;\n"
- "+\n"
- "+\tcsr = readl((u32)hsudc->regs + S3C_ESR);\n"
- "+\tif (csr & S3C_ESR_STALL) {\n"
- "+\t\twritel(S3C_ESR_STALL, hsudc->regs + S3C_ESR);\n"
- "+\t\treturn;\n"
- "+\t}\n"
- "+\n"
- "+\tif (csr & S3C_ESR_TX_SUCCESS) {\n"
- "+\t\twritel(S3C_ESR_TX_SUCCESS, hsudc->regs + S3C_ESR);\n"
- "+\t\tif (list_empty(&hsep->queue))\n"
- "+\t\t\treturn;\n"
- "+\n"
- "+\t\thsreq = list_entry(hsep->queue.next,\n"
- "+\t\t\t\tstruct s3c_hsudc_req, queue);\n"
- "+\t\tif ((s3c_hsudc_write_fifo(hsep, hsreq) == 0) &&\n"
- "+\t\t\t\t(csr & S3C_ESR_PSIF_TWO))\n"
- "+\t\t\ts3c_hsudc_write_fifo(hsep, hsreq);\n"
- "+\t}\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_epout_intr - Handle out-endpoint interrupt.\n"
- "+ * @hsudc - Device controller for which the interrupt is to be handled.\n"
- "+ * @ep_idx - Endpoint number on which an interrupt is pending.\n"
- "+ *\n"
- "+ * Handles interrupt for a out-endpoint. The interrupts that are handled are\n"
- "+ * stall, flush and data ready interrupt.\n"
- "+ */\n"
- "+static void s3c_hsudc_epout_intr(struct s3c_hsudc *hsudc, u32 ep_idx)\n"
- "+{\n"
- "+\tstruct s3c_hsudc_ep *hsep = &hsudc->ep[ep_idx];\n"
- "+\tstruct s3c_hsudc_req *hsreq;\n"
- "+\tu32 csr;\n"
- "+\n"
- "+\tcsr = readl((u32)hsudc->regs + S3C_ESR);\n"
- "+\tif (csr & S3C_ESR_STALL) {\n"
- "+\t\twritel(S3C_ESR_STALL, hsudc->regs + S3C_ESR);\n"
- "+\t\treturn;\n"
- "+\t}\n"
- "+\n"
- "+\tif (csr & S3C_ESR_FLUSH) {\n"
- "+\t\t__orr32(hsudc->regs + S3C_ECR, S3C_ECR_FLUSH);\n"
- "+\t\treturn;\n"
- "+\t}\n"
- "+\n"
- "+\tif (csr & S3C_ESR_RX_SUCCESS) {\n"
- "+\t\tif (list_empty(&hsep->queue))\n"
- "+\t\t\treturn;\n"
- "+\n"
- "+\t\thsreq = list_entry(hsep->queue.next,\n"
- "+\t\t\t\tstruct s3c_hsudc_req, queue);\n"
- "+\t\tif (((s3c_hsudc_read_fifo(hsep, hsreq)) == 0) &&\n"
- "+\t\t\t\t(csr & S3C_ESR_PSIF_TWO))\n"
- "+\t\t\ts3c_hsudc_read_fifo(hsep, hsreq);\n"
- "+\t}\n"
- "+}\n"
- "+\n"
- "+/** s3c_hsudc_set_halt - Set or clear a endpoint halt.\n"
- "+ * @_ep: Endpoint on which halt has to be set or cleared.\n"
- "+ * @value: 1 for setting halt on endpoint, 0 to clear halt.\n"
- "+ *\n"
- "+ * Set or clear endpoint halt. If halt is set, the endpoint is stopped.\n"
- "+ * If halt is cleared, for in-endpoints, if there are any pending\n"
- "+ * transfer requests, transfers are started.\n"
- "+ */\n"
- "+static int s3c_hsudc_set_halt(struct usb_ep *_ep, int value)\n"
- "+{\n"
- "+\tstruct s3c_hsudc_ep *hsep = our_ep(_ep);\n"
- "+\tstruct s3c_hsudc *hsudc = hsep->dev;\n"
- "+\tstruct s3c_hsudc_req *hsreq;\n"
- "+\tunsigned long irqflags;\n"
- "+\tu32 ecr;\n"
- "+\tu32 offset;\n"
- "+\n"
- "+\tif (value && ep_is_in(hsep) && !list_empty(&hsep->queue))\n"
- "+\t\treturn -EAGAIN;\n"
- "+\n"
- "+\tspin_lock_irqsave(&hsudc->lock, irqflags);\n"
- "+\tset_index(hsudc, ep_index(hsep));\n"
- "+\toffset = (ep_index(hsep)) ? S3C_ECR : S3C_EP0CR;\n"
- "+\tecr = readl(hsudc->regs + offset);\n"
- "+\n"
- "+\tif (value) {\n"
- "+\t\tecr |= S3C_ECR_STALL;\n"
- "+\t\tif (ep_index(hsep))\n"
- "+\t\t\tecr |= S3C_ECR_FLUSH;\n"
- "+\t\thsep->stopped = 1;\n"
- "+\t} else {\n"
- "+\t\tecr &= ~S3C_ECR_STALL;\n"
- "+\t\thsep->stopped = 0;\n"
- "+\t}\n"
- "+\twritel(ecr, hsudc->regs + offset);\n"
- "+\n"
- "+\tif (ep_is_in(hsep) && !list_empty(&hsep->queue) && !value) {\n"
- "+\t\thsreq = list_entry(hsep->queue.next,\n"
- "+\t\t\tstruct s3c_hsudc_req, queue);\n"
- "+\t\tif (hsreq)\n"
- "+\t\t\ts3c_hsudc_write_fifo(hsep, hsreq);\n"
- "+\t}\n"
- "+\n"
- "+\tspin_unlock_irqrestore(&hsudc->lock, irqflags);\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+/** s3c_hsudc_handle_reqfeat - Handle set feature or clear feature requests.\n"
- "+ * @_ep: Device controller on which the set/clear feature needs to be handled.\n"
- "+ * @ctrl: Control request as received on the endpoint 0.\n"
- "+ *\n"
- "+ * Handle set feature or clear feature control requests on the control endpoint.\n"
- "+ */\n"
- "+static int s3c_hsudc_handle_reqfeat(struct s3c_hsudc *hsudc,\n"
- "+\t\t\t\t\tstruct usb_ctrlrequest *ctrl)\n"
- "+{\n"
- "+\tstruct s3c_hsudc_ep *hsep;\n"
- "+\tbool set = (ctrl->bRequest == USB_REQ_SET_FEATURE);\n"
- "+\tu8 ep_num = ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK;\n"
- "+\n"
- "+\tif (ctrl->bRequestType == USB_RECIP_ENDPOINT) {\n"
- "+\t\thsep = &hsudc->ep[ep_num];\n"
- "+\t\tswitch (le16_to_cpu(ctrl->wValue)) {\n"
- "+\t\tcase USB_ENDPOINT_HALT:\n"
- "+\t\t\ts3c_hsudc_set_halt(&hsep->ep, set);\n"
- "+\t\t\treturn 0;\n"
- "+\t\t}\n"
- "+\t}\n"
- "+\n"
- "+\treturn -ENOENT;\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_process_req_status - Handle get status control request.\n"
- "+ * @hsudc: Device controller on which get status request has be handled.\n"
- "+ * @ctrl: Control request as received on the endpoint 0.\n"
- "+ *\n"
- "+ * Handle get status control request received on control endpoint.\n"
- "+ */\n"
- "+static void s3c_hsudc_process_req_status(struct s3c_hsudc *hsudc,\n"
- "+\t\t\t\t\tstruct usb_ctrlrequest *ctrl)\n"
- "+{\n"
- "+\tstruct s3c_hsudc_ep *hsep0 = &hsudc->ep[0];\n"
- "+\tstruct s3c_hsudc_req hsreq;\n"
- "+\tstruct s3c_hsudc_ep *hsep;\n"
- "+\t__le16 reply;\n"
- "+\tu8 epnum;\n"
- "+\n"
- "+\tswitch (ctrl->bRequestType & USB_RECIP_MASK) {\n"
- "+\tcase USB_RECIP_DEVICE:\n"
- "+\t\treply = cpu_to_le16(0);\n"
- "+\t\tbreak;\n"
- "+\n"
- "+\tcase USB_RECIP_INTERFACE:\n"
- "+\t\treply = cpu_to_le16(0);\n"
- "+\t\tbreak;\n"
- "+\n"
- "+\tcase USB_RECIP_ENDPOINT:\n"
- "+\t\tepnum = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK;\n"
- "+\t\thsep = &hsudc->ep[epnum];\n"
- "+\t\treply = cpu_to_le16(hsep->stopped ? 1 : 0);\n"
- "+\t\tbreak;\n"
- "+\t}\n"
- "+\n"
- "+\tINIT_LIST_HEAD(&hsreq.queue);\n"
- "+\thsreq.req.length = 2;\n"
- "+\thsreq.req.buf = &reply;\n"
- "+\thsreq.req.actual = 0;\n"
- "+\thsreq.req.complete = NULL;\n"
- "+\ts3c_hsudc_write_fifo(hsep0, &hsreq);\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_process_setup - Process control request received on endpoint 0.\n"
- "+ * @hsudc: Device controller on which control request has been received.\n"
- "+ *\n"
- "+ * Read the control request received on endpoint 0, decode it and handle\n"
- "+ * the request.\n"
- "+ */\n"
- "+static void s3c_hsudc_process_setup(struct s3c_hsudc *hsudc)\n"
- "+{\n"
- "+\tstruct s3c_hsudc_ep *hsep = &hsudc->ep[0];\n"
- "+\tstruct usb_ctrlrequest ctrl = {0};\n"
- "+\tint ret;\n"
- "+\n"
- "+\ts3c_hsudc_nuke_ep(hsep, -EPROTO);\n"
- "+\ts3c_hsudc_read_setup_pkt(hsudc, (u16 *)&ctrl);\n"
- "+\n"
- "+\tif (ctrl.bRequestType & USB_DIR_IN) {\n"
- "+\t\thsep->bEndpointAddress |= USB_DIR_IN;\n"
- "+\t\thsudc->ep0state = DATA_STATE_XMIT;\n"
- "+\t} else {\n"
- "+\t\thsep->bEndpointAddress &= ~USB_DIR_IN;\n"
- "+\t\thsudc->ep0state = DATA_STATE_RECV;\n"
- "+\t}\n"
- "+\n"
- "+\tswitch (ctrl.bRequest) {\n"
- "+\tcase USB_REQ_SET_ADDRESS:\n"
- "+\t\tif (ctrl.bRequestType != (USB_TYPE_STANDARD | USB_RECIP_DEVICE))\n"
- "+\t\t\tbreak;\n"
- "+\t\thsudc->ep0state = WAIT_FOR_SETUP;\n"
- "+\t\treturn;\n"
- "+\n"
- "+\tcase USB_REQ_GET_STATUS:\n"
- "+\t\tif ((ctrl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD)\n"
- "+\t\t\tbreak;\n"
- "+\t\ts3c_hsudc_process_req_status(hsudc, &ctrl);\n"
- "+\t\treturn;\n"
- "+\n"
- "+\tcase USB_REQ_SET_FEATURE:\n"
- "+\tcase USB_REQ_CLEAR_FEATURE:\n"
- "+\t\tif ((ctrl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD)\n"
- "+\t\t\tbreak;\n"
- "+\t\ts3c_hsudc_handle_reqfeat(hsudc, &ctrl);\n"
- "+\t\thsudc->ep0state = WAIT_FOR_SETUP;\n"
- "+\t\treturn;\n"
- "+\t}\n"
- "+\n"
- "+\tif (hsudc->driver) {\n"
- "+\t\tspin_unlock(&hsudc->lock);\n"
- "+\t\tret = hsudc->driver->setup(&hsudc->gadget, &ctrl);\n"
- "+\t\tspin_lock(&hsudc->lock);\n"
- "+\n"
- "+\t\tif (ctrl.bRequest == USB_REQ_SET_CONFIGURATION) {\n"
- "+\t\t\thsep->bEndpointAddress &= ~USB_DIR_IN;\n"
- "+\t\t\thsudc->ep0state = WAIT_FOR_SETUP;\n"
- "+\t\t}\n"
- "+\n"
- "+\t\tif (ret < 0) {\n"
- "+\t\t\tdev_err(hsudc->dev, \"setup failed, returned %d\\n\",\n"
- "+\t\t\t\t\t\tret);\n"
- "+\t\t\ts3c_hsudc_set_halt(&hsep->ep, 1);\n"
- "+\t\t\thsudc->ep0state = WAIT_FOR_SETUP;\n"
- "+\t\t\thsep->bEndpointAddress &= ~USB_DIR_IN;\n"
- "+\t\t}\n"
- "+\t}\n"
- "+}\n"
- "+\n"
- "+/** s3c_hsudc_handle_ep0_intr - Handle endpoint 0 interrupt.\n"
- "+ * @hsudc: Device controller on which endpoint 0 interrupt has occured.\n"
- "+ *\n"
- "+ * Handle endpoint 0 interrupt when it occurs. EP0 interrupt could occur\n"
- "+ * when a stall handshake is sent to host or data is sent/received on\n"
- "+ * endpoint 0.\n"
- "+ */\n"
- "+static void s3c_hsudc_handle_ep0_intr(struct s3c_hsudc *hsudc)\n"
- "+{\n"
- "+\tstruct s3c_hsudc_ep *hsep = &hsudc->ep[0];\n"
- "+\tstruct s3c_hsudc_req *hsreq;\n"
- "+\tu32 csr = readl(hsudc->regs + S3C_EP0SR);\n"
- "+\tu32 ecr;\n"
- "+\n"
- "+\tif (csr & S3C_EP0SR_STALL) {\n"
- "+\t\tecr = readl(hsudc->regs + S3C_EP0CR);\n"
- "+\t\tecr &= ~(S3C_ECR_STALL | S3C_ECR_FLUSH);\n"
- "+\t\twritel(ecr, hsudc->regs + S3C_EP0CR);\n"
- "+\n"
- "+\t\twritel(S3C_EP0SR_STALL, hsudc->regs + S3C_EP0SR);\n"
- "+\t\thsep->stopped = 0;\n"
- "+\n"
- "+\t\ts3c_hsudc_nuke_ep(hsep, -ECONNABORTED);\n"
- "+\t\thsudc->ep0state = WAIT_FOR_SETUP;\n"
- "+\t\thsep->bEndpointAddress &= ~USB_DIR_IN;\n"
- "+\t\treturn;\n"
- "+\t}\n"
- "+\n"
- "+\tif (csr & S3C_EP0SR_TX_SUCCESS) {\n"
- "+\t\twritel(S3C_EP0SR_TX_SUCCESS, hsudc->regs + S3C_EP0SR);\n"
- "+\t\tif (ep_is_in(hsep)) {\n"
- "+\t\t\tif (list_empty(&hsep->queue))\n"
- "+\t\t\t\treturn;\n"
- "+\n"
- "+\t\t\thsreq = list_entry(hsep->queue.next,\n"
- "+\t\t\t\t\tstruct s3c_hsudc_req, queue);\n"
- "+\t\t\ts3c_hsudc_write_fifo(hsep, hsreq);\n"
- "+\t\t}\n"
- "+\t}\n"
- "+\n"
- "+\tif (csr & S3C_EP0SR_RX_SUCCESS) {\n"
- "+\t\tif (hsudc->ep0state == WAIT_FOR_SETUP)\n"
- "+\t\t\ts3c_hsudc_process_setup(hsudc);\n"
- "+\t\telse {\n"
- "+\t\t\tif (!ep_is_in(hsep)) {\n"
- "+\t\t\t\tif (list_empty(&hsep->queue))\n"
- "+\t\t\t\t\treturn;\n"
- "+\t\t\t\thsreq = list_entry(hsep->queue.next,\n"
- "+\t\t\t\t\tstruct s3c_hsudc_req, queue);\n"
- "+\t\t\t\ts3c_hsudc_read_fifo(hsep, hsreq);\n"
- "+\t\t\t}\n"
- "+\t\t}\n"
- "+\t}\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_ep_enable - Enable a endpoint.\n"
- "+ * @_ep: The endpoint to be enabled.\n"
- "+ * @desc: Endpoint descriptor.\n"
- "+ *\n"
- "+ * Enables a endpoint when called from the gadget driver. Endpoint stall if\n"
- "+ * any is cleared, transfer type is configured and endpoint interrupt is\n"
- "+ * enabled.\n"
- "+ */\n"
- "+static int s3c_hsudc_ep_enable(struct usb_ep *_ep,\n"
- "+\t\t\t\tconst struct usb_endpoint_descriptor *desc)\n"
- "+{\n"
- "+\tstruct s3c_hsudc_ep *hsep;\n"
- "+\tstruct s3c_hsudc *hsudc;\n"
- "+\tunsigned long flags;\n"
- "+\tu32 ecr = 0;\n"
- "+\n"
- "+\thsep = container_of(_ep, struct s3c_hsudc_ep, ep);\n"
- "+\tif (!_ep || !desc || hsep->desc || _ep->name == ep0name\n"
- "+\t\t|| desc->bDescriptorType != USB_DT_ENDPOINT\n"
- "+\t\t|| hsep->bEndpointAddress != desc->bEndpointAddress\n"
- "+\t\t|| ep_maxpacket(hsep) < le16_to_cpu(desc->wMaxPacketSize))\n"
- "+\t\treturn -EINVAL;\n"
- "+\n"
- "+\tif ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK\n"
- "+\t\t&& le16_to_cpu(desc->wMaxPacketSize) != ep_maxpacket(hsep))\n"
- "+\t\t|| !desc->wMaxPacketSize)\n"
- "+\t\treturn -ERANGE;\n"
- "+\n"
- "+\thsudc = hsep->dev;\n"
- "+\tif (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN)\n"
- "+\t\treturn -ESHUTDOWN;\n"
- "+\n"
- "+\tspin_lock_irqsave(&hsudc->lock, flags);\n"
- "+\n"
- "+\tset_index(hsudc, hsep->bEndpointAddress);\n"
- "+\tecr |= ((usb_endpoint_xfer_int(desc)) ? S3C_ECR_IEMS : S3C_ECR_DUEN);\n"
- "+\twritel(ecr, hsudc->regs + S3C_ECR);\n"
- "+\n"
- "+\thsep->stopped = 0;\n"
- "+\thsep->desc = desc;\n"
- "+\thsep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize);\n"
- "+\n"
- "+\ts3c_hsudc_set_halt(_ep, 0);\n"
- "+\t__set_bit(ep_index(hsep), hsudc->regs + S3C_EIER);\n"
- "+\n"
- "+\tspin_unlock_irqrestore(&hsudc->lock, flags);\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_ep_disable - Disable a endpoint.\n"
- "+ * @_ep: The endpoint to be disabled.\n"
- "+ * @desc: Endpoint descriptor.\n"
- "+ *\n"
- "+ * Disables a endpoint when called from the gadget driver.\n"
- "+ */\n"
- "+static int s3c_hsudc_ep_disable(struct usb_ep *_ep)\n"
- "+{\n"
- "+\tstruct s3c_hsudc_ep *hsep = our_ep(_ep);\n"
- "+\tstruct s3c_hsudc *hsudc = hsep->dev;\n"
- "+\tunsigned long flags;\n"
- "+\n"
- "+\tif (!_ep || !hsep->desc)\n"
- "+\t\treturn -EINVAL;\n"
- "+\n"
- "+\tspin_lock_irqsave(&hsudc->lock, flags);\n"
- "+\n"
- "+\tset_index(hsudc, hsep->bEndpointAddress);\n"
- "+\t__clear_bit(ep_index(hsep), hsudc->regs + S3C_EIER);\n"
- "+\n"
- "+\ts3c_hsudc_nuke_ep(hsep, -ESHUTDOWN);\n"
- "+\n"
- "+\thsep->desc = 0;\n"
- "+\thsep->stopped = 1;\n"
- "+\n"
- "+\tspin_unlock_irqrestore(&hsudc->lock, flags);\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_alloc_request - Allocate a new request.\n"
- "+ * @_ep: Endpoint for which request is allocated (not used).\n"
- "+ * @gfp_flags: Flags used for the allocation.\n"
- "+ *\n"
- "+ * Allocates a single transfer request structure when called from gadget driver.\n"
- "+ */\n"
- "+static struct usb_request *s3c_hsudc_alloc_request(struct usb_ep *_ep,\n"
- "+\t\t\t\t\t\tgfp_t gfp_flags)\n"
- "+{\n"
- "+\tstruct s3c_hsudc_req *hsreq;\n"
- "+\n"
- "+\thsreq = kzalloc(sizeof *hsreq, gfp_flags);\n"
- "+\tif (!hsreq)\n"
- "+\t\treturn 0;\n"
- "+\n"
- "+\tINIT_LIST_HEAD(&hsreq->queue);\n"
- "+\treturn &hsreq->req;\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_free_request - Deallocate a request.\n"
- "+ * @ep: Endpoint for which request is deallocated (not used).\n"
- "+ * @_req: Request to be deallocated.\n"
- "+ *\n"
- "+ * Allocates a single transfer request structure when called from gadget driver.\n"
- "+ */\n"
- "+static void s3c_hsudc_free_request(struct usb_ep *ep, struct usb_request *_req)\n"
- "+{\n"
- "+\tstruct s3c_hsudc_req *hsreq;\n"
- "+\n"
- "+\thsreq = container_of(_req, struct s3c_hsudc_req, req);\n"
- "+\tWARN_ON(!list_empty(&hsreq->queue));\n"
- "+\tkfree(hsreq);\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_queue - Queue a transfer request for the endpoint.\n"
- "+ * @_ep: Endpoint for which the request is queued.\n"
- "+ * @_req: Request to be queued.\n"
- "+ * @gfp_flags: Not used.\n"
- "+ *\n"
- "+ * Start or enqueue a request for a endpoint when called from gadget driver.\n"
- "+ */\n"
- "+static int s3c_hsudc_queue(struct usb_ep *_ep, struct usb_request *_req,\n"
- "+\t\t\tgfp_t gfp_flags)\n"
- "+{\n"
- "+\tstruct s3c_hsudc_req *hsreq;\n"
- "+\tstruct s3c_hsudc_ep *hsep;\n"
- "+\tstruct s3c_hsudc *hsudc;\n"
- "+\tunsigned long flags;\n"
- "+\tu32 offset;\n"
- "+\tu32 csr;\n"
- "+\n"
- "+\thsreq = container_of(_req, struct s3c_hsudc_req, req);\n"
- "+\tif ((!_req || !_req->complete || !_req->buf ||\n"
- "+\t\t!list_empty(&hsreq->queue)))\n"
- "+\t\treturn -EINVAL;\n"
- "+\n"
- "+\thsep = container_of(_ep, struct s3c_hsudc_ep, ep);\n"
- "+\thsudc = hsep->dev;\n"
- "+\tif (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN)\n"
- "+\t\treturn -ESHUTDOWN;\n"
- "+\n"
- "+\tspin_lock_irqsave(&hsudc->lock, flags);\n"
- "+\tset_index(hsudc, hsep->bEndpointAddress);\n"
- "+\n"
- "+\t_req->status = -EINPROGRESS;\n"
- "+\t_req->actual = 0;\n"
- "+\n"
- "+\tif (!ep_index(hsep) && _req->length == 0) {\n"
- "+\t\thsudc->ep0state = WAIT_FOR_SETUP;\n"
- "+\t\ts3c_hsudc_complete_request(hsep, hsreq, 0);\n"
- "+\t\tspin_unlock_irqrestore(&hsudc->lock, flags);\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+\n"
- "+\tif (list_empty(&hsep->queue) && !hsep->stopped) {\n"
- "+\t\toffset = (ep_index(hsep)) ? S3C_ESR : S3C_EP0SR;\n"
- "+\t\tif (ep_is_in(hsep)) {\n"
- "+\t\t\tcsr = readl((u32)hsudc->regs + offset);\n"
- "+\t\t\tif (!(csr & S3C_ESR_TX_SUCCESS) &&\n"
- "+\t\t\t\t(s3c_hsudc_write_fifo(hsep, hsreq) == 1))\n"
- "+\t\t\t\thsreq = 0;\n"
- "+\t\t} else {\n"
- "+\t\t\tcsr = readl((u32)hsudc->regs + offset);\n"
- "+\t\t\tif ((csr & S3C_ESR_RX_SUCCESS)\n"
- "+\t\t\t\t   && (s3c_hsudc_read_fifo(hsep, hsreq) == 1))\n"
- "+\t\t\t\thsreq = 0;\n"
- "+\t\t}\n"
- "+\t}\n"
- "+\n"
- "+\tif (hsreq != 0)\n"
- "+\t\tlist_add_tail(&hsreq->queue, &hsep->queue);\n"
- "+\n"
- "+\tspin_unlock_irqrestore(&hsudc->lock, flags);\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_dequeue - Dequeue a transfer request from an endpoint.\n"
- "+ * @_ep: Endpoint from which the request is dequeued.\n"
- "+ * @_req: Request to be dequeued.\n"
- "+ *\n"
- "+ * Dequeue a request from a endpoint when called from gadget driver.\n"
- "+ */\n"
- "+static int s3c_hsudc_dequeue(struct usb_ep *_ep, struct usb_request *_req)\n"
- "+{\n"
- "+\tstruct s3c_hsudc_ep *hsep = our_ep(_ep);\n"
- "+\tstruct s3c_hsudc *hsudc = hsep->dev;\n"
- "+\tstruct s3c_hsudc_req *hsreq;\n"
- "+\tunsigned long flags;\n"
- "+\n"
- "+\thsep = container_of(_ep, struct s3c_hsudc_ep, ep);\n"
- "+\tif (!_ep || hsep->ep.name == ep0name)\n"
- "+\t\treturn -EINVAL;\n"
- "+\n"
- "+\tspin_lock_irqsave(&hsudc->lock, flags);\n"
- "+\n"
- "+\tlist_for_each_entry(hsreq, &hsep->queue, queue) {\n"
- "+\t\tif (&hsreq->req == _req)\n"
- "+\t\t\tbreak;\n"
- "+\t}\n"
- "+\tif (&hsreq->req != _req) {\n"
- "+\t\tspin_unlock_irqrestore(&hsudc->lock, flags);\n"
- "+\t\treturn -EINVAL;\n"
- "+\t}\n"
- "+\n"
- "+\tset_index(hsudc, hsep->bEndpointAddress);\n"
- "+\ts3c_hsudc_complete_request(hsep, hsreq, -ECONNRESET);\n"
- "+\n"
- "+\tspin_unlock_irqrestore(&hsudc->lock, flags);\n"
- "+\treturn 0;\n"
- "+}\n"
- "+\n"
- "+static struct usb_ep_ops s3c_hsudc_ep_ops = {\n"
- "+\t.enable = s3c_hsudc_ep_enable,\n"
- "+\t.disable = s3c_hsudc_ep_disable,\n"
- "+\t.alloc_request = s3c_hsudc_alloc_request,\n"
- "+\t.free_request = s3c_hsudc_free_request,\n"
- "+\t.queue = s3c_hsudc_queue,\n"
- "+\t.dequeue = s3c_hsudc_dequeue,\n"
- "+\t.set_halt = s3c_hsudc_set_halt,\n"
- "+};\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_initep - Initialize a endpoint to default state.\n"
- "+ * @hsudc - Reference to the device controller.\n"
- "+ * @hsep - Endpoint to be initialized.\n"
- "+ * @epnum - Address to be assigned to the endpoint.\n"
- "+ *\n"
- "+ * Initialize a endpoint with default configuration.\n"
- "+ */\n"
- "+static void s3c_hsudc_initep(struct s3c_hsudc *hsudc,\n"
- "+\t\t\t\tstruct s3c_hsudc_ep *hsep, int epnum)\n"
- "+{\n"
- "+\tchar *dir;\n"
- "+\n"
- "+\tif ((epnum % 2) == 0) {\n"
- "+\t\tdir = \"out\";\n"
- "+\t} else {\n"
- "+\t\tdir = \"in\";\n"
- "+\t\thsep->bEndpointAddress = USB_DIR_IN;\n"
- "+\t}\n"
- "+\n"
- "+\thsep->bEndpointAddress |= epnum;\n"
- "+\tif (epnum)\n"
- "+\t\tsnprintf(hsep->name, sizeof(hsep->name), \"ep%d%s\", epnum, dir);\n"
- "+\telse\n"
- "+\t\tsnprintf(hsep->name, sizeof(hsep->name), \"%s\", ep0name);\n"
- "+\n"
- "+\tINIT_LIST_HEAD(&hsep->queue);\n"
- "+\tINIT_LIST_HEAD(&hsep->ep.ep_list);\n"
- "+\tif (epnum)\n"
- "+\t\tlist_add_tail(&hsep->ep.ep_list, &hsudc->gadget.ep_list);\n"
- "+\n"
- "+\thsep->dev = hsudc;\n"
- "+\thsep->ep.name = hsep->name;\n"
- "+\thsep->ep.maxpacket = epnum ? 512 : 64;\n"
- "+\thsep->ep.ops = &s3c_hsudc_ep_ops;\n"
- "+\thsep->fifo = hsudc->regs + S3C_BR(epnum);\n"
- "+\thsep->desc = 0;\n"
- "+\thsep->stopped = 0;\n"
- "+\n"
- "+\tset_index(hsudc, epnum);\n"
- "+\twritel(hsep->ep.maxpacket, hsudc->regs + S3C_MPR);\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_setup_ep - Configure all endpoints to default state.\n"
- "+ * @hsudc: Reference to device controller.\n"
- "+ *\n"
- "+ * Configures all endpoints to default state.\n"
- "+ */\n"
- "+static void s3c_hsudc_setup_ep(struct s3c_hsudc *hsudc)\n"
- "+{\n"
- "+\tint epnum;\n"
- "+\n"
- "+\thsudc->ep0state = WAIT_FOR_SETUP;\n"
- "+\tINIT_LIST_HEAD(&hsudc->gadget.ep_list);\n"
- "+\tfor (epnum = 0; epnum < hsudc->pd->epnum; epnum++)\n"
- "+\t\ts3c_hsudc_initep(hsudc, &hsudc->ep[epnum], epnum);\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_reconfig - Reconfigure the device controller to default state.\n"
- "+ * @hsudc: Reference to device controller.\n"
- "+ *\n"
- "+ * Reconfigures the device controller registers to a default state.\n"
- "+ */\n"
- "+static void s3c_hsudc_reconfig(struct s3c_hsudc *hsudc)\n"
- "+{\n"
- "+\twritel(0xAA, hsudc->regs + S3C_EDR);\n"
- "+\twritel(1, hsudc->regs + S3C_EIER);\n"
- "+\twritel(0, hsudc->regs + S3C_TR);\n"
- "+\twritel(S3C_SCR_DTZIEN_EN | S3C_SCR_RRD_EN | S3C_SCR_SUS_EN |\n"
- "+\t\t\tS3C_SCR_RST_EN, hsudc->regs + S3C_SCR);\n"
- "+\twritel(0, hsudc->regs + S3C_EP0CR);\n"
- "+\n"
- "+\ts3c_hsudc_setup_ep(hsudc);\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * s3c_hsudc_irq - Interrupt handler for device controller.\n"
- "+ * @irq: Not used.\n"
- "+ * @_dev: Reference to the device controller.\n"
- "+ *\n"
- "+ * Interrupt handler for the device controller. This handler handles controller\n"
- "+ * interrupts and endpoint interrupts.\n"
- "+ */\n"
- "+static irqreturn_t s3c_hsudc_irq(int irq, void *_dev)\n"
- "+{\n"
- "+\tstruct s3c_hsudc *hsudc = _dev;\n"
- "+\tstruct s3c_hsudc_ep *hsep;\n"
- "+\tu32 ep_intr;\n"
- "+\tu32 sys_status;\n"
- "+\tu32 ep_idx;\n"
- "+\n"
- "+\tspin_lock(&hsudc->lock);\n"
- "+\n"
- "+\tsys_status = readl(hsudc->regs + S3C_SSR);\n"
- "+\tep_intr = readl(hsudc->regs + S3C_EIR) & 0x3FF;\n"
- "+\n"
- "+\tif (!ep_intr && !(sys_status & S3C_SSR_DTZIEN_EN)) {\n"
- "+\t\tspin_unlock(&hsudc->lock);\n"
- "+\t\treturn IRQ_HANDLED;\n"
- "+\t}\n"
- "+\n"
- "+\tif (sys_status) {\n"
- "+\t\tif (sys_status & S3C_SSR_VBUSON)\n"
- "+\t\t\twritel(S3C_SSR_VBUSON, hsudc->regs + S3C_SSR);\n"
- "+\n"
- "+\t\tif (sys_status & S3C_SSR_ERR)\n"
- "+\t\t\twritel(S3C_SSR_ERR, hsudc->regs + S3C_SSR);\n"
- "+\n"
- "+\t\tif (sys_status & S3C_SSR_SDE) {\n"
- "+\t\t\twritel(S3C_SSR_SDE, hsudc->regs + S3C_SSR);\n"
- "+\t\t\thsudc->gadget.speed = (sys_status & S3C_SSR_HSP) ?\n"
- "+\t\t\t\tUSB_SPEED_HIGH : USB_SPEED_FULL;\n"
- "+\t\t}\n"
- "+\n"
- "+\t\tif (sys_status & S3C_SSR_SUSPEND) {\n"
- "+\t\t\twritel(S3C_SSR_SUSPEND, hsudc->regs + S3C_SSR);\n"
- "+\t\t\tif (hsudc->gadget.speed != USB_SPEED_UNKNOWN\n"
- "+\t\t\t\t&& hsudc->driver && hsudc->driver->suspend)\n"
- "+\t\t\t\thsudc->driver->suspend(&hsudc->gadget);\n"
- "+\t\t}\n"
- "+\n"
- "+\t\tif (sys_status & S3C_SSR_RESUME) {\n"
- "+\t\t\twritel(S3C_SSR_RESUME, hsudc->regs + S3C_SSR);\n"
- "+\t\t\tif (hsudc->gadget.speed != USB_SPEED_UNKNOWN\n"
- "+\t\t\t\t&& hsudc->driver && hsudc->driver->resume)\n"
- "+\t\t\t\thsudc->driver->resume(&hsudc->gadget);\n"
- "+\t\t}\n"
- "+\n"
- "+\t\tif (sys_status & S3C_SSR_RESET) {\n"
- "+\t\t\twritel(S3C_SSR_RESET, hsudc->regs + S3C_SSR);\n"
- "+\t\t\tfor (ep_idx = 0; ep_idx < hsudc->pd->epnum; ep_idx++) {\n"
- "+\t\t\t\thsep = &hsudc->ep[ep_idx];\n"
- "+\t\t\t\thsep->stopped = 1;\n"
- "+\t\t\t\ts3c_hsudc_nuke_ep(hsep, -ECONNRESET);\n"
- "+\t\t\t}\n"
- "+\t\t\ts3c_hsudc_reconfig(hsudc);\n"
- "+\t\t\thsudc->ep0state = WAIT_FOR_SETUP;\n"
- "+\t\t}\n"
- "+\t}\n"
- "+\n"
- "+\tif (ep_intr & S3C_EIR_EP0) {\n"
- "+\t\twritel(S3C_EIR_EP0, hsudc->regs + S3C_EIR);\n"
- "+\t\tset_index(hsudc, 0);\n"
- "+\t\ts3c_hsudc_handle_ep0_intr(hsudc);\n"
- "+\t}\n"
- "+\n"
- "+\tep_intr >>= 1;\n"
- "+\tep_idx = 1;\n"
- "+\twhile (ep_intr) {\n"
- "+\t\tif (ep_intr & 1)  {\n"
- "+\t\t\thsep = &hsudc->ep[ep_idx];\n"
- "+\t\t\tset_index(hsudc, ep_idx);\n"
- "+\t\t\twritel(1 << ep_idx, hsudc->regs + S3C_EIR);\n"
- "+\t\t\tif (ep_is_in(hsep))\n"
- "+\t\t\t\ts3c_hsudc_epin_intr(hsudc, ep_idx);\n"
- "+\t\t\telse\n"
- "+\t\t\t\ts3c_hsudc_epout_intr(hsudc, ep_idx);\n"
- "+\t\t}\n"
- "+\t\tep_intr >>= 1;\n"
- "+\t\tep_idx++;\n"
- "+\t}\n"
- "+\n"
- "+\tspin_unlock(&hsudc->lock);\n"
- "+\treturn IRQ_HANDLED;\n"
- "+}\n"
- "+\n"
- "+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,\n"
- "+               int (*bind)(struct usb_gadget *))\n"
- "+{\n"
- "+\tstruct s3c_hsudc *hsudc = the_controller;\n"
- "+\tint ret;\n"
- "+\n"
- "+\tif (!driver\n"
- "+\t\t|| (driver->speed != USB_SPEED_FULL &&\n"
- "+\t\t\tdriver->speed != USB_SPEED_HIGH)\n"
- "+\t\t|| !bind\n"
- "+\t\t|| !driver->unbind || !driver->disconnect || !driver->setup)\n"
- "+\t\treturn -EINVAL;\n"
- "+\n"
- "+\tif (!hsudc)\n"
- "+\t\treturn -ENODEV;\n"
- "+\n"
- "+\tif (hsudc->driver)\n"
- "+\t\treturn -EBUSY;\n"
- "+\n"
- "+\thsudc->driver = driver;\n"
- "+\thsudc->gadget.dev.driver = &driver->driver;\n"
- "+\thsudc->gadget.speed = USB_SPEED_UNKNOWN;\n"
- "+\tret = device_add(&hsudc->gadget.dev);\n"
- "+\tif (ret) {\n"
- "+\t\tdev_err(hsudc->dev, \"failed to probe gadget device\");\n"
- "+\t\treturn ret;\n"
- "+\t}\n"
- "+\n"
- "+\tret = bind(&hsudc->gadget);\n"
- "+\tif (ret) {\n"
- "+\t\tdev_err(hsudc->dev, \"%s: bind failed\\n\", hsudc->gadget.name);\n"
- "+\t\tdevice_del(&hsudc->gadget.dev);\n"
- "+\n"
- "+\t\thsudc->driver = NULL;\n"
- "+\t\thsudc->gadget.dev.driver = NULL;\n"
- "+\t\treturn ret;\n"
- "+\t}\n"
- "+\n"
- "+\tenable_irq(hsudc->irq);\n"
- "+\tdev_info(hsudc->dev, \"bound driver %s\\n\", driver->driver.name);\n"
- "+\n"
- "+\ts3c_hsudc_reconfig(hsudc);\n"
- "+\ts3c_hsudc_init_phy();\n"
- "+\tif (hsudc->pd->gpio_init)\n"
- "+\t\thsudc->pd->gpio_init();\n"
- "+\n"
- "+\treturn 0;\n"
- "+}\n"
- "+EXPORT_SYMBOL(usb_gadget_probe_driver);\n"
- "+\n"
- "+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)\n"
- "+{\n"
- "+\tstruct s3c_hsudc *hsudc = the_controller;\n"
- "+\tunsigned long flags;\n"
- "+\n"
- "+\tif (!hsudc)\n"
- "+\t\treturn -ENODEV;\n"
- "+\n"
- "+\tif (!driver || driver != hsudc->driver || !driver->unbind)\n"
- "+\t\treturn -EINVAL;\n"
- "+\n"
- "+\tspin_lock_irqsave(&hsudc->lock, flags);\n"
- "+\thsudc->driver = 0;\n"
- "+\ts3c_hsudc_uninit_phy();\n"
- "+\tif (hsudc->pd->gpio_uninit)\n"
- "+\t\thsudc->pd->gpio_uninit();\n"
- "+\ts3c_hsudc_stop_activity(hsudc, driver);\n"
- "+\tspin_unlock_irqrestore(&hsudc->lock, flags);\n"
- "+\n"
- "+\tdriver->unbind(&hsudc->gadget);\n"
- "+\tdevice_del(&hsudc->gadget.dev);\n"
- "+\tdisable_irq(hsudc->irq);\n"
- "+\n"
- "+\tdev_info(hsudc->dev, \"unregistered gadget driver '%s'\\n\",\n"
- "+\t\t\tdriver->driver.name);\n"
- "+\treturn 0;\n"
- "+}\n"
- "+EXPORT_SYMBOL(usb_gadget_unregister_driver);\n"
- "+\n"
- "+static inline u32 s3c_hsudc_read_frameno(struct s3c_hsudc *hsudc)\n"
- "+{\n"
- "+\treturn readl(hsudc->regs + S3C_FNR) & 0x3FF;\n"
- "+}\n"
- "+\n"
- "+static int s3c_hsudc_gadget_getframe(struct usb_gadget *gadget)\n"
- "+{\n"
- "+\treturn s3c_hsudc_read_frameno(to_hsudc(gadget));\n"
- "+}\n"
- "+\n"
- "+static struct usb_gadget_ops s3c_hsudc_gadget_ops = {\n"
- "+\t.get_frame\t= s3c_hsudc_gadget_getframe,\n"
- "+};\n"
- "+\n"
- "+static int s3c_hsudc_probe(struct platform_device *pdev)\n"
- "+{\n"
- "+\tstruct device *dev = &pdev->dev;\n"
- "+\tstruct resource *res;\n"
- "+\tstruct s3c_hsudc *hsudc;\n"
- "+\tstruct s3c24xx_hsudc_platdata *pd = pdev->dev.platform_data;\n"
- "+\tint ret;\n"
- "+\n"
- "+\thsudc = kzalloc(sizeof(struct s3c_hsudc) +\n"
- "+\t\t\tsizeof(struct s3c_hsudc_ep) * pd->epnum,\n"
- "+\t\t\tGFP_KERNEL);\n"
- "+\tif (!hsudc) {\n"
- "+\t\tdev_err(dev, \"cannot allocate memory\\n\");\n"
- "+\t\treturn -ENOMEM;\n"
- "+\t}\n"
- "+\n"
- "+\tthe_controller = hsudc;\n"
- "+\tplatform_set_drvdata(pdev, dev);\n"
- "+\thsudc->dev = dev;\n"
- "+\thsudc->pd = pdev->dev.platform_data;\n"
- "+\n"
- "+\tres = platform_get_resource(pdev, IORESOURCE_MEM, 0);\n"
- "+\tif (!res) {\n"
- "+\t\tdev_err(dev, \"unable to obtain driver resource data\\n\");\n"
- "+\t\tret = -ENODEV;\n"
- "+\t\tgoto err_res;\n"
- "+\t}\n"
- "+\n"
- "+\thsudc->mem_rsrc = request_mem_region(res->start, resource_size(res),\n"
- "+\t\t\t\tdev_name(&pdev->dev));\n"
- "+\tif (!hsudc->mem_rsrc) {\n"
- "+\t\tdev_err(dev, \"failed to reserve register area\\n\");\n"
- "+\t\tret = -ENODEV;\n"
- "+\t\tgoto err_res;\n"
- "+\t}\n"
- "+\n"
- "+\thsudc->regs = ioremap(res->start, resource_size(res));\n"
- "+\tif (!hsudc->regs) {\n"
- "+\t\tdev_err(dev, \"error mapping device register area\\n\");\n"
- "+\t\tret = -EBUSY;\n"
- "+\t\tgoto err_remap;\n"
- "+\t}\n"
- "+\n"
- "+\tret = platform_get_irq(pdev, 0);\n"
- "+\tif (ret < 0) {\n"
- "+\t\tdev_err(dev, \"unable to obtain IRQ number\\n\");\n"
- "+\t\tgoto err_irq;\n"
- "+\t}\n"
- "+\thsudc->irq = ret;\n"
- "+\n"
- "+\tret = request_irq(hsudc->irq, s3c_hsudc_irq, 0, driver_name, hsudc);\n"
- "+\tif (ret < 0) {\n"
- "+\t\tdev_err(dev, \"irq request failed\\n\");\n"
- "+\t\tgoto err_irq;\n"
- "+\t}\n"
- "+\n"
- "+\tspin_lock_init(&hsudc->lock);\n"
- "+\n"
- "+\tdevice_initialize(&hsudc->gadget.dev);\n"
- "+\tdev_set_name(&hsudc->gadget.dev, \"gadget\");\n"
- "+\n"
- "+\thsudc->gadget.is_dualspeed = 1;\n"
- "+\thsudc->gadget.ops = &s3c_hsudc_gadget_ops;\n"
- "+\thsudc->gadget.name = dev_name(dev);\n"
- "+\thsudc->gadget.dev.parent = dev;\n"
- "+\thsudc->gadget.dev.dma_mask = dev->dma_mask;\n"
- "+\thsudc->gadget.ep0 = &hsudc->ep[0].ep;\n"
- "+\n"
- "+\thsudc->gadget.is_otg = 0;\n"
- "+\thsudc->gadget.is_a_peripheral = 0;\n"
- "+\n"
- "+\ts3c_hsudc_setup_ep(hsudc);\n"
- "+\n"
- "+\thsudc->uclk = clk_get(&pdev->dev, \"usb-device\");\n"
- "+\tif (hsudc->uclk == NULL) {\n"
- "+\t\tdev_err(dev, \"failed to find usb-device clock source\\n\");\n"
- "+\t\treturn -ENOENT;\n"
- "+\t}\n"
- "+\tclk_enable(hsudc->uclk);\n"
- "+\n"
- "+\tlocal_irq_disable();\n"
- "+\n"
- "+\tdisable_irq(hsudc->irq);\n"
- "+\tlocal_irq_enable();\n"
- "+\treturn 0;\n"
- "+\n"
- "+err_irq:\n"
- "+\tiounmap(hsudc->regs);\n"
- "+\n"
- "+err_remap:\n"
- "+\trelease_resource(hsudc->mem_rsrc);\n"
- "+\tkfree(hsudc->mem_rsrc);\n"
- "+\n"
- "+err_res:\n"
- "+\tkfree(hsudc);\n"
- "+\treturn ret;\n"
- "+}\n"
- "+\n"
- "+static struct platform_driver s3c_hsudc_driver = {\n"
- "+\t.driver\t\t= {\n"
- "+\t\t.owner\t= THIS_MODULE,\n"
- "+\t\t.name\t= \"s3c-hsudc\",\n"
- "+\t},\n"
- "+\t.probe\t\t= s3c_hsudc_probe,\n"
- "+};\n"
- "+\n"
- "+static int __init s3c_hsudc_modinit(void)\n"
- "+{\n"
- "+\treturn platform_driver_register(&s3c_hsudc_driver);\n"
- "+}\n"
- "+\n"
- "+static void __exit s3c_hsudc_modexit(void)\n"
- "+{\n"
- "+\tplatform_driver_unregister(&s3c_hsudc_driver);\n"
- "+}\n"
- "+\n"
- "+module_init(s3c_hsudc_modinit);\n"
- "+module_exit(s3c_hsudc_modexit);\n"
- "+\n"
- "+MODULE_DESCRIPTION(\"Samsung S3C24XX USB high-speed controller driver\");\n"
- "+MODULE_AUTHOR(\"Thomas Abraham <thomas.ab@samsung.com>\");\n"
- "+MODULE_LICENSE(\"GPL\");\n"
- "-- \n"
- 1.7.2.3
- "\01:6\0"
- "b\0"
- "_______________________________________________\n"
- "linux-arm-kernel mailing list\n"
- "linux-arm-kernel@lists.infradead.org\n"
- http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
+ "hack/kernel/commit/c063317869d11c3b8f906061319f8a075de06b5c\n"
+ "-------------- next part --------------\n"
+ "A non-text attachment was scrubbed...\n"
+ "Name: 0001-ARM-S3C2416-Add-USB-Phy-register-definitions.patch\n"
+ "Type: text/x-patch\n"
+ "Size: 2146 bytes\n"
+ "Desc: not available\n"
+ "URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110301/11ab6ee5/attachment-0004.bin>\n"
+ "-------------- next part --------------\n"
+ "A non-text attachment was scrubbed...\n"
+ "Name: 0002-ARM-S3C24XX-Add-plaform-device-definition-for-USB-Hi.patch\n"
+ "Type: text/x-patch\n"
+ "Size: 4593 bytes\n"
+ "Desc: not available\n"
+ "URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110301/11ab6ee5/attachment-0005.bin>\n"
+ "-------------- next part --------------\n"
+ "A non-text attachment was scrubbed...\n"
+ "Name: 0004-ARM-S3C2416-Add-support-for-USB-2.0-High-Speed-gadge.patch\n"
+ "Type: text/x-patch\n"
+ "Size: 2728 bytes\n"
+ "Desc: not available\n"
+ "URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110301/11ab6ee5/attachment-0006.bin>\n"
+ "-------------- next part --------------\n"
+ "A non-text attachment was scrubbed...\n"
+ "Name: 0003-USB-Gadget-Add-Samsung-S3C24XX-USB-High-Speed-contro.patch\n"
+ "Type: text/x-patch\n"
+ "Size: 40485 bytes\n"
+ "Desc: not available\n"
+ URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110301/11ab6ee5/attachment-0007.bin>
 
-0e80b572ba435c6a97a3732751c36973867401e2508fa21da8cba93aac820f41
+fc9b9047967ed39d00418f764371255d0bfc681a132d8797720b455c407e6726

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.