LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v1]460EX on-chip SATA driver<resubmisison>
From: Wolfgang Denk @ 2010-06-30 11:58 UTC (permalink / raw)
  To: Rupjyoti Sarmah
  Cc: linux-ide, rsarmah, linux-kernel, linuxppc-dev, sr, jgarzik
In-Reply-To: <201006241327.o5ODRY6m032299@amcc.com>

Dear Rupjyoti Sarmah,

In message <201006241327.o5ODRY6m032299@amcc.com> you wrote:
> This patch enables the on-chip DWC SATA controller of the AppliedMicro processor 460EX.
> 
> Signed-off-by: Rupjyoti Sarmah <rsarmah@appliedmicro.com> 
> Signed-off-by: Mark Miesfeld <mmiesfeld@appliedmicro.com>
> Signed-off-by: Prodyut Hazarika <phazarika@appliedmicro.com>
> 
> ---
> This patch incorporates the changes advised in the mailing list. The device
> tree changes were submitted as a seperate patch. 

Which kernel is this patch supposed to be applied to?

Using current mainline (v2.6.35-rc3-262-g984bc96) the patch applies
without problems, but when I enable it in the kernel configuration I
get this:

drivers/ata/sata_dwc_460ex.c:43:1: warning: "DRV_NAME" redefined
In file included from drivers/ata/sata_dwc_460ex.c:38:
drivers/ata/libata.h:31:1: warning: this is the location of the previous definition
drivers/ata/sata_dwc_460ex.c:44:1: warning: "DRV_VERSION" redefined
drivers/ata/libata.h:32:1: warning: this is the location of the previous definition
drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_scr_read':
drivers/ata/sata_dwc_460ex.c:777: error: 'struct ata_port' has no member named 'ioaddr'
drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_scr_write':
drivers/ata/sata_dwc_460ex.c:793: error: 'struct ata_port' has no member named 'ioaddr'
drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_error_intr':
drivers/ata/sata_dwc_460ex.c:844: error: 'struct ata_port_operations' has no member named 'sff_check_status'
drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_isr':
drivers/ata/sata_dwc_460ex.c:953: error: 'struct ata_port_operations' has no member named 'sff_check_status'
drivers/ata/sata_dwc_460ex.c:957: error: 'struct ata_port_operations' has no member named 'sff_check_status'
drivers/ata/sata_dwc_460ex.c:991: error: implicit declaration of function 'ata_sff_hsm_move'
drivers/ata/sata_dwc_460ex.c:1030: error: 'struct ata_port_operations' has no member named 'sff_check_status'
drivers/ata/sata_dwc_460ex.c: At top level:
drivers/ata/sata_dwc_460ex.c:1213: warning: 'struct ata_ioports' declared inside parameter list
drivers/ata/sata_dwc_460ex.c:1213: warning: its scope is only this definition or declaration, which is probably not what you want
drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_setup_port':
drivers/ata/sata_dwc_460ex.c:1215: error: dereferencing pointer to incomplete type
drivers/ata/sata_dwc_460ex.c:1216: error: dereferencing pointer to incomplete type
drivers/ata/sata_dwc_460ex.c:1218: error: dereferencing pointer to incomplete type
drivers/ata/sata_dwc_460ex.c:1219: error: dereferencing pointer to incomplete type
drivers/ata/sata_dwc_460ex.c:1221: error: dereferencing pointer to incomplete type
drivers/ata/sata_dwc_460ex.c:1223: error: dereferencing pointer to incomplete type
drivers/ata/sata_dwc_460ex.c:1224: error: dereferencing pointer to incomplete type
drivers/ata/sata_dwc_460ex.c:1225: error: dereferencing pointer to incomplete type
drivers/ata/sata_dwc_460ex.c:1227: error: dereferencing pointer to incomplete type
drivers/ata/sata_dwc_460ex.c:1228: error: dereferencing pointer to incomplete type
drivers/ata/sata_dwc_460ex.c:1229: error: dereferencing pointer to incomplete type
drivers/ata/sata_dwc_460ex.c:1231: error: dereferencing pointer to incomplete type
drivers/ata/sata_dwc_460ex.c:1232: error: dereferencing pointer to incomplete type
drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_port_start':
drivers/ata/sata_dwc_460ex.c:1273: error: 'struct ata_port' has no member named 'bmdma_prd'
drivers/ata/sata_dwc_460ex.c:1274: error: 'struct ata_port' has no member named 'bmdma_prd_dma'
drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_exec_command_by_tag':
drivers/ata/sata_dwc_460ex.c:1356: warning: passing argument 1 of 'ata_get_cmd_descript' makes integer from pointer without a cast
drivers/ata/sata_dwc_460ex.c:1369: error: implicit declaration of function 'ata_sff_exec_command'
drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_qc_issue':
drivers/ata/sata_dwc_460ex.c:1512: error: 'struct ata_port_operations' has no member named 'sff_tf_load'
drivers/ata/sata_dwc_460ex.c:1516: error: implicit declaration of function 'ata_sff_qc_issue'
drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_error_handler':
drivers/ata/sata_dwc_460ex.c:1545: error: implicit declaration of function 'ata_sff_error_handler'
drivers/ata/sata_dwc_460ex.c: At top level:
drivers/ata/sata_dwc_460ex.c:1564: error: 'ata_sff_port_ops' undeclared here (not in a function)
drivers/ata/sata_dwc_460ex.c:1577: error: unknown field 'bmdma_setup' specified in initializer
drivers/ata/sata_dwc_460ex.c:1577: warning: initialization from incompatible pointer type
drivers/ata/sata_dwc_460ex.c:1578: error: unknown field 'bmdma_start' specified in initializer
drivers/ata/sata_dwc_460ex.c:1578: warning: initialization from incompatible pointer type
drivers/ata/sata_dwc_460ex.c: In function 'sata_dwc_probe':
drivers/ata/sata_dwc_460ex.c:1638: error: 'struct ata_port' has no member named 'ioaddr'
drivers/ata/sata_dwc_460ex.c:1639: error: 'struct ata_port' has no member named 'ioaddr'
drivers/ata/sata_dwc_460ex.c:1641: error: 'struct ata_port' has no member named 'ioaddr'
make[2]: *** [drivers/ata/sata_dwc_460ex.o] Error 1
make[1]: *** [drivers/ata] Error 2
make: *** [drivers] Error 2


Does this require any specific kernel version?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
A direct quote from the Boss: "We passed over a lot of good people to
get the ones we hired."

^ permalink raw reply

* Oops while running fs_racer test on a POWER6 box against latest git
From: divya @ 2010-06-30 11:22 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Latchesar Ionkov, Ron Minnich, LKML

