aboutsummaryrefslogtreecommitdiffstats
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2010-09-01 12:30:18 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-09-01 12:30:18 -0700
commit8a26eb4b4e0e04efc8676c3317d997e175851e33 (patch)
tree9e53954c91a0ab13ab608a5e8cf5a2754c07b70b
parentbc995c6ce883ca8dd77a5094a9f7e2937fa16535 (diff)
downloadpatches-8a26eb4b4e0e04efc8676c3317d997e175851e33.tar.gz
new patches
-rw-r--r--driver-core/driver-core-platform-use-drv-driver.bus-instead-of-assuming-platform_bus_type.patch41
-rw-r--r--driver-core/dynamic-debug-initialize-dynamic-debug-earlier-via-arch_initcall.patch111
-rw-r--r--driver-core/dynamic-debug-introduce-ddebug_query-boot-parameter.patch134
-rw-r--r--driver-core/dynamic-debug-introduce-global-fake-module-param-module.ddebug.patch172
-rw-r--r--driver-core/dynamic-debug-split-out-query-string-parsing-setup-from-proc_write.patch86
-rw-r--r--series23
-rw-r--r--staging.current/staging-comedi-das08_cs.c-fix-io_req_t-conversion.patch32
-rw-r--r--staging.current/staging-hv-fix-missing-functions-for-net_device_ops.patch40
-rw-r--r--staging.current/staging-hv-fixed-bounce-kmap-problem-by-using-correct-index.patch43
-rw-r--r--staging.current/staging-hv-fixed-the-value-of-the-64bit-hole-inside-ring-buffer.patch43
-rw-r--r--staging.current/staging-hv-increased-storvsc-ringbuffer-and-max_io_requests.patch47
-rw-r--r--staging.current/staging-octeon-depends-on-netdevices.patch37
-rw-r--r--staging.current/staging-rt2870sta-add-more-device-ids-from-vendor-drivers.patch112
-rw-r--r--staging.current/staging-spectra-depend-on-x86_mrst.patch29
-rw-r--r--staging.current/staging-spectra-needs-linux-slab.h.patch36
-rw-r--r--staging.current/staging-wlan-ng-explicitly-set-some-fields-in-cfg80211-interface.patch39
-rw-r--r--staging.current/staging-zram-free-device-memory-when-init-fails.patch26
-rw-r--r--usb/usb-add-intel-langwell-usb-otg-transceiver-driver.patch2613
-rw-r--r--usb/usb-langwell-usb-client-driver-code-cleanup.patch2133
-rw-r--r--usb/usb-langwell-usb-client-driver-memory-handling.patch223
-rw-r--r--usb/usb-langwell-usb-client-endpoint-initialization.patch84
-rw-r--r--usb/usb-langwell-usb-client-phy-low-power-mode-setting.patch209
-rw-r--r--usb/usb-langwell-usb-client-remote-wakeup-support.patch160
23 files changed, 6473 insertions, 0 deletions
diff --git a/driver-core/driver-core-platform-use-drv-driver.bus-instead-of-assuming-platform_bus_type.patch b/driver-core/driver-core-platform-use-drv-driver.bus-instead-of-assuming-platform_bus_type.patch
new file mode 100644
index 00000000000000..4bc68e72d53471
--- /dev/null
+++ b/driver-core/driver-core-platform-use-drv-driver.bus-instead-of-assuming-platform_bus_type.patch
@@ -0,0 +1,41 @@
+From ppannuto@codeaurora.org Wed Sep 1 11:48:10 2010
+From: Patrick Pannuto <ppannuto@codeaurora.org>
+To: linux-kernel@vger.kernel.org
+Cc: ppannuto@codeaurora.org, linux-arm-msm@vger.kernel.org,
+ Greg Kroah-Hartman <gregkh@suse.de>,
+ Magnus Damm <damm@opensource.se>, Paul Mundt <lethal@linux-sh.org>,
+ =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>,
+ "Rafael J. Wysocki" <rjw@sisk.pl>
+Subject: driver core: platform: Use drv->driver.bus instead of assuming platform_bus_type
+Date: Fri, 6 Aug 2010 17:12:41 -0700
+Message-Id: <1281139962-20538-1-git-send-email-ppannuto@codeaurora.org>
+
+In theory (although not *yet* in practice), a driver being passed
+to platform_driver_probe might have driver.bus set to something
+other than platform_bus_type. Locking drv->driver.bus is always
+correct.
+
+Signed-off-by: Patrick Pannuto <ppannuto@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/base/platform.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/base/platform.c
++++ b/drivers/base/platform.c
+@@ -488,12 +488,12 @@ int __init_or_module platform_driver_pro
+ * if the probe was successful, and make sure any forced probes of
+ * new devices fail.
+ */
+- spin_lock(&platform_bus_type.p->klist_drivers.k_lock);
++ spin_lock(&drv->driver.bus->p->klist_drivers.k_lock);
+ drv->probe = NULL;
+ if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
+ retval = -ENODEV;
+ drv->driver.probe = platform_drv_probe_fail;
+- spin_unlock(&platform_bus_type.p->klist_drivers.k_lock);
++ spin_unlock(&drv->driver.bus->p->klist_drivers.k_lock);
+
+ if (code != retval)
+ platform_driver_unregister(drv);
diff --git a/driver-core/dynamic-debug-initialize-dynamic-debug-earlier-via-arch_initcall.patch b/driver-core/dynamic-debug-initialize-dynamic-debug-earlier-via-arch_initcall.patch
new file mode 100644
index 00000000000000..51f501bd2ed7e1
--- /dev/null
+++ b/driver-core/dynamic-debug-initialize-dynamic-debug-earlier-via-arch_initcall.patch
@@ -0,0 +1,111 @@
+From trenn@suse.de Wed Sep 1 11:46:30 2010
+From: Thomas Renninger <trenn@suse.de>
+To: penberg@cs.helsinki.fi, jbaron@redhat.com, greg@kroah.com
+Cc: trenn@suse.de, linux-acpi@vger.kernel.org, greg@kroah.com
+Subject: Dynamic Debug: Initialize dynamic debug earlier via arch_initcall
+Date: Fri, 6 Aug 2010 16:11:03 +0200
+Message-Id: <1281103864-18860-4-git-send-email-trenn@suse.de>
+
+Having the ddebug_query= boot parameter it makes sense to set up
+dynamic debug as soon as possible.
+
+I expect sysfs files cannot be set up via an arch_initcall, because
+this one is even before fs_initcall. Therefore I splitted the
+dynamic_debug_init function into an early one and a later one providing
+/sys/../dynamic_debug/control file.
+
+Possibly dynamic_debug can be initialized even earlier, not sure whether
+this still makes sense then. I picked up arch_initcall as it covers
+quite a lot already.
+
+Dynamic debug needs to allocate memory, therefore it's not easily possible to
+set it up even before the command line gets parsed.
+Therefore the boot param query string is stored in a temp string which is
+applied when dynamic debug gets set up.
+
+This has been tested with ddebug_query="file ec.c +p"
+and I could retrieve pr_debug() messages early at boot during ACPI setup:
+ACPI: EC: Look up EC in DSDT
+ACPI: EC: ---> status = 0x08
+ACPI: EC: transaction start
+ACPI: EC: <--- command = 0x80
+ACPI: EC: ~~~> interrupt
+ACPI: EC: ---> status = 0x08
+ACPI: EC: <--- data = 0xa4
+...
+ACPI: Interpreter enabled
+ACPI: (supports S0 S3 S4 S5)
+ACPI: Using IOAPIC for interrupt routing
+ACPI: EC: ---> status = 0x00
+ACPI: EC: transaction start
+ACPI: EC: <--- command = 0x80
+
+
+Signed-off-by: Thomas Renninger <trenn@suse.de>
+Acked-by: jbaron@redhat.com
+Acked-by: Pekka Enberg <penberg@cs.helsinki.fi>
+CC: linux-acpi@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ lib/dynamic_debug.c | 33 +++++++++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 10 deletions(-)
+
+--- a/lib/dynamic_debug.c
++++ b/lib/dynamic_debug.c
+@@ -748,13 +748,14 @@ static void ddebug_remove_all_tables(voi
+ mutex_unlock(&ddebug_lock);
+ }
+
+-static int __init dynamic_debug_init(void)
++static __initdata int ddebug_init_success;
++
++static int __init dynamic_debug_init_debugfs(void)
+ {
+ struct dentry *dir, *file;
+- struct _ddebug *iter, *iter_start;
+- const char *modname = NULL;
+- int ret = 0;
+- int n = 0;
++
++ if (!ddebug_init_success)
++ return -ENODEV;
+
+ dir = debugfs_create_dir("dynamic_debug", NULL);
+ if (!dir)
+@@ -765,6 +766,16 @@ static int __init dynamic_debug_init(voi
+ debugfs_remove(dir);
+ return -ENOMEM;
+ }
++ return 0;
++}
++
++static int __init dynamic_debug_init(void)
++{
++ struct _ddebug *iter, *iter_start;
++ const char *modname = NULL;
++ int ret = 0;
++ int n = 0;
++
+ if (__start___verbose != __stop___verbose) {
+ iter = __start___verbose;
+ modname = iter->modname;
+@@ -795,11 +806,13 @@ static int __init dynamic_debug_init(voi
+ }
+
+ out_free:
+- if (ret) {
++ if (ret)
+ ddebug_remove_all_tables();
+- debugfs_remove(dir);
+- debugfs_remove(file);
+- }
++ else
++ ddebug_init_success = 1;
+ return 0;
+ }
+-module_init(dynamic_debug_init);
++/* Allow early initialization for boot messages via boot param */
++arch_initcall(dynamic_debug_init);
++/* Debugfs setup must be done later */
++module_init(dynamic_debug_init_debugfs);
diff --git a/driver-core/dynamic-debug-introduce-ddebug_query-boot-parameter.patch b/driver-core/dynamic-debug-introduce-ddebug_query-boot-parameter.patch
new file mode 100644
index 00000000000000..c79b1436a0ad3c
--- /dev/null
+++ b/driver-core/dynamic-debug-introduce-ddebug_query-boot-parameter.patch
@@ -0,0 +1,134 @@
+From trenn@suse.de Wed Sep 1 11:46:15 2010
+From: Thomas Renninger <trenn@suse.de>
+To: penberg@cs.helsinki.fi, jbaron@redhat.com, greg@kroah.com
+Cc: trenn@suse.de, greg@kroah.com
+Subject: Dynamic Debug: Introduce ddebug_query= boot parameter
+Date: Fri, 6 Aug 2010 16:11:02 +0200
+Message-Id: <1281103864-18860-3-git-send-email-trenn@suse.de>
+
+Dynamic debug lacks the ability to enable debug messages at boot time.
+One could patch initramfs or service startup scripts to write to
+/sys/../dynamic_debug/control, but this sucks.
+
+This patch makes it possible to pass a query in the same format one can
+write to /sys/../dynamic_debug/control via boot param.
+When dynamic debug gets initialized, this query will automatically be
+applied.
+
+
+Signed-off-by: Thomas Renninger <trenn@suse.de>
+Acked-by: jbaron@redhat.com
+Acked-by: Pekka Enberg <penberg@cs.helsinki.fi>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/dynamic-debug-howto.txt | 22 +++++++++++++++++++++-
+ Documentation/kernel-parameters.txt | 7 ++++++-
+ lib/dynamic_debug.c | 25 +++++++++++++++++++++++++
+ 3 files changed, 52 insertions(+), 2 deletions(-)
+
+--- a/Documentation/dynamic-debug-howto.txt
++++ b/Documentation/dynamic-debug-howto.txt
+@@ -24,7 +24,7 @@ Dynamic debug has even more useful featu
+ read to display the complete list of known debug statements, to help guide you
+
+ Controlling dynamic debug Behaviour
+-===============================
++===================================
+
+ The behaviour of pr_debug()/dev_debug()s are controlled via writing to a
+ control file in the 'debugfs' filesystem. Thus, you must first mount the debugfs
+@@ -212,6 +212,26 @@ Note the regexp ^[-+=][scp]+$ matches a
+ Note also that there is no convenient syntax to remove all
+ the flags at once, you need to use "-psc".
+
++
++Debug messages during boot process
++==================================
++
++To be able to activate debug messages during the boot process,
++even before userspace and debugfs exists, use the boot parameter:
++ddebug_query="QUERY"
++
++QUERY follows the syntax described above, but must not exceed 1023
++characters. The enablement of debug messages is done as an arch_initcall.
++Thus you can enable debug messages in all code processed after this
++arch_initcall via this boot parameter.
++On an x86 system for example ACPI enablement is a subsys_initcall and
++ddebug_query="file ec.c +p"
++will show early Embedded Controller transactions during ACPI setup if
++your machine (typically a laptop) has an Embedded Controller.
++PCI (or other devices) initialization also is a hot candidate for using
++this boot parameter for debugging purposes.
++
++
+ Examples
+ ========
+
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -43,10 +43,11 @@ parameter is applicable:
+ AVR32 AVR32 architecture is enabled.
+ AX25 Appropriate AX.25 support is enabled.
+ BLACKFIN Blackfin architecture is enabled.
+- DRM Direct Rendering Management support is enabled.
+ EDD BIOS Enhanced Disk Drive Services (EDD) is enabled
+ EFI EFI Partitioning (GPT) is enabled
+ EIDE EIDE/ATAPI support is enabled.
++ DRM Direct Rendering Management support is enabled.
++ DYNAMIC_DEBUG Build in debug messages and enable them at runtime
+ FB The frame buffer device is enabled.
+ GCOV GCOV profiling is enabled.
+ HW Appropriate hardware is enabled.
+@@ -570,6 +571,10 @@ and is between 256 and 4096 characters.
+ Format: <port#>,<type>
+ See also Documentation/input/joystick-parport.txt
+
++ ddebug_query= [KNL,DYNAMIC_DEBUG] Enable debug messages at early boot
++ time. See Documentation/dynamic-debug-howto.txt for
++ details.
++
+ debug [KNL] Enable kernel debugging (events log level).
+
+ debug_locks_verbose=
+--- a/lib/dynamic_debug.c
++++ b/lib/dynamic_debug.c
+@@ -450,6 +450,19 @@ static int ddebug_exec_query(char *query
+ return 0;
+ }
+
++static __initdata char ddebug_setup_string[1024];
++static __init int ddebug_setup_query(char *str)
++{
++ if (strlen(str) >= 1024) {
++ pr_warning("ddebug boot param string too large\n");
++ return 0;
++ }
++ strcpy(ddebug_setup_string, str);
++ return 1;
++}
++
++__setup("ddebug_query=", ddebug_setup_query);
++
+ /*
+ * File_ops->write method for <debugfs>/dynamic_debug/conrol. Gathers the
+ * command text from userspace, parses and executes it.
+@@ -769,6 +782,18 @@ static int __init dynamic_debug_init(voi
+ }
+ ret = ddebug_add_module(iter_start, n, modname);
+ }
++
++ /* ddebug_query boot param got passed -> set it up */
++ if (ddebug_setup_string[0] != '\0') {
++ ret = ddebug_exec_query(ddebug_setup_string);
++ if (ret)
++ pr_warning("Invalid ddebug boot param %s",
++ ddebug_setup_string);
++ else
++ pr_info("ddebug initialized with string %s",
++ ddebug_setup_string);
++ }
++
+ out_free:
+ if (ret) {
+ ddebug_remove_all_tables();
diff --git a/driver-core/dynamic-debug-introduce-global-fake-module-param-module.ddebug.patch b/driver-core/dynamic-debug-introduce-global-fake-module-param-module.ddebug.patch
new file mode 100644
index 00000000000000..9e8f4adde4c9dc
--- /dev/null
+++ b/driver-core/dynamic-debug-introduce-global-fake-module-param-module.ddebug.patch
@@ -0,0 +1,172 @@
+From trenn@suse.de Wed Sep 1 11:46:46 2010
+From: Thomas Renninger <trenn@suse.de>
+To: penberg@cs.helsinki.fi, jbaron@redhat.com, greg@kroah.com
+Cc: trenn@suse.de, greg@kroah.com
+Subject: Dynamic Debug: Introduce global fake module param module.ddebug
+Date: Fri, 6 Aug 2010 16:11:04 +0200
+Message-Id: <1281103864-18860-5-git-send-email-trenn@suse.de>
+
+Dynamic Debug allows enabling of pr_debug or KERN_DEBUG messages at runtime.
+This is controlled via /sys/kernel/debug/dynamic_debug/control.
+One major drawback is that the whole initialization of a module cannot be
+tracked, because ddebug is only aware of debug strings of loaded modules.
+But this is the most interesting part...
+
+This patch introduces a fake module parameter module.ddebug(not shown in
+/sys/module/*/parameters, thus it does not use any resources/memory).
+
+If a module passes ddebug as a module parameter (e.g. via module.ddebug
+kernel boot param or via "modprobe module ddebug"), all debug strings of this
+module get activated by issuing "module module_name +p" internally
+(not via sysfs) when the module gets loaded.
+
+Possible enhancements for the future if ddebug might get extended with
+further flags:
+module.ddebug=flags
+Then module.ddebug="p" would be the same as module.ddebug, but if there
+is a "x" ddebug flag added, one could pass:
+module.ddebug="xp"
+which would result in such a dynamic debug query:
+module module_name +xp
+
+Modules must not use "ddebug" as module parameter or it will get ignored.
+If it's tried, a warning will show up at module load time that it will get
+ignored (this is the only part which got added late and is compile tested only).
+
+Tested with (additional added pr_debug messages):
+options hp-wmi ddebug
+in modprobe.conf
+-> works and pr_debug messages issued at module initialization time show
+up. Also "p" flag gets set for the whole hp-wmi module:
+grep hp-wmi /sys/../dynamic_debug/control
+
+Signed-off-by: Thomas Renninger <trenn@suse.de>
+Acked-by: Jason Baron <jbaron@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/dynamic-debug-howto.txt | 28 +++++++++++++++++++++++++++-
+ include/linux/dynamic_debug.h | 5 +++++
+ kernel/params.c | 17 ++++++++++++++++-
+ lib/dynamic_debug.c | 2 +-
+ 4 files changed, 49 insertions(+), 3 deletions(-)
+
+--- a/Documentation/dynamic-debug-howto.txt
++++ b/Documentation/dynamic-debug-howto.txt
+@@ -213,7 +213,7 @@ Note also that there is no convenient sy
+ the flags at once, you need to use "-psc".
+
+
+-Debug messages during boot process
++Debug Messages during Boot Process
+ ==================================
+
+ To be able to activate debug messages during the boot process,
+@@ -232,6 +232,32 @@ PCI (or other devices) initialization al
+ this boot parameter for debugging purposes.
+
+
++Debug Messages at Module Initialization Time
++============================================
++
++Enabling debug messages inside a module is only possible if the module itself
++is loaded already. If you unload a module, the dynamic debug flags associated
++to its debug messages are lost.
++Therefore, enabling debug messages that get processed at module initialization
++time through the <debugfs>/dynamic_debug/control interface is not possible.
++Instead, a "ddebug" module paramter can be passed:
++
++ - via kernel boot parameter:
++ module.ddebug
++
++ - as an ordinary module parameter via modprobe
++ modprobe module ddebug
++
++ - or the parameter can be used permanently via modprobe.conf(.local)
++ options module ddebug
++
++The ddebug option is not implemented as an ordinary module parameter and thus
++will not show up in /sys/module/module_name/parameters/ddebug
++The settings can get reverted through the sysfs interface again when the
++module got loaded as soon as debug messages are not needed anymore:
++echo "module module_name -p" > <debugfs>/dynamic_debug/control
++as described in the "Command Language Reference" chapter above.
++
+ Examples
+ ========
+
+--- a/include/linux/dynamic_debug.h
++++ b/include/linux/dynamic_debug.h
+@@ -41,6 +41,7 @@ int ddebug_add_module(struct _ddebug *ta
+
+ #if defined(CONFIG_DYNAMIC_DEBUG)
+ extern int ddebug_remove_module(const char *mod_name);
++extern int ddebug_exec_query(char *query_string);
+
+ #define __dynamic_dbg_enabled(dd) ({ \
+ int __ret = 0; \
+@@ -77,6 +78,10 @@ static inline int ddebug_remove_module(c
+ {
+ return 0;
+ }
++static inline int ddebug_exec_query(char *query_string)
++{
++ return 0;
++}
+
+ #define dynamic_pr_debug(fmt, ...) \
+ do { if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); } while (0)
+--- a/kernel/params.c
++++ b/kernel/params.c
+@@ -24,6 +24,7 @@
+ #include <linux/err.h>
+ #include <linux/slab.h>
+ #include <linux/ctype.h>
++#include <linux/dynamic_debug.h>
+
+ #if 0
+ #define DEBUGP printk
+@@ -175,10 +176,17 @@ int parse_args(const char *name,
+ unsigned num,
+ int (*unknown)(char *param, char *val))
+ {
+- char *param, *val;
++ char *param, *val, ddebug[1024];
++ int i;
+
+ DEBUGP("Parsing ARGS: %s\n", args);
+
++ for (i = 0; i < num; i++) {
++ if (parameq("ddebug", params[i].name))
++ pr_warning("Module %s uses reserved keyword *ddebug* as"
++ "parameter which will get ignored\n", name);
++ }
++
+ /* Chew leading spaces */
+ args = skip_spaces(args);
+
+@@ -187,6 +195,13 @@ int parse_args(const char *name,
+ int irq_was_disabled;
+
+ args = next_arg(args, &param, &val);
++
++ if (parameq(param, "ddebug")) {
++ snprintf(ddebug, "module %s +p", name, 1024);
++ ddebug_exec_query(ddebug);
++ continue;
++ }
++
+ irq_was_disabled = irqs_disabled();
+ ret = parse_one(param, val, params, num, unknown);
+ if (irq_was_disabled && !irqs_disabled()) {
+--- a/lib/dynamic_debug.c
++++ b/lib/dynamic_debug.c
+@@ -429,7 +429,7 @@ static int ddebug_parse_flags(const char
+ return 0;
+ }
+
+-static int ddebug_exec_query(char *query_string)
++int ddebug_exec_query(char *query_string)
+ {
+ unsigned int flags = 0, mask = 0;
+ struct ddebug_query query;
diff --git a/driver-core/dynamic-debug-split-out-query-string-parsing-setup-from-proc_write.patch b/driver-core/dynamic-debug-split-out-query-string-parsing-setup-from-proc_write.patch
new file mode 100644
index 00000000000000..4c9cea2ac17b7f
--- /dev/null
+++ b/driver-core/dynamic-debug-split-out-query-string-parsing-setup-from-proc_write.patch
@@ -0,0 +1,86 @@
+From trenn@suse.de Wed Sep 1 11:46:00 2010
+From: Thomas Renninger <trenn@suse.de>
+To: penberg@cs.helsinki.fi, jbaron@redhat.com, greg@kroah.com
+Cc: trenn@suse.de, greg@kroah.com
+Subject: Dynamic Debug: Split out query string parsing/setup from proc_write
+Date: Fri, 6 Aug 2010 16:11:01 +0200
+Message-Id: <1281103864-18860-2-git-send-email-trenn@suse.de>
+
+The parsing and applying of dynamic debug strings is not only useful for
+/sys/../dynamic_debug/control write access, but can also be used for
+boot parameter parsing.
+The boot parameter is introduced in a follow up patch.
+
+Signed-off-by: Thomas Renninger <trenn@suse.de>
+Acked-by: jbaron@redhat.com
+Acked-by: Pekka Enberg <penberg@cs.helsinki.fi>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ lib/dynamic_debug.c | 40 +++++++++++++++++++++++++---------------
+ 1 file changed, 25 insertions(+), 15 deletions(-)
+
+--- a/lib/dynamic_debug.c
++++ b/lib/dynamic_debug.c
+@@ -429,6 +429,27 @@ static int ddebug_parse_flags(const char
+ return 0;
+ }
+
++static int ddebug_exec_query(char *query_string)
++{
++ unsigned int flags = 0, mask = 0;
++ struct ddebug_query query;
++#define MAXWORDS 9
++ int nwords;
++ char *words[MAXWORDS];
++
++ nwords = ddebug_tokenize(query_string, words, MAXWORDS);
++ if (nwords <= 0)
++ return -EINVAL;
++ if (ddebug_parse_query(words, nwords-1, &query))
++ return -EINVAL;
++ if (ddebug_parse_flags(words[nwords-1], &flags, &mask))
++ return -EINVAL;
++
++ /* actually go and implement the change */
++ ddebug_change(&query, flags, mask);
++ return 0;
++}
++
+ /*
+ * File_ops->write method for <debugfs>/dynamic_debug/conrol. Gathers the
+ * command text from userspace, parses and executes it.
+@@ -436,12 +457,8 @@ static int ddebug_parse_flags(const char
+ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
+ size_t len, loff_t *offp)
+ {
+- unsigned int flags = 0, mask = 0;
+- struct ddebug_query query;
+-#define MAXWORDS 9
+- int nwords;
+- char *words[MAXWORDS];
+ char tmpbuf[256];
++ int ret;
+
+ if (len == 0)
+ return 0;
+@@ -455,16 +472,9 @@ static ssize_t ddebug_proc_write(struct
+ printk(KERN_INFO "%s: read %d bytes from userspace\n",
+ __func__, (int)len);
+
+- nwords = ddebug_tokenize(tmpbuf, words, MAXWORDS);
+- if (nwords <= 0)
+- return -EINVAL;
+- if (ddebug_parse_query(words, nwords-1, &query))
+- return -EINVAL;
+- if (ddebug_parse_flags(words[nwords-1], &flags, &mask))
+- return -EINVAL;
+-
+- /* actually go and implement the change */
+- ddebug_change(&query, flags, mask);
++ ret = ddebug_exec_query(tmpbuf);
++ if (ret)
++ return ret;
+
+ *offp += len;
+ return len;
diff --git a/series b/series
index 288e5a782c2456..f159f9dafcae41 100644
--- a/series
+++ b/series
@@ -8,6 +8,11 @@ gregkh/gkh-version.patch
#################################
# Driver core patches for 2.6.36
#################################
+driver-core/dynamic-debug-split-out-query-string-parsing-setup-from-proc_write.patch
+driver-core/dynamic-debug-introduce-ddebug_query-boot-parameter.patch
+driver-core/dynamic-debug-initialize-dynamic-debug-earlier-via-arch_initcall.patch
+driver-core/dynamic-debug-introduce-global-fake-module-param-module.ddebug.patch
+driver-core/driver-core-platform-use-drv-driver.bus-instead-of-assuming-platform_bus_type.patch
#################################
# TTY patches for 2.6.36
@@ -21,6 +26,17 @@ gregkh/gkh-version.patch
#################################
# Staging patches for 2.6.36
#################################
+staging.current/staging-hv-fix-missing-functions-for-net_device_ops.patch
+staging.current/staging-hv-fixed-bounce-kmap-problem-by-using-correct-index.patch
+staging.current/staging-hv-fixed-the-value-of-the-64bit-hole-inside-ring-buffer.patch
+staging.current/staging-hv-increased-storvsc-ringbuffer-and-max_io_requests.patch
+staging.current/staging-spectra-needs-linux-slab.h.patch
+staging.current/staging-comedi-das08_cs.c-fix-io_req_t-conversion.patch
+staging.current/staging-rt2870sta-add-more-device-ids-from-vendor-drivers.patch
+staging.current/staging-zram-free-device-memory-when-init-fails.patch
+staging.current/staging-spectra-depend-on-x86_mrst.patch
+staging.current/staging-octeon-depends-on-netdevices.patch
+staging.current/staging-wlan-ng-explicitly-set-some-fields-in-cfg80211-interface.patch
#####################################################################
@@ -42,8 +58,15 @@ gregkh/gkh-version.patch
###################################
# USB stuff for after 2.6.36 is out
###################################
+usb/usb-add-intel-langwell-usb-otg-transceiver-driver.patch
+usb/usb-langwell-usb-client-driver-code-cleanup.patch
+usb/usb-langwell-usb-client-endpoint-initialization.patch
+usb/usb-langwell-usb-client-phy-low-power-mode-setting.patch
+usb/usb-langwell-usb-client-remote-wakeup-support.patch
+usb/usb-langwell-usb-client-driver-memory-handling.patch
# staging stuff for next is now in the staging-next tree on git.kernel.org
+
diff --git a/staging.current/staging-comedi-das08_cs.c-fix-io_req_t-conversion.patch b/staging.current/staging-comedi-das08_cs.c-fix-io_req_t-conversion.patch
new file mode 100644
index 00000000000000..653de3b493263f
--- /dev/null
+++ b/staging.current/staging-comedi-das08_cs.c-fix-io_req_t-conversion.patch
@@ -0,0 +1,32 @@
+From andreas@infernal.debian.net Mon Aug 30 16:53:01 2010
+From: Andreas Bombe <aeb@debian.org>
+To: linux-kernel@vger.kernel.org
+Cc: Dominik Brodowski <linux@dominikbrodowski.net>,
+ Greg Kroah-Hartman <gregkh@suse.de>, devel@driverdev.osuosl.org,
+ Andreas Bombe <aeb@debian.org>
+Subject: staging: comedi das08_cs.c: Fix io_req_t conversion
+Date: Sat, 14 Aug 2010 03:24:22 +0200
+Message-Id: <1281749062-9907-1-git-send-email-aeb@debian.org>
+
+Commit 90abdc3b9 converted all PCMCIA users away from io_req_t. In
+das08_cs.c the converted IO lines mask setting was added but the old
+line using the now inexistent p_dev->io was not removed.
+
+Signed-off-by: Andreas Bombe <aeb@debian.org>
+Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/comedi/drivers/das08_cs.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/staging/comedi/drivers/das08_cs.c
++++ b/drivers/staging/comedi/drivers/das08_cs.c
+@@ -222,7 +222,6 @@ static int das08_pcmcia_config_loop(stru
+ p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+ p_dev->resource[0]->flags |=
+ pcmcia_io_cfg_data_width(io->flags);
+- p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->resource[0]->start = io->win[0].base;
+ p_dev->resource[0]->end = io->win[0].len;
+ if (io->nwin > 1) {
diff --git a/staging.current/staging-hv-fix-missing-functions-for-net_device_ops.patch b/staging.current/staging-hv-fix-missing-functions-for-net_device_ops.patch
new file mode 100644
index 00000000000000..61aad0560c5414
--- /dev/null
+++ b/staging.current/staging-hv-fix-missing-functions-for-net_device_ops.patch
@@ -0,0 +1,40 @@
+From devel-bounces@linuxdriverproject.org Tue Aug 3 12:16:38 2010
+From: Haiyang Zhang <haiyangz@microsoft.com>
+Subject: staging: hv: Fix missing functions for net_device_ops
+Date: Tue, 3 Aug 2010 19:15:31 +0000
+Message-ID: <1FB5E1D5CA062146B38059374562DF728380C37B@TK5EX14MBXC126.redmond.corp.microsoft.com>
+
+From: Haiyang Zhang <haiyangz@microsoft.com>
+
+Fix missing functions for net_device_ops.
+It's a bug when porting the drivers from 2.6.27 to 2.6.32. In 2.6.27,
+the default functions for Ethernet, like eth_change_mtu(), were assigned
+by ether_setup(). But in 2.6.32, these function pointers moved to
+net_device_ops structure and no longer be assigned in ether_setup(). So
+we need to set these functions in our driver code. It will ensure the
+MTU won't be set beyond 1500. Otherwise, this can cause an error on the
+server side, because the HyperV linux driver doesn't support jumbo frame
+yet.
+
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: Hank Janssen <hjanssen@microsoft.com>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/staging/hv/netvsc_drv.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/staging/hv/netvsc_drv.c
++++ b/drivers/staging/hv/netvsc_drv.c
+@@ -327,6 +327,9 @@ static const struct net_device_ops devic
+ .ndo_stop = netvsc_close,
+ .ndo_start_xmit = netvsc_start_xmit,
+ .ndo_set_multicast_list = netvsc_set_multicast_list,
++ .ndo_change_mtu = eth_change_mtu,
++ .ndo_validate_addr = eth_validate_addr,
++ .ndo_set_mac_address = eth_mac_addr,
+ };
+
+ static int netvsc_probe(struct device *device)
diff --git a/staging.current/staging-hv-fixed-bounce-kmap-problem-by-using-correct-index.patch b/staging.current/staging-hv-fixed-bounce-kmap-problem-by-using-correct-index.patch
new file mode 100644
index 00000000000000..c04ed93606d1eb
--- /dev/null
+++ b/staging.current/staging-hv-fixed-bounce-kmap-problem-by-using-correct-index.patch
@@ -0,0 +1,43 @@
+From devel-bounces@linuxdriverproject.org Thu Aug 5 12:30:40 2010
+From: Hank Janssen <hjanssen@microsoft.com>
+Subject: staging: hv: Fixed bounce kmap problem by using correct index
+Date: Thu, 5 Aug 2010 19:29:44 +0000
+Message-ID: <8AFC7968D54FB448A30D8F38F259C56223FEC87F@TK5EX14MBXC114.redmond.corp.microsoft.com>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>, "'gregkh@suse.de'" <gregkh@suse.de>
+
+From: Hank Janssen <hjanssen@microsoft.com>
+
+Fixed bounce offset kmap problem by using correct index.
+The symptom of the problem is that in some NAS appliances this problem
+represents Itself by a unresponsive VM under a load with many clients writing
+small files.
+
+Signed-off-by:Hank Janssen <hjanssen@microsoft.com>
+Signed-off-by:Haiyang Zhang <haiyangz@microsoft.com>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/hv/storvsc_drv.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/hv/storvsc_drv.c
++++ b/drivers/staging/hv/storvsc_drv.c
+@@ -495,7 +495,7 @@ static unsigned int copy_to_bounce_buffe
+
+ /* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */
+
+- if (j == 0)
++ if (bounce_addr == 0)
+ bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0);
+
+ while (srclen) {
+@@ -556,7 +556,7 @@ static unsigned int copy_from_bounce_buf
+ destlen = orig_sgl[i].length;
+ /* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */
+
+- if (j == 0)
++ if (bounce_addr == 0)
+ bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0);
+
+ while (destlen) {
diff --git a/staging.current/staging-hv-fixed-the-value-of-the-64bit-hole-inside-ring-buffer.patch b/staging.current/staging-hv-fixed-the-value-of-the-64bit-hole-inside-ring-buffer.patch
new file mode 100644
index 00000000000000..a5ce955c5b5f35
--- /dev/null
+++ b/staging.current/staging-hv-fixed-the-value-of-the-64bit-hole-inside-ring-buffer.patch
@@ -0,0 +1,43 @@
+From hjanssen@microsoft.com Thu Aug 5 12:30:06 2010
+From: Hank Janssen <hjanssen@microsoft.com>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>,
+ "'gregkh@suse.de'" <gregkh@suse.de>
+Subject: staging: hv: Fixed the value of the 64bit-hole inside ring buffer
+Date: Thu, 5 Aug 2010 19:30:01 +0000
+Message-ID: <8AFC7968D54FB448A30D8F38F259C56223FEC892@TK5EX14MBXC114.redmond.corp.microsoft.com>
+
+From: Haiyang Zhang <haiyangz@microsoft.com>
+
+Fixed the value of the 64bit-hole inside ring buffer, this
+caused a problem on Hyper-V when running checked Windows builds.
+
+Checked builds of Windows are used internally and given to external
+system integrators at times. They are builds that for example that all
+elements in a structure follow the definition of that Structure. The bug
+this fixed was for a field that we did not fill in at all (Because we do
+Not use it on the Linux side), and the checked build of windows gives
+errors on it internally to the Windows logs.
+
+This fixes that error.
+
+Signed-off-by:Hank Janssen <hjanssen@microsoft.com>
+Signed-off-by:Haiyang Zhang <haiyangz@microsoft.com>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/hv/ring_buffer.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/staging/hv/ring_buffer.c
++++ b/drivers/staging/hv/ring_buffer.c
+@@ -193,8 +193,7 @@ Description:
+ static inline u64
+ GetRingBufferIndices(struct hv_ring_buffer_info *RingInfo)
+ {
+- return ((u64)RingInfo->RingBuffer->WriteIndex << 32)
+- || RingInfo->RingBuffer->ReadIndex;
++ return (u64)RingInfo->RingBuffer->WriteIndex << 32;
+ }
+
+
diff --git a/staging.current/staging-hv-increased-storvsc-ringbuffer-and-max_io_requests.patch b/staging.current/staging-hv-increased-storvsc-ringbuffer-and-max_io_requests.patch
new file mode 100644
index 00000000000000..6404960843bca3
--- /dev/null
+++ b/staging.current/staging-hv-increased-storvsc-ringbuffer-and-max_io_requests.patch
@@ -0,0 +1,47 @@
+From devel-bounces@linuxdriverproject.org Thu Aug 5 12:34:01 2010
+From: Hank Janssen <hjanssen@microsoft.com>
+Subject: staging: hv: Increased storvsc ringbuffer and max_io_requests
+Date: Thu, 5 Aug 2010 19:30:31 +0000
+Message-ID: <8AFC7968D54FB448A30D8F38F259C56223FEC89F@TK5EX14MBXC114.redmond.corp.microsoft.com>
+Cc: Haiyang Zhang <haiyangz@microsoft.com>, "'gregkh@suse.de'" <gregkh@suse.de>
+
+From: Hank Janssen <hjanssen@microsoft.com>
+
+Increased storvsc ringbuffer and max_io_requests. This now more
+closely mimics the numbers on Hyper-V. And will allow more IO requests
+to take place for the SCSI driver.
+
+Max_IO is set to double from what it was before, Hyper-V allows it and
+we have had appliance builder requests to see if it was a problem to
+increase the number.
+
+Ringbuffer size for storvsc is now increased because I have seen A few buffer
+problems on extremely busy systems. They were Set pretty low before.
+And since max_io_requests is increased I Really needed to increase the buffer
+as well.
+
+
+Signed-off-by:Hank Janssen <hjanssen@microsoft.com>
+Signed-off-by:Haiyang Zhang <haiyangz@microsoft.com>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/hv/storvsc_api.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/hv/storvsc_api.h
++++ b/drivers/staging/hv/storvsc_api.h
+@@ -28,10 +28,10 @@
+ #include "vmbus_api.h"
+
+ /* Defines */
+-#define STORVSC_RING_BUFFER_SIZE (10*PAGE_SIZE)
++#define STORVSC_RING_BUFFER_SIZE (20*PAGE_SIZE)
+ #define BLKVSC_RING_BUFFER_SIZE (20*PAGE_SIZE)
+
+-#define STORVSC_MAX_IO_REQUESTS 64
++#define STORVSC_MAX_IO_REQUESTS 128
+
+ /*
+ * In Hyper-V, each port/path/target maps to 1 scsi host adapter. In
diff --git a/staging.current/staging-octeon-depends-on-netdevices.patch b/staging.current/staging-octeon-depends-on-netdevices.patch
new file mode 100644
index 00000000000000..d6a4db3a8bf8f4
--- /dev/null
+++ b/staging.current/staging-octeon-depends-on-netdevices.patch
@@ -0,0 +1,37 @@
+From randy.dunlap@oracle.com Mon Aug 30 16:56:54 2010
+Date: Tue, 24 Aug 2010 14:09:40 -0700
+From: Randy Dunlap <randy.dunlap@oracle.com>
+To: devel@driverdev.osuosl.org
+Cc: gregkh@suse.de, support@caviumnetworks.com,
+ Arnaud Lacombe <lacombar@gmail.com>
+Subject: Staging: octeon: depends on NETDEVICES
+Message-Id: <20100824140940.57369e83.randy.dunlap@oracle.com>
+
+From: Randy Dunlap <randy.dunlap@oracle.com>
+
+OCTEON_ETHERNET should depend on NETDEVICES.
+
+Fixes this kconfig warning:
+
+warning: (NET_DSA && NET && EXPERIMENTAL && NETDEVICES && !S390 || ...
+|| OCTEON_ETHERNET && STAGING && !STAGING_EXCLUDE_BUILD && CPU_CAVIUM_OCTEON) selects PHYLIB which has unmet direct dependencies (!S390 && NETDEVICES)
+
+Reported-by: Arnaud Lacombe <lacombar@gmail.com>
+Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
+Cc: support@caviumnetworks.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/octeon/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/octeon/Kconfig
++++ b/drivers/staging/octeon/Kconfig
+@@ -1,6 +1,6 @@
+ config OCTEON_ETHERNET
+ tristate "Cavium Networks Octeon Ethernet support"
+- depends on CPU_CAVIUM_OCTEON
++ depends on CPU_CAVIUM_OCTEON && NETDEVICES
+ select PHYLIB
+ select MDIO_OCTEON
+ help
diff --git a/staging.current/staging-rt2870sta-add-more-device-ids-from-vendor-drivers.patch b/staging.current/staging-rt2870sta-add-more-device-ids-from-vendor-drivers.patch
new file mode 100644
index 00000000000000..fe3e6208e6b814
--- /dev/null
+++ b/staging.current/staging-rt2870sta-add-more-device-ids-from-vendor-drivers.patch
@@ -0,0 +1,112 @@
+From ben@decadent.org.uk Mon Aug 30 16:53:26 2010
+Date: Sun, 29 Aug 2010 02:13:11 +0100
+From: Ben Hutchings <ben@decadent.org.uk>
+To: Greg Kroah-Hartman <gregkh@suse.de>
+Cc: devel@driverdev.osuosl.org
+Subject: Staging: rt2870sta: Add more device IDs from vendor drivers
+Message-ID: <20100829011311.GU5063@decadent.org.uk>
+
+Taken from DPO_RT3070_LinuxSTA_V2.3.0.4_20100604.tar.bz2 and
+2010_0709_RT2870_Linux_STA_v2.4.0.1.tar.bz2, with duplicates removed.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/rt2860/usb_main_dev.c | 41 ++++++++++++++++++++++++++++++++--
+ 1 file changed, 39 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/rt2860/usb_main_dev.c
++++ b/drivers/staging/rt2860/usb_main_dev.c
+@@ -44,6 +44,7 @@ struct usb_device_id rtusb_usb_id[] = {
+ {USB_DEVICE(0x07B8, 0x2870)}, /* AboCom */
+ {USB_DEVICE(0x07B8, 0x2770)}, /* AboCom */
+ {USB_DEVICE(0x0DF6, 0x0039)}, /* Sitecom 2770 */
++ {USB_DEVICE(0x0DF6, 0x003F)}, /* Sitecom 2770 */
+ {USB_DEVICE(0x083A, 0x7512)}, /* Arcadyan 2770 */
+ {USB_DEVICE(0x0789, 0x0162)}, /* Logitec 2870 */
+ {USB_DEVICE(0x0789, 0x0163)}, /* Logitec 2870 */
+@@ -95,7 +96,8 @@ struct usb_device_id rtusb_usb_id[] = {
+ {USB_DEVICE(0x050d, 0x815c)},
+ {USB_DEVICE(0x1482, 0x3C09)}, /* Abocom */
+ {USB_DEVICE(0x14B2, 0x3C09)}, /* Alpha */
+- {USB_DEVICE(0x04E8, 0x2018)}, /* samsung */
++ {USB_DEVICE(0x04E8, 0x2018)}, /* samsung linkstick2 */
++ {USB_DEVICE(0x1690, 0x0740)}, /* Askey */
+ {USB_DEVICE(0x5A57, 0x0280)}, /* Zinwell */
+ {USB_DEVICE(0x5A57, 0x0282)}, /* Zinwell */
+ {USB_DEVICE(0x7392, 0x7718)},
+@@ -105,21 +107,34 @@ struct usb_device_id rtusb_usb_id[] = {
+ {USB_DEVICE(0x1737, 0x0071)}, /* Linksys WUSB600N */
+ {USB_DEVICE(0x0411, 0x00e8)}, /* Buffalo WLI-UC-G300N */
+ {USB_DEVICE(0x050d, 0x815c)}, /* Belkin F5D8053 */
++ {USB_DEVICE(0x100D, 0x9031)}, /* Motorola 2770 */
+ #endif /* RT2870 // */
+ #ifdef RT3070
+ {USB_DEVICE(0x148F, 0x3070)}, /* Ralink 3070 */
+ {USB_DEVICE(0x148F, 0x3071)}, /* Ralink 3071 */
+ {USB_DEVICE(0x148F, 0x3072)}, /* Ralink 3072 */
+ {USB_DEVICE(0x0DB0, 0x3820)}, /* Ralink 3070 */
++ {USB_DEVICE(0x0DB0, 0x871C)}, /* Ralink 3070 */
++ {USB_DEVICE(0x0DB0, 0x822C)}, /* Ralink 3070 */
++ {USB_DEVICE(0x0DB0, 0x871B)}, /* Ralink 3070 */
++ {USB_DEVICE(0x0DB0, 0x822B)}, /* Ralink 3070 */
+ {USB_DEVICE(0x0DF6, 0x003E)}, /* Sitecom 3070 */
+ {USB_DEVICE(0x0DF6, 0x0042)}, /* Sitecom 3072 */
++ {USB_DEVICE(0x0DF6, 0x0048)}, /* Sitecom 3070 */
++ {USB_DEVICE(0x0DF6, 0x0047)}, /* Sitecom 3071 */
+ {USB_DEVICE(0x14B2, 0x3C12)}, /* AL 3070 */
+ {USB_DEVICE(0x18C5, 0x0012)}, /* Corega 3070 */
+ {USB_DEVICE(0x083A, 0x7511)}, /* Arcadyan 3070 */
++ {USB_DEVICE(0x083A, 0xA701)}, /* SMC 3070 */
++ {USB_DEVICE(0x083A, 0xA702)}, /* SMC 3072 */
+ {USB_DEVICE(0x1740, 0x9703)}, /* EnGenius 3070 */
+ {USB_DEVICE(0x1740, 0x9705)}, /* EnGenius 3071 */
+ {USB_DEVICE(0x1740, 0x9706)}, /* EnGenius 3072 */
++ {USB_DEVICE(0x1740, 0x9707)}, /* EnGenius 3070 */
++ {USB_DEVICE(0x1740, 0x9708)}, /* EnGenius 3071 */
++ {USB_DEVICE(0x1740, 0x9709)}, /* EnGenius 3072 */
+ {USB_DEVICE(0x13D3, 0x3273)}, /* AzureWave 3070 */
++ {USB_DEVICE(0x13D3, 0x3305)}, /* AzureWave 3070*/
+ {USB_DEVICE(0x1044, 0x800D)}, /* Gigabyte GN-WB32L 3070 */
+ {USB_DEVICE(0x2019, 0xAB25)}, /* Planex Communications, Inc. RT3070 */
+ {USB_DEVICE(0x07B8, 0x3070)}, /* AboCom 3070 */
+@@ -132,14 +147,36 @@ struct usb_device_id rtusb_usb_id[] = {
+ {USB_DEVICE(0x07D1, 0x3C0D)}, /* D-Link 3070 */
+ {USB_DEVICE(0x07D1, 0x3C0E)}, /* D-Link 3070 */
+ {USB_DEVICE(0x07D1, 0x3C0F)}, /* D-Link 3070 */
++ {USB_DEVICE(0x07D1, 0x3C16)}, /* D-Link 3070 */
++ {USB_DEVICE(0x07D1, 0x3C17)}, /* D-Link 8070 */
+ {USB_DEVICE(0x1D4D, 0x000C)}, /* Pegatron Corporation 3070 */
+ {USB_DEVICE(0x1D4D, 0x000E)}, /* Pegatron Corporation 3070 */
+ {USB_DEVICE(0x5A57, 0x5257)}, /* Zinwell 3070 */
+ {USB_DEVICE(0x5A57, 0x0283)}, /* Zinwell 3072 */
+ {USB_DEVICE(0x04BB, 0x0945)}, /* I-O DATA 3072 */
++ {USB_DEVICE(0x04BB, 0x0947)}, /* I-O DATA 3070 */
++ {USB_DEVICE(0x04BB, 0x0948)}, /* I-O DATA 3072 */
+ {USB_DEVICE(0x203D, 0x1480)}, /* Encore 3070 */
++ {USB_DEVICE(0x20B8, 0x8888)}, /* PARA INDUSTRIAL 3070 */
++ {USB_DEVICE(0x0B05, 0x1784)}, /* Asus 3072 */
++ {USB_DEVICE(0x203D, 0x14A9)}, /* Encore 3070*/
++ {USB_DEVICE(0x0DB0, 0x899A)}, /* MSI 3070*/
++ {USB_DEVICE(0x0DB0, 0x3870)}, /* MSI 3070*/
++ {USB_DEVICE(0x0DB0, 0x870A)}, /* MSI 3070*/
++ {USB_DEVICE(0x0DB0, 0x6899)}, /* MSI 3070 */
++ {USB_DEVICE(0x0DB0, 0x3822)}, /* MSI 3070 */
++ {USB_DEVICE(0x0DB0, 0x3871)}, /* MSI 3070 */
++ {USB_DEVICE(0x0DB0, 0x871A)}, /* MSI 3070 */
++ {USB_DEVICE(0x0DB0, 0x822A)}, /* MSI 3070 */
++ {USB_DEVICE(0x0DB0, 0x3821)}, /* Ralink 3070 */
++ {USB_DEVICE(0x0DB0, 0x821A)}, /* Ralink 3070 */
++ {USB_DEVICE(0x083A, 0xA703)}, /* IO-MAGIC */
++ {USB_DEVICE(0x13D3, 0x3307)}, /* Azurewave */
++ {USB_DEVICE(0x13D3, 0x3321)}, /* Azurewave */
++ {USB_DEVICE(0x07FA, 0x7712)}, /* Edimax */
++ {USB_DEVICE(0x0789, 0x0166)}, /* Edimax */
++ {USB_DEVICE(0x148F, 0x2070)}, /* Edimax */
+ #endif /* RT3070 // */
+- {USB_DEVICE(0x0DF6, 0x003F)}, /* Sitecom WL-608 */
+ {USB_DEVICE(0x1737, 0x0077)}, /* Linksys WUSB54GC-EU v3 */
+ {USB_DEVICE(0x2001, 0x3C09)}, /* D-Link */
+ {USB_DEVICE(0x2001, 0x3C0A)}, /* D-Link 3072 */
diff --git a/staging.current/staging-spectra-depend-on-x86_mrst.patch b/staging.current/staging-spectra-depend-on-x86_mrst.patch
new file mode 100644
index 00000000000000..02a2eeeb2d9b69
--- /dev/null
+++ b/staging.current/staging-spectra-depend-on-x86_mrst.patch
@@ -0,0 +1,29 @@
+From jeffm@suse.com Mon Aug 30 16:56:28 2010
+Message-ID: <4C73EF6A.5050603@suse.com>
+Date: Tue, 24 Aug 2010 12:12:26 -0400
+From: Jeff Mahoney <jeffm@suse.com>
+To: Greg Kroah-Hartman <GregKH@suse.de>
+Subject: Staging: spectra: depend on X86_MRST
+
+lld_nand fails to build on arches without virt_to_bus. Since this driver
+is specifically for hardware enablment on Moorestown, this patch adds
+Moorestown MID support as a dependency.
+
+Signed-off-by: Jeff Mahoney <jeffm@suse.com>
+Cc: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/spectra/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/staging/spectra/Kconfig
++++ b/drivers/staging/spectra/Kconfig
+@@ -2,6 +2,7 @@
+ menuconfig SPECTRA
+ tristate "Denali Spectra Flash Translation Layer"
+ depends on BLOCK
++ depends on X86_MRST
+ default n
+ ---help---
+ Enable the FTL pseudo-filesystem used with the NAND Flash
diff --git a/staging.current/staging-spectra-needs-linux-slab.h.patch b/staging.current/staging-spectra-needs-linux-slab.h.patch
new file mode 100644
index 00000000000000..07ad0c9d4d10ba
--- /dev/null
+++ b/staging.current/staging-spectra-needs-linux-slab.h.patch
@@ -0,0 +1,36 @@
+From geert@linux-m68k.org Mon Aug 30 16:52:22 2010
+Date: Mon, 30 Aug 2010 08:57:49 +0200 (CEST)
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+To: Greg Kroah-Hartman <gregkh@suse.de>
+Subject: staging: spectra needs <linux/slab.h>
+Message-ID: <alpine.DEB.2.00.1008300856010.28212@ayla.of.borg>
+
+On one of my m68k test builds I get:
+
+drivers/staging/spectra/ffsport.c: In function ‘ioctl_read_page_data’:
+drivers/staging/spectra/ffsport.c:196: error: implicit declaration of function ‘kmalloc’
+drivers/staging/spectra/ffsport.c:196: warning: assignment makes pointer from integer without a cast
+drivers/staging/spectra/ffsport.c:212: error: implicit declaration of function ‘kfree’
+drivers/staging/spectra/ffsport.c: In function ‘ioctl_write_page_data’:
+drivers/staging/spectra/ffsport.c:229: warning: assignment makes pointer from integer without a cast
+drivers/staging/spectra/ffsport.c: In function ‘SBD_setup_device’:
+drivers/staging/spectra/ffsport.c:637: warning: assignment makes pointer from integer without a cast
+
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Acked-by: Pekka Enberg <penberg@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/spectra/ffsport.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/staging/spectra/ffsport.c
++++ b/drivers/staging/spectra/ffsport.c
+@@ -28,6 +28,7 @@
+ #include <linux/log2.h>
+ #include <linux/init.h>
+ #include <linux/smp_lock.h>
++#include <linux/slab.h>
+
+ /**** Helper functions used for Div, Remainder operation on u64 ****/
+
diff --git a/staging.current/staging-wlan-ng-explicitly-set-some-fields-in-cfg80211-interface.patch b/staging.current/staging-wlan-ng-explicitly-set-some-fields-in-cfg80211-interface.patch
new file mode 100644
index 00000000000000..c7b993b4235089
--- /dev/null
+++ b/staging.current/staging-wlan-ng-explicitly-set-some-fields-in-cfg80211-interface.patch
@@ -0,0 +1,39 @@
+From karllinuxtest.relton@ntlworld.com Wed Sep 1 11:36:50 2010
+Subject: Staging: wlan-ng: Explicitly set some fields in cfg80211 interface
+From: Karl Relton <karllinuxtest.relton@ntlworld.com>
+To: Greg KH <greg@kroah.com>
+Cc: linux-kernel@vger.kernel.org, linux-wireless@vger.kernel.org
+Date: Wed, 11 Aug 2010 18:16:08 +0100
+Message-ID: <1281546968.2010.5.camel@dellpc>
+
+
+The cfg80211 api has introduced a few new fields. Rather than assume
+what cfg80211 api does by default, set these explicitly.
+
+Signed-off-by: Karl Relton <karllinuxtest.relton@ntlworld.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/staging/wlan-ng/cfg80211.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/staging/wlan-ng/cfg80211.c
++++ b/drivers/staging/wlan-ng/cfg80211.c
+@@ -219,6 +219,7 @@ int prism2_get_key(struct wiphy *wiphy,
+ return -ENOENT;
+ params.key_len = len;
+ params.key = wlandev->wep_keys[key_index];
++ params.seq_len = 0;
+
+ callback(cookie, &params);
+
+@@ -735,6 +736,8 @@ struct wiphy *wlan_create_wiphy(struct d
+ priv->band.n_channels = ARRAY_SIZE(prism2_channels);
+ priv->band.bitrates = priv->rates;
+ priv->band.n_bitrates = ARRAY_SIZE(prism2_rates);
++ priv->band.band = IEEE80211_BAND_2GHZ;
++ priv->band.ht_cap.ht_supported = false;
+ wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
+
+ set_wiphy_dev(wiphy, dev);
diff --git a/staging.current/staging-zram-free-device-memory-when-init-fails.patch b/staging.current/staging-zram-free-device-memory-when-init-fails.patch
new file mode 100644
index 00000000000000..8e908e6fb76fa0
--- /dev/null
+++ b/staging.current/staging-zram-free-device-memory-when-init-fails.patch
@@ -0,0 +1,26 @@
+From linux-next-owner@vger.kernel.org Mon Aug 30 16:55:05 2010
+Date: Sat, 28 Aug 2010 10:09:05 +0300
+From: Shahar Havivi <shaharh@redhat.com>
+To: linux-next@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org, greg@kroah.com
+Subject: Staging: zram: free device memory when init fails
+Message-ID: <20100828070901.GA31943@redhat.com>
+Content-Disposition: inline
+
+Signed-off-by: Shahar Havivi <shaharh@redhat.com>
+Cc: Nitin Gupta <ngupta@vflare.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/staging/zram/zram_drv.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/staging/zram/zram_drv.c
++++ b/drivers/staging/zram/zram_drv.c
+@@ -769,6 +769,7 @@ static int __init zram_init(void)
+ free_devices:
+ while (dev_id)
+ destroy_device(&devices[--dev_id]);
++ kfree(devices);
+ unregister:
+ unregister_blkdev(zram_major, "zram");
+ out:
diff --git a/usb/usb-add-intel-langwell-usb-otg-transceiver-driver.patch b/usb/usb-add-intel-langwell-usb-otg-transceiver-driver.patch
new file mode 100644
index 00000000000000..e9d2c754b5bb75
--- /dev/null
+++ b/usb/usb-add-intel-langwell-usb-otg-transceiver-driver.patch
@@ -0,0 +1,2613 @@
+From linux-usb-owner@vger.kernel.org Wed Sep 1 11:39:27 2010
+From: Hao Wu <hao.wu@intel.com>
+Subject: usb: Add Intel Langwell USB OTG Transceiver Driver
+To: linux-usb@vger.kernel.org
+Date: Thu, 05 Aug 2010 14:17:28 +0100
+Message-ID: <20100805131726.12473.94642.stgit@localhost.localdomain>
+
+From: Hao Wu <hao.wu@intel.com>
+
+This adds support for the USB transceiver driver in the Langwell chipset used
+on the Intel MID platforms. It folds up the original patch set which includes
+basic support for the device, PHY low power mode (Please notice that there is
+a limitation, after we drive VBus down, 2ms delay is required from SCU FW to
+sync up OTGSC register with USBCFG register), software timers (the hardware
+timers do not work in low power mode), HNP, SRP.
+
+
+Signed-off-by: Hao Wu <hao.wu@intel.com>
+Signed-off-by: Alek Du <alek.du@intel.com>
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/otg/Kconfig | 14
+ drivers/usb/otg/Makefile | 1
+ drivers/usb/otg/langwell_otg.c | 2408 +++++++++++++++++++++++++++++++++++++++
+ include/linux/usb/langwell_otg.h | 139 ++
+ 4 files changed, 2562 insertions(+)
+
+--- a/drivers/usb/otg/Kconfig
++++ b/drivers/usb/otg/Kconfig
+@@ -67,4 +67,18 @@ config NOP_USB_XCEIV
+ built-in with usb ip or which are autonomous and doesn't require any
+ phy programming such as ISP1x04 etc.
+
++config USB_LANGWELL_OTG
++ tristate "Intel Langwell USB OTG dual-role support"
++ depends on USB && X86_MRST
++ select USB_OTG
++ select USB_OTG_UTILS
++ help
++ Say Y here if you want to build Intel Langwell USB OTG
++ transciever driver in kernel. This driver implements role
++ switch between EHCI host driver and Langwell USB OTG
++ client driver.
++
++ To compile this driver as a module, choose M here: the
++ module will be called langwell_otg.
++
+ endif # USB || OTG
+--- a/drivers/usb/otg/Makefile
++++ b/drivers/usb/otg/Makefile
+@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg.o
+ obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o
+ obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o
+ obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o
++obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o
+ obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o
+ obj-$(CONFIG_USB_ULPI) += ulpi.o
+
+--- /dev/null
++++ b/drivers/usb/otg/langwell_otg.c
+@@ -0,0 +1,2408 @@
++/*
++ * Intel Langwell USB OTG transceiver driver
++ * Copyright (C) 2008 - 2009, Intel Corporation.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program; if not, write to the Free Software Foundation, Inc.,
++ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ */
++/* This driver helps to switch Langwell OTG controller function between host
++ * and peripheral. It works with EHCI driver and Langwell client controller
++ * driver together.
++ */
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/pci.h>
++#include <linux/errno.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/device.h>
++#include <linux/moduleparam.h>
++#include <linux/usb/ch9.h>
++#include <linux/usb/gadget.h>
++#include <linux/usb.h>
++#include <linux/usb/otg.h>
++#include <linux/usb/hcd.h>
++#include <linux/notifier.h>
++#include <linux/delay.h>
++#include <asm/intel_scu_ipc.h>
++
++#include <linux/usb/langwell_otg.h>
++
++#define DRIVER_DESC "Intel Langwell USB OTG transceiver driver"
++#define DRIVER_VERSION "3.0.0.32L.0003"
++
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_AUTHOR("Henry Yuan <hang.yuan@intel.com>, Hao Wu <hao.wu@intel.com>");
++MODULE_VERSION(DRIVER_VERSION);
++MODULE_LICENSE("GPL");
++
++static const char driver_name[] = "langwell_otg";
++
++static int langwell_otg_probe(struct pci_dev *pdev,
++ const struct pci_device_id *id);
++static void langwell_otg_remove(struct pci_dev *pdev);
++static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message);
++static int langwell_otg_resume(struct pci_dev *pdev);
++
++static int langwell_otg_set_host(struct otg_transceiver *otg,
++ struct usb_bus *host);
++static int langwell_otg_set_peripheral(struct otg_transceiver *otg,
++ struct usb_gadget *gadget);
++static int langwell_otg_start_srp(struct otg_transceiver *otg);
++
++static const struct pci_device_id pci_ids[] = {{
++ .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
++ .class_mask = ~0,
++ .vendor = 0x8086,
++ .device = 0x0811,
++ .subvendor = PCI_ANY_ID,
++ .subdevice = PCI_ANY_ID,
++}, { /* end: all zeroes */ }
++};
++
++static struct pci_driver otg_pci_driver = {
++ .name = (char *) driver_name,
++ .id_table = pci_ids,
++
++ .probe = langwell_otg_probe,
++ .remove = langwell_otg_remove,
++
++ .suspend = langwell_otg_suspend,
++ .resume = langwell_otg_resume,
++};
++
++static const char *state_string(enum usb_otg_state state)
++{
++ switch (state) {
++ case OTG_STATE_A_IDLE:
++ return "a_idle";
++ case OTG_STATE_A_WAIT_VRISE:
++ return "a_wait_vrise";
++ case OTG_STATE_A_WAIT_BCON:
++ return "a_wait_bcon";
++ case OTG_STATE_A_HOST:
++ return "a_host";
++ case OTG_STATE_A_SUSPEND:
++ return "a_suspend";
++ case OTG_STATE_A_PERIPHERAL:
++ return "a_peripheral";
++ case OTG_STATE_A_WAIT_VFALL:
++ return "a_wait_vfall";
++ case OTG_STATE_A_VBUS_ERR:
++ return "a_vbus_err";
++ case OTG_STATE_B_IDLE:
++ return "b_idle";
++ case OTG_STATE_B_SRP_INIT:
++ return "b_srp_init";
++ case OTG_STATE_B_PERIPHERAL:
++ return "b_peripheral";
++ case OTG_STATE_B_WAIT_ACON:
++ return "b_wait_acon";
++ case OTG_STATE_B_HOST:
++ return "b_host";
++ default:
++ return "UNDEFINED";
++ }
++}
++
++/* HSM timers */
++static inline struct langwell_otg_timer *otg_timer_initializer
++(void (*function)(unsigned long), unsigned long expires, unsigned long data)
++{
++ struct langwell_otg_timer *timer;
++ timer = kmalloc(sizeof(struct langwell_otg_timer), GFP_KERNEL);
++ if (timer == NULL)
++ return timer;
++
++ timer->function = function;
++ timer->expires = expires;
++ timer->data = data;
++ return timer;
++}
++
++static struct langwell_otg_timer *a_wait_vrise_tmr, *a_aidl_bdis_tmr,
++ *b_se0_srp_tmr, *b_srp_init_tmr;
++
++static struct list_head active_timers;
++
++static struct langwell_otg *the_transceiver;
++
++/* host/client notify transceiver when event affects HNP state */
++void langwell_update_transceiver(void)
++{
++ struct langwell_otg *lnw = the_transceiver;
++
++ dev_dbg(lnw->dev, "transceiver is updated\n");
++
++ if (!lnw->qwork)
++ return ;
++
++ queue_work(lnw->qwork, &lnw->work);
++}
++EXPORT_SYMBOL(langwell_update_transceiver);
++
++static int langwell_otg_set_host(struct otg_transceiver *otg,
++ struct usb_bus *host)
++{
++ otg->host = host;
++
++ return 0;
++}
++
++static int langwell_otg_set_peripheral(struct otg_transceiver *otg,
++ struct usb_gadget *gadget)
++{
++ otg->gadget = gadget;
++
++ return 0;
++}
++
++static int langwell_otg_set_power(struct otg_transceiver *otg,
++ unsigned mA)
++{
++ return 0;
++}
++
++/* A-device drives vbus, controlled through PMIC CHRGCNTL register*/
++static int langwell_otg_set_vbus(struct otg_transceiver *otg, bool enabled)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ u8 r;
++
++ dev_dbg(lnw->dev, "%s <--- %s\n", __func__, enabled ? "on" : "off");
++
++ /* FIXME: surely we should cache this on the first read. If not use
++ readv to avoid two transactions */
++ if (intel_scu_ipc_ioread8(0x00, &r) < 0) {
++ dev_dbg(lnw->dev, "Failed to read PMIC register 0xD2");
++ return -EBUSY;
++ }
++ if ((r & 0x03) != 0x02) {
++ dev_dbg(lnw->dev, "not NEC PMIC attached\n");
++ return -EBUSY;
++ }
++
++ if (intel_scu_ipc_ioread8(0x20, &r) < 0) {
++ dev_dbg(lnw->dev, "Failed to read PMIC register 0xD2");
++ return -EBUSY;
++ }
++
++ if ((r & 0x20) == 0) {
++ dev_dbg(lnw->dev, "no battery attached\n");
++ return -EBUSY;
++ }
++
++ /* Workaround for battery attachment issue */
++ if (r == 0x34) {
++ dev_dbg(lnw->dev, "no battery attached on SH\n");
++ return -EBUSY;
++ }
++
++ dev_dbg(lnw->dev, "battery attached. 2 reg = %x\n", r);
++
++ /* workaround: FW detect writing 0x20/0xc0 to d4 event.
++ * this is only for NEC PMIC.
++ */
++
++ if (intel_scu_ipc_iowrite8(0xD4, enabled ? 0x20 : 0xC0))
++ dev_dbg(lnw->dev, "Failed to write PMIC.\n");
++
++ dev_dbg(lnw->dev, "%s --->\n", __func__);
++
++ return 0;
++}
++
++/* charge vbus or discharge vbus through a resistor to ground */
++static void langwell_otg_chrg_vbus(int on)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ u32 val;
++
++ val = readl(lnw->iotg.base + CI_OTGSC);
++
++ if (on)
++ writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VC,
++ lnw->iotg.base + CI_OTGSC);
++ else
++ writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VD,
++ lnw->iotg.base + CI_OTGSC);
++}
++
++/* Start SRP */
++static int langwell_otg_start_srp(struct otg_transceiver *otg)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
++ u32 val;
++
++ dev_dbg(lnw->dev, "%s --->\n", __func__);
++
++ val = readl(iotg->base + CI_OTGSC);
++
++ writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HADP,
++ iotg->base + CI_OTGSC);
++
++ /* Check if the data plus is finished or not */
++ msleep(8);
++ val = readl(iotg->base + CI_OTGSC);
++ if (val & (OTGSC_HADP | OTGSC_DP))
++ dev_dbg(lnw->dev, "DataLine SRP Error\n");
++
++ /* Disable interrupt - b_sess_vld */
++ val = readl(iotg->base + CI_OTGSC);
++ val &= (~(OTGSC_BSVIE | OTGSC_BSEIE));
++ writel(val, iotg->base + CI_OTGSC);
++
++ /* Start VBus SRP, drive vbus to generate VBus pulse */
++ iotg->otg.set_vbus(&iotg->otg, true);
++ msleep(15);
++ iotg->otg.set_vbus(&iotg->otg, false);
++
++ /* Enable interrupt - b_sess_vld*/
++ val = readl(iotg->base + CI_OTGSC);
++ dev_dbg(lnw->dev, "after VBUS pulse otgsc = %x\n", val);
++
++ val |= (OTGSC_BSVIE | OTGSC_BSEIE);
++ writel(val, iotg->base + CI_OTGSC);
++
++ /* If Vbus is valid, then update the hsm */
++ if (val & OTGSC_BSV) {
++ dev_dbg(lnw->dev, "no b_sess_vld interrupt\n");
++
++ lnw->iotg.hsm.b_sess_vld = 1;
++ langwell_update_transceiver();
++ }
++
++ dev_dbg(lnw->dev, "%s <---\n", __func__);
++ return 0;
++}
++
++/* stop SOF via bus_suspend */
++static void langwell_otg_loc_sof(int on)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct usb_hcd *hcd;
++ int err;
++
++ dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "suspend" : "resume");
++
++ hcd = bus_to_hcd(lnw->iotg.otg.host);
++ if (on)
++ err = hcd->driver->bus_resume(hcd);
++ else
++ err = hcd->driver->bus_suspend(hcd);
++
++ if (err)
++ dev_dbg(lnw->dev, "Fail to resume/suspend USB bus - %d\n", err);
++
++ dev_dbg(lnw->dev, "%s <---\n", __func__);
++}
++
++static int langwell_otg_check_otgsc(void)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ u32 otgsc, usbcfg;
++
++ dev_dbg(lnw->dev, "check sync OTGSC and USBCFG registers\n");
++
++ otgsc = readl(lnw->iotg.base + CI_OTGSC);
++ usbcfg = readl(lnw->usbcfg);
++
++ dev_dbg(lnw->dev, "OTGSC = %08x, USBCFG = %08x\n",
++ otgsc, usbcfg);
++ dev_dbg(lnw->dev, "OTGSC_AVV = %d\n", !!(otgsc & OTGSC_AVV));
++ dev_dbg(lnw->dev, "USBCFG.VBUSVAL = %d\n",
++ !!(usbcfg & USBCFG_VBUSVAL));
++ dev_dbg(lnw->dev, "OTGSC_ASV = %d\n", !!(otgsc & OTGSC_ASV));
++ dev_dbg(lnw->dev, "USBCFG.AVALID = %d\n",
++ !!(usbcfg & USBCFG_AVALID));
++ dev_dbg(lnw->dev, "OTGSC_BSV = %d\n", !!(otgsc & OTGSC_BSV));
++ dev_dbg(lnw->dev, "USBCFG.BVALID = %d\n",
++ !!(usbcfg & USBCFG_BVALID));
++ dev_dbg(lnw->dev, "OTGSC_BSE = %d\n", !!(otgsc & OTGSC_BSE));
++ dev_dbg(lnw->dev, "USBCFG.SESEND = %d\n",
++ !!(usbcfg & USBCFG_SESEND));
++
++ /* Check USBCFG VBusValid/AValid/BValid/SessEnd */
++ if (!!(otgsc & OTGSC_AVV) ^ !!(usbcfg & USBCFG_VBUSVAL)) {
++ dev_dbg(lnw->dev, "OTGSC.AVV != USBCFG.VBUSVAL\n");
++ goto err;
++ }
++ if (!!(otgsc & OTGSC_ASV) ^ !!(usbcfg & USBCFG_AVALID)) {
++ dev_dbg(lnw->dev, "OTGSC.ASV != USBCFG.AVALID\n");
++ goto err;
++ }
++ if (!!(otgsc & OTGSC_BSV) ^ !!(usbcfg & USBCFG_BVALID)) {
++ dev_dbg(lnw->dev, "OTGSC.BSV != USBCFG.BVALID\n");
++ goto err;
++ }
++ if (!!(otgsc & OTGSC_BSE) ^ !!(usbcfg & USBCFG_SESEND)) {
++ dev_dbg(lnw->dev, "OTGSC.BSE != USBCFG.SESSEN\n");
++ goto err;
++ }
++
++ dev_dbg(lnw->dev, "OTGSC and USBCFG are synced\n");
++
++ return 0;
++
++err:
++ dev_warn(lnw->dev, "OTGSC isn't equal to USBCFG\n");
++ return -EPIPE;
++}
++
++
++static void langwell_otg_phy_low_power(int on)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
++ u8 val, phcd;
++ int retval;
++
++ dev_dbg(lnw->dev, "%s ---> %s mode\n",
++ __func__, on ? "Low power" : "Normal");
++
++ phcd = 0x40;
++
++ val = readb(iotg->base + CI_HOSTPC1 + 2);
++
++ if (on) {
++ /* Due to hardware issue, after set PHCD, sync will failed
++ * between USBCFG and OTGSC, so before set PHCD, check if
++ * sync is in process now. If the answer is "yes", then do
++ * not touch PHCD bit */
++ retval = langwell_otg_check_otgsc();
++ if (retval) {
++ dev_dbg(lnw->dev, "Skip PHCD programming..\n");
++ return ;
++ }
++
++ writeb(val | phcd, iotg->base + CI_HOSTPC1 + 2);
++ } else
++ writeb(val & ~phcd, iotg->base + CI_HOSTPC1 + 2);
++
++ dev_dbg(lnw->dev, "%s <--- done\n", __func__);
++}
++
++/* After drv vbus, add 2 ms delay to set PHCD */
++static void langwell_otg_phy_low_power_wait(int on)
++{
++ struct langwell_otg *lnw = the_transceiver;
++
++ dev_dbg(lnw->dev, "add 2ms delay before programing PHCD\n");
++
++ mdelay(2);
++ langwell_otg_phy_low_power(on);
++}
++
++/* Enable/Disable OTG interrupt */
++static void langwell_otg_intr(int on)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
++ u32 val;
++
++ dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
++
++ val = readl(iotg->base + CI_OTGSC);
++
++ /* OTGSC_INT_MASK doesn't contains 1msInt */
++ if (on) {
++ val = val | (OTGSC_INT_MASK);
++ writel(val, iotg->base + CI_OTGSC);
++ } else {
++ val = val & ~(OTGSC_INT_MASK);
++ writel(val, iotg->base + CI_OTGSC);
++ }
++
++ dev_dbg(lnw->dev, "%s <---\n", __func__);
++}
++
++/* set HAAR: Hardware Assist Auto-Reset */
++static void langwell_otg_HAAR(int on)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
++ u32 val;
++
++ dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
++
++ val = readl(iotg->base + CI_OTGSC);
++ if (on)
++ writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HAAR,
++ iotg->base + CI_OTGSC);
++ else
++ writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HAAR,
++ iotg->base + CI_OTGSC);
++
++ dev_dbg(lnw->dev, "%s <---\n", __func__);
++}
++
++/* set HABA: Hardware Assist B-Disconnect to A-Connect */
++static void langwell_otg_HABA(int on)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
++ u32 val;
++
++ dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off");
++
++ val = readl(iotg->base + CI_OTGSC);
++ if (on)
++ writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HABA,
++ iotg->base + CI_OTGSC);
++ else
++ writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HABA,
++ iotg->base + CI_OTGSC);
++
++ dev_dbg(lnw->dev, "%s <---\n", __func__);
++}
++
++static int langwell_otg_check_se0_srp(int on)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ int delay_time = TB_SE0_SRP * 10;
++ u32 val;
++
++ dev_dbg(lnw->dev, "%s --->\n", __func__);
++
++ do {
++ udelay(100);
++ if (!delay_time--)
++ break;
++ val = readl(lnw->iotg.base + CI_PORTSC1);
++ val &= PORTSC_LS;
++ } while (!val);
++
++ dev_dbg(lnw->dev, "%s <---\n", __func__);
++ return val;
++}
++
++/* The timeout callback function to set time out bit */
++static void set_tmout(unsigned long indicator)
++{
++ *(int *)indicator = 1;
++}
++
++void langwell_otg_nsf_msg(unsigned long indicator)
++{
++ struct langwell_otg *lnw = the_transceiver;
++
++ switch (indicator) {
++ case 2:
++ case 4:
++ case 6:
++ case 7:
++ dev_warn(lnw->dev,
++ "OTG:NSF-%lu - deivce not responding\n", indicator);
++ break;
++ case 3:
++ dev_warn(lnw->dev,
++ "OTG:NSF-%lu - deivce not supported\n", indicator);
++ break;
++ default:
++ dev_warn(lnw->dev, "Do not have this kind of NSF\n");
++ break;
++ }
++}
++
++/* Initialize timers */
++static int langwell_otg_init_timers(struct otg_hsm *hsm)
++{
++ /* HSM used timers */
++ a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE,
++ (unsigned long)&hsm->a_wait_vrise_tmout);
++ if (a_wait_vrise_tmr == NULL)
++ return -ENOMEM;
++ a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS,
++ (unsigned long)&hsm->a_aidl_bdis_tmout);
++ if (a_aidl_bdis_tmr == NULL)
++ return -ENOMEM;
++ b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP,
++ (unsigned long)&hsm->b_se0_srp);
++ if (b_se0_srp_tmr == NULL)
++ return -ENOMEM;
++ b_srp_init_tmr = otg_timer_initializer(&set_tmout, TB_SRP_INIT,
++ (unsigned long)&hsm->b_srp_init_tmout);
++ if (b_srp_init_tmr == NULL)
++ return -ENOMEM;
++
++ return 0;
++}
++
++/* Free timers */
++static void langwell_otg_free_timers(void)
++{
++ kfree(a_wait_vrise_tmr);
++ kfree(a_aidl_bdis_tmr);
++ kfree(b_se0_srp_tmr);
++ kfree(b_srp_init_tmr);
++}
++
++/* The timeout callback function to set time out bit */
++static void langwell_otg_timer_fn(unsigned long indicator)
++{
++ struct langwell_otg *lnw = the_transceiver;
++
++ *(int *)indicator = 1;
++
++ dev_dbg(lnw->dev, "kernel timer - timeout\n");
++
++ langwell_update_transceiver();
++}
++
++/* kernel timer used instead of HW based interrupt */
++static void langwell_otg_add_ktimer(enum langwell_otg_timer_type timers)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
++ unsigned long j = jiffies;
++ unsigned long data, time;
++
++ switch (timers) {
++ case TA_WAIT_VRISE_TMR:
++ iotg->hsm.a_wait_vrise_tmout = 0;
++ data = (unsigned long)&iotg->hsm.a_wait_vrise_tmout;
++ time = TA_WAIT_VRISE;
++ break;
++ case TA_WAIT_BCON_TMR:
++ iotg->hsm.a_wait_bcon_tmout = 0;
++ data = (unsigned long)&iotg->hsm.a_wait_bcon_tmout;
++ time = TA_WAIT_BCON;
++ break;
++ case TA_AIDL_BDIS_TMR:
++ iotg->hsm.a_aidl_bdis_tmout = 0;
++ data = (unsigned long)&iotg->hsm.a_aidl_bdis_tmout;
++ time = TA_AIDL_BDIS;
++ break;
++ case TB_ASE0_BRST_TMR:
++ iotg->hsm.b_ase0_brst_tmout = 0;
++ data = (unsigned long)&iotg->hsm.b_ase0_brst_tmout;
++ time = TB_ASE0_BRST;
++ break;
++ case TB_SRP_INIT_TMR:
++ iotg->hsm.b_srp_init_tmout = 0;
++ data = (unsigned long)&iotg->hsm.b_srp_init_tmout;
++ time = TB_SRP_INIT;
++ break;
++ case TB_SRP_FAIL_TMR:
++ iotg->hsm.b_srp_fail_tmout = 0;
++ data = (unsigned long)&iotg->hsm.b_srp_fail_tmout;
++ time = TB_SRP_FAIL;
++ break;
++ case TB_BUS_SUSPEND_TMR:
++ iotg->hsm.b_bus_suspend_tmout = 0;
++ data = (unsigned long)&iotg->hsm.b_bus_suspend_tmout;
++ time = TB_BUS_SUSPEND;
++ break;
++ default:
++ dev_dbg(lnw->dev, "unkown timer, cannot enable it\n");
++ return;
++ }
++
++ lnw->hsm_timer.data = data;
++ lnw->hsm_timer.function = langwell_otg_timer_fn;
++ lnw->hsm_timer.expires = j + time * HZ / 1000; /* milliseconds */
++
++ add_timer(&lnw->hsm_timer);
++
++ dev_dbg(lnw->dev, "add timer successfully\n");
++}
++
++/* Add timer to timer list */
++static void langwell_otg_add_timer(void *gtimer)
++{
++ struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer;
++ struct langwell_otg_timer *tmp_timer;
++ struct intel_mid_otg_xceiv *iotg = &the_transceiver->iotg;
++ u32 val32;
++
++ /* Check if the timer is already in the active list,
++ * if so update timer count
++ */
++ list_for_each_entry(tmp_timer, &active_timers, list)
++ if (tmp_timer == timer) {
++ timer->count = timer->expires;
++ return;
++ }
++ timer->count = timer->expires;
++
++ if (list_empty(&active_timers)) {
++ val32 = readl(iotg->base + CI_OTGSC);
++ writel(val32 | OTGSC_1MSE, iotg->base + CI_OTGSC);
++ }
++
++ list_add_tail(&timer->list, &active_timers);
++}
++
++/* Remove timer from the timer list; clear timeout status */
++static void langwell_otg_del_timer(void *gtimer)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer;
++ struct langwell_otg_timer *tmp_timer, *del_tmp;
++ u32 val32;
++
++ list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list)
++ if (tmp_timer == timer)
++ list_del(&timer->list);
++
++ if (list_empty(&active_timers)) {
++ val32 = readl(lnw->iotg.base + CI_OTGSC);
++ writel(val32 & ~OTGSC_1MSE, lnw->iotg.base + CI_OTGSC);
++ }
++}
++
++/* Reduce timer count by 1, and find timeout conditions.*/
++static int langwell_otg_tick_timer(u32 *int_sts)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct langwell_otg_timer *tmp_timer, *del_tmp;
++ int expired = 0;
++
++ list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) {
++ tmp_timer->count--;
++ /* check if timer expires */
++ if (!tmp_timer->count) {
++ list_del(&tmp_timer->list);
++ tmp_timer->function(tmp_timer->data);
++ expired = 1;
++ }
++ }
++
++ if (list_empty(&active_timers)) {
++ dev_dbg(lnw->dev, "tick timer: disable 1ms int\n");
++ *int_sts = *int_sts & ~OTGSC_1MSE;
++ }
++ return expired;
++}
++
++static void reset_otg(void)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ int delay_time = 1000;
++ u32 val;
++
++ dev_dbg(lnw->dev, "reseting OTG controller ...\n");
++ val = readl(lnw->iotg.base + CI_USBCMD);
++ writel(val | USBCMD_RST, lnw->iotg.base + CI_USBCMD);
++ do {
++ udelay(100);
++ if (!delay_time--)
++ dev_dbg(lnw->dev, "reset timeout\n");
++ val = readl(lnw->iotg.base + CI_USBCMD);
++ val &= USBCMD_RST;
++ } while (val != 0);
++ dev_dbg(lnw->dev, "reset done.\n");
++}
++
++static void set_host_mode(void)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ u32 val;
++
++ reset_otg();
++ val = readl(lnw->iotg.base + CI_USBMODE);
++ val = (val & (~USBMODE_CM)) | USBMODE_HOST;
++ writel(val, lnw->iotg.base + CI_USBMODE);
++}
++
++static void set_client_mode(void)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ u32 val;
++
++ reset_otg();
++ val = readl(lnw->iotg.base + CI_USBMODE);
++ val = (val & (~USBMODE_CM)) | USBMODE_DEVICE;
++ writel(val, lnw->iotg.base + CI_USBMODE);
++}
++
++static void init_hsm(void)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
++ u32 val32;
++
++ /* read OTGSC after reset */
++ val32 = readl(lnw->iotg.base + CI_OTGSC);
++ dev_dbg(lnw->dev, "%s: OTGSC init value = 0x%x\n", __func__, val32);
++
++ /* set init state */
++ if (val32 & OTGSC_ID) {
++ iotg->hsm.id = 1;
++ iotg->otg.default_a = 0;
++ set_client_mode();
++ iotg->otg.state = OTG_STATE_B_IDLE;
++ } else {
++ iotg->hsm.id = 0;
++ iotg->otg.default_a = 1;
++ set_host_mode();
++ iotg->otg.state = OTG_STATE_A_IDLE;
++ }
++
++ /* set session indicator */
++ if (val32 & OTGSC_BSE)
++ iotg->hsm.b_sess_end = 1;
++ if (val32 & OTGSC_BSV)
++ iotg->hsm.b_sess_vld = 1;
++ if (val32 & OTGSC_ASV)
++ iotg->hsm.a_sess_vld = 1;
++ if (val32 & OTGSC_AVV)
++ iotg->hsm.a_vbus_vld = 1;
++
++ /* defautly power the bus */
++ iotg->hsm.a_bus_req = 1;
++ iotg->hsm.a_bus_drop = 0;
++ /* defautly don't request bus as B device */
++ iotg->hsm.b_bus_req = 0;
++ /* no system error */
++ iotg->hsm.a_clr_err = 0;
++
++ langwell_otg_phy_low_power_wait(1);
++}
++
++static void update_hsm(void)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
++ u32 val32;
++
++ /* read OTGSC */
++ val32 = readl(lnw->iotg.base + CI_OTGSC);
++ dev_dbg(lnw->dev, "%s: OTGSC value = 0x%x\n", __func__, val32);
++
++ iotg->hsm.id = !!(val32 & OTGSC_ID);
++ iotg->hsm.b_sess_end = !!(val32 & OTGSC_BSE);
++ iotg->hsm.b_sess_vld = !!(val32 & OTGSC_BSV);
++ iotg->hsm.a_sess_vld = !!(val32 & OTGSC_ASV);
++ iotg->hsm.a_vbus_vld = !!(val32 & OTGSC_AVV);
++}
++
++static irqreturn_t otg_dummy_irq(int irq, void *_dev)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ void __iomem *reg_base = _dev;
++ u32 val;
++ u32 int_mask = 0;
++
++ val = readl(reg_base + CI_USBMODE);
++ if ((val & USBMODE_CM) != USBMODE_DEVICE)
++ return IRQ_NONE;
++
++ val = readl(reg_base + CI_USBSTS);
++ int_mask = val & INTR_DUMMY_MASK;
++
++ if (int_mask == 0)
++ return IRQ_NONE;
++
++ /* clear hsm.b_conn here since host driver can't detect it
++ * otg_dummy_irq called means B-disconnect happened.
++ */
++ if (lnw->iotg.hsm.b_conn) {
++ lnw->iotg.hsm.b_conn = 0;
++ if (spin_trylock(&lnw->wq_lock)) {
++ langwell_update_transceiver();
++ spin_unlock(&lnw->wq_lock);
++ }
++ }
++
++ /* Clear interrupts */
++ writel(int_mask, reg_base + CI_USBSTS);
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t otg_irq(int irq, void *_dev)
++{
++ struct langwell_otg *lnw = _dev;
++ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
++ u32 int_sts, int_en;
++ u32 int_mask = 0;
++ int flag = 0;
++
++ int_sts = readl(lnw->iotg.base + CI_OTGSC);
++ int_en = (int_sts & OTGSC_INTEN_MASK) >> 8;
++ int_mask = int_sts & int_en;
++ if (int_mask == 0)
++ return IRQ_NONE;
++
++ if (int_mask & OTGSC_IDIS) {
++ dev_dbg(lnw->dev, "%s: id change int\n", __func__);
++ iotg->hsm.id = (int_sts & OTGSC_ID) ? 1 : 0;
++ dev_dbg(lnw->dev, "id = %d\n", iotg->hsm.id);
++ flag = 1;
++ }
++ if (int_mask & OTGSC_DPIS) {
++ dev_dbg(lnw->dev, "%s: data pulse int\n", __func__);
++ iotg->hsm.a_srp_det = (int_sts & OTGSC_DPS) ? 1 : 0;
++ dev_dbg(lnw->dev, "data pulse = %d\n", iotg->hsm.a_srp_det);
++ flag = 1;
++ }
++ if (int_mask & OTGSC_BSEIS) {
++ dev_dbg(lnw->dev, "%s: b session end int\n", __func__);
++ iotg->hsm.b_sess_end = (int_sts & OTGSC_BSE) ? 1 : 0;
++ dev_dbg(lnw->dev, "b_sess_end = %d\n", iotg->hsm.b_sess_end);
++ flag = 1;
++ }
++ if (int_mask & OTGSC_BSVIS) {
++ dev_dbg(lnw->dev, "%s: b session valid int\n", __func__);
++ iotg->hsm.b_sess_vld = (int_sts & OTGSC_BSV) ? 1 : 0;
++ dev_dbg(lnw->dev, "b_sess_vld = %d\n", iotg->hsm.b_sess_end);
++ flag = 1;
++ }
++ if (int_mask & OTGSC_ASVIS) {
++ dev_dbg(lnw->dev, "%s: a session valid int\n", __func__);
++ iotg->hsm.a_sess_vld = (int_sts & OTGSC_ASV) ? 1 : 0;
++ dev_dbg(lnw->dev, "a_sess_vld = %d\n", iotg->hsm.a_sess_vld);
++ flag = 1;
++ }
++ if (int_mask & OTGSC_AVVIS) {
++ dev_dbg(lnw->dev, "%s: a vbus valid int\n", __func__);
++ iotg->hsm.a_vbus_vld = (int_sts & OTGSC_AVV) ? 1 : 0;
++ dev_dbg(lnw->dev, "a_vbus_vld = %d\n", iotg->hsm.a_vbus_vld);
++ flag = 1;
++ }
++
++ if (int_mask & OTGSC_1MSS) {
++ /* need to schedule otg_work if any timer is expired */
++ if (langwell_otg_tick_timer(&int_sts))
++ flag = 1;
++ }
++
++ writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask,
++ lnw->iotg.base + CI_OTGSC);
++ if (flag)
++ langwell_update_transceiver();
++
++ return IRQ_HANDLED;
++}
++
++static int langwell_otg_iotg_notify(struct notifier_block *nb,
++ unsigned long action, void *data)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct intel_mid_otg_xceiv *iotg = data;
++ int flag = 0;
++
++ if (iotg == NULL)
++ return NOTIFY_BAD;
++
++ if (lnw == NULL)
++ return NOTIFY_BAD;
++
++ switch (action) {
++ case MID_OTG_NOTIFY_CONNECT:
++ dev_dbg(lnw->dev, "Lnw OTG Notify Connect Event\n");
++ if (iotg->otg.default_a == 1)
++ iotg->hsm.b_conn = 1;
++ else
++ iotg->hsm.a_conn = 1;
++ flag = 1;
++ break;
++ case MID_OTG_NOTIFY_DISCONN:
++ dev_dbg(lnw->dev, "Lnw OTG Notify Disconnect Event\n");
++ if (iotg->otg.default_a == 1)
++ iotg->hsm.b_conn = 0;
++ else
++ iotg->hsm.a_conn = 0;
++ flag = 1;
++ break;
++ case MID_OTG_NOTIFY_HSUSPEND:
++ dev_dbg(lnw->dev, "Lnw OTG Notify Host Bus suspend Event\n");
++ if (iotg->otg.default_a == 1)
++ iotg->hsm.a_suspend_req = 1;
++ else
++ iotg->hsm.b_bus_req = 0;
++ flag = 1;
++ break;
++ case MID_OTG_NOTIFY_HRESUME:
++ dev_dbg(lnw->dev, "Lnw OTG Notify Host Bus resume Event\n");
++ if (iotg->otg.default_a == 1)
++ iotg->hsm.b_bus_resume = 1;
++ flag = 1;
++ break;
++ case MID_OTG_NOTIFY_CSUSPEND:
++ dev_dbg(lnw->dev, "Lnw OTG Notify Client Bus suspend Event\n");
++ if (iotg->otg.default_a == 1) {
++ if (iotg->hsm.b_bus_suspend_vld == 2) {
++ iotg->hsm.b_bus_suspend = 1;
++ iotg->hsm.b_bus_suspend_vld = 0;
++ flag = 1;
++ } else {
++ iotg->hsm.b_bus_suspend_vld++;
++ flag = 0;
++ }
++ } else {
++ if (iotg->hsm.a_bus_suspend == 0) {
++ iotg->hsm.a_bus_suspend = 1;
++ flag = 1;
++ }
++ }
++ break;
++ case MID_OTG_NOTIFY_CRESUME:
++ dev_dbg(lnw->dev, "Lnw OTG Notify Client Bus resume Event\n");
++ if (iotg->otg.default_a == 0)
++ iotg->hsm.a_bus_suspend = 0;
++ flag = 0;
++ break;
++ case MID_OTG_NOTIFY_HOSTADD:
++ dev_dbg(lnw->dev, "Lnw OTG Nofity Host Driver Add\n");
++ flag = 1;
++ break;
++ case MID_OTG_NOTIFY_HOSTREMOVE:
++ dev_dbg(lnw->dev, "Lnw OTG Nofity Host Driver remove\n");
++ flag = 1;
++ break;
++ case MID_OTG_NOTIFY_CLIENTADD:
++ dev_dbg(lnw->dev, "Lnw OTG Nofity Client Driver Add\n");
++ flag = 1;
++ break;
++ case MID_OTG_NOTIFY_CLIENTREMOVE:
++ dev_dbg(lnw->dev, "Lnw OTG Nofity Client Driver remove\n");
++ flag = 1;
++ break;
++ default:
++ dev_dbg(lnw->dev, "Lnw OTG Nofity unknown notify message\n");
++ return NOTIFY_DONE;
++ }
++
++ if (flag)
++ langwell_update_transceiver();
++
++ return NOTIFY_OK;
++}
++
++static void langwell_otg_work(struct work_struct *work)
++{
++ struct langwell_otg *lnw;
++ struct intel_mid_otg_xceiv *iotg;
++ int retval;
++ struct pci_dev *pdev;
++
++ lnw = container_of(work, struct langwell_otg, work);
++ iotg = &lnw->iotg;
++ pdev = to_pci_dev(lnw->dev);
++
++ dev_dbg(lnw->dev, "%s: old state = %s\n", __func__,
++ state_string(iotg->otg.state));
++
++ switch (iotg->otg.state) {
++ case OTG_STATE_UNDEFINED:
++ case OTG_STATE_B_IDLE:
++ if (!iotg->hsm.id) {
++ langwell_otg_del_timer(b_srp_init_tmr);
++ del_timer_sync(&lnw->hsm_timer);
++
++ iotg->otg.default_a = 1;
++ iotg->hsm.a_srp_det = 0;
++
++ langwell_otg_chrg_vbus(0);
++ set_host_mode();
++ langwell_otg_phy_low_power(1);
++
++ iotg->otg.state = OTG_STATE_A_IDLE;
++ langwell_update_transceiver();
++ } else if (iotg->hsm.b_sess_vld) {
++ langwell_otg_del_timer(b_srp_init_tmr);
++ del_timer_sync(&lnw->hsm_timer);
++ iotg->hsm.b_sess_end = 0;
++ iotg->hsm.a_bus_suspend = 0;
++ langwell_otg_chrg_vbus(0);
++
++ if (lnw->iotg.start_peripheral) {
++ lnw->iotg.start_peripheral(&lnw->iotg);
++ iotg->otg.state = OTG_STATE_B_PERIPHERAL;
++ } else
++ dev_dbg(lnw->dev, "client driver not loaded\n");
++
++ } else if (iotg->hsm.b_srp_init_tmout) {
++ iotg->hsm.b_srp_init_tmout = 0;
++ dev_warn(lnw->dev, "SRP init timeout\n");
++ } else if (iotg->hsm.b_srp_fail_tmout) {
++ iotg->hsm.b_srp_fail_tmout = 0;
++ iotg->hsm.b_bus_req = 0;
++
++ /* No silence failure */
++ langwell_otg_nsf_msg(6);
++ } else if (iotg->hsm.b_bus_req && iotg->hsm.b_sess_end) {
++ del_timer_sync(&lnw->hsm_timer);
++ /* workaround for b_se0_srp detection */
++ retval = langwell_otg_check_se0_srp(0);
++ if (retval) {
++ iotg->hsm.b_bus_req = 0;
++ dev_dbg(lnw->dev, "LS isn't SE0, try later\n");
++ } else {
++ /* clear the PHCD before start srp */
++ langwell_otg_phy_low_power(0);
++
++ /* Start SRP */
++ langwell_otg_add_timer(b_srp_init_tmr);
++ iotg->otg.start_srp(&iotg->otg);
++ langwell_otg_del_timer(b_srp_init_tmr);
++ langwell_otg_add_ktimer(TB_SRP_FAIL_TMR);
++
++ /* reset PHY low power mode here */
++ langwell_otg_phy_low_power_wait(1);
++ }
++ }
++ break;
++ case OTG_STATE_B_SRP_INIT:
++ if (!iotg->hsm.id) {
++ iotg->otg.default_a = 1;
++ iotg->hsm.a_srp_det = 0;
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ langwell_otg_chrg_vbus(0);
++ set_host_mode();
++ langwell_otg_phy_low_power(1);
++ iotg->otg.state = OTG_STATE_A_IDLE;
++ langwell_update_transceiver();
++ } else if (iotg->hsm.b_sess_vld) {
++ langwell_otg_chrg_vbus(0);
++ if (lnw->iotg.start_peripheral) {
++ lnw->iotg.start_peripheral(&lnw->iotg);
++ iotg->otg.state = OTG_STATE_B_PERIPHERAL;
++ } else
++ dev_dbg(lnw->dev, "client driver not loaded\n");
++ }
++ break;
++ case OTG_STATE_B_PERIPHERAL:
++ if (!iotg->hsm.id) {
++ iotg->otg.default_a = 1;
++ iotg->hsm.a_srp_det = 0;
++
++ langwell_otg_chrg_vbus(0);
++
++ if (lnw->iotg.stop_peripheral)
++ lnw->iotg.stop_peripheral(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "client driver has been removed.\n");
++
++ set_host_mode();
++ langwell_otg_phy_low_power(1);
++ iotg->otg.state = OTG_STATE_A_IDLE;
++ langwell_update_transceiver();
++ } else if (!iotg->hsm.b_sess_vld) {
++ iotg->hsm.b_hnp_enable = 0;
++
++ if (lnw->iotg.stop_peripheral)
++ lnw->iotg.stop_peripheral(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "client driver has been removed.\n");
++
++ iotg->otg.state = OTG_STATE_B_IDLE;
++ } else if (iotg->hsm.b_bus_req && iotg->otg.gadget &&
++ iotg->otg.gadget->b_hnp_enable &&
++ iotg->hsm.a_bus_suspend) {
++
++ if (lnw->iotg.stop_peripheral)
++ lnw->iotg.stop_peripheral(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "client driver has been removed.\n");
++
++ langwell_otg_HAAR(1);
++ iotg->hsm.a_conn = 0;
++
++ if (lnw->iotg.start_host) {
++ lnw->iotg.start_host(&lnw->iotg);
++ iotg->otg.state = OTG_STATE_B_WAIT_ACON;
++ } else
++ dev_dbg(lnw->dev,
++ "host driver not loaded.\n");
++
++ iotg->hsm.a_bus_resume = 0;
++ langwell_otg_add_ktimer(TB_ASE0_BRST_TMR);
++ }
++ break;
++
++ case OTG_STATE_B_WAIT_ACON:
++ if (!iotg->hsm.id) {
++ /* delete hsm timer for b_ase0_brst_tmr */
++ del_timer_sync(&lnw->hsm_timer);
++
++ iotg->otg.default_a = 1;
++ iotg->hsm.a_srp_det = 0;
++
++ langwell_otg_chrg_vbus(0);
++
++ langwell_otg_HAAR(0);
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ set_host_mode();
++ langwell_otg_phy_low_power(1);
++ iotg->otg.state = OTG_STATE_A_IDLE;
++ langwell_update_transceiver();
++ } else if (!iotg->hsm.b_sess_vld) {
++ /* delete hsm timer for b_ase0_brst_tmr */
++ del_timer_sync(&lnw->hsm_timer);
++
++ iotg->hsm.b_hnp_enable = 0;
++ iotg->hsm.b_bus_req = 0;
++
++ langwell_otg_chrg_vbus(0);
++ langwell_otg_HAAR(0);
++
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ set_client_mode();
++ langwell_otg_phy_low_power(1);
++ iotg->otg.state = OTG_STATE_B_IDLE;
++ } else if (iotg->hsm.a_conn) {
++ /* delete hsm timer for b_ase0_brst_tmr */
++ del_timer_sync(&lnw->hsm_timer);
++
++ langwell_otg_HAAR(0);
++ iotg->otg.state = OTG_STATE_B_HOST;
++ langwell_update_transceiver();
++ } else if (iotg->hsm.a_bus_resume ||
++ iotg->hsm.b_ase0_brst_tmout) {
++ /* delete hsm timer for b_ase0_brst_tmr */
++ del_timer_sync(&lnw->hsm_timer);
++
++ langwell_otg_HAAR(0);
++ langwell_otg_nsf_msg(7);
++
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ iotg->hsm.a_bus_suspend = 0;
++ iotg->hsm.b_bus_req = 0;
++
++ if (lnw->iotg.start_peripheral)
++ lnw->iotg.start_peripheral(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "client driver not loaded.\n");
++
++ iotg->otg.state = OTG_STATE_B_PERIPHERAL;
++ }
++ break;
++
++ case OTG_STATE_B_HOST:
++ if (!iotg->hsm.id) {
++ iotg->otg.default_a = 1;
++ iotg->hsm.a_srp_det = 0;
++
++ langwell_otg_chrg_vbus(0);
++
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ set_host_mode();
++ langwell_otg_phy_low_power(1);
++ iotg->otg.state = OTG_STATE_A_IDLE;
++ langwell_update_transceiver();
++ } else if (!iotg->hsm.b_sess_vld) {
++ iotg->hsm.b_hnp_enable = 0;
++ iotg->hsm.b_bus_req = 0;
++
++ langwell_otg_chrg_vbus(0);
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ set_client_mode();
++ langwell_otg_phy_low_power(1);
++ iotg->otg.state = OTG_STATE_B_IDLE;
++ } else if ((!iotg->hsm.b_bus_req) ||
++ (!iotg->hsm.a_conn)) {
++ iotg->hsm.b_bus_req = 0;
++ langwell_otg_loc_sof(0);
++
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ iotg->hsm.a_bus_suspend = 0;
++
++ if (lnw->iotg.start_peripheral)
++ lnw->iotg.start_peripheral(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "client driver not loaded.\n");
++
++ iotg->otg.state = OTG_STATE_B_PERIPHERAL;
++ }
++ break;
++
++ case OTG_STATE_A_IDLE:
++ iotg->otg.default_a = 1;
++ if (iotg->hsm.id) {
++ iotg->otg.default_a = 0;
++ iotg->hsm.b_bus_req = 0;
++ iotg->hsm.vbus_srp_up = 0;
++
++ langwell_otg_chrg_vbus(0);
++ set_client_mode();
++ langwell_otg_phy_low_power(1);
++ iotg->otg.state = OTG_STATE_B_IDLE;
++ langwell_update_transceiver();
++ } else if (!iotg->hsm.a_bus_drop &&
++ (iotg->hsm.a_srp_det || iotg->hsm.a_bus_req)) {
++ langwell_otg_phy_low_power(0);
++
++ /* Turn on VBus */
++ iotg->otg.set_vbus(&iotg->otg, true);
++
++ iotg->hsm.vbus_srp_up = 0;
++ iotg->hsm.a_wait_vrise_tmout = 0;
++ langwell_otg_add_timer(a_wait_vrise_tmr);
++ iotg->otg.state = OTG_STATE_A_WAIT_VRISE;
++ langwell_update_transceiver();
++ } else if (!iotg->hsm.a_bus_drop && iotg->hsm.a_sess_vld) {
++ iotg->hsm.vbus_srp_up = 1;
++ } else if (!iotg->hsm.a_sess_vld && iotg->hsm.vbus_srp_up) {
++ msleep(10);
++ langwell_otg_phy_low_power(0);
++
++ /* Turn on VBus */
++ iotg->otg.set_vbus(&iotg->otg, true);
++ iotg->hsm.a_srp_det = 1;
++ iotg->hsm.vbus_srp_up = 0;
++ iotg->hsm.a_wait_vrise_tmout = 0;
++ langwell_otg_add_timer(a_wait_vrise_tmr);
++ iotg->otg.state = OTG_STATE_A_WAIT_VRISE;
++ langwell_update_transceiver();
++ } else if (!iotg->hsm.a_sess_vld &&
++ !iotg->hsm.vbus_srp_up) {
++ langwell_otg_phy_low_power(1);
++ }
++ break;
++ case OTG_STATE_A_WAIT_VRISE:
++ if (iotg->hsm.id) {
++ langwell_otg_del_timer(a_wait_vrise_tmr);
++ iotg->hsm.b_bus_req = 0;
++ iotg->otg.default_a = 0;
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ set_client_mode();
++ langwell_otg_phy_low_power_wait(1);
++ iotg->otg.state = OTG_STATE_B_IDLE;
++ } else if (iotg->hsm.a_vbus_vld) {
++ langwell_otg_del_timer(a_wait_vrise_tmr);
++ iotg->hsm.b_conn = 0;
++ if (lnw->iotg.start_host)
++ lnw->iotg.start_host(&lnw->iotg);
++ else {
++ dev_dbg(lnw->dev, "host driver not loaded.\n");
++ break;
++ }
++
++ langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
++ iotg->otg.state = OTG_STATE_A_WAIT_BCON;
++ } else if (iotg->hsm.a_wait_vrise_tmout) {
++ iotg->hsm.b_conn = 0;
++ if (iotg->hsm.a_vbus_vld) {
++ if (lnw->iotg.start_host)
++ lnw->iotg.start_host(&lnw->iotg);
++ else {
++ dev_dbg(lnw->dev,
++ "host driver not loaded.\n");
++ break;
++ }
++ langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
++ iotg->otg.state = OTG_STATE_A_WAIT_BCON;
++ } else {
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ langwell_otg_phy_low_power_wait(1);
++ iotg->otg.state = OTG_STATE_A_VBUS_ERR;
++ }
++ }
++ break;
++ case OTG_STATE_A_WAIT_BCON:
++ if (iotg->hsm.id) {
++ /* delete hsm timer for a_wait_bcon_tmr */
++ del_timer_sync(&lnw->hsm_timer);
++
++ iotg->otg.default_a = 0;
++ iotg->hsm.b_bus_req = 0;
++
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ set_client_mode();
++ langwell_otg_phy_low_power_wait(1);
++ iotg->otg.state = OTG_STATE_B_IDLE;
++ langwell_update_transceiver();
++ } else if (!iotg->hsm.a_vbus_vld) {
++ /* delete hsm timer for a_wait_bcon_tmr */
++ del_timer_sync(&lnw->hsm_timer);
++
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ langwell_otg_phy_low_power_wait(1);
++ iotg->otg.state = OTG_STATE_A_VBUS_ERR;
++ } else if (iotg->hsm.a_bus_drop ||
++ (iotg->hsm.a_wait_bcon_tmout &&
++ !iotg->hsm.a_bus_req)) {
++ /* delete hsm timer for a_wait_bcon_tmr */
++ del_timer_sync(&lnw->hsm_timer);
++
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
++ } else if (iotg->hsm.b_conn) {
++ /* delete hsm timer for a_wait_bcon_tmr */
++ del_timer_sync(&lnw->hsm_timer);
++
++ iotg->hsm.a_suspend_req = 0;
++ iotg->otg.state = OTG_STATE_A_HOST;
++ if (iotg->hsm.a_srp_det && iotg->otg.host &&
++ !iotg->otg.host->b_hnp_enable) {
++ /* SRP capable peripheral-only device */
++ iotg->hsm.a_bus_req = 1;
++ iotg->hsm.a_srp_det = 0;
++ } else if (!iotg->hsm.a_bus_req && iotg->otg.host &&
++ iotg->otg.host->b_hnp_enable) {
++ /* It is not safe enough to do a fast
++ * transistion from A_WAIT_BCON to
++ * A_SUSPEND */
++ msleep(10000);
++ if (iotg->hsm.a_bus_req)
++ break;
++
++ if (request_irq(pdev->irq,
++ otg_dummy_irq, IRQF_SHARED,
++ driver_name, iotg->base) != 0) {
++ dev_dbg(lnw->dev,
++ "request interrupt %d fail\n",
++ pdev->irq);
++ }
++
++ langwell_otg_HABA(1);
++ iotg->hsm.b_bus_resume = 0;
++ iotg->hsm.a_aidl_bdis_tmout = 0;
++
++ langwell_otg_loc_sof(0);
++ /* clear PHCD to enable HW timer */
++ langwell_otg_phy_low_power(0);
++ langwell_otg_add_timer(a_aidl_bdis_tmr);
++ iotg->otg.state = OTG_STATE_A_SUSPEND;
++ } else if (!iotg->hsm.a_bus_req && iotg->otg.host &&
++ !iotg->otg.host->b_hnp_enable) {
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver removed.\n");
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
++ }
++ }
++ break;
++ case OTG_STATE_A_HOST:
++ if (iotg->hsm.id) {
++ iotg->otg.default_a = 0;
++ iotg->hsm.b_bus_req = 0;
++
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ set_client_mode();
++ langwell_otg_phy_low_power_wait(1);
++ iotg->otg.state = OTG_STATE_B_IDLE;
++ langwell_update_transceiver();
++ } else if (iotg->hsm.a_bus_drop ||
++ (iotg->otg.host &&
++ !iotg->otg.host->b_hnp_enable &&
++ !iotg->hsm.a_bus_req)) {
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
++ } else if (!iotg->hsm.a_vbus_vld) {
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ langwell_otg_phy_low_power_wait(1);
++ iotg->otg.state = OTG_STATE_A_VBUS_ERR;
++ } else if (iotg->otg.host &&
++ iotg->otg.host->b_hnp_enable &&
++ !iotg->hsm.a_bus_req) {
++ /* Set HABA to enable hardware assistance to signal
++ * A-connect after receiver B-disconnect. Hardware
++ * will then set client mode and enable URE, SLE and
++ * PCE after the assistance. otg_dummy_irq is used to
++ * clean these ints when client driver is not resumed.
++ */
++ if (request_irq(pdev->irq, otg_dummy_irq, IRQF_SHARED,
++ driver_name, iotg->base) != 0) {
++ dev_dbg(lnw->dev,
++ "request interrupt %d failed\n",
++ pdev->irq);
++ }
++
++ /* set HABA */
++ langwell_otg_HABA(1);
++ iotg->hsm.b_bus_resume = 0;
++ iotg->hsm.a_aidl_bdis_tmout = 0;
++ langwell_otg_loc_sof(0);
++ /* clear PHCD to enable HW timer */
++ langwell_otg_phy_low_power(0);
++ langwell_otg_add_timer(a_aidl_bdis_tmr);
++ iotg->otg.state = OTG_STATE_A_SUSPEND;
++ } else if (!iotg->hsm.b_conn || !iotg->hsm.a_bus_req) {
++ langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
++ iotg->otg.state = OTG_STATE_A_WAIT_BCON;
++ }
++ break;
++ case OTG_STATE_A_SUSPEND:
++ if (iotg->hsm.id) {
++ langwell_otg_del_timer(a_aidl_bdis_tmr);
++ langwell_otg_HABA(0);
++ free_irq(pdev->irq, iotg->base);
++ iotg->otg.default_a = 0;
++ iotg->hsm.b_bus_req = 0;
++
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ set_client_mode();
++ langwell_otg_phy_low_power(1);
++ iotg->otg.state = OTG_STATE_B_IDLE;
++ langwell_update_transceiver();
++ } else if (iotg->hsm.a_bus_req ||
++ iotg->hsm.b_bus_resume) {
++ langwell_otg_del_timer(a_aidl_bdis_tmr);
++ langwell_otg_HABA(0);
++ free_irq(pdev->irq, iotg->base);
++ iotg->hsm.a_suspend_req = 0;
++ langwell_otg_loc_sof(1);
++ iotg->otg.state = OTG_STATE_A_HOST;
++ } else if (iotg->hsm.a_aidl_bdis_tmout ||
++ iotg->hsm.a_bus_drop) {
++ langwell_otg_del_timer(a_aidl_bdis_tmr);
++ langwell_otg_HABA(0);
++ free_irq(pdev->irq, iotg->base);
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
++ } else if (!iotg->hsm.b_conn && iotg->otg.host &&
++ iotg->otg.host->b_hnp_enable) {
++ langwell_otg_del_timer(a_aidl_bdis_tmr);
++ langwell_otg_HABA(0);
++ free_irq(pdev->irq, iotg->base);
++
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ iotg->hsm.b_bus_suspend = 0;
++ iotg->hsm.b_bus_suspend_vld = 0;
++
++ /* msleep(200); */
++ if (lnw->iotg.start_peripheral)
++ lnw->iotg.start_peripheral(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "client driver not loaded.\n");
++
++ langwell_otg_add_ktimer(TB_BUS_SUSPEND_TMR);
++ iotg->otg.state = OTG_STATE_A_PERIPHERAL;
++ break;
++ } else if (!iotg->hsm.a_vbus_vld) {
++ langwell_otg_del_timer(a_aidl_bdis_tmr);
++ langwell_otg_HABA(0);
++ free_irq(pdev->irq, iotg->base);
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver has been removed.\n");
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ langwell_otg_phy_low_power_wait(1);
++ iotg->otg.state = OTG_STATE_A_VBUS_ERR;
++ }
++ break;
++ case OTG_STATE_A_PERIPHERAL:
++ if (iotg->hsm.id) {
++ /* delete hsm timer for b_bus_suspend_tmr */
++ del_timer_sync(&lnw->hsm_timer);
++ iotg->otg.default_a = 0;
++ iotg->hsm.b_bus_req = 0;
++ if (lnw->iotg.stop_peripheral)
++ lnw->iotg.stop_peripheral(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "client driver has been removed.\n");
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ set_client_mode();
++ langwell_otg_phy_low_power_wait(1);
++ iotg->otg.state = OTG_STATE_B_IDLE;
++ langwell_update_transceiver();
++ } else if (!iotg->hsm.a_vbus_vld) {
++ /* delete hsm timer for b_bus_suspend_tmr */
++ del_timer_sync(&lnw->hsm_timer);
++
++ if (lnw->iotg.stop_peripheral)
++ lnw->iotg.stop_peripheral(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "client driver has been removed.\n");
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ langwell_otg_phy_low_power_wait(1);
++ iotg->otg.state = OTG_STATE_A_VBUS_ERR;
++ } else if (iotg->hsm.a_bus_drop) {
++ /* delete hsm timer for b_bus_suspend_tmr */
++ del_timer_sync(&lnw->hsm_timer);
++
++ if (lnw->iotg.stop_peripheral)
++ lnw->iotg.stop_peripheral(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "client driver has been removed.\n");
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
++ } else if (iotg->hsm.b_bus_suspend) {
++ /* delete hsm timer for b_bus_suspend_tmr */
++ del_timer_sync(&lnw->hsm_timer);
++
++ if (lnw->iotg.stop_peripheral)
++ lnw->iotg.stop_peripheral(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "client driver has been removed.\n");
++
++ if (lnw->iotg.start_host)
++ lnw->iotg.start_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver not loaded.\n");
++ langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
++ iotg->otg.state = OTG_STATE_A_WAIT_BCON;
++ } else if (iotg->hsm.b_bus_suspend_tmout) {
++ u32 val;
++ val = readl(lnw->iotg.base + CI_PORTSC1);
++ if (!(val & PORTSC_SUSP))
++ break;
++
++ if (lnw->iotg.stop_peripheral)
++ lnw->iotg.stop_peripheral(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "client driver has been removed.\n");
++
++ if (lnw->iotg.start_host)
++ lnw->iotg.start_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev,
++ "host driver not loaded.\n");
++ langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
++ iotg->otg.state = OTG_STATE_A_WAIT_BCON;
++ }
++ break;
++ case OTG_STATE_A_VBUS_ERR:
++ if (iotg->hsm.id) {
++ iotg->otg.default_a = 0;
++ iotg->hsm.a_clr_err = 0;
++ iotg->hsm.a_srp_det = 0;
++ set_client_mode();
++ langwell_otg_phy_low_power(1);
++ iotg->otg.state = OTG_STATE_B_IDLE;
++ langwell_update_transceiver();
++ } else if (iotg->hsm.a_clr_err) {
++ iotg->hsm.a_clr_err = 0;
++ iotg->hsm.a_srp_det = 0;
++ reset_otg();
++ init_hsm();
++ if (iotg->otg.state == OTG_STATE_A_IDLE)
++ langwell_update_transceiver();
++ } else {
++ /* FW will clear PHCD bit when any VBus
++ * event detected. Reset PHCD to 1 again */
++ langwell_otg_phy_low_power(1);
++ }
++ break;
++ case OTG_STATE_A_WAIT_VFALL:
++ if (iotg->hsm.id) {
++ iotg->otg.default_a = 0;
++ set_client_mode();
++ langwell_otg_phy_low_power(1);
++ iotg->otg.state = OTG_STATE_B_IDLE;
++ langwell_update_transceiver();
++ } else if (iotg->hsm.a_bus_req) {
++
++ /* Turn on VBus */
++ iotg->otg.set_vbus(&iotg->otg, true);
++ iotg->hsm.a_wait_vrise_tmout = 0;
++ langwell_otg_add_timer(a_wait_vrise_tmr);
++ iotg->otg.state = OTG_STATE_A_WAIT_VRISE;
++ } else if (!iotg->hsm.a_sess_vld) {
++ iotg->hsm.a_srp_det = 0;
++ set_host_mode();
++ langwell_otg_phy_low_power(1);
++ iotg->otg.state = OTG_STATE_A_IDLE;
++ }
++ break;
++ default:
++ ;
++ }
++
++ dev_dbg(lnw->dev, "%s: new state = %s\n", __func__,
++ state_string(iotg->otg.state));
++}
++
++static ssize_t
++show_registers(struct device *_dev, struct device_attribute *attr, char *buf)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ char *next;
++ unsigned size, t;
++
++ next = buf;
++ size = PAGE_SIZE;
++
++ t = scnprintf(next, size,
++ "\n"
++ "USBCMD = 0x%08x\n"
++ "USBSTS = 0x%08x\n"
++ "USBINTR = 0x%08x\n"
++ "ASYNCLISTADDR = 0x%08x\n"
++ "PORTSC1 = 0x%08x\n"
++ "HOSTPC1 = 0x%08x\n"
++ "OTGSC = 0x%08x\n"
++ "USBMODE = 0x%08x\n",
++ readl(lnw->iotg.base + 0x30),
++ readl(lnw->iotg.base + 0x34),
++ readl(lnw->iotg.base + 0x38),
++ readl(lnw->iotg.base + 0x48),
++ readl(lnw->iotg.base + 0x74),
++ readl(lnw->iotg.base + 0xb4),
++ readl(lnw->iotg.base + 0xf4),
++ readl(lnw->iotg.base + 0xf8)
++ );
++ size -= t;
++ next += t;
++
++ return PAGE_SIZE - size;
++}
++static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
++
++static ssize_t
++show_hsm(struct device *_dev, struct device_attribute *attr, char *buf)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
++ char *next;
++ unsigned size, t;
++
++ next = buf;
++ size = PAGE_SIZE;
++
++ if (iotg->otg.host)
++ iotg->hsm.a_set_b_hnp_en = iotg->otg.host->b_hnp_enable;
++
++ if (iotg->otg.gadget)
++ iotg->hsm.b_hnp_enable = iotg->otg.gadget->b_hnp_enable;
++
++ t = scnprintf(next, size,
++ "\n"
++ "current state = %s\n"
++ "a_bus_resume = \t%d\n"
++ "a_bus_suspend = \t%d\n"
++ "a_conn = \t%d\n"
++ "a_sess_vld = \t%d\n"
++ "a_srp_det = \t%d\n"
++ "a_vbus_vld = \t%d\n"
++ "b_bus_resume = \t%d\n"
++ "b_bus_suspend = \t%d\n"
++ "b_conn = \t%d\n"
++ "b_se0_srp = \t%d\n"
++ "b_sess_end = \t%d\n"
++ "b_sess_vld = \t%d\n"
++ "id = \t%d\n"
++ "a_set_b_hnp_en = \t%d\n"
++ "b_srp_done = \t%d\n"
++ "b_hnp_enable = \t%d\n"
++ "a_wait_vrise_tmout = \t%d\n"
++ "a_wait_bcon_tmout = \t%d\n"
++ "a_aidl_bdis_tmout = \t%d\n"
++ "b_ase0_brst_tmout = \t%d\n"
++ "a_bus_drop = \t%d\n"
++ "a_bus_req = \t%d\n"
++ "a_clr_err = \t%d\n"
++ "a_suspend_req = \t%d\n"
++ "b_bus_req = \t%d\n"
++ "b_bus_suspend_tmout = \t%d\n"
++ "b_bus_suspend_vld = \t%d\n",
++ state_string(iotg->otg.state),
++ iotg->hsm.a_bus_resume,
++ iotg->hsm.a_bus_suspend,
++ iotg->hsm.a_conn,
++ iotg->hsm.a_sess_vld,
++ iotg->hsm.a_srp_det,
++ iotg->hsm.a_vbus_vld,
++ iotg->hsm.b_bus_resume,
++ iotg->hsm.b_bus_suspend,
++ iotg->hsm.b_conn,
++ iotg->hsm.b_se0_srp,
++ iotg->hsm.b_sess_end,
++ iotg->hsm.b_sess_vld,
++ iotg->hsm.id,
++ iotg->hsm.a_set_b_hnp_en,
++ iotg->hsm.b_srp_done,
++ iotg->hsm.b_hnp_enable,
++ iotg->hsm.a_wait_vrise_tmout,
++ iotg->hsm.a_wait_bcon_tmout,
++ iotg->hsm.a_aidl_bdis_tmout,
++ iotg->hsm.b_ase0_brst_tmout,
++ iotg->hsm.a_bus_drop,
++ iotg->hsm.a_bus_req,
++ iotg->hsm.a_clr_err,
++ iotg->hsm.a_suspend_req,
++ iotg->hsm.b_bus_req,
++ iotg->hsm.b_bus_suspend_tmout,
++ iotg->hsm.b_bus_suspend_vld
++ );
++ size -= t;
++ next += t;
++
++ return PAGE_SIZE - size;
++}
++static DEVICE_ATTR(hsm, S_IRUGO, show_hsm, NULL);
++
++static ssize_t
++get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ char *next;
++ unsigned size, t;
++
++ next = buf;
++ size = PAGE_SIZE;
++
++ t = scnprintf(next, size, "%d", lnw->iotg.hsm.a_bus_req);
++ size -= t;
++ next += t;
++
++ return PAGE_SIZE - size;
++}
++
++static ssize_t
++set_a_bus_req(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
++
++ if (!iotg->otg.default_a)
++ return -1;
++ if (count > 2)
++ return -1;
++
++ if (buf[0] == '0') {
++ iotg->hsm.a_bus_req = 0;
++ dev_dbg(lnw->dev, "User request: a_bus_req = 0\n");
++ } else if (buf[0] == '1') {
++ /* If a_bus_drop is TRUE, a_bus_req can't be set */
++ if (iotg->hsm.a_bus_drop)
++ return -1;
++ iotg->hsm.a_bus_req = 1;
++ dev_dbg(lnw->dev, "User request: a_bus_req = 1\n");
++ }
++ if (spin_trylock(&lnw->wq_lock)) {
++ langwell_update_transceiver();
++ spin_unlock(&lnw->wq_lock);
++ }
++ return count;
++}
++static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUGO, get_a_bus_req, set_a_bus_req);
++
++static ssize_t
++get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ char *next;
++ unsigned size, t;
++
++ next = buf;
++ size = PAGE_SIZE;
++
++ t = scnprintf(next, size, "%d", lnw->iotg.hsm.a_bus_drop);
++ size -= t;
++ next += t;
++
++ return PAGE_SIZE - size;
++}
++
++static ssize_t
++set_a_bus_drop(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
++
++ if (!iotg->otg.default_a)
++ return -1;
++ if (count > 2)
++ return -1;
++
++ if (buf[0] == '0') {
++ iotg->hsm.a_bus_drop = 0;
++ dev_dbg(lnw->dev, "User request: a_bus_drop = 0\n");
++ } else if (buf[0] == '1') {
++ iotg->hsm.a_bus_drop = 1;
++ iotg->hsm.a_bus_req = 0;
++ dev_dbg(lnw->dev, "User request: a_bus_drop = 1\n");
++ dev_dbg(lnw->dev, "User request: and a_bus_req = 0\n");
++ }
++ if (spin_trylock(&lnw->wq_lock)) {
++ langwell_update_transceiver();
++ spin_unlock(&lnw->wq_lock);
++ }
++ return count;
++}
++static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUGO,
++ get_a_bus_drop, set_a_bus_drop);
++
++static ssize_t
++get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ char *next;
++ unsigned size, t;
++
++ next = buf;
++ size = PAGE_SIZE;
++
++ t = scnprintf(next, size, "%d", lnw->iotg.hsm.b_bus_req);
++ size -= t;
++ next += t;
++
++ return PAGE_SIZE - size;
++}
++
++static ssize_t
++set_b_bus_req(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
++
++ if (iotg->otg.default_a)
++ return -1;
++
++ if (count > 2)
++ return -1;
++
++ if (buf[0] == '0') {
++ iotg->hsm.b_bus_req = 0;
++ dev_dbg(lnw->dev, "User request: b_bus_req = 0\n");
++ } else if (buf[0] == '1') {
++ iotg->hsm.b_bus_req = 1;
++ dev_dbg(lnw->dev, "User request: b_bus_req = 1\n");
++ }
++ if (spin_trylock(&lnw->wq_lock)) {
++ langwell_update_transceiver();
++ spin_unlock(&lnw->wq_lock);
++ }
++ return count;
++}
++static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUGO, get_b_bus_req, set_b_bus_req);
++
++static ssize_t
++set_a_clr_err(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
++
++ if (!iotg->otg.default_a)
++ return -1;
++ if (count > 2)
++ return -1;
++
++ if (buf[0] == '1') {
++ iotg->hsm.a_clr_err = 1;
++ dev_dbg(lnw->dev, "User request: a_clr_err = 1\n");
++ }
++ if (spin_trylock(&lnw->wq_lock)) {
++ langwell_update_transceiver();
++ spin_unlock(&lnw->wq_lock);
++ }
++ return count;
++}
++static DEVICE_ATTR(a_clr_err, S_IWUGO, NULL, set_a_clr_err);
++
++static struct attribute *inputs_attrs[] = {
++ &dev_attr_a_bus_req.attr,
++ &dev_attr_a_bus_drop.attr,
++ &dev_attr_b_bus_req.attr,
++ &dev_attr_a_clr_err.attr,
++ NULL,
++};
++
++static struct attribute_group debug_dev_attr_group = {
++ .name = "inputs",
++ .attrs = inputs_attrs,
++};
++
++static int langwell_otg_probe(struct pci_dev *pdev,
++ const struct pci_device_id *id)
++{
++ unsigned long resource, len;
++ void __iomem *base = NULL;
++ int retval;
++ u32 val32;
++ struct langwell_otg *lnw;
++ char qname[] = "langwell_otg_queue";
++
++ retval = 0;
++ dev_dbg(&pdev->dev, "\notg controller is detected.\n");
++ if (pci_enable_device(pdev) < 0) {
++ retval = -ENODEV;
++ goto done;
++ }
++
++ lnw = kzalloc(sizeof *lnw, GFP_KERNEL);
++ if (lnw == NULL) {
++ retval = -ENOMEM;
++ goto done;
++ }
++ the_transceiver = lnw;
++
++ /* control register: BAR 0 */
++ resource = pci_resource_start(pdev, 0);
++ len = pci_resource_len(pdev, 0);
++ if (!request_mem_region(resource, len, driver_name)) {
++ retval = -EBUSY;
++ goto err;
++ }
++ lnw->region = 1;
++
++ base = ioremap_nocache(resource, len);
++ if (base == NULL) {
++ retval = -EFAULT;
++ goto err;
++ }
++ lnw->iotg.base = base;
++
++ if (!request_mem_region(USBCFG_ADDR, USBCFG_LEN, driver_name)) {
++ retval = -EBUSY;
++ goto err;
++ }
++ lnw->cfg_region = 1;
++
++ /* For the SCCB.USBCFG register */
++ base = ioremap_nocache(USBCFG_ADDR, USBCFG_LEN);
++ if (base == NULL) {
++ retval = -EFAULT;
++ goto err;
++ }
++ lnw->usbcfg = base;
++
++ if (!pdev->irq) {
++ dev_dbg(&pdev->dev, "No IRQ.\n");
++ retval = -ENODEV;
++ goto err;
++ }
++
++ lnw->qwork = create_singlethread_workqueue(qname);
++ if (!lnw->qwork) {
++ dev_dbg(&pdev->dev, "cannot create workqueue %s\n", qname);
++ retval = -ENOMEM;
++ goto err;
++ }
++ INIT_WORK(&lnw->work, langwell_otg_work);
++
++ /* OTG common part */
++ lnw->dev = &pdev->dev;
++ lnw->iotg.otg.dev = lnw->dev;
++ lnw->iotg.otg.label = driver_name;
++ lnw->iotg.otg.set_host = langwell_otg_set_host;
++ lnw->iotg.otg.set_peripheral = langwell_otg_set_peripheral;
++ lnw->iotg.otg.set_power = langwell_otg_set_power;
++ lnw->iotg.otg.set_vbus = langwell_otg_set_vbus;
++ lnw->iotg.otg.start_srp = langwell_otg_start_srp;
++ lnw->iotg.otg.state = OTG_STATE_UNDEFINED;
++
++ if (otg_set_transceiver(&lnw->iotg.otg)) {
++ dev_dbg(lnw->dev, "can't set transceiver\n");
++ retval = -EBUSY;
++ goto err;
++ }
++
++ reset_otg();
++ init_hsm();
++
++ spin_lock_init(&lnw->lock);
++ spin_lock_init(&lnw->wq_lock);
++ INIT_LIST_HEAD(&active_timers);
++ retval = langwell_otg_init_timers(&lnw->iotg.hsm);
++ if (retval) {
++ dev_dbg(&pdev->dev, "Failed to init timers\n");
++ goto err;
++ }
++
++ init_timer(&lnw->hsm_timer);
++ ATOMIC_INIT_NOTIFIER_HEAD(&lnw->iotg.iotg_notifier);
++
++ lnw->iotg_notifier.notifier_call = langwell_otg_iotg_notify;
++
++ retval = intel_mid_otg_register_notifier(&lnw->iotg,
++ &lnw->iotg_notifier);
++ if (retval) {
++ dev_dbg(lnw->dev, "Failed to register notifier\n");
++ goto err;
++ }
++
++ if (request_irq(pdev->irq, otg_irq, IRQF_SHARED,
++ driver_name, lnw) != 0) {
++ dev_dbg(lnw->dev, "request interrupt %d failed\n", pdev->irq);
++ retval = -EBUSY;
++ goto err;
++ }
++
++ /* enable OTGSC int */
++ val32 = OTGSC_DPIE | OTGSC_BSEIE | OTGSC_BSVIE |
++ OTGSC_ASVIE | OTGSC_AVVIE | OTGSC_IDIE | OTGSC_IDPU;
++ writel(val32, lnw->iotg.base + CI_OTGSC);
++
++ retval = device_create_file(&pdev->dev, &dev_attr_registers);
++ if (retval < 0) {
++ dev_dbg(lnw->dev,
++ "Can't register sysfs attribute: %d\n", retval);
++ goto err;
++ }
++
++ retval = device_create_file(&pdev->dev, &dev_attr_hsm);
++ if (retval < 0) {
++ dev_dbg(lnw->dev, "Can't hsm sysfs attribute: %d\n", retval);
++ goto err;
++ }
++
++ retval = sysfs_create_group(&pdev->dev.kobj, &debug_dev_attr_group);
++ if (retval < 0) {
++ dev_dbg(lnw->dev,
++ "Can't register sysfs attr group: %d\n", retval);
++ goto err;
++ }
++
++ if (lnw->iotg.otg.state == OTG_STATE_A_IDLE)
++ langwell_update_transceiver();
++
++ return 0;
++
++err:
++ if (the_transceiver)
++ langwell_otg_remove(pdev);
++done:
++ return retval;
++}
++
++static void langwell_otg_remove(struct pci_dev *pdev)
++{
++ struct langwell_otg *lnw = the_transceiver;
++
++ if (lnw->qwork) {
++ flush_workqueue(lnw->qwork);
++ destroy_workqueue(lnw->qwork);
++ }
++ intel_mid_otg_unregister_notifier(&lnw->iotg, &lnw->iotg_notifier);
++ langwell_otg_free_timers();
++
++ /* disable OTGSC interrupt as OTGSC doesn't change in reset */
++ writel(0, lnw->iotg.base + CI_OTGSC);
++
++ if (pdev->irq)
++ free_irq(pdev->irq, lnw);
++ if (lnw->usbcfg)
++ iounmap(lnw->usbcfg);
++ if (lnw->cfg_region)
++ release_mem_region(USBCFG_ADDR, USBCFG_LEN);
++ if (lnw->iotg.base)
++ iounmap(lnw->iotg.base);
++ if (lnw->region)
++ release_mem_region(pci_resource_start(pdev, 0),
++ pci_resource_len(pdev, 0));
++
++ otg_set_transceiver(NULL);
++ pci_disable_device(pdev);
++ sysfs_remove_group(&pdev->dev.kobj, &debug_dev_attr_group);
++ device_remove_file(&pdev->dev, &dev_attr_hsm);
++ device_remove_file(&pdev->dev, &dev_attr_registers);
++ kfree(lnw);
++ lnw = NULL;
++}
++
++static void transceiver_suspend(struct pci_dev *pdev)
++{
++ pci_save_state(pdev);
++ pci_set_power_state(pdev, PCI_D3hot);
++ langwell_otg_phy_low_power(1);
++}
++
++static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ struct intel_mid_otg_xceiv *iotg = &lnw->iotg;
++ int ret = 0;
++
++ /* Disbale OTG interrupts */
++ langwell_otg_intr(0);
++
++ if (pdev->irq)
++ free_irq(pdev->irq, lnw);
++
++ /* Prevent more otg_work */
++ flush_workqueue(lnw->qwork);
++ destroy_workqueue(lnw->qwork);
++ lnw->qwork = NULL;
++
++ /* start actions */
++ switch (iotg->otg.state) {
++ case OTG_STATE_A_WAIT_VFALL:
++ iotg->otg.state = OTG_STATE_A_IDLE;
++ case OTG_STATE_A_IDLE:
++ case OTG_STATE_B_IDLE:
++ case OTG_STATE_A_VBUS_ERR:
++ transceiver_suspend(pdev);
++ break;
++ case OTG_STATE_A_WAIT_VRISE:
++ langwell_otg_del_timer(a_wait_vrise_tmr);
++ iotg->hsm.a_srp_det = 0;
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ iotg->otg.state = OTG_STATE_A_IDLE;
++ transceiver_suspend(pdev);
++ break;
++ case OTG_STATE_A_WAIT_BCON:
++ del_timer_sync(&lnw->hsm_timer);
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(&pdev->dev, "host driver has been removed.\n");
++
++ iotg->hsm.a_srp_det = 0;
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ iotg->otg.state = OTG_STATE_A_IDLE;
++ transceiver_suspend(pdev);
++ break;
++ case OTG_STATE_A_HOST:
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(&pdev->dev, "host driver has been removed.\n");
++
++ iotg->hsm.a_srp_det = 0;
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++
++ iotg->otg.state = OTG_STATE_A_IDLE;
++ transceiver_suspend(pdev);
++ break;
++ case OTG_STATE_A_SUSPEND:
++ langwell_otg_del_timer(a_aidl_bdis_tmr);
++ langwell_otg_HABA(0);
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(lnw->dev, "host driver has been removed.\n");
++ iotg->hsm.a_srp_det = 0;
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ iotg->otg.state = OTG_STATE_A_IDLE;
++ transceiver_suspend(pdev);
++ break;
++ case OTG_STATE_A_PERIPHERAL:
++ del_timer_sync(&lnw->hsm_timer);
++
++ if (lnw->iotg.stop_peripheral)
++ lnw->iotg.stop_peripheral(&lnw->iotg);
++ else
++ dev_dbg(&pdev->dev,
++ "client driver has been removed.\n");
++ iotg->hsm.a_srp_det = 0;
++
++ /* Turn off VBus */
++ iotg->otg.set_vbus(&iotg->otg, false);
++ iotg->otg.state = OTG_STATE_A_IDLE;
++ transceiver_suspend(pdev);
++ break;
++ case OTG_STATE_B_HOST:
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(&pdev->dev, "host driver has been removed.\n");
++ iotg->hsm.b_bus_req = 0;
++ iotg->otg.state = OTG_STATE_B_IDLE;
++ transceiver_suspend(pdev);
++ break;
++ case OTG_STATE_B_PERIPHERAL:
++ if (lnw->iotg.stop_peripheral)
++ lnw->iotg.stop_peripheral(&lnw->iotg);
++ else
++ dev_dbg(&pdev->dev,
++ "client driver has been removed.\n");
++ iotg->otg.state = OTG_STATE_B_IDLE;
++ transceiver_suspend(pdev);
++ break;
++ case OTG_STATE_B_WAIT_ACON:
++ /* delete hsm timer for b_ase0_brst_tmr */
++ del_timer_sync(&lnw->hsm_timer);
++
++ langwell_otg_HAAR(0);
++
++ if (lnw->iotg.stop_host)
++ lnw->iotg.stop_host(&lnw->iotg);
++ else
++ dev_dbg(&pdev->dev, "host driver has been removed.\n");
++ iotg->hsm.b_bus_req = 0;
++ iotg->otg.state = OTG_STATE_B_IDLE;
++ transceiver_suspend(pdev);
++ break;
++ default:
++ dev_dbg(lnw->dev, "error state before suspend\n");
++ break;
++ }
++
++ return ret;
++}
++
++static void transceiver_resume(struct pci_dev *pdev)
++{
++ pci_restore_state(pdev);
++ pci_set_power_state(pdev, PCI_D0);
++}
++
++static int langwell_otg_resume(struct pci_dev *pdev)
++{
++ struct langwell_otg *lnw = the_transceiver;
++ int ret = 0;
++
++ transceiver_resume(pdev);
++
++ lnw->qwork = create_singlethread_workqueue("langwell_otg_queue");
++ if (!lnw->qwork) {
++ dev_dbg(&pdev->dev, "cannot create langwell otg workqueuen");
++ ret = -ENOMEM;
++ goto error;
++ }
++
++ if (request_irq(pdev->irq, otg_irq, IRQF_SHARED,
++ driver_name, lnw) != 0) {
++ dev_dbg(&pdev->dev, "request interrupt %d failed\n", pdev->irq);
++ ret = -EBUSY;
++ goto error;
++ }
++
++ /* enable OTG interrupts */
++ langwell_otg_intr(1);
++
++ update_hsm();
++
++ langwell_update_transceiver();
++
++ return ret;
++error:
++ langwell_otg_intr(0);
++ transceiver_suspend(pdev);
++ return ret;
++}
++
++static int __init langwell_otg_init(void)
++{
++ return pci_register_driver(&otg_pci_driver);
++}
++module_init(langwell_otg_init);
++
++static void __exit langwell_otg_cleanup(void)
++{
++ pci_unregister_driver(&otg_pci_driver);
++}
++module_exit(langwell_otg_cleanup);
+--- /dev/null
++++ b/include/linux/usb/langwell_otg.h
+@@ -0,0 +1,139 @@
++/*
++ * Intel Langwell USB OTG transceiver driver
++ * Copyright (C) 2008, Intel Corporation.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program; if not, write to the Free Software Foundation, Inc.,
++ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ */
++
++#ifndef __LANGWELL_OTG_H
++#define __LANGWELL_OTG_H
++
++#include <linux/usb/intel_mid_otg.h>
++
++#define CI_USBCMD 0x30
++# define USBCMD_RST BIT(1)
++# define USBCMD_RS BIT(0)
++#define CI_USBSTS 0x34
++# define USBSTS_SLI BIT(8)
++# define USBSTS_URI BIT(6)
++# define USBSTS_PCI BIT(2)
++#define CI_PORTSC1 0x74
++# define PORTSC_PP BIT(12)
++# define PORTSC_LS (BIT(11) | BIT(10))
++# define PORTSC_SUSP BIT(7)
++# define PORTSC_CCS BIT(0)
++#define CI_HOSTPC1 0xb4
++# define HOSTPC1_PHCD BIT(22)
++#define CI_OTGSC 0xf4
++# define OTGSC_DPIE BIT(30)
++# define OTGSC_1MSE BIT(29)
++# define OTGSC_BSEIE BIT(28)
++# define OTGSC_BSVIE BIT(27)
++# define OTGSC_ASVIE BIT(26)
++# define OTGSC_AVVIE BIT(25)
++# define OTGSC_IDIE BIT(24)
++# define OTGSC_DPIS BIT(22)
++# define OTGSC_1MSS BIT(21)
++# define OTGSC_BSEIS BIT(20)
++# define OTGSC_BSVIS BIT(19)
++# define OTGSC_ASVIS BIT(18)
++# define OTGSC_AVVIS BIT(17)
++# define OTGSC_IDIS BIT(16)
++# define OTGSC_DPS BIT(14)
++# define OTGSC_1MST BIT(13)
++# define OTGSC_BSE BIT(12)
++# define OTGSC_BSV BIT(11)
++# define OTGSC_ASV BIT(10)
++# define OTGSC_AVV BIT(9)
++# define OTGSC_ID BIT(8)
++# define OTGSC_HABA BIT(7)
++# define OTGSC_HADP BIT(6)
++# define OTGSC_IDPU BIT(5)
++# define OTGSC_DP BIT(4)
++# define OTGSC_OT BIT(3)
++# define OTGSC_HAAR BIT(2)
++# define OTGSC_VC BIT(1)
++# define OTGSC_VD BIT(0)
++# define OTGSC_INTEN_MASK (0x7f << 24)
++# define OTGSC_INT_MASK (0x5f << 24)
++# define OTGSC_INTSTS_MASK (0x7f << 16)
++#define CI_USBMODE 0xf8
++# define USBMODE_CM (BIT(1) | BIT(0))
++# define USBMODE_IDLE 0
++# define USBMODE_DEVICE 0x2
++# define USBMODE_HOST 0x3
++#define USBCFG_ADDR 0xff10801c
++#define USBCFG_LEN 4
++# define USBCFG_VBUSVAL BIT(14)
++# define USBCFG_AVALID BIT(13)
++# define USBCFG_BVALID BIT(12)
++# define USBCFG_SESEND BIT(11)
++
++#define INTR_DUMMY_MASK (USBSTS_SLI | USBSTS_URI | USBSTS_PCI)
++
++enum langwell_otg_timer_type {
++ TA_WAIT_VRISE_TMR,
++ TA_WAIT_BCON_TMR,
++ TA_AIDL_BDIS_TMR,
++ TB_ASE0_BRST_TMR,
++ TB_SE0_SRP_TMR,
++ TB_SRP_INIT_TMR,
++ TB_SRP_FAIL_TMR,
++ TB_BUS_SUSPEND_TMR
++};
++
++#define TA_WAIT_VRISE 100
++#define TA_WAIT_BCON 30000
++#define TA_AIDL_BDIS 15000
++#define TB_ASE0_BRST 5000
++#define TB_SE0_SRP 2
++#define TB_SRP_INIT 100
++#define TB_SRP_FAIL 5500
++#define TB_BUS_SUSPEND 500
++
++struct langwell_otg_timer {
++ unsigned long expires; /* Number of count increase to timeout */
++ unsigned long count; /* Tick counter */
++ void (*function)(unsigned long); /* Timeout function */
++ unsigned long data; /* Data passed to function */
++ struct list_head list;
++};
++
++struct langwell_otg {
++ struct intel_mid_otg_xceiv iotg;
++ struct device *dev;
++
++ void __iomem *usbcfg; /* SCCBUSB config Reg */
++
++ unsigned region;
++ unsigned cfg_region;
++
++ struct work_struct work;
++ struct workqueue_struct *qwork;
++ struct timer_list hsm_timer;
++
++ spinlock_t lock;
++ spinlock_t wq_lock;
++
++ struct notifier_block iotg_notifier;
++};
++
++static inline
++struct langwell_otg *mid_xceiv_to_lnw(struct intel_mid_otg_xceiv *iotg)
++{
++ return container_of(iotg, struct langwell_otg, iotg);
++}
++
++#endif /* __LANGWELL_OTG_H__ */
diff --git a/usb/usb-langwell-usb-client-driver-code-cleanup.patch b/usb/usb-langwell-usb-client-driver-code-cleanup.patch
new file mode 100644
index 00000000000000..6c62a054b2db70
--- /dev/null
+++ b/usb/usb-langwell-usb-client-driver-code-cleanup.patch
@@ -0,0 +1,2133 @@
+From linux-usb-owner@vger.kernel.org Wed Sep 1 11:41:05 2010
+From: JiebingLi <jiebing.li@intel.com>
+Subject: USB: langwell: USB Client driver code cleanup
+To: linux-usb@vger.kernel.org
+Date: Thu, 05 Aug 2010 14:17:54 +0100
+Message-ID: <20100805131753.12473.56494.stgit@localhost.localdomain>
+
+From: JiebingLi <jiebing.li@intel.com>
+
+Code cleanup by using standard debugging API's and USB inline functions
+
+Signed-off-by: JiebingLi <jiebing.li@intel.com>
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/langwell_udc.c | 738 +++++++++++++++++++-------------------
+ 1 file changed, 375 insertions(+), 363 deletions(-)
+
+--- a/drivers/usb/gadget/langwell_udc.c
++++ b/drivers/usb/gadget/langwell_udc.c
+@@ -19,7 +19,7 @@
+
+
+ /* #undef DEBUG */
+-/* #undef VERBOSE */
++/* #undef VERBOSE_DEBUG */
+
+ #if defined(CONFIG_USB_LANGWELL_OTG)
+ #define OTG_TRANSCEIVER
+@@ -77,141 +77,110 @@ langwell_ep0_desc = {
+ /*-------------------------------------------------------------------------*/
+ /* debugging */
+
+-#ifdef DEBUG
+-#define DBG(dev, fmt, args...) \
+- pr_debug("%s %s: " fmt , driver_name, \
+- pci_name(dev->pdev), ## args)
+-#else
+-#define DBG(dev, fmt, args...) \
+- do { } while (0)
+-#endif /* DEBUG */
+-
+-
+-#ifdef VERBOSE
+-#define VDBG DBG
+-#else
+-#define VDBG(dev, fmt, args...) \
+- do { } while (0)
+-#endif /* VERBOSE */
+-
+-
+-#define ERROR(dev, fmt, args...) \
+- pr_err("%s %s: " fmt , driver_name, \
+- pci_name(dev->pdev), ## args)
+-
+-#define WARNING(dev, fmt, args...) \
+- pr_warning("%s %s: " fmt , driver_name, \
+- pci_name(dev->pdev), ## args)
+-
+-#define INFO(dev, fmt, args...) \
+- pr_info("%s %s: " fmt , driver_name, \
+- pci_name(dev->pdev), ## args)
+-
+-
+-#ifdef VERBOSE
++#ifdef VERBOSE_DEBUG
+ static inline void print_all_registers(struct langwell_udc *dev)
+ {
+ int i;
+
+ /* Capability Registers */
+- printk(KERN_DEBUG "Capability Registers (offset: "
+- "0x%04x, length: 0x%08x)\n",
+- CAP_REG_OFFSET,
+- (u32)sizeof(struct langwell_cap_regs));
+- printk(KERN_DEBUG "caplength=0x%02x\n",
++ dev_dbg(&dev->pdev->dev,
++ "Capability Registers (offset: 0x%04x, length: 0x%08x)\n",
++ CAP_REG_OFFSET, (u32)sizeof(struct langwell_cap_regs));
++ dev_dbg(&dev->pdev->dev, "caplength=0x%02x\n",
+ readb(&dev->cap_regs->caplength));
+- printk(KERN_DEBUG "hciversion=0x%04x\n",
++ dev_dbg(&dev->pdev->dev, "hciversion=0x%04x\n",
+ readw(&dev->cap_regs->hciversion));
+- printk(KERN_DEBUG "hcsparams=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "hcsparams=0x%08x\n",
+ readl(&dev->cap_regs->hcsparams));
+- printk(KERN_DEBUG "hccparams=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "hccparams=0x%08x\n",
+ readl(&dev->cap_regs->hccparams));
+- printk(KERN_DEBUG "dciversion=0x%04x\n",
++ dev_dbg(&dev->pdev->dev, "dciversion=0x%04x\n",
+ readw(&dev->cap_regs->dciversion));
+- printk(KERN_DEBUG "dccparams=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "dccparams=0x%08x\n",
+ readl(&dev->cap_regs->dccparams));
+
+ /* Operational Registers */
+- printk(KERN_DEBUG "Operational Registers (offset: "
+- "0x%04x, length: 0x%08x)\n",
+- OP_REG_OFFSET,
+- (u32)sizeof(struct langwell_op_regs));
+- printk(KERN_DEBUG "extsts=0x%08x\n",
++ dev_dbg(&dev->pdev->dev,
++ "Operational Registers (offset: 0x%04x, length: 0x%08x)\n",
++ OP_REG_OFFSET, (u32)sizeof(struct langwell_op_regs));
++ dev_dbg(&dev->pdev->dev, "extsts=0x%08x\n",
+ readl(&dev->op_regs->extsts));
+- printk(KERN_DEBUG "extintr=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "extintr=0x%08x\n",
+ readl(&dev->op_regs->extintr));
+- printk(KERN_DEBUG "usbcmd=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "usbcmd=0x%08x\n",
+ readl(&dev->op_regs->usbcmd));
+- printk(KERN_DEBUG "usbsts=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "usbsts=0x%08x\n",
+ readl(&dev->op_regs->usbsts));
+- printk(KERN_DEBUG "usbintr=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "usbintr=0x%08x\n",
+ readl(&dev->op_regs->usbintr));
+- printk(KERN_DEBUG "frindex=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "frindex=0x%08x\n",
+ readl(&dev->op_regs->frindex));
+- printk(KERN_DEBUG "ctrldssegment=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "ctrldssegment=0x%08x\n",
+ readl(&dev->op_regs->ctrldssegment));
+- printk(KERN_DEBUG "deviceaddr=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "deviceaddr=0x%08x\n",
+ readl(&dev->op_regs->deviceaddr));
+- printk(KERN_DEBUG "endpointlistaddr=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "endpointlistaddr=0x%08x\n",
+ readl(&dev->op_regs->endpointlistaddr));
+- printk(KERN_DEBUG "ttctrl=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "ttctrl=0x%08x\n",
+ readl(&dev->op_regs->ttctrl));
+- printk(KERN_DEBUG "burstsize=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "burstsize=0x%08x\n",
+ readl(&dev->op_regs->burstsize));
+- printk(KERN_DEBUG "txfilltuning=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "txfilltuning=0x%08x\n",
+ readl(&dev->op_regs->txfilltuning));
+- printk(KERN_DEBUG "txttfilltuning=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "txttfilltuning=0x%08x\n",
+ readl(&dev->op_regs->txttfilltuning));
+- printk(KERN_DEBUG "ic_usb=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "ic_usb=0x%08x\n",
+ readl(&dev->op_regs->ic_usb));
+- printk(KERN_DEBUG "ulpi_viewport=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "ulpi_viewport=0x%08x\n",
+ readl(&dev->op_regs->ulpi_viewport));
+- printk(KERN_DEBUG "configflag=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "configflag=0x%08x\n",
+ readl(&dev->op_regs->configflag));
+- printk(KERN_DEBUG "portsc1=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "portsc1=0x%08x\n",
+ readl(&dev->op_regs->portsc1));
+- printk(KERN_DEBUG "devlc=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "devlc=0x%08x\n",
+ readl(&dev->op_regs->devlc));
+- printk(KERN_DEBUG "otgsc=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "otgsc=0x%08x\n",
+ readl(&dev->op_regs->otgsc));
+- printk(KERN_DEBUG "usbmode=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "usbmode=0x%08x\n",
+ readl(&dev->op_regs->usbmode));
+- printk(KERN_DEBUG "endptnak=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "endptnak=0x%08x\n",
+ readl(&dev->op_regs->endptnak));
+- printk(KERN_DEBUG "endptnaken=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "endptnaken=0x%08x\n",
+ readl(&dev->op_regs->endptnaken));
+- printk(KERN_DEBUG "endptsetupstat=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "endptsetupstat=0x%08x\n",
+ readl(&dev->op_regs->endptsetupstat));
+- printk(KERN_DEBUG "endptprime=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "endptprime=0x%08x\n",
+ readl(&dev->op_regs->endptprime));
+- printk(KERN_DEBUG "endptflush=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "endptflush=0x%08x\n",
+ readl(&dev->op_regs->endptflush));
+- printk(KERN_DEBUG "endptstat=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "endptstat=0x%08x\n",
+ readl(&dev->op_regs->endptstat));
+- printk(KERN_DEBUG "endptcomplete=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "endptcomplete=0x%08x\n",
+ readl(&dev->op_regs->endptcomplete));
+
+ for (i = 0; i < dev->ep_max / 2; i++) {
+- printk(KERN_DEBUG "endptctrl[%d]=0x%08x\n",
++ dev_dbg(&dev->pdev->dev, "endptctrl[%d]=0x%08x\n",
+ i, readl(&dev->op_regs->endptctrl[i]));
+ }
+ }
+-#endif /* VERBOSE */
++#else
++
++#define print_all_registers(dev) do { } while (0)
++
++#endif /* VERBOSE_DEBUG */
+
+
+ /*-------------------------------------------------------------------------*/
+
+-#define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out")
++#define is_in(ep) (((ep)->ep_num == 0) ? ((ep)->dev->ep0_dir == \
++ USB_DIR_IN) : (usb_endpoint_dir_in((ep)->desc)))
+
+-#define is_in(ep) (((ep)->ep_num == 0) ? ((ep)->dev->ep0_dir == \
+- USB_DIR_IN) : ((ep)->desc->bEndpointAddress \
+- & USB_DIR_IN) == USB_DIR_IN)
++#define DIR_STRING(ep) (is_in(ep) ? "in" : "out")
+
+
+-#ifdef DEBUG
+-static char *type_string(u8 bmAttributes)
++static char *type_string(const struct usb_endpoint_descriptor *desc)
+ {
+- switch ((bmAttributes) & USB_ENDPOINT_XFERTYPE_MASK) {
++ switch (usb_endpoint_type(desc)) {
+ case USB_ENDPOINT_XFER_BULK:
+ return "bulk";
+ case USB_ENDPOINT_XFER_ISOC:
+@@ -222,7 +191,6 @@ static char *type_string(u8 bmAttributes
+
+ return "control";
+ }
+-#endif
+
+
+ /* configure endpoint control registers */
+@@ -233,7 +201,7 @@ static void ep_reset(struct langwell_ep
+ u32 endptctrl;
+
+ dev = ep->dev;
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
+ if (is_in) { /* TX */
+@@ -250,7 +218,7 @@ static void ep_reset(struct langwell_ep
+
+ writel(endptctrl, &dev->op_regs->endptctrl[ep_num]);
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+
+@@ -260,7 +228,7 @@ static void ep0_reset(struct langwell_ud
+ struct langwell_ep *ep;
+ int i;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* ep0 in and out */
+ for (i = 0; i < 2; i++) {
+@@ -283,7 +251,7 @@ static void ep0_reset(struct langwell_ud
+ ep_reset(&dev->ep[0], 0, i, USB_ENDPOINT_XFER_CONTROL);
+ }
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return;
+ }
+
+@@ -305,7 +273,7 @@ static int langwell_ep_enable(struct usb
+
+ ep = container_of(_ep, struct langwell_ep, ep);
+ dev = ep->dev;
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ if (!_ep || !desc || ep->desc
+ || desc->bDescriptorType != USB_DT_ENDPOINT)
+@@ -326,7 +294,7 @@ static int langwell_ep_enable(struct usb
+ * sanity check type, direction, address, and then
+ * initialize the endpoint capabilities fields in dQH
+ */
+- switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
++ switch (usb_endpoint_type(desc)) {
+ case USB_ENDPOINT_XFER_CONTROL:
+ ios = 1;
+ break;
+@@ -395,24 +363,24 @@ static int langwell_ep_enable(struct usb
+ ep->ep.maxpacket = max;
+ ep->desc = desc;
+ ep->stopped = 0;
+- ep->ep_num = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
++ ep->ep_num = usb_endpoint_num(desc);
+
+ /* ep_type */
+- ep->ep_type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
++ ep->ep_type = usb_endpoint_type(desc);
+
+ /* configure endpoint control registers */
+ ep_reset(ep, ep->ep_num, is_in(ep), ep->ep_type);
+
+- DBG(dev, "enabled %s (ep%d%s-%s), max %04x\n",
++ dev_dbg(&dev->pdev->dev, "enabled %s (ep%d%s-%s), max %04x\n",
+ _ep->name,
+ ep->ep_num,
+- DIR_STRING(desc->bEndpointAddress),
+- type_string(desc->bmAttributes),
++ DIR_STRING(ep),
++ type_string(desc),
+ max);
+
+ spin_unlock_irqrestore(&dev->lock, flags);
+ done:
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return retval;
+ }
+
+@@ -428,7 +396,7 @@ static void done(struct langwell_ep *ep,
+ struct langwell_dtd *curr_dtd, *next_dtd;
+ int i;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* remove the req from ep->queue */
+ list_del_init(&req->queue);
+@@ -448,7 +416,8 @@ static void done(struct langwell_ep *ep,
+ }
+
+ if (req->mapped) {
+- dma_unmap_single(&dev->pdev->dev, req->req.dma, req->req.length,
++ dma_unmap_single(&dev->pdev->dev,
++ req->req.dma, req->req.length,
+ is_in(ep) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
+ req->req.dma = DMA_ADDR_INVALID;
+ req->mapped = 0;
+@@ -458,9 +427,10 @@ static void done(struct langwell_ep *ep,
+ is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+
+ if (status != -ESHUTDOWN)
+- DBG(dev, "complete %s, req %p, stat %d, len %u/%u\n",
+- ep->ep.name, &req->req, status,
+- req->req.actual, req->req.length);
++ dev_dbg(&dev->pdev->dev,
++ "complete %s, req %p, stat %d, len %u/%u\n",
++ ep->ep.name, &req->req, status,
++ req->req.actual, req->req.length);
+
+ /* don't modify queue heads during completion callback */
+ ep->stopped = 1;
+@@ -473,7 +443,7 @@ static void done(struct langwell_ep *ep,
+ spin_lock(&dev->lock);
+ ep->stopped = stopped;
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+
+@@ -511,7 +481,7 @@ static int langwell_ep_disable(struct us
+
+ ep = container_of(_ep, struct langwell_ep, ep);
+ dev = ep->dev;
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ if (!_ep || !ep->desc)
+ return -EINVAL;
+@@ -535,8 +505,8 @@ static int langwell_ep_disable(struct us
+
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+- DBG(dev, "disabled %s\n", _ep->name);
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "disabled %s\n", _ep->name);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+
+ return 0;
+ }
+@@ -555,7 +525,7 @@ static struct usb_request *langwell_allo
+
+ ep = container_of(_ep, struct langwell_ep, ep);
+ dev = ep->dev;
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ req = kzalloc(sizeof(*req), gfp_flags);
+ if (!req)
+@@ -564,8 +534,8 @@ static struct usb_request *langwell_allo
+ req->req.dma = DMA_ADDR_INVALID;
+ INIT_LIST_HEAD(&req->queue);
+
+- VDBG(dev, "alloc request for %s\n", _ep->name);
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "alloc request for %s\n", _ep->name);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return &req->req;
+ }
+
+@@ -580,7 +550,7 @@ static void langwell_free_request(struct
+
+ ep = container_of(_ep, struct langwell_ep, ep);
+ dev = ep->dev;
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ if (!_ep || !_req)
+ return;
+@@ -591,8 +561,8 @@ static void langwell_free_request(struct
+ if (_req)
+ kfree(req);
+
+- VDBG(dev, "free request for %s\n", _ep->name);
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "free request for %s\n", _ep->name);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+
+@@ -608,23 +578,24 @@ static int queue_dtd(struct langwell_ep
+ struct langwell_udc *dev;
+
+ dev = ep->dev;
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ i = ep->ep_num * 2 + is_in(ep);
+ dqh = &dev->ep_dqh[i];
+
+ if (ep->ep_num)
+- VDBG(dev, "%s\n", ep->name);
++ dev_vdbg(&dev->pdev->dev, "%s\n", ep->name);
+ else
+ /* ep0 */
+- VDBG(dev, "%s-%s\n", ep->name, is_in(ep) ? "in" : "out");
++ dev_vdbg(&dev->pdev->dev, "%s-%s\n", ep->name, DIR_STRING(ep));
+
+- VDBG(dev, "ep_dqh[%d] addr: 0x%08x\n", i, (u32)&(dev->ep_dqh[i]));
++ dev_vdbg(&dev->pdev->dev, "ep_dqh[%d] addr: 0x%08x\n",
++ i, (u32)&(dev->ep_dqh[i]));
+
+ bit_mask = is_in(ep) ?
+ (1 << (ep->ep_num + 16)) : (1 << (ep->ep_num));
+
+- VDBG(dev, "bit_mask = 0x%08x\n", bit_mask);
++ dev_vdbg(&dev->pdev->dev, "bit_mask = 0x%08x\n", bit_mask);
+
+ /* check if the pipe is empty */
+ if (!(list_empty(&ep->queue))) {
+@@ -665,14 +636,17 @@ static int queue_dtd(struct langwell_ep
+ /* clear active and halt bit */
+ dtd_status = (u8) ~(DTD_STS_ACTIVE | DTD_STS_HALTED);
+ dqh->dtd_status &= dtd_status;
+- VDBG(dev, "dqh->dtd_status = 0x%x\n", dqh->dtd_status);
++ dev_vdbg(&dev->pdev->dev, "dqh->dtd_status = 0x%x\n", dqh->dtd_status);
++
++ /* ensure that updates to the dQH will occure before priming */
++ wmb();
+
+ /* write 1 to endptprime register to PRIME endpoint */
+ bit_mask = is_in(ep) ? (1 << (ep->ep_num + 16)) : (1 << ep->ep_num);
+- VDBG(dev, "endprime bit_mask = 0x%08x\n", bit_mask);
++ dev_vdbg(&dev->pdev->dev, "endprime bit_mask = 0x%08x\n", bit_mask);
+ writel(bit_mask, &dev->op_regs->endptprime);
+ out:
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+ }
+
+@@ -687,7 +661,7 @@ static struct langwell_dtd *build_dtd(st
+ int i;
+
+ dev = req->ep->dev;
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* the maximum transfer length, up to 16k bytes */
+ *length = min(req->req.length - req->req.actual,
+@@ -708,7 +682,7 @@ static struct langwell_dtd *build_dtd(st
+
+ /* fill in total bytes with transfer size */
+ dtd->dtd_total = cpu_to_le16(*length);
+- VDBG(dev, "dtd->dtd_total = %d\n", dtd->dtd_total);
++ dev_vdbg(&dev->pdev->dev, "dtd->dtd_total = %d\n", dtd->dtd_total);
+
+ /* set is_last flag if req->req.zero is set or not */
+ if (req->req.zero) {
+@@ -722,7 +696,7 @@ static struct langwell_dtd *build_dtd(st
+ *is_last = 0;
+
+ if (*is_last == 0)
+- VDBG(dev, "multi-dtd request!\n");
++ dev_vdbg(&dev->pdev->dev, "multi-dtd request!\n");
+
+ /* set interrupt on complete bit for the last dTD */
+ if (*is_last && !req->req.no_interrupt)
+@@ -733,10 +707,12 @@ static struct langwell_dtd *build_dtd(st
+
+ /* set the active bit of status field to 1 */
+ dtd->dtd_status = DTD_STS_ACTIVE;
+- VDBG(dev, "dtd->dtd_status = 0x%02x\n", dtd->dtd_status);
++ dev_vdbg(&dev->pdev->dev, "dtd->dtd_status = 0x%02x\n",
++ dtd->dtd_status);
+
+- VDBG(dev, "length = %d, dma addr= 0x%08x\n", *length, (int)*dma);
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "length = %d, dma addr= 0x%08x\n",
++ *length, (int)*dma);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return dtd;
+ }
+
+@@ -751,7 +727,7 @@ static int req_to_dtd(struct langwell_re
+ dma_addr_t dma;
+
+ dev = req->ep->dev;
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+ do {
+ dtd = build_dtd(req, &count, &dma, &is_last);
+ if (dtd == NULL)
+@@ -773,7 +749,7 @@ static int req_to_dtd(struct langwell_re
+
+ req->tail = dtd;
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+ }
+
+@@ -803,9 +779,9 @@ static int langwell_ep_queue(struct usb_
+
+ dev = ep->dev;
+ req->ep = ep;
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+- if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
++ if (usb_endpoint_xfer_isoc(ep->desc)) {
+ if (req->req.length > ep->ep.maxpacket)
+ return -EMSGSIZE;
+ is_iso = 1;
+@@ -818,7 +794,7 @@ static int langwell_ep_queue(struct usb_
+ if (_req->dma == DMA_ADDR_INVALID) {
+ /* WORKAROUND: WARN_ON(size == 0) */
+ if (_req->length == 0) {
+- VDBG(dev, "req->length: 0->1\n");
++ dev_vdbg(&dev->pdev->dev, "req->length: 0->1\n");
+ zlflag = 1;
+ _req->length++;
+ }
+@@ -827,24 +803,25 @@ static int langwell_ep_queue(struct usb_
+ _req->buf, _req->length,
+ is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ if (zlflag && (_req->length == 1)) {
+- VDBG(dev, "req->length: 1->0\n");
++ dev_vdbg(&dev->pdev->dev, "req->length: 1->0\n");
+ zlflag = 0;
+ _req->length = 0;
+ }
+
+ req->mapped = 1;
+- VDBG(dev, "req->mapped = 1\n");
++ dev_vdbg(&dev->pdev->dev, "req->mapped = 1\n");
+ } else {
+ dma_sync_single_for_device(&dev->pdev->dev,
+ _req->dma, _req->length,
+ is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ req->mapped = 0;
+- VDBG(dev, "req->mapped = 0\n");
++ dev_vdbg(&dev->pdev->dev, "req->mapped = 0\n");
+ }
+
+- DBG(dev, "%s queue req %p, len %u, buf %p, dma 0x%08llx\n",
+- _ep->name,
+- _req, _req->length, _req->buf, (unsigned long long)_req->dma);
++ dev_dbg(&dev->pdev->dev,
++ "%s queue req %p, len %u, buf %p, dma 0x%08x\n",
++ _ep->name,
++ _req, _req->length, _req->buf, (int)_req->dma);
+
+ _req->status = -EINPROGRESS;
+ _req->actual = 0;
+@@ -866,12 +843,12 @@ static int langwell_ep_queue(struct usb_
+
+ if (likely(req != NULL)) {
+ list_add_tail(&req->queue, &ep->queue);
+- VDBG(dev, "list_add_tail() \n");
++ dev_vdbg(&dev->pdev->dev, "list_add_tail()\n");
+ }
+
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+ }
+
+@@ -888,7 +865,7 @@ static int langwell_ep_dequeue(struct us
+
+ ep = container_of(_ep, struct langwell_ep, ep);
+ dev = ep->dev;
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ if (!_ep || !ep->desc || !_req)
+ return -EINVAL;
+@@ -924,7 +901,7 @@ static int langwell_ep_dequeue(struct us
+
+ /* queue head may be partially complete. */
+ if (ep->queue.next == &req->queue) {
+- DBG(dev, "unlink (%s) dma\n", _ep->name);
++ dev_dbg(&dev->pdev->dev, "unlink (%s) dma\n", _ep->name);
+ _req->status = -ECONNRESET;
+ langwell_ep_fifo_flush(&ep->ep);
+
+@@ -963,7 +940,7 @@ done:
+ ep->stopped = stopped;
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return retval;
+ }
+
+@@ -976,7 +953,7 @@ static void ep_set_halt(struct langwell_
+ u32 endptctrl = 0;
+ int ep_num;
+ struct langwell_udc *dev = ep->dev;
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ ep_num = ep->ep_num;
+ endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
+@@ -1001,7 +978,7 @@ static void ep_set_halt(struct langwell_
+
+ writel(endptctrl, &dev->op_regs->endptctrl[ep_num]);
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+
+@@ -1016,7 +993,7 @@ static int langwell_ep_set_halt(struct u
+ ep = container_of(_ep, struct langwell_ep, ep);
+ dev = ep->dev;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ if (!_ep || !ep->desc)
+ return -EINVAL;
+@@ -1024,8 +1001,7 @@ static int langwell_ep_set_halt(struct u
+ if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
+ return -ESHUTDOWN;
+
+- if (ep->desc && (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+- == USB_ENDPOINT_XFER_ISOC)
++ if (usb_endpoint_xfer_isoc(ep->desc))
+ return -EOPNOTSUPP;
+
+ spin_lock_irqsave(&dev->lock, flags);
+@@ -1036,7 +1012,7 @@ static int langwell_ep_set_halt(struct u
+ */
+ if (!list_empty(&ep->queue) && is_in(ep) && value) {
+ /* IN endpoint FIFO holds bytes */
+- DBG(dev, "%s FIFO holds bytes\n", _ep->name);
++ dev_dbg(&dev->pdev->dev, "%s FIFO holds bytes\n", _ep->name);
+ retval = -EAGAIN;
+ goto done;
+ }
+@@ -1050,8 +1026,9 @@ static int langwell_ep_set_halt(struct u
+ }
+ done:
+ spin_unlock_irqrestore(&dev->lock, flags);
+- DBG(dev, "%s %s halt\n", _ep->name, value ? "set" : "clear");
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "%s %s halt\n",
++ _ep->name, value ? "set" : "clear");
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return retval;
+ }
+
+@@ -1065,12 +1042,12 @@ static int langwell_ep_set_wedge(struct
+ ep = container_of(_ep, struct langwell_ep, ep);
+ dev = ep->dev;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ if (!_ep || !ep->desc)
+ return -EINVAL;
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return usb_ep_set_halt(_ep);
+ }
+
+@@ -1086,15 +1063,16 @@ static void langwell_ep_fifo_flush(struc
+ ep = container_of(_ep, struct langwell_ep, ep);
+ dev = ep->dev;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ if (!_ep || !ep->desc) {
+- VDBG(dev, "ep or ep->desc is NULL\n");
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "ep or ep->desc is NULL\n");
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return;
+ }
+
+- VDBG(dev, "%s-%s fifo flush\n", _ep->name, is_in(ep) ? "in" : "out");
++ dev_vdbg(&dev->pdev->dev, "%s-%s fifo flush\n",
++ _ep->name, DIR_STRING(ep));
+
+ /* flush endpoint buffer */
+ if (ep->ep_num == 0)
+@@ -1110,14 +1088,14 @@ static void langwell_ep_fifo_flush(struc
+ writel(flush_bit, &dev->op_regs->endptflush);
+ while (readl(&dev->op_regs->endptflush)) {
+ if (time_after(jiffies, timeout)) {
+- ERROR(dev, "ep flush timeout\n");
++ dev_err(&dev->pdev->dev, "ep flush timeout\n");
+ goto done;
+ }
+ cpu_relax();
+ }
+ } while (readl(&dev->op_regs->endptstat) & flush_bit);
+ done:
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+
+@@ -1167,11 +1145,11 @@ static int langwell_get_frame(struct usb
+ return -ENODEV;
+
+ dev = container_of(_gadget, struct langwell_udc, gadget);
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ retval = readl(&dev->op_regs->frindex) & FRINDEX_MASK;
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return retval;
+ }
+
+@@ -1180,18 +1158,20 @@ static int langwell_get_frame(struct usb
+ static int langwell_wakeup(struct usb_gadget *_gadget)
+ {
+ struct langwell_udc *dev;
+- u32 portsc1, devlc;
+- unsigned long flags;
++ u32 portsc1, devlc;
++ unsigned long flags;
+
+ if (!_gadget)
+ return 0;
+
+ dev = container_of(_gadget, struct langwell_udc, gadget);
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+- /* Remote Wakeup feature not enabled by host */
+- if (!dev->remote_wakeup)
++ /* remote wakeup feature not enabled by host */
++ if (!dev->remote_wakeup) {
++ dev_info(&dev->pdev->dev, "remote wakeup is disabled\n");
+ return -ENOTSUPP;
++ }
+
+ spin_lock_irqsave(&dev->lock, flags);
+
+@@ -1215,13 +1195,12 @@ static int langwell_wakeup(struct usb_ga
+
+ /* exit PHY low power suspend */
+ devlc = readl(&dev->op_regs->devlc);
+- VDBG(dev, "devlc = 0x%08x\n", devlc);
+ devlc &= ~LPM_PHCD;
+ writel(devlc, &dev->op_regs->devlc);
+
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+ }
+
+@@ -1231,16 +1210,17 @@ static int langwell_vbus_session(struct
+ {
+ struct langwell_udc *dev;
+ unsigned long flags;
+- u32 usbcmd;
++ u32 usbcmd;
+
+ if (!_gadget)
+ return -ENODEV;
+
+ dev = container_of(_gadget, struct langwell_udc, gadget);
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ spin_lock_irqsave(&dev->lock, flags);
+- VDBG(dev, "VBUS status: %s\n", is_active ? "on" : "off");
++ dev_vdbg(&dev->pdev->dev, "VBUS status: %s\n",
++ is_active ? "on" : "off");
+
+ dev->vbus_active = (is_active != 0);
+ if (dev->driver && dev->softconnected && dev->vbus_active) {
+@@ -1255,7 +1235,7 @@ static int langwell_vbus_session(struct
+
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+ }
+
+@@ -1269,15 +1249,15 @@ static int langwell_vbus_draw(struct usb
+ return -ENODEV;
+
+ dev = container_of(_gadget, struct langwell_udc, gadget);
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ if (dev->transceiver) {
+- VDBG(dev, "otg_set_power\n");
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "otg_set_power\n");
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return otg_set_power(dev->transceiver, mA);
+ }
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return -ENOTSUPP;
+ }
+
+@@ -1286,15 +1266,15 @@ static int langwell_vbus_draw(struct usb
+ static int langwell_pullup(struct usb_gadget *_gadget, int is_on)
+ {
+ struct langwell_udc *dev;
+- u32 usbcmd;
+- unsigned long flags;
++ u32 usbcmd;
++ unsigned long flags;
+
+ if (!_gadget)
+ return -ENODEV;
+
+ dev = container_of(_gadget, struct langwell_udc, gadget);
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ spin_lock_irqsave(&dev->lock, flags);
+ dev->softconnected = (is_on != 0);
+@@ -1310,7 +1290,7 @@ static int langwell_pullup(struct usb_ga
+ }
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+ }
+
+@@ -1351,7 +1331,7 @@ static int langwell_udc_reset(struct lan
+ if (!dev)
+ return -EINVAL;
+
+- DBG(dev, "---> %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* set controller to stop state */
+ usbcmd = readl(&dev->op_regs->usbcmd);
+@@ -1367,7 +1347,7 @@ static int langwell_udc_reset(struct lan
+ timeout = jiffies + RESET_TIMEOUT;
+ while (readl(&dev->op_regs->usbcmd) & CMD_RST) {
+ if (time_after(jiffies, timeout)) {
+- ERROR(dev, "device reset timeout\n");
++ dev_err(&dev->pdev->dev, "device reset timeout\n");
+ return -ETIMEDOUT;
+ }
+ cpu_relax();
+@@ -1382,7 +1362,7 @@ static int langwell_udc_reset(struct lan
+
+ writel(usbmode, &dev->op_regs->usbmode);
+ usbmode = readl(&dev->op_regs->usbmode);
+- VDBG(dev, "usbmode=0x%08x\n", usbmode);
++ dev_vdbg(&dev->pdev->dev, "usbmode=0x%08x\n", usbmode);
+
+ /* Write-Clear setup status */
+ writel(0, &dev->op_regs->usbsts);
+@@ -1400,10 +1380,11 @@ static int langwell_udc_reset(struct lan
+ endpointlistaddr &= ENDPOINTLISTADDR_MASK;
+ writel(endpointlistaddr, &dev->op_regs->endpointlistaddr);
+
+- VDBG(dev, "dQH base (vir: %p, phy: 0x%08x), endpointlistaddr=0x%08x\n",
+- dev->ep_dqh, endpointlistaddr,
+- readl(&dev->op_regs->endpointlistaddr));
+- DBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev,
++ "dQH base (vir: %p, phy: 0x%08x), endpointlistaddr=0x%08x\n",
++ dev->ep_dqh, endpointlistaddr,
++ readl(&dev->op_regs->endpointlistaddr));
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+ }
+
+@@ -1415,7 +1396,7 @@ static int eps_reinit(struct langwell_ud
+ char name[14];
+ int i;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* initialize ep0 */
+ ep = &dev->ep[0];
+@@ -1453,7 +1434,7 @@ static int eps_reinit(struct langwell_ud
+ ep->dqh = &dev->ep_dqh[i];
+ }
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+ }
+
+@@ -1462,7 +1443,7 @@ static int eps_reinit(struct langwell_ud
+ static void langwell_udc_start(struct langwell_udc *dev)
+ {
+ u32 usbintr, usbcmd;
+- DBG(dev, "---> %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* enable interrupts */
+ usbintr = INTR_ULPIE /* ULPI */
+@@ -1485,7 +1466,7 @@ static void langwell_udc_start(struct la
+ usbcmd |= CMD_RUNSTOP;
+ writel(usbcmd, &dev->op_regs->usbcmd);
+
+- DBG(dev, "<--- %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return;
+ }
+
+@@ -1495,7 +1476,7 @@ static void langwell_udc_stop(struct lan
+ {
+ u32 usbcmd;
+
+- DBG(dev, "---> %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* disable all interrupts */
+ writel(0, &dev->op_regs->usbintr);
+@@ -1508,7 +1489,7 @@ static void langwell_udc_stop(struct lan
+ usbcmd &= ~CMD_RUNSTOP;
+ writel(usbcmd, &dev->op_regs->usbcmd);
+
+- DBG(dev, "<--- %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return;
+ }
+
+@@ -1518,7 +1499,7 @@ static void stop_activity(struct langwel
+ struct usb_gadget_driver *driver)
+ {
+ struct langwell_ep *ep;
+- DBG(dev, "---> %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ nuke(&dev->ep[0], -ESHUTDOWN);
+
+@@ -1533,7 +1514,7 @@ static void stop_activity(struct langwel
+ spin_lock(&dev->lock);
+ }
+
+- DBG(dev, "<--- %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+
+@@ -1659,13 +1640,15 @@ static ssize_t show_langwell_udc(struct
+ "Over-current Change: %s\n"
+ "Port Enable/Disable Change: %s\n"
+ "Port Enabled/Disabled: %s\n"
+- "Current Connect Status: %s\n\n",
++ "Current Connect Status: %s\n"
++ "LPM Suspend Status: %s\n\n",
+ (tmp_reg & PORTS_PR) ? "Reset" : "Not Reset",
+ (tmp_reg & PORTS_SUSP) ? "Suspend " : "Not Suspend",
+ (tmp_reg & PORTS_OCC) ? "Detected" : "No",
+ (tmp_reg & PORTS_PEC) ? "Changed" : "Not Changed",
+ (tmp_reg & PORTS_PE) ? "Enable" : "Not Correct",
+- (tmp_reg & PORTS_CCS) ? "Attached" : "Not Attached");
++ (tmp_reg & PORTS_CCS) ? "Attached" : "Not Attached",
++ (tmp_reg & PORTS_SLP) ? "LPM L1" : "LPM L0");
+ size -= t;
+ next += t;
+
+@@ -1676,7 +1659,7 @@ static ssize_t show_langwell_udc(struct
+ "Serial Transceiver : %d\n"
+ "Port Speed: %s\n"
+ "Port Force Full Speed Connenct: %s\n"
+- "PHY Low Power Suspend Clock Disable: %s\n"
++ "PHY Low Power Suspend Clock: %s\n"
+ "BmAttributes: %d\n\n",
+ LPM_PTS(tmp_reg),
+ (tmp_reg & LPM_STS) ? 1 : 0,
+@@ -1816,7 +1799,7 @@ int usb_gadget_register_driver(struct us
+ if (!dev)
+ return -ENODEV;
+
+- DBG(dev, "---> %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ if (dev->driver)
+ return -EBUSY;
+@@ -1832,7 +1815,7 @@ int usb_gadget_register_driver(struct us
+
+ retval = driver->bind(&dev->gadget);
+ if (retval) {
+- DBG(dev, "bind to driver %s --> %d\n",
++ dev_dbg(&dev->pdev->dev, "bind to driver %s --> %d\n",
+ driver->driver.name, retval);
+ dev->driver = NULL;
+ dev->gadget.dev.driver = NULL;
+@@ -1851,13 +1834,13 @@ int usb_gadget_register_driver(struct us
+ if (dev->got_irq)
+ langwell_udc_start(dev);
+
+- VDBG(dev, "After langwell_udc_start(), print all registers:\n");
+-#ifdef VERBOSE
++ dev_vdbg(&dev->pdev->dev,
++ "After langwell_udc_start(), print all registers:\n");
+ print_all_registers(dev);
+-#endif
+
+- INFO(dev, "register driver: %s\n", driver->driver.name);
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_info(&dev->pdev->dev, "register driver: %s\n",
++ driver->driver.name);
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+
+ err_unbind:
+@@ -1865,7 +1848,7 @@ err_unbind:
+ dev->gadget.dev.driver = NULL;
+ dev->driver = NULL;
+
+- DBG(dev, "<--- %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return retval;
+ }
+ EXPORT_SYMBOL(usb_gadget_register_driver);
+@@ -1880,7 +1863,7 @@ int usb_gadget_unregister_driver(struct
+ if (!dev)
+ return -ENODEV;
+
+- DBG(dev, "---> %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ if (unlikely(!driver || !driver->bind || !driver->unbind))
+ return -EINVAL;
+@@ -1910,8 +1893,9 @@ int usb_gadget_unregister_driver(struct
+
+ device_remove_file(&dev->pdev->dev, &dev_attr_function);
+
+- INFO(dev, "unregistered driver '%s'\n", driver->driver.name);
+- DBG(dev, "<--- %s()\n", __func__);
++ dev_info(&dev->pdev->dev, "unregistered driver '%s'\n",
++ driver->driver.name);
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+ }
+ EXPORT_SYMBOL(usb_gadget_unregister_driver);
+@@ -1930,7 +1914,7 @@ static void setup_tripwire(struct langwe
+ unsigned long timeout;
+ struct langwell_dqh *dqh;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* ep0 OUT dQH */
+ dqh = &dev->ep_dqh[EP_DIR_OUT];
+@@ -1943,7 +1927,7 @@ static void setup_tripwire(struct langwe
+ timeout = jiffies + SETUPSTAT_TIMEOUT;
+ while (readl(&dev->op_regs->endptsetupstat)) {
+ if (time_after(jiffies, timeout)) {
+- ERROR(dev, "setup_tripwire timeout\n");
++ dev_err(&dev->pdev->dev, "setup_tripwire timeout\n");
+ break;
+ }
+ cpu_relax();
+@@ -1963,7 +1947,7 @@ static void setup_tripwire(struct langwe
+ usbcmd = readl(&dev->op_regs->usbcmd);
+ writel(usbcmd & ~CMD_SUTW, &dev->op_regs->usbcmd);
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+
+@@ -1972,7 +1956,7 @@ static void ep0_stall(struct langwell_ud
+ {
+ u32 endptctrl;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* set TX and RX to stall */
+ endptctrl = readl(&dev->op_regs->endptctrl[0]);
+@@ -1983,7 +1967,7 @@ static void ep0_stall(struct langwell_ud
+ dev->ep0_state = WAIT_FOR_SETUP;
+ dev->ep0_dir = USB_DIR_OUT;
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+
+@@ -1994,7 +1978,7 @@ static int prime_status_phase(struct lan
+ struct langwell_ep *ep;
+ int status = 0;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ if (dir == EP_DIR_IN)
+ dev->ep0_dir = USB_DIR_IN;
+@@ -2019,11 +2003,11 @@ static int prime_status_phase(struct lan
+ return -ENOMEM;
+
+ if (status)
+- ERROR(dev, "can't queue ep0 status request\n");
++ dev_err(&dev->pdev->dev, "can't queue ep0 status request\n");
+
+ list_add_tail(&req->queue, &ep->queue);
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return status;
+ }
+
+@@ -2032,11 +2016,11 @@ static int prime_status_phase(struct lan
+ static void set_address(struct langwell_udc *dev, u16 value,
+ u16 index, u16 length)
+ {
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* save the new address to device struct */
+ dev->dev_addr = (u8) value;
+- VDBG(dev, "dev->dev_addr = %d\n", dev->dev_addr);
++ dev_vdbg(&dev->pdev->dev, "dev->dev_addr = %d\n", dev->dev_addr);
+
+ /* update usb state */
+ dev->usb_state = USB_STATE_ADDRESS;
+@@ -2045,7 +2029,7 @@ static void set_address(struct langwell_
+ if (prime_status_phase(dev, EP_DIR_IN))
+ ep0_stall(dev);
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+
+@@ -2054,7 +2038,7 @@ static struct langwell_ep *get_ep_by_win
+ u16 wIndex)
+ {
+ struct langwell_ep *ep;
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)
+ return &dev->ep[0];
+@@ -2073,7 +2057,7 @@ static struct langwell_ep *get_ep_by_win
+ return ep;
+ }
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return NULL;
+ }
+
+@@ -2085,7 +2069,7 @@ static int ep_is_stall(struct langwell_e
+ u32 endptctrl;
+ int retval;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ endptctrl = readl(&dev->op_regs->endptctrl[ep->ep_num]);
+ if (is_in(ep))
+@@ -2093,7 +2077,7 @@ static int ep_is_stall(struct langwell_e
+ else
+ retval = endptctrl & EPCTRL_RXS ? 1 : 0;
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return retval;
+ }
+
+@@ -2107,7 +2091,7 @@ static void get_status(struct langwell_u
+ u16 status_data = 0; /* 16 bits cpu view status data */
+ int status = 0;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ ep = &dev->ep[0];
+
+@@ -2129,6 +2113,8 @@ static void get_status(struct langwell_u
+ status_data = ep_is_stall(epn) << USB_ENDPOINT_HALT;
+ }
+
++ dev_dbg(&dev->pdev->dev, "get status data: 0x%04x\n", status_data);
++
+ dev->ep0_dir = USB_DIR_IN;
+
+ /* borrow the per device status_req */
+@@ -2150,18 +2136,19 @@ static void get_status(struct langwell_u
+ goto stall;
+
+ if (status) {
+- ERROR(dev, "response error on GET_STATUS request\n");
++ dev_err(&dev->pdev->dev,
++ "response error on GET_STATUS request\n");
+ goto stall;
+ }
+
+ list_add_tail(&req->queue, &ep->queue);
+ dev->ep0_state = DATA_STATE_XMIT;
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return;
+ stall:
+ ep0_stall(dev);
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+
+@@ -2173,12 +2160,12 @@ static void handle_setup_packet(struct l
+ u16 wIndex = le16_to_cpu(setup->wIndex);
+ u16 wLength = le16_to_cpu(setup->wLength);
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* ep0 fifo flush */
+ nuke(&dev->ep[0], -ESHUTDOWN);
+
+- DBG(dev, "SETUP %02x.%02x v%04x i%04x l%04x\n",
++ dev_dbg(&dev->pdev->dev, "SETUP %02x.%02x v%04x i%04x l%04x\n",
+ setup->bRequestType, setup->bRequest,
+ wValue, wIndex, wLength);
+
+@@ -2197,7 +2184,7 @@ static void handle_setup_packet(struct l
+ /* We process some stardard setup requests here */
+ switch (setup->bRequest) {
+ case USB_REQ_GET_STATUS:
+- DBG(dev, "SETUP: USB_REQ_GET_STATUS\n");
++ dev_dbg(&dev->pdev->dev, "SETUP: USB_REQ_GET_STATUS\n");
+ /* get status, DATA and STATUS phase */
+ if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK))
+ != (USB_DIR_IN | USB_TYPE_STANDARD))
+@@ -2206,7 +2193,7 @@ static void handle_setup_packet(struct l
+ goto end;
+
+ case USB_REQ_SET_ADDRESS:
+- DBG(dev, "SETUP: USB_REQ_SET_ADDRESS\n");
++ dev_dbg(&dev->pdev->dev, "SETUP: USB_REQ_SET_ADDRESS\n");
+ /* STATUS phase */
+ if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD
+ | USB_RECIP_DEVICE))
+@@ -2220,9 +2207,11 @@ static void handle_setup_packet(struct l
+ {
+ int rc = -EOPNOTSUPP;
+ if (setup->bRequest == USB_REQ_SET_FEATURE)
+- DBG(dev, "SETUP: USB_REQ_SET_FEATURE\n");
++ dev_dbg(&dev->pdev->dev,
++ "SETUP: USB_REQ_SET_FEATURE\n");
+ else if (setup->bRequest == USB_REQ_CLEAR_FEATURE)
+- DBG(dev, "SETUP: USB_REQ_CLEAR_FEATURE\n");
++ dev_dbg(&dev->pdev->dev,
++ "SETUP: USB_REQ_CLEAR_FEATURE\n");
+
+ if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK))
+ == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) {
+@@ -2240,8 +2229,8 @@ static void handle_setup_packet(struct l
+
+ spin_unlock(&dev->lock);
+ rc = langwell_ep_set_halt(&epn->ep,
+- (setup->bRequest == USB_REQ_SET_FEATURE)
+- ? 1 : 0);
++ (setup->bRequest == USB_REQ_SET_FEATURE)
++ ? 1 : 0);
+ spin_lock(&dev->lock);
+
+ } else if ((setup->bRequestType & (USB_RECIP_MASK
+@@ -2274,31 +2263,38 @@ static void handle_setup_packet(struct l
+ }
+
+ case USB_REQ_GET_DESCRIPTOR:
+- DBG(dev, "SETUP: USB_REQ_GET_DESCRIPTOR\n");
++ dev_dbg(&dev->pdev->dev,
++ "SETUP: USB_REQ_GET_DESCRIPTOR\n");
+ goto delegate;
+
+ case USB_REQ_SET_DESCRIPTOR:
+- DBG(dev, "SETUP: USB_REQ_SET_DESCRIPTOR unsupported\n");
++ dev_dbg(&dev->pdev->dev,
++ "SETUP: USB_REQ_SET_DESCRIPTOR unsupported\n");
+ goto delegate;
+
+ case USB_REQ_GET_CONFIGURATION:
+- DBG(dev, "SETUP: USB_REQ_GET_CONFIGURATION\n");
++ dev_dbg(&dev->pdev->dev,
++ "SETUP: USB_REQ_GET_CONFIGURATION\n");
+ goto delegate;
+
+ case USB_REQ_SET_CONFIGURATION:
+- DBG(dev, "SETUP: USB_REQ_SET_CONFIGURATION\n");
++ dev_dbg(&dev->pdev->dev,
++ "SETUP: USB_REQ_SET_CONFIGURATION\n");
+ goto delegate;
+
+ case USB_REQ_GET_INTERFACE:
+- DBG(dev, "SETUP: USB_REQ_GET_INTERFACE\n");
++ dev_dbg(&dev->pdev->dev,
++ "SETUP: USB_REQ_GET_INTERFACE\n");
+ goto delegate;
+
+ case USB_REQ_SET_INTERFACE:
+- DBG(dev, "SETUP: USB_REQ_SET_INTERFACE\n");
++ dev_dbg(&dev->pdev->dev,
++ "SETUP: USB_REQ_SET_INTERFACE\n");
+ goto delegate;
+
+ case USB_REQ_SYNCH_FRAME:
+- DBG(dev, "SETUP: USB_REQ_SYNCH_FRAME unsupported\n");
++ dev_dbg(&dev->pdev->dev,
++ "SETUP: USB_REQ_SYNCH_FRAME unsupported\n");
+ goto delegate;
+
+ default:
+@@ -2310,7 +2306,8 @@ delegate:
+ /* DATA phase from gadget, STATUS phase from udc */
+ dev->ep0_dir = (setup->bRequestType & USB_DIR_IN)
+ ? USB_DIR_IN : USB_DIR_OUT;
+- VDBG(dev, "dev->ep0_dir = 0x%x, wLength = %d\n",
++ dev_vdbg(&dev->pdev->dev,
++ "dev->ep0_dir = 0x%x, wLength = %d\n",
+ dev->ep0_dir, wLength);
+ spin_unlock(&dev->lock);
+ if (dev->driver->setup(&dev->gadget,
+@@ -2322,7 +2319,8 @@ delegate:
+ } else {
+ /* no DATA phase, IN STATUS phase from gadget */
+ dev->ep0_dir = USB_DIR_IN;
+- VDBG(dev, "dev->ep0_dir = 0x%x, wLength = %d\n",
++ dev_vdbg(&dev->pdev->dev,
++ "dev->ep0_dir = 0x%x, wLength = %d\n",
+ dev->ep0_dir, wLength);
+ spin_unlock(&dev->lock);
+ if (dev->driver->setup(&dev->gadget,
+@@ -2334,7 +2332,7 @@ delegate:
+ break;
+ }
+ end:
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return;
+ }
+
+@@ -2359,7 +2357,7 @@ static int process_ep_req(struct langwel
+ td_complete = 0;
+ actual = curr_req->req.length;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ for (i = 0; i < curr_req->dtd_count; i++) {
+ remaining_length = le16_to_cpu(curr_dtd->dtd_total);
+@@ -2372,10 +2370,12 @@ static int process_ep_req(struct langwel
+ /* transfers completed successfully */
+ if (!remaining_length) {
+ td_complete++;
+- VDBG(dev, "dTD transmitted successfully\n");
++ dev_vdbg(&dev->pdev->dev,
++ "dTD transmitted successfully\n");
+ } else {
+ if (dir) {
+- VDBG(dev, "TX dTD remains data\n");
++ dev_vdbg(&dev->pdev->dev,
++ "TX dTD remains data\n");
+ retval = -EPROTO;
+ break;
+
+@@ -2387,27 +2387,32 @@ static int process_ep_req(struct langwel
+ } else {
+ /* transfers completed with errors */
+ if (dtd_status & DTD_STS_ACTIVE) {
+- DBG(dev, "request not completed\n");
++ dev_dbg(&dev->pdev->dev,
++ "dTD status ACTIVE dQH[%d]\n", index);
+ retval = 1;
+ return retval;
+ } else if (dtd_status & DTD_STS_HALTED) {
+- ERROR(dev, "dTD error %08x dQH[%d]\n",
+- dtd_status, index);
++ dev_err(&dev->pdev->dev,
++ "dTD error %08x dQH[%d]\n",
++ dtd_status, index);
+ /* clear the errors and halt condition */
+ curr_dqh->dtd_status = 0;
+ retval = -EPIPE;
+ break;
+ } else if (dtd_status & DTD_STS_DBE) {
+- DBG(dev, "data buffer (overflow) error\n");
++ dev_dbg(&dev->pdev->dev,
++ "data buffer (overflow) error\n");
+ retval = -EPROTO;
+ break;
+ } else if (dtd_status & DTD_STS_TRE) {
+- DBG(dev, "transaction(ISO) error\n");
++ dev_dbg(&dev->pdev->dev,
++ "transaction(ISO) error\n");
+ retval = -EILSEQ;
+ break;
+ } else
+- ERROR(dev, "unknown error (0x%x)!\n",
+- dtd_status);
++ dev_err(&dev->pdev->dev,
++ "unknown error (0x%x)!\n",
++ dtd_status);
+ }
+
+ if (i != curr_req->dtd_count - 1)
+@@ -2420,7 +2425,7 @@ static int process_ep_req(struct langwel
+
+ curr_req->req.actual = actual;
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+ }
+
+@@ -2430,7 +2435,7 @@ static void ep0_req_complete(struct lang
+ struct langwell_ep *ep0, struct langwell_request *req)
+ {
+ u32 new_addr;
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ if (dev->usb_state == USB_STATE_ADDRESS) {
+ /* set the new address */
+@@ -2438,7 +2443,7 @@ static void ep0_req_complete(struct lang
+ writel(new_addr << USBADR_SHIFT, &dev->op_regs->deviceaddr);
+
+ new_addr = USBADR(readl(&dev->op_regs->deviceaddr));
+- VDBG(dev, "new_addr = %d\n", new_addr);
++ dev_vdbg(&dev->pdev->dev, "new_addr = %d\n", new_addr);
+ }
+
+ done(ep0, req, 0);
+@@ -2458,14 +2463,14 @@ static void ep0_req_complete(struct lang
+ dev->ep0_state = WAIT_FOR_SETUP;
+ break;
+ case WAIT_FOR_SETUP:
+- ERROR(dev, "unexpect ep0 packets\n");
++ dev_err(&dev->pdev->dev, "unexpect ep0 packets\n");
+ break;
+ default:
+ ep0_stall(dev);
+ break;
+ }
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+
+@@ -2477,16 +2482,17 @@ static void handle_trans_complete(struct
+ struct langwell_ep *epn;
+ struct langwell_request *curr_req, *temp_req;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ complete_bits = readl(&dev->op_regs->endptcomplete);
+- VDBG(dev, "endptcomplete register: 0x%08x\n", complete_bits);
++ dev_vdbg(&dev->pdev->dev, "endptcomplete register: 0x%08x\n",
++ complete_bits);
+
+ /* Write-Clear the bits in endptcomplete register */
+ writel(complete_bits, &dev->op_regs->endptcomplete);
+
+ if (!complete_bits) {
+- DBG(dev, "complete_bits = 0\n");
++ dev_dbg(&dev->pdev->dev, "complete_bits = 0\n");
+ goto done;
+ }
+
+@@ -2506,23 +2512,25 @@ static void handle_trans_complete(struct
+ epn = &dev->ep[i];
+
+ if (epn->name == NULL) {
+- WARNING(dev, "invalid endpoint\n");
++ dev_warn(&dev->pdev->dev, "invalid endpoint\n");
+ continue;
+ }
+
+ if (i < 2)
+ /* ep0 in and out */
+- DBG(dev, "%s-%s transfer completed\n",
++ dev_dbg(&dev->pdev->dev, "%s-%s transfer completed\n",
+ epn->name,
+ is_in(epn) ? "in" : "out");
+ else
+- DBG(dev, "%s transfer completed\n", epn->name);
++ dev_dbg(&dev->pdev->dev, "%s transfer completed\n",
++ epn->name);
+
+ /* process the req queue until an uncomplete request */
+ list_for_each_entry_safe(curr_req, temp_req,
+ &epn->queue, queue) {
+ status = process_ep_req(dev, i, curr_req);
+- VDBG(dev, "%s req status: %d\n", epn->name, status);
++ dev_vdbg(&dev->pdev->dev, "%s req status: %d\n",
++ epn->name, status);
+
+ if (status)
+ break;
+@@ -2540,7 +2548,7 @@ static void handle_trans_complete(struct
+ }
+ }
+ done:
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return;
+ }
+
+@@ -2551,14 +2559,14 @@ static void handle_port_change(struct la
+ u32 portsc1, devlc;
+ u32 speed;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ if (dev->bus_reset)
+ dev->bus_reset = 0;
+
+ portsc1 = readl(&dev->op_regs->portsc1);
+ devlc = readl(&dev->op_regs->devlc);
+- VDBG(dev, "portsc1 = 0x%08x, devlc = 0x%08x\n",
++ dev_vdbg(&dev->pdev->dev, "portsc1 = 0x%08x, devlc = 0x%08x\n",
+ portsc1, devlc);
+
+ /* bus reset is finished */
+@@ -2579,25 +2587,22 @@ static void handle_port_change(struct la
+ dev->gadget.speed = USB_SPEED_UNKNOWN;
+ break;
+ }
+- VDBG(dev, "speed = %d, dev->gadget.speed = %d\n",
++ dev_vdbg(&dev->pdev->dev,
++ "speed = %d, dev->gadget.speed = %d\n",
+ speed, dev->gadget.speed);
+ }
+
+ /* LPM L0 to L1 */
+ if (dev->lpm && dev->lpm_state == LPM_L0)
+ if (portsc1 & PORTS_SUSP && portsc1 & PORTS_SLP) {
+- INFO(dev, "LPM L0 to L1\n");
+- dev->lpm_state = LPM_L1;
++ dev_info(&dev->pdev->dev, "LPM L0 to L1\n");
++ dev->lpm_state = LPM_L1;
+ }
+
+ /* LPM L1 to L0, force resume or remote wakeup finished */
+ if (dev->lpm && dev->lpm_state == LPM_L1)
+ if (!(portsc1 & PORTS_SUSP)) {
+- if (portsc1 & PORTS_SLP)
+- INFO(dev, "LPM L1 to L0, force resume\n");
+- else
+- INFO(dev, "LPM L1 to L0, remote wakeup\n");
+-
++ dev_info(&dev->pdev->dev, "LPM L1 to L0\n");
+ dev->lpm_state = LPM_L0;
+ }
+
+@@ -2605,7 +2610,7 @@ static void handle_port_change(struct la
+ if (!dev->resume_state)
+ dev->usb_state = USB_STATE_DEFAULT;
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+
+@@ -2617,7 +2622,7 @@ static void handle_usb_reset(struct lang
+ endptcomplete;
+ unsigned long timeout;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* Write-Clear the device address */
+ deviceaddr = readl(&dev->op_regs->deviceaddr);
+@@ -2651,7 +2656,7 @@ static void handle_usb_reset(struct lang
+ timeout = jiffies + PRIME_TIMEOUT;
+ while (readl(&dev->op_regs->endptprime)) {
+ if (time_after(jiffies, timeout)) {
+- ERROR(dev, "USB reset timeout\n");
++ dev_err(&dev->pdev->dev, "USB reset timeout\n");
+ break;
+ }
+ cpu_relax();
+@@ -2661,7 +2666,7 @@ static void handle_usb_reset(struct lang
+ writel((u32) ~0, &dev->op_regs->endptflush);
+
+ if (readl(&dev->op_regs->portsc1) & PORTS_PR) {
+- VDBG(dev, "USB bus reset\n");
++ dev_vdbg(&dev->pdev->dev, "USB bus reset\n");
+ /* bus is reseting */
+ dev->bus_reset = 1;
+
+@@ -2669,7 +2674,7 @@ static void handle_usb_reset(struct lang
+ stop_activity(dev, dev->driver);
+ dev->usb_state = USB_STATE_DEFAULT;
+ } else {
+- VDBG(dev, "device controller reset\n");
++ dev_vdbg(&dev->pdev->dev, "device controller reset\n");
+ /* controller reset */
+ langwell_udc_reset(dev);
+
+@@ -2691,7 +2696,7 @@ static void handle_usb_reset(struct lang
+ dev->lotg->hsm.b_hnp_enable = 0;
+ #endif
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+
+@@ -2699,7 +2704,7 @@ static void handle_usb_reset(struct lang
+ static void handle_bus_suspend(struct langwell_udc *dev)
+ {
+ u32 devlc;
+- DBG(dev, "---> %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ dev->resume_state = dev->usb_state;
+ dev->usb_state = USB_STATE_SUSPENDED;
+@@ -2733,31 +2738,30 @@ static void handle_bus_suspend(struct la
+ spin_unlock(&dev->lock);
+ dev->driver->suspend(&dev->gadget);
+ spin_lock(&dev->lock);
+- DBG(dev, "suspend %s\n", dev->driver->driver.name);
++ dev_dbg(&dev->pdev->dev, "suspend %s\n",
++ dev->driver->driver.name);
+ }
+ }
+
+ /* enter PHY low power suspend */
+ devlc = readl(&dev->op_regs->devlc);
+- VDBG(dev, "devlc = 0x%08x\n", devlc);
+ devlc |= LPM_PHCD;
+ writel(devlc, &dev->op_regs->devlc);
+
+- DBG(dev, "<--- %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+
+ static void handle_bus_resume(struct langwell_udc *dev)
+ {
+ u32 devlc;
+- DBG(dev, "---> %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ dev->usb_state = dev->resume_state;
+ dev->resume_state = 0;
+
+ /* exit PHY low power suspend */
+ devlc = readl(&dev->op_regs->devlc);
+- VDBG(dev, "devlc = 0x%08x\n", devlc);
+ devlc &= ~LPM_PHCD;
+ writel(devlc, &dev->op_regs->devlc);
+
+@@ -2772,11 +2776,12 @@ static void handle_bus_resume(struct lan
+ spin_unlock(&dev->lock);
+ dev->driver->resume(&dev->gadget);
+ spin_lock(&dev->lock);
+- DBG(dev, "resume %s\n", dev->driver->driver.name);
++ dev_dbg(&dev->pdev->dev, "resume %s\n",
++ dev->driver->driver.name);
+ }
+ }
+
+- DBG(dev, "<--- %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+
+@@ -2789,11 +2794,11 @@ static irqreturn_t langwell_irq(int irq,
+ irq_sts,
+ portsc1;
+
+- VDBG(dev, "---> %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ if (dev->stopped) {
+- VDBG(dev, "handle IRQ_NONE\n");
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "handle IRQ_NONE\n");
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return IRQ_NONE;
+ }
+
+@@ -2806,12 +2811,13 @@ static irqreturn_t langwell_irq(int irq,
+ usbintr = readl(&dev->op_regs->usbintr);
+
+ irq_sts = usbsts & usbintr;
+- VDBG(dev, "usbsts = 0x%08x, usbintr = 0x%08x, irq_sts = 0x%08x\n",
++ dev_vdbg(&dev->pdev->dev,
++ "usbsts = 0x%08x, usbintr = 0x%08x, irq_sts = 0x%08x\n",
+ usbsts, usbintr, irq_sts);
+
+ if (!irq_sts) {
+- VDBG(dev, "handle IRQ_NONE\n");
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "handle IRQ_NONE\n");
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ spin_unlock(&dev->lock);
+ return IRQ_NONE;
+ }
+@@ -2827,12 +2833,13 @@ static irqreturn_t langwell_irq(int irq,
+
+ /* USB interrupt */
+ if (irq_sts & STS_UI) {
+- VDBG(dev, "USB interrupt\n");
++ dev_vdbg(&dev->pdev->dev, "USB interrupt\n");
+
+ /* setup packet received from ep0 */
+ if (readl(&dev->op_regs->endptsetupstat)
+ & EP0SETUPSTAT_MASK) {
+- VDBG(dev, "USB SETUP packet received interrupt\n");
++ dev_vdbg(&dev->pdev->dev,
++ "USB SETUP packet received interrupt\n");
+ /* setup tripwire semaphone */
+ setup_tripwire(dev);
+ handle_setup_packet(dev, &dev->local_setup_buff);
+@@ -2840,7 +2847,8 @@ static irqreturn_t langwell_irq(int irq,
+
+ /* USB transfer completion */
+ if (readl(&dev->op_regs->endptcomplete)) {
+- VDBG(dev, "USB transfer completion interrupt\n");
++ dev_vdbg(&dev->pdev->dev,
++ "USB transfer completion interrupt\n");
+ handle_trans_complete(dev);
+ }
+ }
+@@ -2848,36 +2856,36 @@ static irqreturn_t langwell_irq(int irq,
+ /* SOF received interrupt (for ISO transfer) */
+ if (irq_sts & STS_SRI) {
+ /* FIXME */
+- /* VDBG(dev, "SOF received interrupt\n"); */
++ /* dev_vdbg(&dev->pdev->dev, "SOF received interrupt\n"); */
+ }
+
+ /* port change detect interrupt */
+ if (irq_sts & STS_PCI) {
+- VDBG(dev, "port change detect interrupt\n");
++ dev_vdbg(&dev->pdev->dev, "port change detect interrupt\n");
+ handle_port_change(dev);
+ }
+
+ /* suspend interrrupt */
+ if (irq_sts & STS_SLI) {
+- VDBG(dev, "suspend interrupt\n");
++ dev_vdbg(&dev->pdev->dev, "suspend interrupt\n");
+ handle_bus_suspend(dev);
+ }
+
+ /* USB reset interrupt */
+ if (irq_sts & STS_URI) {
+- VDBG(dev, "USB reset interrupt\n");
++ dev_vdbg(&dev->pdev->dev, "USB reset interrupt\n");
+ handle_usb_reset(dev);
+ }
+
+ /* USB error or system error interrupt */
+ if (irq_sts & (STS_UEI | STS_SEI)) {
+ /* FIXME */
+- WARNING(dev, "error IRQ, irq_sts: %x\n", irq_sts);
++ dev_warn(&dev->pdev->dev, "error IRQ, irq_sts: %x\n", irq_sts);
+ }
+
+ spin_unlock(&dev->lock);
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return IRQ_HANDLED;
+ }
+
+@@ -2889,11 +2897,11 @@ static void gadget_release(struct device
+ {
+ struct langwell_udc *dev = the_controller;
+
+- DBG(dev, "---> %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ complete(dev->done);
+
+- DBG(dev, "<--- %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ kfree(dev);
+ }
+
+@@ -2906,7 +2914,7 @@ static void langwell_udc_remove(struct p
+ DECLARE_COMPLETION(done);
+
+ BUG_ON(dev->driver);
+- DBG(dev, "---> %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ dev->done = &done;
+
+@@ -2949,8 +2957,8 @@ static void langwell_udc_remove(struct p
+
+ dev->cap_regs = NULL;
+
+- INFO(dev, "unbind\n");
+- DBG(dev, "<--- %s()\n", __func__);
++ dev_info(&dev->pdev->dev, "unbind\n");
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+
+ device_unregister(&dev->gadget.dev);
+ device_remove_file(&pdev->dev, &dev_attr_langwell_udc);
+@@ -2997,7 +3005,7 @@ static int langwell_udc_probe(struct pci
+ spin_lock_init(&dev->lock);
+
+ dev->pdev = pdev;
+- DBG(dev, "---> %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ #ifdef OTG_TRANSCEIVER
+ /* PCI device is already enabled by otg_transceiver driver */
+@@ -3022,7 +3030,7 @@ static int langwell_udc_probe(struct pci
+ resource = pci_resource_start(pdev, 0);
+ len = pci_resource_len(pdev, 0);
+ if (!request_mem_region(resource, len, driver_name)) {
+- ERROR(dev, "controller already in use\n");
++ dev_err(&dev->pdev->dev, "controller already in use\n");
+ retval = -EBUSY;
+ goto error;
+ }
+@@ -3031,33 +3039,35 @@ static int langwell_udc_probe(struct pci
+ base = ioremap_nocache(resource, len);
+ #endif
+ if (base == NULL) {
+- ERROR(dev, "can't map memory\n");
++ dev_err(&dev->pdev->dev, "can't map memory\n");
+ retval = -EFAULT;
+ goto error;
+ }
+
+ dev->cap_regs = (struct langwell_cap_regs __iomem *) base;
+- VDBG(dev, "dev->cap_regs: %p\n", dev->cap_regs);
++ dev_vdbg(&dev->pdev->dev, "dev->cap_regs: %p\n", dev->cap_regs);
+ dev->op_regs = (struct langwell_op_regs __iomem *)
+ (base + OP_REG_OFFSET);
+- VDBG(dev, "dev->op_regs: %p\n", dev->op_regs);
++ dev_vdbg(&dev->pdev->dev, "dev->op_regs: %p\n", dev->op_regs);
+
+ /* irq setup after old hardware is cleaned up */
+ if (!pdev->irq) {
+- ERROR(dev, "No IRQ. Check PCI setup!\n");
++ dev_err(&dev->pdev->dev, "No IRQ. Check PCI setup!\n");
+ retval = -ENODEV;
+ goto error;
+ }
+
+ #ifndef OTG_TRANSCEIVER
+- INFO(dev, "irq %d, io mem: 0x%08lx, len: 0x%08lx, pci mem 0x%p\n",
++ dev_info(&dev->pdev->dev,
++ "irq %d, io mem: 0x%08lx, len: 0x%08lx, pci mem 0x%p\n",
+ pdev->irq, resource, len, base);
+ /* enables bus-mastering for device dev */
+ pci_set_master(pdev);
+
+ if (request_irq(pdev->irq, langwell_irq, IRQF_SHARED,
+ driver_name, dev) != 0) {
+- ERROR(dev, "request interrupt %d failed\n", pdev->irq);
++ dev_err(&dev->pdev->dev,
++ "request interrupt %d failed\n", pdev->irq);
+ retval = -EBUSY;
+ goto error;
+ }
+@@ -3071,32 +3081,34 @@ static int langwell_udc_probe(struct pci
+ dev->lpm = (readl(&dev->cap_regs->hccparams) & HCC_LEN) ? 1 : 0;
+ dev->dciversion = readw(&dev->cap_regs->dciversion);
+ dev->devcap = (readl(&dev->cap_regs->dccparams) & DEVCAP) ? 1 : 0;
+- VDBG(dev, "dev->lpm: %d\n", dev->lpm);
+- VDBG(dev, "dev->dciversion: 0x%04x\n", dev->dciversion);
+- VDBG(dev, "dccparams: 0x%08x\n", readl(&dev->cap_regs->dccparams));
+- VDBG(dev, "dev->devcap: %d\n", dev->devcap);
++ dev_vdbg(&dev->pdev->dev, "dev->lpm: %d\n", dev->lpm);
++ dev_vdbg(&dev->pdev->dev, "dev->dciversion: 0x%04x\n",
++ dev->dciversion);
++ dev_vdbg(&dev->pdev->dev, "dccparams: 0x%08x\n",
++ readl(&dev->cap_regs->dccparams));
++ dev_vdbg(&dev->pdev->dev, "dev->devcap: %d\n", dev->devcap);
+ if (!dev->devcap) {
+- ERROR(dev, "can't support device mode\n");
++ dev_err(&dev->pdev->dev, "can't support device mode\n");
+ retval = -ENODEV;
+ goto error;
+ }
+
+ /* a pair of endpoints (out/in) for each address */
+ dev->ep_max = DEN(readl(&dev->cap_regs->dccparams)) * 2;
+- VDBG(dev, "dev->ep_max: %d\n", dev->ep_max);
++ dev_vdbg(&dev->pdev->dev, "dev->ep_max: %d\n", dev->ep_max);
+
+ /* allocate endpoints memory */
+ dev->ep = kzalloc(sizeof(struct langwell_ep) * dev->ep_max,
+ GFP_KERNEL);
+ if (!dev->ep) {
+- ERROR(dev, "allocate endpoints memory failed\n");
++ dev_err(&dev->pdev->dev, "allocate endpoints memory failed\n");
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ /* allocate device dQH memory */
+ size = dev->ep_max * sizeof(struct langwell_dqh);
+- VDBG(dev, "orig size = %d\n", size);
++ dev_vdbg(&dev->pdev->dev, "orig size = %d\n", size);
+ if (size < DQH_ALIGNMENT)
+ size = DQH_ALIGNMENT;
+ else if ((size % DQH_ALIGNMENT) != 0) {
+@@ -3106,17 +3118,18 @@ static int langwell_udc_probe(struct pci
+ dev->ep_dqh = dma_alloc_coherent(&pdev->dev, size,
+ &dev->ep_dqh_dma, GFP_KERNEL);
+ if (!dev->ep_dqh) {
+- ERROR(dev, "allocate dQH memory failed\n");
++ dev_err(&dev->pdev->dev, "allocate dQH memory failed\n");
+ retval = -ENOMEM;
+ goto error;
+ }
+ dev->ep_dqh_size = size;
+- VDBG(dev, "ep_dqh_size = %d\n", dev->ep_dqh_size);
++ dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %d\n", dev->ep_dqh_size);
+
+ /* initialize ep0 status request structure */
+ dev->status_req = kzalloc(sizeof(struct langwell_request), GFP_KERNEL);
+ if (!dev->status_req) {
+- ERROR(dev, "allocate status_req memory failed\n");
++ dev_err(&dev->pdev->dev,
++ "allocate status_req memory failed\n");
+ retval = -ENOMEM;
+ goto error;
+ }
+@@ -3174,18 +3187,20 @@ static int langwell_udc_probe(struct pci
+ }
+
+ /* done */
+- INFO(dev, "%s\n", driver_desc);
+- INFO(dev, "irq %d, pci mem %p\n", pdev->irq, base);
+- INFO(dev, "Driver version: " DRIVER_VERSION "\n");
+- INFO(dev, "Support (max) %d endpoints\n", dev->ep_max);
+- INFO(dev, "Device interface version: 0x%04x\n", dev->dciversion);
+- INFO(dev, "Controller mode: %s\n", dev->devcap ? "Device" : "Host");
+- INFO(dev, "Support USB LPM: %s\n", dev->lpm ? "Yes" : "No");
++ dev_info(&dev->pdev->dev, "%s\n", driver_desc);
++ dev_info(&dev->pdev->dev, "irq %d, pci mem %p\n", pdev->irq, base);
++ dev_info(&dev->pdev->dev, "Driver version: " DRIVER_VERSION "\n");
++ dev_info(&dev->pdev->dev, "Support (max) %d endpoints\n", dev->ep_max);
++ dev_info(&dev->pdev->dev, "Device interface version: 0x%04x\n",
++ dev->dciversion);
++ dev_info(&dev->pdev->dev, "Controller mode: %s\n",
++ dev->devcap ? "Device" : "Host");
++ dev_info(&dev->pdev->dev, "Support USB LPM: %s\n",
++ dev->lpm ? "Yes" : "No");
+
+- VDBG(dev, "After langwell_udc_probe(), print all registers:\n");
+-#ifdef VERBOSE
++ dev_vdbg(&dev->pdev->dev,
++ "After langwell_udc_probe(), print all registers:\n");
+ print_all_registers(dev);
+-#endif
+
+ the_controller = dev;
+
+@@ -3197,12 +3212,12 @@ static int langwell_udc_probe(struct pci
+ if (retval)
+ goto error;
+
+- VDBG(dev, "<--- %s()\n", __func__);
++ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+
+ error:
+ if (dev) {
+- DBG(dev, "<--- %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ langwell_udc_remove(pdev);
+ }
+
+@@ -3216,7 +3231,7 @@ static int langwell_udc_suspend(struct p
+ struct langwell_udc *dev = the_controller;
+ u32 devlc;
+
+- DBG(dev, "---> %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* disable interrupt and set controller to stop state */
+ langwell_udc_stop(dev);
+@@ -3226,7 +3241,6 @@ static int langwell_udc_suspend(struct p
+ free_irq(pdev->irq, dev);
+ dev->got_irq = 0;
+
+-
+ /* save PCI state */
+ pci_save_state(pdev);
+
+@@ -3235,11 +3249,10 @@ static int langwell_udc_suspend(struct p
+
+ /* enter PHY low power suspend */
+ devlc = readl(&dev->op_regs->devlc);
+- VDBG(dev, "devlc = 0x%08x\n", devlc);
+ devlc |= LPM_PHCD;
+ writel(devlc, &dev->op_regs->devlc);
+
+- DBG(dev, "<--- %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+ }
+
+@@ -3250,11 +3263,10 @@ static int langwell_udc_resume(struct pc
+ struct langwell_udc *dev = the_controller;
+ u32 devlc;
+
+- DBG(dev, "---> %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* exit PHY low power suspend */
+ devlc = readl(&dev->op_regs->devlc);
+- VDBG(dev, "devlc = 0x%08x\n", devlc);
+ devlc &= ~LPM_PHCD;
+ writel(devlc, &dev->op_regs->devlc);
+
+@@ -3265,10 +3277,11 @@ static int langwell_udc_resume(struct pc
+ pci_restore_state(pdev);
+
+ /* enable IRQ handler */
+- if (request_irq(pdev->irq, langwell_irq, IRQF_SHARED, driver_name, dev)
+- != 0) {
+- ERROR(dev, "request interrupt %d failed\n", pdev->irq);
+- return -1;
++ if (request_irq(pdev->irq, langwell_irq, IRQF_SHARED,
++ driver_name, dev) != 0) {
++ dev_err(&dev->pdev->dev, "request interrupt %d failed\n",
++ pdev->irq);
++ return -EBUSY;
+ }
+ dev->got_irq = 1;
+
+@@ -3290,7 +3303,7 @@ static int langwell_udc_resume(struct pc
+ dev->ep0_state = WAIT_FOR_SETUP;
+ dev->ep0_dir = USB_DIR_OUT;
+
+- DBG(dev, "<--- %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+ }
+
+@@ -3301,15 +3314,15 @@ static void langwell_udc_shutdown(struct
+ struct langwell_udc *dev = the_controller;
+ u32 usbmode;
+
+- DBG(dev, "---> %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* reset controller mode to IDLE */
+ usbmode = readl(&dev->op_regs->usbmode);
+- DBG(dev, "usbmode = 0x%08x\n", usbmode);
++ dev_dbg(&dev->pdev->dev, "usbmode = 0x%08x\n", usbmode);
+ usbmode &= (~3 | MODE_IDLE);
+ writel(usbmode, &dev->op_regs->usbmode);
+
+- DBG(dev, "<--- %s()\n", __func__);
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+
+ /*-------------------------------------------------------------------------*/
+@@ -3324,7 +3337,6 @@ static const struct pci_device_id pci_id
+ }, { /* end: all zeroes */ }
+ };
+
+-
+ MODULE_DEVICE_TABLE(pci, pci_ids);
+
+
+@@ -3343,12 +3355,6 @@ static struct pci_driver langwell_pci_dr
+ };
+
+
+-MODULE_DESCRIPTION(DRIVER_DESC);
+-MODULE_AUTHOR("Xiaochen Shen <xiaochen.shen@intel.com>");
+-MODULE_VERSION(DRIVER_VERSION);
+-MODULE_LICENSE("GPL");
+-
+-
+ static int __init init(void)
+ {
+ #ifdef OTG_TRANSCEIVER
+@@ -3370,3 +3376,9 @@ static void __exit cleanup(void)
+ }
+ module_exit(cleanup);
+
++
++MODULE_DESCRIPTION(DRIVER_DESC);
++MODULE_AUTHOR("Xiaochen Shen <xiaochen.shen@intel.com>");
++MODULE_VERSION(DRIVER_VERSION);
++MODULE_LICENSE("GPL");
++
diff --git a/usb/usb-langwell-usb-client-driver-memory-handling.patch b/usb/usb-langwell-usb-client-driver-memory-handling.patch
new file mode 100644
index 00000000000000..f3deec1c90d205
--- /dev/null
+++ b/usb/usb-langwell-usb-client-driver-memory-handling.patch
@@ -0,0 +1,223 @@
+From linux-usb-owner@vger.kernel.org Wed Sep 1 11:44:09 2010
+From: JiebingLi <jiebing.li@intel.com>
+Subject: USB: langwell: USB Client driver memory handling
+To: linux-usb@vger.kernel.org
+Date: Thu, 05 Aug 2010 14:18:29 +0100
+Message-ID: <20100805131828.12473.14313.stgit@localhost.localdomain>
+
+From: JiebingLi <jiebing.li@intel.com>
+
+SRAM Memory handling for USB client function
+
+Signed-off-by: JiebingLi <jiebing.li@intel.com>
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+
+ drivers/usb/gadget/langwell_udc.c | 113 ++++++++++++++++++++++++++++++++++++--
+ drivers/usb/gadget/langwell_udc.h | 12 ++--
+ 2 files changed, 115 insertions(+), 10 deletions(-)
+
+
+--- a/drivers/usb/gadget/langwell_udc.c
++++ b/drivers/usb/gadget/langwell_udc.c
+@@ -2988,6 +2988,50 @@ static void gadget_release(struct device
+ }
+
+
++/* enable SRAM caching if SRAM detected */
++static void sram_init(struct langwell_udc *dev)
++{
++ struct pci_dev *pdev = dev->pdev;
++
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
++
++ dev->sram_addr = pci_resource_start(pdev, 1);
++ dev->sram_size = pci_resource_len(pdev, 1);
++ dev_info(&dev->pdev->dev, "Found private SRAM at %x size:%x\n",
++ dev->sram_addr, dev->sram_size);
++ dev->got_sram = 1;
++
++ if (pci_request_region(pdev, 1, kobject_name(&pdev->dev.kobj))) {
++ dev_warn(&dev->pdev->dev, "SRAM request failed\n");
++ dev->got_sram = 0;
++ } else if (!dma_declare_coherent_memory(&pdev->dev, dev->sram_addr,
++ dev->sram_addr, dev->sram_size, DMA_MEMORY_MAP)) {
++ dev_warn(&dev->pdev->dev, "SRAM DMA declare failed\n");
++ pci_release_region(pdev, 1);
++ dev->got_sram = 0;
++ }
++
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
++}
++
++
++/* release SRAM caching */
++static void sram_deinit(struct langwell_udc *dev)
++{
++ struct pci_dev *pdev = dev->pdev;
++
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
++
++ dma_release_declared_memory(&pdev->dev);
++ pci_release_region(pdev, 1);
++
++ dev->got_sram = 0;
++
++ dev_info(&dev->pdev->dev, "release SRAM caching\n");
++ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
++}
++
++
+ /* tear down the binding between this driver and the pci device */
+ static void langwell_udc_remove(struct pci_dev *pdev)
+ {
+@@ -3000,19 +3044,25 @@ static void langwell_udc_remove(struct p
+
+ dev->done = &done;
+
+- /* free memory allocated in probe */
++#ifndef OTG_TRANSCEIVER
++ /* free dTD dma_pool and dQH */
+ if (dev->dtd_pool)
+ dma_pool_destroy(dev->dtd_pool);
+
++ if (dev->ep_dqh)
++ dma_free_coherent(&pdev->dev, dev->ep_dqh_size,
++ dev->ep_dqh, dev->ep_dqh_dma);
++
++ /* release SRAM caching */
++ if (dev->has_sram && dev->got_sram)
++ sram_deinit(dev);
++#endif
++
+ if (dev->status_req) {
+ kfree(dev->status_req->req.buf);
+ kfree(dev->status_req);
+ }
+
+- if (dev->ep_dqh)
+- dma_free_coherent(&pdev->dev, dev->ep_dqh_size,
+- dev->ep_dqh, dev->ep_dqh_dma);
+-
+ kfree(dev->ep);
+
+ /* diable IRQ handler */
+@@ -3140,7 +3190,15 @@ static int langwell_udc_probe(struct pci
+ goto error;
+ }
+
++ dev->has_sram = 1;
++ dev->got_sram = 0;
++ dev_vdbg(&dev->pdev->dev, "dev->has_sram: %d\n", dev->has_sram);
++
+ #ifndef OTG_TRANSCEIVER
++ /* enable SRAM caching if detected */
++ if (dev->has_sram && !dev->got_sram)
++ sram_init(dev);
++
+ dev_info(&dev->pdev->dev,
+ "irq %d, io mem: 0x%08lx, len: 0x%08lx, pci mem 0x%p\n",
+ pdev->irq, resource, len, base);
+@@ -3335,6 +3393,18 @@ static int langwell_udc_suspend(struct p
+ /* save PCI state */
+ pci_save_state(pdev);
+
++ /* free dTD dma_pool and dQH */
++ if (dev->dtd_pool)
++ dma_pool_destroy(dev->dtd_pool);
++
++ if (dev->ep_dqh)
++ dma_free_coherent(&pdev->dev, dev->ep_dqh_size,
++ dev->ep_dqh, dev->ep_dqh_dma);
++
++ /* release SRAM caching */
++ if (dev->has_sram && dev->got_sram)
++ sram_deinit(dev);
++
+ /* set device power state */
+ pci_set_power_state(pdev, PCI_D3hot);
+
+@@ -3351,6 +3421,7 @@ static int langwell_udc_suspend(struct p
+ static int langwell_udc_resume(struct pci_dev *pdev)
+ {
+ struct langwell_udc *dev = the_controller;
++ size_t size;
+
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+@@ -3361,6 +3432,38 @@ static int langwell_udc_resume(struct pc
+ /* set device D0 power state */
+ pci_set_power_state(pdev, PCI_D0);
+
++ /* enable SRAM caching if detected */
++ if (dev->has_sram && !dev->got_sram)
++ sram_init(dev);
++
++ /* allocate device dQH memory */
++ size = dev->ep_max * sizeof(struct langwell_dqh);
++ dev_vdbg(&dev->pdev->dev, "orig size = %d\n", size);
++ if (size < DQH_ALIGNMENT)
++ size = DQH_ALIGNMENT;
++ else if ((size % DQH_ALIGNMENT) != 0) {
++ size += DQH_ALIGNMENT + 1;
++ size &= ~(DQH_ALIGNMENT - 1);
++ }
++ dev->ep_dqh = dma_alloc_coherent(&pdev->dev, size,
++ &dev->ep_dqh_dma, GFP_KERNEL);
++ if (!dev->ep_dqh) {
++ dev_err(&dev->pdev->dev, "allocate dQH memory failed\n");
++ return -ENOMEM;
++ }
++ dev->ep_dqh_size = size;
++ dev_vdbg(&dev->pdev->dev, "ep_dqh_size = %d\n", dev->ep_dqh_size);
++
++ /* create dTD dma_pool resource */
++ dev->dtd_pool = dma_pool_create("langwell_dtd",
++ &dev->pdev->dev,
++ sizeof(struct langwell_dtd),
++ DTD_ALIGNMENT,
++ DMA_BOUNDARY);
++
++ if (!dev->dtd_pool)
++ return -ENOMEM;
++
+ /* restore PCI state */
+ pci_restore_state(pdev);
+
+--- a/drivers/usb/gadget/langwell_udc.h
++++ b/drivers/usb/gadget/langwell_udc.h
+@@ -18,11 +18,7 @@
+ */
+
+ #include <linux/usb/langwell_udc.h>
+-
+-#if defined(CONFIG_USB_LANGWELL_OTG)
+ #include <linux/usb/langwell_otg.h>
+-#endif
+-
+
+ /*-------------------------------------------------------------------------*/
+
+@@ -199,7 +195,9 @@ struct langwell_udc {
+ vbus_active:1,
+ suspended:1,
+ stopped:1,
+- lpm:1; /* LPM capability */
++ lpm:1, /* LPM capability */
++ has_sram:1, /* SRAM caching */
++ got_sram:1;
+
+ /* pci state used to access those endpoints */
+ struct pci_dev *pdev;
+@@ -225,6 +223,10 @@ struct langwell_udc {
+ /* make sure release() is done */
+ struct completion *done;
+
++ /* for private SRAM caching */
++ unsigned int sram_addr;
++ unsigned int sram_size;
++
+ /* device status data for get_status request */
+ u16 dev_status;
+ };
diff --git a/usb/usb-langwell-usb-client-endpoint-initialization.patch b/usb/usb-langwell-usb-client-endpoint-initialization.patch
new file mode 100644
index 00000000000000..0bfea9f422d4ce
--- /dev/null
+++ b/usb/usb-langwell-usb-client-endpoint-initialization.patch
@@ -0,0 +1,84 @@
+From linux-usb-owner@vger.kernel.org Wed Sep 1 11:41:36 2010
+From: JiebingLi <jiebing.li@intel.com>
+Subject: USB: langwell: USB Client Endpoint initialization
+To: linux-usb@vger.kernel.org
+Date: Thu, 05 Aug 2010 14:18:05 +0100
+Message-ID: <20100805131802.12473.31336.stgit@localhost.localdomain>
+
+From: JiebingLi <jiebing.li@intel.com>
+
+Endpoint software structure initialization
+
+Signed-off-by: JiebingLi <jiebing.li@intel.com>
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+
+ drivers/usb/gadget/langwell_udc.c | 23 +++++++++++++----------
+ 1 file changed, 13 insertions(+), 10 deletions(-)
+
+
+--- a/drivers/usb/gadget/langwell_udc.c
++++ b/drivers/usb/gadget/langwell_udc.c
+@@ -242,11 +242,13 @@ static void ep0_reset(struct langwell_ud
+ ep->dqh->dqh_ios = 1;
+ ep->dqh->dqh_mpl = EP0_MAX_PKT_SIZE;
+
+- /* FIXME: enable ep0-in HW zero length termination select */
++ /* enable ep0-in HW zero length termination select */
+ if (is_in(ep))
+ ep->dqh->dqh_zlt = 0;
+ ep->dqh->dqh_mult = 0;
+
++ ep->dqh->dtd_next = DTD_TERM;
++
+ /* configure ep0 control registers */
+ ep_reset(&dev->ep[0], 0, i, USB_ENDPOINT_XFER_CONTROL);
+ }
+@@ -268,7 +270,7 @@ static int langwell_ep_enable(struct usb
+ struct langwell_ep *ep;
+ u16 max = 0;
+ unsigned long flags;
+- int retval = 0;
++ int i, retval = 0;
+ unsigned char zlt, ios = 0, mult = 0;
+
+ ep = container_of(_ep, struct langwell_ep, ep);
+@@ -354,12 +356,6 @@ static int langwell_ep_enable(struct usb
+
+ spin_lock_irqsave(&dev->lock, flags);
+
+- /* configure endpoint capabilities in dQH */
+- ep->dqh->dqh_ios = ios;
+- ep->dqh->dqh_mpl = cpu_to_le16(max);
+- ep->dqh->dqh_zlt = zlt;
+- ep->dqh->dqh_mult = mult;
+-
+ ep->ep.maxpacket = max;
+ ep->desc = desc;
+ ep->stopped = 0;
+@@ -371,6 +367,15 @@ static int langwell_ep_enable(struct usb
+ /* configure endpoint control registers */
+ ep_reset(ep, ep->ep_num, is_in(ep), ep->ep_type);
+
++ /* configure endpoint capabilities in dQH */
++ i = ep->ep_num * 2 + is_in(ep);
++ ep->dqh = &dev->ep_dqh[i];
++ ep->dqh->dqh_ios = ios;
++ ep->dqh->dqh_mpl = cpu_to_le16(max);
++ ep->dqh->dqh_zlt = zlt;
++ ep->dqh->dqh_mult = mult;
++ ep->dqh->dtd_next = DTD_TERM;
++
+ dev_dbg(&dev->pdev->dev, "enabled %s (ep%d%s-%s), max %04x\n",
+ _ep->name,
+ ep->ep_num,
+@@ -1430,8 +1435,6 @@ static int eps_reinit(struct langwell_ud
+
+ INIT_LIST_HEAD(&ep->queue);
+ list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list);
+-
+- ep->dqh = &dev->ep_dqh[i];
+ }
+
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
diff --git a/usb/usb-langwell-usb-client-phy-low-power-mode-setting.patch b/usb/usb-langwell-usb-client-phy-low-power-mode-setting.patch
new file mode 100644
index 00000000000000..b186e55fdba77d
--- /dev/null
+++ b/usb/usb-langwell-usb-client-phy-low-power-mode-setting.patch
@@ -0,0 +1,209 @@
+From linux-usb-owner@vger.kernel.org Wed Sep 1 11:41:55 2010
+From: JiebingLi <jiebing.li@intel.com>
+Subject: USB: langwell: USB Client PHY low power mode setting
+To: linux-usb@vger.kernel.org
+Date: Thu, 05 Aug 2010 14:18:13 +0100
+Message-ID: <20100805131811.12473.42609.stgit@localhost.localdomain>
+
+From: JiebingLi <jiebing.li@intel.com>
+
+PHY low power mode setting with a static function
+
+Signed-off-by: JiebingLi <jiebing.li@intel.com>
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+
+ drivers/usb/gadget/langwell_udc.c | 92 ++++++++++++++++++++++++--------------
+ 1 file changed, 60 insertions(+), 32 deletions(-)
+
+
+--- a/drivers/usb/gadget/langwell_udc.c
++++ b/drivers/usb/gadget/langwell_udc.c
+@@ -1159,11 +1159,37 @@ static int langwell_get_frame(struct usb
+ }
+
+
++/* enter or exit PHY low power state */
++static void langwell_phy_low_power(struct langwell_udc *dev, bool flag)
++{
++ u32 devlc;
++ u8 devlc_byte2;
++ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
++
++ devlc = readl(&dev->op_regs->devlc);
++ dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc);
++
++ if (flag)
++ devlc |= LPM_PHCD;
++ else
++ devlc &= ~LPM_PHCD;
++
++ /* FIXME: workaround for Langwell A1/A2/A3 sighting */
++ devlc_byte2 = (devlc >> 16) & 0xff;
++ writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
++
++ devlc = readl(&dev->op_regs->devlc);
++ dev_vdbg(&dev->pdev->dev,
++ "%s PHY low power suspend, devlc = 0x%08x\n",
++ flag ? "enter" : "exit", devlc);
++}
++
++
+ /* tries to wake up the host connected to this gadget */
+ static int langwell_wakeup(struct usb_gadget *_gadget)
+ {
+ struct langwell_udc *dev;
+- u32 portsc1, devlc;
++ u32 portsc1;
+ unsigned long flags;
+
+ if (!_gadget)
+@@ -1186,22 +1212,19 @@ static int langwell_wakeup(struct usb_ga
+ return 0;
+ }
+
+- /* LPM L1 to L0, remote wakeup */
+- if (dev->lpm && dev->lpm_state == LPM_L1) {
+- portsc1 |= PORTS_SLP;
+- writel(portsc1, &dev->op_regs->portsc1);
+- }
+-
+- /* force port resume */
+- if (dev->usb_state == USB_STATE_SUSPENDED) {
+- portsc1 |= PORTS_FPR;
+- writel(portsc1, &dev->op_regs->portsc1);
+- }
++ /* LPM L1 to L0 or legacy remote wakeup */
++ if (dev->lpm && dev->lpm_state == LPM_L1)
++ dev_info(&dev->pdev->dev, "LPM L1 to L0 remote wakeup\n");
++ else
++ dev_info(&dev->pdev->dev, "device remote wakeup\n");
+
+ /* exit PHY low power suspend */
+- devlc = readl(&dev->op_regs->devlc);
+- devlc &= ~LPM_PHCD;
+- writel(devlc, &dev->op_regs->devlc);
++ if (dev->pdev->device != 0x0829)
++ langwell_phy_low_power(dev, 0);
++
++ /* force port resume */
++ portsc1 |= PORTS_FPR;
++ writel(portsc1, &dev->op_regs->portsc1);
+
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+@@ -1331,6 +1354,7 @@ static const struct usb_gadget_ops langw
+ static int langwell_udc_reset(struct langwell_udc *dev)
+ {
+ u32 usbcmd, usbmode, devlc, endpointlistaddr;
++ u8 devlc_byte0, devlc_byte2;
+ unsigned long timeout;
+
+ if (!dev)
+@@ -1375,9 +1399,17 @@ static int langwell_udc_reset(struct lan
+ /* if support USB LPM, ACK all LPM token */
+ if (dev->lpm) {
+ devlc = readl(&dev->op_regs->devlc);
++ dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc);
++ /* FIXME: workaround for Langwell A1/A2/A3 sighting */
+ devlc &= ~LPM_STL; /* don't STALL LPM token */
+ devlc &= ~LPM_NYT_ACK; /* ACK LPM token */
+- writel(devlc, &dev->op_regs->devlc);
++ devlc_byte0 = devlc & 0xff;
++ devlc_byte2 = (devlc >> 16) & 0xff;
++ writeb(devlc_byte0, (u8 *)&dev->op_regs->devlc);
++ writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
++ devlc = readl(&dev->op_regs->devlc);
++ dev_vdbg(&dev->pdev->dev,
++ "ACK LPM token, devlc = 0x%08x\n", devlc);
+ }
+
+ /* fill endpointlistaddr register */
+@@ -1871,6 +1903,10 @@ int usb_gadget_unregister_driver(struct
+ if (unlikely(!driver || !driver->bind || !driver->unbind))
+ return -EINVAL;
+
++ /* exit PHY low power suspend */
++ if (dev->pdev->device != 0x0829)
++ langwell_phy_low_power(dev, 0);
++
+ /* unbind OTG transceiver */
+ if (dev->transceiver)
+ (void)otg_set_peripheral(dev->transceiver, 0);
+@@ -2706,7 +2742,6 @@ static void handle_usb_reset(struct lang
+ /* USB bus suspend/resume interrupt */
+ static void handle_bus_suspend(struct langwell_udc *dev)
+ {
+- u32 devlc;
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ dev->resume_state = dev->usb_state;
+@@ -2747,9 +2782,8 @@ static void handle_bus_suspend(struct la
+ }
+
+ /* enter PHY low power suspend */
+- devlc = readl(&dev->op_regs->devlc);
+- devlc |= LPM_PHCD;
+- writel(devlc, &dev->op_regs->devlc);
++ if (dev->pdev->device != 0x0829)
++ langwell_phy_low_power(dev, 0);
+
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ }
+@@ -2757,16 +2791,14 @@ static void handle_bus_suspend(struct la
+
+ static void handle_bus_resume(struct langwell_udc *dev)
+ {
+- u32 devlc;
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ dev->usb_state = dev->resume_state;
+ dev->resume_state = 0;
+
+ /* exit PHY low power suspend */
+- devlc = readl(&dev->op_regs->devlc);
+- devlc &= ~LPM_PHCD;
+- writel(devlc, &dev->op_regs->devlc);
++ if (dev->pdev->device != 0x0829)
++ langwell_phy_low_power(dev, 0);
+
+ #ifdef OTG_TRANSCEIVER
+ if (dev->lotg->otg.default_a == 0)
+@@ -3232,7 +3264,6 @@ error:
+ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
+ {
+ struct langwell_udc *dev = the_controller;
+- u32 devlc;
+
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+@@ -3251,9 +3282,8 @@ static int langwell_udc_suspend(struct p
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ /* enter PHY low power suspend */
+- devlc = readl(&dev->op_regs->devlc);
+- devlc |= LPM_PHCD;
+- writel(devlc, &dev->op_regs->devlc);
++ if (dev->pdev->device != 0x0829)
++ langwell_phy_low_power(dev, 1);
+
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+@@ -3264,14 +3294,12 @@ static int langwell_udc_suspend(struct p
+ static int langwell_udc_resume(struct pci_dev *pdev)
+ {
+ struct langwell_udc *dev = the_controller;
+- u32 devlc;
+
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ /* exit PHY low power suspend */
+- devlc = readl(&dev->op_regs->devlc);
+- devlc &= ~LPM_PHCD;
+- writel(devlc, &dev->op_regs->devlc);
++ if (dev->pdev->device != 0x0829)
++ langwell_phy_low_power(dev, 0);
+
+ /* set device D0 power state */
+ pci_set_power_state(pdev, PCI_D0);
diff --git a/usb/usb-langwell-usb-client-remote-wakeup-support.patch b/usb/usb-langwell-usb-client-remote-wakeup-support.patch
new file mode 100644
index 00000000000000..ab7037c06f0cf2
--- /dev/null
+++ b/usb/usb-langwell-usb-client-remote-wakeup-support.patch
@@ -0,0 +1,160 @@
+From linux-usb-owner@vger.kernel.org Wed Sep 1 11:42:33 2010
+From: JiebingLi <jiebing.li@intel.com>
+Subject: USB: langwell: USB Client Remote Wakeup Support
+To: linux-usb@vger.kernel.org
+Date: Thu, 05 Aug 2010 14:18:21 +0100
+Message-ID: <20100805131819.12473.6939.stgit@localhost.localdomain>
+
+From: JiebingLi <jiebing.li@intel.com>
+
+Remote wakeup support in client driver. Made non-debug only this time.
+
+Signed-off-by: JiebingLi <jiebing.li@intel.com>
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+
+ drivers/usb/gadget/langwell_udc.c | 67 +++++++++++++++++++++++++++++++++++---
+ drivers/usb/gadget/langwell_udc.h | 3 +
+ 2 files changed, 65 insertions(+), 5 deletions(-)
+
+
+--- a/drivers/usb/gadget/langwell_udc.c
++++ b/drivers/usb/gadget/langwell_udc.c
+@@ -1815,6 +1815,36 @@ static ssize_t show_langwell_udc(struct
+ static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL);
+
+
++/* device "remote_wakeup" sysfs attribute file */
++static ssize_t store_remote_wakeup(struct device *_dev,
++ struct device_attribute *attr, const char *buf, size_t count)
++{
++ struct langwell_udc *dev = the_controller;
++ unsigned long flags;
++ ssize_t rc = count;
++
++ if (count > 2)
++ return -EINVAL;
++
++ if (count > 0 && buf[count-1] == '\n')
++ ((char *) buf)[count-1] = 0;
++
++ if (buf[0] != '1')
++ return -EINVAL;
++
++ /* force remote wakeup enabled in case gadget driver doesn't support */
++ spin_lock_irqsave(&dev->lock, flags);
++ dev->remote_wakeup = 1;
++ dev->dev_status |= (1 << USB_DEVICE_REMOTE_WAKEUP);
++ spin_unlock_irqrestore(&dev->lock, flags);
++
++ langwell_wakeup(&dev->gadget);
++
++ return rc;
++}
++static DEVICE_ATTR(remote_wakeup, S_IWUSR, NULL, store_remote_wakeup);
++
++
+ /*-------------------------------------------------------------------------*/
+
+ /*
+@@ -2136,8 +2166,7 @@ static void get_status(struct langwell_u
+
+ if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
+ /* get device status */
+- status_data = 1 << USB_DEVICE_SELF_POWERED;
+- status_data |= dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP;
++ status_data = dev->dev_status;
+ } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) {
+ /* get interface status */
+ status_data = 0;
+@@ -2275,6 +2304,22 @@ static void handle_setup_packet(struct l
+ } else if ((setup->bRequestType & (USB_RECIP_MASK
+ | USB_TYPE_MASK)) == (USB_RECIP_DEVICE
+ | USB_TYPE_STANDARD)) {
++ rc = 0;
++ switch (wValue) {
++ case USB_DEVICE_REMOTE_WAKEUP:
++ if (setup->bRequest == USB_REQ_SET_FEATURE) {
++ dev->remote_wakeup = 1;
++ dev->dev_status |= (1 << wValue);
++ } else {
++ dev->remote_wakeup = 0;
++ dev->dev_status &= ~(1 << wValue);
++ }
++ break;
++ default:
++ rc = -EOPNOTSUPP;
++ break;
++ }
++
+ if (!gadget_is_otg(&dev->gadget))
+ break;
+ else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) {
+@@ -2290,7 +2335,6 @@ static void handle_setup_packet(struct l
+ dev->gadget.a_alt_hnp_support = 1;
+ else
+ break;
+- rc = 0;
+ } else
+ break;
+
+@@ -2678,7 +2722,10 @@ static void handle_usb_reset(struct lang
+
+ dev->ep0_dir = USB_DIR_OUT;
+ dev->ep0_state = WAIT_FOR_SETUP;
+- dev->remote_wakeup = 0; /* default to 0 on reset */
++
++ /* remote wakeup reset to 0 when the device is reset */
++ dev->remote_wakeup = 0;
++ dev->dev_status = 1 << USB_DEVICE_SELF_POWERED;
+ dev->gadget.b_hnp_enable = 0;
+ dev->gadget.a_hnp_support = 0;
+ dev->gadget.a_alt_hnp_support = 0;
+@@ -2997,6 +3044,7 @@ static void langwell_udc_remove(struct p
+
+ device_unregister(&dev->gadget.dev);
+ device_remove_file(&pdev->dev, &dev_attr_langwell_udc);
++ device_remove_file(&pdev->dev, &dev_attr_remote_wakeup);
+
+ #ifndef OTG_TRANSCEIVER
+ pci_set_drvdata(pdev, NULL);
+@@ -3177,7 +3225,10 @@ static int langwell_udc_probe(struct pci
+ dev->resume_state = USB_STATE_NOTATTACHED;
+ dev->usb_state = USB_STATE_POWERED;
+ dev->ep0_dir = USB_DIR_OUT;
+- dev->remote_wakeup = 0; /* default to 0 on reset */
++
++ /* remote wakeup reset to 0 when the device is reset */
++ dev->remote_wakeup = 0;
++ dev->dev_status = 1 << USB_DEVICE_SELF_POWERED;
+
+ #ifndef OTG_TRANSCEIVER
+ /* reset device controller */
+@@ -3247,9 +3298,15 @@ static int langwell_udc_probe(struct pci
+ if (retval)
+ goto error;
+
++ retval = device_create_file(&pdev->dev, &dev_attr_remote_wakeup);
++ if (retval)
++ goto error_attr1;
++
+ dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+
++error_attr1:
++ device_remove_file(&pdev->dev, &dev_attr_langwell_udc);
+ error:
+ if (dev) {
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+--- a/drivers/usb/gadget/langwell_udc.h
++++ b/drivers/usb/gadget/langwell_udc.h
+@@ -224,5 +224,8 @@ struct langwell_udc {
+
+ /* make sure release() is done */
+ struct completion *done;
++
++ /* device status data for get_status request */
++ u16 dev_status;
+ };
+