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.