[-- Attachment #1: Type: text/plain, Size: 3860 bytes --]

While running fs_racer test from LTP on a POWER6 box against latest git(2.6.35-rc3-git4 - commitid 984bc9601f64fd)
came across the following warning followed by multiple oops.

------------[ cut here ]------------

Badness at kernel/mutex-debug.c:64
NIP: c0000000000be9e8 LR: c0000000000be9cc CTR: 0000000000000000
REGS: c00000010be8f6f0 TRAP: 0700   Not tainted  (2.6.35-rc3-git4-autotest)
MSR: 8000000000029032<EE,ME,CE,IR,DR>    CR: 24224422  XER: 00000012
TASK = c00000010727cf00[8211] 'fs_racer_file_c' THREAD: c00000010be8bb50 CPU: 2
GPR00: 0000000000000000 c00000010be8f970 c000000000d3d798 0000000000000001
GPR04: c00000010be8fa70 c00000010be8c000 c00000010727d9f8 0000000000000000
GPR08: c0000000043042f0 c0000000016534e8 000000000000017a c000000000c29a1c
GPR12: 0000000028228424 c00000000f600500 c00000010be8fc40 0000000020000000
GPR16: fffffffffffff000 c000000109c73000 c00000010be8fc30 0000000000010442
GPR20: 0000000000000000 0000000000000000 00000000000001b6 c00000010dd12250
GPR24: c00000000017c08c c00000010727cf00 c00000010dd12278 c00000010dd12210
GPR28: 0000000000000001 c00000010be8c000 c000000000ca2008 c00000010be8fa70
NIP [c0000000000be9e8] .mutex_remove_waiter+0xa4/0x130
LR [c0000000000be9cc] .mutex_remove_waiter+0x88/0x130
Call Trace:
[c00000010be8f970] [c00000010be8fa00] 0xc00000010be8fa00 (unreliable)
[c00000010be8fa00] [c00000000064a9f0] .mutex_lock_nested+0x384/0x430
Instruction dump:
e81f0010 e93d0000 7fa04800 41fe0028 482e96e5 60000000 2fa30000 419e0018
e93e8008 80090000 2f800000 409e0008<0fe00000>   e93e8000 80090000 2f800000
Unable to handle kernel paging request for unknown fault
Faulting instruction address: 0xc00000000008d0f4
Oops: Kernel access of bad area, sig: 7 [#1]
SMP NR_CPUS=1024 NUMA
Unrecoverable FP Unavailable Exception 800 at c000000000648ed4
pSeries
last sysfs file: /sys/devices/system/cpu/cpu19/cache/index1/shared_cpu_map
Modules linked in: ipv6 fuse loop dm_mod sr_mod cdrom ibmveth sg
sd_mod crc_t10dif ibmvscsic scsi_transport_srp scsi_tgt scsi_mod
NIP: c00000000008d0f4 LR: c00000000008d0d0 CTR: 0000000000000000
REGS: c00000010978f900 TRAP: 0600   Tainted: G        W    (2.6.35-rc3-git4-autotest)
MSR: 8000000000009032
Unrecoverable FP Unavailable Exception 800 at c000000000648ed4
Unrecoverable FP Unavailable Exception 800 at c000000000648ed4
Unrecoverable FP Unavailable Exception 800 at c000000000648ed4
Unrecoverable FP Unavailable Exception 800 at c000000000648ed4
Unrecoverable FP Unavailable Exception 800 at c000000000648ed4
EE,ME,IR,DR>    CR: 24022442  XER: 00000012
DAR: c000000000648f54, DSISR: 0000000040010000
TASK = c0000001096e4900[7353] 'fs_racer_file_s' THREAD: c00000010978c000 CPU: 10
GPR00: 0000000000004000 c00000010978fb80 c000000000d3d798 0000000000000001
GPR04: c00000000083539e c000000001610228 0000000000000000 c0000000054c6880
GPR08: 00000000000006a5 c000000000648f54 0000000000000007 00000000049b0000
GPR12: 0000000000000000 c00000000f601900 00000000ffffffff ffffffffffffffff
GPR16: 000000004b7dc520 0000000000000000 0000000000000000 c00000010978fea0
GPR20: 00000fffcca7e7a0 00000fffcca7e7a0 00000fffabf7dfd0 00000fffabf7dfd0
GPR24: 0000000000000000 0000000001200011 c000000000e1c0a8 c000000000648ed4
GPR28: 0000000000000000 c0000001096e4900 c000000000ca0458 c00000010725d400
NIP [c00000000008d0f4] .copy_process+0x310/0xf40
LR [c00000000008d0d0] .copy_process+0x2ec/0xf40
Call Trace:
[c00000010978fb80] [c00000000008d0d0] .copy_process+0x2ec/0xf40 (unreliable)
[c00000010978fc80] [c00000000008deb4] .do_fork+0x190/0x3cc
[c00000010978fdc0] [c000000000011ef4] .sys_clone+0x58/0x70
[c00000010978fe30] [c0000000000087f0] .ppc_clone+0x8/0xc
Instruction dump:
419e0010 7fe3fb78 480774cd 60000000 801f0014 e93f0008 7800b842 39290080
78004800 60000042 901f0014 38004000<7d6048a8>   7d6b0078 7d6049ad 40c2fff4

Kernel version 2.6.34-rc3-git3 works fine.

Thanks
Divya



[-- Attachment #2: 2.6.34-rc3-git4.log --]
[-- Type: text/x-log, Size: 43662 bytes --]

Using 007dfade bytes for initrd buffer
Please wait, loading kernel...
Allocated 01800000 bytes for kernel @ 01e00000
   Elf64 kernel loaded...
Loading ramdisk...
ramdisk loaded 007dfade @ 03600000
OF stdout device is: /vdevice/vty@30000000
Preparing to boot Linux version 2.6.35-rc3-git4-autotest (root@p55alp2) (gcc version 4.3.2 [gcc-4_3-branch revision 141291] (SUSE Linux) ) #1 SMP Wed Jun 30 08:47:11 IST 2010
Max number of cores passed to firmware: 0x0000000000000200
Calling ibm,client-architecture-support... not implemented
command line: root=/dev/sda5 IDENT=1277868480
memory layout at init:
  memory_limit : 0000000000000000 (16 MB aligned)
  alloc_bottom : 0000000003de0000
  alloc_top    : 0000000010000000
  alloc_top_hi : 00000001f0000000
  rmo_top      : 0000000010000000
  ram_top      : 00000001f0000000
instantiating rtas at 0x000000000f6a0000... done
boot cpu hw idx 0000000000000000
starting cpu hw idx 0000000000000002... done
starting cpu hw idx 0000000000000004... done
starting cpu hw idx 0000000000000006... done
starting cpu hw idx 0000000000000008... done
starting cpu hw idx 000000000000000a... done
starting cpu hw idx 000000000000000c... done
starting cpu hw idx 000000000000000e... done
starting cpu hw idx 0000000000000010... done
starting cpu hw idx 0000000000000012... done
copying OF device tree...
Building dt strings...
Building dt structure...
Device tree strings 0x0000000003df0000 ->  0x0000000003df1135
Device tree struct  0x0000000003e00000 ->  0x0000000003e10000
Calling quiesce...
returning from prom_init
Phyp-dump not supported on this hardware
Using pSeries machine description
Using 1TB segments
Found initrd at 0xc000000003600000:0xc000000003ddfade
bootconsole [udbg0] enabled
Partition configured for 20 cpus.
CPU maps initialized for 2 threads per core
Starting Linux PPC64 #1 SMP Wed Jun 30 08:47:11 IST 2010
-----------------------------------------------------
ppc64_pft_size                = 0x1b
physicalMemorySize            = 0x1f0000000
htab_hash_mask                = 0xfffff
-----------------------------------------------------
Initializing cgroup subsys cpuset
Initializing cgroup subsys cpu
Linux version 2.6.35-rc3-git4-autotest (root@p55alp2) (gcc version 4.3.2 [gcc-4_3-branch revision 141291] (SUSE Linux) ) #1 SMP Wed Jun 30 08:47:11 IST 2010
[boot]0012 Setup Arch
EEH: No capable adapters found
PPC64 nvram contains 7168 bytes
Zone PFN ranges:
  DMA      0x00000000 ->  0x0001f000
  Normal   empty
Movable zone start PFN for each node
early_node_map[2] active PFN ranges
    0: 0x00000000 ->  0x00011000
    1: 0x00011000 ->  0x0001f000
[boot]0015 Setup Done
PERCPU: Embedded 29 pages/cpu @c000000003f00000 s1861120 r0 d39424 u2097152
pcpu-alloc: s1861120 r0 d39424 u2097152 alloc=2*1048576
pcpu-alloc: [0] 00 [0] 01 [0] 02 [0] 03 [0] 04 [0] 05 [0] 06 [0] 07
pcpu-alloc: [0] 08 [0] 09 [0] 10 [0] 11 [0] 12 [0] 13 [0] 14 [0] 15
pcpu-alloc: [0] 16 [0] 17 [0] 18 [0] 19
Built 2 zonelists in Node order, mobility grouping on.  Total pages: 126867
Policy zone: DMA
Kernel command line: root=/dev/sda5 IDENT=1277868480
PID hash table entries: 4096 (order: -1, 32768 bytes)
freeing bootmem node 0
freeing bootmem node 1
Memory: 8014272k/8126464k available (11392k kernel code, 112192k reserved, 2752k data, 8893k bss, 2304k init)
SLUB: Genslabs=18, HWalign=128, Order=0-3, MinObjects=0, CPUs=20, Nodes=256
Hierarchical RCU implementation.
        RCU torture testing starts during boot.
        Verbose stalled-CPUs detection is disabled.
NR_IRQS:512 nr_irqs:512
[boot]0020 XICS Init
[boot]0021 XICS Done
clocksource: timebase mult[155e24d] shift[22] registered
Console: colour dummy device 80x25
console [hvc0] enabled, bootconsole disabled
console [hvc0] enabled, bootconsole disabled
Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar
... MAX_LOCKDEP_SUBCLASSES:  8
... MAX_LOCK_DEPTH:          48
... MAX_LOCKDEP_KEYS:        8191
... CLASSHASH_SIZE:          4096
... MAX_LOCKDEP_ENTRIES:     16384
... MAX_LOCKDEP_CHAINS:      32768
... CHAINHASH_SIZE:          16384
 memory used by lock dependency info: 6335 kB
 per task-struct memory footprint: 2688 bytes
allocated 5079040 bytes of page_cgroup
please try 'cgroup_disable=memory' option if you don't want memory cgroups
pid_max: default: 32768 minimum: 301
Security Framework initialized
SELinux:  Disabled at boot.
Dentry cache hash table entries: 1048576 (order: 7, 8388608 bytes)
Inode-cache hash table entries: 524288 (order: 6, 4194304 bytes)
Mount-cache hash table entries: 4096
Initializing cgroup subsys ns
Initializing cgroup subsys cpuacct
Initializing cgroup subsys memory
Initializing cgroup subsys devices
Initializing cgroup subsys freezer
Initializing cgroup subsys blkio
Processor 1 found.
Processor 2 found.
Processor 3 found.
Processor 4 found.
Processor 5 found.
Processor 6 found.
Processor 7 found.
Processor 8 found.
Processor 9 found.
Processor 10 found.
Processor 11 found.
Processor 12 found.
Processor 13 found.
Processor 14 found.
Processor 15 found.
Processor 16 found.
Processor 17 found.
Processor 18 found.
Processor 19 found.
Brought up 20 CPUs
NET: Registered protocol family 16
IBM eBus Device Driver
POWER5+/++ performance monitor hardware support registered
PCI: Probing PCI hardware
bio: create slab<bio-0>  at 0
vgaarb: loaded
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
Switching to clocksource timebase
NET: Registered protocol family 2
IP route cache hash table entries: 65536 (order: 3, 524288 bytes)
TCP established hash table entries: 262144 (order: 6, 4194304 bytes)
TCP bind hash table entries: 65536 (order: 6, 4718592 bytes)
TCP: Hash tables configured (established 262144 bind 65536)
TCP reno registered
UDP hash table entries: 4096 (order: 3, 655360 bytes)
UDP-Lite hash table entries: 4096 (order: 3, 655360 bytes)
NET: Registered protocol family 1
Unpacking initramfs...
Freeing initrd memory: 8062k freed
IOMMU table initialized, virtual merging enabled
audit: initializing netlink socket (disabled)
type=2000 audit(1277868538.520:1): initialized
Kprobe smoke test started
Kprobe smoke test passed successfully
rcu-torture:--- Start of test: nreaders=40 nfakewriters=4 stat_interval=0 verbose=0 test_no_idle_hz=0 shuffle_interval=3 stutter=5 irqreader=1 fqs_duration=0 fqs_holdoff=0 fqs_stutter=3
HugeTLB registered 16 MB page size, pre-allocated 0 pages
HugeTLB registered 16 GB page size, pre-allocated 0 pages
VFS: Disk quotas dquot_6.5.2
Dquot-cache hash table entries: 8192 (order 0, 65536 bytes)
Btrfs loaded
msgmni has been set to 15668
alg: No test for stdrng (krng)
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
pci_hotplug: PCI Hot Plug PCI Core version: 0.5
rpaphp: RPA HOT Plug PCI Controller Driver version: 0.1
Generic RTC Driver v1.07
Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
pmac_zilog: 0.6 (Benjamin Herrenschmidt<benh@kernel.crashing.org>)
Uniform Multi-Platform E-IDE driver
ide-gd driver 1.18
IBM eHEA ethernet device driver (Release EHEA_0105)
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
mice: PS/2 mouse device common for all mice
EDAC MC: Ver: 2.1.0 Jun 30 2010
usbcore: registered new interface driver hiddev
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
TCP cubic registered
NET: Registered protocol family 15
registered taskstats version 1
Freeing unused kernel memory: 2304k freed
doing fast boot
SCSI subsystem initialized
ibmvscsi 30000003: SRP_VERSION: 16.a
scsi0 : IBM POWER Virtual SCSI Adapter 1.5.8
ibmvscsi 30000003: partner initialization complete
ibmvscsi 30000003: host srp version: 16.a, host partition p55avios (1), OS 3, max io 262144
ibmvscsi 30000003: Client reserve enabled
ibmvscsi 30000003: sent SRP login
ibmvscsi 30000003: SRP_LOGIN succeeded
scsi 0:0:1:0: Direct-Access     AIX      VDASD            0001 PQ: 0 ANSI: 3
scsi 0:0:2:0: CD-ROM            AIX      VOPTA                 PQ: 0 ANSI: 4
Creating device nodes with udev
udevd version 128 started
sd 0:0:1:0: [sda] 146800640 512-byte logical blocks: (75.1 GB/70.0 GiB)
sd 0:0:1:0: [sda] Write Protect is off
sd 0:0:1:0: [sda] Cache data unavailable
sd 0:0:1:0: [sda] Assuming drive cache: write through
sd 0:0:1:0: [sda] Cache data unavailable
sd 0:0:1:0: [sda] Assuming drive cache: write through
 sda: sda1 sda2 sda3<  sda5 sda6>
sd 0:0:1:0: [sda] Cache data unavailable
sd 0:0:1:0: [sda] Assuming drive cache: write through
sd 0:0:1:0: [sda] Attached SCSI disk
Boot logging started on /dev/hvc0(/dev/console) at Wed Jun 30 03:28:59 2010
resume device  not found (ignoring)
Waiting for device /dev/sda5 to appear:  ok
showconsole: Warning: the ioctl TIOCGDEV is not known by the kernel
fsck 1.41.1 (01-Sep-2008)
[/sbin/fsck.ext3 (1) -- /] fsck.ext3 -a /dev/sda5
/dev/sda5: clean, 339391/2097152 files, 4231791/8379888 blocks
fsck succeeded. Mounting root device read-write.
Mounting root /dev/sda5
mount -o rw,acl,user_xattr -t ext3 /dev/sda5 /root
EXT3-fs: barriers not enabled
kjournald starting.  Commit interval 5 seconds
EXT3-fs (sda5): using internal journal
EXT3-fs (sda5): mounted filesystem with writeback data mode
mount: can't find /root/proc in /etc/fstab or /etc/mtab
INIT: version 2.86 booting
System Boot Control: Running /etc/init.d/boot
Mounting procfs at /proc7[?25l[80C[10D[1;32mdone[m8[?25h
Mounting sysfs at /sys7[?25l[80C[10D[1;32mdone[m8[?25h
Mounting debugfs at /sys/kernel/debug7[?25l[80C[10D[1;32mdone[m8[?25h
Remounting tmpfs at /dev7[?25l[80C[10D[1;32mdone[m8[?25h
Initializing /dev7[?25l[80C[10D[1;32mdone[m8[?25h
Mounting devpts at /dev/pts7[?25l[80C[10D[1;32mdone[m8[?25h
Starting udevd: udevd version 128 started
7[?25l[80C[10D[1;32mdone[m8[?25h
Loading drivers, configuring devices: sd 0:0:1:0: Attached scsi generic sg0 type 0
scsi 0:0:2:0: Attached scsi generic sg1 type 5
sr0: scsi-1 drive
Uniform CD-ROM driver Revision: 3.20
7[?25l[80C[10D[1;32mdone[m8[?25h
Loading required kernel modules
7[?25l[1A[80C[10D[1;32mdone[m8[?25hActivating swap-devices in /etc/fstab...
Adding 8385856k swap on /dev/sda2.  Priority:-1 extents:1 across:8385856k
7[?25l[1A[80C[10D[1;32mdone[m8[?25hSetting up the hardware clock7[?25l[80C[10D[1;32mdone[m8[?25h
Activating device mapper...
device-mapper: uevent: version 1.0.3
device-mapper: ioctl: 4.17.0-ioctl (2010-03-05) initialised: dm-devel@redhat.com
7[?25l[80C[10D[1;32mdone[m8[?25h
Checking file systems...
fsck 1.41.1 (01-Sep-2008)
Checking all file systems.
[/sbin/fsck.ext3 (1) -- /data] fsck.ext3 -a /dev/sda6
/dev/sda6: clean, 12/1966080 files, 906609/7863808 blocks
7[?25l[1A[80C[10D[1;32mdone[m8[?25h7[?25l[80C[10D[1;32mdone[m8[?25h
Mounting local file systems...
/proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
debugfs on /sys/kernel/debug type debugfs (rw)
udev on /dev type tmpfs (rw)
loop: module loaded
devpts on /dev/pts type devpts (rw,mode=0620,gid=5)
EXT3-fs: barriers not enabled
kjournald starting.  Commit interval 5 seconds
EXT3-fs (sda6): using internal journal
EXT3-fs (sda6): mounted filesystem with writeback data mode
/dev/sda6 on /data type ext3 (rw,acl,user_xattr)
7[?25l[1A[80C[10D[1;32mdone[m8[?25hfuse init (API version 7.14)
Loading fuse module 7[?25l[80C[10D[1;32mdone[m8[?25h
Mounting fuse control filesystem7[?25l[80C[10D[1;32mdone[m8[?25h
Setting current sysctl status from /etc/sysctl.conf7[?25l[80C[10D[1;32mdone[m8[?25h
Activating remaining swap-devices in /etc/fstab...
7[?25l[1A[80C[10D[1;32mdone[m8[?25hEnabling syn flood protection[80C[10D[1;32mdone[m
Disabling IP forwarding7[?25l[80C[10D[1;32mdone[m8[?25h
7[?25l[80C[10D[1;32mdone[m8[?25h
Creating /var/log/boot.msg
7[?25l[1A[80C[10D[1;32mdone[m8[?25hshowconsole: Warning: the ioctl TIOCGDEV is not known by the kernel
Turning quota on
Checking quotas. This may take some time.
7[?25l[80C[10D[1;32mdone[m8[?25h
ATTENTION: You have modified /etc/resolv.conf.  Leaving it untouched...
You can find my version in /etc/resolv.conf.netconfig ...
Mounting securityfs on /sys/kernel/security [80C[10D[1;32mdone[m
Loading AppArmor module [80C[10D[1;31mfailed[m
Setting up hostname 'p55alp2'7[?25l[80C[10D[1;32mdone[m8[?25h
Setting up loopback interface     lo
    lo        IP address: 127.0.0.1/8
              IP address: 127.0.0.2/8
7[?25l[80C[10D[1;32mdone[m8[?25h
Loading kdump
Then try loading kdump kernel
Memory for crashkernel is not reserved
Please reserve memory by passing "crashkernel=X@Y" parameter to the kernel
7[?25l[80C[10D[1;31mfailed[m8[?25h
System Boot Control: The system has been [80C[10D[1mset up[m
Failed features: [80C[31D[1;31mboot.apparmor boot.kdump[m
System Boot Control: Running /etc/init.d/boot.local
7[?25l[1A[80C[10D[1;32mdone[m8[?25hINIT: Entering runlevel: 3
Boot logging started on /dev/hvc0(/dev/console) at Wed Jun 30 08:59:10 2010
Master Resource Control: previous runlevel: N, switching to runlevel: [80C[10D[1m3[m
Initializing random number generator7[?25l[80C[10D[1;32mdone[m8[?25h
Starting D-Bus daemon7[?25l[80C[10D[1;32mdone[m8[?25h
Starting syslog services7[?25l[80C[10D[1;32mdone[m8[?25h
Loading CPUFreq modules (CPUFreq not supported)
Starting HAL daemon7[?25l[80C[10D[1;32mdone[m8[?25h
Setting up (localfs) network interfaces:
    lo
    lo        IP address: 127.0.0.1/8
              IP address: 127.0.0.2/8
7[?25l[1A[80C[10D[1;32mdone[m8[?25h    eth0      name: Virtual Ethernet card 0
    eth0      IP address: 9.124.111.212/24
7[?25l[1A[80C[10D[1;32mdone[m8[?25hSetting up service (localfs) network  .  .  .  .  .  .  .  .  .  .7[?25l[80C[10D[1;32mdone[m8[?25h
Mount CIFS File Systems [80C[10D[1munused[m
Starting rpcbind 7[?25l[80C[10D[1;32mdone[m8[?25h
Starting auditd 7[?25l[80C[10D[1;32mdone[m8[?25h
Not starting NFS client services - no NFS found in /etc/fstab:[80C[10D[1munused[m
NET: Registered protocol family 10
lo: Disabled Privacy Extensions
Loading console font lat9w-16.psfu  -m trivial G0:loadable
7[?25l[1A[80C[10D[1;32mdone[m8[?25hLoading keymap assuming iso-8859-15 euro
Loading /usr/share/kbd/keymaps/i386/qwerty/us.map.gz
7[?25l[1A[80C[10D[1;32mdone[m8[?25hLoading compose table latin1.add7[?25l[80C[10D[1;32mdone[m8[?25h
Start Unicode mode
7[?25l[1A[80C[10D[1;32mdone[m8[?25hStarting Name Service Cache Daemon7[?25l[80C[10D[1;32mdone[m8[?25h
Starting cupsd7[?25l[80C[10D[1;32mdone[m8[?25h
Starting rtas_errd (platform error handling) daemon: 7[?25l[80C[10D[1;32mdone[m8[?25h
Starting irqbalance 7[?25l[80C[10D[1;32mdone[m8[?25h
Starting ipr initialization daemon [80C[10D[1;32mdone[m
Checking ipr microcode levels
Completed ipr microcode updates [80C[10D[1;32mdone[m
Starting SSH daemon7[?25l[80C[10D[1;32mdone[m8[?25h
Starting smartd [80C[10D[1munused[m
Starting ipr dump daemon [80C[10D[1;32mdone[m
Setting up (remotefs) network interfaces:
Setting up service (remotefs) network  .  .  .  .  .  .  .  .  .  .7[?25l[80C[10D[1;32mdone[m8[?25h
Starting INET services. (xinetd)7[?25l[80C[10D[1;32mdone[m8[?25h
Starting mail service (Postfix)7[?25l[80C[10D[1;32mdone[m8[?25h
Starting CRON daemon7[?25l[80C[10D[1;32mdone[m8[?25h
Master Resource Control: runlevel 3 has been [80C[10D[1mreached[m
Skipped services in runlevel 3: [80C[30D[1;33msmbfs nfs smartd splash[m
showconsole: Warning: the ioctl TIOCGDEV is not known by the kernel


Welcome to SUSE Linux Enterprise Server 11 (ppc64) - Kernel 2.6.35-rc3-git4-autotest (console).


p55alp2 login:-- 0:conmux-control -- time-stamp -- Jun/29/10 20:31:38 --
-- 0:conmux-control -- time-stamp -- Jun/29/10 21:10:16 --
 ------------[ cut here ]------------
Badness at kernel/mutex-debug.c:64
NIP: c0000000000be9e8 LR: c0000000000be9cc CTR: 0000000000000000
REGS: c00000010be8f6f0 TRAP: 0700   Not tainted  (2.6.35-rc3-git4-autotest)
MSR: 8000000000029032<EE,ME,CE,IR,DR>   CR: 24224422  XER: 00000012
TASK = c00000010727cf00[8211] 'fs_racer_file_c' THREAD: c00000010be8bb50 CPU: 2
GPR00: 0000000000000000 c00000010be8f970 c000000000d3d798 0000000000000001
GPR04: c00000010be8fa70 c00000010be8c000 c00000010727d9f8 0000000000000000
GPR08: c0000000043042f0 c0000000016534e8 000000000000017a c000000000c29a1c
GPR12: 0000000028228424 c00000000f600500 c00000010be8fc40 0000000020000000
GPR16: fffffffffffff000 c000000109c73000 c00000010be8fc30 0000000000010442
GPR20: 0000000000000000 0000000000000000 00000000000001b6 c00000010dd12250
GPR24: c00000000017c08c c00000010727cf00 c00000010dd12278 c00000010dd12210
GPR28: 0000000000000001 c00000010be8c000 c000000000ca2008 c00000010be8fa70
NIP [c0000000000be9e8] .mutex_remove_waiter+0xa4/0x130
LR [c0000000000be9cc] .mutex_remove_waiter+0x88/0x130
Call Trace:
[c00000010be8f970] [c00000010be8fa00] 0xc00000010be8fa00 (unreliable)
[c00000010be8fa00] [c00000000064a9f0] .mutex_lock_nested+0x384/0x430
Instruction dump:
e81f0010 e93d0000 7fa04800 41fe0028 482e96e5 60000000 2fa30000 419e0018
e93e8008 80090000 2f800000 409e0008<0fe00000>  e93e8000 80090000 2f800000
Unable to handle kernel paging request for unknown fault
Faulting instruction address: 0xc00000000008d0f4
Oops: Kernel access of bad area, sig: 7 [#1]
SMP NR_CPUS=1024 NUMA
Unrecoverable FP Unavailable Exception 800 at c000000000648ed4
pSeries
last sysfs file: /sys/devices/system/cpu/cpu19/cache/index1/shared_cpu_map
Modules linked in: ipv6 fuse loop dm_mod sr_mod cdrom ibmveth sg sd_mod crc_t10dif ibmvscsic scsi_transport_srp scsi_tgt scsi_mod
NIP: c00000000008d0f4 LR: c00000000008d0d0 CTR: 0000000000000000
REGS: c00000010978f900 TRAP: 0600   Tainted: G        W    (2.6.35-rc3-git4-autotest)
MSR: 8000000000009032
Unrecoverable FP Unavailable Exception 800 at c000000000648ed4
Unrecoverable FP Unavailable Exception 800 at c000000000648ed4
Unrecoverable FP Unavailable Exception 800 at c000000000648ed4
<
Unrecoverable FP Unavailable Exception 800 at c000000000648ed4
Unrecoverable FP Unavailable Exception 800 at c000000000648ed4
EE,ME,IR,DR>   CR: 24022442  XER: 00000012
DAR: c000000000648f54, DSISR: 0000000040010000
TASK = c0000001096e4900[7353] 'fs_racer_file_s' THREAD: c00000010978c000 CPU: 10
GPR00: 0000000000004000 c00000010978fb80 c000000000d3d798 0000000000000001
GPR04: c00000000083539e c000000001610228 0000000000000000 c0000000054c6880
GPR08: 00000000000006a5 c000000000648f54 0000000000000007 00000000049b0000
GPR12: 0000000000000000 c00000000f601900 00000000ffffffff ffffffffffffffff
GPR16: 000000004b7dc520 0000000000000000 0000000000000000 c00000010978fea0
GPR20: 00000fffcca7e7a0 00000fffcca7e7a0 00000fffabf7dfd0 00000fffabf7dfd0
GPR24: 0000000000000000 0000000001200011 c000000000e1c0a8 c000000000648ed4
GPR28: 0000000000000000 c0000001096e4900 c000000000ca0458 c00000010725d400
NIP [c00000000008d0f4] .copy_process+0x310/0xf40
LR [c00000000008d0d0] .copy_process+0x2ec/0xf40
Call Trace:
[c00000010978fb80] [c00000000008d0d0] .copy_process+0x2ec/0xf40 (unreliable)
[c00000010978fc80] [c00000000008deb4] .do_fork+0x190/0x3cc
[c00000010978fdc0] [c000000000011ef4] .sys_clone+0x58/0x70
[c00000010978fe30] [c0000000000087f0] .ppc_clone+0x8/0xc
Instruction dump:
419e0010 7fe3fb78 480774cd 60000000 801f0014 e93f0008 7800b842 39290080
78004800 60000042 901f0014 38004000<7d6048a8>  7d6b0078 7d6049ad 40c2fff4
Oops: Unrecoverable FP Unavailable Exception, sig: 6 [#2]
SMP NR_CPUS=1024 NUMA pSeries
last sysfs file: /sys/devices/system/cpu/cpu19/cache/index1/shared_cpu_map
Modules linked in: ipv6 fuse loop dm_mod sr_mod cdrom ibmveth sg sd_mod crc_t10dif ibmvscsic scsi_transport_srp scsi_tgt scsi_mod
NIP: c000000000648ed4 LR: c000000000648ed4 CTR: 0000000000000000
REGS: c00000010979b870 TRAP: 0800   Tainted: G      D W    (2.6.35-rc3-git4-autotest)
MSR: 8000000000001032<ME,IR,DR>   CR: 24042422  XER: 00000012
TASK = c0000001096c4e00[7356] 'fs_racer_file_c' THREAD: c000000109798000 CPU: 4
GPR00: c000000000648ed4 c00000010979baf0 c000000000d3d798 c00000010aeb0c00
GPR04: c0000001096c5320 c000000000087028 0000000024042424 c0000000000129c4
GPR08: c00000010979b890 c000000000000000 c000000000086fcc c0000000048c5780
GPR12: 0000000028000428 c00000000f600a00 0000000000000001 c00000010979bb60
GPR16: 0000000000000004 c000000000de2550 0000000000000000 c000000109798080
GPR20: c0000000000939b0 0000000000000000 c000000109798000 c000000000b15780
GPR24: c0000001096c51c0 0000000000000002 0000000100034ba6 c0000001096c4e00
GPR28: c00000010b904e00 c0000000044c5780 c000000000c9fb00 c000000109e70500
NIP [c000000000648ed4] .schedule+0x620/0x770
LR [c000000000648ed4] .schedule+0x620/0x770
Call Trace:
[c00000010979baf0] [c000000000648ed4] .schedule+0x620/0x770 (unreliable)
[c00000010979bc00] [c0000000000939b0] .do_wait+0x19c/0x220
[c00000010979bcc0] [c000000000093b04] .SyS_wait4+0xd0/0x108
[c00000010979bdc0] [c00000000009138c] .SyS_waitpid+0x1c/0x30
[c00000010979be30] [c0000000000085b4] syscall_exit+0x0/0x40
Instruction dump:
2fa00000 409e000c f81b02a8 fbfd0878 387d0018 e8be8940 38800001 4ba79469
60000000 7f84e378 7f63db78 4b9c99b1<c0000001>  0725d400 c0000000 00c29830
Oops: Unrecoverable FP Unavailable Exception, sig: 6 [#3]
SMP NR_CPUS=1024 NUMA pSeries
last sysfs file: /sys/devices/system/cpu/cpu19/cache/index1/shared_cpu_map
Modules linked in: ipv6 fuse loop dm_mod sr_mod cdrom ibmveth sg sd_mod crc_t10dif ibmvscsic scsi_transport_srp scsi_tgt scsi_mod
NIP: c000000000648ed4 LR: c000000000648ed4 CTR: 0000000000000000
REGS: c0000001097cb870 TRAP: 0800   Tainted: G      D W    (2.6.35-rc3-git4-autotest)
MSR: 8000000000001032<ME,IR,DR>   CR: 24042422  XER: 00000010
TASK = c0000001096d5f00[7345] 'fs_racer_dir_cr' THREAD: c0000001097c8000 CPU: 5
GPR00: c000000000648ed4 c0000001097cbaf0 c000000000d3d798 c000000107175a00
GPR04: c0000001096d6420 c000000000087028 0000000024042424 c0000000000129c4
GPR08: c0000001097cb890 c000000000000000 c000000000086fcc c000000004ac5780
GPR12: c00000010c2ac000 c00000000f600c80 0000000000000001 c0000001097cbb60
GPR16: 0000000000000004 c000000000de2550 0000000000000000 c0000001097c8080
GPR20: c0000000000939b0 0000000000000000 c0000001097c8000 c000000000b15780
GPR24: c0000001096d62c0 0000000000000005 0000000100034ba6 c0000001096d5f00
GPR28: c00000010eb8ea00 c000000004ac5780 c000000000c9fb00 c0000001098faf00
NIP [c000000000648ed4] .schedule+0x620/0x770
LR [c000000000648ed4] .schedule+0x620/0x770
Call Trace:
[c0000001097cbaf0] [c000000000648ed4] .schedule+0x620/0x770 (unreliable)
[c0000001097cbc00] [c0000000000939b0] .do_wait+0x19c/0x220
[c0000001097cbcc0] [c000000000093b04] .SyS_wait4+0xd0/0x108
[c0000001097cbdc0] [c00000000009138c] .SyS_waitpid+0x1c/0x30
[c0000001097cbe30] [c0000000000085b4] syscall_exit+0x0/0x40
Instruction dump:
2fa00000 409e000c f81b02a8 fbfd0878 387d0018 e8be8940 38800001 4ba79469
60000000 7f84e378 7f63db78 4b9c99b1<c0000001>  0725d400 c0000000 00c29830
Oops: Unrecoverable FP Unavailable Exception, sig: 6 [#4]
SMP NR_CPUS=1024 NUMA pSeries
last sysfs file: /sys/devices/system/cpu/cpu19/cache/index1/shared_cpu_map
Modules linked in: ipv6 fuse loop dm_mod sr_mod cdrom ibmveth sg sd_mod crc_t10dif ibmvscsic scsi_transport_srp scsi_tgt scsi_mod
NIP: c000000000648ed4 LR: c000000000648ed4 CTR: c000000000078dac
REGS: c00000010e4d7ac0 TRAP: 0800   Tainted: G      D W    (2.6.35-rc3-git4-autotest)
MSR: 8000000000001032<ME,IR,DR>   CR: 24000022  XER: 00000001
TASK = c00000010eb98600[0] 'swapper' THREAD: c00000010e4d4000 CPU: 9
GPR00: c000000000648ed4 c00000010e4d7d40 c000000000d3d798 c000000109307500
GPR04: c00000010eb98b20 c000000000087028 0000000024000024 c0000000000129c4
GPR08: c00000010e4d7ae0 c000000000000000 c000000000086fcc c0000000052c5780
GPR12: 0000000044000028 c00000000f601680 0000000000000001 c00000010e4d7db0
GPR16: 0000000000000004 c000000000de2550 0000000000000000 c00000010e4d4080
GPR20: c0000000000140bc 0000000000000000 c00000010e4d4000 c000000000b15780
GPR24: c00000010eb989c8 0000000000000009 0000000000001680 c00000010eb98600
GPR28: c000000109307500 c0000000052c5780 c000000000c9fb00 c000000109376900
NIP [c000000000648ed4] .schedule+0x620/0x770
LR [c000000000648ed4] .schedule+0x620/0x770
Call Trace:
[c00000010e4d7d40] [c000000000648ed4] .schedule+0x620/0x770 (unreliable)
[c00000010e4d7e50] [c0000000000140bc] .cpu_idle+0x1a4/0x1ac
[c00000010e4d7ee0] [c000000000656530] .start_secondary+0x378/0x3b0
[c00000010e4d7f90] [c0000000000082d8] .start_secondary_prolog+0x10/0x14
Instruction dump:
2fa00000 409e000c f81b02a8 fbfd0878 387d0018 e8be8940 38800001 4ba79469
60000000 7f84e378 7f63db78 4b9c99b1<c0000001>  0725d400 c0000000 00c29830
Oops: Unrecoverable FP Unavailable Exception, sig: 6 [#5]
SMP NR_CPUS=1024 NUMA pSeries
last sysfs file: /sys/devices/system/cpu/cpu19/cache/index1/shared_cpu_map
Modules linked in: ipv6 fuse loop dm_mod sr_mod cdrom ibmveth sg sd_mod crc_t10dif ibmvscsic scsi_transport_srp scsi_tgt scsi_mod
NIP: c000000000648ed4 LR: c000000000648ed4 CTR: c000000000078dac
REGS: c000000000d3fa30 TRAP: 0800   Tainted: G      D W    (2.6.35-rc3-git4-autotest)
MSR: 8000000000001032<ME,IR,DR>   CR: 24000022  XER: 00000012
TASK = c000000000c67710[0] 'swapper' THREAD: c000000000d3c000 CPU: 0
GPR00: c000000000648ed4 c000000000d3fcb0 c000000000d3d798 c0000001096c7500
GPR04: c000000000c67c30 c000000000087028 0000000024000024 c0000000000129c4
GPR08: c000000000d3fa50 c000000000000000 c000000000086fcc c0000000040c5780
GPR12: 0000000042042428 c00000000f600000 0000000000000001 c000000000d3fd20
GPR16: 0000000000000004 c000000000de2550 0000000000000000 c000000000d3c080
GPR20: c0000000000140bc 0000000000000000 c000000000d3c000 c000000000b15780
GPR24: c000000000c67ad8 0000000000000000 0000000001e00000 c000000000c67710
GPR28: c000000107275a00 c0000000040c5780 c000000000c9fb00 c0000001098f9100
NIP [c000000000648ed4] .schedule+0x620/0x770
LR [c000000000648ed4] .schedule+0x620/0x770
Call Trace:
[c000000000d3fcb0] [c000000000648ed4] .schedule+0x620/0x770 (unreliable)
[c000000000d3fdc0] [c0000000000140bc] .cpu_idle+0x1a4/0x1ac
[c000000000d3fe50] [c000000000009d84] .rest_init+0xd8/0x114
[c000000000d3fee0] [c0000000008e0dec] .start_kernel+0x544/0x564
[c000000000d3ff90] [c000000000008434] .start_here_common+0x1c/0x68
Instruction dump:
2fa00000 409e000c f81b02a8 fbfd0878 387d0018 e8be8940 38800001 4ba79469
60000000 7f84e378 7f63db78 4b9c99b1<c0000001>  0725d400 c0000000 00c29830
Oops: Unrecoverable FP Unavailable Exception, sig: 6 [#6]
SMP NR_CPUS=1024 NUMA pSeries
last sysfs file: /sys/devices/system/cpu/cpu19/cache/index1/shared_cpu_map
Modules linked in: ipv6 fuse loop dm_mod sr_mod cdrom ibmveth sg sd_mod crc_t10dif ibmvscsic scsi_transport_srp scsi_tgt scsi_mod
NIP: c000000000648ed4 LR: c000000000648ed4 CTR: c0000000000813e0
REGS: c00000010ed639c0 TRAP: 0800   Tainted: G      D W    (2.6.35-rc3-git4-autotest)
MSR: 8000000000001032<ME,IR,DR>   CR: 24000022  XER: 00000012
TASK = c00000010ecd3800[42] 'migration/13' THREAD: c00000010ed60000 CPU: 13
GPR00: c000000000648ed4 c00000010ed63c40 c000000000d3d798 c00000010edcc300
GPR04: c00000010ecd3d20 c000000000087028 0000000024000028 c0000000000129c4
GPR08: c00000010ed639e0 c000000000000000 c000000000086fcc c000000005ac5780
GPR12: 0000000044224424 c00000000f602080 0000000000000001 c00000010ed63cb0
GPR16: 0000000000000004 c000000000de2550 0000000000000000 c00000010ed60080
GPR20: c0000000000e8a64 0000000000000000 c00000010ed60000 c000000000b15780
GPR24: c00000010ecd3bc0 000000000000000d c000000005ac4250 c00000010ecd3800
GPR28: c00000010a12e500 c000000005ac5780 c000000000c9fb00 c00000010a222800
NIP [c000000000648ed4] .schedule+0x620/0x770
LR [c000000000648ed4] .schedule+0x620/0x770
Call Trace:
[c00000010ed63c40] [c000000000648ed4] .schedule+0x620/0x770 (unreliable)
[c00000010ed63d50] [c0000000000e8a64] .cpu_stopper_thread+0x1e4/0x1ec
[c00000010ed63ea0] [c0000000000acc48] .kthread+0xa8/0xb4
[c00000010ed63f90] [c00000000002c698] .kernel_thread+0x54/0x70
Instruction dump:
2fa00000 409e000c f81b02a8 fbfd0878 387d0018 e8be8940 38800001 4ba79469
60000000 7f84e378 7f63db78 4b9c99b1<c0000001>  0725d400 c0000000 00c29830
Oops: Unrecoverable FP Unavailable Exception, sig: 6 [#7]
SMP NR_CPUS=1024 NUMA pSeries
last sysfs file: /sys/devices/system/cpu/cpu19/cache/index1/shared_cpu_map
Modules linked in: ipv6 fuse loop dm_mod sr_mod cdrom ibmveth sg sd_mod crc_t10dif ibmvscsic scsi_transport_srp scsi_tgt scsi_mod
NIP: c000000000648ed4 LR: c000000000648ed4 CTR: 0000000000000000
REGS: c00000010aadb270 TRAP: 0800   Tainted: G      D W    (2.6.35-rc3-git4-autotest)
MSR: 8000000000001032<ME,IR,DR>   CR: 24022422  XER: 00000000
TASK = c00000010aa5d400[8227] 'fs_racer_file_s' THREAD: c00000010aad8000 CPU: 7
GPR00: c000000000648ed4 c00000010aadb4f0 c000000000d3d798 c00000010809ad00
GPR04: c00000010aa5d920 c000000000087028 0000000024022424 c0000000000129c4
GPR08: c00000010aadb290 c000000000000000 c000000000086fcc c000000004ec5780
GPR12: 0000000028000428 c00000000f601180 0000000000000001 c00000010aadb560
GPR16: 0000000000000004 c000000000de2550 0000000000000000 c00000010aad8080
GPR20: c0000000006490b0 0000000000000000 c00000010aad8000 c000000000b15780
GPR24: c00000010aa5d7c0 0000000000000009 0000000100034b9d c00000010aa5d400
GPR28: c00000010eb98600 c0000000052c5780 c000000000c9fb00 c00000010ab53c00
NIP [c000000000648ed4] .schedule+0x620/0x770
LR [c000000000648ed4] .schedule+0x620/0x770
Call Trace:
[c00000010aadb4f0] [c000000000648ed4] .schedule+0x620/0x770 (unreliable)
[c00000010aadb600] [c0000000006490b0] .io_schedule+0x8c/0x108
[c00000010aadb690] [c000000000118408] .sync_page+0x78/0x94
[c00000010aadb710] [c0000000006495bc] .__wait_on_bit_lock+0x9c/0x140
[c00000010aadb7d0] [c000000000118344] .__lock_page+0x74/0x98
[c00000010aadb8b0] [c000000000118f00] .filemap_fault+0x114/0x430
[c00000010aadb980] [c000000000133d18] .__do_fault+0xa4/0x628
[c00000010aadba90] [c000000000136774] .handle_mm_fault+0x404/0x91c
[c00000010aadbb90] [c00000000064e4a0] .do_page_fault+0x42c/0x6b4
[c00000010aadbe30] [c000000000005628] handle_page_fault+0x20/0x74
Instruction dump:
2fa00000 409e000c f81b02a8 fbfd0878 387d0018 e8be8940 38800001 4ba79469
60000000 7f84e378 7f63db78 4b9c99b1<c0000001>  0725d400 c0000000 00c29830
---[ end trace 6d7478f9c45fb038 ]---
Unrecoverable FP Unavailable Exception 800 at c000000000648ed4
Oops: Unrecoverable FP Unavailable Exception, sig: 6 [#8]
SMP NR_CPUS=1024 NUMA pSeries
last sysfs file: /sys/devices/system/cpu/cpu19/cache/index1/shared_cpu_map
Modules linked in: ipv6 fuse loop dm_mod sr_mod cdrom ibmveth sg sd_mod crc_t10dif ibmvscsic scsi_transport_srp scsi_tgt scsi_mod
NIP: c000000000648ed4 LR: c000000000648ed4 CTR: c00000000007e3f0
REGS: c00000010efaba00 TRAP: 0800   Tainted: G      D W    (2.6.35-rc3-git4-autotest)
MSR: 8000000000001032<ME,IR,DR>   CR: 24000022  XER: 00000006
TASK = c00000010ef18600[73] 'events/10' THREAD: c00000010efa8000 CPU: 10
GPR00: c000000000648ed4 c00000010efabc80 c000000000d3d798 c0000001096e4900
GPR04: c00000010ef18b20 c000000000087028 0000000024000028 c0000000000129c4
GPR08: c00000010efaba20 c000000000000000 c000000000086fcc c0000000054c5780
GPR12: 0000000028022428 c00000000f601900 0000000000000001
Unrecoverable FP Unavailable Exception 800 at c000000000648ed4
c00000010efabcf0
GPR16: 0000000000000004 c000000000de2550 0000000000000000 c00000010efa8080
GPR20: c0000000000a7658 0000000000000000 c00000010efa8000 c000000000b15780
GPR24: c00000010ef189c0 000000000000000a c0000000054c6ac0 c00000010ef18600
GPR28: c00000010b873300 c0000000054c5780 c000000000c9fb00 c000000109b20500
NIP [c000000000648ed4] .schedule+0x620/0x770
LR [c000000000648ed4] .schedule+0x620/0x770
Call Trace:
[c00000010efabc80] [c000000000648ed4] .schedule+0x620/0x770 (unreliable)
[c00000010efabd90] [c0000000000a7658] .worker_thread+0xf0/0x34c
[c00000010efabea0] [c0000000000acc48] .kthread+0xa8/0xb4
[c00000010efabf90] [c00000000002c698] .kernel_thread+0x54/0x70
Instruction dump:
2fa00000 409e000c f81b02a8 fbfd0878 387d0018 e8be8940 38800001 4ba79469
60000000 7f84e378 7f63db78 4b9c99b1<c0000001>  0725d400 c0000000 00c29830
Oops: Unrecoverable FP Unavailable Exception, sig: 6 [#9]
SMP NR_CPUS=1024 NUMA pSeries
last sysfs file: /sys/devices/system/cpu/cpu19/cache/index1/shared_cpu_map
Modules linked in: ipv6 fuse loop dm_mod sr_mod cdrom ibmveth sg sd_mod crc_t10dif ibmvscsic scsi_transport_srp scsi_tgt scsi_mod
NIP: c000000000648ed4 LR: c000000000648ed4 CTR: 0000000000000000
REGS: c000000108adb870 TRAP: 0800   Tainted: G      D W    (2.6.35-rc3-git4-autotest)
MSR: 8000000000001032<ME,IR,DR>   CR: 24042422  XER: 00000001
---[ end trace 6d7478f9c45fb039 ]---
TASK = c000000108a3cf00[7339] 'fs_racer.sh' THREAD: c000000108ad8000 CPU: 19
GPR00: c000000000648ed4 c000000108adbaf0 c000000000d3d798 c00000010ebb0c00
   ---[ end trace 6d7478f9c45fb03a ]---
---[ end trace 6d7478f9c45fb03b ]---
Kernel panic - not syncing: Attempted to kill the idle task!
Call Trace:
[c00000010e4d7790] [c000000000011c30] .show_stack+0x6c/0x16c (unreliable)
[c00000010e4d7840] [c0000000006514a0] .panic+0x94/0x140
[c00000010e4d78d0] [c000000000093ea8] .do_exit+0x98/0x71c
[c00000010e4d79b0] [c00000000002a568] .die+0x27c/0x2ac
[c00000010e4d7a50] [c000000000005110] fp_unavailable_common+0x110/0x180
--- Exception: 800 at .schedule+0x620/0x770
    LR = .schedule+0x620/0x770
[c00000010e4d7e50] [c0000000000140bc] .cpu_idle+0x1a4/0x1ac
[c00000010e4d7ee0] [c000000000656530] .start_secondary+0x378/0x3b0
[c00000010e4d7f90] [c0000000000082d8] .start_secondary_prolog+0x10/0x14
Rebooting in 180 seconds..
---[ end trace 6d7478f9c45fb03c ]---
Kernel panic - not syncing: Attempted to kill the idle task!
Call Trace:
[c000000000d3f700] [c000000000011c30] .show_stack+0x6c/0x16c (unreliable)
[c000000000d3f7b

BUG: spinlock lockup on CPU#5, fs_racer_dir_cr/7345, c000000004ac5780
Call Trace:
[c0000001097cabf0] [c000000000011c30] .show_stack+0x6c/0x16c (unreliable)
[c0000001097caca0] [c0000000003ad784] .do_raw_spin_lock+0x13c/0x184
[c0000001097cad40] [c00000000064c44c] ._raw_spin_lock+0x74/0xa4
[c0000001097cadd0] [c00000000008b804] .scheduler_tick+0x54/0x3a8
[c0000001097cae70] [c00000000009e148] .update_process_times+0x5c/0x88
[c0000001097caf10] [c0000000000bd2fc] .tick_sched_timer+0xa4/0xf0
[c0000001097cafb0] [c0000000000b0d84] .__run_hrtimer+0xac/0x11c
[c0000001097cb050] [c0000000000b1098] .hrtimer_interrupt+0x108/0x258
[c0000001097cb140] [c000000000029230] .timer_interrupt+0xe4/0x138
[c0000001097cb1d0] [c000000000003718] decrementer_common+0x118/0x180
--- Exception: 901 at .raw_local_irq_restore+0x6c/0x80
    LR = ._raw_spin_unlock_irq+0x3c/0x54
[c0000001097cb4c0] [c0000001097cb550] 0xc0000001097cb550 (unreliable)
[c0000001097cb550] [c00000000064cf78] ._raw_spin_unlock_irq+0x3c/0x54
[c0000001097cb5e0] [c0000000000d703c] .acct_collect+0x1b0/0x1d4
[c0000001097cb680] [c000000000094008] .do_exit+0x1f8/0x71c
[c0000001097cb760] [c00000000002a568] .die+0x27c/0x2ac
[c0000001097cb800] [c000000000005110] fp_unavailable_common+0x110/0x180
--- Exception: 800 at .schedule+0x620/0x770
    LR = .schedule+0x620/0x770
[c0000001097cbc00] [c0000000000939b0] .do_wait+0x19c/0x220
[c0000001097cbcc0] [c000000000093b04] .SyS_wait4+0xd0/0x108
[c0000001097cbdc0] [c00000000009138c] .SyS_waitpid+0x1c/0x30
[c0000001097cbe30] [c0000000000085b4] syscall_exit+0x0/0x40
BUG: spinlock lockup on CPU#4, fs_racer_file_c/7356, c0000000048c5780
Call Trace:
[c00000010979abf0] [c000000000011c30] .show_stack+0x6c/0x16c (unreliable)
[c00000010979aca0] [c0000000003ad784] .do_raw_spin_lock+0x13c/0x184
[c00000010979ad40] [c00000000064c44c] ._raw_spin_lock+0x74/0xa4
[c00000010979add0] [c00000000008b804] .scheduler_tick+0x54/0x3a8
[c00000010979ae70] [c00000000009e148] .update_process_times+0x5c/0x88
[c00000010979af10] [c0000000000bd2fc] .tick_sched_timer+0xa4/0xf0
[c00000010979afb0] [c0000000000b0d84] .__run_hrtimer+0xac/0x11c
[c00000010979b050] [c0000000000b1098] .hrtimer_interrupt+0x108/0x258
[c00000010979b140] [c000000000029230] .timer_interrupt+0xe4/0x138
[c00000010979b1d0] [c000000000003718] decrementer_common+0x118/0x180
--- Exception: 901 at .raw_local_irq_restore+0x6c/0x80
    LR = ._raw_spin_unlock_irq+0x3c/0x54
[c00000010979b4c0] [c00000010979b550] 0xc00000010979b550 (unreliable)
[c00000010979b550] [c00000000064cf78] ._raw_spin_unlock_irq+0x3c/0x54
[c00000010979b5e0] [c0000000000d703c] .acct_collect+0x1b0/0x1d4
[c00000010979b680] [c000000000094008] .do_exit+0x1f8/0x71c
[c00000010979b760] [c00000000002a568] .die+0x27c/0x2ac
[c00000010979b800] [c000000000005110] fp_unavailable_common+0x110/0x180
--- Exception: 800 at .schedule+0x620/0x770
    LR = .schedule+0x620/0x770
[c00000010979bc00] [c0000000000939b0] .do_wait+0x19c/0x220
[c00000010979bcc0] [c000000000093b04] .SyS_wait4+0xd0/0x108
[c00000010979bdc0] [c00000000009138c] .SyS_waitpid+0x1c/0x30
[c00000010979be30] [c0000000000085b4] syscall_exit+0x0/0x40
BUG: spinlock lockup on CPU#6, mkdir/8226, c000000001692670
Call Trace:
[c000000108a8b5d0] [c000000000011c30] .show_stack+0x6c/0x16c (unreliable)
[c000000108a8b680] [c0000000003ad784] .do_raw_spin_lock+0x13c/0x184
[c000000108a8b720] [c00000000064c3a0] ._raw_spin_lock_irqsave+0x84/0xbc
[c000000108a8b7c0] [c00000000007b504] .__wake_up+0x34/0x88
[c000000108a8b870] [c0000000000ad180] .__wake_up_bit+0x3c/0x50
[c000000108a8b8f0] [c000000000118538] .unlock_page+0x40/0x58
[c000000108a8b980] [c00000000013421c] .__do_fault+0x5a8/0x628
[c000000108a8ba90] [c000000000136774] .handle_mm_fault+0x404/0x91c
[c000000108a8bb90] [c00000000064e4a0] .do_page_fault+0x42c/0x6b4
[c000000108a8be30] [c000000000005628] handle_page_fault+0x20/0x74
BUG: spinlock lockup on CPU#12, ln/8223, c000000001692670
Call Trace:
[c0000000a28635d0] [c000000000011c30] .show_stack+0x6c/0x16c (unreliable)
[c0000000a2863680] [c0000000003ad784] .do_raw_spin_lock+0x13c/0x184
[c0000000a2863720] [c00000000064c3a0] ._raw_spin_lock_irqsave+0x84/0xbc
[c0000000a28637c0] [c00000000007b504] .__wake_up+0x34/0x88
[c0000000a2863870] [c0000000000ad180] .__wake_up_bit+0x3c/0x50
[c0000000a28638f0] [c000000000118538] .unlock_page+0x40/0x58
[c0000000a2863980] [c00000000013421c] .__do_fault+0x5a8/0x628
[c0000000a2863a90] [c000000000136774] .handle_mm_fault+0x404/0x91c
[c0000000a2863b90] [c00000000064e4a0] .do_page_fault+0x42c/0x6b4
[c0000000a2863e30] [c000000000005628] handle_page_fault+0x20/0x74
BUG: spinlock lockup on CPU#17, fs_racer_file_c/8232, c000000001692670
Call Trace:
[c00000010ee7f5d0] [c000000000011c30] .show_stack+0x6c/0x16c (unreliable)
[c00000010ee7f680] [c0000000003ad784] .do_raw_spin_lock+0x13c/0x184
[c00000010ee7f720] [c00000000064c3a0] ._raw_spin_lock_irqsave+0x84/0xbc
[c00000010ee7f7c0] [c00000000007b504] .__wake_up+0x34/0x88
[c00000010ee7f870] [c0000000000ad180] .__wake_up_bit+0x3c/0x50
[c00000010ee7f8f0] [c000000000118538] .unlock_page+0x40/0x58
[c00000010ee7f980] [c00000000013421c] .__do_fault+0x5a8/0x628
[c00000010ee7fa90] [c000000000136774] .handle_mm_fault+0x404/0x91c
[c00000010ee7fb90] [c00000000064e4a0] .do_page_fault+0x42c/0x6b4
[c00000010ee7fe30] [c000000000005628] handle_page_fault+0x20/0x74
BUG: spinlock lockup on CPU#15, klogd/1511, c0000000040c5780
Call Trace:
[c000000107497300] [c000000000011c30] .show_stack+0x6c/0x16c (unreliable)
[c0000001074973b0] [c0000000003ad784] .do_raw_spin_lock+0x13c/0x184
[c000000107497450] [c00000000064c44c] ._raw_spin_lock+0x74/0xa4
[c0000001074974e0] [c00000000007ba68] .task_rq_lock+0x6c/0xd4
[c000000107497580] [c000000000087d74] .try_to_wake_up+0x50/0x454
[c000000107497640] [c0000000001838dc] .pollwake+0x9c/0xcc
[c000000107497720] [c0000000000797c0] .__wake_up_common+0x6c/0xe0
[c0000001074977d0] [c00000000007b494] .__wake_up_sync_key+0x68/0x9c
[c000000107497870] [c00000000059304c] .sock_def_readable+0x84/0xd8
[c0000001074978f0] [c00000000063996c] .unix_dgram_sendmsg+0x4e4/0x610
[c000000107497a30] [c00000000058e318] .sock_aio_write+0x170/0x1a8
[c000000107497b60] [c00000000016e4e4] .do_sync_write+0xac/0x10c
[c000000107497ce0] [c00000000016f2a4] .vfs_write+0xec/0x1dc
[c000000107497d80] [c00000000016f49c] .SyS_write+0x58/0xa0
[c000000107497e30] [c0000000000085b4] syscall_exit+0x0/0x40
BUG: spinlock lockup on CPU#14, true/8230, c0000000052c5780
Call Trace:
[c00000010b3d6c40] [c000000000011c30] .show_stack+0x6c/0x16c (unreliable)
[c00000010b3d6cf0] [c0000000003ad784] .do_raw_spin_lock+0x13c/0x184
[c00000010b3d6d90] [c00000000064c44c] ._raw_spin_lock+0x74/0xa4
[c00000010b3d6e20] [c00000000007ba68] .task_rq_lock+0x6c/0xd4
[c00000010b3d6ec0] [c000000000087d74] .try_to_wake_up+0x50/0x454
[c00000010b3d6f80] [c0000000000ad1ec] .autoremove_wake_function+0x18/0x54
[c00000010b3d7000] [c0000000000797c0] .__wake_up_common+0x6c/0xe0
[c00000010b3d70b0] [c00000000007b524] .__wake_up+0x54/0x88
[c00000010b3d7160] [c0000000000ad180] .__wake_up_bit+0x3c/0x50
[c00000010b3d71e0] [c000000000118538] .unlock_page+0x40/0x58
[c00000010b3d7270] [c00000000013421c] .__do_fault+0x5a8/0x628
[c00000010b3d7380] [c000000000136774] .handle_mm_fault+0x404/0x91c
[c00000010b3d7480] [c00000000064e4a0] .do_page_fault+0x42c/0x6b4
[c00000010b3d7720] [c000000000005628] handle_page_fault+0x20/0x74
--- Exception: 301 at .__clear_user+0x14/0x7c
    LR = .padzero+0x74/0x128
[c00000010b3d7a10] [c0000000001c2354] .padzero+0x44/0x128 (unreliable)
[c00000010b3d7aa0] [c0000000001c3530] .load_elf_binary+0xca4/0x16a8
[c00000010b3d7be0] [c0000000001753b0] .search_binary_handler+0x11c/0x37c
[c00000010b3d7cc0] [c000000000176d0c] .do_execve+0x1bc/0x2e8
[c00000010b3d7d90] [c000000000012740] .sys_execve+0x70/0xac
[c00000010b3d7e30] [c0000000000085b4] syscall_exit+0x0/0x40
BUG: spinlock lockup on CPU#1, true/8225, c000000001692670
Call Trace:
[c00000010a18b5d0] [c000000000011c30] .show_stack+0x6c/0x16c (unreliable)
[c00000010a18b680] [c0000000003ad784] .do_raw_spin_lock+0x13c/0x184
[c00000010a18b720] [c00000000064c3a0] ._raw_spin_lock_irqsave+0x84/0xbc
[c00000010a18b7c0] [c00000000007b504] .__wake_up+0x34/0x88
[c00000010a18b870] [c0000000000ad180] .__wake_up_bit+0x3c/0x50
[c00000010a18b8f0] [c000000000118538] .unlock_page+0x40/0x58
[c00000010a18b980] [c00000000013421c] .__do_fault+0x5a8/0x628
[c00000010a18ba90] [c000000000136774] .handle_mm_fault+0x404/0x91c
[c00000010a18bb90] [c00000000064e4a0] .do_page_fault+0x42c/0x6b4
[c00000010a18be30] [c000000000005628] handle_page_fault+0x20/0x74
BUG: spinlock lockup on CPU#3, true/8220, c000000001692670
Call Trace:
[c0000001085e75d0] [c000000000011c30] .show_stack+0x6c/0x16c (unreliable)
[c0000001085e7680] [c0000000003ad784] .do_raw_spin_lock+0x13c/0x184
[c0000001085e7720] [c00000000064c3a0] ._raw_spin_lock_irqsave+0x84/0xbc
[c0000001085e77c0] [c00000000007b504] .__wake_up+0x34/0x88
[c0000001085e7870] [c0000000000ad180] .__wake_up_bit+0x3c/0x50
[c0000001085e78f0] [c000000000118538] .unlock_page+0x40/0x58
[c0000001085e7980] [c00000000013421c] .__do_fault+0x5a8/0x628
[c0000001085e7a90] [c000000000136774] .handle_mm_fault+0x404/0x91c
[c0000001085e7b90] [c00000000064e4a0] .do_page_fault+0x42c/0x6b4
[c0000001085e7e30] [c000000000005628] handle_page_fault+0x20/0x74
BUG: spinlock lockup on CPU#2, mkdir/8219, c000000001692670
Call Trace:
[c00000010b3cf5d0] [c000000000011c30] .show_stack+0x6c/0x16c (unreliable)
[c00000010b3cf680] [c0000000003ad784] .do_raw_spin_lock+0x13c/0x184
[c00000010b3cf720] [c00000000064c3a0] ._raw_spin_lock_irqsave+0x84/0xbc
[c00000010b3cf7c0] [c00000000007b504] .__wake_up+0x34/0x88
[c00000010b3cf870] [c0000000000ad180] .__wake_up_bit+0x3c/0x50
[c00000010b3cf8f0] [c000000000118538] .unlock_page+0x40/0x58
[c00000010b3cf980] [c00000000013421c] .__do_fault+0x5a8/0x628
[c00000010b3cfa90] [c000000000136774] .handle_mm_fault+0x404/0x91c
[c00000010b3cfb90] [c00000000064e4a0] .do_page_fault+0x42c/0x6b4
[c00000010b3cfe30] [c000000000005628] handle_page_fault+0x20/0x74
-- 0:conmux-control -- time-stamp -- Jun/29/10 21:12:40 -- 

^ permalink raw reply

* Re: [PATCH 1/9] Add Synopsys DesignWare HS USB OTG Controller driver.
From: Daniel Glöckner @ 2010-06-30  9:53 UTC (permalink / raw)
  To: David Brownell
  Cc: linuxppc-dev, linux-usb, Mark Miesfeld, gregkh, Fushen Chen
In-Reply-To: <5569.83301.qm@web180304.mail.gq1.yahoo.com>

On 06/30/2010 12:41 AM, David Brownell wrote:
> Could you mention a few Linux-enabled chips which
> include this controller?

Ralink APSoC chips (rt2880, rt305x) do:
http://svn.dd-wrt.com:8000/dd-wrt/browser/src/linux/rt2880/linux-2.6.23/drivers/usb/dwc_otg/Kconfig

  Daniel

-- 
Dipl.-Math. Daniel Glöckner, emlix GmbH, http://www.emlix.com
Fon +49 551 30664-0, Fax -11, Bahnhofsallee 1b, 37081 Göttingen, Germany
Sitz der Gesellschaft: Göttingen, Amtsgericht Göttingen HR B 3160
Geschäftsführer: Dr. Uwe Kracke, Ust-IdNr.: DE 205 198 055

emlix - your embedded linux partner

^ permalink raw reply

* Re: [PATCH 1/9] Add Synopsys DesignWare HS USB OTG Controller driver.
From: Sergei Shtylyov @ 2010-06-30 10:10 UTC (permalink / raw)
  To: Fushen Chen; +Cc: linuxppc-dev, linux-usb, Mark Miesfeld, gregkh
In-Reply-To: <12778468223309-git-send-email-fchen@apm.com>

Hello.

Fushen Chen wrote:

> The DWC OTG driver module provides the initialization and cleanup
> entry points for the DWC OTG USB driver.

> Signed-off-by: Fushen Chen <fchen@apm.com>
> Signed-off-by: Mark Miesfeld <mmiesfeld@apm.com>
[...]
> diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts
> index 083e68e..1a141b8 100644
> --- a/arch/powerpc/boot/dts/kilauea.dts
> +++ b/arch/powerpc/boot/dts/kilauea.dts
> @@ -394,5 +394,20 @@
>  				0x0 0x0 0x0 0x3 &UIC2 0xd 0x4 /* swizzled int C */
>  				0x0 0x0 0x0 0x4 &UIC2 0xe 0x4 /* swizzled int D */>;
>  		};
> +
> +		USBOTG0: usbotg@ef6c0000 {
> +			compatible = "amcc,dwc-otg";
> +			reg = <0xef6c0000 0x10000>;
> +			interrupt-parent = <&USBOTG0>;
> +			interrupts = <0x0 0x1 0x2>;
> +			#interrupt-cells = <0x1>;
> +			#address-cells = <0x0>;
> +			#size-cells = <0x0>;
> +			interrupt-map = <
> +				0x0 &UIC2 0x1e 0x4 /* USB-OTG */
> +				0x1 &UIC1 0x1a 0x8 /* HIGH-POWER */
> +				0x2 &UIC0 0xc 0x4  /* DMA */ >;
> +			interrupt-map-mask = <0xffffffff>;
> +		};
>  	};
>  };

    Please put this file in a separate patch and push thru the PowerPC tree.

WBR, Sergei

^ permalink raw reply

* Re: [PATCH 1/9] Add Synopsys DesignWare HS USB OTG Controller driver.
From: Stefan Roese @ 2010-06-30  9:27 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: linuxppc-dev, linux-usb, Mark Miesfeld, Wolfgang Denk,
	Fushen Chen
In-Reply-To: <12778468223309-git-send-email-fchen@apm.com>

Hi Fushen, Hi Mark,

On Tuesday 29 June 2010 23:26:54 Fushen Chen wrote:
> The DWC OTG driver module provides the initialization and cleanup
> entry points for the DWC OTG USB driver.
> 
> Signed-off-by: Fushen Chen <fchen@apm.com>
> Signed-off-by: Mark Miesfeld <mmiesfeld@apm.com>

I tried to compare this driver with the version that's currently available in 
the linux-2.6-denx repository. But the differences are quite big. Could you 
please list the history of this DWC driver? Things like:

- Which Synopsis version is it based upon?
- What changes/enhancements/fixups where made from APM?
- How was this driver tested (USB host and device mode)?

As Wolfgang already pointed out, the driver in our git repository has 
undergone multiple changes/fixes. Did you take a look at them and try to 
integrate them?

Thanks.

Cheers,
Stefan

^ permalink raw reply

* Re: [PATCH 1/9] Add Synopsys DesignWare HS USB OTG Controller driver.
From: Anton Vorontsov @ 2010-06-30  7:06 UTC (permalink / raw)
  To: David Daney
  Cc: gregkh, linux-usb, David Brownell, linuxppc-dev, Mark Miesfeld,
	Fushen Chen
In-Reply-To: <4C2A7E14.4060802@caviumnetworks.com>

On Tue, Jun 29, 2010 at 04:13:24PM -0700, David Daney wrote:
> On 06/29/2010 03:41 PM, David Brownell wrote:
> >Good -- MUSB won't be the only one.  ;)
> >
> >Could you mention a few Linux-enabled chips which
> >include this controller?
> >
> 
> I can.  Some members of the Octeon family:  arch/mips/cavium-octeon

Plus ECONA CNS3xxx (arch/arm/mach-cns3xxx).

-- 
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2

^ permalink raw reply

* Please pull my perf.git tree support
From: Paul Mackerras @ 2010-06-30  6:37 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev, Ingo Molnar, K.Prasad, Frederic Weisbecker

Ben,

When you set up your next branch for commits to go in 2.6.36-rc1,
please do a pull from:

git://git.kernel.org/pub/scm/linux/kernel/git/paulus/perf.git master

to get a series of commits that add support for hw_breakpoint events
on 64-bit POWER server processors in the perf_event subsystem.  This
consists of a commit from me that adds support for most integer
instructions to the emulate_step() function, a series from K. Prasad
that add the ppc64-specific hw_breakpoint code, and some small
commits from me that fix a few bugs that I found in testing.

There is one commit in there from K. Prasad that modifies the generic
hw_breakpoint code to add the ability to have an arch-specific
unregister hook for hw_breakpoints.  It has been acked by Frederic
Weisbecker.

Thanks,
Paul.

The following changes since commit 7e27d6e778cd87b6f2415515d7127eba53fe5d02:

  Linux 2.6.35-rc3 (2010-06-11 19:14:04 -0700)

are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/paulus/perf.git master

K.Prasad (5):
      hw_breakpoints: Allow arch-specific cleanup before breakpoint unregistration
      powerpc, hw_breakpoints: Implement hw_breakpoints for 64-bit server processors
      powerpc, hw_breakpoint: Handle concurrent alignment interrupts
      powerpc, hw_breakpoint: Enable hw-breakpoints while handling intervening signals
      powerpc, hw_breakpoint: Discard extraneous interrupt due to accesses outside symbol length

Paul Mackerras (4):
      powerpc: Emulate most Book I instructions in emulate_step()
      powerpc, hw_breakpoint: Fix off-by-one in checking access address
      powerpc, hw_breakpoint: Cooperate better with other single-steppers
      powerpc, hw_breakpoint: Tell generic code we have no instruction breakpoints

 arch/powerpc/Kconfig                     |    1 +
 arch/powerpc/include/asm/asm-compat.h    |    2 +
 arch/powerpc/include/asm/cputable.h      |    4 +
 arch/powerpc/include/asm/hw_breakpoint.h |   74 ++
 arch/powerpc/include/asm/ppc-opcode.h    |    7 +
 arch/powerpc/include/asm/processor.h     |    8 +
 arch/powerpc/kernel/Makefile             |    1 +
 arch/powerpc/kernel/exceptions-64s.S     |    1 +
 arch/powerpc/kernel/hw_breakpoint.c      |  364 +++++++
 arch/powerpc/kernel/machine_kexec_64.c   |    3 +
 arch/powerpc/kernel/process.c            |   14 +
 arch/powerpc/kernel/ptrace.c             |   64 ++
 arch/powerpc/kernel/signal.c             |    3 +
 arch/powerpc/kernel/traps.c              |    8 +-
 arch/powerpc/lib/Makefile                |    5 +-
 arch/powerpc/lib/ldstfp.S                |  375 ++++++++
 arch/powerpc/lib/sstep.c                 | 1514 +++++++++++++++++++++++++++++-
 kernel/hw_breakpoint.c                   |   12 +
 18 files changed, 2408 insertions(+), 52 deletions(-)
 create mode 100644 arch/powerpc/include/asm/hw_breakpoint.h
 create mode 100644 arch/powerpc/kernel/hw_breakpoint.c
 create mode 100644 arch/powerpc/lib/ldstfp.S

^ permalink raw reply

* Re: machine check in kernel for a mpc870 board
From: Shawn Jin @ 2010-06-30  6:14 UTC (permalink / raw)
  To: Scott Wood; +Cc: ppcdev
In-Reply-To: <20100629185617.GA24285@schlenkerla.am.freescale.net>

Hi Scott,

>> Bus Fault @ 0x00404c40, fixup 0x00000000
>> Machine check in kernel mode.
>> Caused by (from msr): regs 07d1cb80 Unknown values in msr
>> NIP: 00404C40 XER: 00000000 LR: 00404C24 REGS: 07d1cb80 TRAP: 0200 DAR: 00000001
>> MSR: 00001002 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 00
>
> Can you look up the source line/instruction corresponding to 0x404c40, in
> the wrapper ELF file?

I'm not sure how to look up it. But I used the BDI to dump the
instructions in which you may find some clue? These should be kernel
code, right? Maybe the gdb can help to de-assemble them?

BDI>md 0x404c00 0x20
00404c00 : 0x4800317d   1207972221  H.1}
00404c04 : 0x80010014  -2147418092  ....
00404c08 : 0xbbc10008  -1144979448  ....
00404c0c : 0x7c0803a6   2080900006  |...
00404c10 : 0x38210010    941686800  8!..
00404c14 : 0x4e800020   1317011488  N..
00404c18 : 0x9421fff0  -1809711120  .!..
00404c1c : 0x7c0802a6   2080899750  |...
00404c20 : 0x429f0005   1117716485  B...
00404c24 : 0xbfc10008  -1077870584  ....
00404c28 : 0x7fc802a6   2143814310  ....
00404c2c : 0x90010014  -1878982636  ....
00404c30 : 0x3fde0001   1071513601  ?...
00404c34 : 0x3bdedd98   1004461464  ;...
00404c38 : 0x813e8000  -2126610432  .>..
00404c3c : 0x81490000  -2125922304  .I..
00404c40 : 0xa00a0000  -1609957376  ....
00404c44 : 0x0c000000    201326592  ....
00404c48 : 0x4c00012c   1275068716  L..,
00404c4c : 0x70090001   1879638017  p...
00404c50 : 0x4082fff0   1082327024  @...
00404c54 : 0x817e8000  -2122416128  .~..
00404c58 : 0x5469402e   1416183854  Ti@.

Thanks a lot,
-Shawn.

^ permalink raw reply

* [PATCH] powerpc: fix module building for gcc 4.5 and 64 bit
From: Stephen Rothwell @ 2010-06-30  6:08 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Michal Marek, Sam Ravnborg, Rusty Russell, ppc-dev, linux-kernel

Gcc 4.5 is now generating out of line register save and restore
in the function prefix and postfix when we use -Os.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/Makefile        |    4 +-
 arch/powerpc/lib/Makefile    |    4 +-
 arch/powerpc/lib/crtsavres.S |  129 ++++++++++++++++++++++++++++++++++++++++++
 scripts/mod/modpost.c        |    5 ++
 4 files changed, 138 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 42dcd3f..77cfe7a 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -92,10 +92,10 @@ endif
 else
 	KBUILD_CFLAGS += $(call cc-option,-mtune=power4)
 endif
-else
-LDFLAGS_MODULE	+= arch/powerpc/lib/crtsavres.o
 endif
 
+LDFLAGS_MODULE	+= arch/powerpc/lib/crtsavres.o
+
 ifeq ($(CONFIG_TUNE_CELL),y)
 	KBUILD_CFLAGS += $(call cc-option,-mtune=cell)
 endif
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 3040dac..111da1c 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -12,8 +12,8 @@ CFLAGS_REMOVE_code-patching.o = -pg
 CFLAGS_REMOVE_feature-fixups.o = -pg
 
 obj-y			:= string.o alloc.o \
-			   checksum_$(CONFIG_WORD_SIZE).o
-obj-$(CONFIG_PPC32)	+= div64.o copy_32.o crtsavres.o
+			   checksum_$(CONFIG_WORD_SIZE).o crtsavres.o
+obj-$(CONFIG_PPC32)	+= div64.o copy_32.o
 obj-$(CONFIG_HAS_IOMEM)	+= devres.o
 
 obj-$(CONFIG_PPC64)	+= copypage_64.o copyuser_64.o \
diff --git a/arch/powerpc/lib/crtsavres.S b/arch/powerpc/lib/crtsavres.S
index 70a9cd8..1c893f0 100644
--- a/arch/powerpc/lib/crtsavres.S
+++ b/arch/powerpc/lib/crtsavres.S
@@ -6,6 +6,7 @@
  *   Written By Michael Meissner
  *
  * Based on gcc/config/rs6000/crtsavres.asm from gcc
+ * 64 bit additions from reading the PPC elf64abi document.
  *
  * This file is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -44,6 +45,8 @@
 
 #ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
 
+#ifndef CONFIG_PPC64
+
 /* Routines for saving integer registers, called by the compiler.  */
 /* Called with r11 pointing to the stack header word of the caller of the */
 /* function, just beyond the end of the integer save area.  */
@@ -226,4 +229,130 @@ _GLOBAL(_rest32gpr_31_x)
 	mtlr	0
 	mr	1,11
 	blr
+
+#else /* CONFIG_PPC64 */
+
+.globl	_savegpr0_14
+_savegpr0_14:
+	std	r14,-144(r1)
+.globl	_savegpr0_15
+_savegpr0_15:
+	std	r15,-136(r1)
+.globl	_savegpr0_16
+_savegpr0_16:
+	std	r16,-128(r1)
+.globl	_savegpr0_17
+_savegpr0_17:
+	std	r17,-120(r1)
+.globl	_savegpr0_18
+_savegpr0_18:
+	std	r18,-112(r1)
+.globl	_savegpr0_19
+_savegpr0_19:
+	std	r19,-104(r1)
+.globl	_savegpr0_20
+_savegpr0_20:
+	std	r20,-96(r1)
+.globl	_savegpr0_21
+_savegpr0_21:
+	std	r21,-88(r1)
+.globl	_savegpr0_22
+_savegpr0_22:
+	std	r22,-80(r1)
+.globl	_savegpr0_23
+_savegpr0_23:
+	std	r23,-72(r1)
+.globl	_savegpr0_24
+_savegpr0_24:
+	std	r24,-64(r1)
+.globl	_savegpr0_25
+_savegpr0_25:
+	std	r25,-56(r1)
+.globl	_savegpr0_26
+_savegpr0_26:
+	std	r26,-48(r1)
+.globl	_savegpr0_27
+_savegpr0_27:
+	std	r27,-40(r1)
+.globl	_savegpr0_28
+_savegpr0_28:
+	std	r28,-32(r1)
+.globl	_savegpr0_29
+_savegpr0_29:
+	std	r29,-24(r1)
+.globl	_savegpr0_30
+_savegpr0_30:
+	std	r30,-16(r1)
+.globl	_savegpr0_31
+_savegpr0_31:
+	std	r31,-8(r1)
+	std	r0,16(r1)
+	blr
+
+.globl	_restgpr0_14
+_restgpr0_14:
+	ld	r14,-144(r1)
+.globl	_restgpr0_15
+_restgpr0_15:
+	ld	r15,-136(r1)
+.globl	_restgpr0_16
+_restgpr0_16:
+	ld	r16,-128(r1)
+.globl	_restgpr0_17
+_restgpr0_17:
+	ld	r17,-120(r1)
+.globl	_restgpr0_18
+_restgpr0_18:
+	ld	r18,-112(r1)
+.globl	_restgpr0_19
+_restgpr0_19:
+	ld	r19,-104(r1)
+.globl	_restgpr0_20
+_restgpr0_20:
+	ld	r20,-96(r1)
+.globl	_restgpr0_21
+_restgpr0_21:
+	ld	r21,-88(r1)
+.globl	_restgpr0_22
+_restgpr0_22:
+	ld	r22,-80(r1)
+.globl	_restgpr0_23
+_restgpr0_23:
+	ld	r23,-72(r1)
+.globl	_restgpr0_24
+_restgpr0_24:
+	ld	r24,-64(r1)
+.globl	_restgpr0_25
+_restgpr0_25:
+	ld	r25,-56(r1)
+.globl	_restgpr0_26
+_restgpr0_26:
+	ld	r26,-48(r1)
+.globl	_restgpr0_27
+_restgpr0_27:
+	ld	r27,-40(r1)
+.globl	_restgpr0_28
+_restgpr0_28:
+	ld	r28,-32(r1)
+.globl	_restgpr0_29
+_restgpr0_29:
+	ld	r0,16(r1)
+	ld	r29,-24(r1)
+	mtlr	r0
+	ld	r30,-16(r1)
+	ld	r31,-8(r1)
+	blr
+
+.globl	_restgpr0_30
+_restgpr0_30:
+	ld	r30,-16(r1)
+.globl	_restgpr0_31
+_restgpr0_31:
+	ld	r0,16(r1)
+	ld	r31,-8(r1)
+	mtlr	r0
+	blr
+
+#endif /* CONFIG_PPC64 */
+
 #endif
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index f877900..f6127b9 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -503,6 +503,11 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname)
 		    strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 ||
 		    strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0)
 			return 1;
+	if (info->hdr->e_machine == EM_PPC64)
+		/* Special register function linked on all modules during final link of .ko */
+		if (strncmp(symname, "_restgpr0_", sizeof("_restgpr0_") - 1) == 0 ||
+		    strncmp(symname, "_savegpr0_", sizeof("_savegpr0_") - 1) == 0)
+			return 1;
 	/* Do not ignore this symbol */
 	return 0;
 }
-- 
1.7.1

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

^ permalink raw reply related

* [PATCH] powerpc: fix compile errors in prom_init_check for gcc 4.5
From: Stephen Rothwell @ 2010-06-30  6:04 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: ppc-dev

Just whitelist these extra compiler generated symbols.
Fixes these errors:

Error: External symbol '_restgpr0_14' referenced from prom_init.c
Error: External symbol '_restgpr0_20' referenced from prom_init.c
Error: External symbol '_restgpr0_22' referenced from prom_init.c
Error: External symbol '_restgpr0_24' referenced from prom_init.c
Error: External symbol '_restgpr0_25' referenced from prom_init.c
Error: External symbol '_restgpr0_26' referenced from prom_init.c
Error: External symbol '_restgpr0_27' referenced from prom_init.c
Error: External symbol '_restgpr0_28' referenced from prom_init.c
Error: External symbol '_restgpr0_29' referenced from prom_init.c
Error: External symbol '_restgpr0_31' referenced from prom_init.c
Error: External symbol '_savegpr0_14' referenced from prom_init.c
Error: External symbol '_savegpr0_20' referenced from prom_init.c
Error: External symbol '_savegpr0_22' referenced from prom_init.c
Error: External symbol '_savegpr0_24' referenced from prom_init.c
Error: External symbol '_savegpr0_25' referenced from prom_init.c
Error: External symbol '_savegpr0_26' referenced from prom_init.c
Error: External symbol '_savegpr0_27' referenced from prom_init.c
Error: External symbol '_savegpr0_28' referenced from prom_init.c
Error: External symbol '_savegpr0_29' referenced from prom_init.c
Error: External symbol '_savegpr0_31' referenced from prom_init.c

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/kernel/prom_init_check.sh |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
index 1ac136b..9f82f49 100644
--- a/arch/powerpc/kernel/prom_init_check.sh
+++ b/arch/powerpc/kernel/prom_init_check.sh
@@ -52,12 +52,18 @@ do
 	if [ "${UNDEF:0:9}" = "_restgpr_" ]; then
 		OK=1
 	fi
+	if [ "${UNDEF:0:10}" = "_restgpr0_" ]; then
+		OK=1
+	fi
 	if [ "${UNDEF:0:11}" = "_rest32gpr_" ]; then
 		OK=1
 	fi
 	if [ "${UNDEF:0:9}" = "_savegpr_" ]; then
 		OK=1
 	fi
+	if [ "${UNDEF:0:10}" = "_savegpr0_" ]; then
+		OK=1
+	fi
 	if [ "${UNDEF:0:11}" = "_save32gpr_" ]; then
 		OK=1
 	fi
-- 
1.7.1

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

^ permalink raw reply related

* Re: CONFIG_NO_HZ causing poor console responsiveness
From: Richard Cochran @ 2010-06-30  6:49 UTC (permalink / raw)
  To: Timur Tabi; +Cc: Linuxppc-dev Development
In-Reply-To: <AANLkTilMzfwgYvoFhxhcVQVGV-EkMLVHI2TeQ29SYFCH@mail.gmail.com>

On Tue, Jun 29, 2010 at 02:54:17PM -0500, Timur Tabi wrote:
> I'm adding support for a new e500-based board (the P1022DS), and in
> the process I've discovered that enabling CONFIG_NO_HZ (Tickless
> System / Dynamic Ticks) causes significant responsiveness problems on
> the serial console.  When I type on the console, I see delays of up to
> a half-second for almost every character.  It acts as if there's a
> background process eating all the CPU.
> 
> I don't have time to debug this thoroughly at the moment.  The problem
> occurs in the latest kernel, but it appears not to occur in 2.6.32.
> 
> Has anyone else seen anything like this?

Yes, with a P2020RDB and kernel 2.6.35-rc1. Serial console is really
slow on an otherwise idle machine. I assumed it was a hardware
problem.

Richard

^ permalink raw reply

* Re: [PATCH 4/9] Add Synopsys DesignWare HS USB OTG Controller driver.
From: Wolfgang Denk @ 2010-06-30  5:31 UTC (permalink / raw)
  To: David Daney; +Cc: linuxppc-dev, linux-usb, Mark Miesfeld, gregkh, Fushen Chen
In-Reply-To: <4C2A8038.50204@caviumnetworks.com>

Dear David Daney,

In message <4C2A8038.50204@caviumnetworks.com> you wrote:
>
> > Why are you posting this old driver version without trying to sync
> > against our tree which includes a number of fixes - you should know
> > about these.
> >
> 
> This could be a question with an obvious answer, but which tree are you 
> referring to when you say 'our tree'?

git://git.denx.de/linux-2.6-denx.git

Fushen Chen should know this, as the fixes I've mentioned were part
of contract/support work for Applied Micro.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
The Wright Bothers weren't the first to fly. They were just the first
not to crash.

^ permalink raw reply

* Re: [linuxppc-release] [PATCH] powerpc: introduce basic support for the Freescale P1022DS reference board
From: Olof Johansson @ 2010-06-30  2:24 UTC (permalink / raw)
  To: Tabi Timur-B04825; +Cc: linuxppc-dev
In-Reply-To: <5610599F537DD74A8D1F5CC946A7507303478FFA@az33exm25.fsl.freescale.net>

On Tue, Jun 29, 2010 at 06:16:08PM -0700, Tabi Timur-B04825 wrote:
> Olof Johansson wrote:
> > Sure, the family-defconfigs are supposed to be supersets that can boot
> > everywhere. If you're concerned about static kernel size you can always
> > enable it as modules instead.
> 
> It just seems wrong to add full support for audio and video in the kernel, 
> when it can be used only on one, relatively obscure chip.  Video support 
> would need to be in-kernel only in order to get the console working, and I 
> suspect that core ALSA support would need to be in-kernel as well.

See the text you quoted from me above, it applies at a reply to this as well.


-Olof

^ permalink raw reply

* Re: [linuxppc-release] [PATCH] powerpc: introduce basic support for the Freescale P1022DS reference board
From: Tabi Timur-B04825 @ 2010-06-30  1:16 UTC (permalink / raw)
  To: Olof Johansson; +Cc: linuxppc-dev
In-Reply-To: <20100630011000.GA2684@lixom.net>

[-- Attachment #1: Type: text/plain, Size: 547 bytes --]

Olof Johansson wrote:
> Sure, the family-defconfigs are supposed to be supersets that can boot
> everywhere. If you're concerned about static kernel size you can always
> enable it as modules instead.

It just seems wrong to add full support for audio and video in the kernel, 
when it can be used only on one, relatively obscure chip.  Video support 
would need to be in-kernel only in order to get the console working, and I 
suspect that core ALSA support would need to be in-kernel as well.

-- 
Timur Tabi
Linux kernel developer

[-- Attachment #2: Type: text/html, Size: 1057 bytes --]

^ permalink raw reply

* Re: [linuxppc-release] [PATCH] powerpc: introduce basic support for the Freescale P1022DS reference board
From: Olof Johansson @ 2010-06-30  1:10 UTC (permalink / raw)
  To: Tabi Timur-B04825; +Cc: linuxppc-dev
In-Reply-To: <5610599F537DD74A8D1F5CC946A7507303478FF8@az33exm25.fsl.freescale.net>

On Tue, Jun 29, 2010 at 04:37:59PM -0700, Tabi Timur-B04825 wrote:
> Kumar Gala wrote:
> 
> > Drop the defconfig and update mpc85xx_{smp_}defconfig to build p1022.
> 
> What about video and audio support?  I'm going to add that later?  We don't 
> want to compile the DIU and SSI drivers on all 85xx systems, do we?

Sure, the family-defconfigs are supposed to be supersets that can boot
everywhere. If you're concerned about static kernel size you can always
enable it as modules instead.


-Olof

^ permalink raw reply

* Re: kernel init exception
From: David Gibson @ 2010-06-30  0:46 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: linuxppc-dev, wilbur.chan
In-Reply-To: <356261A9-B09F-4E82-A897-FD0724C503F4@kernel.crashing.org>

On Tue, Jun 29, 2010 at 06:51:16PM +0200, Segher Boessenkool wrote:
> >why there generated a signal 4  in  init  process?
> 
> That's SIGILL; sounds like you compiled init with the wrong (sub-)arch
> or cpu flags.

Or it's been corrupted during load.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [PATCH] powerpc: introduce basic support for the Freescale P1022DS reference board
From: Kim Phillips @ 2010-06-29 23:55 UTC (permalink / raw)
  To: Tabi Timur-B04825; +Cc: linuxppc-dev
In-Reply-To: <5610599F537DD74A8D1F5CC946A7507303478FF9@az33exm25.fsl.freescale.net>

On Tue, 29 Jun 2010 17:39:17 -0600
"Tabi Timur-B04825" <B04825@freescale.com> wrote:

> Kim Phillips wrote:
> > On Tue, 29 Jun 2010 16:34:34 -0500
> > Timur Tabi<timur@freescale.com>  wrote:
> >
> >> Introduce basic support for the Freescale P1022DS reference board, based on the
> >> Freescale BSP for this board.
> >>
> >> Details: No DIU video or SSI audio support, no MMC/SD card support, 36-bit and
> >> SWIOTLB support enabled, 36-bit DTS only, and CONFIG_NO_HZ disabled because it
> >> causes performance problems on this kernel.
> >
> > what kind of performance problems?
> 
> See my post on linuxppc-dev about CONFIG_NO_HZ.

looks like it should be easily bisected, esp. since
mpc85xx_smp_defconfig has NO_HZ=y.

> >> +			queue-group@0{
> >> +				#address-cells =<1>;
> >> +				#size-cells =<1>;
> >> +				reg =<0xB1000 0x1000>;
> >> +				fsl,rx-err-int-map =<0xAA>;
> >> +				fsl,tx-int-map =<0xAA>;
> >> +				interrupts =<35 2 36 2 40 2>;
> >> +			};
> >> +			queue-group@1{
> >> +				#address-cells =<1>;
> >> +				#size-cells =<1>;
> >> +				reg =<0xB5000 0x1000>;
> >> +				fsl,rx-err-int-map =<0x55>;
> >> +				fsl,tx-int-map =<0x55>;
> >> +				interrupts =<51 2 52 2 67 2>;
> >> +			};
> >
> > these queue-group nodes, fsl,{r,t}x-* properties...
> 
> I just copied this tree from the BSP.  I have no idea what they should ok 
> like.  Can you be more specific?

eh?  you submitted the patch; I'm just calling out the
foreign/undocumented matter in it.

> >> +		crypto@30000 {
> >
> >> +			fsl,multi-host-mode = "dual";
> >> +			fsl,channel-remap =<0x3>;
> >
> > and the above two properties aren't supported by their respective
> > drivers, nor are they listed in the dts bindings documentation.
> 
> Then please tell me what these nodes should look like.

delete them?

Kim

^ permalink raw reply

* Re: [PATCH] powerpc: introduce basic support for the Freescale P1022DS reference board
From: Tabi Timur-B04825 @ 2010-06-29 23:39 UTC (permalink / raw)
  To: Phillips Kim-R1AAHA; +Cc: linuxppc-dev
In-Reply-To: <20100629171904.d6ae6233.kim.phillips@freescale.com>

[-- Attachment #1: Type: text/plain, Size: 1510 bytes --]

Kim Phillips wrote:
> On Tue, 29 Jun 2010 16:34:34 -0500
> Timur Tabi<timur@freescale.com>  wrote:
>
>> Introduce basic support for the Freescale P1022DS reference board, based on the
>> Freescale BSP for this board.
>>
>> Details: No DIU video or SSI audio support, no MMC/SD card support, 36-bit and
>> SWIOTLB support enabled, 36-bit DTS only, and CONFIG_NO_HZ disabled because it
>> causes performance problems on this kernel.
>
> what kind of performance problems?

See my post on linuxppc-dev about CONFIG_NO_HZ.

>> +			queue-group@0{
>> +				#address-cells =<1>;
>> +				#size-cells =<1>;
>> +				reg =<0xB1000 0x1000>;
>> +				fsl,rx-err-int-map =<0xAA>;
>> +				fsl,tx-int-map =<0xAA>;
>> +				interrupts =<35 2 36 2 40 2>;
>> +			};
>> +			queue-group@1{
>> +				#address-cells =<1>;
>> +				#size-cells =<1>;
>> +				reg =<0xB5000 0x1000>;
>> +				fsl,rx-err-int-map =<0x55>;
>> +				fsl,tx-int-map =<0x55>;
>> +				interrupts =<51 2 52 2 67 2>;
>> +			};
>
> these queue-group nodes, fsl,{r,t}x-* properties...

I just copied this tree from the BSP.  I have no idea what they should ok 
like.  Can you be more specific?

>> +		crypto@30000 {
>
>> +			fsl,multi-host-mode = "dual";
>> +			fsl,channel-remap =<0x3>;
>
> and the above two properties aren't supported by their respective
> drivers, nor are they listed in the dts bindings documentation.

Then please tell me what these nodes should look like.


-- 
Timur Tabi
Linux kernel developer

[-- Attachment #2: Type: text/html, Size: 4833 bytes --]

^ permalink raw reply

* Re: [linuxppc-release] [PATCH] powerpc: introduce basic support for the Freescale P1022DS reference board
From: Tabi Timur-B04825 @ 2010-06-29 23:37 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <22ED4111-892C-4715-BF70-C1E62F838DDA@kernel.crashing.org>

[-- Attachment #1: Type: text/plain, Size: 286 bytes --]

Kumar Gala wrote:

> Drop the defconfig and update mpc85xx_{smp_}defconfig to build p1022.

What about video and audio support?  I'm going to add that later?  We don't 
want to compile the DIU and SSI drivers on all 85xx systems, do we?

-- 
Timur Tabi
Linux kernel developer

[-- Attachment #2: Type: text/html, Size: 785 bytes --]

^ permalink raw reply

* Re: [PATCH 1/9] Add Synopsys DesignWare HS USB OTG Controller driver.
From: David Daney @ 2010-06-29 23:13 UTC (permalink / raw)
  To: David Brownell
  Cc: linuxppc-dev, linux-usb, Mark Miesfeld, gregkh, Fushen Chen
In-Reply-To: <5569.83301.qm@web180304.mail.gq1.yahoo.com>

On 06/29/2010 03:41 PM, David Brownell wrote:
> Good -- MUSB won't be the only one.  ;)
>
> Could you mention a few Linux-enabled chips which
> include this controller?
>

I can.  Some members of the Octeon family:  arch/mips/cavium-octeon

Although there would probably be some SOC specific glue needed for chips 
not targeted by the initial patch set.

David Daney


>
>>   arch/powerpc/boot/dts/kilauea.dts |   15 +
>
> Also, please provide a clean patch that only
> includes the driver, and split PPC hooks into
> a separate patch.
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* Re: [PATCH 4/9] Add Synopsys DesignWare HS USB OTG Controller driver.
From: David Daney @ 2010-06-29 23:22 UTC (permalink / raw)
  To: Wolfgang Denk; +Cc: linuxppc-dev, linux-usb, Mark Miesfeld, gregkh, Fushen Chen
In-Reply-To: <20100629231302.7E6E314EBF8@gemini.denx.de>

On 06/29/2010 04:13 PM, Wolfgang Denk wrote:
> Dear Fushen Chen,
>
> In message<1277846824673-git-send-email-fchen@apm.com>  you wrote:
>> Implements DWC OTG USB Host Controller Driver (HCD) and interface to
>> USB Host controller Driver framework.
>>
>> Signed-off-by: Fushen Chen<fchen@apm.com>
>> Signed-off-by: Mark Miesfeld<mmiesfeld@apm.com>
>> ---
>>   drivers/usb/otg/dwc_otg_hcd.c | 2397 +++++++++++++++++++++++++++++++++++++++++
>>   drivers/usb/otg/dwc_otg_hcd.h |  421 ++++++++
>>   2 files changed, 2818 insertions(+), 0 deletions(-)
>>   create mode 100644 drivers/usb/otg/dwc_otg_hcd.c
>>   create mode 100644 drivers/usb/otg/dwc_otg_hcd.h
>
>
> Why are you posting this old driver version without trying to sync
> against our tree which includes a number of fixes - you should know
> about these.
>

This could be a question with an obvious answer, but which tree are you 
referring to when you say 'our tree'?

David Daney

^ permalink raw reply

* Re: [PATCH 4/9] Add Synopsys DesignWare HS USB OTG Controller driver.
From: Wolfgang Denk @ 2010-06-29 23:13 UTC (permalink / raw)
  To: Fushen Chen; +Cc: linuxppc-dev, linux-usb, Mark Miesfeld, gregkh
In-Reply-To: <1277846824673-git-send-email-fchen@apm.com>

Dear Fushen Chen,

In message <1277846824673-git-send-email-fchen@apm.com> you wrote:
> Implements DWC OTG USB Host Controller Driver (HCD) and interface to
> USB Host controller Driver framework.
> 
> Signed-off-by: Fushen Chen <fchen@apm.com>
> Signed-off-by: Mark Miesfeld <mmiesfeld@apm.com>
> ---
>  drivers/usb/otg/dwc_otg_hcd.c | 2397 +++++++++++++++++++++++++++++++++++++++++
>  drivers/usb/otg/dwc_otg_hcd.h |  421 ++++++++
>  2 files changed, 2818 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/usb/otg/dwc_otg_hcd.c
>  create mode 100644 drivers/usb/otg/dwc_otg_hcd.h


Why are you posting this old driver version without trying to sync
against our tree which includes a number of fixes - you should know
about these.

...
> +		do {
> +			hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
> +			if (++count > 10000) {
> +				printk(KERN_ERR "%s: Unable to clear halt on "
> +						"channel %d\n",	__func__, i);
> +				break;
> +			}
> +		} while (hcchar.b.chen);
> +	}

For example, here you are missing

	commit 018b43db153da063182c87be2eaad037cba2d879
	Author: Stefan Roese <sr@denx.de>
	Date:   Thu Sep 24 17:15:06 2009 +0200

	    USB: Fix timeout problem with polling loops in DWC USB-OTG driver


In [PATCH 6/9] Add Synopsys DesignWare HS USB OTG Controller driver
you are missing

	commit 538fe70d696bc5e694ab08e9627a99a0b11358ec
	Author: Stefan Roese <sr@denx.de>
	Date:   Wed Sep 23 08:50:29 2009 +0200

	    USB: Fix problem with reconnection in DWC USB-OTG driver

etc.


Please update your code and resubmit.



Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
The biggest difference between time and space is that you can't reuse
time.                                                 - Merrick Furst

^ permalink raw reply

* Re: [PATCH 1/9] Add Synopsys DesignWare HS USB OTG Controller driver.
From: David Brownell @ 2010-06-29 22:41 UTC (permalink / raw)
  To: linux-usb, Fushen Chen; +Cc: linuxppc-dev, gregkh, Mark Miesfeld, Fushen Chen
In-Reply-To: <12778468223309-git-send-email-fchen@apm.com>

Good -- MUSB won't be the only one.  ;)=0A=0ACould you mention a few Linux-=
enabled chips which=0Ainclude this controller?=0A=0A=0A>  arch/powerpc/boot=
/dts/kilauea.dts |=A0=A0=A015 +=0A=0AAlso, please provide a clean patch tha=
t only=0Aincludes the driver, and split PPC hooks into=0Aa separate patch.=
=0A=0A

^ permalink raw reply

* [PATCH 9/9] Add Synopsys DesignWare HS USB OTG Controller driver.
From: Fushen Chen @ 2010-06-29 21:27 UTC (permalink / raw)
  To: linux-usb; +Cc: linuxppc-dev, gregkh, Mark Miesfeld, Fushen Chen
In-Reply-To: <1277846824716-git-send-email-fchen@apm.com>

Interfaces with the DWC HS OTG core by reading from and writing to
the Control and Status Register (CSR).

CSRs are classified as follows:
 - Core Global Registers
 - Device Mode Registers
 - Device Global Registers
 - Device Endpoint Specific Registers
 - Host Mode Registers
 - Host Global Registers
 - Host Port CSRs
 - Host Channel Specific Registers

Signed-off-by: Fushen Chen <fchen@apm.com>
Signed-off-by: Mark Miesfeld <mmiesfeld@apm.com>
---
 drivers/usb/otg/dwc_otg_regs.h | 3283 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 3283 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/otg/dwc_otg_regs.h

diff --git a/drivers/usb/otg/dwc_otg_regs.h b/drivers/usb/otg/dwc_otg_regs.h
new file mode 100644
index 0000000..413ee9d
--- /dev/null
+++ b/drivers/usb/otg/dwc_otg_regs.h
@@ -0,0 +1,3283 @@
+/*
+ * DesignWare HS OTG controller driver
+ *
+ * Author: Mark Miesfeld <mmiesfeld@apm.com>
+ *
+ * Based on versions provided by AMCC and Synopsis which are:
+ *	Copyright (C) 2009-2010 AppliedMicro(www.apm.com)
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __DWC_OTG_REGS_H__
+#define __DWC_OTG_REGS_H__
+
+#include <linux/types.h>
+
+/*
+ * This file contains the data structures for accessing the DWC_otg core
+ * registers.
+ *
+ * The application interfaces with the HS OTG core by reading from and
+ * writing to the Control and Status Register (CSR) space through the
+ * AHB Slave interface. These registers are 32 bits wide, and the
+ * addresses are 32-bit-block aligned.
+ * CSRs are classified as follows:
+ * - Core Global Registers
+ * - Device Mode Registers
+ * - Device Global Registers
+ * - Device Endpoint Specific Registers
+ * - Host Mode Registers
+ * - Host Global Registers
+ * - Host Port CSRs
+ * - Host Channel Specific Registers
+ *
+ * Only the Core Global registers can be accessed in both Device and
+ * Host modes. When the HS OTG core is operating in one mode, either
+ * Device or Host, the application must not access registers from the
+ * other mode. When the core switches from one mode to another, the
+ * registers in the new mode of operation must be reprogrammed as they
+ * would be after a power-on reset.
+ */
+
+/*
+ * DWC_otg Core registers.  The core_global_regs structure defines the
+ * size and relative field offsets for the Core Global registers.
+ */
+struct core_global_regs {
+	/* OTG Control and Status Register.		Offset: 000h */
+	u32 gotgctl;
+	/* OTG Interrupt Register.			Offset: 004h */
+	u32 gotgint;
+	/* Core AHB Configuration Register.		Offset: 008h */
+	u32 gahbcfg;
+
+#define DWC_GLBINTRMASK				0x0001
+#define DWC_DMAENABLE				0x0020
+#define DWC_NPTXEMPTYLVL_EMPTY			0x0080
+#define DWC_NPTXEMPTYLVL_HALFEMPTY		0x0000
+#define DWC_PTXEMPTYLVL_EMPTY			0x0100
+#define DWC_PTXEMPTYLVL_HALFEMPTY		0x0000
+
+	/* Core USB Configuration Register.		Offset: 00Ch */
+	u32 gusbcfg;
+	/* Core Reset Register.				Offset: 010h */
+	u32 grstctl;
+	/* Core Interrupt Register.			Offset: 014h */
+	u32 gintsts;
+	/* Core Interrupt Mask Register.		Offset: 018h */
+	u32 gintmsk;
+	/*
+	 * Receive Status Queue Read Register
+	 * (Read Only)					Offset: 01Ch
+	 */
+	u32 grxstsr;
+	/*
+	 * Receive Status Queue Read & POP Register
+	 * (Read Only)					Offset: 020h
+	 */
+	u32 grxstsp;
+	/* Receive FIFO Size Register.			Offset: 024h */
+	u32 grxfsiz;
+	/* Non Periodic Transmit FIFO Size Register.	Offset: 028h */
+	u32 gnptxfsiz;
+	/*
+	 * Non Periodic Transmit FIFO/Queue Status Register
+	 * (Read Only).					Offset: 02Ch
+	 */
+	u32 gnptxsts;
+	/* I2C Access Register.				Offset: 030h */
+	u32 gi2cctl;
+	/* PHY Vendor Control Register.			Offset: 034h */
+	u32 gpvndctl;
+	/* General Purpose Input/Output Register.	Offset: 038h */
+	u32 ggpio;
+	/* User ID Register.				Offset: 03Ch */
+	u32 guid;
+	/* Synopsys ID Register (Read Only).		Offset: 040h */
+	u32 gsnpsid;
+	/* User HW Config1 Register (Read Only).	Offset: 044h */
+	u32 ghwcfg1;
+	/* User HW Config2 Register (Read Only).	Offset: 048h */
+	u32 ghwcfg2;
+#define DWC_SLAVE_ONLY_ARCH			0
+#define DWC_EXT_DMA_ARCH			1
+#define DWC_INT_DMA_ARCH			2
+
+#define DWC_MODE_HNP_SRP_CAPABLE		0
+#define DWC_MODE_SRP_ONLY_CAPABLE		1
+#define DWC_MODE_NO_HNP_SRP_CAPABLE		2
+#define DWC_MODE_SRP_CAPABLE_DEVICE		3
+#define DWC_MODE_NO_SRP_CAPABLE_DEVICE		4
+#define DWC_MODE_SRP_CAPABLE_HOST		5
+#define DWC_MODE_NO_SRP_CAPABLE_HOST		6
+
+	/* User HW Config3 Register (Read Only).	Offset: 04Ch */
+	u32 ghwcfg3;
+	/* User HW Config4 Register (Read Only).	Offset: 050h */
+	u32 ghwcfg4;
+	/*  Reserved					Offset: 054h-0FFh */
+	u32 reserved[43];
+	/*  Host Periodic Transmit FIFO Size Register.	Offset: 100h */
+	u32 hptxfsiz;
+
+	/*
+	 * Device Periodic Transmit FIFO#n Register, if dedicated fifos are
+	 * disabled.  Otherwise Device Transmit FIFO#n Register.
+	 *
+	 * Offset: 104h + (FIFO_Number-1)*04h, 1 <= FIFO Number <= 15 (1<=n<=15)
+	 */
+	u32 dptxfsiz_dieptxf[15];
+};
+
+
+#if defined(CONFIG_DWC_OTG_REG_LE)
+/*
+ * This union represents the bit fields of the Core OTG Controland Status
+ * Register (GOTGCTL).  Set the bits using the bit fields then write the d32
+ * value to the register.
+ */
+union gotgctl_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved31_21:11;
+		unsigned currmod:1;
+		unsigned bsesvld:1;
+		unsigned asesvld:1;
+		unsigned reserved17:1;
+		unsigned conidsts:1;
+		unsigned reserved1_12:4;
+		unsigned devhnpen:1;
+		unsigned hstsethnpen:1;
+		unsigned hnpreq:1;
+		unsigned hstnegscs:1;
+		unsigned reserved07_02:6;
+		unsigned sesreq:1;
+		unsigned sesreqscs:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields of the Core OTG Interrupt Register
+ * (GOTGINT).  Set/clear the bits using the bit fields then write the d32
+ * value to the register.
+ */
+union gotgint_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		/* Current Mode */
+		unsigned reserved31_20:12;
+		/* Debounce Done */
+		unsigned debdone:1;
+		/* A-Device Timeout Change */
+		unsigned adevtoutchng:1;
+		/* Host Negotiation Detected */
+		unsigned hstnegdet:1;
+		unsigned reserver16_10:7;
+		/* Host Negotiation Success Status Change */
+		unsigned hstnegsucstschng:1;
+		/* Session Request Success Status Change */
+		unsigned sesreqsucstschng:1;
+		unsigned reserved3_7:5;
+		/* Session End Detected */
+		unsigned sesenddet:1;
+		unsigned reserved01_00:2;
+	} b;
+};
+
+/*
+ * This union represents the bit fields of the Core AHB Configuration Register
+ * (GAHBCFG).  Set/clear the bits using the bit fields then write the d32 value
+ * to the register.
+ */
+union gahbcfg_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved9_31:23;
+		unsigned ptxfemplvl:1;
+#define DWC_GAHBCFG_TXFEMPTYLVL_EMPTY		1
+#define DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY	0
+
+		unsigned nptxfemplvl_txfemplvl:1;
+		unsigned reserved:1;
+		unsigned dmaenable:1;
+#define DWC_GAHBCFG_DMAENABLE			1
+
+		unsigned hburstlen:4;
+#define DWC_GAHBCFG_INT_DMA_BURST_SINGLE	0
+#define DWC_GAHBCFG_INT_DMA_BURST_INCR		1
+#define DWC_GAHBCFG_INT_DMA_BURST_INCR4	3
+#define DWC_GAHBCFG_INT_DMA_BURST_INCR8	5
+#define DWC_GAHBCFG_INT_DMA_BURST_INCR16	7
+
+		unsigned glblintrmsk:1;
+#define DWC_GAHBCFG_GLBINT_ENABLE		1
+	} b;
+};
+
+/*
+ * This union represents the bit fields of the Core USB Configuration Register
+ * (GUSBCFG).  Set the bits using the bit fields then write the d32 value to the
+ * register.
+ */
+union gusbcfg_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned corrupt_tx_packet:1;
+		unsigned force_device_mode:1;
+		unsigned force_host_mode:1;
+		unsigned reserved23_28:6;
+		unsigned term_sel_dl_pulse:1;
+		unsigned ulpi_int_vbus_indicator:1;
+		unsigned ulpi_ext_vbus_drv:1;
+		unsigned ulpi_clk_sus_m:1;
+		unsigned ulpi_auto_res:1;
+		unsigned ulpi_fsls:1;
+
+		unsigned otgutmifssel:1;
+		unsigned phylpwrclksel:1;
+		unsigned nptxfrwnden:1;
+		unsigned usbtrdtim:4;
+		unsigned hnpcap:1;
+		unsigned srpcap:1;
+		unsigned ddrsel:1;
+		unsigned physel:1;
+		unsigned fsintf:1;
+		unsigned ulpi_utmi_sel:1;
+		unsigned phyif:1;
+		unsigned toutcal:3;
+	} b;
+};
+
+/*
+ * This union represents the bit fields of the Core Reset Register (GRSTCTL).
+ * Set/clear the bits using the bit fields then write the d32 value to the
+ * register.
+ */
+union grstctl_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		/*
+		 *  AHB Master Idle.  Indicates the AHB Master State Machine is
+		 *  in IDLE condition.
+		 */
+		unsigned ahbidle:1;
+
+		/*
+		 * DMA Request Signal.  Indicated DMA request is in probress.
+		   Used for debug purpose.
+		 */
+		unsigned dmareq:1;
+
+		/* Reserved */
+		unsigned reserved29_11:19;
+
+		/*
+		 * TxFIFO Number (TxFNum) (Device and Host).
+		 *
+		 * This is the FIFO number which needs to be flushed,
+		 * using the TxFIFO Flush bit. This field should not
+		 * be changed until the TxFIFO Flush bit is cleared by
+		 * the core.
+		 *   - 0x0:Non Periodic TxFIFO Flush
+		 *   - 0x1 : Periodic TxFIFO #1 Flush in device mode
+		 *     or Periodic TxFIFO in host mode
+		 *   - 0x2 : Periodic TxFIFO #2 Flush in device mode.
+		 *   - ...
+		 *   - 0xF : Periodic TxFIFO #15 Flush in device mode
+		 *   - 0x10: Flush all the Transmit NonPeriodic and
+		 *     Transmit Periodic FIFOs in the core
+		 */
+		unsigned txfnum:5;
+#define DWC_GRSTCTL_TXFNUM_ALL			0x10
+
+		/*
+		 * TxFIFO Flush (TxFFlsh) (Device and Host).
+		 *
+		 * This bit is used to selectively flush a single or all
+		 * transmit FIFOs.  The application must first ensure that the
+		 * core is not in the middle of a transaction.
+		 *
+		 * The application should write into this bit, only after
+		 * making sure that neither the DMA engine is writing into the
+		 * TxFIFO nor the MAC is reading the data out of the FIFO.
+		 *
+		 * The application should wait until the core clears this bit,
+		 * before performing any operations. This bit will takes 8
+		 * clocks (slowest of PHY or AHB clock) to clear.
+		 */
+		unsigned txfflsh:1;
+
+		/*
+		 * RxFIFO Flush (RxFFlsh) (Device and Host)
+		 *
+		 * The application can flush the entire Receive FIFO using this
+		 * bit.
+		 *
+		 * The application must first ensure that the core is not in the
+		 * middle of a transaction.
+		 *
+		 * The application should write into this bit, only after making
+		 * sure that neither the DMA engine is reading from the RxFIFO
+		 * nor the MAC is writing the data in to the FIFO.
+		 *
+		 * The application should wait until the bit is cleared before
+		 * performing any other operations. This bit will takes 8 clocks
+		 * (slowest of PHY or AHB clock) to clear.
+		 */
+		unsigned rxfflsh:1;
+
+		/*
+		 * In Token Sequence Learning Queue Flush
+		 * (INTknQFlsh) (Device Only)
+		 */
+		unsigned intknqflsh:1;
+
+		/*
+		 * Host Frame Counter Reset (Host Only)<br>
+		 *
+		 * The application can reset the (micro)frame number
+		 * counter inside the core, using this bit. When the
+		 * (micro)frame counter is reset, the subsequent SOF
+		 * sent out by the core, will have a (micro)frame
+		 * number of 0.
+		 */
+		unsigned hstfrm:1;
+
+		/*
+		 * Hclk Soft Reset
+		 *
+		 * The application uses this bit to reset the control logic in
+		 * the AHB clock domain. Only AHB clock domain pipelines are
+		 * reset.
+		 */
+		unsigned hsftrst:1;
+
+		/*
+		 * Core Soft Reset (CSftRst) (Device and Host)
+		 *
+		 * The application can flush the control logic in the
+		 * entire core using this bit. This bit resets the
+		 * pipelines in the AHB Clock domain as well as the
+		 * PHY Clock domain.
+		 *
+		 * The state machines are reset to an IDLE state, the
+		 * control bits in the CSRs are cleared, all the
+		 * transmit FIFOs and the receive FIFO are flushed.
+		 *
+		 * The status mask bits that control the generation of
+		 * the interrupt, are cleared, to clear the
+		 * interrupt. The interrupt status bits are not
+		 * cleared, so the application can get the status of
+		 * any events that occurred in the core after it has
+		 * set this bit.
+		 *
+		 * Any transactions on the AHB are terminated as soon
+		 * as possible following the protocol. Any
+		 * transactions on the USB are terminated immediately.
+		 *
+		 * The configuration settings in the CSRs are
+		 * unchanged, so the software doesn't have to
+		 * reprogram these registers (Device
+		 * Configuration/Host Configuration/Core System
+		 * Configuration/Core PHY Configuration).
+		 *
+		 * The application can write to this bit, any time it
+		 * wants to reset the core. This is a self clearing
+		 * bit and the core clears this bit after all the
+		 * necessary logic is reset in the core, which may
+		 * take several clocks, depending on the current state
+		 * of the core.
+		 */
+		unsigned csftrst:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields of the Core Interrupt Mask Register
+ * (GINTMSK).  Set/clear the bits using the bit fields then write the d32 value
+ * to the register.
+ */
+union gintmsk_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned wkupintr:1;
+		unsigned sessreqintr:1;
+		unsigned disconnect:1;
+		unsigned conidstschng:1;
+		unsigned reserved27:1;
+		unsigned ptxfempty:1;
+		unsigned hcintr:1;
+		unsigned portintr:1;
+		unsigned reserved23_22:2;
+		unsigned incomplisoout:1;
+		unsigned incomplisoin:1;
+		unsigned outepintr:1;
+		unsigned inepintr:1;
+		unsigned epmismatch:1;
+		unsigned reserved16:1;
+		unsigned eopframe:1;
+		unsigned isooutdrop:1;
+		unsigned enumdone:1;
+		unsigned usbreset:1;
+		unsigned usbsuspend:1;
+		unsigned erlysuspend:1;
+		unsigned i2cintr:1;
+		unsigned reserved08:1;
+		unsigned goutnakeff:1;
+		unsigned ginnakeff:1;
+		unsigned nptxfempty:1;
+		unsigned rxstsqlvl:1;
+		unsigned sofintr:1;
+		unsigned otgintr:1;
+		unsigned modemismatch:1;
+		unsigned reserved00:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields of the Core Interrupt Register
+ * (GINTSTS).  Set/clear the bits using the bit fields then write the d32 value
+ * to the register.
+ */
+union gintsts_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+#define DWC_SOF_INTR_MASK			0x0008
+	struct {
+#define DWC_HOST_MODE				1
+		unsigned wkupintr:1;
+		unsigned sessreqintr:1;
+		unsigned disconnect:1;
+		unsigned conidstschng:1;
+		unsigned reserved27:1;
+		unsigned ptxfempty:1;
+		unsigned hcintr:1;
+		unsigned portintr:1;
+		unsigned reserved22_23:2;
+		unsigned incomplisoout:1;
+		unsigned incomplisoin:1;
+		unsigned outepintr:1;
+		unsigned inepint:1;
+		unsigned epmismatch:1;
+		unsigned intokenrx:1;
+		unsigned eopframe:1;
+		unsigned isooutdrop:1;
+		unsigned enumdone:1;
+		unsigned usbreset:1;
+		unsigned usbsuspend:1;
+		unsigned erlysuspend:1;
+		unsigned i2cintr:1;
+		unsigned reserved8:1;
+		unsigned goutnakeff:1;
+		unsigned ginnakeff:1;
+		unsigned nptxfempty:1;
+		unsigned rxstsqlvl:1;
+		unsigned sofintr:1;
+		unsigned otgintr:1;
+		unsigned modemismatch:1;
+		unsigned curmode:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Device Receive Status Read and
+ * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the d32
+ * element then read out the bits using the bit elements.
+ */
+union device_grxsts_data {			/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved:7;
+		unsigned fn:4;
+		unsigned pktsts:4;
+#define DWC_STS_DATA_UPDT		0x2  /* OUT Data Packet */
+#define DWC_STS_XFER_COMP		0x3  /* OUT Data Transfer Complete */
+#define DWC_DSTS_GOUT_NAK		0x1  /* Global OUT NAK */
+#define DWC_DSTS_SETUP_COMP		0x4  /* Setup Phase Complete */
+#define DWC_DSTS_SETUP_UPDT		0x6  /* SETUP Packet */
+
+		unsigned dpid:2;
+		unsigned bcnt:11;
+		unsigned epnum:4;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Host Receive Status Read and
+ * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the d32
+ * element then read out the bits using the bit elements.
+ */
+union host_grxsts_data {			/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved31_21:11;
+		unsigned pktsts:4;
+#define DWC_GRXSTS_PKTSTS_IN			0x2
+#define DWC_GRXSTS_PKTSTS_IN_XFER_COMP		0x3
+#define DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR	0x5
+#define DWC_GRXSTS_PKTSTS_CH_HALTED		0x7
+
+		unsigned dpid:2;
+		unsigned bcnt:11;
+		unsigned chnum:4;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the FIFO Size Registers (HPTXFSIZ,
+ * GNPTXFSIZ, DPTXFSIZn). Read the register into the d32 element then
+ * read out the bits using the bit elements.
+ */
+union fifosize_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned depth:16;
+		unsigned startaddr:16;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Non-Periodic Transmit FIFO/Queue
+ * Status Register (GNPTXSTS). Read the register into the d32 element then read
+ * out the bits using the bit elements.
+ */
+union gnptxsts_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved:1;
+		/* Top of the Non-Periodic Transmit Request Queue
+		 *  - bits 30:27 - Channel/EP Number
+		 *  - bits 26:25 - Token Type
+		 *    - 2'b00 - IN/OUT
+		 *    - 2'b01 - Zero Length OUT
+		 *    - 2'b10 - PING/Complete Split
+		 *    - 2'b11 - Channel Halt
+		 *  - bit 24 - Terminate (Last entry for the selected
+		 *    channel/EP)
+		 */
+		unsigned nptxqtop_chnep:4;
+		unsigned nptxqtop_token:2;
+		unsigned nptxqtop_terminate:1;
+		unsigned nptxqspcavail:8;
+		unsigned nptxfspcavail:16;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Transmit	FIFO Status Register
+ * (DTXFSTS). Read the register into the d32 element then read out the bits
+ * using the bit elements.
+ */
+union dtxfsts_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved:16;
+		unsigned txfspcavail:16;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the I2C Control Register (I2CCTL).
+ * Read the register into the d32 element then read out the bits using the bit
+ * elements.
+ */
+union gi2cctl_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned bsydne:1;
+		unsigned rw:1;
+		unsigned reserved:2;
+		unsigned i2cdevaddr:2;
+		unsigned i2csuspctl:1;
+		unsigned ack:1;
+		unsigned i2cen:1;
+		unsigned addr:7;
+		unsigned regaddr:8;
+		unsigned rwdata:8;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the User HW Config1 Register.  Read
+ * the register into the d32 element then read out the bits using the bit
+ * elements.
+ */
+union hwcfg1_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned ep_dir15:2;
+		unsigned ep_dir14:2;
+		unsigned ep_dir13:2;
+		unsigned ep_dir12:2;
+		unsigned ep_dir11:2;
+		unsigned ep_dir10:2;
+		unsigned ep_dir9:2;
+		unsigned ep_dir8:2;
+		unsigned ep_dir7:2;
+		unsigned ep_dir6:2;
+		unsigned ep_dir5:2;
+		unsigned ep_dir4:2;
+		unsigned ep_dir3:2;
+		unsigned ep_dir2:2;
+		unsigned ep_dir1:2;
+		unsigned ep_dir0:2;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the User HW Config2 Register.  Read
+ * the register into the d32 element then read out the bits using the bit
+ * elements.
+ */
+union hwcfg2_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		/* GHWCFG2 */
+		unsigned reserved31:1;
+		unsigned dev_token_q_depth:5;
+		unsigned host_perio_tx_q_depth:2;
+		unsigned nonperio_tx_q_depth:2;
+		unsigned rx_status_q_depth:2;
+		unsigned dynamic_fifo:1;
+		unsigned perio_ep_supported:1;
+		unsigned num_host_chan:4;
+		unsigned num_dev_ep:4;
+		unsigned fs_phy_type:2;
+		unsigned hs_phy_type:2;
+#define DWC_HWCFG2_HS_PHY_TYPE_NOT_SUPPORTED		0
+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI			1
+#define DWC_HWCFG2_HS_PHY_TYPE_ULPI			2
+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI		3
+
+		unsigned point2point:1;
+		unsigned architecture:2;
+		unsigned op_mode:3;
+#define DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG		0
+#define DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG		1
+#define DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG	2
+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE		3
+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE	4
+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST		5
+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST		6
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the User HW Config3 Register.  Read
+ * the register into the d32 element then read out the bits using the bit
+ * elements.
+ */
+union hwcfg3_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		/* GHWCFG3 */
+		unsigned dfifo_depth:16;
+		unsigned reserved15_13:3;
+		unsigned ahb_phy_clock_synch:1;
+		unsigned synch_reset_type:1;
+		unsigned optional_features:1;
+		unsigned vendor_ctrl_if:1;
+		unsigned i2c:1;
+		unsigned otg_func:1;
+		unsigned packet_size_cntr_width:3;
+		unsigned xfer_size_cntr_width:4;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the User HW Config4 Register.  Read
+ * the register into the d32 element then read out the bits using the bit
+ * elements.
+ */
+union hwcfg4_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved31_30:2;
+		unsigned num_in_eps:4;
+		unsigned ded_fifo_en:1;
+
+		unsigned session_end_filt_en:1;
+		unsigned b_valid_filt_en:1;
+		unsigned a_valid_filt_en:1;
+		unsigned vbus_valid_filt_en:1;
+		unsigned iddig_filt_en:1;
+		unsigned num_dev_mode_ctrl_ep:4;
+		unsigned utmi_phy_data_width:2;
+		unsigned min_ahb_freq:9;
+		unsigned power_optimiz:1;
+		unsigned num_dev_perio_in_ep:4;
+	} b;
+};
+
+/*
+ * Device Global Registers. Offsets 800h-BFFh
+ *
+ * The following structures define the size and relative field offsets for the
+ * Device Mode Registers.
+ *
+ * These registers are visible only in Device mode and must not be accessed in
+ * Host mode, as the results are unknown.
+ */
+struct device_global_regs {		/* CONFIG_DWC_OTG_REG_LE */
+	/* Device Configuration Register.			Offset: 800h */
+	u32 dcfg;
+	/* Device Control Register.				Offset: 804h */
+	u32 dctl;
+	/* Device Status Register (Read Only).			Offset: 808h */
+	u32 dsts;
+	/* Reserved.						Offset: 80Ch */
+	u32 unused;
+	/* Device IN Endpoint Common Interrupt Mask Register.	Offset: 810h */
+	u32 diepmsk;
+	/* Device OUT Endpoint Common Interrupt Mask Register.	Offset: 814h */
+	u32 doepmsk;
+	/* Device All Endpoints Interrupt Register.		Offset: 818h */
+	u32 daint;
+	/* Device All Endpoints Interrupt Mask Register.	Offset: 81Ch */
+	u32 daintmsk;
+	/* Device IN Token Queue Read Register-1 (Read Only).	Offset: 820h */
+	u32 dtknqr1;
+	/* Device IN Token Queue Read Register-2 (Read Only).	Offset: 824h */
+	u32 dtknqr2;
+	/* Device VBUS  discharge Register.			Offset: 828h */
+	u32 dvbusdis;
+	/* Device VBUS Pulse Register.				Offset: 82Ch */
+	u32 dvbuspulse;
+	/* Device IN Token Queue Read Register-3 (Read Only).	Offset: 830h */
+	u32 dtknqr3_dthrctl;
+	/* Device IN Token Queue Read Register-4 (Read Only).	Offset: 834h */
+	u32 dtknqr4_fifoemptymsk;
+};
+
+/*
+ * This union represents the bit fields in the Device Configuration
+ * Register.  Read the register into the d32 member then
+ * set/clear the bits using the bit elements.  Write the
+ * d32 member to the dcfg register.
+ */
+union dcfg_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved0_8:9;
+		unsigned epmscnt:5;
+		/* In Endpoint Mis-match count */
+		unsigned reserved17_13:5;
+		/* Periodic Frame Interval */
+		unsigned perfrint:2;
+#define DWC_DCFG_FRAME_INTERVAL_80		0
+#define DWC_DCFG_FRAME_INTERVAL_85		1
+#define DWC_DCFG_FRAME_INTERVAL_90		2
+#define DWC_DCFG_FRAME_INTERVAL_95		3
+
+		/* Device Addresses */
+		unsigned devaddr:7;
+		unsigned reserved3:1;
+		/* Non Zero Length Status OUT Handshake */
+		unsigned nzstsouthshk:1;
+#define DWC_DCFG_SEND_STALL			1
+
+		/* Device Speed */
+		unsigned devspd:2;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Device Control Register.  Read
+ * the register into the d32 member then set/clear the bits using the bit
+ * elements.
+ */
+union dctl_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved31_12:21;
+		/* Clear Global OUT NAK */
+		unsigned cgoutnak:1;
+		/* Set Global OUT NAK */
+		unsigned sgoutnak:1;
+		/* Clear Global Non-Periodic IN NAK */
+		unsigned cgnpinnak:1;
+		/* Set Global Non-Periodic IN NAK */
+		unsigned sgnpinnak:1;
+		/* Test Control */
+		unsigned tstctl:3;
+		/* Global OUT NAK Status */
+		unsigned goutnaksts:1;
+		/* Global Non-Periodic IN NAK Status */
+		unsigned gnpinnaksts:1;
+		/* Soft Disconnect */
+		unsigned sftdiscon:1;
+		/* Remote Wakeup */
+		unsigned rmtwkupsig:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Device Status Register.  Read the
+ * register into the d32 member then set/clear the bits using the bit elements.
+ */
+union dsts_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved31_22:10;
+		/* Frame or Microframe Number of the received SOF */
+		unsigned soffn:14;
+		unsigned reserved07_04:4;
+		/* Erratic Error */
+		unsigned errticerr:1;
+		/* Enumerated Speed */
+		unsigned enumspd:2;
+#define DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ		0
+#define DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ		1
+#define DWC_DSTS_ENUMSPD_LS_PHY_6MHZ			2
+#define DWC_DSTS_ENUMSPD_FS_PHY_48MHZ			3
+		/* Suspend Status */
+		unsigned suspsts:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Device IN EP Interrupt Register
+ * and the Device IN EP Common Mask Register.
+ *
+ * Read the register into the d32 member then set/clear the bits using the bit
+ * elements.
+ */
+union diepint_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved31_08:23;
+		unsigned txfifoundrn:1;
+		/* IN Endpoint HAK Effective mask */
+		unsigned emptyintr:1;
+		/* IN Endpoint NAK Effective mask */
+		unsigned inepnakeff:1;
+		/* IN Token Received with EP mismatch mask */
+		unsigned intknepmis:1;
+		/* IN Token received with TxF Empty mask */
+		unsigned intktxfemp:1;
+		/* TimeOUT Handshake mask (non-ISOC EPs) */
+		unsigned timeout:1;
+		/* AHB Error mask */
+		unsigned ahberr:1;
+		/* Endpoint disable mask */
+		unsigned epdisabled:1;
+		/* Transfer complete mask */
+		unsigned xfercompl:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Device OUT EP Interrupt Register
+ * and Device OUT EP Common Interrupt Mask Register.
+ *
+ * Read the register into the d32 member then set/clear the bits using the bit
+ * elements.
+ */
+union doepint_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved31_04:28; /* Docs say reserved is 27 bits */
+
+		/* There is 1 bit missing here, not used? */
+
+		/* Setup Phase Done (control EPs) */
+		unsigned setup:1;
+		/* AHB Error */
+		unsigned ahberr:1;
+		/* Endpoint disable  */
+		unsigned epdisabled:1;
+		/* Transfer complete */
+		unsigned xfercompl:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Device All EP Interrupt and Mask
+ * Registers.  Read the register into the d32 member then set/clear the bits
+ * using the bit elements.
+ */
+union daint_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		/* OUT Endpoint bits */
+		unsigned out:16;
+		/* IN Endpoint bits */
+		unsigned in:16;
+	} ep;
+	struct {
+		/* OUT Endpoint bits */
+		unsigned outep15:1;
+		unsigned outep14:1;
+		unsigned outep13:1;
+		unsigned outep12:1;
+		unsigned outep11:1;
+		unsigned outep10:1;
+		unsigned outep9:1;
+		unsigned outep8:1;
+		unsigned outep7:1;
+		unsigned outep6:1;
+		unsigned outep5:1;
+		unsigned outep4:1;
+		unsigned outep3:1;
+		unsigned outep2:1;
+		unsigned outep1:1;
+		unsigned outep0:1;
+		/* IN Endpoint bits */
+		unsigned inep15:1;
+		unsigned inep14:1;
+		unsigned inep13:1;
+		unsigned inep12:1;
+		unsigned inep11:1;
+		unsigned inep10:1;
+		unsigned inep9:1;
+		unsigned inep8:1;
+		unsigned inep7:1;
+		unsigned inep6:1;
+		unsigned inep5:1;
+		unsigned inep4:1;
+		unsigned inep3:1;
+		unsigned inep2:1;
+		unsigned inep1:1;
+		unsigned inep0:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Device IN Token Queue Read
+ * Registers.  Read the register into the d32 member. READ-ONLY Register
+ */
+union dtknq1_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		/* EP Numbers of IN Tokens 0 ... 4 */
+		unsigned epnums0_5:24;
+		/* write pointer has wrapped. */
+		unsigned wrap_bit:1;
+		/* Reserved */
+		unsigned reserved05_06:2;
+		/* In Token Queue Write Pointer */
+		unsigned intknwptr:5;
+	} b;
+};
+
+/*
+ * This union represents Threshold control Register. Read and write the register
+ * into the d32 member.  READ-WRITABLE Register
+ */
+union dthrctl_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		/* Reserved */
+		unsigned reserved26_31:6;
+		/* Rx Thr. Length */
+		unsigned rx_thr_len:9;
+		/* Rx Thr. Enable */
+		unsigned rx_thr_en:1;
+		/* Reserved */
+		unsigned reserved11_15:5;
+		/* Tx Thr. Length */
+		unsigned tx_thr_len:9;
+		/* ISO Tx Thr. Enable */
+		unsigned iso_thr_en:1;
+		/* non ISO Tx Thr. Enable */
+		unsigned non_iso_thr_en:1;
+	} b;
+};
+
+/*
+ * Device Logical IN Endpoint-Specific Registers. Offsets 900h-AFCh
+ *
+ * There will be one set of endpoint registers per logical endpoint implemented.
+ *
+ * These registers are visible only in Device mode and must not be accessed in
+ * Host mode, as the results are unknown.
+ */
+ struct device_in_ep_regs {
+	/*
+	 * Device IN Endpoint Control Register.
+	 * Offset:900h + (ep_num * 20h) + 00h
+	 */
+	u32 diepctl;
+	/* Reserved. Offset:900h + (ep_num * 20h) + 04h */
+	u32 reserved04;
+	/*
+	 * Device IN Endpoint Interrupt Register.
+	 * Offset:900h + (ep_num * 20h) + 08h
+	 */
+	u32 diepint;
+	/* Reserved. Offset:900h + (ep_num * 20h) + 0Ch */
+	u32 reserved0C;
+	/* Device IN Endpoint Transfer Size Register.
+	 * Offset:900h + (ep_num * 20h) + 10h
+	 */
+	u32 dieptsiz;
+	/*
+	 * Device IN Endpoint DMA Address Register.
+	 * Offset:900h + (ep_num * 20h) + 14h
+	 */
+	u32 diepdma;
+	/* Reserved.
+	 * Offset:900h + (ep_num * 20h) + 18h - 900h + (ep_num * 20h) + 1Ch
+	 */
+	u32 dtxfsts;
+	/*
+	 * Reserved.
+	 * Offset:900h + (ep_num * 20h) + 1Ch - 900h + (ep_num * 20h) + 1Ch
+	 */
+	u32 reserved18;
+};
+
+/*
+ * Device Logical OUT Endpoint-Specific Registers. Offsets: B00h-CFCh
+ *
+ * There will be one set of endpoint registers per logical endpoint implemented.
+ *
+ * These registers are visible only in Device mode and must not be accessed in
+ * Host mode, as the results are unknown.
+ */
+struct device_out_ep_regs {
+	/*
+	 * Device OUT Endpoint Control Register.
+	 * Offset:B00h + (ep_num * 20h) + 00h
+	 */
+	u32 doepctl;
+	/*
+	 * Device OUT Endpoint Frame number Register.
+	 * Offset: B00h + (ep_num * 20h) + 04h
+	 */
+	u32 doepfn;
+	/*
+	 * Device OUT Endpoint Interrupt Register.
+	 * Offset:B00h + (ep_num * 20h) + 08h
+	 */
+	u32 doepint;
+	/* Reserved. Offset:B00h + (ep_num * 20h) + 0Ch */
+	u32 reserved0C;
+	/*
+	 * Device OUT Endpoint Transfer Size Register.
+	 * Offset: B00h + (ep_num * 20h) + 10h
+	 */
+	u32 doeptsiz;
+	/*
+	 * Device OUT Endpoint DMA Address Register.
+	 * Offset:B00h + (ep_num * 20h) + 14h
+	 */
+	u32 doepdma;
+	/*
+	 * Reserved.
+	 * Offset:B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch
+	 */
+	u32 unused[2];
+};
+
+/*
+ * This union represents the bit fields in the Device EP Control Register.  Read
+ * the register into the d32 member then set/clear the bits using the bit
+ * elements.
+ */
+union depctl_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		/* Endpoint Enable */
+		unsigned epena:1;
+		/* Endpoint Disable */
+		unsigned epdis:1;
+
+		/*
+		 * Set DATA1 PID (INTR/Bulk IN and OUT endpoints) Writing to
+		 * this field sets the Endpoint DPID (DPID) field in this
+		 * register to DATA1 Set Odd (micro)frame (SetOddFr) (ISO IN and
+		 * OUT Endpoints) Writing to this field sets the Even/Odd
+		 * (micro)frame (EO_FrNum) field to odd (micro) frame.
+		 */
+		unsigned setd1pid:1;
+		/*
+		 * Set DATA0 PID (INTR/Bulk IN and OUT endpoints)  Writing to
+		 * this field sets the Endpoint DPID (DPID) field in this
+		 * register to DATA0. Set Even (micro)frame (SetEvenFr) (ISO IN
+		 * and OUT Endpoints) Writing to this field sets the Even/Odd
+		 * (micro)frame (EO_FrNum) field to even (micro) frame.
+		 */
+		unsigned setd0pid:1;
+
+		/* Set NAK */
+		unsigned snak:1;
+		/* Clear NAK */
+		unsigned cnak:1;
+
+		/*
+		 * Tx Fifo Number
+		 * IN EPn/IN EP0
+		 * OUT EPn/OUT EP0 - reserved
+		 */
+		unsigned txfnum:4;
+
+		/* Stall Handshake */
+		unsigned stall:1;
+
+		/* Snoop Mode
+		 * OUT EPn/OUT EP0
+		 * IN EPn/IN EP0 - reserved
+		 */
+		unsigned snp:1;
+
+		/* Endpoint Type
+		 *  2'b00: Control
+		 *  2'b01: Isochronous
+		 *  2'b10: Bulk
+		 *  2'b11: Interrupt
+		 */
+		unsigned eptype:2;
+
+		/* NAK Status */
+		unsigned naksts:1;
+
+		/*
+		 * Endpoint DPID (INTR/Bulk IN and OUT endpoints) This field
+		 * contains the PID of the packet going to be received or
+		 * transmitted on this endpoint. The application should program
+		 * the PID of the first packet going to be received or
+		 * transmitted on this endpoint, after the endpoint is
+		 * activated. Applications use the SetD1PID and SetD0PID fields
+		 * of this register to program either D0 or D1 PID.
+		 *
+		 * The encoding for this field is
+		 *   - 0: D0
+		 *   - 1: D1
+		 */
+		unsigned dpid:1;
+
+		/* USB Active Endpoint */
+		unsigned usbactep:1;
+
+		/*
+		 * Next Endpoint
+		 * IN EPn/IN EP0
+		 * OUT EPn/OUT EP0 - reserved
+		 */
+		unsigned nextep:4;
+
+		/*
+		 * Maximum Packet Size
+		 * IN/OUT EPn
+		 * IN/OUT EP0 - 2 bits
+		 *   2'b00: 64 Bytes
+		 *   2'b01: 32
+		 *   2'b10: 16
+		 *   2'b11: 8
+		 */
+		unsigned mps:11;
+#define DWC_DEP0CTL_MPS_64			0
+#define DWC_DEP0CTL_MPS_32			1
+#define DWC_DEP0CTL_MPS_16			2
+#define DWC_DEP0CTL_MPS_8			3
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Device EP Transfer Size Register.
+ * Read the register into the d32 member then set/clear the bits using the bit
+ * elements.
+ */
+union deptsiz_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+
+	/*
+	 * Added-sr: 2007-07-26
+	 *
+	 * Correct ther register layout for the 405EZ Ultra
+	 * USB device implementation.
+	 */
+#ifdef CONFIG_DWC_LIMITED_XFER_SIZE
+	struct {
+		unsigned reserved:1;
+		/* Multi Count - Periodic IN endpoints */
+		unsigned mc:2;
+		unsigned reserved1:5;
+		/* Packet Count */
+		unsigned pktcnt:5;
+		unsigned reserved2:8;
+		/* Transfer size */
+		unsigned xfersize:11;
+	} b;
+#else
+	struct {
+		unsigned reserved:1;
+		/* Multi Count - Periodic IN endpoints */
+		unsigned mc:2;
+		/* Packet Count */
+		unsigned pktcnt:10;
+		/* Transfer size */
+		unsigned xfersize:19;
+	} b;
+#endif
+};
+
+/*
+ * This union represents the bit fields in the Device EP 0 Transfer Size
+ * Register.  Read the register into the d32 member then set/clear the bits
+ * using the bit elements.
+ */
+union deptsiz0_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved31:1; /* device*/
+		/*Setup Packet Count (DOEPTSIZ0 Only) */
+		unsigned supcnt:2;
+		/* Reserved */
+		unsigned reserved28_20:9;
+		/* Packet Count */
+		unsigned pktcnt:1;
+		/* Reserved */
+		unsigned reserved18_7:12;
+		/* Transfer size */
+		unsigned xfersize:7;
+	} b;
+};
+
+#define MAX_PERIO_FIFOS			15	/* Max periodic FIFOs */
+#define MAX_TX_FIFOS			15	/* Max non-periodic FIFOs */
+
+/* Maximum number of Endpoints/HostChannels */
+#if defined(CONFIG_460EX)
+#define MAX_EPS_CHANNELS 12
+#else
+#define MAX_EPS_CHANNELS 4
+#endif
+
+/*
+ * The device_if structure contains information needed to manage the DWC_otg
+ * controller acting in device mode. It represents the programming view of the
+ * device-specific aspects of the controller.
+ */
+struct device_if {
+	/* Device Global Registers starting at offset 800h */
+	struct device_global_regs *dev_global_regs;
+#define DWC_DEV_GLOBAL_REG_OFFSET		0x800
+
+	/* Device Logical IN Endpoint-Specific Registers 900h-AFCh */
+	struct device_in_ep_regs *in_ep_regs[MAX_EPS_CHANNELS];
+#define DWC_DEV_IN_EP_REG_OFFSET		0x900
+#define DWC_EP_REG_OFFSET			0x20
+
+	/* Device Logical OUT Endpoint-Specific Registers B00h-CFCh */
+	struct device_out_ep_regs *out_ep_regs[MAX_EPS_CHANNELS];
+#define DWC_DEV_OUT_EP_REG_OFFSET		0xB00
+
+	/* Device configuration information */
+	/* Device Speed  0: Unknown, 1: LS, 2:FS, 3: HS */
+	u8  speed;
+	/*  Number # of Tx EP range: 0-15 exept ep0 */
+	u8  num_in_eps;
+	/*  Number # of Rx EP range: 0-15 exept ep 0*/
+	u8  num_out_eps;
+
+	/* Size of periodic FIFOs (Bytes) */
+	u16 perio_tx_fifo_size[MAX_PERIO_FIFOS];
+
+	/* Size of Tx FIFOs (Bytes) */
+	u16 tx_fifo_size[MAX_TX_FIFOS];
+
+	/* Thresholding enable flags and length varaiables */
+	u16 rx_thr_en;
+	u16 iso_tx_thr_en;
+	u16 non_iso_tx_thr_en;
+	u16 rx_thr_length;
+	u16 tx_thr_length;
+};
+
+/*
+ * This union represents the bit fields in the Power and Clock Gating Control
+ * Register. Read the register into the d32 member then set/clear the
+ * bits using the bit elements.
+ */
+union pcgcctl_data {
+	u32 d32;
+	struct {
+		unsigned reserved31_05:27;
+		/* PHY Suspended */
+		unsigned physuspended:1;
+		/* Reset Power Down Modules */
+		unsigned rstpdwnmodule:1;
+		/* Power Clamp */
+		unsigned pwrclmp:1;
+		/* Gate Hclk */
+		unsigned gatehclk:1;
+		/* Stop Pclk */
+		unsigned stoppclk:1;
+	} b;
+};
+
+/*
+ * Host Mode Register Structures
+ */
+
+/*
+ * The Host Global Registers structure defines the size and relative field
+ * offsets for the Host Mode Global Registers.  Host Global Registers offsets
+ * 400h-7FFh.
+*/
+struct host_global_regs {
+	/* Host Configuration Register.				Offset: 400h */
+	u32 hcfg;
+	/* Host Frame Interval Register.			Offset: 404h */
+	u32 hfir;
+	/* Host Frame Number / Frame Remaining Register.	Offset: 408h */
+	u32 hfnum;
+	/* Reserved.						Offset: 40Ch */
+	u32 reserved40C;
+	/* Host Periodic Transmit FIFO/ Queue Status Register.	Offset: 410h */
+	u32 hptxsts;
+	/* Host All Channels Interrupt Register.		Offset: 414h */
+	u32 haint;
+	/* Host All Channels Interrupt Mask Register.		Offset: 418h */
+	u32 haintmsk;
+};
+
+/*
+ * This union represents the bit fields in the Host Configuration Register. Read
+ * the register into the d32 member then set/clear the bits using the bit
+ * elements. Write the d32 member to the hcfg register.
+ */
+union hcfg_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+#define DWC_HCFG_30_60_MHZ			0
+#define DWC_HCFG_48_MHZ				1
+#define DWC_HCFG_6_MHZ				2
+		/* FS/LS Only Support */
+		unsigned fslssupp:1;
+		/* FS/LS Phy Clock Select */
+		unsigned fslspclksel:2;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Host Frame Remaing/Number
+ * Register.
+ */
+union hfir_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved:16;
+		unsigned frint:16;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Host Frame Remaing/Number
+ * Register.
+ */
+union hfnum_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+#define DWC_HFNUM_MAX_FRNUM			0x3FFF
+		unsigned frrem:16;
+		unsigned frnum:16;
+	} b;
+};
+
+union hptxsts_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned ptxqtop_odd:1;
+		unsigned ptxqtop_chnum:4;
+		unsigned ptxqtop_token:2;
+		unsigned ptxqtop_terminate:1;
+		unsigned ptxqspcavail:8;
+		unsigned ptxfspcavail:16;
+		/*
+		 * Top of the Periodic Transmit Request Queue
+		 *  - bit 24 - Terminate (last entry for the selected channel)
+		 *  - bits 26:25 - Token Type
+		 *    - 2'b00 - Zero length
+		 *    - 2'b01 - Ping
+		 *    - 2'b10 - Disable
+		 *  - bits 30:27 - Channel Number
+		 *  - bit 31 - Odd/even microframe
+		 */
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Host Port Control and Status
+ * Register. Read the register into the d32 member then set/clear the bits using
+ * the bit elements. Write the d32 member to the hprt0 register.
+ */
+union hprt0_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+#define DWC_HPRT0_PRTSPD_HIGH_SPEED		0
+#define DWC_HPRT0_PRTSPD_FULL_SPEED		1
+#define DWC_HPRT0_PRTSPD_LOW_SPEED		2
+		unsigned reserved19_31:13;
+		unsigned prtspd:2;
+		unsigned prttstctl:4;
+		unsigned prtpwr:1;
+		unsigned prtlnsts:2;
+		unsigned reserved9:1;
+		unsigned prtrst:1;
+		unsigned prtsusp:1;
+		unsigned prtres:1;
+		unsigned prtovrcurrchng:1;
+		unsigned prtovrcurract:1;
+		unsigned prtenchng:1;
+		unsigned prtena:1;
+		unsigned prtconndet:1;
+		unsigned prtconnsts:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Host All Interrupt Register.
+ */
+union haint_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved:16;
+		unsigned ch15:1;
+		unsigned ch14:1;
+		unsigned ch13:1;
+		unsigned ch12:1;
+		unsigned ch11:1;
+		unsigned ch10:1;
+		unsigned ch9:1;
+		unsigned ch8:1;
+		unsigned ch7:1;
+		unsigned ch6:1;
+		unsigned ch5:1;
+		unsigned ch4:1;
+		unsigned ch3:1;
+		unsigned ch2:1;
+		unsigned ch1:1;
+		unsigned ch0:1;
+	} b;
+	struct {
+		unsigned reserved:16;
+		unsigned chint:16;
+	} b2;
+};
+
+/*
+ * This union represents the bit fields in the Host All Interrupt Register.
+ */
+union haintmsk_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved:16;
+		unsigned ch15:1;
+		unsigned ch14:1;
+		unsigned ch13:1;
+		unsigned ch12:1;
+		unsigned ch11:1;
+		unsigned ch10:1;
+		unsigned ch9:1;
+		unsigned ch8:1;
+		unsigned ch7:1;
+		unsigned ch6:1;
+		unsigned ch5:1;
+		unsigned ch4:1;
+		unsigned ch3:1;
+		unsigned ch2:1;
+		unsigned ch1:1;
+		unsigned ch0:1;
+	} b;
+	struct {
+		unsigned reserved:16;
+		unsigned chint:16;
+	} b2;
+};
+
+/*
+ * Host Channel Specific Registers. 500h-5FCh
+ */
+struct dwc_hc_regs {			/* CONFIG_DWC_OTG_REG_LE */
+	/*
+	 * Host Channel 0 Characteristic Register.
+	 * Offset: 500h + (chan_num * 20h) + 00h
+	 */
+	u32 hcchar;
+	/*
+	 * Host Channel 0 Split Control Register.
+	 * Offset: 500h + (chan_num * 20h) + 04h
+	 */
+	u32 hcsplt;
+	/*
+	 * Host Channel 0 Interrupt Register.
+	 * Offset: 500h + (chan_num * 20h) + 08h
+	 */
+	u32 hcint;
+	/*
+	 * Host Channel 0 Interrupt Mask Register.
+	 * Offset: 500h + (chan_num * 20h) + 0Ch
+	 */
+	u32 hcintmsk;
+	/*
+	 * Host Channel 0 Transfer Size Register.
+	 * Offset: 500h + (chan_num * 20h) + 10h
+	 */
+	u32 hctsiz;
+	/*
+	 * Host Channel 0 DMA Address Register.
+	 * Offset: 500h + (chan_num * 20h) + 14h
+	 */
+	u32 hcdma;
+	/*
+	 * Reserved.
+	 * Offset: 500h + (chan_num * 20h) + 18h - 500h + (chan_num * 20h) + 1Ch
+	  */
+	u32 reserved[2];
+};
+
+/*
+ * This union represents the bit fields in the Host Channel Characteristics
+ * Register. Read the register into the d32 member then set/clear the bits using
+ * the bit elements. Write the d32 member to the hcchar register.
+ */
+union hcchar_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		/* Channel enable */
+		unsigned chen:1;
+		/* Channel disable */
+		unsigned chdis:1;
+		/*
+		 * Frame to transmit periodic transaction.
+		 * 0: even, 1: odd
+		 */
+		unsigned oddfrm:1;
+		/* Device address */
+		unsigned devaddr:7;
+		/* Packets per frame for periodic transfers. 0 is reserved. */
+		unsigned multicnt:2;
+		/* 0: Control, 1: Isoc, 2: Bulk, 3: Intr */
+		unsigned eptype:2;
+		/* 0: Full/high speed device, 1: Low speed device */
+		unsigned lspddev:1;
+		unsigned reserved:1;
+		/* 0: OUT, 1: IN */
+		unsigned epdir:1;
+		/* Endpoint number */
+		unsigned epnum:4;
+		/* Maximum packet size in bytes */
+		unsigned mps:11;
+	} b;
+};
+
+union hcsplt_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		/* Split Enble */
+		unsigned spltena:1;
+		/* Reserved */
+		unsigned reserved:14;
+		/* Do Complete Split */
+		unsigned compsplt:1;
+		/* Transaction Position */
+		unsigned xactpos:2;
+#define DWC_HCSPLIT_XACTPOS_MID			0
+#define DWC_HCSPLIT_XACTPOS_END			1
+#define DWC_HCSPLIT_XACTPOS_BEGIN		2
+#define DWC_HCSPLIT_XACTPOS_ALL			3
+
+		/* Hub Address */
+		unsigned hubaddr:7;
+		/* Port Address */
+		unsigned prtaddr:7;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Host All Interrupt
+ * Register.
+ */
+union hcint_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		/* Reserved */
+		unsigned reserved:21;
+		/* Data Toggle Error */
+		unsigned datatglerr:1;
+		/* Frame Overrun */
+		unsigned frmovrun:1;
+		/* Babble Error */
+		unsigned bblerr:1;
+		/* Transaction Err */
+		unsigned xacterr:1;
+		/* NYET Response Received */
+		unsigned nyet:1;
+		/* ACK Response Received */
+		unsigned ack:1;
+		/* NAK Response Received */
+		unsigned nak:1;
+		/* STALL Response Received */
+		unsigned stall:1;
+		/* AHB Error */
+		unsigned ahberr:1;
+		/* Channel Halted */
+		unsigned chhltd:1;
+		/* Transfer Complete */
+		unsigned xfercomp:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Host Channel Transfer Size
+ * Register. Read the register into the d32 member then set/clear the  bits
+ * using the bit elements. Write the d32 member to the hcchar register.
+ */
+union hctsiz_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+#define DWC_HCTSIZ_DATA0			0
+#define DWC_HCTSIZ_DATA1			2
+#define DWC_HCTSIZ_DATA2			1
+#define DWC_HCTSIZ_MDATA			3
+#define DWC_HCTSIZ_SETUP			3
+
+		/* Do PING protocol when 1 */
+		unsigned dopng:1;
+		/*
+		 * Packet ID for next data packet
+		 * 0: DATA0
+		 * 1: DATA2
+		 * 2: DATA1
+		 * 3: MDATA (non-Control), SETUP (Control)
+		 */
+		unsigned pid:2;
+		/* Data packets to transfer */
+		unsigned pktcnt:10;
+		/* Total transfer size in bytes */
+		unsigned xfersize:19;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Host Channel Interrupt Mask
+ * Register. Read the register into the d32 member then set/clear the bits using
+ * the bit elements. Write the d32 member to the hcintmsk register.
+ */
+union hcintmsk_data {				/* CONFIG_DWC_OTG_REG_LE */
+	u32 d32;
+	struct {
+		unsigned reserved:21;
+		unsigned datatglerr:1;
+		unsigned frmovrun:1;
+		unsigned bblerr:1;
+		unsigned xacterr:1;
+		unsigned nyet:1;
+		unsigned ack:1;
+		unsigned nak:1;
+		unsigned stall:1;
+		unsigned ahberr:1;
+		unsigned chhltd:1;
+		unsigned xfercompl:1;
+	} b;
+};
+
+/*
+ * OTG Host Interface Structure.
+ *
+ * The OTG Host Interface Structure structure contains information needed to
+ * manage the DWC_otg controller acting in host mode. It represents the
+ * programming view of the host-specific aspects of the controller.
+ */
+struct dwc_host_if {			/* CONFIG_DWC_OTG_REG_LE */
+	/* Host Global Registers starting at offset 400h.*/
+	struct host_global_regs *host_global_regs;
+#define DWC_OTG_HOST_GLOBAL_REG_OFFSET		0x400
+
+	/* Host Port 0 Control and Status Register */
+	u32 *hprt0;
+#define DWC_OTG_HOST_PORT_REGS_OFFSET		0x440
+
+	/* Host Channel Specific Registers at offsets 500h-5FCh. */
+	struct dwc_hc_regs *hc_regs[MAX_EPS_CHANNELS];
+#define DWC_OTG_HOST_CHAN_REGS_OFFSET		0x500
+#define DWC_OTG_CHAN_REGS_OFFSET		0x20
+
+	/* Host configuration information */
+	/* Number of Host Channels (range: 1-16) */
+	u8  num_host_channels;
+	/* Periodic EPs supported (0: no, 1: yes) */
+	u8  perio_eps_supported;
+	/* Periodic Tx FIFO Size (Only 1 host periodic Tx FIFO) */
+	u16 perio_tx_fifo_size;
+};
+
+#else  /* CONFIG_DWC_OTG_REG_LE not defined */
+
+/*
+ * This union represents the bit fields of the Core OTG Control
+ * and Status Register (GOTGCTL).  Set the bits using the bit
+ * fields then write the d32 value to the register.
+ */
+union gotgctl_data {
+	u32 d32;
+	struct {
+		unsigned sesreqscs:1;
+		unsigned sesreq:1;
+		unsigned reserved2_7:6;
+		unsigned hstnegscs:1;
+		unsigned hnpreq:1;
+		unsigned hstsethnpen:1;
+		unsigned devhnpen:1;
+		unsigned reserved12_15:4;
+		unsigned conidsts:1;
+		unsigned reserved17:1;
+		unsigned asesvld:1;
+		unsigned bsesvld:1;
+		unsigned currmod:1;
+		unsigned reserved21_31:11;
+	} b;
+};
+
+/*
+ * This union represents the bit fields of the Core OTG Interrupt Register
+ * (GOTGINT).  Set/clear the bits using the bit fields then write the d32
+ * value to the register.
+ */
+union gotgint_data {
+	u32 d32;
+	struct {
+		/* Current Mode */
+		unsigned reserved0_1:2;
+
+		/* Session End Detected */
+		unsigned sesenddet:1;
+
+		unsigned reserved3_7:5;
+
+		/* Session Request Success Status Change */
+		unsigned sesreqsucstschng:1;
+		/* Host Negotiation Success Status Change */
+		unsigned hstnegsucstschng:1;
+
+		unsigned reserver10_16:7;
+
+		/* Host Negotiation Detected */
+		unsigned hstnegdet:1;
+		/* A-Device Timeout Change */
+		unsigned adevtoutchng:1;
+		/* Debounce Done */
+		unsigned debdone:1;
+
+		unsigned reserved31_20:12;
+
+	} b;
+};
+
+/*
+ * This union represents the bit fields of the Core AHB Configuration Register
+ * (GAHBCFG).  Set/clear the bits using the bit fields then write the d32 value
+ * to the register.
+ */
+union gahbcfg_data {
+	u32 d32;
+	struct {
+		unsigned glblintrmsk:1;
+#define DWC_GAHBCFG_GLBINT_ENABLE		1
+
+		unsigned hburstlen:4;
+#define DWC_GAHBCFG_INT_DMA_BURST_SINGLE	0
+#define DWC_GAHBCFG_INT_DMA_BURST_INCR		1
+#define DWC_GAHBCFG_INT_DMA_BURST_INCR4		3
+#define DWC_GAHBCFG_INT_DMA_BURST_INCR8		5
+#define DWC_GAHBCFG_INT_DMA_BURST_INCR16	7
+
+		unsigned dmaenable:1;
+#define DWC_GAHBCFG_DMAENABLE			1
+		unsigned reserved:1;
+		unsigned nptxfemplvl_txfemplvl:1;
+		unsigned ptxfemplvl:1;
+#define DWC_GAHBCFG_TXFEMPTYLVL_EMPTY		1
+#define DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY	0
+		unsigned reserved9_31:23;
+	} b;
+};
+
+/*
+ * This union represents the bit fields of the Core USB Configuration Register
+ * (GUSBCFG).  Set the bits using the bit fields then write the d32 value to
+ * the register.
+ */
+union gusbcfg_data {
+	u32 d32;
+	struct {
+		unsigned toutcal:3;
+		unsigned phyif:1;
+		unsigned ulpi_utmi_sel:1;
+		unsigned fsintf:1;
+		unsigned physel:1;
+		unsigned ddrsel:1;
+		unsigned srpcap:1;
+		unsigned hnpcap:1;
+		unsigned usbtrdtim:4;
+		unsigned nptxfrwnden:1;
+		unsigned phylpwrclksel:1;
+		unsigned otgutmifssel:1;
+		unsigned ulpi_fsls:1;
+		unsigned ulpi_auto_res:1;
+		unsigned ulpi_clk_sus_m:1;
+		unsigned ulpi_ext_vbus_drv:1;
+		unsigned ulpi_int_vbus_indicator:1;
+		unsigned term_sel_dl_pulse:1;
+		unsigned reserved23_28:6;
+		unsigned force_host_mode:1;
+		unsigned force_device_mode:1;
+		unsigned corrupt_tx_packet:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields of the Core Reset Register (GRSTCTL).
+ * Set/clear the bits using the bit fields then write the d32 value to the
+ * register.
+ */
+union grstctl_data {
+	u32 d32;
+	struct {
+		/*
+		 * Core Soft Reset (CSftRst) (Device and Host)
+		 *
+		 * The application can flush the control logic in the entire
+		 * core using this bit. This bit resets the pipelines in the AHB
+		 * Clock domain as well as the PHY Clock domain.
+		 *
+		 * The state machines are reset to an IDLE state, the control
+		 * bits in the CSRs are cleared, all the transmit FIFOs and the
+		 * receive FIFO are flushed.
+		 *
+		 * The status mask bits that control the generation of the
+		 * interrupt, are cleared, to clear the interrupt. The interrupt
+		 * status bits are not cleared, so the application can get the
+		 * status of any events that occurred in the core after it has
+		 * set this bit.
+		 *
+		 * Any transactions on the AHB are terminated as soon as
+		 * possible following the protocol. Any transactions on the USB
+		 * are terminated immediately.
+		 *
+		 * The configuration settings in the CSRs are unchanged, so the
+		 * software doesn't have to reprogram these registers (Device
+		 * Configuration/Host Configuration/Core System
+		 * Configuration/Core PHY Configuration).
+		 *
+		 * The application can write to this bit, any time it wants to
+		 * reset the core. This is a self clearing bit and the core
+		 * clears this bit after all the necessary logic is reset in the
+		 * core, which may take several clocks, depending on the current
+		 * state of the core.
+		 */
+		unsigned csftrst:1;
+		/*
+		 * Hclk Soft Reset
+		 *
+		 * The application uses this bit to reset the control logic in
+		 * the AHB clock domain. Only AHB clock domain pipelines are
+		 * reset.
+		 */
+		unsigned hsftrst:1;
+		/*
+		 * Host Frame Counter Reset (Host Only)<br>
+		 *
+		 * The application can reset the (micro)frame number counter
+		 * inside the core, using this bit. When the (micro)frame
+		 * counter is reset, the subsequent SOF sent out by the core,
+		 * will have a (micro)frame number of 0.
+		 */
+		unsigned hstfrm:1;
+		/*
+		 * In Token Sequence Learning Queue Flush (INTknQFlsh) (Device
+		 * Only)
+		 */
+		unsigned intknqflsh:1;
+		/*
+		 * RxFIFO Flush (RxFFlsh) (Device and Host)
+		 *
+		 * The application can flush the entire Receive FIFO using this
+		 * bit.
+		 *
+		 * The application must first ensure that the core is not in the
+		 * middle of a transaction.
+		 *
+		 * The application should write into this bit, only after making
+		 * sure that neither the DMA engine is reading from the RxFIFO
+		 * nor the MAC is writing the data in to the FIFO.
+		 *
+		 * The application should wait until the bit is cleared before
+		 * performing any other operations. This bit will takes 8 clocks
+		 * (slowest of PHY or AHB clock) to clear.
+		 */
+		unsigned rxfflsh:1;
+		/*
+		 * TxFIFO Flush (TxFFlsh) (Device and Host).
+		 *
+		 * This bit is used to selectively flush a single or all
+		 * transmit FIFOs.  The application must first ensure that the
+		 * core is not in the middle of a transaction.
+		 *
+		 * The application should write into this bit, only after making
+		 * sure that neither the DMA engine is writing into the TxFIFO
+		 * nor the MAC is reading the data out of the FIFO.
+		 *
+		 * The application should wait until the core clears this bit,
+		 * before performing any operations. This bit will takes 8
+		 * clocks (slowest of PHY or AHB clock) to clear.
+		 */
+		unsigned txfflsh:1;
+
+		/*
+		 * TxFIFO Number (TxFNum) (Device and Host).
+		 *
+		 * This is the FIFO number which needs to be flushed, using the
+		 * TxFIFO Flush bit. This field should not be changed until the
+		 * TxFIFO Flush bit is cleared by the core.
+		 *	 - 0x0 : Non Periodic TxFIFO Flush
+		 *	 - 0x1 : Periodic TxFIFO #1 Flush in device mode
+		 *	   or Periodic TxFIFO in host mode
+		 *	 - 0x2 : Periodic TxFIFO #2 Flush in device mode.
+		 *	 - ...
+		 *	 - 0xF : Periodic TxFIFO #15 Flush in device mode
+		 *	 - 0x10: Flush all the Transmit NonPeriodic and
+		 *	   Transmit Periodic FIFOs in the core
+		 */
+		unsigned txfnum:5;
+#define DWC_GRSTCTL_TXFNUM_ALL			0x10
+
+		/* Reserved */
+		unsigned reserved11_29:19;
+		/*
+		 * DMA Request Signal.  Indicated DMA request is in progress.
+		 * Used for debug purpose.
+		 */
+		unsigned dmareq:1;
+		/*
+		 * AHB Master Idle.  Indicates the AHB Master State Machine is
+		 * in IDLE condition.
+		 */
+		unsigned ahbidle:1;
+	} b;
+};
+
+
+/*
+ * This union represents the bit fields of the Core Interrupt Mask Register
+ * (GINTMSK). Set/clear the bits using the bit fields then write the d32 value
+ * to the register.
+ */
+union gintmsk_data {
+	u32 d32;
+	struct {
+		unsigned reserved0:1;
+		unsigned modemismatch:1;
+		unsigned otgintr:1;
+		unsigned sofintr:1;
+		unsigned rxstsqlvl:1;
+		unsigned nptxfempty:1;
+		unsigned ginnakeff:1;
+		unsigned goutnakeff:1;
+		unsigned reserved8:1;
+		unsigned i2cintr:1;
+		unsigned erlysuspend:1;
+		unsigned usbsuspend:1;
+		unsigned usbreset:1;
+		unsigned enumdone:1;
+		unsigned isooutdrop:1;
+		unsigned eopframe:1;
+		unsigned reserved16:1;
+		unsigned epmismatch:1;
+		unsigned inepintr:1;
+		unsigned outepintr:1;
+		unsigned incomplisoin:1;
+		unsigned incomplisoout:1;
+		unsigned reserved22_23:2;
+		unsigned portintr:1;
+		unsigned hcintr:1;
+		unsigned ptxfempty:1;
+		unsigned reserved27:1;
+		unsigned conidstschng:1;
+		unsigned disconnect:1;
+		unsigned sessreqintr:1;
+		unsigned wkupintr:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields of the Core Interrupt Register
+ * (GINTSTS).  Set/clear the bits using the bit fields then write the d32 value
+ * to the register.
+ */
+union gintsts_data {
+	u32 d32;
+#define DWC_SOF_INTR_MASK			0x0008
+
+	struct {
+#define DWC_HOST_MODE 1
+		unsigned curmode:1;
+		unsigned modemismatch:1;
+		unsigned otgintr:1;
+		unsigned sofintr:1;
+		unsigned rxstsqlvl:1;
+		unsigned nptxfempty:1;
+		unsigned ginnakeff:1;
+		unsigned goutnakeff:1;
+		unsigned reserved8:1;
+		unsigned i2cintr:1;
+		unsigned erlysuspend:1;
+		unsigned usbsuspend:1;
+		unsigned usbreset:1;
+		unsigned enumdone:1;
+		unsigned isooutdrop:1;
+		unsigned eopframe:1;
+		unsigned intokenrx:1;
+		unsigned epmismatch:1;
+		unsigned inepint:1;
+		unsigned outepintr:1;
+		unsigned incomplisoin:1;
+		unsigned incomplisoout:1;
+		unsigned reserved22_23:2;
+		unsigned portintr:1;
+		unsigned hcintr:1;
+		unsigned ptxfempty:1;
+		unsigned reserved27:1;
+		unsigned conidstschng:1;
+		unsigned disconnect:1;
+		unsigned sessreqintr:1;
+		unsigned wkupintr:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Device Receive Status Read and
+ * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the d32 element then
+ * read out the bits using the bit elements.
+ */
+union device_grxsts_data {
+	u32 d32;
+	struct {
+		unsigned epnum:4;
+		unsigned bcnt:11;
+		unsigned dpid:2;
+
+#define DWC_STS_DATA_UPDT		0x2	/* OUT Data Packet */
+#define DWC_STS_XFER_COMP		0x3	/* OUT Data Transfer Complete */
+#define DWC_DSTS_GOUT_NAK		0x1	/* Global OUT NAK */
+#define DWC_DSTS_SETUP_COMP		0x4	/* Setup Phase Complete */
+#define DWC_DSTS_SETUP_UPDT		0x6	/* SETUP Packet */
+		unsigned pktsts:4;
+		unsigned fn:4;
+		unsigned reserved:7;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Host Receive Status Read and
+ * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the d32 element then
+ * read out the bits using the bit elements.
+ */
+union host_grxsts_data {
+	u32 d32;
+	struct {
+		unsigned chnum:4;
+		unsigned bcnt:11;
+		unsigned dpid:2;
+
+		unsigned pktsts:4;
+#define DWC_GRXSTS_PKTSTS_IN			0x2
+#define DWC_GRXSTS_PKTSTS_IN_XFER_COMP		0x3
+#define DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR	0x5
+#define DWC_GRXSTS_PKTSTS_CH_HALTED		0x7
+
+		unsigned reserved:11;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the FIFO Size Registers (HPTXFSIZ,
+ * GNPTXFSIZ, DPTXFSIZn, DIEPTXFn). Read the register into the d32 element then
+ * read out the bits using the bit elements.
+ */
+union fifosize_data {
+	u32 d32;
+	struct {
+		unsigned startaddr:16;
+		unsigned depth:16;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Non-Periodic Transmit FIFO/Queue
+ * Status Register (GNPTXSTS). Read the register into the d32 element then read
+ * out the bits using the bit elements.
+ */
+union gnptxsts_data {
+	u32 d32;
+	struct {
+		unsigned nptxfspcavail:16;
+		unsigned nptxqspcavail:8;
+		/*
+		 * Top of the Non-Periodic Transmit Request Queue
+		 *	- bit 24 - Terminate (Last entry for the selected
+		 *	  channel/EP)
+		 *	- bits 26:25 - Token Type
+		 *	  - 2'b00 - IN/OUT
+		 *	  - 2'b01 - Zero Length OUT
+		 *	  - 2'b10 - PING/Complete Split
+		 *	  - 2'b11 - Channel Halt
+		 *	- bits 30:27 - Channel/EP Number
+		 */
+		unsigned nptxqtop_terminate:1;
+		unsigned nptxqtop_token:2;
+		unsigned nptxqtop_chnep:4;
+		unsigned reserved:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Transmit	FIFO Status Register
+ * (DTXFSTS). Read the register into the d32 element then read out the bits
+ * using the bit elements.
+ */
+union dtxfsts_data {
+	u32 d32;
+	struct {
+		unsigned txfspcavail:16;
+		unsigned reserved:16;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the I2C Control Register (I2CCTL).
+ * Read the register into the d32 element then read out the bits using the bit
+ * elements.
+ */
+union gi2cctl_data {
+	u32 d32;
+	struct {
+		unsigned rwdata:8;
+		unsigned regaddr:8;
+		unsigned addr:7;
+		unsigned i2cen:1;
+		unsigned ack:1;
+		unsigned i2csuspctl:1;
+		unsigned i2cdevaddr:2;
+		unsigned reserved:2;
+		unsigned rw:1;
+		unsigned bsydne:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the User HW Config1 Register.  Read
+ * the register into the d32 element then read out the bits using the bit
+ * elements.
+ */
+union hwcfg1_data {
+	u32 d32;
+	struct {
+		unsigned ep_dir0:2;
+		unsigned ep_dir1:2;
+		unsigned ep_dir2:2;
+		unsigned ep_dir3:2;
+		unsigned ep_dir4:2;
+		unsigned ep_dir5:2;
+		unsigned ep_dir6:2;
+		unsigned ep_dir7:2;
+		unsigned ep_dir8:2;
+		unsigned ep_dir9:2;
+		unsigned ep_dir10:2;
+		unsigned ep_dir11:2;
+		unsigned ep_dir12:2;
+		unsigned ep_dir13:2;
+		unsigned ep_dir14:2;
+		unsigned ep_dir15:2;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the User HW Config2 Register.  Read
+ * the register into the d32 element then read out the bits using the bit
+ * elements.
+ */
+union hwcfg2_data {
+	u32 d32;
+	struct {
+		/* GHWCFG2 */
+		unsigned op_mode:3;
+#define DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG		0
+#define DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG		1
+#define DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG	2
+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE		3
+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE	4
+#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST		5
+#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST		6
+
+		unsigned architecture:2;
+		unsigned point2point:1;
+		unsigned hs_phy_type:2;
+#define DWC_HWCFG2_HS_PHY_TYPE_NOT_SUPPORTED		0
+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI			1
+#define DWC_HWCFG2_HS_PHY_TYPE_ULPI			2
+#define DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI		3
+
+		unsigned fs_phy_type:2;
+		unsigned num_dev_ep:4;
+		unsigned num_host_chan:4;
+		unsigned perio_ep_supported:1;
+		unsigned dynamic_fifo:1;
+		unsigned rx_status_q_depth:2;
+		unsigned nonperio_tx_q_depth:2;
+		unsigned host_perio_tx_q_depth:2;
+		unsigned dev_token_q_depth:5;
+		unsigned reserved31:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the User HW Config3 Register.  Read
+ * the register into the d32 element then read out the bits using the bit
+ * elements.
+ */
+union hwcfg3_data {
+	u32 d32;
+	struct {
+		/* GHWCFG3 */
+		unsigned xfer_size_cntr_width:4;
+		unsigned packet_size_cntr_width:3;
+		unsigned otg_func:1;
+		unsigned i2c:1;
+		unsigned vendor_ctrl_if:1;
+		unsigned optional_features:1;
+		unsigned synch_reset_type:1;
+		unsigned reserved15_12:4;
+		unsigned dfifo_depth:16;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the User HW Config4 Register.  Read
+ * the register into the d32 element then read out the bits using the bit
+ * elements.
+ */
+union hwcfg4_data {
+	u32 d32;
+	struct {
+		unsigned num_dev_perio_in_ep:4;
+		unsigned power_optimiz:1;
+		unsigned min_ahb_freq:9;
+		unsigned utmi_phy_data_width:2;
+		unsigned num_dev_mode_ctrl_ep:4;
+		unsigned iddig_filt_en:1;
+		unsigned vbus_valid_filt_en:1;
+		unsigned a_valid_filt_en:1;
+		unsigned b_valid_filt_en:1;
+		unsigned session_end_filt_en:1;
+		unsigned ded_fifo_en:1;
+		unsigned num_in_eps:4;
+		unsigned reserved31_30:2;
+	} b;
+};
+
+/*
+ * Device Global Registers. Offsets 800h-BFFh
+ *
+ * The following structures define the size and relative field offsets for the
+ * Device Mode Registers.
+ *
+ * These registers are visible only in Device mode and must not be accessed in
+ * Host mode, as the results are unknown.
+ */
+struct device_global_regs {
+	/* Device Configuration Register.			Offset 800h */
+	u32 dcfg;
+	/* Device Control Register.				Offset: 804h */
+	u32 dctl;
+	/* Device Status Register (Read Only).			Offset: 808h */
+	u32 dsts;
+	/* Reserved.						Offset: 80Ch */
+	u32 unused;
+	/* Device IN Endpoint Common Interrupt Mask Register.	Offset: 810h */
+	u32 diepmsk;
+	/* Device OUT Endpoint Common Interrupt MaskRegister.	Offset: 814h */
+	u32 doepmsk;
+	/* Device All Endpoints Interrupt Register.		Offset: 818h */
+	u32 daint;
+	/* Device All Endpoints Interrupt Mask Register.	Offset:	81Ch */
+	u32 daintmsk;
+	/* Device IN Token Queue Read Register-1 (Read Only).	Offset: 820h */
+	u32 dtknqr1;
+	/* Device IN Token Queue Read Register-2 (Read Only).	Offset: 824h */
+	u32 dtknqr2;
+	/* Device VBUS	 discharge Register.			Offset: 828h */
+	u32 dvbusdis;
+	/* Device VBUS Pulse Register.				Offset: 82Ch */
+	u32 dvbuspulse;
+	/*
+	 * Device IN Token Queue Read Register-3 (Read Only).
+	 * Device Thresholding control register (Read/Write)
+	 *							Offset: 830h
+	 */
+	u32 dtknqr3_dthrctl;
+	/*
+	 * Device IN Token Queue Read Register-4 (Read Only).
+	 * Device IN EPs empty Inr. Mask Register (Read/Write)
+	 *							Offset: 834h
+	 */
+	u32 dtknqr4_fifoemptymsk;
+};
+
+/*
+ * This union represents the bit fields in the Device Configuration Register.
+ * Read the register into the d32 member then  set/clear the bits using the bit
+ * elements.  Write the d32 member to the dcfg register.
+ */
+union dcfg_data {
+	u32 d32;
+	struct {
+		/* Device Speed */
+		unsigned devspd:2;
+		/* Non Zero Length Status OUT Handshake */
+		unsigned nzstsouthshk:1;
+#define DWC_DCFG_SEND_STALL			1
+
+		unsigned reserved3:1;
+		/* Device Addresses */
+		unsigned devaddr:7;
+		/* Periodic Frame Interval */
+		unsigned perfrint:2;
+#define DWC_DCFG_FRAME_INTERVAL_80		0
+#define DWC_DCFG_FRAME_INTERVAL_85		1
+#define DWC_DCFG_FRAME_INTERVAL_90		2
+#define DWC_DCFG_FRAME_INTERVAL_95		3
+
+		unsigned reserved13_17:5;
+		/* In Endpoint Mis-match count */
+		unsigned epmscnt:4;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Device Control Register.  Read
+ * the register into the d32 member then set/clear the bits using the bit
+ * elements.
+ */
+union dctl_data {
+	u32 d32;
+	struct {
+		/* Remote Wakeup */
+		unsigned rmtwkupsig:1;
+		/* Soft Disconnect */
+		unsigned sftdiscon:1;
+		/* Global Non-Periodic IN NAK Status */
+		unsigned gnpinnaksts:1;
+		/* Global OUT NAK Status */
+		unsigned goutnaksts:1;
+		/* Test Control */
+		unsigned tstctl:3;
+		/* Set Global Non-Periodic IN NAK */
+		unsigned sgnpinnak:1;
+		/* Clear Global Non-Periodic IN NAK */
+		unsigned cgnpinnak:1;
+		/* Set Global OUT NAK */
+		unsigned sgoutnak:1;
+		/* Clear Global OUT NAK */
+		unsigned cgoutnak:1;
+		unsigned reserved:21;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Device Status Register.  Read the
+ * register into the d32 member then set/clear the bits using the bit elements.
+ */
+union dsts_data	{
+	u32 d32;
+	struct {
+		/* Suspend Status */
+		unsigned suspsts:1;
+		/* Enumerated Speed */
+		unsigned enumspd:2;
+#define DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ		0
+#define DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ		1
+#define DWC_DSTS_ENUMSPD_LS_PHY_6MHZ			2
+#define DWC_DSTS_ENUMSPD_FS_PHY_48MHZ			3
+
+		/* Erratic Error */
+		unsigned errticerr:1;
+		unsigned reserved4_7:4;
+		/* Frame or Microframe Number of the received SOF */
+		unsigned soffn:14;
+		unsigned reserved22_31:10;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Device IN EP Interrupt Register
+ * and the Device IN EP Common Mask Register. Read the register into the d32
+ * member then set/clear the bits using the bit elements.
+ */
+union diepint_data {
+	u32 d32;
+	struct {
+		/* Transfer complete mask */
+		unsigned xfercompl:1;
+		/* Endpoint disable mask */
+		unsigned epdisabled:1;
+		/* AHB Error mask */
+		unsigned ahberr:1;
+		/* TimeOUT Handshake mask (non-ISOC EPs) */
+		unsigned timeout:1;
+		/* IN Token received with TxF Empty mask */
+		unsigned intktxfemp:1;
+		/* IN Token Received with EP mismatch mask */
+		unsigned intknepmis:1;
+		/* IN Endpoint HAK Effective mask */
+		unsigned inepnakeff:1;
+		/* IN Endpoint HAK Effective mask */
+		unsigned emptyintr:1;
+		unsigned txfifoundrn:1;
+		unsigned reserved08_31:23;
+		} b;
+};
+
+/*
+ * This union represents the bit fields in the Device OUT EP Interrupt
+ * Registerand Device OUT EP Common Interrupt Mask Register.  Read the register
+ * into the d32 member then set/clear the  bits using the bit elements.
+ */
+union doepint_data {
+	u32 d32;
+	struct {
+		/* Transfer complete */
+		unsigned xfercompl:1;
+		/* Endpoint disable  */
+		unsigned epdisabled:1;
+		/* AHB Error */
+		unsigned ahberr:1;
+		/* Setup Phase Done (contorl EPs) */
+		unsigned setup:1;
+		unsigned reserved04_31:28;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Device All EP Interrupt and Mask
+ * Registers.  Read the register into the d32 member then set/clear the bits
+ * using the bit elements.
+ */
+union daint_data {
+	u32 d32;
+	struct {
+		/* IN Endpoint bits */
+		unsigned in:16;
+		/* OUT Endpoint bits */
+		unsigned out:16;
+	} ep;
+	struct {
+		/* IN Endpoint bits */
+		unsigned inep0:1;
+		unsigned inep1:1;
+		unsigned inep2:1;
+		unsigned inep3:1;
+		unsigned inep4:1;
+		unsigned inep5:1;
+		unsigned inep6:1;
+		unsigned inep7:1;
+		unsigned inep8:1;
+		unsigned inep9:1;
+		unsigned inep10:1;
+		unsigned inep11:1;
+		unsigned inep12:1;
+		unsigned inep13:1;
+		unsigned inep14:1;
+		unsigned inep15:1;
+		/* OUT Endpoint bits */
+		unsigned outep0:1;
+		unsigned outep1:1;
+		unsigned outep2:1;
+		unsigned outep3:1;
+		unsigned outep4:1;
+		unsigned outep5:1;
+		unsigned outep6:1;
+		unsigned outep7:1;
+		unsigned outep8:1;
+		unsigned outep9:1;
+		unsigned outep10:1;
+		unsigned outep11:1;
+		unsigned outep12:1;
+		unsigned outep13:1;
+		unsigned outep14:1;
+		unsigned outep15:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Device IN Token Queue Read
+ * Registers.  Read the register into the d32 member.  READ-ONLY Register
+ */
+union dtknq1_data {
+	u32 d32;
+	struct {
+		/* In Token Queue Write Pointer */
+		unsigned intknwptr:5;
+		/* Reserved */
+		unsigned reserved05_06:2;
+		/* write pointer has wrapped. */
+		unsigned wrap_bit:1;
+		/* EP Numbers of IN Tokens 0 ... 4 */
+		unsigned epnums0_5:24;
+	} b;
+};
+
+/*
+ * This union represents Threshold control Register Read and write the register
+ * into the d32 member.  READ-WRITABLE Register
+ */
+union dthrctl_data {
+	u32 d32;
+	struct {
+		/* non ISO Tx Thr. Enable */
+		unsigned non_iso_thr_en:1;
+		/* ISO Tx Thr. Enable */
+		unsigned iso_thr_en:1;
+		/* Tx Thr. Length */
+		unsigned tx_thr_len:9;
+		/* Reserved */
+		unsigned reserved11_15:5;
+		/* Rx Thr. Enable */
+		unsigned rx_thr_en:1;
+		/* Rx Thr. Length */
+		unsigned rx_thr_len:9;
+		/* Reserved */
+		unsigned reserved26_31:6;
+	} b;
+};
+
+/*
+ * Device Logical IN Endpoint-Specific Registers. Offsets 900h-AFCh
+ *
+ * There will be one set of endpoint registers per logical endpoint implemented.
+ *
+ * These registers are visible only in Device mode and must not be accessed in
+ * Host mode, as the results are unknown.
+ */
+struct device_in_ep_regs {
+	/*
+	 * Device IN Endpoint Control Register.
+	 * Offset: 900h + (ep_num * 20h) + 00h
+	 */
+	u32 diepctl;
+	/* Reserved. Offset:900h + (ep_num * 20h) + 04h */
+	u32 reserved04;
+	/*
+	 * Device IN Endpoint Interrupt Register.
+	 * Offset: 900h + (ep_num * 20h) + 08h
+	 */
+	u32 diepint;
+	/* Reserved. Offset:900h + (ep_num * 20h) + 0Ch */
+	u32 reserved0C;
+	/*
+	 * Device IN Endpoint Transfer Size Register.
+	 * Offset: 900h + (ep_num * 20h) + 10h
+	 */
+	u32 dieptsiz;
+	/*
+	 * Device IN Endpoint DMA Address Register.
+	 * Offset: 900h + (ep_num * 20h) + 14h
+	 */
+	u32 diepdma;
+	/*
+	 * Device IN Endpoint Transmit FIFO Status Register.
+	 * Offset: 900h + (ep_num * 20h) + 18h
+	 */
+	u32 dtxfsts;
+	/*
+	 * Reserved.
+	 * Offset: 900h + (ep_num * 20h) + 1Ch - 900h + (ep_num * 20h) + 1Ch
+	 */
+	u32 reserved18;
+};
+
+/*
+ * Device Logical OUT Endpoint-Specific Registers. Offsets: B00h-CFCh
+ *
+ * There will be one set of endpoint registers per logical endpoint implemented.
+ *
+ * These registers are visible only in Device mode and must not be accessed in
+ * Host mode, as the results are unknown.
+ */
+struct device_out_ep_regs {
+	/*
+	 * Device OUT Endpoint Control Register.
+	 * Offset: B00h + (ep_num * 20h) + 00h
+	 */
+	u32 doepctl;
+	/*
+	 * Device OUT Endpoint Frame number Register.
+	 * Offset: B00h + (ep_num * 20h) + 04h
+	 */
+	u32 doepfn;
+	/*
+	 * Device OUT Endpoint Interrupt Register.
+	 * Offset: B00h + (ep_num * 20h) + 08h
+	 */
+	u32 doepint;
+	/* Reserved. Offset:B00h + (ep_num * 20h) + 0Ch */
+	u32 reserved0C;
+	/*
+	 * Device OUT Endpoint Transfer Size Register.
+	 * Offset: B00h + (ep_num * 20h) + 10h
+	 */
+	u32 doeptsiz;
+	/*
+	 * Device OUT Endpoint DMA Address Register.
+	 * Offset: B00h + (ep_num * 20h) + 14h
+	 */
+	u32 doepdma;
+	/*
+	 * Reserved.
+	 * Offset:B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch
+	 */
+	u32 unused[2];
+};
+
+/*
+ * This union represents the bit fields in the Device EP Control Register.  Read
+ * the register into the d32 member then set/clear the bits using the bit
+ * elements.
+ */
+union depctl_data {
+	u32 d32;
+	struct {
+		/* Maximum Packet Size
+		 * IN/OUT EPn
+		 * IN/OUT EP0 - 2 bits
+		 *	 2'b00: 64 Bytes
+		 *	 2'b01: 32
+		 *	 2'b10: 16
+		 *	 2'b11: 8
+		 */
+		unsigned mps:11;
+#define DWC_DEP0CTL_MPS_64			0
+#define DWC_DEP0CTL_MPS_32			1
+#define DWC_DEP0CTL_MPS_16			2
+#define DWC_DEP0CTL_MPS_8			3
+
+		/*
+		 * Next Endpoint
+		 * IN EPn/IN EP0
+		 * OUT EPn/OUT EP0 - reserved
+		 */
+		unsigned nextep:4;
+		/* USB Active Endpoint */
+		unsigned usbactep:1;
+		/*
+		 * Endpoint DPID (INTR/Bulk IN and OUT endpoints) This field
+		 * contains the PID of the packet going to be received or
+		 * transmitted on this endpoint. The application should program
+		 * the PID of the first packet going to be received or
+		 * transmitted on this endpoint , after the endpoint is
+		 * activated. Application use the SetD1PID and SetD0PID fields
+		 * of this register to program either D0 or D1 PID.
+		 *
+		 * The encoding for this field is
+		 *	 - 0: D0
+		 *	 - 1: D1
+		 */
+		unsigned dpid:1;
+		/* NAK Status */
+		unsigned naksts:1;
+		/* Endpoint Type
+		 *	2'b00: Control
+		 *	2'b01: Isochronous
+		 *	2'b10: Bulk
+		 *	2'b11: Interrupt
+		 */
+		unsigned eptype:2;
+		/*
+		 * Snoop Mode
+		 * OUT EPn/OUT EP0
+		 * IN EPn/IN EP0 - reserved
+		 */
+		unsigned snp:1;
+		/* Stall Handshake */
+		unsigned stall:1;
+		/*
+		 * Tx Fifo Number
+		 * IN EPn/IN EP0
+		 * OUT EPn/OUT EP0 - reserved
+		 */
+		unsigned txfnum:4;
+		/* Clear NAK */
+		unsigned cnak:1;
+		/* Set NAK */
+		unsigned snak:1;
+		/*
+		 * Set DATA0 PID (INTR/Bulk IN and OUT endpoints)
+		 *
+		 * Writing to this field sets the Endpoint DPID (DPID) field in
+		 * this register to DATA0. Set Even (micro)frame (SetEvenFr)
+		 * (ISO IN and OUT Endpoints)
+		 *
+		 * Writing to this field sets the Even/Odd (micro)frame
+		 * (EO_FrNum) field to even (micro) frame.
+		 */
+		unsigned setd0pid:1;
+		/*
+		 * Set DATA1 PID (INTR/Bulk IN and OUT endpoints)
+		 *
+		 * Writing to this field sets the Endpoint DPID (DPID) field in
+		 * this register to DATA1 Set Odd (micro)frame (SetOddFr) (ISO
+		 * IN and OUT Endpoints)
+		 *
+		 * Writing to this field sets the Even/Odd (micro)frame
+		 * (EO_FrNum) field to odd (micro) frame.
+		 */
+		unsigned setd1pid:1;
+		/* Endpoint Disable */
+		unsigned epdis:1;
+		/* Endpoint Enable */
+		unsigned epena:1;
+		} b;
+};
+
+/*
+ * This union represents the bit fields in the Device EP Transfer Size Register.
+ * Read the register into the d32 member then set/clear the bits using the bit
+ * elements.
+ */
+union deptsiz_data {
+	u32 d32;
+	struct {
+		/* Transfer size */
+		unsigned xfersize:19;
+		/* Packet Count */
+		unsigned pktcnt:10;
+		/* Multi Count - Periodic IN endpoints */
+		unsigned mc:2;
+		unsigned reserved:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Device EP 0 Transfer Size
+ * Register.  Read the register into the d32 member then set/clear the bits
+ * using the bit elements.
+ */
+union deptsiz0_data {
+	u32 d32;
+	struct {
+		/* Transfer size */
+		unsigned xfersize:7;
+		/* Reserved */
+		unsigned reserved7_18:12;
+		/* Packet Count */
+		unsigned pktcnt:2;
+		/* Reserved */
+		unsigned reserved21_28:9;
+		/* Setup Packet Count (DOEPTSIZ0 Only) */
+		unsigned supcnt:2;
+		unsigned reserved31;
+	} b;
+};
+
+#define MAX_PERIO_FIFOS			15	/* Max periodic FIFOs */
+#define MAX_TX_FIFOS			15	/* Max non-periodic FIFOs */
+#define MAX_EPS_CHANNELS		4	/* Max Endpoints/HostChannels */
+
+/*
+ * The device_if structure contains information needed to manage the
+ * DWC_otg controller acting in device mode. It represents the programming view
+ * of the device-specific aspects of the controller.
+ */
+struct device_if {
+	/* Device Global Registers starting at offset 800h */
+	struct device_global_regs *dev_global_regs;
+#define DWC_DEV_GLOBAL_REG_OFFSET		0x800
+
+	/* Device Logical IN Endpoint-Specific Registers 900h-AFCh */
+	struct device_in_ep_regs *in_ep_regs[MAX_EPS_CHANNELS/2];
+#define DWC_DEV_IN_EP_REG_OFFSET		0x900
+#define DWC_EP_REG_OFFSET			0x20
+
+	/* Device Logical OUT Endpoint-Specific Registers B00h-CFCh */
+	struct device_out_ep_regs *out_ep_regs[MAX_EPS_CHANNELS/2];
+#define DWC_DEV_OUT_EP_REG_OFFSET		0xB00
+
+	/* Device Speed		0: Unknown, 1: LS, 2:FS, 3: HS */
+	u8 speed;
+	/* Number # of Tx EP range: 0-15 exept ep0 */
+	u8 num_in_eps;
+	/* Number # of Rx EP range: 0-15 exept ep0 */
+	u8 num_out_eps;
+
+	/* Size of periodic FIFOs (Bytes) */
+	u16 perio_tx_fifo_size[MAX_PERIO_FIFOS];
+
+	/* Size of Tx FIFOs (Bytes) */
+	u16 tx_fifo_size[MAX_TX_FIFOS];
+
+	/* Thresholding enable flags and length varaiables */
+	u16 rx_thr_en;
+	u16 iso_tx_thr_en;
+	u16 non_iso_tx_thr_en;
+	u16 rx_thr_length;
+	u16 tx_thr_length;
+};
+
+/*
+ * The Host Global Registers structure defines the size and relative
+ * field offsets for the Host Mode Global Registers.  Host Global
+ * Registers offsets 400h-7FFh.
+*/
+struct host_global_regs {
+	/* Host Configuration Register.   Offset: 400h */
+	u32 hcfg;
+	/* Host Frame Interval Register.	Offset: 404h */
+	u32 hfir;
+	/* Host Frame Number / Frame Remaining Register. Offset: 408h */
+	u32 hfnum;
+       /* Reserved.	Offset: 40Ch */
+	u32 reserved40C;
+	/* Host Periodic Transmit FIFO/ Queue Status Register. Offset: 410h */
+	u32 hptxsts;
+	/* Host All Channels Interrupt Register. Offset: 414h */
+	u32 haint;
+	/* Host All Channels Interrupt Mask Register. Offset: 418h */
+	u32 haintmsk;
+};
+
+/*
+ * This union represents the bit fields in the Host Configuration Register.
+ * Read the register into the d32 member then set/clear the bits using
+ * the bit elements. Write the d32 member to the hcfg register.
+ */
+union hcfg_data {
+	u32 d32;
+	struct {
+		/* FS/LS Phy Clock Select */
+		unsigned fslspclksel:2;
+#define DWC_HCFG_30_60_MHZ			0
+#define DWC_HCFG_48_MHZ				1
+#define DWC_HCFG_6_MHZ				2
+
+		/* FS/LS Only Support */
+		unsigned fslssupp:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Host Frame Remaing/Number
+ * Register.
+ */
+union hfir_data {
+	u32 d32;
+	struct {
+		unsigned frint:16;
+		unsigned reserved:16;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Host Frame Remaing/Number
+ * Register.
+ */
+union hfnum_data {
+	u32 d32;
+	struct {
+		unsigned frnum:16;
+#define DWC_HFNUM_MAX_FRNUM			0x3FFF
+		unsigned frrem:16;
+	} b;
+};
+
+union hptxsts_data {
+	u32 d32;
+	struct {
+		unsigned ptxfspcavail:16;
+		unsigned ptxqspcavail:8;
+		/*
+		 * Top of the Periodic Transmit Request Queue
+		 *	- bit 24 - Terminate (last entry of selected channel)
+		 *	- bits 26:25 - Token Type
+		 *	  - 2'b00 - Zero length
+		 *	  - 2'b01 - Ping
+		 *	  - 2'b10 - Disable
+		 *	- bits 30:27 - Channel Number
+		 *	- bit 31 - Odd/even microframe
+		 */
+		unsigned ptxqtop_terminate:1;
+		unsigned ptxqtop_token:2;
+		unsigned ptxqtop_chnum:4;
+		unsigned ptxqtop_odd:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Host Port Control and Status
+ * Register. Read the register into the d32 member then set/clear the bits using
+ * the bit elements. Write the d32 member to the hprt0 register.
+ */
+union hprt0_data {
+	u32 d32;
+	struct {
+		unsigned prtconnsts:1;
+		unsigned prtconndet:1;
+		unsigned prtena:1;
+		unsigned prtenchng:1;
+		unsigned prtovrcurract:1;
+		unsigned prtovrcurrchng:1;
+		unsigned prtres:1;
+		unsigned prtsusp:1;
+		unsigned prtrst:1;
+		unsigned reserved9:1;
+		unsigned prtlnsts:2;
+		unsigned prtpwr:1;
+		unsigned prttstctl:4;
+		unsigned prtspd:2;
+#define DWC_HPRT0_PRTSPD_HIGH_SPEED		0
+#define DWC_HPRT0_PRTSPD_FULL_SPEED		1
+#define DWC_HPRT0_PRTSPD_LOW_SPEED		2
+		unsigned reserved19_31:13;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Host All Interrupt Register.
+ */
+union haint_data {
+	u32 d32;
+	struct {
+		unsigned ch0:1;
+		unsigned ch1:1;
+		unsigned ch2:1;
+		unsigned ch3:1;
+		unsigned ch4:1;
+		unsigned ch5:1;
+		unsigned ch6:1;
+		unsigned ch7:1;
+		unsigned ch8:1;
+		unsigned ch9:1;
+		unsigned ch10:1;
+		unsigned ch11:1;
+		unsigned ch12:1;
+		unsigned ch13:1;
+		unsigned ch14:1;
+		unsigned ch15:1;
+		unsigned reserved:16;
+	} b;
+
+	struct {
+		unsigned chint:16;
+		unsigned reserved:16;
+	} b2;
+};
+
+/*
+ * This union represents the bit fields in the Host All Interrupt Register.
+ */
+union haintmsk_data {
+	u32 d32;
+	struct {
+		unsigned ch0:1;
+		unsigned ch1:1;
+		unsigned ch2:1;
+		unsigned ch3:1;
+		unsigned ch4:1;
+		unsigned ch5:1;
+		unsigned ch6:1;
+		unsigned ch7:1;
+		unsigned ch8:1;
+		unsigned ch9:1;
+		unsigned ch10:1;
+		unsigned ch11:1;
+		unsigned ch12:1;
+		unsigned ch13:1;
+		unsigned ch14:1;
+		unsigned ch15:1;
+		unsigned reserved:16;
+	} b;
+
+	struct {
+		unsigned chint:16;
+		unsigned reserved:16;
+	} b2;
+};
+
+/*
+ * Host Channel Specific Registers. 500h-5FCh
+ */
+struct dwc_hc_regs {
+	/*
+	 * Host Channel 0 Characteristic Register.
+	 * Offset: 500h + (chan_num * 20h) + 00h
+	 */
+	u32 hcchar;
+	/*
+	 * Host Channel 0 Split Control Register.
+	 * Offset: 500h + (chan_num * 20h) + 04h
+	 */
+	u32 hcsplt;
+	/*
+	 * Host Channel 0 Interrupt Register.
+	 * Offset: 500h + (chan_num * 20h) + 08h
+	 */
+	u32 hcint;
+	/*
+	 * Host Channel 0 Interrupt Mask Register.
+	 * Offset: 500h + (chan_num * 20h) + 0Ch
+	 */
+	u32 hcintmsk;
+	/*
+	 * Host Channel 0 Transfer Size Register.
+	 * Offset: 500h + (chan_num * 20h) + 10h
+	 */
+	u32 hctsiz;
+	/*
+	 * Host Channel 0 DMA Address Register.
+	 * Offset: 500h + (chan_num * 20h) + 14h
+	 */
+	u32 hcdma;
+	/* Reserved.
+	 * Offset: 500h + (chan_num * 20h) + 18h - 500h + (chan_num * 20h) + 1Ch
+	 */
+	u32 reserved[2];
+};
+
+/*
+ * This union represents the bit fields in the Host Channel Characteristics
+ * Register. Read the register into the d32 member then set/clear the bits using
+ * the bit elements. Write the d32 member to the hcchar register.
+ */
+union hcchar_data {
+	u32 d32;
+	struct {
+		/* Maximum packet size in bytes */
+		unsigned mps:11;
+		/* Endpoint number */
+		unsigned epnum:4;
+		/* 0: OUT, 1: IN */
+		unsigned epdir:1;
+		unsigned reserved:1;
+		/* 0: Full/high speed device, 1: Low speed device */
+		unsigned lspddev:1;
+		/* 0: Control, 1: Isoc, 2: Bulk, 3: Intr */
+		unsigned eptype:2;
+		/* Packets per frame for periodic transfers. 0 is reserved. */
+		unsigned multicnt:2;
+		/* Device address */
+		unsigned devaddr:7;
+		/*
+		 * Frame to transmit periodic transaction.
+		 * 0: even, 1: odd
+		 */
+		unsigned oddfrm:1;
+		/* Channel disable */
+		unsigned chdis:1;
+		/* Channel enable */
+		unsigned chen:1;
+	} b;
+};
+
+union hcsplt_data {
+	u32 d32;
+	struct {
+		/* Port Address */
+		unsigned prtaddr:7;
+		/* Hub Address */
+		unsigned hubaddr:7;
+		/* Transaction Position */
+		unsigned xactpos:2;
+#define DWC_HCSPLIT_XACTPOS_MID			0
+#define DWC_HCSPLIT_XACTPOS_END			1
+#define DWC_HCSPLIT_XACTPOS_BEGIN		2
+#define DWC_HCSPLIT_XACTPOS_ALL			3
+
+		/* Do Complete Split */
+		unsigned compsplt:1;
+		/* Reserved */
+		unsigned reserved:14;
+		/* Split Enble */
+		unsigned spltena:1;
+	} b;
+};
+
+
+/*
+ * This union represents the bit fields in the Host All Interrupt Register.
+ */
+union hcint_data {
+	u32 d32;
+	struct {
+		/* Transfer Complete */
+		unsigned xfercomp:1;
+		/* Channel Halted */
+		unsigned chhltd:1;
+		/* AHB Error */
+		unsigned ahberr:1;
+		/* STALL Response Received */
+		unsigned stall:1;
+		/* NAK Response Received */
+		unsigned nak:1;
+		/* ACK Response Received */
+		unsigned ack:1;
+		/* NYET Response Received */
+		unsigned nyet:1;
+		/* Transaction Err */
+		unsigned xacterr:1;
+		/* Babble Error */
+		unsigned bblerr:1;
+		/* Frame Overrun */
+		unsigned frmovrun:1;
+		/* Data Toggle Error */
+		unsigned datatglerr:1;
+		/* Reserved */
+		unsigned reserved:21;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Host Channel Transfer Size
+ * Register. Read the register into the d32 member then set/clear the bits using
+ * the bit elements. Write the d32 member to the hcchar register.
+ */
+union hctsiz_data {
+	u32 d32;
+	struct {
+		/* Total transfer size in bytes */
+		unsigned xfersize:19;
+		/* Data packets to transfer */
+		unsigned pktcnt:10;
+		/*
+		 * Packet ID for next data packet
+		 * 0: DATA0
+		 * 1: DATA2
+		 * 2: DATA1
+		 * 3: MDATA (non-Control), SETUP (Control)
+		 */
+		unsigned pid:2;
+#define DWC_HCTSIZ_DATA0			0
+#define DWC_HCTSIZ_DATA1			2
+#define DWC_HCTSIZ_DATA2			1
+#define DWC_HCTSIZ_MDATA			3
+#define DWC_HCTSIZ_SETUP			3
+
+		/* Do PING protocol when 1 */
+		unsigned dopng:1;
+	} b;
+};
+
+/*
+ * This union represents the bit fields in the Host Channel Interrupt Mask
+ * Register. Read the register into the d32 member then set/clear the bits using
+ * the bit elements. Write the d32 member to the hcintmsk register.
+ */
+union hcintmsk_data {
+	u32 d32;
+	struct {
+		unsigned xfercompl:1;
+		unsigned chhltd:1;
+		unsigned ahberr:1;
+		unsigned stall:1;
+		unsigned nak:1;
+		unsigned ack:1;
+		unsigned nyet:1;
+		unsigned xacterr:1;
+		unsigned bblerr:1;
+		unsigned frmovrun:1;
+		unsigned datatglerr:1;
+		unsigned reserved:21;
+	} b;
+};
+
+/* OTG Host Interface Structure.
+ *
+ * The OTG Host Interface Structure structure contains information needed to
+ * manage the DWC_otg controller acting in host mode. It represents the
+ * programming view of the host-specific aspects of the controller.
+ */
+struct dwc_host_if {
+	/* Host Global Registers starting at offset 400h.*/
+	struct host_global_regs *host_global_regs;
+#define DWC_OTG_HOST_GLOBAL_REG_OFFSET			0x400
+
+	/* Host Port 0 Control and Status Register */
+	u32 *hprt0;
+#define DWC_OTG_HOST_PORT_REGS_OFFSET			0x440
+
+	/* Host Channel Specific Registers at offsets 500h-5FCh. */
+	struct dwc_hc_regs *hc_regs[MAX_EPS_CHANNELS];
+#define DWC_OTG_HOST_CHAN_REGS_OFFSET			0x500
+#define DWC_OTG_CHAN_REGS_OFFSET			0x20
+
+	/* Host configuration information */
+	/* Number of Host Channels (range: 1-16) */
+	u8 num_host_channels;
+	/* Periodic EPs supported (0: no, 1: yes) */
+	u8 perio_eps_supported;
+	/* Periodic Tx FIFO Size (Only 1 host periodic Tx FIFO) */
+	u16 perio_tx_fifo_size;
+};
+
+/*
+ * This union represents the bit fields in the Power and Clock Gating Control
+ * Register. Read the register into the d32 member then set/clear the bits using
+ * the bit elements.
+ */
+union pcgcctl_data {
+	u32 d32;
+	struct {
+		/* Stop Pclk */
+		unsigned stoppclk:1;
+		/* Gate Hclk */
+		unsigned gatehclk:1;
+		/* Power Clamp */
+		unsigned pwrclmp:1;
+		/* Reset Power Down Modules */
+		unsigned rstpdwnmodule:1;
+		/* PHY Suspended */
+		unsigned physuspended:1;
+		unsigned reserved:27;
+	} b;
+};
+
+#endif /* CONFIG_DWC_OTG_REG_LE */
+#endif
-- 
1.6.0.1

^ permalink raw reply related

* [PATCH 4/9] Add Synopsys DesignWare HS USB OTG Controller driver.
From: Fushen Chen @ 2010-06-29 21:26 UTC (permalink / raw)
  To: linux-usb; +Cc: linuxppc-dev, gregkh, Mark Miesfeld, Fushen Chen
In-Reply-To: <12778468231438-git-send-email-fchen@apm.com>

Implements DWC OTG USB Host Controller Driver (HCD) and interface to
USB Host controller Driver framework.

Signed-off-by: Fushen Chen <fchen@apm.com>
Signed-off-by: Mark Miesfeld <mmiesfeld@apm.com>
---
 drivers/usb/otg/dwc_otg_hcd.c | 2397 +++++++++++++++++++++++++++++++++++++++++
 drivers/usb/otg/dwc_otg_hcd.h |  421 ++++++++
 2 files changed, 2818 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/otg/dwc_otg_hcd.c
 create mode 100644 drivers/usb/otg/dwc_otg_hcd.h

diff --git a/drivers/usb/otg/dwc_otg_hcd.c b/drivers/usb/otg/dwc_otg_hcd.c
new file mode 100644
index 0000000..5c9af7c
--- /dev/null
+++ b/drivers/usb/otg/dwc_otg_hcd.c
@@ -0,0 +1,2397 @@
+/*
+ * DesignWare HS OTG controller driver
+ *
+ * Author: Mark Miesfeld <mmiesfeld@apm.com>
+ *
+ * Based on versions provided by AMCC and Synopsis which are:
+ *	Copyright (C) 2009-2010 AppliedMicro(www.apm.com)
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * This file contains the implementation of the HCD. In Linux, the HCD
+ * implements the hc_driver API.
+ */
+
+#include <asm/unaligned.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+
+#include "dwc_otg_driver.h"
+#include "dwc_otg_hcd.h"
+#include "dwc_otg_regs.h"
+
+static const char dwc_otg_hcd_name[] = "dwc_otg_hcd";
+
+/**
+ * Clears the transfer state for a host channel. This function is normally
+ * called after a transfer is done and the host channel is being released. It
+ * clears the channel interrupt enables and any unhandled channel interrupt
+ * conditions.
+ */
+void dwc_otg_hc_cleanup(struct core_if *core_if, struct dwc_hc *hc)
+{
+	struct dwc_hc_regs *regs;
+	hc->xfer_started = 0;
+
+	regs = core_if->host_if->hc_regs[hc->hc_num];
+	dwc_write_reg32(&regs->hcintmsk, 0);
+	dwc_write_reg32(&regs->hcint, 0xFFFFFFFF);
+}
+
+/**
+ * This function enables the Host mode interrupts.
+ */
+static void dwc_otg_enable_host_interrupts(struct core_if *core_if)
+{
+	struct core_global_regs *global_regs = core_if->core_global_regs;
+	union gintmsk_data intr_mask = {.d32 = 0};
+
+	/* Disable all interrupts. */
+	dwc_write_reg32(&global_regs->gintmsk, 0);
+
+	/* Clear any pending interrupts. */
+	dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
+
+	/* Enable the common interrupts */
+	dwc_otg_enable_common_interrupts(core_if);
+
+	/*
+	 * Enable host mode interrupts without disturbing common
+	 * interrupts.
+	 */
+	intr_mask.b.sofintr = 1;
+	intr_mask.b.portintr = 1;
+	intr_mask.b.hcintr = 1;
+	dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
+}
+
+/**
+ * This function initializes the DWC_otg controller registers for
+ * host mode.
+ *
+ * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
+ * request queues. Host channels are reset to ensure that they are ready for
+ * performing transfers.
+ */
+static void dwc_otg_core_host_init(struct core_if *core_if)
+{
+	struct core_global_regs *global_regs = core_if->core_global_regs;
+	struct dwc_host_if *host_if = core_if->host_if;
+	struct core_params *params = core_if->core_params;
+	union hprt0_data hprt0 = {.d32 = 0};
+	union fifosize_data nptxfifosize;
+	union fifosize_data ptxfifosize;
+	u32 i;
+	union hcchar_data hcchar;
+	union hcfg_data hcfg;
+	struct dwc_hc_regs *hc_regs;
+	int num_channels;
+	union gotgctl_data gotgctl = {.d32 = 0};
+
+	/* Restart the Phy Clock */
+	dwc_write_reg32(core_if->pcgcctl, 0);
+
+	/* Initialize Host Configuration Register */
+	init_fslspclksel(core_if);
+	if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
+		hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg);
+		hcfg.b.fslssupp = 1;
+		dwc_write_reg32(&host_if->host_global_regs->hcfg, hcfg.d32);
+	}
+
+	/* Configure data FIFO sizes */
+	if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
+		/* Rx FIFO */
+		dwc_write_reg32(&global_regs->grxfsiz,
+			params->host_rx_fifo_size);
+
+		/* Non-periodic Tx FIFO */
+		nptxfifosize.b.depth = params->host_nperio_tx_fifo_size;
+		nptxfifosize.b.startaddr = params->host_rx_fifo_size;
+		dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32);
+
+		/* Periodic Tx FIFO */
+		ptxfifosize.b.depth = params->host_perio_tx_fifo_size;
+		ptxfifosize.b.startaddr = nptxfifosize.b.startaddr +
+				nptxfifosize.b.depth;
+		dwc_write_reg32(&global_regs->hptxfsiz, ptxfifosize.d32);
+	}
+
+	/* Clear Host Set HNP Enable in the OTG Control Register */
+	gotgctl.b.hstsethnpen = 1;
+	dwc_modify_reg32(&global_regs->gotgctl, gotgctl.d32, 0);
+
+	/* Make sure the FIFOs are flushed. */
+	dwc_otg_flush_tx_fifo(core_if, DWC_GRSTCTL_TXFNUM_ALL);
+	dwc_otg_flush_rx_fifo(core_if);
+
+	/* Flush out any leftover queued requests. */
+	num_channels = core_if->core_params->host_channels;
+	for (i = 0; i < num_channels; i++) {
+		hc_regs = core_if->host_if->hc_regs[i];
+		hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
+		hcchar.b.chen = 0;
+		hcchar.b.chdis = 1;
+		hcchar.b.epdir = 0;
+		dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
+	}
+
+	/* Halt all channels to put them into a known state. */
+	for (i = 0; i < num_channels; i++) {
+		int count = 0;
+		hc_regs = core_if->host_if->hc_regs[i];
+		hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
+		hcchar.b.chen = 1;
+		hcchar.b.chdis = 1;
+		hcchar.b.epdir = 0;
+		dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
+
+		do {
+			hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
+			if (++count > 10000) {
+				printk(KERN_ERR "%s: Unable to clear halt on "
+						"channel %d\n",	__func__, i);
+				break;
+			}
+		} while (hcchar.b.chen);
+	}
+
+	/* Turn on the vbus power. */
+	printk(KERN_INFO "Init: Port Power? op_state=%d\n", core_if->op_state);
+
+	if (core_if->op_state == A_HOST) {
+		hprt0.d32 = dwc_otg_read_hprt0(core_if);
+		printk(KERN_INFO "Init: Power Port (%d)\n", hprt0.b.prtpwr);
+		if (hprt0.b.prtpwr == 0) {
+			hprt0.b.prtpwr = 1;
+			dwc_write_reg32(host_if->hprt0, hprt0.d32);
+		}
+	}
+
+	dwc_otg_enable_host_interrupts(core_if);
+}
+
+/**
+ * Initializes dynamic portions of the DWC_otg HCD state.
+ */
+static void hcd_reinit(struct dwc_hcd *hcd)
+{
+	struct list_head *item;
+	int num_channels;
+	u32 i;
+	struct dwc_hc *channel;
+
+	hcd->flags.d32 = 0;
+	hcd->non_periodic_qh_ptr = &hcd->non_periodic_sched_active;
+	hcd->non_periodic_channels = 0;
+	hcd->periodic_channels = 0;
+
+	/*
+	 * Put all channels in the free channel list and clean up channel
+	 * states.
+	 */
+	item = hcd->free_hc_list.next;
+	while (item != &hcd->free_hc_list) {
+		list_del(item);
+		item = hcd->free_hc_list.next;
+	}
+
+	num_channels = hcd->core_if->core_params->host_channels;
+	for (i = 0; i < num_channels; i++) {
+		channel = hcd->hc_ptr_array[i];
+		list_add_tail(&channel->hc_list_entry, &hcd->free_hc_list);
+		dwc_otg_hc_cleanup(hcd->core_if, channel);
+	}
+
+	/* Initialize the DWC core for host mode operation. */
+	dwc_otg_core_host_init(hcd->core_if);
+}
+
+/* Gets the dwc_hcd from a struct usb_hcd */
+static inline struct dwc_hcd *hcd_to_dwc_otg_hcd(struct usb_hcd *hcd)
+{
+	return (struct dwc_hcd *) hcd->hcd_priv;
+}
+
+/**
+ * Initializes the DWC_otg controller and its root hub and prepares it for host
+ * mode operation. Activates the root port. Returns 0 on success and a negative
+ * error code on failure.
+*/
+static int dwc_otg_hcd_start(struct usb_hcd *hcd)
+{
+	struct dwc_hcd *dwc_hcd = hcd_to_dwc_otg_hcd(hcd);
+	struct usb_bus *bus = hcd_to_bus(hcd);
+
+	hcd->state = HC_STATE_RUNNING;
+
+	/* Inform the HUB driver to resume. */
+	if (bus->root_hub)
+		usb_hcd_resume_root_hub(hcd);
+
+	hcd_reinit(dwc_hcd);
+	return 0;
+}
+
+/**
+ * Work queue function for starting the HCD when A-Cable is connected.
+ * The dwc_otg_hcd_start() must be called in a process context.
+ */
+static void hcd_start_func(struct work_struct *work)
+{
+	struct dwc_hcd *priv =
+		container_of(work, struct dwc_hcd, start_work);
+	struct usb_hcd *usb_hcd = (struct usb_hcd *) priv->_p;
+
+	if (usb_hcd)
+		dwc_otg_hcd_start(usb_hcd);
+}
+
+/**
+ * HCD Callback function for starting the HCD when A-Cable is
+ * connected.
+ */
+static int dwc_otg_hcd_start_cb(void *_p)
+{
+	struct dwc_hcd *dwc_hcd = hcd_to_dwc_otg_hcd(_p);
+	struct core_if *core_if = dwc_hcd->core_if;
+	union hprt0_data hprt0;
+
+	if (core_if->op_state == B_HOST) {
+		/*
+		 * Reset the port.  During a HNP mode switch the reset
+		 * needs to occur within 1ms and have a duration of at
+		 * least 50ms.
+		 */
+		hprt0.d32 = dwc_otg_read_hprt0(core_if);
+		hprt0.b.prtrst = 1;
+		dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+		((struct usb_hcd *) _p)->self.is_b_host = 1;
+	} else {
+		((struct usb_hcd *) _p)->self.is_b_host = 0;
+	}
+
+	/* Need to start the HCD in a non-interrupt context. */
+	INIT_WORK(&dwc_hcd->start_work, hcd_start_func);
+	dwc_hcd->_p = _p;
+	schedule_work(&dwc_hcd->start_work);
+	return 1;
+}
+
+/**
+ * This function disables the Host Mode interrupts.
+ */
+static void dwc_otg_disable_host_interrupts(struct core_if *core_if)
+{
+	struct core_global_regs *global_regs = core_if->core_global_regs;
+	union gintmsk_data intr_mask = {.d32 = 0};
+
+	/*
+	 * Disable host mode interrupts without disturbing common
+	 * interrupts.
+	*/
+	intr_mask.b.sofintr = 1;
+	intr_mask.b.portintr = 1;
+	intr_mask.b.hcintr = 1;
+	intr_mask.b.ptxfempty = 1;
+	intr_mask.b.nptxfempty = 1;
+	dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
+}
+
+/**
+ * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
+ * stopped.
+ */
+static void dwc_otg_hcd_stop(struct usb_hcd *hcd)
+{
+	struct dwc_hcd *dwc_hcd = hcd_to_dwc_otg_hcd(hcd);
+	union hprt0_data hprt0 = {.d32 = 0};
+
+	/* Turn off all host-specific interrupts. */
+	dwc_otg_disable_host_interrupts(dwc_hcd->core_if);
+
+	/*
+	 * The root hub should be disconnected before this function is called.
+	 * The disconnect will clear the QTD lists (via ..._hcd_urb_dequeue)
+	 * and the QH lists (via ..._hcd_endpoint_disable).
+	 */
+
+	/* Turn off the vbus power */
+	printk(KERN_INFO "PortPower off\n");
+	hprt0.b.prtpwr = 0;
+	dwc_write_reg32(dwc_hcd->core_if->host_if->hprt0, hprt0.d32);
+}
+
+/**
+ * HCD Callback function for stopping the HCD.
+ */
+static int dwc_otg_hcd_stop_cb(void *_p)
+{
+	struct usb_hcd *usb_hcd = (struct usb_hcd *) _p;
+
+	dwc_otg_hcd_stop(usb_hcd);
+	return 1;
+}
+
+static void del_timers(struct dwc_hcd *hcd)
+{
+	del_timer_sync(&hcd->conn_timer);
+}
+
+/**
+ * Processes all the URBs in a single list of QHs. Completes them with
+ * -ETIMEDOUT and frees the QTD.
+ */
+static void kill_urbs_in_qh_list(struct dwc_hcd *hcd, struct list_head *qh_list)
+{
+	struct list_head *qh_item, *q;
+
+	qh_item = qh_list->next;
+
+	list_for_each_safe(qh_item, q, qh_list) {
+		struct dwc_qh *qh;
+		struct list_head *qtd_item;
+		struct dwc_qtd *qtd;
+
+		qh = list_entry(qh_item, struct dwc_qh, qh_list_entry);
+		qtd_item = qh->qtd_list.next;
+		qtd = list_entry(qtd_item, struct dwc_qtd, qtd_list_entry);
+		if (qtd->urb != NULL) {
+			dwc_otg_hcd_complete_urb(hcd, qtd->urb, -ETIMEDOUT);
+			dwc_otg_hcd_qtd_remove_and_free(qtd);
+		}
+	}
+}
+
+/**
+ * Responds with an error status of ETIMEDOUT to all URBs in the non-periodic
+ * and periodic schedules. The QTD associated with each URB is removed from
+ * the schedule and freed. This function may be called when a disconnect is
+ * detected or when the HCD is being stopped.
+ */
+static void kill_all_urbs(struct dwc_hcd *hcd)
+{
+	kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_inactive);
+	kill_urbs_in_qh_list(hcd, &hcd->non_periodic_sched_active);
+	kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_inactive);
+	kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_ready);
+	kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_assigned);
+	kill_urbs_in_qh_list(hcd, &hcd->periodic_sched_queued);
+}
+
+/**
+ * HCD Callback function for disconnect of the HCD.
+ */
+static int dwc_otg_hcd_disconnect_cb(void *_p)
+{
+	union gintsts_data intr;
+	struct dwc_hcd *hcd = hcd_to_dwc_otg_hcd(_p);
+	struct core_if *core_if = hcd->core_if;
+
+	/* Set status flags for the hub driver. */
+	hcd->flags.b.port_connect_status_change = 1;
+	hcd->flags.b.port_connect_status = 0;
+
+	/*
+	 * Shutdown any transfers in process by clearing the Tx FIFO Empty
+	 * interrupt mask and status bits and disabling subsequent host
+	 * channel interrupts.
+	 */
+	intr.d32 = 0;
+	intr.b.nptxfempty = 1;
+	intr.b.ptxfempty = 1;
+	intr.b.hcintr = 1;
+	dwc_modify_reg32(gintmsk_reg(hcd), intr.d32, 0);
+	dwc_modify_reg32(gintsts_reg(hcd), intr.d32, 0);
+
+	del_timers(hcd);
+
+	/*
+	 * Turn off the vbus power only if the core has transitioned to device
+	 * mode. If still in host mode, need to keep power on to detect a
+	 * reconnection.
+	 */
+	if (dwc_otg_is_device_mode(core_if)) {
+		if (core_if->op_state != A_SUSPEND) {
+			union hprt0_data hprt0 = {.d32 = 0};
+			printk(KERN_INFO "Disconnect: PortPower off\n");
+			hprt0.b.prtpwr = 0;
+			dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+		}
+		dwc_otg_disable_host_interrupts(core_if);
+	}
+
+	/* Respond with an error status to all URBs in the schedule. */
+	kill_all_urbs(hcd);
+	if (dwc_otg_is_host_mode(core_if)) {
+		/* Clean up any host channels that were in use. */
+		int num_channels;
+		u32 i;
+		struct dwc_hc *channel;
+		struct dwc_hc_regs *regs;
+		union hcchar_data hcchar;
+
+		num_channels = core_if->core_params->host_channels;
+		if (!core_if->dma_enable) {
+			/* Flush out any channel requests in slave mode. */
+			for (i = 0; i < num_channels; i++) {
+				channel = hcd->hc_ptr_array[i];
+				if (list_empty(&channel->hc_list_entry)) {
+					regs = core_if->host_if->hc_regs[i];
+					hcchar.d32 = dwc_read_reg32(
+							&regs->hcchar);
+
+					if (hcchar.b.chen) {
+						hcchar.b.chen = 0;
+						hcchar.b.chdis = 1;
+						hcchar.b.epdir = 0;
+						dwc_write_reg32(&regs->hcchar,
+								hcchar.d32);
+					}
+				}
+			}
+		}
+
+		for (i = 0; i < num_channels; i++) {
+			channel = hcd->hc_ptr_array[i];
+			if (list_empty(&channel->hc_list_entry)) {
+				regs = core_if->host_if->hc_regs[i];
+				hcchar.d32 = dwc_read_reg32(&regs->hcchar);
+
+				if (hcchar.b.chen) {
+					/* Halt the channel. */
+					hcchar.b.chdis = 1;
+					dwc_write_reg32(&regs->hcchar,
+							hcchar.d32);
+				}
+				dwc_otg_hc_cleanup(core_if, channel);
+				list_add_tail(&channel->hc_list_entry,
+						&hcd->free_hc_list);
+			}
+		}
+	}
+
+	/*
+	 * A disconnect will end the session so the B-Device is no
+	 * longer a B-host.
+	 */
+	((struct usb_hcd *) _p)->self.is_b_host = 0;
+	return 1;
+}
+
+/**
+ * Connection timeout function.  An OTG host is required to display a
+ * message if the device does not connect within 10 seconds.
+ */
+static void dwc_otg_hcd_connect_timeout(unsigned long _ptr)
+{
+	printk(KERN_INFO "Connect Timeout\n");
+	printk(KERN_ERR "Device Not Connected/Responding\n");
+}
+
+/**
+ * Start the connection timer.  An OTG host is required to display a
+ * message if the device does not connect within 10 seconds.  The
+ * timer is deleted if a port connect interrupt occurs before the
+ * timer expires.
+ */
+static void dwc_otg_hcd_start_connect_timer(struct dwc_hcd *hcd)
+{
+	init_timer(&hcd->conn_timer);
+	hcd->conn_timer.function = dwc_otg_hcd_connect_timeout;
+	hcd->conn_timer.data = (unsigned long)0;
+	hcd->conn_timer.expires = jiffies + (HZ * 10);
+	add_timer(&hcd->conn_timer);
+}
+
+/**
+ * HCD Callback function for disconnect of the HCD.
+ */
+static int dwc_otg_hcd_session_start_cb(void *_p)
+{
+	struct dwc_hcd *hcd = hcd_to_dwc_otg_hcd(_p);
+
+	dwc_otg_hcd_start_connect_timer(hcd);
+	return 1;
+}
+
+/* HCD Callback structure for handling mode switching. */
+static struct cil_callbacks hcd_cil_callbacks = {
+	.start = dwc_otg_hcd_start_cb,
+	.stop = dwc_otg_hcd_stop_cb,
+	.disconnect = dwc_otg_hcd_disconnect_cb,
+	.session_start = dwc_otg_hcd_session_start_cb,
+	.p = 0,
+};
+
+/*
+ * Reset Workqueue implementation
+ */
+static void port_reset_wqfunc(struct work_struct *work)
+{
+	struct dwc_hcd *hcd = container_of(work, struct dwc_hcd, usb_port_reset);
+
+	struct core_if *core_if = hcd->core_if;
+	union hprt0_data hprt0;
+	unsigned long flags;
+
+	printk(KERN_INFO "%s\n", __func__);
+	spin_lock_irqsave(&hcd->lock, flags);
+	hprt0.d32 = dwc_otg_read_hprt0(core_if);
+	hprt0.b.prtrst = 1;
+	dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+	spin_unlock_irqrestore(&hcd->lock, flags);
+	msleep(60);
+	spin_lock_irqsave(&hcd->lock, flags);
+	hprt0.b.prtrst = 0;
+	dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+	hcd->flags.b.port_reset_change = 1;
+	spin_unlock_irqrestore(&hcd->lock, flags);
+}
+
+/*
+ * Wakeup Workqueue implementation
+ */
+static void port_wakeup_wqfunc(struct work_struct *work)
+{
+	struct core_if *core_if = container_of(to_delayed_work(work),
+			struct core_if, usb_port_wakeup);
+	union hprt0_data hprt0;
+
+	printk(KERN_INFO "%s\n", __func__);
+	/* Now wait for 70 ms. */
+	hprt0.d32 = dwc_otg_read_hprt0(core_if);
+	msleep(70);
+	hprt0.b.prtres = 0;	/* Resume */
+	dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+}
+
+/**
+ * Starts processing a USB transfer request specified by a USB Request Block
+ * (URB). mem_flags indicates the type of memory allocation to use while
+ * processing this URB.
+ */
+static int dwc_otg_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+				gfp_t _mem_flags)
+{
+
+	int retval;
+	unsigned long flags;
+	struct dwc_hcd *dwc_hcd = hcd_to_dwc_otg_hcd(hcd);
+	struct dwc_qtd *qtd;
+
+	if (!dwc_hcd->flags.b.port_connect_status) {
+		/* No longer connected. */
+		retval = -ENODEV;
+		goto err_enq;
+	}
+
+	qtd = dwc_otg_hcd_qtd_create(urb, _mem_flags);
+	if (!qtd) {
+		printk(KERN_ERR "DWC OTG HCD URB Enqueue failed creating "
+					"QTD\n");
+		retval = -ENOMEM;
+		goto err_enq;
+	}
+
+	spin_lock_irqsave(&dwc_hcd->lock, flags);
+	retval = usb_hcd_link_urb_to_ep(hcd, urb);
+	if (unlikely(retval))
+		goto fail;
+
+	retval = dwc_otg_hcd_qtd_add(qtd, dwc_hcd);
+	if (retval < 0) {
+		printk(KERN_ERR "DWC OTG HCD URB Enqueue failed adding QTD. "
+				"Error status %d\n", retval);
+		usb_hcd_unlink_urb_from_ep(hcd, urb);
+		goto fail;
+	}
+
+fail:
+	if (retval)
+		dwc_otg_hcd_qtd_free(qtd);
+
+	spin_unlock_irqrestore(&dwc_hcd->lock, flags);
+err_enq:
+
+	return retval;
+}
+
+/**
+ * Attempts to halt a host channel. This function should only be called in
+ * Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
+ * normal circumstances in DMA mode, the controller halts the channel when the
+ * transfer is complete or a condition occurs that requires application
+ * intervention.
+ *
+ * In slave mode, checks for a free request queue entry, then sets the Channel
+ * Enable and Channel Disable bits of the Host Channel Characteristics
+ * register of the specified channel to intiate the halt. If there is no free
+ * request queue entry, sets only the Channel Disable bit of the HCCHARn
+ * register to flush requests for this channel. In the latter case, sets a
+ * flag to indicate that the host channel needs to be halted when a request
+ * queue slot is open.
+ *
+ * In DMA mode, always sets the Channel Enable and Channel Disable bits of the
+ * HCCHARn register. The controller ensures there is space in the request
+ * queue before submitting the halt request.
+ *
+ * Some time may elapse before the core flushes any posted requests for this
+ * host channel and halts. The Channel Halted interrupt handler completes the
+ * deactivation of the host channel.
+ */
+void dwc_otg_hc_halt(struct core_if *core_if, struct dwc_hc *hc,
+			enum dwc_halt_status hlt_sts)
+{
+	union gnptxsts_data nptxsts;
+	union hptxsts_data hptxsts;
+	union hcchar_data hcchar;
+	struct dwc_hc_regs *hc_regs;
+	struct core_global_regs *global_regs;
+	struct host_global_regs *host_global_regs;
+
+	hc_regs = core_if->host_if->hc_regs[hc->hc_num];
+	global_regs = core_if->core_global_regs;
+	host_global_regs = core_if->host_if->host_global_regs;
+
+	WARN_ON(hlt_sts == DWC_OTG_HC_XFER_NO_HALT_STATUS);
+
+	if (hlt_sts == DWC_OTG_HC_XFER_URB_DEQUEUE ||
+			hlt_sts == DWC_OTG_HC_XFER_AHB_ERR) {
+		/*
+		 * Disable all channel interrupts except Ch Halted. The QTD
+		 * and QH state associated with this transfer has been cleared
+		 * (in the case of URB_DEQUEUE), so the channel needs to be
+		 * shut down carefully to prevent crashes.
+		 */
+		union hcintmsk_data hcintmsk;
+		hcintmsk.d32 = 0;
+		hcintmsk.b.chhltd = 1;
+		dwc_write_reg32(&hc_regs->hcintmsk, hcintmsk.d32);
+
+		/*
+		 * Make sure no other interrupts besides halt are currently
+		 * pending. Handling another interrupt could cause a crash due
+		 * to the QTD and QH state.
+		 */
+		dwc_write_reg32(&hc_regs->hcint, ~hcintmsk.d32);
+
+		/*
+		 * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
+		 * even if the channel was already halted for some other reason.
+		 */
+		hc->halt_status = hlt_sts;
+
+		/*
+		 * If the channel is not enabled, the channel is either already
+		 * halted or it hasn't started yet. In DMA mode, the transfer
+		 * may halt if it finishes normally or a condition occurs that
+		 * requires driver intervention. Don't want to halt the channel
+		 * again. In either Slave or DMA mode, it's possible that the
+		 * transfer has been assigned to a channel, but not started yet
+		 * when an URB is dequeued. Don't want to halt a channel that
+		 * hasn't started yet.
+		 */
+		hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
+		if (!hcchar.b.chen)
+			return;
+	}
+
+	if (hc->halt_pending)
+		/*
+		 * A halt has already been issued for this channel. This might
+		 * happen when a transfer is aborted by a higher level in
+		 * the stack.
+		 */
+		return;
+
+	hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
+	hcchar.b.chen = 1;
+	hcchar.b.chdis = 1;
+	if (!core_if->dma_enable) {
+		/* Check for space in the request queue to issue the halt. */
+		if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
+				hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
+			nptxsts.d32 = dwc_read_reg32(&global_regs->gnptxsts);
+
+			if (!nptxsts.b.nptxqspcavail)
+				hcchar.b.chen = 0;
+		} else {
+			hptxsts.d32 =
+				dwc_read_reg32(&host_global_regs->hptxsts);
+
+			if (!hptxsts.b.ptxqspcavail ||
+					core_if->queuing_high_bandwidth)
+				hcchar.b.chen = 0;
+		}
+	}
+	dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
+
+	hc->halt_status = hlt_sts;
+	if (hcchar.b.chen) {
+		hc->halt_pending = 1;
+		hc->halt_on_queue = 0;
+	} else {
+		hc->halt_on_queue = 1;
+	}
+}
+
+/**
+ * Aborts/cancels a USB transfer request. Always returns 0 to indicate
+ * success.
+ */
+static int dwc_otg_hcd_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
+	int status)
+{
+	unsigned long flags;
+	struct dwc_hcd *dwc_hcd;
+	struct dwc_qtd *urb_qtd;
+	struct dwc_qh *qh;
+	struct usb_host_endpoint *_ep = dwc_urb_to_endpoint(urb);
+	int retval;
+
+	if (!_ep)
+		return -EINVAL;
+
+	urb_qtd = (struct dwc_qtd *) urb->hcpriv;
+	qh = (struct dwc_qh *) _ep->hcpriv;
+	if (!urb_qtd || !qh)
+		return -EINVAL;
+
+	dwc_hcd = hcd_to_dwc_otg_hcd(hcd);
+	spin_lock_irqsave(&dwc_hcd->lock, flags);
+
+	retval = usb_hcd_check_unlink_urb(hcd, urb, status);
+	if (retval) {
+		spin_unlock_irqrestore(&dwc_hcd->lock, flags);
+		return retval;
+	}
+
+	if (qh && urb_qtd == qh->qtd_in_process) {
+		/* The QTD is in process (it has been assigned to a channel). */
+		if (dwc_hcd->flags.b.port_connect_status) {
+			/*
+			 * If still connected (i.e. in host mode), halt the
+			 * channel so it can be used for other transfers. If
+			 * no longer connected, the host registers can't be
+			 * written to halt the channel since the core is in
+			 * device mode.
+			 */
+			dwc_otg_hc_halt(dwc_hcd->core_if, qh->channel,
+					DWC_OTG_HC_XFER_URB_DEQUEUE);
+		}
+	}
+
+	/*
+	 * Free the QTD and clean up the associated QH. Leave the QH in the
+	 * schedule if it has any remaining QTDs.
+	 */
+	dwc_otg_hcd_qtd_remove_and_free(urb_qtd);
+	if (qh && urb_qtd == qh->qtd_in_process) {
+		dwc_otg_hcd_qh_deactivate(dwc_hcd, qh, 0);
+		qh->channel = NULL;
+		qh->qtd_in_process = NULL;
+	} else if (qh && list_empty(&qh->qtd_list)) {
+		dwc_otg_hcd_qh_remove(dwc_hcd, qh);
+	}
+
+	urb->hcpriv = NULL;
+	usb_hcd_unlink_urb_from_ep(hcd, urb);
+	spin_unlock_irqrestore(&dwc_hcd->lock, flags);
+
+	/* Higher layer software sets URB status. */
+	usb_hcd_giveback_urb(hcd, urb, status);
+
+	return 0;
+}
+
+/* Remove and free a QH */
+static inline void dwc_otg_hcd_qh_remove_and_free(struct dwc_hcd *hcd,
+				struct dwc_qh *qh)
+{
+	dwc_otg_hcd_qh_remove(hcd, qh);
+	dwc_otg_hcd_qh_free(qh);
+}
+
+static void qh_list_free(struct dwc_hcd *hcd, struct list_head *_qh_list)
+{
+	struct list_head *item, *tmp;
+	struct dwc_qh *qh;
+
+	/* If the list hasn't been initialized yet, return. */
+	if (_qh_list->next == NULL)
+		return;
+
+	/* Ensure there are no QTDs or URBs left. */
+	kill_urbs_in_qh_list(hcd, _qh_list);
+
+	list_for_each_safe(item, tmp, _qh_list) {
+		qh = list_entry(item, struct dwc_qh, qh_list_entry);
+		dwc_otg_hcd_qh_remove_and_free(hcd, qh);
+	}
+}
+
+/**
+ * Frees resources in the DWC_otg controller related to a given endpoint. Also
+ * clears state in the HCD related to the endpoint. Any URBs for the endpoint
+ * must already be dequeued.
+ */
+static void dwc_otg_hcd_endpoint_disable(struct usb_hcd *hcd,
+		struct usb_host_endpoint *ep)
+{
+	struct dwc_qh *qh;
+	struct dwc_hcd *dwc_hcd = hcd_to_dwc_otg_hcd(hcd);
+	unsigned long flags;
+
+	spin_lock_irqsave(&dwc_hcd->lock, flags);
+	qh = (struct dwc_qh *) ep->hcpriv;
+	if (qh) {
+		dwc_otg_hcd_qh_remove_and_free(dwc_hcd, qh);
+		ep->hcpriv = NULL;
+	}
+	spin_unlock_irqrestore(&dwc_hcd->lock, flags);
+}
+
+/**
+ * Creates Status Change bitmap for the root hub and root port. The bitmap is
+ * returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
+ * is the status change indicator for the single root port. Returns 1 if either
+ * change indicator is 1, otherwise returns 0.
+ */
+static int dwc_otg_hcd_hub_status_data(struct usb_hcd *_hcd, char *buf)
+{
+	struct dwc_hcd *hcd = hcd_to_dwc_otg_hcd(_hcd);
+	buf[0] = 0;
+	buf[0] |= (hcd->flags.b.port_connect_status_change
+			|| hcd->flags.b.port_reset_change
+			|| hcd->flags.b.port_enable_change
+			|| hcd->flags.b.port_suspend_change
+			|| hcd->flags.b.port_over_current_change) << 1;
+
+	return (buf[0] != 0);
+}
+
+/* Handles the hub class-specific ClearPortFeature request.*/
+static int do_clear_port_feature(struct dwc_hcd *hcd, u16 val)
+{
+	struct core_if *core_if = hcd->core_if;
+	union hprt0_data hprt0;
+    unsigned long flags;
+
+    spin_lock_irqsave(&hcd->lock, flags);
+	switch (val) {
+	case USB_PORT_FEAT_ENABLE:
+		hprt0.d32 = dwc_otg_read_hprt0(core_if);
+		hprt0.b.prtena = 1;
+		dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+		break;
+	case USB_PORT_FEAT_SUSPEND:
+		hprt0.d32 = dwc_otg_read_hprt0(core_if);
+		hprt0.b.prtres = 1;
+		dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+
+		/* Clear Resume bit */
+		spin_unlock_irqrestore(&hcd->lock, flags);
+		msleep(100);
+		spin_lock_irqsave(&hcd->lock, flags);
+		hprt0.b.prtres = 0;
+		dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+		break;
+	case USB_PORT_FEAT_POWER:
+		hprt0.d32 = dwc_otg_read_hprt0(core_if);
+		hprt0.b.prtpwr = 0;
+		dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+		break;
+	case USB_PORT_FEAT_INDICATOR:
+		/* Port inidicator not supported */
+		break;
+	case USB_PORT_FEAT_C_CONNECTION:
+		/* Clears drivers internal connect status change flag */
+		hcd->flags.b.port_connect_status_change = 0;
+		break;
+	case USB_PORT_FEAT_C_RESET:
+		/* Clears driver's internal Port Reset Change flag */
+		hcd->flags.b.port_reset_change = 0;
+		break;
+	case USB_PORT_FEAT_C_ENABLE:
+		/* Clears driver's internal Port Enable/Disable Change flag  */
+		hcd->flags.b.port_enable_change = 0;
+		break;
+	case USB_PORT_FEAT_C_SUSPEND:
+		/*
+		 * Clears the driver's internal Port Suspend
+		 * Change flag, which is set when resume signaling on
+		 * the host port is complete
+		 */
+		hcd->flags.b.port_suspend_change = 0;
+		break;
+	case USB_PORT_FEAT_C_OVER_CURRENT:
+		hcd->flags.b.port_over_current_change = 0;
+		break;
+	default:
+		printk(KERN_ERR "DWC OTG HCD - ClearPortFeature request %xh "
+			"unknown or unsupported\n", val);
+		spin_unlock_irqrestore(&hcd->lock, flags);
+		return -EINVAL;
+	}
+	spin_unlock_irqrestore(&hcd->lock, flags);
+	return 0;
+}
+
+/* Handles the hub class-specific SetPortFeature request.*/
+static int do_set_port_feature(struct usb_hcd *hcd, u16 val, u16 index)
+{
+	struct core_if *core_if = hcd_to_dwc_otg_hcd(hcd)->core_if;
+	union hprt0_data hprt0 = {.d32 = 0};
+	struct dwc_hcd *dwc_hcd = hcd_to_dwc_otg_hcd(hcd);
+	unsigned long flags;
+
+	spin_lock_irqsave(&dwc_hcd->lock, flags);
+
+	switch (val) {
+	case USB_PORT_FEAT_SUSPEND:
+		if (hcd->self.otg_port == index && hcd->self.b_hnp_enable) {
+			union gotgctl_data gotgctl = {.d32 = 0};
+			gotgctl.b.hstsethnpen = 1;
+			dwc_modify_reg32(&core_if->core_global_regs->gotgctl,
+						0, gotgctl.d32);
+			core_if->op_state = A_SUSPEND;
+		}
+
+		hprt0.d32 = dwc_otg_read_hprt0(core_if);
+		hprt0.b.prtsusp = 1;
+		dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+
+		/* Suspend the Phy Clock */
+		{
+			union pcgcctl_data pcgcctl = {.d32 = 0};
+			pcgcctl.b.stoppclk = 1;
+			dwc_write_reg32(core_if->pcgcctl, pcgcctl.d32);
+		}
+
+		/* For HNP the bus must be suspended for at least 200ms. */
+		if (hcd->self.b_hnp_enable) {
+			spin_unlock_irqrestore(&dwc_hcd->lock, flags);
+			msleep(200);
+			spin_lock_irqsave(&dwc_hcd->lock, flags);
+		}
+		break;
+	case USB_PORT_FEAT_POWER:
+		hprt0.d32 = dwc_otg_read_hprt0(core_if);
+		hprt0.b.prtpwr = 1;
+		dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+		break;
+	case USB_PORT_FEAT_RESET:
+		hprt0.d32 = dwc_otg_read_hprt0(core_if);
+
+		/*
+		 * When B-Host the Port reset bit is set in the Start HCD
+		 * Callback function, so that the reset is started within 1ms
+		 * of the HNP success interrupt.
+		 */
+		if (!hcd->self.is_b_host) {
+			hprt0.b.prtrst = 1;
+			dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+		}
+
+		/* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
+		spin_unlock_irqrestore(&dwc_hcd->lock, flags);
+		msleep(60);
+		spin_lock_irqsave(&dwc_hcd->lock, flags);
+		hprt0.b.prtrst = 0;
+		dwc_write_reg32(core_if->host_if->hprt0, hprt0.d32);
+		break;
+	case USB_PORT_FEAT_INDICATOR:
+		/* Not supported */
+		break;
+	default:
+		printk(KERN_ERR "DWC OTG HCD - "
+				"SetPortFeature request %xh "
+				"unknown or unsupported\n", val);
+		spin_unlock_irqrestore(&dwc_hcd->lock, flags);
+		return -EINVAL;
+	}
+	spin_unlock_irqrestore(&dwc_hcd->lock, flags);
+	return 0;
+}
+
+/* Handles hub class-specific requests.*/
+static int dwc_otg_hcd_hub_control(struct usb_hcd *hcd, u16 req_type, u16 val,
+		u16 index, char *buf, u16 len)
+{
+	int retval = 0;
+	struct dwc_hcd *dwc_hcd = hcd_to_dwc_otg_hcd(hcd);
+	struct core_if *core_if = hcd_to_dwc_otg_hcd(hcd)->core_if;
+	struct usb_hub_descriptor *desc;
+	union hprt0_data hprt0 = {.d32 = 0};
+	u32 port_status;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dwc_hcd->lock, flags);
+	switch (req_type) {
+	case ClearHubFeature:
+		switch (val) {
+		case C_HUB_LOCAL_POWER:
+		case C_HUB_OVER_CURRENT:
+			/* Nothing required here */
+			break;
+		default:
+			retval = -EINVAL;
+			printk(KERN_ERR "DWC OTG HCD - ClearHubFeature request"
+					" %xh unknown\n", val);
+		}
+		break;
+	case ClearPortFeature:
+		if (!index || index > 1)
+			goto error;
+		spin_unlock_irqrestore(&dwc_hcd->lock, flags);
+		retval = do_clear_port_feature(dwc_hcd, val);
+		spin_lock_irqsave(&dwc_hcd->lock, flags);
+		break;
+	case GetHubDescriptor:
+		desc = (struct usb_hub_descriptor *) buf;
+		desc->bDescLength = 9;
+		desc->bDescriptorType = 0x29;
+		desc->bNbrPorts = 1;
+		desc->wHubCharacteristics = 0x08;
+		desc->bPwrOn2PwrGood = 1;
+		desc->bHubContrCurrent = 0;
+		desc->bitmap[0] = 0;
+		desc->bitmap[1] = 0xff;
+		break;
+	case GetHubStatus:
+		memset(buf, 0, 4);
+		break;
+	case GetPortStatus:
+		if (!index || index > 1)
+			goto error;
+
+		port_status = 0;
+		if (dwc_hcd->flags.b.port_connect_status_change)
+			port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
+		if (dwc_hcd->flags.b.port_enable_change)
+			port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
+		if (dwc_hcd->flags.b.port_suspend_change)
+			port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
+		if (dwc_hcd->flags.b.port_reset_change)
+			port_status |= (1 << USB_PORT_FEAT_C_RESET);
+		if (dwc_hcd->flags.b.port_over_current_change) {
+			printk(KERN_ERR "Device Not Supported\n");
+			port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);
+		}
+		if (!dwc_hcd->flags.b.port_connect_status) {
+			/*
+			 * The port is disconnected, which means the core is
+			 * either in device mode or it soon will be. Just
+			 * return 0's for the remainder of the port status
+			 * since the port register can't be read if the core
+			 * is in device mode.
+			 */
+			*((__le32 *) buf) = cpu_to_le32(port_status);
+			break;
+		}
+
+		hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
+
+		if (hprt0.b.prtconnsts)
+			port_status |= USB_PORT_STAT_CONNECTION;
+		if (hprt0.b.prtena)
+			port_status |= USB_PORT_STAT_ENABLE;
+		if (hprt0.b.prtsusp)
+			port_status |= USB_PORT_STAT_SUSPEND;
+		if (hprt0.b.prtovrcurract)
+			port_status |= USB_PORT_STAT_OVERCURRENT;
+		if (hprt0.b.prtrst)
+			port_status |= USB_PORT_STAT_RESET;
+		if (hprt0.b.prtpwr)
+			port_status |= USB_PORT_STAT_POWER;
+
+		if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED)
+			port_status |= USB_PORT_STAT_HIGH_SPEED;
+		else if (hprt0.b.prtspd == DWC_HPRT0_PRTSPD_LOW_SPEED)
+			port_status |= USB_PORT_STAT_LOW_SPEED;
+
+		if (hprt0.b.prttstctl)
+			port_status |= (1 << USB_PORT_FEAT_TEST);
+
+		/* USB_PORT_FEAT_INDICATOR unsupported always 0 */
+		*((__le32 *) buf) = cpu_to_le32(port_status);
+		break;
+	case SetHubFeature:
+		/* No HUB features supported */
+		break;
+	case SetPortFeature:
+		if (val != USB_PORT_FEAT_TEST && (!index || index > 1))
+			goto error;
+
+		if (!dwc_hcd->flags.b.port_connect_status) {
+			/*
+			 * The port is disconnected, which means the core is
+			 * either in device mode or it soon will be. Just
+			 * return without doing anything since the port
+			 * register can't be written if the core is in device
+			 * mode.
+			 */
+			break;
+		}
+		spin_unlock_irqrestore(&dwc_hcd->lock, flags);
+		retval = do_set_port_feature(hcd, val, index);
+		spin_lock_irqsave(&dwc_hcd->lock, flags);
+		break;
+	default:
+error:
+		retval = -EINVAL;
+		printk(KERN_WARNING "DWC OTG HCD - Unknown hub control request"
+			" type or invalid req_type: %xh index: %xh "
+			"val: %xh\n", req_type, index, val);
+		break;
+	}
+	spin_unlock_irqrestore(&dwc_hcd->lock, flags);
+	return retval;
+}
+
+/**
+ * Handles host mode interrupts for the DWC_otg controller. Returns IRQ_NONE if
+ * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
+ * interrupt.
+ *
+ * This function is called by the USB core when an interrupt occurs
+ */
+static irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd)
+{
+	struct dwc_hcd *dwc_hcd = hcd_to_dwc_otg_hcd(hcd);
+	return IRQ_RETVAL(dwc_otg_hcd_handle_intr(dwc_hcd));
+}
+
+static const struct hc_driver dwc_otg_hc_driver = {
+	.description = dwc_otg_hcd_name,
+	.product_desc = "DWC OTG Controller",
+	.hcd_priv_size = sizeof(struct dwc_hcd),
+	.irq = dwc_otg_hcd_irq,
+	.flags = HCD_MEMORY | HCD_USB2,
+	.start = dwc_otg_hcd_start,
+	.stop = dwc_otg_hcd_stop,
+	.urb_enqueue = dwc_otg_hcd_urb_enqueue,
+	.urb_dequeue = dwc_otg_hcd_urb_dequeue,
+	.endpoint_disable = dwc_otg_hcd_endpoint_disable,
+	.get_frame_number = dwc_otg_hcd_get_frame_number,
+	.hub_status_data = dwc_otg_hcd_hub_status_data,
+	.hub_control = dwc_otg_hcd_hub_control,
+};
+
+/**
+ * Frees secondary storage associated with the dwc_hcd structure contained
+ * in the struct usb_hcd field.
+ */
+static void dwc_otg_hcd_free(struct usb_hcd *hcd)
+{
+	struct dwc_hcd *dwc_hcd = hcd_to_dwc_otg_hcd(hcd);
+	u32 i;
+
+	del_timers(dwc_hcd);
+
+	/* Free memory for QH/QTD lists */
+	qh_list_free(dwc_hcd, &dwc_hcd->non_periodic_sched_inactive);
+	qh_list_free(dwc_hcd, &dwc_hcd->non_periodic_sched_active);
+	qh_list_free(dwc_hcd, &dwc_hcd->periodic_sched_inactive);
+	qh_list_free(dwc_hcd, &dwc_hcd->periodic_sched_ready);
+	qh_list_free(dwc_hcd, &dwc_hcd->periodic_sched_assigned);
+	qh_list_free(dwc_hcd, &dwc_hcd->periodic_sched_queued);
+
+	/* Free memory for the host channels. */
+	for (i = 0; i < MAX_EPS_CHANNELS; i++) {
+		struct dwc_hc *hc = dwc_hcd->hc_ptr_array[i];
+
+		kfree(hc);
+	}
+	if (dwc_hcd->core_if->dma_enable) {
+		if (dwc_hcd->status_buf_dma) {
+			dma_free_coherent(hcd->self.controller,
+					DWC_OTG_HCD_STATUS_BUF_SIZE,
+					dwc_hcd->status_buf,
+					dwc_hcd->status_buf_dma);
+		}
+	} else {
+		kfree(dwc_hcd->status_buf);
+	}
+}
+
+/**
+ * Initializes the HCD. This function allocates memory for and initializes the
+ * static parts of the usb_hcd and dwc_hcd structures. It also registers the
+ * USB bus with the core and calls the hc_driver->start() function. It returns
+ * a negative error on failure.
+ */
+int __devinit dwc_otg_hcd_init(struct device *_dev,
+		struct dwc_otg_device *dwc_otg_device)
+{
+	struct usb_hcd *hcd = NULL;
+	struct dwc_hcd *dwc_hcd = NULL;
+	struct dwc_otg_device *otg_dev = dev_get_drvdata(_dev);
+	int num_channels;
+	u32 i;
+	struct dwc_hc *channel;
+	int retval = 0;
+
+	/*
+	 * Allocate memory for the base HCD plus the DWC OTG HCD.
+	 * Initialize the base HCD.
+	 */
+	hcd = usb_create_hcd(&dwc_otg_hc_driver, _dev, dwc_otg_hcd_name);
+	if (!hcd) {
+		retval = -ENOMEM;
+		goto error1;
+	}
+	dev_set_drvdata(_dev, dwc_otg_device);
+	hcd->regs = otg_dev->base;
+	hcd->self.otg_port = 1;
+
+	/* Initialize the DWC OTG HCD. */
+	dwc_hcd = hcd_to_dwc_otg_hcd(hcd);
+	dwc_hcd->core_if = otg_dev->core_if;
+	spin_lock_init(&dwc_hcd->lock);
+	otg_dev->hcd = dwc_hcd;
+
+	/* Register the HCD CIL Callbacks */
+	dwc_otg_cil_register_hcd_callbacks(otg_dev->core_if, &hcd_cil_callbacks,
+						hcd);
+
+	/* Initialize the non-periodic schedule. */
+	INIT_LIST_HEAD(&dwc_hcd->non_periodic_sched_inactive);
+	INIT_LIST_HEAD(&dwc_hcd->non_periodic_sched_active);
+
+	/* Initialize the periodic schedule. */
+	INIT_LIST_HEAD(&dwc_hcd->periodic_sched_inactive);
+	INIT_LIST_HEAD(&dwc_hcd->periodic_sched_ready);
+	INIT_LIST_HEAD(&dwc_hcd->periodic_sched_assigned);
+	INIT_LIST_HEAD(&dwc_hcd->periodic_sched_queued);
+
+	/*
+	 * Create a host channel descriptor for each host channel implemented
+	 * in the controller. Initialize the channel descriptor array.
+	 */
+	INIT_LIST_HEAD(&dwc_hcd->free_hc_list);
+	num_channels = dwc_hcd->core_if->core_params->host_channels;
+
+	for (i = 0; i < num_channels; i++) {
+		channel = kzalloc(sizeof(struct dwc_hc), GFP_KERNEL);
+		if (!channel) {
+			retval = -ENOMEM;
+			printk(KERN_ERR "%s: host channel allocation failed\n",
+				__func__);
+			goto error2;
+		}
+
+		channel->hc_num = i;
+		dwc_hcd->hc_ptr_array[i] = channel;
+	}
+
+	/* Initialize the Connection timeout timer. */
+	init_timer(&dwc_hcd->conn_timer);
+
+    /* Initialize reset workqueue */
+	INIT_WORK(&dwc_hcd->usb_port_reset, port_reset_wqfunc);
+	INIT_DELAYED_WORK(&dwc_hcd->core_if->usb_port_wakeup,
+		port_wakeup_wqfunc);
+
+	/* Set device flags indicating whether the HCD supports DMA. */
+	if (otg_dev->core_if->dma_enable) {
+		static u64 dummy_mask = DMA_BIT_MASK(32);
+		printk(KERN_INFO "Using DMA mode\n");
+		_dev->dma_mask = (void *) &dummy_mask;
+		_dev->coherent_dma_mask = ~0;
+	} else {
+		printk(KERN_INFO "Using Slave mode\n");
+		_dev->dma_mask = (void *) 0;
+		_dev->coherent_dma_mask = 0;
+	}
+
+	/*
+	 * Finish generic HCD initialization and start the HCD. This function
+	 * allocates the DMA buffer pool, registers the USB bus, requests the
+	 * IRQ line, and calls dwc_otg_hcd_start method.
+	 */
+	retval = usb_add_hcd(hcd, otg_dev->irq, IRQF_SHARED);
+	if (retval < 0)
+		goto error2;
+
+	/*
+	 * Allocate space for storing data on status transactions. Normally no
+	 * data is sent, but this space acts as a bit bucket. This must be
+	 * done after usb_add_hcd since that function allocates the DMA buffer
+	 * pool.
+	 */
+	if (otg_dev->core_if->dma_enable) {
+		dwc_hcd->status_buf =
+			dma_alloc_coherent(_dev, DWC_OTG_HCD_STATUS_BUF_SIZE,
+						&dwc_hcd->status_buf_dma,
+						GFP_KERNEL | GFP_DMA);
+	} else {
+		dwc_hcd->status_buf = kmalloc(DWC_OTG_HCD_STATUS_BUF_SIZE,
+							GFP_KERNEL);
+	}
+	if (!dwc_hcd->status_buf) {
+		retval = -ENOMEM;
+		printk(KERN_ERR "%s: status_buf allocation failed\n", __func__);
+		goto error3;
+	}
+	return 0;
+
+error3:
+	usb_remove_hcd(hcd);
+error2:
+	dwc_otg_hcd_free(hcd);
+	usb_put_hcd(hcd);
+error1:
+	return retval;
+}
+
+/**
+ * Removes the HCD.
+ * Frees memory and resources associated with the HCD and deregisters the bus.
+ */
+void __devexit dwc_otg_hcd_remove(struct device *_dev)
+{
+	struct dwc_otg_device *otg_dev = dev_get_drvdata(_dev);
+	struct dwc_hcd *dwc_hcd = otg_dev->hcd;
+	struct usb_hcd *hcd = dwc_otg_hcd_to_hcd(dwc_hcd);
+
+	/* Turn off all interrupts */
+	dwc_write_reg32(gintmsk_reg(dwc_hcd), 0);
+	dwc_modify_reg32(gahbcfg_reg(dwc_hcd), 1, 0);
+
+	cancel_work_sync(&dwc_hcd->start_work);
+	cancel_work_sync(&dwc_hcd->usb_port_reset);
+	cancel_work_sync(&dwc_hcd->core_if->usb_port_otg);
+	cancel_rearming_delayed_work(&dwc_hcd->core_if->usb_port_wakeup);
+
+	usb_remove_hcd(hcd);
+	dwc_otg_hcd_free(hcd);
+	usb_put_hcd(hcd);
+}
+
+/** Returns the current frame number. */
+int dwc_otg_hcd_get_frame_number(struct usb_hcd *hcd)
+{
+	struct dwc_hcd *dwc_hcd = hcd_to_dwc_otg_hcd(hcd);
+	union hfnum_data hfnum;
+
+	hfnum.d32 = dwc_read_reg32(&dwc_hcd->core_if->host_if->
+					host_global_regs->hfnum);
+
+	return hfnum.b.frnum;
+}
+
+/**
+ * Prepares a host channel for transferring packets to/from a specific
+ * endpoint. The HCCHARn register is set up with the characteristics specified
+ * in _hc. Host channel interrupts that may need to be serviced while this
+ * transfer is in progress are enabled.
+ */
+static void dwc_otg_hc_init(struct core_if *core_if, struct dwc_hc *hc)
+{
+	u32 intr_enable;
+	union hcintmsk_data hc_intr_mask;
+	union gintmsk_data gintmsk = {.d32 = 0};
+	union hcchar_data hcchar;
+	union hcsplt_data hcsplt;
+	u8 hc_num = hc->hc_num;
+	struct dwc_host_if *host_if = core_if->host_if;
+	struct dwc_hc_regs *hc_regs = host_if->hc_regs[hc_num];
+
+	/* Clear old interrupt conditions for this host channel. */
+	hc_intr_mask.d32 = 0xFFFFFFFF;
+	hc_intr_mask.b.reserved = 0;
+	dwc_write_reg32(&hc_regs->hcint, hc_intr_mask.d32);
+
+	/* Enable channel interrupts required for this transfer. */
+	hc_intr_mask.d32 = 0;
+	hc_intr_mask.b.chhltd = 1;
+	if (core_if->dma_enable) {
+		hc_intr_mask.b.ahberr = 1;
+
+		if (hc->error_state && !hc->do_split &&
+				 hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
+			hc_intr_mask.b.ack = 1;
+			if (hc->ep_is_in) {
+				hc_intr_mask.b.datatglerr = 1;
+				if (hc->ep_type != DWC_OTG_EP_TYPE_INTR)
+					hc_intr_mask.b.nak = 1;
+			}
+		}
+	} else {
+		switch (hc->ep_type) {
+		case DWC_OTG_EP_TYPE_CONTROL:
+		case DWC_OTG_EP_TYPE_BULK:
+			hc_intr_mask.b.xfercompl = 1;
+			hc_intr_mask.b.stall = 1;
+			hc_intr_mask.b.xacterr = 1;
+			hc_intr_mask.b.datatglerr = 1;
+
+			if (hc->ep_is_in) {
+				hc_intr_mask.b.bblerr = 1;
+			}
+			else {
+				hc_intr_mask.b.nak = 1;
+				hc_intr_mask.b.nyet = 1;
+				if (hc->do_ping)
+					hc_intr_mask.b.ack = 1;
+			}
+
+			if (hc->do_split) {
+				hc_intr_mask.b.nak = 1;
+				if (hc->complete_split)
+					hc_intr_mask.b.nyet = 1;
+				else
+					hc_intr_mask.b.ack = 1;
+			}
+
+			if (hc->error_state)
+				hc_intr_mask.b.ack = 1;
+			break;
+		case DWC_OTG_EP_TYPE_INTR:
+			hc_intr_mask.b.xfercompl = 1;
+			hc_intr_mask.b.nak = 1;
+			hc_intr_mask.b.stall = 1;
+			hc_intr_mask.b.xacterr = 1;
+			hc_intr_mask.b.datatglerr = 1;
+			hc_intr_mask.b.frmovrun = 1;
+
+			if (hc->ep_is_in)
+				hc_intr_mask.b.bblerr = 1;
+			if (hc->error_state)
+				hc_intr_mask.b.ack = 1;
+
+			if (hc->do_split) {
+				if (hc->complete_split)
+					hc_intr_mask.b.nyet = 1;
+				else
+					hc_intr_mask.b.ack = 1;
+			}
+			break;
+		case DWC_OTG_EP_TYPE_ISOC:
+			hc_intr_mask.b.xfercompl = 1;
+			hc_intr_mask.b.frmovrun = 1;
+			hc_intr_mask.b.ack = 1;
+
+			if (hc->ep_is_in) {
+				hc_intr_mask.b.xacterr = 1;
+				hc_intr_mask.b.bblerr = 1;
+			}
+			break;
+		}
+	}
+	dwc_write_reg32(&hc_regs->hcintmsk, hc_intr_mask.d32);
+
+	/* Enable the top level host channel interrupt. */
+	intr_enable = (1 << hc_num);
+	dwc_modify_reg32(&host_if->host_global_regs->haintmsk, 0, intr_enable);
+
+	/* Make sure host channel interrupts are enabled. */
+	gintmsk.b.hcintr = 1;
+	dwc_modify_reg32(&core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
+
+	/*
+	 * Program the HCCHARn register with the endpoint characteristics for
+	 * the current transfer.
+	 */
+	hcchar.d32 = 0;
+	hcchar.b.devaddr = hc->dev_addr;
+	hcchar.b.epnum = hc->ep_num;
+	hcchar.b.epdir = hc->ep_is_in;
+	hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
+	hcchar.b.eptype = hc->ep_type;
+	hcchar.b.mps = hc->max_packet;
+	dwc_write_reg32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
+
+	/* Program the HCSPLIT register for SPLITs */
+	hcsplt.d32 = 0;
+	if (hc->do_split) {
+		hcsplt.b.compsplt = hc->complete_split;
+		hcsplt.b.xactpos = hc->xact_pos;
+		hcsplt.b.hubaddr = hc->hub_addr;
+		hcsplt.b.prtaddr = hc->port_addr;
+	}
+	dwc_write_reg32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
+}
+
+/**
+ * Assigns transactions from a QTD to a free host channel and initializes the
+ * host channel to perform the transactions. The host channel is removed from
+ * the free list.
+ */
+static void assign_and_init_hc(struct dwc_hcd *hcd, struct dwc_qh * qh)
+{
+	struct dwc_hc *hc;
+	struct dwc_qtd *qtd;
+	struct urb *urb;
+	struct usb_iso_packet_descriptor *frame_desc;
+
+	hc = list_entry(hcd->free_hc_list.next, struct dwc_hc, hc_list_entry);
+
+	/* Remove the host channel from the free list. */
+	list_del_init(&hc->hc_list_entry);
+	qtd = list_entry(qh->qtd_list.next, struct dwc_qtd, qtd_list_entry);
+	urb = qtd->urb;
+	qh->channel = hc;
+	qh->qtd_in_process = qtd;
+
+	/*
+	 * Use usb_pipedevice to determine device address. This address is
+	 * 0 before the SET_ADDRESS command and the correct address afterward.
+	 */
+	hc->dev_addr = usb_pipedevice(urb->pipe);
+	hc->ep_num = usb_pipeendpoint(urb->pipe);
+
+	if (urb->dev->speed == USB_SPEED_LOW)
+		hc->speed = DWC_OTG_EP_SPEED_LOW;
+	else if (urb->dev->speed == USB_SPEED_FULL)
+		hc->speed = DWC_OTG_EP_SPEED_FULL;
+	else
+		hc->speed = DWC_OTG_EP_SPEED_HIGH;
+
+	hc->max_packet = dwc_max_packet(qh->maxp);
+	hc->xfer_started = 0;
+	hc->halt_status = DWC_OTG_HC_XFER_NO_HALT_STATUS;
+	hc->error_state = (qtd->error_count > 0);
+	hc->halt_on_queue = 0;
+	hc->halt_pending = 0;
+	hc->requests = 0;
+
+	/*
+	 * The following values may be modified in the transfer type section
+	 * below. The xfer_len value may be reduced when the transfer is
+	 * started to accommodate the max widths of the XferSize and PktCnt
+	 * fields in the HCTSIZn register.
+	 */
+	hc->do_ping = qh->ping_state;
+	hc->ep_is_in = (usb_pipein(urb->pipe) != 0);
+	hc->data_pid_start = qh->data_toggle;
+	hc->multi_count = 1;
+
+	if (hcd->core_if->dma_enable)
+		hc->xfer_buff = (u8 *) urb->transfer_dma +
+			urb->actual_length;
+	 else
+		hc->xfer_buff = (u8 *) urb->transfer_buffer +
+			urb->actual_length;
+
+	hc->xfer_len = urb->transfer_buffer_length - urb->actual_length;
+	hc->xfer_count = 0;
+
+	/*
+	 * Set the split attributes
+	 */
+	hc->do_split = 0;
+	if (qh->do_split) {
+		hc->do_split = 1;
+		hc->xact_pos = qtd->isoc_split_pos;
+		hc->complete_split = qtd->complete_split;
+		hc->hub_addr = urb->dev->tt->hub->devnum;
+		hc->port_addr = urb->dev->ttport;
+	}
+
+	switch (usb_pipetype(urb->pipe)) {
+	case PIPE_CONTROL:
+		hc->ep_type = DWC_OTG_EP_TYPE_CONTROL;
+
+		switch (qtd->control_phase) {
+		case DWC_OTG_CONTROL_SETUP:
+			hc->do_ping = 0;
+			hc->ep_is_in = 0;
+			hc->data_pid_start = DWC_OTG_HC_PID_SETUP;
+
+			if (hcd->core_if->dma_enable)
+				hc->xfer_buff = (u8 *) urb->setup_dma;
+			else
+				hc->xfer_buff = (u8 *) urb->setup_packet;
+
+			hc->xfer_len = 8;
+			break;
+		case DWC_OTG_CONTROL_DATA:
+			hc->data_pid_start = qtd->data_toggle;
+			break;
+		case DWC_OTG_CONTROL_STATUS:
+			/*
+			 * Direction is opposite of data direction or IN if no
+			 * data.
+			 */
+			if (urb->transfer_buffer_length == 0)
+				hc->ep_is_in = 1;
+			else
+				hc->ep_is_in = (usb_pipein(urb->pipe) !=
+							USB_DIR_IN);
+
+			if (hc->ep_is_in)
+				hc->do_ping = 0;
+
+			hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
+			hc->xfer_len = 0;
+			if (hcd->core_if->dma_enable)
+				hc->xfer_buff = (u8 *) hcd->status_buf_dma;
+			else
+				hc->xfer_buff = (u8 *) hcd->status_buf;
+			break;
+		}
+		break;
+	case PIPE_BULK:
+		hc->ep_type = DWC_OTG_EP_TYPE_BULK;
+		break;
+	case PIPE_INTERRUPT:
+		hc->ep_type = DWC_OTG_EP_TYPE_INTR;
+		break;
+	case PIPE_ISOCHRONOUS:
+		frame_desc = &urb->iso_frame_desc[qtd->isoc_frame_index];
+		hc->ep_type = DWC_OTG_EP_TYPE_ISOC;
+
+		if (hcd->core_if->dma_enable)
+			hc->xfer_buff = (u8 *) urb->transfer_dma;
+		else
+			hc->xfer_buff = (u8 *) urb->transfer_buffer;
+
+		hc->xfer_buff += frame_desc->offset + qtd->isoc_split_offset;
+		hc->xfer_len = frame_desc->length - qtd->isoc_split_offset;
+
+		if (hc->xact_pos == DWC_HCSPLIT_XACTPOS_ALL) {
+			if (hc->xfer_len <= 188)
+				hc->xact_pos = DWC_HCSPLIT_XACTPOS_ALL;
+			else
+				hc->xact_pos = DWC_HCSPLIT_XACTPOS_BEGIN;
+		}
+		break;
+	}
+
+	if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
+			hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
+		/*
+		 * This value may be modified when the transfer is started to
+		 * reflect the actual transfer length.
+		 */
+		hc->multi_count = dwc_hb_mult(qh->maxp);
+
+	dwc_otg_hc_init(hcd->core_if, hc);
+	hc->qh = qh;
+}
+
+/**
+ * This function selects transactions from the HCD transfer schedule and
+ * assigns them to available host channels. It is called from HCD interrupt
+ * handler functions.
+ */
+enum dwc_transaction_type dwc_otg_hcd_select_transactions(struct dwc_hcd *hcd)
+{
+	struct list_head *qh_ptr;
+	struct dwc_qh *qh;
+	int num_channels;
+	enum dwc_transaction_type ret_val = DWC_OTG_TRANSACTION_NONE;
+
+	/* Process entries in the periodic ready list. */
+	qh_ptr = hcd->periodic_sched_ready.next;
+	while (qh_ptr != &hcd->periodic_sched_ready &&
+	       !list_empty(&hcd->free_hc_list)) {
+		qh = list_entry(qh_ptr, struct dwc_qh, qh_list_entry);
+		assign_and_init_hc(hcd, qh);
+
+		/*
+		 * Move the QH from the periodic ready schedule to the
+		 * periodic assigned schedule.
+		 */
+		qh_ptr = qh_ptr->next;
+		list_move(&qh->qh_list_entry, &hcd->periodic_sched_assigned);
+		ret_val = DWC_OTG_TRANSACTION_PERIODIC;
+	}
+
+	/*
+	 * Process entries in the inactive portion of the non-periodic
+	 * schedule. Some free host channels may not be used if they are
+	 * reserved for periodic transfers.
+	 */
+	qh_ptr = hcd->non_periodic_sched_inactive.next;
+	num_channels = hcd->core_if->core_params->host_channels;
+
+	while (qh_ptr != &hcd->non_periodic_sched_inactive &&
+	       (hcd->non_periodic_channels <
+	       num_channels - hcd->periodic_channels) &&
+	       !list_empty(&hcd->free_hc_list)) {
+		qh = list_entry(qh_ptr, struct dwc_qh, qh_list_entry);
+		assign_and_init_hc(hcd, qh);
+
+		/*
+		 * Move the QH from the non-periodic inactive schedule to the
+		 * non-periodic active schedule.
+		 */
+		qh_ptr = qh_ptr->next;
+		list_move(&qh->qh_list_entry, &hcd->non_periodic_sched_active);
+		if (ret_val == DWC_OTG_TRANSACTION_NONE)
+			ret_val = DWC_OTG_TRANSACTION_NON_PERIODIC;
+		else
+			ret_val = DWC_OTG_TRANSACTION_ALL;
+
+		hcd->non_periodic_channels++;
+	}
+	return ret_val;
+}
+
+/**
+ * Sets the channel property that indicates in which frame a periodic transfer
+ * should occur. This is always set to the _next_ frame. This function has no
+ * effect on non-periodic transfers.
+ */
+static inline void hc_set_even_odd_frame(struct core_if *core_if,
+			struct dwc_hc *hc, union hcchar_data *hcchar)
+{
+	if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
+			hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
+		union hfnum_data hfnum;
+		hfnum.d32 = dwc_read_reg32(
+			&core_if->host_if->host_global_regs->hfnum);
+
+		/* 1 if _next_ frame is odd, 0 if it's even */
+		hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
+	}
+}
+
+static void set_initial_xfer_pid(struct dwc_hc *hc)
+{
+	if (hc->speed == DWC_OTG_EP_SPEED_HIGH) {
+		if (hc->ep_is_in) {
+			if (hc->multi_count == 1)
+				hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
+			else if (hc->multi_count == 2)
+				hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
+			else
+				hc->data_pid_start = DWC_OTG_HC_PID_DATA2;
+		} else {
+			if (hc->multi_count == 1)
+				hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
+			else
+				hc->data_pid_start = DWC_OTG_HC_PID_MDATA;
+		}
+	} else {
+		hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
+	}
+}
+
+/**
+ * Starts a PING transfer. This function should only be called in Slave mode.
+ * The Do Ping bit is set in the HCTSIZ register, then the channel is enabled.
+ */
+void dwc_otg_hc_do_ping(struct core_if *core_if, struct dwc_hc *hc)
+{
+	union hcchar_data hcchar;
+	union hctsiz_data hctsiz;
+	struct dwc_hc_regs *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
+
+	hctsiz.d32 = 0;
+	hctsiz.b.dopng = 1;
+	hctsiz.b.pktcnt = 1;
+	dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
+
+	hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
+	hcchar.b.chen = 1;
+	hcchar.b.chdis = 0;
+	dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
+}
+
+/**
+ * This function writes a packet into the Tx FIFO associated with the Host
+ * Channel. For a channel associated with a non-periodic EP, the non-periodic
+ * Tx FIFO is written. For a channel associated with a periodic EP, the
+ * periodic Tx FIFO is written. This function should only be called in Slave
+ * mode.
+ *
+ * Upon return the xfer_buff and xfer_count fields in hc are incremented by
+ * then number of bytes written to the Tx FIFO.
+ */
+static void dwc_otg_hc_write_packet(struct core_if *core_if, struct dwc_hc *hc)
+{
+	u32 i;
+	u32 remaining_count;
+	u32 byte_count;
+	u32 dword_count;
+	u32 *data_buff = (u32 *) (hc->xfer_buff);
+	u32 *data_fifo = core_if->data_fifo[hc->hc_num];
+
+	remaining_count = hc->xfer_len - hc->xfer_count;
+	if (remaining_count > hc->max_packet)
+		byte_count = hc->max_packet;
+	 else
+		byte_count = remaining_count;
+
+	dword_count = (byte_count + 3) / 4;
+
+	if (((unsigned long)data_buff) & 0x3)
+		/* xfer_buff is not DWORD aligned. */
+		for (i = 0; i < dword_count; i++, data_buff++)
+			dwc_write_datafifo32(data_fifo,
+				get_unaligned(data_buff));
+	else
+		/* xfer_buff is DWORD aligned. */
+		for (i = 0; i < dword_count; i++, data_buff++)
+			dwc_write_datafifo32(data_fifo, *data_buff);
+
+	hc->xfer_count += byte_count;
+	hc->xfer_buff += byte_count;
+}
+
+/**
+ * This function does the setup for a data transfer for a host channel and
+ * starts the transfer. May be called in either Slave mode or DMA mode. In
+ * Slave mode, the caller must ensure that there is sufficient space in the
+ * request queue and Tx Data FIFO.
+ *
+ * For an OUT transfer in Slave mode, it loads a data packet into the
+ * appropriate FIFO. If necessary, additional data packets will be loaded in
+ * the Host ISR.
+ *
+ * For an IN transfer in Slave mode, a data packet is requested. The data
+ * packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
+ * additional data packets are requested in the Host ISR.
+ *
+ * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
+ * register along with a packet count of 1 and the channel is enabled. This
+ * causes a single PING transaction to occur. Other fields in HCTSIZ are
+ * simply set to 0 since no data transfer occurs in this case.
+ *
+ * For a PING transfer in DMA mode, the HCTSIZ register is initialized with
+ * all the information required to perform the subsequent data transfer. In
+ * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
+ * controller performs the entire PING protocol, then starts the data
+ * transfer.
+ */
+static void dwc_otg_hc_start_transfer(struct core_if *core_if,
+	struct dwc_hc *hc)
+{
+	union hcchar_data hcchar;
+	union hctsiz_data hctsiz;
+	u16 num_packets;
+	u32 max_hc_xfer_size = core_if->core_params->max_transfer_size;
+	u16 max_hc_pkt_count = core_if->core_params->max_packet_count;
+	struct dwc_hc_regs *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
+	hctsiz.d32 = 0;
+
+	if (hc->do_ping) {
+		if (!core_if->dma_enable) {
+			dwc_otg_hc_do_ping(core_if, hc);
+			hc->xfer_started = 1;
+			return;
+		} else {
+			hctsiz.b.dopng = 1;
+		}
+	}
+
+	if (hc->do_split) {
+		num_packets = 1;
+
+		if (hc->complete_split && !hc->ep_is_in)
+			/*
+			 * For CSPLIT OUT Transfer, set the size to 0 so the
+			 * core doesn't expect any data written to the FIFO
+			 */
+			hc->xfer_len = 0;
+		else if (hc->ep_is_in || (hc->xfer_len > hc->max_packet))
+			hc->xfer_len = hc->max_packet;
+		else if (!hc->ep_is_in && (hc->xfer_len > 188))
+			hc->xfer_len = 188;
+
+		hctsiz.b.xfersize = hc->xfer_len;
+	} else {
+		/*
+		 * Ensure that the transfer length and packet count will fit
+		 * in the widths allocated for them in the HCTSIZn register.
+		 */
+		if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
+				hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
+			u32 max_len = hc->multi_count * hc->max_packet;
+
+			/*
+			 * Make sure the transfer size is no larger than one
+			 * (micro)frame's worth of data. (A check was done
+			 * when the periodic transfer was accepted to ensure
+			 * that a (micro)frame's worth of data can be
+			 * programmed into a channel.)
+			 */
+			if (hc->xfer_len > max_len)
+				hc->xfer_len = max_len;
+		} else if (hc->xfer_len > max_hc_xfer_size) {
+			/*
+			 * Make sure that xfer_len is a multiple of max packet
+			 * size.
+			 */
+			hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1;
+		}
+		if (hc->xfer_len > 0) {
+			num_packets = (hc->xfer_len + hc->max_packet - 1) /
+				hc->max_packet;
+			if (num_packets > max_hc_pkt_count) {
+				num_packets = max_hc_pkt_count;
+				hc->xfer_len = num_packets * hc->max_packet;
+			}
+		} else {
+			/* Need 1 packet for transfer length of 0. */
+			num_packets = 1;
+		}
+
+		if (hc->ep_is_in)
+			/*
+			 * Always program an integral # of max packets for IN
+			 * transfers.
+			 */
+			hc->xfer_len = num_packets * hc->max_packet;
+
+		if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
+				hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
+			/*
+			 * Make sure that the multi_count field matches the
+			 * actual transfer length.
+			 */
+			hc->multi_count = num_packets;
+
+		/* Set up the initial PID for the transfer. */
+		if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
+			set_initial_xfer_pid(hc);
+
+		hctsiz.b.xfersize = hc->xfer_len;
+	}
+
+	hc->start_pkt_count = num_packets;
+	hctsiz.b.pktcnt = num_packets;
+	hctsiz.b.pid = hc->data_pid_start;
+	dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
+
+	if (core_if->dma_enable)
+		dwc_write_reg32(&hc_regs->hcdma, (u32) hc->xfer_buff);
+
+	/* Start the split */
+	if (hc->do_split) {
+		union hcsplt_data hcsplt;
+		hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
+		hcsplt.b.spltena = 1;
+		dwc_write_reg32(&hc_regs->hcsplt, hcsplt.d32);
+	}
+
+	hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
+	hcchar.b.multicnt = hc->multi_count;
+	hc_set_even_odd_frame(core_if, hc, &hcchar);
+
+	/* Set host channel enable after all other setup is complete. */
+	hcchar.b.chen = 1;
+	hcchar.b.chdis = 0;
+	dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
+
+	hc->xfer_started = 1;
+	hc->requests++;
+	if (!core_if->dma_enable && !hc->ep_is_in && hc->xfer_len > 0)
+		/* Load OUT packet into the appropriate Tx FIFO. */
+		dwc_otg_hc_write_packet(core_if, hc);
+}
+
+/**
+ * This function continues a data transfer that was started by previous call
+ * to dwc_otg_hc_start_transfer</code>. The caller must ensure there is
+ * sufficient space in the request queue and Tx Data FIFO. This function
+ * should only be called in Slave mode. In DMA mode, the controller acts
+ * autonomously to complete transfers programmed to a host channel.
+ *
+ * For an OUT transfer, a new data packet is loaded into the appropriate FIFO
+ * if there is any data remaining to be queued. For an IN transfer, another
+ * data packet is always requested. For the SETUP phase of a control transfer,
+ * this function does nothing.
+ */
+static int dwc_otg_hc_continue_transfer(struct core_if *core_if,
+	struct dwc_hc *hc)
+{
+	if (hc->do_split) {
+		/* SPLITs always queue just once per channel */
+		return 0;
+	}
+	else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
+		/* SETUPs are queued only once since they can't be NAKed. */
+		return 0;
+	}
+	else if (hc->ep_is_in) {
+		/*
+		  * Always queue another request for other IN transfers. If
+		  * back-to-back INs are issued and NAKs are received for both,
+		  * the driver may still be processing the first NAK when the
+		  * second NAK is received. When the interrupt handler clears
+		  * the NAK interrupt for the first NAK, the second NAK will
+		  * not be seen. So we can't depend on the NAK interrupt
+		  * handler to requeue a NAKed request. Instead, IN requests
+		  * are issued each time this function is called. When the
+		  * transfer completes, the extra requests for the channel will
+		  * be flushed.
+		  */
+		union hcchar_data hcchar;
+		struct dwc_hc_regs *hc_regs =
+			core_if->host_if->hc_regs[hc->hc_num];
+
+		hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
+		hc_set_even_odd_frame(core_if, hc, &hcchar);
+
+		hcchar.b.chen = 1;
+		hcchar.b.chdis = 0;
+		dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
+
+		hc->requests++;
+		return 1;
+	} else {
+		/* OUT transfers. */
+		if (hc->xfer_count < hc->xfer_len) {
+			if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
+					hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
+				union hcchar_data hcchar;
+				struct dwc_hc_regs *hc_regs;
+
+				hc_regs = core_if->host_if->hc_regs[hc->hc_num];
+				hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
+				hc_set_even_odd_frame(core_if, hc, &hcchar);
+			}
+
+			/* Load OUT packet into the appropriate Tx FIFO. */
+			dwc_otg_hc_write_packet(core_if, hc);
+			hc->requests++;
+			return 1;
+		} else  {
+			return 0;
+		}
+	}
+}
+
+/**
+ * This function writes a packet into the Tx FIFO associated with the Host
+ * Channel. For a channel associated with a non-periodic EP, the non-periodic
+ * Tx FIFO is written. For a channel associated with a periodic EP, the
+ * periodic Tx FIFO is written. This function should only be called in Slave
+ * mode.
+ *
+ * Upon return the xfer_buff and xfer_count fields in hc are incremented by
+ * then number of bytes written to the Tx FIFO.
+ */
+
+/**
+ * Attempts to queue a single transaction request for a host channel
+ * associated with either a periodic or non-periodic transfer. This function
+ * assumes that there is space available in the appropriate request queue. For
+ * an OUT transfer or SETUP transaction in Slave mode, it checks whether space
+ * is available in the appropriate Tx FIFO.
+ */
+static int queue_transaction(struct dwc_hcd *hcd, struct dwc_hc *hc,
+			u16 _fifo_dwords_avail)
+{
+	int retval;
+
+	if (hcd->core_if->dma_enable) {
+		if (!hc->xfer_started) {
+			dwc_otg_hc_start_transfer(hcd->core_if, hc);
+			hc->qh->ping_state = 0;
+		}
+		retval = 0;
+	} else if (hc->halt_pending) {
+		/* Don't queue a request if the channel has been halted. */
+		retval = 0;
+	}
+	else if (hc->halt_on_queue) {
+		dwc_otg_hc_halt(hcd->core_if, hc, hc->halt_status);
+		retval = 0;
+	} else if (hc->do_ping) {
+		if (!hc->xfer_started)
+			dwc_otg_hc_start_transfer(hcd->core_if, hc);
+		retval = 0;
+	} else if (!hc->ep_is_in ||
+			hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
+		if ((_fifo_dwords_avail * 4) >= hc->max_packet) {
+			if (!hc->xfer_started) {
+				dwc_otg_hc_start_transfer(hcd->core_if, hc);
+				retval = 1;
+			} else {
+				retval = dwc_otg_hc_continue_transfer(
+						hcd->core_if, hc);
+			}
+		} else {
+			retval = -1;
+		}
+	} else {
+		if (!hc->xfer_started) {
+			dwc_otg_hc_start_transfer(hcd->core_if, hc);
+			retval = 1;
+		} else {
+			retval = dwc_otg_hc_continue_transfer(hcd->core_if, hc);
+		}
+	}
+	return retval;
+}
+
+/**
+ * Processes active non-periodic channels and queues transactions for these
+ * channels to the DWC_otg controller. After queueing transactions, the NP Tx
+ * FIFO Empty interrupt is enabled if there are more transactions to queue as
+ * NP Tx FIFO or request queue space becomes available. Otherwise, the NP Tx
+ * FIFO Empty interrupt is disabled.
+ */
+static void process_non_periodic_channels(struct dwc_hcd *hcd)
+{
+	union gnptxsts_data tx_status;
+	struct list_head *orig_qh_ptr;
+	struct dwc_qh *qh;
+	int status;
+	int no_queue_space = 0;
+	int no_fifo_space = 0;
+	int more_to_do = 0;
+	struct core_global_regs *regs = hcd->core_if->core_global_regs;
+
+	/*
+	 * Keep track of the starting point. Skip over the start-of-list
+	 * entry.
+	 */
+	if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active)
+		hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
+	orig_qh_ptr = hcd->non_periodic_qh_ptr;
+
+	/*
+	 * Process once through the active list or until no more space is
+	 * available in the request queue or the Tx FIFO.
+	 */
+	do {
+		tx_status.d32 = dwc_read_reg32(&regs->gnptxsts);
+		if (!hcd->core_if->dma_enable &&
+				tx_status.b.nptxqspcavail == 0) {
+			no_queue_space = 1;
+			break;
+		}
+
+		qh = list_entry(hcd->non_periodic_qh_ptr, struct dwc_qh,
+					qh_list_entry);
+		status = queue_transaction(hcd, qh->channel,
+					tx_status.b.nptxfspcavail);
+
+		if (status > 0) {
+			more_to_do = 1;
+		}
+		else if (status < 0) {
+			no_fifo_space = 1;
+			break;
+		}
+
+		/* Advance to next QH, skipping start-of-list entry. */
+		hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next;
+		if (hcd->non_periodic_qh_ptr == &hcd->non_periodic_sched_active)
+			hcd->non_periodic_qh_ptr =
+				hcd->non_periodic_qh_ptr->next;
+	} while (hcd->non_periodic_qh_ptr != orig_qh_ptr);
+
+	if (!hcd->core_if->dma_enable) {
+		union gintmsk_data intr_mask = {.d32 = 0};
+
+		intr_mask.b.nptxfempty = 1;
+
+		if (more_to_do || no_queue_space || no_fifo_space) {
+			/*
+			 * May need to queue more transactions as the request
+			 * queue or Tx FIFO empties. Enable the non-periodic
+			 * Tx FIFO empty interrupt. (Always use the half-empty
+			 * level to ensure that new requests are loaded as
+			 * soon as possible.)
+			 */
+			dwc_modify_reg32(gintmsk_reg(hcd), 0, intr_mask.d32);
+		} else {
+			/*
+			 * Disable the Tx FIFO empty interrupt since there are
+			 * no more transactions that need to be queued right
+			 * now. This function is called from interrupt
+			 * handlers to queue more transactions as transfer
+			 * states change.
+			 */
+			dwc_modify_reg32(gintmsk_reg(hcd), intr_mask.d32, 0);
+		}
+	}
+}
+
+/**
+ * Processes periodic channels for the next frame and queues transactions for
+ * these channels to the DWC_otg controller. After queueing transactions, the
+ * Periodic Tx FIFO Empty interrupt is enabled if there are more transactions
+ * to queue as Periodic Tx FIFO or request queue space becomes available.
+ * Otherwise, the Periodic Tx FIFO Empty interrupt is disabled.
+ */
+static void process_periodic_channels(struct dwc_hcd *hcd)
+{
+	union hptxsts_data tx_status;
+	struct list_head *qh_ptr;
+	struct dwc_qh *qh;
+	int status;
+	int no_queue_space = 0;
+	int no_fifo_space = 0;
+	struct host_global_regs *host_regs;
+
+	host_regs = hcd->core_if->host_if->host_global_regs;
+
+	qh_ptr = hcd->periodic_sched_assigned.next;
+	while (qh_ptr != &hcd->periodic_sched_assigned) {
+		tx_status.d32 = dwc_read_reg32(&host_regs->hptxsts);
+		if (tx_status.b.ptxqspcavail == 0) {
+			no_queue_space = 1;
+			break;
+		}
+
+		qh = list_entry(qh_ptr, struct dwc_qh, qh_list_entry);
+
+		/*
+		 * Set a flag if we're queuing high-bandwidth in slave mode.
+		 * The flag prevents any halts to get into the request queue in
+		 * the middle of multiple high-bandwidth packets getting queued.
+		 */
+		if (!hcd->core_if->dma_enable && qh->channel->multi_count > 1)
+			hcd->core_if->queuing_high_bandwidth = 1;
+
+		status = queue_transaction(hcd, qh->channel,
+				tx_status.b.ptxfspcavail);
+		if (status < 0) {
+			no_fifo_space = 1;
+			break;
+		}
+
+		/*
+		 * In Slave mode, stay on the current transfer until there is
+		 * nothing more to do or the high-bandwidth request count is
+		 * reached. In DMA mode, only need to queue one request. The
+		 * controller automatically handles multiple packets for
+		 * high-bandwidth transfers.
+		 */
+		if (hcd->core_if->dma_enable || (status == 0 ||
+				qh->channel->requests ==
+				qh->channel->multi_count)) {
+			qh_ptr = qh_ptr->next;
+
+			/*
+			 * Move the QH from the periodic assigned schedule to
+			 * the periodic queued schedule.
+			 */
+			list_move(&qh->qh_list_entry,
+				  &hcd->periodic_sched_queued);
+
+			/* done queuing high bandwidth */
+			hcd->core_if->queuing_high_bandwidth = 0;
+		}
+	}
+
+	if (!hcd->core_if->dma_enable) {
+		union gintmsk_data intr_mask = {.d32 = 0};
+
+		intr_mask.b.ptxfempty = 1;
+
+		if (!list_empty(&hcd->periodic_sched_assigned) ||
+				no_queue_space || no_fifo_space)
+			/*
+			 * May need to queue more transactions as the request
+			 * queue or Tx FIFO empties. Enable the periodic Tx
+			 * FIFO empty interrupt. (Always use the half-empty
+			 * level to ensure that new requests are loaded as
+			 * soon as possible.)
+			 */
+			dwc_modify_reg32(gintmsk_reg(hcd), 0, intr_mask.d32);
+		else
+			/*
+			 * Disable the Tx FIFO empty interrupt since there are
+			 * no more transactions that need to be queued right
+			 * now. This function is called from interrupt
+			 * handlers to queue more transactions as transfer
+			 * states change.
+			 */
+			dwc_modify_reg32(gintmsk_reg(hcd), intr_mask.d32, 0);
+	}
+}
+
+/**
+ * This function processes the currently active host channels and queues
+ * transactions for these channels to the DWC_otg controller. It is called
+ * from HCD interrupt handler functions.
+ */
+void dwc_otg_hcd_queue_transactions(struct dwc_hcd *hcd,
+		enum dwc_transaction_type tr_type)
+{
+	/* Process host channels associated with periodic transfers. */
+	if ((tr_type == DWC_OTG_TRANSACTION_PERIODIC ||
+			tr_type == DWC_OTG_TRANSACTION_ALL) &&
+			!list_empty(&hcd->periodic_sched_assigned))
+		process_periodic_channels(hcd);
+
+	/* Process host channels associated with non-periodic transfers. */
+	if (tr_type == DWC_OTG_TRANSACTION_NON_PERIODIC ||
+			tr_type == DWC_OTG_TRANSACTION_ALL) {
+		if (!list_empty(&hcd->non_periodic_sched_active)) {
+			process_non_periodic_channels(hcd);
+		} else {
+			/*
+			 * Ensure NP Tx FIFO empty interrupt is disabled when
+			 * there are no non-periodic transfers to process.
+			 */
+			union gintmsk_data gintmsk = {.d32 = 0};
+			gintmsk.b.nptxfempty = 1;
+			dwc_modify_reg32(gintmsk_reg(hcd), gintmsk.d32, 0);
+		}
+	}
+}
+
+/**
+ * Sets the final status of an URB and returns it to the device driver. Any
+ * required cleanup of the URB is performed.
+ */
+void dwc_otg_hcd_complete_urb(struct dwc_hcd *hcd, struct urb *urb, int status)
+__releases(hcd->lock)
+__acquires(hcd->lock)
+{
+	urb->hcpriv = NULL;
+	usb_hcd_unlink_urb_from_ep(dwc_otg_hcd_to_hcd(hcd), urb);
+
+	spin_unlock(&hcd->lock);
+	usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status);
+	spin_lock(&hcd->lock);
+}
diff --git a/drivers/usb/otg/dwc_otg_hcd.h b/drivers/usb/otg/dwc_otg_hcd.h
new file mode 100644
index 0000000..57c36f2
--- /dev/null
+++ b/drivers/usb/otg/dwc_otg_hcd.h
@@ -0,0 +1,421 @@
+/*
+ * DesignWare HS OTG controller driver
+ *
+ * Author: Mark Miesfeld <mmiesfeld@apm.com>
+ *
+ * Based on versions provided by AMCC and Synopsis which are:
+ *	Copyright (C) 2009-2010 AppliedMicro(www.apm.com)
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if !defined(__DWC_HCD_H__)
+#define __DWC_HCD_H__
+
+#include <linux/list.h>
+#include <linux/usb.h>
+#include <linux/slab.h>
+#include <linux/usb/hcd.h>
+
+struct dwc_otg_device;
+
+#include "dwc_otg_cil.h"
+
+/*
+ * This file contains the structures, constants, and interfaces for
+ * the Host Contoller Driver (HCD).
+ *
+ * The Host Controller Driver (HCD) is responsible for translating requests
+ * from the USB Driver into the appropriate actions on the DWC_otg controller.
+ * It isolates the USBD from the specifics of the controller by providing an
+ * API to the USBD.
+ */
+
+/* Phases for control transfers. */
+enum dwc_control_phase {
+	DWC_OTG_CONTROL_SETUP,
+	DWC_OTG_CONTROL_DATA,
+	DWC_OTG_CONTROL_STATUS
+};
+
+/* Transaction types. */
+enum dwc_transaction_type {
+	DWC_OTG_TRANSACTION_NONE,
+	DWC_OTG_TRANSACTION_PERIODIC,
+	DWC_OTG_TRANSACTION_NON_PERIODIC,
+	DWC_OTG_TRANSACTION_ALL
+};
+
+/*
+ * A Queue Transfer Descriptor (QTD) holds the state of a bulk, control,
+ * interrupt, or isochronous transfer. A single QTD is created for each URB
+ * (of one of these types) submitted to the HCD. The transfer associated with
+ * a QTD may require one or multiple transactions.
+ *
+ * A QTD is linked to a Queue Head, which is entered in either the
+ * non-periodic or periodic schedule for execution. When a QTD is chosen for
+ * execution, some or all of its transactions may be executed. After
+ * execution, the state of the QTD is updated. The QTD may be retired if all
+ * its transactions are complete or if an error occurred. Otherwise, it
+ * remains in the schedule so more transactions can be executed later.
+ */
+struct dwc_qtd {
+	/*
+	 * Determines the PID of the next data packet for the data phase of
+	 * control transfers. Ignored for other transfer types.
+	 * One of the following values:
+	 *	- DWC_OTG_HC_PID_DATA0
+	 *	- DWC_OTG_HC_PID_DATA1
+	 */
+	u8 data_toggle;
+
+	/* Current phase for control transfers (Setup, Data, or Status). */
+	enum dwc_control_phase control_phase;
+
+	/*
+	 * Keep track of the current split type
+	 * for FS/LS endpoints on a HS Hub
+	 */
+	u8 complete_split;
+
+	/* How many bytes transferred during SSPLIT OUT */
+	u32 ssplit_out_xfer_count;
+
+	/*
+	 * Holds the number of bus errors that have occurred for a transaction
+	 * within this transfer.
+	 */
+	u8 error_count;
+
+	/*
+	 * Index of the next frame descriptor for an isochronous transfer. A
+	 * frame descriptor describes the buffer position and length of the
+	 * data to be transferred in the next scheduled (micro)frame of an
+	 * isochronous transfer. It also holds status for that transaction.
+	 * The frame index starts at 0.
+	 */
+	int isoc_frame_index;
+
+	/* Position of the ISOC split on full/low speed */
+	u8 isoc_split_pos;
+
+	/* Position of the ISOC split in the buffer for the current frame */
+	u16 isoc_split_offset;
+
+	/* URB for this transfer */
+	struct urb *urb;
+
+	/* This list of QTDs */
+	struct list_head qtd_list_entry;
+};
+
+/*
+ * A Queue Head (QH) holds the static characteristics of an endpoint and
+ * maintains a list of transfers (QTDs) for that endpoint. A QH structure may
+ * be entered in either the non-periodic or periodic schedule.
+ */
+struct dwc_qh {
+	/*
+	 * Endpoint type.
+	 * One of the following values:
+	 *	- USB_ENDPOINT_XFER_CONTROL
+	 *	- USB_ENDPOINT_XFER_ISOC
+	 *	- USB_ENDPOINT_XFER_BULK
+	 *	- USB_ENDPOINT_XFER_INT
+	 */
+	u8 ep_type;
+	u8 ep_is_in;
+
+	/* wMaxPacketSize Field of Endpoint Descriptor. */
+	u16 maxp;
+
+	/*
+	 * Determines the PID of the next data packet for non-control
+	 * transfers. Ignored for control transfers.
+	 * One of the following values:
+	 *	- DWC_OTG_HC_PID_DATA0
+	 *	- DWC_OTG_HC_PID_DATA1
+	 */
+	u8 data_toggle;
+
+	/* Ping state if 1. */
+	u8 ping_state;
+
+	/* List of QTDs for this QH. */
+	struct list_head qtd_list;
+
+	/* Host channel currently processing transfers for this QH. */
+	struct dwc_hc *channel;
+
+	/* QTD currently assigned to a host channel for this QH. */
+	struct dwc_qtd *qtd_in_process;
+
+	/* Full/low speed endpoint on high-speed hub requires split. */
+	u8 do_split;
+
+	/* Periodic schedule information */
+
+	/* Bandwidth in microseconds per (micro)frame. */
+	u8 usecs;
+
+	/* Interval between transfers in (micro)frames. */
+	u16 interval;
+
+	/*
+	 * (micro)frame to initialize a periodic transfer. The transfer
+	 * executes in the following (micro)frame.
+	 */
+	u16 sched_frame;
+
+	/* (micro)frame at which last start split was initialized. */
+	u16 start_split_frame;
+
+	/* Entry for QH in either the periodic or non-periodic schedule. */
+	struct list_head qh_list_entry;
+};
+
+/* Gets the struct usb_hcd that contains a struct dwc_hcd. */
+static inline struct usb_hcd *dwc_otg_hcd_to_hcd(struct dwc_hcd *dwc_hcd)
+{
+	return container_of((void *)dwc_hcd, struct usb_hcd, hcd_priv);
+}
+
+/* HCD Create/Destroy Functions */
+extern int  __init dwc_otg_hcd_init(struct device *_dev,
+			struct dwc_otg_device *dwc_dev);
+extern void dwc_otg_hcd_remove(struct device *_dev);
+
+/*
+ * The following functions support managing the DWC_otg controller in host
+ * mode.
+ */
+extern int dwc_otg_hcd_get_frame_number(struct usb_hcd *hcd);
+extern void dwc_otg_hc_cleanup(struct core_if *core_if, struct dwc_hc *hc);
+extern void dwc_otg_hc_halt(struct core_if *core_if, struct dwc_hc *hc,
+				enum dwc_halt_status _halt_status);
+
+
+/* Transaction Execution Functions */
+extern enum dwc_transaction_type dwc_otg_hcd_select_transactions(
+				struct dwc_hcd *hcd);
+extern void dwc_otg_hcd_queue_transactions(struct dwc_hcd *hcd,
+			enum dwc_transaction_type tr_type);
+extern void dwc_otg_hcd_complete_urb(struct dwc_hcd *_hcd, struct urb *urb,
+				int status);
+
+/* Interrupt Handler Functions */
+extern int dwc_otg_hcd_handle_intr(struct dwc_hcd *hcd);
+
+/* Schedule Queue Functions */
+extern void dwc_otg_hcd_qh_free(struct dwc_qh *qh);
+extern void dwc_otg_hcd_qh_remove(struct dwc_hcd *hcd, struct dwc_qh *qh);
+extern void dwc_otg_hcd_qh_deactivate(struct dwc_hcd *hcd, struct dwc_qh *qh,
+				int sched_csplit);
+
+extern struct dwc_qtd *dwc_otg_hcd_qtd_create(struct urb *urb,
+				gfp_t _mem_flags);
+extern int dwc_otg_hcd_qtd_add(struct dwc_qtd *qtd, struct dwc_hcd *dwc_hcd);
+
+/*
+ * Frees the memory for a QTD structure.  QTD should already be removed from
+ * list.
+ */
+static inline void dwc_otg_hcd_qtd_free(struct dwc_qtd *_qtd)
+{
+	kfree(_qtd);
+}
+
+/* Removes a QTD from list. */
+static inline void dwc_otg_hcd_qtd_remove(struct dwc_qtd *_qtd)
+{
+	list_del(&_qtd->qtd_list_entry);
+}
+
+/* Remove and free a QTD */
+static inline void dwc_otg_hcd_qtd_remove_and_free(struct dwc_qtd *_qtd)
+{
+	dwc_otg_hcd_qtd_remove(_qtd);
+	dwc_otg_hcd_qtd_free(_qtd);
+}
+
+struct dwc_qh *dwc_urb_to_qh(struct urb *_urb);
+
+/* Gets the usb_host_endpoint associated with an URB. */
+static inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *_urb)
+{
+	struct usb_device *dev = _urb->dev;
+	int ep_num = usb_pipeendpoint(_urb->pipe);
+
+	if (usb_pipein(_urb->pipe))
+		return dev->ep_in[ep_num];
+	else
+		return dev->ep_out[ep_num];
+}
+
+/*
+ * Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
+ * qualified with its direction (possible 32 endpoints per device).
+ */
+#define dwc_ep_addr_to_endpoint(_bEndpointAddress_) \
+		((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
+		((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
+
+/* Gets the QH that contains the list_head */
+#define dwc_list_to_qh(_list_head_ptr_) \
+		(container_of(_list_head_ptr_, struct dwc_qh, qh_list_entry))
+
+/* Gets the QTD that contains the list_head */
+#define dwc_list_to_qtd(_list_head_ptr_) \
+		(container_of(_list_head_ptr_, struct dwc_qtd, qtd_list_entry))
+
+/* Check if QH is non-periodic  */
+#define dwc_qh_is_non_per(_qh_ptr_) \
+		((_qh_ptr_->ep_type == USB_ENDPOINT_XFER_BULK) || \
+		(_qh_ptr_->ep_type == USB_ENDPOINT_XFER_CONTROL))
+
+/* High bandwidth multiplier as encoded in highspeed endpoint descriptors */
+#define dwc_hb_mult(wMaxPacketSize)	(1 + (((wMaxPacketSize) >> 11) & 0x03))
+
+/* Packet size for any kind of endpoint descriptor */
+#define dwc_max_packet(wMaxPacketSize)	((wMaxPacketSize) & 0x07ff)
+
+/*
+ * Returns true if _frame1 is less than or equal to _frame2. The comparison is
+ * done modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the
+ * frame number when the max frame number is reached.
+ */
+static inline int dwc_frame_num_le(u16 _frame1, u16 _frame2)
+{
+	return ((_frame2 - _frame1) & DWC_HFNUM_MAX_FRNUM) <=
+			(DWC_HFNUM_MAX_FRNUM >> 1);
+}
+
+/*
+ * Returns true if _frame1 is greater than _frame2. The comparison is done
+ * modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the frame
+ * number when the max frame number is reached.
+ */
+static inline int dwc_frame_num_gt(u16 _frame1, u16 _frame2)
+{
+	return (_frame1 != _frame2) &&
+			(((_frame1 - _frame2) &
+			DWC_HFNUM_MAX_FRNUM) < (DWC_HFNUM_MAX_FRNUM >> 1));
+}
+
+/*
+ * Increments _frame by the amount specified by _inc. The addition is done
+ * modulo DWC_HFNUM_MAX_FRNUM. Returns the incremented value.
+ */
+static inline u16 dwc_frame_num_inc(u16 _frame, u16 _inc)
+{
+	return (_frame + _inc) & DWC_HFNUM_MAX_FRNUM;
+}
+
+static inline u16 dwc_full_frame_num(u16 _frame)
+{
+	return ((_frame) & DWC_HFNUM_MAX_FRNUM) >> 3;
+}
+
+static inline u16 dwc_micro_frame_num(u16 _frame)
+{
+	return (_frame) & 0x7;
+}
+
+static inline u32 *gintsts_reg(struct dwc_hcd *hcd)
+{
+	return (u32 *) &hcd->core_if->core_global_regs->gintsts;
+}
+
+static inline u32 *gintmsk_reg(struct dwc_hcd *hcd)
+{
+	return (u32 *) &hcd->core_if->core_global_regs->gintmsk;
+}
+
+static inline u32 *gahbcfg_reg(struct dwc_hcd *hcd)
+{
+	return (u32 *) &hcd->core_if->core_global_regs->gahbcfg;
+}
+
+static inline const char *pipetype_str(unsigned int pipe)
+{
+	switch (usb_pipetype(pipe)) {
+	case PIPE_CONTROL:
+		return "control";
+	case PIPE_BULK:
+		return "bulk";
+	case PIPE_INTERRUPT:
+		return "interrupt";
+	case PIPE_ISOCHRONOUS:
+		return "isochronous";
+	default:
+		return "unknown";
+	}
+}
+
+static inline const char *dev_speed_str(enum usb_device_speed speed)
+{
+	switch (speed) {
+	case USB_SPEED_HIGH:
+		return "high";
+	case USB_SPEED_FULL:
+		return "full";
+	case USB_SPEED_LOW:
+		return "low";
+	default:
+		return "unknown";
+	}
+}
+
+static inline const char *ep_type_str(u8 type)
+{
+	switch (type) {
+	case USB_ENDPOINT_XFER_ISOC:
+		return "isochronous";
+	case USB_ENDPOINT_XFER_INT:
+		return "interrupt";
+	case USB_ENDPOINT_XFER_CONTROL:
+		return "control";
+	case USB_ENDPOINT_XFER_BULK:
+		return "bulk";
+	default:
+		return "?";
+	}
+}
+#endif
-- 
1.6.0.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox