linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* similar files: fusbh200-hcd.c and fotg210-hcd.c
@ 2015-09-07 14:47 Peter Senna Tschudin
  2015-09-08 15:52 ` Felipe Balbi
  0 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-07 14:47 UTC (permalink / raw)
  To: Felipe Balbi, stern, Sergei Shtylyov, Masanari Iida, pmladek,
	linux-usb, linux-kernel, Greg Kroah-Hartman

I executed a clone detection tool* on drivers source code and I found
that the files

drivers/usb/host/fusbh200-hcd.c

and

drivers/usb/host/fotg210-hcd.c

are very similar. The main difference between the two files are
replacing the string 'USBH20' by 'OTG21' and some white space fixes.
Some changes are being applied to only one of the files, such as the
commit f848a88d223cafa43cb318839a1171b498cf5ec8 that changes
fotg210-hcd.c but not fusbh200-hcd.c.

Should these files be consolidated? And if so how?

Thank you,

Peter

* https://github.com/petersenna/ccfinderx-core

-- 
Peter

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: similar files: fusbh200-hcd.c and fotg210-hcd.c
  2015-09-07 14:47 similar files: fusbh200-hcd.c and fotg210-hcd.c Peter Senna Tschudin
@ 2015-09-08 15:52 ` Felipe Balbi
  2015-09-12 13:14   ` Peter Senna Tschudin
  0 siblings, 1 reply; 61+ messages in thread
From: Felipe Balbi @ 2015-09-08 15:52 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: Felipe Balbi, stern, Sergei Shtylyov, Masanari Iida, pmladek,
	linux-usb, linux-kernel, Greg Kroah-Hartman

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

On Mon, Sep 07, 2015 at 04:47:45PM +0200, Peter Senna Tschudin wrote:
> I executed a clone detection tool* on drivers source code and I found
> that the files
> 
> drivers/usb/host/fusbh200-hcd.c
> 
> and
> 
> drivers/usb/host/fotg210-hcd.c
> 
> are very similar. The main difference between the two files are
> replacing the string 'USBH20' by 'OTG21' and some white space fixes.
> Some changes are being applied to only one of the files, such as the
> commit f848a88d223cafa43cb318839a1171b498cf5ec8 that changes
> fotg210-hcd.c but not fusbh200-hcd.c.
> 
> Should these files be consolidated? And if so how?

if you can find an easy way, that would be a very, very welcome patch.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: similar files: fusbh200-hcd.c and fotg210-hcd.c
  2015-09-08 15:52 ` Felipe Balbi
@ 2015-09-12 13:14   ` Peter Senna Tschudin
  2015-09-14 15:01     ` Felipe Balbi
  0 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-12 13:14 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Alan Stern, Sergei Shtylyov, Masanari Iida, pmladek, linux-usb,
	linux-kernel, Greg Kroah-Hartman

>> Should these files be consolidated? And if so how?
> if you can find an easy way, that would be a very, very welcome patch.

Is the ideal solution to consolidate both fusbh200-hcd.c and
fotg210-hcd.c in a single module? If this is the case, how to detect
at run time which version of the hw is present? Both are registered as
platform devices and I could not find an obvious way to detect the
model at run time. I could successfully load fusbh200-hcd on my fedora
notebook (hp elitebook 840), and on a VM, even if neither has the hw
($ sudo modprobe fusbh200-hcd). The module loads with the warning
"fusbh200_hcd should always be loaded before uhci_hcd and ohci_hcd,
not after". On another workstation running ubuntu, I could load both
modules at the same time, producing the same warning for each module.
Should the module load if the device is not present?

Other solution for consolidation would be to create a common_code.c,
keeping both fusbh200-hcd.c and fotg210-hcd.c only with the code that
differ. Is this better than what is there now?

Other ideas?


-- 
Peter

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: similar files: fusbh200-hcd.c and fotg210-hcd.c
  2015-09-12 13:14   ` Peter Senna Tschudin
@ 2015-09-14 15:01     ` Felipe Balbi
  2015-09-14 17:50       ` Peter Senna Tschudin
  0 siblings, 1 reply; 61+ messages in thread
From: Felipe Balbi @ 2015-09-14 15:01 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: Felipe Balbi, Alan Stern, Sergei Shtylyov, Masanari Iida,
	pmladek, linux-usb, linux-kernel, Greg Kroah-Hartman

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

On Sat, Sep 12, 2015 at 03:14:50PM +0200, Peter Senna Tschudin wrote:
> >> Should these files be consolidated? And if so how?
> > if you can find an easy way, that would be a very, very welcome patch.
> 
> Is the ideal solution to consolidate both fusbh200-hcd.c and
> fotg210-hcd.c in a single module? If this is the case, how to detect
> at run time which version of the hw is present? Both are registered as

does it matter ? If they work the same way, why does it matter which
one's running?

> platform devices and I could not find an obvious way to detect the
> model at run time. I could successfully load fusbh200-hcd on my fedora

is there a revision register ? Or you may use different platform_device
names with platform_device_id table.

> notebook (hp elitebook 840), and on a VM, even if neither has the hw
> ($ sudo modprobe fusbh200-hcd). The module loads with the warning
> "fusbh200_hcd should always be loaded before uhci_hcd and ohci_hcd,
> not after". On another workstation running ubuntu, I could load both
> modules at the same time, producing the same warning for each module.
> Should the module load if the device is not present?
> 
> Other solution for consolidation would be to create a common_code.c,
> keeping both fusbh200-hcd.c and fotg210-hcd.c only with the code that
> differ. Is this better than what is there now?
> 
> Other ideas?

just combine them :-p Use platform_device_id to differentiate.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: similar files: fusbh200-hcd.c and fotg210-hcd.c
  2015-09-14 15:01     ` Felipe Balbi
@ 2015-09-14 17:50       ` Peter Senna Tschudin
  2015-09-15 14:33         ` Felipe Balbi
  0 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-14 17:50 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Alan Stern, Sergei Shtylyov, Masanari Iida, pmladek, linux-usb,
	linux-kernel, Greg Kroah-Hartman

On Mon, Sep 14, 2015 at 5:01 PM, Felipe Balbi <balbi@ti.com> wrote:
> On Sat, Sep 12, 2015 at 03:14:50PM +0200, Peter Senna Tschudin wrote:
>> >> Should these files be consolidated? And if so how?
>> > if you can find an easy way, that would be a very, very welcome patch.
>>
>> Is the ideal solution to consolidate both fusbh200-hcd.c and
>> fotg210-hcd.c in a single module? If this is the case, how to detect
>> at run time which version of the hw is present? Both are registered as
>
> does it matter ? If they work the same way, why does it matter which
> one's running?

I may be missing something simple, but based on a 2 page product
brief, fotg210 has more resources like memory. So even if the .c files
are _very_ similar, there are some configuration parameters that
differ, for example:

fusbh200.h:
#define BMCSR_VBUS_OFF (1<<4)
#define BMCSR_INT_POLARITY (1<<3)

fotg210.h:
#define OTGCSR_A_BUS_DROP (1 << 5)
#define OTGCSR_A_BUS_REQ (1 << 4)

which are used by {fusbh200,fotg210}_init:

fusbh200-hcd.c:
static void fusbh200_init(struct fusbh200_hcd *fusbh200)
{
u32 reg;

reg = fusbh200_readl(fusbh200, &fusbh200->regs->bmcsr);
reg |= BMCSR_INT_POLARITY;
reg &= ~BMCSR_VBUS_OFF;
fusbh200_writel(fusbh200, reg, &fusbh200->regs->bmcsr);

reg = fusbh200_readl(fusbh200, &fusbh200->regs->bmier);
fusbh200_writel(fusbh200, reg | BMIER_OVC_EN | BMIER_VBUS_ERR_EN,
&fusbh200->regs->bmier);
}


fotg210-hcd.c:
static void fotg210_init(struct fotg210_hcd *fotg210)
{
u32 value;

iowrite32(GMIR_MDEV_INT | GMIR_MOTG_INT | GMIR_INT_POLARITY,
 &fotg210->regs->gmir);

value = ioread32(&fotg210->regs->otgcsr);
value &= ~OTGCSR_A_BUS_DROP;
value |= OTGCSR_A_BUS_REQ;
iowrite32(value, &fotg210->regs->otgcsr);
}

Then:

fusbh200.h:
#define BMCSR_HOST_SPD_TYP (3<<9)

static inline unsigned int
fusbh200_get_speed(struct fusbh200_hcd *fusbh200, unsigned int portsc)
{
return (readl(&fusbh200->regs->bmcsr)
& BMCSR_HOST_SPD_TYP) >> 9;
}

fotg210.h:
#define OTGCSR_HOST_SPD_TYP     (3 << 22)
static inline unsigned int

fotg210_get_speed(struct fotg210_hcd *fotg210, unsigned int portsc)
{
return (readl(&fotg210->regs->otgcsr)
& OTGCSR_HOST_SPD_TYP) >> 22;
}

So my concern is to have a way to identify which is the device version
to use the right parameters. I think that the BMCSR_HOST_SPD_TYP vs
OTGCSR_HOST_SPD_TYP can be solved, but I'm not sure about the
initialization. Ideas?

>
>> platform devices and I could not find an obvious way to detect the
>> model at run time. I could successfully load fusbh200-hcd on my fedora
>
> is there a revision register ? Or you may use different platform_device
> names with platform_device_id table.

I don't know about revision registers. That would be good. I could not
find complete datasheets, only a 2 page product brief, no registry
information there.

>
>> notebook (hp elitebook 840), and on a VM, even if neither has the hw
>> ($ sudo modprobe fusbh200-hcd). The module loads with the warning
>> "fusbh200_hcd should always be loaded before uhci_hcd and ohci_hcd,
>> not after". On another workstation running ubuntu, I could load both
>> modules at the same time, producing the same warning for each module.
>> Should the module load if the device is not present?
>>
>> Other solution for consolidation would be to create a common_code.c,
>> keeping both fusbh200-hcd.c and fotg210-hcd.c only with the code that
>> differ. Is this better than what is there now?
>>
>> Other ideas?
>
> just combine them :-p Use platform_device_id to differentiate.

I'm afraid the combined version will use the correct parameters for
only one of the two. But I may be missing something simple. I did a
diff between the two files after removing white space differences, and
after replacing fusbh200 by fotg210 on the fusbh200 driver. The files
are very similar. See: http://pastebin.com/ZRY3xePv



>
> --
> balbi



-- 
Peter

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: similar files: fusbh200-hcd.c and fotg210-hcd.c
  2015-09-14 17:50       ` Peter Senna Tschudin
@ 2015-09-15 14:33         ` Felipe Balbi
  2015-09-15 16:41           ` Peter Senna Tschudin
  0 siblings, 1 reply; 61+ messages in thread
From: Felipe Balbi @ 2015-09-15 14:33 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: Felipe Balbi, Alan Stern, Sergei Shtylyov, Masanari Iida,
	pmladek, linux-usb, linux-kernel, Greg Kroah-Hartman

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

On Mon, Sep 14, 2015 at 07:50:02PM +0200, Peter Senna Tschudin wrote:
> On Mon, Sep 14, 2015 at 5:01 PM, Felipe Balbi <balbi@ti.com> wrote:
> > On Sat, Sep 12, 2015 at 03:14:50PM +0200, Peter Senna Tschudin wrote:
> >> >> Should these files be consolidated? And if so how?
> >> > if you can find an easy way, that would be a very, very welcome patch.
> >>
> >> Is the ideal solution to consolidate both fusbh200-hcd.c and
> >> fotg210-hcd.c in a single module? If this is the case, how to detect
> >> at run time which version of the hw is present? Both are registered as
> >
> > does it matter ? If they work the same way, why does it matter which
> > one's running?
> 
> I may be missing something simple, but based on a 2 page product
> brief, fotg210 has more resources like memory. So even if the .c files
> are _very_ similar, there are some configuration parameters that
> differ, for example:
> 
> fusbh200.h:
> #define BMCSR_VBUS_OFF (1<<4)
> #define BMCSR_INT_POLARITY (1<<3)
> 
> fotg210.h:
> #define OTGCSR_A_BUS_DROP (1 << 5)
> #define OTGCSR_A_BUS_REQ (1 << 4)

Can you detect that in runtime ? If you can, detect it. If you can't use
different platform_device_id.

> >> notebook (hp elitebook 840), and on a VM, even if neither has the hw
> >> ($ sudo modprobe fusbh200-hcd). The module loads with the warning
> >> "fusbh200_hcd should always be loaded before uhci_hcd and ohci_hcd,
> >> not after". On another workstation running ubuntu, I could load both
> >> modules at the same time, producing the same warning for each module.
> >> Should the module load if the device is not present?
> >>
> >> Other solution for consolidation would be to create a common_code.c,
> >> keeping both fusbh200-hcd.c and fotg210-hcd.c only with the code that
> >> differ. Is this better than what is there now?
> >>
> >> Other ideas?
> >
> > just combine them :-p Use platform_device_id to differentiate.
> 
> I'm afraid the combined version will use the correct parameters for
> only one of the two. But I may be missing something simple. I did a
> diff between the two files after removing white space differences, and
> after replacing fusbh200 by fotg210 on the fusbh200 driver. The files
> are very similar. See: http://pastebin.com/ZRY3xePv

yeah, you can totally combine them. Grep the tree for examples of how to
use platform_device_id as I mentioned.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: similar files: fusbh200-hcd.c and fotg210-hcd.c
  2015-09-15 14:33         ` Felipe Balbi
@ 2015-09-15 16:41           ` Peter Senna Tschudin
  2015-09-15 16:50             ` Felipe Balbi
  0 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-15 16:41 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Alan Stern, Sergei Shtylyov, Masanari Iida, pmladek, linux-usb,
	linux-kernel, Greg Kroah-Hartman

On Tue, Sep 15, 2015 at 4:33 PM, Felipe Balbi <balbi@ti.com> wrote:
> On Mon, Sep 14, 2015 at 07:50:02PM +0200, Peter Senna Tschudin wrote:
>> On Mon, Sep 14, 2015 at 5:01 PM, Felipe Balbi <balbi@ti.com> wrote:
>> > On Sat, Sep 12, 2015 at 03:14:50PM +0200, Peter Senna Tschudin wrote:
>> >> >> Should these files be consolidated? And if so how?
>> >> > if you can find an easy way, that would be a very, very welcome patch.
>> >>
>> >> Is the ideal solution to consolidate both fusbh200-hcd.c and
>> >> fotg210-hcd.c in a single module? If this is the case, how to detect
>> >> at run time which version of the hw is present? Both are registered as
>> >
>> > does it matter ? If they work the same way, why does it matter which
>> > one's running?
>>
>> I may be missing something simple, but based on a 2 page product
>> brief, fotg210 has more resources like memory. So even if the .c files
>> are _very_ similar, there are some configuration parameters that
>> differ, for example:
>>
>> fusbh200.h:
>> #define BMCSR_VBUS_OFF (1<<4)
>> #define BMCSR_INT_POLARITY (1<<3)
>>
>> fotg210.h:
>> #define OTGCSR_A_BUS_DROP (1 << 5)
>> #define OTGCSR_A_BUS_REQ (1 << 4)
>
> Can you detect that in runtime ? If you can, detect it. If you can't use
> different platform_device_id.
>
>> >> notebook (hp elitebook 840), and on a VM, even if neither has the hw
>> >> ($ sudo modprobe fusbh200-hcd). The module loads with the warning
>> >> "fusbh200_hcd should always be loaded before uhci_hcd and ohci_hcd,
>> >> not after". On another workstation running ubuntu, I could load both
>> >> modules at the same time, producing the same warning for each module.
>> >> Should the module load if the device is not present?
>> >>
>> >> Other solution for consolidation would be to create a common_code.c,
>> >> keeping both fusbh200-hcd.c and fotg210-hcd.c only with the code that
>> >> differ. Is this better than what is there now?
>> >>
>> >> Other ideas?
>> >
>> > just combine them :-p Use platform_device_id to differentiate.

Can you check the f2xx branch at:

git@github.com:petersenna/linux.git

And tell me if this is the way to go for the consolidation of the two
drivers? I started with the newest driver, did code cleanup, and
started filling the new driver with parameters from the older
FUSBH200. At the moment it compiles for x86 and probably still works
for FOTG210 devices. A concrete question I have is if should I keep
making many patches for the consolidation or should I do a single big
patch with all changes? Comments are welcome.

>>
>> I'm afraid the combined version will use the correct parameters for
>> only one of the two. But I may be missing something simple. I did a
>> diff between the two files after removing white space differences, and
>> after replacing fusbh200 by fotg210 on the fusbh200 driver. The files
>> are very similar. See: http://pastebin.com/ZRY3xePv
>
> yeah, you can totally combine them. Grep the tree for examples of how to
> use platform_device_id as I mentioned.

I'll do it. Thank you.

>
> --
> balbi



-- 
Peter

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: similar files: fusbh200-hcd.c and fotg210-hcd.c
  2015-09-15 16:41           ` Peter Senna Tschudin
@ 2015-09-15 16:50             ` Felipe Balbi
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
  2015-09-25 13:04               ` similar files: fusbh200-hcd.c and fotg210-hcd.c Peter Senna Tschudin
  0 siblings, 2 replies; 61+ messages in thread
From: Felipe Balbi @ 2015-09-15 16:50 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: Felipe Balbi, Alan Stern, Sergei Shtylyov, Masanari Iida,
	pmladek, linux-usb, linux-kernel, Greg Kroah-Hartman

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

Hi,

On Tue, Sep 15, 2015 at 06:41:55PM +0200, Peter Senna Tschudin wrote:
> On Tue, Sep 15, 2015 at 4:33 PM, Felipe Balbi <balbi@ti.com> wrote:
> > On Mon, Sep 14, 2015 at 07:50:02PM +0200, Peter Senna Tschudin wrote:
> >> On Mon, Sep 14, 2015 at 5:01 PM, Felipe Balbi <balbi@ti.com> wrote:
> >> > On Sat, Sep 12, 2015 at 03:14:50PM +0200, Peter Senna Tschudin wrote:
> >> >> >> Should these files be consolidated? And if so how?
> >> >> > if you can find an easy way, that would be a very, very welcome patch.
> >> >>
> >> >> Is the ideal solution to consolidate both fusbh200-hcd.c and
> >> >> fotg210-hcd.c in a single module? If this is the case, how to detect
> >> >> at run time which version of the hw is present? Both are registered as
> >> >
> >> > does it matter ? If they work the same way, why does it matter which
> >> > one's running?
> >>
> >> I may be missing something simple, but based on a 2 page product
> >> brief, fotg210 has more resources like memory. So even if the .c files
> >> are _very_ similar, there are some configuration parameters that
> >> differ, for example:
> >>
> >> fusbh200.h:
> >> #define BMCSR_VBUS_OFF (1<<4)
> >> #define BMCSR_INT_POLARITY (1<<3)
> >>
> >> fotg210.h:
> >> #define OTGCSR_A_BUS_DROP (1 << 5)
> >> #define OTGCSR_A_BUS_REQ (1 << 4)
> >
> > Can you detect that in runtime ? If you can, detect it. If you can't use
> > different platform_device_id.
> >
> >> >> notebook (hp elitebook 840), and on a VM, even if neither has the hw
> >> >> ($ sudo modprobe fusbh200-hcd). The module loads with the warning
> >> >> "fusbh200_hcd should always be loaded before uhci_hcd and ohci_hcd,
> >> >> not after". On another workstation running ubuntu, I could load both
> >> >> modules at the same time, producing the same warning for each module.
> >> >> Should the module load if the device is not present?
> >> >>
> >> >> Other solution for consolidation would be to create a common_code.c,
> >> >> keeping both fusbh200-hcd.c and fotg210-hcd.c only with the code that
> >> >> differ. Is this better than what is there now?
> >> >>
> >> >> Other ideas?
> >> >
> >> > just combine them :-p Use platform_device_id to differentiate.
> 
> Can you check the f2xx branch at:
> 
> git@github.com:petersenna/linux.git
> 
> And tell me if this is the way to go for the consolidation of the two
> drivers? I started with the newest driver, did code cleanup, and
> started filling the new driver with parameters from the older
> FUSBH200. At the moment it compiles for x86 and probably still works
> for FOTG210 devices. A concrete question I have is if should I keep
> making many patches for the consolidation or should I do a single big
> patch with all changes? Comments are welcome.

it's best to just send patches. Also, you gave me an ssh URL which I
can't use because I don't have write access to your tree (and I don't
want to have it).

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210
  2015-09-15 16:50             ` Felipe Balbi
@ 2015-09-21 15:01               ` Peter Senna Tschudin
  2015-09-21 15:01                 ` [PATCH 01/14] RFC: usb/host/fotg210: Fix coding style issues Peter Senna Tschudin
                                   ` (15 more replies)
  2015-09-25 13:04               ` similar files: fusbh200-hcd.c and fotg210-hcd.c Peter Senna Tschudin
  1 sibling, 16 replies; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-21 15:01 UTC (permalink / raw)
  To: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh
  Cc: Peter Senna Tschudin

I'm working on the consolidation of two very similar Faraday EHCI drivers:

drivers/usb/host/fusbh200-hcd.c and drivers/usb/host/fotg210-hcd.c

I'm sending the work unfinished because I have some questions, and I would
appreciate feedback about the changes. As this is not complete work, please do
_not_ apply the series. 

Patches from 01 to 10 are fixes to issues reported by checkpatch, patches 11,
12 and 13 are changes to prepare the code to support multiple devices, and
patch 14 adds parameters from fusb200 into faraday-hcd.

My questions:
 - Is the name faraday-hcd good for the driver that will support both
   fusb200-hcd and fotg210-hcd?

 - Is this patch series in a good direction for consolidating the two drivers?
   I mean it is a lot of patches, and there are many different orders in which
   I could send them.

 - Is it a good idea to include now changes like patches 06, 09 and 10 that may
   have impact on performance? Or should I wait until I can get some hw to
   test?

 - Do you know easy to find and cheap devices using this two host controllers?

 - Should I worry about drivers/usb/gadget/udc/fotg210-udc.c?

Peter Senna Tschudin (14):
  usb/host/fotg210: Fix coding style issues
  usb/host/fotg210: remove KERN_WARNING from pr_info
  usb/host/fotg210: Remove useless else statement
  usb/host/fotg210: Remove NULL checks dma_pool_destroy
  usb/host/fotg210: change kmalloc by kmalloc_array
  usb/host/fotg210: replace msleep by usleep_range
  usb/host/fotg210: Remove a macro from a call to snprintf
  usb/host/fotg210: convert macro to inline function
  usb/host/fotg210: Add function: output_buf_tds_dir()
  usb/host/fotg210: Add function scan_frame_queue()
  usb/host: Rename fotg210-hcd to faraday-hcd
  usb/host/faraday-hcd: Replace fotg210 by fhcd2xx
  usb/host/faraday-hcd: Move #defines outside struct
  usb/host/faraday-hcd: Import FUSBH200 parameters

 drivers/usb/host/Kconfig       |    2 +-
 drivers/usb/host/Makefile      |    2 +-
 drivers/usb/host/faraday-hcd.c | 5792 ++++++++++++++++++++++++++++++++++++++
 drivers/usb/host/faraday-hcd.h |  751 +++++
 drivers/usb/host/fotg210-hcd.c | 5951 ----------------------------------------
 drivers/usb/host/fotg210.h     |  686 -----
 6 files changed, 6545 insertions(+), 6639 deletions(-)
 create mode 100644 drivers/usb/host/faraday-hcd.c
 create mode 100644 drivers/usb/host/faraday-hcd.h
 delete mode 100644 drivers/usb/host/fotg210-hcd.c
 delete mode 100644 drivers/usb/host/fotg210.h

-- 
2.1.0


^ permalink raw reply	[flat|nested] 61+ messages in thread

* [PATCH 01/14] RFC: usb/host/fotg210: Fix coding style issues
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
@ 2015-09-21 15:01                 ` Peter Senna Tschudin
  2015-10-02 17:29                   ` Felipe Balbi
  2015-09-21 15:01                 ` [PATCH 02/14] RFC: usb/host/fotg210: remove KERN_WARNING from pr_info Peter Senna Tschudin
                                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-21 15:01 UTC (permalink / raw)
  To: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh
  Cc: Peter Senna Tschudin

This patch fix coding style issues reported by checkpatch that do not
change semantics of the code.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 1248 +++++++++++++++++-----------------------
 drivers/usb/host/fotg210.h     |   36 +-
 2 files changed, 558 insertions(+), 726 deletions(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 000ed80..48eac34 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -50,32 +50,30 @@
 #include <asm/irq.h>
 #include <asm/unaligned.h>
 
-/*-------------------------------------------------------------------------*/
 #define DRIVER_AUTHOR "Yuan-Hsin Chen"
 #define DRIVER_DESC "FOTG210 Host Controller (EHCI) Driver"
-
-static const char	hcd_name[] = "fotg210_hcd";
+static const char hcd_name[] = "fotg210_hcd";
 
 #undef FOTG210_URB_TRACE
-
 #define FOTG210_STATS
 
 /* magic numbers that can affect system performance */
-#define	FOTG210_TUNE_CERR		3 /* 0-3 qtd retries; 0 == don't stop */
-#define	FOTG210_TUNE_RL_HS		4 /* nak throttle; see 4.9 */
-#define	FOTG210_TUNE_RL_TT		0
-#define	FOTG210_TUNE_MULT_HS	1	/* 1-3 transactions/uframe; 4.10.3 */
-#define	FOTG210_TUNE_MULT_TT	1
+#define FOTG210_TUNE_CERR	3 /* 0-3 qtd retries; 0 == don't stop */
+#define FOTG210_TUNE_RL_HS	4 /* nak throttle; see 4.9 */
+#define FOTG210_TUNE_RL_TT	0
+#define FOTG210_TUNE_MULT_HS	1 /* 1-3 transactions/uframe; 4.10.3 */
+#define FOTG210_TUNE_MULT_TT	1
+
 /*
- * Some drivers think it's safe to schedule isochronous transfers more than
- * 256 ms into the future (partly as a result of an old bug in the scheduling
+ * Some drivers think it's safe to schedule isochronous transfers more than 256
+ * ms into the future (partly as a result of an old bug in the scheduling
  * code).  In an attempt to avoid trouble, we will use a minimum scheduling
  * length of 512 frames instead of 256.
  */
-#define	FOTG210_TUNE_FLS		1 /* (medium) 512-frame schedule */
+#define FOTG210_TUNE_FLS 1 /* (medium) 512-frame schedule */
 
 /* Initial IRQ latency:  faster than hw default */
-static int log2_irq_thresh;		/* 0 to 6 */
+static int log2_irq_thresh; /* 0 to 6 */
 module_param(log2_irq_thresh, int, S_IRUGO);
 MODULE_PARM_DESC(log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
 
@@ -89,66 +87,57 @@ static unsigned int hird;
 module_param(hird, int, S_IRUGO);
 MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
 
-#define	INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
+#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
 
 #include "fotg210.h"
 
-/*-------------------------------------------------------------------------*/
-
 #define fotg210_dbg(fotg210, fmt, args...) \
-	dev_dbg(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_dbg(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 #define fotg210_err(fotg210, fmt, args...) \
-	dev_err(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_err(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 #define fotg210_info(fotg210, fmt, args...) \
-	dev_info(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_info(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 #define fotg210_warn(fotg210, fmt, args...) \
-	dev_warn(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_warn(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 
-/* check the values in the HCSPARAMS register
- * (host controller _Structural_ parameters)
- * see EHCI spec, Table 2-4 for each value
+/* check the values in the HCSPARAMS register (host controller _Structural_
+ * parameters) see EHCI spec, Table 2-4 for each value
  */
 static void dbg_hcs_params(struct fotg210_hcd *fotg210, char *label)
 {
-	u32	params = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
+	u32 params = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
 
-	fotg210_dbg(fotg210,
-		"%s hcs_params 0x%x ports=%d\n",
-		label, params,
-		HCS_N_PORTS(params)
-		);
+	fotg210_dbg(fotg210, "%s hcs_params 0x%x ports=%d\n", label, params,
+		    HCS_N_PORTS(params));
 }
 
-/* check the values in the HCCPARAMS register
- * (host controller _Capability_ parameters)
- * see EHCI Spec, Table 2-5 for each value
- * */
+/* check the values in the HCCPARAMS register (host controller _Capability_
+ * parameters) see EHCI Spec, Table 2-5 for each value
+ */
 static void dbg_hcc_params(struct fotg210_hcd *fotg210, char *label)
 {
-	u32	params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
+	u32 params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
 
-	fotg210_dbg(fotg210,
-		"%s hcc_params %04x uframes %s%s\n",
-		label,
-		params,
-		HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
-		HCC_CANPARK(params) ? " park" : "");
+	fotg210_dbg(fotg210, "%s hcc_params %04x uframes %s%s\n", label,
+		    params,
+		    HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
+		    HCC_CANPARK(params) ? " park" : "");
 }
 
 static void __maybe_unused
 dbg_qtd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd)
 {
 	fotg210_dbg(fotg210, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
-		hc32_to_cpup(fotg210, &qtd->hw_next),
-		hc32_to_cpup(fotg210, &qtd->hw_alt_next),
-		hc32_to_cpup(fotg210, &qtd->hw_token),
-		hc32_to_cpup(fotg210, &qtd->hw_buf[0]));
+		    hc32_to_cpup(fotg210, &qtd->hw_next),
+		    hc32_to_cpup(fotg210, &qtd->hw_alt_next),
+		    hc32_to_cpup(fotg210, &qtd->hw_token),
+		    hc32_to_cpup(fotg210, &qtd->hw_buf[0]));
 	if (qtd->hw_buf[1])
 		fotg210_dbg(fotg210, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
-			hc32_to_cpup(fotg210, &qtd->hw_buf[1]),
-			hc32_to_cpup(fotg210, &qtd->hw_buf[2]),
-			hc32_to_cpup(fotg210, &qtd->hw_buf[3]),
-			hc32_to_cpup(fotg210, &qtd->hw_buf[4]));
+			    hc32_to_cpup(fotg210, &qtd->hw_buf[1]),
+			    hc32_to_cpup(fotg210, &qtd->hw_buf[2]),
+			    hc32_to_cpup(fotg210, &qtd->hw_buf[3]),
+			    hc32_to_cpup(fotg210, &qtd->hw_buf[4]));
 }
 
 static void __maybe_unused
@@ -156,101 +145,99 @@ dbg_qh(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
 	struct fotg210_qh_hw *hw = qh->hw;
 
-	fotg210_dbg(fotg210, "%s qh %p n%08x info %x %x qtd %x\n", label,
-		qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
+	fotg210_dbg(fotg210, "%s qh %p n%08x info %x %x qtd %x\n", label, qh,
+		    hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
+
 	dbg_qtd("overlay", fotg210, (struct fotg210_qtd *) &hw->hw_qtd_next);
 }
 
 static void __maybe_unused
 dbg_itd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 {
-	fotg210_dbg(fotg210, "%s[%d] itd %p, next %08x, urb %p\n",
-		label, itd->frame, itd, hc32_to_cpu(fotg210, itd->hw_next),
-		itd->urb);
+	fotg210_dbg(fotg210, "%s[%d] itd %p, next %08x, urb %p\n", label,
+		    itd->frame, itd, hc32_to_cpu(fotg210, itd->hw_next),
+		    itd->urb);
+
 	fotg210_dbg(fotg210,
-		"  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
-		hc32_to_cpu(fotg210, itd->hw_transaction[0]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[1]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[2]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[3]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[4]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[5]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[6]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[7]));
+		    "  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
+		    hc32_to_cpu(fotg210, itd->hw_transaction[0]),
+		    hc32_to_cpu(fotg210, itd->hw_transaction[1]),
+		    hc32_to_cpu(fotg210, itd->hw_transaction[2]),
+		    hc32_to_cpu(fotg210, itd->hw_transaction[3]),
+		    hc32_to_cpu(fotg210, itd->hw_transaction[4]),
+		    hc32_to_cpu(fotg210, itd->hw_transaction[5]),
+		    hc32_to_cpu(fotg210, itd->hw_transaction[6]),
+		    hc32_to_cpu(fotg210, itd->hw_transaction[7]));
+
 	fotg210_dbg(fotg210,
-		"  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
-		hc32_to_cpu(fotg210, itd->hw_bufp[0]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[1]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[2]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[3]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[4]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[5]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[6]));
+		    "  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
+		    hc32_to_cpu(fotg210, itd->hw_bufp[0]),
+		    hc32_to_cpu(fotg210, itd->hw_bufp[1]),
+		    hc32_to_cpu(fotg210, itd->hw_bufp[2]),
+		    hc32_to_cpu(fotg210, itd->hw_bufp[3]),
+		    hc32_to_cpu(fotg210, itd->hw_bufp[4]),
+		    hc32_to_cpu(fotg210, itd->hw_bufp[5]),
+		    hc32_to_cpu(fotg210, itd->hw_bufp[6]));
+
 	fotg210_dbg(fotg210, "  index: %d %d %d %d %d %d %d %d\n",
-		itd->index[0], itd->index[1], itd->index[2],
-		itd->index[3], itd->index[4], itd->index[5],
-		itd->index[6], itd->index[7]);
+		    itd->index[0], itd->index[1], itd->index[2],
+		    itd->index[3], itd->index[4], itd->index[5],
+		    itd->index[6], itd->index[7]);
 }
 
 static int __maybe_unused
 dbg_status_buf(char *buf, unsigned len, const char *label, u32 status)
 {
-	return scnprintf(buf, len,
-		"%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
-		label, label[0] ? " " : "", status,
-		(status & STS_ASS) ? " Async" : "",
-		(status & STS_PSS) ? " Periodic" : "",
-		(status & STS_RECL) ? " Recl" : "",
-		(status & STS_HALT) ? " Halt" : "",
-		(status & STS_IAA) ? " IAA" : "",
-		(status & STS_FATAL) ? " FATAL" : "",
-		(status & STS_FLR) ? " FLR" : "",
-		(status & STS_PCD) ? " PCD" : "",
-		(status & STS_ERR) ? " ERR" : "",
-		(status & STS_INT) ? " INT" : ""
-		);
+	return scnprintf(buf, len, "%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
+			 label, label[0] ? " " : "", status,
+			 (status & STS_ASS) ? " Async" : "",
+			 (status & STS_PSS) ? " Periodic" : "",
+			 (status & STS_RECL) ? " Recl" : "",
+			 (status & STS_HALT) ? " Halt" : "",
+			 (status & STS_IAA) ? " IAA" : "",
+			 (status & STS_FATAL) ? " FATAL" : "",
+			 (status & STS_FLR) ? " FLR" : "",
+			 (status & STS_PCD) ? " PCD" : "",
+			 (status & STS_ERR) ? " ERR" : "",
+			 (status & STS_INT) ? " INT" : "");
 }
 
 static int __maybe_unused
 dbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable)
 {
-	return scnprintf(buf, len,
-		"%s%sintrenable %02x%s%s%s%s%s%s",
-		label, label[0] ? " " : "", enable,
-		(enable & STS_IAA) ? " IAA" : "",
-		(enable & STS_FATAL) ? " FATAL" : "",
-		(enable & STS_FLR) ? " FLR" : "",
-		(enable & STS_PCD) ? " PCD" : "",
-		(enable & STS_ERR) ? " ERR" : "",
-		(enable & STS_INT) ? " INT" : ""
-		);
+	return scnprintf(buf, len, "%s%sintrenable %02x%s%s%s%s%s%s",
+			 label, label[0] ? " " : "", enable,
+			 (enable & STS_IAA) ? " IAA" : "",
+			 (enable & STS_FATAL) ? " FATAL" : "",
+			 (enable & STS_FLR) ? " FLR" : "",
+			 (enable & STS_PCD) ? " PCD" : "",
+			 (enable & STS_ERR) ? " ERR" : "",
+			 (enable & STS_INT) ? " INT" : "");
 }
 
 static const char *const fls_strings[] = { "1024", "512", "256", "??" };
 
-static int
-dbg_command_buf(char *buf, unsigned len, const char *label, u32 command)
+static int dbg_command_buf(char *buf, unsigned len, const char *label,
+			   u32 command)
 {
 	return scnprintf(buf, len,
-		"%s%scommand %07x %s=%d ithresh=%d%s%s%s "
-		"period=%s%s %s",
-		label, label[0] ? " " : "", command,
-		(command & CMD_PARK) ? " park" : "(park)",
-		CMD_PARK_CNT(command),
-		(command >> 16) & 0x3f,
-		(command & CMD_IAAD) ? " IAAD" : "",
-		(command & CMD_ASE) ? " Async" : "",
-		(command & CMD_PSE) ? " Periodic" : "",
-		fls_strings[(command >> 2) & 0x3],
-		(command & CMD_RESET) ? " Reset" : "",
-		(command & CMD_RUN) ? "RUN" : "HALT"
-		);
-}
-
-static char
-*dbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status)
-{
-	char	*sig;
+			 "%s%scommand %07x %s=%d ithresh=%d%s%s%s period=%s%s %s",
+			 label, label[0] ? " " : "", command,
+			 (command & CMD_PARK) ? " park" : "(park)",
+			 CMD_PARK_CNT(command),
+			 (command >> 16) & 0x3f,
+			 (command & CMD_IAAD) ? " IAAD" : "",
+			 (command & CMD_ASE) ? " Async" : "",
+			 (command & CMD_PSE) ? " Periodic" : "",
+			 fls_strings[(command >> 2) & 0x3],
+			 (command & CMD_RESET) ? " Reset" : "",
+			 (command & CMD_RUN) ? "RUN" : "HALT");
+}
+
+static char *dbg_port_buf(char *buf, unsigned len, const char *label, int port,
+			  u32 status)
+{
+	char *sig;
 
 	/* signaling state */
 	switch (status & (3 << 10)) {
@@ -268,44 +255,41 @@ static char
 		break;
 	}
 
-	scnprintf(buf, len,
-		"%s%sport:%d status %06x %d "
-		"sig=%s%s%s%s%s%s%s%s",
-		label, label[0] ? " " : "", port, status,
-		status>>25,/*device address */
-		sig,
-		(status & PORT_RESET) ? " RESET" : "",
-		(status & PORT_SUSPEND) ? " SUSPEND" : "",
-		(status & PORT_RESUME) ? " RESUME" : "",
-		(status & PORT_PEC) ? " PEC" : "",
-		(status & PORT_PE) ? " PE" : "",
-		(status & PORT_CSC) ? " CSC" : "",
-		(status & PORT_CONNECT) ? " CONNECT" : "");
+	scnprintf(buf, len, "%s%sport:%d status %06x %d sig=%s%s%s%s%s%s%s%s",
+		  label, label[0] ? " " : "", port, status,
+		  status >> 25, /*device address */
+		  sig,
+		  (status & PORT_RESET) ? " RESET" : "",
+		  (status & PORT_SUSPEND) ? " SUSPEND" : "",
+		  (status & PORT_RESUME) ? " RESUME" : "",
+		  (status & PORT_PEC) ? " PEC" : "",
+		  (status & PORT_PE) ? " PE" : "",
+		  (status & PORT_CSC) ? " CSC" : "",
+		  (status & PORT_CONNECT) ? " CONNECT" : "");
+
 	return buf;
 }
 
 /* functions have the "wrong" filename when they're output... */
-#define dbg_status(fotg210, label, status) { \
-	char _buf[80]; \
-	dbg_status_buf(_buf, sizeof(_buf), label, status); \
-	fotg210_dbg(fotg210, "%s\n", _buf); \
+#define dbg_status(fotg210, label, status) {			\
+	char _buf[80];						\
+	dbg_status_buf(_buf, sizeof(_buf), label, status);	\
+	fotg210_dbg(fotg210, "%s\n", _buf);			\
 }
 
-#define dbg_cmd(fotg210, label, command) { \
-	char _buf[80]; \
-	dbg_command_buf(_buf, sizeof(_buf), label, command); \
-	fotg210_dbg(fotg210, "%s\n", _buf); \
+#define dbg_cmd(fotg210, label, command) {			\
+	char _buf[80];						\
+	dbg_command_buf(_buf, sizeof(_buf), label, command);	\
+	fotg210_dbg(fotg210, "%s\n", _buf);			\
 }
 
-#define dbg_port(fotg210, label, port, status) { \
-	char _buf[80]; \
-	fotg210_dbg(fotg210, "%s\n", dbg_port_buf(_buf, sizeof(_buf), label, port, status) ); \
+#define dbg_port(fotg210, label, port, status) {			    \
+	char _buf[80];							    \
+	fotg210_dbg(fotg210, "%s\n",					    \
+		    dbg_port_buf(_buf, sizeof(_buf), label, port, status)); \
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* troubleshooting help: expose state in debugfs */
-
 static int debug_async_open(struct inode *, struct file *);
 static int debug_periodic_open(struct inode *, struct file *);
 static int debug_registers_open(struct inode *, struct file *);
@@ -373,33 +357,29 @@ static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
 	return '/';
 }
 
-static void qh_lines(
-	struct fotg210_hcd *fotg210,
-	struct fotg210_qh *qh,
-	char **nextp,
-	unsigned *sizep
-)
-{
-	u32			scratch;
-	u32			hw_curr;
-	struct fotg210_qtd	*td;
-	unsigned		temp;
-	unsigned		size = *sizep;
-	char			*next = *nextp;
-	char			mark;
-	__le32			list_end = FOTG210_LIST_END(fotg210);
-	struct fotg210_qh_hw	*hw = qh->hw;
-
-	if (hw->hw_qtd_next == list_end)	/* NEC does this */
+static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
+		     char **nextp, unsigned *sizep)
+{
+	u32 scratch;
+	u32 hw_curr;
+	struct fotg210_qtd *td;
+	unsigned temp;
+	unsigned size = *sizep;
+	char *next = *nextp;
+	char mark;
+	__le32 list_end = FOTG210_LIST_END(fotg210);
+	struct fotg210_qh_hw *hw = qh->hw;
+
+	if (hw->hw_qtd_next == list_end) /* NEC does this */
 		mark = '@';
 	else
 		mark = token_mark(fotg210, hw->hw_token);
-	if (mark == '/') {	/* qh_alt_next controls qh advance? */
-		if ((hw->hw_alt_next & QTD_MASK(fotg210))
-				== fotg210->async->hw->hw_alt_next)
-			mark = '#';	/* blocked */
+	if (mark == '/') { /* qh_alt_next controls qh advance? */
+		if ((hw->hw_alt_next & QTD_MASK(fotg210)) ==
+		    fotg210->async->hw->hw_alt_next)
+			mark = '#'; /* blocked */
 		else if (hw->hw_alt_next == list_end)
-			mark = '.';	/* use hw_qtd_next */
+			mark = '.'; /* use hw_qtd_next */
 		/* else alt_next points to some other qtd */
 	}
 	scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
@@ -462,6 +442,7 @@ static void qh_lines(
 	temp = snprintf(next, size, "\n");
 	if (size < temp)
 		temp = size;
+
 	size -= temp;
 	next += temp;
 
@@ -472,12 +453,12 @@ done:
 
 static ssize_t fill_async_buffer(struct debug_buffer *buf)
 {
-	struct usb_hcd		*hcd;
-	struct fotg210_hcd	*fotg210;
-	unsigned long		flags;
-	unsigned		temp, size;
-	char			*next;
-	struct fotg210_qh		*qh;
+	struct usb_hcd *hcd;
+	struct fotg210_hcd *fotg210;
+	unsigned long flags;
+	unsigned temp, size;
+	char *next;
+	struct fotg210_qh *qh;
 
 	hcd = bus_to_hcd(buf->bus);
 	fotg210 = hcd_to_fotg210(hcd);
@@ -511,18 +492,19 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
 #define DBG_SCHED_LIMIT 64
 static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 {
-	struct usb_hcd		*hcd;
-	struct fotg210_hcd		*fotg210;
-	unsigned long		flags;
-	union fotg210_shadow	p, *seen;
-	unsigned		temp, size, seen_count;
-	char			*next;
-	unsigned		i;
-	__hc32			tag;
+	struct usb_hcd *hcd;
+	struct fotg210_hcd *fotg210;
+	unsigned long flags;
+	union fotg210_shadow p, *seen;
+	unsigned temp, size, seen_count;
+	char *next;
+	unsigned i;
+	__hc32 tag;
 
 	seen = kmalloc(DBG_SCHED_LIMIT * sizeof(*seen), GFP_ATOMIC);
 	if (!seen)
 		return 0;
+
 	seen_count = 0;
 
 	hcd = bus_to_hcd(buf->bus);
@@ -542,6 +524,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 		p = fotg210->pshadow[i];
 		if (likely(!p.ptr))
 			continue;
+
 		tag = Q_NEXT_TYPE(fotg210, fotg210->periodic[i]);
 
 		temp = scnprintf(next, size, "%4d: ", i);
@@ -577,10 +560,10 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 				}
 				/* show more info the first time around */
 				if (temp == seen_count) {
-					u32	scratch = hc32_to_cpup(fotg210,
-							&hw->hw_info1);
-					struct fotg210_qtd	*qtd;
-					char		*type = "";
+					u32 scratch = hc32_to_cpup(fotg210,
+								&hw->hw_info1);
+					struct fotg210_qtd *qtd;
+					char *type = "";
 
 					/* count tds, get ep direction */
 					temp = 0;
@@ -601,8 +584,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 					}
 
 					temp = scnprintf(next, size,
-						"(%c%d ep%d%s "
-						"[%d/%d] q%d p%d)",
+						"(%c%d ep%d%s [%d/%d] q%d p%d)",
 						speed_char(scratch),
 						scratch & 0x007f,
 						(scratch >> 8) & 0x000f, type,
@@ -663,13 +645,13 @@ static const char *rh_state_string(struct fotg210_hcd *fotg210)
 
 static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 {
-	struct usb_hcd		*hcd;
-	struct fotg210_hcd	*fotg210;
-	unsigned long		flags;
-	unsigned		temp, size, i;
-	char			*next, scratch[80];
-	static const char	fmt[] = "%*s\n";
-	static const char	label[] = "";
+	struct usb_hcd *hcd;
+	struct fotg210_hcd *fotg210;
+	unsigned long flags;
+	unsigned temp, size, i;
+	char *next, scratch[80];
+	static const char fmt[] = "%*s\n";
+	static const char label[] = "";
 
 	hcd = bus_to_hcd(buf->bus);
 	fotg210 = hcd_to_fotg210(hcd);
@@ -765,8 +747,8 @@ done:
 	return buf->alloc_size - size;
 }
 
-static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
-				ssize_t (*fill_func)(struct debug_buffer *))
+static struct debug_buffer
+*alloc_buffer(struct usb_bus *bus, ssize_t (*fill_func)(struct debug_buffer *))
 {
 	struct debug_buffer *buf;
 
@@ -850,6 +832,7 @@ static int debug_async_open(struct inode *inode, struct file *file)
 static int debug_periodic_open(struct inode *inode, struct file *file)
 {
 	struct debug_buffer *buf;
+
 	buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
 	if (!buf)
 		return -ENOMEM;
@@ -899,8 +882,6 @@ static inline void remove_debug_files(struct fotg210_hcd *fotg210)
 	debugfs_remove_recursive(fotg210->debug_dir);
 }
 
-/*-------------------------------------------------------------------------*/
-
 /*
  * handshake - spin reading hc until handshake completes or fails
  * @ptr: address of hc register to be read
@@ -919,9 +900,9 @@ static inline void remove_debug_files(struct fotg210_hcd *fotg210)
  * bridge shutdown:  shutting down the bridge before the devices using it.
  */
 static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
-		      u32 mask, u32 done, int usec)
+		     u32 mask, u32 done, int usec)
 {
-	u32	result;
+	u32 result;
 
 	do {
 		result = fotg210_readl(fotg210, ptr);
@@ -942,7 +923,7 @@ static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
  */
 static int fotg210_halt(struct fotg210_hcd *fotg210)
 {
-	u32	temp;
+	u32 temp;
 
 	spin_lock_irq(&fotg210->lock);
 
@@ -971,11 +952,12 @@ static int fotg210_halt(struct fotg210_hcd *fotg210)
  */
 static int fotg210_reset(struct fotg210_hcd *fotg210)
 {
-	int	retval;
-	u32	command = fotg210_readl(fotg210, &fotg210->regs->command);
+	int retval;
+	u32 command = fotg210_readl(fotg210, &fotg210->regs->command);
 
 	/* If the EHCI debug controller is active, special care must be
-	 * taken before and after a host controller reset */
+	 * taken before and after a host controller reset
+	 */
 	if (fotg210->debug && !dbgp_reset_prep(fotg210_to_hcd(fotg210)))
 		fotg210->debug = NULL;
 
@@ -1004,7 +986,7 @@ static int fotg210_reset(struct fotg210_hcd *fotg210)
  */
 static void fotg210_quiesce(struct fotg210_hcd *fotg210)
 {
-	u32	temp;
+	u32 temp;
 
 	if (fotg210->rh_state != FOTG210_RH_RUNNING)
 		return;
@@ -1025,8 +1007,6 @@ static void fotg210_quiesce(struct fotg210_hcd *fotg210)
 		  16 * 125);
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void end_unlink_async(struct fotg210_hcd *fotg210);
 static void unlink_empty_async(struct fotg210_hcd *fotg210);
 static void fotg210_work(struct fotg210_hcd *fotg210);
@@ -1034,8 +1014,6 @@ static void start_unlink_intr(struct fotg210_hcd *fotg210,
 			      struct fotg210_qh *qh);
 static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
 
-/*-------------------------------------------------------------------------*/
-
 /* Set a bit in the USBCMD register */
 static void fotg210_set_command_bit(struct fotg210_hcd *fotg210, u32 bit)
 {
@@ -1056,8 +1034,6 @@ static void fotg210_clear_command_bit(struct fotg210_hcd *fotg210, u32 bit)
 	fotg210_readl(fotg210, &fotg210->regs->command);
 }
 
-/*-------------------------------------------------------------------------*/
-
 /*
  * EHCI timer support...  Now using hrtimers.
  *
@@ -1101,9 +1077,9 @@ static unsigned event_delays_ns[] = {
 
 /* Enable a pending hrtimer event */
 static void fotg210_enable_event(struct fotg210_hcd *fotg210, unsigned event,
-		bool resched)
+				 bool resched)
 {
-	ktime_t		*timeout = &fotg210->hr_timeouts[event];
+	ktime_t *timeout = &fotg210->hr_timeouts[event];
 
 	if (resched)
 		*timeout = ktime_add(ktime_get(),
@@ -1122,7 +1098,7 @@ static void fotg210_enable_event(struct fotg210_hcd *fotg210, unsigned event,
 /* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */
 static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
 {
-	unsigned	actual, want;
+	unsigned actual, want;
 
 	/* Don't enable anything if the controller isn't running (e.g., died) */
 	if (fotg210->rh_state != FOTG210_RH_RUNNING)
@@ -1170,7 +1146,7 @@ static void fotg210_disable_ASE(struct fotg210_hcd *fotg210)
 /* Poll the STS_PSS status bit; see when it agrees with CMD_PSE */
 static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
 {
-	unsigned	actual, want;
+	unsigned actual, want;
 
 	/* Don't do anything if the controller isn't running (e.g., died) */
 	if (fotg210->rh_state != FOTG210_RH_RUNNING)
@@ -1243,7 +1219,7 @@ static void fotg210_handle_controller_death(struct fotg210_hcd *fotg210)
 /* Handle unlinked interrupt QHs once they are gone from the hardware */
 static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
 {
-	bool		stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
+	bool stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
 
 	/*
 	 * Process all the QHs on the intr_unlink list that were added
@@ -1254,7 +1230,7 @@ static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
 	 */
 	fotg210->intr_unlinking = true;
 	while (fotg210->intr_unlink) {
-		struct fotg210_qh	*qh = fotg210->intr_unlink;
+		struct fotg210_qh *qh = fotg210->intr_unlink;
 
 		if (!stopped && qh->unlink_cycle == fotg210->intr_unlink_cycle)
 			break;
@@ -1288,7 +1264,7 @@ static void start_free_itds(struct fotg210_hcd *fotg210)
 /* Wait for controller to stop using old iTDs and siTDs */
 static void end_free_itds(struct fotg210_hcd *fotg210)
 {
-	struct fotg210_itd		*itd, *n;
+	struct fotg210_itd *itd, *n;
 
 	if (fotg210->rh_state < FOTG210_RH_RUNNING)
 		fotg210->last_itd_to_free = NULL;
@@ -1391,10 +1367,10 @@ static enum hrtimer_restart fotg210_hrtimer_func(struct hrtimer *t)
 {
 	struct fotg210_hcd *fotg210 =
 			container_of(t, struct fotg210_hcd, hrtimer);
-	ktime_t		now;
-	unsigned long	events;
-	unsigned long	flags;
-	unsigned	e;
+	ktime_t now;
+	unsigned long events;
+	unsigned long flags;
+	unsigned e;
 
 	spin_lock_irqsave(&fotg210->lock, flags);
 
@@ -1418,19 +1394,12 @@ static enum hrtimer_restart fotg210_hrtimer_func(struct hrtimer *t)
 	return HRTIMER_NORESTART;
 }
 
-/*-------------------------------------------------------------------------*/
-
-#define fotg210_bus_suspend	NULL
-#define fotg210_bus_resume	NULL
+#define fotg210_bus_suspend NULL
+#define fotg210_bus_resume NULL
 
-/*-------------------------------------------------------------------------*/
-
-static int check_reset_complete(
-	struct fotg210_hcd	*fotg210,
-	int		index,
-	u32 __iomem	*status_reg,
-	int		port_status
-) {
+static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
+				u32 __iomem *status_reg, int port_status)
+{
 	if (!(port_status & PORT_CONNECT))
 		return port_status;
 
@@ -1449,19 +1418,16 @@ static int check_reset_complete(
 	return port_status;
 }
 
-/*-------------------------------------------------------------------------*/
-
 
 /* build "status change" packet (one or two bytes) from HC registers */
 
-static int
-fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
+static int fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
-	struct fotg210_hcd	*fotg210 = hcd_to_fotg210(hcd);
-	u32		temp, status;
-	u32		mask;
-	int		retval = 1;
-	unsigned long	flags;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 temp, status;
+	u32 mask;
+	int retval = 1;
+	unsigned long flags;
 
 	/* init status to no-changes */
 	buf[0] = 0;
@@ -1499,15 +1465,11 @@ fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
 	return status ? retval : 0;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static void
-fotg210_hub_descriptor(
-	struct fotg210_hcd		*fotg210,
-	struct usb_hub_descriptor	*desc
-) {
-	int		ports = HCS_N_PORTS(fotg210->hcs_params);
-	u16		temp;
+static void fotg210_hub_descriptor(struct fotg210_hcd *fotg210,
+				   struct usb_hub_descriptor *desc)
+{
+	int ports = HCS_N_PORTS(fotg210->hcs_params);
+	u16 temp;
 
 	desc->bDescriptorType = USB_DT_HUB;
 	desc->bPwrOn2PwrGood = 10;	/* fotg210 1.0, 2.3.9 says 20ms max */
@@ -1526,23 +1488,16 @@ fotg210_hub_descriptor(
 	desc->wHubCharacteristics = cpu_to_le16(temp);
 }
 
-/*-------------------------------------------------------------------------*/
-
-static int fotg210_hub_control(
-	struct usb_hcd	*hcd,
-	u16		typeReq,
-	u16		wValue,
-	u16		wIndex,
-	char		*buf,
-	u16		wLength
-) {
-	struct fotg210_hcd	*fotg210 = hcd_to_fotg210(hcd);
-	int		ports = HCS_N_PORTS(fotg210->hcs_params);
-	u32 __iomem	*status_reg = &fotg210->regs->port_status;
-	u32		temp, temp1, status;
-	unsigned long	flags;
-	int		retval = 0;
-	unsigned	selector;
+static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+			       u16 wIndex, char *buf, u16 wLength)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	int ports = HCS_N_PORTS(fotg210->hcs_params);
+	u32 __iomem *status_reg = &fotg210->regs->port_status;
+	u32 temp, temp1, status;
+	unsigned long flags;
+	int retval = 0;
+	unsigned selector;
 
 	/*
 	 * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
@@ -1862,11 +1817,11 @@ static void __maybe_unused fotg210_relinquish_port(struct usb_hcd *hcd,
 }
 
 static int __maybe_unused fotg210_port_handed_over(struct usb_hcd *hcd,
-		int portnum)
+						   int portnum)
 {
 	return 0;
 }
-/*-------------------------------------------------------------------------*/
+
 /*
  * There's basically three types of memory:
  *	- data used only by the HCD ... kmalloc is fine
@@ -1878,10 +1833,7 @@ static int __maybe_unused fotg210_port_handed_over(struct usb_hcd *hcd,
  * No memory seen by this driver is pageable.
  */
 
-/*-------------------------------------------------------------------------*/
-
 /* Allocate the key transfer structures from the previously allocated pool */
-
 static inline void fotg210_qtd_init(struct fotg210_hcd *fotg210,
 				    struct fotg210_qtd *qtd, dma_addr_t dma)
 {
@@ -1896,8 +1848,8 @@ static inline void fotg210_qtd_init(struct fotg210_hcd *fotg210,
 static struct fotg210_qtd *fotg210_qtd_alloc(struct fotg210_hcd *fotg210,
 					     gfp_t flags)
 {
-	struct fotg210_qtd		*qtd;
-	dma_addr_t		dma;
+	struct fotg210_qtd *qtd;
+	dma_addr_t dma;
 
 	qtd = dma_pool_alloc(fotg210->qtd_pool, flags, &dma);
 	if (qtd != NULL)
@@ -1929,8 +1881,8 @@ static void qh_destroy(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 static struct fotg210_qh *fotg210_qh_alloc(struct fotg210_hcd *fotg210,
 					   gfp_t flags)
 {
-	struct fotg210_qh		*qh;
-	dma_addr_t		dma;
+	struct fotg210_qh *qh;
+	dma_addr_t dma;
 
 	qh = kzalloc(sizeof(*qh), GFP_ATOMIC);
 	if (!qh)
@@ -1958,8 +1910,6 @@ fail:
 	return NULL;
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* The queue heads and transfer descriptors are managed from pools tied
  * to each of the "per device" structures.
  * This is the initialisation and cleanup code.
@@ -2058,7 +2008,6 @@ fail:
 	fotg210_mem_cleanup(fotg210);
 	return -ENOMEM;
 }
-/*-------------------------------------------------------------------------*/
 /*
  * EHCI hardware queue manipulation ... the core.  QH/QTD manipulation.
  *
@@ -2077,16 +2026,12 @@ fail:
  * buffer low/full speed data so the host collects it at high speed.
  */
 
-/*-------------------------------------------------------------------------*/
-
 /* fill a qtd, returning how much of the buffer we were able to queue up */
-
-static int
-qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd, dma_addr_t buf,
-		  size_t len, int token, int maxpacket)
+static int qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd,
+		    dma_addr_t buf, size_t len, int token, int maxpacket)
 {
-	int	i, count;
-	u64	addr = buf;
+	int i, count;
+	u64 addr = buf;
 
 	/* one buffer entry per 4K ... first might be short or unaligned */
 	qtd->hw_buf[0] = cpu_to_hc32(fotg210, (u32)addr);
@@ -2121,11 +2066,9 @@ qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd, dma_addr_t buf,
 	return count;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static inline void
-qh_update(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
-	  struct fotg210_qtd *qtd)
+static inline void qh_update(struct fotg210_hcd *fotg210,
+			     struct fotg210_qh *qh,
+			     struct fotg210_qtd *qtd)
 {
 	struct fotg210_qh_hw *hw = qh->hw;
 
@@ -2141,7 +2084,7 @@ qh_update(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
 	 * ever clear it.
 	 */
 	if (!(hw->hw_info1 & cpu_to_hc32(fotg210, QH_TOGGLE_CTL))) {
-		unsigned	is_out, epnum;
+		unsigned is_out, epnum;
 
 		is_out = qh->is_out;
 		epnum = (hc32_to_cpup(fotg210, &hw->hw_info1) >> 8) & 0x0f;
@@ -2158,8 +2101,7 @@ qh_update(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
  * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault
  * recovery (including urb dequeue) would need software changes to a QH...
  */
-static void
-qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+static void qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
 	struct fotg210_qtd *qtd;
 
@@ -2185,16 +2127,14 @@ qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		qh_update(fotg210, qh, qtd);
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
 
 static void fotg210_clear_tt_buffer_complete(struct usb_hcd *hcd,
-		struct usb_host_endpoint *ep)
+					     struct usb_host_endpoint *ep)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh		*qh = ep->hcpriv;
-	unsigned long		flags;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_qh *qh = ep->hcpriv;
+	unsigned long flags;
 
 	spin_lock_irqsave(&fotg210->lock, flags);
 	qh->clearing_tt = 0;
@@ -2217,6 +2157,7 @@ static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
 	 */
 	if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
 		struct usb_device *tt = urb->dev->tt->hub;
+
 		dev_dbg(&tt->dev,
 			"clear tt buffer port %d, a%d ep%d t%08x\n",
 			urb->dev->ttport, urb->dev->devnum,
@@ -2230,14 +2171,10 @@ static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
 	}
 }
 
-static int qtd_copy_status(
-	struct fotg210_hcd *fotg210,
-	struct urb *urb,
-	size_t length,
-	u32 token
-)
+static int qtd_copy_status(struct fotg210_hcd *fotg210, struct urb *urb,
+			   size_t length, u32 token)
 {
-	int	status = -EINPROGRESS;
+	int status = -EINPROGRESS;
 
 	/* count IN/OUT bytes, not SETUP (even short packets) */
 	if (likely(QTD_PID(token) != 2))
@@ -2293,13 +2230,13 @@ static int qtd_copy_status(
 	return status;
 }
 
-static void
-fotg210_urb_done(struct fotg210_hcd *fotg210, struct urb *urb, int status)
+static void fotg210_urb_done(struct fotg210_hcd *fotg210, struct urb *urb,
+			     int status)
 __releases(fotg210->lock)
 __acquires(fotg210->lock)
 {
 	if (likely(urb->hcpriv != NULL)) {
-		struct fotg210_qh	*qh = (struct fotg210_qh *) urb->hcpriv;
+		struct fotg210_qh *qh = (struct fotg210_qh *) urb->hcpriv;
 
 		/* S-mask in a QH means it's an interrupt urb */
 		if ((qh->hw->hw_info2 & cpu_to_hc32(fotg210, QH_SMASK)) != 0) {
@@ -2342,16 +2279,16 @@ static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
  * Chases up to qh->hw_current.  Returns number of completions called,
  * indicating how much "real" work we did.
  */
-static unsigned
-qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+static unsigned qh_completions(struct fotg210_hcd *fotg210,
+			       struct fotg210_qh *qh)
 {
-	struct fotg210_qtd		*last, *end = qh->dummy;
-	struct list_head	*entry, *tmp;
-	int			last_status;
-	int			stopped;
-	unsigned		count = 0;
-	u8			state;
-	struct fotg210_qh_hw	*hw = qh->hw;
+	struct fotg210_qtd *last, *end = qh->dummy;
+	struct list_head *entry, *tmp;
+	int last_status;
+	int stopped;
+	unsigned count = 0;
+	u8 state;
+	struct fotg210_qh_hw *hw = qh->hw;
 
 	if (unlikely(list_empty(&qh->qtd_list)))
 		return count;
@@ -2370,7 +2307,7 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	qh->qh_state = QH_STATE_COMPLETING;
 	stopped = (state == QH_STATE_IDLE);
 
- rescan:
+rescan:
 	last = NULL;
 	last_status = -EINPROGRESS;
 	qh->needs_rescan = 0;
@@ -2381,9 +2318,9 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	 * if queue is stopped, handles unlinks.
 	 */
 	list_for_each_safe(entry, tmp, &qh->qtd_list) {
-		struct fotg210_qtd	*qtd;
-		struct urb	*urb;
-		u32		token = 0;
+		struct fotg210_qtd *qtd;
+		struct urb *urb;
+		u32 token = 0;
 
 		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
 		urb = qtd->urb;
@@ -2409,7 +2346,7 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		token = hc32_to_cpu(fotg210, qtd->hw_token);
 
 		/* always clean up qtds the hc de-activated */
- retry_xacterr:
+retry_xacterr:
 		if ((token & QTD_STS_ACTIVE) == 0) {
 
 			/* Report Data Buffer Error: non-fatal but useful */
@@ -2615,8 +2552,6 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	return count;
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
 #define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
 /* ... and packet size, for any kind of endpoint descriptor */
@@ -2626,15 +2561,13 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
  * reverse of qh_urb_transaction:  free a list of TDs.
  * used for cleanup after errors, before HC sees an URB's TDs.
  */
-static void qtd_list_free(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list
-) {
-	struct list_head	*entry, *temp;
+static void qtd_list_free(struct fotg210_hcd *fotg210, struct urb *urb,
+			  struct list_head *qtd_list)
+{
+	struct list_head *entry, *temp;
 
 	list_for_each_safe(entry, temp, qtd_list) {
-		struct fotg210_qtd	*qtd;
+		struct fotg210_qtd *qtd;
 
 		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
 		list_del(&qtd->qtd_list);
@@ -2645,20 +2578,18 @@ static void qtd_list_free(
 /*
  * create a list of filled qtds for this URB; won't link into qh.
  */
-static struct list_head *
-qh_urb_transaction(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*head,
-	gfp_t			flags
-) {
-	struct fotg210_qtd		*qtd, *qtd_prev;
-	dma_addr_t		buf;
-	int			len, this_sg_len, maxpacket;
-	int			is_input;
-	u32			token;
-	int			i;
-	struct scatterlist	*sg;
+static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
+					    struct urb *urb,
+					    struct list_head *head,
+					    gfp_t flags)
+{
+	struct fotg210_qtd *qtd, *qtd_prev;
+	dma_addr_t buf;
+	int len, this_sg_len, maxpacket;
+	int is_input;
+	u32 token;
+	int i;
+	struct scatterlist *sg;
 
 	/*
 	 * URBs map to sequences of QTDs:  one logical transaction
@@ -2778,7 +2709,7 @@ qh_urb_transaction(
 	 * (zero length).
 	 */
 	if (likely(urb->transfer_buffer_length != 0)) {
-		int	one_more = 0;
+		int one_more = 0;
 
 		if (usb_pipecontrol(urb->pipe)) {
 			one_more = 1;
@@ -2813,7 +2744,6 @@ cleanup:
 	return NULL;
 }
 
-/*-------------------------------------------------------------------------*/
 /*
  * Would be best to create all qh's from config descriptors,
  * when each interface/altsetting is established.  Unlink
@@ -2831,18 +2761,15 @@ cleanup:
  * just one microframe in the s-mask.  For split interrupt transactions
  * there are additional complications: c-mask, maybe FSTNs.
  */
-static struct fotg210_qh *
-qh_make(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	gfp_t			flags
-) {
-	struct fotg210_qh		*qh = fotg210_qh_alloc(fotg210, flags);
-	u32			info1 = 0, info2 = 0;
-	int			is_input, type;
-	int			maxp = 0;
-	struct usb_tt		*tt = urb->dev->tt;
-	struct fotg210_qh_hw	*hw;
+static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
+				  gfp_t flags)
+{
+	struct fotg210_qh *qh = fotg210_qh_alloc(fotg210, flags);
+	u32 info1 = 0, info2 = 0;
+	int is_input, type;
+	int maxp = 0;
+	struct usb_tt *tt = urb->dev->tt;
+	struct fotg210_qh_hw *hw;
 
 	if (!qh)
 		return qh;
@@ -2896,7 +2823,7 @@ qh_make(
 				urb->interval = qh->period << 3;
 			}
 		} else {
-			int		think_time;
+			int think_time;
 
 			/* gap is f(FS/LS transfer times) */
 			qh->gap_uf = 1 + usb_calc_bus_time(urb->dev->speed,
@@ -3005,8 +2932,6 @@ done:
 	return qh;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void enable_async(struct fotg210_hcd *fotg210)
 {
 	if (fotg210->async_count++)
@@ -3036,8 +2961,8 @@ static void disable_async(struct fotg210_hcd *fotg210)
 
 static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
-	__hc32		dma = QH_NEXT(fotg210, qh->qh_dma);
-	struct fotg210_qh	*head;
+	__hc32 dma = QH_NEXT(fotg210, qh->qh_dma);
+	struct fotg210_qh *head;
 
 	/* Don't link a QH if there's a Clear-TT-Buffer pending */
 	if (unlikely(qh->clearing_tt))
@@ -3064,24 +2989,19 @@ static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	enable_async(fotg210);
 }
 
-/*-------------------------------------------------------------------------*/
-
 /*
  * For control/bulk/interrupt, return QH with these TDs appended.
  * Allocates and initializes the QH if necessary.
  * Returns null if it can't allocate a QH it needs to.
  * If the QH has TDs (urbs) already, that's great.
  */
-static struct fotg210_qh *qh_append_tds(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	int			epnum,
-	void			**ptr
-)
+static struct fotg210_qh *qh_append_tds(struct fotg210_hcd *fotg210,
+					struct urb *urb,
+					struct list_head *qtd_list, int epnum,
+					void **ptr)
 {
-	struct fotg210_qh		*qh = NULL;
-	__hc32			qh_addr_mask = cpu_to_hc32(fotg210, 0x7f);
+	struct fotg210_qh *qh = NULL;
+	__hc32 qh_addr_mask = cpu_to_hc32(fotg210, 0x7f);
 
 	qh = (struct fotg210_qh *) *ptr;
 	if (unlikely(qh == NULL)) {
@@ -3090,7 +3010,7 @@ static struct fotg210_qh *qh_append_tds(
 		*ptr = qh;
 	}
 	if (likely(qh != NULL)) {
-		struct fotg210_qtd	*qtd;
+		struct fotg210_qtd *qtd;
 
 		if (unlikely(list_empty(qtd_list)))
 			qtd = NULL;
@@ -3109,9 +3029,9 @@ static struct fotg210_qh *qh_append_tds(
 		 * only hc or qh_refresh() ever modify the overlay.
 		 */
 		if (likely(qtd != NULL)) {
-			struct fotg210_qtd		*dummy;
-			dma_addr_t		dma;
-			__hc32			token;
+			struct fotg210_qtd *dummy;
+			dma_addr_t dma;
+			__hc32 token;
 
 			/* to avoid racing the HC, use the dummy td instead of
 			 * the first td of our list (becomes new dummy).  both
@@ -3150,25 +3070,20 @@ static struct fotg210_qh *qh_append_tds(
 	return qh;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static int
-submit_async(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	gfp_t			mem_flags
-) {
-	int			epnum;
-	unsigned long		flags;
-	struct fotg210_qh		*qh = NULL;
-	int			rc;
+static int submit_async(struct fotg210_hcd *fotg210, struct urb *urb,
+			struct list_head *qtd_list, gfp_t mem_flags)
+{
+	int epnum;
+	unsigned long flags;
+	struct fotg210_qh *qh = NULL;
+	int rc;
 
 	epnum = urb->ep->desc.bEndpointAddress;
 
 #ifdef FOTG210_URB_TRACE
 	{
 		struct fotg210_qtd *qtd;
+
 		qtd = list_entry(qtd_list->next, struct fotg210_qtd, qtd_list);
 		fotg210_dbg(fotg210,
 			 "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
@@ -3200,19 +3115,17 @@ submit_async(
 	 */
 	if (likely(qh->qh_state == QH_STATE_IDLE))
 		qh_link_async(fotg210, qh);
- done:
+done:
 	spin_unlock_irqrestore(&fotg210->lock, flags);
 	if (unlikely(qh == NULL))
 		qtd_list_free(fotg210, urb, qtd_list);
 	return rc;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void single_unlink_async(struct fotg210_hcd *fotg210,
 				struct fotg210_qh *qh)
 {
-	struct fotg210_qh		*prev;
+	struct fotg210_qh *prev;
 
 	/* Add to the end of the list of QHs waiting for the next IAAD */
 	qh->qh_state = QH_STATE_UNLINK;
@@ -3268,10 +3181,10 @@ static void start_iaa_cycle(struct fotg210_hcd *fotg210, bool nested)
 
 static void end_unlink_async(struct fotg210_hcd *fotg210)
 {
-	struct fotg210_qh		*qh;
+	struct fotg210_qh *qh;
 
 	/* Process the idle QHs */
- restart:
+restart:
 	fotg210->async_unlinking = true;
 	while (fotg210->async_iaa) {
 		qh = fotg210->async_iaa;
@@ -3352,18 +3265,16 @@ static void start_unlink_async(struct fotg210_hcd *fotg210,
 	start_iaa_cycle(fotg210, false);
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void scan_async(struct fotg210_hcd *fotg210)
 {
-	struct fotg210_qh		*qh;
-	bool			check_unlinks_later = false;
+	struct fotg210_qh *qh;
+	bool check_unlinks_later = false;
 
 	fotg210->qh_scan_next = fotg210->async->qh_next.qh;
 	while (fotg210->qh_scan_next) {
 		qh = fotg210->qh_scan_next;
 		fotg210->qh_scan_next = qh->qh_next.qh;
- rescan:
+rescan:
 		/* clean any finished work for this qh */
 		if (!list_empty(&qh->qtd_list)) {
 			int temp;
@@ -3401,7 +3312,6 @@ static void scan_async(struct fotg210_hcd *fotg210)
 		++fotg210->async_unlink_cycle;
 	}
 }
-/*-------------------------------------------------------------------------*/
 /*
  * EHCI scheduled transaction support:  interrupt, iso, split iso
  * These are called "periodic" transactions in the EHCI spec.
@@ -3414,19 +3324,16 @@ static void scan_async(struct fotg210_hcd *fotg210)
  * It keeps track of every ITD (or SITD) that's linked, and holds enough
  * pre-calculated schedule data to make appending to the queue be quick.
  */
-
 static int fotg210_get_frame(struct usb_hcd *hcd);
 
-/*-------------------------------------------------------------------------*/
-
 /*
  * periodic_next_shadow - return "next" pointer on shadow list
  * @periodic: host pointer to qh/itd
  * @tag: hardware tag for type of this record
  */
-static union fotg210_shadow *
-periodic_next_shadow(struct fotg210_hcd *fotg210,
-		     union fotg210_shadow *periodic, __hc32 tag)
+static union fotg210_shadow *periodic_next_shadow(struct fotg210_hcd *fotg210,
+						union fotg210_shadow *periodic,
+						__hc32 tag)
 {
 	switch (hc32_to_cpu(fotg210, tag)) {
 	case Q_TYPE_QH:
@@ -3438,9 +3345,8 @@ periodic_next_shadow(struct fotg210_hcd *fotg210,
 	}
 }
 
-static __hc32 *
-shadow_next_periodic(struct fotg210_hcd *fotg210,
-		     union fotg210_shadow *periodic, __hc32 tag)
+static __hc32 *shadow_next_periodic(struct fotg210_hcd *fotg210,
+				    union fotg210_shadow *periodic, __hc32 tag)
 {
 	switch (hc32_to_cpu(fotg210, tag)) {
 	/* our fotg210_shadow.qh is actually software part */
@@ -3456,9 +3362,9 @@ shadow_next_periodic(struct fotg210_hcd *fotg210,
 static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
 			    void *ptr)
 {
-	union fotg210_shadow	*prev_p = &fotg210->pshadow[frame];
-	__hc32			*hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow	here = *prev_p;
+	union fotg210_shadow *prev_p = &fotg210->pshadow[frame];
+	__hc32 *hw_p = &fotg210->periodic[frame];
+	union fotg210_shadow here = *prev_p;
 
 	/* find predecessor of "ptr"; hw and shadow lists are in sync */
 	while (here.ptr && here.ptr != ptr) {
@@ -3483,13 +3389,13 @@ static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
 }
 
 /* how many of the uframe's 125 usecs are allocated? */
-static unsigned short
-periodic_usecs(struct fotg210_hcd *fotg210, unsigned frame, unsigned uframe)
+static unsigned short periodic_usecs(struct fotg210_hcd *fotg210,
+				     unsigned frame, unsigned uframe)
 {
-	__hc32			*hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow	*q = &fotg210->pshadow[frame];
-	unsigned		usecs = 0;
-	struct fotg210_qh_hw	*hw;
+	__hc32 *hw_p = &fotg210->periodic[frame];
+	union fotg210_shadow *q = &fotg210->pshadow[frame];
+	unsigned usecs = 0;
+	struct fotg210_qh_hw *hw;
 
 	while (q->ptr) {
 		switch (hc32_to_cpu(fotg210, Q_NEXT_TYPE(fotg210, *hw_p))) {
@@ -3530,8 +3436,6 @@ periodic_usecs(struct fotg210_hcd *fotg210, unsigned frame, unsigned uframe)
 	return usecs;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static int same_tt(struct usb_device *dev1, struct usb_device *dev2)
 {
 	if (!dev1->tt || !dev2->tt)
@@ -3548,13 +3452,8 @@ static int same_tt(struct usb_device *dev1, struct usb_device *dev2)
  * for a periodic transfer starting at the specified frame, using
  * all the uframes in the mask.
  */
-static int tt_no_collision(
-	struct fotg210_hcd		*fotg210,
-	unsigned		period,
-	struct usb_device	*dev,
-	unsigned		frame,
-	u32			uf_mask
-)
+static int tt_no_collision(struct fotg210_hcd *fotg210, unsigned period,
+			   struct usb_device *dev, unsigned frame, u32 uf_mask)
 {
 	if (period == 0)	/* error */
 		return 0;
@@ -3564,9 +3463,9 @@ static int tt_no_collision(
 	 * calling convention doesn't make that distinction.
 	 */
 	for (; frame < fotg210->periodic_size; frame += period) {
-		union fotg210_shadow	here;
-		__hc32			type;
-		struct fotg210_qh_hw	*hw;
+		union fotg210_shadow here;
+		__hc32 type;
+		struct fotg210_qh_hw *hw;
 
 		here = fotg210->pshadow[frame];
 		type = Q_NEXT_TYPE(fotg210, fotg210->periodic[frame]);
@@ -3579,7 +3478,7 @@ static int tt_no_collision(
 			case Q_TYPE_QH:
 				hw = here.qh->hw;
 				if (same_tt(dev, here.qh->dev)) {
-					u32		mask;
+					u32 mask;
 
 					mask = hc32_to_cpu(fotg210,
 							hw->hw_info2);
@@ -3607,8 +3506,6 @@ static int tt_no_collision(
 	return 1;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void enable_periodic(struct fotg210_hcd *fotg210)
 {
 	if (fotg210->periodic_count++)
@@ -3632,8 +3529,6 @@ static void disable_periodic(struct fotg210_hcd *fotg210)
 	fotg210_poll_PSS(fotg210);
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* periodic schedule slots have iso tds (normal or split) first, then a
  * sparse tree for active interrupt transfers.
  *
@@ -3642,8 +3537,8 @@ static void disable_periodic(struct fotg210_hcd *fotg210)
  */
 static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
-	unsigned	i;
-	unsigned	period = qh->period;
+	unsigned i;
+	unsigned period = qh->period;
 
 	dev_dbg(&qh->dev->dev,
 		"link qh%d-%04x/%p start %d [%d/%d us]\n",
@@ -3656,10 +3551,10 @@ static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		period = 1;
 
 	for (i = qh->start; i < fotg210->periodic_size; i += period) {
-		union fotg210_shadow	*prev = &fotg210->pshadow[i];
-		__hc32			*hw_p = &fotg210->periodic[i];
-		union fotg210_shadow	here = *prev;
-		__hc32			type = 0;
+		union fotg210_shadow *prev = &fotg210->pshadow[i];
+		__hc32 *hw_p = &fotg210->periodic[i];
+		union fotg210_shadow here = *prev;
+		__hc32 type = 0;
 
 		/* skip the iso nodes at list head */
 		while (here.ptr) {
@@ -3709,8 +3604,8 @@ static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
 			       struct fotg210_qh *qh)
 {
-	unsigned	i;
-	unsigned	period;
+	unsigned i;
+	unsigned period;
 
 	/*
 	 * If qh is for a low/full-speed device, simply unlinking it
@@ -3801,8 +3696,8 @@ static void start_unlink_intr(struct fotg210_hcd *fotg210,
 
 static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
-	struct fotg210_qh_hw	*hw = qh->hw;
-	int			rc;
+	struct fotg210_qh_hw *hw = qh->hw;
+	int rc;
 
 	qh->qh_state = QH_STATE_IDLE;
 	hw->hw_next = FOTG210_LIST_END(fotg210);
@@ -3830,16 +3725,10 @@ static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	disable_periodic(fotg210);
 }
 
-/*-------------------------------------------------------------------------*/
-
-static int check_period(
-	struct fotg210_hcd *fotg210,
-	unsigned	frame,
-	unsigned	uframe,
-	unsigned	period,
-	unsigned	usecs
-) {
-	int		claimed;
+static int check_period(struct fotg210_hcd *fotg210, unsigned frame,
+			unsigned uframe, unsigned period, unsigned usecs)
+{
+	int claimed;
 
 	/* complete split running into next frame?
 	 * given FSTN support, we could sometimes check...
@@ -3876,16 +3765,12 @@ static int check_period(
 	return 1;
 }
 
-static int check_intr_schedule(
-	struct fotg210_hcd		*fotg210,
-	unsigned		frame,
-	unsigned		uframe,
-	const struct fotg210_qh	*qh,
-	__hc32			*c_maskp
-)
+static int check_intr_schedule(struct fotg210_hcd *fotg210, unsigned frame,
+			       unsigned uframe, const struct fotg210_qh *qh,
+			       __hc32 *c_maskp)
 {
-	int		retval = -ENOSPC;
-	u8		mask = 0;
+	int retval = -ENOSPC;
+	u8 mask = 0;
 
 	if (qh->c_usecs && uframe >= 6)		/* FSTN territory? */
 		goto done;
@@ -3927,11 +3812,11 @@ done:
  */
 static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
-	int		status;
-	unsigned	uframe;
-	__hc32		c_mask;
-	unsigned	frame;		/* 0..(qh->period - 1), or NO_FRAME */
-	struct fotg210_qh_hw	*hw = qh->hw;
+	int status;
+	unsigned uframe;
+	__hc32 c_mask;
+	unsigned frame;	/* 0..(qh->period - 1), or NO_FRAME */
+	struct fotg210_qh_hw *hw = qh->hw;
 
 	qh_refresh(fotg210, qh);
 	hw->hw_next = FOTG210_LIST_END(fotg210);
@@ -3954,7 +3839,7 @@ static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	if (status) {
 		/* "normal" case, uframing flexible except with splits */
 		if (qh->period) {
-			int		i;
+			int i;
 
 			for (i = qh->period; status && i > 0; --i) {
 				frame = ++fotg210->random_frame % qh->period;
@@ -3992,17 +3877,14 @@ done:
 	return status;
 }
 
-static int intr_submit(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	gfp_t			mem_flags
-) {
-	unsigned		epnum;
-	unsigned long		flags;
-	struct fotg210_qh		*qh;
-	int			status;
-	struct list_head	empty;
+static int intr_submit(struct fotg210_hcd *fotg210, struct urb *urb,
+		       struct list_head *qtd_list, gfp_t mem_flags)
+{
+	unsigned epnum;
+	unsigned long flags;
+	struct fotg210_qh *qh;
+	int status;
+	struct list_head empty;
 
 	/* get endpoint and transfer/schedule data */
 	epnum = urb->ep->desc.bEndpointAddress;
@@ -4050,11 +3932,11 @@ done_not_linked:
 
 static void scan_intr(struct fotg210_hcd *fotg210)
 {
-	struct fotg210_qh		*qh;
+	struct fotg210_qh *qh;
 
 	list_for_each_entry_safe(qh, fotg210->qh_scan_next,
 				 &fotg210->intr_qh_list, intr_node) {
- rescan:
+rescan:
 		/* clean any finished work for this qh */
 		if (!list_empty(&qh->qtd_list)) {
 			int temp;
@@ -4077,12 +3959,9 @@ static void scan_intr(struct fotg210_hcd *fotg210)
 	}
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* fotg210_iso_stream ops work with both ITD and SITD */
 
-static struct fotg210_iso_stream *
-iso_stream_alloc(gfp_t mem_flags)
+static struct fotg210_iso_stream *iso_stream_alloc(gfp_t mem_flags)
 {
 	struct fotg210_iso_stream *stream;
 
@@ -4095,20 +3974,16 @@ iso_stream_alloc(gfp_t mem_flags)
 	return stream;
 }
 
-static void
-iso_stream_init(
-	struct fotg210_hcd		*fotg210,
-	struct fotg210_iso_stream	*stream,
-	struct usb_device	*dev,
-	int			pipe,
-	unsigned		interval
-)
+static void iso_stream_init(struct fotg210_hcd *fotg210,
+			    struct fotg210_iso_stream *stream,
+			    struct usb_device *dev, int pipe,
+			    unsigned interval)
 {
-	u32			buf1;
-	unsigned		epnum, maxp;
-	int			is_input;
-	long			bandwidth;
-	unsigned		multi;
+	u32 buf1;
+	unsigned epnum, maxp;
+	int is_input;
+	long bandwidth;
+	unsigned multi;
 
 	/*
 	 * this might be a "high bandwidth" highspeed endpoint,
@@ -4153,13 +4028,13 @@ iso_stream_init(
 	stream->maxp = maxp;
 }
 
-static struct fotg210_iso_stream *
-iso_stream_find(struct fotg210_hcd *fotg210, struct urb *urb)
+static struct fotg210_iso_stream *iso_stream_find(struct fotg210_hcd *fotg210,
+						  struct urb *urb)
 {
-	unsigned		epnum;
-	struct fotg210_iso_stream	*stream;
+	unsigned epnum;
+	struct fotg210_iso_stream *stream;
 	struct usb_host_endpoint *ep;
-	unsigned long		flags;
+	unsigned long flags;
 
 	epnum = usb_pipeendpoint(urb->pipe);
 	if (usb_pipein(urb->pipe))
@@ -4191,15 +4066,13 @@ iso_stream_find(struct fotg210_hcd *fotg210, struct urb *urb)
 	return stream;
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* fotg210_iso_sched ops can be ITD-only or SITD-only */
 
-static struct fotg210_iso_sched *
-iso_sched_alloc(unsigned packets, gfp_t mem_flags)
+static struct fotg210_iso_sched *iso_sched_alloc(unsigned packets,
+						 gfp_t mem_flags)
 {
-	struct fotg210_iso_sched	*iso_sched;
-	int			size = sizeof(*iso_sched);
+	struct fotg210_iso_sched *iso_sched;
+	int size = sizeof(*iso_sched);
 
 	size += packets * sizeof(struct fotg210_iso_packet);
 	iso_sched = kzalloc(size, mem_flags);
@@ -4209,16 +4082,13 @@ iso_sched_alloc(unsigned packets, gfp_t mem_flags)
 	return iso_sched;
 }
 
-static inline void
-itd_sched_init(
-	struct fotg210_hcd		*fotg210,
-	struct fotg210_iso_sched	*iso_sched,
-	struct fotg210_iso_stream	*stream,
-	struct urb		*urb
-)
+static inline void itd_sched_init(struct fotg210_hcd *fotg210,
+				  struct fotg210_iso_sched *iso_sched,
+				  struct fotg210_iso_stream *stream,
+				  struct urb *urb)
 {
-	unsigned	i;
-	dma_addr_t	dma = urb->transfer_dma;
+	unsigned i;
+	dma_addr_t dma = urb->transfer_dma;
 
 	/* how many uframes are needed for these transfers */
 	iso_sched->span = urb->number_of_packets * stream->interval;
@@ -4227,10 +4097,10 @@ itd_sched_init(
 	 * when we fit new itds into the schedule.
 	 */
 	for (i = 0; i < urb->number_of_packets; i++) {
-		struct fotg210_iso_packet	*uframe = &iso_sched->packet[i];
-		unsigned		length;
-		dma_addr_t		buf;
-		u32			trans;
+		struct fotg210_iso_packet *uframe = &iso_sched->packet[i];
+		unsigned length;
+		dma_addr_t buf;
+		u32 trans;
 
 		length = urb->iso_frame_desc[i].length;
 		buf = dma + urb->iso_frame_desc[i].offset;
@@ -4251,11 +4121,8 @@ itd_sched_init(
 	}
 }
 
-static void
-iso_sched_free(
-	struct fotg210_iso_stream	*stream,
-	struct fotg210_iso_sched	*iso_sched
-)
+static void iso_sched_free(struct fotg210_iso_stream *stream,
+			   struct fotg210_iso_sched *iso_sched)
 {
 	if (!iso_sched)
 		return;
@@ -4264,20 +4131,16 @@ iso_sched_free(
 	kfree(iso_sched);
 }
 
-static int
-itd_urb_transaction(
-	struct fotg210_iso_stream	*stream,
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	gfp_t			mem_flags
-)
+static int itd_urb_transaction(struct fotg210_iso_stream *stream,
+			       struct fotg210_hcd *fotg210,
+			       struct urb *urb, gfp_t mem_flags)
 {
-	struct fotg210_itd		*itd;
-	dma_addr_t		itd_dma;
-	int			i;
-	unsigned		num_itds;
-	struct fotg210_iso_sched	*sched;
-	unsigned long		flags;
+	struct fotg210_itd *itd;
+	dma_addr_t itd_dma;
+	int i;
+	unsigned num_itds;
+	struct fotg210_iso_sched *sched;
+	unsigned long flags;
 
 	sched = iso_sched_alloc(urb->number_of_packets, mem_flags);
 	if (unlikely(sched == NULL))
@@ -4306,7 +4169,7 @@ itd_urb_transaction(
 			list_del(&itd->itd_list);
 			itd_dma = itd->itd_dma;
 		} else {
- alloc_itd:
+alloc_itd:
 			spin_unlock_irqrestore(&fotg210->lock, flags);
 			itd = dma_pool_alloc(fotg210->itd_pool, mem_flags,
 					&itd_dma);
@@ -4330,16 +4193,8 @@ itd_urb_transaction(
 	return 0;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static inline int
-itd_slot_ok(
-	struct fotg210_hcd		*fotg210,
-	u32			mod,
-	u32			uframe,
-	u8			usecs,
-	u32			period
-)
+static inline int itd_slot_ok(struct fotg210_hcd *fotg210, u32 mod, u32 uframe,
+			      u8 usecs, u32 period)
 {
 	uframe %= period;
 	do {
@@ -4365,19 +4220,15 @@ itd_slot_ok(
  * given FOTG210_TUNE_FLS and the slop).  Or, write a smarter scheduler!
  */
 
-#define SCHEDULE_SLOP	80	/* microframes */
+#define SCHEDULE_SLOP 80 /* microframes */
 
-static int
-iso_stream_schedule(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct fotg210_iso_stream	*stream
-)
+static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
+			       struct fotg210_iso_stream *stream)
 {
-	u32			now, next, start, period, span;
-	int			status;
-	unsigned		mod = fotg210->periodic_size << 3;
-	struct fotg210_iso_sched	*sched = urb->hcpriv;
+	u32 now, next, start, period, span;
+	int status;
+	unsigned mod = fotg210->periodic_size << 3;
+	struct fotg210_iso_sched *sched = urb->hcpriv;
 
 	period = urb->interval;
 	span = sched->span;
@@ -4396,7 +4247,7 @@ iso_stream_schedule(
 	 * slot in the schedule, implicitly assuming URB_ISO_ASAP.
 	 */
 	if (likely(!list_empty(&stream->td_list))) {
-		u32	excess;
+		u32 excess;
 
 		/* For high speed devices, allow scheduling within the
 		 * isochronous scheduling threshold.  For full speed devices
@@ -4435,6 +4286,7 @@ iso_stream_schedule(
 	 */
 	else {
 		int done = 0;
+
 		start = SCHEDULE_SLOP + (now & ~0x07);
 
 		/* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */
@@ -4485,17 +4337,15 @@ iso_stream_schedule(
 		fotg210->next_frame = now >> 3;
 	return 0;
 
- fail:
+fail:
 	iso_sched_free(stream, sched);
 	urb->hcpriv = NULL;
 	return status;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static inline void
-itd_init(struct fotg210_hcd *fotg210, struct fotg210_iso_stream *stream,
-		struct fotg210_itd *itd)
+static inline void itd_init(struct fotg210_hcd *fotg210,
+			    struct fotg210_iso_stream *stream,
+			    struct fotg210_itd *itd)
 {
 	int i;
 
@@ -4511,17 +4361,13 @@ itd_init(struct fotg210_hcd *fotg210, struct fotg210_iso_stream *stream,
 	/* All other fields are filled when scheduling */
 }
 
-static inline void
-itd_patch(
-	struct fotg210_hcd		*fotg210,
-	struct fotg210_itd		*itd,
-	struct fotg210_iso_sched	*iso_sched,
-	unsigned		index,
-	u16			uframe
-)
+static inline void itd_patch(struct fotg210_hcd *fotg210,
+			     struct fotg210_itd *itd,
+			     struct fotg210_iso_sched *iso_sched,
+			     unsigned index, u16 uframe)
 {
-	struct fotg210_iso_packet	*uf = &iso_sched->packet[index];
-	unsigned		pg = itd->pg;
+	struct fotg210_iso_packet *uf = &iso_sched->packet[index];
+	unsigned pg = itd->pg;
 
 	uframe &= 0x07;
 	itd->index[uframe] = index;
@@ -4533,7 +4379,7 @@ itd_patch(
 
 	/* iso_frame_desc[].offset must be strictly increasing */
 	if (unlikely(uf->cross)) {
-		u64	bufp = uf->bufp + 4096;
+		u64 bufp = uf->bufp + 4096;
 
 		itd->pg = ++pg;
 		itd->hw_bufp[pg] |= cpu_to_hc32(fotg210, bufp & ~(u32)0);
@@ -4541,13 +4387,13 @@ itd_patch(
 	}
 }
 
-static inline void
-itd_link(struct fotg210_hcd *fotg210, unsigned frame, struct fotg210_itd *itd)
+static inline void itd_link(struct fotg210_hcd *fotg210, unsigned frame,
+			    struct fotg210_itd *itd)
 {
-	union fotg210_shadow	*prev = &fotg210->pshadow[frame];
-	__hc32			*hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow	here = *prev;
-	__hc32			type = 0;
+	union fotg210_shadow *prev = &fotg210->pshadow[frame];
+	__hc32 *hw_p = &fotg210->periodic[frame];
+	union fotg210_shadow here = *prev;
+	__hc32 type = 0;
 
 	/* skip any iso nodes which might belong to previous microframes */
 	while (here.ptr) {
@@ -4568,17 +4414,13 @@ itd_link(struct fotg210_hcd *fotg210, unsigned frame, struct fotg210_itd *itd)
 }
 
 /* fit urb's itds into the selected schedule slot; activate as needed */
-static void itd_link_urb(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	unsigned		mod,
-	struct fotg210_iso_stream	*stream
-)
-{
-	int			packet;
-	unsigned		next_uframe, uframe, frame;
-	struct fotg210_iso_sched	*iso_sched = urb->hcpriv;
-	struct fotg210_itd		*itd;
+static void itd_link_urb(struct fotg210_hcd *fotg210, struct urb *urb,
+			 unsigned mod, struct fotg210_iso_stream *stream)
+{
+	int packet;
+	unsigned next_uframe, uframe, frame;
+	struct fotg210_iso_sched *iso_sched = urb->hcpriv;
+	struct fotg210_itd *itd;
 
 	next_uframe = stream->next_uframe & (mod - 1);
 
@@ -4635,7 +4477,7 @@ static void itd_link_urb(
 	enable_periodic(fotg210);
 }
 
-#define	ISO_ERRS (FOTG210_ISOC_BUF_ERR | FOTG210_ISOC_BABBLE |\
+#define ISO_ERRS (FOTG210_ISOC_BUF_ERR | FOTG210_ISOC_BABBLE |\
 		  FOTG210_ISOC_XACTERR)
 
 /* Process and recycle a completed ITD.  Return true iff its urb completed,
@@ -4650,14 +4492,14 @@ static void itd_link_urb(
  */
 static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 {
-	struct urb				*urb = itd->urb;
-	struct usb_iso_packet_descriptor	*desc;
-	u32					t;
-	unsigned				uframe;
-	int					urb_index = -1;
-	struct fotg210_iso_stream			*stream = itd->stream;
-	struct usb_device			*dev;
-	bool					retval = false;
+	struct urb *urb = itd->urb;
+	struct usb_iso_packet_descriptor *desc;
+	u32 t;
+	unsigned uframe;
+	int urb_index = -1;
+	struct fotg210_iso_stream *stream = itd->stream;
+	struct usb_device *dev;
+	bool retval = false;
 
 	/* for each uframe with a packet */
 	for (uframe = 0; uframe < 8; uframe++) {
@@ -4702,8 +4544,8 @@ static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 		goto done;
 
 	/* ASSERT: it's really the last itd for this urb
-	list_for_each_entry (itd, &stream->td_list, itd_list)
-		BUG_ON (itd->urb == urb);
+	 * list_for_each_entry (itd, &stream->td_list, itd_list)
+	 *	BUG_ON (itd->urb == urb);
 	 */
 
 	/* give urb back to the driver; completion often (re)submits */
@@ -4740,14 +4582,12 @@ done:
 	return retval;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
-	gfp_t mem_flags)
+		      gfp_t mem_flags)
 {
-	int			status = -EINVAL;
-	unsigned long		flags;
-	struct fotg210_iso_stream	*stream;
+	int status = -EINVAL;
+	unsigned long flags;
+	struct fotg210_iso_stream *stream;
 
 	/* Get iso_stream head */
 	stream = iso_stream_find(fotg210, urb);
@@ -4756,11 +4596,10 @@ static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
 		return -ENOMEM;
 	}
 	if (unlikely(urb->interval != stream->interval &&
-		      fotg210_port_speed(fotg210, 0) ==
-				USB_PORT_STAT_HIGH_SPEED)) {
-			fotg210_dbg(fotg210, "can't change iso interval %d --> %d\n",
-				stream->interval, urb->interval);
-			goto done;
+	    fotg210_port_speed(fotg210, 0) == USB_PORT_STAT_HIGH_SPEED)) {
+		fotg210_dbg(fotg210, "can't change iso interval %d --> %d\n",
+			    stream->interval, urb->interval);
+		goto done;
 	}
 
 #ifdef FOTG210_URB_TRACE
@@ -4795,9 +4634,9 @@ static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
 		itd_link_urb(fotg210, urb, fotg210->periodic_size << 3, stream);
 	else
 		usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
- done_not_linked:
+done_not_linked:
 	spin_unlock_irqrestore(&fotg210->lock, flags);
- done:
+done:
 	return status;
 }
 
@@ -4897,7 +4736,7 @@ restart:
 	}
 	fotg210->next_frame = now_frame;
 }
-/*-------------------------------------------------------------------------*/
+
 /*
  * Display / Set uframe_periodic_max
  */
@@ -4905,8 +4744,8 @@ static ssize_t show_uframe_periodic_max(struct device *dev,
 					struct device_attribute *attr,
 					char *buf)
 {
-	struct fotg210_hcd		*fotg210;
-	int			n;
+	struct fotg210_hcd *fotg210;
+	int n;
 
 	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
 	n = scnprintf(buf, PAGE_SIZE, "%d\n", fotg210->uframe_periodic_max);
@@ -4918,12 +4757,12 @@ static ssize_t store_uframe_periodic_max(struct device *dev,
 					struct device_attribute *attr,
 					const char *buf, size_t count)
 {
-	struct fotg210_hcd	*fotg210;
-	unsigned		uframe_periodic_max;
-	unsigned		frame, uframe;
-	unsigned short		allocated_max;
-	unsigned long		flags;
-	ssize_t			ret;
+	struct fotg210_hcd *fotg210;
+	unsigned uframe_periodic_max;
+	unsigned frame, uframe;
+	unsigned short allocated_max;
+	unsigned long flags;
+	ssize_t ret;
 
 	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
 	if (kstrtouint(buf, 0, &uframe_periodic_max) < 0)
@@ -4954,13 +4793,13 @@ static ssize_t store_uframe_periodic_max(struct device *dev,
 		for (frame = 0; frame < fotg210->periodic_size; ++frame)
 			for (uframe = 0; uframe < 7; ++uframe)
 				allocated_max = max(allocated_max,
-						    periodic_usecs(fotg210, frame, uframe));
+						    periodic_usecs(fotg210,
+								   frame,
+								   uframe));
 
 		if (allocated_max > uframe_periodic_max) {
 			fotg210_info(fotg210,
-				"cannot decrease uframe_periodic_max because "
-				"periodic bandwidth is already allocated "
-				"(%u > %u)\n",
+				"cannot decrease uframe_periodic_max because periodic bandwidth is already allocated (%u > %u)\n",
 				allocated_max, uframe_periodic_max);
 			goto out_unlock;
 		}
@@ -4987,8 +4826,8 @@ static DEVICE_ATTR(uframe_periodic_max, 0644, show_uframe_periodic_max,
 
 static inline int create_sysfs_files(struct fotg210_hcd *fotg210)
 {
-	struct device	*controller = fotg210_to_hcd(fotg210)->self.controller;
-	int	i = 0;
+	struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
+	int i = 0;
 
 	if (i)
 		goto out;
@@ -5000,12 +4839,10 @@ out:
 
 static inline void remove_sysfs_files(struct fotg210_hcd *fotg210)
 {
-	struct device	*controller = fotg210_to_hcd(fotg210)->self.controller;
+	struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
 
 	device_remove_file(controller, &dev_attr_uframe_periodic_max);
 }
-/*-------------------------------------------------------------------------*/
-
 /* On some systems, leaving remote wakeup enabled prevents system shutdown.
  * The firmware seems to think that powering off is a wakeup event!
  * This routine turns off remote wakeup and everything else, on all ports.
@@ -5037,7 +4874,7 @@ static void fotg210_silence_controller(struct fotg210_hcd *fotg210)
  */
 static void fotg210_shutdown(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd	*fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
 
 	spin_lock_irq(&fotg210->lock);
 	fotg210->shutdown = true;
@@ -5050,8 +4887,6 @@ static void fotg210_shutdown(struct usb_hcd *hcd)
 	hrtimer_cancel(&fotg210->hrtimer);
 }
 
-/*-------------------------------------------------------------------------*/
-
 /*
  * fotg210_work is called from some interrupts, timers, and so on.
  * it calls driver completion functions, after dropping fotg210->lock.
@@ -5068,7 +4903,7 @@ static void fotg210_work(struct fotg210_hcd *fotg210)
 	}
 	fotg210->scanning = true;
 
- rescan:
+rescan:
 	fotg210->need_rescan = false;
 	if (fotg210->async_count)
 		scan_async(fotg210);
@@ -5092,7 +4927,7 @@ static void fotg210_work(struct fotg210_hcd *fotg210)
  */
 static void fotg210_stop(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
 
 	fotg210_dbg(fotg210, "stop\n");
 
@@ -5116,7 +4951,7 @@ static void fotg210_stop(struct usb_hcd *hcd)
 	spin_unlock_irq(&fotg210->lock);
 	fotg210_mem_cleanup(fotg210);
 
-#ifdef	FOTG210_STATS
+#ifdef FOTG210_STATS
 	fotg210_dbg(fotg210, "irq normal %ld err %ld iaa %ld (lost %ld)\n",
 		fotg210->stats.normal, fotg210->stats.error, fotg210->stats.iaa,
 		fotg210->stats.lost_iaa);
@@ -5131,11 +4966,11 @@ static void fotg210_stop(struct usb_hcd *hcd)
 /* one-time init, only for memory state */
 static int hcd_fotg210_init(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	u32			temp;
-	int			retval;
-	u32			hcc_params;
-	struct fotg210_qh_hw	*hw;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 temp;
+	int retval;
+	u32 hcc_params;
+	struct fotg210_qh_hw *hw;
 
 	spin_lock_init(&fotg210->lock);
 
@@ -5238,9 +5073,9 @@ static int hcd_fotg210_init(struct usb_hcd *hcd)
 /* start HC running; it's halted, hcd_fotg210_init() has been run (once) */
 static int fotg210_run(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	u32			temp;
-	u32			hcc_params;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 temp;
+	u32 hcc_params;
 
 	hcd->uses_new_polling = 1;
 
@@ -5347,13 +5182,11 @@ static int fotg210_setup(struct usb_hcd *hcd)
 	return 0;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	u32			status, masked_status, pcd_status = 0, cmd;
-	int			bh;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 status, masked_status, pcd_status = 0, cmd;
+	int bh;
 
 	spin_lock(&fotg210->lock);
 
@@ -5485,8 +5318,6 @@ dead:
 	return IRQ_HANDLED;
 }
 
-/*-------------------------------------------------------------------------*/
-
 /*
  * non-error returns are a promise to giveback() the urb later
  * we drop ownership so next owner (or urb unlink) can get it
@@ -5499,13 +5330,11 @@ dead:
  * NOTE:  control, bulk, and interrupt share the same code to append TDs
  * to a (possibly active) QH, and the same QH scanning code.
  */
-static int fotg210_urb_enqueue(
-	struct usb_hcd	*hcd,
-	struct urb	*urb,
-	gfp_t		mem_flags
-) {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct list_head	qtd_list;
+static int fotg210_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+			       gfp_t mem_flags)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct list_head qtd_list;
 
 	INIT_LIST_HEAD(&qtd_list);
 
@@ -5539,10 +5368,10 @@ static int fotg210_urb_enqueue(
 
 static int fotg210_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh		*qh;
-	unsigned long		flags;
-	int			rc;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_qh *qh;
+	unsigned long flags;
+	int rc;
 
 	spin_lock_irqsave(&fotg210->lock, flags);
 	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
@@ -5603,16 +5432,14 @@ done:
 	return rc;
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* bulk qh holds the data toggle */
 
-static void
-fotg210_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
+static void fotg210_endpoint_disable(struct usb_hcd *hcd,
+				     struct usb_host_endpoint *ep)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	unsigned long		flags;
-	struct fotg210_qh		*qh, *tmp;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	unsigned long flags;
+	struct fotg210_qh *qh, *tmp;
 
 	/* ASSERT:  any requests/urbs are being unlinked */
 	/* ASSERT:  nobody can be submitting urbs for this any more */
@@ -5627,7 +5454,7 @@ rescan:
 	 * accelerate iso completions ... so spin a while.
 	 */
 	if (qh->hw == NULL) {
-		struct fotg210_iso_stream	*stream = ep->hcpriv;
+		struct fotg210_iso_stream *stream = ep->hcpriv;
 
 		if (!list_empty(&stream->td_list))
 			goto idle_timeout;
@@ -5675,20 +5502,20 @@ idle_timeout:
 			list_empty(&qh->qtd_list) ? "" : "(has tds)");
 		break;
 	}
- done:
+done:
 	ep->hcpriv = NULL;
 	spin_unlock_irqrestore(&fotg210->lock, flags);
 }
 
-static void
-fotg210_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
+static void fotg210_endpoint_reset(struct usb_hcd *hcd,
+				   struct usb_host_endpoint *ep)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh		*qh;
-	int			eptype = usb_endpoint_type(&ep->desc);
-	int			epnum = usb_endpoint_num(&ep->desc);
-	int			is_out = usb_endpoint_dir_out(&ep->desc);
-	unsigned long		flags;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_qh *qh;
+	int eptype = usb_endpoint_type(&ep->desc);
+	int epnum = usb_endpoint_num(&ep->desc);
+	int is_out = usb_endpoint_dir_out(&ep->desc);
+	unsigned long flags;
 
 	if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
 		return;
@@ -5723,13 +5550,12 @@ fotg210_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
 
 static int fotg210_get_frame(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+
 	return (fotg210_read_frame_index(fotg210) >> 3) %
 		fotg210->periodic_size;
 }
 
-/*-------------------------------------------------------------------------*/
-
 /*
  * The EHCI in ChipIdea HDRC cannot be a separate module or device,
  * because its registers (and irq) are shared between host/gadget/otg
@@ -5808,12 +5634,12 @@ static void fotg210_init(struct fotg210_hcd *fotg210)
  */
 static int fotg210_hcd_probe(struct platform_device *pdev)
 {
-	struct device			*dev = &pdev->dev;
-	struct usb_hcd			*hcd;
-	struct resource			*res;
-	int				irq;
-	int				retval = -ENODEV;
-	struct fotg210_hcd		*fotg210;
+	struct device *dev = &pdev->dev;
+	struct usb_hcd *hcd;
+	struct resource *res;
+	int irq;
+	int retval = -ENODEV;
+	struct fotg210_hcd *fotg210;
 
 	if (usb_disabled())
 		return -ENODEV;
@@ -5883,8 +5709,8 @@ fail_create_hcd:
  */
 static int fotg210_hcd_remove(struct platform_device *pdev)
 {
-	struct device *dev	= &pdev->dev;
-	struct usb_hcd *hcd	= dev_get_drvdata(dev);
+	struct device *dev = &pdev->dev;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
 
 	if (!hcd)
 		return 0;
diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/host/fotg210.h
index 3bad178..b5cfa7a 100644
--- a/drivers/usb/host/fotg210.h
+++ b/drivers/usb/host/fotg210.h
@@ -137,19 +137,25 @@ struct fotg210_hcd {			/* one per controller */
 	/* per root hub port */
 	unsigned long		reset_done[FOTG210_MAX_ROOT_PORTS];
 
-	/* bit vectors (one bit per port) */
-	unsigned long		bus_suspended;		/* which ports were
-			already suspended at the start of a bus suspend */
-	unsigned long		companion_ports;	/* which ports are
-			dedicated to the companion controller */
-	unsigned long		owned_ports;		/* which ports are
-			owned by the companion during a bus suspend */
-	unsigned long		port_c_suspend;		/* which ports have
-			the change-suspend feature turned on */
-	unsigned long		suspended_ports;	/* which ports are
-			suspended */
-	unsigned long		resuming_ports;		/* which ports have
-			started to resume */
+	/* bit vectors (one bit per port)
+	 * which ports were already suspended at the start of a bus suspend
+	 */
+	unsigned long		bus_suspended;
+
+	/* which ports are edicated to the companion controller */
+	unsigned long		companion_ports;
+
+	/* which ports are owned by the companion during a bus suspend */
+	unsigned long		owned_ports;
+
+	/* which ports have the change-suspend feature turned on */
+	unsigned long		port_c_suspend;
+
+	/* which ports are suspended */
+	unsigned long		suspended_ports;
+
+	/* which ports have started to resume */
+	unsigned long		resuming_ports;
 
 	/* per-HC memory pools (could be per-bus, but ...) */
 	struct dma_pool		*qh_pool;	/* qh per active urb */
@@ -585,10 +591,10 @@ struct fotg210_fstn {
 /* Prepare the PORTSC wakeup flags during controller suspend/resume */
 
 #define fotg210_prepare_ports_for_controller_suspend(fotg210, do_wakeup) \
-		fotg210_adjust_port_wakeup_flags(fotg210, true, do_wakeup);
+		fotg210_adjust_port_wakeup_flags(fotg210, true, do_wakeup)
 
 #define fotg210_prepare_ports_for_controller_resume(fotg210)		\
-		fotg210_adjust_port_wakeup_flags(fotg210, false, false);
+		fotg210_adjust_port_wakeup_flags(fotg210, false, false)
 
 /*-------------------------------------------------------------------------*/
 
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 02/14] RFC: usb/host/fotg210: remove KERN_WARNING from pr_info
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
  2015-09-21 15:01                 ` [PATCH 01/14] RFC: usb/host/fotg210: Fix coding style issues Peter Senna Tschudin
@ 2015-09-21 15:01                 ` Peter Senna Tschudin
  2015-09-21 18:54                   ` Sergei Shtylyov
  2015-10-02 17:30                   ` Felipe Balbi
  2015-09-21 15:01                 ` [PATCH 03/14] RFC: usb/host/fotg210: Remove useless else statement Peter Senna Tschudin
                                   ` (13 subsequent siblings)
  15 siblings, 2 replies; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-21 15:01 UTC (permalink / raw)
  To: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh
  Cc: Peter Senna Tschudin

This patch remove KERN_WARNING from a call to pr_info().

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 48eac34..36413b2 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -5740,7 +5740,7 @@ static int __init fotg210_hcd_init(void)
 	set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
 	if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
 			test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
-		pr_warn(KERN_WARNING "Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
+		pr_warn("Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
 
 	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd\n",
 		 hcd_name,
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 03/14] RFC: usb/host/fotg210: Remove useless else statement
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
  2015-09-21 15:01                 ` [PATCH 01/14] RFC: usb/host/fotg210: Fix coding style issues Peter Senna Tschudin
  2015-09-21 15:01                 ` [PATCH 02/14] RFC: usb/host/fotg210: remove KERN_WARNING from pr_info Peter Senna Tschudin
@ 2015-09-21 15:01                 ` Peter Senna Tschudin
  2015-10-02 17:30                   ` Felipe Balbi
  2015-09-21 15:01                 ` [PATCH 04/14] RFC: usb/host/fotg210: Remove NULL checks dma_pool_destroy Peter Senna Tschudin
                                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-21 15:01 UTC (permalink / raw)
  To: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh
  Cc: Peter Senna Tschudin

This patch remove an else statement after a return to make the code
easier to understand.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 36413b2..f574143 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -1410,10 +1410,9 @@ static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
 			"Failed to enable port %d on root hub TT\n",
 			index+1);
 		return port_status;
-	} else {
-		fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
-			index + 1);
 	}
+	fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
+		    index + 1);
 
 	return port_status;
 }
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 04/14] RFC: usb/host/fotg210: Remove NULL checks dma_pool_destroy
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
                                   ` (2 preceding siblings ...)
  2015-09-21 15:01                 ` [PATCH 03/14] RFC: usb/host/fotg210: Remove useless else statement Peter Senna Tschudin
@ 2015-09-21 15:01                 ` Peter Senna Tschudin
  2015-10-02 17:30                   ` Felipe Balbi
  2015-09-21 15:01                 ` [PATCH 05/14] RFC: usb/host/fotg210: change kmalloc by kmalloc_array Peter Senna Tschudin
                                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-21 15:01 UTC (permalink / raw)
  To: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh
  Cc: Peter Senna Tschudin

This patch remove NULL checks before calls to dma_pool_destroy() as the
function now can handle NULL pointers.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index f574143..51feb61 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -1925,17 +1925,13 @@ static void fotg210_mem_cleanup(struct fotg210_hcd *fotg210)
 	fotg210->dummy = NULL;
 
 	/* DMA consistent memory and pools */
-	if (fotg210->qtd_pool)
-		dma_pool_destroy(fotg210->qtd_pool);
+	dma_pool_destroy(fotg210->qtd_pool);
 	fotg210->qtd_pool = NULL;
 
-	if (fotg210->qh_pool) {
-		dma_pool_destroy(fotg210->qh_pool);
-		fotg210->qh_pool = NULL;
-	}
+	dma_pool_destroy(fotg210->qh_pool);
+	fotg210->qh_pool = NULL;
 
-	if (fotg210->itd_pool)
-		dma_pool_destroy(fotg210->itd_pool);
+	dma_pool_destroy(fotg210->itd_pool);
 	fotg210->itd_pool = NULL;
 
 	if (fotg210->periodic)
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 05/14] RFC: usb/host/fotg210: change kmalloc by kmalloc_array
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
                                   ` (3 preceding siblings ...)
  2015-09-21 15:01                 ` [PATCH 04/14] RFC: usb/host/fotg210: Remove NULL checks dma_pool_destroy Peter Senna Tschudin
@ 2015-09-21 15:01                 ` Peter Senna Tschudin
  2015-09-21 18:56                   ` Sergei Shtylyov
  2015-10-02 17:30                   ` Felipe Balbi
  2015-09-21 15:01                 ` [PATCH 06/14] RFC: usb/host/fotg210: replace msleep by usleep_range Peter Senna Tschudin
                                   ` (10 subsequent siblings)
  15 siblings, 2 replies; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-21 15:01 UTC (permalink / raw)
  To: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh
  Cc: Peter Senna Tschudin

This patch change:

kmalloc(DBG_SCHED_LIMIT * sizeof(*seen), GFP_ATOMIC)

by:

kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC)

as kmalloc_array() should be used for allocating arrays.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 51feb61..e7e9991 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -501,7 +501,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 	unsigned i;
 	__hc32 tag;
 
-	seen = kmalloc(DBG_SCHED_LIMIT * sizeof(*seen), GFP_ATOMIC);
+	seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC);
 	if (!seen)
 		return 0;
 
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 06/14] RFC: usb/host/fotg210: replace msleep by usleep_range
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
                                   ` (4 preceding siblings ...)
  2015-09-21 15:01                 ` [PATCH 05/14] RFC: usb/host/fotg210: change kmalloc by kmalloc_array Peter Senna Tschudin
@ 2015-09-21 15:01                 ` Peter Senna Tschudin
  2015-10-02 17:31                   ` Felipe Balbi
  2015-09-21 15:01                 ` [PATCH 07/14] RFC: usb/host/fotg210: Remove a macro from snprintf Peter Senna Tschudin
                                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-21 15:01 UTC (permalink / raw)
  To: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh
  Cc: Peter Senna Tschudin

msleep under 20ms can result in sleeping up to 20ms, which may not be
intended. Replace msleep(5) by usleep_range(5000, 6000).

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index e7e9991..55c2279 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -5122,7 +5122,7 @@ static int fotg210_run(struct usb_hcd *hcd)
 	fotg210->rh_state = FOTG210_RH_RUNNING;
 	/* unblock posted writes */
 	fotg210_readl(fotg210, &fotg210->regs->command);
-	msleep(5);
+	usleep_range(5000, 6000);
 	up_write(&ehci_cf_port_reset_rwsem);
 	fotg210->last_periodic_enable = ktime_get_real();
 
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 07/14] RFC: usb/host/fotg210: Remove a macro from snprintf
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
                                   ` (5 preceding siblings ...)
  2015-09-21 15:01                 ` [PATCH 06/14] RFC: usb/host/fotg210: replace msleep by usleep_range Peter Senna Tschudin
@ 2015-09-21 15:01                 ` Peter Senna Tschudin
  2015-10-02 17:31                   ` Felipe Balbi
  2015-09-21 15:01                 ` [PATCH 08/14] RFC: usb/host/fotg210: convert macro to inline function Peter Senna Tschudin
                                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-21 15:01 UTC (permalink / raw)
  To: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh
  Cc: Peter Senna Tschudin

This patch removes a macro from a call to snprintf() and moves it's
content to just before the call to snprintf() assigning a value to a new
variable named tmp. The goal of this patch is to make the code easier to
understand.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 43 ++++++++++++++++++++++--------------------
 1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 55c2279..4032ed0 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -367,6 +367,8 @@ static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
 	unsigned size = *sizep;
 	char *next = *nextp;
 	char mark;
+	char *tmp;
+
 	__le32 list_end = FOTG210_LIST_END(fotg210);
 	struct fotg210_qh_hw *hw = qh->hw;
 
@@ -411,28 +413,29 @@ static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
 			else if (td->hw_alt_next != list_end)
 				mark = '/';
 		}
-		temp = snprintf(next, size,
-				"\n\t%p%c%s len=%d %08x urb %p",
-				td, mark, ({ char *tmp;
-				 switch ((scratch>>8)&0x03) {
-				 case 0:
-					tmp = "out";
-					break;
-				 case 1:
-					tmp = "in";
-					break;
-				 case 2:
-					tmp = "setup";
-					break;
-				 default:
-					tmp = "?";
-					break;
-				 } tmp; }),
-				(scratch >> 16) & 0x7fff,
-				scratch,
-				td->urb);
+
+		switch ((scratch >> 8) & 0x03) {
+		case 0:
+			tmp = "out";
+			break;
+		case 1:
+			tmp = "in";
+			break;
+		case 2:
+			tmp = "setup";
+			break;
+		default:
+			tmp = "?";
+			break;
+		}
+
+		temp = snprintf(next, size, "\n\t%p%c%s len=%d %08x urb %p",
+				td, mark, tmp, (scratch >> 16) & 0x7fff,
+				scratch, td->urb);
+
 		if (size < temp)
 			temp = size;
+
 		size -= temp;
 		next += temp;
 		if (temp == size)
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 08/14] RFC: usb/host/fotg210: convert macro to inline function
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
                                   ` (6 preceding siblings ...)
  2015-09-21 15:01                 ` [PATCH 07/14] RFC: usb/host/fotg210: Remove a macro from snprintf Peter Senna Tschudin
@ 2015-09-21 15:01                 ` Peter Senna Tschudin
  2015-10-02 17:32                   ` Felipe Balbi
  2015-09-21 15:01                 ` [PATCH 09/14] RFC: usb/host/fotg210: Add function: output_buf_tds_dir() Peter Senna Tschudin
                                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-21 15:01 UTC (permalink / raw)
  To: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh
  Cc: Peter Senna Tschudin

This patch convert the macro speed_char in an inline function. The goal
of this patch is to make the code easier to read.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 4032ed0..82cd5da 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -331,17 +331,22 @@ struct debug_buffer {
 	size_t alloc_size;
 };
 
-#define speed_char(info1)({ char tmp; \
-		switch (info1 & (3 << 12)) { \
-		case QH_FULL_SPEED:	\
-			tmp = 'f'; break; \
-		case QH_LOW_SPEED:	\
-			tmp = 'l'; break; \
-		case QH_HIGH_SPEED:	\
-			tmp = 'h'; break; \
-		default:		\
-			tmp = '?'; break; \
-		} tmp; })
+static inline char speed_char(u32 scratch)
+{
+	switch (scratch & (3 << 12)) {
+	case QH_FULL_SPEED:
+		return 'f';
+
+	case QH_LOW_SPEED:
+		return 'l';
+
+	case QH_HIGH_SPEED:
+		return 'h';
+
+	default:
+		return '?';
+	}
+}
 
 static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
 {
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 09/14] RFC: usb/host/fotg210: Add function: output_buf_tds_dir()
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
                                   ` (7 preceding siblings ...)
  2015-09-21 15:01                 ` [PATCH 08/14] RFC: usb/host/fotg210: convert macro to inline function Peter Senna Tschudin
@ 2015-09-21 15:01                 ` Peter Senna Tschudin
  2015-09-21 19:15                   ` Sergei Shtylyov
  2015-10-02 17:32                   ` Felipe Balbi
  2015-09-21 15:01                 ` [PATCH 10/14] RFC: usb/host/fotg210: Add function scan_frame_queue() Peter Senna Tschudin
                                   ` (6 subsequent siblings)
  15 siblings, 2 replies; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-21 15:01 UTC (permalink / raw)
  To: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh
  Cc: Peter Senna Tschudin

checkpatch complains about too many leading tabs because the switch
statement starts after 6 tabs.

fill_periodic_buffer() -> for() -> do -> switch() -> if() ->
list_for_each_entry() and finally the last switch().

This patch moves the list_for_each_entry() and the last switch() to a
new inline function named output_buf_tds_dir(). This change makes the
code easier to read and calm down checkpatch. This patch changes it to:

fill_periodic_buffer() -> for() -> do -> switch() -> if() ->
output_buf_tds_dir()

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 64 ++++++++++++++++++++++--------------------
 1 file changed, 33 insertions(+), 31 deletions(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 82cd5da..13cca41 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -497,6 +497,36 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
 	return strlen(buf->output_buf);
 }
 
+/* count tds, get ep direction */
+static inline unsigned output_buf_tds_dir(char *buf,
+					  struct fotg210_hcd *fotg210,
+					  struct fotg210_qh_hw *hw,
+					  struct fotg210_qh *qh, unsigned size)
+{
+	u32 scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
+	struct fotg210_qtd *qtd;
+	char *type = "";
+	unsigned temp = 0;
+
+	/* count tds, get ep direction */
+	list_for_each_entry(qtd, &qh->qtd_list, qtd_list) {
+		temp++;
+		switch (0x03 & (hc32_to_cpu(fotg210, qtd->hw_token) >> 8)) {
+		case 0:
+			type = "out";
+			continue;
+		case 1:
+			type = "in";
+			continue;
+		}
+	}
+
+	return scnprintf(buf, size, "(%c%d ep%d%s [%d/%d] q%d p%d)",
+			 speed_char(scratch), scratch & 0x007f,
+			 (scratch >> 8) & 0x000f, type, qh->usecs,
+			 qh->c_usecs, temp, 0x7ff & (scratch >> 16));
+}
+
 #define DBG_SCHED_LIMIT 64
 static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 {
@@ -568,37 +598,9 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 				}
 				/* show more info the first time around */
 				if (temp == seen_count) {
-					u32 scratch = hc32_to_cpup(fotg210,
-								&hw->hw_info1);
-					struct fotg210_qtd *qtd;
-					char *type = "";
-
-					/* count tds, get ep direction */
-					temp = 0;
-					list_for_each_entry(qtd,
-							&p.qh->qtd_list,
-							qtd_list) {
-						temp++;
-						switch (0x03 & (hc32_to_cpu(
-							fotg210,
-							qtd->hw_token) >> 8)) {
-						case 0:
-							type = "out";
-							continue;
-						case 1:
-							type = "in";
-							continue;
-						}
-					}
-
-					temp = scnprintf(next, size,
-						"(%c%d ep%d%s [%d/%d] q%d p%d)",
-						speed_char(scratch),
-						scratch & 0x007f,
-						(scratch >> 8) & 0x000f, type,
-						p.qh->usecs, p.qh->c_usecs,
-						temp,
-						0x7ff & (scratch >> 16));
+					temp = output_buf_tds_dir(next,
+								  fotg210, hw,
+								  p.qh, size);
 
 					if (seen_count < DBG_SCHED_LIMIT)
 						seen[seen_count++].qh = p.qh;
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 10/14] RFC: usb/host/fotg210: Add function scan_frame_queue()
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
                                   ` (8 preceding siblings ...)
  2015-09-21 15:01                 ` [PATCH 09/14] RFC: usb/host/fotg210: Add function: output_buf_tds_dir() Peter Senna Tschudin
@ 2015-09-21 15:01                 ` Peter Senna Tschudin
  2015-10-02 17:35                   ` Felipe Balbi
  2015-09-21 15:01                 ` [PATCH 11/14] RFC: usb/host: Rename fotg210-hcd to faraday-hcd Peter Senna Tschudin
                                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-21 15:01 UTC (permalink / raw)
  To: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh
  Cc: Peter Senna Tschudin

checkpatch complains about too many leading tabs because the if
statement starts after 6 tabs:

scan_iosoc() -> for() -> while() -> switch() -> if() -> for() -> if()

There is also a goto statement going backwards in case of failure. This
patch creates a new inline function named scan_frame_queue() containing
the last 4 nesting levels, and removes the need of backwards goto,
making the code easier to read. After the patch it becomes:

scan_iosoc() -> for() -> while() -> scan_frame_queue()

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 142 ++++++++++++++++++++++-------------------
 1 file changed, 76 insertions(+), 66 deletions(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 13cca41..e60a239 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -4645,13 +4645,81 @@ done:
 	return status;
 }
 
-/*-------------------------------------------------------------------------*/
+static inline int scan_frame_queue(struct fotg210_hcd *fotg210, unsigned frame,
+				   unsigned now_frame, bool live)
+{
+	unsigned uf;
+	bool modified;
+	union fotg210_shadow q, *q_p;
+	__hc32 type, *hw_p;
+
+	/* scan each element in frame's queue for completions */
+	q_p = &fotg210->pshadow[frame];
+	hw_p = &fotg210->periodic[frame];
+	q.ptr = q_p->ptr;
+	type = Q_NEXT_TYPE(fotg210, *hw_p);
+	modified = false;
+
+	while (q.ptr != NULL) {
+		switch (hc32_to_cpu(fotg210, type)) {
+		case Q_TYPE_ITD:
+			/* If this ITD is still active, leave it for
+			 * later processing ... check the next entry.
+			 * No need to check for activity unless the
+			 * frame is current.
+			 */
+			if (frame == now_frame && live) {
+				rmb();
+				for (uf = 0; uf < 8; uf++) {
+					if (q.itd->hw_transaction[uf] &
+						    ITD_ACTIVE(fotg210))
+						break;
+				}
+				if (uf < 8) {
+					q_p = &q.itd->itd_next;
+					hw_p = &q.itd->hw_next;
+					type = Q_NEXT_TYPE(fotg210,
+						q.itd->hw_next);
+					q = *q_p;
+					break;
+				}
+			}
+
+			/* Take finished ITDs out of the schedule
+			 * and process them:  recycle, maybe report
+			 * URB completion.  HC won't cache the
+			 * pointer for much longer, if at all.
+			 */
+			*q_p = q.itd->itd_next;
+			*hw_p = q.itd->hw_next;
+			type = Q_NEXT_TYPE(fotg210, q.itd->hw_next);
+			wmb();
+			modified = itd_complete(fotg210, q.itd);
+			q = *q_p;
+			break;
+		default:
+			fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
+				type, frame, q.ptr);
+			/* FALL THROUGH */
+		case Q_TYPE_QH:
+		case Q_TYPE_FSTN:
+			/* End of the iTDs and siTDs */
+			q.ptr = NULL;
+			break;
+		}
+
+		/* assume completion callbacks modify the queue */
+		if (unlikely(modified && fotg210->isoc_count > 0))
+			return -1;
+	}
+	return 0;
+}
 
 static void scan_isoc(struct fotg210_hcd *fotg210)
 {
-	unsigned	uf, now_frame, frame;
-	unsigned	fmask = fotg210->periodic_size - 1;
-	bool		modified, live;
+	unsigned uf, now_frame, frame, ret;
+	unsigned fmask = fotg210->periodic_size - 1;
+	bool live;
 
 	/*
 	 * When running, scan from last scan point up to "now"
@@ -4670,69 +4738,11 @@ static void scan_isoc(struct fotg210_hcd *fotg210)
 
 	frame = fotg210->next_frame;
 	for (;;) {
-		union fotg210_shadow	q, *q_p;
-		__hc32			type, *hw_p;
 
-restart:
-		/* scan each element in frame's queue for completions */
-		q_p = &fotg210->pshadow[frame];
-		hw_p = &fotg210->periodic[frame];
-		q.ptr = q_p->ptr;
-		type = Q_NEXT_TYPE(fotg210, *hw_p);
-		modified = false;
-
-		while (q.ptr != NULL) {
-			switch (hc32_to_cpu(fotg210, type)) {
-			case Q_TYPE_ITD:
-				/* If this ITD is still active, leave it for
-				 * later processing ... check the next entry.
-				 * No need to check for activity unless the
-				 * frame is current.
-				 */
-				if (frame == now_frame && live) {
-					rmb();
-					for (uf = 0; uf < 8; uf++) {
-						if (q.itd->hw_transaction[uf] &
-							    ITD_ACTIVE(fotg210))
-							break;
-					}
-					if (uf < 8) {
-						q_p = &q.itd->itd_next;
-						hw_p = &q.itd->hw_next;
-						type = Q_NEXT_TYPE(fotg210,
-							q.itd->hw_next);
-						q = *q_p;
-						break;
-					}
-				}
-
-				/* Take finished ITDs out of the schedule
-				 * and process them:  recycle, maybe report
-				 * URB completion.  HC won't cache the
-				 * pointer for much longer, if at all.
-				 */
-				*q_p = q.itd->itd_next;
-				*hw_p = q.itd->hw_next;
-				type = Q_NEXT_TYPE(fotg210, q.itd->hw_next);
-				wmb();
-				modified = itd_complete(fotg210, q.itd);
-				q = *q_p;
-				break;
-			default:
-				fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
-					type, frame, q.ptr);
-				/* FALL THROUGH */
-			case Q_TYPE_QH:
-			case Q_TYPE_FSTN:
-				/* End of the iTDs and siTDs */
-				q.ptr = NULL;
-				break;
-			}
-
-			/* assume completion callbacks modify the queue */
-			if (unlikely(modified && fotg210->isoc_count > 0))
-				goto restart;
-		}
+		ret = 1;
+		while (ret != 0)
+			ret = scan_frame_queue(fotg210, frame, now_frame,
+					       live);
 
 		/* Stop when we have reached the current frame */
 		if (frame == now_frame)
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 11/14] RFC: usb/host: Rename fotg210-hcd to faraday-hcd
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
                                   ` (9 preceding siblings ...)
  2015-09-21 15:01                 ` [PATCH 10/14] RFC: usb/host/fotg210: Add function scan_frame_queue() Peter Senna Tschudin
@ 2015-09-21 15:01                 ` Peter Senna Tschudin
  2015-10-02 17:35                   ` Felipe Balbi
  2015-09-21 15:01                 ` [PATCH 12/14] RFC: usb/host/faraday-hcd: Replace fotg210 by fhcd2xx Peter Senna Tschudin
                                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-21 15:01 UTC (permalink / raw)
  To: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh
  Cc: Peter Senna Tschudin

This patch renames fotg210-hcd to faraday-hcd as a first step of
consolitating Faraday fotg210 and fusbh200 EHCI-like drivers.

The patch also updates Kconfig and Makefile.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/Kconfig       |    2 +-
 drivers/usb/host/Makefile      |    2 +-
 drivers/usb/host/faraday-hcd.c | 5792 ++++++++++++++++++++++++++++++++++++++++
 drivers/usb/host/faraday-hcd.h |  692 +++++
 drivers/usb/host/fotg210-hcd.c | 5792 ----------------------------------------
 drivers/usb/host/fotg210.h     |  692 -----
 6 files changed, 6486 insertions(+), 6486 deletions(-)
 create mode 100644 drivers/usb/host/faraday-hcd.c
 create mode 100644 drivers/usb/host/faraday-hcd.h
 delete mode 100644 drivers/usb/host/fotg210-hcd.c
 delete mode 100644 drivers/usb/host/fotg210.h

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 079991e..e33e10b 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -358,7 +358,7 @@ config USB_FUSBH200_HCD
 	To compile this driver as a module, choose M here: the
 	module will be called fusbh200-hcd.
 
-config USB_FOTG210_HCD
+config USB_FARADAY_HCD
 	tristate "FOTG210 HCD support"
 	depends on USB
 	---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 754efaa..bc407c2 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -76,5 +76,5 @@ obj-$(CONFIG_USB_EHCI_FSL)	+= ehci-fsl.o
 obj-$(CONFIG_USB_HCD_BCMA)	+= bcma-hcd.o
 obj-$(CONFIG_USB_HCD_SSB)	+= ssb-hcd.o
 obj-$(CONFIG_USB_FUSBH200_HCD)	+= fusbh200-hcd.o
-obj-$(CONFIG_USB_FOTG210_HCD)	+= fotg210-hcd.o
+obj-$(CONFIG_USB_FARADAY_HCD)	+= faraday-hcd.o
 obj-$(CONFIG_USB_MAX3421_HCD)	+= max3421-hcd.o
diff --git a/drivers/usb/host/faraday-hcd.c b/drivers/usb/host/faraday-hcd.c
new file mode 100644
index 0000000..ab1257f
--- /dev/null
+++ b/drivers/usb/host/faraday-hcd.c
@@ -0,0 +1,5792 @@
+/*
+ * Faraday FOTG210 EHCI-like driver
+ *
+ * Copyright (c) 2013 Faraday Technology Corporation
+ *
+ * Author: Yuan-Hsin Chen <yhchen@faraday-tech.com>
+ *	   Feng-Hsin Chiang <john453@faraday-tech.com>
+ *	   Po-Yu Chuang <ratbert.chuang@gmail.com>
+ *
+ * Most of code borrowed from the Linux-3.7 EHCI driver
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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.
+ */
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/dmapool.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/vmalloc.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/hrtimer.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <linux/moduleparam.h>
+#include <linux/dma-mapping.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/byteorder.h>
+#include <asm/irq.h>
+#include <asm/unaligned.h>
+
+#define DRIVER_AUTHOR "Yuan-Hsin Chen"
+#define DRIVER_DESC "FOTG210 Host Controller (EHCI) Driver"
+static const char hcd_name[] = "fotg210_hcd";
+
+#undef FOTG210_URB_TRACE
+#define FOTG210_STATS
+
+/* magic numbers that can affect system performance */
+#define FOTG210_TUNE_CERR	3 /* 0-3 qtd retries; 0 == don't stop */
+#define FOTG210_TUNE_RL_HS	4 /* nak throttle; see 4.9 */
+#define FOTG210_TUNE_RL_TT	0
+#define FOTG210_TUNE_MULT_HS	1 /* 1-3 transactions/uframe; 4.10.3 */
+#define FOTG210_TUNE_MULT_TT	1
+
+/*
+ * Some drivers think it's safe to schedule isochronous transfers more than 256
+ * ms into the future (partly as a result of an old bug in the scheduling
+ * code).  In an attempt to avoid trouble, we will use a minimum scheduling
+ * length of 512 frames instead of 256.
+ */
+#define FOTG210_TUNE_FLS 1 /* (medium) 512-frame schedule */
+
+/* Initial IRQ latency:  faster than hw default */
+static int log2_irq_thresh; /* 0 to 6 */
+module_param(log2_irq_thresh, int, S_IRUGO);
+MODULE_PARM_DESC(log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
+
+/* initial park setting:  slower than hw default */
+static unsigned park;
+module_param(park, uint, S_IRUGO);
+MODULE_PARM_DESC(park, "park setting; 1-3 back-to-back async packets");
+
+/* for link power management(LPM) feature */
+static unsigned int hird;
+module_param(hird, int, S_IRUGO);
+MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
+
+#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
+
+#include "faraday-hcd.h"
+
+#define fotg210_dbg(fotg210, fmt, args...) \
+	dev_dbg(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
+#define fotg210_err(fotg210, fmt, args...) \
+	dev_err(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
+#define fotg210_info(fotg210, fmt, args...) \
+	dev_info(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
+#define fotg210_warn(fotg210, fmt, args...) \
+	dev_warn(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
+
+/* check the values in the HCSPARAMS register (host controller _Structural_
+ * parameters) see EHCI spec, Table 2-4 for each value
+ */
+static void dbg_hcs_params(struct fotg210_hcd *fotg210, char *label)
+{
+	u32 params = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
+
+	fotg210_dbg(fotg210, "%s hcs_params 0x%x ports=%d\n", label, params,
+		    HCS_N_PORTS(params));
+}
+
+/* check the values in the HCCPARAMS register (host controller _Capability_
+ * parameters) see EHCI Spec, Table 2-5 for each value
+ */
+static void dbg_hcc_params(struct fotg210_hcd *fotg210, char *label)
+{
+	u32 params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
+
+	fotg210_dbg(fotg210, "%s hcc_params %04x uframes %s%s\n", label,
+		    params,
+		    HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
+		    HCC_CANPARK(params) ? " park" : "");
+}
+
+static void __maybe_unused
+dbg_qtd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd)
+{
+	fotg210_dbg(fotg210, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
+		    hc32_to_cpup(fotg210, &qtd->hw_next),
+		    hc32_to_cpup(fotg210, &qtd->hw_alt_next),
+		    hc32_to_cpup(fotg210, &qtd->hw_token),
+		    hc32_to_cpup(fotg210, &qtd->hw_buf[0]));
+	if (qtd->hw_buf[1])
+		fotg210_dbg(fotg210, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
+			    hc32_to_cpup(fotg210, &qtd->hw_buf[1]),
+			    hc32_to_cpup(fotg210, &qtd->hw_buf[2]),
+			    hc32_to_cpup(fotg210, &qtd->hw_buf[3]),
+			    hc32_to_cpup(fotg210, &qtd->hw_buf[4]));
+}
+
+static void __maybe_unused
+dbg_qh(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+{
+	struct fotg210_qh_hw *hw = qh->hw;
+
+	fotg210_dbg(fotg210, "%s qh %p n%08x info %x %x qtd %x\n", label, qh,
+		    hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
+
+	dbg_qtd("overlay", fotg210, (struct fotg210_qtd *) &hw->hw_qtd_next);
+}
+
+static void __maybe_unused
+dbg_itd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
+{
+	fotg210_dbg(fotg210, "%s[%d] itd %p, next %08x, urb %p\n", label,
+		    itd->frame, itd, hc32_to_cpu(fotg210, itd->hw_next),
+		    itd->urb);
+
+	fotg210_dbg(fotg210,
+		    "  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
+		    hc32_to_cpu(fotg210, itd->hw_transaction[0]),
+		    hc32_to_cpu(fotg210, itd->hw_transaction[1]),
+		    hc32_to_cpu(fotg210, itd->hw_transaction[2]),
+		    hc32_to_cpu(fotg210, itd->hw_transaction[3]),
+		    hc32_to_cpu(fotg210, itd->hw_transaction[4]),
+		    hc32_to_cpu(fotg210, itd->hw_transaction[5]),
+		    hc32_to_cpu(fotg210, itd->hw_transaction[6]),
+		    hc32_to_cpu(fotg210, itd->hw_transaction[7]));
+
+	fotg210_dbg(fotg210,
+		    "  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
+		    hc32_to_cpu(fotg210, itd->hw_bufp[0]),
+		    hc32_to_cpu(fotg210, itd->hw_bufp[1]),
+		    hc32_to_cpu(fotg210, itd->hw_bufp[2]),
+		    hc32_to_cpu(fotg210, itd->hw_bufp[3]),
+		    hc32_to_cpu(fotg210, itd->hw_bufp[4]),
+		    hc32_to_cpu(fotg210, itd->hw_bufp[5]),
+		    hc32_to_cpu(fotg210, itd->hw_bufp[6]));
+
+	fotg210_dbg(fotg210, "  index: %d %d %d %d %d %d %d %d\n",
+		    itd->index[0], itd->index[1], itd->index[2],
+		    itd->index[3], itd->index[4], itd->index[5],
+		    itd->index[6], itd->index[7]);
+}
+
+static int __maybe_unused
+dbg_status_buf(char *buf, unsigned len, const char *label, u32 status)
+{
+	return scnprintf(buf, len, "%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
+			 label, label[0] ? " " : "", status,
+			 (status & STS_ASS) ? " Async" : "",
+			 (status & STS_PSS) ? " Periodic" : "",
+			 (status & STS_RECL) ? " Recl" : "",
+			 (status & STS_HALT) ? " Halt" : "",
+			 (status & STS_IAA) ? " IAA" : "",
+			 (status & STS_FATAL) ? " FATAL" : "",
+			 (status & STS_FLR) ? " FLR" : "",
+			 (status & STS_PCD) ? " PCD" : "",
+			 (status & STS_ERR) ? " ERR" : "",
+			 (status & STS_INT) ? " INT" : "");
+}
+
+static int __maybe_unused
+dbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable)
+{
+	return scnprintf(buf, len, "%s%sintrenable %02x%s%s%s%s%s%s",
+			 label, label[0] ? " " : "", enable,
+			 (enable & STS_IAA) ? " IAA" : "",
+			 (enable & STS_FATAL) ? " FATAL" : "",
+			 (enable & STS_FLR) ? " FLR" : "",
+			 (enable & STS_PCD) ? " PCD" : "",
+			 (enable & STS_ERR) ? " ERR" : "",
+			 (enable & STS_INT) ? " INT" : "");
+}
+
+static const char *const fls_strings[] = { "1024", "512", "256", "??" };
+
+static int dbg_command_buf(char *buf, unsigned len, const char *label,
+			   u32 command)
+{
+	return scnprintf(buf, len,
+			 "%s%scommand %07x %s=%d ithresh=%d%s%s%s period=%s%s %s",
+			 label, label[0] ? " " : "", command,
+			 (command & CMD_PARK) ? " park" : "(park)",
+			 CMD_PARK_CNT(command),
+			 (command >> 16) & 0x3f,
+			 (command & CMD_IAAD) ? " IAAD" : "",
+			 (command & CMD_ASE) ? " Async" : "",
+			 (command & CMD_PSE) ? " Periodic" : "",
+			 fls_strings[(command >> 2) & 0x3],
+			 (command & CMD_RESET) ? " Reset" : "",
+			 (command & CMD_RUN) ? "RUN" : "HALT");
+}
+
+static char *dbg_port_buf(char *buf, unsigned len, const char *label, int port,
+			  u32 status)
+{
+	char *sig;
+
+	/* signaling state */
+	switch (status & (3 << 10)) {
+	case 0 << 10:
+		sig = "se0";
+		break;
+	case 1 << 10:
+		sig = "k";
+		break; /* low speed */
+	case 2 << 10:
+		sig = "j";
+		break;
+	default:
+		sig = "?";
+		break;
+	}
+
+	scnprintf(buf, len, "%s%sport:%d status %06x %d sig=%s%s%s%s%s%s%s%s",
+		  label, label[0] ? " " : "", port, status,
+		  status >> 25, /*device address */
+		  sig,
+		  (status & PORT_RESET) ? " RESET" : "",
+		  (status & PORT_SUSPEND) ? " SUSPEND" : "",
+		  (status & PORT_RESUME) ? " RESUME" : "",
+		  (status & PORT_PEC) ? " PEC" : "",
+		  (status & PORT_PE) ? " PE" : "",
+		  (status & PORT_CSC) ? " CSC" : "",
+		  (status & PORT_CONNECT) ? " CONNECT" : "");
+
+	return buf;
+}
+
+/* functions have the "wrong" filename when they're output... */
+#define dbg_status(fotg210, label, status) {			\
+	char _buf[80];						\
+	dbg_status_buf(_buf, sizeof(_buf), label, status);	\
+	fotg210_dbg(fotg210, "%s\n", _buf);			\
+}
+
+#define dbg_cmd(fotg210, label, command) {			\
+	char _buf[80];						\
+	dbg_command_buf(_buf, sizeof(_buf), label, command);	\
+	fotg210_dbg(fotg210, "%s\n", _buf);			\
+}
+
+#define dbg_port(fotg210, label, port, status) {			    \
+	char _buf[80];							    \
+	fotg210_dbg(fotg210, "%s\n",					    \
+		    dbg_port_buf(_buf, sizeof(_buf), label, port, status)); \
+}
+
+/* troubleshooting help: expose state in debugfs */
+static int debug_async_open(struct inode *, struct file *);
+static int debug_periodic_open(struct inode *, struct file *);
+static int debug_registers_open(struct inode *, struct file *);
+static int debug_async_open(struct inode *, struct file *);
+
+static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
+static int debug_close(struct inode *, struct file *);
+
+static const struct file_operations debug_async_fops = {
+	.owner		= THIS_MODULE,
+	.open		= debug_async_open,
+	.read		= debug_output,
+	.release	= debug_close,
+	.llseek		= default_llseek,
+};
+static const struct file_operations debug_periodic_fops = {
+	.owner		= THIS_MODULE,
+	.open		= debug_periodic_open,
+	.read		= debug_output,
+	.release	= debug_close,
+	.llseek		= default_llseek,
+};
+static const struct file_operations debug_registers_fops = {
+	.owner		= THIS_MODULE,
+	.open		= debug_registers_open,
+	.read		= debug_output,
+	.release	= debug_close,
+	.llseek		= default_llseek,
+};
+
+static struct dentry *fotg210_debug_root;
+
+struct debug_buffer {
+	ssize_t (*fill_func)(struct debug_buffer *);	/* fill method */
+	struct usb_bus *bus;
+	struct mutex mutex;	/* protect filling of buffer */
+	size_t count;		/* number of characters filled into buffer */
+	char *output_buf;
+	size_t alloc_size;
+};
+
+static inline char speed_char(u32 scratch)
+{
+	switch (scratch & (3 << 12)) {
+	case QH_FULL_SPEED:
+		return 'f';
+
+	case QH_LOW_SPEED:
+		return 'l';
+
+	case QH_HIGH_SPEED:
+		return 'h';
+
+	default:
+		return '?';
+	}
+}
+
+static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
+{
+	__u32 v = hc32_to_cpu(fotg210, token);
+
+	if (v & QTD_STS_ACTIVE)
+		return '*';
+	if (v & QTD_STS_HALT)
+		return '-';
+	if (!IS_SHORT_READ(v))
+		return ' ';
+	/* tries to advance through hw_alt_next */
+	return '/';
+}
+
+static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
+		     char **nextp, unsigned *sizep)
+{
+	u32 scratch;
+	u32 hw_curr;
+	struct fotg210_qtd *td;
+	unsigned temp;
+	unsigned size = *sizep;
+	char *next = *nextp;
+	char mark;
+	char *tmp;
+
+	__le32 list_end = FOTG210_LIST_END(fotg210);
+	struct fotg210_qh_hw *hw = qh->hw;
+
+	if (hw->hw_qtd_next == list_end) /* NEC does this */
+		mark = '@';
+	else
+		mark = token_mark(fotg210, hw->hw_token);
+	if (mark == '/') { /* qh_alt_next controls qh advance? */
+		if ((hw->hw_alt_next & QTD_MASK(fotg210)) ==
+		    fotg210->async->hw->hw_alt_next)
+			mark = '#'; /* blocked */
+		else if (hw->hw_alt_next == list_end)
+			mark = '.'; /* use hw_qtd_next */
+		/* else alt_next points to some other qtd */
+	}
+	scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
+	hw_curr = (mark == '*') ? hc32_to_cpup(fotg210, &hw->hw_current) : 0;
+	temp = scnprintf(next, size,
+			"qh/%p dev%d %cs ep%d %08x %08x(%08x%c %s nak%d)",
+			qh, scratch & 0x007f,
+			speed_char(scratch),
+			(scratch >> 8) & 0x000f,
+			scratch, hc32_to_cpup(fotg210, &hw->hw_info2),
+			hc32_to_cpup(fotg210, &hw->hw_token), mark,
+			(cpu_to_hc32(fotg210, QTD_TOGGLE) & hw->hw_token)
+				? "data1" : "data0",
+			(hc32_to_cpup(fotg210, &hw->hw_alt_next) >> 1) & 0x0f);
+	size -= temp;
+	next += temp;
+
+	/* hc may be modifying the list as we read it ... */
+	list_for_each_entry(td, &qh->qtd_list, qtd_list) {
+		scratch = hc32_to_cpup(fotg210, &td->hw_token);
+		mark = ' ';
+		if (hw_curr == td->qtd_dma)
+			mark = '*';
+		else if (hw->hw_qtd_next == cpu_to_hc32(fotg210, td->qtd_dma))
+			mark = '+';
+		else if (QTD_LENGTH(scratch)) {
+			if (td->hw_alt_next == fotg210->async->hw->hw_alt_next)
+				mark = '#';
+			else if (td->hw_alt_next != list_end)
+				mark = '/';
+		}
+
+		switch ((scratch >> 8) & 0x03) {
+		case 0:
+			tmp = "out";
+			break;
+		case 1:
+			tmp = "in";
+			break;
+		case 2:
+			tmp = "setup";
+			break;
+		default:
+			tmp = "?";
+			break;
+		}
+
+		temp = snprintf(next, size, "\n\t%p%c%s len=%d %08x urb %p",
+				td, mark, tmp, (scratch >> 16) & 0x7fff,
+				scratch, td->urb);
+
+		if (size < temp)
+			temp = size;
+
+		size -= temp;
+		next += temp;
+		if (temp == size)
+			goto done;
+	}
+
+	temp = snprintf(next, size, "\n");
+	if (size < temp)
+		temp = size;
+
+	size -= temp;
+	next += temp;
+
+done:
+	*sizep = size;
+	*nextp = next;
+}
+
+static ssize_t fill_async_buffer(struct debug_buffer *buf)
+{
+	struct usb_hcd *hcd;
+	struct fotg210_hcd *fotg210;
+	unsigned long flags;
+	unsigned temp, size;
+	char *next;
+	struct fotg210_qh *qh;
+
+	hcd = bus_to_hcd(buf->bus);
+	fotg210 = hcd_to_fotg210(hcd);
+	next = buf->output_buf;
+	size = buf->alloc_size;
+
+	*next = 0;
+
+	/* dumps a snapshot of the async schedule.
+	 * usually empty except for long-term bulk reads, or head.
+	 * one QH per line, and TDs we know about
+	 */
+	spin_lock_irqsave(&fotg210->lock, flags);
+	for (qh = fotg210->async->qh_next.qh; size > 0 && qh;
+	     qh = qh->qh_next.qh)
+		qh_lines(fotg210, qh, &next, &size);
+	if (fotg210->async_unlink && size > 0) {
+		temp = scnprintf(next, size, "\nunlink =\n");
+		size -= temp;
+		next += temp;
+
+		for (qh = fotg210->async_unlink; size > 0 && qh;
+				qh = qh->unlink_next)
+			qh_lines(fotg210, qh, &next, &size);
+	}
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+
+	return strlen(buf->output_buf);
+}
+
+/* count tds, get ep direction */
+static inline unsigned output_buf_tds_dir(char *buf,
+					  struct fotg210_hcd *fotg210,
+					  struct fotg210_qh_hw *hw,
+					  struct fotg210_qh *qh, unsigned size)
+{
+	u32 scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
+	struct fotg210_qtd *qtd;
+	char *type = "";
+	unsigned temp = 0;
+
+	/* count tds, get ep direction */
+	list_for_each_entry(qtd, &qh->qtd_list, qtd_list) {
+		temp++;
+		switch (0x03 & (hc32_to_cpu(fotg210, qtd->hw_token) >> 8)) {
+		case 0:
+			type = "out";
+			continue;
+		case 1:
+			type = "in";
+			continue;
+		}
+	}
+
+	return scnprintf(buf, size, "(%c%d ep%d%s [%d/%d] q%d p%d)",
+			 speed_char(scratch), scratch & 0x007f,
+			 (scratch >> 8) & 0x000f, type, qh->usecs,
+			 qh->c_usecs, temp, 0x7ff & (scratch >> 16));
+}
+
+#define DBG_SCHED_LIMIT 64
+static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
+{
+	struct usb_hcd *hcd;
+	struct fotg210_hcd *fotg210;
+	unsigned long flags;
+	union fotg210_shadow p, *seen;
+	unsigned temp, size, seen_count;
+	char *next;
+	unsigned i;
+	__hc32 tag;
+
+	seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC);
+	if (!seen)
+		return 0;
+
+	seen_count = 0;
+
+	hcd = bus_to_hcd(buf->bus);
+	fotg210 = hcd_to_fotg210(hcd);
+	next = buf->output_buf;
+	size = buf->alloc_size;
+
+	temp = scnprintf(next, size, "size = %d\n", fotg210->periodic_size);
+	size -= temp;
+	next += temp;
+
+	/* dump a snapshot of the periodic schedule.
+	 * iso changes, interrupt usually doesn't.
+	 */
+	spin_lock_irqsave(&fotg210->lock, flags);
+	for (i = 0; i < fotg210->periodic_size; i++) {
+		p = fotg210->pshadow[i];
+		if (likely(!p.ptr))
+			continue;
+
+		tag = Q_NEXT_TYPE(fotg210, fotg210->periodic[i]);
+
+		temp = scnprintf(next, size, "%4d: ", i);
+		size -= temp;
+		next += temp;
+
+		do {
+			struct fotg210_qh_hw *hw;
+
+			switch (hc32_to_cpu(fotg210, tag)) {
+			case Q_TYPE_QH:
+				hw = p.qh->hw;
+				temp = scnprintf(next, size, " qh%d-%04x/%p",
+						p.qh->period,
+						hc32_to_cpup(fotg210,
+							&hw->hw_info2)
+							/* uframe masks */
+							& (QH_CMASK | QH_SMASK),
+						p.qh);
+				size -= temp;
+				next += temp;
+				/* don't repeat what follows this qh */
+				for (temp = 0; temp < seen_count; temp++) {
+					if (seen[temp].ptr != p.ptr)
+						continue;
+					if (p.qh->qh_next.ptr) {
+						temp = scnprintf(next, size,
+							" ...");
+						size -= temp;
+						next += temp;
+					}
+					break;
+				}
+				/* show more info the first time around */
+				if (temp == seen_count) {
+					temp = output_buf_tds_dir(next,
+								  fotg210, hw,
+								  p.qh, size);
+
+					if (seen_count < DBG_SCHED_LIMIT)
+						seen[seen_count++].qh = p.qh;
+				} else
+					temp = 0;
+				tag = Q_NEXT_TYPE(fotg210, hw->hw_next);
+				p = p.qh->qh_next;
+				break;
+			case Q_TYPE_FSTN:
+				temp = scnprintf(next, size,
+					" fstn-%8x/%p", p.fstn->hw_prev,
+					p.fstn);
+				tag = Q_NEXT_TYPE(fotg210, p.fstn->hw_next);
+				p = p.fstn->fstn_next;
+				break;
+			case Q_TYPE_ITD:
+				temp = scnprintf(next, size,
+					" itd/%p", p.itd);
+				tag = Q_NEXT_TYPE(fotg210, p.itd->hw_next);
+				p = p.itd->itd_next;
+				break;
+			}
+			size -= temp;
+			next += temp;
+		} while (p.ptr);
+
+		temp = scnprintf(next, size, "\n");
+		size -= temp;
+		next += temp;
+	}
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+	kfree(seen);
+
+	return buf->alloc_size - size;
+}
+#undef DBG_SCHED_LIMIT
+
+static const char *rh_state_string(struct fotg210_hcd *fotg210)
+{
+	switch (fotg210->rh_state) {
+	case FOTG210_RH_HALTED:
+		return "halted";
+	case FOTG210_RH_SUSPENDED:
+		return "suspended";
+	case FOTG210_RH_RUNNING:
+		return "running";
+	case FOTG210_RH_STOPPING:
+		return "stopping";
+	}
+	return "?";
+}
+
+static ssize_t fill_registers_buffer(struct debug_buffer *buf)
+{
+	struct usb_hcd *hcd;
+	struct fotg210_hcd *fotg210;
+	unsigned long flags;
+	unsigned temp, size, i;
+	char *next, scratch[80];
+	static const char fmt[] = "%*s\n";
+	static const char label[] = "";
+
+	hcd = bus_to_hcd(buf->bus);
+	fotg210 = hcd_to_fotg210(hcd);
+	next = buf->output_buf;
+	size = buf->alloc_size;
+
+	spin_lock_irqsave(&fotg210->lock, flags);
+
+	if (!HCD_HW_ACCESSIBLE(hcd)) {
+		size = scnprintf(next, size,
+			"bus %s, device %s\n"
+			"%s\n"
+			"SUSPENDED(no register access)\n",
+			hcd->self.controller->bus->name,
+			dev_name(hcd->self.controller),
+			hcd->product_desc);
+		goto done;
+	}
+
+	/* Capability Registers */
+	i = HC_VERSION(fotg210, fotg210_readl(fotg210,
+					      &fotg210->caps->hc_capbase));
+	temp = scnprintf(next, size,
+		"bus %s, device %s\n"
+		"%s\n"
+		"EHCI %x.%02x, rh state %s\n",
+		hcd->self.controller->bus->name,
+		dev_name(hcd->self.controller),
+		hcd->product_desc,
+		i >> 8, i & 0x0ff, rh_state_string(fotg210));
+	size -= temp;
+	next += temp;
+
+	/* FIXME interpret both types of params */
+	i = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
+	temp = scnprintf(next, size, "structural params 0x%08x\n", i);
+	size -= temp;
+	next += temp;
+
+	i = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
+	temp = scnprintf(next, size, "capability params 0x%08x\n", i);
+	size -= temp;
+	next += temp;
+
+	/* Operational Registers */
+	temp = dbg_status_buf(scratch, sizeof(scratch), label,
+			fotg210_readl(fotg210, &fotg210->regs->status));
+	temp = scnprintf(next, size, fmt, temp, scratch);
+	size -= temp;
+	next += temp;
+
+	temp = dbg_command_buf(scratch, sizeof(scratch), label,
+			fotg210_readl(fotg210, &fotg210->regs->command));
+	temp = scnprintf(next, size, fmt, temp, scratch);
+	size -= temp;
+	next += temp;
+
+	temp = dbg_intr_buf(scratch, sizeof(scratch), label,
+			fotg210_readl(fotg210, &fotg210->regs->intr_enable));
+	temp = scnprintf(next, size, fmt, temp, scratch);
+	size -= temp;
+	next += temp;
+
+	temp = scnprintf(next, size, "uframe %04x\n",
+			fotg210_read_frame_index(fotg210));
+	size -= temp;
+	next += temp;
+
+	if (fotg210->async_unlink) {
+		temp = scnprintf(next, size, "async unlink qh %p\n",
+				fotg210->async_unlink);
+		size -= temp;
+		next += temp;
+	}
+
+#ifdef FOTG210_STATS
+	temp = scnprintf(next, size,
+		"irq normal %ld err %ld iaa %ld(lost %ld)\n",
+		fotg210->stats.normal, fotg210->stats.error, fotg210->stats.iaa,
+		fotg210->stats.lost_iaa);
+	size -= temp;
+	next += temp;
+
+	temp = scnprintf(next, size, "complete %ld unlink %ld\n",
+		fotg210->stats.complete, fotg210->stats.unlink);
+	size -= temp;
+	next += temp;
+#endif
+
+done:
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+
+	return buf->alloc_size - size;
+}
+
+static struct debug_buffer
+*alloc_buffer(struct usb_bus *bus, ssize_t (*fill_func)(struct debug_buffer *))
+{
+	struct debug_buffer *buf;
+
+	buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL);
+
+	if (buf) {
+		buf->bus = bus;
+		buf->fill_func = fill_func;
+		mutex_init(&buf->mutex);
+		buf->alloc_size = PAGE_SIZE;
+	}
+
+	return buf;
+}
+
+static int fill_buffer(struct debug_buffer *buf)
+{
+	int ret = 0;
+
+	if (!buf->output_buf)
+		buf->output_buf = vmalloc(buf->alloc_size);
+
+	if (!buf->output_buf) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = buf->fill_func(buf);
+
+	if (ret >= 0) {
+		buf->count = ret;
+		ret = 0;
+	}
+
+out:
+	return ret;
+}
+
+static ssize_t debug_output(struct file *file, char __user *user_buf,
+			    size_t len, loff_t *offset)
+{
+	struct debug_buffer *buf = file->private_data;
+	int ret = 0;
+
+	mutex_lock(&buf->mutex);
+	if (buf->count == 0) {
+		ret = fill_buffer(buf);
+		if (ret != 0) {
+			mutex_unlock(&buf->mutex);
+			goto out;
+		}
+	}
+	mutex_unlock(&buf->mutex);
+
+	ret = simple_read_from_buffer(user_buf, len, offset,
+				      buf->output_buf, buf->count);
+
+out:
+	return ret;
+
+}
+
+static int debug_close(struct inode *inode, struct file *file)
+{
+	struct debug_buffer *buf = file->private_data;
+
+	if (buf) {
+		vfree(buf->output_buf);
+		kfree(buf);
+	}
+
+	return 0;
+}
+static int debug_async_open(struct inode *inode, struct file *file)
+{
+	file->private_data = alloc_buffer(inode->i_private, fill_async_buffer);
+
+	return file->private_data ? 0 : -ENOMEM;
+}
+
+static int debug_periodic_open(struct inode *inode, struct file *file)
+{
+	struct debug_buffer *buf;
+
+	buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
+	if (!buf)
+		return -ENOMEM;
+
+	buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8)*PAGE_SIZE;
+	file->private_data = buf;
+	return 0;
+}
+
+static int debug_registers_open(struct inode *inode, struct file *file)
+{
+	file->private_data = alloc_buffer(inode->i_private,
+					  fill_registers_buffer);
+
+	return file->private_data ? 0 : -ENOMEM;
+}
+
+static inline void create_debug_files(struct fotg210_hcd *fotg210)
+{
+	struct usb_bus *bus = &fotg210_to_hcd(fotg210)->self;
+
+	fotg210->debug_dir = debugfs_create_dir(bus->bus_name,
+						fotg210_debug_root);
+	if (!fotg210->debug_dir)
+		return;
+
+	if (!debugfs_create_file("async", S_IRUGO, fotg210->debug_dir, bus,
+						&debug_async_fops))
+		goto file_error;
+
+	if (!debugfs_create_file("periodic", S_IRUGO, fotg210->debug_dir, bus,
+						&debug_periodic_fops))
+		goto file_error;
+
+	if (!debugfs_create_file("registers", S_IRUGO, fotg210->debug_dir, bus,
+						    &debug_registers_fops))
+		goto file_error;
+
+	return;
+
+file_error:
+	debugfs_remove_recursive(fotg210->debug_dir);
+}
+
+static inline void remove_debug_files(struct fotg210_hcd *fotg210)
+{
+	debugfs_remove_recursive(fotg210->debug_dir);
+}
+
+/*
+ * handshake - spin reading hc until handshake completes or fails
+ * @ptr: address of hc register to be read
+ * @mask: bits to look at in result of read
+ * @done: value of those bits when handshake succeeds
+ * @usec: timeout in microseconds
+ *
+ * Returns negative errno, or zero on success
+ *
+ * Success happens when the "mask" bits have the specified value (hardware
+ * handshake done).  There are two failure modes:  "usec" have passed (major
+ * hardware flakeout), or the register reads as all-ones (hardware removed).
+ *
+ * That last failure should_only happen in cases like physical cardbus eject
+ * before driver shutdown. But it also seems to be caused by bugs in cardbus
+ * bridge shutdown:  shutting down the bridge before the devices using it.
+ */
+static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
+		     u32 mask, u32 done, int usec)
+{
+	u32 result;
+
+	do {
+		result = fotg210_readl(fotg210, ptr);
+		if (result == ~(u32)0)		/* card removed */
+			return -ENODEV;
+		result &= mask;
+		if (result == done)
+			return 0;
+		udelay(1);
+		usec--;
+	} while (usec > 0);
+	return -ETIMEDOUT;
+}
+
+/*
+ * Force HC to halt state from unknown (EHCI spec section 2.3).
+ * Must be called with interrupts enabled and the lock not held.
+ */
+static int fotg210_halt(struct fotg210_hcd *fotg210)
+{
+	u32 temp;
+
+	spin_lock_irq(&fotg210->lock);
+
+	/* disable any irqs left enabled by previous code */
+	fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
+
+	/*
+	 * This routine gets called during probe before fotg210->command
+	 * has been initialized, so we can't rely on its value.
+	 */
+	fotg210->command &= ~CMD_RUN;
+	temp = fotg210_readl(fotg210, &fotg210->regs->command);
+	temp &= ~(CMD_RUN | CMD_IAAD);
+	fotg210_writel(fotg210, temp, &fotg210->regs->command);
+
+	spin_unlock_irq(&fotg210->lock);
+	synchronize_irq(fotg210_to_hcd(fotg210)->irq);
+
+	return handshake(fotg210, &fotg210->regs->status,
+			  STS_HALT, STS_HALT, 16 * 125);
+}
+
+/*
+ * Reset a non-running (STS_HALT == 1) controller.
+ * Must be called with interrupts enabled and the lock not held.
+ */
+static int fotg210_reset(struct fotg210_hcd *fotg210)
+{
+	int retval;
+	u32 command = fotg210_readl(fotg210, &fotg210->regs->command);
+
+	/* If the EHCI debug controller is active, special care must be
+	 * taken before and after a host controller reset
+	 */
+	if (fotg210->debug && !dbgp_reset_prep(fotg210_to_hcd(fotg210)))
+		fotg210->debug = NULL;
+
+	command |= CMD_RESET;
+	dbg_cmd(fotg210, "reset", command);
+	fotg210_writel(fotg210, command, &fotg210->regs->command);
+	fotg210->rh_state = FOTG210_RH_HALTED;
+	fotg210->next_statechange = jiffies;
+	retval = handshake(fotg210, &fotg210->regs->command,
+			    CMD_RESET, 0, 250 * 1000);
+
+	if (retval)
+		return retval;
+
+	if (fotg210->debug)
+		dbgp_external_startup(fotg210_to_hcd(fotg210));
+
+	fotg210->port_c_suspend = fotg210->suspended_ports =
+			fotg210->resuming_ports = 0;
+	return retval;
+}
+
+/*
+ * Idle the controller (turn off the schedules).
+ * Must be called with interrupts enabled and the lock not held.
+ */
+static void fotg210_quiesce(struct fotg210_hcd *fotg210)
+{
+	u32 temp;
+
+	if (fotg210->rh_state != FOTG210_RH_RUNNING)
+		return;
+
+	/* wait for any schedule enables/disables to take effect */
+	temp = (fotg210->command << 10) & (STS_ASS | STS_PSS);
+	handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, temp,
+		  16 * 125);
+
+	/* then disable anything that's still active */
+	spin_lock_irq(&fotg210->lock);
+	fotg210->command &= ~(CMD_ASE | CMD_PSE);
+	fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
+	spin_unlock_irq(&fotg210->lock);
+
+	/* hardware can take 16 microframes to turn off ... */
+	handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, 0,
+		  16 * 125);
+}
+
+static void end_unlink_async(struct fotg210_hcd *fotg210);
+static void unlink_empty_async(struct fotg210_hcd *fotg210);
+static void fotg210_work(struct fotg210_hcd *fotg210);
+static void start_unlink_intr(struct fotg210_hcd *fotg210,
+			      struct fotg210_qh *qh);
+static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
+
+/* Set a bit in the USBCMD register */
+static void fotg210_set_command_bit(struct fotg210_hcd *fotg210, u32 bit)
+{
+	fotg210->command |= bit;
+	fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
+
+	/* unblock posted write */
+	fotg210_readl(fotg210, &fotg210->regs->command);
+}
+
+/* Clear a bit in the USBCMD register */
+static void fotg210_clear_command_bit(struct fotg210_hcd *fotg210, u32 bit)
+{
+	fotg210->command &= ~bit;
+	fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
+
+	/* unblock posted write */
+	fotg210_readl(fotg210, &fotg210->regs->command);
+}
+
+/*
+ * EHCI timer support...  Now using hrtimers.
+ *
+ * Lots of different events are triggered from fotg210->hrtimer.  Whenever
+ * the timer routine runs, it checks each possible event; events that are
+ * currently enabled and whose expiration time has passed get handled.
+ * The set of enabled events is stored as a collection of bitflags in
+ * fotg210->enabled_hrtimer_events, and they are numbered in order of
+ * increasing delay values (ranging between 1 ms and 100 ms).
+ *
+ * Rather than implementing a sorted list or tree of all pending events,
+ * we keep track only of the lowest-numbered pending event, in
+ * fotg210->next_hrtimer_event.  Whenever fotg210->hrtimer gets restarted, its
+ * expiration time is set to the timeout value for this event.
+ *
+ * As a result, events might not get handled right away; the actual delay
+ * could be anywhere up to twice the requested delay.  This doesn't
+ * matter, because none of the events are especially time-critical.  The
+ * ones that matter most all have a delay of 1 ms, so they will be
+ * handled after 2 ms at most, which is okay.  In addition to this, we
+ * allow for an expiration range of 1 ms.
+ */
+
+/*
+ * Delay lengths for the hrtimer event types.
+ * Keep this list sorted by delay length, in the same order as
+ * the event types indexed by enum fotg210_hrtimer_event in fotg210.h.
+ */
+static unsigned event_delays_ns[] = {
+	1 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_POLL_ASS */
+	1 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_POLL_PSS */
+	1 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_POLL_DEAD */
+	1125 * NSEC_PER_USEC,	/* FOTG210_HRTIMER_UNLINK_INTR */
+	2 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_FREE_ITDS */
+	6 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_ASYNC_UNLINKS */
+	10 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_IAA_WATCHDOG */
+	10 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_DISABLE_PERIODIC */
+	15 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_DISABLE_ASYNC */
+	100 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_IO_WATCHDOG */
+};
+
+/* Enable a pending hrtimer event */
+static void fotg210_enable_event(struct fotg210_hcd *fotg210, unsigned event,
+				 bool resched)
+{
+	ktime_t *timeout = &fotg210->hr_timeouts[event];
+
+	if (resched)
+		*timeout = ktime_add(ktime_get(),
+				ktime_set(0, event_delays_ns[event]));
+	fotg210->enabled_hrtimer_events |= (1 << event);
+
+	/* Track only the lowest-numbered pending event */
+	if (event < fotg210->next_hrtimer_event) {
+		fotg210->next_hrtimer_event = event;
+		hrtimer_start_range_ns(&fotg210->hrtimer, *timeout,
+				NSEC_PER_MSEC, HRTIMER_MODE_ABS);
+	}
+}
+
+
+/* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */
+static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
+{
+	unsigned actual, want;
+
+	/* Don't enable anything if the controller isn't running (e.g., died) */
+	if (fotg210->rh_state != FOTG210_RH_RUNNING)
+		return;
+
+	want = (fotg210->command & CMD_ASE) ? STS_ASS : 0;
+	actual = fotg210_readl(fotg210, &fotg210->regs->status) & STS_ASS;
+
+	if (want != actual) {
+
+		/* Poll again later, but give up after about 20 ms */
+		if (fotg210->ASS_poll_count++ < 20) {
+			fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_ASS,
+					     true);
+			return;
+		}
+		fotg210_dbg(fotg210, "Waited too long for the async schedule status (%x/%x), giving up\n",
+				want, actual);
+	}
+	fotg210->ASS_poll_count = 0;
+
+	/* The status is up-to-date; restart or stop the schedule as needed */
+	if (want == 0) {	/* Stopped */
+		if (fotg210->async_count > 0)
+			fotg210_set_command_bit(fotg210, CMD_ASE);
+
+	} else {		/* Running */
+		if (fotg210->async_count == 0) {
+
+			/* Turn off the schedule after a while */
+			fotg210_enable_event(fotg210,
+					     FOTG210_HRTIMER_DISABLE_ASYNC,
+					     true);
+		}
+	}
+}
+
+/* Turn off the async schedule after a brief delay */
+static void fotg210_disable_ASE(struct fotg210_hcd *fotg210)
+{
+	fotg210_clear_command_bit(fotg210, CMD_ASE);
+}
+
+
+/* Poll the STS_PSS status bit; see when it agrees with CMD_PSE */
+static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
+{
+	unsigned actual, want;
+
+	/* Don't do anything if the controller isn't running (e.g., died) */
+	if (fotg210->rh_state != FOTG210_RH_RUNNING)
+		return;
+
+	want = (fotg210->command & CMD_PSE) ? STS_PSS : 0;
+	actual = fotg210_readl(fotg210, &fotg210->regs->status) & STS_PSS;
+
+	if (want != actual) {
+
+		/* Poll again later, but give up after about 20 ms */
+		if (fotg210->PSS_poll_count++ < 20) {
+			fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_PSS,
+					     true);
+			return;
+		}
+		fotg210_dbg(fotg210, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
+				want, actual);
+	}
+	fotg210->PSS_poll_count = 0;
+
+	/* The status is up-to-date; restart or stop the schedule as needed */
+	if (want == 0) {	/* Stopped */
+		if (fotg210->periodic_count > 0)
+			fotg210_set_command_bit(fotg210, CMD_PSE);
+
+	} else {		/* Running */
+		if (fotg210->periodic_count == 0) {
+
+			/* Turn off the schedule after a while */
+			fotg210_enable_event(fotg210,
+					     FOTG210_HRTIMER_DISABLE_PERIODIC,
+					     true);
+		}
+	}
+}
+
+/* Turn off the periodic schedule after a brief delay */
+static void fotg210_disable_PSE(struct fotg210_hcd *fotg210)
+{
+	fotg210_clear_command_bit(fotg210, CMD_PSE);
+}
+
+
+/* Poll the STS_HALT status bit; see when a dead controller stops */
+static void fotg210_handle_controller_death(struct fotg210_hcd *fotg210)
+{
+	if (!(fotg210_readl(fotg210, &fotg210->regs->status) & STS_HALT)) {
+
+		/* Give up after a few milliseconds */
+		if (fotg210->died_poll_count++ < 5) {
+			/* Try again later */
+			fotg210_enable_event(fotg210,
+					     FOTG210_HRTIMER_POLL_DEAD, true);
+			return;
+		}
+		fotg210_warn(fotg210, "Waited too long for the controller to stop, giving up\n");
+	}
+
+	/* Clean up the mess */
+	fotg210->rh_state = FOTG210_RH_HALTED;
+	fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
+	fotg210_work(fotg210);
+	end_unlink_async(fotg210);
+
+	/* Not in process context, so don't try to reset the controller */
+}
+
+
+/* Handle unlinked interrupt QHs once they are gone from the hardware */
+static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
+{
+	bool stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
+
+	/*
+	 * Process all the QHs on the intr_unlink list that were added
+	 * before the current unlink cycle began.  The list is in
+	 * temporal order, so stop when we reach the first entry in the
+	 * current cycle.  But if the root hub isn't running then
+	 * process all the QHs on the list.
+	 */
+	fotg210->intr_unlinking = true;
+	while (fotg210->intr_unlink) {
+		struct fotg210_qh *qh = fotg210->intr_unlink;
+
+		if (!stopped && qh->unlink_cycle == fotg210->intr_unlink_cycle)
+			break;
+		fotg210->intr_unlink = qh->unlink_next;
+		qh->unlink_next = NULL;
+		end_unlink_intr(fotg210, qh);
+	}
+
+	/* Handle remaining entries later */
+	if (fotg210->intr_unlink) {
+		fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
+				     true);
+		++fotg210->intr_unlink_cycle;
+	}
+	fotg210->intr_unlinking = false;
+}
+
+
+/* Start another free-iTDs/siTDs cycle */
+static void start_free_itds(struct fotg210_hcd *fotg210)
+{
+	if (!(fotg210->enabled_hrtimer_events &
+			BIT(FOTG210_HRTIMER_FREE_ITDS))) {
+		fotg210->last_itd_to_free = list_entry(
+				fotg210->cached_itd_list.prev,
+				struct fotg210_itd, itd_list);
+		fotg210_enable_event(fotg210, FOTG210_HRTIMER_FREE_ITDS, true);
+	}
+}
+
+/* Wait for controller to stop using old iTDs and siTDs */
+static void end_free_itds(struct fotg210_hcd *fotg210)
+{
+	struct fotg210_itd *itd, *n;
+
+	if (fotg210->rh_state < FOTG210_RH_RUNNING)
+		fotg210->last_itd_to_free = NULL;
+
+	list_for_each_entry_safe(itd, n, &fotg210->cached_itd_list, itd_list) {
+		list_del(&itd->itd_list);
+		dma_pool_free(fotg210->itd_pool, itd, itd->itd_dma);
+		if (itd == fotg210->last_itd_to_free)
+			break;
+	}
+
+	if (!list_empty(&fotg210->cached_itd_list))
+		start_free_itds(fotg210);
+}
+
+
+/* Handle lost (or very late) IAA interrupts */
+static void fotg210_iaa_watchdog(struct fotg210_hcd *fotg210)
+{
+	if (fotg210->rh_state != FOTG210_RH_RUNNING)
+		return;
+
+	/*
+	 * Lost IAA irqs wedge things badly; seen first with a vt8235.
+	 * So we need this watchdog, but must protect it against both
+	 * (a) SMP races against real IAA firing and retriggering, and
+	 * (b) clean HC shutdown, when IAA watchdog was pending.
+	 */
+	if (fotg210->async_iaa) {
+		u32 cmd, status;
+
+		/* If we get here, IAA is *REALLY* late.  It's barely
+		 * conceivable that the system is so busy that CMD_IAAD
+		 * is still legitimately set, so let's be sure it's
+		 * clear before we read STS_IAA.  (The HC should clear
+		 * CMD_IAAD when it sets STS_IAA.)
+		 */
+		cmd = fotg210_readl(fotg210, &fotg210->regs->command);
+
+		/*
+		 * If IAA is set here it either legitimately triggered
+		 * after the watchdog timer expired (_way_ late, so we'll
+		 * still count it as lost) ... or a silicon erratum:
+		 * - VIA seems to set IAA without triggering the IRQ;
+		 * - IAAD potentially cleared without setting IAA.
+		 */
+		status = fotg210_readl(fotg210, &fotg210->regs->status);
+		if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
+			COUNT(fotg210->stats.lost_iaa);
+			fotg210_writel(fotg210, STS_IAA,
+				       &fotg210->regs->status);
+		}
+
+		fotg210_dbg(fotg210, "IAA watchdog: status %x cmd %x\n",
+				status, cmd);
+		end_unlink_async(fotg210);
+	}
+}
+
+
+/* Enable the I/O watchdog, if appropriate */
+static void turn_on_io_watchdog(struct fotg210_hcd *fotg210)
+{
+	/* Not needed if the controller isn't running or it's already enabled */
+	if (fotg210->rh_state != FOTG210_RH_RUNNING ||
+			(fotg210->enabled_hrtimer_events &
+				BIT(FOTG210_HRTIMER_IO_WATCHDOG)))
+		return;
+
+	/*
+	 * Isochronous transfers always need the watchdog.
+	 * For other sorts we use it only if the flag is set.
+	 */
+	if (fotg210->isoc_count > 0 || (fotg210->need_io_watchdog &&
+			fotg210->async_count + fotg210->intr_count > 0))
+		fotg210_enable_event(fotg210, FOTG210_HRTIMER_IO_WATCHDOG,
+				     true);
+}
+
+
+/*
+ * Handler functions for the hrtimer event types.
+ * Keep this array in the same order as the event types indexed by
+ * enum fotg210_hrtimer_event in fotg210.h.
+ */
+static void (*event_handlers[])(struct fotg210_hcd *) = {
+	fotg210_poll_ASS,			/* FOTG210_HRTIMER_POLL_ASS */
+	fotg210_poll_PSS,			/* FOTG210_HRTIMER_POLL_PSS */
+	fotg210_handle_controller_death,	/* FOTG210_HRTIMER_POLL_DEAD */
+	fotg210_handle_intr_unlinks,	/* FOTG210_HRTIMER_UNLINK_INTR */
+	end_free_itds,			/* FOTG210_HRTIMER_FREE_ITDS */
+	unlink_empty_async,		/* FOTG210_HRTIMER_ASYNC_UNLINKS */
+	fotg210_iaa_watchdog,		/* FOTG210_HRTIMER_IAA_WATCHDOG */
+	fotg210_disable_PSE,		/* FOTG210_HRTIMER_DISABLE_PERIODIC */
+	fotg210_disable_ASE,		/* FOTG210_HRTIMER_DISABLE_ASYNC */
+	fotg210_work,			/* FOTG210_HRTIMER_IO_WATCHDOG */
+};
+
+static enum hrtimer_restart fotg210_hrtimer_func(struct hrtimer *t)
+{
+	struct fotg210_hcd *fotg210 =
+			container_of(t, struct fotg210_hcd, hrtimer);
+	ktime_t now;
+	unsigned long events;
+	unsigned long flags;
+	unsigned e;
+
+	spin_lock_irqsave(&fotg210->lock, flags);
+
+	events = fotg210->enabled_hrtimer_events;
+	fotg210->enabled_hrtimer_events = 0;
+	fotg210->next_hrtimer_event = FOTG210_HRTIMER_NO_EVENT;
+
+	/*
+	 * Check each pending event.  If its time has expired, handle
+	 * the event; otherwise re-enable it.
+	 */
+	now = ktime_get();
+	for_each_set_bit(e, &events, FOTG210_HRTIMER_NUM_EVENTS) {
+		if (now.tv64 >= fotg210->hr_timeouts[e].tv64)
+			event_handlers[e](fotg210);
+		else
+			fotg210_enable_event(fotg210, e, false);
+	}
+
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+	return HRTIMER_NORESTART;
+}
+
+#define fotg210_bus_suspend NULL
+#define fotg210_bus_resume NULL
+
+static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
+				u32 __iomem *status_reg, int port_status)
+{
+	if (!(port_status & PORT_CONNECT))
+		return port_status;
+
+	/* if reset finished and it's still not enabled -- handoff */
+	if (!(port_status & PORT_PE)) {
+		/* with integrated TT, there's nobody to hand it to! */
+		fotg210_dbg(fotg210,
+			"Failed to enable port %d on root hub TT\n",
+			index+1);
+		return port_status;
+	}
+	fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
+		    index + 1);
+
+	return port_status;
+}
+
+
+/* build "status change" packet (one or two bytes) from HC registers */
+
+static int fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 temp, status;
+	u32 mask;
+	int retval = 1;
+	unsigned long flags;
+
+	/* init status to no-changes */
+	buf[0] = 0;
+
+	/* Inform the core about resumes-in-progress by returning
+	 * a non-zero value even if there are no status changes.
+	 */
+	status = fotg210->resuming_ports;
+
+	mask = PORT_CSC | PORT_PEC;
+	/* PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND */
+
+	/* no hub change reports (bit 0) for now (power, ...) */
+
+	/* port N changes (bit N)? */
+	spin_lock_irqsave(&fotg210->lock, flags);
+
+	temp = fotg210_readl(fotg210, &fotg210->regs->port_status);
+
+	/*
+	 * Return status information even for ports with OWNER set.
+	 * Otherwise hub_wq wouldn't see the disconnect event when a
+	 * high-speed device is switched over to the companion
+	 * controller by the user.
+	 */
+
+	if ((temp & mask) != 0 || test_bit(0, &fotg210->port_c_suspend)
+			|| (fotg210->reset_done[0] && time_after_eq(
+				jiffies, fotg210->reset_done[0]))) {
+		buf[0] |= 1 << 1;
+		status = STS_PCD;
+	}
+	/* FIXME autosuspend idle root hubs */
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+	return status ? retval : 0;
+}
+
+static void fotg210_hub_descriptor(struct fotg210_hcd *fotg210,
+				   struct usb_hub_descriptor *desc)
+{
+	int ports = HCS_N_PORTS(fotg210->hcs_params);
+	u16 temp;
+
+	desc->bDescriptorType = USB_DT_HUB;
+	desc->bPwrOn2PwrGood = 10;	/* fotg210 1.0, 2.3.9 says 20ms max */
+	desc->bHubContrCurrent = 0;
+
+	desc->bNbrPorts = ports;
+	temp = 1 + (ports / 8);
+	desc->bDescLength = 7 + 2 * temp;
+
+	/* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
+	memset(&desc->u.hs.DeviceRemovable[0], 0, temp);
+	memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp);
+
+	temp = HUB_CHAR_INDV_PORT_OCPM;	/* per-port overcurrent reporting */
+	temp |= HUB_CHAR_NO_LPSM;	/* no power switching */
+	desc->wHubCharacteristics = cpu_to_le16(temp);
+}
+
+static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+			       u16 wIndex, char *buf, u16 wLength)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	int ports = HCS_N_PORTS(fotg210->hcs_params);
+	u32 __iomem *status_reg = &fotg210->regs->port_status;
+	u32 temp, temp1, status;
+	unsigned long flags;
+	int retval = 0;
+	unsigned selector;
+
+	/*
+	 * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
+	 * HCS_INDICATOR may say we can change LEDs to off/amber/green.
+	 * (track current state ourselves) ... blink for diagnostics,
+	 * power, "this is the one", etc.  EHCI spec supports this.
+	 */
+
+	spin_lock_irqsave(&fotg210->lock, flags);
+	switch (typeReq) {
+	case ClearHubFeature:
+		switch (wValue) {
+		case C_HUB_LOCAL_POWER:
+		case C_HUB_OVER_CURRENT:
+			/* no hub-wide feature/status flags */
+			break;
+		default:
+			goto error;
+		}
+		break;
+	case ClearPortFeature:
+		if (!wIndex || wIndex > ports)
+			goto error;
+		wIndex--;
+		temp = fotg210_readl(fotg210, status_reg);
+		temp &= ~PORT_RWC_BITS;
+
+		/*
+		 * Even if OWNER is set, so the port is owned by the
+		 * companion controller, hub_wq needs to be able to clear
+		 * the port-change status bits (especially
+		 * USB_PORT_STAT_C_CONNECTION).
+		 */
+
+		switch (wValue) {
+		case USB_PORT_FEAT_ENABLE:
+			fotg210_writel(fotg210, temp & ~PORT_PE, status_reg);
+			break;
+		case USB_PORT_FEAT_C_ENABLE:
+			fotg210_writel(fotg210, temp | PORT_PEC, status_reg);
+			break;
+		case USB_PORT_FEAT_SUSPEND:
+			if (temp & PORT_RESET)
+				goto error;
+			if (!(temp & PORT_SUSPEND))
+				break;
+			if ((temp & PORT_PE) == 0)
+				goto error;
+
+			/* resume signaling for 20 msec */
+			fotg210_writel(fotg210, temp | PORT_RESUME, status_reg);
+			fotg210->reset_done[wIndex] = jiffies
+					+ msecs_to_jiffies(USB_RESUME_TIMEOUT);
+			break;
+		case USB_PORT_FEAT_C_SUSPEND:
+			clear_bit(wIndex, &fotg210->port_c_suspend);
+			break;
+		case USB_PORT_FEAT_C_CONNECTION:
+			fotg210_writel(fotg210, temp | PORT_CSC, status_reg);
+			break;
+		case USB_PORT_FEAT_C_OVER_CURRENT:
+			fotg210_writel(fotg210, temp | OTGISR_OVC,
+				       &fotg210->regs->otgisr);
+			break;
+		case USB_PORT_FEAT_C_RESET:
+			/* GetPortStatus clears reset */
+			break;
+		default:
+			goto error;
+		}
+		fotg210_readl(fotg210, &fotg210->regs->command);
+		break;
+	case GetHubDescriptor:
+		fotg210_hub_descriptor(fotg210, (struct usb_hub_descriptor *)
+			buf);
+		break;
+	case GetHubStatus:
+		/* no hub-wide feature/status flags */
+		memset(buf, 0, 4);
+		/*cpu_to_le32s ((u32 *) buf); */
+		break;
+	case GetPortStatus:
+		if (!wIndex || wIndex > ports)
+			goto error;
+		wIndex--;
+		status = 0;
+		temp = fotg210_readl(fotg210, status_reg);
+
+		/* wPortChange bits */
+		if (temp & PORT_CSC)
+			status |= USB_PORT_STAT_C_CONNECTION << 16;
+		if (temp & PORT_PEC)
+			status |= USB_PORT_STAT_C_ENABLE << 16;
+
+		temp1 = fotg210_readl(fotg210, &fotg210->regs->otgisr);
+		if (temp1 & OTGISR_OVC)
+			status |= USB_PORT_STAT_C_OVERCURRENT << 16;
+
+		/* whoever resumes must GetPortStatus to complete it!! */
+		if (temp & PORT_RESUME) {
+
+			/* Remote Wakeup received? */
+			if (!fotg210->reset_done[wIndex]) {
+				/* resume signaling for 20 msec */
+				fotg210->reset_done[wIndex] = jiffies
+						+ msecs_to_jiffies(20);
+				/* check the port again */
+				mod_timer(&fotg210_to_hcd(fotg210)->rh_timer,
+						fotg210->reset_done[wIndex]);
+			}
+
+			/* resume completed? */
+			else if (time_after_eq(jiffies,
+					fotg210->reset_done[wIndex])) {
+				clear_bit(wIndex, &fotg210->suspended_ports);
+				set_bit(wIndex, &fotg210->port_c_suspend);
+				fotg210->reset_done[wIndex] = 0;
+
+				/* stop resume signaling */
+				temp = fotg210_readl(fotg210, status_reg);
+				fotg210_writel(fotg210,
+					temp & ~(PORT_RWC_BITS | PORT_RESUME),
+					status_reg);
+				clear_bit(wIndex, &fotg210->resuming_ports);
+				retval = handshake(fotg210, status_reg,
+					   PORT_RESUME, 0, 2000 /* 2msec */);
+				if (retval != 0) {
+					fotg210_err(fotg210,
+						"port %d resume error %d\n",
+						wIndex + 1, retval);
+					goto error;
+				}
+				temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
+			}
+		}
+
+		/* whoever resets must GetPortStatus to complete it!! */
+		if ((temp & PORT_RESET)
+				&& time_after_eq(jiffies,
+					fotg210->reset_done[wIndex])) {
+			status |= USB_PORT_STAT_C_RESET << 16;
+			fotg210->reset_done[wIndex] = 0;
+			clear_bit(wIndex, &fotg210->resuming_ports);
+
+			/* force reset to complete */
+			fotg210_writel(fotg210,
+				       temp & ~(PORT_RWC_BITS | PORT_RESET),
+				       status_reg);
+			/* REVISIT:  some hardware needs 550+ usec to clear
+			 * this bit; seems too long to spin routinely...
+			 */
+			retval = handshake(fotg210, status_reg,
+					PORT_RESET, 0, 1000);
+			if (retval != 0) {
+				fotg210_err(fotg210, "port %d reset error %d\n",
+					wIndex + 1, retval);
+				goto error;
+			}
+
+			/* see what we found out */
+			temp = check_reset_complete(fotg210, wIndex, status_reg,
+					fotg210_readl(fotg210, status_reg));
+		}
+
+		if (!(temp & (PORT_RESUME|PORT_RESET))) {
+			fotg210->reset_done[wIndex] = 0;
+			clear_bit(wIndex, &fotg210->resuming_ports);
+		}
+
+		/* transfer dedicated ports to the companion hc */
+		if ((temp & PORT_CONNECT) &&
+				test_bit(wIndex, &fotg210->companion_ports)) {
+			temp &= ~PORT_RWC_BITS;
+			fotg210_writel(fotg210, temp, status_reg);
+			fotg210_dbg(fotg210, "port %d --> companion\n",
+				    wIndex + 1);
+			temp = fotg210_readl(fotg210, status_reg);
+		}
+
+		/*
+		 * Even if OWNER is set, there's no harm letting hub_wq
+		 * see the wPortStatus values (they should all be 0 except
+		 * for PORT_POWER anyway).
+		 */
+
+		if (temp & PORT_CONNECT) {
+			status |= USB_PORT_STAT_CONNECTION;
+			status |= fotg210_port_speed(fotg210, temp);
+		}
+		if (temp & PORT_PE)
+			status |= USB_PORT_STAT_ENABLE;
+
+		/* maybe the port was unsuspended without our knowledge */
+		if (temp & (PORT_SUSPEND|PORT_RESUME)) {
+			status |= USB_PORT_STAT_SUSPEND;
+		} else if (test_bit(wIndex, &fotg210->suspended_ports)) {
+			clear_bit(wIndex, &fotg210->suspended_ports);
+			clear_bit(wIndex, &fotg210->resuming_ports);
+			fotg210->reset_done[wIndex] = 0;
+			if (temp & PORT_PE)
+				set_bit(wIndex, &fotg210->port_c_suspend);
+		}
+
+		temp1 = fotg210_readl(fotg210, &fotg210->regs->otgisr);
+		if (temp1 & OTGISR_OVC)
+			status |= USB_PORT_STAT_OVERCURRENT;
+		if (temp & PORT_RESET)
+			status |= USB_PORT_STAT_RESET;
+		if (test_bit(wIndex, &fotg210->port_c_suspend))
+			status |= USB_PORT_STAT_C_SUSPEND << 16;
+
+		if (status & ~0xffff)	/* only if wPortChange is interesting */
+			dbg_port(fotg210, "GetStatus", wIndex + 1, temp);
+		put_unaligned_le32(status, buf);
+		break;
+	case SetHubFeature:
+		switch (wValue) {
+		case C_HUB_LOCAL_POWER:
+		case C_HUB_OVER_CURRENT:
+			/* no hub-wide feature/status flags */
+			break;
+		default:
+			goto error;
+		}
+		break;
+	case SetPortFeature:
+		selector = wIndex >> 8;
+		wIndex &= 0xff;
+
+		if (!wIndex || wIndex > ports)
+			goto error;
+		wIndex--;
+		temp = fotg210_readl(fotg210, status_reg);
+		temp &= ~PORT_RWC_BITS;
+		switch (wValue) {
+		case USB_PORT_FEAT_SUSPEND:
+			if ((temp & PORT_PE) == 0
+					|| (temp & PORT_RESET) != 0)
+				goto error;
+
+			/* After above check the port must be connected.
+			 * Set appropriate bit thus could put phy into low power
+			 * mode if we have hostpc feature
+			 */
+			fotg210_writel(fotg210, temp | PORT_SUSPEND,
+				       status_reg);
+			set_bit(wIndex, &fotg210->suspended_ports);
+			break;
+		case USB_PORT_FEAT_RESET:
+			if (temp & PORT_RESUME)
+				goto error;
+			/* line status bits may report this as low speed,
+			 * which can be fine if this root hub has a
+			 * transaction translator built in.
+			 */
+			fotg210_dbg(fotg210, "port %d reset\n", wIndex + 1);
+			temp |= PORT_RESET;
+			temp &= ~PORT_PE;
+
+			/*
+			 * caller must wait, then call GetPortStatus
+			 * usb 2.0 spec says 50 ms resets on root
+			 */
+			fotg210->reset_done[wIndex] = jiffies
+					+ msecs_to_jiffies(50);
+			fotg210_writel(fotg210, temp, status_reg);
+			break;
+
+		/* For downstream facing ports (these):  one hub port is put
+		 * into test mode according to USB2 11.24.2.13, then the hub
+		 * must be reset (which for root hub now means rmmod+modprobe,
+		 * or else system reboot).  See EHCI 2.3.9 and 4.14 for info
+		 * about the EHCI-specific stuff.
+		 */
+		case USB_PORT_FEAT_TEST:
+			if (!selector || selector > 5)
+				goto error;
+			spin_unlock_irqrestore(&fotg210->lock, flags);
+			fotg210_quiesce(fotg210);
+			spin_lock_irqsave(&fotg210->lock, flags);
+
+			/* Put all enabled ports into suspend */
+			temp = fotg210_readl(fotg210, status_reg) &
+				~PORT_RWC_BITS;
+			if (temp & PORT_PE)
+				fotg210_writel(fotg210, temp | PORT_SUSPEND,
+						status_reg);
+
+			spin_unlock_irqrestore(&fotg210->lock, flags);
+			fotg210_halt(fotg210);
+			spin_lock_irqsave(&fotg210->lock, flags);
+
+			temp = fotg210_readl(fotg210, status_reg);
+			temp |= selector << 16;
+			fotg210_writel(fotg210, temp, status_reg);
+			break;
+
+		default:
+			goto error;
+		}
+		fotg210_readl(fotg210, &fotg210->regs->command);
+		break;
+
+	default:
+error:
+		/* "stall" on error */
+		retval = -EPIPE;
+	}
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+	return retval;
+}
+
+static void __maybe_unused fotg210_relinquish_port(struct usb_hcd *hcd,
+		int portnum)
+{
+	return;
+}
+
+static int __maybe_unused fotg210_port_handed_over(struct usb_hcd *hcd,
+						   int portnum)
+{
+	return 0;
+}
+
+/*
+ * There's basically three types of memory:
+ *	- data used only by the HCD ... kmalloc is fine
+ *	- async and periodic schedules, shared by HC and HCD ... these
+ *	  need to use dma_pool or dma_alloc_coherent
+ *	- driver buffers, read/written by HC ... single shot DMA mapped
+ *
+ * There's also "register" data (e.g. PCI or SOC), which is memory mapped.
+ * No memory seen by this driver is pageable.
+ */
+
+/* Allocate the key transfer structures from the previously allocated pool */
+static inline void fotg210_qtd_init(struct fotg210_hcd *fotg210,
+				    struct fotg210_qtd *qtd, dma_addr_t dma)
+{
+	memset(qtd, 0, sizeof(*qtd));
+	qtd->qtd_dma = dma;
+	qtd->hw_token = cpu_to_hc32(fotg210, QTD_STS_HALT);
+	qtd->hw_next = FOTG210_LIST_END(fotg210);
+	qtd->hw_alt_next = FOTG210_LIST_END(fotg210);
+	INIT_LIST_HEAD(&qtd->qtd_list);
+}
+
+static struct fotg210_qtd *fotg210_qtd_alloc(struct fotg210_hcd *fotg210,
+					     gfp_t flags)
+{
+	struct fotg210_qtd *qtd;
+	dma_addr_t dma;
+
+	qtd = dma_pool_alloc(fotg210->qtd_pool, flags, &dma);
+	if (qtd != NULL)
+		fotg210_qtd_init(fotg210, qtd, dma);
+
+	return qtd;
+}
+
+static inline void fotg210_qtd_free(struct fotg210_hcd *fotg210,
+				    struct fotg210_qtd *qtd)
+{
+	dma_pool_free(fotg210->qtd_pool, qtd, qtd->qtd_dma);
+}
+
+
+static void qh_destroy(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+{
+	/* clean qtds first, and know this is not linked */
+	if (!list_empty(&qh->qtd_list) || qh->qh_next.ptr) {
+		fotg210_dbg(fotg210, "unused qh not empty!\n");
+		BUG();
+	}
+	if (qh->dummy)
+		fotg210_qtd_free(fotg210, qh->dummy);
+	dma_pool_free(fotg210->qh_pool, qh->hw, qh->qh_dma);
+	kfree(qh);
+}
+
+static struct fotg210_qh *fotg210_qh_alloc(struct fotg210_hcd *fotg210,
+					   gfp_t flags)
+{
+	struct fotg210_qh *qh;
+	dma_addr_t dma;
+
+	qh = kzalloc(sizeof(*qh), GFP_ATOMIC);
+	if (!qh)
+		goto done;
+	qh->hw = (struct fotg210_qh_hw *)
+		dma_pool_alloc(fotg210->qh_pool, flags, &dma);
+	if (!qh->hw)
+		goto fail;
+	memset(qh->hw, 0, sizeof(*qh->hw));
+	qh->qh_dma = dma;
+	INIT_LIST_HEAD(&qh->qtd_list);
+
+	/* dummy td enables safe urb queuing */
+	qh->dummy = fotg210_qtd_alloc(fotg210, flags);
+	if (qh->dummy == NULL) {
+		fotg210_dbg(fotg210, "no dummy td\n");
+		goto fail1;
+	}
+done:
+	return qh;
+fail1:
+	dma_pool_free(fotg210->qh_pool, qh->hw, qh->qh_dma);
+fail:
+	kfree(qh);
+	return NULL;
+}
+
+/* The queue heads and transfer descriptors are managed from pools tied
+ * to each of the "per device" structures.
+ * This is the initialisation and cleanup code.
+ */
+
+static void fotg210_mem_cleanup(struct fotg210_hcd *fotg210)
+{
+	if (fotg210->async)
+		qh_destroy(fotg210, fotg210->async);
+	fotg210->async = NULL;
+
+	if (fotg210->dummy)
+		qh_destroy(fotg210, fotg210->dummy);
+	fotg210->dummy = NULL;
+
+	/* DMA consistent memory and pools */
+	dma_pool_destroy(fotg210->qtd_pool);
+	fotg210->qtd_pool = NULL;
+
+	dma_pool_destroy(fotg210->qh_pool);
+	fotg210->qh_pool = NULL;
+
+	dma_pool_destroy(fotg210->itd_pool);
+	fotg210->itd_pool = NULL;
+
+	if (fotg210->periodic)
+		dma_free_coherent(fotg210_to_hcd(fotg210)->self.controller,
+			fotg210->periodic_size * sizeof(u32),
+			fotg210->periodic, fotg210->periodic_dma);
+	fotg210->periodic = NULL;
+
+	/* shadow periodic table */
+	kfree(fotg210->pshadow);
+	fotg210->pshadow = NULL;
+}
+
+/* remember to add cleanup code (above) if you add anything here */
+static int fotg210_mem_init(struct fotg210_hcd *fotg210, gfp_t flags)
+{
+	int i;
+
+	/* QTDs for control/bulk/intr transfers */
+	fotg210->qtd_pool = dma_pool_create("fotg210_qtd",
+			fotg210_to_hcd(fotg210)->self.controller,
+			sizeof(struct fotg210_qtd),
+			32 /* byte alignment (for hw parts) */,
+			4096 /* can't cross 4K */);
+	if (!fotg210->qtd_pool)
+		goto fail;
+
+	/* QHs for control/bulk/intr transfers */
+	fotg210->qh_pool = dma_pool_create("fotg210_qh",
+			fotg210_to_hcd(fotg210)->self.controller,
+			sizeof(struct fotg210_qh_hw),
+			32 /* byte alignment (for hw parts) */,
+			4096 /* can't cross 4K */);
+	if (!fotg210->qh_pool)
+		goto fail;
+
+	fotg210->async = fotg210_qh_alloc(fotg210, flags);
+	if (!fotg210->async)
+		goto fail;
+
+	/* ITD for high speed ISO transfers */
+	fotg210->itd_pool = dma_pool_create("fotg210_itd",
+			fotg210_to_hcd(fotg210)->self.controller,
+			sizeof(struct fotg210_itd),
+			64 /* byte alignment (for hw parts) */,
+			4096 /* can't cross 4K */);
+	if (!fotg210->itd_pool)
+		goto fail;
+
+	/* Hardware periodic table */
+	fotg210->periodic = (__le32 *)
+		dma_alloc_coherent(fotg210_to_hcd(fotg210)->self.controller,
+			fotg210->periodic_size * sizeof(__le32),
+			&fotg210->periodic_dma, 0);
+	if (fotg210->periodic == NULL)
+		goto fail;
+
+	for (i = 0; i < fotg210->periodic_size; i++)
+		fotg210->periodic[i] = FOTG210_LIST_END(fotg210);
+
+	/* software shadow of hardware table */
+	fotg210->pshadow = kcalloc(fotg210->periodic_size, sizeof(void *),
+				   flags);
+	if (fotg210->pshadow != NULL)
+		return 0;
+
+fail:
+	fotg210_dbg(fotg210, "couldn't init memory\n");
+	fotg210_mem_cleanup(fotg210);
+	return -ENOMEM;
+}
+/*
+ * EHCI hardware queue manipulation ... the core.  QH/QTD manipulation.
+ *
+ * Control, bulk, and interrupt traffic all use "qh" lists.  They list "qtd"
+ * entries describing USB transactions, max 16-20kB/entry (with 4kB-aligned
+ * buffers needed for the larger number).  We use one QH per endpoint, queue
+ * multiple urbs (all three types) per endpoint.  URBs may need several qtds.
+ *
+ * ISO traffic uses "ISO TD" (itd) records, and (along with
+ * interrupts) needs careful scheduling.  Performance improvements can be
+ * an ongoing challenge.  That's in "ehci-sched.c".
+ *
+ * USB 1.1 devices are handled (a) by "companion" OHCI or UHCI root hubs,
+ * or otherwise through transaction translators (TTs) in USB 2.0 hubs using
+ * (b) special fields in qh entries or (c) split iso entries.  TTs will
+ * buffer low/full speed data so the host collects it at high speed.
+ */
+
+/* fill a qtd, returning how much of the buffer we were able to queue up */
+static int qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd,
+		    dma_addr_t buf, size_t len, int token, int maxpacket)
+{
+	int i, count;
+	u64 addr = buf;
+
+	/* one buffer entry per 4K ... first might be short or unaligned */
+	qtd->hw_buf[0] = cpu_to_hc32(fotg210, (u32)addr);
+	qtd->hw_buf_hi[0] = cpu_to_hc32(fotg210, (u32)(addr >> 32));
+	count = 0x1000 - (buf & 0x0fff);	/* rest of that page */
+	if (likely(len < count))		/* ... iff needed */
+		count = len;
+	else {
+		buf +=  0x1000;
+		buf &= ~0x0fff;
+
+		/* per-qtd limit: from 16K to 20K (best alignment) */
+		for (i = 1; count < len && i < 5; i++) {
+			addr = buf;
+			qtd->hw_buf[i] = cpu_to_hc32(fotg210, (u32)addr);
+			qtd->hw_buf_hi[i] = cpu_to_hc32(fotg210,
+					(u32)(addr >> 32));
+			buf += 0x1000;
+			if ((count + 0x1000) < len)
+				count += 0x1000;
+			else
+				count = len;
+		}
+
+		/* short packets may only terminate transfers */
+		if (count != len)
+			count -= (count % maxpacket);
+	}
+	qtd->hw_token = cpu_to_hc32(fotg210, (count << 16) | token);
+	qtd->length = count;
+
+	return count;
+}
+
+static inline void qh_update(struct fotg210_hcd *fotg210,
+			     struct fotg210_qh *qh,
+			     struct fotg210_qtd *qtd)
+{
+	struct fotg210_qh_hw *hw = qh->hw;
+
+	/* writes to an active overlay are unsafe */
+	BUG_ON(qh->qh_state != QH_STATE_IDLE);
+
+	hw->hw_qtd_next = QTD_NEXT(fotg210, qtd->qtd_dma);
+	hw->hw_alt_next = FOTG210_LIST_END(fotg210);
+
+	/* Except for control endpoints, we make hardware maintain data
+	 * toggle (like OHCI) ... here (re)initialize the toggle in the QH,
+	 * and set the pseudo-toggle in udev. Only usb_clear_halt() will
+	 * ever clear it.
+	 */
+	if (!(hw->hw_info1 & cpu_to_hc32(fotg210, QH_TOGGLE_CTL))) {
+		unsigned is_out, epnum;
+
+		is_out = qh->is_out;
+		epnum = (hc32_to_cpup(fotg210, &hw->hw_info1) >> 8) & 0x0f;
+		if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) {
+			hw->hw_token &= ~cpu_to_hc32(fotg210, QTD_TOGGLE);
+			usb_settoggle(qh->dev, epnum, is_out, 1);
+		}
+	}
+
+	hw->hw_token &= cpu_to_hc32(fotg210, QTD_TOGGLE | QTD_STS_PING);
+}
+
+/* if it weren't for a common silicon quirk (writing the dummy into the qh
+ * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault
+ * recovery (including urb dequeue) would need software changes to a QH...
+ */
+static void qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+{
+	struct fotg210_qtd *qtd;
+
+	if (list_empty(&qh->qtd_list))
+		qtd = qh->dummy;
+	else {
+		qtd = list_entry(qh->qtd_list.next,
+				struct fotg210_qtd, qtd_list);
+		/*
+		 * first qtd may already be partially processed.
+		 * If we come here during unlink, the QH overlay region
+		 * might have reference to the just unlinked qtd. The
+		 * qtd is updated in qh_completions(). Update the QH
+		 * overlay here.
+		 */
+		if (cpu_to_hc32(fotg210, qtd->qtd_dma) == qh->hw->hw_current) {
+			qh->hw->hw_qtd_next = qtd->hw_next;
+			qtd = NULL;
+		}
+	}
+
+	if (qtd)
+		qh_update(fotg210, qh, qtd);
+}
+
+static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
+
+static void fotg210_clear_tt_buffer_complete(struct usb_hcd *hcd,
+					     struct usb_host_endpoint *ep)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_qh *qh = ep->hcpriv;
+	unsigned long flags;
+
+	spin_lock_irqsave(&fotg210->lock, flags);
+	qh->clearing_tt = 0;
+	if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list)
+			&& fotg210->rh_state == FOTG210_RH_RUNNING)
+		qh_link_async(fotg210, qh);
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+}
+
+static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
+				    struct fotg210_qh *qh,
+				    struct urb *urb, u32 token)
+{
+
+	/* If an async split transaction gets an error or is unlinked,
+	 * the TT buffer may be left in an indeterminate state.  We
+	 * have to clear the TT buffer.
+	 *
+	 * Note: this routine is never called for Isochronous transfers.
+	 */
+	if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
+		struct usb_device *tt = urb->dev->tt->hub;
+
+		dev_dbg(&tt->dev,
+			"clear tt buffer port %d, a%d ep%d t%08x\n",
+			urb->dev->ttport, urb->dev->devnum,
+			usb_pipeendpoint(urb->pipe), token);
+
+		if (urb->dev->tt->hub !=
+		    fotg210_to_hcd(fotg210)->self.root_hub) {
+			if (usb_hub_clear_tt_buffer(urb) == 0)
+				qh->clearing_tt = 1;
+		}
+	}
+}
+
+static int qtd_copy_status(struct fotg210_hcd *fotg210, struct urb *urb,
+			   size_t length, u32 token)
+{
+	int status = -EINPROGRESS;
+
+	/* count IN/OUT bytes, not SETUP (even short packets) */
+	if (likely(QTD_PID(token) != 2))
+		urb->actual_length += length - QTD_LENGTH(token);
+
+	/* don't modify error codes */
+	if (unlikely(urb->unlinked))
+		return status;
+
+	/* force cleanup after short read; not always an error */
+	if (unlikely(IS_SHORT_READ(token)))
+		status = -EREMOTEIO;
+
+	/* serious "can't proceed" faults reported by the hardware */
+	if (token & QTD_STS_HALT) {
+		if (token & QTD_STS_BABBLE) {
+			/* FIXME "must" disable babbling device's port too */
+			status = -EOVERFLOW;
+		/* CERR nonzero + halt --> stall */
+		} else if (QTD_CERR(token)) {
+			status = -EPIPE;
+
+		/* In theory, more than one of the following bits can be set
+		 * since they are sticky and the transaction is retried.
+		 * Which to test first is rather arbitrary.
+		 */
+		} else if (token & QTD_STS_MMF) {
+			/* fs/ls interrupt xfer missed the complete-split */
+			status = -EPROTO;
+		} else if (token & QTD_STS_DBE) {
+			status = (QTD_PID(token) == 1) /* IN ? */
+				? -ENOSR  /* hc couldn't read data */
+				: -ECOMM; /* hc couldn't write data */
+		} else if (token & QTD_STS_XACT) {
+			/* timeout, bad CRC, wrong PID, etc */
+			fotg210_dbg(fotg210, "devpath %s ep%d%s 3strikes\n",
+				urb->dev->devpath,
+				usb_pipeendpoint(urb->pipe),
+				usb_pipein(urb->pipe) ? "in" : "out");
+			status = -EPROTO;
+		} else {	/* unknown */
+			status = -EPROTO;
+		}
+
+		fotg210_dbg(fotg210,
+			"dev%d ep%d%s qtd token %08x --> status %d\n",
+			usb_pipedevice(urb->pipe),
+			usb_pipeendpoint(urb->pipe),
+			usb_pipein(urb->pipe) ? "in" : "out",
+			token, status);
+	}
+
+	return status;
+}
+
+static void fotg210_urb_done(struct fotg210_hcd *fotg210, struct urb *urb,
+			     int status)
+__releases(fotg210->lock)
+__acquires(fotg210->lock)
+{
+	if (likely(urb->hcpriv != NULL)) {
+		struct fotg210_qh *qh = (struct fotg210_qh *) urb->hcpriv;
+
+		/* S-mask in a QH means it's an interrupt urb */
+		if ((qh->hw->hw_info2 & cpu_to_hc32(fotg210, QH_SMASK)) != 0) {
+
+			/* ... update hc-wide periodic stats (for usbfs) */
+			fotg210_to_hcd(fotg210)->self.bandwidth_int_reqs--;
+		}
+	}
+
+	if (unlikely(urb->unlinked)) {
+		COUNT(fotg210->stats.unlink);
+	} else {
+		/* report non-error and short read status as zero */
+		if (status == -EINPROGRESS || status == -EREMOTEIO)
+			status = 0;
+		COUNT(fotg210->stats.complete);
+	}
+
+#ifdef FOTG210_URB_TRACE
+	fotg210_dbg(fotg210,
+		"%s %s urb %p ep%d%s status %d len %d/%d\n",
+		__func__, urb->dev->devpath, urb,
+		usb_pipeendpoint(urb->pipe),
+		usb_pipein(urb->pipe) ? "in" : "out",
+		status,
+		urb->actual_length, urb->transfer_buffer_length);
+#endif
+
+	/* complete() can reenter this HCD */
+	usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
+	spin_unlock(&fotg210->lock);
+	usb_hcd_giveback_urb(fotg210_to_hcd(fotg210), urb, status);
+	spin_lock(&fotg210->lock);
+}
+
+static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
+
+/*
+ * Process and free completed qtds for a qh, returning URBs to drivers.
+ * Chases up to qh->hw_current.  Returns number of completions called,
+ * indicating how much "real" work we did.
+ */
+static unsigned qh_completions(struct fotg210_hcd *fotg210,
+			       struct fotg210_qh *qh)
+{
+	struct fotg210_qtd *last, *end = qh->dummy;
+	struct list_head *entry, *tmp;
+	int last_status;
+	int stopped;
+	unsigned count = 0;
+	u8 state;
+	struct fotg210_qh_hw *hw = qh->hw;
+
+	if (unlikely(list_empty(&qh->qtd_list)))
+		return count;
+
+	/* completions (or tasks on other cpus) must never clobber HALT
+	 * till we've gone through and cleaned everything up, even when
+	 * they add urbs to this qh's queue or mark them for unlinking.
+	 *
+	 * NOTE:  unlinking expects to be done in queue order.
+	 *
+	 * It's a bug for qh->qh_state to be anything other than
+	 * QH_STATE_IDLE, unless our caller is scan_async() or
+	 * scan_intr().
+	 */
+	state = qh->qh_state;
+	qh->qh_state = QH_STATE_COMPLETING;
+	stopped = (state == QH_STATE_IDLE);
+
+rescan:
+	last = NULL;
+	last_status = -EINPROGRESS;
+	qh->needs_rescan = 0;
+
+	/* remove de-activated QTDs from front of queue.
+	 * after faults (including short reads), cleanup this urb
+	 * then let the queue advance.
+	 * if queue is stopped, handles unlinks.
+	 */
+	list_for_each_safe(entry, tmp, &qh->qtd_list) {
+		struct fotg210_qtd *qtd;
+		struct urb *urb;
+		u32 token = 0;
+
+		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
+		urb = qtd->urb;
+
+		/* clean up any state from previous QTD ...*/
+		if (last) {
+			if (likely(last->urb != urb)) {
+				fotg210_urb_done(fotg210, last->urb,
+						 last_status);
+				count++;
+				last_status = -EINPROGRESS;
+			}
+			fotg210_qtd_free(fotg210, last);
+			last = NULL;
+		}
+
+		/* ignore urbs submitted during completions we reported */
+		if (qtd == end)
+			break;
+
+		/* hardware copies qtd out of qh overlay */
+		rmb();
+		token = hc32_to_cpu(fotg210, qtd->hw_token);
+
+		/* always clean up qtds the hc de-activated */
+retry_xacterr:
+		if ((token & QTD_STS_ACTIVE) == 0) {
+
+			/* Report Data Buffer Error: non-fatal but useful */
+			if (token & QTD_STS_DBE)
+				fotg210_dbg(fotg210,
+					"detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n",
+					urb,
+					usb_endpoint_num(&urb->ep->desc),
+					usb_endpoint_dir_in(&urb->ep->desc)
+						? "in" : "out",
+					urb->transfer_buffer_length,
+					qtd,
+					qh);
+
+			/* on STALL, error, and short reads this urb must
+			 * complete and all its qtds must be recycled.
+			 */
+			if ((token & QTD_STS_HALT) != 0) {
+
+				/* retry transaction errors until we
+				 * reach the software xacterr limit
+				 */
+				if ((token & QTD_STS_XACT) &&
+					QTD_CERR(token) == 0 &&
+					++qh->xacterrs < QH_XACTERR_MAX &&
+					!urb->unlinked) {
+					fotg210_dbg(fotg210,
+	"detected XactErr len %zu/%zu retry %d\n",
+	qtd->length - QTD_LENGTH(token), qtd->length, qh->xacterrs);
+
+					/* reset the token in the qtd and the
+					 * qh overlay (which still contains
+					 * the qtd) so that we pick up from
+					 * where we left off
+					 */
+					token &= ~QTD_STS_HALT;
+					token |= QTD_STS_ACTIVE |
+						 (FOTG210_TUNE_CERR << 10);
+					qtd->hw_token = cpu_to_hc32(fotg210,
+							token);
+					wmb();
+					hw->hw_token = cpu_to_hc32(fotg210,
+							token);
+					goto retry_xacterr;
+				}
+				stopped = 1;
+
+			/* magic dummy for some short reads; qh won't advance.
+			 * that silicon quirk can kick in with this dummy too.
+			 *
+			 * other short reads won't stop the queue, including
+			 * control transfers (status stage handles that) or
+			 * most other single-qtd reads ... the queue stops if
+			 * URB_SHORT_NOT_OK was set so the driver submitting
+			 * the urbs could clean it up.
+			 */
+			} else if (IS_SHORT_READ(token)
+					&& !(qtd->hw_alt_next
+						& FOTG210_LIST_END(fotg210))) {
+				stopped = 1;
+			}
+
+		/* stop scanning when we reach qtds the hc is using */
+		} else if (likely(!stopped
+				&& fotg210->rh_state >= FOTG210_RH_RUNNING)) {
+			break;
+
+		/* scan the whole queue for unlinks whenever it stops */
+		} else {
+			stopped = 1;
+
+			/* cancel everything if we halt, suspend, etc */
+			if (fotg210->rh_state < FOTG210_RH_RUNNING)
+				last_status = -ESHUTDOWN;
+
+			/* this qtd is active; skip it unless a previous qtd
+			 * for its urb faulted, or its urb was canceled.
+			 */
+			else if (last_status == -EINPROGRESS && !urb->unlinked)
+				continue;
+
+			/* qh unlinked; token in overlay may be most current */
+			if (state == QH_STATE_IDLE
+					&& cpu_to_hc32(fotg210, qtd->qtd_dma)
+						== hw->hw_current) {
+				token = hc32_to_cpu(fotg210, hw->hw_token);
+
+				/* An unlink may leave an incomplete
+				 * async transaction in the TT buffer.
+				 * We have to clear it.
+				 */
+				fotg210_clear_tt_buffer(fotg210, qh, urb,
+							token);
+			}
+		}
+
+		/* unless we already know the urb's status, collect qtd status
+		 * and update count of bytes transferred.  in common short read
+		 * cases with only one data qtd (including control transfers),
+		 * queue processing won't halt.  but with two or more qtds (for
+		 * example, with a 32 KB transfer), when the first qtd gets a
+		 * short read the second must be removed by hand.
+		 */
+		if (last_status == -EINPROGRESS) {
+			last_status = qtd_copy_status(fotg210, urb,
+					qtd->length, token);
+			if (last_status == -EREMOTEIO
+					&& (qtd->hw_alt_next
+						& FOTG210_LIST_END(fotg210)))
+				last_status = -EINPROGRESS;
+
+			/* As part of low/full-speed endpoint-halt processing
+			 * we must clear the TT buffer (11.17.5).
+			 */
+			if (unlikely(last_status != -EINPROGRESS &&
+					last_status != -EREMOTEIO)) {
+				/* The TT's in some hubs malfunction when they
+				 * receive this request following a STALL (they
+				 * stop sending isochronous packets).  Since a
+				 * STALL can't leave the TT buffer in a busy
+				 * state (if you believe Figures 11-48 - 11-51
+				 * in the USB 2.0 spec), we won't clear the TT
+				 * buffer in this case.  Strictly speaking this
+				 * is a violation of the spec.
+				 */
+				if (last_status != -EPIPE)
+					fotg210_clear_tt_buffer(fotg210, qh,
+								urb, token);
+			}
+		}
+
+		/* if we're removing something not at the queue head,
+		 * patch the hardware queue pointer.
+		 */
+		if (stopped && qtd->qtd_list.prev != &qh->qtd_list) {
+			last = list_entry(qtd->qtd_list.prev,
+					struct fotg210_qtd, qtd_list);
+			last->hw_next = qtd->hw_next;
+		}
+
+		/* remove qtd; it's recycled after possible urb completion */
+		list_del(&qtd->qtd_list);
+		last = qtd;
+
+		/* reinit the xacterr counter for the next qtd */
+		qh->xacterrs = 0;
+	}
+
+	/* last urb's completion might still need calling */
+	if (likely(last != NULL)) {
+		fotg210_urb_done(fotg210, last->urb, last_status);
+		count++;
+		fotg210_qtd_free(fotg210, last);
+	}
+
+	/* Do we need to rescan for URBs dequeued during a giveback? */
+	if (unlikely(qh->needs_rescan)) {
+		/* If the QH is already unlinked, do the rescan now. */
+		if (state == QH_STATE_IDLE)
+			goto rescan;
+
+		/* Otherwise we have to wait until the QH is fully unlinked.
+		 * Our caller will start an unlink if qh->needs_rescan is
+		 * set.  But if an unlink has already started, nothing needs
+		 * to be done.
+		 */
+		if (state != QH_STATE_LINKED)
+			qh->needs_rescan = 0;
+	}
+
+	/* restore original state; caller must unlink or relink */
+	qh->qh_state = state;
+
+	/* be sure the hardware's done with the qh before refreshing
+	 * it after fault cleanup, or recovering from silicon wrongly
+	 * overlaying the dummy qtd (which reduces DMA chatter).
+	 */
+	if (stopped != 0 || hw->hw_qtd_next == FOTG210_LIST_END(fotg210)) {
+		switch (state) {
+		case QH_STATE_IDLE:
+			qh_refresh(fotg210, qh);
+			break;
+		case QH_STATE_LINKED:
+			/* We won't refresh a QH that's linked (after the HC
+			 * stopped the queue).  That avoids a race:
+			 *  - HC reads first part of QH;
+			 *  - CPU updates that first part and the token;
+			 *  - HC reads rest of that QH, including token
+			 * Result:  HC gets an inconsistent image, and then
+			 * DMAs to/from the wrong memory (corrupting it).
+			 *
+			 * That should be rare for interrupt transfers,
+			 * except maybe high bandwidth ...
+			 */
+
+			/* Tell the caller to start an unlink */
+			qh->needs_rescan = 1;
+			break;
+		/* otherwise, unlink already started */
+		}
+	}
+
+	return count;
+}
+
+/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
+#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
+/* ... and packet size, for any kind of endpoint descriptor */
+#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
+
+/*
+ * reverse of qh_urb_transaction:  free a list of TDs.
+ * used for cleanup after errors, before HC sees an URB's TDs.
+ */
+static void qtd_list_free(struct fotg210_hcd *fotg210, struct urb *urb,
+			  struct list_head *qtd_list)
+{
+	struct list_head *entry, *temp;
+
+	list_for_each_safe(entry, temp, qtd_list) {
+		struct fotg210_qtd *qtd;
+
+		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
+		list_del(&qtd->qtd_list);
+		fotg210_qtd_free(fotg210, qtd);
+	}
+}
+
+/*
+ * create a list of filled qtds for this URB; won't link into qh.
+ */
+static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
+					    struct urb *urb,
+					    struct list_head *head,
+					    gfp_t flags)
+{
+	struct fotg210_qtd *qtd, *qtd_prev;
+	dma_addr_t buf;
+	int len, this_sg_len, maxpacket;
+	int is_input;
+	u32 token;
+	int i;
+	struct scatterlist *sg;
+
+	/*
+	 * URBs map to sequences of QTDs:  one logical transaction
+	 */
+	qtd = fotg210_qtd_alloc(fotg210, flags);
+	if (unlikely(!qtd))
+		return NULL;
+	list_add_tail(&qtd->qtd_list, head);
+	qtd->urb = urb;
+
+	token = QTD_STS_ACTIVE;
+	token |= (FOTG210_TUNE_CERR << 10);
+	/* for split transactions, SplitXState initialized to zero */
+
+	len = urb->transfer_buffer_length;
+	is_input = usb_pipein(urb->pipe);
+	if (usb_pipecontrol(urb->pipe)) {
+		/* SETUP pid */
+		qtd_fill(fotg210, qtd, urb->setup_dma,
+				sizeof(struct usb_ctrlrequest),
+				token | (2 /* "setup" */ << 8), 8);
+
+		/* ... and always at least one more pid */
+		token ^= QTD_TOGGLE;
+		qtd_prev = qtd;
+		qtd = fotg210_qtd_alloc(fotg210, flags);
+		if (unlikely(!qtd))
+			goto cleanup;
+		qtd->urb = urb;
+		qtd_prev->hw_next = QTD_NEXT(fotg210, qtd->qtd_dma);
+		list_add_tail(&qtd->qtd_list, head);
+
+		/* for zero length DATA stages, STATUS is always IN */
+		if (len == 0)
+			token |= (1 /* "in" */ << 8);
+	}
+
+	/*
+	 * data transfer stage:  buffer setup
+	 */
+	i = urb->num_mapped_sgs;
+	if (len > 0 && i > 0) {
+		sg = urb->sg;
+		buf = sg_dma_address(sg);
+
+		/* urb->transfer_buffer_length may be smaller than the
+		 * size of the scatterlist (or vice versa)
+		 */
+		this_sg_len = min_t(int, sg_dma_len(sg), len);
+	} else {
+		sg = NULL;
+		buf = urb->transfer_dma;
+		this_sg_len = len;
+	}
+
+	if (is_input)
+		token |= (1 /* "in" */ << 8);
+	/* else it's already initted to "out" pid (0 << 8) */
+
+	maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input));
+
+	/*
+	 * buffer gets wrapped in one or more qtds;
+	 * last one may be "short" (including zero len)
+	 * and may serve as a control status ack
+	 */
+	for (;;) {
+		int this_qtd_len;
+
+		this_qtd_len = qtd_fill(fotg210, qtd, buf, this_sg_len, token,
+				maxpacket);
+		this_sg_len -= this_qtd_len;
+		len -= this_qtd_len;
+		buf += this_qtd_len;
+
+		/*
+		 * short reads advance to a "magic" dummy instead of the next
+		 * qtd ... that forces the queue to stop, for manual cleanup.
+		 * (this will usually be overridden later.)
+		 */
+		if (is_input)
+			qtd->hw_alt_next = fotg210->async->hw->hw_alt_next;
+
+		/* qh makes control packets use qtd toggle; maybe switch it */
+		if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
+			token ^= QTD_TOGGLE;
+
+		if (likely(this_sg_len <= 0)) {
+			if (--i <= 0 || len <= 0)
+				break;
+			sg = sg_next(sg);
+			buf = sg_dma_address(sg);
+			this_sg_len = min_t(int, sg_dma_len(sg), len);
+		}
+
+		qtd_prev = qtd;
+		qtd = fotg210_qtd_alloc(fotg210, flags);
+		if (unlikely(!qtd))
+			goto cleanup;
+		qtd->urb = urb;
+		qtd_prev->hw_next = QTD_NEXT(fotg210, qtd->qtd_dma);
+		list_add_tail(&qtd->qtd_list, head);
+	}
+
+	/*
+	 * unless the caller requires manual cleanup after short reads,
+	 * have the alt_next mechanism keep the queue running after the
+	 * last data qtd (the only one, for control and most other cases).
+	 */
+	if (likely((urb->transfer_flags & URB_SHORT_NOT_OK) == 0
+				|| usb_pipecontrol(urb->pipe)))
+		qtd->hw_alt_next = FOTG210_LIST_END(fotg210);
+
+	/*
+	 * control requests may need a terminating data "status" ack;
+	 * other OUT ones may need a terminating short packet
+	 * (zero length).
+	 */
+	if (likely(urb->transfer_buffer_length != 0)) {
+		int one_more = 0;
+
+		if (usb_pipecontrol(urb->pipe)) {
+			one_more = 1;
+			token ^= 0x0100;	/* "in" <--> "out"  */
+			token |= QTD_TOGGLE;	/* force DATA1 */
+		} else if (usb_pipeout(urb->pipe)
+				&& (urb->transfer_flags & URB_ZERO_PACKET)
+				&& !(urb->transfer_buffer_length % maxpacket)) {
+			one_more = 1;
+		}
+		if (one_more) {
+			qtd_prev = qtd;
+			qtd = fotg210_qtd_alloc(fotg210, flags);
+			if (unlikely(!qtd))
+				goto cleanup;
+			qtd->urb = urb;
+			qtd_prev->hw_next = QTD_NEXT(fotg210, qtd->qtd_dma);
+			list_add_tail(&qtd->qtd_list, head);
+
+			/* never any data in such packets */
+			qtd_fill(fotg210, qtd, 0, 0, token, 0);
+		}
+	}
+
+	/* by default, enable interrupt on urb completion */
+	if (likely(!(urb->transfer_flags & URB_NO_INTERRUPT)))
+		qtd->hw_token |= cpu_to_hc32(fotg210, QTD_IOC);
+	return head;
+
+cleanup:
+	qtd_list_free(fotg210, urb, head);
+	return NULL;
+}
+
+/*
+ * Would be best to create all qh's from config descriptors,
+ * when each interface/altsetting is established.  Unlink
+ * any previous qh and cancel its urbs first; endpoints are
+ * implicitly reset then (data toggle too).
+ * That'd mean updating how usbcore talks to HCDs. (2.7?)
+*/
+
+
+/*
+ * Each QH holds a qtd list; a QH is used for everything except iso.
+ *
+ * For interrupt urbs, the scheduler must set the microframe scheduling
+ * mask(s) each time the QH gets scheduled.  For highspeed, that's
+ * just one microframe in the s-mask.  For split interrupt transactions
+ * there are additional complications: c-mask, maybe FSTNs.
+ */
+static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
+				  gfp_t flags)
+{
+	struct fotg210_qh *qh = fotg210_qh_alloc(fotg210, flags);
+	u32 info1 = 0, info2 = 0;
+	int is_input, type;
+	int maxp = 0;
+	struct usb_tt *tt = urb->dev->tt;
+	struct fotg210_qh_hw *hw;
+
+	if (!qh)
+		return qh;
+
+	/*
+	 * init endpoint/device data for this QH
+	 */
+	info1 |= usb_pipeendpoint(urb->pipe) << 8;
+	info1 |= usb_pipedevice(urb->pipe) << 0;
+
+	is_input = usb_pipein(urb->pipe);
+	type = usb_pipetype(urb->pipe);
+	maxp = usb_maxpacket(urb->dev, urb->pipe, !is_input);
+
+	/* 1024 byte maxpacket is a hardware ceiling.  High bandwidth
+	 * acts like up to 3KB, but is built from smaller packets.
+	 */
+	if (max_packet(maxp) > 1024) {
+		fotg210_dbg(fotg210, "bogus qh maxpacket %d\n",
+			    max_packet(maxp));
+		goto done;
+	}
+
+	/* Compute interrupt scheduling parameters just once, and save.
+	 * - allowing for high bandwidth, how many nsec/uframe are used?
+	 * - split transactions need a second CSPLIT uframe; same question
+	 * - splits also need a schedule gap (for full/low speed I/O)
+	 * - qh has a polling interval
+	 *
+	 * For control/bulk requests, the HC or TT handles these.
+	 */
+	if (type == PIPE_INTERRUPT) {
+		qh->usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH,
+				is_input, 0,
+				hb_mult(maxp) * max_packet(maxp)));
+		qh->start = NO_FRAME;
+
+		if (urb->dev->speed == USB_SPEED_HIGH) {
+			qh->c_usecs = 0;
+			qh->gap_uf = 0;
+
+			qh->period = urb->interval >> 3;
+			if (qh->period == 0 && urb->interval != 1) {
+				/* NOTE interval 2 or 4 uframes could work.
+				 * But interval 1 scheduling is simpler, and
+				 * includes high bandwidth.
+				 */
+				urb->interval = 1;
+			} else if (qh->period > fotg210->periodic_size) {
+				qh->period = fotg210->periodic_size;
+				urb->interval = qh->period << 3;
+			}
+		} else {
+			int think_time;
+
+			/* gap is f(FS/LS transfer times) */
+			qh->gap_uf = 1 + usb_calc_bus_time(urb->dev->speed,
+					is_input, 0, maxp) / (125 * 1000);
+
+			/* FIXME this just approximates SPLIT/CSPLIT times */
+			if (is_input) {		/* SPLIT, gap, CSPLIT+DATA */
+				qh->c_usecs = qh->usecs + HS_USECS(0);
+				qh->usecs = HS_USECS(1);
+			} else {		/* SPLIT+DATA, gap, CSPLIT */
+				qh->usecs += HS_USECS(1);
+				qh->c_usecs = HS_USECS(0);
+			}
+
+			think_time = tt ? tt->think_time : 0;
+			qh->tt_usecs = NS_TO_US(think_time +
+					usb_calc_bus_time(urb->dev->speed,
+					is_input, 0, max_packet(maxp)));
+			qh->period = urb->interval;
+			if (qh->period > fotg210->periodic_size) {
+				qh->period = fotg210->periodic_size;
+				urb->interval = qh->period;
+			}
+		}
+	}
+
+	/* support for tt scheduling, and access to toggles */
+	qh->dev = urb->dev;
+
+	/* using TT? */
+	switch (urb->dev->speed) {
+	case USB_SPEED_LOW:
+		info1 |= QH_LOW_SPEED;
+		/* FALL THROUGH */
+
+	case USB_SPEED_FULL:
+		/* EPS 0 means "full" */
+		if (type != PIPE_INTERRUPT)
+			info1 |= (FOTG210_TUNE_RL_TT << 28);
+		if (type == PIPE_CONTROL) {
+			info1 |= QH_CONTROL_EP;		/* for TT */
+			info1 |= QH_TOGGLE_CTL;		/* toggle from qtd */
+		}
+		info1 |= maxp << 16;
+
+		info2 |= (FOTG210_TUNE_MULT_TT << 30);
+
+		/* Some Freescale processors have an erratum in which the
+		 * port number in the queue head was 0..N-1 instead of 1..N.
+		 */
+		if (fotg210_has_fsl_portno_bug(fotg210))
+			info2 |= (urb->dev->ttport-1) << 23;
+		else
+			info2 |= urb->dev->ttport << 23;
+
+		/* set the address of the TT; for TDI's integrated
+		 * root hub tt, leave it zeroed.
+		 */
+		if (tt && tt->hub != fotg210_to_hcd(fotg210)->self.root_hub)
+			info2 |= tt->hub->devnum << 16;
+
+		/* NOTE:  if (PIPE_INTERRUPT) { scheduler sets c-mask } */
+
+		break;
+
+	case USB_SPEED_HIGH:		/* no TT involved */
+		info1 |= QH_HIGH_SPEED;
+		if (type == PIPE_CONTROL) {
+			info1 |= (FOTG210_TUNE_RL_HS << 28);
+			info1 |= 64 << 16;	/* usb2 fixed maxpacket */
+			info1 |= QH_TOGGLE_CTL;	/* toggle from qtd */
+			info2 |= (FOTG210_TUNE_MULT_HS << 30);
+		} else if (type == PIPE_BULK) {
+			info1 |= (FOTG210_TUNE_RL_HS << 28);
+			/* The USB spec says that high speed bulk endpoints
+			 * always use 512 byte maxpacket.  But some device
+			 * vendors decided to ignore that, and MSFT is happy
+			 * to help them do so.  So now people expect to use
+			 * such nonconformant devices with Linux too; sigh.
+			 */
+			info1 |= max_packet(maxp) << 16;
+			info2 |= (FOTG210_TUNE_MULT_HS << 30);
+		} else {		/* PIPE_INTERRUPT */
+			info1 |= max_packet(maxp) << 16;
+			info2 |= hb_mult(maxp) << 30;
+		}
+		break;
+	default:
+		fotg210_dbg(fotg210, "bogus dev %p speed %d\n", urb->dev,
+			urb->dev->speed);
+done:
+		qh_destroy(fotg210, qh);
+		return NULL;
+	}
+
+	/* NOTE:  if (PIPE_INTERRUPT) { scheduler sets s-mask } */
+
+	/* init as live, toggle clear, advance to dummy */
+	qh->qh_state = QH_STATE_IDLE;
+	hw = qh->hw;
+	hw->hw_info1 = cpu_to_hc32(fotg210, info1);
+	hw->hw_info2 = cpu_to_hc32(fotg210, info2);
+	qh->is_out = !is_input;
+	usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), !is_input, 1);
+	qh_refresh(fotg210, qh);
+	return qh;
+}
+
+static void enable_async(struct fotg210_hcd *fotg210)
+{
+	if (fotg210->async_count++)
+		return;
+
+	/* Stop waiting to turn off the async schedule */
+	fotg210->enabled_hrtimer_events &= ~BIT(FOTG210_HRTIMER_DISABLE_ASYNC);
+
+	/* Don't start the schedule until ASS is 0 */
+	fotg210_poll_ASS(fotg210);
+	turn_on_io_watchdog(fotg210);
+}
+
+static void disable_async(struct fotg210_hcd *fotg210)
+{
+	if (--fotg210->async_count)
+		return;
+
+	/* The async schedule and async_unlink list are supposed to be empty */
+	WARN_ON(fotg210->async->qh_next.qh || fotg210->async_unlink);
+
+	/* Don't turn off the schedule until ASS is 1 */
+	fotg210_poll_ASS(fotg210);
+}
+
+/* move qh (and its qtds) onto async queue; maybe enable queue.  */
+
+static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+{
+	__hc32 dma = QH_NEXT(fotg210, qh->qh_dma);
+	struct fotg210_qh *head;
+
+	/* Don't link a QH if there's a Clear-TT-Buffer pending */
+	if (unlikely(qh->clearing_tt))
+		return;
+
+	WARN_ON(qh->qh_state != QH_STATE_IDLE);
+
+	/* clear halt and/or toggle; and maybe recover from silicon quirk */
+	qh_refresh(fotg210, qh);
+
+	/* splice right after start */
+	head = fotg210->async;
+	qh->qh_next = head->qh_next;
+	qh->hw->hw_next = head->hw->hw_next;
+	wmb();
+
+	head->qh_next.qh = qh;
+	head->hw->hw_next = dma;
+
+	qh->xacterrs = 0;
+	qh->qh_state = QH_STATE_LINKED;
+	/* qtd completions reported later by interrupt */
+
+	enable_async(fotg210);
+}
+
+/*
+ * For control/bulk/interrupt, return QH with these TDs appended.
+ * Allocates and initializes the QH if necessary.
+ * Returns null if it can't allocate a QH it needs to.
+ * If the QH has TDs (urbs) already, that's great.
+ */
+static struct fotg210_qh *qh_append_tds(struct fotg210_hcd *fotg210,
+					struct urb *urb,
+					struct list_head *qtd_list, int epnum,
+					void **ptr)
+{
+	struct fotg210_qh *qh = NULL;
+	__hc32 qh_addr_mask = cpu_to_hc32(fotg210, 0x7f);
+
+	qh = (struct fotg210_qh *) *ptr;
+	if (unlikely(qh == NULL)) {
+		/* can't sleep here, we have fotg210->lock... */
+		qh = qh_make(fotg210, urb, GFP_ATOMIC);
+		*ptr = qh;
+	}
+	if (likely(qh != NULL)) {
+		struct fotg210_qtd *qtd;
+
+		if (unlikely(list_empty(qtd_list)))
+			qtd = NULL;
+		else
+			qtd = list_entry(qtd_list->next, struct fotg210_qtd,
+					qtd_list);
+
+		/* control qh may need patching ... */
+		if (unlikely(epnum == 0)) {
+			/* usb_reset_device() briefly reverts to address 0 */
+			if (usb_pipedevice(urb->pipe) == 0)
+				qh->hw->hw_info1 &= ~qh_addr_mask;
+		}
+
+		/* just one way to queue requests: swap with the dummy qtd.
+		 * only hc or qh_refresh() ever modify the overlay.
+		 */
+		if (likely(qtd != NULL)) {
+			struct fotg210_qtd *dummy;
+			dma_addr_t dma;
+			__hc32 token;
+
+			/* to avoid racing the HC, use the dummy td instead of
+			 * the first td of our list (becomes new dummy).  both
+			 * tds stay deactivated until we're done, when the
+			 * HC is allowed to fetch the old dummy (4.10.2).
+			 */
+			token = qtd->hw_token;
+			qtd->hw_token = HALT_BIT(fotg210);
+
+			dummy = qh->dummy;
+
+			dma = dummy->qtd_dma;
+			*dummy = *qtd;
+			dummy->qtd_dma = dma;
+
+			list_del(&qtd->qtd_list);
+			list_add(&dummy->qtd_list, qtd_list);
+			list_splice_tail(qtd_list, &qh->qtd_list);
+
+			fotg210_qtd_init(fotg210, qtd, qtd->qtd_dma);
+			qh->dummy = qtd;
+
+			/* hc must see the new dummy at list end */
+			dma = qtd->qtd_dma;
+			qtd = list_entry(qh->qtd_list.prev,
+					struct fotg210_qtd, qtd_list);
+			qtd->hw_next = QTD_NEXT(fotg210, dma);
+
+			/* let the hc process these next qtds */
+			wmb();
+			dummy->hw_token = token;
+
+			urb->hcpriv = qh;
+		}
+	}
+	return qh;
+}
+
+static int submit_async(struct fotg210_hcd *fotg210, struct urb *urb,
+			struct list_head *qtd_list, gfp_t mem_flags)
+{
+	int epnum;
+	unsigned long flags;
+	struct fotg210_qh *qh = NULL;
+	int rc;
+
+	epnum = urb->ep->desc.bEndpointAddress;
+
+#ifdef FOTG210_URB_TRACE
+	{
+		struct fotg210_qtd *qtd;
+
+		qtd = list_entry(qtd_list->next, struct fotg210_qtd, qtd_list);
+		fotg210_dbg(fotg210,
+			 "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
+			 __func__, urb->dev->devpath, urb,
+			 epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
+			 urb->transfer_buffer_length,
+			 qtd, urb->ep->hcpriv);
+	}
+#endif
+
+	spin_lock_irqsave(&fotg210->lock, flags);
+	if (unlikely(!HCD_HW_ACCESSIBLE(fotg210_to_hcd(fotg210)))) {
+		rc = -ESHUTDOWN;
+		goto done;
+	}
+	rc = usb_hcd_link_urb_to_ep(fotg210_to_hcd(fotg210), urb);
+	if (unlikely(rc))
+		goto done;
+
+	qh = qh_append_tds(fotg210, urb, qtd_list, epnum, &urb->ep->hcpriv);
+	if (unlikely(qh == NULL)) {
+		usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
+		rc = -ENOMEM;
+		goto done;
+	}
+
+	/* Control/bulk operations through TTs don't need scheduling,
+	 * the HC and TT handle it when the TT has a buffer ready.
+	 */
+	if (likely(qh->qh_state == QH_STATE_IDLE))
+		qh_link_async(fotg210, qh);
+done:
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+	if (unlikely(qh == NULL))
+		qtd_list_free(fotg210, urb, qtd_list);
+	return rc;
+}
+
+static void single_unlink_async(struct fotg210_hcd *fotg210,
+				struct fotg210_qh *qh)
+{
+	struct fotg210_qh *prev;
+
+	/* Add to the end of the list of QHs waiting for the next IAAD */
+	qh->qh_state = QH_STATE_UNLINK;
+	if (fotg210->async_unlink)
+		fotg210->async_unlink_last->unlink_next = qh;
+	else
+		fotg210->async_unlink = qh;
+	fotg210->async_unlink_last = qh;
+
+	/* Unlink it from the schedule */
+	prev = fotg210->async;
+	while (prev->qh_next.qh != qh)
+		prev = prev->qh_next.qh;
+
+	prev->hw->hw_next = qh->hw->hw_next;
+	prev->qh_next = qh->qh_next;
+	if (fotg210->qh_scan_next == qh)
+		fotg210->qh_scan_next = qh->qh_next.qh;
+}
+
+static void start_iaa_cycle(struct fotg210_hcd *fotg210, bool nested)
+{
+	/*
+	 * Do nothing if an IAA cycle is already running or
+	 * if one will be started shortly.
+	 */
+	if (fotg210->async_iaa || fotg210->async_unlinking)
+		return;
+
+	/* Do all the waiting QHs at once */
+	fotg210->async_iaa = fotg210->async_unlink;
+	fotg210->async_unlink = NULL;
+
+	/* If the controller isn't running, we don't have to wait for it */
+	if (unlikely(fotg210->rh_state < FOTG210_RH_RUNNING)) {
+		if (!nested)		/* Avoid recursion */
+			end_unlink_async(fotg210);
+
+	/* Otherwise start a new IAA cycle */
+	} else if (likely(fotg210->rh_state == FOTG210_RH_RUNNING)) {
+		/* Make sure the unlinks are all visible to the hardware */
+		wmb();
+
+		fotg210_writel(fotg210, fotg210->command | CMD_IAAD,
+				&fotg210->regs->command);
+		fotg210_readl(fotg210, &fotg210->regs->command);
+		fotg210_enable_event(fotg210, FOTG210_HRTIMER_IAA_WATCHDOG,
+				     true);
+	}
+}
+
+/* the async qh for the qtds being unlinked are now gone from the HC */
+
+static void end_unlink_async(struct fotg210_hcd *fotg210)
+{
+	struct fotg210_qh *qh;
+
+	/* Process the idle QHs */
+restart:
+	fotg210->async_unlinking = true;
+	while (fotg210->async_iaa) {
+		qh = fotg210->async_iaa;
+		fotg210->async_iaa = qh->unlink_next;
+		qh->unlink_next = NULL;
+
+		qh->qh_state = QH_STATE_IDLE;
+		qh->qh_next.qh = NULL;
+
+		qh_completions(fotg210, qh);
+		if (!list_empty(&qh->qtd_list) &&
+				fotg210->rh_state == FOTG210_RH_RUNNING)
+			qh_link_async(fotg210, qh);
+		disable_async(fotg210);
+	}
+	fotg210->async_unlinking = false;
+
+	/* Start a new IAA cycle if any QHs are waiting for it */
+	if (fotg210->async_unlink) {
+		start_iaa_cycle(fotg210, true);
+		if (unlikely(fotg210->rh_state < FOTG210_RH_RUNNING))
+			goto restart;
+	}
+}
+
+static void unlink_empty_async(struct fotg210_hcd *fotg210)
+{
+	struct fotg210_qh *qh, *next;
+	bool stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
+	bool check_unlinks_later = false;
+
+	/* Unlink all the async QHs that have been empty for a timer cycle */
+	next = fotg210->async->qh_next.qh;
+	while (next) {
+		qh = next;
+		next = qh->qh_next.qh;
+
+		if (list_empty(&qh->qtd_list) &&
+				qh->qh_state == QH_STATE_LINKED) {
+			if (!stopped && qh->unlink_cycle ==
+					fotg210->async_unlink_cycle)
+				check_unlinks_later = true;
+			else
+				single_unlink_async(fotg210, qh);
+		}
+	}
+
+	/* Start a new IAA cycle if any QHs are waiting for it */
+	if (fotg210->async_unlink)
+		start_iaa_cycle(fotg210, false);
+
+	/* QHs that haven't been empty for long enough will be handled later */
+	if (check_unlinks_later) {
+		fotg210_enable_event(fotg210, FOTG210_HRTIMER_ASYNC_UNLINKS,
+				     true);
+		++fotg210->async_unlink_cycle;
+	}
+}
+
+/* makes sure the async qh will become idle */
+/* caller must own fotg210->lock */
+
+static void start_unlink_async(struct fotg210_hcd *fotg210,
+			       struct fotg210_qh *qh)
+{
+	/*
+	 * If the QH isn't linked then there's nothing we can do
+	 * unless we were called during a giveback, in which case
+	 * qh_completions() has to deal with it.
+	 */
+	if (qh->qh_state != QH_STATE_LINKED) {
+		if (qh->qh_state == QH_STATE_COMPLETING)
+			qh->needs_rescan = 1;
+		return;
+	}
+
+	single_unlink_async(fotg210, qh);
+	start_iaa_cycle(fotg210, false);
+}
+
+static void scan_async(struct fotg210_hcd *fotg210)
+{
+	struct fotg210_qh *qh;
+	bool check_unlinks_later = false;
+
+	fotg210->qh_scan_next = fotg210->async->qh_next.qh;
+	while (fotg210->qh_scan_next) {
+		qh = fotg210->qh_scan_next;
+		fotg210->qh_scan_next = qh->qh_next.qh;
+rescan:
+		/* clean any finished work for this qh */
+		if (!list_empty(&qh->qtd_list)) {
+			int temp;
+
+			/*
+			 * Unlinks could happen here; completion reporting
+			 * drops the lock.  That's why fotg210->qh_scan_next
+			 * always holds the next qh to scan; if the next qh
+			 * gets unlinked then fotg210->qh_scan_next is adjusted
+			 * in single_unlink_async().
+			 */
+			temp = qh_completions(fotg210, qh);
+			if (qh->needs_rescan) {
+				start_unlink_async(fotg210, qh);
+			} else if (list_empty(&qh->qtd_list)
+					&& qh->qh_state == QH_STATE_LINKED) {
+				qh->unlink_cycle = fotg210->async_unlink_cycle;
+				check_unlinks_later = true;
+			} else if (temp != 0)
+				goto rescan;
+		}
+	}
+
+	/*
+	 * Unlink empty entries, reducing DMA usage as well
+	 * as HCD schedule-scanning costs.  Delay for any qh
+	 * we just scanned, there's a not-unusual case that it
+	 * doesn't stay idle for long.
+	 */
+	if (check_unlinks_later && fotg210->rh_state == FOTG210_RH_RUNNING &&
+			!(fotg210->enabled_hrtimer_events &
+				BIT(FOTG210_HRTIMER_ASYNC_UNLINKS))) {
+		fotg210_enable_event(fotg210,
+				     FOTG210_HRTIMER_ASYNC_UNLINKS, true);
+		++fotg210->async_unlink_cycle;
+	}
+}
+/*
+ * EHCI scheduled transaction support:  interrupt, iso, split iso
+ * These are called "periodic" transactions in the EHCI spec.
+ *
+ * Note that for interrupt transfers, the QH/QTD manipulation is shared
+ * with the "asynchronous" transaction support (control/bulk transfers).
+ * The only real difference is in how interrupt transfers are scheduled.
+ *
+ * For ISO, we make an "iso_stream" head to serve the same role as a QH.
+ * It keeps track of every ITD (or SITD) that's linked, and holds enough
+ * pre-calculated schedule data to make appending to the queue be quick.
+ */
+static int fotg210_get_frame(struct usb_hcd *hcd);
+
+/*
+ * periodic_next_shadow - return "next" pointer on shadow list
+ * @periodic: host pointer to qh/itd
+ * @tag: hardware tag for type of this record
+ */
+static union fotg210_shadow *periodic_next_shadow(struct fotg210_hcd *fotg210,
+						union fotg210_shadow *periodic,
+						__hc32 tag)
+{
+	switch (hc32_to_cpu(fotg210, tag)) {
+	case Q_TYPE_QH:
+		return &periodic->qh->qh_next;
+	case Q_TYPE_FSTN:
+		return &periodic->fstn->fstn_next;
+	default:
+		return &periodic->itd->itd_next;
+	}
+}
+
+static __hc32 *shadow_next_periodic(struct fotg210_hcd *fotg210,
+				    union fotg210_shadow *periodic, __hc32 tag)
+{
+	switch (hc32_to_cpu(fotg210, tag)) {
+	/* our fotg210_shadow.qh is actually software part */
+	case Q_TYPE_QH:
+		return &periodic->qh->hw->hw_next;
+	/* others are hw parts */
+	default:
+		return periodic->hw_next;
+	}
+}
+
+/* caller must hold fotg210->lock */
+static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
+			    void *ptr)
+{
+	union fotg210_shadow *prev_p = &fotg210->pshadow[frame];
+	__hc32 *hw_p = &fotg210->periodic[frame];
+	union fotg210_shadow here = *prev_p;
+
+	/* find predecessor of "ptr"; hw and shadow lists are in sync */
+	while (here.ptr && here.ptr != ptr) {
+		prev_p = periodic_next_shadow(fotg210, prev_p,
+				Q_NEXT_TYPE(fotg210, *hw_p));
+		hw_p = shadow_next_periodic(fotg210, &here,
+				Q_NEXT_TYPE(fotg210, *hw_p));
+		here = *prev_p;
+	}
+	/* an interrupt entry (at list end) could have been shared */
+	if (!here.ptr)
+		return;
+
+	/* update shadow and hardware lists ... the old "next" pointers
+	 * from ptr may still be in use, the caller updates them.
+	 */
+	*prev_p = *periodic_next_shadow(fotg210, &here,
+			Q_NEXT_TYPE(fotg210, *hw_p));
+
+	*hw_p = *shadow_next_periodic(fotg210, &here,
+				Q_NEXT_TYPE(fotg210, *hw_p));
+}
+
+/* how many of the uframe's 125 usecs are allocated? */
+static unsigned short periodic_usecs(struct fotg210_hcd *fotg210,
+				     unsigned frame, unsigned uframe)
+{
+	__hc32 *hw_p = &fotg210->periodic[frame];
+	union fotg210_shadow *q = &fotg210->pshadow[frame];
+	unsigned usecs = 0;
+	struct fotg210_qh_hw *hw;
+
+	while (q->ptr) {
+		switch (hc32_to_cpu(fotg210, Q_NEXT_TYPE(fotg210, *hw_p))) {
+		case Q_TYPE_QH:
+			hw = q->qh->hw;
+			/* is it in the S-mask? */
+			if (hw->hw_info2 & cpu_to_hc32(fotg210, 1 << uframe))
+				usecs += q->qh->usecs;
+			/* ... or C-mask? */
+			if (hw->hw_info2 & cpu_to_hc32(fotg210,
+					1 << (8 + uframe)))
+				usecs += q->qh->c_usecs;
+			hw_p = &hw->hw_next;
+			q = &q->qh->qh_next;
+			break;
+		/* case Q_TYPE_FSTN: */
+		default:
+			/* for "save place" FSTNs, count the relevant INTR
+			 * bandwidth from the previous frame
+			 */
+			if (q->fstn->hw_prev != FOTG210_LIST_END(fotg210))
+				fotg210_dbg(fotg210, "ignoring FSTN cost ...\n");
+
+			hw_p = &q->fstn->hw_next;
+			q = &q->fstn->fstn_next;
+			break;
+		case Q_TYPE_ITD:
+			if (q->itd->hw_transaction[uframe])
+				usecs += q->itd->stream->usecs;
+			hw_p = &q->itd->hw_next;
+			q = &q->itd->itd_next;
+			break;
+		}
+	}
+	if (usecs > fotg210->uframe_periodic_max)
+		fotg210_err(fotg210, "uframe %d sched overrun: %d usecs\n",
+			frame * 8 + uframe, usecs);
+	return usecs;
+}
+
+static int same_tt(struct usb_device *dev1, struct usb_device *dev2)
+{
+	if (!dev1->tt || !dev2->tt)
+		return 0;
+	if (dev1->tt != dev2->tt)
+		return 0;
+	if (dev1->tt->multi)
+		return dev1->ttport == dev2->ttport;
+	else
+		return 1;
+}
+
+/* return true iff the device's transaction translator is available
+ * for a periodic transfer starting at the specified frame, using
+ * all the uframes in the mask.
+ */
+static int tt_no_collision(struct fotg210_hcd *fotg210, unsigned period,
+			   struct usb_device *dev, unsigned frame, u32 uf_mask)
+{
+	if (period == 0)	/* error */
+		return 0;
+
+	/* note bandwidth wastage:  split never follows csplit
+	 * (different dev or endpoint) until the next uframe.
+	 * calling convention doesn't make that distinction.
+	 */
+	for (; frame < fotg210->periodic_size; frame += period) {
+		union fotg210_shadow here;
+		__hc32 type;
+		struct fotg210_qh_hw *hw;
+
+		here = fotg210->pshadow[frame];
+		type = Q_NEXT_TYPE(fotg210, fotg210->periodic[frame]);
+		while (here.ptr) {
+			switch (hc32_to_cpu(fotg210, type)) {
+			case Q_TYPE_ITD:
+				type = Q_NEXT_TYPE(fotg210, here.itd->hw_next);
+				here = here.itd->itd_next;
+				continue;
+			case Q_TYPE_QH:
+				hw = here.qh->hw;
+				if (same_tt(dev, here.qh->dev)) {
+					u32 mask;
+
+					mask = hc32_to_cpu(fotg210,
+							hw->hw_info2);
+					/* "knows" no gap is needed */
+					mask |= mask >> 8;
+					if (mask & uf_mask)
+						break;
+				}
+				type = Q_NEXT_TYPE(fotg210, hw->hw_next);
+				here = here.qh->qh_next;
+				continue;
+			/* case Q_TYPE_FSTN: */
+			default:
+				fotg210_dbg(fotg210,
+					"periodic frame %d bogus type %d\n",
+					frame, type);
+			}
+
+			/* collision or error */
+			return 0;
+		}
+	}
+
+	/* no collision */
+	return 1;
+}
+
+static void enable_periodic(struct fotg210_hcd *fotg210)
+{
+	if (fotg210->periodic_count++)
+		return;
+
+	/* Stop waiting to turn off the periodic schedule */
+	fotg210->enabled_hrtimer_events &=
+		~BIT(FOTG210_HRTIMER_DISABLE_PERIODIC);
+
+	/* Don't start the schedule until PSS is 0 */
+	fotg210_poll_PSS(fotg210);
+	turn_on_io_watchdog(fotg210);
+}
+
+static void disable_periodic(struct fotg210_hcd *fotg210)
+{
+	if (--fotg210->periodic_count)
+		return;
+
+	/* Don't turn off the schedule until PSS is 1 */
+	fotg210_poll_PSS(fotg210);
+}
+
+/* periodic schedule slots have iso tds (normal or split) first, then a
+ * sparse tree for active interrupt transfers.
+ *
+ * this just links in a qh; caller guarantees uframe masks are set right.
+ * no FSTN support (yet; fotg210 0.96+)
+ */
+static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+{
+	unsigned i;
+	unsigned period = qh->period;
+
+	dev_dbg(&qh->dev->dev,
+		"link qh%d-%04x/%p start %d [%d/%d us]\n",
+		period, hc32_to_cpup(fotg210, &qh->hw->hw_info2)
+			& (QH_CMASK | QH_SMASK),
+		qh, qh->start, qh->usecs, qh->c_usecs);
+
+	/* high bandwidth, or otherwise every microframe */
+	if (period == 0)
+		period = 1;
+
+	for (i = qh->start; i < fotg210->periodic_size; i += period) {
+		union fotg210_shadow *prev = &fotg210->pshadow[i];
+		__hc32 *hw_p = &fotg210->periodic[i];
+		union fotg210_shadow here = *prev;
+		__hc32 type = 0;
+
+		/* skip the iso nodes at list head */
+		while (here.ptr) {
+			type = Q_NEXT_TYPE(fotg210, *hw_p);
+			if (type == cpu_to_hc32(fotg210, Q_TYPE_QH))
+				break;
+			prev = periodic_next_shadow(fotg210, prev, type);
+			hw_p = shadow_next_periodic(fotg210, &here, type);
+			here = *prev;
+		}
+
+		/* sorting each branch by period (slow-->fast)
+		 * enables sharing interior tree nodes
+		 */
+		while (here.ptr && qh != here.qh) {
+			if (qh->period > here.qh->period)
+				break;
+			prev = &here.qh->qh_next;
+			hw_p = &here.qh->hw->hw_next;
+			here = *prev;
+		}
+		/* link in this qh, unless some earlier pass did that */
+		if (qh != here.qh) {
+			qh->qh_next = here;
+			if (here.qh)
+				qh->hw->hw_next = *hw_p;
+			wmb();
+			prev->qh = qh;
+			*hw_p = QH_NEXT(fotg210, qh->qh_dma);
+		}
+	}
+	qh->qh_state = QH_STATE_LINKED;
+	qh->xacterrs = 0;
+
+	/* update per-qh bandwidth for usbfs */
+	fotg210_to_hcd(fotg210)->self.bandwidth_allocated += qh->period
+		? ((qh->usecs + qh->c_usecs) / qh->period)
+		: (qh->usecs * 8);
+
+	list_add(&qh->intr_node, &fotg210->intr_qh_list);
+
+	/* maybe enable periodic schedule processing */
+	++fotg210->intr_count;
+	enable_periodic(fotg210);
+}
+
+static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
+			       struct fotg210_qh *qh)
+{
+	unsigned i;
+	unsigned period;
+
+	/*
+	 * If qh is for a low/full-speed device, simply unlinking it
+	 * could interfere with an ongoing split transaction.  To unlink
+	 * it safely would require setting the QH_INACTIVATE bit and
+	 * waiting at least one frame, as described in EHCI 4.12.2.5.
+	 *
+	 * We won't bother with any of this.  Instead, we assume that the
+	 * only reason for unlinking an interrupt QH while the current URB
+	 * is still active is to dequeue all the URBs (flush the whole
+	 * endpoint queue).
+	 *
+	 * If rebalancing the periodic schedule is ever implemented, this
+	 * approach will no longer be valid.
+	 */
+
+	/* high bandwidth, or otherwise part of every microframe */
+	period = qh->period;
+	if (!period)
+		period = 1;
+
+	for (i = qh->start; i < fotg210->periodic_size; i += period)
+		periodic_unlink(fotg210, i, qh);
+
+	/* update per-qh bandwidth for usbfs */
+	fotg210_to_hcd(fotg210)->self.bandwidth_allocated -= qh->period
+		? ((qh->usecs + qh->c_usecs) / qh->period)
+		: (qh->usecs * 8);
+
+	dev_dbg(&qh->dev->dev,
+		"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
+		qh->period,
+		hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
+		(QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs, qh->c_usecs);
+
+	/* qh->qh_next still "live" to HC */
+	qh->qh_state = QH_STATE_UNLINK;
+	qh->qh_next.ptr = NULL;
+
+	if (fotg210->qh_scan_next == qh)
+		fotg210->qh_scan_next = list_entry(qh->intr_node.next,
+				struct fotg210_qh, intr_node);
+	list_del(&qh->intr_node);
+}
+
+static void start_unlink_intr(struct fotg210_hcd *fotg210,
+			      struct fotg210_qh *qh)
+{
+	/* If the QH isn't linked then there's nothing we can do
+	 * unless we were called during a giveback, in which case
+	 * qh_completions() has to deal with it.
+	 */
+	if (qh->qh_state != QH_STATE_LINKED) {
+		if (qh->qh_state == QH_STATE_COMPLETING)
+			qh->needs_rescan = 1;
+		return;
+	}
+
+	qh_unlink_periodic(fotg210, qh);
+
+	/* Make sure the unlinks are visible before starting the timer */
+	wmb();
+
+	/*
+	 * The EHCI spec doesn't say how long it takes the controller to
+	 * stop accessing an unlinked interrupt QH.  The timer delay is
+	 * 9 uframes; presumably that will be long enough.
+	 */
+	qh->unlink_cycle = fotg210->intr_unlink_cycle;
+
+	/* New entries go at the end of the intr_unlink list */
+	if (fotg210->intr_unlink)
+		fotg210->intr_unlink_last->unlink_next = qh;
+	else
+		fotg210->intr_unlink = qh;
+	fotg210->intr_unlink_last = qh;
+
+	if (fotg210->intr_unlinking)
+		;	/* Avoid recursive calls */
+	else if (fotg210->rh_state < FOTG210_RH_RUNNING)
+		fotg210_handle_intr_unlinks(fotg210);
+	else if (fotg210->intr_unlink == qh) {
+		fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
+				     true);
+		++fotg210->intr_unlink_cycle;
+	}
+}
+
+static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+{
+	struct fotg210_qh_hw *hw = qh->hw;
+	int rc;
+
+	qh->qh_state = QH_STATE_IDLE;
+	hw->hw_next = FOTG210_LIST_END(fotg210);
+
+	qh_completions(fotg210, qh);
+
+	/* reschedule QH iff another request is queued */
+	if (!list_empty(&qh->qtd_list) &&
+	    fotg210->rh_state == FOTG210_RH_RUNNING) {
+		rc = qh_schedule(fotg210, qh);
+
+		/* An error here likely indicates handshake failure
+		 * or no space left in the schedule.  Neither fault
+		 * should happen often ...
+		 *
+		 * FIXME kill the now-dysfunctional queued urbs
+		 */
+		if (rc != 0)
+			fotg210_err(fotg210, "can't reschedule qh %p, err %d\n",
+					qh, rc);
+	}
+
+	/* maybe turn off periodic schedule */
+	--fotg210->intr_count;
+	disable_periodic(fotg210);
+}
+
+static int check_period(struct fotg210_hcd *fotg210, unsigned frame,
+			unsigned uframe, unsigned period, unsigned usecs)
+{
+	int claimed;
+
+	/* complete split running into next frame?
+	 * given FSTN support, we could sometimes check...
+	 */
+	if (uframe >= 8)
+		return 0;
+
+	/* convert "usecs we need" to "max already claimed" */
+	usecs = fotg210->uframe_periodic_max - usecs;
+
+	/* we "know" 2 and 4 uframe intervals were rejected; so
+	 * for period 0, check _every_ microframe in the schedule.
+	 */
+	if (unlikely(period == 0)) {
+		do {
+			for (uframe = 0; uframe < 7; uframe++) {
+				claimed = periodic_usecs(fotg210, frame,
+							 uframe);
+				if (claimed > usecs)
+					return 0;
+			}
+		} while ((frame += 1) < fotg210->periodic_size);
+
+	/* just check the specified uframe, at that period */
+	} else {
+		do {
+			claimed = periodic_usecs(fotg210, frame, uframe);
+			if (claimed > usecs)
+				return 0;
+		} while ((frame += period) < fotg210->periodic_size);
+	}
+
+	/* success! */
+	return 1;
+}
+
+static int check_intr_schedule(struct fotg210_hcd *fotg210, unsigned frame,
+			       unsigned uframe, const struct fotg210_qh *qh,
+			       __hc32 *c_maskp)
+{
+	int retval = -ENOSPC;
+	u8 mask = 0;
+
+	if (qh->c_usecs && uframe >= 6)		/* FSTN territory? */
+		goto done;
+
+	if (!check_period(fotg210, frame, uframe, qh->period, qh->usecs))
+		goto done;
+	if (!qh->c_usecs) {
+		retval = 0;
+		*c_maskp = 0;
+		goto done;
+	}
+
+	/* Make sure this tt's buffer is also available for CSPLITs.
+	 * We pessimize a bit; probably the typical full speed case
+	 * doesn't need the second CSPLIT.
+	 *
+	 * NOTE:  both SPLIT and CSPLIT could be checked in just
+	 * one smart pass...
+	 */
+	mask = 0x03 << (uframe + qh->gap_uf);
+	*c_maskp = cpu_to_hc32(fotg210, mask << 8);
+
+	mask |= 1 << uframe;
+	if (tt_no_collision(fotg210, qh->period, qh->dev, frame, mask)) {
+		if (!check_period(fotg210, frame, uframe + qh->gap_uf + 1,
+					qh->period, qh->c_usecs))
+			goto done;
+		if (!check_period(fotg210, frame, uframe + qh->gap_uf,
+					qh->period, qh->c_usecs))
+			goto done;
+		retval = 0;
+	}
+done:
+	return retval;
+}
+
+/* "first fit" scheduling policy used the first time through,
+ * or when the previous schedule slot can't be re-used.
+ */
+static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+{
+	int status;
+	unsigned uframe;
+	__hc32 c_mask;
+	unsigned frame;	/* 0..(qh->period - 1), or NO_FRAME */
+	struct fotg210_qh_hw *hw = qh->hw;
+
+	qh_refresh(fotg210, qh);
+	hw->hw_next = FOTG210_LIST_END(fotg210);
+	frame = qh->start;
+
+	/* reuse the previous schedule slots, if we can */
+	if (frame < qh->period) {
+		uframe = ffs(hc32_to_cpup(fotg210, &hw->hw_info2) & QH_SMASK);
+		status = check_intr_schedule(fotg210, frame, --uframe,
+				qh, &c_mask);
+	} else {
+		uframe = 0;
+		c_mask = 0;
+		status = -ENOSPC;
+	}
+
+	/* else scan the schedule to find a group of slots such that all
+	 * uframes have enough periodic bandwidth available.
+	 */
+	if (status) {
+		/* "normal" case, uframing flexible except with splits */
+		if (qh->period) {
+			int i;
+
+			for (i = qh->period; status && i > 0; --i) {
+				frame = ++fotg210->random_frame % qh->period;
+				for (uframe = 0; uframe < 8; uframe++) {
+					status = check_intr_schedule(fotg210,
+							frame, uframe, qh,
+							&c_mask);
+					if (status == 0)
+						break;
+				}
+			}
+
+		/* qh->period == 0 means every uframe */
+		} else {
+			frame = 0;
+			status = check_intr_schedule(fotg210, 0, 0, qh,
+						     &c_mask);
+		}
+		if (status)
+			goto done;
+		qh->start = frame;
+
+		/* reset S-frame and (maybe) C-frame masks */
+		hw->hw_info2 &= cpu_to_hc32(fotg210, ~(QH_CMASK | QH_SMASK));
+		hw->hw_info2 |= qh->period
+			? cpu_to_hc32(fotg210, 1 << uframe)
+			: cpu_to_hc32(fotg210, QH_SMASK);
+		hw->hw_info2 |= c_mask;
+	} else
+		fotg210_dbg(fotg210, "reused qh %p schedule\n", qh);
+
+	/* stuff into the periodic schedule */
+	qh_link_periodic(fotg210, qh);
+done:
+	return status;
+}
+
+static int intr_submit(struct fotg210_hcd *fotg210, struct urb *urb,
+		       struct list_head *qtd_list, gfp_t mem_flags)
+{
+	unsigned epnum;
+	unsigned long flags;
+	struct fotg210_qh *qh;
+	int status;
+	struct list_head empty;
+
+	/* get endpoint and transfer/schedule data */
+	epnum = urb->ep->desc.bEndpointAddress;
+
+	spin_lock_irqsave(&fotg210->lock, flags);
+
+	if (unlikely(!HCD_HW_ACCESSIBLE(fotg210_to_hcd(fotg210)))) {
+		status = -ESHUTDOWN;
+		goto done_not_linked;
+	}
+	status = usb_hcd_link_urb_to_ep(fotg210_to_hcd(fotg210), urb);
+	if (unlikely(status))
+		goto done_not_linked;
+
+	/* get qh and force any scheduling errors */
+	INIT_LIST_HEAD(&empty);
+	qh = qh_append_tds(fotg210, urb, &empty, epnum, &urb->ep->hcpriv);
+	if (qh == NULL) {
+		status = -ENOMEM;
+		goto done;
+	}
+	if (qh->qh_state == QH_STATE_IDLE) {
+		status = qh_schedule(fotg210, qh);
+		if (status)
+			goto done;
+	}
+
+	/* then queue the urb's tds to the qh */
+	qh = qh_append_tds(fotg210, urb, qtd_list, epnum, &urb->ep->hcpriv);
+	BUG_ON(qh == NULL);
+
+	/* ... update usbfs periodic stats */
+	fotg210_to_hcd(fotg210)->self.bandwidth_int_reqs++;
+
+done:
+	if (unlikely(status))
+		usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
+done_not_linked:
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+	if (status)
+		qtd_list_free(fotg210, urb, qtd_list);
+
+	return status;
+}
+
+static void scan_intr(struct fotg210_hcd *fotg210)
+{
+	struct fotg210_qh *qh;
+
+	list_for_each_entry_safe(qh, fotg210->qh_scan_next,
+				 &fotg210->intr_qh_list, intr_node) {
+rescan:
+		/* clean any finished work for this qh */
+		if (!list_empty(&qh->qtd_list)) {
+			int temp;
+
+			/*
+			 * Unlinks could happen here; completion reporting
+			 * drops the lock.  That's why fotg210->qh_scan_next
+			 * always holds the next qh to scan; if the next qh
+			 * gets unlinked then fotg210->qh_scan_next is adjusted
+			 * in qh_unlink_periodic().
+			 */
+			temp = qh_completions(fotg210, qh);
+			if (unlikely(qh->needs_rescan ||
+					(list_empty(&qh->qtd_list) &&
+					 qh->qh_state == QH_STATE_LINKED)))
+				start_unlink_intr(fotg210, qh);
+			else if (temp != 0)
+				goto rescan;
+		}
+	}
+}
+
+/* fotg210_iso_stream ops work with both ITD and SITD */
+
+static struct fotg210_iso_stream *iso_stream_alloc(gfp_t mem_flags)
+{
+	struct fotg210_iso_stream *stream;
+
+	stream = kzalloc(sizeof(*stream), mem_flags);
+	if (likely(stream != NULL)) {
+		INIT_LIST_HEAD(&stream->td_list);
+		INIT_LIST_HEAD(&stream->free_list);
+		stream->next_uframe = -1;
+	}
+	return stream;
+}
+
+static void iso_stream_init(struct fotg210_hcd *fotg210,
+			    struct fotg210_iso_stream *stream,
+			    struct usb_device *dev, int pipe,
+			    unsigned interval)
+{
+	u32 buf1;
+	unsigned epnum, maxp;
+	int is_input;
+	long bandwidth;
+	unsigned multi;
+
+	/*
+	 * this might be a "high bandwidth" highspeed endpoint,
+	 * as encoded in the ep descriptor's wMaxPacket field
+	 */
+	epnum = usb_pipeendpoint(pipe);
+	is_input = usb_pipein(pipe) ? USB_DIR_IN : 0;
+	maxp = usb_maxpacket(dev, pipe, !is_input);
+	if (is_input)
+		buf1 = (1 << 11);
+	else
+		buf1 = 0;
+
+	maxp = max_packet(maxp);
+	multi = hb_mult(maxp);
+	buf1 |= maxp;
+	maxp *= multi;
+
+	stream->buf0 = cpu_to_hc32(fotg210, (epnum << 8) | dev->devnum);
+	stream->buf1 = cpu_to_hc32(fotg210, buf1);
+	stream->buf2 = cpu_to_hc32(fotg210, multi);
+
+	/* usbfs wants to report the average usecs per frame tied up
+	 * when transfers on this endpoint are scheduled ...
+	 */
+	if (dev->speed == USB_SPEED_FULL) {
+		interval <<= 3;
+		stream->usecs = NS_TO_US(usb_calc_bus_time(dev->speed,
+				is_input, 1, maxp));
+		stream->usecs /= 8;
+	} else {
+		stream->highspeed = 1;
+		stream->usecs = HS_USECS_ISO(maxp);
+	}
+	bandwidth = stream->usecs * 8;
+	bandwidth /= interval;
+
+	stream->bandwidth = bandwidth;
+	stream->udev = dev;
+	stream->bEndpointAddress = is_input | epnum;
+	stream->interval = interval;
+	stream->maxp = maxp;
+}
+
+static struct fotg210_iso_stream *iso_stream_find(struct fotg210_hcd *fotg210,
+						  struct urb *urb)
+{
+	unsigned epnum;
+	struct fotg210_iso_stream *stream;
+	struct usb_host_endpoint *ep;
+	unsigned long flags;
+
+	epnum = usb_pipeendpoint(urb->pipe);
+	if (usb_pipein(urb->pipe))
+		ep = urb->dev->ep_in[epnum];
+	else
+		ep = urb->dev->ep_out[epnum];
+
+	spin_lock_irqsave(&fotg210->lock, flags);
+	stream = ep->hcpriv;
+
+	if (unlikely(stream == NULL)) {
+		stream = iso_stream_alloc(GFP_ATOMIC);
+		if (likely(stream != NULL)) {
+			ep->hcpriv = stream;
+			stream->ep = ep;
+			iso_stream_init(fotg210, stream, urb->dev, urb->pipe,
+					urb->interval);
+		}
+
+	/* if dev->ep[epnum] is a QH, hw is set */
+	} else if (unlikely(stream->hw != NULL)) {
+		fotg210_dbg(fotg210, "dev %s ep%d%s, not iso??\n",
+			urb->dev->devpath, epnum,
+			usb_pipein(urb->pipe) ? "in" : "out");
+		stream = NULL;
+	}
+
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+	return stream;
+}
+
+/* fotg210_iso_sched ops can be ITD-only or SITD-only */
+
+static struct fotg210_iso_sched *iso_sched_alloc(unsigned packets,
+						 gfp_t mem_flags)
+{
+	struct fotg210_iso_sched *iso_sched;
+	int size = sizeof(*iso_sched);
+
+	size += packets * sizeof(struct fotg210_iso_packet);
+	iso_sched = kzalloc(size, mem_flags);
+	if (likely(iso_sched != NULL))
+		INIT_LIST_HEAD(&iso_sched->td_list);
+
+	return iso_sched;
+}
+
+static inline void itd_sched_init(struct fotg210_hcd *fotg210,
+				  struct fotg210_iso_sched *iso_sched,
+				  struct fotg210_iso_stream *stream,
+				  struct urb *urb)
+{
+	unsigned i;
+	dma_addr_t dma = urb->transfer_dma;
+
+	/* how many uframes are needed for these transfers */
+	iso_sched->span = urb->number_of_packets * stream->interval;
+
+	/* figure out per-uframe itd fields that we'll need later
+	 * when we fit new itds into the schedule.
+	 */
+	for (i = 0; i < urb->number_of_packets; i++) {
+		struct fotg210_iso_packet *uframe = &iso_sched->packet[i];
+		unsigned length;
+		dma_addr_t buf;
+		u32 trans;
+
+		length = urb->iso_frame_desc[i].length;
+		buf = dma + urb->iso_frame_desc[i].offset;
+
+		trans = FOTG210_ISOC_ACTIVE;
+		trans |= buf & 0x0fff;
+		if (unlikely(((i + 1) == urb->number_of_packets))
+				&& !(urb->transfer_flags & URB_NO_INTERRUPT))
+			trans |= FOTG210_ITD_IOC;
+		trans |= length << 16;
+		uframe->transaction = cpu_to_hc32(fotg210, trans);
+
+		/* might need to cross a buffer page within a uframe */
+		uframe->bufp = (buf & ~(u64)0x0fff);
+		buf += length;
+		if (unlikely((uframe->bufp != (buf & ~(u64)0x0fff))))
+			uframe->cross = 1;
+	}
+}
+
+static void iso_sched_free(struct fotg210_iso_stream *stream,
+			   struct fotg210_iso_sched *iso_sched)
+{
+	if (!iso_sched)
+		return;
+	/* caller must hold fotg210->lock!*/
+	list_splice(&iso_sched->td_list, &stream->free_list);
+	kfree(iso_sched);
+}
+
+static int itd_urb_transaction(struct fotg210_iso_stream *stream,
+			       struct fotg210_hcd *fotg210,
+			       struct urb *urb, gfp_t mem_flags)
+{
+	struct fotg210_itd *itd;
+	dma_addr_t itd_dma;
+	int i;
+	unsigned num_itds;
+	struct fotg210_iso_sched *sched;
+	unsigned long flags;
+
+	sched = iso_sched_alloc(urb->number_of_packets, mem_flags);
+	if (unlikely(sched == NULL))
+		return -ENOMEM;
+
+	itd_sched_init(fotg210, sched, stream, urb);
+
+	if (urb->interval < 8)
+		num_itds = 1 + (sched->span + 7) / 8;
+	else
+		num_itds = urb->number_of_packets;
+
+	/* allocate/init ITDs */
+	spin_lock_irqsave(&fotg210->lock, flags);
+	for (i = 0; i < num_itds; i++) {
+
+		/*
+		 * Use iTDs from the free list, but not iTDs that may
+		 * still be in use by the hardware.
+		 */
+		if (likely(!list_empty(&stream->free_list))) {
+			itd = list_first_entry(&stream->free_list,
+					struct fotg210_itd, itd_list);
+			if (itd->frame == fotg210->now_frame)
+				goto alloc_itd;
+			list_del(&itd->itd_list);
+			itd_dma = itd->itd_dma;
+		} else {
+alloc_itd:
+			spin_unlock_irqrestore(&fotg210->lock, flags);
+			itd = dma_pool_alloc(fotg210->itd_pool, mem_flags,
+					&itd_dma);
+			spin_lock_irqsave(&fotg210->lock, flags);
+			if (!itd) {
+				iso_sched_free(stream, sched);
+				spin_unlock_irqrestore(&fotg210->lock, flags);
+				return -ENOMEM;
+			}
+		}
+
+		memset(itd, 0, sizeof(*itd));
+		itd->itd_dma = itd_dma;
+		list_add(&itd->itd_list, &sched->td_list);
+	}
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+
+	/* temporarily store schedule info in hcpriv */
+	urb->hcpriv = sched;
+	urb->error_count = 0;
+	return 0;
+}
+
+static inline int itd_slot_ok(struct fotg210_hcd *fotg210, u32 mod, u32 uframe,
+			      u8 usecs, u32 period)
+{
+	uframe %= period;
+	do {
+		/* can't commit more than uframe_periodic_max usec */
+		if (periodic_usecs(fotg210, uframe >> 3, uframe & 0x7)
+				> (fotg210->uframe_periodic_max - usecs))
+			return 0;
+
+		/* we know urb->interval is 2^N uframes */
+		uframe += period;
+	} while (uframe < mod);
+	return 1;
+}
+
+/*
+ * This scheduler plans almost as far into the future as it has actual
+ * periodic schedule slots.  (Affected by TUNE_FLS, which defaults to
+ * "as small as possible" to be cache-friendlier.)  That limits the size
+ * transfers you can stream reliably; avoid more than 64 msec per urb.
+ * Also avoid queue depths of less than fotg210's worst irq latency (affected
+ * by the per-urb URB_NO_INTERRUPT hint, the log2_irq_thresh module parameter,
+ * and other factors); or more than about 230 msec total (for portability,
+ * given FOTG210_TUNE_FLS and the slop).  Or, write a smarter scheduler!
+ */
+
+#define SCHEDULE_SLOP 80 /* microframes */
+
+static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
+			       struct fotg210_iso_stream *stream)
+{
+	u32 now, next, start, period, span;
+	int status;
+	unsigned mod = fotg210->periodic_size << 3;
+	struct fotg210_iso_sched *sched = urb->hcpriv;
+
+	period = urb->interval;
+	span = sched->span;
+
+	if (span > mod - SCHEDULE_SLOP) {
+		fotg210_dbg(fotg210, "iso request %p too long\n", urb);
+		status = -EFBIG;
+		goto fail;
+	}
+
+	now = fotg210_read_frame_index(fotg210) & (mod - 1);
+
+	/* Typical case: reuse current schedule, stream is still active.
+	 * Hopefully there are no gaps from the host falling behind
+	 * (irq delays etc), but if there are we'll take the next
+	 * slot in the schedule, implicitly assuming URB_ISO_ASAP.
+	 */
+	if (likely(!list_empty(&stream->td_list))) {
+		u32 excess;
+
+		/* For high speed devices, allow scheduling within the
+		 * isochronous scheduling threshold.  For full speed devices
+		 * and Intel PCI-based controllers, don't (work around for
+		 * Intel ICH9 bug).
+		 */
+		if (!stream->highspeed && fotg210->fs_i_thresh)
+			next = now + fotg210->i_thresh;
+		else
+			next = now;
+
+		/* Fell behind (by up to twice the slop amount)?
+		 * We decide based on the time of the last currently-scheduled
+		 * slot, not the time of the next available slot.
+		 */
+		excess = (stream->next_uframe - period - next) & (mod - 1);
+		if (excess >= mod - 2 * SCHEDULE_SLOP)
+			start = next + excess - mod + period *
+					DIV_ROUND_UP(mod - excess, period);
+		else
+			start = next + excess + period;
+		if (start - now >= mod) {
+			fotg210_dbg(fotg210, "request %p would overflow (%d+%d >= %d)\n",
+					urb, start - now - period, period,
+					mod);
+			status = -EFBIG;
+			goto fail;
+		}
+	}
+
+	/* need to schedule; when's the next (u)frame we could start?
+	 * this is bigger than fotg210->i_thresh allows; scheduling itself
+	 * isn't free, the slop should handle reasonably slow cpus.  it
+	 * can also help high bandwidth if the dma and irq loads don't
+	 * jump until after the queue is primed.
+	 */
+	else {
+		int done = 0;
+
+		start = SCHEDULE_SLOP + (now & ~0x07);
+
+		/* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */
+
+		/* find a uframe slot with enough bandwidth.
+		 * Early uframes are more precious because full-speed
+		 * iso IN transfers can't use late uframes,
+		 * and therefore they should be allocated last.
+		 */
+		next = start;
+		start += period;
+		do {
+			start--;
+			/* check schedule: enough space? */
+			if (itd_slot_ok(fotg210, mod, start,
+					stream->usecs, period))
+				done = 1;
+		} while (start > next && !done);
+
+		/* no room in the schedule */
+		if (!done) {
+			fotg210_dbg(fotg210, "iso resched full %p (now %d max %d)\n",
+				urb, now, now + mod);
+			status = -ENOSPC;
+			goto fail;
+		}
+	}
+
+	/* Tried to schedule too far into the future? */
+	if (unlikely(start - now + span - period
+				>= mod - 2 * SCHEDULE_SLOP)) {
+		fotg210_dbg(fotg210, "request %p would overflow (%d+%d >= %d)\n",
+				urb, start - now, span - period,
+				mod - 2 * SCHEDULE_SLOP);
+		status = -EFBIG;
+		goto fail;
+	}
+
+	stream->next_uframe = start & (mod - 1);
+
+	/* report high speed start in uframes; full speed, in frames */
+	urb->start_frame = stream->next_uframe;
+	if (!stream->highspeed)
+		urb->start_frame >>= 3;
+
+	/* Make sure scan_isoc() sees these */
+	if (fotg210->isoc_count == 0)
+		fotg210->next_frame = now >> 3;
+	return 0;
+
+fail:
+	iso_sched_free(stream, sched);
+	urb->hcpriv = NULL;
+	return status;
+}
+
+static inline void itd_init(struct fotg210_hcd *fotg210,
+			    struct fotg210_iso_stream *stream,
+			    struct fotg210_itd *itd)
+{
+	int i;
+
+	/* it's been recently zeroed */
+	itd->hw_next = FOTG210_LIST_END(fotg210);
+	itd->hw_bufp[0] = stream->buf0;
+	itd->hw_bufp[1] = stream->buf1;
+	itd->hw_bufp[2] = stream->buf2;
+
+	for (i = 0; i < 8; i++)
+		itd->index[i] = -1;
+
+	/* All other fields are filled when scheduling */
+}
+
+static inline void itd_patch(struct fotg210_hcd *fotg210,
+			     struct fotg210_itd *itd,
+			     struct fotg210_iso_sched *iso_sched,
+			     unsigned index, u16 uframe)
+{
+	struct fotg210_iso_packet *uf = &iso_sched->packet[index];
+	unsigned pg = itd->pg;
+
+	uframe &= 0x07;
+	itd->index[uframe] = index;
+
+	itd->hw_transaction[uframe] = uf->transaction;
+	itd->hw_transaction[uframe] |= cpu_to_hc32(fotg210, pg << 12);
+	itd->hw_bufp[pg] |= cpu_to_hc32(fotg210, uf->bufp & ~(u32)0);
+	itd->hw_bufp_hi[pg] |= cpu_to_hc32(fotg210, (u32)(uf->bufp >> 32));
+
+	/* iso_frame_desc[].offset must be strictly increasing */
+	if (unlikely(uf->cross)) {
+		u64 bufp = uf->bufp + 4096;
+
+		itd->pg = ++pg;
+		itd->hw_bufp[pg] |= cpu_to_hc32(fotg210, bufp & ~(u32)0);
+		itd->hw_bufp_hi[pg] |= cpu_to_hc32(fotg210, (u32)(bufp >> 32));
+	}
+}
+
+static inline void itd_link(struct fotg210_hcd *fotg210, unsigned frame,
+			    struct fotg210_itd *itd)
+{
+	union fotg210_shadow *prev = &fotg210->pshadow[frame];
+	__hc32 *hw_p = &fotg210->periodic[frame];
+	union fotg210_shadow here = *prev;
+	__hc32 type = 0;
+
+	/* skip any iso nodes which might belong to previous microframes */
+	while (here.ptr) {
+		type = Q_NEXT_TYPE(fotg210, *hw_p);
+		if (type == cpu_to_hc32(fotg210, Q_TYPE_QH))
+			break;
+		prev = periodic_next_shadow(fotg210, prev, type);
+		hw_p = shadow_next_periodic(fotg210, &here, type);
+		here = *prev;
+	}
+
+	itd->itd_next = here;
+	itd->hw_next = *hw_p;
+	prev->itd = itd;
+	itd->frame = frame;
+	wmb();
+	*hw_p = cpu_to_hc32(fotg210, itd->itd_dma | Q_TYPE_ITD);
+}
+
+/* fit urb's itds into the selected schedule slot; activate as needed */
+static void itd_link_urb(struct fotg210_hcd *fotg210, struct urb *urb,
+			 unsigned mod, struct fotg210_iso_stream *stream)
+{
+	int packet;
+	unsigned next_uframe, uframe, frame;
+	struct fotg210_iso_sched *iso_sched = urb->hcpriv;
+	struct fotg210_itd *itd;
+
+	next_uframe = stream->next_uframe & (mod - 1);
+
+	if (unlikely(list_empty(&stream->td_list))) {
+		fotg210_to_hcd(fotg210)->self.bandwidth_allocated
+				+= stream->bandwidth;
+		fotg210_dbg(fotg210,
+			"schedule devp %s ep%d%s-iso period %d start %d.%d\n",
+			urb->dev->devpath, stream->bEndpointAddress & 0x0f,
+			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
+			urb->interval,
+			next_uframe >> 3, next_uframe & 0x7);
+	}
+
+	/* fill iTDs uframe by uframe */
+	for (packet = 0, itd = NULL; packet < urb->number_of_packets;) {
+		if (itd == NULL) {
+			/* ASSERT:  we have all necessary itds */
+
+			/* ASSERT:  no itds for this endpoint in this uframe */
+
+			itd = list_entry(iso_sched->td_list.next,
+					struct fotg210_itd, itd_list);
+			list_move_tail(&itd->itd_list, &stream->td_list);
+			itd->stream = stream;
+			itd->urb = urb;
+			itd_init(fotg210, stream, itd);
+		}
+
+		uframe = next_uframe & 0x07;
+		frame = next_uframe >> 3;
+
+		itd_patch(fotg210, itd, iso_sched, packet, uframe);
+
+		next_uframe += stream->interval;
+		next_uframe &= mod - 1;
+		packet++;
+
+		/* link completed itds into the schedule */
+		if (((next_uframe >> 3) != frame)
+				|| packet == urb->number_of_packets) {
+			itd_link(fotg210, frame & (fotg210->periodic_size - 1),
+				 itd);
+			itd = NULL;
+		}
+	}
+	stream->next_uframe = next_uframe;
+
+	/* don't need that schedule data any more */
+	iso_sched_free(stream, iso_sched);
+	urb->hcpriv = NULL;
+
+	++fotg210->isoc_count;
+	enable_periodic(fotg210);
+}
+
+#define ISO_ERRS (FOTG210_ISOC_BUF_ERR | FOTG210_ISOC_BABBLE |\
+		  FOTG210_ISOC_XACTERR)
+
+/* Process and recycle a completed ITD.  Return true iff its urb completed,
+ * and hence its completion callback probably added things to the hardware
+ * schedule.
+ *
+ * Note that we carefully avoid recycling this descriptor until after any
+ * completion callback runs, so that it won't be reused quickly.  That is,
+ * assuming (a) no more than two urbs per frame on this endpoint, and also
+ * (b) only this endpoint's completions submit URBs.  It seems some silicon
+ * corrupts things if you reuse completed descriptors very quickly...
+ */
+static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
+{
+	struct urb *urb = itd->urb;
+	struct usb_iso_packet_descriptor *desc;
+	u32 t;
+	unsigned uframe;
+	int urb_index = -1;
+	struct fotg210_iso_stream *stream = itd->stream;
+	struct usb_device *dev;
+	bool retval = false;
+
+	/* for each uframe with a packet */
+	for (uframe = 0; uframe < 8; uframe++) {
+		if (likely(itd->index[uframe] == -1))
+			continue;
+		urb_index = itd->index[uframe];
+		desc = &urb->iso_frame_desc[urb_index];
+
+		t = hc32_to_cpup(fotg210, &itd->hw_transaction[uframe]);
+		itd->hw_transaction[uframe] = 0;
+
+		/* report transfer status */
+		if (unlikely(t & ISO_ERRS)) {
+			urb->error_count++;
+			if (t & FOTG210_ISOC_BUF_ERR)
+				desc->status = usb_pipein(urb->pipe)
+					? -ENOSR  /* hc couldn't read */
+					: -ECOMM; /* hc couldn't write */
+			else if (t & FOTG210_ISOC_BABBLE)
+				desc->status = -EOVERFLOW;
+			else /* (t & FOTG210_ISOC_XACTERR) */
+				desc->status = -EPROTO;
+
+			/* HC need not update length with this error */
+			if (!(t & FOTG210_ISOC_BABBLE)) {
+				desc->actual_length =
+					fotg210_itdlen(urb, desc, t);
+				urb->actual_length += desc->actual_length;
+			}
+		} else if (likely((t & FOTG210_ISOC_ACTIVE) == 0)) {
+			desc->status = 0;
+			desc->actual_length = fotg210_itdlen(urb, desc, t);
+			urb->actual_length += desc->actual_length;
+		} else {
+			/* URB was too late */
+			desc->status = -EXDEV;
+		}
+	}
+
+	/* handle completion now? */
+	if (likely((urb_index + 1) != urb->number_of_packets))
+		goto done;
+
+	/* ASSERT: it's really the last itd for this urb
+	 * list_for_each_entry (itd, &stream->td_list, itd_list)
+	 *	BUG_ON (itd->urb == urb);
+	 */
+
+	/* give urb back to the driver; completion often (re)submits */
+	dev = urb->dev;
+	fotg210_urb_done(fotg210, urb, 0);
+	retval = true;
+	urb = NULL;
+
+	--fotg210->isoc_count;
+	disable_periodic(fotg210);
+
+	if (unlikely(list_is_singular(&stream->td_list))) {
+		fotg210_to_hcd(fotg210)->self.bandwidth_allocated
+				-= stream->bandwidth;
+		fotg210_dbg(fotg210,
+			"deschedule devp %s ep%d%s-iso\n",
+			dev->devpath, stream->bEndpointAddress & 0x0f,
+			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
+	}
+
+done:
+	itd->urb = NULL;
+
+	/* Add to the end of the free list for later reuse */
+	list_move_tail(&itd->itd_list, &stream->free_list);
+
+	/* Recycle the iTDs when the pipeline is empty (ep no longer in use) */
+	if (list_empty(&stream->td_list)) {
+		list_splice_tail_init(&stream->free_list,
+				&fotg210->cached_itd_list);
+		start_free_itds(fotg210);
+	}
+
+	return retval;
+}
+
+static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
+		      gfp_t mem_flags)
+{
+	int status = -EINVAL;
+	unsigned long flags;
+	struct fotg210_iso_stream *stream;
+
+	/* Get iso_stream head */
+	stream = iso_stream_find(fotg210, urb);
+	if (unlikely(stream == NULL)) {
+		fotg210_dbg(fotg210, "can't get iso stream\n");
+		return -ENOMEM;
+	}
+	if (unlikely(urb->interval != stream->interval &&
+	    fotg210_port_speed(fotg210, 0) == USB_PORT_STAT_HIGH_SPEED)) {
+		fotg210_dbg(fotg210, "can't change iso interval %d --> %d\n",
+			    stream->interval, urb->interval);
+		goto done;
+	}
+
+#ifdef FOTG210_URB_TRACE
+	fotg210_dbg(fotg210,
+		"%s %s urb %p ep%d%s len %d, %d pkts %d uframes[%p]\n",
+		__func__, urb->dev->devpath, urb,
+		usb_pipeendpoint(urb->pipe),
+		usb_pipein(urb->pipe) ? "in" : "out",
+		urb->transfer_buffer_length,
+		urb->number_of_packets, urb->interval,
+		stream);
+#endif
+
+	/* allocate ITDs w/o locking anything */
+	status = itd_urb_transaction(stream, fotg210, urb, mem_flags);
+	if (unlikely(status < 0)) {
+		fotg210_dbg(fotg210, "can't init itds\n");
+		goto done;
+	}
+
+	/* schedule ... need to lock */
+	spin_lock_irqsave(&fotg210->lock, flags);
+	if (unlikely(!HCD_HW_ACCESSIBLE(fotg210_to_hcd(fotg210)))) {
+		status = -ESHUTDOWN;
+		goto done_not_linked;
+	}
+	status = usb_hcd_link_urb_to_ep(fotg210_to_hcd(fotg210), urb);
+	if (unlikely(status))
+		goto done_not_linked;
+	status = iso_stream_schedule(fotg210, urb, stream);
+	if (likely(status == 0))
+		itd_link_urb(fotg210, urb, fotg210->periodic_size << 3, stream);
+	else
+		usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
+done_not_linked:
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+done:
+	return status;
+}
+
+static inline int scan_frame_queue(struct fotg210_hcd *fotg210, unsigned frame,
+				   unsigned now_frame, bool live)
+{
+	unsigned uf;
+	bool modified;
+	union fotg210_shadow q, *q_p;
+	__hc32 type, *hw_p;
+
+	/* scan each element in frame's queue for completions */
+	q_p = &fotg210->pshadow[frame];
+	hw_p = &fotg210->periodic[frame];
+	q.ptr = q_p->ptr;
+	type = Q_NEXT_TYPE(fotg210, *hw_p);
+	modified = false;
+
+	while (q.ptr != NULL) {
+		switch (hc32_to_cpu(fotg210, type)) {
+		case Q_TYPE_ITD:
+			/* If this ITD is still active, leave it for
+			 * later processing ... check the next entry.
+			 * No need to check for activity unless the
+			 * frame is current.
+			 */
+			if (frame == now_frame && live) {
+				rmb();
+				for (uf = 0; uf < 8; uf++) {
+					if (q.itd->hw_transaction[uf] &
+						    ITD_ACTIVE(fotg210))
+						break;
+				}
+				if (uf < 8) {
+					q_p = &q.itd->itd_next;
+					hw_p = &q.itd->hw_next;
+					type = Q_NEXT_TYPE(fotg210,
+						q.itd->hw_next);
+					q = *q_p;
+					break;
+				}
+			}
+
+			/* Take finished ITDs out of the schedule
+			 * and process them:  recycle, maybe report
+			 * URB completion.  HC won't cache the
+			 * pointer for much longer, if at all.
+			 */
+			*q_p = q.itd->itd_next;
+			*hw_p = q.itd->hw_next;
+			type = Q_NEXT_TYPE(fotg210, q.itd->hw_next);
+			wmb();
+			modified = itd_complete(fotg210, q.itd);
+			q = *q_p;
+			break;
+		default:
+			fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
+				type, frame, q.ptr);
+			/* FALL THROUGH */
+		case Q_TYPE_QH:
+		case Q_TYPE_FSTN:
+			/* End of the iTDs and siTDs */
+			q.ptr = NULL;
+			break;
+		}
+
+		/* assume completion callbacks modify the queue */
+		if (unlikely(modified && fotg210->isoc_count > 0))
+			return -1;
+	}
+	return 0;
+}
+
+static void scan_isoc(struct fotg210_hcd *fotg210)
+{
+	unsigned uf, now_frame, frame, ret;
+	unsigned fmask = fotg210->periodic_size - 1;
+	bool live;
+
+	/*
+	 * When running, scan from last scan point up to "now"
+	 * else clean up by scanning everything that's left.
+	 * Touches as few pages as possible:  cache-friendly.
+	 */
+	if (fotg210->rh_state >= FOTG210_RH_RUNNING) {
+		uf = fotg210_read_frame_index(fotg210);
+		now_frame = (uf >> 3) & fmask;
+		live = true;
+	} else  {
+		now_frame = (fotg210->next_frame - 1) & fmask;
+		live = false;
+	}
+	fotg210->now_frame = now_frame;
+
+	frame = fotg210->next_frame;
+	for (;;) {
+
+		ret = 1;
+		while (ret != 0)
+			ret = scan_frame_queue(fotg210, frame, now_frame,
+					       live);
+
+		/* Stop when we have reached the current frame */
+		if (frame == now_frame)
+			break;
+		frame = (frame + 1) & fmask;
+	}
+	fotg210->next_frame = now_frame;
+}
+
+/*
+ * Display / Set uframe_periodic_max
+ */
+static ssize_t show_uframe_periodic_max(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct fotg210_hcd *fotg210;
+	int n;
+
+	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
+	n = scnprintf(buf, PAGE_SIZE, "%d\n", fotg210->uframe_periodic_max);
+	return n;
+}
+
+
+static ssize_t store_uframe_periodic_max(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	struct fotg210_hcd *fotg210;
+	unsigned uframe_periodic_max;
+	unsigned frame, uframe;
+	unsigned short allocated_max;
+	unsigned long flags;
+	ssize_t ret;
+
+	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
+	if (kstrtouint(buf, 0, &uframe_periodic_max) < 0)
+		return -EINVAL;
+
+	if (uframe_periodic_max < 100 || uframe_periodic_max >= 125) {
+		fotg210_info(fotg210, "rejecting invalid request for uframe_periodic_max=%u\n",
+			     uframe_periodic_max);
+		return -EINVAL;
+	}
+
+	ret = -EINVAL;
+
+	/*
+	 * lock, so that our checking does not race with possible periodic
+	 * bandwidth allocation through submitting new urbs.
+	 */
+	spin_lock_irqsave(&fotg210->lock, flags);
+
+	/*
+	 * for request to decrease max periodic bandwidth, we have to check
+	 * every microframe in the schedule to see whether the decrease is
+	 * possible.
+	 */
+	if (uframe_periodic_max < fotg210->uframe_periodic_max) {
+		allocated_max = 0;
+
+		for (frame = 0; frame < fotg210->periodic_size; ++frame)
+			for (uframe = 0; uframe < 7; ++uframe)
+				allocated_max = max(allocated_max,
+						    periodic_usecs(fotg210,
+								   frame,
+								   uframe));
+
+		if (allocated_max > uframe_periodic_max) {
+			fotg210_info(fotg210,
+				"cannot decrease uframe_periodic_max because periodic bandwidth is already allocated (%u > %u)\n",
+				allocated_max, uframe_periodic_max);
+			goto out_unlock;
+		}
+	}
+
+	/* increasing is always ok */
+
+	fotg210_info(fotg210, "setting max periodic bandwidth to %u%% (== %u usec/uframe)\n",
+		     100 * uframe_periodic_max/125, uframe_periodic_max);
+
+	if (uframe_periodic_max != 100)
+		fotg210_warn(fotg210, "max periodic bandwidth set is non-standard\n");
+
+	fotg210->uframe_periodic_max = uframe_periodic_max;
+	ret = count;
+
+out_unlock:
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+	return ret;
+}
+
+static DEVICE_ATTR(uframe_periodic_max, 0644, show_uframe_periodic_max,
+		   store_uframe_periodic_max);
+
+static inline int create_sysfs_files(struct fotg210_hcd *fotg210)
+{
+	struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
+	int i = 0;
+
+	if (i)
+		goto out;
+
+	i = device_create_file(controller, &dev_attr_uframe_periodic_max);
+out:
+	return i;
+}
+
+static inline void remove_sysfs_files(struct fotg210_hcd *fotg210)
+{
+	struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
+
+	device_remove_file(controller, &dev_attr_uframe_periodic_max);
+}
+/* On some systems, leaving remote wakeup enabled prevents system shutdown.
+ * The firmware seems to think that powering off is a wakeup event!
+ * This routine turns off remote wakeup and everything else, on all ports.
+ */
+static void fotg210_turn_off_all_ports(struct fotg210_hcd *fotg210)
+{
+	u32 __iomem *status_reg = &fotg210->regs->port_status;
+
+	fotg210_writel(fotg210, PORT_RWC_BITS, status_reg);
+}
+
+/*
+ * Halt HC, turn off all ports, and let the BIOS use the companion controllers.
+ * Must be called with interrupts enabled and the lock not held.
+ */
+static void fotg210_silence_controller(struct fotg210_hcd *fotg210)
+{
+	fotg210_halt(fotg210);
+
+	spin_lock_irq(&fotg210->lock);
+	fotg210->rh_state = FOTG210_RH_HALTED;
+	fotg210_turn_off_all_ports(fotg210);
+	spin_unlock_irq(&fotg210->lock);
+}
+
+/* fotg210_shutdown kick in for silicon on any bus (not just pci, etc).
+ * This forcibly disables dma and IRQs, helping kexec and other cases
+ * where the next system software may expect clean state.
+ */
+static void fotg210_shutdown(struct usb_hcd *hcd)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+
+	spin_lock_irq(&fotg210->lock);
+	fotg210->shutdown = true;
+	fotg210->rh_state = FOTG210_RH_STOPPING;
+	fotg210->enabled_hrtimer_events = 0;
+	spin_unlock_irq(&fotg210->lock);
+
+	fotg210_silence_controller(fotg210);
+
+	hrtimer_cancel(&fotg210->hrtimer);
+}
+
+/*
+ * fotg210_work is called from some interrupts, timers, and so on.
+ * it calls driver completion functions, after dropping fotg210->lock.
+ */
+static void fotg210_work(struct fotg210_hcd *fotg210)
+{
+	/* another CPU may drop fotg210->lock during a schedule scan while
+	 * it reports urb completions.  this flag guards against bogus
+	 * attempts at re-entrant schedule scanning.
+	 */
+	if (fotg210->scanning) {
+		fotg210->need_rescan = true;
+		return;
+	}
+	fotg210->scanning = true;
+
+rescan:
+	fotg210->need_rescan = false;
+	if (fotg210->async_count)
+		scan_async(fotg210);
+	if (fotg210->intr_count > 0)
+		scan_intr(fotg210);
+	if (fotg210->isoc_count > 0)
+		scan_isoc(fotg210);
+	if (fotg210->need_rescan)
+		goto rescan;
+	fotg210->scanning = false;
+
+	/* the IO watchdog guards against hardware or driver bugs that
+	 * misplace IRQs, and should let us run completely without IRQs.
+	 * such lossage has been observed on both VT6202 and VT8235.
+	 */
+	turn_on_io_watchdog(fotg210);
+}
+
+/*
+ * Called when the fotg210_hcd module is removed.
+ */
+static void fotg210_stop(struct usb_hcd *hcd)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+
+	fotg210_dbg(fotg210, "stop\n");
+
+	/* no more interrupts ... */
+
+	spin_lock_irq(&fotg210->lock);
+	fotg210->enabled_hrtimer_events = 0;
+	spin_unlock_irq(&fotg210->lock);
+
+	fotg210_quiesce(fotg210);
+	fotg210_silence_controller(fotg210);
+	fotg210_reset(fotg210);
+
+	hrtimer_cancel(&fotg210->hrtimer);
+	remove_sysfs_files(fotg210);
+	remove_debug_files(fotg210);
+
+	/* root hub is shut down separately (first, when possible) */
+	spin_lock_irq(&fotg210->lock);
+	end_free_itds(fotg210);
+	spin_unlock_irq(&fotg210->lock);
+	fotg210_mem_cleanup(fotg210);
+
+#ifdef FOTG210_STATS
+	fotg210_dbg(fotg210, "irq normal %ld err %ld iaa %ld (lost %ld)\n",
+		fotg210->stats.normal, fotg210->stats.error, fotg210->stats.iaa,
+		fotg210->stats.lost_iaa);
+	fotg210_dbg(fotg210, "complete %ld unlink %ld\n",
+		fotg210->stats.complete, fotg210->stats.unlink);
+#endif
+
+	dbg_status(fotg210, "fotg210_stop completed",
+		    fotg210_readl(fotg210, &fotg210->regs->status));
+}
+
+/* one-time init, only for memory state */
+static int hcd_fotg210_init(struct usb_hcd *hcd)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 temp;
+	int retval;
+	u32 hcc_params;
+	struct fotg210_qh_hw *hw;
+
+	spin_lock_init(&fotg210->lock);
+
+	/*
+	 * keep io watchdog by default, those good HCDs could turn off it later
+	 */
+	fotg210->need_io_watchdog = 1;
+
+	hrtimer_init(&fotg210->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+	fotg210->hrtimer.function = fotg210_hrtimer_func;
+	fotg210->next_hrtimer_event = FOTG210_HRTIMER_NO_EVENT;
+
+	hcc_params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
+
+	/*
+	 * by default set standard 80% (== 100 usec/uframe) max periodic
+	 * bandwidth as required by USB 2.0
+	 */
+	fotg210->uframe_periodic_max = 100;
+
+	/*
+	 * hw default: 1K periodic list heads, one per frame.
+	 * periodic_size can shrink by USBCMD update if hcc_params allows.
+	 */
+	fotg210->periodic_size = DEFAULT_I_TDPS;
+	INIT_LIST_HEAD(&fotg210->intr_qh_list);
+	INIT_LIST_HEAD(&fotg210->cached_itd_list);
+
+	if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
+		/* periodic schedule size can be smaller than default */
+		switch (FOTG210_TUNE_FLS) {
+		case 0:
+			fotg210->periodic_size = 1024;
+			break;
+		case 1:
+			fotg210->periodic_size = 512;
+			break;
+		case 2:
+			fotg210->periodic_size = 256;
+			break;
+		default:
+			BUG();
+		}
+	}
+	retval = fotg210_mem_init(fotg210, GFP_KERNEL);
+	if (retval < 0)
+		return retval;
+
+	/* controllers may cache some of the periodic schedule ... */
+	fotg210->i_thresh = 2;
+
+	/*
+	 * dedicate a qh for the async ring head, since we couldn't unlink
+	 * a 'real' qh without stopping the async schedule [4.8].  use it
+	 * as the 'reclamation list head' too.
+	 * its dummy is used in hw_alt_next of many tds, to prevent the qh
+	 * from automatically advancing to the next td after short reads.
+	 */
+	fotg210->async->qh_next.qh = NULL;
+	hw = fotg210->async->hw;
+	hw->hw_next = QH_NEXT(fotg210, fotg210->async->qh_dma);
+	hw->hw_info1 = cpu_to_hc32(fotg210, QH_HEAD);
+	hw->hw_token = cpu_to_hc32(fotg210, QTD_STS_HALT);
+	hw->hw_qtd_next = FOTG210_LIST_END(fotg210);
+	fotg210->async->qh_state = QH_STATE_LINKED;
+	hw->hw_alt_next = QTD_NEXT(fotg210, fotg210->async->dummy->qtd_dma);
+
+	/* clear interrupt enables, set irq latency */
+	if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
+		log2_irq_thresh = 0;
+	temp = 1 << (16 + log2_irq_thresh);
+	if (HCC_CANPARK(hcc_params)) {
+		/* HW default park == 3, on hardware that supports it (like
+		 * NVidia and ALI silicon), maximizes throughput on the async
+		 * schedule by avoiding QH fetches between transfers.
+		 *
+		 * With fast usb storage devices and NForce2, "park" seems to
+		 * make problems:  throughput reduction (!), data errors...
+		 */
+		if (park) {
+			park = min_t(unsigned, park, 3);
+			temp |= CMD_PARK;
+			temp |= park << 8;
+		}
+		fotg210_dbg(fotg210, "park %d\n", park);
+	}
+	if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
+		/* periodic schedule size can be smaller than default */
+		temp &= ~(3 << 2);
+		temp |= (FOTG210_TUNE_FLS << 2);
+	}
+	fotg210->command = temp;
+
+	/* Accept arbitrarily long scatter-gather lists */
+	if (!(hcd->driver->flags & HCD_LOCAL_MEM))
+		hcd->self.sg_tablesize = ~0;
+	return 0;
+}
+
+/* start HC running; it's halted, hcd_fotg210_init() has been run (once) */
+static int fotg210_run(struct usb_hcd *hcd)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 temp;
+	u32 hcc_params;
+
+	hcd->uses_new_polling = 1;
+
+	/* EHCI spec section 4.1 */
+
+	fotg210_writel(fotg210, fotg210->periodic_dma,
+		       &fotg210->regs->frame_list);
+	fotg210_writel(fotg210, (u32)fotg210->async->qh_dma,
+		       &fotg210->regs->async_next);
+
+	/*
+	 * hcc_params controls whether fotg210->regs->segment must (!!!)
+	 * be used; it constrains QH/ITD/SITD and QTD locations.
+	 * pci_pool consistent memory always uses segment zero.
+	 * streaming mappings for I/O buffers, like pci_map_single(),
+	 * can return segments above 4GB, if the device allows.
+	 *
+	 * NOTE:  the dma mask is visible through dma_supported(), so
+	 * drivers can pass this info along ... like NETIF_F_HIGHDMA,
+	 * Scsi_Host.highmem_io, and so forth.  It's readonly to all
+	 * host side drivers though.
+	 */
+	hcc_params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
+
+	/*
+	 * Philips, Intel, and maybe others need CMD_RUN before the
+	 * root hub will detect new devices (why?); NEC doesn't
+	 */
+	fotg210->command &= ~(CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
+	fotg210->command |= CMD_RUN;
+	fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
+	dbg_cmd(fotg210, "init", fotg210->command);
+
+	/*
+	 * Start, enabling full USB 2.0 functionality ... usb 1.1 devices
+	 * are explicitly handed to companion controller(s), so no TT is
+	 * involved with the root hub.  (Except where one is integrated,
+	 * and there's no companion controller unless maybe for USB OTG.)
+	 *
+	 * Turning on the CF flag will transfer ownership of all ports
+	 * from the companions to the EHCI controller.  If any of the
+	 * companions are in the middle of a port reset at the time, it
+	 * could cause trouble.  Write-locking ehci_cf_port_reset_rwsem
+	 * guarantees that no resets are in progress.  After we set CF,
+	 * a short delay lets the hardware catch up; new resets shouldn't
+	 * be started before the port switching actions could complete.
+	 */
+	down_write(&ehci_cf_port_reset_rwsem);
+	fotg210->rh_state = FOTG210_RH_RUNNING;
+	/* unblock posted writes */
+	fotg210_readl(fotg210, &fotg210->regs->command);
+	usleep_range(5000, 6000);
+	up_write(&ehci_cf_port_reset_rwsem);
+	fotg210->last_periodic_enable = ktime_get_real();
+
+	temp = HC_VERSION(fotg210,
+			  fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
+	fotg210_info(fotg210,
+		"USB %x.%x started, EHCI %x.%02x\n",
+		((fotg210->sbrn & 0xf0)>>4), (fotg210->sbrn & 0x0f),
+		temp >> 8, temp & 0xff);
+
+	fotg210_writel(fotg210, INTR_MASK,
+		    &fotg210->regs->intr_enable); /* Turn On Interrupts */
+
+	/* GRR this is run-once init(), being done every time the HC starts.
+	 * So long as they're part of class devices, we can't do it init()
+	 * since the class device isn't created that early.
+	 */
+	create_debug_files(fotg210);
+	create_sysfs_files(fotg210);
+
+	return 0;
+}
+
+static int fotg210_setup(struct usb_hcd *hcd)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	int retval;
+
+	fotg210->regs = (void __iomem *)fotg210->caps +
+	    HC_LENGTH(fotg210,
+		      fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
+	dbg_hcs_params(fotg210, "reset");
+	dbg_hcc_params(fotg210, "reset");
+
+	/* cache this readonly data; minimize chip reads */
+	fotg210->hcs_params = fotg210_readl(fotg210,
+					    &fotg210->caps->hcs_params);
+
+	fotg210->sbrn = HCD_USB2;
+
+	/* data structure init */
+	retval = hcd_fotg210_init(hcd);
+	if (retval)
+		return retval;
+
+	retval = fotg210_halt(fotg210);
+	if (retval)
+		return retval;
+
+	fotg210_reset(fotg210);
+
+	return 0;
+}
+
+static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 status, masked_status, pcd_status = 0, cmd;
+	int bh;
+
+	spin_lock(&fotg210->lock);
+
+	status = fotg210_readl(fotg210, &fotg210->regs->status);
+
+	/* e.g. cardbus physical eject */
+	if (status == ~(u32) 0) {
+		fotg210_dbg(fotg210, "device removed\n");
+		goto dead;
+	}
+
+	/*
+	 * We don't use STS_FLR, but some controllers don't like it to
+	 * remain on, so mask it out along with the other status bits.
+	 */
+	masked_status = status & (INTR_MASK | STS_FLR);
+
+	/* Shared IRQ? */
+	if (!masked_status ||
+	    unlikely(fotg210->rh_state == FOTG210_RH_HALTED)) {
+		spin_unlock(&fotg210->lock);
+		return IRQ_NONE;
+	}
+
+	/* clear (just) interrupts */
+	fotg210_writel(fotg210, masked_status, &fotg210->regs->status);
+	cmd = fotg210_readl(fotg210, &fotg210->regs->command);
+	bh = 0;
+
+	/* unrequested/ignored: Frame List Rollover */
+	dbg_status(fotg210, "irq", status);
+
+	/* INT, ERR, and IAA interrupt rates can be throttled */
+
+	/* normal [4.15.1.2] or error [4.15.1.1] completion */
+	if (likely((status & (STS_INT|STS_ERR)) != 0)) {
+		if (likely((status & STS_ERR) == 0))
+			COUNT(fotg210->stats.normal);
+		else
+			COUNT(fotg210->stats.error);
+		bh = 1;
+	}
+
+	/* complete the unlinking of some qh [4.15.2.3] */
+	if (status & STS_IAA) {
+
+		/* Turn off the IAA watchdog */
+		fotg210->enabled_hrtimer_events &=
+			~BIT(FOTG210_HRTIMER_IAA_WATCHDOG);
+
+		/*
+		 * Mild optimization: Allow another IAAD to reset the
+		 * hrtimer, if one occurs before the next expiration.
+		 * In theory we could always cancel the hrtimer, but
+		 * tests show that about half the time it will be reset
+		 * for some other event anyway.
+		 */
+		if (fotg210->next_hrtimer_event == FOTG210_HRTIMER_IAA_WATCHDOG)
+			++fotg210->next_hrtimer_event;
+
+		/* guard against (alleged) silicon errata */
+		if (cmd & CMD_IAAD)
+			fotg210_dbg(fotg210, "IAA with IAAD still set?\n");
+		if (fotg210->async_iaa) {
+			COUNT(fotg210->stats.iaa);
+			end_unlink_async(fotg210);
+		} else
+			fotg210_dbg(fotg210, "IAA with nothing unlinked?\n");
+	}
+
+	/* remote wakeup [4.3.1] */
+	if (status & STS_PCD) {
+		int pstatus;
+		u32 __iomem *status_reg = &fotg210->regs->port_status;
+
+		/* kick root hub later */
+		pcd_status = status;
+
+		/* resume root hub? */
+		if (fotg210->rh_state == FOTG210_RH_SUSPENDED)
+			usb_hcd_resume_root_hub(hcd);
+
+		pstatus = fotg210_readl(fotg210, status_reg);
+
+		if (test_bit(0, &fotg210->suspended_ports) &&
+				((pstatus & PORT_RESUME) ||
+					!(pstatus & PORT_SUSPEND)) &&
+				(pstatus & PORT_PE) &&
+				fotg210->reset_done[0] == 0) {
+
+			/* start 20 msec resume signaling from this port,
+			 * and make hub_wq collect PORT_STAT_C_SUSPEND to
+			 * stop that signaling.  Use 5 ms extra for safety,
+			 * like usb_port_resume() does.
+			 */
+			fotg210->reset_done[0] = jiffies + msecs_to_jiffies(25);
+			set_bit(0, &fotg210->resuming_ports);
+			fotg210_dbg(fotg210, "port 1 remote wakeup\n");
+			mod_timer(&hcd->rh_timer, fotg210->reset_done[0]);
+		}
+	}
+
+	/* PCI errors [4.15.2.4] */
+	if (unlikely((status & STS_FATAL) != 0)) {
+		fotg210_err(fotg210, "fatal error\n");
+		dbg_cmd(fotg210, "fatal", cmd);
+		dbg_status(fotg210, "fatal", status);
+dead:
+		usb_hc_died(hcd);
+
+		/* Don't let the controller do anything more */
+		fotg210->shutdown = true;
+		fotg210->rh_state = FOTG210_RH_STOPPING;
+		fotg210->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
+		fotg210_writel(fotg210, fotg210->command,
+			       &fotg210->regs->command);
+		fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
+		fotg210_handle_controller_death(fotg210);
+
+		/* Handle completions when the controller stops */
+		bh = 0;
+	}
+
+	if (bh)
+		fotg210_work(fotg210);
+	spin_unlock(&fotg210->lock);
+	if (pcd_status)
+		usb_hcd_poll_rh_status(hcd);
+	return IRQ_HANDLED;
+}
+
+/*
+ * non-error returns are a promise to giveback() the urb later
+ * we drop ownership so next owner (or urb unlink) can get it
+ *
+ * urb + dev is in hcd.self.controller.urb_list
+ * we're queueing TDs onto software and hardware lists
+ *
+ * hcd-specific init for hcpriv hasn't been done yet
+ *
+ * NOTE:  control, bulk, and interrupt share the same code to append TDs
+ * to a (possibly active) QH, and the same QH scanning code.
+ */
+static int fotg210_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+			       gfp_t mem_flags)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct list_head qtd_list;
+
+	INIT_LIST_HEAD(&qtd_list);
+
+	switch (usb_pipetype(urb->pipe)) {
+	case PIPE_CONTROL:
+		/* qh_completions() code doesn't handle all the fault cases
+		 * in multi-TD control transfers.  Even 1KB is rare anyway.
+		 */
+		if (urb->transfer_buffer_length > (16 * 1024))
+			return -EMSGSIZE;
+		/* FALLTHROUGH */
+	/* case PIPE_BULK: */
+	default:
+		if (!qh_urb_transaction(fotg210, urb, &qtd_list, mem_flags))
+			return -ENOMEM;
+		return submit_async(fotg210, urb, &qtd_list, mem_flags);
+
+	case PIPE_INTERRUPT:
+		if (!qh_urb_transaction(fotg210, urb, &qtd_list, mem_flags))
+			return -ENOMEM;
+		return intr_submit(fotg210, urb, &qtd_list, mem_flags);
+
+	case PIPE_ISOCHRONOUS:
+		return itd_submit(fotg210, urb, mem_flags);
+	}
+}
+
+/* remove from hardware lists
+ * completions normally happen asynchronously
+ */
+
+static int fotg210_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_qh *qh;
+	unsigned long flags;
+	int rc;
+
+	spin_lock_irqsave(&fotg210->lock, flags);
+	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
+	if (rc)
+		goto done;
+
+	switch (usb_pipetype(urb->pipe)) {
+	/* case PIPE_CONTROL: */
+	/* case PIPE_BULK:*/
+	default:
+		qh = (struct fotg210_qh *) urb->hcpriv;
+		if (!qh)
+			break;
+		switch (qh->qh_state) {
+		case QH_STATE_LINKED:
+		case QH_STATE_COMPLETING:
+			start_unlink_async(fotg210, qh);
+			break;
+		case QH_STATE_UNLINK:
+		case QH_STATE_UNLINK_WAIT:
+			/* already started */
+			break;
+		case QH_STATE_IDLE:
+			/* QH might be waiting for a Clear-TT-Buffer */
+			qh_completions(fotg210, qh);
+			break;
+		}
+		break;
+
+	case PIPE_INTERRUPT:
+		qh = (struct fotg210_qh *) urb->hcpriv;
+		if (!qh)
+			break;
+		switch (qh->qh_state) {
+		case QH_STATE_LINKED:
+		case QH_STATE_COMPLETING:
+			start_unlink_intr(fotg210, qh);
+			break;
+		case QH_STATE_IDLE:
+			qh_completions(fotg210, qh);
+			break;
+		default:
+			fotg210_dbg(fotg210, "bogus qh %p state %d\n",
+					qh, qh->qh_state);
+			goto done;
+		}
+		break;
+
+	case PIPE_ISOCHRONOUS:
+		/* itd... */
+
+		/* wait till next completion, do it then. */
+		/* completion irqs can wait up to 1024 msec, */
+		break;
+	}
+done:
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+	return rc;
+}
+
+/* bulk qh holds the data toggle */
+
+static void fotg210_endpoint_disable(struct usb_hcd *hcd,
+				     struct usb_host_endpoint *ep)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	unsigned long flags;
+	struct fotg210_qh *qh, *tmp;
+
+	/* ASSERT:  any requests/urbs are being unlinked */
+	/* ASSERT:  nobody can be submitting urbs for this any more */
+
+rescan:
+	spin_lock_irqsave(&fotg210->lock, flags);
+	qh = ep->hcpriv;
+	if (!qh)
+		goto done;
+
+	/* endpoints can be iso streams.  for now, we don't
+	 * accelerate iso completions ... so spin a while.
+	 */
+	if (qh->hw == NULL) {
+		struct fotg210_iso_stream *stream = ep->hcpriv;
+
+		if (!list_empty(&stream->td_list))
+			goto idle_timeout;
+
+		/* BUG_ON(!list_empty(&stream->free_list)); */
+		kfree(stream);
+		goto done;
+	}
+
+	if (fotg210->rh_state < FOTG210_RH_RUNNING)
+		qh->qh_state = QH_STATE_IDLE;
+	switch (qh->qh_state) {
+	case QH_STATE_LINKED:
+	case QH_STATE_COMPLETING:
+		for (tmp = fotg210->async->qh_next.qh;
+				tmp && tmp != qh;
+				tmp = tmp->qh_next.qh)
+			continue;
+		/* periodic qh self-unlinks on empty, and a COMPLETING qh
+		 * may already be unlinked.
+		 */
+		if (tmp)
+			start_unlink_async(fotg210, qh);
+		/* FALL THROUGH */
+	case QH_STATE_UNLINK:		/* wait for hw to finish? */
+	case QH_STATE_UNLINK_WAIT:
+idle_timeout:
+		spin_unlock_irqrestore(&fotg210->lock, flags);
+		schedule_timeout_uninterruptible(1);
+		goto rescan;
+	case QH_STATE_IDLE:		/* fully unlinked */
+		if (qh->clearing_tt)
+			goto idle_timeout;
+		if (list_empty(&qh->qtd_list)) {
+			qh_destroy(fotg210, qh);
+			break;
+		}
+		/* else FALL THROUGH */
+	default:
+		/* caller was supposed to have unlinked any requests;
+		 * that's not our job.  just leak this memory.
+		 */
+		fotg210_err(fotg210, "qh %p (#%02x) state %d%s\n",
+			qh, ep->desc.bEndpointAddress, qh->qh_state,
+			list_empty(&qh->qtd_list) ? "" : "(has tds)");
+		break;
+	}
+done:
+	ep->hcpriv = NULL;
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+}
+
+static void fotg210_endpoint_reset(struct usb_hcd *hcd,
+				   struct usb_host_endpoint *ep)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_qh *qh;
+	int eptype = usb_endpoint_type(&ep->desc);
+	int epnum = usb_endpoint_num(&ep->desc);
+	int is_out = usb_endpoint_dir_out(&ep->desc);
+	unsigned long flags;
+
+	if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
+		return;
+
+	spin_lock_irqsave(&fotg210->lock, flags);
+	qh = ep->hcpriv;
+
+	/* For Bulk and Interrupt endpoints we maintain the toggle state
+	 * in the hardware; the toggle bits in udev aren't used at all.
+	 * When an endpoint is reset by usb_clear_halt() we must reset
+	 * the toggle bit in the QH.
+	 */
+	if (qh) {
+		usb_settoggle(qh->dev, epnum, is_out, 0);
+		if (!list_empty(&qh->qtd_list)) {
+			WARN_ONCE(1, "clear_halt for a busy endpoint\n");
+		} else if (qh->qh_state == QH_STATE_LINKED ||
+				qh->qh_state == QH_STATE_COMPLETING) {
+
+			/* The toggle value in the QH can't be updated
+			 * while the QH is active.  Unlink it now;
+			 * re-linking will call qh_refresh().
+			 */
+			if (eptype == USB_ENDPOINT_XFER_BULK)
+				start_unlink_async(fotg210, qh);
+			else
+				start_unlink_intr(fotg210, qh);
+		}
+	}
+	spin_unlock_irqrestore(&fotg210->lock, flags);
+}
+
+static int fotg210_get_frame(struct usb_hcd *hcd)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+
+	return (fotg210_read_frame_index(fotg210) >> 3) %
+		fotg210->periodic_size;
+}
+
+/*
+ * The EHCI in ChipIdea HDRC cannot be a separate module or device,
+ * because its registers (and irq) are shared between host/gadget/otg
+ * functions  and in order to facilitate role switching we cannot
+ * give the fotg210 driver exclusive access to those.
+ */
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE("GPL");
+
+static const struct hc_driver fotg210_fotg210_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "Faraday USB2.0 Host Controller",
+	.hcd_priv_size		= sizeof(struct fotg210_hcd),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq			= fotg210_irq,
+	.flags			= HCD_MEMORY | HCD_USB2,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	.reset			= hcd_fotg210_init,
+	.start			= fotg210_run,
+	.stop			= fotg210_stop,
+	.shutdown		= fotg210_shutdown,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue		= fotg210_urb_enqueue,
+	.urb_dequeue		= fotg210_urb_dequeue,
+	.endpoint_disable	= fotg210_endpoint_disable,
+	.endpoint_reset		= fotg210_endpoint_reset,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number	= fotg210_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data	= fotg210_hub_status_data,
+	.hub_control		= fotg210_hub_control,
+	.bus_suspend		= fotg210_bus_suspend,
+	.bus_resume		= fotg210_bus_resume,
+
+	.relinquish_port	= fotg210_relinquish_port,
+	.port_handed_over	= fotg210_port_handed_over,
+
+	.clear_tt_buffer_complete = fotg210_clear_tt_buffer_complete,
+};
+
+static void fotg210_init(struct fotg210_hcd *fotg210)
+{
+	u32 value;
+
+	iowrite32(GMIR_MDEV_INT | GMIR_MOTG_INT | GMIR_INT_POLARITY,
+		  &fotg210->regs->gmir);
+
+	value = ioread32(&fotg210->regs->otgcsr);
+	value &= ~OTGCSR_A_BUS_DROP;
+	value |= OTGCSR_A_BUS_REQ;
+	iowrite32(value, &fotg210->regs->otgcsr);
+}
+
+/**
+ * fotg210_hcd_probe - initialize faraday FOTG210 HCDs
+ *
+ * Allocates basic resources for this USB host controller, and
+ * then invokes the start() method for the HCD associated with it
+ * through the hotplug entry's driver_data.
+ */
+static int fotg210_hcd_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct usb_hcd *hcd;
+	struct resource *res;
+	int irq;
+	int retval = -ENODEV;
+	struct fotg210_hcd *fotg210;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	pdev->dev.power.power_state = PMSG_ON;
+
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res) {
+		dev_err(dev,
+			"Found HC with no IRQ. Check %s setup!\n",
+			dev_name(dev));
+		return -ENODEV;
+	}
+
+	irq = res->start;
+
+	hcd = usb_create_hcd(&fotg210_fotg210_hc_driver, dev,
+			dev_name(dev));
+	if (!hcd) {
+		dev_err(dev, "failed to create hcd with err %d\n", retval);
+		retval = -ENOMEM;
+		goto fail_create_hcd;
+	}
+
+	hcd->has_tt = 1;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	hcd->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(hcd->regs)) {
+		retval = PTR_ERR(hcd->regs);
+		goto failed;
+	}
+
+	hcd->rsrc_start = res->start;
+	hcd->rsrc_len = resource_size(res);
+
+	fotg210 = hcd_to_fotg210(hcd);
+
+	fotg210->caps = hcd->regs;
+
+	retval = fotg210_setup(hcd);
+	if (retval)
+		goto failed;
+
+	fotg210_init(fotg210);
+
+	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
+	if (retval) {
+		dev_err(dev, "failed to add hcd with err %d\n", retval);
+		goto failed;
+	}
+	device_wakeup_enable(hcd->self.controller);
+
+	return retval;
+
+failed:
+	usb_put_hcd(hcd);
+fail_create_hcd:
+	dev_err(dev, "init %s fail, %d\n", dev_name(dev), retval);
+	return retval;
+}
+
+/**
+ * fotg210_hcd_remove - shutdown processing for EHCI HCDs
+ * @dev: USB Host Controller being removed
+ *
+ */
+static int fotg210_hcd_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+
+	if (!hcd)
+		return 0;
+
+	usb_remove_hcd(hcd);
+	usb_put_hcd(hcd);
+
+	return 0;
+}
+
+static struct platform_driver fotg210_hcd_driver = {
+	.driver = {
+		.name   = "fotg210-hcd",
+	},
+	.probe  = fotg210_hcd_probe,
+	.remove = fotg210_hcd_remove,
+};
+
+static int __init fotg210_hcd_init(void)
+{
+	int retval = 0;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+	set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
+	if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
+			test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
+		pr_warn("Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
+
+	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd\n",
+		 hcd_name,
+		 sizeof(struct fotg210_qh), sizeof(struct fotg210_qtd),
+		 sizeof(struct fotg210_itd));
+
+	fotg210_debug_root = debugfs_create_dir("fotg210", usb_debug_root);
+	if (!fotg210_debug_root) {
+		retval = -ENOENT;
+		goto err_debug;
+	}
+
+	retval = platform_driver_register(&fotg210_hcd_driver);
+	if (retval < 0)
+		goto clean;
+	return retval;
+
+	platform_driver_unregister(&fotg210_hcd_driver);
+clean:
+	debugfs_remove(fotg210_debug_root);
+	fotg210_debug_root = NULL;
+err_debug:
+	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
+	return retval;
+}
+module_init(fotg210_hcd_init);
+
+static void __exit fotg210_hcd_cleanup(void)
+{
+	platform_driver_unregister(&fotg210_hcd_driver);
+	debugfs_remove(fotg210_debug_root);
+	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
+}
+module_exit(fotg210_hcd_cleanup);
diff --git a/drivers/usb/host/faraday-hcd.h b/drivers/usb/host/faraday-hcd.h
new file mode 100644
index 0000000..b5cfa7a
--- /dev/null
+++ b/drivers/usb/host/faraday-hcd.h
@@ -0,0 +1,692 @@
+#ifndef __LINUX_FOTG210_H
+#define __LINUX_FOTG210_H
+
+#include <linux/usb/ehci-dbgp.h>
+
+/* definitions used for the EHCI driver */
+
+/*
+ * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to
+ * __leXX (normally) or __beXX (given FOTG210_BIG_ENDIAN_DESC), depending on
+ * the host controller implementation.
+ *
+ * To facilitate the strongest possible byte-order checking from "sparse"
+ * and so on, we use __leXX unless that's not practical.
+ */
+#define __hc32	__le32
+#define __hc16	__le16
+
+/* statistics can be kept for tuning/monitoring */
+struct fotg210_stats {
+	/* irq usage */
+	unsigned long		normal;
+	unsigned long		error;
+	unsigned long		iaa;
+	unsigned long		lost_iaa;
+
+	/* termination of urbs from core */
+	unsigned long		complete;
+	unsigned long		unlink;
+};
+
+/* fotg210_hcd->lock guards shared data against other CPUs:
+ *   fotg210_hcd:	async, unlink, periodic (and shadow), ...
+ *   usb_host_endpoint: hcpriv
+ *   fotg210_qh:	qh_next, qtd_list
+ *   fotg210_qtd:	qtd_list
+ *
+ * Also, hold this lock when talking to HC registers or
+ * when updating hw_* fields in shared qh/qtd/... structures.
+ */
+
+#define	FOTG210_MAX_ROOT_PORTS	1		/* see HCS_N_PORTS */
+
+/*
+ * fotg210_rh_state values of FOTG210_RH_RUNNING or above mean that the
+ * controller may be doing DMA.  Lower values mean there's no DMA.
+ */
+enum fotg210_rh_state {
+	FOTG210_RH_HALTED,
+	FOTG210_RH_SUSPENDED,
+	FOTG210_RH_RUNNING,
+	FOTG210_RH_STOPPING
+};
+
+/*
+ * Timer events, ordered by increasing delay length.
+ * Always update event_delays_ns[] and event_handlers[] (defined in
+ * ehci-timer.c) in parallel with this list.
+ */
+enum fotg210_hrtimer_event {
+	FOTG210_HRTIMER_POLL_ASS,	/* Poll for async schedule off */
+	FOTG210_HRTIMER_POLL_PSS,	/* Poll for periodic schedule off */
+	FOTG210_HRTIMER_POLL_DEAD,	/* Wait for dead controller to stop */
+	FOTG210_HRTIMER_UNLINK_INTR,	/* Wait for interrupt QH unlink */
+	FOTG210_HRTIMER_FREE_ITDS,	/* Wait for unused iTDs and siTDs */
+	FOTG210_HRTIMER_ASYNC_UNLINKS,	/* Unlink empty async QHs */
+	FOTG210_HRTIMER_IAA_WATCHDOG,	/* Handle lost IAA interrupts */
+	FOTG210_HRTIMER_DISABLE_PERIODIC, /* Wait to disable periodic sched */
+	FOTG210_HRTIMER_DISABLE_ASYNC,	/* Wait to disable async sched */
+	FOTG210_HRTIMER_IO_WATCHDOG,	/* Check for missing IRQs */
+	FOTG210_HRTIMER_NUM_EVENTS	/* Must come last */
+};
+#define FOTG210_HRTIMER_NO_EVENT	99
+
+struct fotg210_hcd {			/* one per controller */
+	/* timing support */
+	enum fotg210_hrtimer_event	next_hrtimer_event;
+	unsigned		enabled_hrtimer_events;
+	ktime_t			hr_timeouts[FOTG210_HRTIMER_NUM_EVENTS];
+	struct hrtimer		hrtimer;
+
+	int			PSS_poll_count;
+	int			ASS_poll_count;
+	int			died_poll_count;
+
+	/* glue to PCI and HCD framework */
+	struct fotg210_caps __iomem *caps;
+	struct fotg210_regs __iomem *regs;
+	struct ehci_dbg_port __iomem *debug;
+
+	__u32			hcs_params;	/* cached register copy */
+	spinlock_t		lock;
+	enum fotg210_rh_state	rh_state;
+
+	/* general schedule support */
+	bool			scanning:1;
+	bool			need_rescan:1;
+	bool			intr_unlinking:1;
+	bool			async_unlinking:1;
+	bool			shutdown:1;
+	struct fotg210_qh		*qh_scan_next;
+
+	/* async schedule support */
+	struct fotg210_qh		*async;
+	struct fotg210_qh		*dummy;		/* For AMD quirk use */
+	struct fotg210_qh		*async_unlink;
+	struct fotg210_qh		*async_unlink_last;
+	struct fotg210_qh		*async_iaa;
+	unsigned		async_unlink_cycle;
+	unsigned		async_count;	/* async activity count */
+
+	/* periodic schedule support */
+#define	DEFAULT_I_TDPS		1024		/* some HCs can do less */
+	unsigned		periodic_size;
+	__hc32			*periodic;	/* hw periodic table */
+	dma_addr_t		periodic_dma;
+	struct list_head	intr_qh_list;
+	unsigned		i_thresh;	/* uframes HC might cache */
+
+	union fotg210_shadow	*pshadow;	/* mirror hw periodic table */
+	struct fotg210_qh		*intr_unlink;
+	struct fotg210_qh		*intr_unlink_last;
+	unsigned		intr_unlink_cycle;
+	unsigned		now_frame;	/* frame from HC hardware */
+	unsigned		next_frame;	/* scan periodic, start here */
+	unsigned		intr_count;	/* intr activity count */
+	unsigned		isoc_count;	/* isoc activity count */
+	unsigned		periodic_count;	/* periodic activity count */
+	/* max periodic time per uframe */
+	unsigned		uframe_periodic_max;
+
+
+	/* list of itds completed while now_frame was still active */
+	struct list_head	cached_itd_list;
+	struct fotg210_itd	*last_itd_to_free;
+
+	/* per root hub port */
+	unsigned long		reset_done[FOTG210_MAX_ROOT_PORTS];
+
+	/* bit vectors (one bit per port)
+	 * which ports were already suspended at the start of a bus suspend
+	 */
+	unsigned long		bus_suspended;
+
+	/* which ports are edicated to the companion controller */
+	unsigned long		companion_ports;
+
+	/* which ports are owned by the companion during a bus suspend */
+	unsigned long		owned_ports;
+
+	/* which ports have the change-suspend feature turned on */
+	unsigned long		port_c_suspend;
+
+	/* which ports are suspended */
+	unsigned long		suspended_ports;
+
+	/* which ports have started to resume */
+	unsigned long		resuming_ports;
+
+	/* per-HC memory pools (could be per-bus, but ...) */
+	struct dma_pool		*qh_pool;	/* qh per active urb */
+	struct dma_pool		*qtd_pool;	/* one or more per qh */
+	struct dma_pool		*itd_pool;	/* itd per iso urb */
+
+	unsigned		random_frame;
+	unsigned long		next_statechange;
+	ktime_t			last_periodic_enable;
+	u32			command;
+
+	/* SILICON QUIRKS */
+	unsigned		need_io_watchdog:1;
+	unsigned		fs_i_thresh:1;	/* Intel iso scheduling */
+
+	u8			sbrn;		/* packed release number */
+
+	/* irq statistics */
+#ifdef FOTG210_STATS
+	struct fotg210_stats	stats;
+#	define COUNT(x) ((x)++)
+#else
+#	define COUNT(x)
+#endif
+
+	/* debug files */
+	struct dentry		*debug_dir;
+};
+
+/* convert between an HCD pointer and the corresponding FOTG210_HCD */
+static inline struct fotg210_hcd *hcd_to_fotg210(struct usb_hcd *hcd)
+{
+	return (struct fotg210_hcd *)(hcd->hcd_priv);
+}
+static inline struct usb_hcd *fotg210_to_hcd(struct fotg210_hcd *fotg210)
+{
+	return container_of((void *) fotg210, struct usb_hcd, hcd_priv);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */
+
+/* Section 2.2 Host Controller Capability Registers */
+struct fotg210_caps {
+	/* these fields are specified as 8 and 16 bit registers,
+	 * but some hosts can't perform 8 or 16 bit PCI accesses.
+	 * some hosts treat caplength and hciversion as parts of a 32-bit
+	 * register, others treat them as two separate registers, this
+	 * affects the memory map for big endian controllers.
+	 */
+	u32		hc_capbase;
+#define HC_LENGTH(fotg210, p)	(0x00ff&((p) >> /* bits 7:0 / offset 00h */ \
+				(fotg210_big_endian_capbase(fotg210) ? 24 : 0)))
+#define HC_VERSION(fotg210, p)	(0xffff&((p) >> /* bits 31:16 / offset 02h */ \
+				(fotg210_big_endian_capbase(fotg210) ? 0 : 16)))
+	u32		hcs_params;     /* HCSPARAMS - offset 0x4 */
+#define HCS_N_PORTS(p)		(((p)>>0)&0xf)	/* bits 3:0, ports on HC */
+
+	u32		hcc_params;	/* HCCPARAMS - offset 0x8 */
+#define HCC_CANPARK(p)		((p)&(1 << 2))  /* true: can park on async qh */
+#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1))  /* true: periodic_size changes*/
+	u8		portroute[8];	 /* nibbles for routing - offset 0xC */
+};
+
+
+/* Section 2.3 Host Controller Operational Registers */
+struct fotg210_regs {
+
+	/* USBCMD: offset 0x00 */
+	u32		command;
+
+/* EHCI 1.1 addendum */
+/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
+#define CMD_PARK	(1<<11)		/* enable "park" on async qh */
+#define CMD_PARK_CNT(c)	(((c)>>8)&3)	/* how many transfers to park for */
+#define CMD_IAAD	(1<<6)		/* "doorbell" interrupt async advance */
+#define CMD_ASE		(1<<5)		/* async schedule enable */
+#define CMD_PSE		(1<<4)		/* periodic schedule enable */
+/* 3:2 is periodic frame list size */
+#define CMD_RESET	(1<<1)		/* reset HC not bus */
+#define CMD_RUN		(1<<0)		/* start/stop HC */
+
+	/* USBSTS: offset 0x04 */
+	u32		status;
+#define STS_ASS		(1<<15)		/* Async Schedule Status */
+#define STS_PSS		(1<<14)		/* Periodic Schedule Status */
+#define STS_RECL	(1<<13)		/* Reclamation */
+#define STS_HALT	(1<<12)		/* Not running (any reason) */
+/* some bits reserved */
+	/* these STS_* flags are also intr_enable bits (USBINTR) */
+#define STS_IAA		(1<<5)		/* Interrupted on async advance */
+#define STS_FATAL	(1<<4)		/* such as some PCI access errors */
+#define STS_FLR		(1<<3)		/* frame list rolled over */
+#define STS_PCD		(1<<2)		/* port change detect */
+#define STS_ERR		(1<<1)		/* "error" completion (overflow, ...) */
+#define STS_INT		(1<<0)		/* "normal" completion (short, ...) */
+
+	/* USBINTR: offset 0x08 */
+	u32		intr_enable;
+
+	/* FRINDEX: offset 0x0C */
+	u32		frame_index;	/* current microframe number */
+	/* CTRLDSSEGMENT: offset 0x10 */
+	u32		segment;	/* address bits 63:32 if needed */
+	/* PERIODICLISTBASE: offset 0x14 */
+	u32		frame_list;	/* points to periodic list */
+	/* ASYNCLISTADDR: offset 0x18 */
+	u32		async_next;	/* address of next async queue head */
+
+	u32	reserved1;
+	/* PORTSC: offset 0x20 */
+	u32	port_status;
+/* 31:23 reserved */
+#define PORT_USB11(x) (((x)&(3<<10)) == (1<<10))	/* USB 1.1 device */
+#define PORT_RESET	(1<<8)		/* reset port */
+#define PORT_SUSPEND	(1<<7)		/* suspend port */
+#define PORT_RESUME	(1<<6)		/* resume it */
+#define PORT_PEC	(1<<3)		/* port enable change */
+#define PORT_PE		(1<<2)		/* port enable */
+#define PORT_CSC	(1<<1)		/* connect status change */
+#define PORT_CONNECT	(1<<0)		/* device connected */
+#define PORT_RWC_BITS   (PORT_CSC | PORT_PEC)
+	u32     reserved2[19];
+
+	/* OTGCSR: offet 0x70 */
+	u32     otgcsr;
+#define OTGCSR_HOST_SPD_TYP     (3 << 22)
+#define OTGCSR_A_BUS_DROP	(1 << 5)
+#define OTGCSR_A_BUS_REQ	(1 << 4)
+
+	/* OTGISR: offset 0x74 */
+	u32     otgisr;
+#define OTGISR_OVC	(1 << 10)
+
+	u32     reserved3[15];
+
+	/* GMIR: offset 0xB4 */
+	u32     gmir;
+#define GMIR_INT_POLARITY	(1 << 3) /*Active High*/
+#define GMIR_MHC_INT		(1 << 2)
+#define GMIR_MOTG_INT		(1 << 1)
+#define GMIR_MDEV_INT	(1 << 0)
+};
+
+/*-------------------------------------------------------------------------*/
+
+#define	QTD_NEXT(fotg210, dma)	cpu_to_hc32(fotg210, (u32)dma)
+
+/*
+ * EHCI Specification 0.95 Section 3.5
+ * QTD: describe data transfer components (buffer, direction, ...)
+ * See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram".
+ *
+ * These are associated only with "QH" (Queue Head) structures,
+ * used with control, bulk, and interrupt transfers.
+ */
+struct fotg210_qtd {
+	/* first part defined by EHCI spec */
+	__hc32			hw_next;	/* see EHCI 3.5.1 */
+	__hc32			hw_alt_next;    /* see EHCI 3.5.2 */
+	__hc32			hw_token;	/* see EHCI 3.5.3 */
+#define	QTD_TOGGLE	(1 << 31)	/* data toggle */
+#define	QTD_LENGTH(tok)	(((tok)>>16) & 0x7fff)
+#define	QTD_IOC		(1 << 15)	/* interrupt on complete */
+#define	QTD_CERR(tok)	(((tok)>>10) & 0x3)
+#define	QTD_PID(tok)	(((tok)>>8) & 0x3)
+#define	QTD_STS_ACTIVE	(1 << 7)	/* HC may execute this */
+#define	QTD_STS_HALT	(1 << 6)	/* halted on error */
+#define	QTD_STS_DBE	(1 << 5)	/* data buffer error (in HC) */
+#define	QTD_STS_BABBLE	(1 << 4)	/* device was babbling (qtd halted) */
+#define	QTD_STS_XACT	(1 << 3)	/* device gave illegal response */
+#define	QTD_STS_MMF	(1 << 2)	/* incomplete split transaction */
+#define	QTD_STS_STS	(1 << 1)	/* split transaction state */
+#define	QTD_STS_PING	(1 << 0)	/* issue PING? */
+
+#define ACTIVE_BIT(fotg210)	cpu_to_hc32(fotg210, QTD_STS_ACTIVE)
+#define HALT_BIT(fotg210)		cpu_to_hc32(fotg210, QTD_STS_HALT)
+#define STATUS_BIT(fotg210)	cpu_to_hc32(fotg210, QTD_STS_STS)
+
+	__hc32			hw_buf[5];	/* see EHCI 3.5.4 */
+	__hc32			hw_buf_hi[5];	/* Appendix B */
+
+	/* the rest is HCD-private */
+	dma_addr_t		qtd_dma;		/* qtd address */
+	struct list_head	qtd_list;		/* sw qtd list */
+	struct urb		*urb;			/* qtd's urb */
+	size_t			length;			/* length of buffer */
+} __aligned(32);
+
+/* mask NakCnt+T in qh->hw_alt_next */
+#define QTD_MASK(fotg210)	cpu_to_hc32(fotg210, ~0x1f)
+
+#define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1)
+
+/*-------------------------------------------------------------------------*/
+
+/* type tag from {qh,itd,fstn}->hw_next */
+#define Q_NEXT_TYPE(fotg210, dma)	((dma) & cpu_to_hc32(fotg210, 3 << 1))
+
+/*
+ * Now the following defines are not converted using the
+ * cpu_to_le32() macro anymore, since we have to support
+ * "dynamic" switching between be and le support, so that the driver
+ * can be used on one system with SoC EHCI controller using big-endian
+ * descriptors as well as a normal little-endian PCI EHCI controller.
+ */
+/* values for that type tag */
+#define Q_TYPE_ITD	(0 << 1)
+#define Q_TYPE_QH	(1 << 1)
+#define Q_TYPE_SITD	(2 << 1)
+#define Q_TYPE_FSTN	(3 << 1)
+
+/* next async queue entry, or pointer to interrupt/periodic QH */
+#define QH_NEXT(fotg210, dma) \
+	(cpu_to_hc32(fotg210, (((u32)dma)&~0x01f)|Q_TYPE_QH))
+
+/* for periodic/async schedules and qtd lists, mark end of list */
+#define FOTG210_LIST_END(fotg210) \
+	cpu_to_hc32(fotg210, 1) /* "null pointer" to hw */
+
+/*
+ * Entries in periodic shadow table are pointers to one of four kinds
+ * of data structure.  That's dictated by the hardware; a type tag is
+ * encoded in the low bits of the hardware's periodic schedule.  Use
+ * Q_NEXT_TYPE to get the tag.
+ *
+ * For entries in the async schedule, the type tag always says "qh".
+ */
+union fotg210_shadow {
+	struct fotg210_qh	*qh;		/* Q_TYPE_QH */
+	struct fotg210_itd	*itd;		/* Q_TYPE_ITD */
+	struct fotg210_fstn	*fstn;		/* Q_TYPE_FSTN */
+	__hc32			*hw_next;	/* (all types) */
+	void			*ptr;
+};
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * EHCI Specification 0.95 Section 3.6
+ * QH: describes control/bulk/interrupt endpoints
+ * See Fig 3-7 "Queue Head Structure Layout".
+ *
+ * These appear in both the async and (for interrupt) periodic schedules.
+ */
+
+/* first part defined by EHCI spec */
+struct fotg210_qh_hw {
+	__hc32			hw_next;	/* see EHCI 3.6.1 */
+	__hc32			hw_info1;	/* see EHCI 3.6.2 */
+#define	QH_CONTROL_EP	(1 << 27)	/* FS/LS control endpoint */
+#define	QH_HEAD		(1 << 15)	/* Head of async reclamation list */
+#define	QH_TOGGLE_CTL	(1 << 14)	/* Data toggle control */
+#define	QH_HIGH_SPEED	(2 << 12)	/* Endpoint speed */
+#define	QH_LOW_SPEED	(1 << 12)
+#define	QH_FULL_SPEED	(0 << 12)
+#define	QH_INACTIVATE	(1 << 7)	/* Inactivate on next transaction */
+	__hc32			hw_info2;	/* see EHCI 3.6.2 */
+#define	QH_SMASK	0x000000ff
+#define	QH_CMASK	0x0000ff00
+#define	QH_HUBADDR	0x007f0000
+#define	QH_HUBPORT	0x3f800000
+#define	QH_MULT		0xc0000000
+	__hc32			hw_current;	/* qtd list - see EHCI 3.6.4 */
+
+	/* qtd overlay (hardware parts of a struct fotg210_qtd) */
+	__hc32			hw_qtd_next;
+	__hc32			hw_alt_next;
+	__hc32			hw_token;
+	__hc32			hw_buf[5];
+	__hc32			hw_buf_hi[5];
+} __aligned(32);
+
+struct fotg210_qh {
+	struct fotg210_qh_hw	*hw;		/* Must come first */
+	/* the rest is HCD-private */
+	dma_addr_t		qh_dma;		/* address of qh */
+	union fotg210_shadow	qh_next;	/* ptr to qh; or periodic */
+	struct list_head	qtd_list;	/* sw qtd list */
+	struct list_head	intr_node;	/* list of intr QHs */
+	struct fotg210_qtd	*dummy;
+	struct fotg210_qh	*unlink_next;	/* next on unlink list */
+
+	unsigned		unlink_cycle;
+
+	u8			needs_rescan;	/* Dequeue during giveback */
+	u8			qh_state;
+#define	QH_STATE_LINKED		1		/* HC sees this */
+#define	QH_STATE_UNLINK		2		/* HC may still see this */
+#define	QH_STATE_IDLE		3		/* HC doesn't see this */
+#define	QH_STATE_UNLINK_WAIT	4		/* LINKED and on unlink q */
+#define	QH_STATE_COMPLETING	5		/* don't touch token.HALT */
+
+	u8			xacterrs;	/* XactErr retry counter */
+#define	QH_XACTERR_MAX		32		/* XactErr retry limit */
+
+	/* periodic schedule info */
+	u8			usecs;		/* intr bandwidth */
+	u8			gap_uf;		/* uframes split/csplit gap */
+	u8			c_usecs;	/* ... split completion bw */
+	u16			tt_usecs;	/* tt downstream bandwidth */
+	unsigned short		period;		/* polling interval */
+	unsigned short		start;		/* where polling starts */
+#define NO_FRAME ((unsigned short)~0)			/* pick new start */
+
+	struct usb_device	*dev;		/* access to TT */
+	unsigned		is_out:1;	/* bulk or intr OUT */
+	unsigned		clearing_tt:1;	/* Clear-TT-Buf in progress */
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* description of one iso transaction (up to 3 KB data if highspeed) */
+struct fotg210_iso_packet {
+	/* These will be copied to iTD when scheduling */
+	u64			bufp;		/* itd->hw_bufp{,_hi}[pg] |= */
+	__hc32			transaction;	/* itd->hw_transaction[i] |= */
+	u8			cross;		/* buf crosses pages */
+	/* for full speed OUT splits */
+	u32			buf1;
+};
+
+/* temporary schedule data for packets from iso urbs (both speeds)
+ * each packet is one logical usb transaction to the device (not TT),
+ * beginning at stream->next_uframe
+ */
+struct fotg210_iso_sched {
+	struct list_head	td_list;
+	unsigned		span;
+	struct fotg210_iso_packet	packet[0];
+};
+
+/*
+ * fotg210_iso_stream - groups all (s)itds for this endpoint.
+ * acts like a qh would, if EHCI had them for ISO.
+ */
+struct fotg210_iso_stream {
+	/* first field matches fotg210_hq, but is NULL */
+	struct fotg210_qh_hw	*hw;
+
+	u8			bEndpointAddress;
+	u8			highspeed;
+	struct list_head	td_list;	/* queued itds */
+	struct list_head	free_list;	/* list of unused itds */
+	struct usb_device	*udev;
+	struct usb_host_endpoint *ep;
+
+	/* output of (re)scheduling */
+	int			next_uframe;
+	__hc32			splits;
+
+	/* the rest is derived from the endpoint descriptor,
+	 * trusting urb->interval == f(epdesc->bInterval) and
+	 * including the extra info for hw_bufp[0..2]
+	 */
+	u8			usecs, c_usecs;
+	u16			interval;
+	u16			tt_usecs;
+	u16			maxp;
+	u16			raw_mask;
+	unsigned		bandwidth;
+
+	/* This is used to initialize iTD's hw_bufp fields */
+	__hc32			buf0;
+	__hc32			buf1;
+	__hc32			buf2;
+
+	/* this is used to initialize sITD's tt info */
+	__hc32			address;
+};
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * EHCI Specification 0.95 Section 3.3
+ * Fig 3-4 "Isochronous Transaction Descriptor (iTD)"
+ *
+ * Schedule records for high speed iso xfers
+ */
+struct fotg210_itd {
+	/* first part defined by EHCI spec */
+	__hc32			hw_next;	/* see EHCI 3.3.1 */
+	__hc32			hw_transaction[8]; /* see EHCI 3.3.2 */
+#define FOTG210_ISOC_ACTIVE	(1<<31)	/* activate transfer this slot */
+#define FOTG210_ISOC_BUF_ERR	(1<<30)	/* Data buffer error */
+#define FOTG210_ISOC_BABBLE	(1<<29)	/* babble detected */
+#define FOTG210_ISOC_XACTERR	(1<<28)	/* XactErr - transaction error */
+#define	FOTG210_ITD_LENGTH(tok)	(((tok)>>16) & 0x0fff)
+#define	FOTG210_ITD_IOC		(1 << 15)	/* interrupt on complete */
+
+#define ITD_ACTIVE(fotg210)	cpu_to_hc32(fotg210, FOTG210_ISOC_ACTIVE)
+
+	__hc32			hw_bufp[7];	/* see EHCI 3.3.3 */
+	__hc32			hw_bufp_hi[7];	/* Appendix B */
+
+	/* the rest is HCD-private */
+	dma_addr_t		itd_dma;	/* for this itd */
+	union fotg210_shadow	itd_next;	/* ptr to periodic q entry */
+
+	struct urb		*urb;
+	struct fotg210_iso_stream	*stream;	/* endpoint's queue */
+	struct list_head	itd_list;	/* list of stream's itds */
+
+	/* any/all hw_transactions here may be used by that urb */
+	unsigned		frame;		/* where scheduled */
+	unsigned		pg;
+	unsigned		index[8];	/* in urb->iso_frame_desc */
+} __aligned(32);
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * EHCI Specification 0.96 Section 3.7
+ * Periodic Frame Span Traversal Node (FSTN)
+ *
+ * Manages split interrupt transactions (using TT) that span frame boundaries
+ * into uframes 0/1; see 4.12.2.2.  In those uframes, a "save place" FSTN
+ * makes the HC jump (back) to a QH to scan for fs/ls QH completions until
+ * it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work.
+ */
+struct fotg210_fstn {
+	__hc32			hw_next;	/* any periodic q entry */
+	__hc32			hw_prev;	/* qh or FOTG210_LIST_END */
+
+	/* the rest is HCD-private */
+	dma_addr_t		fstn_dma;
+	union fotg210_shadow	fstn_next;	/* ptr to periodic q entry */
+} __aligned(32);
+
+/*-------------------------------------------------------------------------*/
+
+/* Prepare the PORTSC wakeup flags during controller suspend/resume */
+
+#define fotg210_prepare_ports_for_controller_suspend(fotg210, do_wakeup) \
+		fotg210_adjust_port_wakeup_flags(fotg210, true, do_wakeup)
+
+#define fotg210_prepare_ports_for_controller_resume(fotg210)		\
+		fotg210_adjust_port_wakeup_flags(fotg210, false, false)
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Some EHCI controllers have a Transaction Translator built into the
+ * root hub. This is a non-standard feature.  Each controller will need
+ * to add code to the following inline functions, and call them as
+ * needed (mostly in root hub code).
+ */
+
+static inline unsigned int
+fotg210_get_speed(struct fotg210_hcd *fotg210, unsigned int portsc)
+{
+	return (readl(&fotg210->regs->otgcsr)
+		& OTGCSR_HOST_SPD_TYP) >> 22;
+}
+
+/* Returns the speed of a device attached to a port on the root hub. */
+static inline unsigned int
+fotg210_port_speed(struct fotg210_hcd *fotg210, unsigned int portsc)
+{
+	switch (fotg210_get_speed(fotg210, portsc)) {
+	case 0:
+		return 0;
+	case 1:
+		return USB_PORT_STAT_LOW_SPEED;
+	case 2:
+	default:
+		return USB_PORT_STAT_HIGH_SPEED;
+	}
+}
+
+/*-------------------------------------------------------------------------*/
+
+#define	fotg210_has_fsl_portno_bug(e)		(0)
+
+/*
+ * While most USB host controllers implement their registers in
+ * little-endian format, a minority (celleb companion chip) implement
+ * them in big endian format.
+ *
+ * This attempts to support either format at compile time without a
+ * runtime penalty, or both formats with the additional overhead
+ * of checking a flag bit.
+ *
+ */
+
+#define fotg210_big_endian_mmio(e)	0
+#define fotg210_big_endian_capbase(e)	0
+
+static inline unsigned int fotg210_readl(const struct fotg210_hcd *fotg210,
+		__u32 __iomem *regs)
+{
+	return readl(regs);
+}
+
+static inline void fotg210_writel(const struct fotg210_hcd *fotg210,
+		const unsigned int val, __u32 __iomem *regs)
+{
+	writel(val, regs);
+}
+
+/* cpu to fotg210 */
+static inline __hc32 cpu_to_hc32(const struct fotg210_hcd *fotg210, const u32 x)
+{
+	return cpu_to_le32(x);
+}
+
+/* fotg210 to cpu */
+static inline u32 hc32_to_cpu(const struct fotg210_hcd *fotg210, const __hc32 x)
+{
+	return le32_to_cpu(x);
+}
+
+static inline u32 hc32_to_cpup(const struct fotg210_hcd *fotg210,
+			       const __hc32 *x)
+{
+	return le32_to_cpup(x);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static inline unsigned fotg210_read_frame_index(struct fotg210_hcd *fotg210)
+{
+	return fotg210_readl(fotg210, &fotg210->regs->frame_index);
+}
+
+#define fotg210_itdlen(urb, desc, t) ({			\
+	usb_pipein((urb)->pipe) ?				\
+	(desc)->length - FOTG210_ITD_LENGTH(t) :			\
+	FOTG210_ITD_LENGTH(t);					\
+})
+/*-------------------------------------------------------------------------*/
+
+#endif /* __LINUX_FOTG210_H */
diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
deleted file mode 100644
index e60a239..0000000
--- a/drivers/usb/host/fotg210-hcd.c
+++ /dev/null
@@ -1,5792 +0,0 @@
-/*
- * Faraday FOTG210 EHCI-like driver
- *
- * Copyright (c) 2013 Faraday Technology Corporation
- *
- * Author: Yuan-Hsin Chen <yhchen@faraday-tech.com>
- *	   Feng-Hsin Chiang <john453@faraday-tech.com>
- *	   Po-Yu Chuang <ratbert.chuang@gmail.com>
- *
- * Most of code borrowed from the Linux-3.7 EHCI driver
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * 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.
- */
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/dmapool.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/vmalloc.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/hrtimer.h>
-#include <linux/list.h>
-#include <linux/interrupt.h>
-#include <linux/usb.h>
-#include <linux/usb/hcd.h>
-#include <linux/moduleparam.h>
-#include <linux/dma-mapping.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <asm/byteorder.h>
-#include <asm/irq.h>
-#include <asm/unaligned.h>
-
-#define DRIVER_AUTHOR "Yuan-Hsin Chen"
-#define DRIVER_DESC "FOTG210 Host Controller (EHCI) Driver"
-static const char hcd_name[] = "fotg210_hcd";
-
-#undef FOTG210_URB_TRACE
-#define FOTG210_STATS
-
-/* magic numbers that can affect system performance */
-#define FOTG210_TUNE_CERR	3 /* 0-3 qtd retries; 0 == don't stop */
-#define FOTG210_TUNE_RL_HS	4 /* nak throttle; see 4.9 */
-#define FOTG210_TUNE_RL_TT	0
-#define FOTG210_TUNE_MULT_HS	1 /* 1-3 transactions/uframe; 4.10.3 */
-#define FOTG210_TUNE_MULT_TT	1
-
-/*
- * Some drivers think it's safe to schedule isochronous transfers more than 256
- * ms into the future (partly as a result of an old bug in the scheduling
- * code).  In an attempt to avoid trouble, we will use a minimum scheduling
- * length of 512 frames instead of 256.
- */
-#define FOTG210_TUNE_FLS 1 /* (medium) 512-frame schedule */
-
-/* Initial IRQ latency:  faster than hw default */
-static int log2_irq_thresh; /* 0 to 6 */
-module_param(log2_irq_thresh, int, S_IRUGO);
-MODULE_PARM_DESC(log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
-
-/* initial park setting:  slower than hw default */
-static unsigned park;
-module_param(park, uint, S_IRUGO);
-MODULE_PARM_DESC(park, "park setting; 1-3 back-to-back async packets");
-
-/* for link power management(LPM) feature */
-static unsigned int hird;
-module_param(hird, int, S_IRUGO);
-MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
-
-#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
-
-#include "fotg210.h"
-
-#define fotg210_dbg(fotg210, fmt, args...) \
-	dev_dbg(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
-#define fotg210_err(fotg210, fmt, args...) \
-	dev_err(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
-#define fotg210_info(fotg210, fmt, args...) \
-	dev_info(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
-#define fotg210_warn(fotg210, fmt, args...) \
-	dev_warn(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
-
-/* check the values in the HCSPARAMS register (host controller _Structural_
- * parameters) see EHCI spec, Table 2-4 for each value
- */
-static void dbg_hcs_params(struct fotg210_hcd *fotg210, char *label)
-{
-	u32 params = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
-
-	fotg210_dbg(fotg210, "%s hcs_params 0x%x ports=%d\n", label, params,
-		    HCS_N_PORTS(params));
-}
-
-/* check the values in the HCCPARAMS register (host controller _Capability_
- * parameters) see EHCI Spec, Table 2-5 for each value
- */
-static void dbg_hcc_params(struct fotg210_hcd *fotg210, char *label)
-{
-	u32 params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
-
-	fotg210_dbg(fotg210, "%s hcc_params %04x uframes %s%s\n", label,
-		    params,
-		    HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
-		    HCC_CANPARK(params) ? " park" : "");
-}
-
-static void __maybe_unused
-dbg_qtd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd)
-{
-	fotg210_dbg(fotg210, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
-		    hc32_to_cpup(fotg210, &qtd->hw_next),
-		    hc32_to_cpup(fotg210, &qtd->hw_alt_next),
-		    hc32_to_cpup(fotg210, &qtd->hw_token),
-		    hc32_to_cpup(fotg210, &qtd->hw_buf[0]));
-	if (qtd->hw_buf[1])
-		fotg210_dbg(fotg210, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
-			    hc32_to_cpup(fotg210, &qtd->hw_buf[1]),
-			    hc32_to_cpup(fotg210, &qtd->hw_buf[2]),
-			    hc32_to_cpup(fotg210, &qtd->hw_buf[3]),
-			    hc32_to_cpup(fotg210, &qtd->hw_buf[4]));
-}
-
-static void __maybe_unused
-dbg_qh(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
-{
-	struct fotg210_qh_hw *hw = qh->hw;
-
-	fotg210_dbg(fotg210, "%s qh %p n%08x info %x %x qtd %x\n", label, qh,
-		    hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
-
-	dbg_qtd("overlay", fotg210, (struct fotg210_qtd *) &hw->hw_qtd_next);
-}
-
-static void __maybe_unused
-dbg_itd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
-{
-	fotg210_dbg(fotg210, "%s[%d] itd %p, next %08x, urb %p\n", label,
-		    itd->frame, itd, hc32_to_cpu(fotg210, itd->hw_next),
-		    itd->urb);
-
-	fotg210_dbg(fotg210,
-		    "  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
-		    hc32_to_cpu(fotg210, itd->hw_transaction[0]),
-		    hc32_to_cpu(fotg210, itd->hw_transaction[1]),
-		    hc32_to_cpu(fotg210, itd->hw_transaction[2]),
-		    hc32_to_cpu(fotg210, itd->hw_transaction[3]),
-		    hc32_to_cpu(fotg210, itd->hw_transaction[4]),
-		    hc32_to_cpu(fotg210, itd->hw_transaction[5]),
-		    hc32_to_cpu(fotg210, itd->hw_transaction[6]),
-		    hc32_to_cpu(fotg210, itd->hw_transaction[7]));
-
-	fotg210_dbg(fotg210,
-		    "  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
-		    hc32_to_cpu(fotg210, itd->hw_bufp[0]),
-		    hc32_to_cpu(fotg210, itd->hw_bufp[1]),
-		    hc32_to_cpu(fotg210, itd->hw_bufp[2]),
-		    hc32_to_cpu(fotg210, itd->hw_bufp[3]),
-		    hc32_to_cpu(fotg210, itd->hw_bufp[4]),
-		    hc32_to_cpu(fotg210, itd->hw_bufp[5]),
-		    hc32_to_cpu(fotg210, itd->hw_bufp[6]));
-
-	fotg210_dbg(fotg210, "  index: %d %d %d %d %d %d %d %d\n",
-		    itd->index[0], itd->index[1], itd->index[2],
-		    itd->index[3], itd->index[4], itd->index[5],
-		    itd->index[6], itd->index[7]);
-}
-
-static int __maybe_unused
-dbg_status_buf(char *buf, unsigned len, const char *label, u32 status)
-{
-	return scnprintf(buf, len, "%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
-			 label, label[0] ? " " : "", status,
-			 (status & STS_ASS) ? " Async" : "",
-			 (status & STS_PSS) ? " Periodic" : "",
-			 (status & STS_RECL) ? " Recl" : "",
-			 (status & STS_HALT) ? " Halt" : "",
-			 (status & STS_IAA) ? " IAA" : "",
-			 (status & STS_FATAL) ? " FATAL" : "",
-			 (status & STS_FLR) ? " FLR" : "",
-			 (status & STS_PCD) ? " PCD" : "",
-			 (status & STS_ERR) ? " ERR" : "",
-			 (status & STS_INT) ? " INT" : "");
-}
-
-static int __maybe_unused
-dbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable)
-{
-	return scnprintf(buf, len, "%s%sintrenable %02x%s%s%s%s%s%s",
-			 label, label[0] ? " " : "", enable,
-			 (enable & STS_IAA) ? " IAA" : "",
-			 (enable & STS_FATAL) ? " FATAL" : "",
-			 (enable & STS_FLR) ? " FLR" : "",
-			 (enable & STS_PCD) ? " PCD" : "",
-			 (enable & STS_ERR) ? " ERR" : "",
-			 (enable & STS_INT) ? " INT" : "");
-}
-
-static const char *const fls_strings[] = { "1024", "512", "256", "??" };
-
-static int dbg_command_buf(char *buf, unsigned len, const char *label,
-			   u32 command)
-{
-	return scnprintf(buf, len,
-			 "%s%scommand %07x %s=%d ithresh=%d%s%s%s period=%s%s %s",
-			 label, label[0] ? " " : "", command,
-			 (command & CMD_PARK) ? " park" : "(park)",
-			 CMD_PARK_CNT(command),
-			 (command >> 16) & 0x3f,
-			 (command & CMD_IAAD) ? " IAAD" : "",
-			 (command & CMD_ASE) ? " Async" : "",
-			 (command & CMD_PSE) ? " Periodic" : "",
-			 fls_strings[(command >> 2) & 0x3],
-			 (command & CMD_RESET) ? " Reset" : "",
-			 (command & CMD_RUN) ? "RUN" : "HALT");
-}
-
-static char *dbg_port_buf(char *buf, unsigned len, const char *label, int port,
-			  u32 status)
-{
-	char *sig;
-
-	/* signaling state */
-	switch (status & (3 << 10)) {
-	case 0 << 10:
-		sig = "se0";
-		break;
-	case 1 << 10:
-		sig = "k";
-		break; /* low speed */
-	case 2 << 10:
-		sig = "j";
-		break;
-	default:
-		sig = "?";
-		break;
-	}
-
-	scnprintf(buf, len, "%s%sport:%d status %06x %d sig=%s%s%s%s%s%s%s%s",
-		  label, label[0] ? " " : "", port, status,
-		  status >> 25, /*device address */
-		  sig,
-		  (status & PORT_RESET) ? " RESET" : "",
-		  (status & PORT_SUSPEND) ? " SUSPEND" : "",
-		  (status & PORT_RESUME) ? " RESUME" : "",
-		  (status & PORT_PEC) ? " PEC" : "",
-		  (status & PORT_PE) ? " PE" : "",
-		  (status & PORT_CSC) ? " CSC" : "",
-		  (status & PORT_CONNECT) ? " CONNECT" : "");
-
-	return buf;
-}
-
-/* functions have the "wrong" filename when they're output... */
-#define dbg_status(fotg210, label, status) {			\
-	char _buf[80];						\
-	dbg_status_buf(_buf, sizeof(_buf), label, status);	\
-	fotg210_dbg(fotg210, "%s\n", _buf);			\
-}
-
-#define dbg_cmd(fotg210, label, command) {			\
-	char _buf[80];						\
-	dbg_command_buf(_buf, sizeof(_buf), label, command);	\
-	fotg210_dbg(fotg210, "%s\n", _buf);			\
-}
-
-#define dbg_port(fotg210, label, port, status) {			    \
-	char _buf[80];							    \
-	fotg210_dbg(fotg210, "%s\n",					    \
-		    dbg_port_buf(_buf, sizeof(_buf), label, port, status)); \
-}
-
-/* troubleshooting help: expose state in debugfs */
-static int debug_async_open(struct inode *, struct file *);
-static int debug_periodic_open(struct inode *, struct file *);
-static int debug_registers_open(struct inode *, struct file *);
-static int debug_async_open(struct inode *, struct file *);
-
-static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
-static int debug_close(struct inode *, struct file *);
-
-static const struct file_operations debug_async_fops = {
-	.owner		= THIS_MODULE,
-	.open		= debug_async_open,
-	.read		= debug_output,
-	.release	= debug_close,
-	.llseek		= default_llseek,
-};
-static const struct file_operations debug_periodic_fops = {
-	.owner		= THIS_MODULE,
-	.open		= debug_periodic_open,
-	.read		= debug_output,
-	.release	= debug_close,
-	.llseek		= default_llseek,
-};
-static const struct file_operations debug_registers_fops = {
-	.owner		= THIS_MODULE,
-	.open		= debug_registers_open,
-	.read		= debug_output,
-	.release	= debug_close,
-	.llseek		= default_llseek,
-};
-
-static struct dentry *fotg210_debug_root;
-
-struct debug_buffer {
-	ssize_t (*fill_func)(struct debug_buffer *);	/* fill method */
-	struct usb_bus *bus;
-	struct mutex mutex;	/* protect filling of buffer */
-	size_t count;		/* number of characters filled into buffer */
-	char *output_buf;
-	size_t alloc_size;
-};
-
-static inline char speed_char(u32 scratch)
-{
-	switch (scratch & (3 << 12)) {
-	case QH_FULL_SPEED:
-		return 'f';
-
-	case QH_LOW_SPEED:
-		return 'l';
-
-	case QH_HIGH_SPEED:
-		return 'h';
-
-	default:
-		return '?';
-	}
-}
-
-static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
-{
-	__u32 v = hc32_to_cpu(fotg210, token);
-
-	if (v & QTD_STS_ACTIVE)
-		return '*';
-	if (v & QTD_STS_HALT)
-		return '-';
-	if (!IS_SHORT_READ(v))
-		return ' ';
-	/* tries to advance through hw_alt_next */
-	return '/';
-}
-
-static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
-		     char **nextp, unsigned *sizep)
-{
-	u32 scratch;
-	u32 hw_curr;
-	struct fotg210_qtd *td;
-	unsigned temp;
-	unsigned size = *sizep;
-	char *next = *nextp;
-	char mark;
-	char *tmp;
-
-	__le32 list_end = FOTG210_LIST_END(fotg210);
-	struct fotg210_qh_hw *hw = qh->hw;
-
-	if (hw->hw_qtd_next == list_end) /* NEC does this */
-		mark = '@';
-	else
-		mark = token_mark(fotg210, hw->hw_token);
-	if (mark == '/') { /* qh_alt_next controls qh advance? */
-		if ((hw->hw_alt_next & QTD_MASK(fotg210)) ==
-		    fotg210->async->hw->hw_alt_next)
-			mark = '#'; /* blocked */
-		else if (hw->hw_alt_next == list_end)
-			mark = '.'; /* use hw_qtd_next */
-		/* else alt_next points to some other qtd */
-	}
-	scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
-	hw_curr = (mark == '*') ? hc32_to_cpup(fotg210, &hw->hw_current) : 0;
-	temp = scnprintf(next, size,
-			"qh/%p dev%d %cs ep%d %08x %08x(%08x%c %s nak%d)",
-			qh, scratch & 0x007f,
-			speed_char(scratch),
-			(scratch >> 8) & 0x000f,
-			scratch, hc32_to_cpup(fotg210, &hw->hw_info2),
-			hc32_to_cpup(fotg210, &hw->hw_token), mark,
-			(cpu_to_hc32(fotg210, QTD_TOGGLE) & hw->hw_token)
-				? "data1" : "data0",
-			(hc32_to_cpup(fotg210, &hw->hw_alt_next) >> 1) & 0x0f);
-	size -= temp;
-	next += temp;
-
-	/* hc may be modifying the list as we read it ... */
-	list_for_each_entry(td, &qh->qtd_list, qtd_list) {
-		scratch = hc32_to_cpup(fotg210, &td->hw_token);
-		mark = ' ';
-		if (hw_curr == td->qtd_dma)
-			mark = '*';
-		else if (hw->hw_qtd_next == cpu_to_hc32(fotg210, td->qtd_dma))
-			mark = '+';
-		else if (QTD_LENGTH(scratch)) {
-			if (td->hw_alt_next == fotg210->async->hw->hw_alt_next)
-				mark = '#';
-			else if (td->hw_alt_next != list_end)
-				mark = '/';
-		}
-
-		switch ((scratch >> 8) & 0x03) {
-		case 0:
-			tmp = "out";
-			break;
-		case 1:
-			tmp = "in";
-			break;
-		case 2:
-			tmp = "setup";
-			break;
-		default:
-			tmp = "?";
-			break;
-		}
-
-		temp = snprintf(next, size, "\n\t%p%c%s len=%d %08x urb %p",
-				td, mark, tmp, (scratch >> 16) & 0x7fff,
-				scratch, td->urb);
-
-		if (size < temp)
-			temp = size;
-
-		size -= temp;
-		next += temp;
-		if (temp == size)
-			goto done;
-	}
-
-	temp = snprintf(next, size, "\n");
-	if (size < temp)
-		temp = size;
-
-	size -= temp;
-	next += temp;
-
-done:
-	*sizep = size;
-	*nextp = next;
-}
-
-static ssize_t fill_async_buffer(struct debug_buffer *buf)
-{
-	struct usb_hcd *hcd;
-	struct fotg210_hcd *fotg210;
-	unsigned long flags;
-	unsigned temp, size;
-	char *next;
-	struct fotg210_qh *qh;
-
-	hcd = bus_to_hcd(buf->bus);
-	fotg210 = hcd_to_fotg210(hcd);
-	next = buf->output_buf;
-	size = buf->alloc_size;
-
-	*next = 0;
-
-	/* dumps a snapshot of the async schedule.
-	 * usually empty except for long-term bulk reads, or head.
-	 * one QH per line, and TDs we know about
-	 */
-	spin_lock_irqsave(&fotg210->lock, flags);
-	for (qh = fotg210->async->qh_next.qh; size > 0 && qh;
-	     qh = qh->qh_next.qh)
-		qh_lines(fotg210, qh, &next, &size);
-	if (fotg210->async_unlink && size > 0) {
-		temp = scnprintf(next, size, "\nunlink =\n");
-		size -= temp;
-		next += temp;
-
-		for (qh = fotg210->async_unlink; size > 0 && qh;
-				qh = qh->unlink_next)
-			qh_lines(fotg210, qh, &next, &size);
-	}
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-
-	return strlen(buf->output_buf);
-}
-
-/* count tds, get ep direction */
-static inline unsigned output_buf_tds_dir(char *buf,
-					  struct fotg210_hcd *fotg210,
-					  struct fotg210_qh_hw *hw,
-					  struct fotg210_qh *qh, unsigned size)
-{
-	u32 scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
-	struct fotg210_qtd *qtd;
-	char *type = "";
-	unsigned temp = 0;
-
-	/* count tds, get ep direction */
-	list_for_each_entry(qtd, &qh->qtd_list, qtd_list) {
-		temp++;
-		switch (0x03 & (hc32_to_cpu(fotg210, qtd->hw_token) >> 8)) {
-		case 0:
-			type = "out";
-			continue;
-		case 1:
-			type = "in";
-			continue;
-		}
-	}
-
-	return scnprintf(buf, size, "(%c%d ep%d%s [%d/%d] q%d p%d)",
-			 speed_char(scratch), scratch & 0x007f,
-			 (scratch >> 8) & 0x000f, type, qh->usecs,
-			 qh->c_usecs, temp, 0x7ff & (scratch >> 16));
-}
-
-#define DBG_SCHED_LIMIT 64
-static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
-{
-	struct usb_hcd *hcd;
-	struct fotg210_hcd *fotg210;
-	unsigned long flags;
-	union fotg210_shadow p, *seen;
-	unsigned temp, size, seen_count;
-	char *next;
-	unsigned i;
-	__hc32 tag;
-
-	seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC);
-	if (!seen)
-		return 0;
-
-	seen_count = 0;
-
-	hcd = bus_to_hcd(buf->bus);
-	fotg210 = hcd_to_fotg210(hcd);
-	next = buf->output_buf;
-	size = buf->alloc_size;
-
-	temp = scnprintf(next, size, "size = %d\n", fotg210->periodic_size);
-	size -= temp;
-	next += temp;
-
-	/* dump a snapshot of the periodic schedule.
-	 * iso changes, interrupt usually doesn't.
-	 */
-	spin_lock_irqsave(&fotg210->lock, flags);
-	for (i = 0; i < fotg210->periodic_size; i++) {
-		p = fotg210->pshadow[i];
-		if (likely(!p.ptr))
-			continue;
-
-		tag = Q_NEXT_TYPE(fotg210, fotg210->periodic[i]);
-
-		temp = scnprintf(next, size, "%4d: ", i);
-		size -= temp;
-		next += temp;
-
-		do {
-			struct fotg210_qh_hw *hw;
-
-			switch (hc32_to_cpu(fotg210, tag)) {
-			case Q_TYPE_QH:
-				hw = p.qh->hw;
-				temp = scnprintf(next, size, " qh%d-%04x/%p",
-						p.qh->period,
-						hc32_to_cpup(fotg210,
-							&hw->hw_info2)
-							/* uframe masks */
-							& (QH_CMASK | QH_SMASK),
-						p.qh);
-				size -= temp;
-				next += temp;
-				/* don't repeat what follows this qh */
-				for (temp = 0; temp < seen_count; temp++) {
-					if (seen[temp].ptr != p.ptr)
-						continue;
-					if (p.qh->qh_next.ptr) {
-						temp = scnprintf(next, size,
-							" ...");
-						size -= temp;
-						next += temp;
-					}
-					break;
-				}
-				/* show more info the first time around */
-				if (temp == seen_count) {
-					temp = output_buf_tds_dir(next,
-								  fotg210, hw,
-								  p.qh, size);
-
-					if (seen_count < DBG_SCHED_LIMIT)
-						seen[seen_count++].qh = p.qh;
-				} else
-					temp = 0;
-				tag = Q_NEXT_TYPE(fotg210, hw->hw_next);
-				p = p.qh->qh_next;
-				break;
-			case Q_TYPE_FSTN:
-				temp = scnprintf(next, size,
-					" fstn-%8x/%p", p.fstn->hw_prev,
-					p.fstn);
-				tag = Q_NEXT_TYPE(fotg210, p.fstn->hw_next);
-				p = p.fstn->fstn_next;
-				break;
-			case Q_TYPE_ITD:
-				temp = scnprintf(next, size,
-					" itd/%p", p.itd);
-				tag = Q_NEXT_TYPE(fotg210, p.itd->hw_next);
-				p = p.itd->itd_next;
-				break;
-			}
-			size -= temp;
-			next += temp;
-		} while (p.ptr);
-
-		temp = scnprintf(next, size, "\n");
-		size -= temp;
-		next += temp;
-	}
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-	kfree(seen);
-
-	return buf->alloc_size - size;
-}
-#undef DBG_SCHED_LIMIT
-
-static const char *rh_state_string(struct fotg210_hcd *fotg210)
-{
-	switch (fotg210->rh_state) {
-	case FOTG210_RH_HALTED:
-		return "halted";
-	case FOTG210_RH_SUSPENDED:
-		return "suspended";
-	case FOTG210_RH_RUNNING:
-		return "running";
-	case FOTG210_RH_STOPPING:
-		return "stopping";
-	}
-	return "?";
-}
-
-static ssize_t fill_registers_buffer(struct debug_buffer *buf)
-{
-	struct usb_hcd *hcd;
-	struct fotg210_hcd *fotg210;
-	unsigned long flags;
-	unsigned temp, size, i;
-	char *next, scratch[80];
-	static const char fmt[] = "%*s\n";
-	static const char label[] = "";
-
-	hcd = bus_to_hcd(buf->bus);
-	fotg210 = hcd_to_fotg210(hcd);
-	next = buf->output_buf;
-	size = buf->alloc_size;
-
-	spin_lock_irqsave(&fotg210->lock, flags);
-
-	if (!HCD_HW_ACCESSIBLE(hcd)) {
-		size = scnprintf(next, size,
-			"bus %s, device %s\n"
-			"%s\n"
-			"SUSPENDED(no register access)\n",
-			hcd->self.controller->bus->name,
-			dev_name(hcd->self.controller),
-			hcd->product_desc);
-		goto done;
-	}
-
-	/* Capability Registers */
-	i = HC_VERSION(fotg210, fotg210_readl(fotg210,
-					      &fotg210->caps->hc_capbase));
-	temp = scnprintf(next, size,
-		"bus %s, device %s\n"
-		"%s\n"
-		"EHCI %x.%02x, rh state %s\n",
-		hcd->self.controller->bus->name,
-		dev_name(hcd->self.controller),
-		hcd->product_desc,
-		i >> 8, i & 0x0ff, rh_state_string(fotg210));
-	size -= temp;
-	next += temp;
-
-	/* FIXME interpret both types of params */
-	i = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
-	temp = scnprintf(next, size, "structural params 0x%08x\n", i);
-	size -= temp;
-	next += temp;
-
-	i = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
-	temp = scnprintf(next, size, "capability params 0x%08x\n", i);
-	size -= temp;
-	next += temp;
-
-	/* Operational Registers */
-	temp = dbg_status_buf(scratch, sizeof(scratch), label,
-			fotg210_readl(fotg210, &fotg210->regs->status));
-	temp = scnprintf(next, size, fmt, temp, scratch);
-	size -= temp;
-	next += temp;
-
-	temp = dbg_command_buf(scratch, sizeof(scratch), label,
-			fotg210_readl(fotg210, &fotg210->regs->command));
-	temp = scnprintf(next, size, fmt, temp, scratch);
-	size -= temp;
-	next += temp;
-
-	temp = dbg_intr_buf(scratch, sizeof(scratch), label,
-			fotg210_readl(fotg210, &fotg210->regs->intr_enable));
-	temp = scnprintf(next, size, fmt, temp, scratch);
-	size -= temp;
-	next += temp;
-
-	temp = scnprintf(next, size, "uframe %04x\n",
-			fotg210_read_frame_index(fotg210));
-	size -= temp;
-	next += temp;
-
-	if (fotg210->async_unlink) {
-		temp = scnprintf(next, size, "async unlink qh %p\n",
-				fotg210->async_unlink);
-		size -= temp;
-		next += temp;
-	}
-
-#ifdef FOTG210_STATS
-	temp = scnprintf(next, size,
-		"irq normal %ld err %ld iaa %ld(lost %ld)\n",
-		fotg210->stats.normal, fotg210->stats.error, fotg210->stats.iaa,
-		fotg210->stats.lost_iaa);
-	size -= temp;
-	next += temp;
-
-	temp = scnprintf(next, size, "complete %ld unlink %ld\n",
-		fotg210->stats.complete, fotg210->stats.unlink);
-	size -= temp;
-	next += temp;
-#endif
-
-done:
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-
-	return buf->alloc_size - size;
-}
-
-static struct debug_buffer
-*alloc_buffer(struct usb_bus *bus, ssize_t (*fill_func)(struct debug_buffer *))
-{
-	struct debug_buffer *buf;
-
-	buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL);
-
-	if (buf) {
-		buf->bus = bus;
-		buf->fill_func = fill_func;
-		mutex_init(&buf->mutex);
-		buf->alloc_size = PAGE_SIZE;
-	}
-
-	return buf;
-}
-
-static int fill_buffer(struct debug_buffer *buf)
-{
-	int ret = 0;
-
-	if (!buf->output_buf)
-		buf->output_buf = vmalloc(buf->alloc_size);
-
-	if (!buf->output_buf) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	ret = buf->fill_func(buf);
-
-	if (ret >= 0) {
-		buf->count = ret;
-		ret = 0;
-	}
-
-out:
-	return ret;
-}
-
-static ssize_t debug_output(struct file *file, char __user *user_buf,
-			    size_t len, loff_t *offset)
-{
-	struct debug_buffer *buf = file->private_data;
-	int ret = 0;
-
-	mutex_lock(&buf->mutex);
-	if (buf->count == 0) {
-		ret = fill_buffer(buf);
-		if (ret != 0) {
-			mutex_unlock(&buf->mutex);
-			goto out;
-		}
-	}
-	mutex_unlock(&buf->mutex);
-
-	ret = simple_read_from_buffer(user_buf, len, offset,
-				      buf->output_buf, buf->count);
-
-out:
-	return ret;
-
-}
-
-static int debug_close(struct inode *inode, struct file *file)
-{
-	struct debug_buffer *buf = file->private_data;
-
-	if (buf) {
-		vfree(buf->output_buf);
-		kfree(buf);
-	}
-
-	return 0;
-}
-static int debug_async_open(struct inode *inode, struct file *file)
-{
-	file->private_data = alloc_buffer(inode->i_private, fill_async_buffer);
-
-	return file->private_data ? 0 : -ENOMEM;
-}
-
-static int debug_periodic_open(struct inode *inode, struct file *file)
-{
-	struct debug_buffer *buf;
-
-	buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
-	if (!buf)
-		return -ENOMEM;
-
-	buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8)*PAGE_SIZE;
-	file->private_data = buf;
-	return 0;
-}
-
-static int debug_registers_open(struct inode *inode, struct file *file)
-{
-	file->private_data = alloc_buffer(inode->i_private,
-					  fill_registers_buffer);
-
-	return file->private_data ? 0 : -ENOMEM;
-}
-
-static inline void create_debug_files(struct fotg210_hcd *fotg210)
-{
-	struct usb_bus *bus = &fotg210_to_hcd(fotg210)->self;
-
-	fotg210->debug_dir = debugfs_create_dir(bus->bus_name,
-						fotg210_debug_root);
-	if (!fotg210->debug_dir)
-		return;
-
-	if (!debugfs_create_file("async", S_IRUGO, fotg210->debug_dir, bus,
-						&debug_async_fops))
-		goto file_error;
-
-	if (!debugfs_create_file("periodic", S_IRUGO, fotg210->debug_dir, bus,
-						&debug_periodic_fops))
-		goto file_error;
-
-	if (!debugfs_create_file("registers", S_IRUGO, fotg210->debug_dir, bus,
-						    &debug_registers_fops))
-		goto file_error;
-
-	return;
-
-file_error:
-	debugfs_remove_recursive(fotg210->debug_dir);
-}
-
-static inline void remove_debug_files(struct fotg210_hcd *fotg210)
-{
-	debugfs_remove_recursive(fotg210->debug_dir);
-}
-
-/*
- * handshake - spin reading hc until handshake completes or fails
- * @ptr: address of hc register to be read
- * @mask: bits to look at in result of read
- * @done: value of those bits when handshake succeeds
- * @usec: timeout in microseconds
- *
- * Returns negative errno, or zero on success
- *
- * Success happens when the "mask" bits have the specified value (hardware
- * handshake done).  There are two failure modes:  "usec" have passed (major
- * hardware flakeout), or the register reads as all-ones (hardware removed).
- *
- * That last failure should_only happen in cases like physical cardbus eject
- * before driver shutdown. But it also seems to be caused by bugs in cardbus
- * bridge shutdown:  shutting down the bridge before the devices using it.
- */
-static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
-		     u32 mask, u32 done, int usec)
-{
-	u32 result;
-
-	do {
-		result = fotg210_readl(fotg210, ptr);
-		if (result == ~(u32)0)		/* card removed */
-			return -ENODEV;
-		result &= mask;
-		if (result == done)
-			return 0;
-		udelay(1);
-		usec--;
-	} while (usec > 0);
-	return -ETIMEDOUT;
-}
-
-/*
- * Force HC to halt state from unknown (EHCI spec section 2.3).
- * Must be called with interrupts enabled and the lock not held.
- */
-static int fotg210_halt(struct fotg210_hcd *fotg210)
-{
-	u32 temp;
-
-	spin_lock_irq(&fotg210->lock);
-
-	/* disable any irqs left enabled by previous code */
-	fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
-
-	/*
-	 * This routine gets called during probe before fotg210->command
-	 * has been initialized, so we can't rely on its value.
-	 */
-	fotg210->command &= ~CMD_RUN;
-	temp = fotg210_readl(fotg210, &fotg210->regs->command);
-	temp &= ~(CMD_RUN | CMD_IAAD);
-	fotg210_writel(fotg210, temp, &fotg210->regs->command);
-
-	spin_unlock_irq(&fotg210->lock);
-	synchronize_irq(fotg210_to_hcd(fotg210)->irq);
-
-	return handshake(fotg210, &fotg210->regs->status,
-			  STS_HALT, STS_HALT, 16 * 125);
-}
-
-/*
- * Reset a non-running (STS_HALT == 1) controller.
- * Must be called with interrupts enabled and the lock not held.
- */
-static int fotg210_reset(struct fotg210_hcd *fotg210)
-{
-	int retval;
-	u32 command = fotg210_readl(fotg210, &fotg210->regs->command);
-
-	/* If the EHCI debug controller is active, special care must be
-	 * taken before and after a host controller reset
-	 */
-	if (fotg210->debug && !dbgp_reset_prep(fotg210_to_hcd(fotg210)))
-		fotg210->debug = NULL;
-
-	command |= CMD_RESET;
-	dbg_cmd(fotg210, "reset", command);
-	fotg210_writel(fotg210, command, &fotg210->regs->command);
-	fotg210->rh_state = FOTG210_RH_HALTED;
-	fotg210->next_statechange = jiffies;
-	retval = handshake(fotg210, &fotg210->regs->command,
-			    CMD_RESET, 0, 250 * 1000);
-
-	if (retval)
-		return retval;
-
-	if (fotg210->debug)
-		dbgp_external_startup(fotg210_to_hcd(fotg210));
-
-	fotg210->port_c_suspend = fotg210->suspended_ports =
-			fotg210->resuming_ports = 0;
-	return retval;
-}
-
-/*
- * Idle the controller (turn off the schedules).
- * Must be called with interrupts enabled and the lock not held.
- */
-static void fotg210_quiesce(struct fotg210_hcd *fotg210)
-{
-	u32 temp;
-
-	if (fotg210->rh_state != FOTG210_RH_RUNNING)
-		return;
-
-	/* wait for any schedule enables/disables to take effect */
-	temp = (fotg210->command << 10) & (STS_ASS | STS_PSS);
-	handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, temp,
-		  16 * 125);
-
-	/* then disable anything that's still active */
-	spin_lock_irq(&fotg210->lock);
-	fotg210->command &= ~(CMD_ASE | CMD_PSE);
-	fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
-	spin_unlock_irq(&fotg210->lock);
-
-	/* hardware can take 16 microframes to turn off ... */
-	handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, 0,
-		  16 * 125);
-}
-
-static void end_unlink_async(struct fotg210_hcd *fotg210);
-static void unlink_empty_async(struct fotg210_hcd *fotg210);
-static void fotg210_work(struct fotg210_hcd *fotg210);
-static void start_unlink_intr(struct fotg210_hcd *fotg210,
-			      struct fotg210_qh *qh);
-static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
-
-/* Set a bit in the USBCMD register */
-static void fotg210_set_command_bit(struct fotg210_hcd *fotg210, u32 bit)
-{
-	fotg210->command |= bit;
-	fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
-
-	/* unblock posted write */
-	fotg210_readl(fotg210, &fotg210->regs->command);
-}
-
-/* Clear a bit in the USBCMD register */
-static void fotg210_clear_command_bit(struct fotg210_hcd *fotg210, u32 bit)
-{
-	fotg210->command &= ~bit;
-	fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
-
-	/* unblock posted write */
-	fotg210_readl(fotg210, &fotg210->regs->command);
-}
-
-/*
- * EHCI timer support...  Now using hrtimers.
- *
- * Lots of different events are triggered from fotg210->hrtimer.  Whenever
- * the timer routine runs, it checks each possible event; events that are
- * currently enabled and whose expiration time has passed get handled.
- * The set of enabled events is stored as a collection of bitflags in
- * fotg210->enabled_hrtimer_events, and they are numbered in order of
- * increasing delay values (ranging between 1 ms and 100 ms).
- *
- * Rather than implementing a sorted list or tree of all pending events,
- * we keep track only of the lowest-numbered pending event, in
- * fotg210->next_hrtimer_event.  Whenever fotg210->hrtimer gets restarted, its
- * expiration time is set to the timeout value for this event.
- *
- * As a result, events might not get handled right away; the actual delay
- * could be anywhere up to twice the requested delay.  This doesn't
- * matter, because none of the events are especially time-critical.  The
- * ones that matter most all have a delay of 1 ms, so they will be
- * handled after 2 ms at most, which is okay.  In addition to this, we
- * allow for an expiration range of 1 ms.
- */
-
-/*
- * Delay lengths for the hrtimer event types.
- * Keep this list sorted by delay length, in the same order as
- * the event types indexed by enum fotg210_hrtimer_event in fotg210.h.
- */
-static unsigned event_delays_ns[] = {
-	1 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_POLL_ASS */
-	1 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_POLL_PSS */
-	1 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_POLL_DEAD */
-	1125 * NSEC_PER_USEC,	/* FOTG210_HRTIMER_UNLINK_INTR */
-	2 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_FREE_ITDS */
-	6 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_ASYNC_UNLINKS */
-	10 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_IAA_WATCHDOG */
-	10 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_DISABLE_PERIODIC */
-	15 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_DISABLE_ASYNC */
-	100 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_IO_WATCHDOG */
-};
-
-/* Enable a pending hrtimer event */
-static void fotg210_enable_event(struct fotg210_hcd *fotg210, unsigned event,
-				 bool resched)
-{
-	ktime_t *timeout = &fotg210->hr_timeouts[event];
-
-	if (resched)
-		*timeout = ktime_add(ktime_get(),
-				ktime_set(0, event_delays_ns[event]));
-	fotg210->enabled_hrtimer_events |= (1 << event);
-
-	/* Track only the lowest-numbered pending event */
-	if (event < fotg210->next_hrtimer_event) {
-		fotg210->next_hrtimer_event = event;
-		hrtimer_start_range_ns(&fotg210->hrtimer, *timeout,
-				NSEC_PER_MSEC, HRTIMER_MODE_ABS);
-	}
-}
-
-
-/* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */
-static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
-{
-	unsigned actual, want;
-
-	/* Don't enable anything if the controller isn't running (e.g., died) */
-	if (fotg210->rh_state != FOTG210_RH_RUNNING)
-		return;
-
-	want = (fotg210->command & CMD_ASE) ? STS_ASS : 0;
-	actual = fotg210_readl(fotg210, &fotg210->regs->status) & STS_ASS;
-
-	if (want != actual) {
-
-		/* Poll again later, but give up after about 20 ms */
-		if (fotg210->ASS_poll_count++ < 20) {
-			fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_ASS,
-					     true);
-			return;
-		}
-		fotg210_dbg(fotg210, "Waited too long for the async schedule status (%x/%x), giving up\n",
-				want, actual);
-	}
-	fotg210->ASS_poll_count = 0;
-
-	/* The status is up-to-date; restart or stop the schedule as needed */
-	if (want == 0) {	/* Stopped */
-		if (fotg210->async_count > 0)
-			fotg210_set_command_bit(fotg210, CMD_ASE);
-
-	} else {		/* Running */
-		if (fotg210->async_count == 0) {
-
-			/* Turn off the schedule after a while */
-			fotg210_enable_event(fotg210,
-					     FOTG210_HRTIMER_DISABLE_ASYNC,
-					     true);
-		}
-	}
-}
-
-/* Turn off the async schedule after a brief delay */
-static void fotg210_disable_ASE(struct fotg210_hcd *fotg210)
-{
-	fotg210_clear_command_bit(fotg210, CMD_ASE);
-}
-
-
-/* Poll the STS_PSS status bit; see when it agrees with CMD_PSE */
-static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
-{
-	unsigned actual, want;
-
-	/* Don't do anything if the controller isn't running (e.g., died) */
-	if (fotg210->rh_state != FOTG210_RH_RUNNING)
-		return;
-
-	want = (fotg210->command & CMD_PSE) ? STS_PSS : 0;
-	actual = fotg210_readl(fotg210, &fotg210->regs->status) & STS_PSS;
-
-	if (want != actual) {
-
-		/* Poll again later, but give up after about 20 ms */
-		if (fotg210->PSS_poll_count++ < 20) {
-			fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_PSS,
-					     true);
-			return;
-		}
-		fotg210_dbg(fotg210, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
-				want, actual);
-	}
-	fotg210->PSS_poll_count = 0;
-
-	/* The status is up-to-date; restart or stop the schedule as needed */
-	if (want == 0) {	/* Stopped */
-		if (fotg210->periodic_count > 0)
-			fotg210_set_command_bit(fotg210, CMD_PSE);
-
-	} else {		/* Running */
-		if (fotg210->periodic_count == 0) {
-
-			/* Turn off the schedule after a while */
-			fotg210_enable_event(fotg210,
-					     FOTG210_HRTIMER_DISABLE_PERIODIC,
-					     true);
-		}
-	}
-}
-
-/* Turn off the periodic schedule after a brief delay */
-static void fotg210_disable_PSE(struct fotg210_hcd *fotg210)
-{
-	fotg210_clear_command_bit(fotg210, CMD_PSE);
-}
-
-
-/* Poll the STS_HALT status bit; see when a dead controller stops */
-static void fotg210_handle_controller_death(struct fotg210_hcd *fotg210)
-{
-	if (!(fotg210_readl(fotg210, &fotg210->regs->status) & STS_HALT)) {
-
-		/* Give up after a few milliseconds */
-		if (fotg210->died_poll_count++ < 5) {
-			/* Try again later */
-			fotg210_enable_event(fotg210,
-					     FOTG210_HRTIMER_POLL_DEAD, true);
-			return;
-		}
-		fotg210_warn(fotg210, "Waited too long for the controller to stop, giving up\n");
-	}
-
-	/* Clean up the mess */
-	fotg210->rh_state = FOTG210_RH_HALTED;
-	fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
-	fotg210_work(fotg210);
-	end_unlink_async(fotg210);
-
-	/* Not in process context, so don't try to reset the controller */
-}
-
-
-/* Handle unlinked interrupt QHs once they are gone from the hardware */
-static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
-{
-	bool stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
-
-	/*
-	 * Process all the QHs on the intr_unlink list that were added
-	 * before the current unlink cycle began.  The list is in
-	 * temporal order, so stop when we reach the first entry in the
-	 * current cycle.  But if the root hub isn't running then
-	 * process all the QHs on the list.
-	 */
-	fotg210->intr_unlinking = true;
-	while (fotg210->intr_unlink) {
-		struct fotg210_qh *qh = fotg210->intr_unlink;
-
-		if (!stopped && qh->unlink_cycle == fotg210->intr_unlink_cycle)
-			break;
-		fotg210->intr_unlink = qh->unlink_next;
-		qh->unlink_next = NULL;
-		end_unlink_intr(fotg210, qh);
-	}
-
-	/* Handle remaining entries later */
-	if (fotg210->intr_unlink) {
-		fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
-				     true);
-		++fotg210->intr_unlink_cycle;
-	}
-	fotg210->intr_unlinking = false;
-}
-
-
-/* Start another free-iTDs/siTDs cycle */
-static void start_free_itds(struct fotg210_hcd *fotg210)
-{
-	if (!(fotg210->enabled_hrtimer_events &
-			BIT(FOTG210_HRTIMER_FREE_ITDS))) {
-		fotg210->last_itd_to_free = list_entry(
-				fotg210->cached_itd_list.prev,
-				struct fotg210_itd, itd_list);
-		fotg210_enable_event(fotg210, FOTG210_HRTIMER_FREE_ITDS, true);
-	}
-}
-
-/* Wait for controller to stop using old iTDs and siTDs */
-static void end_free_itds(struct fotg210_hcd *fotg210)
-{
-	struct fotg210_itd *itd, *n;
-
-	if (fotg210->rh_state < FOTG210_RH_RUNNING)
-		fotg210->last_itd_to_free = NULL;
-
-	list_for_each_entry_safe(itd, n, &fotg210->cached_itd_list, itd_list) {
-		list_del(&itd->itd_list);
-		dma_pool_free(fotg210->itd_pool, itd, itd->itd_dma);
-		if (itd == fotg210->last_itd_to_free)
-			break;
-	}
-
-	if (!list_empty(&fotg210->cached_itd_list))
-		start_free_itds(fotg210);
-}
-
-
-/* Handle lost (or very late) IAA interrupts */
-static void fotg210_iaa_watchdog(struct fotg210_hcd *fotg210)
-{
-	if (fotg210->rh_state != FOTG210_RH_RUNNING)
-		return;
-
-	/*
-	 * Lost IAA irqs wedge things badly; seen first with a vt8235.
-	 * So we need this watchdog, but must protect it against both
-	 * (a) SMP races against real IAA firing and retriggering, and
-	 * (b) clean HC shutdown, when IAA watchdog was pending.
-	 */
-	if (fotg210->async_iaa) {
-		u32 cmd, status;
-
-		/* If we get here, IAA is *REALLY* late.  It's barely
-		 * conceivable that the system is so busy that CMD_IAAD
-		 * is still legitimately set, so let's be sure it's
-		 * clear before we read STS_IAA.  (The HC should clear
-		 * CMD_IAAD when it sets STS_IAA.)
-		 */
-		cmd = fotg210_readl(fotg210, &fotg210->regs->command);
-
-		/*
-		 * If IAA is set here it either legitimately triggered
-		 * after the watchdog timer expired (_way_ late, so we'll
-		 * still count it as lost) ... or a silicon erratum:
-		 * - VIA seems to set IAA without triggering the IRQ;
-		 * - IAAD potentially cleared without setting IAA.
-		 */
-		status = fotg210_readl(fotg210, &fotg210->regs->status);
-		if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
-			COUNT(fotg210->stats.lost_iaa);
-			fotg210_writel(fotg210, STS_IAA,
-				       &fotg210->regs->status);
-		}
-
-		fotg210_dbg(fotg210, "IAA watchdog: status %x cmd %x\n",
-				status, cmd);
-		end_unlink_async(fotg210);
-	}
-}
-
-
-/* Enable the I/O watchdog, if appropriate */
-static void turn_on_io_watchdog(struct fotg210_hcd *fotg210)
-{
-	/* Not needed if the controller isn't running or it's already enabled */
-	if (fotg210->rh_state != FOTG210_RH_RUNNING ||
-			(fotg210->enabled_hrtimer_events &
-				BIT(FOTG210_HRTIMER_IO_WATCHDOG)))
-		return;
-
-	/*
-	 * Isochronous transfers always need the watchdog.
-	 * For other sorts we use it only if the flag is set.
-	 */
-	if (fotg210->isoc_count > 0 || (fotg210->need_io_watchdog &&
-			fotg210->async_count + fotg210->intr_count > 0))
-		fotg210_enable_event(fotg210, FOTG210_HRTIMER_IO_WATCHDOG,
-				     true);
-}
-
-
-/*
- * Handler functions for the hrtimer event types.
- * Keep this array in the same order as the event types indexed by
- * enum fotg210_hrtimer_event in fotg210.h.
- */
-static void (*event_handlers[])(struct fotg210_hcd *) = {
-	fotg210_poll_ASS,			/* FOTG210_HRTIMER_POLL_ASS */
-	fotg210_poll_PSS,			/* FOTG210_HRTIMER_POLL_PSS */
-	fotg210_handle_controller_death,	/* FOTG210_HRTIMER_POLL_DEAD */
-	fotg210_handle_intr_unlinks,	/* FOTG210_HRTIMER_UNLINK_INTR */
-	end_free_itds,			/* FOTG210_HRTIMER_FREE_ITDS */
-	unlink_empty_async,		/* FOTG210_HRTIMER_ASYNC_UNLINKS */
-	fotg210_iaa_watchdog,		/* FOTG210_HRTIMER_IAA_WATCHDOG */
-	fotg210_disable_PSE,		/* FOTG210_HRTIMER_DISABLE_PERIODIC */
-	fotg210_disable_ASE,		/* FOTG210_HRTIMER_DISABLE_ASYNC */
-	fotg210_work,			/* FOTG210_HRTIMER_IO_WATCHDOG */
-};
-
-static enum hrtimer_restart fotg210_hrtimer_func(struct hrtimer *t)
-{
-	struct fotg210_hcd *fotg210 =
-			container_of(t, struct fotg210_hcd, hrtimer);
-	ktime_t now;
-	unsigned long events;
-	unsigned long flags;
-	unsigned e;
-
-	spin_lock_irqsave(&fotg210->lock, flags);
-
-	events = fotg210->enabled_hrtimer_events;
-	fotg210->enabled_hrtimer_events = 0;
-	fotg210->next_hrtimer_event = FOTG210_HRTIMER_NO_EVENT;
-
-	/*
-	 * Check each pending event.  If its time has expired, handle
-	 * the event; otherwise re-enable it.
-	 */
-	now = ktime_get();
-	for_each_set_bit(e, &events, FOTG210_HRTIMER_NUM_EVENTS) {
-		if (now.tv64 >= fotg210->hr_timeouts[e].tv64)
-			event_handlers[e](fotg210);
-		else
-			fotg210_enable_event(fotg210, e, false);
-	}
-
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-	return HRTIMER_NORESTART;
-}
-
-#define fotg210_bus_suspend NULL
-#define fotg210_bus_resume NULL
-
-static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
-				u32 __iomem *status_reg, int port_status)
-{
-	if (!(port_status & PORT_CONNECT))
-		return port_status;
-
-	/* if reset finished and it's still not enabled -- handoff */
-	if (!(port_status & PORT_PE)) {
-		/* with integrated TT, there's nobody to hand it to! */
-		fotg210_dbg(fotg210,
-			"Failed to enable port %d on root hub TT\n",
-			index+1);
-		return port_status;
-	}
-	fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
-		    index + 1);
-
-	return port_status;
-}
-
-
-/* build "status change" packet (one or two bytes) from HC registers */
-
-static int fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
-{
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-	u32 temp, status;
-	u32 mask;
-	int retval = 1;
-	unsigned long flags;
-
-	/* init status to no-changes */
-	buf[0] = 0;
-
-	/* Inform the core about resumes-in-progress by returning
-	 * a non-zero value even if there are no status changes.
-	 */
-	status = fotg210->resuming_ports;
-
-	mask = PORT_CSC | PORT_PEC;
-	/* PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND */
-
-	/* no hub change reports (bit 0) for now (power, ...) */
-
-	/* port N changes (bit N)? */
-	spin_lock_irqsave(&fotg210->lock, flags);
-
-	temp = fotg210_readl(fotg210, &fotg210->regs->port_status);
-
-	/*
-	 * Return status information even for ports with OWNER set.
-	 * Otherwise hub_wq wouldn't see the disconnect event when a
-	 * high-speed device is switched over to the companion
-	 * controller by the user.
-	 */
-
-	if ((temp & mask) != 0 || test_bit(0, &fotg210->port_c_suspend)
-			|| (fotg210->reset_done[0] && time_after_eq(
-				jiffies, fotg210->reset_done[0]))) {
-		buf[0] |= 1 << 1;
-		status = STS_PCD;
-	}
-	/* FIXME autosuspend idle root hubs */
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-	return status ? retval : 0;
-}
-
-static void fotg210_hub_descriptor(struct fotg210_hcd *fotg210,
-				   struct usb_hub_descriptor *desc)
-{
-	int ports = HCS_N_PORTS(fotg210->hcs_params);
-	u16 temp;
-
-	desc->bDescriptorType = USB_DT_HUB;
-	desc->bPwrOn2PwrGood = 10;	/* fotg210 1.0, 2.3.9 says 20ms max */
-	desc->bHubContrCurrent = 0;
-
-	desc->bNbrPorts = ports;
-	temp = 1 + (ports / 8);
-	desc->bDescLength = 7 + 2 * temp;
-
-	/* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
-	memset(&desc->u.hs.DeviceRemovable[0], 0, temp);
-	memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp);
-
-	temp = HUB_CHAR_INDV_PORT_OCPM;	/* per-port overcurrent reporting */
-	temp |= HUB_CHAR_NO_LPSM;	/* no power switching */
-	desc->wHubCharacteristics = cpu_to_le16(temp);
-}
-
-static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
-			       u16 wIndex, char *buf, u16 wLength)
-{
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-	int ports = HCS_N_PORTS(fotg210->hcs_params);
-	u32 __iomem *status_reg = &fotg210->regs->port_status;
-	u32 temp, temp1, status;
-	unsigned long flags;
-	int retval = 0;
-	unsigned selector;
-
-	/*
-	 * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
-	 * HCS_INDICATOR may say we can change LEDs to off/amber/green.
-	 * (track current state ourselves) ... blink for diagnostics,
-	 * power, "this is the one", etc.  EHCI spec supports this.
-	 */
-
-	spin_lock_irqsave(&fotg210->lock, flags);
-	switch (typeReq) {
-	case ClearHubFeature:
-		switch (wValue) {
-		case C_HUB_LOCAL_POWER:
-		case C_HUB_OVER_CURRENT:
-			/* no hub-wide feature/status flags */
-			break;
-		default:
-			goto error;
-		}
-		break;
-	case ClearPortFeature:
-		if (!wIndex || wIndex > ports)
-			goto error;
-		wIndex--;
-		temp = fotg210_readl(fotg210, status_reg);
-		temp &= ~PORT_RWC_BITS;
-
-		/*
-		 * Even if OWNER is set, so the port is owned by the
-		 * companion controller, hub_wq needs to be able to clear
-		 * the port-change status bits (especially
-		 * USB_PORT_STAT_C_CONNECTION).
-		 */
-
-		switch (wValue) {
-		case USB_PORT_FEAT_ENABLE:
-			fotg210_writel(fotg210, temp & ~PORT_PE, status_reg);
-			break;
-		case USB_PORT_FEAT_C_ENABLE:
-			fotg210_writel(fotg210, temp | PORT_PEC, status_reg);
-			break;
-		case USB_PORT_FEAT_SUSPEND:
-			if (temp & PORT_RESET)
-				goto error;
-			if (!(temp & PORT_SUSPEND))
-				break;
-			if ((temp & PORT_PE) == 0)
-				goto error;
-
-			/* resume signaling for 20 msec */
-			fotg210_writel(fotg210, temp | PORT_RESUME, status_reg);
-			fotg210->reset_done[wIndex] = jiffies
-					+ msecs_to_jiffies(USB_RESUME_TIMEOUT);
-			break;
-		case USB_PORT_FEAT_C_SUSPEND:
-			clear_bit(wIndex, &fotg210->port_c_suspend);
-			break;
-		case USB_PORT_FEAT_C_CONNECTION:
-			fotg210_writel(fotg210, temp | PORT_CSC, status_reg);
-			break;
-		case USB_PORT_FEAT_C_OVER_CURRENT:
-			fotg210_writel(fotg210, temp | OTGISR_OVC,
-				       &fotg210->regs->otgisr);
-			break;
-		case USB_PORT_FEAT_C_RESET:
-			/* GetPortStatus clears reset */
-			break;
-		default:
-			goto error;
-		}
-		fotg210_readl(fotg210, &fotg210->regs->command);
-		break;
-	case GetHubDescriptor:
-		fotg210_hub_descriptor(fotg210, (struct usb_hub_descriptor *)
-			buf);
-		break;
-	case GetHubStatus:
-		/* no hub-wide feature/status flags */
-		memset(buf, 0, 4);
-		/*cpu_to_le32s ((u32 *) buf); */
-		break;
-	case GetPortStatus:
-		if (!wIndex || wIndex > ports)
-			goto error;
-		wIndex--;
-		status = 0;
-		temp = fotg210_readl(fotg210, status_reg);
-
-		/* wPortChange bits */
-		if (temp & PORT_CSC)
-			status |= USB_PORT_STAT_C_CONNECTION << 16;
-		if (temp & PORT_PEC)
-			status |= USB_PORT_STAT_C_ENABLE << 16;
-
-		temp1 = fotg210_readl(fotg210, &fotg210->regs->otgisr);
-		if (temp1 & OTGISR_OVC)
-			status |= USB_PORT_STAT_C_OVERCURRENT << 16;
-
-		/* whoever resumes must GetPortStatus to complete it!! */
-		if (temp & PORT_RESUME) {
-
-			/* Remote Wakeup received? */
-			if (!fotg210->reset_done[wIndex]) {
-				/* resume signaling for 20 msec */
-				fotg210->reset_done[wIndex] = jiffies
-						+ msecs_to_jiffies(20);
-				/* check the port again */
-				mod_timer(&fotg210_to_hcd(fotg210)->rh_timer,
-						fotg210->reset_done[wIndex]);
-			}
-
-			/* resume completed? */
-			else if (time_after_eq(jiffies,
-					fotg210->reset_done[wIndex])) {
-				clear_bit(wIndex, &fotg210->suspended_ports);
-				set_bit(wIndex, &fotg210->port_c_suspend);
-				fotg210->reset_done[wIndex] = 0;
-
-				/* stop resume signaling */
-				temp = fotg210_readl(fotg210, status_reg);
-				fotg210_writel(fotg210,
-					temp & ~(PORT_RWC_BITS | PORT_RESUME),
-					status_reg);
-				clear_bit(wIndex, &fotg210->resuming_ports);
-				retval = handshake(fotg210, status_reg,
-					   PORT_RESUME, 0, 2000 /* 2msec */);
-				if (retval != 0) {
-					fotg210_err(fotg210,
-						"port %d resume error %d\n",
-						wIndex + 1, retval);
-					goto error;
-				}
-				temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
-			}
-		}
-
-		/* whoever resets must GetPortStatus to complete it!! */
-		if ((temp & PORT_RESET)
-				&& time_after_eq(jiffies,
-					fotg210->reset_done[wIndex])) {
-			status |= USB_PORT_STAT_C_RESET << 16;
-			fotg210->reset_done[wIndex] = 0;
-			clear_bit(wIndex, &fotg210->resuming_ports);
-
-			/* force reset to complete */
-			fotg210_writel(fotg210,
-				       temp & ~(PORT_RWC_BITS | PORT_RESET),
-				       status_reg);
-			/* REVISIT:  some hardware needs 550+ usec to clear
-			 * this bit; seems too long to spin routinely...
-			 */
-			retval = handshake(fotg210, status_reg,
-					PORT_RESET, 0, 1000);
-			if (retval != 0) {
-				fotg210_err(fotg210, "port %d reset error %d\n",
-					wIndex + 1, retval);
-				goto error;
-			}
-
-			/* see what we found out */
-			temp = check_reset_complete(fotg210, wIndex, status_reg,
-					fotg210_readl(fotg210, status_reg));
-		}
-
-		if (!(temp & (PORT_RESUME|PORT_RESET))) {
-			fotg210->reset_done[wIndex] = 0;
-			clear_bit(wIndex, &fotg210->resuming_ports);
-		}
-
-		/* transfer dedicated ports to the companion hc */
-		if ((temp & PORT_CONNECT) &&
-				test_bit(wIndex, &fotg210->companion_ports)) {
-			temp &= ~PORT_RWC_BITS;
-			fotg210_writel(fotg210, temp, status_reg);
-			fotg210_dbg(fotg210, "port %d --> companion\n",
-				    wIndex + 1);
-			temp = fotg210_readl(fotg210, status_reg);
-		}
-
-		/*
-		 * Even if OWNER is set, there's no harm letting hub_wq
-		 * see the wPortStatus values (they should all be 0 except
-		 * for PORT_POWER anyway).
-		 */
-
-		if (temp & PORT_CONNECT) {
-			status |= USB_PORT_STAT_CONNECTION;
-			status |= fotg210_port_speed(fotg210, temp);
-		}
-		if (temp & PORT_PE)
-			status |= USB_PORT_STAT_ENABLE;
-
-		/* maybe the port was unsuspended without our knowledge */
-		if (temp & (PORT_SUSPEND|PORT_RESUME)) {
-			status |= USB_PORT_STAT_SUSPEND;
-		} else if (test_bit(wIndex, &fotg210->suspended_ports)) {
-			clear_bit(wIndex, &fotg210->suspended_ports);
-			clear_bit(wIndex, &fotg210->resuming_ports);
-			fotg210->reset_done[wIndex] = 0;
-			if (temp & PORT_PE)
-				set_bit(wIndex, &fotg210->port_c_suspend);
-		}
-
-		temp1 = fotg210_readl(fotg210, &fotg210->regs->otgisr);
-		if (temp1 & OTGISR_OVC)
-			status |= USB_PORT_STAT_OVERCURRENT;
-		if (temp & PORT_RESET)
-			status |= USB_PORT_STAT_RESET;
-		if (test_bit(wIndex, &fotg210->port_c_suspend))
-			status |= USB_PORT_STAT_C_SUSPEND << 16;
-
-		if (status & ~0xffff)	/* only if wPortChange is interesting */
-			dbg_port(fotg210, "GetStatus", wIndex + 1, temp);
-		put_unaligned_le32(status, buf);
-		break;
-	case SetHubFeature:
-		switch (wValue) {
-		case C_HUB_LOCAL_POWER:
-		case C_HUB_OVER_CURRENT:
-			/* no hub-wide feature/status flags */
-			break;
-		default:
-			goto error;
-		}
-		break;
-	case SetPortFeature:
-		selector = wIndex >> 8;
-		wIndex &= 0xff;
-
-		if (!wIndex || wIndex > ports)
-			goto error;
-		wIndex--;
-		temp = fotg210_readl(fotg210, status_reg);
-		temp &= ~PORT_RWC_BITS;
-		switch (wValue) {
-		case USB_PORT_FEAT_SUSPEND:
-			if ((temp & PORT_PE) == 0
-					|| (temp & PORT_RESET) != 0)
-				goto error;
-
-			/* After above check the port must be connected.
-			 * Set appropriate bit thus could put phy into low power
-			 * mode if we have hostpc feature
-			 */
-			fotg210_writel(fotg210, temp | PORT_SUSPEND,
-				       status_reg);
-			set_bit(wIndex, &fotg210->suspended_ports);
-			break;
-		case USB_PORT_FEAT_RESET:
-			if (temp & PORT_RESUME)
-				goto error;
-			/* line status bits may report this as low speed,
-			 * which can be fine if this root hub has a
-			 * transaction translator built in.
-			 */
-			fotg210_dbg(fotg210, "port %d reset\n", wIndex + 1);
-			temp |= PORT_RESET;
-			temp &= ~PORT_PE;
-
-			/*
-			 * caller must wait, then call GetPortStatus
-			 * usb 2.0 spec says 50 ms resets on root
-			 */
-			fotg210->reset_done[wIndex] = jiffies
-					+ msecs_to_jiffies(50);
-			fotg210_writel(fotg210, temp, status_reg);
-			break;
-
-		/* For downstream facing ports (these):  one hub port is put
-		 * into test mode according to USB2 11.24.2.13, then the hub
-		 * must be reset (which for root hub now means rmmod+modprobe,
-		 * or else system reboot).  See EHCI 2.3.9 and 4.14 for info
-		 * about the EHCI-specific stuff.
-		 */
-		case USB_PORT_FEAT_TEST:
-			if (!selector || selector > 5)
-				goto error;
-			spin_unlock_irqrestore(&fotg210->lock, flags);
-			fotg210_quiesce(fotg210);
-			spin_lock_irqsave(&fotg210->lock, flags);
-
-			/* Put all enabled ports into suspend */
-			temp = fotg210_readl(fotg210, status_reg) &
-				~PORT_RWC_BITS;
-			if (temp & PORT_PE)
-				fotg210_writel(fotg210, temp | PORT_SUSPEND,
-						status_reg);
-
-			spin_unlock_irqrestore(&fotg210->lock, flags);
-			fotg210_halt(fotg210);
-			spin_lock_irqsave(&fotg210->lock, flags);
-
-			temp = fotg210_readl(fotg210, status_reg);
-			temp |= selector << 16;
-			fotg210_writel(fotg210, temp, status_reg);
-			break;
-
-		default:
-			goto error;
-		}
-		fotg210_readl(fotg210, &fotg210->regs->command);
-		break;
-
-	default:
-error:
-		/* "stall" on error */
-		retval = -EPIPE;
-	}
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-	return retval;
-}
-
-static void __maybe_unused fotg210_relinquish_port(struct usb_hcd *hcd,
-		int portnum)
-{
-	return;
-}
-
-static int __maybe_unused fotg210_port_handed_over(struct usb_hcd *hcd,
-						   int portnum)
-{
-	return 0;
-}
-
-/*
- * There's basically three types of memory:
- *	- data used only by the HCD ... kmalloc is fine
- *	- async and periodic schedules, shared by HC and HCD ... these
- *	  need to use dma_pool or dma_alloc_coherent
- *	- driver buffers, read/written by HC ... single shot DMA mapped
- *
- * There's also "register" data (e.g. PCI or SOC), which is memory mapped.
- * No memory seen by this driver is pageable.
- */
-
-/* Allocate the key transfer structures from the previously allocated pool */
-static inline void fotg210_qtd_init(struct fotg210_hcd *fotg210,
-				    struct fotg210_qtd *qtd, dma_addr_t dma)
-{
-	memset(qtd, 0, sizeof(*qtd));
-	qtd->qtd_dma = dma;
-	qtd->hw_token = cpu_to_hc32(fotg210, QTD_STS_HALT);
-	qtd->hw_next = FOTG210_LIST_END(fotg210);
-	qtd->hw_alt_next = FOTG210_LIST_END(fotg210);
-	INIT_LIST_HEAD(&qtd->qtd_list);
-}
-
-static struct fotg210_qtd *fotg210_qtd_alloc(struct fotg210_hcd *fotg210,
-					     gfp_t flags)
-{
-	struct fotg210_qtd *qtd;
-	dma_addr_t dma;
-
-	qtd = dma_pool_alloc(fotg210->qtd_pool, flags, &dma);
-	if (qtd != NULL)
-		fotg210_qtd_init(fotg210, qtd, dma);
-
-	return qtd;
-}
-
-static inline void fotg210_qtd_free(struct fotg210_hcd *fotg210,
-				    struct fotg210_qtd *qtd)
-{
-	dma_pool_free(fotg210->qtd_pool, qtd, qtd->qtd_dma);
-}
-
-
-static void qh_destroy(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
-{
-	/* clean qtds first, and know this is not linked */
-	if (!list_empty(&qh->qtd_list) || qh->qh_next.ptr) {
-		fotg210_dbg(fotg210, "unused qh not empty!\n");
-		BUG();
-	}
-	if (qh->dummy)
-		fotg210_qtd_free(fotg210, qh->dummy);
-	dma_pool_free(fotg210->qh_pool, qh->hw, qh->qh_dma);
-	kfree(qh);
-}
-
-static struct fotg210_qh *fotg210_qh_alloc(struct fotg210_hcd *fotg210,
-					   gfp_t flags)
-{
-	struct fotg210_qh *qh;
-	dma_addr_t dma;
-
-	qh = kzalloc(sizeof(*qh), GFP_ATOMIC);
-	if (!qh)
-		goto done;
-	qh->hw = (struct fotg210_qh_hw *)
-		dma_pool_alloc(fotg210->qh_pool, flags, &dma);
-	if (!qh->hw)
-		goto fail;
-	memset(qh->hw, 0, sizeof(*qh->hw));
-	qh->qh_dma = dma;
-	INIT_LIST_HEAD(&qh->qtd_list);
-
-	/* dummy td enables safe urb queuing */
-	qh->dummy = fotg210_qtd_alloc(fotg210, flags);
-	if (qh->dummy == NULL) {
-		fotg210_dbg(fotg210, "no dummy td\n");
-		goto fail1;
-	}
-done:
-	return qh;
-fail1:
-	dma_pool_free(fotg210->qh_pool, qh->hw, qh->qh_dma);
-fail:
-	kfree(qh);
-	return NULL;
-}
-
-/* The queue heads and transfer descriptors are managed from pools tied
- * to each of the "per device" structures.
- * This is the initialisation and cleanup code.
- */
-
-static void fotg210_mem_cleanup(struct fotg210_hcd *fotg210)
-{
-	if (fotg210->async)
-		qh_destroy(fotg210, fotg210->async);
-	fotg210->async = NULL;
-
-	if (fotg210->dummy)
-		qh_destroy(fotg210, fotg210->dummy);
-	fotg210->dummy = NULL;
-
-	/* DMA consistent memory and pools */
-	dma_pool_destroy(fotg210->qtd_pool);
-	fotg210->qtd_pool = NULL;
-
-	dma_pool_destroy(fotg210->qh_pool);
-	fotg210->qh_pool = NULL;
-
-	dma_pool_destroy(fotg210->itd_pool);
-	fotg210->itd_pool = NULL;
-
-	if (fotg210->periodic)
-		dma_free_coherent(fotg210_to_hcd(fotg210)->self.controller,
-			fotg210->periodic_size * sizeof(u32),
-			fotg210->periodic, fotg210->periodic_dma);
-	fotg210->periodic = NULL;
-
-	/* shadow periodic table */
-	kfree(fotg210->pshadow);
-	fotg210->pshadow = NULL;
-}
-
-/* remember to add cleanup code (above) if you add anything here */
-static int fotg210_mem_init(struct fotg210_hcd *fotg210, gfp_t flags)
-{
-	int i;
-
-	/* QTDs for control/bulk/intr transfers */
-	fotg210->qtd_pool = dma_pool_create("fotg210_qtd",
-			fotg210_to_hcd(fotg210)->self.controller,
-			sizeof(struct fotg210_qtd),
-			32 /* byte alignment (for hw parts) */,
-			4096 /* can't cross 4K */);
-	if (!fotg210->qtd_pool)
-		goto fail;
-
-	/* QHs for control/bulk/intr transfers */
-	fotg210->qh_pool = dma_pool_create("fotg210_qh",
-			fotg210_to_hcd(fotg210)->self.controller,
-			sizeof(struct fotg210_qh_hw),
-			32 /* byte alignment (for hw parts) */,
-			4096 /* can't cross 4K */);
-	if (!fotg210->qh_pool)
-		goto fail;
-
-	fotg210->async = fotg210_qh_alloc(fotg210, flags);
-	if (!fotg210->async)
-		goto fail;
-
-	/* ITD for high speed ISO transfers */
-	fotg210->itd_pool = dma_pool_create("fotg210_itd",
-			fotg210_to_hcd(fotg210)->self.controller,
-			sizeof(struct fotg210_itd),
-			64 /* byte alignment (for hw parts) */,
-			4096 /* can't cross 4K */);
-	if (!fotg210->itd_pool)
-		goto fail;
-
-	/* Hardware periodic table */
-	fotg210->periodic = (__le32 *)
-		dma_alloc_coherent(fotg210_to_hcd(fotg210)->self.controller,
-			fotg210->periodic_size * sizeof(__le32),
-			&fotg210->periodic_dma, 0);
-	if (fotg210->periodic == NULL)
-		goto fail;
-
-	for (i = 0; i < fotg210->periodic_size; i++)
-		fotg210->periodic[i] = FOTG210_LIST_END(fotg210);
-
-	/* software shadow of hardware table */
-	fotg210->pshadow = kcalloc(fotg210->periodic_size, sizeof(void *),
-				   flags);
-	if (fotg210->pshadow != NULL)
-		return 0;
-
-fail:
-	fotg210_dbg(fotg210, "couldn't init memory\n");
-	fotg210_mem_cleanup(fotg210);
-	return -ENOMEM;
-}
-/*
- * EHCI hardware queue manipulation ... the core.  QH/QTD manipulation.
- *
- * Control, bulk, and interrupt traffic all use "qh" lists.  They list "qtd"
- * entries describing USB transactions, max 16-20kB/entry (with 4kB-aligned
- * buffers needed for the larger number).  We use one QH per endpoint, queue
- * multiple urbs (all three types) per endpoint.  URBs may need several qtds.
- *
- * ISO traffic uses "ISO TD" (itd) records, and (along with
- * interrupts) needs careful scheduling.  Performance improvements can be
- * an ongoing challenge.  That's in "ehci-sched.c".
- *
- * USB 1.1 devices are handled (a) by "companion" OHCI or UHCI root hubs,
- * or otherwise through transaction translators (TTs) in USB 2.0 hubs using
- * (b) special fields in qh entries or (c) split iso entries.  TTs will
- * buffer low/full speed data so the host collects it at high speed.
- */
-
-/* fill a qtd, returning how much of the buffer we were able to queue up */
-static int qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd,
-		    dma_addr_t buf, size_t len, int token, int maxpacket)
-{
-	int i, count;
-	u64 addr = buf;
-
-	/* one buffer entry per 4K ... first might be short or unaligned */
-	qtd->hw_buf[0] = cpu_to_hc32(fotg210, (u32)addr);
-	qtd->hw_buf_hi[0] = cpu_to_hc32(fotg210, (u32)(addr >> 32));
-	count = 0x1000 - (buf & 0x0fff);	/* rest of that page */
-	if (likely(len < count))		/* ... iff needed */
-		count = len;
-	else {
-		buf +=  0x1000;
-		buf &= ~0x0fff;
-
-		/* per-qtd limit: from 16K to 20K (best alignment) */
-		for (i = 1; count < len && i < 5; i++) {
-			addr = buf;
-			qtd->hw_buf[i] = cpu_to_hc32(fotg210, (u32)addr);
-			qtd->hw_buf_hi[i] = cpu_to_hc32(fotg210,
-					(u32)(addr >> 32));
-			buf += 0x1000;
-			if ((count + 0x1000) < len)
-				count += 0x1000;
-			else
-				count = len;
-		}
-
-		/* short packets may only terminate transfers */
-		if (count != len)
-			count -= (count % maxpacket);
-	}
-	qtd->hw_token = cpu_to_hc32(fotg210, (count << 16) | token);
-	qtd->length = count;
-
-	return count;
-}
-
-static inline void qh_update(struct fotg210_hcd *fotg210,
-			     struct fotg210_qh *qh,
-			     struct fotg210_qtd *qtd)
-{
-	struct fotg210_qh_hw *hw = qh->hw;
-
-	/* writes to an active overlay are unsafe */
-	BUG_ON(qh->qh_state != QH_STATE_IDLE);
-
-	hw->hw_qtd_next = QTD_NEXT(fotg210, qtd->qtd_dma);
-	hw->hw_alt_next = FOTG210_LIST_END(fotg210);
-
-	/* Except for control endpoints, we make hardware maintain data
-	 * toggle (like OHCI) ... here (re)initialize the toggle in the QH,
-	 * and set the pseudo-toggle in udev. Only usb_clear_halt() will
-	 * ever clear it.
-	 */
-	if (!(hw->hw_info1 & cpu_to_hc32(fotg210, QH_TOGGLE_CTL))) {
-		unsigned is_out, epnum;
-
-		is_out = qh->is_out;
-		epnum = (hc32_to_cpup(fotg210, &hw->hw_info1) >> 8) & 0x0f;
-		if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) {
-			hw->hw_token &= ~cpu_to_hc32(fotg210, QTD_TOGGLE);
-			usb_settoggle(qh->dev, epnum, is_out, 1);
-		}
-	}
-
-	hw->hw_token &= cpu_to_hc32(fotg210, QTD_TOGGLE | QTD_STS_PING);
-}
-
-/* if it weren't for a common silicon quirk (writing the dummy into the qh
- * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault
- * recovery (including urb dequeue) would need software changes to a QH...
- */
-static void qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
-{
-	struct fotg210_qtd *qtd;
-
-	if (list_empty(&qh->qtd_list))
-		qtd = qh->dummy;
-	else {
-		qtd = list_entry(qh->qtd_list.next,
-				struct fotg210_qtd, qtd_list);
-		/*
-		 * first qtd may already be partially processed.
-		 * If we come here during unlink, the QH overlay region
-		 * might have reference to the just unlinked qtd. The
-		 * qtd is updated in qh_completions(). Update the QH
-		 * overlay here.
-		 */
-		if (cpu_to_hc32(fotg210, qtd->qtd_dma) == qh->hw->hw_current) {
-			qh->hw->hw_qtd_next = qtd->hw_next;
-			qtd = NULL;
-		}
-	}
-
-	if (qtd)
-		qh_update(fotg210, qh, qtd);
-}
-
-static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
-
-static void fotg210_clear_tt_buffer_complete(struct usb_hcd *hcd,
-					     struct usb_host_endpoint *ep)
-{
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh *qh = ep->hcpriv;
-	unsigned long flags;
-
-	spin_lock_irqsave(&fotg210->lock, flags);
-	qh->clearing_tt = 0;
-	if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list)
-			&& fotg210->rh_state == FOTG210_RH_RUNNING)
-		qh_link_async(fotg210, qh);
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-}
-
-static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
-				    struct fotg210_qh *qh,
-				    struct urb *urb, u32 token)
-{
-
-	/* If an async split transaction gets an error or is unlinked,
-	 * the TT buffer may be left in an indeterminate state.  We
-	 * have to clear the TT buffer.
-	 *
-	 * Note: this routine is never called for Isochronous transfers.
-	 */
-	if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
-		struct usb_device *tt = urb->dev->tt->hub;
-
-		dev_dbg(&tt->dev,
-			"clear tt buffer port %d, a%d ep%d t%08x\n",
-			urb->dev->ttport, urb->dev->devnum,
-			usb_pipeendpoint(urb->pipe), token);
-
-		if (urb->dev->tt->hub !=
-		    fotg210_to_hcd(fotg210)->self.root_hub) {
-			if (usb_hub_clear_tt_buffer(urb) == 0)
-				qh->clearing_tt = 1;
-		}
-	}
-}
-
-static int qtd_copy_status(struct fotg210_hcd *fotg210, struct urb *urb,
-			   size_t length, u32 token)
-{
-	int status = -EINPROGRESS;
-
-	/* count IN/OUT bytes, not SETUP (even short packets) */
-	if (likely(QTD_PID(token) != 2))
-		urb->actual_length += length - QTD_LENGTH(token);
-
-	/* don't modify error codes */
-	if (unlikely(urb->unlinked))
-		return status;
-
-	/* force cleanup after short read; not always an error */
-	if (unlikely(IS_SHORT_READ(token)))
-		status = -EREMOTEIO;
-
-	/* serious "can't proceed" faults reported by the hardware */
-	if (token & QTD_STS_HALT) {
-		if (token & QTD_STS_BABBLE) {
-			/* FIXME "must" disable babbling device's port too */
-			status = -EOVERFLOW;
-		/* CERR nonzero + halt --> stall */
-		} else if (QTD_CERR(token)) {
-			status = -EPIPE;
-
-		/* In theory, more than one of the following bits can be set
-		 * since they are sticky and the transaction is retried.
-		 * Which to test first is rather arbitrary.
-		 */
-		} else if (token & QTD_STS_MMF) {
-			/* fs/ls interrupt xfer missed the complete-split */
-			status = -EPROTO;
-		} else if (token & QTD_STS_DBE) {
-			status = (QTD_PID(token) == 1) /* IN ? */
-				? -ENOSR  /* hc couldn't read data */
-				: -ECOMM; /* hc couldn't write data */
-		} else if (token & QTD_STS_XACT) {
-			/* timeout, bad CRC, wrong PID, etc */
-			fotg210_dbg(fotg210, "devpath %s ep%d%s 3strikes\n",
-				urb->dev->devpath,
-				usb_pipeendpoint(urb->pipe),
-				usb_pipein(urb->pipe) ? "in" : "out");
-			status = -EPROTO;
-		} else {	/* unknown */
-			status = -EPROTO;
-		}
-
-		fotg210_dbg(fotg210,
-			"dev%d ep%d%s qtd token %08x --> status %d\n",
-			usb_pipedevice(urb->pipe),
-			usb_pipeendpoint(urb->pipe),
-			usb_pipein(urb->pipe) ? "in" : "out",
-			token, status);
-	}
-
-	return status;
-}
-
-static void fotg210_urb_done(struct fotg210_hcd *fotg210, struct urb *urb,
-			     int status)
-__releases(fotg210->lock)
-__acquires(fotg210->lock)
-{
-	if (likely(urb->hcpriv != NULL)) {
-		struct fotg210_qh *qh = (struct fotg210_qh *) urb->hcpriv;
-
-		/* S-mask in a QH means it's an interrupt urb */
-		if ((qh->hw->hw_info2 & cpu_to_hc32(fotg210, QH_SMASK)) != 0) {
-
-			/* ... update hc-wide periodic stats (for usbfs) */
-			fotg210_to_hcd(fotg210)->self.bandwidth_int_reqs--;
-		}
-	}
-
-	if (unlikely(urb->unlinked)) {
-		COUNT(fotg210->stats.unlink);
-	} else {
-		/* report non-error and short read status as zero */
-		if (status == -EINPROGRESS || status == -EREMOTEIO)
-			status = 0;
-		COUNT(fotg210->stats.complete);
-	}
-
-#ifdef FOTG210_URB_TRACE
-	fotg210_dbg(fotg210,
-		"%s %s urb %p ep%d%s status %d len %d/%d\n",
-		__func__, urb->dev->devpath, urb,
-		usb_pipeendpoint(urb->pipe),
-		usb_pipein(urb->pipe) ? "in" : "out",
-		status,
-		urb->actual_length, urb->transfer_buffer_length);
-#endif
-
-	/* complete() can reenter this HCD */
-	usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
-	spin_unlock(&fotg210->lock);
-	usb_hcd_giveback_urb(fotg210_to_hcd(fotg210), urb, status);
-	spin_lock(&fotg210->lock);
-}
-
-static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
-
-/*
- * Process and free completed qtds for a qh, returning URBs to drivers.
- * Chases up to qh->hw_current.  Returns number of completions called,
- * indicating how much "real" work we did.
- */
-static unsigned qh_completions(struct fotg210_hcd *fotg210,
-			       struct fotg210_qh *qh)
-{
-	struct fotg210_qtd *last, *end = qh->dummy;
-	struct list_head *entry, *tmp;
-	int last_status;
-	int stopped;
-	unsigned count = 0;
-	u8 state;
-	struct fotg210_qh_hw *hw = qh->hw;
-
-	if (unlikely(list_empty(&qh->qtd_list)))
-		return count;
-
-	/* completions (or tasks on other cpus) must never clobber HALT
-	 * till we've gone through and cleaned everything up, even when
-	 * they add urbs to this qh's queue or mark them for unlinking.
-	 *
-	 * NOTE:  unlinking expects to be done in queue order.
-	 *
-	 * It's a bug for qh->qh_state to be anything other than
-	 * QH_STATE_IDLE, unless our caller is scan_async() or
-	 * scan_intr().
-	 */
-	state = qh->qh_state;
-	qh->qh_state = QH_STATE_COMPLETING;
-	stopped = (state == QH_STATE_IDLE);
-
-rescan:
-	last = NULL;
-	last_status = -EINPROGRESS;
-	qh->needs_rescan = 0;
-
-	/* remove de-activated QTDs from front of queue.
-	 * after faults (including short reads), cleanup this urb
-	 * then let the queue advance.
-	 * if queue is stopped, handles unlinks.
-	 */
-	list_for_each_safe(entry, tmp, &qh->qtd_list) {
-		struct fotg210_qtd *qtd;
-		struct urb *urb;
-		u32 token = 0;
-
-		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
-		urb = qtd->urb;
-
-		/* clean up any state from previous QTD ...*/
-		if (last) {
-			if (likely(last->urb != urb)) {
-				fotg210_urb_done(fotg210, last->urb,
-						 last_status);
-				count++;
-				last_status = -EINPROGRESS;
-			}
-			fotg210_qtd_free(fotg210, last);
-			last = NULL;
-		}
-
-		/* ignore urbs submitted during completions we reported */
-		if (qtd == end)
-			break;
-
-		/* hardware copies qtd out of qh overlay */
-		rmb();
-		token = hc32_to_cpu(fotg210, qtd->hw_token);
-
-		/* always clean up qtds the hc de-activated */
-retry_xacterr:
-		if ((token & QTD_STS_ACTIVE) == 0) {
-
-			/* Report Data Buffer Error: non-fatal but useful */
-			if (token & QTD_STS_DBE)
-				fotg210_dbg(fotg210,
-					"detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-					urb,
-					usb_endpoint_num(&urb->ep->desc),
-					usb_endpoint_dir_in(&urb->ep->desc)
-						? "in" : "out",
-					urb->transfer_buffer_length,
-					qtd,
-					qh);
-
-			/* on STALL, error, and short reads this urb must
-			 * complete and all its qtds must be recycled.
-			 */
-			if ((token & QTD_STS_HALT) != 0) {
-
-				/* retry transaction errors until we
-				 * reach the software xacterr limit
-				 */
-				if ((token & QTD_STS_XACT) &&
-					QTD_CERR(token) == 0 &&
-					++qh->xacterrs < QH_XACTERR_MAX &&
-					!urb->unlinked) {
-					fotg210_dbg(fotg210,
-	"detected XactErr len %zu/%zu retry %d\n",
-	qtd->length - QTD_LENGTH(token), qtd->length, qh->xacterrs);
-
-					/* reset the token in the qtd and the
-					 * qh overlay (which still contains
-					 * the qtd) so that we pick up from
-					 * where we left off
-					 */
-					token &= ~QTD_STS_HALT;
-					token |= QTD_STS_ACTIVE |
-						 (FOTG210_TUNE_CERR << 10);
-					qtd->hw_token = cpu_to_hc32(fotg210,
-							token);
-					wmb();
-					hw->hw_token = cpu_to_hc32(fotg210,
-							token);
-					goto retry_xacterr;
-				}
-				stopped = 1;
-
-			/* magic dummy for some short reads; qh won't advance.
-			 * that silicon quirk can kick in with this dummy too.
-			 *
-			 * other short reads won't stop the queue, including
-			 * control transfers (status stage handles that) or
-			 * most other single-qtd reads ... the queue stops if
-			 * URB_SHORT_NOT_OK was set so the driver submitting
-			 * the urbs could clean it up.
-			 */
-			} else if (IS_SHORT_READ(token)
-					&& !(qtd->hw_alt_next
-						& FOTG210_LIST_END(fotg210))) {
-				stopped = 1;
-			}
-
-		/* stop scanning when we reach qtds the hc is using */
-		} else if (likely(!stopped
-				&& fotg210->rh_state >= FOTG210_RH_RUNNING)) {
-			break;
-
-		/* scan the whole queue for unlinks whenever it stops */
-		} else {
-			stopped = 1;
-
-			/* cancel everything if we halt, suspend, etc */
-			if (fotg210->rh_state < FOTG210_RH_RUNNING)
-				last_status = -ESHUTDOWN;
-
-			/* this qtd is active; skip it unless a previous qtd
-			 * for its urb faulted, or its urb was canceled.
-			 */
-			else if (last_status == -EINPROGRESS && !urb->unlinked)
-				continue;
-
-			/* qh unlinked; token in overlay may be most current */
-			if (state == QH_STATE_IDLE
-					&& cpu_to_hc32(fotg210, qtd->qtd_dma)
-						== hw->hw_current) {
-				token = hc32_to_cpu(fotg210, hw->hw_token);
-
-				/* An unlink may leave an incomplete
-				 * async transaction in the TT buffer.
-				 * We have to clear it.
-				 */
-				fotg210_clear_tt_buffer(fotg210, qh, urb,
-							token);
-			}
-		}
-
-		/* unless we already know the urb's status, collect qtd status
-		 * and update count of bytes transferred.  in common short read
-		 * cases with only one data qtd (including control transfers),
-		 * queue processing won't halt.  but with two or more qtds (for
-		 * example, with a 32 KB transfer), when the first qtd gets a
-		 * short read the second must be removed by hand.
-		 */
-		if (last_status == -EINPROGRESS) {
-			last_status = qtd_copy_status(fotg210, urb,
-					qtd->length, token);
-			if (last_status == -EREMOTEIO
-					&& (qtd->hw_alt_next
-						& FOTG210_LIST_END(fotg210)))
-				last_status = -EINPROGRESS;
-
-			/* As part of low/full-speed endpoint-halt processing
-			 * we must clear the TT buffer (11.17.5).
-			 */
-			if (unlikely(last_status != -EINPROGRESS &&
-					last_status != -EREMOTEIO)) {
-				/* The TT's in some hubs malfunction when they
-				 * receive this request following a STALL (they
-				 * stop sending isochronous packets).  Since a
-				 * STALL can't leave the TT buffer in a busy
-				 * state (if you believe Figures 11-48 - 11-51
-				 * in the USB 2.0 spec), we won't clear the TT
-				 * buffer in this case.  Strictly speaking this
-				 * is a violation of the spec.
-				 */
-				if (last_status != -EPIPE)
-					fotg210_clear_tt_buffer(fotg210, qh,
-								urb, token);
-			}
-		}
-
-		/* if we're removing something not at the queue head,
-		 * patch the hardware queue pointer.
-		 */
-		if (stopped && qtd->qtd_list.prev != &qh->qtd_list) {
-			last = list_entry(qtd->qtd_list.prev,
-					struct fotg210_qtd, qtd_list);
-			last->hw_next = qtd->hw_next;
-		}
-
-		/* remove qtd; it's recycled after possible urb completion */
-		list_del(&qtd->qtd_list);
-		last = qtd;
-
-		/* reinit the xacterr counter for the next qtd */
-		qh->xacterrs = 0;
-	}
-
-	/* last urb's completion might still need calling */
-	if (likely(last != NULL)) {
-		fotg210_urb_done(fotg210, last->urb, last_status);
-		count++;
-		fotg210_qtd_free(fotg210, last);
-	}
-
-	/* Do we need to rescan for URBs dequeued during a giveback? */
-	if (unlikely(qh->needs_rescan)) {
-		/* If the QH is already unlinked, do the rescan now. */
-		if (state == QH_STATE_IDLE)
-			goto rescan;
-
-		/* Otherwise we have to wait until the QH is fully unlinked.
-		 * Our caller will start an unlink if qh->needs_rescan is
-		 * set.  But if an unlink has already started, nothing needs
-		 * to be done.
-		 */
-		if (state != QH_STATE_LINKED)
-			qh->needs_rescan = 0;
-	}
-
-	/* restore original state; caller must unlink or relink */
-	qh->qh_state = state;
-
-	/* be sure the hardware's done with the qh before refreshing
-	 * it after fault cleanup, or recovering from silicon wrongly
-	 * overlaying the dummy qtd (which reduces DMA chatter).
-	 */
-	if (stopped != 0 || hw->hw_qtd_next == FOTG210_LIST_END(fotg210)) {
-		switch (state) {
-		case QH_STATE_IDLE:
-			qh_refresh(fotg210, qh);
-			break;
-		case QH_STATE_LINKED:
-			/* We won't refresh a QH that's linked (after the HC
-			 * stopped the queue).  That avoids a race:
-			 *  - HC reads first part of QH;
-			 *  - CPU updates that first part and the token;
-			 *  - HC reads rest of that QH, including token
-			 * Result:  HC gets an inconsistent image, and then
-			 * DMAs to/from the wrong memory (corrupting it).
-			 *
-			 * That should be rare for interrupt transfers,
-			 * except maybe high bandwidth ...
-			 */
-
-			/* Tell the caller to start an unlink */
-			qh->needs_rescan = 1;
-			break;
-		/* otherwise, unlink already started */
-		}
-	}
-
-	return count;
-}
-
-/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
-#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
-/* ... and packet size, for any kind of endpoint descriptor */
-#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
-
-/*
- * reverse of qh_urb_transaction:  free a list of TDs.
- * used for cleanup after errors, before HC sees an URB's TDs.
- */
-static void qtd_list_free(struct fotg210_hcd *fotg210, struct urb *urb,
-			  struct list_head *qtd_list)
-{
-	struct list_head *entry, *temp;
-
-	list_for_each_safe(entry, temp, qtd_list) {
-		struct fotg210_qtd *qtd;
-
-		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
-		list_del(&qtd->qtd_list);
-		fotg210_qtd_free(fotg210, qtd);
-	}
-}
-
-/*
- * create a list of filled qtds for this URB; won't link into qh.
- */
-static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
-					    struct urb *urb,
-					    struct list_head *head,
-					    gfp_t flags)
-{
-	struct fotg210_qtd *qtd, *qtd_prev;
-	dma_addr_t buf;
-	int len, this_sg_len, maxpacket;
-	int is_input;
-	u32 token;
-	int i;
-	struct scatterlist *sg;
-
-	/*
-	 * URBs map to sequences of QTDs:  one logical transaction
-	 */
-	qtd = fotg210_qtd_alloc(fotg210, flags);
-	if (unlikely(!qtd))
-		return NULL;
-	list_add_tail(&qtd->qtd_list, head);
-	qtd->urb = urb;
-
-	token = QTD_STS_ACTIVE;
-	token |= (FOTG210_TUNE_CERR << 10);
-	/* for split transactions, SplitXState initialized to zero */
-
-	len = urb->transfer_buffer_length;
-	is_input = usb_pipein(urb->pipe);
-	if (usb_pipecontrol(urb->pipe)) {
-		/* SETUP pid */
-		qtd_fill(fotg210, qtd, urb->setup_dma,
-				sizeof(struct usb_ctrlrequest),
-				token | (2 /* "setup" */ << 8), 8);
-
-		/* ... and always at least one more pid */
-		token ^= QTD_TOGGLE;
-		qtd_prev = qtd;
-		qtd = fotg210_qtd_alloc(fotg210, flags);
-		if (unlikely(!qtd))
-			goto cleanup;
-		qtd->urb = urb;
-		qtd_prev->hw_next = QTD_NEXT(fotg210, qtd->qtd_dma);
-		list_add_tail(&qtd->qtd_list, head);
-
-		/* for zero length DATA stages, STATUS is always IN */
-		if (len == 0)
-			token |= (1 /* "in" */ << 8);
-	}
-
-	/*
-	 * data transfer stage:  buffer setup
-	 */
-	i = urb->num_mapped_sgs;
-	if (len > 0 && i > 0) {
-		sg = urb->sg;
-		buf = sg_dma_address(sg);
-
-		/* urb->transfer_buffer_length may be smaller than the
-		 * size of the scatterlist (or vice versa)
-		 */
-		this_sg_len = min_t(int, sg_dma_len(sg), len);
-	} else {
-		sg = NULL;
-		buf = urb->transfer_dma;
-		this_sg_len = len;
-	}
-
-	if (is_input)
-		token |= (1 /* "in" */ << 8);
-	/* else it's already initted to "out" pid (0 << 8) */
-
-	maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input));
-
-	/*
-	 * buffer gets wrapped in one or more qtds;
-	 * last one may be "short" (including zero len)
-	 * and may serve as a control status ack
-	 */
-	for (;;) {
-		int this_qtd_len;
-
-		this_qtd_len = qtd_fill(fotg210, qtd, buf, this_sg_len, token,
-				maxpacket);
-		this_sg_len -= this_qtd_len;
-		len -= this_qtd_len;
-		buf += this_qtd_len;
-
-		/*
-		 * short reads advance to a "magic" dummy instead of the next
-		 * qtd ... that forces the queue to stop, for manual cleanup.
-		 * (this will usually be overridden later.)
-		 */
-		if (is_input)
-			qtd->hw_alt_next = fotg210->async->hw->hw_alt_next;
-
-		/* qh makes control packets use qtd toggle; maybe switch it */
-		if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
-			token ^= QTD_TOGGLE;
-
-		if (likely(this_sg_len <= 0)) {
-			if (--i <= 0 || len <= 0)
-				break;
-			sg = sg_next(sg);
-			buf = sg_dma_address(sg);
-			this_sg_len = min_t(int, sg_dma_len(sg), len);
-		}
-
-		qtd_prev = qtd;
-		qtd = fotg210_qtd_alloc(fotg210, flags);
-		if (unlikely(!qtd))
-			goto cleanup;
-		qtd->urb = urb;
-		qtd_prev->hw_next = QTD_NEXT(fotg210, qtd->qtd_dma);
-		list_add_tail(&qtd->qtd_list, head);
-	}
-
-	/*
-	 * unless the caller requires manual cleanup after short reads,
-	 * have the alt_next mechanism keep the queue running after the
-	 * last data qtd (the only one, for control and most other cases).
-	 */
-	if (likely((urb->transfer_flags & URB_SHORT_NOT_OK) == 0
-				|| usb_pipecontrol(urb->pipe)))
-		qtd->hw_alt_next = FOTG210_LIST_END(fotg210);
-
-	/*
-	 * control requests may need a terminating data "status" ack;
-	 * other OUT ones may need a terminating short packet
-	 * (zero length).
-	 */
-	if (likely(urb->transfer_buffer_length != 0)) {
-		int one_more = 0;
-
-		if (usb_pipecontrol(urb->pipe)) {
-			one_more = 1;
-			token ^= 0x0100;	/* "in" <--> "out"  */
-			token |= QTD_TOGGLE;	/* force DATA1 */
-		} else if (usb_pipeout(urb->pipe)
-				&& (urb->transfer_flags & URB_ZERO_PACKET)
-				&& !(urb->transfer_buffer_length % maxpacket)) {
-			one_more = 1;
-		}
-		if (one_more) {
-			qtd_prev = qtd;
-			qtd = fotg210_qtd_alloc(fotg210, flags);
-			if (unlikely(!qtd))
-				goto cleanup;
-			qtd->urb = urb;
-			qtd_prev->hw_next = QTD_NEXT(fotg210, qtd->qtd_dma);
-			list_add_tail(&qtd->qtd_list, head);
-
-			/* never any data in such packets */
-			qtd_fill(fotg210, qtd, 0, 0, token, 0);
-		}
-	}
-
-	/* by default, enable interrupt on urb completion */
-	if (likely(!(urb->transfer_flags & URB_NO_INTERRUPT)))
-		qtd->hw_token |= cpu_to_hc32(fotg210, QTD_IOC);
-	return head;
-
-cleanup:
-	qtd_list_free(fotg210, urb, head);
-	return NULL;
-}
-
-/*
- * Would be best to create all qh's from config descriptors,
- * when each interface/altsetting is established.  Unlink
- * any previous qh and cancel its urbs first; endpoints are
- * implicitly reset then (data toggle too).
- * That'd mean updating how usbcore talks to HCDs. (2.7?)
-*/
-
-
-/*
- * Each QH holds a qtd list; a QH is used for everything except iso.
- *
- * For interrupt urbs, the scheduler must set the microframe scheduling
- * mask(s) each time the QH gets scheduled.  For highspeed, that's
- * just one microframe in the s-mask.  For split interrupt transactions
- * there are additional complications: c-mask, maybe FSTNs.
- */
-static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
-				  gfp_t flags)
-{
-	struct fotg210_qh *qh = fotg210_qh_alloc(fotg210, flags);
-	u32 info1 = 0, info2 = 0;
-	int is_input, type;
-	int maxp = 0;
-	struct usb_tt *tt = urb->dev->tt;
-	struct fotg210_qh_hw *hw;
-
-	if (!qh)
-		return qh;
-
-	/*
-	 * init endpoint/device data for this QH
-	 */
-	info1 |= usb_pipeendpoint(urb->pipe) << 8;
-	info1 |= usb_pipedevice(urb->pipe) << 0;
-
-	is_input = usb_pipein(urb->pipe);
-	type = usb_pipetype(urb->pipe);
-	maxp = usb_maxpacket(urb->dev, urb->pipe, !is_input);
-
-	/* 1024 byte maxpacket is a hardware ceiling.  High bandwidth
-	 * acts like up to 3KB, but is built from smaller packets.
-	 */
-	if (max_packet(maxp) > 1024) {
-		fotg210_dbg(fotg210, "bogus qh maxpacket %d\n",
-			    max_packet(maxp));
-		goto done;
-	}
-
-	/* Compute interrupt scheduling parameters just once, and save.
-	 * - allowing for high bandwidth, how many nsec/uframe are used?
-	 * - split transactions need a second CSPLIT uframe; same question
-	 * - splits also need a schedule gap (for full/low speed I/O)
-	 * - qh has a polling interval
-	 *
-	 * For control/bulk requests, the HC or TT handles these.
-	 */
-	if (type == PIPE_INTERRUPT) {
-		qh->usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH,
-				is_input, 0,
-				hb_mult(maxp) * max_packet(maxp)));
-		qh->start = NO_FRAME;
-
-		if (urb->dev->speed == USB_SPEED_HIGH) {
-			qh->c_usecs = 0;
-			qh->gap_uf = 0;
-
-			qh->period = urb->interval >> 3;
-			if (qh->period == 0 && urb->interval != 1) {
-				/* NOTE interval 2 or 4 uframes could work.
-				 * But interval 1 scheduling is simpler, and
-				 * includes high bandwidth.
-				 */
-				urb->interval = 1;
-			} else if (qh->period > fotg210->periodic_size) {
-				qh->period = fotg210->periodic_size;
-				urb->interval = qh->period << 3;
-			}
-		} else {
-			int think_time;
-
-			/* gap is f(FS/LS transfer times) */
-			qh->gap_uf = 1 + usb_calc_bus_time(urb->dev->speed,
-					is_input, 0, maxp) / (125 * 1000);
-
-			/* FIXME this just approximates SPLIT/CSPLIT times */
-			if (is_input) {		/* SPLIT, gap, CSPLIT+DATA */
-				qh->c_usecs = qh->usecs + HS_USECS(0);
-				qh->usecs = HS_USECS(1);
-			} else {		/* SPLIT+DATA, gap, CSPLIT */
-				qh->usecs += HS_USECS(1);
-				qh->c_usecs = HS_USECS(0);
-			}
-
-			think_time = tt ? tt->think_time : 0;
-			qh->tt_usecs = NS_TO_US(think_time +
-					usb_calc_bus_time(urb->dev->speed,
-					is_input, 0, max_packet(maxp)));
-			qh->period = urb->interval;
-			if (qh->period > fotg210->periodic_size) {
-				qh->period = fotg210->periodic_size;
-				urb->interval = qh->period;
-			}
-		}
-	}
-
-	/* support for tt scheduling, and access to toggles */
-	qh->dev = urb->dev;
-
-	/* using TT? */
-	switch (urb->dev->speed) {
-	case USB_SPEED_LOW:
-		info1 |= QH_LOW_SPEED;
-		/* FALL THROUGH */
-
-	case USB_SPEED_FULL:
-		/* EPS 0 means "full" */
-		if (type != PIPE_INTERRUPT)
-			info1 |= (FOTG210_TUNE_RL_TT << 28);
-		if (type == PIPE_CONTROL) {
-			info1 |= QH_CONTROL_EP;		/* for TT */
-			info1 |= QH_TOGGLE_CTL;		/* toggle from qtd */
-		}
-		info1 |= maxp << 16;
-
-		info2 |= (FOTG210_TUNE_MULT_TT << 30);
-
-		/* Some Freescale processors have an erratum in which the
-		 * port number in the queue head was 0..N-1 instead of 1..N.
-		 */
-		if (fotg210_has_fsl_portno_bug(fotg210))
-			info2 |= (urb->dev->ttport-1) << 23;
-		else
-			info2 |= urb->dev->ttport << 23;
-
-		/* set the address of the TT; for TDI's integrated
-		 * root hub tt, leave it zeroed.
-		 */
-		if (tt && tt->hub != fotg210_to_hcd(fotg210)->self.root_hub)
-			info2 |= tt->hub->devnum << 16;
-
-		/* NOTE:  if (PIPE_INTERRUPT) { scheduler sets c-mask } */
-
-		break;
-
-	case USB_SPEED_HIGH:		/* no TT involved */
-		info1 |= QH_HIGH_SPEED;
-		if (type == PIPE_CONTROL) {
-			info1 |= (FOTG210_TUNE_RL_HS << 28);
-			info1 |= 64 << 16;	/* usb2 fixed maxpacket */
-			info1 |= QH_TOGGLE_CTL;	/* toggle from qtd */
-			info2 |= (FOTG210_TUNE_MULT_HS << 30);
-		} else if (type == PIPE_BULK) {
-			info1 |= (FOTG210_TUNE_RL_HS << 28);
-			/* The USB spec says that high speed bulk endpoints
-			 * always use 512 byte maxpacket.  But some device
-			 * vendors decided to ignore that, and MSFT is happy
-			 * to help them do so.  So now people expect to use
-			 * such nonconformant devices with Linux too; sigh.
-			 */
-			info1 |= max_packet(maxp) << 16;
-			info2 |= (FOTG210_TUNE_MULT_HS << 30);
-		} else {		/* PIPE_INTERRUPT */
-			info1 |= max_packet(maxp) << 16;
-			info2 |= hb_mult(maxp) << 30;
-		}
-		break;
-	default:
-		fotg210_dbg(fotg210, "bogus dev %p speed %d\n", urb->dev,
-			urb->dev->speed);
-done:
-		qh_destroy(fotg210, qh);
-		return NULL;
-	}
-
-	/* NOTE:  if (PIPE_INTERRUPT) { scheduler sets s-mask } */
-
-	/* init as live, toggle clear, advance to dummy */
-	qh->qh_state = QH_STATE_IDLE;
-	hw = qh->hw;
-	hw->hw_info1 = cpu_to_hc32(fotg210, info1);
-	hw->hw_info2 = cpu_to_hc32(fotg210, info2);
-	qh->is_out = !is_input;
-	usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), !is_input, 1);
-	qh_refresh(fotg210, qh);
-	return qh;
-}
-
-static void enable_async(struct fotg210_hcd *fotg210)
-{
-	if (fotg210->async_count++)
-		return;
-
-	/* Stop waiting to turn off the async schedule */
-	fotg210->enabled_hrtimer_events &= ~BIT(FOTG210_HRTIMER_DISABLE_ASYNC);
-
-	/* Don't start the schedule until ASS is 0 */
-	fotg210_poll_ASS(fotg210);
-	turn_on_io_watchdog(fotg210);
-}
-
-static void disable_async(struct fotg210_hcd *fotg210)
-{
-	if (--fotg210->async_count)
-		return;
-
-	/* The async schedule and async_unlink list are supposed to be empty */
-	WARN_ON(fotg210->async->qh_next.qh || fotg210->async_unlink);
-
-	/* Don't turn off the schedule until ASS is 1 */
-	fotg210_poll_ASS(fotg210);
-}
-
-/* move qh (and its qtds) onto async queue; maybe enable queue.  */
-
-static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
-{
-	__hc32 dma = QH_NEXT(fotg210, qh->qh_dma);
-	struct fotg210_qh *head;
-
-	/* Don't link a QH if there's a Clear-TT-Buffer pending */
-	if (unlikely(qh->clearing_tt))
-		return;
-
-	WARN_ON(qh->qh_state != QH_STATE_IDLE);
-
-	/* clear halt and/or toggle; and maybe recover from silicon quirk */
-	qh_refresh(fotg210, qh);
-
-	/* splice right after start */
-	head = fotg210->async;
-	qh->qh_next = head->qh_next;
-	qh->hw->hw_next = head->hw->hw_next;
-	wmb();
-
-	head->qh_next.qh = qh;
-	head->hw->hw_next = dma;
-
-	qh->xacterrs = 0;
-	qh->qh_state = QH_STATE_LINKED;
-	/* qtd completions reported later by interrupt */
-
-	enable_async(fotg210);
-}
-
-/*
- * For control/bulk/interrupt, return QH with these TDs appended.
- * Allocates and initializes the QH if necessary.
- * Returns null if it can't allocate a QH it needs to.
- * If the QH has TDs (urbs) already, that's great.
- */
-static struct fotg210_qh *qh_append_tds(struct fotg210_hcd *fotg210,
-					struct urb *urb,
-					struct list_head *qtd_list, int epnum,
-					void **ptr)
-{
-	struct fotg210_qh *qh = NULL;
-	__hc32 qh_addr_mask = cpu_to_hc32(fotg210, 0x7f);
-
-	qh = (struct fotg210_qh *) *ptr;
-	if (unlikely(qh == NULL)) {
-		/* can't sleep here, we have fotg210->lock... */
-		qh = qh_make(fotg210, urb, GFP_ATOMIC);
-		*ptr = qh;
-	}
-	if (likely(qh != NULL)) {
-		struct fotg210_qtd *qtd;
-
-		if (unlikely(list_empty(qtd_list)))
-			qtd = NULL;
-		else
-			qtd = list_entry(qtd_list->next, struct fotg210_qtd,
-					qtd_list);
-
-		/* control qh may need patching ... */
-		if (unlikely(epnum == 0)) {
-			/* usb_reset_device() briefly reverts to address 0 */
-			if (usb_pipedevice(urb->pipe) == 0)
-				qh->hw->hw_info1 &= ~qh_addr_mask;
-		}
-
-		/* just one way to queue requests: swap with the dummy qtd.
-		 * only hc or qh_refresh() ever modify the overlay.
-		 */
-		if (likely(qtd != NULL)) {
-			struct fotg210_qtd *dummy;
-			dma_addr_t dma;
-			__hc32 token;
-
-			/* to avoid racing the HC, use the dummy td instead of
-			 * the first td of our list (becomes new dummy).  both
-			 * tds stay deactivated until we're done, when the
-			 * HC is allowed to fetch the old dummy (4.10.2).
-			 */
-			token = qtd->hw_token;
-			qtd->hw_token = HALT_BIT(fotg210);
-
-			dummy = qh->dummy;
-
-			dma = dummy->qtd_dma;
-			*dummy = *qtd;
-			dummy->qtd_dma = dma;
-
-			list_del(&qtd->qtd_list);
-			list_add(&dummy->qtd_list, qtd_list);
-			list_splice_tail(qtd_list, &qh->qtd_list);
-
-			fotg210_qtd_init(fotg210, qtd, qtd->qtd_dma);
-			qh->dummy = qtd;
-
-			/* hc must see the new dummy at list end */
-			dma = qtd->qtd_dma;
-			qtd = list_entry(qh->qtd_list.prev,
-					struct fotg210_qtd, qtd_list);
-			qtd->hw_next = QTD_NEXT(fotg210, dma);
-
-			/* let the hc process these next qtds */
-			wmb();
-			dummy->hw_token = token;
-
-			urb->hcpriv = qh;
-		}
-	}
-	return qh;
-}
-
-static int submit_async(struct fotg210_hcd *fotg210, struct urb *urb,
-			struct list_head *qtd_list, gfp_t mem_flags)
-{
-	int epnum;
-	unsigned long flags;
-	struct fotg210_qh *qh = NULL;
-	int rc;
-
-	epnum = urb->ep->desc.bEndpointAddress;
-
-#ifdef FOTG210_URB_TRACE
-	{
-		struct fotg210_qtd *qtd;
-
-		qtd = list_entry(qtd_list->next, struct fotg210_qtd, qtd_list);
-		fotg210_dbg(fotg210,
-			 "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-			 __func__, urb->dev->devpath, urb,
-			 epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
-			 urb->transfer_buffer_length,
-			 qtd, urb->ep->hcpriv);
-	}
-#endif
-
-	spin_lock_irqsave(&fotg210->lock, flags);
-	if (unlikely(!HCD_HW_ACCESSIBLE(fotg210_to_hcd(fotg210)))) {
-		rc = -ESHUTDOWN;
-		goto done;
-	}
-	rc = usb_hcd_link_urb_to_ep(fotg210_to_hcd(fotg210), urb);
-	if (unlikely(rc))
-		goto done;
-
-	qh = qh_append_tds(fotg210, urb, qtd_list, epnum, &urb->ep->hcpriv);
-	if (unlikely(qh == NULL)) {
-		usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
-		rc = -ENOMEM;
-		goto done;
-	}
-
-	/* Control/bulk operations through TTs don't need scheduling,
-	 * the HC and TT handle it when the TT has a buffer ready.
-	 */
-	if (likely(qh->qh_state == QH_STATE_IDLE))
-		qh_link_async(fotg210, qh);
-done:
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-	if (unlikely(qh == NULL))
-		qtd_list_free(fotg210, urb, qtd_list);
-	return rc;
-}
-
-static void single_unlink_async(struct fotg210_hcd *fotg210,
-				struct fotg210_qh *qh)
-{
-	struct fotg210_qh *prev;
-
-	/* Add to the end of the list of QHs waiting for the next IAAD */
-	qh->qh_state = QH_STATE_UNLINK;
-	if (fotg210->async_unlink)
-		fotg210->async_unlink_last->unlink_next = qh;
-	else
-		fotg210->async_unlink = qh;
-	fotg210->async_unlink_last = qh;
-
-	/* Unlink it from the schedule */
-	prev = fotg210->async;
-	while (prev->qh_next.qh != qh)
-		prev = prev->qh_next.qh;
-
-	prev->hw->hw_next = qh->hw->hw_next;
-	prev->qh_next = qh->qh_next;
-	if (fotg210->qh_scan_next == qh)
-		fotg210->qh_scan_next = qh->qh_next.qh;
-}
-
-static void start_iaa_cycle(struct fotg210_hcd *fotg210, bool nested)
-{
-	/*
-	 * Do nothing if an IAA cycle is already running or
-	 * if one will be started shortly.
-	 */
-	if (fotg210->async_iaa || fotg210->async_unlinking)
-		return;
-
-	/* Do all the waiting QHs at once */
-	fotg210->async_iaa = fotg210->async_unlink;
-	fotg210->async_unlink = NULL;
-
-	/* If the controller isn't running, we don't have to wait for it */
-	if (unlikely(fotg210->rh_state < FOTG210_RH_RUNNING)) {
-		if (!nested)		/* Avoid recursion */
-			end_unlink_async(fotg210);
-
-	/* Otherwise start a new IAA cycle */
-	} else if (likely(fotg210->rh_state == FOTG210_RH_RUNNING)) {
-		/* Make sure the unlinks are all visible to the hardware */
-		wmb();
-
-		fotg210_writel(fotg210, fotg210->command | CMD_IAAD,
-				&fotg210->regs->command);
-		fotg210_readl(fotg210, &fotg210->regs->command);
-		fotg210_enable_event(fotg210, FOTG210_HRTIMER_IAA_WATCHDOG,
-				     true);
-	}
-}
-
-/* the async qh for the qtds being unlinked are now gone from the HC */
-
-static void end_unlink_async(struct fotg210_hcd *fotg210)
-{
-	struct fotg210_qh *qh;
-
-	/* Process the idle QHs */
-restart:
-	fotg210->async_unlinking = true;
-	while (fotg210->async_iaa) {
-		qh = fotg210->async_iaa;
-		fotg210->async_iaa = qh->unlink_next;
-		qh->unlink_next = NULL;
-
-		qh->qh_state = QH_STATE_IDLE;
-		qh->qh_next.qh = NULL;
-
-		qh_completions(fotg210, qh);
-		if (!list_empty(&qh->qtd_list) &&
-				fotg210->rh_state == FOTG210_RH_RUNNING)
-			qh_link_async(fotg210, qh);
-		disable_async(fotg210);
-	}
-	fotg210->async_unlinking = false;
-
-	/* Start a new IAA cycle if any QHs are waiting for it */
-	if (fotg210->async_unlink) {
-		start_iaa_cycle(fotg210, true);
-		if (unlikely(fotg210->rh_state < FOTG210_RH_RUNNING))
-			goto restart;
-	}
-}
-
-static void unlink_empty_async(struct fotg210_hcd *fotg210)
-{
-	struct fotg210_qh *qh, *next;
-	bool stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
-	bool check_unlinks_later = false;
-
-	/* Unlink all the async QHs that have been empty for a timer cycle */
-	next = fotg210->async->qh_next.qh;
-	while (next) {
-		qh = next;
-		next = qh->qh_next.qh;
-
-		if (list_empty(&qh->qtd_list) &&
-				qh->qh_state == QH_STATE_LINKED) {
-			if (!stopped && qh->unlink_cycle ==
-					fotg210->async_unlink_cycle)
-				check_unlinks_later = true;
-			else
-				single_unlink_async(fotg210, qh);
-		}
-	}
-
-	/* Start a new IAA cycle if any QHs are waiting for it */
-	if (fotg210->async_unlink)
-		start_iaa_cycle(fotg210, false);
-
-	/* QHs that haven't been empty for long enough will be handled later */
-	if (check_unlinks_later) {
-		fotg210_enable_event(fotg210, FOTG210_HRTIMER_ASYNC_UNLINKS,
-				     true);
-		++fotg210->async_unlink_cycle;
-	}
-}
-
-/* makes sure the async qh will become idle */
-/* caller must own fotg210->lock */
-
-static void start_unlink_async(struct fotg210_hcd *fotg210,
-			       struct fotg210_qh *qh)
-{
-	/*
-	 * If the QH isn't linked then there's nothing we can do
-	 * unless we were called during a giveback, in which case
-	 * qh_completions() has to deal with it.
-	 */
-	if (qh->qh_state != QH_STATE_LINKED) {
-		if (qh->qh_state == QH_STATE_COMPLETING)
-			qh->needs_rescan = 1;
-		return;
-	}
-
-	single_unlink_async(fotg210, qh);
-	start_iaa_cycle(fotg210, false);
-}
-
-static void scan_async(struct fotg210_hcd *fotg210)
-{
-	struct fotg210_qh *qh;
-	bool check_unlinks_later = false;
-
-	fotg210->qh_scan_next = fotg210->async->qh_next.qh;
-	while (fotg210->qh_scan_next) {
-		qh = fotg210->qh_scan_next;
-		fotg210->qh_scan_next = qh->qh_next.qh;
-rescan:
-		/* clean any finished work for this qh */
-		if (!list_empty(&qh->qtd_list)) {
-			int temp;
-
-			/*
-			 * Unlinks could happen here; completion reporting
-			 * drops the lock.  That's why fotg210->qh_scan_next
-			 * always holds the next qh to scan; if the next qh
-			 * gets unlinked then fotg210->qh_scan_next is adjusted
-			 * in single_unlink_async().
-			 */
-			temp = qh_completions(fotg210, qh);
-			if (qh->needs_rescan) {
-				start_unlink_async(fotg210, qh);
-			} else if (list_empty(&qh->qtd_list)
-					&& qh->qh_state == QH_STATE_LINKED) {
-				qh->unlink_cycle = fotg210->async_unlink_cycle;
-				check_unlinks_later = true;
-			} else if (temp != 0)
-				goto rescan;
-		}
-	}
-
-	/*
-	 * Unlink empty entries, reducing DMA usage as well
-	 * as HCD schedule-scanning costs.  Delay for any qh
-	 * we just scanned, there's a not-unusual case that it
-	 * doesn't stay idle for long.
-	 */
-	if (check_unlinks_later && fotg210->rh_state == FOTG210_RH_RUNNING &&
-			!(fotg210->enabled_hrtimer_events &
-				BIT(FOTG210_HRTIMER_ASYNC_UNLINKS))) {
-		fotg210_enable_event(fotg210,
-				     FOTG210_HRTIMER_ASYNC_UNLINKS, true);
-		++fotg210->async_unlink_cycle;
-	}
-}
-/*
- * EHCI scheduled transaction support:  interrupt, iso, split iso
- * These are called "periodic" transactions in the EHCI spec.
- *
- * Note that for interrupt transfers, the QH/QTD manipulation is shared
- * with the "asynchronous" transaction support (control/bulk transfers).
- * The only real difference is in how interrupt transfers are scheduled.
- *
- * For ISO, we make an "iso_stream" head to serve the same role as a QH.
- * It keeps track of every ITD (or SITD) that's linked, and holds enough
- * pre-calculated schedule data to make appending to the queue be quick.
- */
-static int fotg210_get_frame(struct usb_hcd *hcd);
-
-/*
- * periodic_next_shadow - return "next" pointer on shadow list
- * @periodic: host pointer to qh/itd
- * @tag: hardware tag for type of this record
- */
-static union fotg210_shadow *periodic_next_shadow(struct fotg210_hcd *fotg210,
-						union fotg210_shadow *periodic,
-						__hc32 tag)
-{
-	switch (hc32_to_cpu(fotg210, tag)) {
-	case Q_TYPE_QH:
-		return &periodic->qh->qh_next;
-	case Q_TYPE_FSTN:
-		return &periodic->fstn->fstn_next;
-	default:
-		return &periodic->itd->itd_next;
-	}
-}
-
-static __hc32 *shadow_next_periodic(struct fotg210_hcd *fotg210,
-				    union fotg210_shadow *periodic, __hc32 tag)
-{
-	switch (hc32_to_cpu(fotg210, tag)) {
-	/* our fotg210_shadow.qh is actually software part */
-	case Q_TYPE_QH:
-		return &periodic->qh->hw->hw_next;
-	/* others are hw parts */
-	default:
-		return periodic->hw_next;
-	}
-}
-
-/* caller must hold fotg210->lock */
-static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
-			    void *ptr)
-{
-	union fotg210_shadow *prev_p = &fotg210->pshadow[frame];
-	__hc32 *hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow here = *prev_p;
-
-	/* find predecessor of "ptr"; hw and shadow lists are in sync */
-	while (here.ptr && here.ptr != ptr) {
-		prev_p = periodic_next_shadow(fotg210, prev_p,
-				Q_NEXT_TYPE(fotg210, *hw_p));
-		hw_p = shadow_next_periodic(fotg210, &here,
-				Q_NEXT_TYPE(fotg210, *hw_p));
-		here = *prev_p;
-	}
-	/* an interrupt entry (at list end) could have been shared */
-	if (!here.ptr)
-		return;
-
-	/* update shadow and hardware lists ... the old "next" pointers
-	 * from ptr may still be in use, the caller updates them.
-	 */
-	*prev_p = *periodic_next_shadow(fotg210, &here,
-			Q_NEXT_TYPE(fotg210, *hw_p));
-
-	*hw_p = *shadow_next_periodic(fotg210, &here,
-				Q_NEXT_TYPE(fotg210, *hw_p));
-}
-
-/* how many of the uframe's 125 usecs are allocated? */
-static unsigned short periodic_usecs(struct fotg210_hcd *fotg210,
-				     unsigned frame, unsigned uframe)
-{
-	__hc32 *hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow *q = &fotg210->pshadow[frame];
-	unsigned usecs = 0;
-	struct fotg210_qh_hw *hw;
-
-	while (q->ptr) {
-		switch (hc32_to_cpu(fotg210, Q_NEXT_TYPE(fotg210, *hw_p))) {
-		case Q_TYPE_QH:
-			hw = q->qh->hw;
-			/* is it in the S-mask? */
-			if (hw->hw_info2 & cpu_to_hc32(fotg210, 1 << uframe))
-				usecs += q->qh->usecs;
-			/* ... or C-mask? */
-			if (hw->hw_info2 & cpu_to_hc32(fotg210,
-					1 << (8 + uframe)))
-				usecs += q->qh->c_usecs;
-			hw_p = &hw->hw_next;
-			q = &q->qh->qh_next;
-			break;
-		/* case Q_TYPE_FSTN: */
-		default:
-			/* for "save place" FSTNs, count the relevant INTR
-			 * bandwidth from the previous frame
-			 */
-			if (q->fstn->hw_prev != FOTG210_LIST_END(fotg210))
-				fotg210_dbg(fotg210, "ignoring FSTN cost ...\n");
-
-			hw_p = &q->fstn->hw_next;
-			q = &q->fstn->fstn_next;
-			break;
-		case Q_TYPE_ITD:
-			if (q->itd->hw_transaction[uframe])
-				usecs += q->itd->stream->usecs;
-			hw_p = &q->itd->hw_next;
-			q = &q->itd->itd_next;
-			break;
-		}
-	}
-	if (usecs > fotg210->uframe_periodic_max)
-		fotg210_err(fotg210, "uframe %d sched overrun: %d usecs\n",
-			frame * 8 + uframe, usecs);
-	return usecs;
-}
-
-static int same_tt(struct usb_device *dev1, struct usb_device *dev2)
-{
-	if (!dev1->tt || !dev2->tt)
-		return 0;
-	if (dev1->tt != dev2->tt)
-		return 0;
-	if (dev1->tt->multi)
-		return dev1->ttport == dev2->ttport;
-	else
-		return 1;
-}
-
-/* return true iff the device's transaction translator is available
- * for a periodic transfer starting at the specified frame, using
- * all the uframes in the mask.
- */
-static int tt_no_collision(struct fotg210_hcd *fotg210, unsigned period,
-			   struct usb_device *dev, unsigned frame, u32 uf_mask)
-{
-	if (period == 0)	/* error */
-		return 0;
-
-	/* note bandwidth wastage:  split never follows csplit
-	 * (different dev or endpoint) until the next uframe.
-	 * calling convention doesn't make that distinction.
-	 */
-	for (; frame < fotg210->periodic_size; frame += period) {
-		union fotg210_shadow here;
-		__hc32 type;
-		struct fotg210_qh_hw *hw;
-
-		here = fotg210->pshadow[frame];
-		type = Q_NEXT_TYPE(fotg210, fotg210->periodic[frame]);
-		while (here.ptr) {
-			switch (hc32_to_cpu(fotg210, type)) {
-			case Q_TYPE_ITD:
-				type = Q_NEXT_TYPE(fotg210, here.itd->hw_next);
-				here = here.itd->itd_next;
-				continue;
-			case Q_TYPE_QH:
-				hw = here.qh->hw;
-				if (same_tt(dev, here.qh->dev)) {
-					u32 mask;
-
-					mask = hc32_to_cpu(fotg210,
-							hw->hw_info2);
-					/* "knows" no gap is needed */
-					mask |= mask >> 8;
-					if (mask & uf_mask)
-						break;
-				}
-				type = Q_NEXT_TYPE(fotg210, hw->hw_next);
-				here = here.qh->qh_next;
-				continue;
-			/* case Q_TYPE_FSTN: */
-			default:
-				fotg210_dbg(fotg210,
-					"periodic frame %d bogus type %d\n",
-					frame, type);
-			}
-
-			/* collision or error */
-			return 0;
-		}
-	}
-
-	/* no collision */
-	return 1;
-}
-
-static void enable_periodic(struct fotg210_hcd *fotg210)
-{
-	if (fotg210->periodic_count++)
-		return;
-
-	/* Stop waiting to turn off the periodic schedule */
-	fotg210->enabled_hrtimer_events &=
-		~BIT(FOTG210_HRTIMER_DISABLE_PERIODIC);
-
-	/* Don't start the schedule until PSS is 0 */
-	fotg210_poll_PSS(fotg210);
-	turn_on_io_watchdog(fotg210);
-}
-
-static void disable_periodic(struct fotg210_hcd *fotg210)
-{
-	if (--fotg210->periodic_count)
-		return;
-
-	/* Don't turn off the schedule until PSS is 1 */
-	fotg210_poll_PSS(fotg210);
-}
-
-/* periodic schedule slots have iso tds (normal or split) first, then a
- * sparse tree for active interrupt transfers.
- *
- * this just links in a qh; caller guarantees uframe masks are set right.
- * no FSTN support (yet; fotg210 0.96+)
- */
-static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
-{
-	unsigned i;
-	unsigned period = qh->period;
-
-	dev_dbg(&qh->dev->dev,
-		"link qh%d-%04x/%p start %d [%d/%d us]\n",
-		period, hc32_to_cpup(fotg210, &qh->hw->hw_info2)
-			& (QH_CMASK | QH_SMASK),
-		qh, qh->start, qh->usecs, qh->c_usecs);
-
-	/* high bandwidth, or otherwise every microframe */
-	if (period == 0)
-		period = 1;
-
-	for (i = qh->start; i < fotg210->periodic_size; i += period) {
-		union fotg210_shadow *prev = &fotg210->pshadow[i];
-		__hc32 *hw_p = &fotg210->periodic[i];
-		union fotg210_shadow here = *prev;
-		__hc32 type = 0;
-
-		/* skip the iso nodes at list head */
-		while (here.ptr) {
-			type = Q_NEXT_TYPE(fotg210, *hw_p);
-			if (type == cpu_to_hc32(fotg210, Q_TYPE_QH))
-				break;
-			prev = periodic_next_shadow(fotg210, prev, type);
-			hw_p = shadow_next_periodic(fotg210, &here, type);
-			here = *prev;
-		}
-
-		/* sorting each branch by period (slow-->fast)
-		 * enables sharing interior tree nodes
-		 */
-		while (here.ptr && qh != here.qh) {
-			if (qh->period > here.qh->period)
-				break;
-			prev = &here.qh->qh_next;
-			hw_p = &here.qh->hw->hw_next;
-			here = *prev;
-		}
-		/* link in this qh, unless some earlier pass did that */
-		if (qh != here.qh) {
-			qh->qh_next = here;
-			if (here.qh)
-				qh->hw->hw_next = *hw_p;
-			wmb();
-			prev->qh = qh;
-			*hw_p = QH_NEXT(fotg210, qh->qh_dma);
-		}
-	}
-	qh->qh_state = QH_STATE_LINKED;
-	qh->xacterrs = 0;
-
-	/* update per-qh bandwidth for usbfs */
-	fotg210_to_hcd(fotg210)->self.bandwidth_allocated += qh->period
-		? ((qh->usecs + qh->c_usecs) / qh->period)
-		: (qh->usecs * 8);
-
-	list_add(&qh->intr_node, &fotg210->intr_qh_list);
-
-	/* maybe enable periodic schedule processing */
-	++fotg210->intr_count;
-	enable_periodic(fotg210);
-}
-
-static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
-			       struct fotg210_qh *qh)
-{
-	unsigned i;
-	unsigned period;
-
-	/*
-	 * If qh is for a low/full-speed device, simply unlinking it
-	 * could interfere with an ongoing split transaction.  To unlink
-	 * it safely would require setting the QH_INACTIVATE bit and
-	 * waiting at least one frame, as described in EHCI 4.12.2.5.
-	 *
-	 * We won't bother with any of this.  Instead, we assume that the
-	 * only reason for unlinking an interrupt QH while the current URB
-	 * is still active is to dequeue all the URBs (flush the whole
-	 * endpoint queue).
-	 *
-	 * If rebalancing the periodic schedule is ever implemented, this
-	 * approach will no longer be valid.
-	 */
-
-	/* high bandwidth, or otherwise part of every microframe */
-	period = qh->period;
-	if (!period)
-		period = 1;
-
-	for (i = qh->start; i < fotg210->periodic_size; i += period)
-		periodic_unlink(fotg210, i, qh);
-
-	/* update per-qh bandwidth for usbfs */
-	fotg210_to_hcd(fotg210)->self.bandwidth_allocated -= qh->period
-		? ((qh->usecs + qh->c_usecs) / qh->period)
-		: (qh->usecs * 8);
-
-	dev_dbg(&qh->dev->dev,
-		"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
-		qh->period,
-		hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
-		(QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs, qh->c_usecs);
-
-	/* qh->qh_next still "live" to HC */
-	qh->qh_state = QH_STATE_UNLINK;
-	qh->qh_next.ptr = NULL;
-
-	if (fotg210->qh_scan_next == qh)
-		fotg210->qh_scan_next = list_entry(qh->intr_node.next,
-				struct fotg210_qh, intr_node);
-	list_del(&qh->intr_node);
-}
-
-static void start_unlink_intr(struct fotg210_hcd *fotg210,
-			      struct fotg210_qh *qh)
-{
-	/* If the QH isn't linked then there's nothing we can do
-	 * unless we were called during a giveback, in which case
-	 * qh_completions() has to deal with it.
-	 */
-	if (qh->qh_state != QH_STATE_LINKED) {
-		if (qh->qh_state == QH_STATE_COMPLETING)
-			qh->needs_rescan = 1;
-		return;
-	}
-
-	qh_unlink_periodic(fotg210, qh);
-
-	/* Make sure the unlinks are visible before starting the timer */
-	wmb();
-
-	/*
-	 * The EHCI spec doesn't say how long it takes the controller to
-	 * stop accessing an unlinked interrupt QH.  The timer delay is
-	 * 9 uframes; presumably that will be long enough.
-	 */
-	qh->unlink_cycle = fotg210->intr_unlink_cycle;
-
-	/* New entries go at the end of the intr_unlink list */
-	if (fotg210->intr_unlink)
-		fotg210->intr_unlink_last->unlink_next = qh;
-	else
-		fotg210->intr_unlink = qh;
-	fotg210->intr_unlink_last = qh;
-
-	if (fotg210->intr_unlinking)
-		;	/* Avoid recursive calls */
-	else if (fotg210->rh_state < FOTG210_RH_RUNNING)
-		fotg210_handle_intr_unlinks(fotg210);
-	else if (fotg210->intr_unlink == qh) {
-		fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
-				     true);
-		++fotg210->intr_unlink_cycle;
-	}
-}
-
-static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
-{
-	struct fotg210_qh_hw *hw = qh->hw;
-	int rc;
-
-	qh->qh_state = QH_STATE_IDLE;
-	hw->hw_next = FOTG210_LIST_END(fotg210);
-
-	qh_completions(fotg210, qh);
-
-	/* reschedule QH iff another request is queued */
-	if (!list_empty(&qh->qtd_list) &&
-	    fotg210->rh_state == FOTG210_RH_RUNNING) {
-		rc = qh_schedule(fotg210, qh);
-
-		/* An error here likely indicates handshake failure
-		 * or no space left in the schedule.  Neither fault
-		 * should happen often ...
-		 *
-		 * FIXME kill the now-dysfunctional queued urbs
-		 */
-		if (rc != 0)
-			fotg210_err(fotg210, "can't reschedule qh %p, err %d\n",
-					qh, rc);
-	}
-
-	/* maybe turn off periodic schedule */
-	--fotg210->intr_count;
-	disable_periodic(fotg210);
-}
-
-static int check_period(struct fotg210_hcd *fotg210, unsigned frame,
-			unsigned uframe, unsigned period, unsigned usecs)
-{
-	int claimed;
-
-	/* complete split running into next frame?
-	 * given FSTN support, we could sometimes check...
-	 */
-	if (uframe >= 8)
-		return 0;
-
-	/* convert "usecs we need" to "max already claimed" */
-	usecs = fotg210->uframe_periodic_max - usecs;
-
-	/* we "know" 2 and 4 uframe intervals were rejected; so
-	 * for period 0, check _every_ microframe in the schedule.
-	 */
-	if (unlikely(period == 0)) {
-		do {
-			for (uframe = 0; uframe < 7; uframe++) {
-				claimed = periodic_usecs(fotg210, frame,
-							 uframe);
-				if (claimed > usecs)
-					return 0;
-			}
-		} while ((frame += 1) < fotg210->periodic_size);
-
-	/* just check the specified uframe, at that period */
-	} else {
-		do {
-			claimed = periodic_usecs(fotg210, frame, uframe);
-			if (claimed > usecs)
-				return 0;
-		} while ((frame += period) < fotg210->periodic_size);
-	}
-
-	/* success! */
-	return 1;
-}
-
-static int check_intr_schedule(struct fotg210_hcd *fotg210, unsigned frame,
-			       unsigned uframe, const struct fotg210_qh *qh,
-			       __hc32 *c_maskp)
-{
-	int retval = -ENOSPC;
-	u8 mask = 0;
-
-	if (qh->c_usecs && uframe >= 6)		/* FSTN territory? */
-		goto done;
-
-	if (!check_period(fotg210, frame, uframe, qh->period, qh->usecs))
-		goto done;
-	if (!qh->c_usecs) {
-		retval = 0;
-		*c_maskp = 0;
-		goto done;
-	}
-
-	/* Make sure this tt's buffer is also available for CSPLITs.
-	 * We pessimize a bit; probably the typical full speed case
-	 * doesn't need the second CSPLIT.
-	 *
-	 * NOTE:  both SPLIT and CSPLIT could be checked in just
-	 * one smart pass...
-	 */
-	mask = 0x03 << (uframe + qh->gap_uf);
-	*c_maskp = cpu_to_hc32(fotg210, mask << 8);
-
-	mask |= 1 << uframe;
-	if (tt_no_collision(fotg210, qh->period, qh->dev, frame, mask)) {
-		if (!check_period(fotg210, frame, uframe + qh->gap_uf + 1,
-					qh->period, qh->c_usecs))
-			goto done;
-		if (!check_period(fotg210, frame, uframe + qh->gap_uf,
-					qh->period, qh->c_usecs))
-			goto done;
-		retval = 0;
-	}
-done:
-	return retval;
-}
-
-/* "first fit" scheduling policy used the first time through,
- * or when the previous schedule slot can't be re-used.
- */
-static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
-{
-	int status;
-	unsigned uframe;
-	__hc32 c_mask;
-	unsigned frame;	/* 0..(qh->period - 1), or NO_FRAME */
-	struct fotg210_qh_hw *hw = qh->hw;
-
-	qh_refresh(fotg210, qh);
-	hw->hw_next = FOTG210_LIST_END(fotg210);
-	frame = qh->start;
-
-	/* reuse the previous schedule slots, if we can */
-	if (frame < qh->period) {
-		uframe = ffs(hc32_to_cpup(fotg210, &hw->hw_info2) & QH_SMASK);
-		status = check_intr_schedule(fotg210, frame, --uframe,
-				qh, &c_mask);
-	} else {
-		uframe = 0;
-		c_mask = 0;
-		status = -ENOSPC;
-	}
-
-	/* else scan the schedule to find a group of slots such that all
-	 * uframes have enough periodic bandwidth available.
-	 */
-	if (status) {
-		/* "normal" case, uframing flexible except with splits */
-		if (qh->period) {
-			int i;
-
-			for (i = qh->period; status && i > 0; --i) {
-				frame = ++fotg210->random_frame % qh->period;
-				for (uframe = 0; uframe < 8; uframe++) {
-					status = check_intr_schedule(fotg210,
-							frame, uframe, qh,
-							&c_mask);
-					if (status == 0)
-						break;
-				}
-			}
-
-		/* qh->period == 0 means every uframe */
-		} else {
-			frame = 0;
-			status = check_intr_schedule(fotg210, 0, 0, qh,
-						     &c_mask);
-		}
-		if (status)
-			goto done;
-		qh->start = frame;
-
-		/* reset S-frame and (maybe) C-frame masks */
-		hw->hw_info2 &= cpu_to_hc32(fotg210, ~(QH_CMASK | QH_SMASK));
-		hw->hw_info2 |= qh->period
-			? cpu_to_hc32(fotg210, 1 << uframe)
-			: cpu_to_hc32(fotg210, QH_SMASK);
-		hw->hw_info2 |= c_mask;
-	} else
-		fotg210_dbg(fotg210, "reused qh %p schedule\n", qh);
-
-	/* stuff into the periodic schedule */
-	qh_link_periodic(fotg210, qh);
-done:
-	return status;
-}
-
-static int intr_submit(struct fotg210_hcd *fotg210, struct urb *urb,
-		       struct list_head *qtd_list, gfp_t mem_flags)
-{
-	unsigned epnum;
-	unsigned long flags;
-	struct fotg210_qh *qh;
-	int status;
-	struct list_head empty;
-
-	/* get endpoint and transfer/schedule data */
-	epnum = urb->ep->desc.bEndpointAddress;
-
-	spin_lock_irqsave(&fotg210->lock, flags);
-
-	if (unlikely(!HCD_HW_ACCESSIBLE(fotg210_to_hcd(fotg210)))) {
-		status = -ESHUTDOWN;
-		goto done_not_linked;
-	}
-	status = usb_hcd_link_urb_to_ep(fotg210_to_hcd(fotg210), urb);
-	if (unlikely(status))
-		goto done_not_linked;
-
-	/* get qh and force any scheduling errors */
-	INIT_LIST_HEAD(&empty);
-	qh = qh_append_tds(fotg210, urb, &empty, epnum, &urb->ep->hcpriv);
-	if (qh == NULL) {
-		status = -ENOMEM;
-		goto done;
-	}
-	if (qh->qh_state == QH_STATE_IDLE) {
-		status = qh_schedule(fotg210, qh);
-		if (status)
-			goto done;
-	}
-
-	/* then queue the urb's tds to the qh */
-	qh = qh_append_tds(fotg210, urb, qtd_list, epnum, &urb->ep->hcpriv);
-	BUG_ON(qh == NULL);
-
-	/* ... update usbfs periodic stats */
-	fotg210_to_hcd(fotg210)->self.bandwidth_int_reqs++;
-
-done:
-	if (unlikely(status))
-		usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
-done_not_linked:
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-	if (status)
-		qtd_list_free(fotg210, urb, qtd_list);
-
-	return status;
-}
-
-static void scan_intr(struct fotg210_hcd *fotg210)
-{
-	struct fotg210_qh *qh;
-
-	list_for_each_entry_safe(qh, fotg210->qh_scan_next,
-				 &fotg210->intr_qh_list, intr_node) {
-rescan:
-		/* clean any finished work for this qh */
-		if (!list_empty(&qh->qtd_list)) {
-			int temp;
-
-			/*
-			 * Unlinks could happen here; completion reporting
-			 * drops the lock.  That's why fotg210->qh_scan_next
-			 * always holds the next qh to scan; if the next qh
-			 * gets unlinked then fotg210->qh_scan_next is adjusted
-			 * in qh_unlink_periodic().
-			 */
-			temp = qh_completions(fotg210, qh);
-			if (unlikely(qh->needs_rescan ||
-					(list_empty(&qh->qtd_list) &&
-					 qh->qh_state == QH_STATE_LINKED)))
-				start_unlink_intr(fotg210, qh);
-			else if (temp != 0)
-				goto rescan;
-		}
-	}
-}
-
-/* fotg210_iso_stream ops work with both ITD and SITD */
-
-static struct fotg210_iso_stream *iso_stream_alloc(gfp_t mem_flags)
-{
-	struct fotg210_iso_stream *stream;
-
-	stream = kzalloc(sizeof(*stream), mem_flags);
-	if (likely(stream != NULL)) {
-		INIT_LIST_HEAD(&stream->td_list);
-		INIT_LIST_HEAD(&stream->free_list);
-		stream->next_uframe = -1;
-	}
-	return stream;
-}
-
-static void iso_stream_init(struct fotg210_hcd *fotg210,
-			    struct fotg210_iso_stream *stream,
-			    struct usb_device *dev, int pipe,
-			    unsigned interval)
-{
-	u32 buf1;
-	unsigned epnum, maxp;
-	int is_input;
-	long bandwidth;
-	unsigned multi;
-
-	/*
-	 * this might be a "high bandwidth" highspeed endpoint,
-	 * as encoded in the ep descriptor's wMaxPacket field
-	 */
-	epnum = usb_pipeendpoint(pipe);
-	is_input = usb_pipein(pipe) ? USB_DIR_IN : 0;
-	maxp = usb_maxpacket(dev, pipe, !is_input);
-	if (is_input)
-		buf1 = (1 << 11);
-	else
-		buf1 = 0;
-
-	maxp = max_packet(maxp);
-	multi = hb_mult(maxp);
-	buf1 |= maxp;
-	maxp *= multi;
-
-	stream->buf0 = cpu_to_hc32(fotg210, (epnum << 8) | dev->devnum);
-	stream->buf1 = cpu_to_hc32(fotg210, buf1);
-	stream->buf2 = cpu_to_hc32(fotg210, multi);
-
-	/* usbfs wants to report the average usecs per frame tied up
-	 * when transfers on this endpoint are scheduled ...
-	 */
-	if (dev->speed == USB_SPEED_FULL) {
-		interval <<= 3;
-		stream->usecs = NS_TO_US(usb_calc_bus_time(dev->speed,
-				is_input, 1, maxp));
-		stream->usecs /= 8;
-	} else {
-		stream->highspeed = 1;
-		stream->usecs = HS_USECS_ISO(maxp);
-	}
-	bandwidth = stream->usecs * 8;
-	bandwidth /= interval;
-
-	stream->bandwidth = bandwidth;
-	stream->udev = dev;
-	stream->bEndpointAddress = is_input | epnum;
-	stream->interval = interval;
-	stream->maxp = maxp;
-}
-
-static struct fotg210_iso_stream *iso_stream_find(struct fotg210_hcd *fotg210,
-						  struct urb *urb)
-{
-	unsigned epnum;
-	struct fotg210_iso_stream *stream;
-	struct usb_host_endpoint *ep;
-	unsigned long flags;
-
-	epnum = usb_pipeendpoint(urb->pipe);
-	if (usb_pipein(urb->pipe))
-		ep = urb->dev->ep_in[epnum];
-	else
-		ep = urb->dev->ep_out[epnum];
-
-	spin_lock_irqsave(&fotg210->lock, flags);
-	stream = ep->hcpriv;
-
-	if (unlikely(stream == NULL)) {
-		stream = iso_stream_alloc(GFP_ATOMIC);
-		if (likely(stream != NULL)) {
-			ep->hcpriv = stream;
-			stream->ep = ep;
-			iso_stream_init(fotg210, stream, urb->dev, urb->pipe,
-					urb->interval);
-		}
-
-	/* if dev->ep[epnum] is a QH, hw is set */
-	} else if (unlikely(stream->hw != NULL)) {
-		fotg210_dbg(fotg210, "dev %s ep%d%s, not iso??\n",
-			urb->dev->devpath, epnum,
-			usb_pipein(urb->pipe) ? "in" : "out");
-		stream = NULL;
-	}
-
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-	return stream;
-}
-
-/* fotg210_iso_sched ops can be ITD-only or SITD-only */
-
-static struct fotg210_iso_sched *iso_sched_alloc(unsigned packets,
-						 gfp_t mem_flags)
-{
-	struct fotg210_iso_sched *iso_sched;
-	int size = sizeof(*iso_sched);
-
-	size += packets * sizeof(struct fotg210_iso_packet);
-	iso_sched = kzalloc(size, mem_flags);
-	if (likely(iso_sched != NULL))
-		INIT_LIST_HEAD(&iso_sched->td_list);
-
-	return iso_sched;
-}
-
-static inline void itd_sched_init(struct fotg210_hcd *fotg210,
-				  struct fotg210_iso_sched *iso_sched,
-				  struct fotg210_iso_stream *stream,
-				  struct urb *urb)
-{
-	unsigned i;
-	dma_addr_t dma = urb->transfer_dma;
-
-	/* how many uframes are needed for these transfers */
-	iso_sched->span = urb->number_of_packets * stream->interval;
-
-	/* figure out per-uframe itd fields that we'll need later
-	 * when we fit new itds into the schedule.
-	 */
-	for (i = 0; i < urb->number_of_packets; i++) {
-		struct fotg210_iso_packet *uframe = &iso_sched->packet[i];
-		unsigned length;
-		dma_addr_t buf;
-		u32 trans;
-
-		length = urb->iso_frame_desc[i].length;
-		buf = dma + urb->iso_frame_desc[i].offset;
-
-		trans = FOTG210_ISOC_ACTIVE;
-		trans |= buf & 0x0fff;
-		if (unlikely(((i + 1) == urb->number_of_packets))
-				&& !(urb->transfer_flags & URB_NO_INTERRUPT))
-			trans |= FOTG210_ITD_IOC;
-		trans |= length << 16;
-		uframe->transaction = cpu_to_hc32(fotg210, trans);
-
-		/* might need to cross a buffer page within a uframe */
-		uframe->bufp = (buf & ~(u64)0x0fff);
-		buf += length;
-		if (unlikely((uframe->bufp != (buf & ~(u64)0x0fff))))
-			uframe->cross = 1;
-	}
-}
-
-static void iso_sched_free(struct fotg210_iso_stream *stream,
-			   struct fotg210_iso_sched *iso_sched)
-{
-	if (!iso_sched)
-		return;
-	/* caller must hold fotg210->lock!*/
-	list_splice(&iso_sched->td_list, &stream->free_list);
-	kfree(iso_sched);
-}
-
-static int itd_urb_transaction(struct fotg210_iso_stream *stream,
-			       struct fotg210_hcd *fotg210,
-			       struct urb *urb, gfp_t mem_flags)
-{
-	struct fotg210_itd *itd;
-	dma_addr_t itd_dma;
-	int i;
-	unsigned num_itds;
-	struct fotg210_iso_sched *sched;
-	unsigned long flags;
-
-	sched = iso_sched_alloc(urb->number_of_packets, mem_flags);
-	if (unlikely(sched == NULL))
-		return -ENOMEM;
-
-	itd_sched_init(fotg210, sched, stream, urb);
-
-	if (urb->interval < 8)
-		num_itds = 1 + (sched->span + 7) / 8;
-	else
-		num_itds = urb->number_of_packets;
-
-	/* allocate/init ITDs */
-	spin_lock_irqsave(&fotg210->lock, flags);
-	for (i = 0; i < num_itds; i++) {
-
-		/*
-		 * Use iTDs from the free list, but not iTDs that may
-		 * still be in use by the hardware.
-		 */
-		if (likely(!list_empty(&stream->free_list))) {
-			itd = list_first_entry(&stream->free_list,
-					struct fotg210_itd, itd_list);
-			if (itd->frame == fotg210->now_frame)
-				goto alloc_itd;
-			list_del(&itd->itd_list);
-			itd_dma = itd->itd_dma;
-		} else {
-alloc_itd:
-			spin_unlock_irqrestore(&fotg210->lock, flags);
-			itd = dma_pool_alloc(fotg210->itd_pool, mem_flags,
-					&itd_dma);
-			spin_lock_irqsave(&fotg210->lock, flags);
-			if (!itd) {
-				iso_sched_free(stream, sched);
-				spin_unlock_irqrestore(&fotg210->lock, flags);
-				return -ENOMEM;
-			}
-		}
-
-		memset(itd, 0, sizeof(*itd));
-		itd->itd_dma = itd_dma;
-		list_add(&itd->itd_list, &sched->td_list);
-	}
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-
-	/* temporarily store schedule info in hcpriv */
-	urb->hcpriv = sched;
-	urb->error_count = 0;
-	return 0;
-}
-
-static inline int itd_slot_ok(struct fotg210_hcd *fotg210, u32 mod, u32 uframe,
-			      u8 usecs, u32 period)
-{
-	uframe %= period;
-	do {
-		/* can't commit more than uframe_periodic_max usec */
-		if (periodic_usecs(fotg210, uframe >> 3, uframe & 0x7)
-				> (fotg210->uframe_periodic_max - usecs))
-			return 0;
-
-		/* we know urb->interval is 2^N uframes */
-		uframe += period;
-	} while (uframe < mod);
-	return 1;
-}
-
-/*
- * This scheduler plans almost as far into the future as it has actual
- * periodic schedule slots.  (Affected by TUNE_FLS, which defaults to
- * "as small as possible" to be cache-friendlier.)  That limits the size
- * transfers you can stream reliably; avoid more than 64 msec per urb.
- * Also avoid queue depths of less than fotg210's worst irq latency (affected
- * by the per-urb URB_NO_INTERRUPT hint, the log2_irq_thresh module parameter,
- * and other factors); or more than about 230 msec total (for portability,
- * given FOTG210_TUNE_FLS and the slop).  Or, write a smarter scheduler!
- */
-
-#define SCHEDULE_SLOP 80 /* microframes */
-
-static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
-			       struct fotg210_iso_stream *stream)
-{
-	u32 now, next, start, period, span;
-	int status;
-	unsigned mod = fotg210->periodic_size << 3;
-	struct fotg210_iso_sched *sched = urb->hcpriv;
-
-	period = urb->interval;
-	span = sched->span;
-
-	if (span > mod - SCHEDULE_SLOP) {
-		fotg210_dbg(fotg210, "iso request %p too long\n", urb);
-		status = -EFBIG;
-		goto fail;
-	}
-
-	now = fotg210_read_frame_index(fotg210) & (mod - 1);
-
-	/* Typical case: reuse current schedule, stream is still active.
-	 * Hopefully there are no gaps from the host falling behind
-	 * (irq delays etc), but if there are we'll take the next
-	 * slot in the schedule, implicitly assuming URB_ISO_ASAP.
-	 */
-	if (likely(!list_empty(&stream->td_list))) {
-		u32 excess;
-
-		/* For high speed devices, allow scheduling within the
-		 * isochronous scheduling threshold.  For full speed devices
-		 * and Intel PCI-based controllers, don't (work around for
-		 * Intel ICH9 bug).
-		 */
-		if (!stream->highspeed && fotg210->fs_i_thresh)
-			next = now + fotg210->i_thresh;
-		else
-			next = now;
-
-		/* Fell behind (by up to twice the slop amount)?
-		 * We decide based on the time of the last currently-scheduled
-		 * slot, not the time of the next available slot.
-		 */
-		excess = (stream->next_uframe - period - next) & (mod - 1);
-		if (excess >= mod - 2 * SCHEDULE_SLOP)
-			start = next + excess - mod + period *
-					DIV_ROUND_UP(mod - excess, period);
-		else
-			start = next + excess + period;
-		if (start - now >= mod) {
-			fotg210_dbg(fotg210, "request %p would overflow (%d+%d >= %d)\n",
-					urb, start - now - period, period,
-					mod);
-			status = -EFBIG;
-			goto fail;
-		}
-	}
-
-	/* need to schedule; when's the next (u)frame we could start?
-	 * this is bigger than fotg210->i_thresh allows; scheduling itself
-	 * isn't free, the slop should handle reasonably slow cpus.  it
-	 * can also help high bandwidth if the dma and irq loads don't
-	 * jump until after the queue is primed.
-	 */
-	else {
-		int done = 0;
-
-		start = SCHEDULE_SLOP + (now & ~0x07);
-
-		/* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */
-
-		/* find a uframe slot with enough bandwidth.
-		 * Early uframes are more precious because full-speed
-		 * iso IN transfers can't use late uframes,
-		 * and therefore they should be allocated last.
-		 */
-		next = start;
-		start += period;
-		do {
-			start--;
-			/* check schedule: enough space? */
-			if (itd_slot_ok(fotg210, mod, start,
-					stream->usecs, period))
-				done = 1;
-		} while (start > next && !done);
-
-		/* no room in the schedule */
-		if (!done) {
-			fotg210_dbg(fotg210, "iso resched full %p (now %d max %d)\n",
-				urb, now, now + mod);
-			status = -ENOSPC;
-			goto fail;
-		}
-	}
-
-	/* Tried to schedule too far into the future? */
-	if (unlikely(start - now + span - period
-				>= mod - 2 * SCHEDULE_SLOP)) {
-		fotg210_dbg(fotg210, "request %p would overflow (%d+%d >= %d)\n",
-				urb, start - now, span - period,
-				mod - 2 * SCHEDULE_SLOP);
-		status = -EFBIG;
-		goto fail;
-	}
-
-	stream->next_uframe = start & (mod - 1);
-
-	/* report high speed start in uframes; full speed, in frames */
-	urb->start_frame = stream->next_uframe;
-	if (!stream->highspeed)
-		urb->start_frame >>= 3;
-
-	/* Make sure scan_isoc() sees these */
-	if (fotg210->isoc_count == 0)
-		fotg210->next_frame = now >> 3;
-	return 0;
-
-fail:
-	iso_sched_free(stream, sched);
-	urb->hcpriv = NULL;
-	return status;
-}
-
-static inline void itd_init(struct fotg210_hcd *fotg210,
-			    struct fotg210_iso_stream *stream,
-			    struct fotg210_itd *itd)
-{
-	int i;
-
-	/* it's been recently zeroed */
-	itd->hw_next = FOTG210_LIST_END(fotg210);
-	itd->hw_bufp[0] = stream->buf0;
-	itd->hw_bufp[1] = stream->buf1;
-	itd->hw_bufp[2] = stream->buf2;
-
-	for (i = 0; i < 8; i++)
-		itd->index[i] = -1;
-
-	/* All other fields are filled when scheduling */
-}
-
-static inline void itd_patch(struct fotg210_hcd *fotg210,
-			     struct fotg210_itd *itd,
-			     struct fotg210_iso_sched *iso_sched,
-			     unsigned index, u16 uframe)
-{
-	struct fotg210_iso_packet *uf = &iso_sched->packet[index];
-	unsigned pg = itd->pg;
-
-	uframe &= 0x07;
-	itd->index[uframe] = index;
-
-	itd->hw_transaction[uframe] = uf->transaction;
-	itd->hw_transaction[uframe] |= cpu_to_hc32(fotg210, pg << 12);
-	itd->hw_bufp[pg] |= cpu_to_hc32(fotg210, uf->bufp & ~(u32)0);
-	itd->hw_bufp_hi[pg] |= cpu_to_hc32(fotg210, (u32)(uf->bufp >> 32));
-
-	/* iso_frame_desc[].offset must be strictly increasing */
-	if (unlikely(uf->cross)) {
-		u64 bufp = uf->bufp + 4096;
-
-		itd->pg = ++pg;
-		itd->hw_bufp[pg] |= cpu_to_hc32(fotg210, bufp & ~(u32)0);
-		itd->hw_bufp_hi[pg] |= cpu_to_hc32(fotg210, (u32)(bufp >> 32));
-	}
-}
-
-static inline void itd_link(struct fotg210_hcd *fotg210, unsigned frame,
-			    struct fotg210_itd *itd)
-{
-	union fotg210_shadow *prev = &fotg210->pshadow[frame];
-	__hc32 *hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow here = *prev;
-	__hc32 type = 0;
-
-	/* skip any iso nodes which might belong to previous microframes */
-	while (here.ptr) {
-		type = Q_NEXT_TYPE(fotg210, *hw_p);
-		if (type == cpu_to_hc32(fotg210, Q_TYPE_QH))
-			break;
-		prev = periodic_next_shadow(fotg210, prev, type);
-		hw_p = shadow_next_periodic(fotg210, &here, type);
-		here = *prev;
-	}
-
-	itd->itd_next = here;
-	itd->hw_next = *hw_p;
-	prev->itd = itd;
-	itd->frame = frame;
-	wmb();
-	*hw_p = cpu_to_hc32(fotg210, itd->itd_dma | Q_TYPE_ITD);
-}
-
-/* fit urb's itds into the selected schedule slot; activate as needed */
-static void itd_link_urb(struct fotg210_hcd *fotg210, struct urb *urb,
-			 unsigned mod, struct fotg210_iso_stream *stream)
-{
-	int packet;
-	unsigned next_uframe, uframe, frame;
-	struct fotg210_iso_sched *iso_sched = urb->hcpriv;
-	struct fotg210_itd *itd;
-
-	next_uframe = stream->next_uframe & (mod - 1);
-
-	if (unlikely(list_empty(&stream->td_list))) {
-		fotg210_to_hcd(fotg210)->self.bandwidth_allocated
-				+= stream->bandwidth;
-		fotg210_dbg(fotg210,
-			"schedule devp %s ep%d%s-iso period %d start %d.%d\n",
-			urb->dev->devpath, stream->bEndpointAddress & 0x0f,
-			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
-			urb->interval,
-			next_uframe >> 3, next_uframe & 0x7);
-	}
-
-	/* fill iTDs uframe by uframe */
-	for (packet = 0, itd = NULL; packet < urb->number_of_packets;) {
-		if (itd == NULL) {
-			/* ASSERT:  we have all necessary itds */
-
-			/* ASSERT:  no itds for this endpoint in this uframe */
-
-			itd = list_entry(iso_sched->td_list.next,
-					struct fotg210_itd, itd_list);
-			list_move_tail(&itd->itd_list, &stream->td_list);
-			itd->stream = stream;
-			itd->urb = urb;
-			itd_init(fotg210, stream, itd);
-		}
-
-		uframe = next_uframe & 0x07;
-		frame = next_uframe >> 3;
-
-		itd_patch(fotg210, itd, iso_sched, packet, uframe);
-
-		next_uframe += stream->interval;
-		next_uframe &= mod - 1;
-		packet++;
-
-		/* link completed itds into the schedule */
-		if (((next_uframe >> 3) != frame)
-				|| packet == urb->number_of_packets) {
-			itd_link(fotg210, frame & (fotg210->periodic_size - 1),
-				 itd);
-			itd = NULL;
-		}
-	}
-	stream->next_uframe = next_uframe;
-
-	/* don't need that schedule data any more */
-	iso_sched_free(stream, iso_sched);
-	urb->hcpriv = NULL;
-
-	++fotg210->isoc_count;
-	enable_periodic(fotg210);
-}
-
-#define ISO_ERRS (FOTG210_ISOC_BUF_ERR | FOTG210_ISOC_BABBLE |\
-		  FOTG210_ISOC_XACTERR)
-
-/* Process and recycle a completed ITD.  Return true iff its urb completed,
- * and hence its completion callback probably added things to the hardware
- * schedule.
- *
- * Note that we carefully avoid recycling this descriptor until after any
- * completion callback runs, so that it won't be reused quickly.  That is,
- * assuming (a) no more than two urbs per frame on this endpoint, and also
- * (b) only this endpoint's completions submit URBs.  It seems some silicon
- * corrupts things if you reuse completed descriptors very quickly...
- */
-static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
-{
-	struct urb *urb = itd->urb;
-	struct usb_iso_packet_descriptor *desc;
-	u32 t;
-	unsigned uframe;
-	int urb_index = -1;
-	struct fotg210_iso_stream *stream = itd->stream;
-	struct usb_device *dev;
-	bool retval = false;
-
-	/* for each uframe with a packet */
-	for (uframe = 0; uframe < 8; uframe++) {
-		if (likely(itd->index[uframe] == -1))
-			continue;
-		urb_index = itd->index[uframe];
-		desc = &urb->iso_frame_desc[urb_index];
-
-		t = hc32_to_cpup(fotg210, &itd->hw_transaction[uframe]);
-		itd->hw_transaction[uframe] = 0;
-
-		/* report transfer status */
-		if (unlikely(t & ISO_ERRS)) {
-			urb->error_count++;
-			if (t & FOTG210_ISOC_BUF_ERR)
-				desc->status = usb_pipein(urb->pipe)
-					? -ENOSR  /* hc couldn't read */
-					: -ECOMM; /* hc couldn't write */
-			else if (t & FOTG210_ISOC_BABBLE)
-				desc->status = -EOVERFLOW;
-			else /* (t & FOTG210_ISOC_XACTERR) */
-				desc->status = -EPROTO;
-
-			/* HC need not update length with this error */
-			if (!(t & FOTG210_ISOC_BABBLE)) {
-				desc->actual_length =
-					fotg210_itdlen(urb, desc, t);
-				urb->actual_length += desc->actual_length;
-			}
-		} else if (likely((t & FOTG210_ISOC_ACTIVE) == 0)) {
-			desc->status = 0;
-			desc->actual_length = fotg210_itdlen(urb, desc, t);
-			urb->actual_length += desc->actual_length;
-		} else {
-			/* URB was too late */
-			desc->status = -EXDEV;
-		}
-	}
-
-	/* handle completion now? */
-	if (likely((urb_index + 1) != urb->number_of_packets))
-		goto done;
-
-	/* ASSERT: it's really the last itd for this urb
-	 * list_for_each_entry (itd, &stream->td_list, itd_list)
-	 *	BUG_ON (itd->urb == urb);
-	 */
-
-	/* give urb back to the driver; completion often (re)submits */
-	dev = urb->dev;
-	fotg210_urb_done(fotg210, urb, 0);
-	retval = true;
-	urb = NULL;
-
-	--fotg210->isoc_count;
-	disable_periodic(fotg210);
-
-	if (unlikely(list_is_singular(&stream->td_list))) {
-		fotg210_to_hcd(fotg210)->self.bandwidth_allocated
-				-= stream->bandwidth;
-		fotg210_dbg(fotg210,
-			"deschedule devp %s ep%d%s-iso\n",
-			dev->devpath, stream->bEndpointAddress & 0x0f,
-			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
-	}
-
-done:
-	itd->urb = NULL;
-
-	/* Add to the end of the free list for later reuse */
-	list_move_tail(&itd->itd_list, &stream->free_list);
-
-	/* Recycle the iTDs when the pipeline is empty (ep no longer in use) */
-	if (list_empty(&stream->td_list)) {
-		list_splice_tail_init(&stream->free_list,
-				&fotg210->cached_itd_list);
-		start_free_itds(fotg210);
-	}
-
-	return retval;
-}
-
-static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
-		      gfp_t mem_flags)
-{
-	int status = -EINVAL;
-	unsigned long flags;
-	struct fotg210_iso_stream *stream;
-
-	/* Get iso_stream head */
-	stream = iso_stream_find(fotg210, urb);
-	if (unlikely(stream == NULL)) {
-		fotg210_dbg(fotg210, "can't get iso stream\n");
-		return -ENOMEM;
-	}
-	if (unlikely(urb->interval != stream->interval &&
-	    fotg210_port_speed(fotg210, 0) == USB_PORT_STAT_HIGH_SPEED)) {
-		fotg210_dbg(fotg210, "can't change iso interval %d --> %d\n",
-			    stream->interval, urb->interval);
-		goto done;
-	}
-
-#ifdef FOTG210_URB_TRACE
-	fotg210_dbg(fotg210,
-		"%s %s urb %p ep%d%s len %d, %d pkts %d uframes[%p]\n",
-		__func__, urb->dev->devpath, urb,
-		usb_pipeendpoint(urb->pipe),
-		usb_pipein(urb->pipe) ? "in" : "out",
-		urb->transfer_buffer_length,
-		urb->number_of_packets, urb->interval,
-		stream);
-#endif
-
-	/* allocate ITDs w/o locking anything */
-	status = itd_urb_transaction(stream, fotg210, urb, mem_flags);
-	if (unlikely(status < 0)) {
-		fotg210_dbg(fotg210, "can't init itds\n");
-		goto done;
-	}
-
-	/* schedule ... need to lock */
-	spin_lock_irqsave(&fotg210->lock, flags);
-	if (unlikely(!HCD_HW_ACCESSIBLE(fotg210_to_hcd(fotg210)))) {
-		status = -ESHUTDOWN;
-		goto done_not_linked;
-	}
-	status = usb_hcd_link_urb_to_ep(fotg210_to_hcd(fotg210), urb);
-	if (unlikely(status))
-		goto done_not_linked;
-	status = iso_stream_schedule(fotg210, urb, stream);
-	if (likely(status == 0))
-		itd_link_urb(fotg210, urb, fotg210->periodic_size << 3, stream);
-	else
-		usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
-done_not_linked:
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-done:
-	return status;
-}
-
-static inline int scan_frame_queue(struct fotg210_hcd *fotg210, unsigned frame,
-				   unsigned now_frame, bool live)
-{
-	unsigned uf;
-	bool modified;
-	union fotg210_shadow q, *q_p;
-	__hc32 type, *hw_p;
-
-	/* scan each element in frame's queue for completions */
-	q_p = &fotg210->pshadow[frame];
-	hw_p = &fotg210->periodic[frame];
-	q.ptr = q_p->ptr;
-	type = Q_NEXT_TYPE(fotg210, *hw_p);
-	modified = false;
-
-	while (q.ptr != NULL) {
-		switch (hc32_to_cpu(fotg210, type)) {
-		case Q_TYPE_ITD:
-			/* If this ITD is still active, leave it for
-			 * later processing ... check the next entry.
-			 * No need to check for activity unless the
-			 * frame is current.
-			 */
-			if (frame == now_frame && live) {
-				rmb();
-				for (uf = 0; uf < 8; uf++) {
-					if (q.itd->hw_transaction[uf] &
-						    ITD_ACTIVE(fotg210))
-						break;
-				}
-				if (uf < 8) {
-					q_p = &q.itd->itd_next;
-					hw_p = &q.itd->hw_next;
-					type = Q_NEXT_TYPE(fotg210,
-						q.itd->hw_next);
-					q = *q_p;
-					break;
-				}
-			}
-
-			/* Take finished ITDs out of the schedule
-			 * and process them:  recycle, maybe report
-			 * URB completion.  HC won't cache the
-			 * pointer for much longer, if at all.
-			 */
-			*q_p = q.itd->itd_next;
-			*hw_p = q.itd->hw_next;
-			type = Q_NEXT_TYPE(fotg210, q.itd->hw_next);
-			wmb();
-			modified = itd_complete(fotg210, q.itd);
-			q = *q_p;
-			break;
-		default:
-			fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
-				type, frame, q.ptr);
-			/* FALL THROUGH */
-		case Q_TYPE_QH:
-		case Q_TYPE_FSTN:
-			/* End of the iTDs and siTDs */
-			q.ptr = NULL;
-			break;
-		}
-
-		/* assume completion callbacks modify the queue */
-		if (unlikely(modified && fotg210->isoc_count > 0))
-			return -1;
-	}
-	return 0;
-}
-
-static void scan_isoc(struct fotg210_hcd *fotg210)
-{
-	unsigned uf, now_frame, frame, ret;
-	unsigned fmask = fotg210->periodic_size - 1;
-	bool live;
-
-	/*
-	 * When running, scan from last scan point up to "now"
-	 * else clean up by scanning everything that's left.
-	 * Touches as few pages as possible:  cache-friendly.
-	 */
-	if (fotg210->rh_state >= FOTG210_RH_RUNNING) {
-		uf = fotg210_read_frame_index(fotg210);
-		now_frame = (uf >> 3) & fmask;
-		live = true;
-	} else  {
-		now_frame = (fotg210->next_frame - 1) & fmask;
-		live = false;
-	}
-	fotg210->now_frame = now_frame;
-
-	frame = fotg210->next_frame;
-	for (;;) {
-
-		ret = 1;
-		while (ret != 0)
-			ret = scan_frame_queue(fotg210, frame, now_frame,
-					       live);
-
-		/* Stop when we have reached the current frame */
-		if (frame == now_frame)
-			break;
-		frame = (frame + 1) & fmask;
-	}
-	fotg210->next_frame = now_frame;
-}
-
-/*
- * Display / Set uframe_periodic_max
- */
-static ssize_t show_uframe_periodic_max(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
-{
-	struct fotg210_hcd *fotg210;
-	int n;
-
-	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
-	n = scnprintf(buf, PAGE_SIZE, "%d\n", fotg210->uframe_periodic_max);
-	return n;
-}
-
-
-static ssize_t store_uframe_periodic_max(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf, size_t count)
-{
-	struct fotg210_hcd *fotg210;
-	unsigned uframe_periodic_max;
-	unsigned frame, uframe;
-	unsigned short allocated_max;
-	unsigned long flags;
-	ssize_t ret;
-
-	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
-	if (kstrtouint(buf, 0, &uframe_periodic_max) < 0)
-		return -EINVAL;
-
-	if (uframe_periodic_max < 100 || uframe_periodic_max >= 125) {
-		fotg210_info(fotg210, "rejecting invalid request for uframe_periodic_max=%u\n",
-			     uframe_periodic_max);
-		return -EINVAL;
-	}
-
-	ret = -EINVAL;
-
-	/*
-	 * lock, so that our checking does not race with possible periodic
-	 * bandwidth allocation through submitting new urbs.
-	 */
-	spin_lock_irqsave(&fotg210->lock, flags);
-
-	/*
-	 * for request to decrease max periodic bandwidth, we have to check
-	 * every microframe in the schedule to see whether the decrease is
-	 * possible.
-	 */
-	if (uframe_periodic_max < fotg210->uframe_periodic_max) {
-		allocated_max = 0;
-
-		for (frame = 0; frame < fotg210->periodic_size; ++frame)
-			for (uframe = 0; uframe < 7; ++uframe)
-				allocated_max = max(allocated_max,
-						    periodic_usecs(fotg210,
-								   frame,
-								   uframe));
-
-		if (allocated_max > uframe_periodic_max) {
-			fotg210_info(fotg210,
-				"cannot decrease uframe_periodic_max because periodic bandwidth is already allocated (%u > %u)\n",
-				allocated_max, uframe_periodic_max);
-			goto out_unlock;
-		}
-	}
-
-	/* increasing is always ok */
-
-	fotg210_info(fotg210, "setting max periodic bandwidth to %u%% (== %u usec/uframe)\n",
-		     100 * uframe_periodic_max/125, uframe_periodic_max);
-
-	if (uframe_periodic_max != 100)
-		fotg210_warn(fotg210, "max periodic bandwidth set is non-standard\n");
-
-	fotg210->uframe_periodic_max = uframe_periodic_max;
-	ret = count;
-
-out_unlock:
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-	return ret;
-}
-
-static DEVICE_ATTR(uframe_periodic_max, 0644, show_uframe_periodic_max,
-		   store_uframe_periodic_max);
-
-static inline int create_sysfs_files(struct fotg210_hcd *fotg210)
-{
-	struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
-	int i = 0;
-
-	if (i)
-		goto out;
-
-	i = device_create_file(controller, &dev_attr_uframe_periodic_max);
-out:
-	return i;
-}
-
-static inline void remove_sysfs_files(struct fotg210_hcd *fotg210)
-{
-	struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
-
-	device_remove_file(controller, &dev_attr_uframe_periodic_max);
-}
-/* On some systems, leaving remote wakeup enabled prevents system shutdown.
- * The firmware seems to think that powering off is a wakeup event!
- * This routine turns off remote wakeup and everything else, on all ports.
- */
-static void fotg210_turn_off_all_ports(struct fotg210_hcd *fotg210)
-{
-	u32 __iomem *status_reg = &fotg210->regs->port_status;
-
-	fotg210_writel(fotg210, PORT_RWC_BITS, status_reg);
-}
-
-/*
- * Halt HC, turn off all ports, and let the BIOS use the companion controllers.
- * Must be called with interrupts enabled and the lock not held.
- */
-static void fotg210_silence_controller(struct fotg210_hcd *fotg210)
-{
-	fotg210_halt(fotg210);
-
-	spin_lock_irq(&fotg210->lock);
-	fotg210->rh_state = FOTG210_RH_HALTED;
-	fotg210_turn_off_all_ports(fotg210);
-	spin_unlock_irq(&fotg210->lock);
-}
-
-/* fotg210_shutdown kick in for silicon on any bus (not just pci, etc).
- * This forcibly disables dma and IRQs, helping kexec and other cases
- * where the next system software may expect clean state.
- */
-static void fotg210_shutdown(struct usb_hcd *hcd)
-{
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-
-	spin_lock_irq(&fotg210->lock);
-	fotg210->shutdown = true;
-	fotg210->rh_state = FOTG210_RH_STOPPING;
-	fotg210->enabled_hrtimer_events = 0;
-	spin_unlock_irq(&fotg210->lock);
-
-	fotg210_silence_controller(fotg210);
-
-	hrtimer_cancel(&fotg210->hrtimer);
-}
-
-/*
- * fotg210_work is called from some interrupts, timers, and so on.
- * it calls driver completion functions, after dropping fotg210->lock.
- */
-static void fotg210_work(struct fotg210_hcd *fotg210)
-{
-	/* another CPU may drop fotg210->lock during a schedule scan while
-	 * it reports urb completions.  this flag guards against bogus
-	 * attempts at re-entrant schedule scanning.
-	 */
-	if (fotg210->scanning) {
-		fotg210->need_rescan = true;
-		return;
-	}
-	fotg210->scanning = true;
-
-rescan:
-	fotg210->need_rescan = false;
-	if (fotg210->async_count)
-		scan_async(fotg210);
-	if (fotg210->intr_count > 0)
-		scan_intr(fotg210);
-	if (fotg210->isoc_count > 0)
-		scan_isoc(fotg210);
-	if (fotg210->need_rescan)
-		goto rescan;
-	fotg210->scanning = false;
-
-	/* the IO watchdog guards against hardware or driver bugs that
-	 * misplace IRQs, and should let us run completely without IRQs.
-	 * such lossage has been observed on both VT6202 and VT8235.
-	 */
-	turn_on_io_watchdog(fotg210);
-}
-
-/*
- * Called when the fotg210_hcd module is removed.
- */
-static void fotg210_stop(struct usb_hcd *hcd)
-{
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-
-	fotg210_dbg(fotg210, "stop\n");
-
-	/* no more interrupts ... */
-
-	spin_lock_irq(&fotg210->lock);
-	fotg210->enabled_hrtimer_events = 0;
-	spin_unlock_irq(&fotg210->lock);
-
-	fotg210_quiesce(fotg210);
-	fotg210_silence_controller(fotg210);
-	fotg210_reset(fotg210);
-
-	hrtimer_cancel(&fotg210->hrtimer);
-	remove_sysfs_files(fotg210);
-	remove_debug_files(fotg210);
-
-	/* root hub is shut down separately (first, when possible) */
-	spin_lock_irq(&fotg210->lock);
-	end_free_itds(fotg210);
-	spin_unlock_irq(&fotg210->lock);
-	fotg210_mem_cleanup(fotg210);
-
-#ifdef FOTG210_STATS
-	fotg210_dbg(fotg210, "irq normal %ld err %ld iaa %ld (lost %ld)\n",
-		fotg210->stats.normal, fotg210->stats.error, fotg210->stats.iaa,
-		fotg210->stats.lost_iaa);
-	fotg210_dbg(fotg210, "complete %ld unlink %ld\n",
-		fotg210->stats.complete, fotg210->stats.unlink);
-#endif
-
-	dbg_status(fotg210, "fotg210_stop completed",
-		    fotg210_readl(fotg210, &fotg210->regs->status));
-}
-
-/* one-time init, only for memory state */
-static int hcd_fotg210_init(struct usb_hcd *hcd)
-{
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-	u32 temp;
-	int retval;
-	u32 hcc_params;
-	struct fotg210_qh_hw *hw;
-
-	spin_lock_init(&fotg210->lock);
-
-	/*
-	 * keep io watchdog by default, those good HCDs could turn off it later
-	 */
-	fotg210->need_io_watchdog = 1;
-
-	hrtimer_init(&fotg210->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
-	fotg210->hrtimer.function = fotg210_hrtimer_func;
-	fotg210->next_hrtimer_event = FOTG210_HRTIMER_NO_EVENT;
-
-	hcc_params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
-
-	/*
-	 * by default set standard 80% (== 100 usec/uframe) max periodic
-	 * bandwidth as required by USB 2.0
-	 */
-	fotg210->uframe_periodic_max = 100;
-
-	/*
-	 * hw default: 1K periodic list heads, one per frame.
-	 * periodic_size can shrink by USBCMD update if hcc_params allows.
-	 */
-	fotg210->periodic_size = DEFAULT_I_TDPS;
-	INIT_LIST_HEAD(&fotg210->intr_qh_list);
-	INIT_LIST_HEAD(&fotg210->cached_itd_list);
-
-	if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
-		/* periodic schedule size can be smaller than default */
-		switch (FOTG210_TUNE_FLS) {
-		case 0:
-			fotg210->periodic_size = 1024;
-			break;
-		case 1:
-			fotg210->periodic_size = 512;
-			break;
-		case 2:
-			fotg210->periodic_size = 256;
-			break;
-		default:
-			BUG();
-		}
-	}
-	retval = fotg210_mem_init(fotg210, GFP_KERNEL);
-	if (retval < 0)
-		return retval;
-
-	/* controllers may cache some of the periodic schedule ... */
-	fotg210->i_thresh = 2;
-
-	/*
-	 * dedicate a qh for the async ring head, since we couldn't unlink
-	 * a 'real' qh without stopping the async schedule [4.8].  use it
-	 * as the 'reclamation list head' too.
-	 * its dummy is used in hw_alt_next of many tds, to prevent the qh
-	 * from automatically advancing to the next td after short reads.
-	 */
-	fotg210->async->qh_next.qh = NULL;
-	hw = fotg210->async->hw;
-	hw->hw_next = QH_NEXT(fotg210, fotg210->async->qh_dma);
-	hw->hw_info1 = cpu_to_hc32(fotg210, QH_HEAD);
-	hw->hw_token = cpu_to_hc32(fotg210, QTD_STS_HALT);
-	hw->hw_qtd_next = FOTG210_LIST_END(fotg210);
-	fotg210->async->qh_state = QH_STATE_LINKED;
-	hw->hw_alt_next = QTD_NEXT(fotg210, fotg210->async->dummy->qtd_dma);
-
-	/* clear interrupt enables, set irq latency */
-	if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
-		log2_irq_thresh = 0;
-	temp = 1 << (16 + log2_irq_thresh);
-	if (HCC_CANPARK(hcc_params)) {
-		/* HW default park == 3, on hardware that supports it (like
-		 * NVidia and ALI silicon), maximizes throughput on the async
-		 * schedule by avoiding QH fetches between transfers.
-		 *
-		 * With fast usb storage devices and NForce2, "park" seems to
-		 * make problems:  throughput reduction (!), data errors...
-		 */
-		if (park) {
-			park = min_t(unsigned, park, 3);
-			temp |= CMD_PARK;
-			temp |= park << 8;
-		}
-		fotg210_dbg(fotg210, "park %d\n", park);
-	}
-	if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
-		/* periodic schedule size can be smaller than default */
-		temp &= ~(3 << 2);
-		temp |= (FOTG210_TUNE_FLS << 2);
-	}
-	fotg210->command = temp;
-
-	/* Accept arbitrarily long scatter-gather lists */
-	if (!(hcd->driver->flags & HCD_LOCAL_MEM))
-		hcd->self.sg_tablesize = ~0;
-	return 0;
-}
-
-/* start HC running; it's halted, hcd_fotg210_init() has been run (once) */
-static int fotg210_run(struct usb_hcd *hcd)
-{
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-	u32 temp;
-	u32 hcc_params;
-
-	hcd->uses_new_polling = 1;
-
-	/* EHCI spec section 4.1 */
-
-	fotg210_writel(fotg210, fotg210->periodic_dma,
-		       &fotg210->regs->frame_list);
-	fotg210_writel(fotg210, (u32)fotg210->async->qh_dma,
-		       &fotg210->regs->async_next);
-
-	/*
-	 * hcc_params controls whether fotg210->regs->segment must (!!!)
-	 * be used; it constrains QH/ITD/SITD and QTD locations.
-	 * pci_pool consistent memory always uses segment zero.
-	 * streaming mappings for I/O buffers, like pci_map_single(),
-	 * can return segments above 4GB, if the device allows.
-	 *
-	 * NOTE:  the dma mask is visible through dma_supported(), so
-	 * drivers can pass this info along ... like NETIF_F_HIGHDMA,
-	 * Scsi_Host.highmem_io, and so forth.  It's readonly to all
-	 * host side drivers though.
-	 */
-	hcc_params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
-
-	/*
-	 * Philips, Intel, and maybe others need CMD_RUN before the
-	 * root hub will detect new devices (why?); NEC doesn't
-	 */
-	fotg210->command &= ~(CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
-	fotg210->command |= CMD_RUN;
-	fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
-	dbg_cmd(fotg210, "init", fotg210->command);
-
-	/*
-	 * Start, enabling full USB 2.0 functionality ... usb 1.1 devices
-	 * are explicitly handed to companion controller(s), so no TT is
-	 * involved with the root hub.  (Except where one is integrated,
-	 * and there's no companion controller unless maybe for USB OTG.)
-	 *
-	 * Turning on the CF flag will transfer ownership of all ports
-	 * from the companions to the EHCI controller.  If any of the
-	 * companions are in the middle of a port reset at the time, it
-	 * could cause trouble.  Write-locking ehci_cf_port_reset_rwsem
-	 * guarantees that no resets are in progress.  After we set CF,
-	 * a short delay lets the hardware catch up; new resets shouldn't
-	 * be started before the port switching actions could complete.
-	 */
-	down_write(&ehci_cf_port_reset_rwsem);
-	fotg210->rh_state = FOTG210_RH_RUNNING;
-	/* unblock posted writes */
-	fotg210_readl(fotg210, &fotg210->regs->command);
-	usleep_range(5000, 6000);
-	up_write(&ehci_cf_port_reset_rwsem);
-	fotg210->last_periodic_enable = ktime_get_real();
-
-	temp = HC_VERSION(fotg210,
-			  fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
-	fotg210_info(fotg210,
-		"USB %x.%x started, EHCI %x.%02x\n",
-		((fotg210->sbrn & 0xf0)>>4), (fotg210->sbrn & 0x0f),
-		temp >> 8, temp & 0xff);
-
-	fotg210_writel(fotg210, INTR_MASK,
-		    &fotg210->regs->intr_enable); /* Turn On Interrupts */
-
-	/* GRR this is run-once init(), being done every time the HC starts.
-	 * So long as they're part of class devices, we can't do it init()
-	 * since the class device isn't created that early.
-	 */
-	create_debug_files(fotg210);
-	create_sysfs_files(fotg210);
-
-	return 0;
-}
-
-static int fotg210_setup(struct usb_hcd *hcd)
-{
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-	int retval;
-
-	fotg210->regs = (void __iomem *)fotg210->caps +
-	    HC_LENGTH(fotg210,
-		      fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
-	dbg_hcs_params(fotg210, "reset");
-	dbg_hcc_params(fotg210, "reset");
-
-	/* cache this readonly data; minimize chip reads */
-	fotg210->hcs_params = fotg210_readl(fotg210,
-					    &fotg210->caps->hcs_params);
-
-	fotg210->sbrn = HCD_USB2;
-
-	/* data structure init */
-	retval = hcd_fotg210_init(hcd);
-	if (retval)
-		return retval;
-
-	retval = fotg210_halt(fotg210);
-	if (retval)
-		return retval;
-
-	fotg210_reset(fotg210);
-
-	return 0;
-}
-
-static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
-{
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-	u32 status, masked_status, pcd_status = 0, cmd;
-	int bh;
-
-	spin_lock(&fotg210->lock);
-
-	status = fotg210_readl(fotg210, &fotg210->regs->status);
-
-	/* e.g. cardbus physical eject */
-	if (status == ~(u32) 0) {
-		fotg210_dbg(fotg210, "device removed\n");
-		goto dead;
-	}
-
-	/*
-	 * We don't use STS_FLR, but some controllers don't like it to
-	 * remain on, so mask it out along with the other status bits.
-	 */
-	masked_status = status & (INTR_MASK | STS_FLR);
-
-	/* Shared IRQ? */
-	if (!masked_status ||
-	    unlikely(fotg210->rh_state == FOTG210_RH_HALTED)) {
-		spin_unlock(&fotg210->lock);
-		return IRQ_NONE;
-	}
-
-	/* clear (just) interrupts */
-	fotg210_writel(fotg210, masked_status, &fotg210->regs->status);
-	cmd = fotg210_readl(fotg210, &fotg210->regs->command);
-	bh = 0;
-
-	/* unrequested/ignored: Frame List Rollover */
-	dbg_status(fotg210, "irq", status);
-
-	/* INT, ERR, and IAA interrupt rates can be throttled */
-
-	/* normal [4.15.1.2] or error [4.15.1.1] completion */
-	if (likely((status & (STS_INT|STS_ERR)) != 0)) {
-		if (likely((status & STS_ERR) == 0))
-			COUNT(fotg210->stats.normal);
-		else
-			COUNT(fotg210->stats.error);
-		bh = 1;
-	}
-
-	/* complete the unlinking of some qh [4.15.2.3] */
-	if (status & STS_IAA) {
-
-		/* Turn off the IAA watchdog */
-		fotg210->enabled_hrtimer_events &=
-			~BIT(FOTG210_HRTIMER_IAA_WATCHDOG);
-
-		/*
-		 * Mild optimization: Allow another IAAD to reset the
-		 * hrtimer, if one occurs before the next expiration.
-		 * In theory we could always cancel the hrtimer, but
-		 * tests show that about half the time it will be reset
-		 * for some other event anyway.
-		 */
-		if (fotg210->next_hrtimer_event == FOTG210_HRTIMER_IAA_WATCHDOG)
-			++fotg210->next_hrtimer_event;
-
-		/* guard against (alleged) silicon errata */
-		if (cmd & CMD_IAAD)
-			fotg210_dbg(fotg210, "IAA with IAAD still set?\n");
-		if (fotg210->async_iaa) {
-			COUNT(fotg210->stats.iaa);
-			end_unlink_async(fotg210);
-		} else
-			fotg210_dbg(fotg210, "IAA with nothing unlinked?\n");
-	}
-
-	/* remote wakeup [4.3.1] */
-	if (status & STS_PCD) {
-		int pstatus;
-		u32 __iomem *status_reg = &fotg210->regs->port_status;
-
-		/* kick root hub later */
-		pcd_status = status;
-
-		/* resume root hub? */
-		if (fotg210->rh_state == FOTG210_RH_SUSPENDED)
-			usb_hcd_resume_root_hub(hcd);
-
-		pstatus = fotg210_readl(fotg210, status_reg);
-
-		if (test_bit(0, &fotg210->suspended_ports) &&
-				((pstatus & PORT_RESUME) ||
-					!(pstatus & PORT_SUSPEND)) &&
-				(pstatus & PORT_PE) &&
-				fotg210->reset_done[0] == 0) {
-
-			/* start 20 msec resume signaling from this port,
-			 * and make hub_wq collect PORT_STAT_C_SUSPEND to
-			 * stop that signaling.  Use 5 ms extra for safety,
-			 * like usb_port_resume() does.
-			 */
-			fotg210->reset_done[0] = jiffies + msecs_to_jiffies(25);
-			set_bit(0, &fotg210->resuming_ports);
-			fotg210_dbg(fotg210, "port 1 remote wakeup\n");
-			mod_timer(&hcd->rh_timer, fotg210->reset_done[0]);
-		}
-	}
-
-	/* PCI errors [4.15.2.4] */
-	if (unlikely((status & STS_FATAL) != 0)) {
-		fotg210_err(fotg210, "fatal error\n");
-		dbg_cmd(fotg210, "fatal", cmd);
-		dbg_status(fotg210, "fatal", status);
-dead:
-		usb_hc_died(hcd);
-
-		/* Don't let the controller do anything more */
-		fotg210->shutdown = true;
-		fotg210->rh_state = FOTG210_RH_STOPPING;
-		fotg210->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
-		fotg210_writel(fotg210, fotg210->command,
-			       &fotg210->regs->command);
-		fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
-		fotg210_handle_controller_death(fotg210);
-
-		/* Handle completions when the controller stops */
-		bh = 0;
-	}
-
-	if (bh)
-		fotg210_work(fotg210);
-	spin_unlock(&fotg210->lock);
-	if (pcd_status)
-		usb_hcd_poll_rh_status(hcd);
-	return IRQ_HANDLED;
-}
-
-/*
- * non-error returns are a promise to giveback() the urb later
- * we drop ownership so next owner (or urb unlink) can get it
- *
- * urb + dev is in hcd.self.controller.urb_list
- * we're queueing TDs onto software and hardware lists
- *
- * hcd-specific init for hcpriv hasn't been done yet
- *
- * NOTE:  control, bulk, and interrupt share the same code to append TDs
- * to a (possibly active) QH, and the same QH scanning code.
- */
-static int fotg210_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
-			       gfp_t mem_flags)
-{
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-	struct list_head qtd_list;
-
-	INIT_LIST_HEAD(&qtd_list);
-
-	switch (usb_pipetype(urb->pipe)) {
-	case PIPE_CONTROL:
-		/* qh_completions() code doesn't handle all the fault cases
-		 * in multi-TD control transfers.  Even 1KB is rare anyway.
-		 */
-		if (urb->transfer_buffer_length > (16 * 1024))
-			return -EMSGSIZE;
-		/* FALLTHROUGH */
-	/* case PIPE_BULK: */
-	default:
-		if (!qh_urb_transaction(fotg210, urb, &qtd_list, mem_flags))
-			return -ENOMEM;
-		return submit_async(fotg210, urb, &qtd_list, mem_flags);
-
-	case PIPE_INTERRUPT:
-		if (!qh_urb_transaction(fotg210, urb, &qtd_list, mem_flags))
-			return -ENOMEM;
-		return intr_submit(fotg210, urb, &qtd_list, mem_flags);
-
-	case PIPE_ISOCHRONOUS:
-		return itd_submit(fotg210, urb, mem_flags);
-	}
-}
-
-/* remove from hardware lists
- * completions normally happen asynchronously
- */
-
-static int fotg210_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
-{
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh *qh;
-	unsigned long flags;
-	int rc;
-
-	spin_lock_irqsave(&fotg210->lock, flags);
-	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
-	if (rc)
-		goto done;
-
-	switch (usb_pipetype(urb->pipe)) {
-	/* case PIPE_CONTROL: */
-	/* case PIPE_BULK:*/
-	default:
-		qh = (struct fotg210_qh *) urb->hcpriv;
-		if (!qh)
-			break;
-		switch (qh->qh_state) {
-		case QH_STATE_LINKED:
-		case QH_STATE_COMPLETING:
-			start_unlink_async(fotg210, qh);
-			break;
-		case QH_STATE_UNLINK:
-		case QH_STATE_UNLINK_WAIT:
-			/* already started */
-			break;
-		case QH_STATE_IDLE:
-			/* QH might be waiting for a Clear-TT-Buffer */
-			qh_completions(fotg210, qh);
-			break;
-		}
-		break;
-
-	case PIPE_INTERRUPT:
-		qh = (struct fotg210_qh *) urb->hcpriv;
-		if (!qh)
-			break;
-		switch (qh->qh_state) {
-		case QH_STATE_LINKED:
-		case QH_STATE_COMPLETING:
-			start_unlink_intr(fotg210, qh);
-			break;
-		case QH_STATE_IDLE:
-			qh_completions(fotg210, qh);
-			break;
-		default:
-			fotg210_dbg(fotg210, "bogus qh %p state %d\n",
-					qh, qh->qh_state);
-			goto done;
-		}
-		break;
-
-	case PIPE_ISOCHRONOUS:
-		/* itd... */
-
-		/* wait till next completion, do it then. */
-		/* completion irqs can wait up to 1024 msec, */
-		break;
-	}
-done:
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-	return rc;
-}
-
-/* bulk qh holds the data toggle */
-
-static void fotg210_endpoint_disable(struct usb_hcd *hcd,
-				     struct usb_host_endpoint *ep)
-{
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-	unsigned long flags;
-	struct fotg210_qh *qh, *tmp;
-
-	/* ASSERT:  any requests/urbs are being unlinked */
-	/* ASSERT:  nobody can be submitting urbs for this any more */
-
-rescan:
-	spin_lock_irqsave(&fotg210->lock, flags);
-	qh = ep->hcpriv;
-	if (!qh)
-		goto done;
-
-	/* endpoints can be iso streams.  for now, we don't
-	 * accelerate iso completions ... so spin a while.
-	 */
-	if (qh->hw == NULL) {
-		struct fotg210_iso_stream *stream = ep->hcpriv;
-
-		if (!list_empty(&stream->td_list))
-			goto idle_timeout;
-
-		/* BUG_ON(!list_empty(&stream->free_list)); */
-		kfree(stream);
-		goto done;
-	}
-
-	if (fotg210->rh_state < FOTG210_RH_RUNNING)
-		qh->qh_state = QH_STATE_IDLE;
-	switch (qh->qh_state) {
-	case QH_STATE_LINKED:
-	case QH_STATE_COMPLETING:
-		for (tmp = fotg210->async->qh_next.qh;
-				tmp && tmp != qh;
-				tmp = tmp->qh_next.qh)
-			continue;
-		/* periodic qh self-unlinks on empty, and a COMPLETING qh
-		 * may already be unlinked.
-		 */
-		if (tmp)
-			start_unlink_async(fotg210, qh);
-		/* FALL THROUGH */
-	case QH_STATE_UNLINK:		/* wait for hw to finish? */
-	case QH_STATE_UNLINK_WAIT:
-idle_timeout:
-		spin_unlock_irqrestore(&fotg210->lock, flags);
-		schedule_timeout_uninterruptible(1);
-		goto rescan;
-	case QH_STATE_IDLE:		/* fully unlinked */
-		if (qh->clearing_tt)
-			goto idle_timeout;
-		if (list_empty(&qh->qtd_list)) {
-			qh_destroy(fotg210, qh);
-			break;
-		}
-		/* else FALL THROUGH */
-	default:
-		/* caller was supposed to have unlinked any requests;
-		 * that's not our job.  just leak this memory.
-		 */
-		fotg210_err(fotg210, "qh %p (#%02x) state %d%s\n",
-			qh, ep->desc.bEndpointAddress, qh->qh_state,
-			list_empty(&qh->qtd_list) ? "" : "(has tds)");
-		break;
-	}
-done:
-	ep->hcpriv = NULL;
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-}
-
-static void fotg210_endpoint_reset(struct usb_hcd *hcd,
-				   struct usb_host_endpoint *ep)
-{
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh *qh;
-	int eptype = usb_endpoint_type(&ep->desc);
-	int epnum = usb_endpoint_num(&ep->desc);
-	int is_out = usb_endpoint_dir_out(&ep->desc);
-	unsigned long flags;
-
-	if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
-		return;
-
-	spin_lock_irqsave(&fotg210->lock, flags);
-	qh = ep->hcpriv;
-
-	/* For Bulk and Interrupt endpoints we maintain the toggle state
-	 * in the hardware; the toggle bits in udev aren't used at all.
-	 * When an endpoint is reset by usb_clear_halt() we must reset
-	 * the toggle bit in the QH.
-	 */
-	if (qh) {
-		usb_settoggle(qh->dev, epnum, is_out, 0);
-		if (!list_empty(&qh->qtd_list)) {
-			WARN_ONCE(1, "clear_halt for a busy endpoint\n");
-		} else if (qh->qh_state == QH_STATE_LINKED ||
-				qh->qh_state == QH_STATE_COMPLETING) {
-
-			/* The toggle value in the QH can't be updated
-			 * while the QH is active.  Unlink it now;
-			 * re-linking will call qh_refresh().
-			 */
-			if (eptype == USB_ENDPOINT_XFER_BULK)
-				start_unlink_async(fotg210, qh);
-			else
-				start_unlink_intr(fotg210, qh);
-		}
-	}
-	spin_unlock_irqrestore(&fotg210->lock, flags);
-}
-
-static int fotg210_get_frame(struct usb_hcd *hcd)
-{
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-
-	return (fotg210_read_frame_index(fotg210) >> 3) %
-		fotg210->periodic_size;
-}
-
-/*
- * The EHCI in ChipIdea HDRC cannot be a separate module or device,
- * because its registers (and irq) are shared between host/gadget/otg
- * functions  and in order to facilitate role switching we cannot
- * give the fotg210 driver exclusive access to those.
- */
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_LICENSE("GPL");
-
-static const struct hc_driver fotg210_fotg210_hc_driver = {
-	.description		= hcd_name,
-	.product_desc		= "Faraday USB2.0 Host Controller",
-	.hcd_priv_size		= sizeof(struct fotg210_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq			= fotg210_irq,
-	.flags			= HCD_MEMORY | HCD_USB2,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset			= hcd_fotg210_init,
-	.start			= fotg210_run,
-	.stop			= fotg210_stop,
-	.shutdown		= fotg210_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue		= fotg210_urb_enqueue,
-	.urb_dequeue		= fotg210_urb_dequeue,
-	.endpoint_disable	= fotg210_endpoint_disable,
-	.endpoint_reset		= fotg210_endpoint_reset,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number	= fotg210_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data	= fotg210_hub_status_data,
-	.hub_control		= fotg210_hub_control,
-	.bus_suspend		= fotg210_bus_suspend,
-	.bus_resume		= fotg210_bus_resume,
-
-	.relinquish_port	= fotg210_relinquish_port,
-	.port_handed_over	= fotg210_port_handed_over,
-
-	.clear_tt_buffer_complete = fotg210_clear_tt_buffer_complete,
-};
-
-static void fotg210_init(struct fotg210_hcd *fotg210)
-{
-	u32 value;
-
-	iowrite32(GMIR_MDEV_INT | GMIR_MOTG_INT | GMIR_INT_POLARITY,
-		  &fotg210->regs->gmir);
-
-	value = ioread32(&fotg210->regs->otgcsr);
-	value &= ~OTGCSR_A_BUS_DROP;
-	value |= OTGCSR_A_BUS_REQ;
-	iowrite32(value, &fotg210->regs->otgcsr);
-}
-
-/**
- * fotg210_hcd_probe - initialize faraday FOTG210 HCDs
- *
- * Allocates basic resources for this USB host controller, and
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
- */
-static int fotg210_hcd_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct usb_hcd *hcd;
-	struct resource *res;
-	int irq;
-	int retval = -ENODEV;
-	struct fotg210_hcd *fotg210;
-
-	if (usb_disabled())
-		return -ENODEV;
-
-	pdev->dev.power.power_state = PMSG_ON;
-
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res) {
-		dev_err(dev,
-			"Found HC with no IRQ. Check %s setup!\n",
-			dev_name(dev));
-		return -ENODEV;
-	}
-
-	irq = res->start;
-
-	hcd = usb_create_hcd(&fotg210_fotg210_hc_driver, dev,
-			dev_name(dev));
-	if (!hcd) {
-		dev_err(dev, "failed to create hcd with err %d\n", retval);
-		retval = -ENOMEM;
-		goto fail_create_hcd;
-	}
-
-	hcd->has_tt = 1;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	hcd->regs = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(hcd->regs)) {
-		retval = PTR_ERR(hcd->regs);
-		goto failed;
-	}
-
-	hcd->rsrc_start = res->start;
-	hcd->rsrc_len = resource_size(res);
-
-	fotg210 = hcd_to_fotg210(hcd);
-
-	fotg210->caps = hcd->regs;
-
-	retval = fotg210_setup(hcd);
-	if (retval)
-		goto failed;
-
-	fotg210_init(fotg210);
-
-	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
-	if (retval) {
-		dev_err(dev, "failed to add hcd with err %d\n", retval);
-		goto failed;
-	}
-	device_wakeup_enable(hcd->self.controller);
-
-	return retval;
-
-failed:
-	usb_put_hcd(hcd);
-fail_create_hcd:
-	dev_err(dev, "init %s fail, %d\n", dev_name(dev), retval);
-	return retval;
-}
-
-/**
- * fotg210_hcd_remove - shutdown processing for EHCI HCDs
- * @dev: USB Host Controller being removed
- *
- */
-static int fotg210_hcd_remove(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct usb_hcd *hcd = dev_get_drvdata(dev);
-
-	if (!hcd)
-		return 0;
-
-	usb_remove_hcd(hcd);
-	usb_put_hcd(hcd);
-
-	return 0;
-}
-
-static struct platform_driver fotg210_hcd_driver = {
-	.driver = {
-		.name   = "fotg210-hcd",
-	},
-	.probe  = fotg210_hcd_probe,
-	.remove = fotg210_hcd_remove,
-};
-
-static int __init fotg210_hcd_init(void)
-{
-	int retval = 0;
-
-	if (usb_disabled())
-		return -ENODEV;
-
-	pr_info("%s: " DRIVER_DESC "\n", hcd_name);
-	set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-	if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
-			test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
-		pr_warn("Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
-
-	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd\n",
-		 hcd_name,
-		 sizeof(struct fotg210_qh), sizeof(struct fotg210_qtd),
-		 sizeof(struct fotg210_itd));
-
-	fotg210_debug_root = debugfs_create_dir("fotg210", usb_debug_root);
-	if (!fotg210_debug_root) {
-		retval = -ENOENT;
-		goto err_debug;
-	}
-
-	retval = platform_driver_register(&fotg210_hcd_driver);
-	if (retval < 0)
-		goto clean;
-	return retval;
-
-	platform_driver_unregister(&fotg210_hcd_driver);
-clean:
-	debugfs_remove(fotg210_debug_root);
-	fotg210_debug_root = NULL;
-err_debug:
-	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-	return retval;
-}
-module_init(fotg210_hcd_init);
-
-static void __exit fotg210_hcd_cleanup(void)
-{
-	platform_driver_unregister(&fotg210_hcd_driver);
-	debugfs_remove(fotg210_debug_root);
-	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-}
-module_exit(fotg210_hcd_cleanup);
diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/host/fotg210.h
deleted file mode 100644
index b5cfa7a..0000000
--- a/drivers/usb/host/fotg210.h
+++ /dev/null
@@ -1,692 +0,0 @@
-#ifndef __LINUX_FOTG210_H
-#define __LINUX_FOTG210_H
-
-#include <linux/usb/ehci-dbgp.h>
-
-/* definitions used for the EHCI driver */
-
-/*
- * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to
- * __leXX (normally) or __beXX (given FOTG210_BIG_ENDIAN_DESC), depending on
- * the host controller implementation.
- *
- * To facilitate the strongest possible byte-order checking from "sparse"
- * and so on, we use __leXX unless that's not practical.
- */
-#define __hc32	__le32
-#define __hc16	__le16
-
-/* statistics can be kept for tuning/monitoring */
-struct fotg210_stats {
-	/* irq usage */
-	unsigned long		normal;
-	unsigned long		error;
-	unsigned long		iaa;
-	unsigned long		lost_iaa;
-
-	/* termination of urbs from core */
-	unsigned long		complete;
-	unsigned long		unlink;
-};
-
-/* fotg210_hcd->lock guards shared data against other CPUs:
- *   fotg210_hcd:	async, unlink, periodic (and shadow), ...
- *   usb_host_endpoint: hcpriv
- *   fotg210_qh:	qh_next, qtd_list
- *   fotg210_qtd:	qtd_list
- *
- * Also, hold this lock when talking to HC registers or
- * when updating hw_* fields in shared qh/qtd/... structures.
- */
-
-#define	FOTG210_MAX_ROOT_PORTS	1		/* see HCS_N_PORTS */
-
-/*
- * fotg210_rh_state values of FOTG210_RH_RUNNING or above mean that the
- * controller may be doing DMA.  Lower values mean there's no DMA.
- */
-enum fotg210_rh_state {
-	FOTG210_RH_HALTED,
-	FOTG210_RH_SUSPENDED,
-	FOTG210_RH_RUNNING,
-	FOTG210_RH_STOPPING
-};
-
-/*
- * Timer events, ordered by increasing delay length.
- * Always update event_delays_ns[] and event_handlers[] (defined in
- * ehci-timer.c) in parallel with this list.
- */
-enum fotg210_hrtimer_event {
-	FOTG210_HRTIMER_POLL_ASS,	/* Poll for async schedule off */
-	FOTG210_HRTIMER_POLL_PSS,	/* Poll for periodic schedule off */
-	FOTG210_HRTIMER_POLL_DEAD,	/* Wait for dead controller to stop */
-	FOTG210_HRTIMER_UNLINK_INTR,	/* Wait for interrupt QH unlink */
-	FOTG210_HRTIMER_FREE_ITDS,	/* Wait for unused iTDs and siTDs */
-	FOTG210_HRTIMER_ASYNC_UNLINKS,	/* Unlink empty async QHs */
-	FOTG210_HRTIMER_IAA_WATCHDOG,	/* Handle lost IAA interrupts */
-	FOTG210_HRTIMER_DISABLE_PERIODIC, /* Wait to disable periodic sched */
-	FOTG210_HRTIMER_DISABLE_ASYNC,	/* Wait to disable async sched */
-	FOTG210_HRTIMER_IO_WATCHDOG,	/* Check for missing IRQs */
-	FOTG210_HRTIMER_NUM_EVENTS	/* Must come last */
-};
-#define FOTG210_HRTIMER_NO_EVENT	99
-
-struct fotg210_hcd {			/* one per controller */
-	/* timing support */
-	enum fotg210_hrtimer_event	next_hrtimer_event;
-	unsigned		enabled_hrtimer_events;
-	ktime_t			hr_timeouts[FOTG210_HRTIMER_NUM_EVENTS];
-	struct hrtimer		hrtimer;
-
-	int			PSS_poll_count;
-	int			ASS_poll_count;
-	int			died_poll_count;
-
-	/* glue to PCI and HCD framework */
-	struct fotg210_caps __iomem *caps;
-	struct fotg210_regs __iomem *regs;
-	struct ehci_dbg_port __iomem *debug;
-
-	__u32			hcs_params;	/* cached register copy */
-	spinlock_t		lock;
-	enum fotg210_rh_state	rh_state;
-
-	/* general schedule support */
-	bool			scanning:1;
-	bool			need_rescan:1;
-	bool			intr_unlinking:1;
-	bool			async_unlinking:1;
-	bool			shutdown:1;
-	struct fotg210_qh		*qh_scan_next;
-
-	/* async schedule support */
-	struct fotg210_qh		*async;
-	struct fotg210_qh		*dummy;		/* For AMD quirk use */
-	struct fotg210_qh		*async_unlink;
-	struct fotg210_qh		*async_unlink_last;
-	struct fotg210_qh		*async_iaa;
-	unsigned		async_unlink_cycle;
-	unsigned		async_count;	/* async activity count */
-
-	/* periodic schedule support */
-#define	DEFAULT_I_TDPS		1024		/* some HCs can do less */
-	unsigned		periodic_size;
-	__hc32			*periodic;	/* hw periodic table */
-	dma_addr_t		periodic_dma;
-	struct list_head	intr_qh_list;
-	unsigned		i_thresh;	/* uframes HC might cache */
-
-	union fotg210_shadow	*pshadow;	/* mirror hw periodic table */
-	struct fotg210_qh		*intr_unlink;
-	struct fotg210_qh		*intr_unlink_last;
-	unsigned		intr_unlink_cycle;
-	unsigned		now_frame;	/* frame from HC hardware */
-	unsigned		next_frame;	/* scan periodic, start here */
-	unsigned		intr_count;	/* intr activity count */
-	unsigned		isoc_count;	/* isoc activity count */
-	unsigned		periodic_count;	/* periodic activity count */
-	/* max periodic time per uframe */
-	unsigned		uframe_periodic_max;
-
-
-	/* list of itds completed while now_frame was still active */
-	struct list_head	cached_itd_list;
-	struct fotg210_itd	*last_itd_to_free;
-
-	/* per root hub port */
-	unsigned long		reset_done[FOTG210_MAX_ROOT_PORTS];
-
-	/* bit vectors (one bit per port)
-	 * which ports were already suspended at the start of a bus suspend
-	 */
-	unsigned long		bus_suspended;
-
-	/* which ports are edicated to the companion controller */
-	unsigned long		companion_ports;
-
-	/* which ports are owned by the companion during a bus suspend */
-	unsigned long		owned_ports;
-
-	/* which ports have the change-suspend feature turned on */
-	unsigned long		port_c_suspend;
-
-	/* which ports are suspended */
-	unsigned long		suspended_ports;
-
-	/* which ports have started to resume */
-	unsigned long		resuming_ports;
-
-	/* per-HC memory pools (could be per-bus, but ...) */
-	struct dma_pool		*qh_pool;	/* qh per active urb */
-	struct dma_pool		*qtd_pool;	/* one or more per qh */
-	struct dma_pool		*itd_pool;	/* itd per iso urb */
-
-	unsigned		random_frame;
-	unsigned long		next_statechange;
-	ktime_t			last_periodic_enable;
-	u32			command;
-
-	/* SILICON QUIRKS */
-	unsigned		need_io_watchdog:1;
-	unsigned		fs_i_thresh:1;	/* Intel iso scheduling */
-
-	u8			sbrn;		/* packed release number */
-
-	/* irq statistics */
-#ifdef FOTG210_STATS
-	struct fotg210_stats	stats;
-#	define COUNT(x) ((x)++)
-#else
-#	define COUNT(x)
-#endif
-
-	/* debug files */
-	struct dentry		*debug_dir;
-};
-
-/* convert between an HCD pointer and the corresponding FOTG210_HCD */
-static inline struct fotg210_hcd *hcd_to_fotg210(struct usb_hcd *hcd)
-{
-	return (struct fotg210_hcd *)(hcd->hcd_priv);
-}
-static inline struct usb_hcd *fotg210_to_hcd(struct fotg210_hcd *fotg210)
-{
-	return container_of((void *) fotg210, struct usb_hcd, hcd_priv);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */
-
-/* Section 2.2 Host Controller Capability Registers */
-struct fotg210_caps {
-	/* these fields are specified as 8 and 16 bit registers,
-	 * but some hosts can't perform 8 or 16 bit PCI accesses.
-	 * some hosts treat caplength and hciversion as parts of a 32-bit
-	 * register, others treat them as two separate registers, this
-	 * affects the memory map for big endian controllers.
-	 */
-	u32		hc_capbase;
-#define HC_LENGTH(fotg210, p)	(0x00ff&((p) >> /* bits 7:0 / offset 00h */ \
-				(fotg210_big_endian_capbase(fotg210) ? 24 : 0)))
-#define HC_VERSION(fotg210, p)	(0xffff&((p) >> /* bits 31:16 / offset 02h */ \
-				(fotg210_big_endian_capbase(fotg210) ? 0 : 16)))
-	u32		hcs_params;     /* HCSPARAMS - offset 0x4 */
-#define HCS_N_PORTS(p)		(((p)>>0)&0xf)	/* bits 3:0, ports on HC */
-
-	u32		hcc_params;	/* HCCPARAMS - offset 0x8 */
-#define HCC_CANPARK(p)		((p)&(1 << 2))  /* true: can park on async qh */
-#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1))  /* true: periodic_size changes*/
-	u8		portroute[8];	 /* nibbles for routing - offset 0xC */
-};
-
-
-/* Section 2.3 Host Controller Operational Registers */
-struct fotg210_regs {
-
-	/* USBCMD: offset 0x00 */
-	u32		command;
-
-/* EHCI 1.1 addendum */
-/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
-#define CMD_PARK	(1<<11)		/* enable "park" on async qh */
-#define CMD_PARK_CNT(c)	(((c)>>8)&3)	/* how many transfers to park for */
-#define CMD_IAAD	(1<<6)		/* "doorbell" interrupt async advance */
-#define CMD_ASE		(1<<5)		/* async schedule enable */
-#define CMD_PSE		(1<<4)		/* periodic schedule enable */
-/* 3:2 is periodic frame list size */
-#define CMD_RESET	(1<<1)		/* reset HC not bus */
-#define CMD_RUN		(1<<0)		/* start/stop HC */
-
-	/* USBSTS: offset 0x04 */
-	u32		status;
-#define STS_ASS		(1<<15)		/* Async Schedule Status */
-#define STS_PSS		(1<<14)		/* Periodic Schedule Status */
-#define STS_RECL	(1<<13)		/* Reclamation */
-#define STS_HALT	(1<<12)		/* Not running (any reason) */
-/* some bits reserved */
-	/* these STS_* flags are also intr_enable bits (USBINTR) */
-#define STS_IAA		(1<<5)		/* Interrupted on async advance */
-#define STS_FATAL	(1<<4)		/* such as some PCI access errors */
-#define STS_FLR		(1<<3)		/* frame list rolled over */
-#define STS_PCD		(1<<2)		/* port change detect */
-#define STS_ERR		(1<<1)		/* "error" completion (overflow, ...) */
-#define STS_INT		(1<<0)		/* "normal" completion (short, ...) */
-
-	/* USBINTR: offset 0x08 */
-	u32		intr_enable;
-
-	/* FRINDEX: offset 0x0C */
-	u32		frame_index;	/* current microframe number */
-	/* CTRLDSSEGMENT: offset 0x10 */
-	u32		segment;	/* address bits 63:32 if needed */
-	/* PERIODICLISTBASE: offset 0x14 */
-	u32		frame_list;	/* points to periodic list */
-	/* ASYNCLISTADDR: offset 0x18 */
-	u32		async_next;	/* address of next async queue head */
-
-	u32	reserved1;
-	/* PORTSC: offset 0x20 */
-	u32	port_status;
-/* 31:23 reserved */
-#define PORT_USB11(x) (((x)&(3<<10)) == (1<<10))	/* USB 1.1 device */
-#define PORT_RESET	(1<<8)		/* reset port */
-#define PORT_SUSPEND	(1<<7)		/* suspend port */
-#define PORT_RESUME	(1<<6)		/* resume it */
-#define PORT_PEC	(1<<3)		/* port enable change */
-#define PORT_PE		(1<<2)		/* port enable */
-#define PORT_CSC	(1<<1)		/* connect status change */
-#define PORT_CONNECT	(1<<0)		/* device connected */
-#define PORT_RWC_BITS   (PORT_CSC | PORT_PEC)
-	u32     reserved2[19];
-
-	/* OTGCSR: offet 0x70 */
-	u32     otgcsr;
-#define OTGCSR_HOST_SPD_TYP     (3 << 22)
-#define OTGCSR_A_BUS_DROP	(1 << 5)
-#define OTGCSR_A_BUS_REQ	(1 << 4)
-
-	/* OTGISR: offset 0x74 */
-	u32     otgisr;
-#define OTGISR_OVC	(1 << 10)
-
-	u32     reserved3[15];
-
-	/* GMIR: offset 0xB4 */
-	u32     gmir;
-#define GMIR_INT_POLARITY	(1 << 3) /*Active High*/
-#define GMIR_MHC_INT		(1 << 2)
-#define GMIR_MOTG_INT		(1 << 1)
-#define GMIR_MDEV_INT	(1 << 0)
-};
-
-/*-------------------------------------------------------------------------*/
-
-#define	QTD_NEXT(fotg210, dma)	cpu_to_hc32(fotg210, (u32)dma)
-
-/*
- * EHCI Specification 0.95 Section 3.5
- * QTD: describe data transfer components (buffer, direction, ...)
- * See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram".
- *
- * These are associated only with "QH" (Queue Head) structures,
- * used with control, bulk, and interrupt transfers.
- */
-struct fotg210_qtd {
-	/* first part defined by EHCI spec */
-	__hc32			hw_next;	/* see EHCI 3.5.1 */
-	__hc32			hw_alt_next;    /* see EHCI 3.5.2 */
-	__hc32			hw_token;	/* see EHCI 3.5.3 */
-#define	QTD_TOGGLE	(1 << 31)	/* data toggle */
-#define	QTD_LENGTH(tok)	(((tok)>>16) & 0x7fff)
-#define	QTD_IOC		(1 << 15)	/* interrupt on complete */
-#define	QTD_CERR(tok)	(((tok)>>10) & 0x3)
-#define	QTD_PID(tok)	(((tok)>>8) & 0x3)
-#define	QTD_STS_ACTIVE	(1 << 7)	/* HC may execute this */
-#define	QTD_STS_HALT	(1 << 6)	/* halted on error */
-#define	QTD_STS_DBE	(1 << 5)	/* data buffer error (in HC) */
-#define	QTD_STS_BABBLE	(1 << 4)	/* device was babbling (qtd halted) */
-#define	QTD_STS_XACT	(1 << 3)	/* device gave illegal response */
-#define	QTD_STS_MMF	(1 << 2)	/* incomplete split transaction */
-#define	QTD_STS_STS	(1 << 1)	/* split transaction state */
-#define	QTD_STS_PING	(1 << 0)	/* issue PING? */
-
-#define ACTIVE_BIT(fotg210)	cpu_to_hc32(fotg210, QTD_STS_ACTIVE)
-#define HALT_BIT(fotg210)		cpu_to_hc32(fotg210, QTD_STS_HALT)
-#define STATUS_BIT(fotg210)	cpu_to_hc32(fotg210, QTD_STS_STS)
-
-	__hc32			hw_buf[5];	/* see EHCI 3.5.4 */
-	__hc32			hw_buf_hi[5];	/* Appendix B */
-
-	/* the rest is HCD-private */
-	dma_addr_t		qtd_dma;		/* qtd address */
-	struct list_head	qtd_list;		/* sw qtd list */
-	struct urb		*urb;			/* qtd's urb */
-	size_t			length;			/* length of buffer */
-} __aligned(32);
-
-/* mask NakCnt+T in qh->hw_alt_next */
-#define QTD_MASK(fotg210)	cpu_to_hc32(fotg210, ~0x1f)
-
-#define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1)
-
-/*-------------------------------------------------------------------------*/
-
-/* type tag from {qh,itd,fstn}->hw_next */
-#define Q_NEXT_TYPE(fotg210, dma)	((dma) & cpu_to_hc32(fotg210, 3 << 1))
-
-/*
- * Now the following defines are not converted using the
- * cpu_to_le32() macro anymore, since we have to support
- * "dynamic" switching between be and le support, so that the driver
- * can be used on one system with SoC EHCI controller using big-endian
- * descriptors as well as a normal little-endian PCI EHCI controller.
- */
-/* values for that type tag */
-#define Q_TYPE_ITD	(0 << 1)
-#define Q_TYPE_QH	(1 << 1)
-#define Q_TYPE_SITD	(2 << 1)
-#define Q_TYPE_FSTN	(3 << 1)
-
-/* next async queue entry, or pointer to interrupt/periodic QH */
-#define QH_NEXT(fotg210, dma) \
-	(cpu_to_hc32(fotg210, (((u32)dma)&~0x01f)|Q_TYPE_QH))
-
-/* for periodic/async schedules and qtd lists, mark end of list */
-#define FOTG210_LIST_END(fotg210) \
-	cpu_to_hc32(fotg210, 1) /* "null pointer" to hw */
-
-/*
- * Entries in periodic shadow table are pointers to one of four kinds
- * of data structure.  That's dictated by the hardware; a type tag is
- * encoded in the low bits of the hardware's periodic schedule.  Use
- * Q_NEXT_TYPE to get the tag.
- *
- * For entries in the async schedule, the type tag always says "qh".
- */
-union fotg210_shadow {
-	struct fotg210_qh	*qh;		/* Q_TYPE_QH */
-	struct fotg210_itd	*itd;		/* Q_TYPE_ITD */
-	struct fotg210_fstn	*fstn;		/* Q_TYPE_FSTN */
-	__hc32			*hw_next;	/* (all types) */
-	void			*ptr;
-};
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.95 Section 3.6
- * QH: describes control/bulk/interrupt endpoints
- * See Fig 3-7 "Queue Head Structure Layout".
- *
- * These appear in both the async and (for interrupt) periodic schedules.
- */
-
-/* first part defined by EHCI spec */
-struct fotg210_qh_hw {
-	__hc32			hw_next;	/* see EHCI 3.6.1 */
-	__hc32			hw_info1;	/* see EHCI 3.6.2 */
-#define	QH_CONTROL_EP	(1 << 27)	/* FS/LS control endpoint */
-#define	QH_HEAD		(1 << 15)	/* Head of async reclamation list */
-#define	QH_TOGGLE_CTL	(1 << 14)	/* Data toggle control */
-#define	QH_HIGH_SPEED	(2 << 12)	/* Endpoint speed */
-#define	QH_LOW_SPEED	(1 << 12)
-#define	QH_FULL_SPEED	(0 << 12)
-#define	QH_INACTIVATE	(1 << 7)	/* Inactivate on next transaction */
-	__hc32			hw_info2;	/* see EHCI 3.6.2 */
-#define	QH_SMASK	0x000000ff
-#define	QH_CMASK	0x0000ff00
-#define	QH_HUBADDR	0x007f0000
-#define	QH_HUBPORT	0x3f800000
-#define	QH_MULT		0xc0000000
-	__hc32			hw_current;	/* qtd list - see EHCI 3.6.4 */
-
-	/* qtd overlay (hardware parts of a struct fotg210_qtd) */
-	__hc32			hw_qtd_next;
-	__hc32			hw_alt_next;
-	__hc32			hw_token;
-	__hc32			hw_buf[5];
-	__hc32			hw_buf_hi[5];
-} __aligned(32);
-
-struct fotg210_qh {
-	struct fotg210_qh_hw	*hw;		/* Must come first */
-	/* the rest is HCD-private */
-	dma_addr_t		qh_dma;		/* address of qh */
-	union fotg210_shadow	qh_next;	/* ptr to qh; or periodic */
-	struct list_head	qtd_list;	/* sw qtd list */
-	struct list_head	intr_node;	/* list of intr QHs */
-	struct fotg210_qtd	*dummy;
-	struct fotg210_qh	*unlink_next;	/* next on unlink list */
-
-	unsigned		unlink_cycle;
-
-	u8			needs_rescan;	/* Dequeue during giveback */
-	u8			qh_state;
-#define	QH_STATE_LINKED		1		/* HC sees this */
-#define	QH_STATE_UNLINK		2		/* HC may still see this */
-#define	QH_STATE_IDLE		3		/* HC doesn't see this */
-#define	QH_STATE_UNLINK_WAIT	4		/* LINKED and on unlink q */
-#define	QH_STATE_COMPLETING	5		/* don't touch token.HALT */
-
-	u8			xacterrs;	/* XactErr retry counter */
-#define	QH_XACTERR_MAX		32		/* XactErr retry limit */
-
-	/* periodic schedule info */
-	u8			usecs;		/* intr bandwidth */
-	u8			gap_uf;		/* uframes split/csplit gap */
-	u8			c_usecs;	/* ... split completion bw */
-	u16			tt_usecs;	/* tt downstream bandwidth */
-	unsigned short		period;		/* polling interval */
-	unsigned short		start;		/* where polling starts */
-#define NO_FRAME ((unsigned short)~0)			/* pick new start */
-
-	struct usb_device	*dev;		/* access to TT */
-	unsigned		is_out:1;	/* bulk or intr OUT */
-	unsigned		clearing_tt:1;	/* Clear-TT-Buf in progress */
-};
-
-/*-------------------------------------------------------------------------*/
-
-/* description of one iso transaction (up to 3 KB data if highspeed) */
-struct fotg210_iso_packet {
-	/* These will be copied to iTD when scheduling */
-	u64			bufp;		/* itd->hw_bufp{,_hi}[pg] |= */
-	__hc32			transaction;	/* itd->hw_transaction[i] |= */
-	u8			cross;		/* buf crosses pages */
-	/* for full speed OUT splits */
-	u32			buf1;
-};
-
-/* temporary schedule data for packets from iso urbs (both speeds)
- * each packet is one logical usb transaction to the device (not TT),
- * beginning at stream->next_uframe
- */
-struct fotg210_iso_sched {
-	struct list_head	td_list;
-	unsigned		span;
-	struct fotg210_iso_packet	packet[0];
-};
-
-/*
- * fotg210_iso_stream - groups all (s)itds for this endpoint.
- * acts like a qh would, if EHCI had them for ISO.
- */
-struct fotg210_iso_stream {
-	/* first field matches fotg210_hq, but is NULL */
-	struct fotg210_qh_hw	*hw;
-
-	u8			bEndpointAddress;
-	u8			highspeed;
-	struct list_head	td_list;	/* queued itds */
-	struct list_head	free_list;	/* list of unused itds */
-	struct usb_device	*udev;
-	struct usb_host_endpoint *ep;
-
-	/* output of (re)scheduling */
-	int			next_uframe;
-	__hc32			splits;
-
-	/* the rest is derived from the endpoint descriptor,
-	 * trusting urb->interval == f(epdesc->bInterval) and
-	 * including the extra info for hw_bufp[0..2]
-	 */
-	u8			usecs, c_usecs;
-	u16			interval;
-	u16			tt_usecs;
-	u16			maxp;
-	u16			raw_mask;
-	unsigned		bandwidth;
-
-	/* This is used to initialize iTD's hw_bufp fields */
-	__hc32			buf0;
-	__hc32			buf1;
-	__hc32			buf2;
-
-	/* this is used to initialize sITD's tt info */
-	__hc32			address;
-};
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.95 Section 3.3
- * Fig 3-4 "Isochronous Transaction Descriptor (iTD)"
- *
- * Schedule records for high speed iso xfers
- */
-struct fotg210_itd {
-	/* first part defined by EHCI spec */
-	__hc32			hw_next;	/* see EHCI 3.3.1 */
-	__hc32			hw_transaction[8]; /* see EHCI 3.3.2 */
-#define FOTG210_ISOC_ACTIVE	(1<<31)	/* activate transfer this slot */
-#define FOTG210_ISOC_BUF_ERR	(1<<30)	/* Data buffer error */
-#define FOTG210_ISOC_BABBLE	(1<<29)	/* babble detected */
-#define FOTG210_ISOC_XACTERR	(1<<28)	/* XactErr - transaction error */
-#define	FOTG210_ITD_LENGTH(tok)	(((tok)>>16) & 0x0fff)
-#define	FOTG210_ITD_IOC		(1 << 15)	/* interrupt on complete */
-
-#define ITD_ACTIVE(fotg210)	cpu_to_hc32(fotg210, FOTG210_ISOC_ACTIVE)
-
-	__hc32			hw_bufp[7];	/* see EHCI 3.3.3 */
-	__hc32			hw_bufp_hi[7];	/* Appendix B */
-
-	/* the rest is HCD-private */
-	dma_addr_t		itd_dma;	/* for this itd */
-	union fotg210_shadow	itd_next;	/* ptr to periodic q entry */
-
-	struct urb		*urb;
-	struct fotg210_iso_stream	*stream;	/* endpoint's queue */
-	struct list_head	itd_list;	/* list of stream's itds */
-
-	/* any/all hw_transactions here may be used by that urb */
-	unsigned		frame;		/* where scheduled */
-	unsigned		pg;
-	unsigned		index[8];	/* in urb->iso_frame_desc */
-} __aligned(32);
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.96 Section 3.7
- * Periodic Frame Span Traversal Node (FSTN)
- *
- * Manages split interrupt transactions (using TT) that span frame boundaries
- * into uframes 0/1; see 4.12.2.2.  In those uframes, a "save place" FSTN
- * makes the HC jump (back) to a QH to scan for fs/ls QH completions until
- * it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work.
- */
-struct fotg210_fstn {
-	__hc32			hw_next;	/* any periodic q entry */
-	__hc32			hw_prev;	/* qh or FOTG210_LIST_END */
-
-	/* the rest is HCD-private */
-	dma_addr_t		fstn_dma;
-	union fotg210_shadow	fstn_next;	/* ptr to periodic q entry */
-} __aligned(32);
-
-/*-------------------------------------------------------------------------*/
-
-/* Prepare the PORTSC wakeup flags during controller suspend/resume */
-
-#define fotg210_prepare_ports_for_controller_suspend(fotg210, do_wakeup) \
-		fotg210_adjust_port_wakeup_flags(fotg210, true, do_wakeup)
-
-#define fotg210_prepare_ports_for_controller_resume(fotg210)		\
-		fotg210_adjust_port_wakeup_flags(fotg210, false, false)
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * Some EHCI controllers have a Transaction Translator built into the
- * root hub. This is a non-standard feature.  Each controller will need
- * to add code to the following inline functions, and call them as
- * needed (mostly in root hub code).
- */
-
-static inline unsigned int
-fotg210_get_speed(struct fotg210_hcd *fotg210, unsigned int portsc)
-{
-	return (readl(&fotg210->regs->otgcsr)
-		& OTGCSR_HOST_SPD_TYP) >> 22;
-}
-
-/* Returns the speed of a device attached to a port on the root hub. */
-static inline unsigned int
-fotg210_port_speed(struct fotg210_hcd *fotg210, unsigned int portsc)
-{
-	switch (fotg210_get_speed(fotg210, portsc)) {
-	case 0:
-		return 0;
-	case 1:
-		return USB_PORT_STAT_LOW_SPEED;
-	case 2:
-	default:
-		return USB_PORT_STAT_HIGH_SPEED;
-	}
-}
-
-/*-------------------------------------------------------------------------*/
-
-#define	fotg210_has_fsl_portno_bug(e)		(0)
-
-/*
- * While most USB host controllers implement their registers in
- * little-endian format, a minority (celleb companion chip) implement
- * them in big endian format.
- *
- * This attempts to support either format at compile time without a
- * runtime penalty, or both formats with the additional overhead
- * of checking a flag bit.
- *
- */
-
-#define fotg210_big_endian_mmio(e)	0
-#define fotg210_big_endian_capbase(e)	0
-
-static inline unsigned int fotg210_readl(const struct fotg210_hcd *fotg210,
-		__u32 __iomem *regs)
-{
-	return readl(regs);
-}
-
-static inline void fotg210_writel(const struct fotg210_hcd *fotg210,
-		const unsigned int val, __u32 __iomem *regs)
-{
-	writel(val, regs);
-}
-
-/* cpu to fotg210 */
-static inline __hc32 cpu_to_hc32(const struct fotg210_hcd *fotg210, const u32 x)
-{
-	return cpu_to_le32(x);
-}
-
-/* fotg210 to cpu */
-static inline u32 hc32_to_cpu(const struct fotg210_hcd *fotg210, const __hc32 x)
-{
-	return le32_to_cpu(x);
-}
-
-static inline u32 hc32_to_cpup(const struct fotg210_hcd *fotg210,
-			       const __hc32 *x)
-{
-	return le32_to_cpup(x);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static inline unsigned fotg210_read_frame_index(struct fotg210_hcd *fotg210)
-{
-	return fotg210_readl(fotg210, &fotg210->regs->frame_index);
-}
-
-#define fotg210_itdlen(urb, desc, t) ({			\
-	usb_pipein((urb)->pipe) ?				\
-	(desc)->length - FOTG210_ITD_LENGTH(t) :			\
-	FOTG210_ITD_LENGTH(t);					\
-})
-/*-------------------------------------------------------------------------*/
-
-#endif /* __LINUX_FOTG210_H */
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 12/14] RFC: usb/host/faraday-hcd: Replace fotg210 by fhcd2xx
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
                                   ` (10 preceding siblings ...)
  2015-09-21 15:01                 ` [PATCH 11/14] RFC: usb/host: Rename fotg210-hcd to faraday-hcd Peter Senna Tschudin
@ 2015-09-21 15:01                 ` Peter Senna Tschudin
  2015-10-02 17:36                   ` Felipe Balbi
  2015-09-21 15:01                 ` [PATCH 13/14] RFC: usb/host/faraday-hcd: Move #defines outside struct Peter Senna Tschudin
                                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-21 15:01 UTC (permalink / raw)
  To: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh
  Cc: Peter Senna Tschudin

This patch replaces the strings:
FOTG210 by FHCD2XX
fotg210 by fhcd2xx

The goal is to remove all references to fotg210 as the driver will
support both fotg210 and fusbh200.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/faraday-hcd.c | 2612 ++++++++++++++++++++--------------------
 drivers/usb/host/faraday-hcd.h |  248 ++--
 2 files changed, 1430 insertions(+), 1430 deletions(-)

diff --git a/drivers/usb/host/faraday-hcd.c b/drivers/usb/host/faraday-hcd.c
index ab1257f..3da3f59 100644
--- a/drivers/usb/host/faraday-hcd.c
+++ b/drivers/usb/host/faraday-hcd.c
@@ -52,17 +52,17 @@
 
 #define DRIVER_AUTHOR "Yuan-Hsin Chen"
 #define DRIVER_DESC "FOTG210 Host Controller (EHCI) Driver"
-static const char hcd_name[] = "fotg210_hcd";
+static const char hcd_name[] = "fhcd2xx_hcd";
 
-#undef FOTG210_URB_TRACE
-#define FOTG210_STATS
+#undef FHCD2XX_URB_TRACE
+#define FHCD2XX_STATS
 
 /* magic numbers that can affect system performance */
-#define FOTG210_TUNE_CERR	3 /* 0-3 qtd retries; 0 == don't stop */
-#define FOTG210_TUNE_RL_HS	4 /* nak throttle; see 4.9 */
-#define FOTG210_TUNE_RL_TT	0
-#define FOTG210_TUNE_MULT_HS	1 /* 1-3 transactions/uframe; 4.10.3 */
-#define FOTG210_TUNE_MULT_TT	1
+#define FHCD2XX_TUNE_CERR	3 /* 0-3 qtd retries; 0 == don't stop */
+#define FHCD2XX_TUNE_RL_HS	4 /* nak throttle; see 4.9 */
+#define FHCD2XX_TUNE_RL_TT	0
+#define FHCD2XX_TUNE_MULT_HS	1 /* 1-3 transactions/uframe; 4.10.3 */
+#define FHCD2XX_TUNE_MULT_TT	1
 
 /*
  * Some drivers think it's safe to schedule isochronous transfers more than 256
@@ -70,7 +70,7 @@ static const char hcd_name[] = "fotg210_hcd";
  * code).  In an attempt to avoid trouble, we will use a minimum scheduling
  * length of 512 frames instead of 256.
  */
-#define FOTG210_TUNE_FLS 1 /* (medium) 512-frame schedule */
+#define FHCD2XX_TUNE_FLS 1 /* (medium) 512-frame schedule */
 
 /* Initial IRQ latency:  faster than hw default */
 static int log2_irq_thresh; /* 0 to 6 */
@@ -91,95 +91,95 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
 
 #include "faraday-hcd.h"
 
-#define fotg210_dbg(fotg210, fmt, args...) \
-	dev_dbg(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
-#define fotg210_err(fotg210, fmt, args...) \
-	dev_err(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
-#define fotg210_info(fotg210, fmt, args...) \
-	dev_info(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
-#define fotg210_warn(fotg210, fmt, args...) \
-	dev_warn(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
+#define fhcd2xx_dbg(fhcd2xx, fmt, args...) \
+	dev_dbg(fhcd2xx_to_hcd(fhcd2xx)->self.controller, fmt, ## args)
+#define fhcd2xx_err(fhcd2xx, fmt, args...) \
+	dev_err(fhcd2xx_to_hcd(fhcd2xx)->self.controller, fmt, ## args)
+#define fhcd2xx_info(fhcd2xx, fmt, args...) \
+	dev_info(fhcd2xx_to_hcd(fhcd2xx)->self.controller, fmt, ## args)
+#define fhcd2xx_warn(fhcd2xx, fmt, args...) \
+	dev_warn(fhcd2xx_to_hcd(fhcd2xx)->self.controller, fmt, ## args)
 
 /* check the values in the HCSPARAMS register (host controller _Structural_
  * parameters) see EHCI spec, Table 2-4 for each value
  */
-static void dbg_hcs_params(struct fotg210_hcd *fotg210, char *label)
+static void dbg_hcs_params(struct fhcd2xx_hcd *fhcd2xx, char *label)
 {
-	u32 params = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
+	u32 params = fhcd2xx_readl(fhcd2xx, &fhcd2xx->caps->hcs_params);
 
-	fotg210_dbg(fotg210, "%s hcs_params 0x%x ports=%d\n", label, params,
+	fhcd2xx_dbg(fhcd2xx, "%s hcs_params 0x%x ports=%d\n", label, params,
 		    HCS_N_PORTS(params));
 }
 
 /* check the values in the HCCPARAMS register (host controller _Capability_
  * parameters) see EHCI Spec, Table 2-5 for each value
  */
-static void dbg_hcc_params(struct fotg210_hcd *fotg210, char *label)
+static void dbg_hcc_params(struct fhcd2xx_hcd *fhcd2xx, char *label)
 {
-	u32 params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
+	u32 params = fhcd2xx_readl(fhcd2xx, &fhcd2xx->caps->hcc_params);
 
-	fotg210_dbg(fotg210, "%s hcc_params %04x uframes %s%s\n", label,
+	fhcd2xx_dbg(fhcd2xx, "%s hcc_params %04x uframes %s%s\n", label,
 		    params,
 		    HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
 		    HCC_CANPARK(params) ? " park" : "");
 }
 
 static void __maybe_unused
-dbg_qtd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd)
+dbg_qtd(const char *label, struct fhcd2xx_hcd *fhcd2xx, struct fhcd2xx_qtd *qtd)
 {
-	fotg210_dbg(fotg210, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
-		    hc32_to_cpup(fotg210, &qtd->hw_next),
-		    hc32_to_cpup(fotg210, &qtd->hw_alt_next),
-		    hc32_to_cpup(fotg210, &qtd->hw_token),
-		    hc32_to_cpup(fotg210, &qtd->hw_buf[0]));
+	fhcd2xx_dbg(fhcd2xx, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
+		    hc32_to_cpup(fhcd2xx, &qtd->hw_next),
+		    hc32_to_cpup(fhcd2xx, &qtd->hw_alt_next),
+		    hc32_to_cpup(fhcd2xx, &qtd->hw_token),
+		    hc32_to_cpup(fhcd2xx, &qtd->hw_buf[0]));
 	if (qtd->hw_buf[1])
-		fotg210_dbg(fotg210, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
-			    hc32_to_cpup(fotg210, &qtd->hw_buf[1]),
-			    hc32_to_cpup(fotg210, &qtd->hw_buf[2]),
-			    hc32_to_cpup(fotg210, &qtd->hw_buf[3]),
-			    hc32_to_cpup(fotg210, &qtd->hw_buf[4]));
+		fhcd2xx_dbg(fhcd2xx, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
+			    hc32_to_cpup(fhcd2xx, &qtd->hw_buf[1]),
+			    hc32_to_cpup(fhcd2xx, &qtd->hw_buf[2]),
+			    hc32_to_cpup(fhcd2xx, &qtd->hw_buf[3]),
+			    hc32_to_cpup(fhcd2xx, &qtd->hw_buf[4]));
 }
 
 static void __maybe_unused
-dbg_qh(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+dbg_qh(const char *label, struct fhcd2xx_hcd *fhcd2xx, struct fhcd2xx_qh *qh)
 {
-	struct fotg210_qh_hw *hw = qh->hw;
+	struct fhcd2xx_qh_hw *hw = qh->hw;
 
-	fotg210_dbg(fotg210, "%s qh %p n%08x info %x %x qtd %x\n", label, qh,
+	fhcd2xx_dbg(fhcd2xx, "%s qh %p n%08x info %x %x qtd %x\n", label, qh,
 		    hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
 
-	dbg_qtd("overlay", fotg210, (struct fotg210_qtd *) &hw->hw_qtd_next);
+	dbg_qtd("overlay", fhcd2xx, (struct fhcd2xx_qtd *) &hw->hw_qtd_next);
 }
 
 static void __maybe_unused
-dbg_itd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
+dbg_itd(const char *label, struct fhcd2xx_hcd *fhcd2xx, struct fhcd2xx_itd *itd)
 {
-	fotg210_dbg(fotg210, "%s[%d] itd %p, next %08x, urb %p\n", label,
-		    itd->frame, itd, hc32_to_cpu(fotg210, itd->hw_next),
+	fhcd2xx_dbg(fhcd2xx, "%s[%d] itd %p, next %08x, urb %p\n", label,
+		    itd->frame, itd, hc32_to_cpu(fhcd2xx, itd->hw_next),
 		    itd->urb);
 
-	fotg210_dbg(fotg210,
+	fhcd2xx_dbg(fhcd2xx,
 		    "  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
-		    hc32_to_cpu(fotg210, itd->hw_transaction[0]),
-		    hc32_to_cpu(fotg210, itd->hw_transaction[1]),
-		    hc32_to_cpu(fotg210, itd->hw_transaction[2]),
-		    hc32_to_cpu(fotg210, itd->hw_transaction[3]),
-		    hc32_to_cpu(fotg210, itd->hw_transaction[4]),
-		    hc32_to_cpu(fotg210, itd->hw_transaction[5]),
-		    hc32_to_cpu(fotg210, itd->hw_transaction[6]),
-		    hc32_to_cpu(fotg210, itd->hw_transaction[7]));
-
-	fotg210_dbg(fotg210,
+		    hc32_to_cpu(fhcd2xx, itd->hw_transaction[0]),
+		    hc32_to_cpu(fhcd2xx, itd->hw_transaction[1]),
+		    hc32_to_cpu(fhcd2xx, itd->hw_transaction[2]),
+		    hc32_to_cpu(fhcd2xx, itd->hw_transaction[3]),
+		    hc32_to_cpu(fhcd2xx, itd->hw_transaction[4]),
+		    hc32_to_cpu(fhcd2xx, itd->hw_transaction[5]),
+		    hc32_to_cpu(fhcd2xx, itd->hw_transaction[6]),
+		    hc32_to_cpu(fhcd2xx, itd->hw_transaction[7]));
+
+	fhcd2xx_dbg(fhcd2xx,
 		    "  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
-		    hc32_to_cpu(fotg210, itd->hw_bufp[0]),
-		    hc32_to_cpu(fotg210, itd->hw_bufp[1]),
-		    hc32_to_cpu(fotg210, itd->hw_bufp[2]),
-		    hc32_to_cpu(fotg210, itd->hw_bufp[3]),
-		    hc32_to_cpu(fotg210, itd->hw_bufp[4]),
-		    hc32_to_cpu(fotg210, itd->hw_bufp[5]),
-		    hc32_to_cpu(fotg210, itd->hw_bufp[6]));
-
-	fotg210_dbg(fotg210, "  index: %d %d %d %d %d %d %d %d\n",
+		    hc32_to_cpu(fhcd2xx, itd->hw_bufp[0]),
+		    hc32_to_cpu(fhcd2xx, itd->hw_bufp[1]),
+		    hc32_to_cpu(fhcd2xx, itd->hw_bufp[2]),
+		    hc32_to_cpu(fhcd2xx, itd->hw_bufp[3]),
+		    hc32_to_cpu(fhcd2xx, itd->hw_bufp[4]),
+		    hc32_to_cpu(fhcd2xx, itd->hw_bufp[5]),
+		    hc32_to_cpu(fhcd2xx, itd->hw_bufp[6]));
+
+	fhcd2xx_dbg(fhcd2xx, "  index: %d %d %d %d %d %d %d %d\n",
 		    itd->index[0], itd->index[1], itd->index[2],
 		    itd->index[3], itd->index[4], itd->index[5],
 		    itd->index[6], itd->index[7]);
@@ -271,21 +271,21 @@ static char *dbg_port_buf(char *buf, unsigned len, const char *label, int port,
 }
 
 /* functions have the "wrong" filename when they're output... */
-#define dbg_status(fotg210, label, status) {			\
+#define dbg_status(fhcd2xx, label, status) {			\
 	char _buf[80];						\
 	dbg_status_buf(_buf, sizeof(_buf), label, status);	\
-	fotg210_dbg(fotg210, "%s\n", _buf);			\
+	fhcd2xx_dbg(fhcd2xx, "%s\n", _buf);			\
 }
 
-#define dbg_cmd(fotg210, label, command) {			\
+#define dbg_cmd(fhcd2xx, label, command) {			\
 	char _buf[80];						\
 	dbg_command_buf(_buf, sizeof(_buf), label, command);	\
-	fotg210_dbg(fotg210, "%s\n", _buf);			\
+	fhcd2xx_dbg(fhcd2xx, "%s\n", _buf);			\
 }
 
-#define dbg_port(fotg210, label, port, status) {			    \
+#define dbg_port(fhcd2xx, label, port, status) {			    \
 	char _buf[80];							    \
-	fotg210_dbg(fotg210, "%s\n",					    \
+	fhcd2xx_dbg(fhcd2xx, "%s\n",					    \
 		    dbg_port_buf(_buf, sizeof(_buf), label, port, status)); \
 }
 
@@ -320,7 +320,7 @@ static const struct file_operations debug_registers_fops = {
 	.llseek		= default_llseek,
 };
 
-static struct dentry *fotg210_debug_root;
+static struct dentry *fhcd2xx_debug_root;
 
 struct debug_buffer {
 	ssize_t (*fill_func)(struct debug_buffer *);	/* fill method */
@@ -348,9 +348,9 @@ static inline char speed_char(u32 scratch)
 	}
 }
 
-static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
+static inline char token_mark(struct fhcd2xx_hcd *fhcd2xx, __hc32 token)
 {
-	__u32 v = hc32_to_cpu(fotg210, token);
+	__u32 v = hc32_to_cpu(fhcd2xx, token);
 
 	if (v & QTD_STS_ACTIVE)
 		return '*';
@@ -362,58 +362,58 @@ static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
 	return '/';
 }
 
-static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
+static void qh_lines(struct fhcd2xx_hcd *fhcd2xx, struct fhcd2xx_qh *qh,
 		     char **nextp, unsigned *sizep)
 {
 	u32 scratch;
 	u32 hw_curr;
-	struct fotg210_qtd *td;
+	struct fhcd2xx_qtd *td;
 	unsigned temp;
 	unsigned size = *sizep;
 	char *next = *nextp;
 	char mark;
 	char *tmp;
 
-	__le32 list_end = FOTG210_LIST_END(fotg210);
-	struct fotg210_qh_hw *hw = qh->hw;
+	__le32 list_end = FHCD2XX_LIST_END(fhcd2xx);
+	struct fhcd2xx_qh_hw *hw = qh->hw;
 
 	if (hw->hw_qtd_next == list_end) /* NEC does this */
 		mark = '@';
 	else
-		mark = token_mark(fotg210, hw->hw_token);
+		mark = token_mark(fhcd2xx, hw->hw_token);
 	if (mark == '/') { /* qh_alt_next controls qh advance? */
-		if ((hw->hw_alt_next & QTD_MASK(fotg210)) ==
-		    fotg210->async->hw->hw_alt_next)
+		if ((hw->hw_alt_next & QTD_MASK(fhcd2xx)) ==
+		    fhcd2xx->async->hw->hw_alt_next)
 			mark = '#'; /* blocked */
 		else if (hw->hw_alt_next == list_end)
 			mark = '.'; /* use hw_qtd_next */
 		/* else alt_next points to some other qtd */
 	}
-	scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
-	hw_curr = (mark == '*') ? hc32_to_cpup(fotg210, &hw->hw_current) : 0;
+	scratch = hc32_to_cpup(fhcd2xx, &hw->hw_info1);
+	hw_curr = (mark == '*') ? hc32_to_cpup(fhcd2xx, &hw->hw_current) : 0;
 	temp = scnprintf(next, size,
 			"qh/%p dev%d %cs ep%d %08x %08x(%08x%c %s nak%d)",
 			qh, scratch & 0x007f,
 			speed_char(scratch),
 			(scratch >> 8) & 0x000f,
-			scratch, hc32_to_cpup(fotg210, &hw->hw_info2),
-			hc32_to_cpup(fotg210, &hw->hw_token), mark,
-			(cpu_to_hc32(fotg210, QTD_TOGGLE) & hw->hw_token)
+			scratch, hc32_to_cpup(fhcd2xx, &hw->hw_info2),
+			hc32_to_cpup(fhcd2xx, &hw->hw_token), mark,
+			(cpu_to_hc32(fhcd2xx, QTD_TOGGLE) & hw->hw_token)
 				? "data1" : "data0",
-			(hc32_to_cpup(fotg210, &hw->hw_alt_next) >> 1) & 0x0f);
+			(hc32_to_cpup(fhcd2xx, &hw->hw_alt_next) >> 1) & 0x0f);
 	size -= temp;
 	next += temp;
 
 	/* hc may be modifying the list as we read it ... */
 	list_for_each_entry(td, &qh->qtd_list, qtd_list) {
-		scratch = hc32_to_cpup(fotg210, &td->hw_token);
+		scratch = hc32_to_cpup(fhcd2xx, &td->hw_token);
 		mark = ' ';
 		if (hw_curr == td->qtd_dma)
 			mark = '*';
-		else if (hw->hw_qtd_next == cpu_to_hc32(fotg210, td->qtd_dma))
+		else if (hw->hw_qtd_next == cpu_to_hc32(fhcd2xx, td->qtd_dma))
 			mark = '+';
 		else if (QTD_LENGTH(scratch)) {
-			if (td->hw_alt_next == fotg210->async->hw->hw_alt_next)
+			if (td->hw_alt_next == fhcd2xx->async->hw->hw_alt_next)
 				mark = '#';
 			else if (td->hw_alt_next != list_end)
 				mark = '/';
@@ -462,14 +462,14 @@ done:
 static ssize_t fill_async_buffer(struct debug_buffer *buf)
 {
 	struct usb_hcd *hcd;
-	struct fotg210_hcd *fotg210;
+	struct fhcd2xx_hcd *fhcd2xx;
 	unsigned long flags;
 	unsigned temp, size;
 	char *next;
-	struct fotg210_qh *qh;
+	struct fhcd2xx_qh *qh;
 
 	hcd = bus_to_hcd(buf->bus);
-	fotg210 = hcd_to_fotg210(hcd);
+	fhcd2xx = hcd_to_fhcd2xx(hcd);
 	next = buf->output_buf;
 	size = buf->alloc_size;
 
@@ -479,39 +479,39 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
 	 * usually empty except for long-term bulk reads, or head.
 	 * one QH per line, and TDs we know about
 	 */
-	spin_lock_irqsave(&fotg210->lock, flags);
-	for (qh = fotg210->async->qh_next.qh; size > 0 && qh;
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
+	for (qh = fhcd2xx->async->qh_next.qh; size > 0 && qh;
 	     qh = qh->qh_next.qh)
-		qh_lines(fotg210, qh, &next, &size);
-	if (fotg210->async_unlink && size > 0) {
+		qh_lines(fhcd2xx, qh, &next, &size);
+	if (fhcd2xx->async_unlink && size > 0) {
 		temp = scnprintf(next, size, "\nunlink =\n");
 		size -= temp;
 		next += temp;
 
-		for (qh = fotg210->async_unlink; size > 0 && qh;
+		for (qh = fhcd2xx->async_unlink; size > 0 && qh;
 				qh = qh->unlink_next)
-			qh_lines(fotg210, qh, &next, &size);
+			qh_lines(fhcd2xx, qh, &next, &size);
 	}
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 
 	return strlen(buf->output_buf);
 }
 
 /* count tds, get ep direction */
 static inline unsigned output_buf_tds_dir(char *buf,
-					  struct fotg210_hcd *fotg210,
-					  struct fotg210_qh_hw *hw,
-					  struct fotg210_qh *qh, unsigned size)
+					  struct fhcd2xx_hcd *fhcd2xx,
+					  struct fhcd2xx_qh_hw *hw,
+					  struct fhcd2xx_qh *qh, unsigned size)
 {
-	u32 scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
-	struct fotg210_qtd *qtd;
+	u32 scratch = hc32_to_cpup(fhcd2xx, &hw->hw_info1);
+	struct fhcd2xx_qtd *qtd;
 	char *type = "";
 	unsigned temp = 0;
 
 	/* count tds, get ep direction */
 	list_for_each_entry(qtd, &qh->qtd_list, qtd_list) {
 		temp++;
-		switch (0x03 & (hc32_to_cpu(fotg210, qtd->hw_token) >> 8)) {
+		switch (0x03 & (hc32_to_cpu(fhcd2xx, qtd->hw_token) >> 8)) {
 		case 0:
 			type = "out";
 			continue;
@@ -531,9 +531,9 @@ static inline unsigned output_buf_tds_dir(char *buf,
 static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 {
 	struct usb_hcd *hcd;
-	struct fotg210_hcd *fotg210;
+	struct fhcd2xx_hcd *fhcd2xx;
 	unsigned long flags;
-	union fotg210_shadow p, *seen;
+	union fhcd2xx_shadow p, *seen;
 	unsigned temp, size, seen_count;
 	char *next;
 	unsigned i;
@@ -546,38 +546,38 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 	seen_count = 0;
 
 	hcd = bus_to_hcd(buf->bus);
-	fotg210 = hcd_to_fotg210(hcd);
+	fhcd2xx = hcd_to_fhcd2xx(hcd);
 	next = buf->output_buf;
 	size = buf->alloc_size;
 
-	temp = scnprintf(next, size, "size = %d\n", fotg210->periodic_size);
+	temp = scnprintf(next, size, "size = %d\n", fhcd2xx->periodic_size);
 	size -= temp;
 	next += temp;
 
 	/* dump a snapshot of the periodic schedule.
 	 * iso changes, interrupt usually doesn't.
 	 */
-	spin_lock_irqsave(&fotg210->lock, flags);
-	for (i = 0; i < fotg210->periodic_size; i++) {
-		p = fotg210->pshadow[i];
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
+	for (i = 0; i < fhcd2xx->periodic_size; i++) {
+		p = fhcd2xx->pshadow[i];
 		if (likely(!p.ptr))
 			continue;
 
-		tag = Q_NEXT_TYPE(fotg210, fotg210->periodic[i]);
+		tag = Q_NEXT_TYPE(fhcd2xx, fhcd2xx->periodic[i]);
 
 		temp = scnprintf(next, size, "%4d: ", i);
 		size -= temp;
 		next += temp;
 
 		do {
-			struct fotg210_qh_hw *hw;
+			struct fhcd2xx_qh_hw *hw;
 
-			switch (hc32_to_cpu(fotg210, tag)) {
+			switch (hc32_to_cpu(fhcd2xx, tag)) {
 			case Q_TYPE_QH:
 				hw = p.qh->hw;
 				temp = scnprintf(next, size, " qh%d-%04x/%p",
 						p.qh->period,
-						hc32_to_cpup(fotg210,
+						hc32_to_cpup(fhcd2xx,
 							&hw->hw_info2)
 							/* uframe masks */
 							& (QH_CMASK | QH_SMASK),
@@ -599,27 +599,27 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 				/* show more info the first time around */
 				if (temp == seen_count) {
 					temp = output_buf_tds_dir(next,
-								  fotg210, hw,
+								  fhcd2xx, hw,
 								  p.qh, size);
 
 					if (seen_count < DBG_SCHED_LIMIT)
 						seen[seen_count++].qh = p.qh;
 				} else
 					temp = 0;
-				tag = Q_NEXT_TYPE(fotg210, hw->hw_next);
+				tag = Q_NEXT_TYPE(fhcd2xx, hw->hw_next);
 				p = p.qh->qh_next;
 				break;
 			case Q_TYPE_FSTN:
 				temp = scnprintf(next, size,
 					" fstn-%8x/%p", p.fstn->hw_prev,
 					p.fstn);
-				tag = Q_NEXT_TYPE(fotg210, p.fstn->hw_next);
+				tag = Q_NEXT_TYPE(fhcd2xx, p.fstn->hw_next);
 				p = p.fstn->fstn_next;
 				break;
 			case Q_TYPE_ITD:
 				temp = scnprintf(next, size,
 					" itd/%p", p.itd);
-				tag = Q_NEXT_TYPE(fotg210, p.itd->hw_next);
+				tag = Q_NEXT_TYPE(fhcd2xx, p.itd->hw_next);
 				p = p.itd->itd_next;
 				break;
 			}
@@ -631,23 +631,23 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 		size -= temp;
 		next += temp;
 	}
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 	kfree(seen);
 
 	return buf->alloc_size - size;
 }
 #undef DBG_SCHED_LIMIT
 
-static const char *rh_state_string(struct fotg210_hcd *fotg210)
+static const char *rh_state_string(struct fhcd2xx_hcd *fhcd2xx)
 {
-	switch (fotg210->rh_state) {
-	case FOTG210_RH_HALTED:
+	switch (fhcd2xx->rh_state) {
+	case FHCD2XX_RH_HALTED:
 		return "halted";
-	case FOTG210_RH_SUSPENDED:
+	case FHCD2XX_RH_SUSPENDED:
 		return "suspended";
-	case FOTG210_RH_RUNNING:
+	case FHCD2XX_RH_RUNNING:
 		return "running";
-	case FOTG210_RH_STOPPING:
+	case FHCD2XX_RH_STOPPING:
 		return "stopping";
 	}
 	return "?";
@@ -656,7 +656,7 @@ static const char *rh_state_string(struct fotg210_hcd *fotg210)
 static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 {
 	struct usb_hcd *hcd;
-	struct fotg210_hcd *fotg210;
+	struct fhcd2xx_hcd *fhcd2xx;
 	unsigned long flags;
 	unsigned temp, size, i;
 	char *next, scratch[80];
@@ -664,11 +664,11 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 	static const char label[] = "";
 
 	hcd = bus_to_hcd(buf->bus);
-	fotg210 = hcd_to_fotg210(hcd);
+	fhcd2xx = hcd_to_fhcd2xx(hcd);
 	next = buf->output_buf;
 	size = buf->alloc_size;
 
-	spin_lock_irqsave(&fotg210->lock, flags);
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
 
 	if (!HCD_HW_ACCESSIBLE(hcd)) {
 		size = scnprintf(next, size,
@@ -682,8 +682,8 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 	}
 
 	/* Capability Registers */
-	i = HC_VERSION(fotg210, fotg210_readl(fotg210,
-					      &fotg210->caps->hc_capbase));
+	i = HC_VERSION(fhcd2xx, fhcd2xx_readl(fhcd2xx,
+					      &fhcd2xx->caps->hc_capbase));
 	temp = scnprintf(next, size,
 		"bus %s, device %s\n"
 		"%s\n"
@@ -691,68 +691,68 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 		hcd->self.controller->bus->name,
 		dev_name(hcd->self.controller),
 		hcd->product_desc,
-		i >> 8, i & 0x0ff, rh_state_string(fotg210));
+		i >> 8, i & 0x0ff, rh_state_string(fhcd2xx));
 	size -= temp;
 	next += temp;
 
 	/* FIXME interpret both types of params */
-	i = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
+	i = fhcd2xx_readl(fhcd2xx, &fhcd2xx->caps->hcs_params);
 	temp = scnprintf(next, size, "structural params 0x%08x\n", i);
 	size -= temp;
 	next += temp;
 
-	i = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
+	i = fhcd2xx_readl(fhcd2xx, &fhcd2xx->caps->hcc_params);
 	temp = scnprintf(next, size, "capability params 0x%08x\n", i);
 	size -= temp;
 	next += temp;
 
 	/* Operational Registers */
 	temp = dbg_status_buf(scratch, sizeof(scratch), label,
-			fotg210_readl(fotg210, &fotg210->regs->status));
+			fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->status));
 	temp = scnprintf(next, size, fmt, temp, scratch);
 	size -= temp;
 	next += temp;
 
 	temp = dbg_command_buf(scratch, sizeof(scratch), label,
-			fotg210_readl(fotg210, &fotg210->regs->command));
+			fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->command));
 	temp = scnprintf(next, size, fmt, temp, scratch);
 	size -= temp;
 	next += temp;
 
 	temp = dbg_intr_buf(scratch, sizeof(scratch), label,
-			fotg210_readl(fotg210, &fotg210->regs->intr_enable));
+			fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->intr_enable));
 	temp = scnprintf(next, size, fmt, temp, scratch);
 	size -= temp;
 	next += temp;
 
 	temp = scnprintf(next, size, "uframe %04x\n",
-			fotg210_read_frame_index(fotg210));
+			fhcd2xx_read_frame_index(fhcd2xx));
 	size -= temp;
 	next += temp;
 
-	if (fotg210->async_unlink) {
+	if (fhcd2xx->async_unlink) {
 		temp = scnprintf(next, size, "async unlink qh %p\n",
-				fotg210->async_unlink);
+				fhcd2xx->async_unlink);
 		size -= temp;
 		next += temp;
 	}
 
-#ifdef FOTG210_STATS
+#ifdef FHCD2XX_STATS
 	temp = scnprintf(next, size,
 		"irq normal %ld err %ld iaa %ld(lost %ld)\n",
-		fotg210->stats.normal, fotg210->stats.error, fotg210->stats.iaa,
-		fotg210->stats.lost_iaa);
+		fhcd2xx->stats.normal, fhcd2xx->stats.error, fhcd2xx->stats.iaa,
+		fhcd2xx->stats.lost_iaa);
 	size -= temp;
 	next += temp;
 
 	temp = scnprintf(next, size, "complete %ld unlink %ld\n",
-		fotg210->stats.complete, fotg210->stats.unlink);
+		fhcd2xx->stats.complete, fhcd2xx->stats.unlink);
 	size -= temp;
 	next += temp;
 #endif
 
 done:
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 
 	return buf->alloc_size - size;
 }
@@ -860,36 +860,36 @@ static int debug_registers_open(struct inode *inode, struct file *file)
 	return file->private_data ? 0 : -ENOMEM;
 }
 
-static inline void create_debug_files(struct fotg210_hcd *fotg210)
+static inline void create_debug_files(struct fhcd2xx_hcd *fhcd2xx)
 {
-	struct usb_bus *bus = &fotg210_to_hcd(fotg210)->self;
+	struct usb_bus *bus = &fhcd2xx_to_hcd(fhcd2xx)->self;
 
-	fotg210->debug_dir = debugfs_create_dir(bus->bus_name,
-						fotg210_debug_root);
-	if (!fotg210->debug_dir)
+	fhcd2xx->debug_dir = debugfs_create_dir(bus->bus_name,
+						fhcd2xx_debug_root);
+	if (!fhcd2xx->debug_dir)
 		return;
 
-	if (!debugfs_create_file("async", S_IRUGO, fotg210->debug_dir, bus,
+	if (!debugfs_create_file("async", S_IRUGO, fhcd2xx->debug_dir, bus,
 						&debug_async_fops))
 		goto file_error;
 
-	if (!debugfs_create_file("periodic", S_IRUGO, fotg210->debug_dir, bus,
+	if (!debugfs_create_file("periodic", S_IRUGO, fhcd2xx->debug_dir, bus,
 						&debug_periodic_fops))
 		goto file_error;
 
-	if (!debugfs_create_file("registers", S_IRUGO, fotg210->debug_dir, bus,
+	if (!debugfs_create_file("registers", S_IRUGO, fhcd2xx->debug_dir, bus,
 						    &debug_registers_fops))
 		goto file_error;
 
 	return;
 
 file_error:
-	debugfs_remove_recursive(fotg210->debug_dir);
+	debugfs_remove_recursive(fhcd2xx->debug_dir);
 }
 
-static inline void remove_debug_files(struct fotg210_hcd *fotg210)
+static inline void remove_debug_files(struct fhcd2xx_hcd *fhcd2xx)
 {
-	debugfs_remove_recursive(fotg210->debug_dir);
+	debugfs_remove_recursive(fhcd2xx->debug_dir);
 }
 
 /*
@@ -909,13 +909,13 @@ static inline void remove_debug_files(struct fotg210_hcd *fotg210)
  * before driver shutdown. But it also seems to be caused by bugs in cardbus
  * bridge shutdown:  shutting down the bridge before the devices using it.
  */
-static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
+static int handshake(struct fhcd2xx_hcd *fhcd2xx, void __iomem *ptr,
 		     u32 mask, u32 done, int usec)
 {
 	u32 result;
 
 	do {
-		result = fotg210_readl(fotg210, ptr);
+		result = fhcd2xx_readl(fhcd2xx, ptr);
 		if (result == ~(u32)0)		/* card removed */
 			return -ENODEV;
 		result &= mask;
@@ -931,28 +931,28 @@ static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
  * Force HC to halt state from unknown (EHCI spec section 2.3).
  * Must be called with interrupts enabled and the lock not held.
  */
-static int fotg210_halt(struct fotg210_hcd *fotg210)
+static int fhcd2xx_halt(struct fhcd2xx_hcd *fhcd2xx)
 {
 	u32 temp;
 
-	spin_lock_irq(&fotg210->lock);
+	spin_lock_irq(&fhcd2xx->lock);
 
 	/* disable any irqs left enabled by previous code */
-	fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
+	fhcd2xx_writel(fhcd2xx, 0, &fhcd2xx->regs->intr_enable);
 
 	/*
-	 * This routine gets called during probe before fotg210->command
+	 * This routine gets called during probe before fhcd2xx->command
 	 * has been initialized, so we can't rely on its value.
 	 */
-	fotg210->command &= ~CMD_RUN;
-	temp = fotg210_readl(fotg210, &fotg210->regs->command);
+	fhcd2xx->command &= ~CMD_RUN;
+	temp = fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->command);
 	temp &= ~(CMD_RUN | CMD_IAAD);
-	fotg210_writel(fotg210, temp, &fotg210->regs->command);
+	fhcd2xx_writel(fhcd2xx, temp, &fhcd2xx->regs->command);
 
-	spin_unlock_irq(&fotg210->lock);
-	synchronize_irq(fotg210_to_hcd(fotg210)->irq);
+	spin_unlock_irq(&fhcd2xx->lock);
+	synchronize_irq(fhcd2xx_to_hcd(fhcd2xx)->irq);
 
-	return handshake(fotg210, &fotg210->regs->status,
+	return handshake(fhcd2xx, &fhcd2xx->regs->status,
 			  STS_HALT, STS_HALT, 16 * 125);
 }
 
@@ -960,33 +960,33 @@ static int fotg210_halt(struct fotg210_hcd *fotg210)
  * Reset a non-running (STS_HALT == 1) controller.
  * Must be called with interrupts enabled and the lock not held.
  */
-static int fotg210_reset(struct fotg210_hcd *fotg210)
+static int fhcd2xx_reset(struct fhcd2xx_hcd *fhcd2xx)
 {
 	int retval;
-	u32 command = fotg210_readl(fotg210, &fotg210->regs->command);
+	u32 command = fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->command);
 
 	/* If the EHCI debug controller is active, special care must be
 	 * taken before and after a host controller reset
 	 */
-	if (fotg210->debug && !dbgp_reset_prep(fotg210_to_hcd(fotg210)))
-		fotg210->debug = NULL;
+	if (fhcd2xx->debug && !dbgp_reset_prep(fhcd2xx_to_hcd(fhcd2xx)))
+		fhcd2xx->debug = NULL;
 
 	command |= CMD_RESET;
-	dbg_cmd(fotg210, "reset", command);
-	fotg210_writel(fotg210, command, &fotg210->regs->command);
-	fotg210->rh_state = FOTG210_RH_HALTED;
-	fotg210->next_statechange = jiffies;
-	retval = handshake(fotg210, &fotg210->regs->command,
+	dbg_cmd(fhcd2xx, "reset", command);
+	fhcd2xx_writel(fhcd2xx, command, &fhcd2xx->regs->command);
+	fhcd2xx->rh_state = FHCD2XX_RH_HALTED;
+	fhcd2xx->next_statechange = jiffies;
+	retval = handshake(fhcd2xx, &fhcd2xx->regs->command,
 			    CMD_RESET, 0, 250 * 1000);
 
 	if (retval)
 		return retval;
 
-	if (fotg210->debug)
-		dbgp_external_startup(fotg210_to_hcd(fotg210));
+	if (fhcd2xx->debug)
+		dbgp_external_startup(fhcd2xx_to_hcd(fhcd2xx));
 
-	fotg210->port_c_suspend = fotg210->suspended_ports =
-			fotg210->resuming_ports = 0;
+	fhcd2xx->port_c_suspend = fhcd2xx->suspended_ports =
+			fhcd2xx->resuming_ports = 0;
 	return retval;
 }
 
@@ -994,69 +994,69 @@ static int fotg210_reset(struct fotg210_hcd *fotg210)
  * Idle the controller (turn off the schedules).
  * Must be called with interrupts enabled and the lock not held.
  */
-static void fotg210_quiesce(struct fotg210_hcd *fotg210)
+static void fhcd2xx_quiesce(struct fhcd2xx_hcd *fhcd2xx)
 {
 	u32 temp;
 
-	if (fotg210->rh_state != FOTG210_RH_RUNNING)
+	if (fhcd2xx->rh_state != FHCD2XX_RH_RUNNING)
 		return;
 
 	/* wait for any schedule enables/disables to take effect */
-	temp = (fotg210->command << 10) & (STS_ASS | STS_PSS);
-	handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, temp,
+	temp = (fhcd2xx->command << 10) & (STS_ASS | STS_PSS);
+	handshake(fhcd2xx, &fhcd2xx->regs->status, STS_ASS | STS_PSS, temp,
 		  16 * 125);
 
 	/* then disable anything that's still active */
-	spin_lock_irq(&fotg210->lock);
-	fotg210->command &= ~(CMD_ASE | CMD_PSE);
-	fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
-	spin_unlock_irq(&fotg210->lock);
+	spin_lock_irq(&fhcd2xx->lock);
+	fhcd2xx->command &= ~(CMD_ASE | CMD_PSE);
+	fhcd2xx_writel(fhcd2xx, fhcd2xx->command, &fhcd2xx->regs->command);
+	spin_unlock_irq(&fhcd2xx->lock);
 
 	/* hardware can take 16 microframes to turn off ... */
-	handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, 0,
+	handshake(fhcd2xx, &fhcd2xx->regs->status, STS_ASS | STS_PSS, 0,
 		  16 * 125);
 }
 
-static void end_unlink_async(struct fotg210_hcd *fotg210);
-static void unlink_empty_async(struct fotg210_hcd *fotg210);
-static void fotg210_work(struct fotg210_hcd *fotg210);
-static void start_unlink_intr(struct fotg210_hcd *fotg210,
-			      struct fotg210_qh *qh);
-static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
+static void end_unlink_async(struct fhcd2xx_hcd *fhcd2xx);
+static void unlink_empty_async(struct fhcd2xx_hcd *fhcd2xx);
+static void fhcd2xx_work(struct fhcd2xx_hcd *fhcd2xx);
+static void start_unlink_intr(struct fhcd2xx_hcd *fhcd2xx,
+			      struct fhcd2xx_qh *qh);
+static void end_unlink_intr(struct fhcd2xx_hcd *fhcd2xx, struct fhcd2xx_qh *qh);
 
 /* Set a bit in the USBCMD register */
-static void fotg210_set_command_bit(struct fotg210_hcd *fotg210, u32 bit)
+static void fhcd2xx_set_command_bit(struct fhcd2xx_hcd *fhcd2xx, u32 bit)
 {
-	fotg210->command |= bit;
-	fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
+	fhcd2xx->command |= bit;
+	fhcd2xx_writel(fhcd2xx, fhcd2xx->command, &fhcd2xx->regs->command);
 
 	/* unblock posted write */
-	fotg210_readl(fotg210, &fotg210->regs->command);
+	fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->command);
 }
 
 /* Clear a bit in the USBCMD register */
-static void fotg210_clear_command_bit(struct fotg210_hcd *fotg210, u32 bit)
+static void fhcd2xx_clear_command_bit(struct fhcd2xx_hcd *fhcd2xx, u32 bit)
 {
-	fotg210->command &= ~bit;
-	fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
+	fhcd2xx->command &= ~bit;
+	fhcd2xx_writel(fhcd2xx, fhcd2xx->command, &fhcd2xx->regs->command);
 
 	/* unblock posted write */
-	fotg210_readl(fotg210, &fotg210->regs->command);
+	fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->command);
 }
 
 /*
  * EHCI timer support...  Now using hrtimers.
  *
- * Lots of different events are triggered from fotg210->hrtimer.  Whenever
+ * Lots of different events are triggered from fhcd2xx->hrtimer.  Whenever
  * the timer routine runs, it checks each possible event; events that are
  * currently enabled and whose expiration time has passed get handled.
  * The set of enabled events is stored as a collection of bitflags in
- * fotg210->enabled_hrtimer_events, and they are numbered in order of
+ * fhcd2xx->enabled_hrtimer_events, and they are numbered in order of
  * increasing delay values (ranging between 1 ms and 100 ms).
  *
  * Rather than implementing a sorted list or tree of all pending events,
  * we keep track only of the lowest-numbered pending event, in
- * fotg210->next_hrtimer_event.  Whenever fotg210->hrtimer gets restarted, its
+ * fhcd2xx->next_hrtimer_event.  Whenever fhcd2xx->hrtimer gets restarted, its
  * expiration time is set to the timeout value for this event.
  *
  * As a result, events might not get handled right away; the actual delay
@@ -1070,166 +1070,166 @@ static void fotg210_clear_command_bit(struct fotg210_hcd *fotg210, u32 bit)
 /*
  * Delay lengths for the hrtimer event types.
  * Keep this list sorted by delay length, in the same order as
- * the event types indexed by enum fotg210_hrtimer_event in fotg210.h.
+ * the event types indexed by enum fhcd2xx_hrtimer_event in fhcd2xx.h.
  */
 static unsigned event_delays_ns[] = {
-	1 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_POLL_ASS */
-	1 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_POLL_PSS */
-	1 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_POLL_DEAD */
-	1125 * NSEC_PER_USEC,	/* FOTG210_HRTIMER_UNLINK_INTR */
-	2 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_FREE_ITDS */
-	6 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_ASYNC_UNLINKS */
-	10 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_IAA_WATCHDOG */
-	10 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_DISABLE_PERIODIC */
-	15 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_DISABLE_ASYNC */
-	100 * NSEC_PER_MSEC,	/* FOTG210_HRTIMER_IO_WATCHDOG */
+	1 * NSEC_PER_MSEC,	/* FHCD2XX_HRTIMER_POLL_ASS */
+	1 * NSEC_PER_MSEC,	/* FHCD2XX_HRTIMER_POLL_PSS */
+	1 * NSEC_PER_MSEC,	/* FHCD2XX_HRTIMER_POLL_DEAD */
+	1125 * NSEC_PER_USEC,	/* FHCD2XX_HRTIMER_UNLINK_INTR */
+	2 * NSEC_PER_MSEC,	/* FHCD2XX_HRTIMER_FREE_ITDS */
+	6 * NSEC_PER_MSEC,	/* FHCD2XX_HRTIMER_ASYNC_UNLINKS */
+	10 * NSEC_PER_MSEC,	/* FHCD2XX_HRTIMER_IAA_WATCHDOG */
+	10 * NSEC_PER_MSEC,	/* FHCD2XX_HRTIMER_DISABLE_PERIODIC */
+	15 * NSEC_PER_MSEC,	/* FHCD2XX_HRTIMER_DISABLE_ASYNC */
+	100 * NSEC_PER_MSEC,	/* FHCD2XX_HRTIMER_IO_WATCHDOG */
 };
 
 /* Enable a pending hrtimer event */
-static void fotg210_enable_event(struct fotg210_hcd *fotg210, unsigned event,
+static void fhcd2xx_enable_event(struct fhcd2xx_hcd *fhcd2xx, unsigned event,
 				 bool resched)
 {
-	ktime_t *timeout = &fotg210->hr_timeouts[event];
+	ktime_t *timeout = &fhcd2xx->hr_timeouts[event];
 
 	if (resched)
 		*timeout = ktime_add(ktime_get(),
 				ktime_set(0, event_delays_ns[event]));
-	fotg210->enabled_hrtimer_events |= (1 << event);
+	fhcd2xx->enabled_hrtimer_events |= (1 << event);
 
 	/* Track only the lowest-numbered pending event */
-	if (event < fotg210->next_hrtimer_event) {
-		fotg210->next_hrtimer_event = event;
-		hrtimer_start_range_ns(&fotg210->hrtimer, *timeout,
+	if (event < fhcd2xx->next_hrtimer_event) {
+		fhcd2xx->next_hrtimer_event = event;
+		hrtimer_start_range_ns(&fhcd2xx->hrtimer, *timeout,
 				NSEC_PER_MSEC, HRTIMER_MODE_ABS);
 	}
 }
 
 
 /* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */
-static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
+static void fhcd2xx_poll_ASS(struct fhcd2xx_hcd *fhcd2xx)
 {
 	unsigned actual, want;
 
 	/* Don't enable anything if the controller isn't running (e.g., died) */
-	if (fotg210->rh_state != FOTG210_RH_RUNNING)
+	if (fhcd2xx->rh_state != FHCD2XX_RH_RUNNING)
 		return;
 
-	want = (fotg210->command & CMD_ASE) ? STS_ASS : 0;
-	actual = fotg210_readl(fotg210, &fotg210->regs->status) & STS_ASS;
+	want = (fhcd2xx->command & CMD_ASE) ? STS_ASS : 0;
+	actual = fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->status) & STS_ASS;
 
 	if (want != actual) {
 
 		/* Poll again later, but give up after about 20 ms */
-		if (fotg210->ASS_poll_count++ < 20) {
-			fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_ASS,
+		if (fhcd2xx->ASS_poll_count++ < 20) {
+			fhcd2xx_enable_event(fhcd2xx, FHCD2XX_HRTIMER_POLL_ASS,
 					     true);
 			return;
 		}
-		fotg210_dbg(fotg210, "Waited too long for the async schedule status (%x/%x), giving up\n",
+		fhcd2xx_dbg(fhcd2xx, "Waited too long for the async schedule status (%x/%x), giving up\n",
 				want, actual);
 	}
-	fotg210->ASS_poll_count = 0;
+	fhcd2xx->ASS_poll_count = 0;
 
 	/* The status is up-to-date; restart or stop the schedule as needed */
 	if (want == 0) {	/* Stopped */
-		if (fotg210->async_count > 0)
-			fotg210_set_command_bit(fotg210, CMD_ASE);
+		if (fhcd2xx->async_count > 0)
+			fhcd2xx_set_command_bit(fhcd2xx, CMD_ASE);
 
 	} else {		/* Running */
-		if (fotg210->async_count == 0) {
+		if (fhcd2xx->async_count == 0) {
 
 			/* Turn off the schedule after a while */
-			fotg210_enable_event(fotg210,
-					     FOTG210_HRTIMER_DISABLE_ASYNC,
+			fhcd2xx_enable_event(fhcd2xx,
+					     FHCD2XX_HRTIMER_DISABLE_ASYNC,
 					     true);
 		}
 	}
 }
 
 /* Turn off the async schedule after a brief delay */
-static void fotg210_disable_ASE(struct fotg210_hcd *fotg210)
+static void fhcd2xx_disable_ASE(struct fhcd2xx_hcd *fhcd2xx)
 {
-	fotg210_clear_command_bit(fotg210, CMD_ASE);
+	fhcd2xx_clear_command_bit(fhcd2xx, CMD_ASE);
 }
 
 
 /* Poll the STS_PSS status bit; see when it agrees with CMD_PSE */
-static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
+static void fhcd2xx_poll_PSS(struct fhcd2xx_hcd *fhcd2xx)
 {
 	unsigned actual, want;
 
 	/* Don't do anything if the controller isn't running (e.g., died) */
-	if (fotg210->rh_state != FOTG210_RH_RUNNING)
+	if (fhcd2xx->rh_state != FHCD2XX_RH_RUNNING)
 		return;
 
-	want = (fotg210->command & CMD_PSE) ? STS_PSS : 0;
-	actual = fotg210_readl(fotg210, &fotg210->regs->status) & STS_PSS;
+	want = (fhcd2xx->command & CMD_PSE) ? STS_PSS : 0;
+	actual = fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->status) & STS_PSS;
 
 	if (want != actual) {
 
 		/* Poll again later, but give up after about 20 ms */
-		if (fotg210->PSS_poll_count++ < 20) {
-			fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_PSS,
+		if (fhcd2xx->PSS_poll_count++ < 20) {
+			fhcd2xx_enable_event(fhcd2xx, FHCD2XX_HRTIMER_POLL_PSS,
 					     true);
 			return;
 		}
-		fotg210_dbg(fotg210, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
+		fhcd2xx_dbg(fhcd2xx, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
 				want, actual);
 	}
-	fotg210->PSS_poll_count = 0;
+	fhcd2xx->PSS_poll_count = 0;
 
 	/* The status is up-to-date; restart or stop the schedule as needed */
 	if (want == 0) {	/* Stopped */
-		if (fotg210->periodic_count > 0)
-			fotg210_set_command_bit(fotg210, CMD_PSE);
+		if (fhcd2xx->periodic_count > 0)
+			fhcd2xx_set_command_bit(fhcd2xx, CMD_PSE);
 
 	} else {		/* Running */
-		if (fotg210->periodic_count == 0) {
+		if (fhcd2xx->periodic_count == 0) {
 
 			/* Turn off the schedule after a while */
-			fotg210_enable_event(fotg210,
-					     FOTG210_HRTIMER_DISABLE_PERIODIC,
+			fhcd2xx_enable_event(fhcd2xx,
+					     FHCD2XX_HRTIMER_DISABLE_PERIODIC,
 					     true);
 		}
 	}
 }
 
 /* Turn off the periodic schedule after a brief delay */
-static void fotg210_disable_PSE(struct fotg210_hcd *fotg210)
+static void fhcd2xx_disable_PSE(struct fhcd2xx_hcd *fhcd2xx)
 {
-	fotg210_clear_command_bit(fotg210, CMD_PSE);
+	fhcd2xx_clear_command_bit(fhcd2xx, CMD_PSE);
 }
 
 
 /* Poll the STS_HALT status bit; see when a dead controller stops */
-static void fotg210_handle_controller_death(struct fotg210_hcd *fotg210)
+static void fhcd2xx_handle_controller_death(struct fhcd2xx_hcd *fhcd2xx)
 {
-	if (!(fotg210_readl(fotg210, &fotg210->regs->status) & STS_HALT)) {
+	if (!(fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->status) & STS_HALT)) {
 
 		/* Give up after a few milliseconds */
-		if (fotg210->died_poll_count++ < 5) {
+		if (fhcd2xx->died_poll_count++ < 5) {
 			/* Try again later */
-			fotg210_enable_event(fotg210,
-					     FOTG210_HRTIMER_POLL_DEAD, true);
+			fhcd2xx_enable_event(fhcd2xx,
+					     FHCD2XX_HRTIMER_POLL_DEAD, true);
 			return;
 		}
-		fotg210_warn(fotg210, "Waited too long for the controller to stop, giving up\n");
+		fhcd2xx_warn(fhcd2xx, "Waited too long for the controller to stop, giving up\n");
 	}
 
 	/* Clean up the mess */
-	fotg210->rh_state = FOTG210_RH_HALTED;
-	fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
-	fotg210_work(fotg210);
-	end_unlink_async(fotg210);
+	fhcd2xx->rh_state = FHCD2XX_RH_HALTED;
+	fhcd2xx_writel(fhcd2xx, 0, &fhcd2xx->regs->intr_enable);
+	fhcd2xx_work(fhcd2xx);
+	end_unlink_async(fhcd2xx);
 
 	/* Not in process context, so don't try to reset the controller */
 }
 
 
 /* Handle unlinked interrupt QHs once they are gone from the hardware */
-static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
+static void fhcd2xx_handle_intr_unlinks(struct fhcd2xx_hcd *fhcd2xx)
 {
-	bool stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
+	bool stopped = (fhcd2xx->rh_state < FHCD2XX_RH_RUNNING);
 
 	/*
 	 * Process all the QHs on the intr_unlink list that were added
@@ -1238,63 +1238,63 @@ static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
 	 * current cycle.  But if the root hub isn't running then
 	 * process all the QHs on the list.
 	 */
-	fotg210->intr_unlinking = true;
-	while (fotg210->intr_unlink) {
-		struct fotg210_qh *qh = fotg210->intr_unlink;
+	fhcd2xx->intr_unlinking = true;
+	while (fhcd2xx->intr_unlink) {
+		struct fhcd2xx_qh *qh = fhcd2xx->intr_unlink;
 
-		if (!stopped && qh->unlink_cycle == fotg210->intr_unlink_cycle)
+		if (!stopped && qh->unlink_cycle == fhcd2xx->intr_unlink_cycle)
 			break;
-		fotg210->intr_unlink = qh->unlink_next;
+		fhcd2xx->intr_unlink = qh->unlink_next;
 		qh->unlink_next = NULL;
-		end_unlink_intr(fotg210, qh);
+		end_unlink_intr(fhcd2xx, qh);
 	}
 
 	/* Handle remaining entries later */
-	if (fotg210->intr_unlink) {
-		fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
+	if (fhcd2xx->intr_unlink) {
+		fhcd2xx_enable_event(fhcd2xx, FHCD2XX_HRTIMER_UNLINK_INTR,
 				     true);
-		++fotg210->intr_unlink_cycle;
+		++fhcd2xx->intr_unlink_cycle;
 	}
-	fotg210->intr_unlinking = false;
+	fhcd2xx->intr_unlinking = false;
 }
 
 
 /* Start another free-iTDs/siTDs cycle */
-static void start_free_itds(struct fotg210_hcd *fotg210)
-{
-	if (!(fotg210->enabled_hrtimer_events &
-			BIT(FOTG210_HRTIMER_FREE_ITDS))) {
-		fotg210->last_itd_to_free = list_entry(
-				fotg210->cached_itd_list.prev,
-				struct fotg210_itd, itd_list);
-		fotg210_enable_event(fotg210, FOTG210_HRTIMER_FREE_ITDS, true);
+static void start_free_itds(struct fhcd2xx_hcd *fhcd2xx)
+{
+	if (!(fhcd2xx->enabled_hrtimer_events &
+			BIT(FHCD2XX_HRTIMER_FREE_ITDS))) {
+		fhcd2xx->last_itd_to_free = list_entry(
+				fhcd2xx->cached_itd_list.prev,
+				struct fhcd2xx_itd, itd_list);
+		fhcd2xx_enable_event(fhcd2xx, FHCD2XX_HRTIMER_FREE_ITDS, true);
 	}
 }
 
 /* Wait for controller to stop using old iTDs and siTDs */
-static void end_free_itds(struct fotg210_hcd *fotg210)
+static void end_free_itds(struct fhcd2xx_hcd *fhcd2xx)
 {
-	struct fotg210_itd *itd, *n;
+	struct fhcd2xx_itd *itd, *n;
 
-	if (fotg210->rh_state < FOTG210_RH_RUNNING)
-		fotg210->last_itd_to_free = NULL;
+	if (fhcd2xx->rh_state < FHCD2XX_RH_RUNNING)
+		fhcd2xx->last_itd_to_free = NULL;
 
-	list_for_each_entry_safe(itd, n, &fotg210->cached_itd_list, itd_list) {
+	list_for_each_entry_safe(itd, n, &fhcd2xx->cached_itd_list, itd_list) {
 		list_del(&itd->itd_list);
-		dma_pool_free(fotg210->itd_pool, itd, itd->itd_dma);
-		if (itd == fotg210->last_itd_to_free)
+		dma_pool_free(fhcd2xx->itd_pool, itd, itd->itd_dma);
+		if (itd == fhcd2xx->last_itd_to_free)
 			break;
 	}
 
-	if (!list_empty(&fotg210->cached_itd_list))
-		start_free_itds(fotg210);
+	if (!list_empty(&fhcd2xx->cached_itd_list))
+		start_free_itds(fhcd2xx);
 }
 
 
 /* Handle lost (or very late) IAA interrupts */
-static void fotg210_iaa_watchdog(struct fotg210_hcd *fotg210)
+static void fhcd2xx_iaa_watchdog(struct fhcd2xx_hcd *fhcd2xx)
 {
-	if (fotg210->rh_state != FOTG210_RH_RUNNING)
+	if (fhcd2xx->rh_state != FHCD2XX_RH_RUNNING)
 		return;
 
 	/*
@@ -1303,7 +1303,7 @@ static void fotg210_iaa_watchdog(struct fotg210_hcd *fotg210)
 	 * (a) SMP races against real IAA firing and retriggering, and
 	 * (b) clean HC shutdown, when IAA watchdog was pending.
 	 */
-	if (fotg210->async_iaa) {
+	if (fhcd2xx->async_iaa) {
 		u32 cmd, status;
 
 		/* If we get here, IAA is *REALLY* late.  It's barely
@@ -1312,7 +1312,7 @@ static void fotg210_iaa_watchdog(struct fotg210_hcd *fotg210)
 		 * clear before we read STS_IAA.  (The HC should clear
 		 * CMD_IAAD when it sets STS_IAA.)
 		 */
-		cmd = fotg210_readl(fotg210, &fotg210->regs->command);
+		cmd = fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->command);
 
 		/*
 		 * If IAA is set here it either legitimately triggered
@@ -1321,36 +1321,36 @@ static void fotg210_iaa_watchdog(struct fotg210_hcd *fotg210)
 		 * - VIA seems to set IAA without triggering the IRQ;
 		 * - IAAD potentially cleared without setting IAA.
 		 */
-		status = fotg210_readl(fotg210, &fotg210->regs->status);
+		status = fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->status);
 		if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
-			COUNT(fotg210->stats.lost_iaa);
-			fotg210_writel(fotg210, STS_IAA,
-				       &fotg210->regs->status);
+			COUNT(fhcd2xx->stats.lost_iaa);
+			fhcd2xx_writel(fhcd2xx, STS_IAA,
+				       &fhcd2xx->regs->status);
 		}
 
-		fotg210_dbg(fotg210, "IAA watchdog: status %x cmd %x\n",
+		fhcd2xx_dbg(fhcd2xx, "IAA watchdog: status %x cmd %x\n",
 				status, cmd);
-		end_unlink_async(fotg210);
+		end_unlink_async(fhcd2xx);
 	}
 }
 
 
 /* Enable the I/O watchdog, if appropriate */
-static void turn_on_io_watchdog(struct fotg210_hcd *fotg210)
+static void turn_on_io_watchdog(struct fhcd2xx_hcd *fhcd2xx)
 {
 	/* Not needed if the controller isn't running or it's already enabled */
-	if (fotg210->rh_state != FOTG210_RH_RUNNING ||
-			(fotg210->enabled_hrtimer_events &
-				BIT(FOTG210_HRTIMER_IO_WATCHDOG)))
+	if (fhcd2xx->rh_state != FHCD2XX_RH_RUNNING ||
+			(fhcd2xx->enabled_hrtimer_events &
+				BIT(FHCD2XX_HRTIMER_IO_WATCHDOG)))
 		return;
 
 	/*
 	 * Isochronous transfers always need the watchdog.
 	 * For other sorts we use it only if the flag is set.
 	 */
-	if (fotg210->isoc_count > 0 || (fotg210->need_io_watchdog &&
-			fotg210->async_count + fotg210->intr_count > 0))
-		fotg210_enable_event(fotg210, FOTG210_HRTIMER_IO_WATCHDOG,
+	if (fhcd2xx->isoc_count > 0 || (fhcd2xx->need_io_watchdog &&
+			fhcd2xx->async_count + fhcd2xx->intr_count > 0))
+		fhcd2xx_enable_event(fhcd2xx, FHCD2XX_HRTIMER_IO_WATCHDOG,
 				     true);
 }
 
@@ -1358,56 +1358,56 @@ static void turn_on_io_watchdog(struct fotg210_hcd *fotg210)
 /*
  * Handler functions for the hrtimer event types.
  * Keep this array in the same order as the event types indexed by
- * enum fotg210_hrtimer_event in fotg210.h.
+ * enum fhcd2xx_hrtimer_event in fhcd2xx.h.
  */
-static void (*event_handlers[])(struct fotg210_hcd *) = {
-	fotg210_poll_ASS,			/* FOTG210_HRTIMER_POLL_ASS */
-	fotg210_poll_PSS,			/* FOTG210_HRTIMER_POLL_PSS */
-	fotg210_handle_controller_death,	/* FOTG210_HRTIMER_POLL_DEAD */
-	fotg210_handle_intr_unlinks,	/* FOTG210_HRTIMER_UNLINK_INTR */
-	end_free_itds,			/* FOTG210_HRTIMER_FREE_ITDS */
-	unlink_empty_async,		/* FOTG210_HRTIMER_ASYNC_UNLINKS */
-	fotg210_iaa_watchdog,		/* FOTG210_HRTIMER_IAA_WATCHDOG */
-	fotg210_disable_PSE,		/* FOTG210_HRTIMER_DISABLE_PERIODIC */
-	fotg210_disable_ASE,		/* FOTG210_HRTIMER_DISABLE_ASYNC */
-	fotg210_work,			/* FOTG210_HRTIMER_IO_WATCHDOG */
+static void (*event_handlers[])(struct fhcd2xx_hcd *) = {
+	fhcd2xx_poll_ASS,			/* FHCD2XX_HRTIMER_POLL_ASS */
+	fhcd2xx_poll_PSS,			/* FHCD2XX_HRTIMER_POLL_PSS */
+	fhcd2xx_handle_controller_death,	/* FHCD2XX_HRTIMER_POLL_DEAD */
+	fhcd2xx_handle_intr_unlinks,	/* FHCD2XX_HRTIMER_UNLINK_INTR */
+	end_free_itds,			/* FHCD2XX_HRTIMER_FREE_ITDS */
+	unlink_empty_async,		/* FHCD2XX_HRTIMER_ASYNC_UNLINKS */
+	fhcd2xx_iaa_watchdog,		/* FHCD2XX_HRTIMER_IAA_WATCHDOG */
+	fhcd2xx_disable_PSE,		/* FHCD2XX_HRTIMER_DISABLE_PERIODIC */
+	fhcd2xx_disable_ASE,		/* FHCD2XX_HRTIMER_DISABLE_ASYNC */
+	fhcd2xx_work,			/* FHCD2XX_HRTIMER_IO_WATCHDOG */
 };
 
-static enum hrtimer_restart fotg210_hrtimer_func(struct hrtimer *t)
+static enum hrtimer_restart fhcd2xx_hrtimer_func(struct hrtimer *t)
 {
-	struct fotg210_hcd *fotg210 =
-			container_of(t, struct fotg210_hcd, hrtimer);
+	struct fhcd2xx_hcd *fhcd2xx =
+			container_of(t, struct fhcd2xx_hcd, hrtimer);
 	ktime_t now;
 	unsigned long events;
 	unsigned long flags;
 	unsigned e;
 
-	spin_lock_irqsave(&fotg210->lock, flags);
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
 
-	events = fotg210->enabled_hrtimer_events;
-	fotg210->enabled_hrtimer_events = 0;
-	fotg210->next_hrtimer_event = FOTG210_HRTIMER_NO_EVENT;
+	events = fhcd2xx->enabled_hrtimer_events;
+	fhcd2xx->enabled_hrtimer_events = 0;
+	fhcd2xx->next_hrtimer_event = FHCD2XX_HRTIMER_NO_EVENT;
 
 	/*
 	 * Check each pending event.  If its time has expired, handle
 	 * the event; otherwise re-enable it.
 	 */
 	now = ktime_get();
-	for_each_set_bit(e, &events, FOTG210_HRTIMER_NUM_EVENTS) {
-		if (now.tv64 >= fotg210->hr_timeouts[e].tv64)
-			event_handlers[e](fotg210);
+	for_each_set_bit(e, &events, FHCD2XX_HRTIMER_NUM_EVENTS) {
+		if (now.tv64 >= fhcd2xx->hr_timeouts[e].tv64)
+			event_handlers[e](fhcd2xx);
 		else
-			fotg210_enable_event(fotg210, e, false);
+			fhcd2xx_enable_event(fhcd2xx, e, false);
 	}
 
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 	return HRTIMER_NORESTART;
 }
 
-#define fotg210_bus_suspend NULL
-#define fotg210_bus_resume NULL
+#define fhcd2xx_bus_suspend NULL
+#define fhcd2xx_bus_resume NULL
 
-static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
+static int check_reset_complete(struct fhcd2xx_hcd *fhcd2xx, int index,
 				u32 __iomem *status_reg, int port_status)
 {
 	if (!(port_status & PORT_CONNECT))
@@ -1416,12 +1416,12 @@ static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
 	/* if reset finished and it's still not enabled -- handoff */
 	if (!(port_status & PORT_PE)) {
 		/* with integrated TT, there's nobody to hand it to! */
-		fotg210_dbg(fotg210,
+		fhcd2xx_dbg(fhcd2xx,
 			"Failed to enable port %d on root hub TT\n",
 			index+1);
 		return port_status;
 	}
-	fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
+	fhcd2xx_dbg(fhcd2xx, "port %d reset complete, port enabled\n",
 		    index + 1);
 
 	return port_status;
@@ -1430,9 +1430,9 @@ static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
 
 /* build "status change" packet (one or two bytes) from HC registers */
 
-static int fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
+static int fhcd2xx_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fhcd2xx_hcd *fhcd2xx = hcd_to_fhcd2xx(hcd);
 	u32 temp, status;
 	u32 mask;
 	int retval = 1;
@@ -1444,7 +1444,7 @@ static int fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
 	/* Inform the core about resumes-in-progress by returning
 	 * a non-zero value even if there are no status changes.
 	 */
-	status = fotg210->resuming_ports;
+	status = fhcd2xx->resuming_ports;
 
 	mask = PORT_CSC | PORT_PEC;
 	/* PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND */
@@ -1452,9 +1452,9 @@ static int fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
 	/* no hub change reports (bit 0) for now (power, ...) */
 
 	/* port N changes (bit N)? */
-	spin_lock_irqsave(&fotg210->lock, flags);
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
 
-	temp = fotg210_readl(fotg210, &fotg210->regs->port_status);
+	temp = fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->port_status);
 
 	/*
 	 * Return status information even for ports with OWNER set.
@@ -1463,25 +1463,25 @@ static int fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
 	 * controller by the user.
 	 */
 
-	if ((temp & mask) != 0 || test_bit(0, &fotg210->port_c_suspend)
-			|| (fotg210->reset_done[0] && time_after_eq(
-				jiffies, fotg210->reset_done[0]))) {
+	if ((temp & mask) != 0 || test_bit(0, &fhcd2xx->port_c_suspend)
+			|| (fhcd2xx->reset_done[0] && time_after_eq(
+				jiffies, fhcd2xx->reset_done[0]))) {
 		buf[0] |= 1 << 1;
 		status = STS_PCD;
 	}
 	/* FIXME autosuspend idle root hubs */
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 	return status ? retval : 0;
 }
 
-static void fotg210_hub_descriptor(struct fotg210_hcd *fotg210,
+static void fhcd2xx_hub_descriptor(struct fhcd2xx_hcd *fhcd2xx,
 				   struct usb_hub_descriptor *desc)
 {
-	int ports = HCS_N_PORTS(fotg210->hcs_params);
+	int ports = HCS_N_PORTS(fhcd2xx->hcs_params);
 	u16 temp;
 
 	desc->bDescriptorType = USB_DT_HUB;
-	desc->bPwrOn2PwrGood = 10;	/* fotg210 1.0, 2.3.9 says 20ms max */
+	desc->bPwrOn2PwrGood = 10;	/* fhcd2xx 1.0, 2.3.9 says 20ms max */
 	desc->bHubContrCurrent = 0;
 
 	desc->bNbrPorts = ports;
@@ -1497,12 +1497,12 @@ static void fotg210_hub_descriptor(struct fotg210_hcd *fotg210,
 	desc->wHubCharacteristics = cpu_to_le16(temp);
 }
 
-static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+static int fhcd2xx_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 			       u16 wIndex, char *buf, u16 wLength)
 {
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-	int ports = HCS_N_PORTS(fotg210->hcs_params);
-	u32 __iomem *status_reg = &fotg210->regs->port_status;
+	struct fhcd2xx_hcd *fhcd2xx = hcd_to_fhcd2xx(hcd);
+	int ports = HCS_N_PORTS(fhcd2xx->hcs_params);
+	u32 __iomem *status_reg = &fhcd2xx->regs->port_status;
 	u32 temp, temp1, status;
 	unsigned long flags;
 	int retval = 0;
@@ -1515,7 +1515,7 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 	 * power, "this is the one", etc.  EHCI spec supports this.
 	 */
 
-	spin_lock_irqsave(&fotg210->lock, flags);
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
 	switch (typeReq) {
 	case ClearHubFeature:
 		switch (wValue) {
@@ -1531,7 +1531,7 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		if (!wIndex || wIndex > ports)
 			goto error;
 		wIndex--;
-		temp = fotg210_readl(fotg210, status_reg);
+		temp = fhcd2xx_readl(fhcd2xx, status_reg);
 		temp &= ~PORT_RWC_BITS;
 
 		/*
@@ -1543,10 +1543,10 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
 		switch (wValue) {
 		case USB_PORT_FEAT_ENABLE:
-			fotg210_writel(fotg210, temp & ~PORT_PE, status_reg);
+			fhcd2xx_writel(fhcd2xx, temp & ~PORT_PE, status_reg);
 			break;
 		case USB_PORT_FEAT_C_ENABLE:
-			fotg210_writel(fotg210, temp | PORT_PEC, status_reg);
+			fhcd2xx_writel(fhcd2xx, temp | PORT_PEC, status_reg);
 			break;
 		case USB_PORT_FEAT_SUSPEND:
 			if (temp & PORT_RESET)
@@ -1557,19 +1557,19 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 				goto error;
 
 			/* resume signaling for 20 msec */
-			fotg210_writel(fotg210, temp | PORT_RESUME, status_reg);
-			fotg210->reset_done[wIndex] = jiffies
+			fhcd2xx_writel(fhcd2xx, temp | PORT_RESUME, status_reg);
+			fhcd2xx->reset_done[wIndex] = jiffies
 					+ msecs_to_jiffies(USB_RESUME_TIMEOUT);
 			break;
 		case USB_PORT_FEAT_C_SUSPEND:
-			clear_bit(wIndex, &fotg210->port_c_suspend);
+			clear_bit(wIndex, &fhcd2xx->port_c_suspend);
 			break;
 		case USB_PORT_FEAT_C_CONNECTION:
-			fotg210_writel(fotg210, temp | PORT_CSC, status_reg);
+			fhcd2xx_writel(fhcd2xx, temp | PORT_CSC, status_reg);
 			break;
 		case USB_PORT_FEAT_C_OVER_CURRENT:
-			fotg210_writel(fotg210, temp | OTGISR_OVC,
-				       &fotg210->regs->otgisr);
+			fhcd2xx_writel(fhcd2xx, temp | OTGISR_OVC,
+				       &fhcd2xx->regs->otgisr);
 			break;
 		case USB_PORT_FEAT_C_RESET:
 			/* GetPortStatus clears reset */
@@ -1577,10 +1577,10 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		default:
 			goto error;
 		}
-		fotg210_readl(fotg210, &fotg210->regs->command);
+		fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->command);
 		break;
 	case GetHubDescriptor:
-		fotg210_hub_descriptor(fotg210, (struct usb_hub_descriptor *)
+		fhcd2xx_hub_descriptor(fhcd2xx, (struct usb_hub_descriptor *)
 			buf);
 		break;
 	case GetHubStatus:
@@ -1593,7 +1593,7 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 			goto error;
 		wIndex--;
 		status = 0;
-		temp = fotg210_readl(fotg210, status_reg);
+		temp = fhcd2xx_readl(fhcd2xx, status_reg);
 
 		/* wPortChange bits */
 		if (temp & PORT_CSC)
@@ -1601,7 +1601,7 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		if (temp & PORT_PEC)
 			status |= USB_PORT_STAT_C_ENABLE << 16;
 
-		temp1 = fotg210_readl(fotg210, &fotg210->regs->otgisr);
+		temp1 = fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->otgisr);
 		if (temp1 & OTGISR_OVC)
 			status |= USB_PORT_STAT_C_OVERCURRENT << 16;
 
@@ -1609,32 +1609,32 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		if (temp & PORT_RESUME) {
 
 			/* Remote Wakeup received? */
-			if (!fotg210->reset_done[wIndex]) {
+			if (!fhcd2xx->reset_done[wIndex]) {
 				/* resume signaling for 20 msec */
-				fotg210->reset_done[wIndex] = jiffies
+				fhcd2xx->reset_done[wIndex] = jiffies
 						+ msecs_to_jiffies(20);
 				/* check the port again */
-				mod_timer(&fotg210_to_hcd(fotg210)->rh_timer,
-						fotg210->reset_done[wIndex]);
+				mod_timer(&fhcd2xx_to_hcd(fhcd2xx)->rh_timer,
+						fhcd2xx->reset_done[wIndex]);
 			}
 
 			/* resume completed? */
 			else if (time_after_eq(jiffies,
-					fotg210->reset_done[wIndex])) {
-				clear_bit(wIndex, &fotg210->suspended_ports);
-				set_bit(wIndex, &fotg210->port_c_suspend);
-				fotg210->reset_done[wIndex] = 0;
+					fhcd2xx->reset_done[wIndex])) {
+				clear_bit(wIndex, &fhcd2xx->suspended_ports);
+				set_bit(wIndex, &fhcd2xx->port_c_suspend);
+				fhcd2xx->reset_done[wIndex] = 0;
 
 				/* stop resume signaling */
-				temp = fotg210_readl(fotg210, status_reg);
-				fotg210_writel(fotg210,
+				temp = fhcd2xx_readl(fhcd2xx, status_reg);
+				fhcd2xx_writel(fhcd2xx,
 					temp & ~(PORT_RWC_BITS | PORT_RESUME),
 					status_reg);
-				clear_bit(wIndex, &fotg210->resuming_ports);
-				retval = handshake(fotg210, status_reg,
+				clear_bit(wIndex, &fhcd2xx->resuming_ports);
+				retval = handshake(fhcd2xx, status_reg,
 					   PORT_RESUME, 0, 2000 /* 2msec */);
 				if (retval != 0) {
-					fotg210_err(fotg210,
+					fhcd2xx_err(fhcd2xx,
 						"port %d resume error %d\n",
 						wIndex + 1, retval);
 					goto error;
@@ -1646,44 +1646,44 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		/* whoever resets must GetPortStatus to complete it!! */
 		if ((temp & PORT_RESET)
 				&& time_after_eq(jiffies,
-					fotg210->reset_done[wIndex])) {
+					fhcd2xx->reset_done[wIndex])) {
 			status |= USB_PORT_STAT_C_RESET << 16;
-			fotg210->reset_done[wIndex] = 0;
-			clear_bit(wIndex, &fotg210->resuming_ports);
+			fhcd2xx->reset_done[wIndex] = 0;
+			clear_bit(wIndex, &fhcd2xx->resuming_ports);
 
 			/* force reset to complete */
-			fotg210_writel(fotg210,
+			fhcd2xx_writel(fhcd2xx,
 				       temp & ~(PORT_RWC_BITS | PORT_RESET),
 				       status_reg);
 			/* REVISIT:  some hardware needs 550+ usec to clear
 			 * this bit; seems too long to spin routinely...
 			 */
-			retval = handshake(fotg210, status_reg,
+			retval = handshake(fhcd2xx, status_reg,
 					PORT_RESET, 0, 1000);
 			if (retval != 0) {
-				fotg210_err(fotg210, "port %d reset error %d\n",
+				fhcd2xx_err(fhcd2xx, "port %d reset error %d\n",
 					wIndex + 1, retval);
 				goto error;
 			}
 
 			/* see what we found out */
-			temp = check_reset_complete(fotg210, wIndex, status_reg,
-					fotg210_readl(fotg210, status_reg));
+			temp = check_reset_complete(fhcd2xx, wIndex, status_reg,
+					fhcd2xx_readl(fhcd2xx, status_reg));
 		}
 
 		if (!(temp & (PORT_RESUME|PORT_RESET))) {
-			fotg210->reset_done[wIndex] = 0;
-			clear_bit(wIndex, &fotg210->resuming_ports);
+			fhcd2xx->reset_done[wIndex] = 0;
+			clear_bit(wIndex, &fhcd2xx->resuming_ports);
 		}
 
 		/* transfer dedicated ports to the companion hc */
 		if ((temp & PORT_CONNECT) &&
-				test_bit(wIndex, &fotg210->companion_ports)) {
+				test_bit(wIndex, &fhcd2xx->companion_ports)) {
 			temp &= ~PORT_RWC_BITS;
-			fotg210_writel(fotg210, temp, status_reg);
-			fotg210_dbg(fotg210, "port %d --> companion\n",
+			fhcd2xx_writel(fhcd2xx, temp, status_reg);
+			fhcd2xx_dbg(fhcd2xx, "port %d --> companion\n",
 				    wIndex + 1);
-			temp = fotg210_readl(fotg210, status_reg);
+			temp = fhcd2xx_readl(fhcd2xx, status_reg);
 		}
 
 		/*
@@ -1694,7 +1694,7 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
 		if (temp & PORT_CONNECT) {
 			status |= USB_PORT_STAT_CONNECTION;
-			status |= fotg210_port_speed(fotg210, temp);
+			status |= fhcd2xx_port_speed(fhcd2xx, temp);
 		}
 		if (temp & PORT_PE)
 			status |= USB_PORT_STAT_ENABLE;
@@ -1702,24 +1702,24 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		/* maybe the port was unsuspended without our knowledge */
 		if (temp & (PORT_SUSPEND|PORT_RESUME)) {
 			status |= USB_PORT_STAT_SUSPEND;
-		} else if (test_bit(wIndex, &fotg210->suspended_ports)) {
-			clear_bit(wIndex, &fotg210->suspended_ports);
-			clear_bit(wIndex, &fotg210->resuming_ports);
-			fotg210->reset_done[wIndex] = 0;
+		} else if (test_bit(wIndex, &fhcd2xx->suspended_ports)) {
+			clear_bit(wIndex, &fhcd2xx->suspended_ports);
+			clear_bit(wIndex, &fhcd2xx->resuming_ports);
+			fhcd2xx->reset_done[wIndex] = 0;
 			if (temp & PORT_PE)
-				set_bit(wIndex, &fotg210->port_c_suspend);
+				set_bit(wIndex, &fhcd2xx->port_c_suspend);
 		}
 
-		temp1 = fotg210_readl(fotg210, &fotg210->regs->otgisr);
+		temp1 = fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->otgisr);
 		if (temp1 & OTGISR_OVC)
 			status |= USB_PORT_STAT_OVERCURRENT;
 		if (temp & PORT_RESET)
 			status |= USB_PORT_STAT_RESET;
-		if (test_bit(wIndex, &fotg210->port_c_suspend))
+		if (test_bit(wIndex, &fhcd2xx->port_c_suspend))
 			status |= USB_PORT_STAT_C_SUSPEND << 16;
 
 		if (status & ~0xffff)	/* only if wPortChange is interesting */
-			dbg_port(fotg210, "GetStatus", wIndex + 1, temp);
+			dbg_port(fhcd2xx, "GetStatus", wIndex + 1, temp);
 		put_unaligned_le32(status, buf);
 		break;
 	case SetHubFeature:
@@ -1739,7 +1739,7 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		if (!wIndex || wIndex > ports)
 			goto error;
 		wIndex--;
-		temp = fotg210_readl(fotg210, status_reg);
+		temp = fhcd2xx_readl(fhcd2xx, status_reg);
 		temp &= ~PORT_RWC_BITS;
 		switch (wValue) {
 		case USB_PORT_FEAT_SUSPEND:
@@ -1751,9 +1751,9 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 			 * Set appropriate bit thus could put phy into low power
 			 * mode if we have hostpc feature
 			 */
-			fotg210_writel(fotg210, temp | PORT_SUSPEND,
+			fhcd2xx_writel(fhcd2xx, temp | PORT_SUSPEND,
 				       status_reg);
-			set_bit(wIndex, &fotg210->suspended_ports);
+			set_bit(wIndex, &fhcd2xx->suspended_ports);
 			break;
 		case USB_PORT_FEAT_RESET:
 			if (temp & PORT_RESUME)
@@ -1762,7 +1762,7 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 			 * which can be fine if this root hub has a
 			 * transaction translator built in.
 			 */
-			fotg210_dbg(fotg210, "port %d reset\n", wIndex + 1);
+			fhcd2xx_dbg(fhcd2xx, "port %d reset\n", wIndex + 1);
 			temp |= PORT_RESET;
 			temp &= ~PORT_PE;
 
@@ -1770,9 +1770,9 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 			 * caller must wait, then call GetPortStatus
 			 * usb 2.0 spec says 50 ms resets on root
 			 */
-			fotg210->reset_done[wIndex] = jiffies
+			fhcd2xx->reset_done[wIndex] = jiffies
 					+ msecs_to_jiffies(50);
-			fotg210_writel(fotg210, temp, status_reg);
+			fhcd2xx_writel(fhcd2xx, temp, status_reg);
 			break;
 
 		/* For downstream facing ports (these):  one hub port is put
@@ -1784,30 +1784,30 @@ static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		case USB_PORT_FEAT_TEST:
 			if (!selector || selector > 5)
 				goto error;
-			spin_unlock_irqrestore(&fotg210->lock, flags);
-			fotg210_quiesce(fotg210);
-			spin_lock_irqsave(&fotg210->lock, flags);
+			spin_unlock_irqrestore(&fhcd2xx->lock, flags);
+			fhcd2xx_quiesce(fhcd2xx);
+			spin_lock_irqsave(&fhcd2xx->lock, flags);
 
 			/* Put all enabled ports into suspend */
-			temp = fotg210_readl(fotg210, status_reg) &
+			temp = fhcd2xx_readl(fhcd2xx, status_reg) &
 				~PORT_RWC_BITS;
 			if (temp & PORT_PE)
-				fotg210_writel(fotg210, temp | PORT_SUSPEND,
+				fhcd2xx_writel(fhcd2xx, temp | PORT_SUSPEND,
 						status_reg);
 
-			spin_unlock_irqrestore(&fotg210->lock, flags);
-			fotg210_halt(fotg210);
-			spin_lock_irqsave(&fotg210->lock, flags);
+			spin_unlock_irqrestore(&fhcd2xx->lock, flags);
+			fhcd2xx_halt(fhcd2xx);
+			spin_lock_irqsave(&fhcd2xx->lock, flags);
 
-			temp = fotg210_readl(fotg210, status_reg);
+			temp = fhcd2xx_readl(fhcd2xx, status_reg);
 			temp |= selector << 16;
-			fotg210_writel(fotg210, temp, status_reg);
+			fhcd2xx_writel(fhcd2xx, temp, status_reg);
 			break;
 
 		default:
 			goto error;
 		}
-		fotg210_readl(fotg210, &fotg210->regs->command);
+		fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->command);
 		break;
 
 	default:
@@ -1815,17 +1815,17 @@ error:
 		/* "stall" on error */
 		retval = -EPIPE;
 	}
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 	return retval;
 }
 
-static void __maybe_unused fotg210_relinquish_port(struct usb_hcd *hcd,
+static void __maybe_unused fhcd2xx_relinquish_port(struct usb_hcd *hcd,
 		int portnum)
 {
 	return;
 }
 
-static int __maybe_unused fotg210_port_handed_over(struct usb_hcd *hcd,
+static int __maybe_unused fhcd2xx_port_handed_over(struct usb_hcd *hcd,
 						   int portnum)
 {
 	return 0;
@@ -1843,61 +1843,61 @@ static int __maybe_unused fotg210_port_handed_over(struct usb_hcd *hcd,
  */
 
 /* Allocate the key transfer structures from the previously allocated pool */
-static inline void fotg210_qtd_init(struct fotg210_hcd *fotg210,
-				    struct fotg210_qtd *qtd, dma_addr_t dma)
+static inline void fhcd2xx_qtd_init(struct fhcd2xx_hcd *fhcd2xx,
+				    struct fhcd2xx_qtd *qtd, dma_addr_t dma)
 {
 	memset(qtd, 0, sizeof(*qtd));
 	qtd->qtd_dma = dma;
-	qtd->hw_token = cpu_to_hc32(fotg210, QTD_STS_HALT);
-	qtd->hw_next = FOTG210_LIST_END(fotg210);
-	qtd->hw_alt_next = FOTG210_LIST_END(fotg210);
+	qtd->hw_token = cpu_to_hc32(fhcd2xx, QTD_STS_HALT);
+	qtd->hw_next = FHCD2XX_LIST_END(fhcd2xx);
+	qtd->hw_alt_next = FHCD2XX_LIST_END(fhcd2xx);
 	INIT_LIST_HEAD(&qtd->qtd_list);
 }
 
-static struct fotg210_qtd *fotg210_qtd_alloc(struct fotg210_hcd *fotg210,
+static struct fhcd2xx_qtd *fhcd2xx_qtd_alloc(struct fhcd2xx_hcd *fhcd2xx,
 					     gfp_t flags)
 {
-	struct fotg210_qtd *qtd;
+	struct fhcd2xx_qtd *qtd;
 	dma_addr_t dma;
 
-	qtd = dma_pool_alloc(fotg210->qtd_pool, flags, &dma);
+	qtd = dma_pool_alloc(fhcd2xx->qtd_pool, flags, &dma);
 	if (qtd != NULL)
-		fotg210_qtd_init(fotg210, qtd, dma);
+		fhcd2xx_qtd_init(fhcd2xx, qtd, dma);
 
 	return qtd;
 }
 
-static inline void fotg210_qtd_free(struct fotg210_hcd *fotg210,
-				    struct fotg210_qtd *qtd)
+static inline void fhcd2xx_qtd_free(struct fhcd2xx_hcd *fhcd2xx,
+				    struct fhcd2xx_qtd *qtd)
 {
-	dma_pool_free(fotg210->qtd_pool, qtd, qtd->qtd_dma);
+	dma_pool_free(fhcd2xx->qtd_pool, qtd, qtd->qtd_dma);
 }
 
 
-static void qh_destroy(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+static void qh_destroy(struct fhcd2xx_hcd *fhcd2xx, struct fhcd2xx_qh *qh)
 {
 	/* clean qtds first, and know this is not linked */
 	if (!list_empty(&qh->qtd_list) || qh->qh_next.ptr) {
-		fotg210_dbg(fotg210, "unused qh not empty!\n");
+		fhcd2xx_dbg(fhcd2xx, "unused qh not empty!\n");
 		BUG();
 	}
 	if (qh->dummy)
-		fotg210_qtd_free(fotg210, qh->dummy);
-	dma_pool_free(fotg210->qh_pool, qh->hw, qh->qh_dma);
+		fhcd2xx_qtd_free(fhcd2xx, qh->dummy);
+	dma_pool_free(fhcd2xx->qh_pool, qh->hw, qh->qh_dma);
 	kfree(qh);
 }
 
-static struct fotg210_qh *fotg210_qh_alloc(struct fotg210_hcd *fotg210,
+static struct fhcd2xx_qh *fhcd2xx_qh_alloc(struct fhcd2xx_hcd *fhcd2xx,
 					   gfp_t flags)
 {
-	struct fotg210_qh *qh;
+	struct fhcd2xx_qh *qh;
 	dma_addr_t dma;
 
 	qh = kzalloc(sizeof(*qh), GFP_ATOMIC);
 	if (!qh)
 		goto done;
-	qh->hw = (struct fotg210_qh_hw *)
-		dma_pool_alloc(fotg210->qh_pool, flags, &dma);
+	qh->hw = (struct fhcd2xx_qh_hw *)
+		dma_pool_alloc(fhcd2xx->qh_pool, flags, &dma);
 	if (!qh->hw)
 		goto fail;
 	memset(qh->hw, 0, sizeof(*qh->hw));
@@ -1905,15 +1905,15 @@ static struct fotg210_qh *fotg210_qh_alloc(struct fotg210_hcd *fotg210,
 	INIT_LIST_HEAD(&qh->qtd_list);
 
 	/* dummy td enables safe urb queuing */
-	qh->dummy = fotg210_qtd_alloc(fotg210, flags);
+	qh->dummy = fhcd2xx_qtd_alloc(fhcd2xx, flags);
 	if (qh->dummy == NULL) {
-		fotg210_dbg(fotg210, "no dummy td\n");
+		fhcd2xx_dbg(fhcd2xx, "no dummy td\n");
 		goto fail1;
 	}
 done:
 	return qh;
 fail1:
-	dma_pool_free(fotg210->qh_pool, qh->hw, qh->qh_dma);
+	dma_pool_free(fhcd2xx->qh_pool, qh->hw, qh->qh_dma);
 fail:
 	kfree(qh);
 	return NULL;
@@ -1924,93 +1924,93 @@ fail:
  * This is the initialisation and cleanup code.
  */
 
-static void fotg210_mem_cleanup(struct fotg210_hcd *fotg210)
+static void fhcd2xx_mem_cleanup(struct fhcd2xx_hcd *fhcd2xx)
 {
-	if (fotg210->async)
-		qh_destroy(fotg210, fotg210->async);
-	fotg210->async = NULL;
+	if (fhcd2xx->async)
+		qh_destroy(fhcd2xx, fhcd2xx->async);
+	fhcd2xx->async = NULL;
 
-	if (fotg210->dummy)
-		qh_destroy(fotg210, fotg210->dummy);
-	fotg210->dummy = NULL;
+	if (fhcd2xx->dummy)
+		qh_destroy(fhcd2xx, fhcd2xx->dummy);
+	fhcd2xx->dummy = NULL;
 
 	/* DMA consistent memory and pools */
-	dma_pool_destroy(fotg210->qtd_pool);
-	fotg210->qtd_pool = NULL;
+	dma_pool_destroy(fhcd2xx->qtd_pool);
+	fhcd2xx->qtd_pool = NULL;
 
-	dma_pool_destroy(fotg210->qh_pool);
-	fotg210->qh_pool = NULL;
+	dma_pool_destroy(fhcd2xx->qh_pool);
+	fhcd2xx->qh_pool = NULL;
 
-	dma_pool_destroy(fotg210->itd_pool);
-	fotg210->itd_pool = NULL;
+	dma_pool_destroy(fhcd2xx->itd_pool);
+	fhcd2xx->itd_pool = NULL;
 
-	if (fotg210->periodic)
-		dma_free_coherent(fotg210_to_hcd(fotg210)->self.controller,
-			fotg210->periodic_size * sizeof(u32),
-			fotg210->periodic, fotg210->periodic_dma);
-	fotg210->periodic = NULL;
+	if (fhcd2xx->periodic)
+		dma_free_coherent(fhcd2xx_to_hcd(fhcd2xx)->self.controller,
+			fhcd2xx->periodic_size * sizeof(u32),
+			fhcd2xx->periodic, fhcd2xx->periodic_dma);
+	fhcd2xx->periodic = NULL;
 
 	/* shadow periodic table */
-	kfree(fotg210->pshadow);
-	fotg210->pshadow = NULL;
+	kfree(fhcd2xx->pshadow);
+	fhcd2xx->pshadow = NULL;
 }
 
 /* remember to add cleanup code (above) if you add anything here */
-static int fotg210_mem_init(struct fotg210_hcd *fotg210, gfp_t flags)
+static int fhcd2xx_mem_init(struct fhcd2xx_hcd *fhcd2xx, gfp_t flags)
 {
 	int i;
 
 	/* QTDs for control/bulk/intr transfers */
-	fotg210->qtd_pool = dma_pool_create("fotg210_qtd",
-			fotg210_to_hcd(fotg210)->self.controller,
-			sizeof(struct fotg210_qtd),
+	fhcd2xx->qtd_pool = dma_pool_create("fhcd2xx_qtd",
+			fhcd2xx_to_hcd(fhcd2xx)->self.controller,
+			sizeof(struct fhcd2xx_qtd),
 			32 /* byte alignment (for hw parts) */,
 			4096 /* can't cross 4K */);
-	if (!fotg210->qtd_pool)
+	if (!fhcd2xx->qtd_pool)
 		goto fail;
 
 	/* QHs for control/bulk/intr transfers */
-	fotg210->qh_pool = dma_pool_create("fotg210_qh",
-			fotg210_to_hcd(fotg210)->self.controller,
-			sizeof(struct fotg210_qh_hw),
+	fhcd2xx->qh_pool = dma_pool_create("fhcd2xx_qh",
+			fhcd2xx_to_hcd(fhcd2xx)->self.controller,
+			sizeof(struct fhcd2xx_qh_hw),
 			32 /* byte alignment (for hw parts) */,
 			4096 /* can't cross 4K */);
-	if (!fotg210->qh_pool)
+	if (!fhcd2xx->qh_pool)
 		goto fail;
 
-	fotg210->async = fotg210_qh_alloc(fotg210, flags);
-	if (!fotg210->async)
+	fhcd2xx->async = fhcd2xx_qh_alloc(fhcd2xx, flags);
+	if (!fhcd2xx->async)
 		goto fail;
 
 	/* ITD for high speed ISO transfers */
-	fotg210->itd_pool = dma_pool_create("fotg210_itd",
-			fotg210_to_hcd(fotg210)->self.controller,
-			sizeof(struct fotg210_itd),
+	fhcd2xx->itd_pool = dma_pool_create("fhcd2xx_itd",
+			fhcd2xx_to_hcd(fhcd2xx)->self.controller,
+			sizeof(struct fhcd2xx_itd),
 			64 /* byte alignment (for hw parts) */,
 			4096 /* can't cross 4K */);
-	if (!fotg210->itd_pool)
+	if (!fhcd2xx->itd_pool)
 		goto fail;
 
 	/* Hardware periodic table */
-	fotg210->periodic = (__le32 *)
-		dma_alloc_coherent(fotg210_to_hcd(fotg210)->self.controller,
-			fotg210->periodic_size * sizeof(__le32),
-			&fotg210->periodic_dma, 0);
-	if (fotg210->periodic == NULL)
+	fhcd2xx->periodic = (__le32 *)
+		dma_alloc_coherent(fhcd2xx_to_hcd(fhcd2xx)->self.controller,
+			fhcd2xx->periodic_size * sizeof(__le32),
+			&fhcd2xx->periodic_dma, 0);
+	if (fhcd2xx->periodic == NULL)
 		goto fail;
 
-	for (i = 0; i < fotg210->periodic_size; i++)
-		fotg210->periodic[i] = FOTG210_LIST_END(fotg210);
+	for (i = 0; i < fhcd2xx->periodic_size; i++)
+		fhcd2xx->periodic[i] = FHCD2XX_LIST_END(fhcd2xx);
 
 	/* software shadow of hardware table */
-	fotg210->pshadow = kcalloc(fotg210->periodic_size, sizeof(void *),
+	fhcd2xx->pshadow = kcalloc(fhcd2xx->periodic_size, sizeof(void *),
 				   flags);
-	if (fotg210->pshadow != NULL)
+	if (fhcd2xx->pshadow != NULL)
 		return 0;
 
 fail:
-	fotg210_dbg(fotg210, "couldn't init memory\n");
-	fotg210_mem_cleanup(fotg210);
+	fhcd2xx_dbg(fhcd2xx, "couldn't init memory\n");
+	fhcd2xx_mem_cleanup(fhcd2xx);
 	return -ENOMEM;
 }
 /*
@@ -2032,15 +2032,15 @@ fail:
  */
 
 /* fill a qtd, returning how much of the buffer we were able to queue up */
-static int qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd,
+static int qtd_fill(struct fhcd2xx_hcd *fhcd2xx, struct fhcd2xx_qtd *qtd,
 		    dma_addr_t buf, size_t len, int token, int maxpacket)
 {
 	int i, count;
 	u64 addr = buf;
 
 	/* one buffer entry per 4K ... first might be short or unaligned */
-	qtd->hw_buf[0] = cpu_to_hc32(fotg210, (u32)addr);
-	qtd->hw_buf_hi[0] = cpu_to_hc32(fotg210, (u32)(addr >> 32));
+	qtd->hw_buf[0] = cpu_to_hc32(fhcd2xx, (u32)addr);
+	qtd->hw_buf_hi[0] = cpu_to_hc32(fhcd2xx, (u32)(addr >> 32));
 	count = 0x1000 - (buf & 0x0fff);	/* rest of that page */
 	if (likely(len < count))		/* ... iff needed */
 		count = len;
@@ -2051,8 +2051,8 @@ static int qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd,
 		/* per-qtd limit: from 16K to 20K (best alignment) */
 		for (i = 1; count < len && i < 5; i++) {
 			addr = buf;
-			qtd->hw_buf[i] = cpu_to_hc32(fotg210, (u32)addr);
-			qtd->hw_buf_hi[i] = cpu_to_hc32(fotg210,
+			qtd->hw_buf[i] = cpu_to_hc32(fhcd2xx, (u32)addr);
+			qtd->hw_buf_hi[i] = cpu_to_hc32(fhcd2xx,
 					(u32)(addr >> 32));
 			buf += 0x1000;
 			if ((count + 0x1000) < len)
@@ -2065,56 +2065,56 @@ static int qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd,
 		if (count != len)
 			count -= (count % maxpacket);
 	}
-	qtd->hw_token = cpu_to_hc32(fotg210, (count << 16) | token);
+	qtd->hw_token = cpu_to_hc32(fhcd2xx, (count << 16) | token);
 	qtd->length = count;
 
 	return count;
 }
 
-static inline void qh_update(struct fotg210_hcd *fotg210,
-			     struct fotg210_qh *qh,
-			     struct fotg210_qtd *qtd)
+static inline void qh_update(struct fhcd2xx_hcd *fhcd2xx,
+			     struct fhcd2xx_qh *qh,
+			     struct fhcd2xx_qtd *qtd)
 {
-	struct fotg210_qh_hw *hw = qh->hw;
+	struct fhcd2xx_qh_hw *hw = qh->hw;
 
 	/* writes to an active overlay are unsafe */
 	BUG_ON(qh->qh_state != QH_STATE_IDLE);
 
-	hw->hw_qtd_next = QTD_NEXT(fotg210, qtd->qtd_dma);
-	hw->hw_alt_next = FOTG210_LIST_END(fotg210);
+	hw->hw_qtd_next = QTD_NEXT(fhcd2xx, qtd->qtd_dma);
+	hw->hw_alt_next = FHCD2XX_LIST_END(fhcd2xx);
 
 	/* Except for control endpoints, we make hardware maintain data
 	 * toggle (like OHCI) ... here (re)initialize the toggle in the QH,
 	 * and set the pseudo-toggle in udev. Only usb_clear_halt() will
 	 * ever clear it.
 	 */
-	if (!(hw->hw_info1 & cpu_to_hc32(fotg210, QH_TOGGLE_CTL))) {
+	if (!(hw->hw_info1 & cpu_to_hc32(fhcd2xx, QH_TOGGLE_CTL))) {
 		unsigned is_out, epnum;
 
 		is_out = qh->is_out;
-		epnum = (hc32_to_cpup(fotg210, &hw->hw_info1) >> 8) & 0x0f;
+		epnum = (hc32_to_cpup(fhcd2xx, &hw->hw_info1) >> 8) & 0x0f;
 		if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) {
-			hw->hw_token &= ~cpu_to_hc32(fotg210, QTD_TOGGLE);
+			hw->hw_token &= ~cpu_to_hc32(fhcd2xx, QTD_TOGGLE);
 			usb_settoggle(qh->dev, epnum, is_out, 1);
 		}
 	}
 
-	hw->hw_token &= cpu_to_hc32(fotg210, QTD_TOGGLE | QTD_STS_PING);
+	hw->hw_token &= cpu_to_hc32(fhcd2xx, QTD_TOGGLE | QTD_STS_PING);
 }
 
 /* if it weren't for a common silicon quirk (writing the dummy into the qh
  * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault
  * recovery (including urb dequeue) would need software changes to a QH...
  */
-static void qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+static void qh_refresh(struct fhcd2xx_hcd *fhcd2xx, struct fhcd2xx_qh *qh)
 {
-	struct fotg210_qtd *qtd;
+	struct fhcd2xx_qtd *qtd;
 
 	if (list_empty(&qh->qtd_list))
 		qtd = qh->dummy;
 	else {
 		qtd = list_entry(qh->qtd_list.next,
-				struct fotg210_qtd, qtd_list);
+				struct fhcd2xx_qtd, qtd_list);
 		/*
 		 * first qtd may already be partially processed.
 		 * If we come here during unlink, the QH overlay region
@@ -2122,35 +2122,35 @@ static void qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		 * qtd is updated in qh_completions(). Update the QH
 		 * overlay here.
 		 */
-		if (cpu_to_hc32(fotg210, qtd->qtd_dma) == qh->hw->hw_current) {
+		if (cpu_to_hc32(fhcd2xx, qtd->qtd_dma) == qh->hw->hw_current) {
 			qh->hw->hw_qtd_next = qtd->hw_next;
 			qtd = NULL;
 		}
 	}
 
 	if (qtd)
-		qh_update(fotg210, qh, qtd);
+		qh_update(fhcd2xx, qh, qtd);
 }
 
-static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
+static void qh_link_async(struct fhcd2xx_hcd *fhcd2xx, struct fhcd2xx_qh *qh);
 
-static void fotg210_clear_tt_buffer_complete(struct usb_hcd *hcd,
+static void fhcd2xx_clear_tt_buffer_complete(struct usb_hcd *hcd,
 					     struct usb_host_endpoint *ep)
 {
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh *qh = ep->hcpriv;
+	struct fhcd2xx_hcd *fhcd2xx = hcd_to_fhcd2xx(hcd);
+	struct fhcd2xx_qh *qh = ep->hcpriv;
 	unsigned long flags;
 
-	spin_lock_irqsave(&fotg210->lock, flags);
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
 	qh->clearing_tt = 0;
 	if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list)
-			&& fotg210->rh_state == FOTG210_RH_RUNNING)
-		qh_link_async(fotg210, qh);
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+			&& fhcd2xx->rh_state == FHCD2XX_RH_RUNNING)
+		qh_link_async(fhcd2xx, qh);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 }
 
-static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
-				    struct fotg210_qh *qh,
+static void fhcd2xx_clear_tt_buffer(struct fhcd2xx_hcd *fhcd2xx,
+				    struct fhcd2xx_qh *qh,
 				    struct urb *urb, u32 token)
 {
 
@@ -2169,14 +2169,14 @@ static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
 			usb_pipeendpoint(urb->pipe), token);
 
 		if (urb->dev->tt->hub !=
-		    fotg210_to_hcd(fotg210)->self.root_hub) {
+		    fhcd2xx_to_hcd(fhcd2xx)->self.root_hub) {
 			if (usb_hub_clear_tt_buffer(urb) == 0)
 				qh->clearing_tt = 1;
 		}
 	}
 }
 
-static int qtd_copy_status(struct fotg210_hcd *fotg210, struct urb *urb,
+static int qtd_copy_status(struct fhcd2xx_hcd *fhcd2xx, struct urb *urb,
 			   size_t length, u32 token)
 {
 	int status = -EINPROGRESS;
@@ -2215,7 +2215,7 @@ static int qtd_copy_status(struct fotg210_hcd *fotg210, struct urb *urb,
 				: -ECOMM; /* hc couldn't write data */
 		} else if (token & QTD_STS_XACT) {
 			/* timeout, bad CRC, wrong PID, etc */
-			fotg210_dbg(fotg210, "devpath %s ep%d%s 3strikes\n",
+			fhcd2xx_dbg(fhcd2xx, "devpath %s ep%d%s 3strikes\n",
 				urb->dev->devpath,
 				usb_pipeendpoint(urb->pipe),
 				usb_pipein(urb->pipe) ? "in" : "out");
@@ -2224,7 +2224,7 @@ static int qtd_copy_status(struct fotg210_hcd *fotg210, struct urb *urb,
 			status = -EPROTO;
 		}
 
-		fotg210_dbg(fotg210,
+		fhcd2xx_dbg(fhcd2xx,
 			"dev%d ep%d%s qtd token %08x --> status %d\n",
 			usb_pipedevice(urb->pipe),
 			usb_pipeendpoint(urb->pipe),
@@ -2235,33 +2235,33 @@ static int qtd_copy_status(struct fotg210_hcd *fotg210, struct urb *urb,
 	return status;
 }
 
-static void fotg210_urb_done(struct fotg210_hcd *fotg210, struct urb *urb,
+static void fhcd2xx_urb_done(struct fhcd2xx_hcd *fhcd2xx, struct urb *urb,
 			     int status)
-__releases(fotg210->lock)
-__acquires(fotg210->lock)
+__releases(fhcd2xx->lock)
+__acquires(fhcd2xx->lock)
 {
 	if (likely(urb->hcpriv != NULL)) {
-		struct fotg210_qh *qh = (struct fotg210_qh *) urb->hcpriv;
+		struct fhcd2xx_qh *qh = (struct fhcd2xx_qh *) urb->hcpriv;
 
 		/* S-mask in a QH means it's an interrupt urb */
-		if ((qh->hw->hw_info2 & cpu_to_hc32(fotg210, QH_SMASK)) != 0) {
+		if ((qh->hw->hw_info2 & cpu_to_hc32(fhcd2xx, QH_SMASK)) != 0) {
 
 			/* ... update hc-wide periodic stats (for usbfs) */
-			fotg210_to_hcd(fotg210)->self.bandwidth_int_reqs--;
+			fhcd2xx_to_hcd(fhcd2xx)->self.bandwidth_int_reqs--;
 		}
 	}
 
 	if (unlikely(urb->unlinked)) {
-		COUNT(fotg210->stats.unlink);
+		COUNT(fhcd2xx->stats.unlink);
 	} else {
 		/* report non-error and short read status as zero */
 		if (status == -EINPROGRESS || status == -EREMOTEIO)
 			status = 0;
-		COUNT(fotg210->stats.complete);
+		COUNT(fhcd2xx->stats.complete);
 	}
 
-#ifdef FOTG210_URB_TRACE
-	fotg210_dbg(fotg210,
+#ifdef FHCD2XX_URB_TRACE
+	fhcd2xx_dbg(fhcd2xx,
 		"%s %s urb %p ep%d%s status %d len %d/%d\n",
 		__func__, urb->dev->devpath, urb,
 		usb_pipeendpoint(urb->pipe),
@@ -2271,29 +2271,29 @@ __acquires(fotg210->lock)
 #endif
 
 	/* complete() can reenter this HCD */
-	usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
-	spin_unlock(&fotg210->lock);
-	usb_hcd_giveback_urb(fotg210_to_hcd(fotg210), urb, status);
-	spin_lock(&fotg210->lock);
+	usb_hcd_unlink_urb_from_ep(fhcd2xx_to_hcd(fhcd2xx), urb);
+	spin_unlock(&fhcd2xx->lock);
+	usb_hcd_giveback_urb(fhcd2xx_to_hcd(fhcd2xx), urb, status);
+	spin_lock(&fhcd2xx->lock);
 }
 
-static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
+static int qh_schedule(struct fhcd2xx_hcd *fhcd2xx, struct fhcd2xx_qh *qh);
 
 /*
  * Process and free completed qtds for a qh, returning URBs to drivers.
  * Chases up to qh->hw_current.  Returns number of completions called,
  * indicating how much "real" work we did.
  */
-static unsigned qh_completions(struct fotg210_hcd *fotg210,
-			       struct fotg210_qh *qh)
+static unsigned qh_completions(struct fhcd2xx_hcd *fhcd2xx,
+			       struct fhcd2xx_qh *qh)
 {
-	struct fotg210_qtd *last, *end = qh->dummy;
+	struct fhcd2xx_qtd *last, *end = qh->dummy;
 	struct list_head *entry, *tmp;
 	int last_status;
 	int stopped;
 	unsigned count = 0;
 	u8 state;
-	struct fotg210_qh_hw *hw = qh->hw;
+	struct fhcd2xx_qh_hw *hw = qh->hw;
 
 	if (unlikely(list_empty(&qh->qtd_list)))
 		return count;
@@ -2323,22 +2323,22 @@ rescan:
 	 * if queue is stopped, handles unlinks.
 	 */
 	list_for_each_safe(entry, tmp, &qh->qtd_list) {
-		struct fotg210_qtd *qtd;
+		struct fhcd2xx_qtd *qtd;
 		struct urb *urb;
 		u32 token = 0;
 
-		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
+		qtd = list_entry(entry, struct fhcd2xx_qtd, qtd_list);
 		urb = qtd->urb;
 
 		/* clean up any state from previous QTD ...*/
 		if (last) {
 			if (likely(last->urb != urb)) {
-				fotg210_urb_done(fotg210, last->urb,
+				fhcd2xx_urb_done(fhcd2xx, last->urb,
 						 last_status);
 				count++;
 				last_status = -EINPROGRESS;
 			}
-			fotg210_qtd_free(fotg210, last);
+			fhcd2xx_qtd_free(fhcd2xx, last);
 			last = NULL;
 		}
 
@@ -2348,7 +2348,7 @@ rescan:
 
 		/* hardware copies qtd out of qh overlay */
 		rmb();
-		token = hc32_to_cpu(fotg210, qtd->hw_token);
+		token = hc32_to_cpu(fhcd2xx, qtd->hw_token);
 
 		/* always clean up qtds the hc de-activated */
 retry_xacterr:
@@ -2356,7 +2356,7 @@ retry_xacterr:
 
 			/* Report Data Buffer Error: non-fatal but useful */
 			if (token & QTD_STS_DBE)
-				fotg210_dbg(fotg210,
+				fhcd2xx_dbg(fhcd2xx,
 					"detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n",
 					urb,
 					usb_endpoint_num(&urb->ep->desc),
@@ -2378,7 +2378,7 @@ retry_xacterr:
 					QTD_CERR(token) == 0 &&
 					++qh->xacterrs < QH_XACTERR_MAX &&
 					!urb->unlinked) {
-					fotg210_dbg(fotg210,
+					fhcd2xx_dbg(fhcd2xx,
 	"detected XactErr len %zu/%zu retry %d\n",
 	qtd->length - QTD_LENGTH(token), qtd->length, qh->xacterrs);
 
@@ -2389,11 +2389,11 @@ retry_xacterr:
 					 */
 					token &= ~QTD_STS_HALT;
 					token |= QTD_STS_ACTIVE |
-						 (FOTG210_TUNE_CERR << 10);
-					qtd->hw_token = cpu_to_hc32(fotg210,
+						 (FHCD2XX_TUNE_CERR << 10);
+					qtd->hw_token = cpu_to_hc32(fhcd2xx,
 							token);
 					wmb();
-					hw->hw_token = cpu_to_hc32(fotg210,
+					hw->hw_token = cpu_to_hc32(fhcd2xx,
 							token);
 					goto retry_xacterr;
 				}
@@ -2410,13 +2410,13 @@ retry_xacterr:
 			 */
 			} else if (IS_SHORT_READ(token)
 					&& !(qtd->hw_alt_next
-						& FOTG210_LIST_END(fotg210))) {
+						& FHCD2XX_LIST_END(fhcd2xx))) {
 				stopped = 1;
 			}
 
 		/* stop scanning when we reach qtds the hc is using */
 		} else if (likely(!stopped
-				&& fotg210->rh_state >= FOTG210_RH_RUNNING)) {
+				&& fhcd2xx->rh_state >= FHCD2XX_RH_RUNNING)) {
 			break;
 
 		/* scan the whole queue for unlinks whenever it stops */
@@ -2424,7 +2424,7 @@ retry_xacterr:
 			stopped = 1;
 
 			/* cancel everything if we halt, suspend, etc */
-			if (fotg210->rh_state < FOTG210_RH_RUNNING)
+			if (fhcd2xx->rh_state < FHCD2XX_RH_RUNNING)
 				last_status = -ESHUTDOWN;
 
 			/* this qtd is active; skip it unless a previous qtd
@@ -2435,15 +2435,15 @@ retry_xacterr:
 
 			/* qh unlinked; token in overlay may be most current */
 			if (state == QH_STATE_IDLE
-					&& cpu_to_hc32(fotg210, qtd->qtd_dma)
+					&& cpu_to_hc32(fhcd2xx, qtd->qtd_dma)
 						== hw->hw_current) {
-				token = hc32_to_cpu(fotg210, hw->hw_token);
+				token = hc32_to_cpu(fhcd2xx, hw->hw_token);
 
 				/* An unlink may leave an incomplete
 				 * async transaction in the TT buffer.
 				 * We have to clear it.
 				 */
-				fotg210_clear_tt_buffer(fotg210, qh, urb,
+				fhcd2xx_clear_tt_buffer(fhcd2xx, qh, urb,
 							token);
 			}
 		}
@@ -2456,11 +2456,11 @@ retry_xacterr:
 		 * short read the second must be removed by hand.
 		 */
 		if (last_status == -EINPROGRESS) {
-			last_status = qtd_copy_status(fotg210, urb,
+			last_status = qtd_copy_status(fhcd2xx, urb,
 					qtd->length, token);
 			if (last_status == -EREMOTEIO
 					&& (qtd->hw_alt_next
-						& FOTG210_LIST_END(fotg210)))
+						& FHCD2XX_LIST_END(fhcd2xx)))
 				last_status = -EINPROGRESS;
 
 			/* As part of low/full-speed endpoint-halt processing
@@ -2478,7 +2478,7 @@ retry_xacterr:
 				 * is a violation of the spec.
 				 */
 				if (last_status != -EPIPE)
-					fotg210_clear_tt_buffer(fotg210, qh,
+					fhcd2xx_clear_tt_buffer(fhcd2xx, qh,
 								urb, token);
 			}
 		}
@@ -2488,7 +2488,7 @@ retry_xacterr:
 		 */
 		if (stopped && qtd->qtd_list.prev != &qh->qtd_list) {
 			last = list_entry(qtd->qtd_list.prev,
-					struct fotg210_qtd, qtd_list);
+					struct fhcd2xx_qtd, qtd_list);
 			last->hw_next = qtd->hw_next;
 		}
 
@@ -2502,9 +2502,9 @@ retry_xacterr:
 
 	/* last urb's completion might still need calling */
 	if (likely(last != NULL)) {
-		fotg210_urb_done(fotg210, last->urb, last_status);
+		fhcd2xx_urb_done(fhcd2xx, last->urb, last_status);
 		count++;
-		fotg210_qtd_free(fotg210, last);
+		fhcd2xx_qtd_free(fhcd2xx, last);
 	}
 
 	/* Do we need to rescan for URBs dequeued during a giveback? */
@@ -2529,10 +2529,10 @@ retry_xacterr:
 	 * it after fault cleanup, or recovering from silicon wrongly
 	 * overlaying the dummy qtd (which reduces DMA chatter).
 	 */
-	if (stopped != 0 || hw->hw_qtd_next == FOTG210_LIST_END(fotg210)) {
+	if (stopped != 0 || hw->hw_qtd_next == FHCD2XX_LIST_END(fhcd2xx)) {
 		switch (state) {
 		case QH_STATE_IDLE:
-			qh_refresh(fotg210, qh);
+			qh_refresh(fhcd2xx, qh);
 			break;
 		case QH_STATE_LINKED:
 			/* We won't refresh a QH that's linked (after the HC
@@ -2566,29 +2566,29 @@ retry_xacterr:
  * reverse of qh_urb_transaction:  free a list of TDs.
  * used for cleanup after errors, before HC sees an URB's TDs.
  */
-static void qtd_list_free(struct fotg210_hcd *fotg210, struct urb *urb,
+static void qtd_list_free(struct fhcd2xx_hcd *fhcd2xx, struct urb *urb,
 			  struct list_head *qtd_list)
 {
 	struct list_head *entry, *temp;
 
 	list_for_each_safe(entry, temp, qtd_list) {
-		struct fotg210_qtd *qtd;
+		struct fhcd2xx_qtd *qtd;
 
-		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
+		qtd = list_entry(entry, struct fhcd2xx_qtd, qtd_list);
 		list_del(&qtd->qtd_list);
-		fotg210_qtd_free(fotg210, qtd);
+		fhcd2xx_qtd_free(fhcd2xx, qtd);
 	}
 }
 
 /*
  * create a list of filled qtds for this URB; won't link into qh.
  */
-static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
+static struct list_head *qh_urb_transaction(struct fhcd2xx_hcd *fhcd2xx,
 					    struct urb *urb,
 					    struct list_head *head,
 					    gfp_t flags)
 {
-	struct fotg210_qtd *qtd, *qtd_prev;
+	struct fhcd2xx_qtd *qtd, *qtd_prev;
 	dma_addr_t buf;
 	int len, this_sg_len, maxpacket;
 	int is_input;
@@ -2599,32 +2599,32 @@ static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
 	/*
 	 * URBs map to sequences of QTDs:  one logical transaction
 	 */
-	qtd = fotg210_qtd_alloc(fotg210, flags);
+	qtd = fhcd2xx_qtd_alloc(fhcd2xx, flags);
 	if (unlikely(!qtd))
 		return NULL;
 	list_add_tail(&qtd->qtd_list, head);
 	qtd->urb = urb;
 
 	token = QTD_STS_ACTIVE;
-	token |= (FOTG210_TUNE_CERR << 10);
+	token |= (FHCD2XX_TUNE_CERR << 10);
 	/* for split transactions, SplitXState initialized to zero */
 
 	len = urb->transfer_buffer_length;
 	is_input = usb_pipein(urb->pipe);
 	if (usb_pipecontrol(urb->pipe)) {
 		/* SETUP pid */
-		qtd_fill(fotg210, qtd, urb->setup_dma,
+		qtd_fill(fhcd2xx, qtd, urb->setup_dma,
 				sizeof(struct usb_ctrlrequest),
 				token | (2 /* "setup" */ << 8), 8);
 
 		/* ... and always at least one more pid */
 		token ^= QTD_TOGGLE;
 		qtd_prev = qtd;
-		qtd = fotg210_qtd_alloc(fotg210, flags);
+		qtd = fhcd2xx_qtd_alloc(fhcd2xx, flags);
 		if (unlikely(!qtd))
 			goto cleanup;
 		qtd->urb = urb;
-		qtd_prev->hw_next = QTD_NEXT(fotg210, qtd->qtd_dma);
+		qtd_prev->hw_next = QTD_NEXT(fhcd2xx, qtd->qtd_dma);
 		list_add_tail(&qtd->qtd_list, head);
 
 		/* for zero length DATA stages, STATUS is always IN */
@@ -2664,7 +2664,7 @@ static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
 	for (;;) {
 		int this_qtd_len;
 
-		this_qtd_len = qtd_fill(fotg210, qtd, buf, this_sg_len, token,
+		this_qtd_len = qtd_fill(fhcd2xx, qtd, buf, this_sg_len, token,
 				maxpacket);
 		this_sg_len -= this_qtd_len;
 		len -= this_qtd_len;
@@ -2676,7 +2676,7 @@ static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
 		 * (this will usually be overridden later.)
 		 */
 		if (is_input)
-			qtd->hw_alt_next = fotg210->async->hw->hw_alt_next;
+			qtd->hw_alt_next = fhcd2xx->async->hw->hw_alt_next;
 
 		/* qh makes control packets use qtd toggle; maybe switch it */
 		if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
@@ -2691,11 +2691,11 @@ static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
 		}
 
 		qtd_prev = qtd;
-		qtd = fotg210_qtd_alloc(fotg210, flags);
+		qtd = fhcd2xx_qtd_alloc(fhcd2xx, flags);
 		if (unlikely(!qtd))
 			goto cleanup;
 		qtd->urb = urb;
-		qtd_prev->hw_next = QTD_NEXT(fotg210, qtd->qtd_dma);
+		qtd_prev->hw_next = QTD_NEXT(fhcd2xx, qtd->qtd_dma);
 		list_add_tail(&qtd->qtd_list, head);
 	}
 
@@ -2706,7 +2706,7 @@ static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
 	 */
 	if (likely((urb->transfer_flags & URB_SHORT_NOT_OK) == 0
 				|| usb_pipecontrol(urb->pipe)))
-		qtd->hw_alt_next = FOTG210_LIST_END(fotg210);
+		qtd->hw_alt_next = FHCD2XX_LIST_END(fhcd2xx);
 
 	/*
 	 * control requests may need a terminating data "status" ack;
@@ -2727,25 +2727,25 @@ static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
 		}
 		if (one_more) {
 			qtd_prev = qtd;
-			qtd = fotg210_qtd_alloc(fotg210, flags);
+			qtd = fhcd2xx_qtd_alloc(fhcd2xx, flags);
 			if (unlikely(!qtd))
 				goto cleanup;
 			qtd->urb = urb;
-			qtd_prev->hw_next = QTD_NEXT(fotg210, qtd->qtd_dma);
+			qtd_prev->hw_next = QTD_NEXT(fhcd2xx, qtd->qtd_dma);
 			list_add_tail(&qtd->qtd_list, head);
 
 			/* never any data in such packets */
-			qtd_fill(fotg210, qtd, 0, 0, token, 0);
+			qtd_fill(fhcd2xx, qtd, 0, 0, token, 0);
 		}
 	}
 
 	/* by default, enable interrupt on urb completion */
 	if (likely(!(urb->transfer_flags & URB_NO_INTERRUPT)))
-		qtd->hw_token |= cpu_to_hc32(fotg210, QTD_IOC);
+		qtd->hw_token |= cpu_to_hc32(fhcd2xx, QTD_IOC);
 	return head;
 
 cleanup:
-	qtd_list_free(fotg210, urb, head);
+	qtd_list_free(fhcd2xx, urb, head);
 	return NULL;
 }
 
@@ -2766,15 +2766,15 @@ cleanup:
  * just one microframe in the s-mask.  For split interrupt transactions
  * there are additional complications: c-mask, maybe FSTNs.
  */
-static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
+static struct fhcd2xx_qh *qh_make(struct fhcd2xx_hcd *fhcd2xx, struct urb *urb,
 				  gfp_t flags)
 {
-	struct fotg210_qh *qh = fotg210_qh_alloc(fotg210, flags);
+	struct fhcd2xx_qh *qh = fhcd2xx_qh_alloc(fhcd2xx, flags);
 	u32 info1 = 0, info2 = 0;
 	int is_input, type;
 	int maxp = 0;
 	struct usb_tt *tt = urb->dev->tt;
-	struct fotg210_qh_hw *hw;
+	struct fhcd2xx_qh_hw *hw;
 
 	if (!qh)
 		return qh;
@@ -2793,7 +2793,7 @@ static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
 	 * acts like up to 3KB, but is built from smaller packets.
 	 */
 	if (max_packet(maxp) > 1024) {
-		fotg210_dbg(fotg210, "bogus qh maxpacket %d\n",
+		fhcd2xx_dbg(fhcd2xx, "bogus qh maxpacket %d\n",
 			    max_packet(maxp));
 		goto done;
 	}
@@ -2823,8 +2823,8 @@ static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
 				 * includes high bandwidth.
 				 */
 				urb->interval = 1;
-			} else if (qh->period > fotg210->periodic_size) {
-				qh->period = fotg210->periodic_size;
+			} else if (qh->period > fhcd2xx->periodic_size) {
+				qh->period = fhcd2xx->periodic_size;
 				urb->interval = qh->period << 3;
 			}
 		} else {
@@ -2848,8 +2848,8 @@ static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
 					usb_calc_bus_time(urb->dev->speed,
 					is_input, 0, max_packet(maxp)));
 			qh->period = urb->interval;
-			if (qh->period > fotg210->periodic_size) {
-				qh->period = fotg210->periodic_size;
+			if (qh->period > fhcd2xx->periodic_size) {
+				qh->period = fhcd2xx->periodic_size;
 				urb->interval = qh->period;
 			}
 		}
@@ -2867,19 +2867,19 @@ static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
 	case USB_SPEED_FULL:
 		/* EPS 0 means "full" */
 		if (type != PIPE_INTERRUPT)
-			info1 |= (FOTG210_TUNE_RL_TT << 28);
+			info1 |= (FHCD2XX_TUNE_RL_TT << 28);
 		if (type == PIPE_CONTROL) {
 			info1 |= QH_CONTROL_EP;		/* for TT */
 			info1 |= QH_TOGGLE_CTL;		/* toggle from qtd */
 		}
 		info1 |= maxp << 16;
 
-		info2 |= (FOTG210_TUNE_MULT_TT << 30);
+		info2 |= (FHCD2XX_TUNE_MULT_TT << 30);
 
 		/* Some Freescale processors have an erratum in which the
 		 * port number in the queue head was 0..N-1 instead of 1..N.
 		 */
-		if (fotg210_has_fsl_portno_bug(fotg210))
+		if (fhcd2xx_has_fsl_portno_bug(fhcd2xx))
 			info2 |= (urb->dev->ttport-1) << 23;
 		else
 			info2 |= urb->dev->ttport << 23;
@@ -2887,7 +2887,7 @@ static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
 		/* set the address of the TT; for TDI's integrated
 		 * root hub tt, leave it zeroed.
 		 */
-		if (tt && tt->hub != fotg210_to_hcd(fotg210)->self.root_hub)
+		if (tt && tt->hub != fhcd2xx_to_hcd(fhcd2xx)->self.root_hub)
 			info2 |= tt->hub->devnum << 16;
 
 		/* NOTE:  if (PIPE_INTERRUPT) { scheduler sets c-mask } */
@@ -2897,12 +2897,12 @@ static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
 	case USB_SPEED_HIGH:		/* no TT involved */
 		info1 |= QH_HIGH_SPEED;
 		if (type == PIPE_CONTROL) {
-			info1 |= (FOTG210_TUNE_RL_HS << 28);
+			info1 |= (FHCD2XX_TUNE_RL_HS << 28);
 			info1 |= 64 << 16;	/* usb2 fixed maxpacket */
 			info1 |= QH_TOGGLE_CTL;	/* toggle from qtd */
-			info2 |= (FOTG210_TUNE_MULT_HS << 30);
+			info2 |= (FHCD2XX_TUNE_MULT_HS << 30);
 		} else if (type == PIPE_BULK) {
-			info1 |= (FOTG210_TUNE_RL_HS << 28);
+			info1 |= (FHCD2XX_TUNE_RL_HS << 28);
 			/* The USB spec says that high speed bulk endpoints
 			 * always use 512 byte maxpacket.  But some device
 			 * vendors decided to ignore that, and MSFT is happy
@@ -2910,17 +2910,17 @@ static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
 			 * such nonconformant devices with Linux too; sigh.
 			 */
 			info1 |= max_packet(maxp) << 16;
-			info2 |= (FOTG210_TUNE_MULT_HS << 30);
+			info2 |= (FHCD2XX_TUNE_MULT_HS << 30);
 		} else {		/* PIPE_INTERRUPT */
 			info1 |= max_packet(maxp) << 16;
 			info2 |= hb_mult(maxp) << 30;
 		}
 		break;
 	default:
-		fotg210_dbg(fotg210, "bogus dev %p speed %d\n", urb->dev,
+		fhcd2xx_dbg(fhcd2xx, "bogus dev %p speed %d\n", urb->dev,
 			urb->dev->speed);
 done:
-		qh_destroy(fotg210, qh);
+		qh_destroy(fhcd2xx, qh);
 		return NULL;
 	}
 
@@ -2929,45 +2929,45 @@ done:
 	/* init as live, toggle clear, advance to dummy */
 	qh->qh_state = QH_STATE_IDLE;
 	hw = qh->hw;
-	hw->hw_info1 = cpu_to_hc32(fotg210, info1);
-	hw->hw_info2 = cpu_to_hc32(fotg210, info2);
+	hw->hw_info1 = cpu_to_hc32(fhcd2xx, info1);
+	hw->hw_info2 = cpu_to_hc32(fhcd2xx, info2);
 	qh->is_out = !is_input;
 	usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), !is_input, 1);
-	qh_refresh(fotg210, qh);
+	qh_refresh(fhcd2xx, qh);
 	return qh;
 }
 
-static void enable_async(struct fotg210_hcd *fotg210)
+static void enable_async(struct fhcd2xx_hcd *fhcd2xx)
 {
-	if (fotg210->async_count++)
+	if (fhcd2xx->async_count++)
 		return;
 
 	/* Stop waiting to turn off the async schedule */
-	fotg210->enabled_hrtimer_events &= ~BIT(FOTG210_HRTIMER_DISABLE_ASYNC);
+	fhcd2xx->enabled_hrtimer_events &= ~BIT(FHCD2XX_HRTIMER_DISABLE_ASYNC);
 
 	/* Don't start the schedule until ASS is 0 */
-	fotg210_poll_ASS(fotg210);
-	turn_on_io_watchdog(fotg210);
+	fhcd2xx_poll_ASS(fhcd2xx);
+	turn_on_io_watchdog(fhcd2xx);
 }
 
-static void disable_async(struct fotg210_hcd *fotg210)
+static void disable_async(struct fhcd2xx_hcd *fhcd2xx)
 {
-	if (--fotg210->async_count)
+	if (--fhcd2xx->async_count)
 		return;
 
 	/* The async schedule and async_unlink list are supposed to be empty */
-	WARN_ON(fotg210->async->qh_next.qh || fotg210->async_unlink);
+	WARN_ON(fhcd2xx->async->qh_next.qh || fhcd2xx->async_unlink);
 
 	/* Don't turn off the schedule until ASS is 1 */
-	fotg210_poll_ASS(fotg210);
+	fhcd2xx_poll_ASS(fhcd2xx);
 }
 
 /* move qh (and its qtds) onto async queue; maybe enable queue.  */
 
-static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+static void qh_link_async(struct fhcd2xx_hcd *fhcd2xx, struct fhcd2xx_qh *qh)
 {
-	__hc32 dma = QH_NEXT(fotg210, qh->qh_dma);
-	struct fotg210_qh *head;
+	__hc32 dma = QH_NEXT(fhcd2xx, qh->qh_dma);
+	struct fhcd2xx_qh *head;
 
 	/* Don't link a QH if there's a Clear-TT-Buffer pending */
 	if (unlikely(qh->clearing_tt))
@@ -2976,10 +2976,10 @@ static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	WARN_ON(qh->qh_state != QH_STATE_IDLE);
 
 	/* clear halt and/or toggle; and maybe recover from silicon quirk */
-	qh_refresh(fotg210, qh);
+	qh_refresh(fhcd2xx, qh);
 
 	/* splice right after start */
-	head = fotg210->async;
+	head = fhcd2xx->async;
 	qh->qh_next = head->qh_next;
 	qh->hw->hw_next = head->hw->hw_next;
 	wmb();
@@ -2991,7 +2991,7 @@ static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	qh->qh_state = QH_STATE_LINKED;
 	/* qtd completions reported later by interrupt */
 
-	enable_async(fotg210);
+	enable_async(fhcd2xx);
 }
 
 /*
@@ -3000,27 +3000,27 @@ static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
  * Returns null if it can't allocate a QH it needs to.
  * If the QH has TDs (urbs) already, that's great.
  */
-static struct fotg210_qh *qh_append_tds(struct fotg210_hcd *fotg210,
+static struct fhcd2xx_qh *qh_append_tds(struct fhcd2xx_hcd *fhcd2xx,
 					struct urb *urb,
 					struct list_head *qtd_list, int epnum,
 					void **ptr)
 {
-	struct fotg210_qh *qh = NULL;
-	__hc32 qh_addr_mask = cpu_to_hc32(fotg210, 0x7f);
+	struct fhcd2xx_qh *qh = NULL;
+	__hc32 qh_addr_mask = cpu_to_hc32(fhcd2xx, 0x7f);
 
-	qh = (struct fotg210_qh *) *ptr;
+	qh = (struct fhcd2xx_qh *) *ptr;
 	if (unlikely(qh == NULL)) {
-		/* can't sleep here, we have fotg210->lock... */
-		qh = qh_make(fotg210, urb, GFP_ATOMIC);
+		/* can't sleep here, we have fhcd2xx->lock... */
+		qh = qh_make(fhcd2xx, urb, GFP_ATOMIC);
 		*ptr = qh;
 	}
 	if (likely(qh != NULL)) {
-		struct fotg210_qtd *qtd;
+		struct fhcd2xx_qtd *qtd;
 
 		if (unlikely(list_empty(qtd_list)))
 			qtd = NULL;
 		else
-			qtd = list_entry(qtd_list->next, struct fotg210_qtd,
+			qtd = list_entry(qtd_list->next, struct fhcd2xx_qtd,
 					qtd_list);
 
 		/* control qh may need patching ... */
@@ -3034,7 +3034,7 @@ static struct fotg210_qh *qh_append_tds(struct fotg210_hcd *fotg210,
 		 * only hc or qh_refresh() ever modify the overlay.
 		 */
 		if (likely(qtd != NULL)) {
-			struct fotg210_qtd *dummy;
+			struct fhcd2xx_qtd *dummy;
 			dma_addr_t dma;
 			__hc32 token;
 
@@ -3044,7 +3044,7 @@ static struct fotg210_qh *qh_append_tds(struct fotg210_hcd *fotg210,
 			 * HC is allowed to fetch the old dummy (4.10.2).
 			 */
 			token = qtd->hw_token;
-			qtd->hw_token = HALT_BIT(fotg210);
+			qtd->hw_token = HALT_BIT(fhcd2xx);
 
 			dummy = qh->dummy;
 
@@ -3056,14 +3056,14 @@ static struct fotg210_qh *qh_append_tds(struct fotg210_hcd *fotg210,
 			list_add(&dummy->qtd_list, qtd_list);
 			list_splice_tail(qtd_list, &qh->qtd_list);
 
-			fotg210_qtd_init(fotg210, qtd, qtd->qtd_dma);
+			fhcd2xx_qtd_init(fhcd2xx, qtd, qtd->qtd_dma);
 			qh->dummy = qtd;
 
 			/* hc must see the new dummy at list end */
 			dma = qtd->qtd_dma;
 			qtd = list_entry(qh->qtd_list.prev,
-					struct fotg210_qtd, qtd_list);
-			qtd->hw_next = QTD_NEXT(fotg210, dma);
+					struct fhcd2xx_qtd, qtd_list);
+			qtd->hw_next = QTD_NEXT(fhcd2xx, dma);
 
 			/* let the hc process these next qtds */
 			wmb();
@@ -3075,22 +3075,22 @@ static struct fotg210_qh *qh_append_tds(struct fotg210_hcd *fotg210,
 	return qh;
 }
 
-static int submit_async(struct fotg210_hcd *fotg210, struct urb *urb,
+static int submit_async(struct fhcd2xx_hcd *fhcd2xx, struct urb *urb,
 			struct list_head *qtd_list, gfp_t mem_flags)
 {
 	int epnum;
 	unsigned long flags;
-	struct fotg210_qh *qh = NULL;
+	struct fhcd2xx_qh *qh = NULL;
 	int rc;
 
 	epnum = urb->ep->desc.bEndpointAddress;
 
-#ifdef FOTG210_URB_TRACE
+#ifdef FHCD2XX_URB_TRACE
 	{
-		struct fotg210_qtd *qtd;
+		struct fhcd2xx_qtd *qtd;
 
-		qtd = list_entry(qtd_list->next, struct fotg210_qtd, qtd_list);
-		fotg210_dbg(fotg210,
+		qtd = list_entry(qtd_list->next, struct fhcd2xx_qtd, qtd_list);
+		fhcd2xx_dbg(fhcd2xx,
 			 "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
 			 __func__, urb->dev->devpath, urb,
 			 epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
@@ -3099,18 +3099,18 @@ static int submit_async(struct fotg210_hcd *fotg210, struct urb *urb,
 	}
 #endif
 
-	spin_lock_irqsave(&fotg210->lock, flags);
-	if (unlikely(!HCD_HW_ACCESSIBLE(fotg210_to_hcd(fotg210)))) {
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
+	if (unlikely(!HCD_HW_ACCESSIBLE(fhcd2xx_to_hcd(fhcd2xx)))) {
 		rc = -ESHUTDOWN;
 		goto done;
 	}
-	rc = usb_hcd_link_urb_to_ep(fotg210_to_hcd(fotg210), urb);
+	rc = usb_hcd_link_urb_to_ep(fhcd2xx_to_hcd(fhcd2xx), urb);
 	if (unlikely(rc))
 		goto done;
 
-	qh = qh_append_tds(fotg210, urb, qtd_list, epnum, &urb->ep->hcpriv);
+	qh = qh_append_tds(fhcd2xx, urb, qtd_list, epnum, &urb->ep->hcpriv);
 	if (unlikely(qh == NULL)) {
-		usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
+		usb_hcd_unlink_urb_from_ep(fhcd2xx_to_hcd(fhcd2xx), urb);
 		rc = -ENOMEM;
 		goto done;
 	}
@@ -3119,110 +3119,110 @@ static int submit_async(struct fotg210_hcd *fotg210, struct urb *urb,
 	 * the HC and TT handle it when the TT has a buffer ready.
 	 */
 	if (likely(qh->qh_state == QH_STATE_IDLE))
-		qh_link_async(fotg210, qh);
+		qh_link_async(fhcd2xx, qh);
 done:
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 	if (unlikely(qh == NULL))
-		qtd_list_free(fotg210, urb, qtd_list);
+		qtd_list_free(fhcd2xx, urb, qtd_list);
 	return rc;
 }
 
-static void single_unlink_async(struct fotg210_hcd *fotg210,
-				struct fotg210_qh *qh)
+static void single_unlink_async(struct fhcd2xx_hcd *fhcd2xx,
+				struct fhcd2xx_qh *qh)
 {
-	struct fotg210_qh *prev;
+	struct fhcd2xx_qh *prev;
 
 	/* Add to the end of the list of QHs waiting for the next IAAD */
 	qh->qh_state = QH_STATE_UNLINK;
-	if (fotg210->async_unlink)
-		fotg210->async_unlink_last->unlink_next = qh;
+	if (fhcd2xx->async_unlink)
+		fhcd2xx->async_unlink_last->unlink_next = qh;
 	else
-		fotg210->async_unlink = qh;
-	fotg210->async_unlink_last = qh;
+		fhcd2xx->async_unlink = qh;
+	fhcd2xx->async_unlink_last = qh;
 
 	/* Unlink it from the schedule */
-	prev = fotg210->async;
+	prev = fhcd2xx->async;
 	while (prev->qh_next.qh != qh)
 		prev = prev->qh_next.qh;
 
 	prev->hw->hw_next = qh->hw->hw_next;
 	prev->qh_next = qh->qh_next;
-	if (fotg210->qh_scan_next == qh)
-		fotg210->qh_scan_next = qh->qh_next.qh;
+	if (fhcd2xx->qh_scan_next == qh)
+		fhcd2xx->qh_scan_next = qh->qh_next.qh;
 }
 
-static void start_iaa_cycle(struct fotg210_hcd *fotg210, bool nested)
+static void start_iaa_cycle(struct fhcd2xx_hcd *fhcd2xx, bool nested)
 {
 	/*
 	 * Do nothing if an IAA cycle is already running or
 	 * if one will be started shortly.
 	 */
-	if (fotg210->async_iaa || fotg210->async_unlinking)
+	if (fhcd2xx->async_iaa || fhcd2xx->async_unlinking)
 		return;
 
 	/* Do all the waiting QHs at once */
-	fotg210->async_iaa = fotg210->async_unlink;
-	fotg210->async_unlink = NULL;
+	fhcd2xx->async_iaa = fhcd2xx->async_unlink;
+	fhcd2xx->async_unlink = NULL;
 
 	/* If the controller isn't running, we don't have to wait for it */
-	if (unlikely(fotg210->rh_state < FOTG210_RH_RUNNING)) {
+	if (unlikely(fhcd2xx->rh_state < FHCD2XX_RH_RUNNING)) {
 		if (!nested)		/* Avoid recursion */
-			end_unlink_async(fotg210);
+			end_unlink_async(fhcd2xx);
 
 	/* Otherwise start a new IAA cycle */
-	} else if (likely(fotg210->rh_state == FOTG210_RH_RUNNING)) {
+	} else if (likely(fhcd2xx->rh_state == FHCD2XX_RH_RUNNING)) {
 		/* Make sure the unlinks are all visible to the hardware */
 		wmb();
 
-		fotg210_writel(fotg210, fotg210->command | CMD_IAAD,
-				&fotg210->regs->command);
-		fotg210_readl(fotg210, &fotg210->regs->command);
-		fotg210_enable_event(fotg210, FOTG210_HRTIMER_IAA_WATCHDOG,
+		fhcd2xx_writel(fhcd2xx, fhcd2xx->command | CMD_IAAD,
+				&fhcd2xx->regs->command);
+		fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->command);
+		fhcd2xx_enable_event(fhcd2xx, FHCD2XX_HRTIMER_IAA_WATCHDOG,
 				     true);
 	}
 }
 
 /* the async qh for the qtds being unlinked are now gone from the HC */
 
-static void end_unlink_async(struct fotg210_hcd *fotg210)
+static void end_unlink_async(struct fhcd2xx_hcd *fhcd2xx)
 {
-	struct fotg210_qh *qh;
+	struct fhcd2xx_qh *qh;
 
 	/* Process the idle QHs */
 restart:
-	fotg210->async_unlinking = true;
-	while (fotg210->async_iaa) {
-		qh = fotg210->async_iaa;
-		fotg210->async_iaa = qh->unlink_next;
+	fhcd2xx->async_unlinking = true;
+	while (fhcd2xx->async_iaa) {
+		qh = fhcd2xx->async_iaa;
+		fhcd2xx->async_iaa = qh->unlink_next;
 		qh->unlink_next = NULL;
 
 		qh->qh_state = QH_STATE_IDLE;
 		qh->qh_next.qh = NULL;
 
-		qh_completions(fotg210, qh);
+		qh_completions(fhcd2xx, qh);
 		if (!list_empty(&qh->qtd_list) &&
-				fotg210->rh_state == FOTG210_RH_RUNNING)
-			qh_link_async(fotg210, qh);
-		disable_async(fotg210);
+				fhcd2xx->rh_state == FHCD2XX_RH_RUNNING)
+			qh_link_async(fhcd2xx, qh);
+		disable_async(fhcd2xx);
 	}
-	fotg210->async_unlinking = false;
+	fhcd2xx->async_unlinking = false;
 
 	/* Start a new IAA cycle if any QHs are waiting for it */
-	if (fotg210->async_unlink) {
-		start_iaa_cycle(fotg210, true);
-		if (unlikely(fotg210->rh_state < FOTG210_RH_RUNNING))
+	if (fhcd2xx->async_unlink) {
+		start_iaa_cycle(fhcd2xx, true);
+		if (unlikely(fhcd2xx->rh_state < FHCD2XX_RH_RUNNING))
 			goto restart;
 	}
 }
 
-static void unlink_empty_async(struct fotg210_hcd *fotg210)
+static void unlink_empty_async(struct fhcd2xx_hcd *fhcd2xx)
 {
-	struct fotg210_qh *qh, *next;
-	bool stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
+	struct fhcd2xx_qh *qh, *next;
+	bool stopped = (fhcd2xx->rh_state < FHCD2XX_RH_RUNNING);
 	bool check_unlinks_later = false;
 
 	/* Unlink all the async QHs that have been empty for a timer cycle */
-	next = fotg210->async->qh_next.qh;
+	next = fhcd2xx->async->qh_next.qh;
 	while (next) {
 		qh = next;
 		next = qh->qh_next.qh;
@@ -3230,30 +3230,30 @@ static void unlink_empty_async(struct fotg210_hcd *fotg210)
 		if (list_empty(&qh->qtd_list) &&
 				qh->qh_state == QH_STATE_LINKED) {
 			if (!stopped && qh->unlink_cycle ==
-					fotg210->async_unlink_cycle)
+					fhcd2xx->async_unlink_cycle)
 				check_unlinks_later = true;
 			else
-				single_unlink_async(fotg210, qh);
+				single_unlink_async(fhcd2xx, qh);
 		}
 	}
 
 	/* Start a new IAA cycle if any QHs are waiting for it */
-	if (fotg210->async_unlink)
-		start_iaa_cycle(fotg210, false);
+	if (fhcd2xx->async_unlink)
+		start_iaa_cycle(fhcd2xx, false);
 
 	/* QHs that haven't been empty for long enough will be handled later */
 	if (check_unlinks_later) {
-		fotg210_enable_event(fotg210, FOTG210_HRTIMER_ASYNC_UNLINKS,
+		fhcd2xx_enable_event(fhcd2xx, FHCD2XX_HRTIMER_ASYNC_UNLINKS,
 				     true);
-		++fotg210->async_unlink_cycle;
+		++fhcd2xx->async_unlink_cycle;
 	}
 }
 
 /* makes sure the async qh will become idle */
-/* caller must own fotg210->lock */
+/* caller must own fhcd2xx->lock */
 
-static void start_unlink_async(struct fotg210_hcd *fotg210,
-			       struct fotg210_qh *qh)
+static void start_unlink_async(struct fhcd2xx_hcd *fhcd2xx,
+			       struct fhcd2xx_qh *qh)
 {
 	/*
 	 * If the QH isn't linked then there's nothing we can do
@@ -3266,19 +3266,19 @@ static void start_unlink_async(struct fotg210_hcd *fotg210,
 		return;
 	}
 
-	single_unlink_async(fotg210, qh);
-	start_iaa_cycle(fotg210, false);
+	single_unlink_async(fhcd2xx, qh);
+	start_iaa_cycle(fhcd2xx, false);
 }
 
-static void scan_async(struct fotg210_hcd *fotg210)
+static void scan_async(struct fhcd2xx_hcd *fhcd2xx)
 {
-	struct fotg210_qh *qh;
+	struct fhcd2xx_qh *qh;
 	bool check_unlinks_later = false;
 
-	fotg210->qh_scan_next = fotg210->async->qh_next.qh;
-	while (fotg210->qh_scan_next) {
-		qh = fotg210->qh_scan_next;
-		fotg210->qh_scan_next = qh->qh_next.qh;
+	fhcd2xx->qh_scan_next = fhcd2xx->async->qh_next.qh;
+	while (fhcd2xx->qh_scan_next) {
+		qh = fhcd2xx->qh_scan_next;
+		fhcd2xx->qh_scan_next = qh->qh_next.qh;
 rescan:
 		/* clean any finished work for this qh */
 		if (!list_empty(&qh->qtd_list)) {
@@ -3286,17 +3286,17 @@ rescan:
 
 			/*
 			 * Unlinks could happen here; completion reporting
-			 * drops the lock.  That's why fotg210->qh_scan_next
+			 * drops the lock.  That's why fhcd2xx->qh_scan_next
 			 * always holds the next qh to scan; if the next qh
-			 * gets unlinked then fotg210->qh_scan_next is adjusted
+			 * gets unlinked then fhcd2xx->qh_scan_next is adjusted
 			 * in single_unlink_async().
 			 */
-			temp = qh_completions(fotg210, qh);
+			temp = qh_completions(fhcd2xx, qh);
 			if (qh->needs_rescan) {
-				start_unlink_async(fotg210, qh);
+				start_unlink_async(fhcd2xx, qh);
 			} else if (list_empty(&qh->qtd_list)
 					&& qh->qh_state == QH_STATE_LINKED) {
-				qh->unlink_cycle = fotg210->async_unlink_cycle;
+				qh->unlink_cycle = fhcd2xx->async_unlink_cycle;
 				check_unlinks_later = true;
 			} else if (temp != 0)
 				goto rescan;
@@ -3309,12 +3309,12 @@ rescan:
 	 * we just scanned, there's a not-unusual case that it
 	 * doesn't stay idle for long.
 	 */
-	if (check_unlinks_later && fotg210->rh_state == FOTG210_RH_RUNNING &&
-			!(fotg210->enabled_hrtimer_events &
-				BIT(FOTG210_HRTIMER_ASYNC_UNLINKS))) {
-		fotg210_enable_event(fotg210,
-				     FOTG210_HRTIMER_ASYNC_UNLINKS, true);
-		++fotg210->async_unlink_cycle;
+	if (check_unlinks_later && fhcd2xx->rh_state == FHCD2XX_RH_RUNNING &&
+			!(fhcd2xx->enabled_hrtimer_events &
+				BIT(FHCD2XX_HRTIMER_ASYNC_UNLINKS))) {
+		fhcd2xx_enable_event(fhcd2xx,
+				     FHCD2XX_HRTIMER_ASYNC_UNLINKS, true);
+		++fhcd2xx->async_unlink_cycle;
 	}
 }
 /*
@@ -3329,18 +3329,18 @@ rescan:
  * It keeps track of every ITD (or SITD) that's linked, and holds enough
  * pre-calculated schedule data to make appending to the queue be quick.
  */
-static int fotg210_get_frame(struct usb_hcd *hcd);
+static int fhcd2xx_get_frame(struct usb_hcd *hcd);
 
 /*
  * periodic_next_shadow - return "next" pointer on shadow list
  * @periodic: host pointer to qh/itd
  * @tag: hardware tag for type of this record
  */
-static union fotg210_shadow *periodic_next_shadow(struct fotg210_hcd *fotg210,
-						union fotg210_shadow *periodic,
+static union fhcd2xx_shadow *periodic_next_shadow(struct fhcd2xx_hcd *fhcd2xx,
+						union fhcd2xx_shadow *periodic,
 						__hc32 tag)
 {
-	switch (hc32_to_cpu(fotg210, tag)) {
+	switch (hc32_to_cpu(fhcd2xx, tag)) {
 	case Q_TYPE_QH:
 		return &periodic->qh->qh_next;
 	case Q_TYPE_FSTN:
@@ -3350,11 +3350,11 @@ static union fotg210_shadow *periodic_next_shadow(struct fotg210_hcd *fotg210,
 	}
 }
 
-static __hc32 *shadow_next_periodic(struct fotg210_hcd *fotg210,
-				    union fotg210_shadow *periodic, __hc32 tag)
+static __hc32 *shadow_next_periodic(struct fhcd2xx_hcd *fhcd2xx,
+				    union fhcd2xx_shadow *periodic, __hc32 tag)
 {
-	switch (hc32_to_cpu(fotg210, tag)) {
-	/* our fotg210_shadow.qh is actually software part */
+	switch (hc32_to_cpu(fhcd2xx, tag)) {
+	/* our fhcd2xx_shadow.qh is actually software part */
 	case Q_TYPE_QH:
 		return &periodic->qh->hw->hw_next;
 	/* others are hw parts */
@@ -3363,20 +3363,20 @@ static __hc32 *shadow_next_periodic(struct fotg210_hcd *fotg210,
 	}
 }
 
-/* caller must hold fotg210->lock */
-static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
+/* caller must hold fhcd2xx->lock */
+static void periodic_unlink(struct fhcd2xx_hcd *fhcd2xx, unsigned frame,
 			    void *ptr)
 {
-	union fotg210_shadow *prev_p = &fotg210->pshadow[frame];
-	__hc32 *hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow here = *prev_p;
+	union fhcd2xx_shadow *prev_p = &fhcd2xx->pshadow[frame];
+	__hc32 *hw_p = &fhcd2xx->periodic[frame];
+	union fhcd2xx_shadow here = *prev_p;
 
 	/* find predecessor of "ptr"; hw and shadow lists are in sync */
 	while (here.ptr && here.ptr != ptr) {
-		prev_p = periodic_next_shadow(fotg210, prev_p,
-				Q_NEXT_TYPE(fotg210, *hw_p));
-		hw_p = shadow_next_periodic(fotg210, &here,
-				Q_NEXT_TYPE(fotg210, *hw_p));
+		prev_p = periodic_next_shadow(fhcd2xx, prev_p,
+				Q_NEXT_TYPE(fhcd2xx, *hw_p));
+		hw_p = shadow_next_periodic(fhcd2xx, &here,
+				Q_NEXT_TYPE(fhcd2xx, *hw_p));
 		here = *prev_p;
 	}
 	/* an interrupt entry (at list end) could have been shared */
@@ -3386,31 +3386,31 @@ static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
 	/* update shadow and hardware lists ... the old "next" pointers
 	 * from ptr may still be in use, the caller updates them.
 	 */
-	*prev_p = *periodic_next_shadow(fotg210, &here,
-			Q_NEXT_TYPE(fotg210, *hw_p));
+	*prev_p = *periodic_next_shadow(fhcd2xx, &here,
+			Q_NEXT_TYPE(fhcd2xx, *hw_p));
 
-	*hw_p = *shadow_next_periodic(fotg210, &here,
-				Q_NEXT_TYPE(fotg210, *hw_p));
+	*hw_p = *shadow_next_periodic(fhcd2xx, &here,
+				Q_NEXT_TYPE(fhcd2xx, *hw_p));
 }
 
 /* how many of the uframe's 125 usecs are allocated? */
-static unsigned short periodic_usecs(struct fotg210_hcd *fotg210,
+static unsigned short periodic_usecs(struct fhcd2xx_hcd *fhcd2xx,
 				     unsigned frame, unsigned uframe)
 {
-	__hc32 *hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow *q = &fotg210->pshadow[frame];
+	__hc32 *hw_p = &fhcd2xx->periodic[frame];
+	union fhcd2xx_shadow *q = &fhcd2xx->pshadow[frame];
 	unsigned usecs = 0;
-	struct fotg210_qh_hw *hw;
+	struct fhcd2xx_qh_hw *hw;
 
 	while (q->ptr) {
-		switch (hc32_to_cpu(fotg210, Q_NEXT_TYPE(fotg210, *hw_p))) {
+		switch (hc32_to_cpu(fhcd2xx, Q_NEXT_TYPE(fhcd2xx, *hw_p))) {
 		case Q_TYPE_QH:
 			hw = q->qh->hw;
 			/* is it in the S-mask? */
-			if (hw->hw_info2 & cpu_to_hc32(fotg210, 1 << uframe))
+			if (hw->hw_info2 & cpu_to_hc32(fhcd2xx, 1 << uframe))
 				usecs += q->qh->usecs;
 			/* ... or C-mask? */
-			if (hw->hw_info2 & cpu_to_hc32(fotg210,
+			if (hw->hw_info2 & cpu_to_hc32(fhcd2xx,
 					1 << (8 + uframe)))
 				usecs += q->qh->c_usecs;
 			hw_p = &hw->hw_next;
@@ -3421,8 +3421,8 @@ static unsigned short periodic_usecs(struct fotg210_hcd *fotg210,
 			/* for "save place" FSTNs, count the relevant INTR
 			 * bandwidth from the previous frame
 			 */
-			if (q->fstn->hw_prev != FOTG210_LIST_END(fotg210))
-				fotg210_dbg(fotg210, "ignoring FSTN cost ...\n");
+			if (q->fstn->hw_prev != FHCD2XX_LIST_END(fhcd2xx))
+				fhcd2xx_dbg(fhcd2xx, "ignoring FSTN cost ...\n");
 
 			hw_p = &q->fstn->hw_next;
 			q = &q->fstn->fstn_next;
@@ -3435,8 +3435,8 @@ static unsigned short periodic_usecs(struct fotg210_hcd *fotg210,
 			break;
 		}
 	}
-	if (usecs > fotg210->uframe_periodic_max)
-		fotg210_err(fotg210, "uframe %d sched overrun: %d usecs\n",
+	if (usecs > fhcd2xx->uframe_periodic_max)
+		fhcd2xx_err(fhcd2xx, "uframe %d sched overrun: %d usecs\n",
 			frame * 8 + uframe, usecs);
 	return usecs;
 }
@@ -3457,7 +3457,7 @@ static int same_tt(struct usb_device *dev1, struct usb_device *dev2)
  * for a periodic transfer starting at the specified frame, using
  * all the uframes in the mask.
  */
-static int tt_no_collision(struct fotg210_hcd *fotg210, unsigned period,
+static int tt_no_collision(struct fhcd2xx_hcd *fhcd2xx, unsigned period,
 			   struct usb_device *dev, unsigned frame, u32 uf_mask)
 {
 	if (period == 0)	/* error */
@@ -3467,17 +3467,17 @@ static int tt_no_collision(struct fotg210_hcd *fotg210, unsigned period,
 	 * (different dev or endpoint) until the next uframe.
 	 * calling convention doesn't make that distinction.
 	 */
-	for (; frame < fotg210->periodic_size; frame += period) {
-		union fotg210_shadow here;
+	for (; frame < fhcd2xx->periodic_size; frame += period) {
+		union fhcd2xx_shadow here;
 		__hc32 type;
-		struct fotg210_qh_hw *hw;
+		struct fhcd2xx_qh_hw *hw;
 
-		here = fotg210->pshadow[frame];
-		type = Q_NEXT_TYPE(fotg210, fotg210->periodic[frame]);
+		here = fhcd2xx->pshadow[frame];
+		type = Q_NEXT_TYPE(fhcd2xx, fhcd2xx->periodic[frame]);
 		while (here.ptr) {
-			switch (hc32_to_cpu(fotg210, type)) {
+			switch (hc32_to_cpu(fhcd2xx, type)) {
 			case Q_TYPE_ITD:
-				type = Q_NEXT_TYPE(fotg210, here.itd->hw_next);
+				type = Q_NEXT_TYPE(fhcd2xx, here.itd->hw_next);
 				here = here.itd->itd_next;
 				continue;
 			case Q_TYPE_QH:
@@ -3485,19 +3485,19 @@ static int tt_no_collision(struct fotg210_hcd *fotg210, unsigned period,
 				if (same_tt(dev, here.qh->dev)) {
 					u32 mask;
 
-					mask = hc32_to_cpu(fotg210,
+					mask = hc32_to_cpu(fhcd2xx,
 							hw->hw_info2);
 					/* "knows" no gap is needed */
 					mask |= mask >> 8;
 					if (mask & uf_mask)
 						break;
 				}
-				type = Q_NEXT_TYPE(fotg210, hw->hw_next);
+				type = Q_NEXT_TYPE(fhcd2xx, hw->hw_next);
 				here = here.qh->qh_next;
 				continue;
 			/* case Q_TYPE_FSTN: */
 			default:
-				fotg210_dbg(fotg210,
+				fhcd2xx_dbg(fhcd2xx,
 					"periodic frame %d bogus type %d\n",
 					frame, type);
 			}
@@ -3511,43 +3511,43 @@ static int tt_no_collision(struct fotg210_hcd *fotg210, unsigned period,
 	return 1;
 }
 
-static void enable_periodic(struct fotg210_hcd *fotg210)
+static void enable_periodic(struct fhcd2xx_hcd *fhcd2xx)
 {
-	if (fotg210->periodic_count++)
+	if (fhcd2xx->periodic_count++)
 		return;
 
 	/* Stop waiting to turn off the periodic schedule */
-	fotg210->enabled_hrtimer_events &=
-		~BIT(FOTG210_HRTIMER_DISABLE_PERIODIC);
+	fhcd2xx->enabled_hrtimer_events &=
+		~BIT(FHCD2XX_HRTIMER_DISABLE_PERIODIC);
 
 	/* Don't start the schedule until PSS is 0 */
-	fotg210_poll_PSS(fotg210);
-	turn_on_io_watchdog(fotg210);
+	fhcd2xx_poll_PSS(fhcd2xx);
+	turn_on_io_watchdog(fhcd2xx);
 }
 
-static void disable_periodic(struct fotg210_hcd *fotg210)
+static void disable_periodic(struct fhcd2xx_hcd *fhcd2xx)
 {
-	if (--fotg210->periodic_count)
+	if (--fhcd2xx->periodic_count)
 		return;
 
 	/* Don't turn off the schedule until PSS is 1 */
-	fotg210_poll_PSS(fotg210);
+	fhcd2xx_poll_PSS(fhcd2xx);
 }
 
 /* periodic schedule slots have iso tds (normal or split) first, then a
  * sparse tree for active interrupt transfers.
  *
  * this just links in a qh; caller guarantees uframe masks are set right.
- * no FSTN support (yet; fotg210 0.96+)
+ * no FSTN support (yet; fhcd2xx 0.96+)
  */
-static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+static void qh_link_periodic(struct fhcd2xx_hcd *fhcd2xx, struct fhcd2xx_qh *qh)
 {
 	unsigned i;
 	unsigned period = qh->period;
 
 	dev_dbg(&qh->dev->dev,
 		"link qh%d-%04x/%p start %d [%d/%d us]\n",
-		period, hc32_to_cpup(fotg210, &qh->hw->hw_info2)
+		period, hc32_to_cpup(fhcd2xx, &qh->hw->hw_info2)
 			& (QH_CMASK | QH_SMASK),
 		qh, qh->start, qh->usecs, qh->c_usecs);
 
@@ -3555,19 +3555,19 @@ static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	if (period == 0)
 		period = 1;
 
-	for (i = qh->start; i < fotg210->periodic_size; i += period) {
-		union fotg210_shadow *prev = &fotg210->pshadow[i];
-		__hc32 *hw_p = &fotg210->periodic[i];
-		union fotg210_shadow here = *prev;
+	for (i = qh->start; i < fhcd2xx->periodic_size; i += period) {
+		union fhcd2xx_shadow *prev = &fhcd2xx->pshadow[i];
+		__hc32 *hw_p = &fhcd2xx->periodic[i];
+		union fhcd2xx_shadow here = *prev;
 		__hc32 type = 0;
 
 		/* skip the iso nodes at list head */
 		while (here.ptr) {
-			type = Q_NEXT_TYPE(fotg210, *hw_p);
-			if (type == cpu_to_hc32(fotg210, Q_TYPE_QH))
+			type = Q_NEXT_TYPE(fhcd2xx, *hw_p);
+			if (type == cpu_to_hc32(fhcd2xx, Q_TYPE_QH))
 				break;
-			prev = periodic_next_shadow(fotg210, prev, type);
-			hw_p = shadow_next_periodic(fotg210, &here, type);
+			prev = periodic_next_shadow(fhcd2xx, prev, type);
+			hw_p = shadow_next_periodic(fhcd2xx, &here, type);
 			here = *prev;
 		}
 
@@ -3588,26 +3588,26 @@ static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 				qh->hw->hw_next = *hw_p;
 			wmb();
 			prev->qh = qh;
-			*hw_p = QH_NEXT(fotg210, qh->qh_dma);
+			*hw_p = QH_NEXT(fhcd2xx, qh->qh_dma);
 		}
 	}
 	qh->qh_state = QH_STATE_LINKED;
 	qh->xacterrs = 0;
 
 	/* update per-qh bandwidth for usbfs */
-	fotg210_to_hcd(fotg210)->self.bandwidth_allocated += qh->period
+	fhcd2xx_to_hcd(fhcd2xx)->self.bandwidth_allocated += qh->period
 		? ((qh->usecs + qh->c_usecs) / qh->period)
 		: (qh->usecs * 8);
 
-	list_add(&qh->intr_node, &fotg210->intr_qh_list);
+	list_add(&qh->intr_node, &fhcd2xx->intr_qh_list);
 
 	/* maybe enable periodic schedule processing */
-	++fotg210->intr_count;
-	enable_periodic(fotg210);
+	++fhcd2xx->intr_count;
+	enable_periodic(fhcd2xx);
 }
 
-static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
-			       struct fotg210_qh *qh)
+static void qh_unlink_periodic(struct fhcd2xx_hcd *fhcd2xx,
+			       struct fhcd2xx_qh *qh)
 {
 	unsigned i;
 	unsigned period;
@@ -3632,32 +3632,32 @@ static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
 	if (!period)
 		period = 1;
 
-	for (i = qh->start; i < fotg210->periodic_size; i += period)
-		periodic_unlink(fotg210, i, qh);
+	for (i = qh->start; i < fhcd2xx->periodic_size; i += period)
+		periodic_unlink(fhcd2xx, i, qh);
 
 	/* update per-qh bandwidth for usbfs */
-	fotg210_to_hcd(fotg210)->self.bandwidth_allocated -= qh->period
+	fhcd2xx_to_hcd(fhcd2xx)->self.bandwidth_allocated -= qh->period
 		? ((qh->usecs + qh->c_usecs) / qh->period)
 		: (qh->usecs * 8);
 
 	dev_dbg(&qh->dev->dev,
 		"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
 		qh->period,
-		hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
+		hc32_to_cpup(fhcd2xx, &qh->hw->hw_info2) &
 		(QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs, qh->c_usecs);
 
 	/* qh->qh_next still "live" to HC */
 	qh->qh_state = QH_STATE_UNLINK;
 	qh->qh_next.ptr = NULL;
 
-	if (fotg210->qh_scan_next == qh)
-		fotg210->qh_scan_next = list_entry(qh->intr_node.next,
-				struct fotg210_qh, intr_node);
+	if (fhcd2xx->qh_scan_next == qh)
+		fhcd2xx->qh_scan_next = list_entry(qh->intr_node.next,
+				struct fhcd2xx_qh, intr_node);
 	list_del(&qh->intr_node);
 }
 
-static void start_unlink_intr(struct fotg210_hcd *fotg210,
-			      struct fotg210_qh *qh)
+static void start_unlink_intr(struct fhcd2xx_hcd *fhcd2xx,
+			      struct fhcd2xx_qh *qh)
 {
 	/* If the QH isn't linked then there's nothing we can do
 	 * unless we were called during a giveback, in which case
@@ -3669,7 +3669,7 @@ static void start_unlink_intr(struct fotg210_hcd *fotg210,
 		return;
 	}
 
-	qh_unlink_periodic(fotg210, qh);
+	qh_unlink_periodic(fhcd2xx, qh);
 
 	/* Make sure the unlinks are visible before starting the timer */
 	wmb();
@@ -3679,40 +3679,40 @@ static void start_unlink_intr(struct fotg210_hcd *fotg210,
 	 * stop accessing an unlinked interrupt QH.  The timer delay is
 	 * 9 uframes; presumably that will be long enough.
 	 */
-	qh->unlink_cycle = fotg210->intr_unlink_cycle;
+	qh->unlink_cycle = fhcd2xx->intr_unlink_cycle;
 
 	/* New entries go at the end of the intr_unlink list */
-	if (fotg210->intr_unlink)
-		fotg210->intr_unlink_last->unlink_next = qh;
+	if (fhcd2xx->intr_unlink)
+		fhcd2xx->intr_unlink_last->unlink_next = qh;
 	else
-		fotg210->intr_unlink = qh;
-	fotg210->intr_unlink_last = qh;
+		fhcd2xx->intr_unlink = qh;
+	fhcd2xx->intr_unlink_last = qh;
 
-	if (fotg210->intr_unlinking)
+	if (fhcd2xx->intr_unlinking)
 		;	/* Avoid recursive calls */
-	else if (fotg210->rh_state < FOTG210_RH_RUNNING)
-		fotg210_handle_intr_unlinks(fotg210);
-	else if (fotg210->intr_unlink == qh) {
-		fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
+	else if (fhcd2xx->rh_state < FHCD2XX_RH_RUNNING)
+		fhcd2xx_handle_intr_unlinks(fhcd2xx);
+	else if (fhcd2xx->intr_unlink == qh) {
+		fhcd2xx_enable_event(fhcd2xx, FHCD2XX_HRTIMER_UNLINK_INTR,
 				     true);
-		++fotg210->intr_unlink_cycle;
+		++fhcd2xx->intr_unlink_cycle;
 	}
 }
 
-static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+static void end_unlink_intr(struct fhcd2xx_hcd *fhcd2xx, struct fhcd2xx_qh *qh)
 {
-	struct fotg210_qh_hw *hw = qh->hw;
+	struct fhcd2xx_qh_hw *hw = qh->hw;
 	int rc;
 
 	qh->qh_state = QH_STATE_IDLE;
-	hw->hw_next = FOTG210_LIST_END(fotg210);
+	hw->hw_next = FHCD2XX_LIST_END(fhcd2xx);
 
-	qh_completions(fotg210, qh);
+	qh_completions(fhcd2xx, qh);
 
 	/* reschedule QH iff another request is queued */
 	if (!list_empty(&qh->qtd_list) &&
-	    fotg210->rh_state == FOTG210_RH_RUNNING) {
-		rc = qh_schedule(fotg210, qh);
+	    fhcd2xx->rh_state == FHCD2XX_RH_RUNNING) {
+		rc = qh_schedule(fhcd2xx, qh);
 
 		/* An error here likely indicates handshake failure
 		 * or no space left in the schedule.  Neither fault
@@ -3721,16 +3721,16 @@ static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		 * FIXME kill the now-dysfunctional queued urbs
 		 */
 		if (rc != 0)
-			fotg210_err(fotg210, "can't reschedule qh %p, err %d\n",
+			fhcd2xx_err(fhcd2xx, "can't reschedule qh %p, err %d\n",
 					qh, rc);
 	}
 
 	/* maybe turn off periodic schedule */
-	--fotg210->intr_count;
-	disable_periodic(fotg210);
+	--fhcd2xx->intr_count;
+	disable_periodic(fhcd2xx);
 }
 
-static int check_period(struct fotg210_hcd *fotg210, unsigned frame,
+static int check_period(struct fhcd2xx_hcd *fhcd2xx, unsigned frame,
 			unsigned uframe, unsigned period, unsigned usecs)
 {
 	int claimed;
@@ -3742,7 +3742,7 @@ static int check_period(struct fotg210_hcd *fotg210, unsigned frame,
 		return 0;
 
 	/* convert "usecs we need" to "max already claimed" */
-	usecs = fotg210->uframe_periodic_max - usecs;
+	usecs = fhcd2xx->uframe_periodic_max - usecs;
 
 	/* we "know" 2 and 4 uframe intervals were rejected; so
 	 * for period 0, check _every_ microframe in the schedule.
@@ -3750,28 +3750,28 @@ static int check_period(struct fotg210_hcd *fotg210, unsigned frame,
 	if (unlikely(period == 0)) {
 		do {
 			for (uframe = 0; uframe < 7; uframe++) {
-				claimed = periodic_usecs(fotg210, frame,
+				claimed = periodic_usecs(fhcd2xx, frame,
 							 uframe);
 				if (claimed > usecs)
 					return 0;
 			}
-		} while ((frame += 1) < fotg210->periodic_size);
+		} while ((frame += 1) < fhcd2xx->periodic_size);
 
 	/* just check the specified uframe, at that period */
 	} else {
 		do {
-			claimed = periodic_usecs(fotg210, frame, uframe);
+			claimed = periodic_usecs(fhcd2xx, frame, uframe);
 			if (claimed > usecs)
 				return 0;
-		} while ((frame += period) < fotg210->periodic_size);
+		} while ((frame += period) < fhcd2xx->periodic_size);
 	}
 
 	/* success! */
 	return 1;
 }
 
-static int check_intr_schedule(struct fotg210_hcd *fotg210, unsigned frame,
-			       unsigned uframe, const struct fotg210_qh *qh,
+static int check_intr_schedule(struct fhcd2xx_hcd *fhcd2xx, unsigned frame,
+			       unsigned uframe, const struct fhcd2xx_qh *qh,
 			       __hc32 *c_maskp)
 {
 	int retval = -ENOSPC;
@@ -3780,7 +3780,7 @@ static int check_intr_schedule(struct fotg210_hcd *fotg210, unsigned frame,
 	if (qh->c_usecs && uframe >= 6)		/* FSTN territory? */
 		goto done;
 
-	if (!check_period(fotg210, frame, uframe, qh->period, qh->usecs))
+	if (!check_period(fhcd2xx, frame, uframe, qh->period, qh->usecs))
 		goto done;
 	if (!qh->c_usecs) {
 		retval = 0;
@@ -3796,14 +3796,14 @@ static int check_intr_schedule(struct fotg210_hcd *fotg210, unsigned frame,
 	 * one smart pass...
 	 */
 	mask = 0x03 << (uframe + qh->gap_uf);
-	*c_maskp = cpu_to_hc32(fotg210, mask << 8);
+	*c_maskp = cpu_to_hc32(fhcd2xx, mask << 8);
 
 	mask |= 1 << uframe;
-	if (tt_no_collision(fotg210, qh->period, qh->dev, frame, mask)) {
-		if (!check_period(fotg210, frame, uframe + qh->gap_uf + 1,
+	if (tt_no_collision(fhcd2xx, qh->period, qh->dev, frame, mask)) {
+		if (!check_period(fhcd2xx, frame, uframe + qh->gap_uf + 1,
 					qh->period, qh->c_usecs))
 			goto done;
-		if (!check_period(fotg210, frame, uframe + qh->gap_uf,
+		if (!check_period(fhcd2xx, frame, uframe + qh->gap_uf,
 					qh->period, qh->c_usecs))
 			goto done;
 		retval = 0;
@@ -3815,22 +3815,22 @@ done:
 /* "first fit" scheduling policy used the first time through,
  * or when the previous schedule slot can't be re-used.
  */
-static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+static int qh_schedule(struct fhcd2xx_hcd *fhcd2xx, struct fhcd2xx_qh *qh)
 {
 	int status;
 	unsigned uframe;
 	__hc32 c_mask;
 	unsigned frame;	/* 0..(qh->period - 1), or NO_FRAME */
-	struct fotg210_qh_hw *hw = qh->hw;
+	struct fhcd2xx_qh_hw *hw = qh->hw;
 
-	qh_refresh(fotg210, qh);
-	hw->hw_next = FOTG210_LIST_END(fotg210);
+	qh_refresh(fhcd2xx, qh);
+	hw->hw_next = FHCD2XX_LIST_END(fhcd2xx);
 	frame = qh->start;
 
 	/* reuse the previous schedule slots, if we can */
 	if (frame < qh->period) {
-		uframe = ffs(hc32_to_cpup(fotg210, &hw->hw_info2) & QH_SMASK);
-		status = check_intr_schedule(fotg210, frame, --uframe,
+		uframe = ffs(hc32_to_cpup(fhcd2xx, &hw->hw_info2) & QH_SMASK);
+		status = check_intr_schedule(fhcd2xx, frame, --uframe,
 				qh, &c_mask);
 	} else {
 		uframe = 0;
@@ -3847,9 +3847,9 @@ static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 			int i;
 
 			for (i = qh->period; status && i > 0; --i) {
-				frame = ++fotg210->random_frame % qh->period;
+				frame = ++fhcd2xx->random_frame % qh->period;
 				for (uframe = 0; uframe < 8; uframe++) {
-					status = check_intr_schedule(fotg210,
+					status = check_intr_schedule(fhcd2xx,
 							frame, uframe, qh,
 							&c_mask);
 					if (status == 0)
@@ -3860,7 +3860,7 @@ static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		/* qh->period == 0 means every uframe */
 		} else {
 			frame = 0;
-			status = check_intr_schedule(fotg210, 0, 0, qh,
+			status = check_intr_schedule(fhcd2xx, 0, 0, qh,
 						     &c_mask);
 		}
 		if (status)
@@ -3868,79 +3868,79 @@ static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		qh->start = frame;
 
 		/* reset S-frame and (maybe) C-frame masks */
-		hw->hw_info2 &= cpu_to_hc32(fotg210, ~(QH_CMASK | QH_SMASK));
+		hw->hw_info2 &= cpu_to_hc32(fhcd2xx, ~(QH_CMASK | QH_SMASK));
 		hw->hw_info2 |= qh->period
-			? cpu_to_hc32(fotg210, 1 << uframe)
-			: cpu_to_hc32(fotg210, QH_SMASK);
+			? cpu_to_hc32(fhcd2xx, 1 << uframe)
+			: cpu_to_hc32(fhcd2xx, QH_SMASK);
 		hw->hw_info2 |= c_mask;
 	} else
-		fotg210_dbg(fotg210, "reused qh %p schedule\n", qh);
+		fhcd2xx_dbg(fhcd2xx, "reused qh %p schedule\n", qh);
 
 	/* stuff into the periodic schedule */
-	qh_link_periodic(fotg210, qh);
+	qh_link_periodic(fhcd2xx, qh);
 done:
 	return status;
 }
 
-static int intr_submit(struct fotg210_hcd *fotg210, struct urb *urb,
+static int intr_submit(struct fhcd2xx_hcd *fhcd2xx, struct urb *urb,
 		       struct list_head *qtd_list, gfp_t mem_flags)
 {
 	unsigned epnum;
 	unsigned long flags;
-	struct fotg210_qh *qh;
+	struct fhcd2xx_qh *qh;
 	int status;
 	struct list_head empty;
 
 	/* get endpoint and transfer/schedule data */
 	epnum = urb->ep->desc.bEndpointAddress;
 
-	spin_lock_irqsave(&fotg210->lock, flags);
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
 
-	if (unlikely(!HCD_HW_ACCESSIBLE(fotg210_to_hcd(fotg210)))) {
+	if (unlikely(!HCD_HW_ACCESSIBLE(fhcd2xx_to_hcd(fhcd2xx)))) {
 		status = -ESHUTDOWN;
 		goto done_not_linked;
 	}
-	status = usb_hcd_link_urb_to_ep(fotg210_to_hcd(fotg210), urb);
+	status = usb_hcd_link_urb_to_ep(fhcd2xx_to_hcd(fhcd2xx), urb);
 	if (unlikely(status))
 		goto done_not_linked;
 
 	/* get qh and force any scheduling errors */
 	INIT_LIST_HEAD(&empty);
-	qh = qh_append_tds(fotg210, urb, &empty, epnum, &urb->ep->hcpriv);
+	qh = qh_append_tds(fhcd2xx, urb, &empty, epnum, &urb->ep->hcpriv);
 	if (qh == NULL) {
 		status = -ENOMEM;
 		goto done;
 	}
 	if (qh->qh_state == QH_STATE_IDLE) {
-		status = qh_schedule(fotg210, qh);
+		status = qh_schedule(fhcd2xx, qh);
 		if (status)
 			goto done;
 	}
 
 	/* then queue the urb's tds to the qh */
-	qh = qh_append_tds(fotg210, urb, qtd_list, epnum, &urb->ep->hcpriv);
+	qh = qh_append_tds(fhcd2xx, urb, qtd_list, epnum, &urb->ep->hcpriv);
 	BUG_ON(qh == NULL);
 
 	/* ... update usbfs periodic stats */
-	fotg210_to_hcd(fotg210)->self.bandwidth_int_reqs++;
+	fhcd2xx_to_hcd(fhcd2xx)->self.bandwidth_int_reqs++;
 
 done:
 	if (unlikely(status))
-		usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
+		usb_hcd_unlink_urb_from_ep(fhcd2xx_to_hcd(fhcd2xx), urb);
 done_not_linked:
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 	if (status)
-		qtd_list_free(fotg210, urb, qtd_list);
+		qtd_list_free(fhcd2xx, urb, qtd_list);
 
 	return status;
 }
 
-static void scan_intr(struct fotg210_hcd *fotg210)
+static void scan_intr(struct fhcd2xx_hcd *fhcd2xx)
 {
-	struct fotg210_qh *qh;
+	struct fhcd2xx_qh *qh;
 
-	list_for_each_entry_safe(qh, fotg210->qh_scan_next,
-				 &fotg210->intr_qh_list, intr_node) {
+	list_for_each_entry_safe(qh, fhcd2xx->qh_scan_next,
+				 &fhcd2xx->intr_qh_list, intr_node) {
 rescan:
 		/* clean any finished work for this qh */
 		if (!list_empty(&qh->qtd_list)) {
@@ -3948,27 +3948,27 @@ rescan:
 
 			/*
 			 * Unlinks could happen here; completion reporting
-			 * drops the lock.  That's why fotg210->qh_scan_next
+			 * drops the lock.  That's why fhcd2xx->qh_scan_next
 			 * always holds the next qh to scan; if the next qh
-			 * gets unlinked then fotg210->qh_scan_next is adjusted
+			 * gets unlinked then fhcd2xx->qh_scan_next is adjusted
 			 * in qh_unlink_periodic().
 			 */
-			temp = qh_completions(fotg210, qh);
+			temp = qh_completions(fhcd2xx, qh);
 			if (unlikely(qh->needs_rescan ||
 					(list_empty(&qh->qtd_list) &&
 					 qh->qh_state == QH_STATE_LINKED)))
-				start_unlink_intr(fotg210, qh);
+				start_unlink_intr(fhcd2xx, qh);
 			else if (temp != 0)
 				goto rescan;
 		}
 	}
 }
 
-/* fotg210_iso_stream ops work with both ITD and SITD */
+/* fhcd2xx_iso_stream ops work with both ITD and SITD */
 
-static struct fotg210_iso_stream *iso_stream_alloc(gfp_t mem_flags)
+static struct fhcd2xx_iso_stream *iso_stream_alloc(gfp_t mem_flags)
 {
-	struct fotg210_iso_stream *stream;
+	struct fhcd2xx_iso_stream *stream;
 
 	stream = kzalloc(sizeof(*stream), mem_flags);
 	if (likely(stream != NULL)) {
@@ -3979,8 +3979,8 @@ static struct fotg210_iso_stream *iso_stream_alloc(gfp_t mem_flags)
 	return stream;
 }
 
-static void iso_stream_init(struct fotg210_hcd *fotg210,
-			    struct fotg210_iso_stream *stream,
+static void iso_stream_init(struct fhcd2xx_hcd *fhcd2xx,
+			    struct fhcd2xx_iso_stream *stream,
 			    struct usb_device *dev, int pipe,
 			    unsigned interval)
 {
@@ -4007,9 +4007,9 @@ static void iso_stream_init(struct fotg210_hcd *fotg210,
 	buf1 |= maxp;
 	maxp *= multi;
 
-	stream->buf0 = cpu_to_hc32(fotg210, (epnum << 8) | dev->devnum);
-	stream->buf1 = cpu_to_hc32(fotg210, buf1);
-	stream->buf2 = cpu_to_hc32(fotg210, multi);
+	stream->buf0 = cpu_to_hc32(fhcd2xx, (epnum << 8) | dev->devnum);
+	stream->buf1 = cpu_to_hc32(fhcd2xx, buf1);
+	stream->buf2 = cpu_to_hc32(fhcd2xx, multi);
 
 	/* usbfs wants to report the average usecs per frame tied up
 	 * when transfers on this endpoint are scheduled ...
@@ -4033,11 +4033,11 @@ static void iso_stream_init(struct fotg210_hcd *fotg210,
 	stream->maxp = maxp;
 }
 
-static struct fotg210_iso_stream *iso_stream_find(struct fotg210_hcd *fotg210,
+static struct fhcd2xx_iso_stream *iso_stream_find(struct fhcd2xx_hcd *fhcd2xx,
 						  struct urb *urb)
 {
 	unsigned epnum;
-	struct fotg210_iso_stream *stream;
+	struct fhcd2xx_iso_stream *stream;
 	struct usb_host_endpoint *ep;
 	unsigned long flags;
 
@@ -4047,7 +4047,7 @@ static struct fotg210_iso_stream *iso_stream_find(struct fotg210_hcd *fotg210,
 	else
 		ep = urb->dev->ep_out[epnum];
 
-	spin_lock_irqsave(&fotg210->lock, flags);
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
 	stream = ep->hcpriv;
 
 	if (unlikely(stream == NULL)) {
@@ -4055,31 +4055,31 @@ static struct fotg210_iso_stream *iso_stream_find(struct fotg210_hcd *fotg210,
 		if (likely(stream != NULL)) {
 			ep->hcpriv = stream;
 			stream->ep = ep;
-			iso_stream_init(fotg210, stream, urb->dev, urb->pipe,
+			iso_stream_init(fhcd2xx, stream, urb->dev, urb->pipe,
 					urb->interval);
 		}
 
 	/* if dev->ep[epnum] is a QH, hw is set */
 	} else if (unlikely(stream->hw != NULL)) {
-		fotg210_dbg(fotg210, "dev %s ep%d%s, not iso??\n",
+		fhcd2xx_dbg(fhcd2xx, "dev %s ep%d%s, not iso??\n",
 			urb->dev->devpath, epnum,
 			usb_pipein(urb->pipe) ? "in" : "out");
 		stream = NULL;
 	}
 
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 	return stream;
 }
 
-/* fotg210_iso_sched ops can be ITD-only or SITD-only */
+/* fhcd2xx_iso_sched ops can be ITD-only or SITD-only */
 
-static struct fotg210_iso_sched *iso_sched_alloc(unsigned packets,
+static struct fhcd2xx_iso_sched *iso_sched_alloc(unsigned packets,
 						 gfp_t mem_flags)
 {
-	struct fotg210_iso_sched *iso_sched;
+	struct fhcd2xx_iso_sched *iso_sched;
 	int size = sizeof(*iso_sched);
 
-	size += packets * sizeof(struct fotg210_iso_packet);
+	size += packets * sizeof(struct fhcd2xx_iso_packet);
 	iso_sched = kzalloc(size, mem_flags);
 	if (likely(iso_sched != NULL))
 		INIT_LIST_HEAD(&iso_sched->td_list);
@@ -4087,9 +4087,9 @@ static struct fotg210_iso_sched *iso_sched_alloc(unsigned packets,
 	return iso_sched;
 }
 
-static inline void itd_sched_init(struct fotg210_hcd *fotg210,
-				  struct fotg210_iso_sched *iso_sched,
-				  struct fotg210_iso_stream *stream,
+static inline void itd_sched_init(struct fhcd2xx_hcd *fhcd2xx,
+				  struct fhcd2xx_iso_sched *iso_sched,
+				  struct fhcd2xx_iso_stream *stream,
 				  struct urb *urb)
 {
 	unsigned i;
@@ -4102,7 +4102,7 @@ static inline void itd_sched_init(struct fotg210_hcd *fotg210,
 	 * when we fit new itds into the schedule.
 	 */
 	for (i = 0; i < urb->number_of_packets; i++) {
-		struct fotg210_iso_packet *uframe = &iso_sched->packet[i];
+		struct fhcd2xx_iso_packet *uframe = &iso_sched->packet[i];
 		unsigned length;
 		dma_addr_t buf;
 		u32 trans;
@@ -4110,13 +4110,13 @@ static inline void itd_sched_init(struct fotg210_hcd *fotg210,
 		length = urb->iso_frame_desc[i].length;
 		buf = dma + urb->iso_frame_desc[i].offset;
 
-		trans = FOTG210_ISOC_ACTIVE;
+		trans = FHCD2XX_ISOC_ACTIVE;
 		trans |= buf & 0x0fff;
 		if (unlikely(((i + 1) == urb->number_of_packets))
 				&& !(urb->transfer_flags & URB_NO_INTERRUPT))
-			trans |= FOTG210_ITD_IOC;
+			trans |= FHCD2XX_ITD_IOC;
 		trans |= length << 16;
-		uframe->transaction = cpu_to_hc32(fotg210, trans);
+		uframe->transaction = cpu_to_hc32(fhcd2xx, trans);
 
 		/* might need to cross a buffer page within a uframe */
 		uframe->bufp = (buf & ~(u64)0x0fff);
@@ -4126,32 +4126,32 @@ static inline void itd_sched_init(struct fotg210_hcd *fotg210,
 	}
 }
 
-static void iso_sched_free(struct fotg210_iso_stream *stream,
-			   struct fotg210_iso_sched *iso_sched)
+static void iso_sched_free(struct fhcd2xx_iso_stream *stream,
+			   struct fhcd2xx_iso_sched *iso_sched)
 {
 	if (!iso_sched)
 		return;
-	/* caller must hold fotg210->lock!*/
+	/* caller must hold fhcd2xx->lock!*/
 	list_splice(&iso_sched->td_list, &stream->free_list);
 	kfree(iso_sched);
 }
 
-static int itd_urb_transaction(struct fotg210_iso_stream *stream,
-			       struct fotg210_hcd *fotg210,
+static int itd_urb_transaction(struct fhcd2xx_iso_stream *stream,
+			       struct fhcd2xx_hcd *fhcd2xx,
 			       struct urb *urb, gfp_t mem_flags)
 {
-	struct fotg210_itd *itd;
+	struct fhcd2xx_itd *itd;
 	dma_addr_t itd_dma;
 	int i;
 	unsigned num_itds;
-	struct fotg210_iso_sched *sched;
+	struct fhcd2xx_iso_sched *sched;
 	unsigned long flags;
 
 	sched = iso_sched_alloc(urb->number_of_packets, mem_flags);
 	if (unlikely(sched == NULL))
 		return -ENOMEM;
 
-	itd_sched_init(fotg210, sched, stream, urb);
+	itd_sched_init(fhcd2xx, sched, stream, urb);
 
 	if (urb->interval < 8)
 		num_itds = 1 + (sched->span + 7) / 8;
@@ -4159,7 +4159,7 @@ static int itd_urb_transaction(struct fotg210_iso_stream *stream,
 		num_itds = urb->number_of_packets;
 
 	/* allocate/init ITDs */
-	spin_lock_irqsave(&fotg210->lock, flags);
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
 	for (i = 0; i < num_itds; i++) {
 
 		/*
@@ -4168,20 +4168,20 @@ static int itd_urb_transaction(struct fotg210_iso_stream *stream,
 		 */
 		if (likely(!list_empty(&stream->free_list))) {
 			itd = list_first_entry(&stream->free_list,
-					struct fotg210_itd, itd_list);
-			if (itd->frame == fotg210->now_frame)
+					struct fhcd2xx_itd, itd_list);
+			if (itd->frame == fhcd2xx->now_frame)
 				goto alloc_itd;
 			list_del(&itd->itd_list);
 			itd_dma = itd->itd_dma;
 		} else {
 alloc_itd:
-			spin_unlock_irqrestore(&fotg210->lock, flags);
-			itd = dma_pool_alloc(fotg210->itd_pool, mem_flags,
+			spin_unlock_irqrestore(&fhcd2xx->lock, flags);
+			itd = dma_pool_alloc(fhcd2xx->itd_pool, mem_flags,
 					&itd_dma);
-			spin_lock_irqsave(&fotg210->lock, flags);
+			spin_lock_irqsave(&fhcd2xx->lock, flags);
 			if (!itd) {
 				iso_sched_free(stream, sched);
-				spin_unlock_irqrestore(&fotg210->lock, flags);
+				spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 				return -ENOMEM;
 			}
 		}
@@ -4190,7 +4190,7 @@ alloc_itd:
 		itd->itd_dma = itd_dma;
 		list_add(&itd->itd_list, &sched->td_list);
 	}
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 
 	/* temporarily store schedule info in hcpriv */
 	urb->hcpriv = sched;
@@ -4198,14 +4198,14 @@ alloc_itd:
 	return 0;
 }
 
-static inline int itd_slot_ok(struct fotg210_hcd *fotg210, u32 mod, u32 uframe,
+static inline int itd_slot_ok(struct fhcd2xx_hcd *fhcd2xx, u32 mod, u32 uframe,
 			      u8 usecs, u32 period)
 {
 	uframe %= period;
 	do {
 		/* can't commit more than uframe_periodic_max usec */
-		if (periodic_usecs(fotg210, uframe >> 3, uframe & 0x7)
-				> (fotg210->uframe_periodic_max - usecs))
+		if (periodic_usecs(fhcd2xx, uframe >> 3, uframe & 0x7)
+				> (fhcd2xx->uframe_periodic_max - usecs))
 			return 0;
 
 		/* we know urb->interval is 2^N uframes */
@@ -4219,32 +4219,32 @@ static inline int itd_slot_ok(struct fotg210_hcd *fotg210, u32 mod, u32 uframe,
  * periodic schedule slots.  (Affected by TUNE_FLS, which defaults to
  * "as small as possible" to be cache-friendlier.)  That limits the size
  * transfers you can stream reliably; avoid more than 64 msec per urb.
- * Also avoid queue depths of less than fotg210's worst irq latency (affected
+ * Also avoid queue depths of less than fhcd2xx's worst irq latency (affected
  * by the per-urb URB_NO_INTERRUPT hint, the log2_irq_thresh module parameter,
  * and other factors); or more than about 230 msec total (for portability,
- * given FOTG210_TUNE_FLS and the slop).  Or, write a smarter scheduler!
+ * given FHCD2XX_TUNE_FLS and the slop).  Or, write a smarter scheduler!
  */
 
 #define SCHEDULE_SLOP 80 /* microframes */
 
-static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
-			       struct fotg210_iso_stream *stream)
+static int iso_stream_schedule(struct fhcd2xx_hcd *fhcd2xx, struct urb *urb,
+			       struct fhcd2xx_iso_stream *stream)
 {
 	u32 now, next, start, period, span;
 	int status;
-	unsigned mod = fotg210->periodic_size << 3;
-	struct fotg210_iso_sched *sched = urb->hcpriv;
+	unsigned mod = fhcd2xx->periodic_size << 3;
+	struct fhcd2xx_iso_sched *sched = urb->hcpriv;
 
 	period = urb->interval;
 	span = sched->span;
 
 	if (span > mod - SCHEDULE_SLOP) {
-		fotg210_dbg(fotg210, "iso request %p too long\n", urb);
+		fhcd2xx_dbg(fhcd2xx, "iso request %p too long\n", urb);
 		status = -EFBIG;
 		goto fail;
 	}
 
-	now = fotg210_read_frame_index(fotg210) & (mod - 1);
+	now = fhcd2xx_read_frame_index(fhcd2xx) & (mod - 1);
 
 	/* Typical case: reuse current schedule, stream is still active.
 	 * Hopefully there are no gaps from the host falling behind
@@ -4259,8 +4259,8 @@ static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
 		 * and Intel PCI-based controllers, don't (work around for
 		 * Intel ICH9 bug).
 		 */
-		if (!stream->highspeed && fotg210->fs_i_thresh)
-			next = now + fotg210->i_thresh;
+		if (!stream->highspeed && fhcd2xx->fs_i_thresh)
+			next = now + fhcd2xx->i_thresh;
 		else
 			next = now;
 
@@ -4275,7 +4275,7 @@ static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
 		else
 			start = next + excess + period;
 		if (start - now >= mod) {
-			fotg210_dbg(fotg210, "request %p would overflow (%d+%d >= %d)\n",
+			fhcd2xx_dbg(fhcd2xx, "request %p would overflow (%d+%d >= %d)\n",
 					urb, start - now - period, period,
 					mod);
 			status = -EFBIG;
@@ -4284,7 +4284,7 @@ static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
 	}
 
 	/* need to schedule; when's the next (u)frame we could start?
-	 * this is bigger than fotg210->i_thresh allows; scheduling itself
+	 * this is bigger than fhcd2xx->i_thresh allows; scheduling itself
 	 * isn't free, the slop should handle reasonably slow cpus.  it
 	 * can also help high bandwidth if the dma and irq loads don't
 	 * jump until after the queue is primed.
@@ -4306,14 +4306,14 @@ static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
 		do {
 			start--;
 			/* check schedule: enough space? */
-			if (itd_slot_ok(fotg210, mod, start,
+			if (itd_slot_ok(fhcd2xx, mod, start,
 					stream->usecs, period))
 				done = 1;
 		} while (start > next && !done);
 
 		/* no room in the schedule */
 		if (!done) {
-			fotg210_dbg(fotg210, "iso resched full %p (now %d max %d)\n",
+			fhcd2xx_dbg(fhcd2xx, "iso resched full %p (now %d max %d)\n",
 				urb, now, now + mod);
 			status = -ENOSPC;
 			goto fail;
@@ -4323,7 +4323,7 @@ static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
 	/* Tried to schedule too far into the future? */
 	if (unlikely(start - now + span - period
 				>= mod - 2 * SCHEDULE_SLOP)) {
-		fotg210_dbg(fotg210, "request %p would overflow (%d+%d >= %d)\n",
+		fhcd2xx_dbg(fhcd2xx, "request %p would overflow (%d+%d >= %d)\n",
 				urb, start - now, span - period,
 				mod - 2 * SCHEDULE_SLOP);
 		status = -EFBIG;
@@ -4338,8 +4338,8 @@ static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
 		urb->start_frame >>= 3;
 
 	/* Make sure scan_isoc() sees these */
-	if (fotg210->isoc_count == 0)
-		fotg210->next_frame = now >> 3;
+	if (fhcd2xx->isoc_count == 0)
+		fhcd2xx->next_frame = now >> 3;
 	return 0;
 
 fail:
@@ -4348,14 +4348,14 @@ fail:
 	return status;
 }
 
-static inline void itd_init(struct fotg210_hcd *fotg210,
-			    struct fotg210_iso_stream *stream,
-			    struct fotg210_itd *itd)
+static inline void itd_init(struct fhcd2xx_hcd *fhcd2xx,
+			    struct fhcd2xx_iso_stream *stream,
+			    struct fhcd2xx_itd *itd)
 {
 	int i;
 
 	/* it's been recently zeroed */
-	itd->hw_next = FOTG210_LIST_END(fotg210);
+	itd->hw_next = FHCD2XX_LIST_END(fhcd2xx);
 	itd->hw_bufp[0] = stream->buf0;
 	itd->hw_bufp[1] = stream->buf1;
 	itd->hw_bufp[2] = stream->buf2;
@@ -4366,47 +4366,47 @@ static inline void itd_init(struct fotg210_hcd *fotg210,
 	/* All other fields are filled when scheduling */
 }
 
-static inline void itd_patch(struct fotg210_hcd *fotg210,
-			     struct fotg210_itd *itd,
-			     struct fotg210_iso_sched *iso_sched,
+static inline void itd_patch(struct fhcd2xx_hcd *fhcd2xx,
+			     struct fhcd2xx_itd *itd,
+			     struct fhcd2xx_iso_sched *iso_sched,
 			     unsigned index, u16 uframe)
 {
-	struct fotg210_iso_packet *uf = &iso_sched->packet[index];
+	struct fhcd2xx_iso_packet *uf = &iso_sched->packet[index];
 	unsigned pg = itd->pg;
 
 	uframe &= 0x07;
 	itd->index[uframe] = index;
 
 	itd->hw_transaction[uframe] = uf->transaction;
-	itd->hw_transaction[uframe] |= cpu_to_hc32(fotg210, pg << 12);
-	itd->hw_bufp[pg] |= cpu_to_hc32(fotg210, uf->bufp & ~(u32)0);
-	itd->hw_bufp_hi[pg] |= cpu_to_hc32(fotg210, (u32)(uf->bufp >> 32));
+	itd->hw_transaction[uframe] |= cpu_to_hc32(fhcd2xx, pg << 12);
+	itd->hw_bufp[pg] |= cpu_to_hc32(fhcd2xx, uf->bufp & ~(u32)0);
+	itd->hw_bufp_hi[pg] |= cpu_to_hc32(fhcd2xx, (u32)(uf->bufp >> 32));
 
 	/* iso_frame_desc[].offset must be strictly increasing */
 	if (unlikely(uf->cross)) {
 		u64 bufp = uf->bufp + 4096;
 
 		itd->pg = ++pg;
-		itd->hw_bufp[pg] |= cpu_to_hc32(fotg210, bufp & ~(u32)0);
-		itd->hw_bufp_hi[pg] |= cpu_to_hc32(fotg210, (u32)(bufp >> 32));
+		itd->hw_bufp[pg] |= cpu_to_hc32(fhcd2xx, bufp & ~(u32)0);
+		itd->hw_bufp_hi[pg] |= cpu_to_hc32(fhcd2xx, (u32)(bufp >> 32));
 	}
 }
 
-static inline void itd_link(struct fotg210_hcd *fotg210, unsigned frame,
-			    struct fotg210_itd *itd)
+static inline void itd_link(struct fhcd2xx_hcd *fhcd2xx, unsigned frame,
+			    struct fhcd2xx_itd *itd)
 {
-	union fotg210_shadow *prev = &fotg210->pshadow[frame];
-	__hc32 *hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow here = *prev;
+	union fhcd2xx_shadow *prev = &fhcd2xx->pshadow[frame];
+	__hc32 *hw_p = &fhcd2xx->periodic[frame];
+	union fhcd2xx_shadow here = *prev;
 	__hc32 type = 0;
 
 	/* skip any iso nodes which might belong to previous microframes */
 	while (here.ptr) {
-		type = Q_NEXT_TYPE(fotg210, *hw_p);
-		if (type == cpu_to_hc32(fotg210, Q_TYPE_QH))
+		type = Q_NEXT_TYPE(fhcd2xx, *hw_p);
+		if (type == cpu_to_hc32(fhcd2xx, Q_TYPE_QH))
 			break;
-		prev = periodic_next_shadow(fotg210, prev, type);
-		hw_p = shadow_next_periodic(fotg210, &here, type);
+		prev = periodic_next_shadow(fhcd2xx, prev, type);
+		hw_p = shadow_next_periodic(fhcd2xx, &here, type);
 		here = *prev;
 	}
 
@@ -4415,24 +4415,24 @@ static inline void itd_link(struct fotg210_hcd *fotg210, unsigned frame,
 	prev->itd = itd;
 	itd->frame = frame;
 	wmb();
-	*hw_p = cpu_to_hc32(fotg210, itd->itd_dma | Q_TYPE_ITD);
+	*hw_p = cpu_to_hc32(fhcd2xx, itd->itd_dma | Q_TYPE_ITD);
 }
 
 /* fit urb's itds into the selected schedule slot; activate as needed */
-static void itd_link_urb(struct fotg210_hcd *fotg210, struct urb *urb,
-			 unsigned mod, struct fotg210_iso_stream *stream)
+static void itd_link_urb(struct fhcd2xx_hcd *fhcd2xx, struct urb *urb,
+			 unsigned mod, struct fhcd2xx_iso_stream *stream)
 {
 	int packet;
 	unsigned next_uframe, uframe, frame;
-	struct fotg210_iso_sched *iso_sched = urb->hcpriv;
-	struct fotg210_itd *itd;
+	struct fhcd2xx_iso_sched *iso_sched = urb->hcpriv;
+	struct fhcd2xx_itd *itd;
 
 	next_uframe = stream->next_uframe & (mod - 1);
 
 	if (unlikely(list_empty(&stream->td_list))) {
-		fotg210_to_hcd(fotg210)->self.bandwidth_allocated
+		fhcd2xx_to_hcd(fhcd2xx)->self.bandwidth_allocated
 				+= stream->bandwidth;
-		fotg210_dbg(fotg210,
+		fhcd2xx_dbg(fhcd2xx,
 			"schedule devp %s ep%d%s-iso period %d start %d.%d\n",
 			urb->dev->devpath, stream->bEndpointAddress & 0x0f,
 			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
@@ -4448,17 +4448,17 @@ static void itd_link_urb(struct fotg210_hcd *fotg210, struct urb *urb,
 			/* ASSERT:  no itds for this endpoint in this uframe */
 
 			itd = list_entry(iso_sched->td_list.next,
-					struct fotg210_itd, itd_list);
+					struct fhcd2xx_itd, itd_list);
 			list_move_tail(&itd->itd_list, &stream->td_list);
 			itd->stream = stream;
 			itd->urb = urb;
-			itd_init(fotg210, stream, itd);
+			itd_init(fhcd2xx, stream, itd);
 		}
 
 		uframe = next_uframe & 0x07;
 		frame = next_uframe >> 3;
 
-		itd_patch(fotg210, itd, iso_sched, packet, uframe);
+		itd_patch(fhcd2xx, itd, iso_sched, packet, uframe);
 
 		next_uframe += stream->interval;
 		next_uframe &= mod - 1;
@@ -4467,7 +4467,7 @@ static void itd_link_urb(struct fotg210_hcd *fotg210, struct urb *urb,
 		/* link completed itds into the schedule */
 		if (((next_uframe >> 3) != frame)
 				|| packet == urb->number_of_packets) {
-			itd_link(fotg210, frame & (fotg210->periodic_size - 1),
+			itd_link(fhcd2xx, frame & (fhcd2xx->periodic_size - 1),
 				 itd);
 			itd = NULL;
 		}
@@ -4478,12 +4478,12 @@ static void itd_link_urb(struct fotg210_hcd *fotg210, struct urb *urb,
 	iso_sched_free(stream, iso_sched);
 	urb->hcpriv = NULL;
 
-	++fotg210->isoc_count;
-	enable_periodic(fotg210);
+	++fhcd2xx->isoc_count;
+	enable_periodic(fhcd2xx);
 }
 
-#define ISO_ERRS (FOTG210_ISOC_BUF_ERR | FOTG210_ISOC_BABBLE |\
-		  FOTG210_ISOC_XACTERR)
+#define ISO_ERRS (FHCD2XX_ISOC_BUF_ERR | FHCD2XX_ISOC_BABBLE |\
+		  FHCD2XX_ISOC_XACTERR)
 
 /* Process and recycle a completed ITD.  Return true iff its urb completed,
  * and hence its completion callback probably added things to the hardware
@@ -4495,14 +4495,14 @@ static void itd_link_urb(struct fotg210_hcd *fotg210, struct urb *urb,
  * (b) only this endpoint's completions submit URBs.  It seems some silicon
  * corrupts things if you reuse completed descriptors very quickly...
  */
-static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
+static bool itd_complete(struct fhcd2xx_hcd *fhcd2xx, struct fhcd2xx_itd *itd)
 {
 	struct urb *urb = itd->urb;
 	struct usb_iso_packet_descriptor *desc;
 	u32 t;
 	unsigned uframe;
 	int urb_index = -1;
-	struct fotg210_iso_stream *stream = itd->stream;
+	struct fhcd2xx_iso_stream *stream = itd->stream;
 	struct usb_device *dev;
 	bool retval = false;
 
@@ -4513,30 +4513,30 @@ static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 		urb_index = itd->index[uframe];
 		desc = &urb->iso_frame_desc[urb_index];
 
-		t = hc32_to_cpup(fotg210, &itd->hw_transaction[uframe]);
+		t = hc32_to_cpup(fhcd2xx, &itd->hw_transaction[uframe]);
 		itd->hw_transaction[uframe] = 0;
 
 		/* report transfer status */
 		if (unlikely(t & ISO_ERRS)) {
 			urb->error_count++;
-			if (t & FOTG210_ISOC_BUF_ERR)
+			if (t & FHCD2XX_ISOC_BUF_ERR)
 				desc->status = usb_pipein(urb->pipe)
 					? -ENOSR  /* hc couldn't read */
 					: -ECOMM; /* hc couldn't write */
-			else if (t & FOTG210_ISOC_BABBLE)
+			else if (t & FHCD2XX_ISOC_BABBLE)
 				desc->status = -EOVERFLOW;
-			else /* (t & FOTG210_ISOC_XACTERR) */
+			else /* (t & FHCD2XX_ISOC_XACTERR) */
 				desc->status = -EPROTO;
 
 			/* HC need not update length with this error */
-			if (!(t & FOTG210_ISOC_BABBLE)) {
+			if (!(t & FHCD2XX_ISOC_BABBLE)) {
 				desc->actual_length =
-					fotg210_itdlen(urb, desc, t);
+					fhcd2xx_itdlen(urb, desc, t);
 				urb->actual_length += desc->actual_length;
 			}
-		} else if (likely((t & FOTG210_ISOC_ACTIVE) == 0)) {
+		} else if (likely((t & FHCD2XX_ISOC_ACTIVE) == 0)) {
 			desc->status = 0;
-			desc->actual_length = fotg210_itdlen(urb, desc, t);
+			desc->actual_length = fhcd2xx_itdlen(urb, desc, t);
 			urb->actual_length += desc->actual_length;
 		} else {
 			/* URB was too late */
@@ -4555,17 +4555,17 @@ static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 
 	/* give urb back to the driver; completion often (re)submits */
 	dev = urb->dev;
-	fotg210_urb_done(fotg210, urb, 0);
+	fhcd2xx_urb_done(fhcd2xx, urb, 0);
 	retval = true;
 	urb = NULL;
 
-	--fotg210->isoc_count;
-	disable_periodic(fotg210);
+	--fhcd2xx->isoc_count;
+	disable_periodic(fhcd2xx);
 
 	if (unlikely(list_is_singular(&stream->td_list))) {
-		fotg210_to_hcd(fotg210)->self.bandwidth_allocated
+		fhcd2xx_to_hcd(fhcd2xx)->self.bandwidth_allocated
 				-= stream->bandwidth;
-		fotg210_dbg(fotg210,
+		fhcd2xx_dbg(fhcd2xx,
 			"deschedule devp %s ep%d%s-iso\n",
 			dev->devpath, stream->bEndpointAddress & 0x0f,
 			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
@@ -4580,35 +4580,35 @@ done:
 	/* Recycle the iTDs when the pipeline is empty (ep no longer in use) */
 	if (list_empty(&stream->td_list)) {
 		list_splice_tail_init(&stream->free_list,
-				&fotg210->cached_itd_list);
-		start_free_itds(fotg210);
+				&fhcd2xx->cached_itd_list);
+		start_free_itds(fhcd2xx);
 	}
 
 	return retval;
 }
 
-static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
+static int itd_submit(struct fhcd2xx_hcd *fhcd2xx, struct urb *urb,
 		      gfp_t mem_flags)
 {
 	int status = -EINVAL;
 	unsigned long flags;
-	struct fotg210_iso_stream *stream;
+	struct fhcd2xx_iso_stream *stream;
 
 	/* Get iso_stream head */
-	stream = iso_stream_find(fotg210, urb);
+	stream = iso_stream_find(fhcd2xx, urb);
 	if (unlikely(stream == NULL)) {
-		fotg210_dbg(fotg210, "can't get iso stream\n");
+		fhcd2xx_dbg(fhcd2xx, "can't get iso stream\n");
 		return -ENOMEM;
 	}
 	if (unlikely(urb->interval != stream->interval &&
-	    fotg210_port_speed(fotg210, 0) == USB_PORT_STAT_HIGH_SPEED)) {
-		fotg210_dbg(fotg210, "can't change iso interval %d --> %d\n",
+	    fhcd2xx_port_speed(fhcd2xx, 0) == USB_PORT_STAT_HIGH_SPEED)) {
+		fhcd2xx_dbg(fhcd2xx, "can't change iso interval %d --> %d\n",
 			    stream->interval, urb->interval);
 		goto done;
 	}
 
-#ifdef FOTG210_URB_TRACE
-	fotg210_dbg(fotg210,
+#ifdef FHCD2XX_URB_TRACE
+	fhcd2xx_dbg(fhcd2xx,
 		"%s %s urb %p ep%d%s len %d, %d pkts %d uframes[%p]\n",
 		__func__, urb->dev->devpath, urb,
 		usb_pipeendpoint(urb->pipe),
@@ -4619,49 +4619,49 @@ static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
 #endif
 
 	/* allocate ITDs w/o locking anything */
-	status = itd_urb_transaction(stream, fotg210, urb, mem_flags);
+	status = itd_urb_transaction(stream, fhcd2xx, urb, mem_flags);
 	if (unlikely(status < 0)) {
-		fotg210_dbg(fotg210, "can't init itds\n");
+		fhcd2xx_dbg(fhcd2xx, "can't init itds\n");
 		goto done;
 	}
 
 	/* schedule ... need to lock */
-	spin_lock_irqsave(&fotg210->lock, flags);
-	if (unlikely(!HCD_HW_ACCESSIBLE(fotg210_to_hcd(fotg210)))) {
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
+	if (unlikely(!HCD_HW_ACCESSIBLE(fhcd2xx_to_hcd(fhcd2xx)))) {
 		status = -ESHUTDOWN;
 		goto done_not_linked;
 	}
-	status = usb_hcd_link_urb_to_ep(fotg210_to_hcd(fotg210), urb);
+	status = usb_hcd_link_urb_to_ep(fhcd2xx_to_hcd(fhcd2xx), urb);
 	if (unlikely(status))
 		goto done_not_linked;
-	status = iso_stream_schedule(fotg210, urb, stream);
+	status = iso_stream_schedule(fhcd2xx, urb, stream);
 	if (likely(status == 0))
-		itd_link_urb(fotg210, urb, fotg210->periodic_size << 3, stream);
+		itd_link_urb(fhcd2xx, urb, fhcd2xx->periodic_size << 3, stream);
 	else
-		usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
+		usb_hcd_unlink_urb_from_ep(fhcd2xx_to_hcd(fhcd2xx), urb);
 done_not_linked:
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 done:
 	return status;
 }
 
-static inline int scan_frame_queue(struct fotg210_hcd *fotg210, unsigned frame,
+static inline int scan_frame_queue(struct fhcd2xx_hcd *fhcd2xx, unsigned frame,
 				   unsigned now_frame, bool live)
 {
 	unsigned uf;
 	bool modified;
-	union fotg210_shadow q, *q_p;
+	union fhcd2xx_shadow q, *q_p;
 	__hc32 type, *hw_p;
 
 	/* scan each element in frame's queue for completions */
-	q_p = &fotg210->pshadow[frame];
-	hw_p = &fotg210->periodic[frame];
+	q_p = &fhcd2xx->pshadow[frame];
+	hw_p = &fhcd2xx->periodic[frame];
 	q.ptr = q_p->ptr;
-	type = Q_NEXT_TYPE(fotg210, *hw_p);
+	type = Q_NEXT_TYPE(fhcd2xx, *hw_p);
 	modified = false;
 
 	while (q.ptr != NULL) {
-		switch (hc32_to_cpu(fotg210, type)) {
+		switch (hc32_to_cpu(fhcd2xx, type)) {
 		case Q_TYPE_ITD:
 			/* If this ITD is still active, leave it for
 			 * later processing ... check the next entry.
@@ -4672,13 +4672,13 @@ static inline int scan_frame_queue(struct fotg210_hcd *fotg210, unsigned frame,
 				rmb();
 				for (uf = 0; uf < 8; uf++) {
 					if (q.itd->hw_transaction[uf] &
-						    ITD_ACTIVE(fotg210))
+						    ITD_ACTIVE(fhcd2xx))
 						break;
 				}
 				if (uf < 8) {
 					q_p = &q.itd->itd_next;
 					hw_p = &q.itd->hw_next;
-					type = Q_NEXT_TYPE(fotg210,
+					type = Q_NEXT_TYPE(fhcd2xx,
 						q.itd->hw_next);
 					q = *q_p;
 					break;
@@ -4692,13 +4692,13 @@ static inline int scan_frame_queue(struct fotg210_hcd *fotg210, unsigned frame,
 			 */
 			*q_p = q.itd->itd_next;
 			*hw_p = q.itd->hw_next;
-			type = Q_NEXT_TYPE(fotg210, q.itd->hw_next);
+			type = Q_NEXT_TYPE(fhcd2xx, q.itd->hw_next);
 			wmb();
-			modified = itd_complete(fotg210, q.itd);
+			modified = itd_complete(fhcd2xx, q.itd);
 			q = *q_p;
 			break;
 		default:
-			fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
+			fhcd2xx_dbg(fhcd2xx, "corrupt type %d frame %d shadow %p\n",
 				type, frame, q.ptr);
 			/* FALL THROUGH */
 		case Q_TYPE_QH:
@@ -4709,16 +4709,16 @@ static inline int scan_frame_queue(struct fotg210_hcd *fotg210, unsigned frame,
 		}
 
 		/* assume completion callbacks modify the queue */
-		if (unlikely(modified && fotg210->isoc_count > 0))
+		if (unlikely(modified && fhcd2xx->isoc_count > 0))
 			return -1;
 	}
 	return 0;
 }
 
-static void scan_isoc(struct fotg210_hcd *fotg210)
+static void scan_isoc(struct fhcd2xx_hcd *fhcd2xx)
 {
 	unsigned uf, now_frame, frame, ret;
-	unsigned fmask = fotg210->periodic_size - 1;
+	unsigned fmask = fhcd2xx->periodic_size - 1;
 	bool live;
 
 	/*
@@ -4726,22 +4726,22 @@ static void scan_isoc(struct fotg210_hcd *fotg210)
 	 * else clean up by scanning everything that's left.
 	 * Touches as few pages as possible:  cache-friendly.
 	 */
-	if (fotg210->rh_state >= FOTG210_RH_RUNNING) {
-		uf = fotg210_read_frame_index(fotg210);
+	if (fhcd2xx->rh_state >= FHCD2XX_RH_RUNNING) {
+		uf = fhcd2xx_read_frame_index(fhcd2xx);
 		now_frame = (uf >> 3) & fmask;
 		live = true;
 	} else  {
-		now_frame = (fotg210->next_frame - 1) & fmask;
+		now_frame = (fhcd2xx->next_frame - 1) & fmask;
 		live = false;
 	}
-	fotg210->now_frame = now_frame;
+	fhcd2xx->now_frame = now_frame;
 
-	frame = fotg210->next_frame;
+	frame = fhcd2xx->next_frame;
 	for (;;) {
 
 		ret = 1;
 		while (ret != 0)
-			ret = scan_frame_queue(fotg210, frame, now_frame,
+			ret = scan_frame_queue(fhcd2xx, frame, now_frame,
 					       live);
 
 		/* Stop when we have reached the current frame */
@@ -4749,7 +4749,7 @@ static void scan_isoc(struct fotg210_hcd *fotg210)
 			break;
 		frame = (frame + 1) & fmask;
 	}
-	fotg210->next_frame = now_frame;
+	fhcd2xx->next_frame = now_frame;
 }
 
 /*
@@ -4759,11 +4759,11 @@ static ssize_t show_uframe_periodic_max(struct device *dev,
 					struct device_attribute *attr,
 					char *buf)
 {
-	struct fotg210_hcd *fotg210;
+	struct fhcd2xx_hcd *fhcd2xx;
 	int n;
 
-	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
-	n = scnprintf(buf, PAGE_SIZE, "%d\n", fotg210->uframe_periodic_max);
+	fhcd2xx = hcd_to_fhcd2xx(bus_to_hcd(dev_get_drvdata(dev)));
+	n = scnprintf(buf, PAGE_SIZE, "%d\n", fhcd2xx->uframe_periodic_max);
 	return n;
 }
 
@@ -4772,19 +4772,19 @@ static ssize_t store_uframe_periodic_max(struct device *dev,
 					struct device_attribute *attr,
 					const char *buf, size_t count)
 {
-	struct fotg210_hcd *fotg210;
+	struct fhcd2xx_hcd *fhcd2xx;
 	unsigned uframe_periodic_max;
 	unsigned frame, uframe;
 	unsigned short allocated_max;
 	unsigned long flags;
 	ssize_t ret;
 
-	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
+	fhcd2xx = hcd_to_fhcd2xx(bus_to_hcd(dev_get_drvdata(dev)));
 	if (kstrtouint(buf, 0, &uframe_periodic_max) < 0)
 		return -EINVAL;
 
 	if (uframe_periodic_max < 100 || uframe_periodic_max >= 125) {
-		fotg210_info(fotg210, "rejecting invalid request for uframe_periodic_max=%u\n",
+		fhcd2xx_info(fhcd2xx, "rejecting invalid request for uframe_periodic_max=%u\n",
 			     uframe_periodic_max);
 		return -EINVAL;
 	}
@@ -4795,25 +4795,25 @@ static ssize_t store_uframe_periodic_max(struct device *dev,
 	 * lock, so that our checking does not race with possible periodic
 	 * bandwidth allocation through submitting new urbs.
 	 */
-	spin_lock_irqsave(&fotg210->lock, flags);
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
 
 	/*
 	 * for request to decrease max periodic bandwidth, we have to check
 	 * every microframe in the schedule to see whether the decrease is
 	 * possible.
 	 */
-	if (uframe_periodic_max < fotg210->uframe_periodic_max) {
+	if (uframe_periodic_max < fhcd2xx->uframe_periodic_max) {
 		allocated_max = 0;
 
-		for (frame = 0; frame < fotg210->periodic_size; ++frame)
+		for (frame = 0; frame < fhcd2xx->periodic_size; ++frame)
 			for (uframe = 0; uframe < 7; ++uframe)
 				allocated_max = max(allocated_max,
-						    periodic_usecs(fotg210,
+						    periodic_usecs(fhcd2xx,
 								   frame,
 								   uframe));
 
 		if (allocated_max > uframe_periodic_max) {
-			fotg210_info(fotg210,
+			fhcd2xx_info(fhcd2xx,
 				"cannot decrease uframe_periodic_max because periodic bandwidth is already allocated (%u > %u)\n",
 				allocated_max, uframe_periodic_max);
 			goto out_unlock;
@@ -4822,26 +4822,26 @@ static ssize_t store_uframe_periodic_max(struct device *dev,
 
 	/* increasing is always ok */
 
-	fotg210_info(fotg210, "setting max periodic bandwidth to %u%% (== %u usec/uframe)\n",
+	fhcd2xx_info(fhcd2xx, "setting max periodic bandwidth to %u%% (== %u usec/uframe)\n",
 		     100 * uframe_periodic_max/125, uframe_periodic_max);
 
 	if (uframe_periodic_max != 100)
-		fotg210_warn(fotg210, "max periodic bandwidth set is non-standard\n");
+		fhcd2xx_warn(fhcd2xx, "max periodic bandwidth set is non-standard\n");
 
-	fotg210->uframe_periodic_max = uframe_periodic_max;
+	fhcd2xx->uframe_periodic_max = uframe_periodic_max;
 	ret = count;
 
 out_unlock:
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 	return ret;
 }
 
 static DEVICE_ATTR(uframe_periodic_max, 0644, show_uframe_periodic_max,
 		   store_uframe_periodic_max);
 
-static inline int create_sysfs_files(struct fotg210_hcd *fotg210)
+static inline int create_sysfs_files(struct fhcd2xx_hcd *fhcd2xx)
 {
-	struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
+	struct device *controller = fhcd2xx_to_hcd(fhcd2xx)->self.controller;
 	int i = 0;
 
 	if (i)
@@ -4852,9 +4852,9 @@ out:
 	return i;
 }
 
-static inline void remove_sysfs_files(struct fotg210_hcd *fotg210)
+static inline void remove_sysfs_files(struct fhcd2xx_hcd *fhcd2xx)
 {
-	struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
+	struct device *controller = fhcd2xx_to_hcd(fhcd2xx)->self.controller;
 
 	device_remove_file(controller, &dev_attr_uframe_periodic_max);
 }
@@ -4862,180 +4862,180 @@ static inline void remove_sysfs_files(struct fotg210_hcd *fotg210)
  * The firmware seems to think that powering off is a wakeup event!
  * This routine turns off remote wakeup and everything else, on all ports.
  */
-static void fotg210_turn_off_all_ports(struct fotg210_hcd *fotg210)
+static void fhcd2xx_turn_off_all_ports(struct fhcd2xx_hcd *fhcd2xx)
 {
-	u32 __iomem *status_reg = &fotg210->regs->port_status;
+	u32 __iomem *status_reg = &fhcd2xx->regs->port_status;
 
-	fotg210_writel(fotg210, PORT_RWC_BITS, status_reg);
+	fhcd2xx_writel(fhcd2xx, PORT_RWC_BITS, status_reg);
 }
 
 /*
  * Halt HC, turn off all ports, and let the BIOS use the companion controllers.
  * Must be called with interrupts enabled and the lock not held.
  */
-static void fotg210_silence_controller(struct fotg210_hcd *fotg210)
+static void fhcd2xx_silence_controller(struct fhcd2xx_hcd *fhcd2xx)
 {
-	fotg210_halt(fotg210);
+	fhcd2xx_halt(fhcd2xx);
 
-	spin_lock_irq(&fotg210->lock);
-	fotg210->rh_state = FOTG210_RH_HALTED;
-	fotg210_turn_off_all_ports(fotg210);
-	spin_unlock_irq(&fotg210->lock);
+	spin_lock_irq(&fhcd2xx->lock);
+	fhcd2xx->rh_state = FHCD2XX_RH_HALTED;
+	fhcd2xx_turn_off_all_ports(fhcd2xx);
+	spin_unlock_irq(&fhcd2xx->lock);
 }
 
-/* fotg210_shutdown kick in for silicon on any bus (not just pci, etc).
+/* fhcd2xx_shutdown kick in for silicon on any bus (not just pci, etc).
  * This forcibly disables dma and IRQs, helping kexec and other cases
  * where the next system software may expect clean state.
  */
-static void fotg210_shutdown(struct usb_hcd *hcd)
+static void fhcd2xx_shutdown(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fhcd2xx_hcd *fhcd2xx = hcd_to_fhcd2xx(hcd);
 
-	spin_lock_irq(&fotg210->lock);
-	fotg210->shutdown = true;
-	fotg210->rh_state = FOTG210_RH_STOPPING;
-	fotg210->enabled_hrtimer_events = 0;
-	spin_unlock_irq(&fotg210->lock);
+	spin_lock_irq(&fhcd2xx->lock);
+	fhcd2xx->shutdown = true;
+	fhcd2xx->rh_state = FHCD2XX_RH_STOPPING;
+	fhcd2xx->enabled_hrtimer_events = 0;
+	spin_unlock_irq(&fhcd2xx->lock);
 
-	fotg210_silence_controller(fotg210);
+	fhcd2xx_silence_controller(fhcd2xx);
 
-	hrtimer_cancel(&fotg210->hrtimer);
+	hrtimer_cancel(&fhcd2xx->hrtimer);
 }
 
 /*
- * fotg210_work is called from some interrupts, timers, and so on.
- * it calls driver completion functions, after dropping fotg210->lock.
+ * fhcd2xx_work is called from some interrupts, timers, and so on.
+ * it calls driver completion functions, after dropping fhcd2xx->lock.
  */
-static void fotg210_work(struct fotg210_hcd *fotg210)
+static void fhcd2xx_work(struct fhcd2xx_hcd *fhcd2xx)
 {
-	/* another CPU may drop fotg210->lock during a schedule scan while
+	/* another CPU may drop fhcd2xx->lock during a schedule scan while
 	 * it reports urb completions.  this flag guards against bogus
 	 * attempts at re-entrant schedule scanning.
 	 */
-	if (fotg210->scanning) {
-		fotg210->need_rescan = true;
+	if (fhcd2xx->scanning) {
+		fhcd2xx->need_rescan = true;
 		return;
 	}
-	fotg210->scanning = true;
+	fhcd2xx->scanning = true;
 
 rescan:
-	fotg210->need_rescan = false;
-	if (fotg210->async_count)
-		scan_async(fotg210);
-	if (fotg210->intr_count > 0)
-		scan_intr(fotg210);
-	if (fotg210->isoc_count > 0)
-		scan_isoc(fotg210);
-	if (fotg210->need_rescan)
+	fhcd2xx->need_rescan = false;
+	if (fhcd2xx->async_count)
+		scan_async(fhcd2xx);
+	if (fhcd2xx->intr_count > 0)
+		scan_intr(fhcd2xx);
+	if (fhcd2xx->isoc_count > 0)
+		scan_isoc(fhcd2xx);
+	if (fhcd2xx->need_rescan)
 		goto rescan;
-	fotg210->scanning = false;
+	fhcd2xx->scanning = false;
 
 	/* the IO watchdog guards against hardware or driver bugs that
 	 * misplace IRQs, and should let us run completely without IRQs.
 	 * such lossage has been observed on both VT6202 and VT8235.
 	 */
-	turn_on_io_watchdog(fotg210);
+	turn_on_io_watchdog(fhcd2xx);
 }
 
 /*
- * Called when the fotg210_hcd module is removed.
+ * Called when the fhcd2xx_hcd module is removed.
  */
-static void fotg210_stop(struct usb_hcd *hcd)
+static void fhcd2xx_stop(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fhcd2xx_hcd *fhcd2xx = hcd_to_fhcd2xx(hcd);
 
-	fotg210_dbg(fotg210, "stop\n");
+	fhcd2xx_dbg(fhcd2xx, "stop\n");
 
 	/* no more interrupts ... */
 
-	spin_lock_irq(&fotg210->lock);
-	fotg210->enabled_hrtimer_events = 0;
-	spin_unlock_irq(&fotg210->lock);
+	spin_lock_irq(&fhcd2xx->lock);
+	fhcd2xx->enabled_hrtimer_events = 0;
+	spin_unlock_irq(&fhcd2xx->lock);
 
-	fotg210_quiesce(fotg210);
-	fotg210_silence_controller(fotg210);
-	fotg210_reset(fotg210);
+	fhcd2xx_quiesce(fhcd2xx);
+	fhcd2xx_silence_controller(fhcd2xx);
+	fhcd2xx_reset(fhcd2xx);
 
-	hrtimer_cancel(&fotg210->hrtimer);
-	remove_sysfs_files(fotg210);
-	remove_debug_files(fotg210);
+	hrtimer_cancel(&fhcd2xx->hrtimer);
+	remove_sysfs_files(fhcd2xx);
+	remove_debug_files(fhcd2xx);
 
 	/* root hub is shut down separately (first, when possible) */
-	spin_lock_irq(&fotg210->lock);
-	end_free_itds(fotg210);
-	spin_unlock_irq(&fotg210->lock);
-	fotg210_mem_cleanup(fotg210);
-
-#ifdef FOTG210_STATS
-	fotg210_dbg(fotg210, "irq normal %ld err %ld iaa %ld (lost %ld)\n",
-		fotg210->stats.normal, fotg210->stats.error, fotg210->stats.iaa,
-		fotg210->stats.lost_iaa);
-	fotg210_dbg(fotg210, "complete %ld unlink %ld\n",
-		fotg210->stats.complete, fotg210->stats.unlink);
+	spin_lock_irq(&fhcd2xx->lock);
+	end_free_itds(fhcd2xx);
+	spin_unlock_irq(&fhcd2xx->lock);
+	fhcd2xx_mem_cleanup(fhcd2xx);
+
+#ifdef FHCD2XX_STATS
+	fhcd2xx_dbg(fhcd2xx, "irq normal %ld err %ld iaa %ld (lost %ld)\n",
+		fhcd2xx->stats.normal, fhcd2xx->stats.error, fhcd2xx->stats.iaa,
+		fhcd2xx->stats.lost_iaa);
+	fhcd2xx_dbg(fhcd2xx, "complete %ld unlink %ld\n",
+		fhcd2xx->stats.complete, fhcd2xx->stats.unlink);
 #endif
 
-	dbg_status(fotg210, "fotg210_stop completed",
-		    fotg210_readl(fotg210, &fotg210->regs->status));
+	dbg_status(fhcd2xx, "fhcd2xx_stop completed",
+		    fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->status));
 }
 
 /* one-time init, only for memory state */
-static int hcd_fotg210_init(struct usb_hcd *hcd)
+static int hcd_fhcd2xx_init(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fhcd2xx_hcd *fhcd2xx = hcd_to_fhcd2xx(hcd);
 	u32 temp;
 	int retval;
 	u32 hcc_params;
-	struct fotg210_qh_hw *hw;
+	struct fhcd2xx_qh_hw *hw;
 
-	spin_lock_init(&fotg210->lock);
+	spin_lock_init(&fhcd2xx->lock);
 
 	/*
 	 * keep io watchdog by default, those good HCDs could turn off it later
 	 */
-	fotg210->need_io_watchdog = 1;
+	fhcd2xx->need_io_watchdog = 1;
 
-	hrtimer_init(&fotg210->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
-	fotg210->hrtimer.function = fotg210_hrtimer_func;
-	fotg210->next_hrtimer_event = FOTG210_HRTIMER_NO_EVENT;
+	hrtimer_init(&fhcd2xx->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+	fhcd2xx->hrtimer.function = fhcd2xx_hrtimer_func;
+	fhcd2xx->next_hrtimer_event = FHCD2XX_HRTIMER_NO_EVENT;
 
-	hcc_params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
+	hcc_params = fhcd2xx_readl(fhcd2xx, &fhcd2xx->caps->hcc_params);
 
 	/*
 	 * by default set standard 80% (== 100 usec/uframe) max periodic
 	 * bandwidth as required by USB 2.0
 	 */
-	fotg210->uframe_periodic_max = 100;
+	fhcd2xx->uframe_periodic_max = 100;
 
 	/*
 	 * hw default: 1K periodic list heads, one per frame.
 	 * periodic_size can shrink by USBCMD update if hcc_params allows.
 	 */
-	fotg210->periodic_size = DEFAULT_I_TDPS;
-	INIT_LIST_HEAD(&fotg210->intr_qh_list);
-	INIT_LIST_HEAD(&fotg210->cached_itd_list);
+	fhcd2xx->periodic_size = DEFAULT_I_TDPS;
+	INIT_LIST_HEAD(&fhcd2xx->intr_qh_list);
+	INIT_LIST_HEAD(&fhcd2xx->cached_itd_list);
 
 	if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
 		/* periodic schedule size can be smaller than default */
-		switch (FOTG210_TUNE_FLS) {
+		switch (FHCD2XX_TUNE_FLS) {
 		case 0:
-			fotg210->periodic_size = 1024;
+			fhcd2xx->periodic_size = 1024;
 			break;
 		case 1:
-			fotg210->periodic_size = 512;
+			fhcd2xx->periodic_size = 512;
 			break;
 		case 2:
-			fotg210->periodic_size = 256;
+			fhcd2xx->periodic_size = 256;
 			break;
 		default:
 			BUG();
 		}
 	}
-	retval = fotg210_mem_init(fotg210, GFP_KERNEL);
+	retval = fhcd2xx_mem_init(fhcd2xx, GFP_KERNEL);
 	if (retval < 0)
 		return retval;
 
 	/* controllers may cache some of the periodic schedule ... */
-	fotg210->i_thresh = 2;
+	fhcd2xx->i_thresh = 2;
 
 	/*
 	 * dedicate a qh for the async ring head, since we couldn't unlink
@@ -5044,14 +5044,14 @@ static int hcd_fotg210_init(struct usb_hcd *hcd)
 	 * its dummy is used in hw_alt_next of many tds, to prevent the qh
 	 * from automatically advancing to the next td after short reads.
 	 */
-	fotg210->async->qh_next.qh = NULL;
-	hw = fotg210->async->hw;
-	hw->hw_next = QH_NEXT(fotg210, fotg210->async->qh_dma);
-	hw->hw_info1 = cpu_to_hc32(fotg210, QH_HEAD);
-	hw->hw_token = cpu_to_hc32(fotg210, QTD_STS_HALT);
-	hw->hw_qtd_next = FOTG210_LIST_END(fotg210);
-	fotg210->async->qh_state = QH_STATE_LINKED;
-	hw->hw_alt_next = QTD_NEXT(fotg210, fotg210->async->dummy->qtd_dma);
+	fhcd2xx->async->qh_next.qh = NULL;
+	hw = fhcd2xx->async->hw;
+	hw->hw_next = QH_NEXT(fhcd2xx, fhcd2xx->async->qh_dma);
+	hw->hw_info1 = cpu_to_hc32(fhcd2xx, QH_HEAD);
+	hw->hw_token = cpu_to_hc32(fhcd2xx, QTD_STS_HALT);
+	hw->hw_qtd_next = FHCD2XX_LIST_END(fhcd2xx);
+	fhcd2xx->async->qh_state = QH_STATE_LINKED;
+	hw->hw_alt_next = QTD_NEXT(fhcd2xx, fhcd2xx->async->dummy->qtd_dma);
 
 	/* clear interrupt enables, set irq latency */
 	if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
@@ -5070,14 +5070,14 @@ static int hcd_fotg210_init(struct usb_hcd *hcd)
 			temp |= CMD_PARK;
 			temp |= park << 8;
 		}
-		fotg210_dbg(fotg210, "park %d\n", park);
+		fhcd2xx_dbg(fhcd2xx, "park %d\n", park);
 	}
 	if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
 		/* periodic schedule size can be smaller than default */
 		temp &= ~(3 << 2);
-		temp |= (FOTG210_TUNE_FLS << 2);
+		temp |= (FHCD2XX_TUNE_FLS << 2);
 	}
-	fotg210->command = temp;
+	fhcd2xx->command = temp;
 
 	/* Accept arbitrarily long scatter-gather lists */
 	if (!(hcd->driver->flags & HCD_LOCAL_MEM))
@@ -5085,10 +5085,10 @@ static int hcd_fotg210_init(struct usb_hcd *hcd)
 	return 0;
 }
 
-/* start HC running; it's halted, hcd_fotg210_init() has been run (once) */
-static int fotg210_run(struct usb_hcd *hcd)
+/* start HC running; it's halted, hcd_fhcd2xx_init() has been run (once) */
+static int fhcd2xx_run(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fhcd2xx_hcd *fhcd2xx = hcd_to_fhcd2xx(hcd);
 	u32 temp;
 	u32 hcc_params;
 
@@ -5096,13 +5096,13 @@ static int fotg210_run(struct usb_hcd *hcd)
 
 	/* EHCI spec section 4.1 */
 
-	fotg210_writel(fotg210, fotg210->periodic_dma,
-		       &fotg210->regs->frame_list);
-	fotg210_writel(fotg210, (u32)fotg210->async->qh_dma,
-		       &fotg210->regs->async_next);
+	fhcd2xx_writel(fhcd2xx, fhcd2xx->periodic_dma,
+		       &fhcd2xx->regs->frame_list);
+	fhcd2xx_writel(fhcd2xx, (u32)fhcd2xx->async->qh_dma,
+		       &fhcd2xx->regs->async_next);
 
 	/*
-	 * hcc_params controls whether fotg210->regs->segment must (!!!)
+	 * hcc_params controls whether fhcd2xx->regs->segment must (!!!)
 	 * be used; it constrains QH/ITD/SITD and QTD locations.
 	 * pci_pool consistent memory always uses segment zero.
 	 * streaming mappings for I/O buffers, like pci_map_single(),
@@ -5113,16 +5113,16 @@ static int fotg210_run(struct usb_hcd *hcd)
 	 * Scsi_Host.highmem_io, and so forth.  It's readonly to all
 	 * host side drivers though.
 	 */
-	hcc_params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
+	hcc_params = fhcd2xx_readl(fhcd2xx, &fhcd2xx->caps->hcc_params);
 
 	/*
 	 * Philips, Intel, and maybe others need CMD_RUN before the
 	 * root hub will detect new devices (why?); NEC doesn't
 	 */
-	fotg210->command &= ~(CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
-	fotg210->command |= CMD_RUN;
-	fotg210_writel(fotg210, fotg210->command, &fotg210->regs->command);
-	dbg_cmd(fotg210, "init", fotg210->command);
+	fhcd2xx->command &= ~(CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
+	fhcd2xx->command |= CMD_RUN;
+	fhcd2xx_writel(fhcd2xx, fhcd2xx->command, &fhcd2xx->regs->command);
+	dbg_cmd(fhcd2xx, "init", fhcd2xx->command);
 
 	/*
 	 * Start, enabling full USB 2.0 functionality ... usb 1.1 devices
@@ -5139,77 +5139,77 @@ static int fotg210_run(struct usb_hcd *hcd)
 	 * be started before the port switching actions could complete.
 	 */
 	down_write(&ehci_cf_port_reset_rwsem);
-	fotg210->rh_state = FOTG210_RH_RUNNING;
+	fhcd2xx->rh_state = FHCD2XX_RH_RUNNING;
 	/* unblock posted writes */
-	fotg210_readl(fotg210, &fotg210->regs->command);
+	fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->command);
 	usleep_range(5000, 6000);
 	up_write(&ehci_cf_port_reset_rwsem);
-	fotg210->last_periodic_enable = ktime_get_real();
+	fhcd2xx->last_periodic_enable = ktime_get_real();
 
-	temp = HC_VERSION(fotg210,
-			  fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
-	fotg210_info(fotg210,
+	temp = HC_VERSION(fhcd2xx,
+			  fhcd2xx_readl(fhcd2xx, &fhcd2xx->caps->hc_capbase));
+	fhcd2xx_info(fhcd2xx,
 		"USB %x.%x started, EHCI %x.%02x\n",
-		((fotg210->sbrn & 0xf0)>>4), (fotg210->sbrn & 0x0f),
+		((fhcd2xx->sbrn & 0xf0)>>4), (fhcd2xx->sbrn & 0x0f),
 		temp >> 8, temp & 0xff);
 
-	fotg210_writel(fotg210, INTR_MASK,
-		    &fotg210->regs->intr_enable); /* Turn On Interrupts */
+	fhcd2xx_writel(fhcd2xx, INTR_MASK,
+		    &fhcd2xx->regs->intr_enable); /* Turn On Interrupts */
 
 	/* GRR this is run-once init(), being done every time the HC starts.
 	 * So long as they're part of class devices, we can't do it init()
 	 * since the class device isn't created that early.
 	 */
-	create_debug_files(fotg210);
-	create_sysfs_files(fotg210);
+	create_debug_files(fhcd2xx);
+	create_sysfs_files(fhcd2xx);
 
 	return 0;
 }
 
-static int fotg210_setup(struct usb_hcd *hcd)
+static int fhcd2xx_setup(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fhcd2xx_hcd *fhcd2xx = hcd_to_fhcd2xx(hcd);
 	int retval;
 
-	fotg210->regs = (void __iomem *)fotg210->caps +
-	    HC_LENGTH(fotg210,
-		      fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
-	dbg_hcs_params(fotg210, "reset");
-	dbg_hcc_params(fotg210, "reset");
+	fhcd2xx->regs = (void __iomem *)fhcd2xx->caps +
+	    HC_LENGTH(fhcd2xx,
+		      fhcd2xx_readl(fhcd2xx, &fhcd2xx->caps->hc_capbase));
+	dbg_hcs_params(fhcd2xx, "reset");
+	dbg_hcc_params(fhcd2xx, "reset");
 
 	/* cache this readonly data; minimize chip reads */
-	fotg210->hcs_params = fotg210_readl(fotg210,
-					    &fotg210->caps->hcs_params);
+	fhcd2xx->hcs_params = fhcd2xx_readl(fhcd2xx,
+					    &fhcd2xx->caps->hcs_params);
 
-	fotg210->sbrn = HCD_USB2;
+	fhcd2xx->sbrn = HCD_USB2;
 
 	/* data structure init */
-	retval = hcd_fotg210_init(hcd);
+	retval = hcd_fhcd2xx_init(hcd);
 	if (retval)
 		return retval;
 
-	retval = fotg210_halt(fotg210);
+	retval = fhcd2xx_halt(fhcd2xx);
 	if (retval)
 		return retval;
 
-	fotg210_reset(fotg210);
+	fhcd2xx_reset(fhcd2xx);
 
 	return 0;
 }
 
-static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
+static irqreturn_t fhcd2xx_irq(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fhcd2xx_hcd *fhcd2xx = hcd_to_fhcd2xx(hcd);
 	u32 status, masked_status, pcd_status = 0, cmd;
 	int bh;
 
-	spin_lock(&fotg210->lock);
+	spin_lock(&fhcd2xx->lock);
 
-	status = fotg210_readl(fotg210, &fotg210->regs->status);
+	status = fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->status);
 
 	/* e.g. cardbus physical eject */
 	if (status == ~(u32) 0) {
-		fotg210_dbg(fotg210, "device removed\n");
+		fhcd2xx_dbg(fhcd2xx, "device removed\n");
 		goto dead;
 	}
 
@@ -5221,27 +5221,27 @@ static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 
 	/* Shared IRQ? */
 	if (!masked_status ||
-	    unlikely(fotg210->rh_state == FOTG210_RH_HALTED)) {
-		spin_unlock(&fotg210->lock);
+	    unlikely(fhcd2xx->rh_state == FHCD2XX_RH_HALTED)) {
+		spin_unlock(&fhcd2xx->lock);
 		return IRQ_NONE;
 	}
 
 	/* clear (just) interrupts */
-	fotg210_writel(fotg210, masked_status, &fotg210->regs->status);
-	cmd = fotg210_readl(fotg210, &fotg210->regs->command);
+	fhcd2xx_writel(fhcd2xx, masked_status, &fhcd2xx->regs->status);
+	cmd = fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->command);
 	bh = 0;
 
 	/* unrequested/ignored: Frame List Rollover */
-	dbg_status(fotg210, "irq", status);
+	dbg_status(fhcd2xx, "irq", status);
 
 	/* INT, ERR, and IAA interrupt rates can be throttled */
 
 	/* normal [4.15.1.2] or error [4.15.1.1] completion */
 	if (likely((status & (STS_INT|STS_ERR)) != 0)) {
 		if (likely((status & STS_ERR) == 0))
-			COUNT(fotg210->stats.normal);
+			COUNT(fhcd2xx->stats.normal);
 		else
-			COUNT(fotg210->stats.error);
+			COUNT(fhcd2xx->stats.error);
 		bh = 1;
 	}
 
@@ -5249,8 +5249,8 @@ static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 	if (status & STS_IAA) {
 
 		/* Turn off the IAA watchdog */
-		fotg210->enabled_hrtimer_events &=
-			~BIT(FOTG210_HRTIMER_IAA_WATCHDOG);
+		fhcd2xx->enabled_hrtimer_events &=
+			~BIT(FHCD2XX_HRTIMER_IAA_WATCHDOG);
 
 		/*
 		 * Mild optimization: Allow another IAAD to reset the
@@ -5259,75 +5259,75 @@ static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 		 * tests show that about half the time it will be reset
 		 * for some other event anyway.
 		 */
-		if (fotg210->next_hrtimer_event == FOTG210_HRTIMER_IAA_WATCHDOG)
-			++fotg210->next_hrtimer_event;
+		if (fhcd2xx->next_hrtimer_event == FHCD2XX_HRTIMER_IAA_WATCHDOG)
+			++fhcd2xx->next_hrtimer_event;
 
 		/* guard against (alleged) silicon errata */
 		if (cmd & CMD_IAAD)
-			fotg210_dbg(fotg210, "IAA with IAAD still set?\n");
-		if (fotg210->async_iaa) {
-			COUNT(fotg210->stats.iaa);
-			end_unlink_async(fotg210);
+			fhcd2xx_dbg(fhcd2xx, "IAA with IAAD still set?\n");
+		if (fhcd2xx->async_iaa) {
+			COUNT(fhcd2xx->stats.iaa);
+			end_unlink_async(fhcd2xx);
 		} else
-			fotg210_dbg(fotg210, "IAA with nothing unlinked?\n");
+			fhcd2xx_dbg(fhcd2xx, "IAA with nothing unlinked?\n");
 	}
 
 	/* remote wakeup [4.3.1] */
 	if (status & STS_PCD) {
 		int pstatus;
-		u32 __iomem *status_reg = &fotg210->regs->port_status;
+		u32 __iomem *status_reg = &fhcd2xx->regs->port_status;
 
 		/* kick root hub later */
 		pcd_status = status;
 
 		/* resume root hub? */
-		if (fotg210->rh_state == FOTG210_RH_SUSPENDED)
+		if (fhcd2xx->rh_state == FHCD2XX_RH_SUSPENDED)
 			usb_hcd_resume_root_hub(hcd);
 
-		pstatus = fotg210_readl(fotg210, status_reg);
+		pstatus = fhcd2xx_readl(fhcd2xx, status_reg);
 
-		if (test_bit(0, &fotg210->suspended_ports) &&
+		if (test_bit(0, &fhcd2xx->suspended_ports) &&
 				((pstatus & PORT_RESUME) ||
 					!(pstatus & PORT_SUSPEND)) &&
 				(pstatus & PORT_PE) &&
-				fotg210->reset_done[0] == 0) {
+				fhcd2xx->reset_done[0] == 0) {
 
 			/* start 20 msec resume signaling from this port,
 			 * and make hub_wq collect PORT_STAT_C_SUSPEND to
 			 * stop that signaling.  Use 5 ms extra for safety,
 			 * like usb_port_resume() does.
 			 */
-			fotg210->reset_done[0] = jiffies + msecs_to_jiffies(25);
-			set_bit(0, &fotg210->resuming_ports);
-			fotg210_dbg(fotg210, "port 1 remote wakeup\n");
-			mod_timer(&hcd->rh_timer, fotg210->reset_done[0]);
+			fhcd2xx->reset_done[0] = jiffies + msecs_to_jiffies(25);
+			set_bit(0, &fhcd2xx->resuming_ports);
+			fhcd2xx_dbg(fhcd2xx, "port 1 remote wakeup\n");
+			mod_timer(&hcd->rh_timer, fhcd2xx->reset_done[0]);
 		}
 	}
 
 	/* PCI errors [4.15.2.4] */
 	if (unlikely((status & STS_FATAL) != 0)) {
-		fotg210_err(fotg210, "fatal error\n");
-		dbg_cmd(fotg210, "fatal", cmd);
-		dbg_status(fotg210, "fatal", status);
+		fhcd2xx_err(fhcd2xx, "fatal error\n");
+		dbg_cmd(fhcd2xx, "fatal", cmd);
+		dbg_status(fhcd2xx, "fatal", status);
 dead:
 		usb_hc_died(hcd);
 
 		/* Don't let the controller do anything more */
-		fotg210->shutdown = true;
-		fotg210->rh_state = FOTG210_RH_STOPPING;
-		fotg210->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
-		fotg210_writel(fotg210, fotg210->command,
-			       &fotg210->regs->command);
-		fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
-		fotg210_handle_controller_death(fotg210);
+		fhcd2xx->shutdown = true;
+		fhcd2xx->rh_state = FHCD2XX_RH_STOPPING;
+		fhcd2xx->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
+		fhcd2xx_writel(fhcd2xx, fhcd2xx->command,
+			       &fhcd2xx->regs->command);
+		fhcd2xx_writel(fhcd2xx, 0, &fhcd2xx->regs->intr_enable);
+		fhcd2xx_handle_controller_death(fhcd2xx);
 
 		/* Handle completions when the controller stops */
 		bh = 0;
 	}
 
 	if (bh)
-		fotg210_work(fotg210);
-	spin_unlock(&fotg210->lock);
+		fhcd2xx_work(fhcd2xx);
+	spin_unlock(&fhcd2xx->lock);
 	if (pcd_status)
 		usb_hcd_poll_rh_status(hcd);
 	return IRQ_HANDLED;
@@ -5345,10 +5345,10 @@ dead:
  * NOTE:  control, bulk, and interrupt share the same code to append TDs
  * to a (possibly active) QH, and the same QH scanning code.
  */
-static int fotg210_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+static int fhcd2xx_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 			       gfp_t mem_flags)
 {
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fhcd2xx_hcd *fhcd2xx = hcd_to_fhcd2xx(hcd);
 	struct list_head qtd_list;
 
 	INIT_LIST_HEAD(&qtd_list);
@@ -5363,17 +5363,17 @@ static int fotg210_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 		/* FALLTHROUGH */
 	/* case PIPE_BULK: */
 	default:
-		if (!qh_urb_transaction(fotg210, urb, &qtd_list, mem_flags))
+		if (!qh_urb_transaction(fhcd2xx, urb, &qtd_list, mem_flags))
 			return -ENOMEM;
-		return submit_async(fotg210, urb, &qtd_list, mem_flags);
+		return submit_async(fhcd2xx, urb, &qtd_list, mem_flags);
 
 	case PIPE_INTERRUPT:
-		if (!qh_urb_transaction(fotg210, urb, &qtd_list, mem_flags))
+		if (!qh_urb_transaction(fhcd2xx, urb, &qtd_list, mem_flags))
 			return -ENOMEM;
-		return intr_submit(fotg210, urb, &qtd_list, mem_flags);
+		return intr_submit(fhcd2xx, urb, &qtd_list, mem_flags);
 
 	case PIPE_ISOCHRONOUS:
-		return itd_submit(fotg210, urb, mem_flags);
+		return itd_submit(fhcd2xx, urb, mem_flags);
 	}
 }
 
@@ -5381,14 +5381,14 @@ static int fotg210_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
  * completions normally happen asynchronously
  */
 
-static int fotg210_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+static int fhcd2xx_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 {
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh *qh;
+	struct fhcd2xx_hcd *fhcd2xx = hcd_to_fhcd2xx(hcd);
+	struct fhcd2xx_qh *qh;
 	unsigned long flags;
 	int rc;
 
-	spin_lock_irqsave(&fotg210->lock, flags);
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
 	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
 	if (rc)
 		goto done;
@@ -5397,13 +5397,13 @@ static int fotg210_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 	/* case PIPE_CONTROL: */
 	/* case PIPE_BULK:*/
 	default:
-		qh = (struct fotg210_qh *) urb->hcpriv;
+		qh = (struct fhcd2xx_qh *) urb->hcpriv;
 		if (!qh)
 			break;
 		switch (qh->qh_state) {
 		case QH_STATE_LINKED:
 		case QH_STATE_COMPLETING:
-			start_unlink_async(fotg210, qh);
+			start_unlink_async(fhcd2xx, qh);
 			break;
 		case QH_STATE_UNLINK:
 		case QH_STATE_UNLINK_WAIT:
@@ -5411,25 +5411,25 @@ static int fotg210_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 			break;
 		case QH_STATE_IDLE:
 			/* QH might be waiting for a Clear-TT-Buffer */
-			qh_completions(fotg210, qh);
+			qh_completions(fhcd2xx, qh);
 			break;
 		}
 		break;
 
 	case PIPE_INTERRUPT:
-		qh = (struct fotg210_qh *) urb->hcpriv;
+		qh = (struct fhcd2xx_qh *) urb->hcpriv;
 		if (!qh)
 			break;
 		switch (qh->qh_state) {
 		case QH_STATE_LINKED:
 		case QH_STATE_COMPLETING:
-			start_unlink_intr(fotg210, qh);
+			start_unlink_intr(fhcd2xx, qh);
 			break;
 		case QH_STATE_IDLE:
-			qh_completions(fotg210, qh);
+			qh_completions(fhcd2xx, qh);
 			break;
 		default:
-			fotg210_dbg(fotg210, "bogus qh %p state %d\n",
+			fhcd2xx_dbg(fhcd2xx, "bogus qh %p state %d\n",
 					qh, qh->qh_state);
 			goto done;
 		}
@@ -5443,24 +5443,24 @@ static int fotg210_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 		break;
 	}
 done:
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 	return rc;
 }
 
 /* bulk qh holds the data toggle */
 
-static void fotg210_endpoint_disable(struct usb_hcd *hcd,
+static void fhcd2xx_endpoint_disable(struct usb_hcd *hcd,
 				     struct usb_host_endpoint *ep)
 {
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fhcd2xx_hcd *fhcd2xx = hcd_to_fhcd2xx(hcd);
 	unsigned long flags;
-	struct fotg210_qh *qh, *tmp;
+	struct fhcd2xx_qh *qh, *tmp;
 
 	/* ASSERT:  any requests/urbs are being unlinked */
 	/* ASSERT:  nobody can be submitting urbs for this any more */
 
 rescan:
-	spin_lock_irqsave(&fotg210->lock, flags);
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
 	qh = ep->hcpriv;
 	if (!qh)
 		goto done;
@@ -5469,7 +5469,7 @@ rescan:
 	 * accelerate iso completions ... so spin a while.
 	 */
 	if (qh->hw == NULL) {
-		struct fotg210_iso_stream *stream = ep->hcpriv;
+		struct fhcd2xx_iso_stream *stream = ep->hcpriv;
 
 		if (!list_empty(&stream->td_list))
 			goto idle_timeout;
@@ -5479,12 +5479,12 @@ rescan:
 		goto done;
 	}
 
-	if (fotg210->rh_state < FOTG210_RH_RUNNING)
+	if (fhcd2xx->rh_state < FHCD2XX_RH_RUNNING)
 		qh->qh_state = QH_STATE_IDLE;
 	switch (qh->qh_state) {
 	case QH_STATE_LINKED:
 	case QH_STATE_COMPLETING:
-		for (tmp = fotg210->async->qh_next.qh;
+		for (tmp = fhcd2xx->async->qh_next.qh;
 				tmp && tmp != qh;
 				tmp = tmp->qh_next.qh)
 			continue;
@@ -5492,19 +5492,19 @@ rescan:
 		 * may already be unlinked.
 		 */
 		if (tmp)
-			start_unlink_async(fotg210, qh);
+			start_unlink_async(fhcd2xx, qh);
 		/* FALL THROUGH */
 	case QH_STATE_UNLINK:		/* wait for hw to finish? */
 	case QH_STATE_UNLINK_WAIT:
 idle_timeout:
-		spin_unlock_irqrestore(&fotg210->lock, flags);
+		spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 		schedule_timeout_uninterruptible(1);
 		goto rescan;
 	case QH_STATE_IDLE:		/* fully unlinked */
 		if (qh->clearing_tt)
 			goto idle_timeout;
 		if (list_empty(&qh->qtd_list)) {
-			qh_destroy(fotg210, qh);
+			qh_destroy(fhcd2xx, qh);
 			break;
 		}
 		/* else FALL THROUGH */
@@ -5512,21 +5512,21 @@ idle_timeout:
 		/* caller was supposed to have unlinked any requests;
 		 * that's not our job.  just leak this memory.
 		 */
-		fotg210_err(fotg210, "qh %p (#%02x) state %d%s\n",
+		fhcd2xx_err(fhcd2xx, "qh %p (#%02x) state %d%s\n",
 			qh, ep->desc.bEndpointAddress, qh->qh_state,
 			list_empty(&qh->qtd_list) ? "" : "(has tds)");
 		break;
 	}
 done:
 	ep->hcpriv = NULL;
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 }
 
-static void fotg210_endpoint_reset(struct usb_hcd *hcd,
+static void fhcd2xx_endpoint_reset(struct usb_hcd *hcd,
 				   struct usb_host_endpoint *ep)
 {
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh *qh;
+	struct fhcd2xx_hcd *fhcd2xx = hcd_to_fhcd2xx(hcd);
+	struct fhcd2xx_qh *qh;
 	int eptype = usb_endpoint_type(&ep->desc);
 	int epnum = usb_endpoint_num(&ep->desc);
 	int is_out = usb_endpoint_dir_out(&ep->desc);
@@ -5535,7 +5535,7 @@ static void fotg210_endpoint_reset(struct usb_hcd *hcd,
 	if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
 		return;
 
-	spin_lock_irqsave(&fotg210->lock, flags);
+	spin_lock_irqsave(&fhcd2xx->lock, flags);
 	qh = ep->hcpriv;
 
 	/* For Bulk and Interrupt endpoints we maintain the toggle state
@@ -5555,106 +5555,106 @@ static void fotg210_endpoint_reset(struct usb_hcd *hcd,
 			 * re-linking will call qh_refresh().
 			 */
 			if (eptype == USB_ENDPOINT_XFER_BULK)
-				start_unlink_async(fotg210, qh);
+				start_unlink_async(fhcd2xx, qh);
 			else
-				start_unlink_intr(fotg210, qh);
+				start_unlink_intr(fhcd2xx, qh);
 		}
 	}
-	spin_unlock_irqrestore(&fotg210->lock, flags);
+	spin_unlock_irqrestore(&fhcd2xx->lock, flags);
 }
 
-static int fotg210_get_frame(struct usb_hcd *hcd)
+static int fhcd2xx_get_frame(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fhcd2xx_hcd *fhcd2xx = hcd_to_fhcd2xx(hcd);
 
-	return (fotg210_read_frame_index(fotg210) >> 3) %
-		fotg210->periodic_size;
+	return (fhcd2xx_read_frame_index(fhcd2xx) >> 3) %
+		fhcd2xx->periodic_size;
 }
 
 /*
  * The EHCI in ChipIdea HDRC cannot be a separate module or device,
  * because its registers (and irq) are shared between host/gadget/otg
  * functions  and in order to facilitate role switching we cannot
- * give the fotg210 driver exclusive access to those.
+ * give the fhcd2xx driver exclusive access to those.
  */
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_LICENSE("GPL");
 
-static const struct hc_driver fotg210_fotg210_hc_driver = {
+static const struct hc_driver fhcd2xx_fhcd2xx_hc_driver = {
 	.description		= hcd_name,
 	.product_desc		= "Faraday USB2.0 Host Controller",
-	.hcd_priv_size		= sizeof(struct fotg210_hcd),
+	.hcd_priv_size		= sizeof(struct fhcd2xx_hcd),
 
 	/*
 	 * generic hardware linkage
 	 */
-	.irq			= fotg210_irq,
+	.irq			= fhcd2xx_irq,
 	.flags			= HCD_MEMORY | HCD_USB2,
 
 	/*
 	 * basic lifecycle operations
 	 */
-	.reset			= hcd_fotg210_init,
-	.start			= fotg210_run,
-	.stop			= fotg210_stop,
-	.shutdown		= fotg210_shutdown,
+	.reset			= hcd_fhcd2xx_init,
+	.start			= fhcd2xx_run,
+	.stop			= fhcd2xx_stop,
+	.shutdown		= fhcd2xx_shutdown,
 
 	/*
 	 * managing i/o requests and associated device resources
 	 */
-	.urb_enqueue		= fotg210_urb_enqueue,
-	.urb_dequeue		= fotg210_urb_dequeue,
-	.endpoint_disable	= fotg210_endpoint_disable,
-	.endpoint_reset		= fotg210_endpoint_reset,
+	.urb_enqueue		= fhcd2xx_urb_enqueue,
+	.urb_dequeue		= fhcd2xx_urb_dequeue,
+	.endpoint_disable	= fhcd2xx_endpoint_disable,
+	.endpoint_reset		= fhcd2xx_endpoint_reset,
 
 	/*
 	 * scheduling support
 	 */
-	.get_frame_number	= fotg210_get_frame,
+	.get_frame_number	= fhcd2xx_get_frame,
 
 	/*
 	 * root hub support
 	 */
-	.hub_status_data	= fotg210_hub_status_data,
-	.hub_control		= fotg210_hub_control,
-	.bus_suspend		= fotg210_bus_suspend,
-	.bus_resume		= fotg210_bus_resume,
+	.hub_status_data	= fhcd2xx_hub_status_data,
+	.hub_control		= fhcd2xx_hub_control,
+	.bus_suspend		= fhcd2xx_bus_suspend,
+	.bus_resume		= fhcd2xx_bus_resume,
 
-	.relinquish_port	= fotg210_relinquish_port,
-	.port_handed_over	= fotg210_port_handed_over,
+	.relinquish_port	= fhcd2xx_relinquish_port,
+	.port_handed_over	= fhcd2xx_port_handed_over,
 
-	.clear_tt_buffer_complete = fotg210_clear_tt_buffer_complete,
+	.clear_tt_buffer_complete = fhcd2xx_clear_tt_buffer_complete,
 };
 
-static void fotg210_init(struct fotg210_hcd *fotg210)
+static void fhcd2xx_init(struct fhcd2xx_hcd *fhcd2xx)
 {
 	u32 value;
 
 	iowrite32(GMIR_MDEV_INT | GMIR_MOTG_INT | GMIR_INT_POLARITY,
-		  &fotg210->regs->gmir);
+		  &fhcd2xx->regs->gmir);
 
-	value = ioread32(&fotg210->regs->otgcsr);
+	value = ioread32(&fhcd2xx->regs->otgcsr);
 	value &= ~OTGCSR_A_BUS_DROP;
 	value |= OTGCSR_A_BUS_REQ;
-	iowrite32(value, &fotg210->regs->otgcsr);
+	iowrite32(value, &fhcd2xx->regs->otgcsr);
 }
 
 /**
- * fotg210_hcd_probe - initialize faraday FOTG210 HCDs
+ * fhcd2xx_hcd_probe - initialize faraday FHCD2XX HCDs
  *
  * Allocates basic resources for this USB host controller, and
  * then invokes the start() method for the HCD associated with it
  * through the hotplug entry's driver_data.
  */
-static int fotg210_hcd_probe(struct platform_device *pdev)
+static int fhcd2xx_hcd_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct usb_hcd *hcd;
 	struct resource *res;
 	int irq;
 	int retval = -ENODEV;
-	struct fotg210_hcd *fotg210;
+	struct fhcd2xx_hcd *fhcd2xx;
 
 	if (usb_disabled())
 		return -ENODEV;
@@ -5671,7 +5671,7 @@ static int fotg210_hcd_probe(struct platform_device *pdev)
 
 	irq = res->start;
 
-	hcd = usb_create_hcd(&fotg210_fotg210_hc_driver, dev,
+	hcd = usb_create_hcd(&fhcd2xx_fhcd2xx_hc_driver, dev,
 			dev_name(dev));
 	if (!hcd) {
 		dev_err(dev, "failed to create hcd with err %d\n", retval);
@@ -5691,15 +5691,15 @@ static int fotg210_hcd_probe(struct platform_device *pdev)
 	hcd->rsrc_start = res->start;
 	hcd->rsrc_len = resource_size(res);
 
-	fotg210 = hcd_to_fotg210(hcd);
+	fhcd2xx = hcd_to_fhcd2xx(hcd);
 
-	fotg210->caps = hcd->regs;
+	fhcd2xx->caps = hcd->regs;
 
-	retval = fotg210_setup(hcd);
+	retval = fhcd2xx_setup(hcd);
 	if (retval)
 		goto failed;
 
-	fotg210_init(fotg210);
+	fhcd2xx_init(fhcd2xx);
 
 	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (retval) {
@@ -5718,11 +5718,11 @@ fail_create_hcd:
 }
 
 /**
- * fotg210_hcd_remove - shutdown processing for EHCI HCDs
+ * fhcd2xx_hcd_remove - shutdown processing for EHCI HCDs
  * @dev: USB Host Controller being removed
  *
  */
-static int fotg210_hcd_remove(struct platform_device *pdev)
+static int fhcd2xx_hcd_remove(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct usb_hcd *hcd = dev_get_drvdata(dev);
@@ -5736,15 +5736,15 @@ static int fotg210_hcd_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static struct platform_driver fotg210_hcd_driver = {
+static struct platform_driver fhcd2xx_hcd_driver = {
 	.driver = {
-		.name   = "fotg210-hcd",
+		.name   = "fhcd2xx-hcd",
 	},
-	.probe  = fotg210_hcd_probe,
-	.remove = fotg210_hcd_remove,
+	.probe  = fhcd2xx_hcd_probe,
+	.remove = fhcd2xx_hcd_remove,
 };
 
-static int __init fotg210_hcd_init(void)
+static int __init fhcd2xx_hcd_init(void)
 {
 	int retval = 0;
 
@@ -5755,38 +5755,38 @@ static int __init fotg210_hcd_init(void)
 	set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
 	if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
 			test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
-		pr_warn("Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
+		pr_warn("Warning! fhcd2xx_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
 
 	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd\n",
 		 hcd_name,
-		 sizeof(struct fotg210_qh), sizeof(struct fotg210_qtd),
-		 sizeof(struct fotg210_itd));
+		 sizeof(struct fhcd2xx_qh), sizeof(struct fhcd2xx_qtd),
+		 sizeof(struct fhcd2xx_itd));
 
-	fotg210_debug_root = debugfs_create_dir("fotg210", usb_debug_root);
-	if (!fotg210_debug_root) {
+	fhcd2xx_debug_root = debugfs_create_dir("fhcd2xx", usb_debug_root);
+	if (!fhcd2xx_debug_root) {
 		retval = -ENOENT;
 		goto err_debug;
 	}
 
-	retval = platform_driver_register(&fotg210_hcd_driver);
+	retval = platform_driver_register(&fhcd2xx_hcd_driver);
 	if (retval < 0)
 		goto clean;
 	return retval;
 
-	platform_driver_unregister(&fotg210_hcd_driver);
+	platform_driver_unregister(&fhcd2xx_hcd_driver);
 clean:
-	debugfs_remove(fotg210_debug_root);
-	fotg210_debug_root = NULL;
+	debugfs_remove(fhcd2xx_debug_root);
+	fhcd2xx_debug_root = NULL;
 err_debug:
 	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
 	return retval;
 }
-module_init(fotg210_hcd_init);
+module_init(fhcd2xx_hcd_init);
 
-static void __exit fotg210_hcd_cleanup(void)
+static void __exit fhcd2xx_hcd_cleanup(void)
 {
-	platform_driver_unregister(&fotg210_hcd_driver);
-	debugfs_remove(fotg210_debug_root);
+	platform_driver_unregister(&fhcd2xx_hcd_driver);
+	debugfs_remove(fhcd2xx_debug_root);
 	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
 }
-module_exit(fotg210_hcd_cleanup);
+module_exit(fhcd2xx_hcd_cleanup);
diff --git a/drivers/usb/host/faraday-hcd.h b/drivers/usb/host/faraday-hcd.h
index b5cfa7a..cf29edf 100644
--- a/drivers/usb/host/faraday-hcd.h
+++ b/drivers/usb/host/faraday-hcd.h
@@ -1,5 +1,5 @@
-#ifndef __LINUX_FOTG210_H
-#define __LINUX_FOTG210_H
+#ifndef __LINUX_FHCD2XX_H
+#define __LINUX_FHCD2XX_H
 
 #include <linux/usb/ehci-dbgp.h>
 
@@ -7,7 +7,7 @@
 
 /*
  * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to
- * __leXX (normally) or __beXX (given FOTG210_BIG_ENDIAN_DESC), depending on
+ * __leXX (normally) or __beXX (given FHCD2XX_BIG_ENDIAN_DESC), depending on
  * the host controller implementation.
  *
  * To facilitate the strongest possible byte-order checking from "sparse"
@@ -17,7 +17,7 @@
 #define __hc16	__le16
 
 /* statistics can be kept for tuning/monitoring */
-struct fotg210_stats {
+struct fhcd2xx_stats {
 	/* irq usage */
 	unsigned long		normal;
 	unsigned long		error;
@@ -29,27 +29,27 @@ struct fotg210_stats {
 	unsigned long		unlink;
 };
 
-/* fotg210_hcd->lock guards shared data against other CPUs:
- *   fotg210_hcd:	async, unlink, periodic (and shadow), ...
+/* fhcd2xx_hcd->lock guards shared data against other CPUs:
+ *   fhcd2xx_hcd:	async, unlink, periodic (and shadow), ...
  *   usb_host_endpoint: hcpriv
- *   fotg210_qh:	qh_next, qtd_list
- *   fotg210_qtd:	qtd_list
+ *   fhcd2xx_qh:	qh_next, qtd_list
+ *   fhcd2xx_qtd:	qtd_list
  *
  * Also, hold this lock when talking to HC registers or
  * when updating hw_* fields in shared qh/qtd/... structures.
  */
 
-#define	FOTG210_MAX_ROOT_PORTS	1		/* see HCS_N_PORTS */
+#define	FHCD2XX_MAX_ROOT_PORTS	1		/* see HCS_N_PORTS */
 
 /*
- * fotg210_rh_state values of FOTG210_RH_RUNNING or above mean that the
+ * fhcd2xx_rh_state values of FHCD2XX_RH_RUNNING or above mean that the
  * controller may be doing DMA.  Lower values mean there's no DMA.
  */
-enum fotg210_rh_state {
-	FOTG210_RH_HALTED,
-	FOTG210_RH_SUSPENDED,
-	FOTG210_RH_RUNNING,
-	FOTG210_RH_STOPPING
+enum fhcd2xx_rh_state {
+	FHCD2XX_RH_HALTED,
+	FHCD2XX_RH_SUSPENDED,
+	FHCD2XX_RH_RUNNING,
+	FHCD2XX_RH_STOPPING
 };
 
 /*
@@ -57,26 +57,26 @@ enum fotg210_rh_state {
  * Always update event_delays_ns[] and event_handlers[] (defined in
  * ehci-timer.c) in parallel with this list.
  */
-enum fotg210_hrtimer_event {
-	FOTG210_HRTIMER_POLL_ASS,	/* Poll for async schedule off */
-	FOTG210_HRTIMER_POLL_PSS,	/* Poll for periodic schedule off */
-	FOTG210_HRTIMER_POLL_DEAD,	/* Wait for dead controller to stop */
-	FOTG210_HRTIMER_UNLINK_INTR,	/* Wait for interrupt QH unlink */
-	FOTG210_HRTIMER_FREE_ITDS,	/* Wait for unused iTDs and siTDs */
-	FOTG210_HRTIMER_ASYNC_UNLINKS,	/* Unlink empty async QHs */
-	FOTG210_HRTIMER_IAA_WATCHDOG,	/* Handle lost IAA interrupts */
-	FOTG210_HRTIMER_DISABLE_PERIODIC, /* Wait to disable periodic sched */
-	FOTG210_HRTIMER_DISABLE_ASYNC,	/* Wait to disable async sched */
-	FOTG210_HRTIMER_IO_WATCHDOG,	/* Check for missing IRQs */
-	FOTG210_HRTIMER_NUM_EVENTS	/* Must come last */
+enum fhcd2xx_hrtimer_event {
+	FHCD2XX_HRTIMER_POLL_ASS,	/* Poll for async schedule off */
+	FHCD2XX_HRTIMER_POLL_PSS,	/* Poll for periodic schedule off */
+	FHCD2XX_HRTIMER_POLL_DEAD,	/* Wait for dead controller to stop */
+	FHCD2XX_HRTIMER_UNLINK_INTR,	/* Wait for interrupt QH unlink */
+	FHCD2XX_HRTIMER_FREE_ITDS,	/* Wait for unused iTDs and siTDs */
+	FHCD2XX_HRTIMER_ASYNC_UNLINKS,	/* Unlink empty async QHs */
+	FHCD2XX_HRTIMER_IAA_WATCHDOG,	/* Handle lost IAA interrupts */
+	FHCD2XX_HRTIMER_DISABLE_PERIODIC, /* Wait to disable periodic sched */
+	FHCD2XX_HRTIMER_DISABLE_ASYNC,	/* Wait to disable async sched */
+	FHCD2XX_HRTIMER_IO_WATCHDOG,	/* Check for missing IRQs */
+	FHCD2XX_HRTIMER_NUM_EVENTS	/* Must come last */
 };
-#define FOTG210_HRTIMER_NO_EVENT	99
+#define FHCD2XX_HRTIMER_NO_EVENT	99
 
-struct fotg210_hcd {			/* one per controller */
+struct fhcd2xx_hcd {			/* one per controller */
 	/* timing support */
-	enum fotg210_hrtimer_event	next_hrtimer_event;
+	enum fhcd2xx_hrtimer_event	next_hrtimer_event;
 	unsigned		enabled_hrtimer_events;
-	ktime_t			hr_timeouts[FOTG210_HRTIMER_NUM_EVENTS];
+	ktime_t			hr_timeouts[FHCD2XX_HRTIMER_NUM_EVENTS];
 	struct hrtimer		hrtimer;
 
 	int			PSS_poll_count;
@@ -84,13 +84,13 @@ struct fotg210_hcd {			/* one per controller */
 	int			died_poll_count;
 
 	/* glue to PCI and HCD framework */
-	struct fotg210_caps __iomem *caps;
-	struct fotg210_regs __iomem *regs;
+	struct fhcd2xx_caps __iomem *caps;
+	struct fhcd2xx_regs __iomem *regs;
 	struct ehci_dbg_port __iomem *debug;
 
 	__u32			hcs_params;	/* cached register copy */
 	spinlock_t		lock;
-	enum fotg210_rh_state	rh_state;
+	enum fhcd2xx_rh_state	rh_state;
 
 	/* general schedule support */
 	bool			scanning:1;
@@ -98,14 +98,14 @@ struct fotg210_hcd {			/* one per controller */
 	bool			intr_unlinking:1;
 	bool			async_unlinking:1;
 	bool			shutdown:1;
-	struct fotg210_qh		*qh_scan_next;
+	struct fhcd2xx_qh		*qh_scan_next;
 
 	/* async schedule support */
-	struct fotg210_qh		*async;
-	struct fotg210_qh		*dummy;		/* For AMD quirk use */
-	struct fotg210_qh		*async_unlink;
-	struct fotg210_qh		*async_unlink_last;
-	struct fotg210_qh		*async_iaa;
+	struct fhcd2xx_qh		*async;
+	struct fhcd2xx_qh		*dummy;		/* For AMD quirk use */
+	struct fhcd2xx_qh		*async_unlink;
+	struct fhcd2xx_qh		*async_unlink_last;
+	struct fhcd2xx_qh		*async_iaa;
 	unsigned		async_unlink_cycle;
 	unsigned		async_count;	/* async activity count */
 
@@ -117,9 +117,9 @@ struct fotg210_hcd {			/* one per controller */
 	struct list_head	intr_qh_list;
 	unsigned		i_thresh;	/* uframes HC might cache */
 
-	union fotg210_shadow	*pshadow;	/* mirror hw periodic table */
-	struct fotg210_qh		*intr_unlink;
-	struct fotg210_qh		*intr_unlink_last;
+	union fhcd2xx_shadow	*pshadow;	/* mirror hw periodic table */
+	struct fhcd2xx_qh		*intr_unlink;
+	struct fhcd2xx_qh		*intr_unlink_last;
 	unsigned		intr_unlink_cycle;
 	unsigned		now_frame;	/* frame from HC hardware */
 	unsigned		next_frame;	/* scan periodic, start here */
@@ -132,10 +132,10 @@ struct fotg210_hcd {			/* one per controller */
 
 	/* list of itds completed while now_frame was still active */
 	struct list_head	cached_itd_list;
-	struct fotg210_itd	*last_itd_to_free;
+	struct fhcd2xx_itd	*last_itd_to_free;
 
 	/* per root hub port */
-	unsigned long		reset_done[FOTG210_MAX_ROOT_PORTS];
+	unsigned long		reset_done[FHCD2XX_MAX_ROOT_PORTS];
 
 	/* bit vectors (one bit per port)
 	 * which ports were already suspended at the start of a bus suspend
@@ -174,8 +174,8 @@ struct fotg210_hcd {			/* one per controller */
 	u8			sbrn;		/* packed release number */
 
 	/* irq statistics */
-#ifdef FOTG210_STATS
-	struct fotg210_stats	stats;
+#ifdef FHCD2XX_STATS
+	struct fhcd2xx_stats	stats;
 #	define COUNT(x) ((x)++)
 #else
 #	define COUNT(x)
@@ -185,14 +185,14 @@ struct fotg210_hcd {			/* one per controller */
 	struct dentry		*debug_dir;
 };
 
-/* convert between an HCD pointer and the corresponding FOTG210_HCD */
-static inline struct fotg210_hcd *hcd_to_fotg210(struct usb_hcd *hcd)
+/* convert between an HCD pointer and the corresponding FHCD2XX_HCD */
+static inline struct fhcd2xx_hcd *hcd_to_fhcd2xx(struct usb_hcd *hcd)
 {
-	return (struct fotg210_hcd *)(hcd->hcd_priv);
+	return (struct fhcd2xx_hcd *)(hcd->hcd_priv);
 }
-static inline struct usb_hcd *fotg210_to_hcd(struct fotg210_hcd *fotg210)
+static inline struct usb_hcd *fhcd2xx_to_hcd(struct fhcd2xx_hcd *fhcd2xx)
 {
-	return container_of((void *) fotg210, struct usb_hcd, hcd_priv);
+	return container_of((void *) fhcd2xx, struct usb_hcd, hcd_priv);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -200,7 +200,7 @@ static inline struct usb_hcd *fotg210_to_hcd(struct fotg210_hcd *fotg210)
 /* EHCI register interface, corresponds to EHCI Revision 0.95 specification */
 
 /* Section 2.2 Host Controller Capability Registers */
-struct fotg210_caps {
+struct fhcd2xx_caps {
 	/* these fields are specified as 8 and 16 bit registers,
 	 * but some hosts can't perform 8 or 16 bit PCI accesses.
 	 * some hosts treat caplength and hciversion as parts of a 32-bit
@@ -208,10 +208,10 @@ struct fotg210_caps {
 	 * affects the memory map for big endian controllers.
 	 */
 	u32		hc_capbase;
-#define HC_LENGTH(fotg210, p)	(0x00ff&((p) >> /* bits 7:0 / offset 00h */ \
-				(fotg210_big_endian_capbase(fotg210) ? 24 : 0)))
-#define HC_VERSION(fotg210, p)	(0xffff&((p) >> /* bits 31:16 / offset 02h */ \
-				(fotg210_big_endian_capbase(fotg210) ? 0 : 16)))
+#define HC_LENGTH(fhcd2xx, p)	(0x00ff&((p) >> /* bits 7:0 / offset 00h */ \
+				(fhcd2xx_big_endian_capbase(fhcd2xx) ? 24 : 0)))
+#define HC_VERSION(fhcd2xx, p)	(0xffff&((p) >> /* bits 31:16 / offset 02h */ \
+				(fhcd2xx_big_endian_capbase(fhcd2xx) ? 0 : 16)))
 	u32		hcs_params;     /* HCSPARAMS - offset 0x4 */
 #define HCS_N_PORTS(p)		(((p)>>0)&0xf)	/* bits 3:0, ports on HC */
 
@@ -223,7 +223,7 @@ struct fotg210_caps {
 
 
 /* Section 2.3 Host Controller Operational Registers */
-struct fotg210_regs {
+struct fhcd2xx_regs {
 
 	/* USBCMD: offset 0x00 */
 	u32		command;
@@ -303,7 +303,7 @@ struct fotg210_regs {
 
 /*-------------------------------------------------------------------------*/
 
-#define	QTD_NEXT(fotg210, dma)	cpu_to_hc32(fotg210, (u32)dma)
+#define	QTD_NEXT(fhcd2xx, dma)	cpu_to_hc32(fhcd2xx, (u32)dma)
 
 /*
  * EHCI Specification 0.95 Section 3.5
@@ -313,7 +313,7 @@ struct fotg210_regs {
  * These are associated only with "QH" (Queue Head) structures,
  * used with control, bulk, and interrupt transfers.
  */
-struct fotg210_qtd {
+struct fhcd2xx_qtd {
 	/* first part defined by EHCI spec */
 	__hc32			hw_next;	/* see EHCI 3.5.1 */
 	__hc32			hw_alt_next;    /* see EHCI 3.5.2 */
@@ -332,9 +332,9 @@ struct fotg210_qtd {
 #define	QTD_STS_STS	(1 << 1)	/* split transaction state */
 #define	QTD_STS_PING	(1 << 0)	/* issue PING? */
 
-#define ACTIVE_BIT(fotg210)	cpu_to_hc32(fotg210, QTD_STS_ACTIVE)
-#define HALT_BIT(fotg210)		cpu_to_hc32(fotg210, QTD_STS_HALT)
-#define STATUS_BIT(fotg210)	cpu_to_hc32(fotg210, QTD_STS_STS)
+#define ACTIVE_BIT(fhcd2xx)	cpu_to_hc32(fhcd2xx, QTD_STS_ACTIVE)
+#define HALT_BIT(fhcd2xx)		cpu_to_hc32(fhcd2xx, QTD_STS_HALT)
+#define STATUS_BIT(fhcd2xx)	cpu_to_hc32(fhcd2xx, QTD_STS_STS)
 
 	__hc32			hw_buf[5];	/* see EHCI 3.5.4 */
 	__hc32			hw_buf_hi[5];	/* Appendix B */
@@ -347,14 +347,14 @@ struct fotg210_qtd {
 } __aligned(32);
 
 /* mask NakCnt+T in qh->hw_alt_next */
-#define QTD_MASK(fotg210)	cpu_to_hc32(fotg210, ~0x1f)
+#define QTD_MASK(fhcd2xx)	cpu_to_hc32(fhcd2xx, ~0x1f)
 
 #define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1)
 
 /*-------------------------------------------------------------------------*/
 
 /* type tag from {qh,itd,fstn}->hw_next */
-#define Q_NEXT_TYPE(fotg210, dma)	((dma) & cpu_to_hc32(fotg210, 3 << 1))
+#define Q_NEXT_TYPE(fhcd2xx, dma)	((dma) & cpu_to_hc32(fhcd2xx, 3 << 1))
 
 /*
  * Now the following defines are not converted using the
@@ -370,12 +370,12 @@ struct fotg210_qtd {
 #define Q_TYPE_FSTN	(3 << 1)
 
 /* next async queue entry, or pointer to interrupt/periodic QH */
-#define QH_NEXT(fotg210, dma) \
-	(cpu_to_hc32(fotg210, (((u32)dma)&~0x01f)|Q_TYPE_QH))
+#define QH_NEXT(fhcd2xx, dma) \
+	(cpu_to_hc32(fhcd2xx, (((u32)dma)&~0x01f)|Q_TYPE_QH))
 
 /* for periodic/async schedules and qtd lists, mark end of list */
-#define FOTG210_LIST_END(fotg210) \
-	cpu_to_hc32(fotg210, 1) /* "null pointer" to hw */
+#define FHCD2XX_LIST_END(fhcd2xx) \
+	cpu_to_hc32(fhcd2xx, 1) /* "null pointer" to hw */
 
 /*
  * Entries in periodic shadow table are pointers to one of four kinds
@@ -385,10 +385,10 @@ struct fotg210_qtd {
  *
  * For entries in the async schedule, the type tag always says "qh".
  */
-union fotg210_shadow {
-	struct fotg210_qh	*qh;		/* Q_TYPE_QH */
-	struct fotg210_itd	*itd;		/* Q_TYPE_ITD */
-	struct fotg210_fstn	*fstn;		/* Q_TYPE_FSTN */
+union fhcd2xx_shadow {
+	struct fhcd2xx_qh	*qh;		/* Q_TYPE_QH */
+	struct fhcd2xx_itd	*itd;		/* Q_TYPE_ITD */
+	struct fhcd2xx_fstn	*fstn;		/* Q_TYPE_FSTN */
 	__hc32			*hw_next;	/* (all types) */
 	void			*ptr;
 };
@@ -404,7 +404,7 @@ union fotg210_shadow {
  */
 
 /* first part defined by EHCI spec */
-struct fotg210_qh_hw {
+struct fhcd2xx_qh_hw {
 	__hc32			hw_next;	/* see EHCI 3.6.1 */
 	__hc32			hw_info1;	/* see EHCI 3.6.2 */
 #define	QH_CONTROL_EP	(1 << 27)	/* FS/LS control endpoint */
@@ -422,7 +422,7 @@ struct fotg210_qh_hw {
 #define	QH_MULT		0xc0000000
 	__hc32			hw_current;	/* qtd list - see EHCI 3.6.4 */
 
-	/* qtd overlay (hardware parts of a struct fotg210_qtd) */
+	/* qtd overlay (hardware parts of a struct fhcd2xx_qtd) */
 	__hc32			hw_qtd_next;
 	__hc32			hw_alt_next;
 	__hc32			hw_token;
@@ -430,15 +430,15 @@ struct fotg210_qh_hw {
 	__hc32			hw_buf_hi[5];
 } __aligned(32);
 
-struct fotg210_qh {
-	struct fotg210_qh_hw	*hw;		/* Must come first */
+struct fhcd2xx_qh {
+	struct fhcd2xx_qh_hw	*hw;		/* Must come first */
 	/* the rest is HCD-private */
 	dma_addr_t		qh_dma;		/* address of qh */
-	union fotg210_shadow	qh_next;	/* ptr to qh; or periodic */
+	union fhcd2xx_shadow	qh_next;	/* ptr to qh; or periodic */
 	struct list_head	qtd_list;	/* sw qtd list */
 	struct list_head	intr_node;	/* list of intr QHs */
-	struct fotg210_qtd	*dummy;
-	struct fotg210_qh	*unlink_next;	/* next on unlink list */
+	struct fhcd2xx_qtd	*dummy;
+	struct fhcd2xx_qh	*unlink_next;	/* next on unlink list */
 
 	unsigned		unlink_cycle;
 
@@ -470,7 +470,7 @@ struct fotg210_qh {
 /*-------------------------------------------------------------------------*/
 
 /* description of one iso transaction (up to 3 KB data if highspeed) */
-struct fotg210_iso_packet {
+struct fhcd2xx_iso_packet {
 	/* These will be copied to iTD when scheduling */
 	u64			bufp;		/* itd->hw_bufp{,_hi}[pg] |= */
 	__hc32			transaction;	/* itd->hw_transaction[i] |= */
@@ -483,19 +483,19 @@ struct fotg210_iso_packet {
  * each packet is one logical usb transaction to the device (not TT),
  * beginning at stream->next_uframe
  */
-struct fotg210_iso_sched {
+struct fhcd2xx_iso_sched {
 	struct list_head	td_list;
 	unsigned		span;
-	struct fotg210_iso_packet	packet[0];
+	struct fhcd2xx_iso_packet	packet[0];
 };
 
 /*
- * fotg210_iso_stream - groups all (s)itds for this endpoint.
+ * fhcd2xx_iso_stream - groups all (s)itds for this endpoint.
  * acts like a qh would, if EHCI had them for ISO.
  */
-struct fotg210_iso_stream {
-	/* first field matches fotg210_hq, but is NULL */
-	struct fotg210_qh_hw	*hw;
+struct fhcd2xx_iso_stream {
+	/* first field matches fhcd2xx_hq, but is NULL */
+	struct fhcd2xx_qh_hw	*hw;
 
 	u8			bEndpointAddress;
 	u8			highspeed;
@@ -536,28 +536,28 @@ struct fotg210_iso_stream {
  *
  * Schedule records for high speed iso xfers
  */
-struct fotg210_itd {
+struct fhcd2xx_itd {
 	/* first part defined by EHCI spec */
 	__hc32			hw_next;	/* see EHCI 3.3.1 */
 	__hc32			hw_transaction[8]; /* see EHCI 3.3.2 */
-#define FOTG210_ISOC_ACTIVE	(1<<31)	/* activate transfer this slot */
-#define FOTG210_ISOC_BUF_ERR	(1<<30)	/* Data buffer error */
-#define FOTG210_ISOC_BABBLE	(1<<29)	/* babble detected */
-#define FOTG210_ISOC_XACTERR	(1<<28)	/* XactErr - transaction error */
-#define	FOTG210_ITD_LENGTH(tok)	(((tok)>>16) & 0x0fff)
-#define	FOTG210_ITD_IOC		(1 << 15)	/* interrupt on complete */
+#define FHCD2XX_ISOC_ACTIVE	(1<<31)	/* activate transfer this slot */
+#define FHCD2XX_ISOC_BUF_ERR	(1<<30)	/* Data buffer error */
+#define FHCD2XX_ISOC_BABBLE	(1<<29)	/* babble detected */
+#define FHCD2XX_ISOC_XACTERR	(1<<28)	/* XactErr - transaction error */
+#define	FHCD2XX_ITD_LENGTH(tok)	(((tok)>>16) & 0x0fff)
+#define	FHCD2XX_ITD_IOC		(1 << 15)	/* interrupt on complete */
 
-#define ITD_ACTIVE(fotg210)	cpu_to_hc32(fotg210, FOTG210_ISOC_ACTIVE)
+#define ITD_ACTIVE(fhcd2xx)	cpu_to_hc32(fhcd2xx, FHCD2XX_ISOC_ACTIVE)
 
 	__hc32			hw_bufp[7];	/* see EHCI 3.3.3 */
 	__hc32			hw_bufp_hi[7];	/* Appendix B */
 
 	/* the rest is HCD-private */
 	dma_addr_t		itd_dma;	/* for this itd */
-	union fotg210_shadow	itd_next;	/* ptr to periodic q entry */
+	union fhcd2xx_shadow	itd_next;	/* ptr to periodic q entry */
 
 	struct urb		*urb;
-	struct fotg210_iso_stream	*stream;	/* endpoint's queue */
+	struct fhcd2xx_iso_stream	*stream;	/* endpoint's queue */
 	struct list_head	itd_list;	/* list of stream's itds */
 
 	/* any/all hw_transactions here may be used by that urb */
@@ -577,24 +577,24 @@ struct fotg210_itd {
  * makes the HC jump (back) to a QH to scan for fs/ls QH completions until
  * it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work.
  */
-struct fotg210_fstn {
+struct fhcd2xx_fstn {
 	__hc32			hw_next;	/* any periodic q entry */
-	__hc32			hw_prev;	/* qh or FOTG210_LIST_END */
+	__hc32			hw_prev;	/* qh or FHCD2XX_LIST_END */
 
 	/* the rest is HCD-private */
 	dma_addr_t		fstn_dma;
-	union fotg210_shadow	fstn_next;	/* ptr to periodic q entry */
+	union fhcd2xx_shadow	fstn_next;	/* ptr to periodic q entry */
 } __aligned(32);
 
 /*-------------------------------------------------------------------------*/
 
 /* Prepare the PORTSC wakeup flags during controller suspend/resume */
 
-#define fotg210_prepare_ports_for_controller_suspend(fotg210, do_wakeup) \
-		fotg210_adjust_port_wakeup_flags(fotg210, true, do_wakeup)
+#define fhcd2xx_prepare_ports_for_controller_suspend(fhcd2xx, do_wakeup) \
+		fhcd2xx_adjust_port_wakeup_flags(fhcd2xx, true, do_wakeup)
 
-#define fotg210_prepare_ports_for_controller_resume(fotg210)		\
-		fotg210_adjust_port_wakeup_flags(fotg210, false, false)
+#define fhcd2xx_prepare_ports_for_controller_resume(fhcd2xx)		\
+		fhcd2xx_adjust_port_wakeup_flags(fhcd2xx, false, false)
 
 /*-------------------------------------------------------------------------*/
 
@@ -606,17 +606,17 @@ struct fotg210_fstn {
  */
 
 static inline unsigned int
-fotg210_get_speed(struct fotg210_hcd *fotg210, unsigned int portsc)
+fhcd2xx_get_speed(struct fhcd2xx_hcd *fhcd2xx, unsigned int portsc)
 {
-	return (readl(&fotg210->regs->otgcsr)
+	return (readl(&fhcd2xx->regs->otgcsr)
 		& OTGCSR_HOST_SPD_TYP) >> 22;
 }
 
 /* Returns the speed of a device attached to a port on the root hub. */
 static inline unsigned int
-fotg210_port_speed(struct fotg210_hcd *fotg210, unsigned int portsc)
+fhcd2xx_port_speed(struct fhcd2xx_hcd *fhcd2xx, unsigned int portsc)
 {
-	switch (fotg210_get_speed(fotg210, portsc)) {
+	switch (fhcd2xx_get_speed(fhcd2xx, portsc)) {
 	case 0:
 		return 0;
 	case 1:
@@ -629,7 +629,7 @@ fotg210_port_speed(struct fotg210_hcd *fotg210, unsigned int portsc)
 
 /*-------------------------------------------------------------------------*/
 
-#define	fotg210_has_fsl_portno_bug(e)		(0)
+#define	fhcd2xx_has_fsl_portno_bug(e)		(0)
 
 /*
  * While most USB host controllers implement their registers in
@@ -642,34 +642,34 @@ fotg210_port_speed(struct fotg210_hcd *fotg210, unsigned int portsc)
  *
  */
 
-#define fotg210_big_endian_mmio(e)	0
-#define fotg210_big_endian_capbase(e)	0
+#define fhcd2xx_big_endian_mmio(e)	0
+#define fhcd2xx_big_endian_capbase(e)	0
 
-static inline unsigned int fotg210_readl(const struct fotg210_hcd *fotg210,
+static inline unsigned int fhcd2xx_readl(const struct fhcd2xx_hcd *fhcd2xx,
 		__u32 __iomem *regs)
 {
 	return readl(regs);
 }
 
-static inline void fotg210_writel(const struct fotg210_hcd *fotg210,
+static inline void fhcd2xx_writel(const struct fhcd2xx_hcd *fhcd2xx,
 		const unsigned int val, __u32 __iomem *regs)
 {
 	writel(val, regs);
 }
 
-/* cpu to fotg210 */
-static inline __hc32 cpu_to_hc32(const struct fotg210_hcd *fotg210, const u32 x)
+/* cpu to fhcd2xx */
+static inline __hc32 cpu_to_hc32(const struct fhcd2xx_hcd *fhcd2xx, const u32 x)
 {
 	return cpu_to_le32(x);
 }
 
-/* fotg210 to cpu */
-static inline u32 hc32_to_cpu(const struct fotg210_hcd *fotg210, const __hc32 x)
+/* fhcd2xx to cpu */
+static inline u32 hc32_to_cpu(const struct fhcd2xx_hcd *fhcd2xx, const __hc32 x)
 {
 	return le32_to_cpu(x);
 }
 
-static inline u32 hc32_to_cpup(const struct fotg210_hcd *fotg210,
+static inline u32 hc32_to_cpup(const struct fhcd2xx_hcd *fhcd2xx,
 			       const __hc32 *x)
 {
 	return le32_to_cpup(x);
@@ -677,16 +677,16 @@ static inline u32 hc32_to_cpup(const struct fotg210_hcd *fotg210,
 
 /*-------------------------------------------------------------------------*/
 
-static inline unsigned fotg210_read_frame_index(struct fotg210_hcd *fotg210)
+static inline unsigned fhcd2xx_read_frame_index(struct fhcd2xx_hcd *fhcd2xx)
 {
-	return fotg210_readl(fotg210, &fotg210->regs->frame_index);
+	return fhcd2xx_readl(fhcd2xx, &fhcd2xx->regs->frame_index);
 }
 
-#define fotg210_itdlen(urb, desc, t) ({			\
+#define fhcd2xx_itdlen(urb, desc, t) ({			\
 	usb_pipein((urb)->pipe) ?				\
-	(desc)->length - FOTG210_ITD_LENGTH(t) :			\
-	FOTG210_ITD_LENGTH(t);					\
+	(desc)->length - FHCD2XX_ITD_LENGTH(t) :			\
+	FHCD2XX_ITD_LENGTH(t);					\
 })
 /*-------------------------------------------------------------------------*/
 
-#endif /* __LINUX_FOTG210_H */
+#endif /* __LINUX_FHCD2XX_H */
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 13/14] RFC: usb/host/faraday-hcd: Move #defines outside struct
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
                                   ` (11 preceding siblings ...)
  2015-09-21 15:01                 ` [PATCH 12/14] RFC: usb/host/faraday-hcd: Replace fotg210 by fhcd2xx Peter Senna Tschudin
@ 2015-09-21 15:01                 ` Peter Senna Tschudin
  2015-10-02 17:37                   ` Felipe Balbi
  2015-09-21 15:01                 ` [PATCH 14/14] RFC: usb/host/faraday-hcd: Import FUSBH200 parameters Peter Senna Tschudin
                                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-21 15:01 UTC (permalink / raw)
  To: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh
  Cc: Peter Senna Tschudin

For making the code more readable and to facilitate supporting multiple
hardware versions, move #defines to outside the struct declaration. This
patch also renames fhcd2xx_regs to fotg210_regs as this struct is
specific to fotg210.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/faraday-hcd.h | 137 ++++++++++++++++++++++-------------------
 1 file changed, 74 insertions(+), 63 deletions(-)

diff --git a/drivers/usb/host/faraday-hcd.h b/drivers/usb/host/faraday-hcd.h
index cf29edf..f75c467 100644
--- a/drivers/usb/host/faraday-hcd.h
+++ b/drivers/usb/host/faraday-hcd.h
@@ -85,7 +85,7 @@ struct fhcd2xx_hcd {			/* one per controller */
 
 	/* glue to PCI and HCD framework */
 	struct fhcd2xx_caps __iomem *caps;
-	struct fhcd2xx_regs __iomem *regs;
+	struct fotg210_regs __iomem *regs;
 	struct ehci_dbg_port __iomem *debug;
 
 	__u32			hcs_params;	/* cached register copy */
@@ -221,84 +221,95 @@ struct fhcd2xx_caps {
 	u8		portroute[8];	 /* nibbles for routing - offset 0xC */
 };
 
-
-/* Section 2.3 Host Controller Operational Registers */
-struct fhcd2xx_regs {
-
-	/* USBCMD: offset 0x00 */
-	u32		command;
-
 /* EHCI 1.1 addendum */
 /* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
-#define CMD_PARK	(1<<11)		/* enable "park" on async qh */
-#define CMD_PARK_CNT(c)	(((c)>>8)&3)	/* how many transfers to park for */
-#define CMD_IAAD	(1<<6)		/* "doorbell" interrupt async advance */
-#define CMD_ASE		(1<<5)		/* async schedule enable */
-#define CMD_PSE		(1<<4)		/* periodic schedule enable */
+#define CMD_PARK	(1<<11) /* enable "park" on async qh */
+#define CMD_PARK_CNT(c)	(((c)>>8)&3) /* how many transfers to park for */
+#define CMD_IAAD	(1<<6) /* "doorbell" interrupt async advance */
+#define CMD_ASE		(1<<5) /* async schedule enable */
+#define CMD_PSE		(1<<4) /* periodic schedule enable */
+
 /* 3:2 is periodic frame list size */
-#define CMD_RESET	(1<<1)		/* reset HC not bus */
-#define CMD_RUN		(1<<0)		/* start/stop HC */
+#define CMD_RESET	(1<<1) /* reset HC not bus */
+#define CMD_RUN		(1<<0) /* start/stop HC */
 
-	/* USBSTS: offset 0x04 */
-	u32		status;
-#define STS_ASS		(1<<15)		/* Async Schedule Status */
-#define STS_PSS		(1<<14)		/* Periodic Schedule Status */
-#define STS_RECL	(1<<13)		/* Reclamation */
-#define STS_HALT	(1<<12)		/* Not running (any reason) */
-/* some bits reserved */
-	/* these STS_* flags are also intr_enable bits (USBINTR) */
-#define STS_IAA		(1<<5)		/* Interrupted on async advance */
-#define STS_FATAL	(1<<4)		/* such as some PCI access errors */
-#define STS_FLR		(1<<3)		/* frame list rolled over */
-#define STS_PCD		(1<<2)		/* port change detect */
-#define STS_ERR		(1<<1)		/* "error" completion (overflow, ...) */
-#define STS_INT		(1<<0)		/* "normal" completion (short, ...) */
+#define STS_ASS		(1<<15) /* Async Schedule Status */
+#define STS_PSS		(1<<14) /* Periodic Schedule Status */
+#define STS_RECL	(1<<13) /* Reclamation */
+#define STS_HALT	(1<<12) /* Not running (any reason) */
+
+/* some bits reserved
+ * these STS_* flags are also intr_enable bits (USBINTR)
+ */
+#define STS_IAA		(1<<5) /* Interrupted on async advance */
+#define STS_FATAL	(1<<4) /* such as some PCI access errors */
+#define STS_FLR		(1<<3) /* frame list rolled over */
+#define STS_PCD		(1<<2) /* port change detect */
+#define STS_ERR		(1<<1) /* "error" completion (overflow, ...) */
+#define STS_INT		(1<<0) /* "normal" completion (short, ...) */
 
-	/* USBINTR: offset 0x08 */
-	u32		intr_enable;
-
-	/* FRINDEX: offset 0x0C */
-	u32		frame_index;	/* current microframe number */
-	/* CTRLDSSEGMENT: offset 0x10 */
-	u32		segment;	/* address bits 63:32 if needed */
-	/* PERIODICLISTBASE: offset 0x14 */
-	u32		frame_list;	/* points to periodic list */
-	/* ASYNCLISTADDR: offset 0x18 */
-	u32		async_next;	/* address of next async queue head */
-
-	u32	reserved1;
-	/* PORTSC: offset 0x20 */
-	u32	port_status;
 /* 31:23 reserved */
-#define PORT_USB11(x) (((x)&(3<<10)) == (1<<10))	/* USB 1.1 device */
-#define PORT_RESET	(1<<8)		/* reset port */
-#define PORT_SUSPEND	(1<<7)		/* suspend port */
-#define PORT_RESUME	(1<<6)		/* resume it */
-#define PORT_PEC	(1<<3)		/* port enable change */
-#define PORT_PE		(1<<2)		/* port enable */
-#define PORT_CSC	(1<<1)		/* connect status change */
-#define PORT_CONNECT	(1<<0)		/* device connected */
+#define PORT_USB11(x) (((x)&(3<<10)) == (1<<10)) /* USB 1.1 device */
+#define PORT_RESET	(1<<8) /* reset port */
+#define PORT_SUSPEND	(1<<7) /* suspend port */
+#define PORT_RESUME	(1<<6) /* resume it */
+#define PORT_PEC	(1<<3) /* port enable change */
+#define PORT_PE		(1<<2) /* port enable */
+#define PORT_CSC	(1<<1) /* connect status change */
+#define PORT_CONNECT	(1<<0) /* device connected */
 #define PORT_RWC_BITS   (PORT_CSC | PORT_PEC)
-	u32     reserved2[19];
 
-	/* OTGCSR: offet 0x70 */
-	u32     otgcsr;
+/* FOTG210 only: */
 #define OTGCSR_HOST_SPD_TYP     (3 << 22)
 #define OTGCSR_A_BUS_DROP	(1 << 5)
 #define OTGCSR_A_BUS_REQ	(1 << 4)
+#define OTGISR_OVC		(1 << 10)
+#define GMIR_INT_POLARITY	(1 << 3) /*Active High*/
+#define GMIR_MHC_INT		(1 << 2)
+#define GMIR_MOTG_INT		(1 << 1)
+#define GMIR_MDEV_INT		(1 << 0)
+
+/* Section 2.3 Host Controller Operational Registers */
+struct fotg210_regs {
+
+	/* USBCMD: offset 0x00 */
+	u32 command;
+
+	/* USBSTS: offset 0x04 */
+	u32 status;
+
+	/* USBINTR: offset 0x08 */
+	u32 intr_enable;
+
+	/* FRINDEX: offset 0x0C - current microframe number */
+	u32 frame_index;
+
+	/* CTRLDSSEGMENT: offset 0x10 - address bits 63:32 if needed */
+	u32 segment;
+
+	/* PERIODICLISTBASE: offset 0x14 - points to periodic list */
+	u32 frame_list;
+
+	/* ASYNCLISTADDR: offset 0x18 - address of next async queue head */
+	u32 async_next;
+
+	u32 reserved1;
+
+	/* PORTSC: offset 0x20 */
+	u32 port_status;
+
+	u32 reserved2[19];
+
+	/* OTGCSR: offet 0x70 */
+	u32 otgcsr;
 
 	/* OTGISR: offset 0x74 */
-	u32     otgisr;
-#define OTGISR_OVC	(1 << 10)
+	u32 otgisr;
 
-	u32     reserved3[15];
+	u32 reserved3[15];
 
 	/* GMIR: offset 0xB4 */
-	u32     gmir;
-#define GMIR_INT_POLARITY	(1 << 3) /*Active High*/
-#define GMIR_MHC_INT		(1 << 2)
-#define GMIR_MOTG_INT		(1 << 1)
-#define GMIR_MDEV_INT	(1 << 0)
+	u32 gmir;
 };
 
 /*-------------------------------------------------------------------------*/
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 14/14] RFC: usb/host/faraday-hcd: Import FUSBH200 parameters
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
                                   ` (12 preceding siblings ...)
  2015-09-21 15:01                 ` [PATCH 13/14] RFC: usb/host/faraday-hcd: Move #defines outside struct Peter Senna Tschudin
@ 2015-09-21 15:01                 ` Peter Senna Tschudin
  2015-10-02 17:38                   ` Felipe Balbi
  2015-10-02 11:18                 ` [PATCH] usb-host: Remove fusbh200 driver Peter Senna Tschudin
  2015-10-12 21:22                 ` [PATCH 0/9] usb/host/fotg210: code style and warning fixes Peter Senna Tschudin
  15 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-21 15:01 UTC (permalink / raw)
  To: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh
  Cc: Peter Senna Tschudin

This patch adds FUSBH200 parameters to faraday-hcd.h.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/faraday-hcd.h | 50 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/faraday-hcd.h b/drivers/usb/host/faraday-hcd.h
index f75c467..fd3b261 100644
--- a/drivers/usb/host/faraday-hcd.h
+++ b/drivers/usb/host/faraday-hcd.h
@@ -259,6 +259,14 @@ struct fhcd2xx_caps {
 #define PORT_CONNECT	(1<<0) /* device connected */
 #define PORT_RWC_BITS   (PORT_CSC | PORT_PEC)
 
+/* FUSB200 only: */
+#define BMCSR_HOST_SPD_TYP      (3<<9)
+#define BMCSR_VBUS_OFF          (1<<4)
+#define BMCSR_INT_POLARITY      (1<<3)
+#define BMISR_OVC               (1<<1)
+#define BMIER_OVC_EN            (1<<1)
+#define BMIER_VBUS_ERR_EN       (1<<0)
+
 /* FOTG210 only: */
 #define OTGCSR_HOST_SPD_TYP     (3 << 22)
 #define OTGCSR_A_BUS_DROP	(1 << 5)
@@ -269,7 +277,47 @@ struct fhcd2xx_caps {
 #define GMIR_MOTG_INT		(1 << 1)
 #define GMIR_MDEV_INT		(1 << 0)
 
-/* Section 2.3 Host Controller Operational Registers */
+/* FUSB200: Section 2.3 Host Controller Operational Registers */
+struct fusbh200_regs {
+	/* USBCMD: offset 0x00 */
+	u32 command;
+
+	/* USBSTS: offset 0x04 */
+	u32 status;
+
+	/* USBINTR: offset 0x08 */
+	u32 intr_enable;
+
+	/* FRINDEX: offset 0x0C - current microframe number */
+	u32 frame_index;
+
+	/* CTRLDSSEGMENT: offset 0x10 - address bits 63:32 if needed */
+	u32 segment;
+
+	/* PERIODICLISTBASE: offset 0x14 - points to periodic list */
+	u32 frame_list;
+
+	/* ASYNCLISTADDR: offset 0x18 - address of next async queue head */
+	u32 async_next;
+
+	u32 reserved1;
+
+	/* PORTSC: offset 0x20 */
+	u32 port_status;
+
+	u32 reserved2[3];
+
+	/* BMCSR: offset 0x30 - Bus Moniter Control/Status Register */
+	u32 bmcsr;
+
+	/* BMISR: offset 0x34 - Bus Moniter Interrupt Status Register */
+	u32 bmisr;
+
+	/* BMIER: offset 0x38 - Bus Moniter Interrupt Enable Register */
+	u32 bmier;
+};
+
+/* FOTG210: Section 2.3 Host Controller Operational Registers */
 struct fotg210_regs {
 
 	/* USBCMD: offset 0x00 */
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* Re: [PATCH 02/14] RFC: usb/host/fotg210: remove KERN_WARNING from pr_info
  2015-09-21 15:01                 ` [PATCH 02/14] RFC: usb/host/fotg210: remove KERN_WARNING from pr_info Peter Senna Tschudin
@ 2015-09-21 18:54                   ` Sergei Shtylyov
  2015-10-02 17:30                   ` Felipe Balbi
  1 sibling, 0 replies; 61+ messages in thread
From: Sergei Shtylyov @ 2015-09-21 18:54 UTC (permalink / raw)
  To: Peter Senna Tschudin, balbi, stern, standby24x7, pmladek,
	linux-usb, linux-kernel, gregkh

Hello.

On 09/21/2015 06:01 PM, Peter Senna Tschudin wrote:

> This patch remove KERN_WARNING from a call to pr_info().

    Not pr_warn()?

> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
> ---
>   drivers/usb/host/fotg210-hcd.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
> index 48eac34..36413b2 100644
> --- a/drivers/usb/host/fotg210-hcd.c
> +++ b/drivers/usb/host/fotg210-hcd.c
> @@ -5740,7 +5740,7 @@ static int __init fotg210_hcd_init(void)
>   	set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
>   	if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
>   			test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
> -		pr_warn(KERN_WARNING "Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
> +		pr_warn("Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
[...]

MBR, Sergei


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 05/14] RFC: usb/host/fotg210: change kmalloc by kmalloc_array
  2015-09-21 15:01                 ` [PATCH 05/14] RFC: usb/host/fotg210: change kmalloc by kmalloc_array Peter Senna Tschudin
@ 2015-09-21 18:56                   ` Sergei Shtylyov
  2015-10-02 17:30                   ` Felipe Balbi
  1 sibling, 0 replies; 61+ messages in thread
From: Sergei Shtylyov @ 2015-09-21 18:56 UTC (permalink / raw)
  To: Peter Senna Tschudin, balbi, stern, standby24x7, pmladek,
	linux-usb, linux-kernel, gregkh

On 09/21/2015 06:01 PM, Peter Senna Tschudin wrote:

> This patch change:

    "Replaces" maybe?

> kmalloc(DBG_SCHED_LIMIT * sizeof(*seen), GFP_ATOMIC)
>
> by:
>
> kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC)
>
> as kmalloc_array() should be used for allocating arrays.
>
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>

[...]

MBR, Sergei


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 09/14] RFC: usb/host/fotg210: Add function: output_buf_tds_dir()
  2015-09-21 15:01                 ` [PATCH 09/14] RFC: usb/host/fotg210: Add function: output_buf_tds_dir() Peter Senna Tschudin
@ 2015-09-21 19:15                   ` Sergei Shtylyov
  2015-10-02 17:32                   ` Felipe Balbi
  1 sibling, 0 replies; 61+ messages in thread
From: Sergei Shtylyov @ 2015-09-21 19:15 UTC (permalink / raw)
  To: Peter Senna Tschudin, balbi, stern, standby24x7, pmladek,
	linux-usb, linux-kernel, gregkh

On 09/21/2015 06:01 PM, Peter Senna Tschudin wrote:

> checkpatch complains about too many leading tabs because the switch
> statement starts after 6 tabs.
>
> fill_periodic_buffer() -> for() -> do -> switch() -> if() ->
> list_for_each_entry() and finally the last switch().
>
> This patch moves the list_for_each_entry() and the last switch() to a
> new inline function named output_buf_tds_dir(). This change makes the
> code easier to read and calm down checkpatch. This patch changes it to:
>
> fill_periodic_buffer() -> for() -> do -> switch() -> if() ->
> output_buf_tds_dir()
>
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
> ---
>   drivers/usb/host/fotg210-hcd.c | 64 ++++++++++++++++++++++--------------------
>   1 file changed, 33 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
> index 82cd5da..13cca41 100644
> --- a/drivers/usb/host/fotg210-hcd.c
> +++ b/drivers/usb/host/fotg210-hcd.c
> @@ -497,6 +497,36 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
>   	return strlen(buf->output_buf);
>   }
>
> +/* count tds, get ep direction */
> +static inline unsigned output_buf_tds_dir(char *buf,

    Please drop *inline*, let gcc figure it out.

> +					  struct fotg210_hcd *fotg210,
> +					  struct fotg210_qh_hw *hw,
> +					  struct fotg210_qh *qh, unsigned size)
> +{
> +	u32 scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
> +	struct fotg210_qtd *qtd;
> +	char *type = "";
> +	unsigned temp = 0;
> +
> +	/* count tds, get ep direction */
> +	list_for_each_entry(qtd, &qh->qtd_list, qtd_list) {
> +		temp++;
> +		switch (0x03 & (hc32_to_cpu(fotg210, qtd->hw_token) >> 8)) {

    I think the preference is to place immediate value after &.

> +		case 0:
> +			type = "out";
> +			continue;
> +		case 1:
> +			type = "in";
> +			continue;
> +		}
> +	}
> +
> +	return scnprintf(buf, size, "(%c%d ep%d%s [%d/%d] q%d p%d)",
> +			 speed_char(scratch), scratch & 0x007f,
> +			 (scratch >> 8) & 0x000f, type, qh->usecs,
> +			 qh->c_usecs, temp, 0x7ff & (scratch >> 16));

    Likewise.

[...]

MBR, Sergei


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: similar files: fusbh200-hcd.c and fotg210-hcd.c
  2015-09-15 16:50             ` Felipe Balbi
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
@ 2015-09-25 13:04               ` Peter Senna Tschudin
  1 sibling, 0 replies; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-09-25 13:04 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Alan Stern, Sergei Shtylyov, Masanari Iida, pmladek, linux-usb,
	linux-kernel, Greg Kroah-Hartman

On Tue, Sep 15, 2015 at 6:50 PM, Felipe Balbi <balbi@ti.com> wrote:
> Hi,
>
> On Tue, Sep 15, 2015 at 06:41:55PM +0200, Peter Senna Tschudin wrote:
>> On Tue, Sep 15, 2015 at 4:33 PM, Felipe Balbi <balbi@ti.com> wrote:
>> > On Mon, Sep 14, 2015 at 07:50:02PM +0200, Peter Senna Tschudin wrote:
>> >> On Mon, Sep 14, 2015 at 5:01 PM, Felipe Balbi <balbi@ti.com> wrote:
>> >> > On Sat, Sep 12, 2015 at 03:14:50PM +0200, Peter Senna Tschudin wrote:
>> >> >> >> Should these files be consolidated? And if so how?
>> >> >> > if you can find an easy way, that would be a very, very welcome patch.
>> >> >>
>> >> >> Is the ideal solution to consolidate both fusbh200-hcd.c and
>> >> >> fotg210-hcd.c in a single module? If this is the case, how to detect
>> >> >> at run time which version of the hw is present? Both are registered as
>> >> >
>> >> > does it matter ? If they work the same way, why does it matter which
>> >> > one's running?
>> >>
>> >> I may be missing something simple, but based on a 2 page product
>> >> brief, fotg210 has more resources like memory. So even if the .c files
>> >> are _very_ similar, there are some configuration parameters that
>> >> differ, for example:
>> >>
>> >> fusbh200.h:
>> >> #define BMCSR_VBUS_OFF (1<<4)
>> >> #define BMCSR_INT_POLARITY (1<<3)
>> >>
>> >> fotg210.h:
>> >> #define OTGCSR_A_BUS_DROP (1 << 5)
>> >> #define OTGCSR_A_BUS_REQ (1 << 4)
>> >
>> > Can you detect that in runtime ? If you can, detect it. If you can't use
>> > different platform_device_id.
>> >
>> >> >> notebook (hp elitebook 840), and on a VM, even if neither has the hw
>> >> >> ($ sudo modprobe fusbh200-hcd). The module loads with the warning
>> >> >> "fusbh200_hcd should always be loaded before uhci_hcd and ohci_hcd,
>> >> >> not after". On another workstation running ubuntu, I could load both
>> >> >> modules at the same time, producing the same warning for each module.
>> >> >> Should the module load if the device is not present?
>> >> >>
>> >> >> Other solution for consolidation would be to create a common_code.c,
>> >> >> keeping both fusbh200-hcd.c and fotg210-hcd.c only with the code that
>> >> >> differ. Is this better than what is there now?
>> >> >>
>> >> >> Other ideas?
>> >> >
>> >> > just combine them :-p Use platform_device_id to differentiate.
>>
>> Can you check the f2xx branch at:
>>
>> git@github.com:petersenna/linux.git
>>
>> And tell me if this is the way to go for the consolidation of the two
>> drivers? I started with the newest driver, did code cleanup, and
>> started filling the new driver with parameters from the older
>> FUSBH200. At the moment it compiles for x86 and probably still works
>> for FOTG210 devices. A concrete question I have is if should I keep
>> making many patches for the consolidation or should I do a single big
>> patch with all changes? Comments are welcome.
>
> it's best to just send patches. Also, you gave me an ssh URL which I
> can't use because I don't have write access to your tree (and I don't
> want to have it).
Sorry for that, my goal was not to send more than 10 patches just to
illustrate my questions. It looked more efficient to make the patches
available for analysis instead of spamming you.

I sent a RFC patch series to the list, it would help me a lot if you
can give me some feedback, mainly hints about the questions on the
cover letter.

Thank you for the feedback Sergei Shtylyov! I'll include your
suggestions in the next series.


>
> --
> balbi



-- 
Peter

^ permalink raw reply	[flat|nested] 61+ messages in thread

* [PATCH] usb-host: Remove fusbh200 driver
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
                                   ` (13 preceding siblings ...)
  2015-09-21 15:01                 ` [PATCH 14/14] RFC: usb/host/faraday-hcd: Import FUSBH200 parameters Peter Senna Tschudin
@ 2015-10-02 11:18                 ` Peter Senna Tschudin
  2015-10-02 17:39                   ` Felipe Balbi
  2015-10-12 21:22                 ` [PATCH 0/9] usb/host/fotg210: code style and warning fixes Peter Senna Tschudin
  15 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-10-02 11:18 UTC (permalink / raw)
  To: john453, yuanlmm, gregkh, stern, mathias.nyman, ralf,
	alexandre.belloni, ramneek.mehresh, laurent.pinchart, abrestic,
	sboyd, zajec5, haokexin, peter.senna, balbi, pebolle,
	sergei.shtylyov, standby24x7, rdunlap, chris, linux-kernel,
	linux-usb

fusbh200 and fotg210 are very similar. The initial idea was to consolidate
both drivers but I'm afraid fusbh200 is not being used.

This patch remove the fusbh200 source code, update Kconfig and two
Makefiles.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/Makefile            |    1 -
 drivers/usb/host/Kconfig        |   10 -
 drivers/usb/host/Makefile       |    1 -
 drivers/usb/host/fusbh200-hcd.c | 5894 ---------------------------------------
 drivers/usb/host/fusbh200.h     |  675 -----
 5 files changed, 6581 deletions(-)
 delete mode 100644 drivers/usb/host/fusbh200-hcd.c
 delete mode 100644 drivers/usb/host/fusbh200.h

diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index d8926c6..d5c57f1 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -27,7 +27,6 @@ obj-$(CONFIG_USB_R8A66597_HCD)	+= host/
 obj-$(CONFIG_USB_HWA_HCD)	+= host/
 obj-$(CONFIG_USB_IMX21_HCD)	+= host/
 obj-$(CONFIG_USB_FSL_MPH_DR_OF)	+= host/
-obj-$(CONFIG_USB_FUSBH200_HCD)	+= host/
 obj-$(CONFIG_USB_FOTG210_HCD)	+= host/
 obj-$(CONFIG_USB_MAX3421_HCD)	+= host/
 
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 079991e..3bb0887 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -348,16 +348,6 @@ config USB_ISP1362_HCD
 	  To compile this driver as a module, choose M here: the
 	  module will be called isp1362-hcd.
 
-config USB_FUSBH200_HCD
-	tristate "FUSBH200 HCD support"
-	depends on USB
-	---help---
-	Faraday FUSBH200 is designed to meet USB2.0 EHCI specification
-	with minor modification.
-
-	To compile this driver as a module, choose M here: the
-	module will be called fusbh200-hcd.
-
 config USB_FOTG210_HCD
 	tristate "FOTG210 HCD support"
 	depends on USB
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 754efaa..685f7c9 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -75,6 +75,5 @@ obj-$(CONFIG_USB_FSL_MPH_DR_OF)	+= fsl-mph-dr-of.o
 obj-$(CONFIG_USB_EHCI_FSL)	+= ehci-fsl.o
 obj-$(CONFIG_USB_HCD_BCMA)	+= bcma-hcd.o
 obj-$(CONFIG_USB_HCD_SSB)	+= ssb-hcd.o
-obj-$(CONFIG_USB_FUSBH200_HCD)	+= fusbh200-hcd.o
 obj-$(CONFIG_USB_FOTG210_HCD)	+= fotg210-hcd.o
 obj-$(CONFIG_USB_MAX3421_HCD)	+= max3421-hcd.o
diff --git a/drivers/usb/host/fusbh200-hcd.c b/drivers/usb/host/fusbh200-hcd.c
deleted file mode 100644
index 1fd8718..0000000
--- a/drivers/usb/host/fusbh200-hcd.c
+++ /dev/null
@@ -1,5894 +0,0 @@
-/*
- * Faraday FUSBH200 EHCI-like driver
- *
- * Copyright (c) 2013 Faraday Technology Corporation
- *
- * Author: Yuan-Hsin Chen <yhchen@faraday-tech.com>
- * 	   Feng-Hsin Chiang <john453@faraday-tech.com>
- * 	   Po-Yu Chuang <ratbert.chuang@gmail.com>
- *
- * Most of code borrowed from the Linux-3.7 EHCI driver
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * 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.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/dmapool.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/vmalloc.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/hrtimer.h>
-#include <linux/list.h>
-#include <linux/interrupt.h>
-#include <linux/usb.h>
-#include <linux/usb/hcd.h>
-#include <linux/moduleparam.h>
-#include <linux/dma-mapping.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/platform_device.h>
-
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/unaligned.h>
-
-/*-------------------------------------------------------------------------*/
-#define DRIVER_AUTHOR "Yuan-Hsin Chen"
-#define DRIVER_DESC "FUSBH200 Host Controller (EHCI) Driver"
-
-static const char	hcd_name [] = "fusbh200_hcd";
-
-#undef FUSBH200_URB_TRACE
-
-/* magic numbers that can affect system performance */
-#define	FUSBH200_TUNE_CERR		3	/* 0-3 qtd retries; 0 == don't stop */
-#define	FUSBH200_TUNE_RL_HS		4	/* nak throttle; see 4.9 */
-#define	FUSBH200_TUNE_RL_TT		0
-#define	FUSBH200_TUNE_MULT_HS	1	/* 1-3 transactions/uframe; 4.10.3 */
-#define	FUSBH200_TUNE_MULT_TT	1
-/*
- * Some drivers think it's safe to schedule isochronous transfers more than
- * 256 ms into the future (partly as a result of an old bug in the scheduling
- * code).  In an attempt to avoid trouble, we will use a minimum scheduling
- * length of 512 frames instead of 256.
- */
-#define	FUSBH200_TUNE_FLS		1	/* (medium) 512-frame schedule */
-
-/* Initial IRQ latency:  faster than hw default */
-static int log2_irq_thresh = 0;		// 0 to 6
-module_param (log2_irq_thresh, int, S_IRUGO);
-MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
-
-/* initial park setting:  slower than hw default */
-static unsigned park = 0;
-module_param (park, uint, S_IRUGO);
-MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets");
-
-/* for link power management(LPM) feature */
-static unsigned int hird;
-module_param(hird, int, S_IRUGO);
-MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
-
-#define	INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
-
-#include "fusbh200.h"
-
-/*-------------------------------------------------------------------------*/
-
-#define fusbh200_dbg(fusbh200, fmt, args...) \
-	dev_dbg (fusbh200_to_hcd(fusbh200)->self.controller , fmt , ## args )
-#define fusbh200_err(fusbh200, fmt, args...) \
-	dev_err (fusbh200_to_hcd(fusbh200)->self.controller , fmt , ## args )
-#define fusbh200_info(fusbh200, fmt, args...) \
-	dev_info (fusbh200_to_hcd(fusbh200)->self.controller , fmt , ## args )
-#define fusbh200_warn(fusbh200, fmt, args...) \
-	dev_warn (fusbh200_to_hcd(fusbh200)->self.controller , fmt , ## args )
-
-/* check the values in the HCSPARAMS register
- * (host controller _Structural_ parameters)
- * see EHCI spec, Table 2-4 for each value
- */
-static void dbg_hcs_params (struct fusbh200_hcd *fusbh200, char *label)
-{
-	u32	params = fusbh200_readl(fusbh200, &fusbh200->caps->hcs_params);
-
-	fusbh200_dbg (fusbh200,
-		"%s hcs_params 0x%x ports=%d\n",
-		label, params,
-		HCS_N_PORTS (params)
-		);
-}
-
-/* check the values in the HCCPARAMS register
- * (host controller _Capability_ parameters)
- * see EHCI Spec, Table 2-5 for each value
- * */
-static void dbg_hcc_params (struct fusbh200_hcd *fusbh200, char *label)
-{
-	u32	params = fusbh200_readl(fusbh200, &fusbh200->caps->hcc_params);
-
-	fusbh200_dbg (fusbh200,
-		"%s hcc_params %04x uframes %s%s\n",
-		label,
-		params,
-		HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
-		HCC_CANPARK(params) ? " park" : "");
-}
-
-static void __maybe_unused
-dbg_qtd (const char *label, struct fusbh200_hcd *fusbh200, struct fusbh200_qtd *qtd)
-{
-	fusbh200_dbg(fusbh200, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
-		hc32_to_cpup(fusbh200, &qtd->hw_next),
-		hc32_to_cpup(fusbh200, &qtd->hw_alt_next),
-		hc32_to_cpup(fusbh200, &qtd->hw_token),
-		hc32_to_cpup(fusbh200, &qtd->hw_buf [0]));
-	if (qtd->hw_buf [1])
-		fusbh200_dbg(fusbh200, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
-			hc32_to_cpup(fusbh200, &qtd->hw_buf[1]),
-			hc32_to_cpup(fusbh200, &qtd->hw_buf[2]),
-			hc32_to_cpup(fusbh200, &qtd->hw_buf[3]),
-			hc32_to_cpup(fusbh200, &qtd->hw_buf[4]));
-}
-
-static void __maybe_unused
-dbg_qh (const char *label, struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	struct fusbh200_qh_hw *hw = qh->hw;
-
-	fusbh200_dbg (fusbh200, "%s qh %p n%08x info %x %x qtd %x\n", label,
-		qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
-	dbg_qtd("overlay", fusbh200, (struct fusbh200_qtd *) &hw->hw_qtd_next);
-}
-
-static void __maybe_unused
-dbg_itd (const char *label, struct fusbh200_hcd *fusbh200, struct fusbh200_itd *itd)
-{
-	fusbh200_dbg (fusbh200, "%s [%d] itd %p, next %08x, urb %p\n",
-		label, itd->frame, itd, hc32_to_cpu(fusbh200, itd->hw_next),
-		itd->urb);
-	fusbh200_dbg (fusbh200,
-		"  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
-		hc32_to_cpu(fusbh200, itd->hw_transaction[0]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[1]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[2]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[3]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[4]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[5]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[6]),
-		hc32_to_cpu(fusbh200, itd->hw_transaction[7]));
-	fusbh200_dbg (fusbh200,
-		"  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
-		hc32_to_cpu(fusbh200, itd->hw_bufp[0]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[1]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[2]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[3]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[4]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[5]),
-		hc32_to_cpu(fusbh200, itd->hw_bufp[6]));
-	fusbh200_dbg (fusbh200, "  index: %d %d %d %d %d %d %d %d\n",
-		itd->index[0], itd->index[1], itd->index[2],
-		itd->index[3], itd->index[4], itd->index[5],
-		itd->index[6], itd->index[7]);
-}
-
-static int __maybe_unused
-dbg_status_buf (char *buf, unsigned len, const char *label, u32 status)
-{
-	return scnprintf (buf, len,
-		"%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
-		label, label [0] ? " " : "", status,
-		(status & STS_ASS) ? " Async" : "",
-		(status & STS_PSS) ? " Periodic" : "",
-		(status & STS_RECL) ? " Recl" : "",
-		(status & STS_HALT) ? " Halt" : "",
-		(status & STS_IAA) ? " IAA" : "",
-		(status & STS_FATAL) ? " FATAL" : "",
-		(status & STS_FLR) ? " FLR" : "",
-		(status & STS_PCD) ? " PCD" : "",
-		(status & STS_ERR) ? " ERR" : "",
-		(status & STS_INT) ? " INT" : ""
-		);
-}
-
-static int __maybe_unused
-dbg_intr_buf (char *buf, unsigned len, const char *label, u32 enable)
-{
-	return scnprintf (buf, len,
-		"%s%sintrenable %02x%s%s%s%s%s%s",
-		label, label [0] ? " " : "", enable,
-		(enable & STS_IAA) ? " IAA" : "",
-		(enable & STS_FATAL) ? " FATAL" : "",
-		(enable & STS_FLR) ? " FLR" : "",
-		(enable & STS_PCD) ? " PCD" : "",
-		(enable & STS_ERR) ? " ERR" : "",
-		(enable & STS_INT) ? " INT" : ""
-		);
-}
-
-static const char *const fls_strings [] =
-    { "1024", "512", "256", "??" };
-
-static int
-dbg_command_buf (char *buf, unsigned len, const char *label, u32 command)
-{
-	return scnprintf (buf, len,
-		"%s%scommand %07x %s=%d ithresh=%d%s%s%s "
-		"period=%s%s %s",
-		label, label [0] ? " " : "", command,
-		(command & CMD_PARK) ? " park" : "(park)",
-		CMD_PARK_CNT (command),
-		(command >> 16) & 0x3f,
-		(command & CMD_IAAD) ? " IAAD" : "",
-		(command & CMD_ASE) ? " Async" : "",
-		(command & CMD_PSE) ? " Periodic" : "",
-		fls_strings [(command >> 2) & 0x3],
-		(command & CMD_RESET) ? " Reset" : "",
-		(command & CMD_RUN) ? "RUN" : "HALT"
-		);
-}
-
-static int
-dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)
-{
-	char	*sig;
-
-	/* signaling state */
-	switch (status & (3 << 10)) {
-	case 0 << 10: sig = "se0"; break;
-	case 1 << 10: sig = "k"; break;		/* low speed */
-	case 2 << 10: sig = "j"; break;
-	default: sig = "?"; break;
-	}
-
-	return scnprintf (buf, len,
-		"%s%sport:%d status %06x %d "
-		"sig=%s%s%s%s%s%s%s%s",
-		label, label [0] ? " " : "", port, status,
-		status>>25,/*device address */
-		sig,
-		(status & PORT_RESET) ? " RESET" : "",
-		(status & PORT_SUSPEND) ? " SUSPEND" : "",
-		(status & PORT_RESUME) ? " RESUME" : "",
-		(status & PORT_PEC) ? " PEC" : "",
-		(status & PORT_PE) ? " PE" : "",
-		(status & PORT_CSC) ? " CSC" : "",
-		(status & PORT_CONNECT) ? " CONNECT" : "");
-}
-
-/* functions have the "wrong" filename when they're output... */
-#define dbg_status(fusbh200, label, status) { \
-	char _buf [80]; \
-	dbg_status_buf (_buf, sizeof _buf, label, status); \
-	fusbh200_dbg (fusbh200, "%s\n", _buf); \
-}
-
-#define dbg_cmd(fusbh200, label, command) { \
-	char _buf [80]; \
-	dbg_command_buf (_buf, sizeof _buf, label, command); \
-	fusbh200_dbg (fusbh200, "%s\n", _buf); \
-}
-
-#define dbg_port(fusbh200, label, port, status) { \
-	char _buf [80]; \
-	dbg_port_buf (_buf, sizeof _buf, label, port, status); \
-	fusbh200_dbg (fusbh200, "%s\n", _buf); \
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* troubleshooting help: expose state in debugfs */
-
-static int debug_async_open(struct inode *, struct file *);
-static int debug_periodic_open(struct inode *, struct file *);
-static int debug_registers_open(struct inode *, struct file *);
-static int debug_async_open(struct inode *, struct file *);
-
-static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
-static int debug_close(struct inode *, struct file *);
-
-static const struct file_operations debug_async_fops = {
-	.owner		= THIS_MODULE,
-	.open		= debug_async_open,
-	.read		= debug_output,
-	.release	= debug_close,
-	.llseek		= default_llseek,
-};
-static const struct file_operations debug_periodic_fops = {
-	.owner		= THIS_MODULE,
-	.open		= debug_periodic_open,
-	.read		= debug_output,
-	.release	= debug_close,
-	.llseek		= default_llseek,
-};
-static const struct file_operations debug_registers_fops = {
-	.owner		= THIS_MODULE,
-	.open		= debug_registers_open,
-	.read		= debug_output,
-	.release	= debug_close,
-	.llseek		= default_llseek,
-};
-
-static struct dentry *fusbh200_debug_root;
-
-struct debug_buffer {
-	ssize_t (*fill_func)(struct debug_buffer *);	/* fill method */
-	struct usb_bus *bus;
-	struct mutex mutex;	/* protect filling of buffer */
-	size_t count;		/* number of characters filled into buffer */
-	char *output_buf;
-	size_t alloc_size;
-};
-
-#define speed_char(info1) ({ char tmp; \
-		switch (info1 & (3 << 12)) { \
-		case QH_FULL_SPEED: tmp = 'f'; break; \
-		case QH_LOW_SPEED:  tmp = 'l'; break; \
-		case QH_HIGH_SPEED: tmp = 'h'; break; \
-		default: tmp = '?'; break; \
-		} tmp; })
-
-static inline char token_mark(struct fusbh200_hcd *fusbh200, __hc32 token)
-{
-	__u32 v = hc32_to_cpu(fusbh200, token);
-
-	if (v & QTD_STS_ACTIVE)
-		return '*';
-	if (v & QTD_STS_HALT)
-		return '-';
-	if (!IS_SHORT_READ (v))
-		return ' ';
-	/* tries to advance through hw_alt_next */
-	return '/';
-}
-
-static void qh_lines (
-	struct fusbh200_hcd *fusbh200,
-	struct fusbh200_qh *qh,
-	char **nextp,
-	unsigned *sizep
-)
-{
-	u32			scratch;
-	u32			hw_curr;
-	struct fusbh200_qtd		*td;
-	unsigned		temp;
-	unsigned		size = *sizep;
-	char			*next = *nextp;
-	char			mark;
-	__le32			list_end = FUSBH200_LIST_END(fusbh200);
-	struct fusbh200_qh_hw	*hw = qh->hw;
-
-	if (hw->hw_qtd_next == list_end)	/* NEC does this */
-		mark = '@';
-	else
-		mark = token_mark(fusbh200, hw->hw_token);
-	if (mark == '/') {	/* qh_alt_next controls qh advance? */
-		if ((hw->hw_alt_next & QTD_MASK(fusbh200))
-				== fusbh200->async->hw->hw_alt_next)
-			mark = '#';	/* blocked */
-		else if (hw->hw_alt_next == list_end)
-			mark = '.';	/* use hw_qtd_next */
-		/* else alt_next points to some other qtd */
-	}
-	scratch = hc32_to_cpup(fusbh200, &hw->hw_info1);
-	hw_curr = (mark == '*') ? hc32_to_cpup(fusbh200, &hw->hw_current) : 0;
-	temp = scnprintf (next, size,
-			"qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)",
-			qh, scratch & 0x007f,
-			speed_char (scratch),
-			(scratch >> 8) & 0x000f,
-			scratch, hc32_to_cpup(fusbh200, &hw->hw_info2),
-			hc32_to_cpup(fusbh200, &hw->hw_token), mark,
-			(cpu_to_hc32(fusbh200, QTD_TOGGLE) & hw->hw_token)
-				? "data1" : "data0",
-			(hc32_to_cpup(fusbh200, &hw->hw_alt_next) >> 1) & 0x0f);
-	size -= temp;
-	next += temp;
-
-	/* hc may be modifying the list as we read it ... */
-	list_for_each_entry(td, &qh->qtd_list, qtd_list) {
-		scratch = hc32_to_cpup(fusbh200, &td->hw_token);
-		mark = ' ';
-		if (hw_curr == td->qtd_dma)
-			mark = '*';
-		else if (hw->hw_qtd_next == cpu_to_hc32(fusbh200, td->qtd_dma))
-			mark = '+';
-		else if (QTD_LENGTH (scratch)) {
-			if (td->hw_alt_next == fusbh200->async->hw->hw_alt_next)
-				mark = '#';
-			else if (td->hw_alt_next != list_end)
-				mark = '/';
-		}
-		temp = snprintf (next, size,
-				"\n\t%p%c%s len=%d %08x urb %p",
-				td, mark, ({ char *tmp;
-				 switch ((scratch>>8)&0x03) {
-				 case 0: tmp = "out"; break;
-				 case 1: tmp = "in"; break;
-				 case 2: tmp = "setup"; break;
-				 default: tmp = "?"; break;
-				 } tmp;}),
-				(scratch >> 16) & 0x7fff,
-				scratch,
-				td->urb);
-		if (size < temp)
-			temp = size;
-		size -= temp;
-		next += temp;
-		if (temp == size)
-			goto done;
-	}
-
-	temp = snprintf (next, size, "\n");
-	if (size < temp)
-		temp = size;
-	size -= temp;
-	next += temp;
-
-done:
-	*sizep = size;
-	*nextp = next;
-}
-
-static ssize_t fill_async_buffer(struct debug_buffer *buf)
-{
-	struct usb_hcd		*hcd;
-	struct fusbh200_hcd	*fusbh200;
-	unsigned long		flags;
-	unsigned		temp, size;
-	char			*next;
-	struct fusbh200_qh		*qh;
-
-	hcd = bus_to_hcd(buf->bus);
-	fusbh200 = hcd_to_fusbh200 (hcd);
-	next = buf->output_buf;
-	size = buf->alloc_size;
-
-	*next = 0;
-
-	/* dumps a snapshot of the async schedule.
-	 * usually empty except for long-term bulk reads, or head.
-	 * one QH per line, and TDs we know about
-	 */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	for (qh = fusbh200->async->qh_next.qh; size > 0 && qh; qh = qh->qh_next.qh)
-		qh_lines (fusbh200, qh, &next, &size);
-	if (fusbh200->async_unlink && size > 0) {
-		temp = scnprintf(next, size, "\nunlink =\n");
-		size -= temp;
-		next += temp;
-
-		for (qh = fusbh200->async_unlink; size > 0 && qh;
-				qh = qh->unlink_next)
-			qh_lines (fusbh200, qh, &next, &size);
-	}
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-
-	return strlen(buf->output_buf);
-}
-
-#define DBG_SCHED_LIMIT 64
-static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
-{
-	struct usb_hcd		*hcd;
-	struct fusbh200_hcd		*fusbh200;
-	unsigned long		flags;
-	union fusbh200_shadow	p, *seen;
-	unsigned		temp, size, seen_count;
-	char			*next;
-	unsigned		i;
-	__hc32			tag;
-
-	seen = kmalloc(DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC);
-	if (!seen)
-		return 0;
-	seen_count = 0;
-
-	hcd = bus_to_hcd(buf->bus);
-	fusbh200 = hcd_to_fusbh200 (hcd);
-	next = buf->output_buf;
-	size = buf->alloc_size;
-
-	temp = scnprintf (next, size, "size = %d\n", fusbh200->periodic_size);
-	size -= temp;
-	next += temp;
-
-	/* dump a snapshot of the periodic schedule.
-	 * iso changes, interrupt usually doesn't.
-	 */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	for (i = 0; i < fusbh200->periodic_size; i++) {
-		p = fusbh200->pshadow [i];
-		if (likely (!p.ptr))
-			continue;
-		tag = Q_NEXT_TYPE(fusbh200, fusbh200->periodic [i]);
-
-		temp = scnprintf (next, size, "%4d: ", i);
-		size -= temp;
-		next += temp;
-
-		do {
-			struct fusbh200_qh_hw *hw;
-
-			switch (hc32_to_cpu(fusbh200, tag)) {
-			case Q_TYPE_QH:
-				hw = p.qh->hw;
-				temp = scnprintf (next, size, " qh%d-%04x/%p",
-						p.qh->period,
-						hc32_to_cpup(fusbh200,
-							&hw->hw_info2)
-							/* uframe masks */
-							& (QH_CMASK | QH_SMASK),
-						p.qh);
-				size -= temp;
-				next += temp;
-				/* don't repeat what follows this qh */
-				for (temp = 0; temp < seen_count; temp++) {
-					if (seen [temp].ptr != p.ptr)
-						continue;
-					if (p.qh->qh_next.ptr) {
-						temp = scnprintf (next, size,
-							" ...");
-						size -= temp;
-						next += temp;
-					}
-					break;
-				}
-				/* show more info the first time around */
-				if (temp == seen_count) {
-					u32	scratch = hc32_to_cpup(fusbh200,
-							&hw->hw_info1);
-					struct fusbh200_qtd	*qtd;
-					char		*type = "";
-
-					/* count tds, get ep direction */
-					temp = 0;
-					list_for_each_entry (qtd,
-							&p.qh->qtd_list,
-							qtd_list) {
-						temp++;
-						switch (0x03 & (hc32_to_cpu(
-							fusbh200,
-							qtd->hw_token) >> 8)) {
-						case 0: type = "out"; continue;
-						case 1: type = "in"; continue;
-						}
-					}
-
-					temp = scnprintf (next, size,
-						" (%c%d ep%d%s "
-						"[%d/%d] q%d p%d)",
-						speed_char (scratch),
-						scratch & 0x007f,
-						(scratch >> 8) & 0x000f, type,
-						p.qh->usecs, p.qh->c_usecs,
-						temp,
-						0x7ff & (scratch >> 16));
-
-					if (seen_count < DBG_SCHED_LIMIT)
-						seen [seen_count++].qh = p.qh;
-				} else
-					temp = 0;
-				tag = Q_NEXT_TYPE(fusbh200, hw->hw_next);
-				p = p.qh->qh_next;
-				break;
-			case Q_TYPE_FSTN:
-				temp = scnprintf (next, size,
-					" fstn-%8x/%p", p.fstn->hw_prev,
-					p.fstn);
-				tag = Q_NEXT_TYPE(fusbh200, p.fstn->hw_next);
-				p = p.fstn->fstn_next;
-				break;
-			case Q_TYPE_ITD:
-				temp = scnprintf (next, size,
-					" itd/%p", p.itd);
-				tag = Q_NEXT_TYPE(fusbh200, p.itd->hw_next);
-				p = p.itd->itd_next;
-				break;
-			}
-			size -= temp;
-			next += temp;
-		} while (p.ptr);
-
-		temp = scnprintf (next, size, "\n");
-		size -= temp;
-		next += temp;
-	}
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	kfree (seen);
-
-	return buf->alloc_size - size;
-}
-#undef DBG_SCHED_LIMIT
-
-static const char *rh_state_string(struct fusbh200_hcd *fusbh200)
-{
-	switch (fusbh200->rh_state) {
-	case FUSBH200_RH_HALTED:
-		return "halted";
-	case FUSBH200_RH_SUSPENDED:
-		return "suspended";
-	case FUSBH200_RH_RUNNING:
-		return "running";
-	case FUSBH200_RH_STOPPING:
-		return "stopping";
-	}
-	return "?";
-}
-
-static ssize_t fill_registers_buffer(struct debug_buffer *buf)
-{
-	struct usb_hcd		*hcd;
-	struct fusbh200_hcd	*fusbh200;
-	unsigned long		flags;
-	unsigned		temp, size, i;
-	char			*next, scratch [80];
-	static char		fmt [] = "%*s\n";
-	static char		label [] = "";
-
-	hcd = bus_to_hcd(buf->bus);
-	fusbh200 = hcd_to_fusbh200 (hcd);
-	next = buf->output_buf;
-	size = buf->alloc_size;
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-
-	if (!HCD_HW_ACCESSIBLE(hcd)) {
-		size = scnprintf (next, size,
-			"bus %s, device %s\n"
-			"%s\n"
-			"SUSPENDED (no register access)\n",
-			hcd->self.controller->bus->name,
-			dev_name(hcd->self.controller),
-			hcd->product_desc);
-		goto done;
-	}
-
-	/* Capability Registers */
-	i = HC_VERSION(fusbh200, fusbh200_readl(fusbh200, &fusbh200->caps->hc_capbase));
-	temp = scnprintf (next, size,
-		"bus %s, device %s\n"
-		"%s\n"
-		"EHCI %x.%02x, rh state %s\n",
-		hcd->self.controller->bus->name,
-		dev_name(hcd->self.controller),
-		hcd->product_desc,
-		i >> 8, i & 0x0ff, rh_state_string(fusbh200));
-	size -= temp;
-	next += temp;
-
-	// FIXME interpret both types of params
-	i = fusbh200_readl(fusbh200, &fusbh200->caps->hcs_params);
-	temp = scnprintf (next, size, "structural params 0x%08x\n", i);
-	size -= temp;
-	next += temp;
-
-	i = fusbh200_readl(fusbh200, &fusbh200->caps->hcc_params);
-	temp = scnprintf (next, size, "capability params 0x%08x\n", i);
-	size -= temp;
-	next += temp;
-
-	/* Operational Registers */
-	temp = dbg_status_buf (scratch, sizeof scratch, label,
-			fusbh200_readl(fusbh200, &fusbh200->regs->status));
-	temp = scnprintf (next, size, fmt, temp, scratch);
-	size -= temp;
-	next += temp;
-
-	temp = dbg_command_buf (scratch, sizeof scratch, label,
-			fusbh200_readl(fusbh200, &fusbh200->regs->command));
-	temp = scnprintf (next, size, fmt, temp, scratch);
-	size -= temp;
-	next += temp;
-
-	temp = dbg_intr_buf (scratch, sizeof scratch, label,
-			fusbh200_readl(fusbh200, &fusbh200->regs->intr_enable));
-	temp = scnprintf (next, size, fmt, temp, scratch);
-	size -= temp;
-	next += temp;
-
-	temp = scnprintf (next, size, "uframe %04x\n",
-			fusbh200_read_frame_index(fusbh200));
-	size -= temp;
-	next += temp;
-
-	if (fusbh200->async_unlink) {
-		temp = scnprintf(next, size, "async unlink qh %p\n",
-				fusbh200->async_unlink);
-		size -= temp;
-		next += temp;
-	}
-
-	temp = scnprintf (next, size,
-		"irq normal %ld err %ld iaa %ld (lost %ld)\n",
-		fusbh200->stats.normal, fusbh200->stats.error, fusbh200->stats.iaa,
-		fusbh200->stats.lost_iaa);
-	size -= temp;
-	next += temp;
-
-	temp = scnprintf (next, size, "complete %ld unlink %ld\n",
-		fusbh200->stats.complete, fusbh200->stats.unlink);
-	size -= temp;
-	next += temp;
-
-done:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-
-	return buf->alloc_size - size;
-}
-
-static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
-				ssize_t (*fill_func)(struct debug_buffer *))
-{
-	struct debug_buffer *buf;
-
-	buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL);
-
-	if (buf) {
-		buf->bus = bus;
-		buf->fill_func = fill_func;
-		mutex_init(&buf->mutex);
-		buf->alloc_size = PAGE_SIZE;
-	}
-
-	return buf;
-}
-
-static int fill_buffer(struct debug_buffer *buf)
-{
-	int ret = 0;
-
-	if (!buf->output_buf)
-		buf->output_buf = vmalloc(buf->alloc_size);
-
-	if (!buf->output_buf) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	ret = buf->fill_func(buf);
-
-	if (ret >= 0) {
-		buf->count = ret;
-		ret = 0;
-	}
-
-out:
-	return ret;
-}
-
-static ssize_t debug_output(struct file *file, char __user *user_buf,
-			    size_t len, loff_t *offset)
-{
-	struct debug_buffer *buf = file->private_data;
-	int ret = 0;
-
-	mutex_lock(&buf->mutex);
-	if (buf->count == 0) {
-		ret = fill_buffer(buf);
-		if (ret != 0) {
-			mutex_unlock(&buf->mutex);
-			goto out;
-		}
-	}
-	mutex_unlock(&buf->mutex);
-
-	ret = simple_read_from_buffer(user_buf, len, offset,
-				      buf->output_buf, buf->count);
-
-out:
-	return ret;
-
-}
-
-static int debug_close(struct inode *inode, struct file *file)
-{
-	struct debug_buffer *buf = file->private_data;
-
-	if (buf) {
-		vfree(buf->output_buf);
-		kfree(buf);
-	}
-
-	return 0;
-}
-static int debug_async_open(struct inode *inode, struct file *file)
-{
-	file->private_data = alloc_buffer(inode->i_private, fill_async_buffer);
-
-	return file->private_data ? 0 : -ENOMEM;
-}
-
-static int debug_periodic_open(struct inode *inode, struct file *file)
-{
-	struct debug_buffer *buf;
-	buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
-	if (!buf)
-		return -ENOMEM;
-
-	buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8)*PAGE_SIZE;
-	file->private_data = buf;
-	return 0;
-}
-
-static int debug_registers_open(struct inode *inode, struct file *file)
-{
-	file->private_data = alloc_buffer(inode->i_private,
-					  fill_registers_buffer);
-
-	return file->private_data ? 0 : -ENOMEM;
-}
-
-static inline void create_debug_files (struct fusbh200_hcd *fusbh200)
-{
-	struct usb_bus *bus = &fusbh200_to_hcd(fusbh200)->self;
-
-	fusbh200->debug_dir = debugfs_create_dir(bus->bus_name, fusbh200_debug_root);
-	if (!fusbh200->debug_dir)
-		return;
-
-	if (!debugfs_create_file("async", S_IRUGO, fusbh200->debug_dir, bus,
-						&debug_async_fops))
-		goto file_error;
-
-	if (!debugfs_create_file("periodic", S_IRUGO, fusbh200->debug_dir, bus,
-						&debug_periodic_fops))
-		goto file_error;
-
-	if (!debugfs_create_file("registers", S_IRUGO, fusbh200->debug_dir, bus,
-						    &debug_registers_fops))
-		goto file_error;
-
-	return;
-
-file_error:
-	debugfs_remove_recursive(fusbh200->debug_dir);
-}
-
-static inline void remove_debug_files (struct fusbh200_hcd *fusbh200)
-{
-	debugfs_remove_recursive(fusbh200->debug_dir);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * handshake - spin reading hc until handshake completes or fails
- * @ptr: address of hc register to be read
- * @mask: bits to look at in result of read
- * @done: value of those bits when handshake succeeds
- * @usec: timeout in microseconds
- *
- * Returns negative errno, or zero on success
- *
- * Success happens when the "mask" bits have the specified value (hardware
- * handshake done).  There are two failure modes:  "usec" have passed (major
- * hardware flakeout), or the register reads as all-ones (hardware removed).
- *
- * That last failure should_only happen in cases like physical cardbus eject
- * before driver shutdown. But it also seems to be caused by bugs in cardbus
- * bridge shutdown:  shutting down the bridge before the devices using it.
- */
-static int handshake (struct fusbh200_hcd *fusbh200, void __iomem *ptr,
-		      u32 mask, u32 done, int usec)
-{
-	u32	result;
-
-	do {
-		result = fusbh200_readl(fusbh200, ptr);
-		if (result == ~(u32)0)		/* card removed */
-			return -ENODEV;
-		result &= mask;
-		if (result == done)
-			return 0;
-		udelay (1);
-		usec--;
-	} while (usec > 0);
-	return -ETIMEDOUT;
-}
-
-/*
- * Force HC to halt state from unknown (EHCI spec section 2.3).
- * Must be called with interrupts enabled and the lock not held.
- */
-static int fusbh200_halt (struct fusbh200_hcd *fusbh200)
-{
-	u32	temp;
-
-	spin_lock_irq(&fusbh200->lock);
-
-	/* disable any irqs left enabled by previous code */
-	fusbh200_writel(fusbh200, 0, &fusbh200->regs->intr_enable);
-
-	/*
-	 * This routine gets called during probe before fusbh200->command
-	 * has been initialized, so we can't rely on its value.
-	 */
-	fusbh200->command &= ~CMD_RUN;
-	temp = fusbh200_readl(fusbh200, &fusbh200->regs->command);
-	temp &= ~(CMD_RUN | CMD_IAAD);
-	fusbh200_writel(fusbh200, temp, &fusbh200->regs->command);
-
-	spin_unlock_irq(&fusbh200->lock);
-	synchronize_irq(fusbh200_to_hcd(fusbh200)->irq);
-
-	return handshake(fusbh200, &fusbh200->regs->status,
-			  STS_HALT, STS_HALT, 16 * 125);
-}
-
-/*
- * Reset a non-running (STS_HALT == 1) controller.
- * Must be called with interrupts enabled and the lock not held.
- */
-static int fusbh200_reset (struct fusbh200_hcd *fusbh200)
-{
-	int	retval;
-	u32	command = fusbh200_readl(fusbh200, &fusbh200->regs->command);
-
-	/* If the EHCI debug controller is active, special care must be
-	 * taken before and after a host controller reset */
-	if (fusbh200->debug && !dbgp_reset_prep(fusbh200_to_hcd(fusbh200)))
-		fusbh200->debug = NULL;
-
-	command |= CMD_RESET;
-	dbg_cmd (fusbh200, "reset", command);
-	fusbh200_writel(fusbh200, command, &fusbh200->regs->command);
-	fusbh200->rh_state = FUSBH200_RH_HALTED;
-	fusbh200->next_statechange = jiffies;
-	retval = handshake (fusbh200, &fusbh200->regs->command,
-			    CMD_RESET, 0, 250 * 1000);
-
-	if (retval)
-		return retval;
-
-	if (fusbh200->debug)
-		dbgp_external_startup(fusbh200_to_hcd(fusbh200));
-
-	fusbh200->port_c_suspend = fusbh200->suspended_ports =
-			fusbh200->resuming_ports = 0;
-	return retval;
-}
-
-/*
- * Idle the controller (turn off the schedules).
- * Must be called with interrupts enabled and the lock not held.
- */
-static void fusbh200_quiesce (struct fusbh200_hcd *fusbh200)
-{
-	u32	temp;
-
-	if (fusbh200->rh_state != FUSBH200_RH_RUNNING)
-		return;
-
-	/* wait for any schedule enables/disables to take effect */
-	temp = (fusbh200->command << 10) & (STS_ASS | STS_PSS);
-	handshake(fusbh200, &fusbh200->regs->status, STS_ASS | STS_PSS, temp, 16 * 125);
-
-	/* then disable anything that's still active */
-	spin_lock_irq(&fusbh200->lock);
-	fusbh200->command &= ~(CMD_ASE | CMD_PSE);
-	fusbh200_writel(fusbh200, fusbh200->command, &fusbh200->regs->command);
-	spin_unlock_irq(&fusbh200->lock);
-
-	/* hardware can take 16 microframes to turn off ... */
-	handshake(fusbh200, &fusbh200->regs->status, STS_ASS | STS_PSS, 0, 16 * 125);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void end_unlink_async(struct fusbh200_hcd *fusbh200);
-static void unlink_empty_async(struct fusbh200_hcd *fusbh200);
-static void fusbh200_work(struct fusbh200_hcd *fusbh200);
-static void start_unlink_intr(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh);
-static void end_unlink_intr(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh);
-
-/*-------------------------------------------------------------------------*/
-
-/* Set a bit in the USBCMD register */
-static void fusbh200_set_command_bit(struct fusbh200_hcd *fusbh200, u32 bit)
-{
-	fusbh200->command |= bit;
-	fusbh200_writel(fusbh200, fusbh200->command, &fusbh200->regs->command);
-
-	/* unblock posted write */
-	fusbh200_readl(fusbh200, &fusbh200->regs->command);
-}
-
-/* Clear a bit in the USBCMD register */
-static void fusbh200_clear_command_bit(struct fusbh200_hcd *fusbh200, u32 bit)
-{
-	fusbh200->command &= ~bit;
-	fusbh200_writel(fusbh200, fusbh200->command, &fusbh200->regs->command);
-
-	/* unblock posted write */
-	fusbh200_readl(fusbh200, &fusbh200->regs->command);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI timer support...  Now using hrtimers.
- *
- * Lots of different events are triggered from fusbh200->hrtimer.  Whenever
- * the timer routine runs, it checks each possible event; events that are
- * currently enabled and whose expiration time has passed get handled.
- * The set of enabled events is stored as a collection of bitflags in
- * fusbh200->enabled_hrtimer_events, and they are numbered in order of
- * increasing delay values (ranging between 1 ms and 100 ms).
- *
- * Rather than implementing a sorted list or tree of all pending events,
- * we keep track only of the lowest-numbered pending event, in
- * fusbh200->next_hrtimer_event.  Whenever fusbh200->hrtimer gets restarted, its
- * expiration time is set to the timeout value for this event.
- *
- * As a result, events might not get handled right away; the actual delay
- * could be anywhere up to twice the requested delay.  This doesn't
- * matter, because none of the events are especially time-critical.  The
- * ones that matter most all have a delay of 1 ms, so they will be
- * handled after 2 ms at most, which is okay.  In addition to this, we
- * allow for an expiration range of 1 ms.
- */
-
-/*
- * Delay lengths for the hrtimer event types.
- * Keep this list sorted by delay length, in the same order as
- * the event types indexed by enum fusbh200_hrtimer_event in fusbh200.h.
- */
-static unsigned event_delays_ns[] = {
-	1 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_POLL_ASS */
-	1 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_POLL_PSS */
-	1 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_POLL_DEAD */
-	1125 * NSEC_PER_USEC,	/* FUSBH200_HRTIMER_UNLINK_INTR */
-	2 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_FREE_ITDS */
-	6 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_ASYNC_UNLINKS */
-	10 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_IAA_WATCHDOG */
-	10 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_DISABLE_PERIODIC */
-	15 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_DISABLE_ASYNC */
-	100 * NSEC_PER_MSEC,	/* FUSBH200_HRTIMER_IO_WATCHDOG */
-};
-
-/* Enable a pending hrtimer event */
-static void fusbh200_enable_event(struct fusbh200_hcd *fusbh200, unsigned event,
-		bool resched)
-{
-	ktime_t		*timeout = &fusbh200->hr_timeouts[event];
-
-	if (resched)
-		*timeout = ktime_add(ktime_get(),
-				ktime_set(0, event_delays_ns[event]));
-	fusbh200->enabled_hrtimer_events |= (1 << event);
-
-	/* Track only the lowest-numbered pending event */
-	if (event < fusbh200->next_hrtimer_event) {
-		fusbh200->next_hrtimer_event = event;
-		hrtimer_start_range_ns(&fusbh200->hrtimer, *timeout,
-				NSEC_PER_MSEC, HRTIMER_MODE_ABS);
-	}
-}
-
-
-/* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */
-static void fusbh200_poll_ASS(struct fusbh200_hcd *fusbh200)
-{
-	unsigned	actual, want;
-
-	/* Don't enable anything if the controller isn't running (e.g., died) */
-	if (fusbh200->rh_state != FUSBH200_RH_RUNNING)
-		return;
-
-	want = (fusbh200->command & CMD_ASE) ? STS_ASS : 0;
-	actual = fusbh200_readl(fusbh200, &fusbh200->regs->status) & STS_ASS;
-
-	if (want != actual) {
-
-		/* Poll again later, but give up after about 20 ms */
-		if (fusbh200->ASS_poll_count++ < 20) {
-			fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_POLL_ASS, true);
-			return;
-		}
-		fusbh200_dbg(fusbh200, "Waited too long for the async schedule status (%x/%x), giving up\n",
-				want, actual);
-	}
-	fusbh200->ASS_poll_count = 0;
-
-	/* The status is up-to-date; restart or stop the schedule as needed */
-	if (want == 0) {	/* Stopped */
-		if (fusbh200->async_count > 0)
-			fusbh200_set_command_bit(fusbh200, CMD_ASE);
-
-	} else {		/* Running */
-		if (fusbh200->async_count == 0) {
-
-			/* Turn off the schedule after a while */
-			fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_DISABLE_ASYNC,
-					true);
-		}
-	}
-}
-
-/* Turn off the async schedule after a brief delay */
-static void fusbh200_disable_ASE(struct fusbh200_hcd *fusbh200)
-{
-	fusbh200_clear_command_bit(fusbh200, CMD_ASE);
-}
-
-
-/* Poll the STS_PSS status bit; see when it agrees with CMD_PSE */
-static void fusbh200_poll_PSS(struct fusbh200_hcd *fusbh200)
-{
-	unsigned	actual, want;
-
-	/* Don't do anything if the controller isn't running (e.g., died) */
-	if (fusbh200->rh_state != FUSBH200_RH_RUNNING)
-		return;
-
-	want = (fusbh200->command & CMD_PSE) ? STS_PSS : 0;
-	actual = fusbh200_readl(fusbh200, &fusbh200->regs->status) & STS_PSS;
-
-	if (want != actual) {
-
-		/* Poll again later, but give up after about 20 ms */
-		if (fusbh200->PSS_poll_count++ < 20) {
-			fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_POLL_PSS, true);
-			return;
-		}
-		fusbh200_dbg(fusbh200, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
-				want, actual);
-	}
-	fusbh200->PSS_poll_count = 0;
-
-	/* The status is up-to-date; restart or stop the schedule as needed */
-	if (want == 0) {	/* Stopped */
-		if (fusbh200->periodic_count > 0)
-			fusbh200_set_command_bit(fusbh200, CMD_PSE);
-
-	} else {		/* Running */
-		if (fusbh200->periodic_count == 0) {
-
-			/* Turn off the schedule after a while */
-			fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_DISABLE_PERIODIC,
-					true);
-		}
-	}
-}
-
-/* Turn off the periodic schedule after a brief delay */
-static void fusbh200_disable_PSE(struct fusbh200_hcd *fusbh200)
-{
-	fusbh200_clear_command_bit(fusbh200, CMD_PSE);
-}
-
-
-/* Poll the STS_HALT status bit; see when a dead controller stops */
-static void fusbh200_handle_controller_death(struct fusbh200_hcd *fusbh200)
-{
-	if (!(fusbh200_readl(fusbh200, &fusbh200->regs->status) & STS_HALT)) {
-
-		/* Give up after a few milliseconds */
-		if (fusbh200->died_poll_count++ < 5) {
-			/* Try again later */
-			fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_POLL_DEAD, true);
-			return;
-		}
-		fusbh200_warn(fusbh200, "Waited too long for the controller to stop, giving up\n");
-	}
-
-	/* Clean up the mess */
-	fusbh200->rh_state = FUSBH200_RH_HALTED;
-	fusbh200_writel(fusbh200, 0, &fusbh200->regs->intr_enable);
-	fusbh200_work(fusbh200);
-	end_unlink_async(fusbh200);
-
-	/* Not in process context, so don't try to reset the controller */
-}
-
-
-/* Handle unlinked interrupt QHs once they are gone from the hardware */
-static void fusbh200_handle_intr_unlinks(struct fusbh200_hcd *fusbh200)
-{
-	bool		stopped = (fusbh200->rh_state < FUSBH200_RH_RUNNING);
-
-	/*
-	 * Process all the QHs on the intr_unlink list that were added
-	 * before the current unlink cycle began.  The list is in
-	 * temporal order, so stop when we reach the first entry in the
-	 * current cycle.  But if the root hub isn't running then
-	 * process all the QHs on the list.
-	 */
-	fusbh200->intr_unlinking = true;
-	while (fusbh200->intr_unlink) {
-		struct fusbh200_qh	*qh = fusbh200->intr_unlink;
-
-		if (!stopped && qh->unlink_cycle == fusbh200->intr_unlink_cycle)
-			break;
-		fusbh200->intr_unlink = qh->unlink_next;
-		qh->unlink_next = NULL;
-		end_unlink_intr(fusbh200, qh);
-	}
-
-	/* Handle remaining entries later */
-	if (fusbh200->intr_unlink) {
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_UNLINK_INTR, true);
-		++fusbh200->intr_unlink_cycle;
-	}
-	fusbh200->intr_unlinking = false;
-}
-
-
-/* Start another free-iTDs/siTDs cycle */
-static void start_free_itds(struct fusbh200_hcd *fusbh200)
-{
-	if (!(fusbh200->enabled_hrtimer_events & BIT(FUSBH200_HRTIMER_FREE_ITDS))) {
-		fusbh200->last_itd_to_free = list_entry(
-				fusbh200->cached_itd_list.prev,
-				struct fusbh200_itd, itd_list);
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_FREE_ITDS, true);
-	}
-}
-
-/* Wait for controller to stop using old iTDs and siTDs */
-static void end_free_itds(struct fusbh200_hcd *fusbh200)
-{
-	struct fusbh200_itd		*itd, *n;
-
-	if (fusbh200->rh_state < FUSBH200_RH_RUNNING) {
-		fusbh200->last_itd_to_free = NULL;
-	}
-
-	list_for_each_entry_safe(itd, n, &fusbh200->cached_itd_list, itd_list) {
-		list_del(&itd->itd_list);
-		dma_pool_free(fusbh200->itd_pool, itd, itd->itd_dma);
-		if (itd == fusbh200->last_itd_to_free)
-			break;
-	}
-
-	if (!list_empty(&fusbh200->cached_itd_list))
-		start_free_itds(fusbh200);
-}
-
-
-/* Handle lost (or very late) IAA interrupts */
-static void fusbh200_iaa_watchdog(struct fusbh200_hcd *fusbh200)
-{
-	if (fusbh200->rh_state != FUSBH200_RH_RUNNING)
-		return;
-
-	/*
-	 * Lost IAA irqs wedge things badly; seen first with a vt8235.
-	 * So we need this watchdog, but must protect it against both
-	 * (a) SMP races against real IAA firing and retriggering, and
-	 * (b) clean HC shutdown, when IAA watchdog was pending.
-	 */
-	if (fusbh200->async_iaa) {
-		u32 cmd, status;
-
-		/* If we get here, IAA is *REALLY* late.  It's barely
-		 * conceivable that the system is so busy that CMD_IAAD
-		 * is still legitimately set, so let's be sure it's
-		 * clear before we read STS_IAA.  (The HC should clear
-		 * CMD_IAAD when it sets STS_IAA.)
-		 */
-		cmd = fusbh200_readl(fusbh200, &fusbh200->regs->command);
-
-		/*
-		 * If IAA is set here it either legitimately triggered
-		 * after the watchdog timer expired (_way_ late, so we'll
-		 * still count it as lost) ... or a silicon erratum:
-		 * - VIA seems to set IAA without triggering the IRQ;
-		 * - IAAD potentially cleared without setting IAA.
-		 */
-		status = fusbh200_readl(fusbh200, &fusbh200->regs->status);
-		if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
-			COUNT(fusbh200->stats.lost_iaa);
-			fusbh200_writel(fusbh200, STS_IAA, &fusbh200->regs->status);
-		}
-
-		fusbh200_dbg(fusbh200, "IAA watchdog: status %x cmd %x\n",
-				status, cmd);
-		end_unlink_async(fusbh200);
-	}
-}
-
-
-/* Enable the I/O watchdog, if appropriate */
-static void turn_on_io_watchdog(struct fusbh200_hcd *fusbh200)
-{
-	/* Not needed if the controller isn't running or it's already enabled */
-	if (fusbh200->rh_state != FUSBH200_RH_RUNNING ||
-			(fusbh200->enabled_hrtimer_events &
-				BIT(FUSBH200_HRTIMER_IO_WATCHDOG)))
-		return;
-
-	/*
-	 * Isochronous transfers always need the watchdog.
-	 * For other sorts we use it only if the flag is set.
-	 */
-	if (fusbh200->isoc_count > 0 || (fusbh200->need_io_watchdog &&
-			fusbh200->async_count + fusbh200->intr_count > 0))
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_IO_WATCHDOG, true);
-}
-
-
-/*
- * Handler functions for the hrtimer event types.
- * Keep this array in the same order as the event types indexed by
- * enum fusbh200_hrtimer_event in fusbh200.h.
- */
-static void (*event_handlers[])(struct fusbh200_hcd *) = {
-	fusbh200_poll_ASS,			/* FUSBH200_HRTIMER_POLL_ASS */
-	fusbh200_poll_PSS,			/* FUSBH200_HRTIMER_POLL_PSS */
-	fusbh200_handle_controller_death,	/* FUSBH200_HRTIMER_POLL_DEAD */
-	fusbh200_handle_intr_unlinks,	/* FUSBH200_HRTIMER_UNLINK_INTR */
-	end_free_itds,			/* FUSBH200_HRTIMER_FREE_ITDS */
-	unlink_empty_async,		/* FUSBH200_HRTIMER_ASYNC_UNLINKS */
-	fusbh200_iaa_watchdog,		/* FUSBH200_HRTIMER_IAA_WATCHDOG */
-	fusbh200_disable_PSE,		/* FUSBH200_HRTIMER_DISABLE_PERIODIC */
-	fusbh200_disable_ASE,		/* FUSBH200_HRTIMER_DISABLE_ASYNC */
-	fusbh200_work,			/* FUSBH200_HRTIMER_IO_WATCHDOG */
-};
-
-static enum hrtimer_restart fusbh200_hrtimer_func(struct hrtimer *t)
-{
-	struct fusbh200_hcd	*fusbh200 = container_of(t, struct fusbh200_hcd, hrtimer);
-	ktime_t		now;
-	unsigned long	events;
-	unsigned long	flags;
-	unsigned	e;
-
-	spin_lock_irqsave(&fusbh200->lock, flags);
-
-	events = fusbh200->enabled_hrtimer_events;
-	fusbh200->enabled_hrtimer_events = 0;
-	fusbh200->next_hrtimer_event = FUSBH200_HRTIMER_NO_EVENT;
-
-	/*
-	 * Check each pending event.  If its time has expired, handle
-	 * the event; otherwise re-enable it.
-	 */
-	now = ktime_get();
-	for_each_set_bit(e, &events, FUSBH200_HRTIMER_NUM_EVENTS) {
-		if (now.tv64 >= fusbh200->hr_timeouts[e].tv64)
-			event_handlers[e](fusbh200);
-		else
-			fusbh200_enable_event(fusbh200, e, false);
-	}
-
-	spin_unlock_irqrestore(&fusbh200->lock, flags);
-	return HRTIMER_NORESTART;
-}
-
-/*-------------------------------------------------------------------------*/
-
-#define fusbh200_bus_suspend	NULL
-#define fusbh200_bus_resume	NULL
-
-/*-------------------------------------------------------------------------*/
-
-static int check_reset_complete (
-	struct fusbh200_hcd	*fusbh200,
-	int		index,
-	u32 __iomem	*status_reg,
-	int		port_status
-) {
-	if (!(port_status & PORT_CONNECT))
-		return port_status;
-
-	/* if reset finished and it's still not enabled -- handoff */
-	if (!(port_status & PORT_PE)) {
-		/* with integrated TT, there's nobody to hand it to! */
-		fusbh200_dbg (fusbh200,
-			"Failed to enable port %d on root hub TT\n",
-			index+1);
-		return port_status;
-	} else {
-		fusbh200_dbg(fusbh200, "port %d reset complete, port enabled\n",
-			index + 1);
-	}
-
-	return port_status;
-}
-
-/*-------------------------------------------------------------------------*/
-
-
-/* build "status change" packet (one or two bytes) from HC registers */
-
-static int
-fusbh200_hub_status_data (struct usb_hcd *hcd, char *buf)
-{
-	struct fusbh200_hcd	*fusbh200 = hcd_to_fusbh200 (hcd);
-	u32		temp, status;
-	u32		mask;
-	int		retval = 1;
-	unsigned long	flags;
-
-	/* init status to no-changes */
-	buf [0] = 0;
-
-	/* Inform the core about resumes-in-progress by returning
-	 * a non-zero value even if there are no status changes.
-	 */
-	status = fusbh200->resuming_ports;
-
-	mask = PORT_CSC | PORT_PEC;
-	// PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND
-
-	/* no hub change reports (bit 0) for now (power, ...) */
-
-	/* port N changes (bit N)? */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-
-	temp = fusbh200_readl(fusbh200, &fusbh200->regs->port_status);
-
-	/*
-	 * Return status information even for ports with OWNER set.
-	 * Otherwise hub_wq wouldn't see the disconnect event when a
-	 * high-speed device is switched over to the companion
-	 * controller by the user.
-	 */
-
-	if ((temp & mask) != 0 || test_bit(0, &fusbh200->port_c_suspend)
-			|| (fusbh200->reset_done[0] && time_after_eq(
-				jiffies, fusbh200->reset_done[0]))) {
-		buf [0] |= 1 << 1;
-		status = STS_PCD;
-	}
-	/* FIXME autosuspend idle root hubs */
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	return status ? retval : 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void
-fusbh200_hub_descriptor (
-	struct fusbh200_hcd		*fusbh200,
-	struct usb_hub_descriptor	*desc
-) {
-	int		ports = HCS_N_PORTS (fusbh200->hcs_params);
-	u16		temp;
-
-	desc->bDescriptorType = USB_DT_HUB;
-	desc->bPwrOn2PwrGood = 10;	/* fusbh200 1.0, 2.3.9 says 20ms max */
-	desc->bHubContrCurrent = 0;
-
-	desc->bNbrPorts = ports;
-	temp = 1 + (ports / 8);
-	desc->bDescLength = 7 + 2 * temp;
-
-	/* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
-	memset(&desc->u.hs.DeviceRemovable[0], 0, temp);
-	memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp);
-
-	temp = HUB_CHAR_INDV_PORT_OCPM;	/* per-port overcurrent reporting */
-	temp |= HUB_CHAR_NO_LPSM;	/* no power switching */
-	desc->wHubCharacteristics = cpu_to_le16(temp);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int fusbh200_hub_control (
-	struct usb_hcd	*hcd,
-	u16		typeReq,
-	u16		wValue,
-	u16		wIndex,
-	char		*buf,
-	u16		wLength
-) {
-	struct fusbh200_hcd	*fusbh200 = hcd_to_fusbh200 (hcd);
-	int		ports = HCS_N_PORTS (fusbh200->hcs_params);
-	u32 __iomem	*status_reg = &fusbh200->regs->port_status;
-	u32		temp, temp1, status;
-	unsigned long	flags;
-	int		retval = 0;
-	unsigned	selector;
-
-	/*
-	 * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
-	 * HCS_INDICATOR may say we can change LEDs to off/amber/green.
-	 * (track current state ourselves) ... blink for diagnostics,
-	 * power, "this is the one", etc.  EHCI spec supports this.
-	 */
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	switch (typeReq) {
-	case ClearHubFeature:
-		switch (wValue) {
-		case C_HUB_LOCAL_POWER:
-		case C_HUB_OVER_CURRENT:
-			/* no hub-wide feature/status flags */
-			break;
-		default:
-			goto error;
-		}
-		break;
-	case ClearPortFeature:
-		if (!wIndex || wIndex > ports)
-			goto error;
-		wIndex--;
-		temp = fusbh200_readl(fusbh200, status_reg);
-		temp &= ~PORT_RWC_BITS;
-
-		/*
-		 * Even if OWNER is set, so the port is owned by the
-		 * companion controller, hub_wq needs to be able to clear
-		 * the port-change status bits (especially
-		 * USB_PORT_STAT_C_CONNECTION).
-		 */
-
-		switch (wValue) {
-		case USB_PORT_FEAT_ENABLE:
-			fusbh200_writel(fusbh200, temp & ~PORT_PE, status_reg);
-			break;
-		case USB_PORT_FEAT_C_ENABLE:
-			fusbh200_writel(fusbh200, temp | PORT_PEC, status_reg);
-			break;
-		case USB_PORT_FEAT_SUSPEND:
-			if (temp & PORT_RESET)
-				goto error;
-			if (!(temp & PORT_SUSPEND))
-				break;
-			if ((temp & PORT_PE) == 0)
-				goto error;
-
-			fusbh200_writel(fusbh200, temp | PORT_RESUME, status_reg);
-			fusbh200->reset_done[wIndex] = jiffies
-					+ msecs_to_jiffies(USB_RESUME_TIMEOUT);
-			break;
-		case USB_PORT_FEAT_C_SUSPEND:
-			clear_bit(wIndex, &fusbh200->port_c_suspend);
-			break;
-		case USB_PORT_FEAT_C_CONNECTION:
-			fusbh200_writel(fusbh200, temp | PORT_CSC, status_reg);
-			break;
-		case USB_PORT_FEAT_C_OVER_CURRENT:
-			fusbh200_writel(fusbh200, temp | BMISR_OVC, &fusbh200->regs->bmisr);
-			break;
-		case USB_PORT_FEAT_C_RESET:
-			/* GetPortStatus clears reset */
-			break;
-		default:
-			goto error;
-		}
-		fusbh200_readl(fusbh200, &fusbh200->regs->command);	/* unblock posted write */
-		break;
-	case GetHubDescriptor:
-		fusbh200_hub_descriptor (fusbh200, (struct usb_hub_descriptor *)
-			buf);
-		break;
-	case GetHubStatus:
-		/* no hub-wide feature/status flags */
-		memset (buf, 0, 4);
-		//cpu_to_le32s ((u32 *) buf);
-		break;
-	case GetPortStatus:
-		if (!wIndex || wIndex > ports)
-			goto error;
-		wIndex--;
-		status = 0;
-		temp = fusbh200_readl(fusbh200, status_reg);
-
-		// wPortChange bits
-		if (temp & PORT_CSC)
-			status |= USB_PORT_STAT_C_CONNECTION << 16;
-		if (temp & PORT_PEC)
-			status |= USB_PORT_STAT_C_ENABLE << 16;
-
-		temp1 = fusbh200_readl(fusbh200, &fusbh200->regs->bmisr);
-		if (temp1 & BMISR_OVC)
-			status |= USB_PORT_STAT_C_OVERCURRENT << 16;
-
-		/* whoever resumes must GetPortStatus to complete it!! */
-		if (temp & PORT_RESUME) {
-
-			/* Remote Wakeup received? */
-			if (!fusbh200->reset_done[wIndex]) {
-				/* resume signaling for 20 msec */
-				fusbh200->reset_done[wIndex] = jiffies
-						+ msecs_to_jiffies(20);
-				/* check the port again */
-				mod_timer(&fusbh200_to_hcd(fusbh200)->rh_timer,
-						fusbh200->reset_done[wIndex]);
-			}
-
-			/* resume completed? */
-			else if (time_after_eq(jiffies,
-					fusbh200->reset_done[wIndex])) {
-				clear_bit(wIndex, &fusbh200->suspended_ports);
-				set_bit(wIndex, &fusbh200->port_c_suspend);
-				fusbh200->reset_done[wIndex] = 0;
-
-				/* stop resume signaling */
-				temp = fusbh200_readl(fusbh200, status_reg);
-				fusbh200_writel(fusbh200,
-					temp & ~(PORT_RWC_BITS | PORT_RESUME),
-					status_reg);
-				clear_bit(wIndex, &fusbh200->resuming_ports);
-				retval = handshake(fusbh200, status_reg,
-					   PORT_RESUME, 0, 2000 /* 2msec */);
-				if (retval != 0) {
-					fusbh200_err(fusbh200,
-						"port %d resume error %d\n",
-						wIndex + 1, retval);
-					goto error;
-				}
-				temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
-			}
-		}
-
-		/* whoever resets must GetPortStatus to complete it!! */
-		if ((temp & PORT_RESET)
-				&& time_after_eq(jiffies,
-					fusbh200->reset_done[wIndex])) {
-			status |= USB_PORT_STAT_C_RESET << 16;
-			fusbh200->reset_done [wIndex] = 0;
-			clear_bit(wIndex, &fusbh200->resuming_ports);
-
-			/* force reset to complete */
-			fusbh200_writel(fusbh200, temp & ~(PORT_RWC_BITS | PORT_RESET),
-					status_reg);
-			/* REVISIT:  some hardware needs 550+ usec to clear
-			 * this bit; seems too long to spin routinely...
-			 */
-			retval = handshake(fusbh200, status_reg,
-					PORT_RESET, 0, 1000);
-			if (retval != 0) {
-				fusbh200_err (fusbh200, "port %d reset error %d\n",
-					wIndex + 1, retval);
-				goto error;
-			}
-
-			/* see what we found out */
-			temp = check_reset_complete (fusbh200, wIndex, status_reg,
-					fusbh200_readl(fusbh200, status_reg));
-		}
-
-		if (!(temp & (PORT_RESUME|PORT_RESET))) {
-			fusbh200->reset_done[wIndex] = 0;
-			clear_bit(wIndex, &fusbh200->resuming_ports);
-		}
-
-		/* transfer dedicated ports to the companion hc */
-		if ((temp & PORT_CONNECT) &&
-				test_bit(wIndex, &fusbh200->companion_ports)) {
-			temp &= ~PORT_RWC_BITS;
-			fusbh200_writel(fusbh200, temp, status_reg);
-			fusbh200_dbg(fusbh200, "port %d --> companion\n", wIndex + 1);
-			temp = fusbh200_readl(fusbh200, status_reg);
-		}
-
-		/*
-		 * Even if OWNER is set, there's no harm letting hub_wq
-		 * see the wPortStatus values (they should all be 0 except
-		 * for PORT_POWER anyway).
-		 */
-
-		if (temp & PORT_CONNECT) {
-			status |= USB_PORT_STAT_CONNECTION;
-			status |= fusbh200_port_speed(fusbh200, temp);
-		}
-		if (temp & PORT_PE)
-			status |= USB_PORT_STAT_ENABLE;
-
-		/* maybe the port was unsuspended without our knowledge */
-		if (temp & (PORT_SUSPEND|PORT_RESUME)) {
-			status |= USB_PORT_STAT_SUSPEND;
-		} else if (test_bit(wIndex, &fusbh200->suspended_ports)) {
-			clear_bit(wIndex, &fusbh200->suspended_ports);
-			clear_bit(wIndex, &fusbh200->resuming_ports);
-			fusbh200->reset_done[wIndex] = 0;
-			if (temp & PORT_PE)
-				set_bit(wIndex, &fusbh200->port_c_suspend);
-		}
-
-		temp1 = fusbh200_readl(fusbh200, &fusbh200->regs->bmisr);
-		if (temp1 & BMISR_OVC)
-			status |= USB_PORT_STAT_OVERCURRENT;
-		if (temp & PORT_RESET)
-			status |= USB_PORT_STAT_RESET;
-		if (test_bit(wIndex, &fusbh200->port_c_suspend))
-			status |= USB_PORT_STAT_C_SUSPEND << 16;
-
-		if (status & ~0xffff)	/* only if wPortChange is interesting */
-			dbg_port(fusbh200, "GetStatus", wIndex + 1, temp);
-		put_unaligned_le32(status, buf);
-		break;
-	case SetHubFeature:
-		switch (wValue) {
-		case C_HUB_LOCAL_POWER:
-		case C_HUB_OVER_CURRENT:
-			/* no hub-wide feature/status flags */
-			break;
-		default:
-			goto error;
-		}
-		break;
-	case SetPortFeature:
-		selector = wIndex >> 8;
-		wIndex &= 0xff;
-
-		if (!wIndex || wIndex > ports)
-			goto error;
-		wIndex--;
-		temp = fusbh200_readl(fusbh200, status_reg);
-		temp &= ~PORT_RWC_BITS;
-		switch (wValue) {
-		case USB_PORT_FEAT_SUSPEND:
-			if ((temp & PORT_PE) == 0
-					|| (temp & PORT_RESET) != 0)
-				goto error;
-
-			/* After above check the port must be connected.
-			 * Set appropriate bit thus could put phy into low power
-			 * mode if we have hostpc feature
-			 */
-			fusbh200_writel(fusbh200, temp | PORT_SUSPEND, status_reg);
-			set_bit(wIndex, &fusbh200->suspended_ports);
-			break;
-		case USB_PORT_FEAT_RESET:
-			if (temp & PORT_RESUME)
-				goto error;
-			/* line status bits may report this as low speed,
-			 * which can be fine if this root hub has a
-			 * transaction translator built in.
-			 */
-			fusbh200_dbg(fusbh200, "port %d reset\n", wIndex + 1);
-			temp |= PORT_RESET;
-			temp &= ~PORT_PE;
-
-			/*
-			 * caller must wait, then call GetPortStatus
-			 * usb 2.0 spec says 50 ms resets on root
-			 */
-			fusbh200->reset_done [wIndex] = jiffies
-					+ msecs_to_jiffies (50);
-			fusbh200_writel(fusbh200, temp, status_reg);
-			break;
-
-		/* For downstream facing ports (these):  one hub port is put
-		 * into test mode according to USB2 11.24.2.13, then the hub
-		 * must be reset (which for root hub now means rmmod+modprobe,
-		 * or else system reboot).  See EHCI 2.3.9 and 4.14 for info
-		 * about the EHCI-specific stuff.
-		 */
-		case USB_PORT_FEAT_TEST:
-			if (!selector || selector > 5)
-				goto error;
-			spin_unlock_irqrestore(&fusbh200->lock, flags);
-			fusbh200_quiesce(fusbh200);
-			spin_lock_irqsave(&fusbh200->lock, flags);
-
-			/* Put all enabled ports into suspend */
-			temp = fusbh200_readl(fusbh200, status_reg) & ~PORT_RWC_BITS;
-			if (temp & PORT_PE)
-				fusbh200_writel(fusbh200, temp | PORT_SUSPEND,
-						status_reg);
-
-			spin_unlock_irqrestore(&fusbh200->lock, flags);
-			fusbh200_halt(fusbh200);
-			spin_lock_irqsave(&fusbh200->lock, flags);
-
-			temp = fusbh200_readl(fusbh200, status_reg);
-			temp |= selector << 16;
-			fusbh200_writel(fusbh200, temp, status_reg);
-			break;
-
-		default:
-			goto error;
-		}
-		fusbh200_readl(fusbh200, &fusbh200->regs->command);	/* unblock posted writes */
-		break;
-
-	default:
-error:
-		/* "stall" on error */
-		retval = -EPIPE;
-	}
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	return retval;
-}
-
-static void __maybe_unused fusbh200_relinquish_port(struct usb_hcd *hcd,
-		int portnum)
-{
-	return;
-}
-
-static int __maybe_unused fusbh200_port_handed_over(struct usb_hcd *hcd,
-		int portnum)
-{
-	return 0;
-}
-/*-------------------------------------------------------------------------*/
-/*
- * There's basically three types of memory:
- *	- data used only by the HCD ... kmalloc is fine
- *	- async and periodic schedules, shared by HC and HCD ... these
- *	  need to use dma_pool or dma_alloc_coherent
- *	- driver buffers, read/written by HC ... single shot DMA mapped
- *
- * There's also "register" data (e.g. PCI or SOC), which is memory mapped.
- * No memory seen by this driver is pageable.
- */
-
-/*-------------------------------------------------------------------------*/
-
-/* Allocate the key transfer structures from the previously allocated pool */
-
-static inline void fusbh200_qtd_init(struct fusbh200_hcd *fusbh200, struct fusbh200_qtd *qtd,
-				  dma_addr_t dma)
-{
-	memset (qtd, 0, sizeof *qtd);
-	qtd->qtd_dma = dma;
-	qtd->hw_token = cpu_to_hc32(fusbh200, QTD_STS_HALT);
-	qtd->hw_next = FUSBH200_LIST_END(fusbh200);
-	qtd->hw_alt_next = FUSBH200_LIST_END(fusbh200);
-	INIT_LIST_HEAD (&qtd->qtd_list);
-}
-
-static struct fusbh200_qtd *fusbh200_qtd_alloc (struct fusbh200_hcd *fusbh200, gfp_t flags)
-{
-	struct fusbh200_qtd		*qtd;
-	dma_addr_t		dma;
-
-	qtd = dma_pool_alloc (fusbh200->qtd_pool, flags, &dma);
-	if (qtd != NULL) {
-		fusbh200_qtd_init(fusbh200, qtd, dma);
-	}
-	return qtd;
-}
-
-static inline void fusbh200_qtd_free (struct fusbh200_hcd *fusbh200, struct fusbh200_qtd *qtd)
-{
-	dma_pool_free (fusbh200->qtd_pool, qtd, qtd->qtd_dma);
-}
-
-
-static void qh_destroy(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	/* clean qtds first, and know this is not linked */
-	if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr) {
-		fusbh200_dbg (fusbh200, "unused qh not empty!\n");
-		BUG ();
-	}
-	if (qh->dummy)
-		fusbh200_qtd_free (fusbh200, qh->dummy);
-	dma_pool_free(fusbh200->qh_pool, qh->hw, qh->qh_dma);
-	kfree(qh);
-}
-
-static struct fusbh200_qh *fusbh200_qh_alloc (struct fusbh200_hcd *fusbh200, gfp_t flags)
-{
-	struct fusbh200_qh		*qh;
-	dma_addr_t		dma;
-
-	qh = kzalloc(sizeof *qh, GFP_ATOMIC);
-	if (!qh)
-		goto done;
-	qh->hw = (struct fusbh200_qh_hw *)
-		dma_pool_alloc(fusbh200->qh_pool, flags, &dma);
-	if (!qh->hw)
-		goto fail;
-	memset(qh->hw, 0, sizeof *qh->hw);
-	qh->qh_dma = dma;
-	// INIT_LIST_HEAD (&qh->qh_list);
-	INIT_LIST_HEAD (&qh->qtd_list);
-
-	/* dummy td enables safe urb queuing */
-	qh->dummy = fusbh200_qtd_alloc (fusbh200, flags);
-	if (qh->dummy == NULL) {
-		fusbh200_dbg (fusbh200, "no dummy td\n");
-		goto fail1;
-	}
-done:
-	return qh;
-fail1:
-	dma_pool_free(fusbh200->qh_pool, qh->hw, qh->qh_dma);
-fail:
-	kfree(qh);
-	return NULL;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* The queue heads and transfer descriptors are managed from pools tied
- * to each of the "per device" structures.
- * This is the initialisation and cleanup code.
- */
-
-static void fusbh200_mem_cleanup (struct fusbh200_hcd *fusbh200)
-{
-	if (fusbh200->async)
-		qh_destroy(fusbh200, fusbh200->async);
-	fusbh200->async = NULL;
-
-	if (fusbh200->dummy)
-		qh_destroy(fusbh200, fusbh200->dummy);
-	fusbh200->dummy = NULL;
-
-	/* DMA consistent memory and pools */
-	if (fusbh200->qtd_pool)
-		dma_pool_destroy (fusbh200->qtd_pool);
-	fusbh200->qtd_pool = NULL;
-
-	if (fusbh200->qh_pool) {
-		dma_pool_destroy (fusbh200->qh_pool);
-		fusbh200->qh_pool = NULL;
-	}
-
-	if (fusbh200->itd_pool)
-		dma_pool_destroy (fusbh200->itd_pool);
-	fusbh200->itd_pool = NULL;
-
-	if (fusbh200->periodic)
-		dma_free_coherent (fusbh200_to_hcd(fusbh200)->self.controller,
-			fusbh200->periodic_size * sizeof (u32),
-			fusbh200->periodic, fusbh200->periodic_dma);
-	fusbh200->periodic = NULL;
-
-	/* shadow periodic table */
-	kfree(fusbh200->pshadow);
-	fusbh200->pshadow = NULL;
-}
-
-/* remember to add cleanup code (above) if you add anything here */
-static int fusbh200_mem_init (struct fusbh200_hcd *fusbh200, gfp_t flags)
-{
-	int i;
-
-	/* QTDs for control/bulk/intr transfers */
-	fusbh200->qtd_pool = dma_pool_create ("fusbh200_qtd",
-			fusbh200_to_hcd(fusbh200)->self.controller,
-			sizeof (struct fusbh200_qtd),
-			32 /* byte alignment (for hw parts) */,
-			4096 /* can't cross 4K */);
-	if (!fusbh200->qtd_pool) {
-		goto fail;
-	}
-
-	/* QHs for control/bulk/intr transfers */
-	fusbh200->qh_pool = dma_pool_create ("fusbh200_qh",
-			fusbh200_to_hcd(fusbh200)->self.controller,
-			sizeof(struct fusbh200_qh_hw),
-			32 /* byte alignment (for hw parts) */,
-			4096 /* can't cross 4K */);
-	if (!fusbh200->qh_pool) {
-		goto fail;
-	}
-	fusbh200->async = fusbh200_qh_alloc (fusbh200, flags);
-	if (!fusbh200->async) {
-		goto fail;
-	}
-
-	/* ITD for high speed ISO transfers */
-	fusbh200->itd_pool = dma_pool_create ("fusbh200_itd",
-			fusbh200_to_hcd(fusbh200)->self.controller,
-			sizeof (struct fusbh200_itd),
-			64 /* byte alignment (for hw parts) */,
-			4096 /* can't cross 4K */);
-	if (!fusbh200->itd_pool) {
-		goto fail;
-	}
-
-	/* Hardware periodic table */
-	fusbh200->periodic = (__le32 *)
-		dma_alloc_coherent (fusbh200_to_hcd(fusbh200)->self.controller,
-			fusbh200->periodic_size * sizeof(__le32),
-			&fusbh200->periodic_dma, 0);
-	if (fusbh200->periodic == NULL) {
-		goto fail;
-	}
-
-		for (i = 0; i < fusbh200->periodic_size; i++)
-			fusbh200->periodic[i] = FUSBH200_LIST_END(fusbh200);
-
-	/* software shadow of hardware table */
-	fusbh200->pshadow = kcalloc(fusbh200->periodic_size, sizeof(void *), flags);
-	if (fusbh200->pshadow != NULL)
-		return 0;
-
-fail:
-	fusbh200_dbg (fusbh200, "couldn't init memory\n");
-	fusbh200_mem_cleanup (fusbh200);
-	return -ENOMEM;
-}
-/*-------------------------------------------------------------------------*/
-/*
- * EHCI hardware queue manipulation ... the core.  QH/QTD manipulation.
- *
- * Control, bulk, and interrupt traffic all use "qh" lists.  They list "qtd"
- * entries describing USB transactions, max 16-20kB/entry (with 4kB-aligned
- * buffers needed for the larger number).  We use one QH per endpoint, queue
- * multiple urbs (all three types) per endpoint.  URBs may need several qtds.
- *
- * ISO traffic uses "ISO TD" (itd) records, and (along with
- * interrupts) needs careful scheduling.  Performance improvements can be
- * an ongoing challenge.  That's in "ehci-sched.c".
- *
- * USB 1.1 devices are handled (a) by "companion" OHCI or UHCI root hubs,
- * or otherwise through transaction translators (TTs) in USB 2.0 hubs using
- * (b) special fields in qh entries or (c) split iso entries.  TTs will
- * buffer low/full speed data so the host collects it at high speed.
- */
-
-/*-------------------------------------------------------------------------*/
-
-/* fill a qtd, returning how much of the buffer we were able to queue up */
-
-static int
-qtd_fill(struct fusbh200_hcd *fusbh200, struct fusbh200_qtd *qtd, dma_addr_t buf,
-		  size_t len, int token, int maxpacket)
-{
-	int	i, count;
-	u64	addr = buf;
-
-	/* one buffer entry per 4K ... first might be short or unaligned */
-	qtd->hw_buf[0] = cpu_to_hc32(fusbh200, (u32)addr);
-	qtd->hw_buf_hi[0] = cpu_to_hc32(fusbh200, (u32)(addr >> 32));
-	count = 0x1000 - (buf & 0x0fff);	/* rest of that page */
-	if (likely (len < count))		/* ... iff needed */
-		count = len;
-	else {
-		buf +=  0x1000;
-		buf &= ~0x0fff;
-
-		/* per-qtd limit: from 16K to 20K (best alignment) */
-		for (i = 1; count < len && i < 5; i++) {
-			addr = buf;
-			qtd->hw_buf[i] = cpu_to_hc32(fusbh200, (u32)addr);
-			qtd->hw_buf_hi[i] = cpu_to_hc32(fusbh200,
-					(u32)(addr >> 32));
-			buf += 0x1000;
-			if ((count + 0x1000) < len)
-				count += 0x1000;
-			else
-				count = len;
-		}
-
-		/* short packets may only terminate transfers */
-		if (count != len)
-			count -= (count % maxpacket);
-	}
-	qtd->hw_token = cpu_to_hc32(fusbh200, (count << 16) | token);
-	qtd->length = count;
-
-	return count;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static inline void
-qh_update (struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh, struct fusbh200_qtd *qtd)
-{
-	struct fusbh200_qh_hw *hw = qh->hw;
-
-	/* writes to an active overlay are unsafe */
-	BUG_ON(qh->qh_state != QH_STATE_IDLE);
-
-	hw->hw_qtd_next = QTD_NEXT(fusbh200, qtd->qtd_dma);
-	hw->hw_alt_next = FUSBH200_LIST_END(fusbh200);
-
-	/* Except for control endpoints, we make hardware maintain data
-	 * toggle (like OHCI) ... here (re)initialize the toggle in the QH,
-	 * and set the pseudo-toggle in udev. Only usb_clear_halt() will
-	 * ever clear it.
-	 */
-	if (!(hw->hw_info1 & cpu_to_hc32(fusbh200, QH_TOGGLE_CTL))) {
-		unsigned	is_out, epnum;
-
-		is_out = qh->is_out;
-		epnum = (hc32_to_cpup(fusbh200, &hw->hw_info1) >> 8) & 0x0f;
-		if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
-			hw->hw_token &= ~cpu_to_hc32(fusbh200, QTD_TOGGLE);
-			usb_settoggle (qh->dev, epnum, is_out, 1);
-		}
-	}
-
-	hw->hw_token &= cpu_to_hc32(fusbh200, QTD_TOGGLE | QTD_STS_PING);
-}
-
-/* if it weren't for a common silicon quirk (writing the dummy into the qh
- * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault
- * recovery (including urb dequeue) would need software changes to a QH...
- */
-static void
-qh_refresh (struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	struct fusbh200_qtd *qtd;
-
-	if (list_empty (&qh->qtd_list))
-		qtd = qh->dummy;
-	else {
-		qtd = list_entry (qh->qtd_list.next,
-				struct fusbh200_qtd, qtd_list);
-		/*
-		 * first qtd may already be partially processed.
-		 * If we come here during unlink, the QH overlay region
-		 * might have reference to the just unlinked qtd. The
-		 * qtd is updated in qh_completions(). Update the QH
-		 * overlay here.
-		 */
-		if (cpu_to_hc32(fusbh200, qtd->qtd_dma) == qh->hw->hw_current) {
-			qh->hw->hw_qtd_next = qtd->hw_next;
-			qtd = NULL;
-		}
-	}
-
-	if (qtd)
-		qh_update (fusbh200, qh, qtd);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void qh_link_async(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh);
-
-static void fusbh200_clear_tt_buffer_complete(struct usb_hcd *hcd,
-		struct usb_host_endpoint *ep)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200(hcd);
-	struct fusbh200_qh		*qh = ep->hcpriv;
-	unsigned long		flags;
-
-	spin_lock_irqsave(&fusbh200->lock, flags);
-	qh->clearing_tt = 0;
-	if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list)
-			&& fusbh200->rh_state == FUSBH200_RH_RUNNING)
-		qh_link_async(fusbh200, qh);
-	spin_unlock_irqrestore(&fusbh200->lock, flags);
-}
-
-static void fusbh200_clear_tt_buffer(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh,
-		struct urb *urb, u32 token)
-{
-
-	/* If an async split transaction gets an error or is unlinked,
-	 * the TT buffer may be left in an indeterminate state.  We
-	 * have to clear the TT buffer.
-	 *
-	 * Note: this routine is never called for Isochronous transfers.
-	 */
-	if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
-		struct usb_device *tt = urb->dev->tt->hub;
-
-		dev_dbg(&tt->dev,
-			"clear tt buffer port %d, a%d ep%d t%08x\n",
-			urb->dev->ttport, urb->dev->devnum,
-			usb_pipeendpoint(urb->pipe), token);
-
-		if (urb->dev->tt->hub !=
-		    fusbh200_to_hcd(fusbh200)->self.root_hub) {
-			if (usb_hub_clear_tt_buffer(urb) == 0)
-				qh->clearing_tt = 1;
-		}
-	}
-}
-
-static int qtd_copy_status (
-	struct fusbh200_hcd *fusbh200,
-	struct urb *urb,
-	size_t length,
-	u32 token
-)
-{
-	int	status = -EINPROGRESS;
-
-	/* count IN/OUT bytes, not SETUP (even short packets) */
-	if (likely (QTD_PID (token) != 2))
-		urb->actual_length += length - QTD_LENGTH (token);
-
-	/* don't modify error codes */
-	if (unlikely(urb->unlinked))
-		return status;
-
-	/* force cleanup after short read; not always an error */
-	if (unlikely (IS_SHORT_READ (token)))
-		status = -EREMOTEIO;
-
-	/* serious "can't proceed" faults reported by the hardware */
-	if (token & QTD_STS_HALT) {
-		if (token & QTD_STS_BABBLE) {
-			/* FIXME "must" disable babbling device's port too */
-			status = -EOVERFLOW;
-		/* CERR nonzero + halt --> stall */
-		} else if (QTD_CERR(token)) {
-			status = -EPIPE;
-
-		/* In theory, more than one of the following bits can be set
-		 * since they are sticky and the transaction is retried.
-		 * Which to test first is rather arbitrary.
-		 */
-		} else if (token & QTD_STS_MMF) {
-			/* fs/ls interrupt xfer missed the complete-split */
-			status = -EPROTO;
-		} else if (token & QTD_STS_DBE) {
-			status = (QTD_PID (token) == 1) /* IN ? */
-				? -ENOSR  /* hc couldn't read data */
-				: -ECOMM; /* hc couldn't write data */
-		} else if (token & QTD_STS_XACT) {
-			/* timeout, bad CRC, wrong PID, etc */
-			fusbh200_dbg(fusbh200, "devpath %s ep%d%s 3strikes\n",
-				urb->dev->devpath,
-				usb_pipeendpoint(urb->pipe),
-				usb_pipein(urb->pipe) ? "in" : "out");
-			status = -EPROTO;
-		} else {	/* unknown */
-			status = -EPROTO;
-		}
-
-		fusbh200_dbg(fusbh200,
-			"dev%d ep%d%s qtd token %08x --> status %d\n",
-			usb_pipedevice (urb->pipe),
-			usb_pipeendpoint (urb->pipe),
-			usb_pipein (urb->pipe) ? "in" : "out",
-			token, status);
-	}
-
-	return status;
-}
-
-static void
-fusbh200_urb_done(struct fusbh200_hcd *fusbh200, struct urb *urb, int status)
-__releases(fusbh200->lock)
-__acquires(fusbh200->lock)
-{
-	if (likely (urb->hcpriv != NULL)) {
-		struct fusbh200_qh	*qh = (struct fusbh200_qh *) urb->hcpriv;
-
-		/* S-mask in a QH means it's an interrupt urb */
-		if ((qh->hw->hw_info2 & cpu_to_hc32(fusbh200, QH_SMASK)) != 0) {
-
-			/* ... update hc-wide periodic stats (for usbfs) */
-			fusbh200_to_hcd(fusbh200)->self.bandwidth_int_reqs--;
-		}
-	}
-
-	if (unlikely(urb->unlinked)) {
-		COUNT(fusbh200->stats.unlink);
-	} else {
-		/* report non-error and short read status as zero */
-		if (status == -EINPROGRESS || status == -EREMOTEIO)
-			status = 0;
-		COUNT(fusbh200->stats.complete);
-	}
-
-#ifdef FUSBH200_URB_TRACE
-	fusbh200_dbg (fusbh200,
-		"%s %s urb %p ep%d%s status %d len %d/%d\n",
-		__func__, urb->dev->devpath, urb,
-		usb_pipeendpoint (urb->pipe),
-		usb_pipein (urb->pipe) ? "in" : "out",
-		status,
-		urb->actual_length, urb->transfer_buffer_length);
-#endif
-
-	/* complete() can reenter this HCD */
-	usb_hcd_unlink_urb_from_ep(fusbh200_to_hcd(fusbh200), urb);
-	spin_unlock (&fusbh200->lock);
-	usb_hcd_giveback_urb(fusbh200_to_hcd(fusbh200), urb, status);
-	spin_lock (&fusbh200->lock);
-}
-
-static int qh_schedule (struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh);
-
-/*
- * Process and free completed qtds for a qh, returning URBs to drivers.
- * Chases up to qh->hw_current.  Returns number of completions called,
- * indicating how much "real" work we did.
- */
-static unsigned
-qh_completions (struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	struct fusbh200_qtd		*last, *end = qh->dummy;
-	struct list_head	*entry, *tmp;
-	int			last_status;
-	int			stopped;
-	unsigned		count = 0;
-	u8			state;
-	struct fusbh200_qh_hw	*hw = qh->hw;
-
-	if (unlikely (list_empty (&qh->qtd_list)))
-		return count;
-
-	/* completions (or tasks on other cpus) must never clobber HALT
-	 * till we've gone through and cleaned everything up, even when
-	 * they add urbs to this qh's queue or mark them for unlinking.
-	 *
-	 * NOTE:  unlinking expects to be done in queue order.
-	 *
-	 * It's a bug for qh->qh_state to be anything other than
-	 * QH_STATE_IDLE, unless our caller is scan_async() or
-	 * scan_intr().
-	 */
-	state = qh->qh_state;
-	qh->qh_state = QH_STATE_COMPLETING;
-	stopped = (state == QH_STATE_IDLE);
-
- rescan:
-	last = NULL;
-	last_status = -EINPROGRESS;
-	qh->needs_rescan = 0;
-
-	/* remove de-activated QTDs from front of queue.
-	 * after faults (including short reads), cleanup this urb
-	 * then let the queue advance.
-	 * if queue is stopped, handles unlinks.
-	 */
-	list_for_each_safe (entry, tmp, &qh->qtd_list) {
-		struct fusbh200_qtd	*qtd;
-		struct urb	*urb;
-		u32		token = 0;
-
-		qtd = list_entry (entry, struct fusbh200_qtd, qtd_list);
-		urb = qtd->urb;
-
-		/* clean up any state from previous QTD ...*/
-		if (last) {
-			if (likely (last->urb != urb)) {
-				fusbh200_urb_done(fusbh200, last->urb, last_status);
-				count++;
-				last_status = -EINPROGRESS;
-			}
-			fusbh200_qtd_free (fusbh200, last);
-			last = NULL;
-		}
-
-		/* ignore urbs submitted during completions we reported */
-		if (qtd == end)
-			break;
-
-		/* hardware copies qtd out of qh overlay */
-		rmb ();
-		token = hc32_to_cpu(fusbh200, qtd->hw_token);
-
-		/* always clean up qtds the hc de-activated */
- retry_xacterr:
-		if ((token & QTD_STS_ACTIVE) == 0) {
-
-			/* Report Data Buffer Error: non-fatal but useful */
-			if (token & QTD_STS_DBE)
-				fusbh200_dbg(fusbh200,
-					"detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-					urb,
-					usb_endpoint_num(&urb->ep->desc),
-					usb_endpoint_dir_in(&urb->ep->desc) ? "in" : "out",
-					urb->transfer_buffer_length,
-					qtd,
-					qh);
-
-			/* on STALL, error, and short reads this urb must
-			 * complete and all its qtds must be recycled.
-			 */
-			if ((token & QTD_STS_HALT) != 0) {
-
-				/* retry transaction errors until we
-				 * reach the software xacterr limit
-				 */
-				if ((token & QTD_STS_XACT) &&
-						QTD_CERR(token) == 0 &&
-						++qh->xacterrs < QH_XACTERR_MAX &&
-						!urb->unlinked) {
-					fusbh200_dbg(fusbh200,
-	"detected XactErr len %zu/%zu retry %d\n",
-	qtd->length - QTD_LENGTH(token), qtd->length, qh->xacterrs);
-
-					/* reset the token in the qtd and the
-					 * qh overlay (which still contains
-					 * the qtd) so that we pick up from
-					 * where we left off
-					 */
-					token &= ~QTD_STS_HALT;
-					token |= QTD_STS_ACTIVE |
-							(FUSBH200_TUNE_CERR << 10);
-					qtd->hw_token = cpu_to_hc32(fusbh200,
-							token);
-					wmb();
-					hw->hw_token = cpu_to_hc32(fusbh200,
-							token);
-					goto retry_xacterr;
-				}
-				stopped = 1;
-
-			/* magic dummy for some short reads; qh won't advance.
-			 * that silicon quirk can kick in with this dummy too.
-			 *
-			 * other short reads won't stop the queue, including
-			 * control transfers (status stage handles that) or
-			 * most other single-qtd reads ... the queue stops if
-			 * URB_SHORT_NOT_OK was set so the driver submitting
-			 * the urbs could clean it up.
-			 */
-			} else if (IS_SHORT_READ (token)
-					&& !(qtd->hw_alt_next
-						& FUSBH200_LIST_END(fusbh200))) {
-				stopped = 1;
-			}
-
-		/* stop scanning when we reach qtds the hc is using */
-		} else if (likely (!stopped
-				&& fusbh200->rh_state >= FUSBH200_RH_RUNNING)) {
-			break;
-
-		/* scan the whole queue for unlinks whenever it stops */
-		} else {
-			stopped = 1;
-
-			/* cancel everything if we halt, suspend, etc */
-			if (fusbh200->rh_state < FUSBH200_RH_RUNNING)
-				last_status = -ESHUTDOWN;
-
-			/* this qtd is active; skip it unless a previous qtd
-			 * for its urb faulted, or its urb was canceled.
-			 */
-			else if (last_status == -EINPROGRESS && !urb->unlinked)
-				continue;
-
-			/* qh unlinked; token in overlay may be most current */
-			if (state == QH_STATE_IDLE
-					&& cpu_to_hc32(fusbh200, qtd->qtd_dma)
-						== hw->hw_current) {
-				token = hc32_to_cpu(fusbh200, hw->hw_token);
-
-				/* An unlink may leave an incomplete
-				 * async transaction in the TT buffer.
-				 * We have to clear it.
-				 */
-				fusbh200_clear_tt_buffer(fusbh200, qh, urb, token);
-			}
-		}
-
-		/* unless we already know the urb's status, collect qtd status
-		 * and update count of bytes transferred.  in common short read
-		 * cases with only one data qtd (including control transfers),
-		 * queue processing won't halt.  but with two or more qtds (for
-		 * example, with a 32 KB transfer), when the first qtd gets a
-		 * short read the second must be removed by hand.
-		 */
-		if (last_status == -EINPROGRESS) {
-			last_status = qtd_copy_status(fusbh200, urb,
-					qtd->length, token);
-			if (last_status == -EREMOTEIO
-					&& (qtd->hw_alt_next
-						& FUSBH200_LIST_END(fusbh200)))
-				last_status = -EINPROGRESS;
-
-			/* As part of low/full-speed endpoint-halt processing
-			 * we must clear the TT buffer (11.17.5).
-			 */
-			if (unlikely(last_status != -EINPROGRESS &&
-					last_status != -EREMOTEIO)) {
-				/* The TT's in some hubs malfunction when they
-				 * receive this request following a STALL (they
-				 * stop sending isochronous packets).  Since a
-				 * STALL can't leave the TT buffer in a busy
-				 * state (if you believe Figures 11-48 - 11-51
-				 * in the USB 2.0 spec), we won't clear the TT
-				 * buffer in this case.  Strictly speaking this
-				 * is a violation of the spec.
-				 */
-				if (last_status != -EPIPE)
-					fusbh200_clear_tt_buffer(fusbh200, qh, urb,
-							token);
-			}
-		}
-
-		/* if we're removing something not at the queue head,
-		 * patch the hardware queue pointer.
-		 */
-		if (stopped && qtd->qtd_list.prev != &qh->qtd_list) {
-			last = list_entry (qtd->qtd_list.prev,
-					struct fusbh200_qtd, qtd_list);
-			last->hw_next = qtd->hw_next;
-		}
-
-		/* remove qtd; it's recycled after possible urb completion */
-		list_del (&qtd->qtd_list);
-		last = qtd;
-
-		/* reinit the xacterr counter for the next qtd */
-		qh->xacterrs = 0;
-	}
-
-	/* last urb's completion might still need calling */
-	if (likely (last != NULL)) {
-		fusbh200_urb_done(fusbh200, last->urb, last_status);
-		count++;
-		fusbh200_qtd_free (fusbh200, last);
-	}
-
-	/* Do we need to rescan for URBs dequeued during a giveback? */
-	if (unlikely(qh->needs_rescan)) {
-		/* If the QH is already unlinked, do the rescan now. */
-		if (state == QH_STATE_IDLE)
-			goto rescan;
-
-		/* Otherwise we have to wait until the QH is fully unlinked.
-		 * Our caller will start an unlink if qh->needs_rescan is
-		 * set.  But if an unlink has already started, nothing needs
-		 * to be done.
-		 */
-		if (state != QH_STATE_LINKED)
-			qh->needs_rescan = 0;
-	}
-
-	/* restore original state; caller must unlink or relink */
-	qh->qh_state = state;
-
-	/* be sure the hardware's done with the qh before refreshing
-	 * it after fault cleanup, or recovering from silicon wrongly
-	 * overlaying the dummy qtd (which reduces DMA chatter).
-	 */
-	if (stopped != 0 || hw->hw_qtd_next == FUSBH200_LIST_END(fusbh200)) {
-		switch (state) {
-		case QH_STATE_IDLE:
-			qh_refresh(fusbh200, qh);
-			break;
-		case QH_STATE_LINKED:
-			/* We won't refresh a QH that's linked (after the HC
-			 * stopped the queue).  That avoids a race:
-			 *  - HC reads first part of QH;
-			 *  - CPU updates that first part and the token;
-			 *  - HC reads rest of that QH, including token
-			 * Result:  HC gets an inconsistent image, and then
-			 * DMAs to/from the wrong memory (corrupting it).
-			 *
-			 * That should be rare for interrupt transfers,
-			 * except maybe high bandwidth ...
-			 */
-
-			/* Tell the caller to start an unlink */
-			qh->needs_rescan = 1;
-			break;
-		/* otherwise, unlink already started */
-		}
-	}
-
-	return count;
-}
-
-/*-------------------------------------------------------------------------*/
-
-// high bandwidth multiplier, as encoded in highspeed endpoint descriptors
-#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
-// ... and packet size, for any kind of endpoint descriptor
-#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
-
-/*
- * reverse of qh_urb_transaction:  free a list of TDs.
- * used for cleanup after errors, before HC sees an URB's TDs.
- */
-static void qtd_list_free (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct list_head	*qtd_list
-) {
-	struct list_head	*entry, *temp;
-
-	list_for_each_safe (entry, temp, qtd_list) {
-		struct fusbh200_qtd	*qtd;
-
-		qtd = list_entry (entry, struct fusbh200_qtd, qtd_list);
-		list_del (&qtd->qtd_list);
-		fusbh200_qtd_free (fusbh200, qtd);
-	}
-}
-
-/*
- * create a list of filled qtds for this URB; won't link into qh.
- */
-static struct list_head *
-qh_urb_transaction (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct list_head	*head,
-	gfp_t			flags
-) {
-	struct fusbh200_qtd		*qtd, *qtd_prev;
-	dma_addr_t		buf;
-	int			len, this_sg_len, maxpacket;
-	int			is_input;
-	u32			token;
-	int			i;
-	struct scatterlist	*sg;
-
-	/*
-	 * URBs map to sequences of QTDs:  one logical transaction
-	 */
-	qtd = fusbh200_qtd_alloc (fusbh200, flags);
-	if (unlikely (!qtd))
-		return NULL;
-	list_add_tail (&qtd->qtd_list, head);
-	qtd->urb = urb;
-
-	token = QTD_STS_ACTIVE;
-	token |= (FUSBH200_TUNE_CERR << 10);
-	/* for split transactions, SplitXState initialized to zero */
-
-	len = urb->transfer_buffer_length;
-	is_input = usb_pipein (urb->pipe);
-	if (usb_pipecontrol (urb->pipe)) {
-		/* SETUP pid */
-		qtd_fill(fusbh200, qtd, urb->setup_dma,
-				sizeof (struct usb_ctrlrequest),
-				token | (2 /* "setup" */ << 8), 8);
-
-		/* ... and always at least one more pid */
-		token ^= QTD_TOGGLE;
-		qtd_prev = qtd;
-		qtd = fusbh200_qtd_alloc (fusbh200, flags);
-		if (unlikely (!qtd))
-			goto cleanup;
-		qtd->urb = urb;
-		qtd_prev->hw_next = QTD_NEXT(fusbh200, qtd->qtd_dma);
-		list_add_tail (&qtd->qtd_list, head);
-
-		/* for zero length DATA stages, STATUS is always IN */
-		if (len == 0)
-			token |= (1 /* "in" */ << 8);
-	}
-
-	/*
-	 * data transfer stage:  buffer setup
-	 */
-	i = urb->num_mapped_sgs;
-	if (len > 0 && i > 0) {
-		sg = urb->sg;
-		buf = sg_dma_address(sg);
-
-		/* urb->transfer_buffer_length may be smaller than the
-		 * size of the scatterlist (or vice versa)
-		 */
-		this_sg_len = min_t(int, sg_dma_len(sg), len);
-	} else {
-		sg = NULL;
-		buf = urb->transfer_dma;
-		this_sg_len = len;
-	}
-
-	if (is_input)
-		token |= (1 /* "in" */ << 8);
-	/* else it's already initted to "out" pid (0 << 8) */
-
-	maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input));
-
-	/*
-	 * buffer gets wrapped in one or more qtds;
-	 * last one may be "short" (including zero len)
-	 * and may serve as a control status ack
-	 */
-	for (;;) {
-		int this_qtd_len;
-
-		this_qtd_len = qtd_fill(fusbh200, qtd, buf, this_sg_len, token,
-				maxpacket);
-		this_sg_len -= this_qtd_len;
-		len -= this_qtd_len;
-		buf += this_qtd_len;
-
-		/*
-		 * short reads advance to a "magic" dummy instead of the next
-		 * qtd ... that forces the queue to stop, for manual cleanup.
-		 * (this will usually be overridden later.)
-		 */
-		if (is_input)
-			qtd->hw_alt_next = fusbh200->async->hw->hw_alt_next;
-
-		/* qh makes control packets use qtd toggle; maybe switch it */
-		if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
-			token ^= QTD_TOGGLE;
-
-		if (likely(this_sg_len <= 0)) {
-			if (--i <= 0 || len <= 0)
-				break;
-			sg = sg_next(sg);
-			buf = sg_dma_address(sg);
-			this_sg_len = min_t(int, sg_dma_len(sg), len);
-		}
-
-		qtd_prev = qtd;
-		qtd = fusbh200_qtd_alloc (fusbh200, flags);
-		if (unlikely (!qtd))
-			goto cleanup;
-		qtd->urb = urb;
-		qtd_prev->hw_next = QTD_NEXT(fusbh200, qtd->qtd_dma);
-		list_add_tail (&qtd->qtd_list, head);
-	}
-
-	/*
-	 * unless the caller requires manual cleanup after short reads,
-	 * have the alt_next mechanism keep the queue running after the
-	 * last data qtd (the only one, for control and most other cases).
-	 */
-	if (likely ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0
-				|| usb_pipecontrol (urb->pipe)))
-		qtd->hw_alt_next = FUSBH200_LIST_END(fusbh200);
-
-	/*
-	 * control requests may need a terminating data "status" ack;
-	 * other OUT ones may need a terminating short packet
-	 * (zero length).
-	 */
-	if (likely (urb->transfer_buffer_length != 0)) {
-		int	one_more = 0;
-
-		if (usb_pipecontrol (urb->pipe)) {
-			one_more = 1;
-			token ^= 0x0100;	/* "in" <--> "out"  */
-			token |= QTD_TOGGLE;	/* force DATA1 */
-		} else if (usb_pipeout(urb->pipe)
-				&& (urb->transfer_flags & URB_ZERO_PACKET)
-				&& !(urb->transfer_buffer_length % maxpacket)) {
-			one_more = 1;
-		}
-		if (one_more) {
-			qtd_prev = qtd;
-			qtd = fusbh200_qtd_alloc (fusbh200, flags);
-			if (unlikely (!qtd))
-				goto cleanup;
-			qtd->urb = urb;
-			qtd_prev->hw_next = QTD_NEXT(fusbh200, qtd->qtd_dma);
-			list_add_tail (&qtd->qtd_list, head);
-
-			/* never any data in such packets */
-			qtd_fill(fusbh200, qtd, 0, 0, token, 0);
-		}
-	}
-
-	/* by default, enable interrupt on urb completion */
-	if (likely (!(urb->transfer_flags & URB_NO_INTERRUPT)))
-		qtd->hw_token |= cpu_to_hc32(fusbh200, QTD_IOC);
-	return head;
-
-cleanup:
-	qtd_list_free (fusbh200, urb, head);
-	return NULL;
-}
-
-/*-------------------------------------------------------------------------*/
-
-// Would be best to create all qh's from config descriptors,
-// when each interface/altsetting is established.  Unlink
-// any previous qh and cancel its urbs first; endpoints are
-// implicitly reset then (data toggle too).
-// That'd mean updating how usbcore talks to HCDs. (2.7?)
-
-
-/*
- * Each QH holds a qtd list; a QH is used for everything except iso.
- *
- * For interrupt urbs, the scheduler must set the microframe scheduling
- * mask(s) each time the QH gets scheduled.  For highspeed, that's
- * just one microframe in the s-mask.  For split interrupt transactions
- * there are additional complications: c-mask, maybe FSTNs.
- */
-static struct fusbh200_qh *
-qh_make (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	gfp_t			flags
-) {
-	struct fusbh200_qh		*qh = fusbh200_qh_alloc (fusbh200, flags);
-	u32			info1 = 0, info2 = 0;
-	int			is_input, type;
-	int			maxp = 0;
-	struct usb_tt		*tt = urb->dev->tt;
-	struct fusbh200_qh_hw	*hw;
-
-	if (!qh)
-		return qh;
-
-	/*
-	 * init endpoint/device data for this QH
-	 */
-	info1 |= usb_pipeendpoint (urb->pipe) << 8;
-	info1 |= usb_pipedevice (urb->pipe) << 0;
-
-	is_input = usb_pipein (urb->pipe);
-	type = usb_pipetype (urb->pipe);
-	maxp = usb_maxpacket (urb->dev, urb->pipe, !is_input);
-
-	/* 1024 byte maxpacket is a hardware ceiling.  High bandwidth
-	 * acts like up to 3KB, but is built from smaller packets.
-	 */
-	if (max_packet(maxp) > 1024) {
-		fusbh200_dbg(fusbh200, "bogus qh maxpacket %d\n", max_packet(maxp));
-		goto done;
-	}
-
-	/* Compute interrupt scheduling parameters just once, and save.
-	 * - allowing for high bandwidth, how many nsec/uframe are used?
-	 * - split transactions need a second CSPLIT uframe; same question
-	 * - splits also need a schedule gap (for full/low speed I/O)
-	 * - qh has a polling interval
-	 *
-	 * For control/bulk requests, the HC or TT handles these.
-	 */
-	if (type == PIPE_INTERRUPT) {
-		qh->usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH,
-				is_input, 0,
-				hb_mult(maxp) * max_packet(maxp)));
-		qh->start = NO_FRAME;
-
-		if (urb->dev->speed == USB_SPEED_HIGH) {
-			qh->c_usecs = 0;
-			qh->gap_uf = 0;
-
-			qh->period = urb->interval >> 3;
-			if (qh->period == 0 && urb->interval != 1) {
-				/* NOTE interval 2 or 4 uframes could work.
-				 * But interval 1 scheduling is simpler, and
-				 * includes high bandwidth.
-				 */
-				urb->interval = 1;
-			} else if (qh->period > fusbh200->periodic_size) {
-				qh->period = fusbh200->periodic_size;
-				urb->interval = qh->period << 3;
-			}
-		} else {
-			int		think_time;
-
-			/* gap is f(FS/LS transfer times) */
-			qh->gap_uf = 1 + usb_calc_bus_time (urb->dev->speed,
-					is_input, 0, maxp) / (125 * 1000);
-
-			/* FIXME this just approximates SPLIT/CSPLIT times */
-			if (is_input) {		// SPLIT, gap, CSPLIT+DATA
-				qh->c_usecs = qh->usecs + HS_USECS (0);
-				qh->usecs = HS_USECS (1);
-			} else {		// SPLIT+DATA, gap, CSPLIT
-				qh->usecs += HS_USECS (1);
-				qh->c_usecs = HS_USECS (0);
-			}
-
-			think_time = tt ? tt->think_time : 0;
-			qh->tt_usecs = NS_TO_US (think_time +
-					usb_calc_bus_time (urb->dev->speed,
-					is_input, 0, max_packet (maxp)));
-			qh->period = urb->interval;
-			if (qh->period > fusbh200->periodic_size) {
-				qh->period = fusbh200->periodic_size;
-				urb->interval = qh->period;
-			}
-		}
-	}
-
-	/* support for tt scheduling, and access to toggles */
-	qh->dev = urb->dev;
-
-	/* using TT? */
-	switch (urb->dev->speed) {
-	case USB_SPEED_LOW:
-		info1 |= QH_LOW_SPEED;
-		/* FALL THROUGH */
-
-	case USB_SPEED_FULL:
-		/* EPS 0 means "full" */
-		if (type != PIPE_INTERRUPT)
-			info1 |= (FUSBH200_TUNE_RL_TT << 28);
-		if (type == PIPE_CONTROL) {
-			info1 |= QH_CONTROL_EP;		/* for TT */
-			info1 |= QH_TOGGLE_CTL;		/* toggle from qtd */
-		}
-		info1 |= maxp << 16;
-
-		info2 |= (FUSBH200_TUNE_MULT_TT << 30);
-
-		/* Some Freescale processors have an erratum in which the
-		 * port number in the queue head was 0..N-1 instead of 1..N.
-		 */
-		if (fusbh200_has_fsl_portno_bug(fusbh200))
-			info2 |= (urb->dev->ttport-1) << 23;
-		else
-			info2 |= urb->dev->ttport << 23;
-
-		/* set the address of the TT; for TDI's integrated
-		 * root hub tt, leave it zeroed.
-		 */
-		if (tt && tt->hub != fusbh200_to_hcd(fusbh200)->self.root_hub)
-			info2 |= tt->hub->devnum << 16;
-
-		/* NOTE:  if (PIPE_INTERRUPT) { scheduler sets c-mask } */
-
-		break;
-
-	case USB_SPEED_HIGH:		/* no TT involved */
-		info1 |= QH_HIGH_SPEED;
-		if (type == PIPE_CONTROL) {
-			info1 |= (FUSBH200_TUNE_RL_HS << 28);
-			info1 |= 64 << 16;	/* usb2 fixed maxpacket */
-			info1 |= QH_TOGGLE_CTL;	/* toggle from qtd */
-			info2 |= (FUSBH200_TUNE_MULT_HS << 30);
-		} else if (type == PIPE_BULK) {
-			info1 |= (FUSBH200_TUNE_RL_HS << 28);
-			/* The USB spec says that high speed bulk endpoints
-			 * always use 512 byte maxpacket.  But some device
-			 * vendors decided to ignore that, and MSFT is happy
-			 * to help them do so.  So now people expect to use
-			 * such nonconformant devices with Linux too; sigh.
-			 */
-			info1 |= max_packet(maxp) << 16;
-			info2 |= (FUSBH200_TUNE_MULT_HS << 30);
-		} else {		/* PIPE_INTERRUPT */
-			info1 |= max_packet (maxp) << 16;
-			info2 |= hb_mult (maxp) << 30;
-		}
-		break;
-	default:
-		fusbh200_dbg(fusbh200, "bogus dev %p speed %d\n", urb->dev,
-			urb->dev->speed);
-done:
-		qh_destroy(fusbh200, qh);
-		return NULL;
-	}
-
-	/* NOTE:  if (PIPE_INTERRUPT) { scheduler sets s-mask } */
-
-	/* init as live, toggle clear, advance to dummy */
-	qh->qh_state = QH_STATE_IDLE;
-	hw = qh->hw;
-	hw->hw_info1 = cpu_to_hc32(fusbh200, info1);
-	hw->hw_info2 = cpu_to_hc32(fusbh200, info2);
-	qh->is_out = !is_input;
-	usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
-	qh_refresh (fusbh200, qh);
-	return qh;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void enable_async(struct fusbh200_hcd *fusbh200)
-{
-	if (fusbh200->async_count++)
-		return;
-
-	/* Stop waiting to turn off the async schedule */
-	fusbh200->enabled_hrtimer_events &= ~BIT(FUSBH200_HRTIMER_DISABLE_ASYNC);
-
-	/* Don't start the schedule until ASS is 0 */
-	fusbh200_poll_ASS(fusbh200);
-	turn_on_io_watchdog(fusbh200);
-}
-
-static void disable_async(struct fusbh200_hcd *fusbh200)
-{
-	if (--fusbh200->async_count)
-		return;
-
-	/* The async schedule and async_unlink list are supposed to be empty */
-	WARN_ON(fusbh200->async->qh_next.qh || fusbh200->async_unlink);
-
-	/* Don't turn off the schedule until ASS is 1 */
-	fusbh200_poll_ASS(fusbh200);
-}
-
-/* move qh (and its qtds) onto async queue; maybe enable queue.  */
-
-static void qh_link_async (struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	__hc32		dma = QH_NEXT(fusbh200, qh->qh_dma);
-	struct fusbh200_qh	*head;
-
-	/* Don't link a QH if there's a Clear-TT-Buffer pending */
-	if (unlikely(qh->clearing_tt))
-		return;
-
-	WARN_ON(qh->qh_state != QH_STATE_IDLE);
-
-	/* clear halt and/or toggle; and maybe recover from silicon quirk */
-	qh_refresh(fusbh200, qh);
-
-	/* splice right after start */
-	head = fusbh200->async;
-	qh->qh_next = head->qh_next;
-	qh->hw->hw_next = head->hw->hw_next;
-	wmb ();
-
-	head->qh_next.qh = qh;
-	head->hw->hw_next = dma;
-
-	qh->xacterrs = 0;
-	qh->qh_state = QH_STATE_LINKED;
-	/* qtd completions reported later by interrupt */
-
-	enable_async(fusbh200);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * For control/bulk/interrupt, return QH with these TDs appended.
- * Allocates and initializes the QH if necessary.
- * Returns null if it can't allocate a QH it needs to.
- * If the QH has TDs (urbs) already, that's great.
- */
-static struct fusbh200_qh *qh_append_tds (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	int			epnum,
-	void			**ptr
-)
-{
-	struct fusbh200_qh		*qh = NULL;
-	__hc32			qh_addr_mask = cpu_to_hc32(fusbh200, 0x7f);
-
-	qh = (struct fusbh200_qh *) *ptr;
-	if (unlikely (qh == NULL)) {
-		/* can't sleep here, we have fusbh200->lock... */
-		qh = qh_make (fusbh200, urb, GFP_ATOMIC);
-		*ptr = qh;
-	}
-	if (likely (qh != NULL)) {
-		struct fusbh200_qtd	*qtd;
-
-		if (unlikely (list_empty (qtd_list)))
-			qtd = NULL;
-		else
-			qtd = list_entry (qtd_list->next, struct fusbh200_qtd,
-					qtd_list);
-
-		/* control qh may need patching ... */
-		if (unlikely (epnum == 0)) {
-
-                        /* usb_reset_device() briefly reverts to address 0 */
-                        if (usb_pipedevice (urb->pipe) == 0)
-				qh->hw->hw_info1 &= ~qh_addr_mask;
-		}
-
-		/* just one way to queue requests: swap with the dummy qtd.
-		 * only hc or qh_refresh() ever modify the overlay.
-		 */
-		if (likely (qtd != NULL)) {
-			struct fusbh200_qtd		*dummy;
-			dma_addr_t		dma;
-			__hc32			token;
-
-			/* to avoid racing the HC, use the dummy td instead of
-			 * the first td of our list (becomes new dummy).  both
-			 * tds stay deactivated until we're done, when the
-			 * HC is allowed to fetch the old dummy (4.10.2).
-			 */
-			token = qtd->hw_token;
-			qtd->hw_token = HALT_BIT(fusbh200);
-
-			dummy = qh->dummy;
-
-			dma = dummy->qtd_dma;
-			*dummy = *qtd;
-			dummy->qtd_dma = dma;
-
-			list_del (&qtd->qtd_list);
-			list_add (&dummy->qtd_list, qtd_list);
-			list_splice_tail(qtd_list, &qh->qtd_list);
-
-			fusbh200_qtd_init(fusbh200, qtd, qtd->qtd_dma);
-			qh->dummy = qtd;
-
-			/* hc must see the new dummy at list end */
-			dma = qtd->qtd_dma;
-			qtd = list_entry (qh->qtd_list.prev,
-					struct fusbh200_qtd, qtd_list);
-			qtd->hw_next = QTD_NEXT(fusbh200, dma);
-
-			/* let the hc process these next qtds */
-			wmb ();
-			dummy->hw_token = token;
-
-			urb->hcpriv = qh;
-		}
-	}
-	return qh;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int
-submit_async (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	gfp_t			mem_flags
-) {
-	int			epnum;
-	unsigned long		flags;
-	struct fusbh200_qh		*qh = NULL;
-	int			rc;
-
-	epnum = urb->ep->desc.bEndpointAddress;
-
-#ifdef FUSBH200_URB_TRACE
-	{
-		struct fusbh200_qtd *qtd;
-		qtd = list_entry(qtd_list->next, struct fusbh200_qtd, qtd_list);
-		fusbh200_dbg(fusbh200,
-			 "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-			 __func__, urb->dev->devpath, urb,
-			 epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
-			 urb->transfer_buffer_length,
-			 qtd, urb->ep->hcpriv);
-	}
-#endif
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	if (unlikely(!HCD_HW_ACCESSIBLE(fusbh200_to_hcd(fusbh200)))) {
-		rc = -ESHUTDOWN;
-		goto done;
-	}
-	rc = usb_hcd_link_urb_to_ep(fusbh200_to_hcd(fusbh200), urb);
-	if (unlikely(rc))
-		goto done;
-
-	qh = qh_append_tds(fusbh200, urb, qtd_list, epnum, &urb->ep->hcpriv);
-	if (unlikely(qh == NULL)) {
-		usb_hcd_unlink_urb_from_ep(fusbh200_to_hcd(fusbh200), urb);
-		rc = -ENOMEM;
-		goto done;
-	}
-
-	/* Control/bulk operations through TTs don't need scheduling,
-	 * the HC and TT handle it when the TT has a buffer ready.
-	 */
-	if (likely (qh->qh_state == QH_STATE_IDLE))
-		qh_link_async(fusbh200, qh);
- done:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	if (unlikely (qh == NULL))
-		qtd_list_free (fusbh200, urb, qtd_list);
-	return rc;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void single_unlink_async(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	struct fusbh200_qh		*prev;
-
-	/* Add to the end of the list of QHs waiting for the next IAAD */
-	qh->qh_state = QH_STATE_UNLINK;
-	if (fusbh200->async_unlink)
-		fusbh200->async_unlink_last->unlink_next = qh;
-	else
-		fusbh200->async_unlink = qh;
-	fusbh200->async_unlink_last = qh;
-
-	/* Unlink it from the schedule */
-	prev = fusbh200->async;
-	while (prev->qh_next.qh != qh)
-		prev = prev->qh_next.qh;
-
-	prev->hw->hw_next = qh->hw->hw_next;
-	prev->qh_next = qh->qh_next;
-	if (fusbh200->qh_scan_next == qh)
-		fusbh200->qh_scan_next = qh->qh_next.qh;
-}
-
-static void start_iaa_cycle(struct fusbh200_hcd *fusbh200, bool nested)
-{
-	/*
-	 * Do nothing if an IAA cycle is already running or
-	 * if one will be started shortly.
-	 */
-	if (fusbh200->async_iaa || fusbh200->async_unlinking)
-		return;
-
-	/* Do all the waiting QHs at once */
-	fusbh200->async_iaa = fusbh200->async_unlink;
-	fusbh200->async_unlink = NULL;
-
-	/* If the controller isn't running, we don't have to wait for it */
-	if (unlikely(fusbh200->rh_state < FUSBH200_RH_RUNNING)) {
-		if (!nested)		/* Avoid recursion */
-			end_unlink_async(fusbh200);
-
-	/* Otherwise start a new IAA cycle */
-	} else if (likely(fusbh200->rh_state == FUSBH200_RH_RUNNING)) {
-		/* Make sure the unlinks are all visible to the hardware */
-		wmb();
-
-		fusbh200_writel(fusbh200, fusbh200->command | CMD_IAAD,
-				&fusbh200->regs->command);
-		fusbh200_readl(fusbh200, &fusbh200->regs->command);
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_IAA_WATCHDOG, true);
-	}
-}
-
-/* the async qh for the qtds being unlinked are now gone from the HC */
-
-static void end_unlink_async(struct fusbh200_hcd *fusbh200)
-{
-	struct fusbh200_qh		*qh;
-
-	/* Process the idle QHs */
- restart:
-	fusbh200->async_unlinking = true;
-	while (fusbh200->async_iaa) {
-		qh = fusbh200->async_iaa;
-		fusbh200->async_iaa = qh->unlink_next;
-		qh->unlink_next = NULL;
-
-		qh->qh_state = QH_STATE_IDLE;
-		qh->qh_next.qh = NULL;
-
-		qh_completions(fusbh200, qh);
-		if (!list_empty(&qh->qtd_list) &&
-				fusbh200->rh_state == FUSBH200_RH_RUNNING)
-			qh_link_async(fusbh200, qh);
-		disable_async(fusbh200);
-	}
-	fusbh200->async_unlinking = false;
-
-	/* Start a new IAA cycle if any QHs are waiting for it */
-	if (fusbh200->async_unlink) {
-		start_iaa_cycle(fusbh200, true);
-		if (unlikely(fusbh200->rh_state < FUSBH200_RH_RUNNING))
-			goto restart;
-	}
-}
-
-static void unlink_empty_async(struct fusbh200_hcd *fusbh200)
-{
-	struct fusbh200_qh		*qh, *next;
-	bool			stopped = (fusbh200->rh_state < FUSBH200_RH_RUNNING);
-	bool			check_unlinks_later = false;
-
-	/* Unlink all the async QHs that have been empty for a timer cycle */
-	next = fusbh200->async->qh_next.qh;
-	while (next) {
-		qh = next;
-		next = qh->qh_next.qh;
-
-		if (list_empty(&qh->qtd_list) &&
-				qh->qh_state == QH_STATE_LINKED) {
-			if (!stopped && qh->unlink_cycle ==
-					fusbh200->async_unlink_cycle)
-				check_unlinks_later = true;
-			else
-				single_unlink_async(fusbh200, qh);
-		}
-	}
-
-	/* Start a new IAA cycle if any QHs are waiting for it */
-	if (fusbh200->async_unlink)
-		start_iaa_cycle(fusbh200, false);
-
-	/* QHs that haven't been empty for long enough will be handled later */
-	if (check_unlinks_later) {
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_ASYNC_UNLINKS, true);
-		++fusbh200->async_unlink_cycle;
-	}
-}
-
-/* makes sure the async qh will become idle */
-/* caller must own fusbh200->lock */
-
-static void start_unlink_async(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	/*
-	 * If the QH isn't linked then there's nothing we can do
-	 * unless we were called during a giveback, in which case
-	 * qh_completions() has to deal with it.
-	 */
-	if (qh->qh_state != QH_STATE_LINKED) {
-		if (qh->qh_state == QH_STATE_COMPLETING)
-			qh->needs_rescan = 1;
-		return;
-	}
-
-	single_unlink_async(fusbh200, qh);
-	start_iaa_cycle(fusbh200, false);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void scan_async (struct fusbh200_hcd *fusbh200)
-{
-	struct fusbh200_qh		*qh;
-	bool			check_unlinks_later = false;
-
-	fusbh200->qh_scan_next = fusbh200->async->qh_next.qh;
-	while (fusbh200->qh_scan_next) {
-		qh = fusbh200->qh_scan_next;
-		fusbh200->qh_scan_next = qh->qh_next.qh;
- rescan:
-		/* clean any finished work for this qh */
-		if (!list_empty(&qh->qtd_list)) {
-			int temp;
-
-			/*
-			 * Unlinks could happen here; completion reporting
-			 * drops the lock.  That's why fusbh200->qh_scan_next
-			 * always holds the next qh to scan; if the next qh
-			 * gets unlinked then fusbh200->qh_scan_next is adjusted
-			 * in single_unlink_async().
-			 */
-			temp = qh_completions(fusbh200, qh);
-			if (qh->needs_rescan) {
-				start_unlink_async(fusbh200, qh);
-			} else if (list_empty(&qh->qtd_list)
-					&& qh->qh_state == QH_STATE_LINKED) {
-				qh->unlink_cycle = fusbh200->async_unlink_cycle;
-				check_unlinks_later = true;
-			} else if (temp != 0)
-				goto rescan;
-		}
-	}
-
-	/*
-	 * Unlink empty entries, reducing DMA usage as well
-	 * as HCD schedule-scanning costs.  Delay for any qh
-	 * we just scanned, there's a not-unusual case that it
-	 * doesn't stay idle for long.
-	 */
-	if (check_unlinks_later && fusbh200->rh_state == FUSBH200_RH_RUNNING &&
-			!(fusbh200->enabled_hrtimer_events &
-				BIT(FUSBH200_HRTIMER_ASYNC_UNLINKS))) {
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_ASYNC_UNLINKS, true);
-		++fusbh200->async_unlink_cycle;
-	}
-}
-/*-------------------------------------------------------------------------*/
-/*
- * EHCI scheduled transaction support:  interrupt, iso, split iso
- * These are called "periodic" transactions in the EHCI spec.
- *
- * Note that for interrupt transfers, the QH/QTD manipulation is shared
- * with the "asynchronous" transaction support (control/bulk transfers).
- * The only real difference is in how interrupt transfers are scheduled.
- *
- * For ISO, we make an "iso_stream" head to serve the same role as a QH.
- * It keeps track of every ITD (or SITD) that's linked, and holds enough
- * pre-calculated schedule data to make appending to the queue be quick.
- */
-
-static int fusbh200_get_frame (struct usb_hcd *hcd);
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * periodic_next_shadow - return "next" pointer on shadow list
- * @periodic: host pointer to qh/itd
- * @tag: hardware tag for type of this record
- */
-static union fusbh200_shadow *
-periodic_next_shadow(struct fusbh200_hcd *fusbh200, union fusbh200_shadow *periodic,
-		__hc32 tag)
-{
-	switch (hc32_to_cpu(fusbh200, tag)) {
-	case Q_TYPE_QH:
-		return &periodic->qh->qh_next;
-	case Q_TYPE_FSTN:
-		return &periodic->fstn->fstn_next;
-	default:
-		return &periodic->itd->itd_next;
-	}
-}
-
-static __hc32 *
-shadow_next_periodic(struct fusbh200_hcd *fusbh200, union fusbh200_shadow *periodic,
-		__hc32 tag)
-{
-	switch (hc32_to_cpu(fusbh200, tag)) {
-	/* our fusbh200_shadow.qh is actually software part */
-	case Q_TYPE_QH:
-		return &periodic->qh->hw->hw_next;
-	/* others are hw parts */
-	default:
-		return periodic->hw_next;
-	}
-}
-
-/* caller must hold fusbh200->lock */
-static void periodic_unlink (struct fusbh200_hcd *fusbh200, unsigned frame, void *ptr)
-{
-	union fusbh200_shadow	*prev_p = &fusbh200->pshadow[frame];
-	__hc32			*hw_p = &fusbh200->periodic[frame];
-	union fusbh200_shadow	here = *prev_p;
-
-	/* find predecessor of "ptr"; hw and shadow lists are in sync */
-	while (here.ptr && here.ptr != ptr) {
-		prev_p = periodic_next_shadow(fusbh200, prev_p,
-				Q_NEXT_TYPE(fusbh200, *hw_p));
-		hw_p = shadow_next_periodic(fusbh200, &here,
-				Q_NEXT_TYPE(fusbh200, *hw_p));
-		here = *prev_p;
-	}
-	/* an interrupt entry (at list end) could have been shared */
-	if (!here.ptr)
-		return;
-
-	/* update shadow and hardware lists ... the old "next" pointers
-	 * from ptr may still be in use, the caller updates them.
-	 */
-	*prev_p = *periodic_next_shadow(fusbh200, &here,
-			Q_NEXT_TYPE(fusbh200, *hw_p));
-
-	*hw_p = *shadow_next_periodic(fusbh200, &here,
-				Q_NEXT_TYPE(fusbh200, *hw_p));
-}
-
-/* how many of the uframe's 125 usecs are allocated? */
-static unsigned short
-periodic_usecs (struct fusbh200_hcd *fusbh200, unsigned frame, unsigned uframe)
-{
-	__hc32			*hw_p = &fusbh200->periodic [frame];
-	union fusbh200_shadow	*q = &fusbh200->pshadow [frame];
-	unsigned		usecs = 0;
-	struct fusbh200_qh_hw	*hw;
-
-	while (q->ptr) {
-		switch (hc32_to_cpu(fusbh200, Q_NEXT_TYPE(fusbh200, *hw_p))) {
-		case Q_TYPE_QH:
-			hw = q->qh->hw;
-			/* is it in the S-mask? */
-			if (hw->hw_info2 & cpu_to_hc32(fusbh200, 1 << uframe))
-				usecs += q->qh->usecs;
-			/* ... or C-mask? */
-			if (hw->hw_info2 & cpu_to_hc32(fusbh200,
-					1 << (8 + uframe)))
-				usecs += q->qh->c_usecs;
-			hw_p = &hw->hw_next;
-			q = &q->qh->qh_next;
-			break;
-		// case Q_TYPE_FSTN:
-		default:
-			/* for "save place" FSTNs, count the relevant INTR
-			 * bandwidth from the previous frame
-			 */
-			if (q->fstn->hw_prev != FUSBH200_LIST_END(fusbh200)) {
-				fusbh200_dbg (fusbh200, "ignoring FSTN cost ...\n");
-			}
-			hw_p = &q->fstn->hw_next;
-			q = &q->fstn->fstn_next;
-			break;
-		case Q_TYPE_ITD:
-			if (q->itd->hw_transaction[uframe])
-				usecs += q->itd->stream->usecs;
-			hw_p = &q->itd->hw_next;
-			q = &q->itd->itd_next;
-			break;
-		}
-	}
-	if (usecs > fusbh200->uframe_periodic_max)
-		fusbh200_err (fusbh200, "uframe %d sched overrun: %d usecs\n",
-			frame * 8 + uframe, usecs);
-	return usecs;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int same_tt (struct usb_device *dev1, struct usb_device *dev2)
-{
-	if (!dev1->tt || !dev2->tt)
-		return 0;
-	if (dev1->tt != dev2->tt)
-		return 0;
-	if (dev1->tt->multi)
-		return dev1->ttport == dev2->ttport;
-	else
-		return 1;
-}
-
-/* return true iff the device's transaction translator is available
- * for a periodic transfer starting at the specified frame, using
- * all the uframes in the mask.
- */
-static int tt_no_collision (
-	struct fusbh200_hcd		*fusbh200,
-	unsigned		period,
-	struct usb_device	*dev,
-	unsigned		frame,
-	u32			uf_mask
-)
-{
-	if (period == 0)	/* error */
-		return 0;
-
-	/* note bandwidth wastage:  split never follows csplit
-	 * (different dev or endpoint) until the next uframe.
-	 * calling convention doesn't make that distinction.
-	 */
-	for (; frame < fusbh200->periodic_size; frame += period) {
-		union fusbh200_shadow	here;
-		__hc32			type;
-		struct fusbh200_qh_hw	*hw;
-
-		here = fusbh200->pshadow [frame];
-		type = Q_NEXT_TYPE(fusbh200, fusbh200->periodic [frame]);
-		while (here.ptr) {
-			switch (hc32_to_cpu(fusbh200, type)) {
-			case Q_TYPE_ITD:
-				type = Q_NEXT_TYPE(fusbh200, here.itd->hw_next);
-				here = here.itd->itd_next;
-				continue;
-			case Q_TYPE_QH:
-				hw = here.qh->hw;
-				if (same_tt (dev, here.qh->dev)) {
-					u32		mask;
-
-					mask = hc32_to_cpu(fusbh200,
-							hw->hw_info2);
-					/* "knows" no gap is needed */
-					mask |= mask >> 8;
-					if (mask & uf_mask)
-						break;
-				}
-				type = Q_NEXT_TYPE(fusbh200, hw->hw_next);
-				here = here.qh->qh_next;
-				continue;
-			// case Q_TYPE_FSTN:
-			default:
-				fusbh200_dbg (fusbh200,
-					"periodic frame %d bogus type %d\n",
-					frame, type);
-			}
-
-			/* collision or error */
-			return 0;
-		}
-	}
-
-	/* no collision */
-	return 1;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void enable_periodic(struct fusbh200_hcd *fusbh200)
-{
-	if (fusbh200->periodic_count++)
-		return;
-
-	/* Stop waiting to turn off the periodic schedule */
-	fusbh200->enabled_hrtimer_events &= ~BIT(FUSBH200_HRTIMER_DISABLE_PERIODIC);
-
-	/* Don't start the schedule until PSS is 0 */
-	fusbh200_poll_PSS(fusbh200);
-	turn_on_io_watchdog(fusbh200);
-}
-
-static void disable_periodic(struct fusbh200_hcd *fusbh200)
-{
-	if (--fusbh200->periodic_count)
-		return;
-
-	/* Don't turn off the schedule until PSS is 1 */
-	fusbh200_poll_PSS(fusbh200);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* periodic schedule slots have iso tds (normal or split) first, then a
- * sparse tree for active interrupt transfers.
- *
- * this just links in a qh; caller guarantees uframe masks are set right.
- * no FSTN support (yet; fusbh200 0.96+)
- */
-static void qh_link_periodic(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	unsigned	i;
-	unsigned	period = qh->period;
-
-	dev_dbg (&qh->dev->dev,
-		"link qh%d-%04x/%p start %d [%d/%d us]\n",
-		period, hc32_to_cpup(fusbh200, &qh->hw->hw_info2)
-			& (QH_CMASK | QH_SMASK),
-		qh, qh->start, qh->usecs, qh->c_usecs);
-
-	/* high bandwidth, or otherwise every microframe */
-	if (period == 0)
-		period = 1;
-
-	for (i = qh->start; i < fusbh200->periodic_size; i += period) {
-		union fusbh200_shadow	*prev = &fusbh200->pshadow[i];
-		__hc32			*hw_p = &fusbh200->periodic[i];
-		union fusbh200_shadow	here = *prev;
-		__hc32			type = 0;
-
-		/* skip the iso nodes at list head */
-		while (here.ptr) {
-			type = Q_NEXT_TYPE(fusbh200, *hw_p);
-			if (type == cpu_to_hc32(fusbh200, Q_TYPE_QH))
-				break;
-			prev = periodic_next_shadow(fusbh200, prev, type);
-			hw_p = shadow_next_periodic(fusbh200, &here, type);
-			here = *prev;
-		}
-
-		/* sorting each branch by period (slow-->fast)
-		 * enables sharing interior tree nodes
-		 */
-		while (here.ptr && qh != here.qh) {
-			if (qh->period > here.qh->period)
-				break;
-			prev = &here.qh->qh_next;
-			hw_p = &here.qh->hw->hw_next;
-			here = *prev;
-		}
-		/* link in this qh, unless some earlier pass did that */
-		if (qh != here.qh) {
-			qh->qh_next = here;
-			if (here.qh)
-				qh->hw->hw_next = *hw_p;
-			wmb ();
-			prev->qh = qh;
-			*hw_p = QH_NEXT (fusbh200, qh->qh_dma);
-		}
-	}
-	qh->qh_state = QH_STATE_LINKED;
-	qh->xacterrs = 0;
-
-	/* update per-qh bandwidth for usbfs */
-	fusbh200_to_hcd(fusbh200)->self.bandwidth_allocated += qh->period
-		? ((qh->usecs + qh->c_usecs) / qh->period)
-		: (qh->usecs * 8);
-
-	list_add(&qh->intr_node, &fusbh200->intr_qh_list);
-
-	/* maybe enable periodic schedule processing */
-	++fusbh200->intr_count;
-	enable_periodic(fusbh200);
-}
-
-static void qh_unlink_periodic(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	unsigned	i;
-	unsigned	period;
-
-	/*
-	 * If qh is for a low/full-speed device, simply unlinking it
-	 * could interfere with an ongoing split transaction.  To unlink
-	 * it safely would require setting the QH_INACTIVATE bit and
-	 * waiting at least one frame, as described in EHCI 4.12.2.5.
-	 *
-	 * We won't bother with any of this.  Instead, we assume that the
-	 * only reason for unlinking an interrupt QH while the current URB
-	 * is still active is to dequeue all the URBs (flush the whole
-	 * endpoint queue).
-	 *
-	 * If rebalancing the periodic schedule is ever implemented, this
-	 * approach will no longer be valid.
-	 */
-
-	/* high bandwidth, or otherwise part of every microframe */
-	if ((period = qh->period) == 0)
-		period = 1;
-
-	for (i = qh->start; i < fusbh200->periodic_size; i += period)
-		periodic_unlink (fusbh200, i, qh);
-
-	/* update per-qh bandwidth for usbfs */
-	fusbh200_to_hcd(fusbh200)->self.bandwidth_allocated -= qh->period
-		? ((qh->usecs + qh->c_usecs) / qh->period)
-		: (qh->usecs * 8);
-
-	dev_dbg (&qh->dev->dev,
-		"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
-		qh->period,
-		hc32_to_cpup(fusbh200, &qh->hw->hw_info2) & (QH_CMASK | QH_SMASK),
-		qh, qh->start, qh->usecs, qh->c_usecs);
-
-	/* qh->qh_next still "live" to HC */
-	qh->qh_state = QH_STATE_UNLINK;
-	qh->qh_next.ptr = NULL;
-
-	if (fusbh200->qh_scan_next == qh)
-		fusbh200->qh_scan_next = list_entry(qh->intr_node.next,
-				struct fusbh200_qh, intr_node);
-	list_del(&qh->intr_node);
-}
-
-static void start_unlink_intr(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	/* If the QH isn't linked then there's nothing we can do
-	 * unless we were called during a giveback, in which case
-	 * qh_completions() has to deal with it.
-	 */
-	if (qh->qh_state != QH_STATE_LINKED) {
-		if (qh->qh_state == QH_STATE_COMPLETING)
-			qh->needs_rescan = 1;
-		return;
-	}
-
-	qh_unlink_periodic (fusbh200, qh);
-
-	/* Make sure the unlinks are visible before starting the timer */
-	wmb();
-
-	/*
-	 * The EHCI spec doesn't say how long it takes the controller to
-	 * stop accessing an unlinked interrupt QH.  The timer delay is
-	 * 9 uframes; presumably that will be long enough.
-	 */
-	qh->unlink_cycle = fusbh200->intr_unlink_cycle;
-
-	/* New entries go at the end of the intr_unlink list */
-	if (fusbh200->intr_unlink)
-		fusbh200->intr_unlink_last->unlink_next = qh;
-	else
-		fusbh200->intr_unlink = qh;
-	fusbh200->intr_unlink_last = qh;
-
-	if (fusbh200->intr_unlinking)
-		;	/* Avoid recursive calls */
-	else if (fusbh200->rh_state < FUSBH200_RH_RUNNING)
-		fusbh200_handle_intr_unlinks(fusbh200);
-	else if (fusbh200->intr_unlink == qh) {
-		fusbh200_enable_event(fusbh200, FUSBH200_HRTIMER_UNLINK_INTR, true);
-		++fusbh200->intr_unlink_cycle;
-	}
-}
-
-static void end_unlink_intr(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	struct fusbh200_qh_hw	*hw = qh->hw;
-	int			rc;
-
-	qh->qh_state = QH_STATE_IDLE;
-	hw->hw_next = FUSBH200_LIST_END(fusbh200);
-
-	qh_completions(fusbh200, qh);
-
-	/* reschedule QH iff another request is queued */
-	if (!list_empty(&qh->qtd_list) && fusbh200->rh_state == FUSBH200_RH_RUNNING) {
-		rc = qh_schedule(fusbh200, qh);
-
-		/* An error here likely indicates handshake failure
-		 * or no space left in the schedule.  Neither fault
-		 * should happen often ...
-		 *
-		 * FIXME kill the now-dysfunctional queued urbs
-		 */
-		if (rc != 0)
-			fusbh200_err(fusbh200, "can't reschedule qh %p, err %d\n",
-					qh, rc);
-	}
-
-	/* maybe turn off periodic schedule */
-	--fusbh200->intr_count;
-	disable_periodic(fusbh200);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int check_period (
-	struct fusbh200_hcd *fusbh200,
-	unsigned	frame,
-	unsigned	uframe,
-	unsigned	period,
-	unsigned	usecs
-) {
-	int		claimed;
-
-	/* complete split running into next frame?
-	 * given FSTN support, we could sometimes check...
-	 */
-	if (uframe >= 8)
-		return 0;
-
-	/* convert "usecs we need" to "max already claimed" */
-	usecs = fusbh200->uframe_periodic_max - usecs;
-
-	/* we "know" 2 and 4 uframe intervals were rejected; so
-	 * for period 0, check _every_ microframe in the schedule.
-	 */
-	if (unlikely (period == 0)) {
-		do {
-			for (uframe = 0; uframe < 7; uframe++) {
-				claimed = periodic_usecs (fusbh200, frame, uframe);
-				if (claimed > usecs)
-					return 0;
-			}
-		} while ((frame += 1) < fusbh200->periodic_size);
-
-	/* just check the specified uframe, at that period */
-	} else {
-		do {
-			claimed = periodic_usecs (fusbh200, frame, uframe);
-			if (claimed > usecs)
-				return 0;
-		} while ((frame += period) < fusbh200->periodic_size);
-	}
-
-	// success!
-	return 1;
-}
-
-static int check_intr_schedule (
-	struct fusbh200_hcd		*fusbh200,
-	unsigned		frame,
-	unsigned		uframe,
-	const struct fusbh200_qh	*qh,
-	__hc32			*c_maskp
-)
-{
-	int		retval = -ENOSPC;
-	u8		mask = 0;
-
-	if (qh->c_usecs && uframe >= 6)		/* FSTN territory? */
-		goto done;
-
-	if (!check_period (fusbh200, frame, uframe, qh->period, qh->usecs))
-		goto done;
-	if (!qh->c_usecs) {
-		retval = 0;
-		*c_maskp = 0;
-		goto done;
-	}
-
-	/* Make sure this tt's buffer is also available for CSPLITs.
-	 * We pessimize a bit; probably the typical full speed case
-	 * doesn't need the second CSPLIT.
-	 *
-	 * NOTE:  both SPLIT and CSPLIT could be checked in just
-	 * one smart pass...
-	 */
-	mask = 0x03 << (uframe + qh->gap_uf);
-	*c_maskp = cpu_to_hc32(fusbh200, mask << 8);
-
-	mask |= 1 << uframe;
-	if (tt_no_collision (fusbh200, qh->period, qh->dev, frame, mask)) {
-		if (!check_period (fusbh200, frame, uframe + qh->gap_uf + 1,
-					qh->period, qh->c_usecs))
-			goto done;
-		if (!check_period (fusbh200, frame, uframe + qh->gap_uf,
-					qh->period, qh->c_usecs))
-			goto done;
-		retval = 0;
-	}
-done:
-	return retval;
-}
-
-/* "first fit" scheduling policy used the first time through,
- * or when the previous schedule slot can't be re-used.
- */
-static int qh_schedule(struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh)
-{
-	int		status;
-	unsigned	uframe;
-	__hc32		c_mask;
-	unsigned	frame;		/* 0..(qh->period - 1), or NO_FRAME */
-	struct fusbh200_qh_hw	*hw = qh->hw;
-
-	qh_refresh(fusbh200, qh);
-	hw->hw_next = FUSBH200_LIST_END(fusbh200);
-	frame = qh->start;
-
-	/* reuse the previous schedule slots, if we can */
-	if (frame < qh->period) {
-		uframe = ffs(hc32_to_cpup(fusbh200, &hw->hw_info2) & QH_SMASK);
-		status = check_intr_schedule (fusbh200, frame, --uframe,
-				qh, &c_mask);
-	} else {
-		uframe = 0;
-		c_mask = 0;
-		status = -ENOSPC;
-	}
-
-	/* else scan the schedule to find a group of slots such that all
-	 * uframes have enough periodic bandwidth available.
-	 */
-	if (status) {
-		/* "normal" case, uframing flexible except with splits */
-		if (qh->period) {
-			int		i;
-
-			for (i = qh->period; status && i > 0; --i) {
-				frame = ++fusbh200->random_frame % qh->period;
-				for (uframe = 0; uframe < 8; uframe++) {
-					status = check_intr_schedule (fusbh200,
-							frame, uframe, qh,
-							&c_mask);
-					if (status == 0)
-						break;
-				}
-			}
-
-		/* qh->period == 0 means every uframe */
-		} else {
-			frame = 0;
-			status = check_intr_schedule (fusbh200, 0, 0, qh, &c_mask);
-		}
-		if (status)
-			goto done;
-		qh->start = frame;
-
-		/* reset S-frame and (maybe) C-frame masks */
-		hw->hw_info2 &= cpu_to_hc32(fusbh200, ~(QH_CMASK | QH_SMASK));
-		hw->hw_info2 |= qh->period
-			? cpu_to_hc32(fusbh200, 1 << uframe)
-			: cpu_to_hc32(fusbh200, QH_SMASK);
-		hw->hw_info2 |= c_mask;
-	} else
-		fusbh200_dbg (fusbh200, "reused qh %p schedule\n", qh);
-
-	/* stuff into the periodic schedule */
-	qh_link_periodic(fusbh200, qh);
-done:
-	return status;
-}
-
-static int intr_submit (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	gfp_t			mem_flags
-) {
-	unsigned		epnum;
-	unsigned long		flags;
-	struct fusbh200_qh		*qh;
-	int			status;
-	struct list_head	empty;
-
-	/* get endpoint and transfer/schedule data */
-	epnum = urb->ep->desc.bEndpointAddress;
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-
-	if (unlikely(!HCD_HW_ACCESSIBLE(fusbh200_to_hcd(fusbh200)))) {
-		status = -ESHUTDOWN;
-		goto done_not_linked;
-	}
-	status = usb_hcd_link_urb_to_ep(fusbh200_to_hcd(fusbh200), urb);
-	if (unlikely(status))
-		goto done_not_linked;
-
-	/* get qh and force any scheduling errors */
-	INIT_LIST_HEAD (&empty);
-	qh = qh_append_tds(fusbh200, urb, &empty, epnum, &urb->ep->hcpriv);
-	if (qh == NULL) {
-		status = -ENOMEM;
-		goto done;
-	}
-	if (qh->qh_state == QH_STATE_IDLE) {
-		if ((status = qh_schedule (fusbh200, qh)) != 0)
-			goto done;
-	}
-
-	/* then queue the urb's tds to the qh */
-	qh = qh_append_tds(fusbh200, urb, qtd_list, epnum, &urb->ep->hcpriv);
-	BUG_ON (qh == NULL);
-
-	/* ... update usbfs periodic stats */
-	fusbh200_to_hcd(fusbh200)->self.bandwidth_int_reqs++;
-
-done:
-	if (unlikely(status))
-		usb_hcd_unlink_urb_from_ep(fusbh200_to_hcd(fusbh200), urb);
-done_not_linked:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	if (status)
-		qtd_list_free (fusbh200, urb, qtd_list);
-
-	return status;
-}
-
-static void scan_intr(struct fusbh200_hcd *fusbh200)
-{
-	struct fusbh200_qh		*qh;
-
-	list_for_each_entry_safe(qh, fusbh200->qh_scan_next, &fusbh200->intr_qh_list,
-			intr_node) {
- rescan:
-		/* clean any finished work for this qh */
-		if (!list_empty(&qh->qtd_list)) {
-			int temp;
-
-			/*
-			 * Unlinks could happen here; completion reporting
-			 * drops the lock.  That's why fusbh200->qh_scan_next
-			 * always holds the next qh to scan; if the next qh
-			 * gets unlinked then fusbh200->qh_scan_next is adjusted
-			 * in qh_unlink_periodic().
-			 */
-			temp = qh_completions(fusbh200, qh);
-			if (unlikely(qh->needs_rescan ||
-					(list_empty(&qh->qtd_list) &&
-						qh->qh_state == QH_STATE_LINKED)))
-				start_unlink_intr(fusbh200, qh);
-			else if (temp != 0)
-				goto rescan;
-		}
-	}
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* fusbh200_iso_stream ops work with both ITD and SITD */
-
-static struct fusbh200_iso_stream *
-iso_stream_alloc (gfp_t mem_flags)
-{
-	struct fusbh200_iso_stream *stream;
-
-	stream = kzalloc(sizeof *stream, mem_flags);
-	if (likely (stream != NULL)) {
-		INIT_LIST_HEAD(&stream->td_list);
-		INIT_LIST_HEAD(&stream->free_list);
-		stream->next_uframe = -1;
-	}
-	return stream;
-}
-
-static void
-iso_stream_init (
-	struct fusbh200_hcd		*fusbh200,
-	struct fusbh200_iso_stream	*stream,
-	struct usb_device	*dev,
-	int			pipe,
-	unsigned		interval
-)
-{
-	u32			buf1;
-	unsigned		epnum, maxp;
-	int			is_input;
-	long			bandwidth;
-	unsigned 		multi;
-
-	/*
-	 * this might be a "high bandwidth" highspeed endpoint,
-	 * as encoded in the ep descriptor's wMaxPacket field
-	 */
-	epnum = usb_pipeendpoint (pipe);
-	is_input = usb_pipein (pipe) ? USB_DIR_IN : 0;
-	maxp = usb_maxpacket(dev, pipe, !is_input);
-	if (is_input) {
-		buf1 = (1 << 11);
-	} else {
-		buf1 = 0;
-	}
-
-	maxp = max_packet(maxp);
-	multi = hb_mult(maxp);
-	buf1 |= maxp;
-	maxp *= multi;
-
-	stream->buf0 = cpu_to_hc32(fusbh200, (epnum << 8) | dev->devnum);
-	stream->buf1 = cpu_to_hc32(fusbh200, buf1);
-	stream->buf2 = cpu_to_hc32(fusbh200, multi);
-
-	/* usbfs wants to report the average usecs per frame tied up
-	 * when transfers on this endpoint are scheduled ...
-	 */
-	if (dev->speed == USB_SPEED_FULL) {
-		interval <<= 3;
-		stream->usecs = NS_TO_US(usb_calc_bus_time(dev->speed,
-				is_input, 1, maxp));
-		stream->usecs /= 8;
-	} else {
-		stream->highspeed = 1;
-		stream->usecs = HS_USECS_ISO (maxp);
-	}
-	bandwidth = stream->usecs * 8;
-	bandwidth /= interval;
-
-	stream->bandwidth = bandwidth;
-	stream->udev = dev;
-	stream->bEndpointAddress = is_input | epnum;
-	stream->interval = interval;
-	stream->maxp = maxp;
-}
-
-static struct fusbh200_iso_stream *
-iso_stream_find (struct fusbh200_hcd *fusbh200, struct urb *urb)
-{
-	unsigned		epnum;
-	struct fusbh200_iso_stream	*stream;
-	struct usb_host_endpoint *ep;
-	unsigned long		flags;
-
-	epnum = usb_pipeendpoint (urb->pipe);
-	if (usb_pipein(urb->pipe))
-		ep = urb->dev->ep_in[epnum];
-	else
-		ep = urb->dev->ep_out[epnum];
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	stream = ep->hcpriv;
-
-	if (unlikely (stream == NULL)) {
-		stream = iso_stream_alloc(GFP_ATOMIC);
-		if (likely (stream != NULL)) {
-			ep->hcpriv = stream;
-			stream->ep = ep;
-			iso_stream_init(fusbh200, stream, urb->dev, urb->pipe,
-					urb->interval);
-		}
-
-	/* if dev->ep [epnum] is a QH, hw is set */
-	} else if (unlikely (stream->hw != NULL)) {
-		fusbh200_dbg (fusbh200, "dev %s ep%d%s, not iso??\n",
-			urb->dev->devpath, epnum,
-			usb_pipein(urb->pipe) ? "in" : "out");
-		stream = NULL;
-	}
-
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	return stream;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* fusbh200_iso_sched ops can be ITD-only or SITD-only */
-
-static struct fusbh200_iso_sched *
-iso_sched_alloc (unsigned packets, gfp_t mem_flags)
-{
-	struct fusbh200_iso_sched	*iso_sched;
-	int			size = sizeof *iso_sched;
-
-	size += packets * sizeof (struct fusbh200_iso_packet);
-	iso_sched = kzalloc(size, mem_flags);
-	if (likely (iso_sched != NULL)) {
-		INIT_LIST_HEAD (&iso_sched->td_list);
-	}
-	return iso_sched;
-}
-
-static inline void
-itd_sched_init(
-	struct fusbh200_hcd		*fusbh200,
-	struct fusbh200_iso_sched	*iso_sched,
-	struct fusbh200_iso_stream	*stream,
-	struct urb		*urb
-)
-{
-	unsigned	i;
-	dma_addr_t	dma = urb->transfer_dma;
-
-	/* how many uframes are needed for these transfers */
-	iso_sched->span = urb->number_of_packets * stream->interval;
-
-	/* figure out per-uframe itd fields that we'll need later
-	 * when we fit new itds into the schedule.
-	 */
-	for (i = 0; i < urb->number_of_packets; i++) {
-		struct fusbh200_iso_packet	*uframe = &iso_sched->packet [i];
-		unsigned		length;
-		dma_addr_t		buf;
-		u32			trans;
-
-		length = urb->iso_frame_desc [i].length;
-		buf = dma + urb->iso_frame_desc [i].offset;
-
-		trans = FUSBH200_ISOC_ACTIVE;
-		trans |= buf & 0x0fff;
-		if (unlikely (((i + 1) == urb->number_of_packets))
-				&& !(urb->transfer_flags & URB_NO_INTERRUPT))
-			trans |= FUSBH200_ITD_IOC;
-		trans |= length << 16;
-		uframe->transaction = cpu_to_hc32(fusbh200, trans);
-
-		/* might need to cross a buffer page within a uframe */
-		uframe->bufp = (buf & ~(u64)0x0fff);
-		buf += length;
-		if (unlikely ((uframe->bufp != (buf & ~(u64)0x0fff))))
-			uframe->cross = 1;
-	}
-}
-
-static void
-iso_sched_free (
-	struct fusbh200_iso_stream	*stream,
-	struct fusbh200_iso_sched	*iso_sched
-)
-{
-	if (!iso_sched)
-		return;
-	// caller must hold fusbh200->lock!
-	list_splice (&iso_sched->td_list, &stream->free_list);
-	kfree (iso_sched);
-}
-
-static int
-itd_urb_transaction (
-	struct fusbh200_iso_stream	*stream,
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	gfp_t			mem_flags
-)
-{
-	struct fusbh200_itd		*itd;
-	dma_addr_t		itd_dma;
-	int			i;
-	unsigned		num_itds;
-	struct fusbh200_iso_sched	*sched;
-	unsigned long		flags;
-
-	sched = iso_sched_alloc (urb->number_of_packets, mem_flags);
-	if (unlikely (sched == NULL))
-		return -ENOMEM;
-
-	itd_sched_init(fusbh200, sched, stream, urb);
-
-	if (urb->interval < 8)
-		num_itds = 1 + (sched->span + 7) / 8;
-	else
-		num_itds = urb->number_of_packets;
-
-	/* allocate/init ITDs */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	for (i = 0; i < num_itds; i++) {
-
-		/*
-		 * Use iTDs from the free list, but not iTDs that may
-		 * still be in use by the hardware.
-		 */
-		if (likely(!list_empty(&stream->free_list))) {
-			itd = list_first_entry(&stream->free_list,
-					struct fusbh200_itd, itd_list);
-			if (itd->frame == fusbh200->now_frame)
-				goto alloc_itd;
-			list_del (&itd->itd_list);
-			itd_dma = itd->itd_dma;
-		} else {
- alloc_itd:
-			spin_unlock_irqrestore (&fusbh200->lock, flags);
-			itd = dma_pool_alloc (fusbh200->itd_pool, mem_flags,
-					&itd_dma);
-			spin_lock_irqsave (&fusbh200->lock, flags);
-			if (!itd) {
-				iso_sched_free(stream, sched);
-				spin_unlock_irqrestore(&fusbh200->lock, flags);
-				return -ENOMEM;
-			}
-		}
-
-		memset (itd, 0, sizeof *itd);
-		itd->itd_dma = itd_dma;
-		list_add (&itd->itd_list, &sched->td_list);
-	}
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-
-	/* temporarily store schedule info in hcpriv */
-	urb->hcpriv = sched;
-	urb->error_count = 0;
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static inline int
-itd_slot_ok (
-	struct fusbh200_hcd		*fusbh200,
-	u32			mod,
-	u32			uframe,
-	u8			usecs,
-	u32			period
-)
-{
-	uframe %= period;
-	do {
-		/* can't commit more than uframe_periodic_max usec */
-		if (periodic_usecs (fusbh200, uframe >> 3, uframe & 0x7)
-				> (fusbh200->uframe_periodic_max - usecs))
-			return 0;
-
-		/* we know urb->interval is 2^N uframes */
-		uframe += period;
-	} while (uframe < mod);
-	return 1;
-}
-
-/*
- * This scheduler plans almost as far into the future as it has actual
- * periodic schedule slots.  (Affected by TUNE_FLS, which defaults to
- * "as small as possible" to be cache-friendlier.)  That limits the size
- * transfers you can stream reliably; avoid more than 64 msec per urb.
- * Also avoid queue depths of less than fusbh200's worst irq latency (affected
- * by the per-urb URB_NO_INTERRUPT hint, the log2_irq_thresh module parameter,
- * and other factors); or more than about 230 msec total (for portability,
- * given FUSBH200_TUNE_FLS and the slop).  Or, write a smarter scheduler!
- */
-
-#define SCHEDULE_SLOP	80	/* microframes */
-
-static int
-iso_stream_schedule (
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	struct fusbh200_iso_stream	*stream
-)
-{
-	u32			now, next, start, period, span;
-	int			status;
-	unsigned		mod = fusbh200->periodic_size << 3;
-	struct fusbh200_iso_sched	*sched = urb->hcpriv;
-
-	period = urb->interval;
-	span = sched->span;
-
-	if (span > mod - SCHEDULE_SLOP) {
-		fusbh200_dbg (fusbh200, "iso request %p too long\n", urb);
-		status = -EFBIG;
-		goto fail;
-	}
-
-	now = fusbh200_read_frame_index(fusbh200) & (mod - 1);
-
-	/* Typical case: reuse current schedule, stream is still active.
-	 * Hopefully there are no gaps from the host falling behind
-	 * (irq delays etc), but if there are we'll take the next
-	 * slot in the schedule, implicitly assuming URB_ISO_ASAP.
-	 */
-	if (likely (!list_empty (&stream->td_list))) {
-		u32	excess;
-
-		/* For high speed devices, allow scheduling within the
-		 * isochronous scheduling threshold.  For full speed devices
-		 * and Intel PCI-based controllers, don't (work around for
-		 * Intel ICH9 bug).
-		 */
-		if (!stream->highspeed && fusbh200->fs_i_thresh)
-			next = now + fusbh200->i_thresh;
-		else
-			next = now;
-
-		/* Fell behind (by up to twice the slop amount)?
-		 * We decide based on the time of the last currently-scheduled
-		 * slot, not the time of the next available slot.
-		 */
-		excess = (stream->next_uframe - period - next) & (mod - 1);
-		if (excess >= mod - 2 * SCHEDULE_SLOP)
-			start = next + excess - mod + period *
-					DIV_ROUND_UP(mod - excess, period);
-		else
-			start = next + excess + period;
-		if (start - now >= mod) {
-			fusbh200_dbg(fusbh200, "request %p would overflow (%d+%d >= %d)\n",
-					urb, start - now - period, period,
-					mod);
-			status = -EFBIG;
-			goto fail;
-		}
-	}
-
-	/* need to schedule; when's the next (u)frame we could start?
-	 * this is bigger than fusbh200->i_thresh allows; scheduling itself
-	 * isn't free, the slop should handle reasonably slow cpus.  it
-	 * can also help high bandwidth if the dma and irq loads don't
-	 * jump until after the queue is primed.
-	 */
-	else {
-		int done = 0;
-		start = SCHEDULE_SLOP + (now & ~0x07);
-
-		/* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */
-
-		/* find a uframe slot with enough bandwidth.
-		 * Early uframes are more precious because full-speed
-		 * iso IN transfers can't use late uframes,
-		 * and therefore they should be allocated last.
-		 */
-		next = start;
-		start += period;
-		do {
-			start--;
-			/* check schedule: enough space? */
-			if (itd_slot_ok(fusbh200, mod, start,
-					stream->usecs, period))
-				done = 1;
-		} while (start > next && !done);
-
-		/* no room in the schedule */
-		if (!done) {
-			fusbh200_dbg(fusbh200, "iso resched full %p (now %d max %d)\n",
-				urb, now, now + mod);
-			status = -ENOSPC;
-			goto fail;
-		}
-	}
-
-	/* Tried to schedule too far into the future? */
-	if (unlikely(start - now + span - period
-				>= mod - 2 * SCHEDULE_SLOP)) {
-		fusbh200_dbg(fusbh200, "request %p would overflow (%d+%d >= %d)\n",
-				urb, start - now, span - period,
-				mod - 2 * SCHEDULE_SLOP);
-		status = -EFBIG;
-		goto fail;
-	}
-
-	stream->next_uframe = start & (mod - 1);
-
-	/* report high speed start in uframes; full speed, in frames */
-	urb->start_frame = stream->next_uframe;
-	if (!stream->highspeed)
-		urb->start_frame >>= 3;
-
-	/* Make sure scan_isoc() sees these */
-	if (fusbh200->isoc_count == 0)
-		fusbh200->next_frame = now >> 3;
-	return 0;
-
- fail:
-	iso_sched_free(stream, sched);
-	urb->hcpriv = NULL;
-	return status;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static inline void
-itd_init(struct fusbh200_hcd *fusbh200, struct fusbh200_iso_stream *stream,
-		struct fusbh200_itd *itd)
-{
-	int i;
-
-	/* it's been recently zeroed */
-	itd->hw_next = FUSBH200_LIST_END(fusbh200);
-	itd->hw_bufp [0] = stream->buf0;
-	itd->hw_bufp [1] = stream->buf1;
-	itd->hw_bufp [2] = stream->buf2;
-
-	for (i = 0; i < 8; i++)
-		itd->index[i] = -1;
-
-	/* All other fields are filled when scheduling */
-}
-
-static inline void
-itd_patch(
-	struct fusbh200_hcd		*fusbh200,
-	struct fusbh200_itd		*itd,
-	struct fusbh200_iso_sched	*iso_sched,
-	unsigned		index,
-	u16			uframe
-)
-{
-	struct fusbh200_iso_packet	*uf = &iso_sched->packet [index];
-	unsigned		pg = itd->pg;
-
-	// BUG_ON (pg == 6 && uf->cross);
-
-	uframe &= 0x07;
-	itd->index [uframe] = index;
-
-	itd->hw_transaction[uframe] = uf->transaction;
-	itd->hw_transaction[uframe] |= cpu_to_hc32(fusbh200, pg << 12);
-	itd->hw_bufp[pg] |= cpu_to_hc32(fusbh200, uf->bufp & ~(u32)0);
-	itd->hw_bufp_hi[pg] |= cpu_to_hc32(fusbh200, (u32)(uf->bufp >> 32));
-
-	/* iso_frame_desc[].offset must be strictly increasing */
-	if (unlikely (uf->cross)) {
-		u64	bufp = uf->bufp + 4096;
-
-		itd->pg = ++pg;
-		itd->hw_bufp[pg] |= cpu_to_hc32(fusbh200, bufp & ~(u32)0);
-		itd->hw_bufp_hi[pg] |= cpu_to_hc32(fusbh200, (u32)(bufp >> 32));
-	}
-}
-
-static inline void
-itd_link (struct fusbh200_hcd *fusbh200, unsigned frame, struct fusbh200_itd *itd)
-{
-	union fusbh200_shadow	*prev = &fusbh200->pshadow[frame];
-	__hc32			*hw_p = &fusbh200->periodic[frame];
-	union fusbh200_shadow	here = *prev;
-	__hc32			type = 0;
-
-	/* skip any iso nodes which might belong to previous microframes */
-	while (here.ptr) {
-		type = Q_NEXT_TYPE(fusbh200, *hw_p);
-		if (type == cpu_to_hc32(fusbh200, Q_TYPE_QH))
-			break;
-		prev = periodic_next_shadow(fusbh200, prev, type);
-		hw_p = shadow_next_periodic(fusbh200, &here, type);
-		here = *prev;
-	}
-
-	itd->itd_next = here;
-	itd->hw_next = *hw_p;
-	prev->itd = itd;
-	itd->frame = frame;
-	wmb ();
-	*hw_p = cpu_to_hc32(fusbh200, itd->itd_dma | Q_TYPE_ITD);
-}
-
-/* fit urb's itds into the selected schedule slot; activate as needed */
-static void itd_link_urb(
-	struct fusbh200_hcd		*fusbh200,
-	struct urb		*urb,
-	unsigned		mod,
-	struct fusbh200_iso_stream	*stream
-)
-{
-	int			packet;
-	unsigned		next_uframe, uframe, frame;
-	struct fusbh200_iso_sched	*iso_sched = urb->hcpriv;
-	struct fusbh200_itd		*itd;
-
-	next_uframe = stream->next_uframe & (mod - 1);
-
-	if (unlikely (list_empty(&stream->td_list))) {
-		fusbh200_to_hcd(fusbh200)->self.bandwidth_allocated
-				+= stream->bandwidth;
-		fusbh200_dbg(fusbh200,
-			"schedule devp %s ep%d%s-iso period %d start %d.%d\n",
-			urb->dev->devpath, stream->bEndpointAddress & 0x0f,
-			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
-			urb->interval,
-			next_uframe >> 3, next_uframe & 0x7);
-	}
-
-	/* fill iTDs uframe by uframe */
-	for (packet = 0, itd = NULL; packet < urb->number_of_packets; ) {
-		if (itd == NULL) {
-			/* ASSERT:  we have all necessary itds */
-			// BUG_ON (list_empty (&iso_sched->td_list));
-
-			/* ASSERT:  no itds for this endpoint in this uframe */
-
-			itd = list_entry (iso_sched->td_list.next,
-					struct fusbh200_itd, itd_list);
-			list_move_tail (&itd->itd_list, &stream->td_list);
-			itd->stream = stream;
-			itd->urb = urb;
-			itd_init (fusbh200, stream, itd);
-		}
-
-		uframe = next_uframe & 0x07;
-		frame = next_uframe >> 3;
-
-		itd_patch(fusbh200, itd, iso_sched, packet, uframe);
-
-		next_uframe += stream->interval;
-		next_uframe &= mod - 1;
-		packet++;
-
-		/* link completed itds into the schedule */
-		if (((next_uframe >> 3) != frame)
-				|| packet == urb->number_of_packets) {
-			itd_link(fusbh200, frame & (fusbh200->periodic_size - 1), itd);
-			itd = NULL;
-		}
-	}
-	stream->next_uframe = next_uframe;
-
-	/* don't need that schedule data any more */
-	iso_sched_free (stream, iso_sched);
-	urb->hcpriv = NULL;
-
-	++fusbh200->isoc_count;
-	enable_periodic(fusbh200);
-}
-
-#define	ISO_ERRS (FUSBH200_ISOC_BUF_ERR | FUSBH200_ISOC_BABBLE | FUSBH200_ISOC_XACTERR)
-
-/* Process and recycle a completed ITD.  Return true iff its urb completed,
- * and hence its completion callback probably added things to the hardware
- * schedule.
- *
- * Note that we carefully avoid recycling this descriptor until after any
- * completion callback runs, so that it won't be reused quickly.  That is,
- * assuming (a) no more than two urbs per frame on this endpoint, and also
- * (b) only this endpoint's completions submit URBs.  It seems some silicon
- * corrupts things if you reuse completed descriptors very quickly...
- */
-static bool itd_complete(struct fusbh200_hcd *fusbh200, struct fusbh200_itd *itd)
-{
-	struct urb				*urb = itd->urb;
-	struct usb_iso_packet_descriptor	*desc;
-	u32					t;
-	unsigned				uframe;
-	int					urb_index = -1;
-	struct fusbh200_iso_stream			*stream = itd->stream;
-	struct usb_device			*dev;
-	bool					retval = false;
-
-	/* for each uframe with a packet */
-	for (uframe = 0; uframe < 8; uframe++) {
-		if (likely (itd->index[uframe] == -1))
-			continue;
-		urb_index = itd->index[uframe];
-		desc = &urb->iso_frame_desc [urb_index];
-
-		t = hc32_to_cpup(fusbh200, &itd->hw_transaction [uframe]);
-		itd->hw_transaction [uframe] = 0;
-
-		/* report transfer status */
-		if (unlikely (t & ISO_ERRS)) {
-			urb->error_count++;
-			if (t & FUSBH200_ISOC_BUF_ERR)
-				desc->status = usb_pipein (urb->pipe)
-					? -ENOSR  /* hc couldn't read */
-					: -ECOMM; /* hc couldn't write */
-			else if (t & FUSBH200_ISOC_BABBLE)
-				desc->status = -EOVERFLOW;
-			else /* (t & FUSBH200_ISOC_XACTERR) */
-				desc->status = -EPROTO;
-
-			/* HC need not update length with this error */
-			if (!(t & FUSBH200_ISOC_BABBLE)) {
-				desc->actual_length = fusbh200_itdlen(urb, desc, t);
-				urb->actual_length += desc->actual_length;
-			}
-		} else if (likely ((t & FUSBH200_ISOC_ACTIVE) == 0)) {
-			desc->status = 0;
-			desc->actual_length = fusbh200_itdlen(urb, desc, t);
-			urb->actual_length += desc->actual_length;
-		} else {
-			/* URB was too late */
-			desc->status = -EXDEV;
-		}
-	}
-
-	/* handle completion now? */
-	if (likely ((urb_index + 1) != urb->number_of_packets))
-		goto done;
-
-	/* ASSERT: it's really the last itd for this urb
-	list_for_each_entry (itd, &stream->td_list, itd_list)
-		BUG_ON (itd->urb == urb);
-	 */
-
-	/* give urb back to the driver; completion often (re)submits */
-	dev = urb->dev;
-	fusbh200_urb_done(fusbh200, urb, 0);
-	retval = true;
-	urb = NULL;
-
-	--fusbh200->isoc_count;
-	disable_periodic(fusbh200);
-
-	if (unlikely(list_is_singular(&stream->td_list))) {
-		fusbh200_to_hcd(fusbh200)->self.bandwidth_allocated
-				-= stream->bandwidth;
-		fusbh200_dbg(fusbh200,
-			"deschedule devp %s ep%d%s-iso\n",
-			dev->devpath, stream->bEndpointAddress & 0x0f,
-			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
-	}
-
-done:
-	itd->urb = NULL;
-
-	/* Add to the end of the free list for later reuse */
-	list_move_tail(&itd->itd_list, &stream->free_list);
-
-	/* Recycle the iTDs when the pipeline is empty (ep no longer in use) */
-	if (list_empty(&stream->td_list)) {
-		list_splice_tail_init(&stream->free_list,
-				&fusbh200->cached_itd_list);
-		start_free_itds(fusbh200);
-	}
-
-	return retval;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int itd_submit (struct fusbh200_hcd *fusbh200, struct urb *urb,
-	gfp_t mem_flags)
-{
-	int			status = -EINVAL;
-	unsigned long		flags;
-	struct fusbh200_iso_stream	*stream;
-
-	/* Get iso_stream head */
-	stream = iso_stream_find (fusbh200, urb);
-	if (unlikely (stream == NULL)) {
-		fusbh200_dbg (fusbh200, "can't get iso stream\n");
-		return -ENOMEM;
-	}
-	if (unlikely (urb->interval != stream->interval &&
-		      fusbh200_port_speed(fusbh200, 0) == USB_PORT_STAT_HIGH_SPEED)) {
-			fusbh200_dbg (fusbh200, "can't change iso interval %d --> %d\n",
-				stream->interval, urb->interval);
-			goto done;
-	}
-
-#ifdef FUSBH200_URB_TRACE
-	fusbh200_dbg (fusbh200,
-		"%s %s urb %p ep%d%s len %d, %d pkts %d uframes [%p]\n",
-		__func__, urb->dev->devpath, urb,
-		usb_pipeendpoint (urb->pipe),
-		usb_pipein (urb->pipe) ? "in" : "out",
-		urb->transfer_buffer_length,
-		urb->number_of_packets, urb->interval,
-		stream);
-#endif
-
-	/* allocate ITDs w/o locking anything */
-	status = itd_urb_transaction (stream, fusbh200, urb, mem_flags);
-	if (unlikely (status < 0)) {
-		fusbh200_dbg (fusbh200, "can't init itds\n");
-		goto done;
-	}
-
-	/* schedule ... need to lock */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	if (unlikely(!HCD_HW_ACCESSIBLE(fusbh200_to_hcd(fusbh200)))) {
-		status = -ESHUTDOWN;
-		goto done_not_linked;
-	}
-	status = usb_hcd_link_urb_to_ep(fusbh200_to_hcd(fusbh200), urb);
-	if (unlikely(status))
-		goto done_not_linked;
-	status = iso_stream_schedule(fusbh200, urb, stream);
-	if (likely (status == 0))
-		itd_link_urb (fusbh200, urb, fusbh200->periodic_size << 3, stream);
-	else
-		usb_hcd_unlink_urb_from_ep(fusbh200_to_hcd(fusbh200), urb);
- done_not_linked:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
- done:
-	return status;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void scan_isoc(struct fusbh200_hcd *fusbh200)
-{
-	unsigned	uf, now_frame, frame;
-	unsigned	fmask = fusbh200->periodic_size - 1;
-	bool		modified, live;
-
-	/*
-	 * When running, scan from last scan point up to "now"
-	 * else clean up by scanning everything that's left.
-	 * Touches as few pages as possible:  cache-friendly.
-	 */
-	if (fusbh200->rh_state >= FUSBH200_RH_RUNNING) {
-		uf = fusbh200_read_frame_index(fusbh200);
-		now_frame = (uf >> 3) & fmask;
-		live = true;
-	} else  {
-		now_frame = (fusbh200->next_frame - 1) & fmask;
-		live = false;
-	}
-	fusbh200->now_frame = now_frame;
-
-	frame = fusbh200->next_frame;
-	for (;;) {
-		union fusbh200_shadow	q, *q_p;
-		__hc32			type, *hw_p;
-
-restart:
-		/* scan each element in frame's queue for completions */
-		q_p = &fusbh200->pshadow [frame];
-		hw_p = &fusbh200->periodic [frame];
-		q.ptr = q_p->ptr;
-		type = Q_NEXT_TYPE(fusbh200, *hw_p);
-		modified = false;
-
-		while (q.ptr != NULL) {
-			switch (hc32_to_cpu(fusbh200, type)) {
-			case Q_TYPE_ITD:
-				/* If this ITD is still active, leave it for
-				 * later processing ... check the next entry.
-				 * No need to check for activity unless the
-				 * frame is current.
-				 */
-				if (frame == now_frame && live) {
-					rmb();
-					for (uf = 0; uf < 8; uf++) {
-						if (q.itd->hw_transaction[uf] &
-							    ITD_ACTIVE(fusbh200))
-							break;
-					}
-					if (uf < 8) {
-						q_p = &q.itd->itd_next;
-						hw_p = &q.itd->hw_next;
-						type = Q_NEXT_TYPE(fusbh200,
-							q.itd->hw_next);
-						q = *q_p;
-						break;
-					}
-				}
-
-				/* Take finished ITDs out of the schedule
-				 * and process them:  recycle, maybe report
-				 * URB completion.  HC won't cache the
-				 * pointer for much longer, if at all.
-				 */
-				*q_p = q.itd->itd_next;
-				*hw_p = q.itd->hw_next;
-				type = Q_NEXT_TYPE(fusbh200, q.itd->hw_next);
-				wmb();
-				modified = itd_complete (fusbh200, q.itd);
-				q = *q_p;
-				break;
-			default:
-				fusbh200_dbg(fusbh200, "corrupt type %d frame %d shadow %p\n",
-					type, frame, q.ptr);
-				// BUG ();
-				/* FALL THROUGH */
-			case Q_TYPE_QH:
-			case Q_TYPE_FSTN:
-				/* End of the iTDs and siTDs */
-				q.ptr = NULL;
-				break;
-			}
-
-			/* assume completion callbacks modify the queue */
-			if (unlikely(modified && fusbh200->isoc_count > 0))
-				goto restart;
-		}
-
-		/* Stop when we have reached the current frame */
-		if (frame == now_frame)
-			break;
-		frame = (frame + 1) & fmask;
-	}
-	fusbh200->next_frame = now_frame;
-}
-/*-------------------------------------------------------------------------*/
-/*
- * Display / Set uframe_periodic_max
- */
-static ssize_t show_uframe_periodic_max(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
-{
-	struct fusbh200_hcd		*fusbh200;
-	int			n;
-
-	fusbh200 = hcd_to_fusbh200(bus_to_hcd(dev_get_drvdata(dev)));
-	n = scnprintf(buf, PAGE_SIZE, "%d\n", fusbh200->uframe_periodic_max);
-	return n;
-}
-
-
-static ssize_t store_uframe_periodic_max(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf, size_t count)
-{
-	struct fusbh200_hcd		*fusbh200;
-	unsigned		uframe_periodic_max;
-	unsigned		frame, uframe;
-	unsigned short		allocated_max;
-	unsigned long		flags;
-	ssize_t			ret;
-
-	fusbh200 = hcd_to_fusbh200(bus_to_hcd(dev_get_drvdata(dev)));
-	if (kstrtouint(buf, 0, &uframe_periodic_max) < 0)
-		return -EINVAL;
-
-	if (uframe_periodic_max < 100 || uframe_periodic_max >= 125) {
-		fusbh200_info(fusbh200, "rejecting invalid request for "
-				"uframe_periodic_max=%u\n", uframe_periodic_max);
-		return -EINVAL;
-	}
-
-	ret = -EINVAL;
-
-	/*
-	 * lock, so that our checking does not race with possible periodic
-	 * bandwidth allocation through submitting new urbs.
-	 */
-	spin_lock_irqsave (&fusbh200->lock, flags);
-
-	/*
-	 * for request to decrease max periodic bandwidth, we have to check
-	 * every microframe in the schedule to see whether the decrease is
-	 * possible.
-	 */
-	if (uframe_periodic_max < fusbh200->uframe_periodic_max) {
-		allocated_max = 0;
-
-		for (frame = 0; frame < fusbh200->periodic_size; ++frame)
-			for (uframe = 0; uframe < 7; ++uframe)
-				allocated_max = max(allocated_max,
-						    periodic_usecs (fusbh200, frame, uframe));
-
-		if (allocated_max > uframe_periodic_max) {
-			fusbh200_info(fusbh200,
-				"cannot decrease uframe_periodic_max because "
-				"periodic bandwidth is already allocated "
-				"(%u > %u)\n",
-				allocated_max, uframe_periodic_max);
-			goto out_unlock;
-		}
-	}
-
-	/* increasing is always ok */
-
-	fusbh200_info(fusbh200, "setting max periodic bandwidth to %u%% "
-			"(== %u usec/uframe)\n",
-			100*uframe_periodic_max/125, uframe_periodic_max);
-
-	if (uframe_periodic_max != 100)
-		fusbh200_warn(fusbh200, "max periodic bandwidth set is non-standard\n");
-
-	fusbh200->uframe_periodic_max = uframe_periodic_max;
-	ret = count;
-
-out_unlock:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	return ret;
-}
-static DEVICE_ATTR(uframe_periodic_max, 0644, show_uframe_periodic_max, store_uframe_periodic_max);
-
-
-static inline int create_sysfs_files(struct fusbh200_hcd *fusbh200)
-{
-	struct device	*controller = fusbh200_to_hcd(fusbh200)->self.controller;
-	int	i = 0;
-
-	if (i)
-		goto out;
-
-	i = device_create_file(controller, &dev_attr_uframe_periodic_max);
-out:
-	return i;
-}
-
-static inline void remove_sysfs_files(struct fusbh200_hcd *fusbh200)
-{
-	struct device	*controller = fusbh200_to_hcd(fusbh200)->self.controller;
-
-	device_remove_file(controller, &dev_attr_uframe_periodic_max);
-}
-/*-------------------------------------------------------------------------*/
-
-/* On some systems, leaving remote wakeup enabled prevents system shutdown.
- * The firmware seems to think that powering off is a wakeup event!
- * This routine turns off remote wakeup and everything else, on all ports.
- */
-static void fusbh200_turn_off_all_ports(struct fusbh200_hcd *fusbh200)
-{
-	u32 __iomem *status_reg = &fusbh200->regs->port_status;
-
-	fusbh200_writel(fusbh200, PORT_RWC_BITS, status_reg);
-}
-
-/*
- * Halt HC, turn off all ports, and let the BIOS use the companion controllers.
- * Must be called with interrupts enabled and the lock not held.
- */
-static void fusbh200_silence_controller(struct fusbh200_hcd *fusbh200)
-{
-	fusbh200_halt(fusbh200);
-
-	spin_lock_irq(&fusbh200->lock);
-	fusbh200->rh_state = FUSBH200_RH_HALTED;
-	fusbh200_turn_off_all_ports(fusbh200);
-	spin_unlock_irq(&fusbh200->lock);
-}
-
-/* fusbh200_shutdown kick in for silicon on any bus (not just pci, etc).
- * This forcibly disables dma and IRQs, helping kexec and other cases
- * where the next system software may expect clean state.
- */
-static void fusbh200_shutdown(struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd	*fusbh200 = hcd_to_fusbh200(hcd);
-
-	spin_lock_irq(&fusbh200->lock);
-	fusbh200->shutdown = true;
-	fusbh200->rh_state = FUSBH200_RH_STOPPING;
-	fusbh200->enabled_hrtimer_events = 0;
-	spin_unlock_irq(&fusbh200->lock);
-
-	fusbh200_silence_controller(fusbh200);
-
-	hrtimer_cancel(&fusbh200->hrtimer);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * fusbh200_work is called from some interrupts, timers, and so on.
- * it calls driver completion functions, after dropping fusbh200->lock.
- */
-static void fusbh200_work (struct fusbh200_hcd *fusbh200)
-{
-	/* another CPU may drop fusbh200->lock during a schedule scan while
-	 * it reports urb completions.  this flag guards against bogus
-	 * attempts at re-entrant schedule scanning.
-	 */
-	if (fusbh200->scanning) {
-		fusbh200->need_rescan = true;
-		return;
-	}
-	fusbh200->scanning = true;
-
- rescan:
-	fusbh200->need_rescan = false;
-	if (fusbh200->async_count)
-		scan_async(fusbh200);
-	if (fusbh200->intr_count > 0)
-		scan_intr(fusbh200);
-	if (fusbh200->isoc_count > 0)
-		scan_isoc(fusbh200);
-	if (fusbh200->need_rescan)
-		goto rescan;
-	fusbh200->scanning = false;
-
-	/* the IO watchdog guards against hardware or driver bugs that
-	 * misplace IRQs, and should let us run completely without IRQs.
-	 * such lossage has been observed on both VT6202 and VT8235.
-	 */
-	turn_on_io_watchdog(fusbh200);
-}
-
-/*
- * Called when the fusbh200_hcd module is removed.
- */
-static void fusbh200_stop (struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-
-	fusbh200_dbg (fusbh200, "stop\n");
-
-	/* no more interrupts ... */
-
-	spin_lock_irq(&fusbh200->lock);
-	fusbh200->enabled_hrtimer_events = 0;
-	spin_unlock_irq(&fusbh200->lock);
-
-	fusbh200_quiesce(fusbh200);
-	fusbh200_silence_controller(fusbh200);
-	fusbh200_reset (fusbh200);
-
-	hrtimer_cancel(&fusbh200->hrtimer);
-	remove_sysfs_files(fusbh200);
-	remove_debug_files (fusbh200);
-
-	/* root hub is shut down separately (first, when possible) */
-	spin_lock_irq (&fusbh200->lock);
-	end_free_itds(fusbh200);
-	spin_unlock_irq (&fusbh200->lock);
-	fusbh200_mem_cleanup (fusbh200);
-
-	fusbh200_dbg(fusbh200, "irq normal %ld err %ld iaa %ld (lost %ld)\n",
-		fusbh200->stats.normal, fusbh200->stats.error, fusbh200->stats.iaa,
-		fusbh200->stats.lost_iaa);
-	fusbh200_dbg (fusbh200, "complete %ld unlink %ld\n",
-		fusbh200->stats.complete, fusbh200->stats.unlink);
-
-	dbg_status (fusbh200, "fusbh200_stop completed",
-		    fusbh200_readl(fusbh200, &fusbh200->regs->status));
-}
-
-/* one-time init, only for memory state */
-static int hcd_fusbh200_init(struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200(hcd);
-	u32			temp;
-	int			retval;
-	u32			hcc_params;
-	struct fusbh200_qh_hw	*hw;
-
-	spin_lock_init(&fusbh200->lock);
-
-	/*
-	 * keep io watchdog by default, those good HCDs could turn off it later
-	 */
-	fusbh200->need_io_watchdog = 1;
-
-	hrtimer_init(&fusbh200->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
-	fusbh200->hrtimer.function = fusbh200_hrtimer_func;
-	fusbh200->next_hrtimer_event = FUSBH200_HRTIMER_NO_EVENT;
-
-	hcc_params = fusbh200_readl(fusbh200, &fusbh200->caps->hcc_params);
-
-	/*
-	 * by default set standard 80% (== 100 usec/uframe) max periodic
-	 * bandwidth as required by USB 2.0
-	 */
-	fusbh200->uframe_periodic_max = 100;
-
-	/*
-	 * hw default: 1K periodic list heads, one per frame.
-	 * periodic_size can shrink by USBCMD update if hcc_params allows.
-	 */
-	fusbh200->periodic_size = DEFAULT_I_TDPS;
-	INIT_LIST_HEAD(&fusbh200->intr_qh_list);
-	INIT_LIST_HEAD(&fusbh200->cached_itd_list);
-
-	if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
-		/* periodic schedule size can be smaller than default */
-		switch (FUSBH200_TUNE_FLS) {
-		case 0: fusbh200->periodic_size = 1024; break;
-		case 1: fusbh200->periodic_size = 512; break;
-		case 2: fusbh200->periodic_size = 256; break;
-		default:	BUG();
-		}
-	}
-	if ((retval = fusbh200_mem_init(fusbh200, GFP_KERNEL)) < 0)
-		return retval;
-
-	/* controllers may cache some of the periodic schedule ... */
-	fusbh200->i_thresh = 2;
-
-	/*
-	 * dedicate a qh for the async ring head, since we couldn't unlink
-	 * a 'real' qh without stopping the async schedule [4.8].  use it
-	 * as the 'reclamation list head' too.
-	 * its dummy is used in hw_alt_next of many tds, to prevent the qh
-	 * from automatically advancing to the next td after short reads.
-	 */
-	fusbh200->async->qh_next.qh = NULL;
-	hw = fusbh200->async->hw;
-	hw->hw_next = QH_NEXT(fusbh200, fusbh200->async->qh_dma);
-	hw->hw_info1 = cpu_to_hc32(fusbh200, QH_HEAD);
-	hw->hw_token = cpu_to_hc32(fusbh200, QTD_STS_HALT);
-	hw->hw_qtd_next = FUSBH200_LIST_END(fusbh200);
-	fusbh200->async->qh_state = QH_STATE_LINKED;
-	hw->hw_alt_next = QTD_NEXT(fusbh200, fusbh200->async->dummy->qtd_dma);
-
-	/* clear interrupt enables, set irq latency */
-	if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
-		log2_irq_thresh = 0;
-	temp = 1 << (16 + log2_irq_thresh);
-	if (HCC_CANPARK(hcc_params)) {
-		/* HW default park == 3, on hardware that supports it (like
-		 * NVidia and ALI silicon), maximizes throughput on the async
-		 * schedule by avoiding QH fetches between transfers.
-		 *
-		 * With fast usb storage devices and NForce2, "park" seems to
-		 * make problems:  throughput reduction (!), data errors...
-		 */
-		if (park) {
-			park = min(park, (unsigned) 3);
-			temp |= CMD_PARK;
-			temp |= park << 8;
-		}
-		fusbh200_dbg(fusbh200, "park %d\n", park);
-	}
-	if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
-		/* periodic schedule size can be smaller than default */
-		temp &= ~(3 << 2);
-		temp |= (FUSBH200_TUNE_FLS << 2);
-	}
-	fusbh200->command = temp;
-
-	/* Accept arbitrarily long scatter-gather lists */
-	if (!(hcd->driver->flags & HCD_LOCAL_MEM))
-		hcd->self.sg_tablesize = ~0;
-	return 0;
-}
-
-/* start HC running; it's halted, hcd_fusbh200_init() has been run (once) */
-static int fusbh200_run (struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	u32			temp;
-	u32			hcc_params;
-
-	hcd->uses_new_polling = 1;
-
-	/* EHCI spec section 4.1 */
-
-	fusbh200_writel(fusbh200, fusbh200->periodic_dma, &fusbh200->regs->frame_list);
-	fusbh200_writel(fusbh200, (u32)fusbh200->async->qh_dma, &fusbh200->regs->async_next);
-
-	/*
-	 * hcc_params controls whether fusbh200->regs->segment must (!!!)
-	 * be used; it constrains QH/ITD/SITD and QTD locations.
-	 * pci_pool consistent memory always uses segment zero.
-	 * streaming mappings for I/O buffers, like pci_map_single(),
-	 * can return segments above 4GB, if the device allows.
-	 *
-	 * NOTE:  the dma mask is visible through dma_supported(), so
-	 * drivers can pass this info along ... like NETIF_F_HIGHDMA,
-	 * Scsi_Host.highmem_io, and so forth.  It's readonly to all
-	 * host side drivers though.
-	 */
-	hcc_params = fusbh200_readl(fusbh200, &fusbh200->caps->hcc_params);
-
-	// Philips, Intel, and maybe others need CMD_RUN before the
-	// root hub will detect new devices (why?); NEC doesn't
-	fusbh200->command &= ~(CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
-	fusbh200->command |= CMD_RUN;
-	fusbh200_writel(fusbh200, fusbh200->command, &fusbh200->regs->command);
-	dbg_cmd (fusbh200, "init", fusbh200->command);
-
-	/*
-	 * Start, enabling full USB 2.0 functionality ... usb 1.1 devices
-	 * are explicitly handed to companion controller(s), so no TT is
-	 * involved with the root hub.  (Except where one is integrated,
-	 * and there's no companion controller unless maybe for USB OTG.)
-	 *
-	 * Turning on the CF flag will transfer ownership of all ports
-	 * from the companions to the EHCI controller.  If any of the
-	 * companions are in the middle of a port reset at the time, it
-	 * could cause trouble.  Write-locking ehci_cf_port_reset_rwsem
-	 * guarantees that no resets are in progress.  After we set CF,
-	 * a short delay lets the hardware catch up; new resets shouldn't
-	 * be started before the port switching actions could complete.
-	 */
-	down_write(&ehci_cf_port_reset_rwsem);
-	fusbh200->rh_state = FUSBH200_RH_RUNNING;
-	fusbh200_readl(fusbh200, &fusbh200->regs->command);	/* unblock posted writes */
-	msleep(5);
-	up_write(&ehci_cf_port_reset_rwsem);
-	fusbh200->last_periodic_enable = ktime_get_real();
-
-	temp = HC_VERSION(fusbh200, fusbh200_readl(fusbh200, &fusbh200->caps->hc_capbase));
-	fusbh200_info (fusbh200,
-		"USB %x.%x started, EHCI %x.%02x\n",
-		((fusbh200->sbrn & 0xf0)>>4), (fusbh200->sbrn & 0x0f),
-		temp >> 8, temp & 0xff);
-
-	fusbh200_writel(fusbh200, INTR_MASK,
-		    &fusbh200->regs->intr_enable); /* Turn On Interrupts */
-
-	/* GRR this is run-once init(), being done every time the HC starts.
-	 * So long as they're part of class devices, we can't do it init()
-	 * since the class device isn't created that early.
-	 */
-	create_debug_files(fusbh200);
-	create_sysfs_files(fusbh200);
-
-	return 0;
-}
-
-static int fusbh200_setup(struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd *fusbh200 = hcd_to_fusbh200(hcd);
-	int retval;
-
-	fusbh200->regs = (void __iomem *)fusbh200->caps +
-	    HC_LENGTH(fusbh200, fusbh200_readl(fusbh200, &fusbh200->caps->hc_capbase));
-	dbg_hcs_params(fusbh200, "reset");
-	dbg_hcc_params(fusbh200, "reset");
-
-	/* cache this readonly data; minimize chip reads */
-	fusbh200->hcs_params = fusbh200_readl(fusbh200, &fusbh200->caps->hcs_params);
-
-	fusbh200->sbrn = HCD_USB2;
-
-	/* data structure init */
-	retval = hcd_fusbh200_init(hcd);
-	if (retval)
-		return retval;
-
-	retval = fusbh200_halt(fusbh200);
-	if (retval)
-		return retval;
-
-	fusbh200_reset(fusbh200);
-
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static irqreturn_t fusbh200_irq (struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	u32			status, masked_status, pcd_status = 0, cmd;
-	int			bh;
-
-	spin_lock (&fusbh200->lock);
-
-	status = fusbh200_readl(fusbh200, &fusbh200->regs->status);
-
-	/* e.g. cardbus physical eject */
-	if (status == ~(u32) 0) {
-		fusbh200_dbg (fusbh200, "device removed\n");
-		goto dead;
-	}
-
-	/*
-	 * We don't use STS_FLR, but some controllers don't like it to
-	 * remain on, so mask it out along with the other status bits.
-	 */
-	masked_status = status & (INTR_MASK | STS_FLR);
-
-	/* Shared IRQ? */
-	if (!masked_status || unlikely(fusbh200->rh_state == FUSBH200_RH_HALTED)) {
-		spin_unlock(&fusbh200->lock);
-		return IRQ_NONE;
-	}
-
-	/* clear (just) interrupts */
-	fusbh200_writel(fusbh200, masked_status, &fusbh200->regs->status);
-	cmd = fusbh200_readl(fusbh200, &fusbh200->regs->command);
-	bh = 0;
-
-	/* normal [4.15.1.2] or error [4.15.1.1] completion */
-	if (likely ((status & (STS_INT|STS_ERR)) != 0)) {
-		if (likely ((status & STS_ERR) == 0))
-			COUNT (fusbh200->stats.normal);
-		else
-			COUNT (fusbh200->stats.error);
-		bh = 1;
-	}
-
-	/* complete the unlinking of some qh [4.15.2.3] */
-	if (status & STS_IAA) {
-
-		/* Turn off the IAA watchdog */
-		fusbh200->enabled_hrtimer_events &= ~BIT(FUSBH200_HRTIMER_IAA_WATCHDOG);
-
-		/*
-		 * Mild optimization: Allow another IAAD to reset the
-		 * hrtimer, if one occurs before the next expiration.
-		 * In theory we could always cancel the hrtimer, but
-		 * tests show that about half the time it will be reset
-		 * for some other event anyway.
-		 */
-		if (fusbh200->next_hrtimer_event == FUSBH200_HRTIMER_IAA_WATCHDOG)
-			++fusbh200->next_hrtimer_event;
-
-		/* guard against (alleged) silicon errata */
-		if (cmd & CMD_IAAD)
-			fusbh200_dbg(fusbh200, "IAA with IAAD still set?\n");
-		if (fusbh200->async_iaa) {
-			COUNT(fusbh200->stats.iaa);
-			end_unlink_async(fusbh200);
-		} else
-			fusbh200_dbg(fusbh200, "IAA with nothing unlinked?\n");
-	}
-
-	/* remote wakeup [4.3.1] */
-	if (status & STS_PCD) {
-		int pstatus;
-		u32 __iomem *status_reg = &fusbh200->regs->port_status;
-
-		/* kick root hub later */
-		pcd_status = status;
-
-		/* resume root hub? */
-		if (fusbh200->rh_state == FUSBH200_RH_SUSPENDED)
-			usb_hcd_resume_root_hub(hcd);
-
-		pstatus = fusbh200_readl(fusbh200, status_reg);
-
-		if (test_bit(0, &fusbh200->suspended_ports) &&
-				((pstatus & PORT_RESUME) ||
-					!(pstatus & PORT_SUSPEND)) &&
-				(pstatus & PORT_PE) &&
-				fusbh200->reset_done[0] == 0) {
-
-			/* start 20 msec resume signaling from this port,
-			 * and make hub_wq collect PORT_STAT_C_SUSPEND to
-			 * stop that signaling.  Use 5 ms extra for safety,
-			 * like usb_port_resume() does.
-			 */
-			fusbh200->reset_done[0] = jiffies + msecs_to_jiffies(25);
-			set_bit(0, &fusbh200->resuming_ports);
-			fusbh200_dbg (fusbh200, "port 1 remote wakeup\n");
-			mod_timer(&hcd->rh_timer, fusbh200->reset_done[0]);
-		}
-	}
-
-	/* PCI errors [4.15.2.4] */
-	if (unlikely ((status & STS_FATAL) != 0)) {
-		fusbh200_err(fusbh200, "fatal error\n");
-		dbg_cmd(fusbh200, "fatal", cmd);
-		dbg_status(fusbh200, "fatal", status);
-dead:
-		usb_hc_died(hcd);
-
-		/* Don't let the controller do anything more */
-		fusbh200->shutdown = true;
-		fusbh200->rh_state = FUSBH200_RH_STOPPING;
-		fusbh200->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
-		fusbh200_writel(fusbh200, fusbh200->command, &fusbh200->regs->command);
-		fusbh200_writel(fusbh200, 0, &fusbh200->regs->intr_enable);
-		fusbh200_handle_controller_death(fusbh200);
-
-		/* Handle completions when the controller stops */
-		bh = 0;
-	}
-
-	if (bh)
-		fusbh200_work (fusbh200);
-	spin_unlock (&fusbh200->lock);
-	if (pcd_status)
-		usb_hcd_poll_rh_status(hcd);
-	return IRQ_HANDLED;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * non-error returns are a promise to giveback() the urb later
- * we drop ownership so next owner (or urb unlink) can get it
- *
- * urb + dev is in hcd.self.controller.urb_list
- * we're queueing TDs onto software and hardware lists
- *
- * hcd-specific init for hcpriv hasn't been done yet
- *
- * NOTE:  control, bulk, and interrupt share the same code to append TDs
- * to a (possibly active) QH, and the same QH scanning code.
- */
-static int fusbh200_urb_enqueue (
-	struct usb_hcd	*hcd,
-	struct urb	*urb,
-	gfp_t		mem_flags
-) {
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	struct list_head	qtd_list;
-
-	INIT_LIST_HEAD (&qtd_list);
-
-	switch (usb_pipetype (urb->pipe)) {
-	case PIPE_CONTROL:
-		/* qh_completions() code doesn't handle all the fault cases
-		 * in multi-TD control transfers.  Even 1KB is rare anyway.
-		 */
-		if (urb->transfer_buffer_length > (16 * 1024))
-			return -EMSGSIZE;
-		/* FALLTHROUGH */
-	/* case PIPE_BULK: */
-	default:
-		if (!qh_urb_transaction (fusbh200, urb, &qtd_list, mem_flags))
-			return -ENOMEM;
-		return submit_async(fusbh200, urb, &qtd_list, mem_flags);
-
-	case PIPE_INTERRUPT:
-		if (!qh_urb_transaction (fusbh200, urb, &qtd_list, mem_flags))
-			return -ENOMEM;
-		return intr_submit(fusbh200, urb, &qtd_list, mem_flags);
-
-	case PIPE_ISOCHRONOUS:
-		return itd_submit (fusbh200, urb, mem_flags);
-	}
-}
-
-/* remove from hardware lists
- * completions normally happen asynchronously
- */
-
-static int fusbh200_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	struct fusbh200_qh		*qh;
-	unsigned long		flags;
-	int			rc;
-
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
-	if (rc)
-		goto done;
-
-	switch (usb_pipetype (urb->pipe)) {
-	// case PIPE_CONTROL:
-	// case PIPE_BULK:
-	default:
-		qh = (struct fusbh200_qh *) urb->hcpriv;
-		if (!qh)
-			break;
-		switch (qh->qh_state) {
-		case QH_STATE_LINKED:
-		case QH_STATE_COMPLETING:
-			start_unlink_async(fusbh200, qh);
-			break;
-		case QH_STATE_UNLINK:
-		case QH_STATE_UNLINK_WAIT:
-			/* already started */
-			break;
-		case QH_STATE_IDLE:
-			/* QH might be waiting for a Clear-TT-Buffer */
-			qh_completions(fusbh200, qh);
-			break;
-		}
-		break;
-
-	case PIPE_INTERRUPT:
-		qh = (struct fusbh200_qh *) urb->hcpriv;
-		if (!qh)
-			break;
-		switch (qh->qh_state) {
-		case QH_STATE_LINKED:
-		case QH_STATE_COMPLETING:
-			start_unlink_intr(fusbh200, qh);
-			break;
-		case QH_STATE_IDLE:
-			qh_completions (fusbh200, qh);
-			break;
-		default:
-			fusbh200_dbg (fusbh200, "bogus qh %p state %d\n",
-					qh, qh->qh_state);
-			goto done;
-		}
-		break;
-
-	case PIPE_ISOCHRONOUS:
-		// itd...
-
-		// wait till next completion, do it then.
-		// completion irqs can wait up to 1024 msec,
-		break;
-	}
-done:
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-	return rc;
-}
-
-/*-------------------------------------------------------------------------*/
-
-// bulk qh holds the data toggle
-
-static void
-fusbh200_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	unsigned long		flags;
-	struct fusbh200_qh		*qh, *tmp;
-
-	/* ASSERT:  any requests/urbs are being unlinked */
-	/* ASSERT:  nobody can be submitting urbs for this any more */
-
-rescan:
-	spin_lock_irqsave (&fusbh200->lock, flags);
-	qh = ep->hcpriv;
-	if (!qh)
-		goto done;
-
-	/* endpoints can be iso streams.  for now, we don't
-	 * accelerate iso completions ... so spin a while.
-	 */
-	if (qh->hw == NULL) {
-		struct fusbh200_iso_stream	*stream = ep->hcpriv;
-
-		if (!list_empty(&stream->td_list))
-			goto idle_timeout;
-
-		/* BUG_ON(!list_empty(&stream->free_list)); */
-		kfree(stream);
-		goto done;
-	}
-
-	if (fusbh200->rh_state < FUSBH200_RH_RUNNING)
-		qh->qh_state = QH_STATE_IDLE;
-	switch (qh->qh_state) {
-	case QH_STATE_LINKED:
-	case QH_STATE_COMPLETING:
-		for (tmp = fusbh200->async->qh_next.qh;
-				tmp && tmp != qh;
-				tmp = tmp->qh_next.qh)
-			continue;
-		/* periodic qh self-unlinks on empty, and a COMPLETING qh
-		 * may already be unlinked.
-		 */
-		if (tmp)
-			start_unlink_async(fusbh200, qh);
-		/* FALL THROUGH */
-	case QH_STATE_UNLINK:		/* wait for hw to finish? */
-	case QH_STATE_UNLINK_WAIT:
-idle_timeout:
-		spin_unlock_irqrestore (&fusbh200->lock, flags);
-		schedule_timeout_uninterruptible(1);
-		goto rescan;
-	case QH_STATE_IDLE:		/* fully unlinked */
-		if (qh->clearing_tt)
-			goto idle_timeout;
-		if (list_empty (&qh->qtd_list)) {
-			qh_destroy(fusbh200, qh);
-			break;
-		}
-		/* else FALL THROUGH */
-	default:
-		/* caller was supposed to have unlinked any requests;
-		 * that's not our job.  just leak this memory.
-		 */
-		fusbh200_err (fusbh200, "qh %p (#%02x) state %d%s\n",
-			qh, ep->desc.bEndpointAddress, qh->qh_state,
-			list_empty (&qh->qtd_list) ? "" : "(has tds)");
-		break;
-	}
- done:
-	ep->hcpriv = NULL;
-	spin_unlock_irqrestore (&fusbh200->lock, flags);
-}
-
-static void
-fusbh200_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200(hcd);
-	struct fusbh200_qh		*qh;
-	int			eptype = usb_endpoint_type(&ep->desc);
-	int			epnum = usb_endpoint_num(&ep->desc);
-	int			is_out = usb_endpoint_dir_out(&ep->desc);
-	unsigned long		flags;
-
-	if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
-		return;
-
-	spin_lock_irqsave(&fusbh200->lock, flags);
-	qh = ep->hcpriv;
-
-	/* For Bulk and Interrupt endpoints we maintain the toggle state
-	 * in the hardware; the toggle bits in udev aren't used at all.
-	 * When an endpoint is reset by usb_clear_halt() we must reset
-	 * the toggle bit in the QH.
-	 */
-	if (qh) {
-		usb_settoggle(qh->dev, epnum, is_out, 0);
-		if (!list_empty(&qh->qtd_list)) {
-			WARN_ONCE(1, "clear_halt for a busy endpoint\n");
-		} else if (qh->qh_state == QH_STATE_LINKED ||
-				qh->qh_state == QH_STATE_COMPLETING) {
-
-			/* The toggle value in the QH can't be updated
-			 * while the QH is active.  Unlink it now;
-			 * re-linking will call qh_refresh().
-			 */
-			if (eptype == USB_ENDPOINT_XFER_BULK)
-				start_unlink_async(fusbh200, qh);
-			else
-				start_unlink_intr(fusbh200, qh);
-		}
-	}
-	spin_unlock_irqrestore(&fusbh200->lock, flags);
-}
-
-static int fusbh200_get_frame (struct usb_hcd *hcd)
-{
-	struct fusbh200_hcd		*fusbh200 = hcd_to_fusbh200 (hcd);
-	return (fusbh200_read_frame_index(fusbh200) >> 3) % fusbh200->periodic_size;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * The EHCI in ChipIdea HDRC cannot be a separate module or device,
- * because its registers (and irq) are shared between host/gadget/otg
- * functions  and in order to facilitate role switching we cannot
- * give the fusbh200 driver exclusive access to those.
- */
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_AUTHOR (DRIVER_AUTHOR);
-MODULE_LICENSE ("GPL");
-
-static const struct hc_driver fusbh200_fusbh200_hc_driver = {
-	.description 		= hcd_name,
-	.product_desc 		= "Faraday USB2.0 Host Controller",
-	.hcd_priv_size 		= sizeof(struct fusbh200_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq 			= fusbh200_irq,
-	.flags 			= HCD_MEMORY | HCD_USB2,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset 			= hcd_fusbh200_init,
-	.start 			= fusbh200_run,
-	.stop 			= fusbh200_stop,
-	.shutdown 		= fusbh200_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue 		= fusbh200_urb_enqueue,
-	.urb_dequeue 		= fusbh200_urb_dequeue,
-	.endpoint_disable 	= fusbh200_endpoint_disable,
-	.endpoint_reset 	= fusbh200_endpoint_reset,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number 	= fusbh200_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data 	= fusbh200_hub_status_data,
-	.hub_control 		= fusbh200_hub_control,
-	.bus_suspend 		= fusbh200_bus_suspend,
-	.bus_resume 		= fusbh200_bus_resume,
-
-	.relinquish_port 	= fusbh200_relinquish_port,
-	.port_handed_over 	= fusbh200_port_handed_over,
-
-	.clear_tt_buffer_complete = fusbh200_clear_tt_buffer_complete,
-};
-
-static void fusbh200_init(struct fusbh200_hcd *fusbh200)
-{
-	u32 reg;
-
-	reg = fusbh200_readl(fusbh200, &fusbh200->regs->bmcsr);
-	reg |= BMCSR_INT_POLARITY;
-	reg &= ~BMCSR_VBUS_OFF;
-	fusbh200_writel(fusbh200, reg, &fusbh200->regs->bmcsr);
-
-	reg = fusbh200_readl(fusbh200, &fusbh200->regs->bmier);
-	fusbh200_writel(fusbh200, reg | BMIER_OVC_EN | BMIER_VBUS_ERR_EN,
-		&fusbh200->regs->bmier);
-}
-
-/**
- * fusbh200_hcd_probe - initialize faraday FUSBH200 HCDs
- *
- * Allocates basic resources for this USB host controller, and
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
- */
-static int fusbh200_hcd_probe(struct platform_device *pdev)
-{
-	struct device			*dev = &pdev->dev;
-	struct usb_hcd 			*hcd;
-	struct resource			*res;
-	int 				irq;
-	int 				retval = -ENODEV;
-	struct fusbh200_hcd 		*fusbh200;
-
-	if (usb_disabled())
-		return -ENODEV;
-
-	pdev->dev.power.power_state = PMSG_ON;
-
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res) {
-		dev_err(dev,
-			"Found HC with no IRQ. Check %s setup!\n",
-			dev_name(dev));
-		return -ENODEV;
-	}
-
-	irq = res->start;
-
-	hcd = usb_create_hcd(&fusbh200_fusbh200_hc_driver, dev,
-			dev_name(dev));
-	if (!hcd) {
-		dev_err(dev, "failed to create hcd with err %d\n", retval);
-		retval = -ENOMEM;
-		goto fail_create_hcd;
-	}
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(dev,
-			"Found HC with no register addr. Check %s setup!\n",
-			dev_name(dev));
-		retval = -ENODEV;
-		goto fail_request_resource;
-	}
-
-	hcd->rsrc_start = res->start;
-	hcd->rsrc_len = resource_size(res);
-	hcd->has_tt = 1;
-
-	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
-				fusbh200_fusbh200_hc_driver.description)) {
-		dev_dbg(dev, "controller already in use\n");
-		retval = -EBUSY;
-		goto fail_request_resource;
-	}
-
-	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	if (!res) {
-		dev_err(dev,
-			"Found HC with no register addr. Check %s setup!\n",
-			dev_name(dev));
-		retval = -ENODEV;
-		goto fail_request_resource;
-	}
-
-	hcd->regs = ioremap_nocache(res->start, resource_size(res));
-	if (hcd->regs == NULL) {
-		dev_dbg(dev, "error mapping memory\n");
-		retval = -EFAULT;
-		goto fail_ioremap;
-	}
-
-	fusbh200 = hcd_to_fusbh200(hcd);
-
-	fusbh200->caps = hcd->regs;
-
-	retval = fusbh200_setup(hcd);
-	if (retval)
-		goto fail_add_hcd;
-
-	fusbh200_init(fusbh200);
-
-	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
-	if (retval) {
-		dev_err(dev, "failed to add hcd with err %d\n", retval);
-		goto fail_add_hcd;
-	}
-	device_wakeup_enable(hcd->self.controller);
-
-	return retval;
-
-fail_add_hcd:
-	iounmap(hcd->regs);
-fail_ioremap:
-	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-fail_request_resource:
-	usb_put_hcd(hcd);
-fail_create_hcd:
-	dev_err(dev, "init %s fail, %d\n", dev_name(dev), retval);
-	return retval;
-}
-
-/**
- * fusbh200_hcd_remove - shutdown processing for EHCI HCDs
- * @dev: USB Host Controller being removed
- *
- * Reverses the effect of fotg2xx_usb_hcd_probe(), first invoking
- * the HCD's stop() method.  It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
- */
-static int fusbh200_hcd_remove(struct platform_device *pdev)
-{
-	struct device *dev	= &pdev->dev;
-	struct usb_hcd *hcd	= dev_get_drvdata(dev);
-
-	if (!hcd)
-		return 0;
-
-	usb_remove_hcd(hcd);
-	iounmap(hcd->regs);
-	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-	usb_put_hcd(hcd);
-
-	return 0;
-}
-
-static struct platform_driver fusbh200_hcd_fusbh200_driver = {
-	.driver = {
-		.name   = "fusbh200",
-	},
-	.probe  = fusbh200_hcd_probe,
-	.remove = fusbh200_hcd_remove,
-};
-
-static int __init fusbh200_hcd_init(void)
-{
-	int retval = 0;
-
-	if (usb_disabled())
-		return -ENODEV;
-
-	printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name);
-	set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-	if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
-			test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
-		printk(KERN_WARNING "Warning! fusbh200_hcd should always be loaded"
-				" before uhci_hcd and ohci_hcd, not after\n");
-
-	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd\n",
-		 hcd_name,
-		 sizeof(struct fusbh200_qh), sizeof(struct fusbh200_qtd),
-		 sizeof(struct fusbh200_itd));
-
-	fusbh200_debug_root = debugfs_create_dir("fusbh200", usb_debug_root);
-	if (!fusbh200_debug_root) {
-		retval = -ENOENT;
-		goto err_debug;
-	}
-
-	retval = platform_driver_register(&fusbh200_hcd_fusbh200_driver);
-	if (retval < 0)
-		goto clean;
-	return retval;
-
-	platform_driver_unregister(&fusbh200_hcd_fusbh200_driver);
-clean:
-	debugfs_remove(fusbh200_debug_root);
-	fusbh200_debug_root = NULL;
-err_debug:
-	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-	return retval;
-}
-module_init(fusbh200_hcd_init);
-
-static void __exit fusbh200_hcd_cleanup(void)
-{
-	platform_driver_unregister(&fusbh200_hcd_fusbh200_driver);
-	debugfs_remove(fusbh200_debug_root);
-	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
-}
-module_exit(fusbh200_hcd_cleanup);
diff --git a/drivers/usb/host/fusbh200.h b/drivers/usb/host/fusbh200.h
deleted file mode 100644
index d6e5b3d..0000000
--- a/drivers/usb/host/fusbh200.h
+++ /dev/null
@@ -1,675 +0,0 @@
-#ifndef __LINUX_FUSBH200_H
-#define __LINUX_FUSBH200_H
-
-#include <linux/usb/ehci-dbgp.h>
-
-/* definitions used for the EHCI driver */
-
-/*
- * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to
- * __leXX (normally) or __beXX (given FUSBH200_BIG_ENDIAN_DESC), depending on
- * the host controller implementation.
- *
- * To facilitate the strongest possible byte-order checking from "sparse"
- * and so on, we use __leXX unless that's not practical.
- */
-#define __hc32	__le32
-#define __hc16	__le16
-
-/* statistics can be kept for tuning/monitoring */
-struct fusbh200_stats {
-	/* irq usage */
-	unsigned long		normal;
-	unsigned long		error;
-	unsigned long		iaa;
-	unsigned long		lost_iaa;
-
-	/* termination of urbs from core */
-	unsigned long		complete;
-	unsigned long		unlink;
-};
-
-/* fusbh200_hcd->lock guards shared data against other CPUs:
- *   fusbh200_hcd:	async, unlink, periodic (and shadow), ...
- *   usb_host_endpoint: hcpriv
- *   fusbh200_qh:	qh_next, qtd_list
- *   fusbh200_qtd:	qtd_list
- *
- * Also, hold this lock when talking to HC registers or
- * when updating hw_* fields in shared qh/qtd/... structures.
- */
-
-#define	FUSBH200_MAX_ROOT_PORTS	1		/* see HCS_N_PORTS */
-
-/*
- * fusbh200_rh_state values of FUSBH200_RH_RUNNING or above mean that the
- * controller may be doing DMA.  Lower values mean there's no DMA.
- */
-enum fusbh200_rh_state {
-	FUSBH200_RH_HALTED,
-	FUSBH200_RH_SUSPENDED,
-	FUSBH200_RH_RUNNING,
-	FUSBH200_RH_STOPPING
-};
-
-/*
- * Timer events, ordered by increasing delay length.
- * Always update event_delays_ns[] and event_handlers[] (defined in
- * ehci-timer.c) in parallel with this list.
- */
-enum fusbh200_hrtimer_event {
-	FUSBH200_HRTIMER_POLL_ASS,		/* Poll for async schedule off */
-	FUSBH200_HRTIMER_POLL_PSS,		/* Poll for periodic schedule off */
-	FUSBH200_HRTIMER_POLL_DEAD,		/* Wait for dead controller to stop */
-	FUSBH200_HRTIMER_UNLINK_INTR,	/* Wait for interrupt QH unlink */
-	FUSBH200_HRTIMER_FREE_ITDS,		/* Wait for unused iTDs and siTDs */
-	FUSBH200_HRTIMER_ASYNC_UNLINKS,	/* Unlink empty async QHs */
-	FUSBH200_HRTIMER_IAA_WATCHDOG,	/* Handle lost IAA interrupts */
-	FUSBH200_HRTIMER_DISABLE_PERIODIC,	/* Wait to disable periodic sched */
-	FUSBH200_HRTIMER_DISABLE_ASYNC,	/* Wait to disable async sched */
-	FUSBH200_HRTIMER_IO_WATCHDOG,	/* Check for missing IRQs */
-	FUSBH200_HRTIMER_NUM_EVENTS		/* Must come last */
-};
-#define FUSBH200_HRTIMER_NO_EVENT	99
-
-struct fusbh200_hcd {			/* one per controller */
-	/* timing support */
-	enum fusbh200_hrtimer_event	next_hrtimer_event;
-	unsigned		enabled_hrtimer_events;
-	ktime_t			hr_timeouts[FUSBH200_HRTIMER_NUM_EVENTS];
-	struct hrtimer		hrtimer;
-
-	int			PSS_poll_count;
-	int			ASS_poll_count;
-	int			died_poll_count;
-
-	/* glue to PCI and HCD framework */
-	struct fusbh200_caps __iomem *caps;
-	struct fusbh200_regs __iomem *regs;
-	struct ehci_dbg_port __iomem *debug;
-
-	__u32			hcs_params;	/* cached register copy */
-	spinlock_t		lock;
-	enum fusbh200_rh_state	rh_state;
-
-	/* general schedule support */
-	bool			scanning:1;
-	bool			need_rescan:1;
-	bool			intr_unlinking:1;
-	bool			async_unlinking:1;
-	bool			shutdown:1;
-	struct fusbh200_qh		*qh_scan_next;
-
-	/* async schedule support */
-	struct fusbh200_qh		*async;
-	struct fusbh200_qh		*dummy;		/* For AMD quirk use */
-	struct fusbh200_qh		*async_unlink;
-	struct fusbh200_qh		*async_unlink_last;
-	struct fusbh200_qh		*async_iaa;
-	unsigned		async_unlink_cycle;
-	unsigned		async_count;	/* async activity count */
-
-	/* periodic schedule support */
-#define	DEFAULT_I_TDPS		1024		/* some HCs can do less */
-	unsigned		periodic_size;
-	__hc32			*periodic;	/* hw periodic table */
-	dma_addr_t		periodic_dma;
-	struct list_head	intr_qh_list;
-	unsigned		i_thresh;	/* uframes HC might cache */
-
-	union fusbh200_shadow	*pshadow;	/* mirror hw periodic table */
-	struct fusbh200_qh		*intr_unlink;
-	struct fusbh200_qh		*intr_unlink_last;
-	unsigned		intr_unlink_cycle;
-	unsigned		now_frame;	/* frame from HC hardware */
-	unsigned		next_frame;	/* scan periodic, start here */
-	unsigned		intr_count;	/* intr activity count */
-	unsigned		isoc_count;	/* isoc activity count */
-	unsigned		periodic_count;	/* periodic activity count */
-	unsigned		uframe_periodic_max; /* max periodic time per uframe */
-
-
-	/* list of itds completed while now_frame was still active */
-	struct list_head	cached_itd_list;
-	struct fusbh200_itd	*last_itd_to_free;
-
-	/* per root hub port */
-	unsigned long		reset_done [FUSBH200_MAX_ROOT_PORTS];
-
-	/* bit vectors (one bit per port) */
-	unsigned long		bus_suspended;		/* which ports were
-			already suspended at the start of a bus suspend */
-	unsigned long		companion_ports;	/* which ports are
-			dedicated to the companion controller */
-	unsigned long		owned_ports;		/* which ports are
-			owned by the companion during a bus suspend */
-	unsigned long		port_c_suspend;		/* which ports have
-			the change-suspend feature turned on */
-	unsigned long		suspended_ports;	/* which ports are
-			suspended */
-	unsigned long		resuming_ports;		/* which ports have
-			started to resume */
-
-	/* per-HC memory pools (could be per-bus, but ...) */
-	struct dma_pool		*qh_pool;	/* qh per active urb */
-	struct dma_pool		*qtd_pool;	/* one or more per qh */
-	struct dma_pool		*itd_pool;	/* itd per iso urb */
-
-	unsigned		random_frame;
-	unsigned long		next_statechange;
-	ktime_t			last_periodic_enable;
-	u32			command;
-
-	/* SILICON QUIRKS */
-	unsigned		need_io_watchdog:1;
-	unsigned		fs_i_thresh:1;	/* Intel iso scheduling */
-
-	u8			sbrn;		/* packed release number */
-
-	/* irq statistics */
-	struct fusbh200_stats	stats;
-#	define COUNT(x) do { (x)++; } while (0)
-
-	/* debug files */
-	struct dentry		*debug_dir;
-};
-
-/* convert between an HCD pointer and the corresponding FUSBH200_HCD */
-static inline struct fusbh200_hcd *hcd_to_fusbh200 (struct usb_hcd *hcd)
-{
-	return (struct fusbh200_hcd *) (hcd->hcd_priv);
-}
-static inline struct usb_hcd *fusbh200_to_hcd (struct fusbh200_hcd *fusbh200)
-{
-	return container_of ((void *) fusbh200, struct usb_hcd, hcd_priv);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */
-
-/* Section 2.2 Host Controller Capability Registers */
-struct fusbh200_caps {
-	/* these fields are specified as 8 and 16 bit registers,
-	 * but some hosts can't perform 8 or 16 bit PCI accesses.
-	 * some hosts treat caplength and hciversion as parts of a 32-bit
-	 * register, others treat them as two separate registers, this
-	 * affects the memory map for big endian controllers.
-	 */
-	u32		hc_capbase;
-#define HC_LENGTH(fusbh200, p)	(0x00ff&((p) >> /* bits 7:0 / offset 00h */ \
-				(fusbh200_big_endian_capbase(fusbh200) ? 24 : 0)))
-#define HC_VERSION(fusbh200, p)	(0xffff&((p) >> /* bits 31:16 / offset 02h */ \
-				(fusbh200_big_endian_capbase(fusbh200) ? 0 : 16)))
-	u32		hcs_params;     /* HCSPARAMS - offset 0x4 */
-#define HCS_N_PORTS(p)		(((p)>>0)&0xf)	/* bits 3:0, ports on HC */
-
-	u32		hcc_params;      /* HCCPARAMS - offset 0x8 */
-#define HCC_CANPARK(p)		((p)&(1 << 2))  /* true: can park on async qh */
-#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1))  /* true: periodic_size changes*/
-	u8		portroute[8];	 /* nibbles for routing - offset 0xC */
-};
-
-
-/* Section 2.3 Host Controller Operational Registers */
-struct fusbh200_regs {
-
-	/* USBCMD: offset 0x00 */
-	u32		command;
-
-/* EHCI 1.1 addendum */
-/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
-#define CMD_PARK	(1<<11)		/* enable "park" on async qh */
-#define CMD_PARK_CNT(c)	(((c)>>8)&3)	/* how many transfers to park for */
-#define CMD_IAAD	(1<<6)		/* "doorbell" interrupt async advance */
-#define CMD_ASE		(1<<5)		/* async schedule enable */
-#define CMD_PSE		(1<<4)		/* periodic schedule enable */
-/* 3:2 is periodic frame list size */
-#define CMD_RESET	(1<<1)		/* reset HC not bus */
-#define CMD_RUN		(1<<0)		/* start/stop HC */
-
-	/* USBSTS: offset 0x04 */
-	u32		status;
-#define STS_ASS		(1<<15)		/* Async Schedule Status */
-#define STS_PSS		(1<<14)		/* Periodic Schedule Status */
-#define STS_RECL	(1<<13)		/* Reclamation */
-#define STS_HALT	(1<<12)		/* Not running (any reason) */
-/* some bits reserved */
-	/* these STS_* flags are also intr_enable bits (USBINTR) */
-#define STS_IAA		(1<<5)		/* Interrupted on async advance */
-#define STS_FATAL	(1<<4)		/* such as some PCI access errors */
-#define STS_FLR		(1<<3)		/* frame list rolled over */
-#define STS_PCD		(1<<2)		/* port change detect */
-#define STS_ERR		(1<<1)		/* "error" completion (overflow, ...) */
-#define STS_INT		(1<<0)		/* "normal" completion (short, ...) */
-
-	/* USBINTR: offset 0x08 */
-	u32		intr_enable;
-
-	/* FRINDEX: offset 0x0C */
-	u32		frame_index;	/* current microframe number */
-	/* CTRLDSSEGMENT: offset 0x10 */
-	u32		segment;	/* address bits 63:32 if needed */
-	/* PERIODICLISTBASE: offset 0x14 */
-	u32		frame_list;	/* points to periodic list */
-	/* ASYNCLISTADDR: offset 0x18 */
-	u32		async_next;	/* address of next async queue head */
-
-	u32	reserved1;
-	/* PORTSC: offset 0x20 */
-	u32	port_status;
-/* 31:23 reserved */
-#define PORT_USB11(x) (((x)&(3<<10)) == (1<<10))	/* USB 1.1 device */
-#define PORT_RESET	(1<<8)		/* reset port */
-#define PORT_SUSPEND	(1<<7)		/* suspend port */
-#define PORT_RESUME	(1<<6)		/* resume it */
-#define PORT_PEC	(1<<3)		/* port enable change */
-#define PORT_PE		(1<<2)		/* port enable */
-#define PORT_CSC	(1<<1)		/* connect status change */
-#define PORT_CONNECT	(1<<0)		/* device connected */
-#define PORT_RWC_BITS   (PORT_CSC | PORT_PEC)
-
-	u32	reserved2[3];
-
-	/* BMCSR: offset 0x30 */
-	u32	bmcsr; /* Bus Moniter Control/Status Register */
-#define BMCSR_HOST_SPD_TYP	(3<<9)
-#define BMCSR_VBUS_OFF		(1<<4)
-#define BMCSR_INT_POLARITY	(1<<3)
-
-	/* BMISR: offset 0x34 */
-	u32	bmisr; /* Bus Moniter Interrupt Status Register*/
-#define BMISR_OVC		(1<<1)
-
-	/* BMIER: offset 0x38 */
-	u32	bmier; /* Bus Moniter Interrupt Enable Register */
-#define BMIER_OVC_EN		(1<<1)
-#define BMIER_VBUS_ERR_EN	(1<<0)
-};
-
-/*-------------------------------------------------------------------------*/
-
-#define	QTD_NEXT(fusbh200, dma)	cpu_to_hc32(fusbh200, (u32)dma)
-
-/*
- * EHCI Specification 0.95 Section 3.5
- * QTD: describe data transfer components (buffer, direction, ...)
- * See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram".
- *
- * These are associated only with "QH" (Queue Head) structures,
- * used with control, bulk, and interrupt transfers.
- */
-struct fusbh200_qtd {
-	/* first part defined by EHCI spec */
-	__hc32			hw_next;	/* see EHCI 3.5.1 */
-	__hc32			hw_alt_next;    /* see EHCI 3.5.2 */
-	__hc32			hw_token;       /* see EHCI 3.5.3 */
-#define	QTD_TOGGLE	(1 << 31)	/* data toggle */
-#define	QTD_LENGTH(tok)	(((tok)>>16) & 0x7fff)
-#define	QTD_IOC		(1 << 15)	/* interrupt on complete */
-#define	QTD_CERR(tok)	(((tok)>>10) & 0x3)
-#define	QTD_PID(tok)	(((tok)>>8) & 0x3)
-#define	QTD_STS_ACTIVE	(1 << 7)	/* HC may execute this */
-#define	QTD_STS_HALT	(1 << 6)	/* halted on error */
-#define	QTD_STS_DBE	(1 << 5)	/* data buffer error (in HC) */
-#define	QTD_STS_BABBLE	(1 << 4)	/* device was babbling (qtd halted) */
-#define	QTD_STS_XACT	(1 << 3)	/* device gave illegal response */
-#define	QTD_STS_MMF	(1 << 2)	/* incomplete split transaction */
-#define	QTD_STS_STS	(1 << 1)	/* split transaction state */
-#define	QTD_STS_PING	(1 << 0)	/* issue PING? */
-
-#define ACTIVE_BIT(fusbh200)	cpu_to_hc32(fusbh200, QTD_STS_ACTIVE)
-#define HALT_BIT(fusbh200)		cpu_to_hc32(fusbh200, QTD_STS_HALT)
-#define STATUS_BIT(fusbh200)	cpu_to_hc32(fusbh200, QTD_STS_STS)
-
-	__hc32			hw_buf [5];        /* see EHCI 3.5.4 */
-	__hc32			hw_buf_hi [5];        /* Appendix B */
-
-	/* the rest is HCD-private */
-	dma_addr_t		qtd_dma;		/* qtd address */
-	struct list_head	qtd_list;		/* sw qtd list */
-	struct urb		*urb;			/* qtd's urb */
-	size_t			length;			/* length of buffer */
-} __attribute__ ((aligned (32)));
-
-/* mask NakCnt+T in qh->hw_alt_next */
-#define QTD_MASK(fusbh200)	cpu_to_hc32 (fusbh200, ~0x1f)
-
-#define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1)
-
-/*-------------------------------------------------------------------------*/
-
-/* type tag from {qh,itd,fstn}->hw_next */
-#define Q_NEXT_TYPE(fusbh200,dma)	((dma) & cpu_to_hc32(fusbh200, 3 << 1))
-
-/*
- * Now the following defines are not converted using the
- * cpu_to_le32() macro anymore, since we have to support
- * "dynamic" switching between be and le support, so that the driver
- * can be used on one system with SoC EHCI controller using big-endian
- * descriptors as well as a normal little-endian PCI EHCI controller.
- */
-/* values for that type tag */
-#define Q_TYPE_ITD	(0 << 1)
-#define Q_TYPE_QH	(1 << 1)
-#define Q_TYPE_SITD	(2 << 1)
-#define Q_TYPE_FSTN	(3 << 1)
-
-/* next async queue entry, or pointer to interrupt/periodic QH */
-#define QH_NEXT(fusbh200,dma)	(cpu_to_hc32(fusbh200, (((u32)dma)&~0x01f)|Q_TYPE_QH))
-
-/* for periodic/async schedules and qtd lists, mark end of list */
-#define FUSBH200_LIST_END(fusbh200)	cpu_to_hc32(fusbh200, 1) /* "null pointer" to hw */
-
-/*
- * Entries in periodic shadow table are pointers to one of four kinds
- * of data structure.  That's dictated by the hardware; a type tag is
- * encoded in the low bits of the hardware's periodic schedule.  Use
- * Q_NEXT_TYPE to get the tag.
- *
- * For entries in the async schedule, the type tag always says "qh".
- */
-union fusbh200_shadow {
-	struct fusbh200_qh	*qh;		/* Q_TYPE_QH */
-	struct fusbh200_itd	*itd;		/* Q_TYPE_ITD */
-	struct fusbh200_fstn	*fstn;		/* Q_TYPE_FSTN */
-	__hc32			*hw_next;	/* (all types) */
-	void			*ptr;
-};
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.95 Section 3.6
- * QH: describes control/bulk/interrupt endpoints
- * See Fig 3-7 "Queue Head Structure Layout".
- *
- * These appear in both the async and (for interrupt) periodic schedules.
- */
-
-/* first part defined by EHCI spec */
-struct fusbh200_qh_hw {
-	__hc32			hw_next;	/* see EHCI 3.6.1 */
-	__hc32			hw_info1;       /* see EHCI 3.6.2 */
-#define	QH_CONTROL_EP	(1 << 27)	/* FS/LS control endpoint */
-#define	QH_HEAD		(1 << 15)	/* Head of async reclamation list */
-#define	QH_TOGGLE_CTL	(1 << 14)	/* Data toggle control */
-#define	QH_HIGH_SPEED	(2 << 12)	/* Endpoint speed */
-#define	QH_LOW_SPEED	(1 << 12)
-#define	QH_FULL_SPEED	(0 << 12)
-#define	QH_INACTIVATE	(1 << 7)	/* Inactivate on next transaction */
-	__hc32			hw_info2;        /* see EHCI 3.6.2 */
-#define	QH_SMASK	0x000000ff
-#define	QH_CMASK	0x0000ff00
-#define	QH_HUBADDR	0x007f0000
-#define	QH_HUBPORT	0x3f800000
-#define	QH_MULT		0xc0000000
-	__hc32			hw_current;	/* qtd list - see EHCI 3.6.4 */
-
-	/* qtd overlay (hardware parts of a struct fusbh200_qtd) */
-	__hc32			hw_qtd_next;
-	__hc32			hw_alt_next;
-	__hc32			hw_token;
-	__hc32			hw_buf [5];
-	__hc32			hw_buf_hi [5];
-} __attribute__ ((aligned(32)));
-
-struct fusbh200_qh {
-	struct fusbh200_qh_hw	*hw;		/* Must come first */
-	/* the rest is HCD-private */
-	dma_addr_t		qh_dma;		/* address of qh */
-	union fusbh200_shadow	qh_next;	/* ptr to qh; or periodic */
-	struct list_head	qtd_list;	/* sw qtd list */
-	struct list_head	intr_node;	/* list of intr QHs */
-	struct fusbh200_qtd		*dummy;
-	struct fusbh200_qh		*unlink_next;	/* next on unlink list */
-
-	unsigned		unlink_cycle;
-
-	u8			needs_rescan;	/* Dequeue during giveback */
-	u8			qh_state;
-#define	QH_STATE_LINKED		1		/* HC sees this */
-#define	QH_STATE_UNLINK		2		/* HC may still see this */
-#define	QH_STATE_IDLE		3		/* HC doesn't see this */
-#define	QH_STATE_UNLINK_WAIT	4		/* LINKED and on unlink q */
-#define	QH_STATE_COMPLETING	5		/* don't touch token.HALT */
-
-	u8			xacterrs;	/* XactErr retry counter */
-#define	QH_XACTERR_MAX		32		/* XactErr retry limit */
-
-	/* periodic schedule info */
-	u8			usecs;		/* intr bandwidth */
-	u8			gap_uf;		/* uframes split/csplit gap */
-	u8			c_usecs;	/* ... split completion bw */
-	u16			tt_usecs;	/* tt downstream bandwidth */
-	unsigned short		period;		/* polling interval */
-	unsigned short		start;		/* where polling starts */
-#define NO_FRAME ((unsigned short)~0)			/* pick new start */
-
-	struct usb_device	*dev;		/* access to TT */
-	unsigned		is_out:1;	/* bulk or intr OUT */
-	unsigned		clearing_tt:1;	/* Clear-TT-Buf in progress */
-};
-
-/*-------------------------------------------------------------------------*/
-
-/* description of one iso transaction (up to 3 KB data if highspeed) */
-struct fusbh200_iso_packet {
-	/* These will be copied to iTD when scheduling */
-	u64			bufp;		/* itd->hw_bufp{,_hi}[pg] |= */
-	__hc32			transaction;	/* itd->hw_transaction[i] |= */
-	u8			cross;		/* buf crosses pages */
-	/* for full speed OUT splits */
-	u32			buf1;
-};
-
-/* temporary schedule data for packets from iso urbs (both speeds)
- * each packet is one logical usb transaction to the device (not TT),
- * beginning at stream->next_uframe
- */
-struct fusbh200_iso_sched {
-	struct list_head	td_list;
-	unsigned		span;
-	struct fusbh200_iso_packet	packet [0];
-};
-
-/*
- * fusbh200_iso_stream - groups all (s)itds for this endpoint.
- * acts like a qh would, if EHCI had them for ISO.
- */
-struct fusbh200_iso_stream {
-	/* first field matches fusbh200_hq, but is NULL */
-	struct fusbh200_qh_hw	*hw;
-
-	u8			bEndpointAddress;
-	u8			highspeed;
-	struct list_head	td_list;	/* queued itds */
-	struct list_head	free_list;	/* list of unused itds */
-	struct usb_device	*udev;
-	struct usb_host_endpoint *ep;
-
-	/* output of (re)scheduling */
-	int			next_uframe;
-	__hc32			splits;
-
-	/* the rest is derived from the endpoint descriptor,
-	 * trusting urb->interval == f(epdesc->bInterval) and
-	 * including the extra info for hw_bufp[0..2]
-	 */
-	u8			usecs, c_usecs;
-	u16			interval;
-	u16			tt_usecs;
-	u16			maxp;
-	u16			raw_mask;
-	unsigned		bandwidth;
-
-	/* This is used to initialize iTD's hw_bufp fields */
-	__hc32			buf0;
-	__hc32			buf1;
-	__hc32			buf2;
-
-	/* this is used to initialize sITD's tt info */
-	__hc32			address;
-};
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.95 Section 3.3
- * Fig 3-4 "Isochronous Transaction Descriptor (iTD)"
- *
- * Schedule records for high speed iso xfers
- */
-struct fusbh200_itd {
-	/* first part defined by EHCI spec */
-	__hc32			hw_next;           /* see EHCI 3.3.1 */
-	__hc32			hw_transaction [8]; /* see EHCI 3.3.2 */
-#define FUSBH200_ISOC_ACTIVE        (1<<31)        /* activate transfer this slot */
-#define FUSBH200_ISOC_BUF_ERR       (1<<30)        /* Data buffer error */
-#define FUSBH200_ISOC_BABBLE        (1<<29)        /* babble detected */
-#define FUSBH200_ISOC_XACTERR       (1<<28)        /* XactErr - transaction error */
-#define	FUSBH200_ITD_LENGTH(tok)	(((tok)>>16) & 0x0fff)
-#define	FUSBH200_ITD_IOC		(1 << 15)	/* interrupt on complete */
-
-#define ITD_ACTIVE(fusbh200)	cpu_to_hc32(fusbh200, FUSBH200_ISOC_ACTIVE)
-
-	__hc32			hw_bufp [7];	/* see EHCI 3.3.3 */
-	__hc32			hw_bufp_hi [7];	/* Appendix B */
-
-	/* the rest is HCD-private */
-	dma_addr_t		itd_dma;	/* for this itd */
-	union fusbh200_shadow	itd_next;	/* ptr to periodic q entry */
-
-	struct urb		*urb;
-	struct fusbh200_iso_stream	*stream;	/* endpoint's queue */
-	struct list_head	itd_list;	/* list of stream's itds */
-
-	/* any/all hw_transactions here may be used by that urb */
-	unsigned		frame;		/* where scheduled */
-	unsigned		pg;
-	unsigned		index[8];	/* in urb->iso_frame_desc */
-} __attribute__ ((aligned (32)));
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI Specification 0.96 Section 3.7
- * Periodic Frame Span Traversal Node (FSTN)
- *
- * Manages split interrupt transactions (using TT) that span frame boundaries
- * into uframes 0/1; see 4.12.2.2.  In those uframes, a "save place" FSTN
- * makes the HC jump (back) to a QH to scan for fs/ls QH completions until
- * it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work.
- */
-struct fusbh200_fstn {
-	__hc32			hw_next;	/* any periodic q entry */
-	__hc32			hw_prev;	/* qh or FUSBH200_LIST_END */
-
-	/* the rest is HCD-private */
-	dma_addr_t		fstn_dma;
-	union fusbh200_shadow	fstn_next;	/* ptr to periodic q entry */
-} __attribute__ ((aligned (32)));
-
-/*-------------------------------------------------------------------------*/
-
-/* Prepare the PORTSC wakeup flags during controller suspend/resume */
-
-#define fusbh200_prepare_ports_for_controller_suspend(fusbh200, do_wakeup)	\
-		fusbh200_adjust_port_wakeup_flags(fusbh200, true, do_wakeup);
-
-#define fusbh200_prepare_ports_for_controller_resume(fusbh200)			\
-		fusbh200_adjust_port_wakeup_flags(fusbh200, false, false);
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * Some EHCI controllers have a Transaction Translator built into the
- * root hub. This is a non-standard feature.  Each controller will need
- * to add code to the following inline functions, and call them as
- * needed (mostly in root hub code).
- */
-
-static inline unsigned int
-fusbh200_get_speed(struct fusbh200_hcd *fusbh200, unsigned int portsc)
-{
-	return (readl(&fusbh200->regs->bmcsr)
-		& BMCSR_HOST_SPD_TYP) >> 9;
-}
-
-/* Returns the speed of a device attached to a port on the root hub. */
-static inline unsigned int
-fusbh200_port_speed(struct fusbh200_hcd *fusbh200, unsigned int portsc)
-{
-	switch (fusbh200_get_speed(fusbh200, portsc)) {
-	case 0:
-		return 0;
-	case 1:
-		return USB_PORT_STAT_LOW_SPEED;
-	case 2:
-	default:
-		return USB_PORT_STAT_HIGH_SPEED;
-	}
-}
-
-/*-------------------------------------------------------------------------*/
-
-#define	fusbh200_has_fsl_portno_bug(e)		(0)
-
-/*
- * While most USB host controllers implement their registers in
- * little-endian format, a minority (celleb companion chip) implement
- * them in big endian format.
- *
- * This attempts to support either format at compile time without a
- * runtime penalty, or both formats with the additional overhead
- * of checking a flag bit.
- *
- */
-
-#define fusbh200_big_endian_mmio(e)	0
-#define fusbh200_big_endian_capbase(e)	0
-
-static inline unsigned int fusbh200_readl(const struct fusbh200_hcd *fusbh200,
-		__u32 __iomem * regs)
-{
-	return readl(regs);
-}
-
-static inline void fusbh200_writel(const struct fusbh200_hcd *fusbh200,
-		const unsigned int val, __u32 __iomem *regs)
-{
-	writel(val, regs);
-}
-
-/* cpu to fusbh200 */
-static inline __hc32 cpu_to_hc32 (const struct fusbh200_hcd *fusbh200, const u32 x)
-{
-	return cpu_to_le32(x);
-}
-
-/* fusbh200 to cpu */
-static inline u32 hc32_to_cpu (const struct fusbh200_hcd *fusbh200, const __hc32 x)
-{
-	return le32_to_cpu(x);
-}
-
-static inline u32 hc32_to_cpup (const struct fusbh200_hcd *fusbh200, const __hc32 *x)
-{
-	return le32_to_cpup(x);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static inline unsigned fusbh200_read_frame_index(struct fusbh200_hcd *fusbh200)
-{
-	return fusbh200_readl(fusbh200, &fusbh200->regs->frame_index);
-}
-
-#define fusbh200_itdlen(urb, desc, t) ({			\
-	usb_pipein((urb)->pipe) ?				\
-	(desc)->length - FUSBH200_ITD_LENGTH(t) :			\
-	FUSBH200_ITD_LENGTH(t);					\
-})
-/*-------------------------------------------------------------------------*/
-
-#endif /* __LINUX_FUSBH200_H */
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* Re: [PATCH 01/14] RFC: usb/host/fotg210: Fix coding style issues
  2015-09-21 15:01                 ` [PATCH 01/14] RFC: usb/host/fotg210: Fix coding style issues Peter Senna Tschudin
@ 2015-10-02 17:29                   ` Felipe Balbi
  0 siblings, 0 replies; 61+ messages in thread
From: Felipe Balbi @ 2015-10-02 17:29 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh

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

On Mon, Sep 21, 2015 at 05:01:05PM +0200, Peter Senna Tschudin wrote:
> This patch fix coding style issues reported by checkpatch that do not
> change semantics of the code.
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
> ---
>  drivers/usb/host/fotg210-hcd.c | 1248 +++++++++++++++++-----------------------
>  drivers/usb/host/fotg210.h     |   36 +-
>  2 files changed, 558 insertions(+), 726 deletions(-)
> 
> diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
> index 000ed80..48eac34 100644
> --- a/drivers/usb/host/fotg210-hcd.c
> +++ b/drivers/usb/host/fotg210-hcd.c
> @@ -50,32 +50,30 @@
>  #include <asm/irq.h>
>  #include <asm/unaligned.h>
>  
> -/*-------------------------------------------------------------------------*/
>  #define DRIVER_AUTHOR "Yuan-Hsin Chen"
>  #define DRIVER_DESC "FOTG210 Host Controller (EHCI) Driver"
> -
> -static const char	hcd_name[] = "fotg210_hcd";
> +static const char hcd_name[] = "fotg210_hcd";
>  
>  #undef FOTG210_URB_TRACE
> -
>  #define FOTG210_STATS
>  
>  /* magic numbers that can affect system performance */
> -#define	FOTG210_TUNE_CERR		3 /* 0-3 qtd retries; 0 == don't stop */
> -#define	FOTG210_TUNE_RL_HS		4 /* nak throttle; see 4.9 */
> -#define	FOTG210_TUNE_RL_TT		0
> -#define	FOTG210_TUNE_MULT_HS	1	/* 1-3 transactions/uframe; 4.10.3 */
> -#define	FOTG210_TUNE_MULT_TT	1
> +#define FOTG210_TUNE_CERR	3 /* 0-3 qtd retries; 0 == don't stop */
> +#define FOTG210_TUNE_RL_HS	4 /* nak throttle; see 4.9 */
> +#define FOTG210_TUNE_RL_TT	0
> +#define FOTG210_TUNE_MULT_HS	1 /* 1-3 transactions/uframe; 4.10.3 */
> +#define FOTG210_TUNE_MULT_TT	1
> +
>  /*
> - * Some drivers think it's safe to schedule isochronous transfers more than
> - * 256 ms into the future (partly as a result of an old bug in the scheduling
> + * Some drivers think it's safe to schedule isochronous transfers more than 256
> + * ms into the future (partly as a result of an old bug in the scheduling
>   * code).  In an attempt to avoid trouble, we will use a minimum scheduling
>   * length of 512 frames instead of 256.
>   */
> -#define	FOTG210_TUNE_FLS		1 /* (medium) 512-frame schedule */
> +#define FOTG210_TUNE_FLS 1 /* (medium) 512-frame schedule */
>  
>  /* Initial IRQ latency:  faster than hw default */
> -static int log2_irq_thresh;		/* 0 to 6 */
> +static int log2_irq_thresh; /* 0 to 6 */
>  module_param(log2_irq_thresh, int, S_IRUGO);
>  MODULE_PARM_DESC(log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
>  
> @@ -89,66 +87,57 @@ static unsigned int hird;
>  module_param(hird, int, S_IRUGO);
>  MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
>  
> -#define	INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
> +#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
>  
>  #include "fotg210.h"
>  
> -/*-------------------------------------------------------------------------*/
> -
>  #define fotg210_dbg(fotg210, fmt, args...) \
> -	dev_dbg(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
> +	dev_dbg(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
>  #define fotg210_err(fotg210, fmt, args...) \
> -	dev_err(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
> +	dev_err(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
>  #define fotg210_info(fotg210, fmt, args...) \
> -	dev_info(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
> +	dev_info(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
>  #define fotg210_warn(fotg210, fmt, args...) \
> -	dev_warn(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
> +	dev_warn(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
>  
> -/* check the values in the HCSPARAMS register
> - * (host controller _Structural_ parameters)
> - * see EHCI spec, Table 2-4 for each value
> +/* check the values in the HCSPARAMS register (host controller _Structural_

if you're fixing coding style issues, you might as well go ahead and fix this
comment style too:

/*
 * check the values ....

--
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 02/14] RFC: usb/host/fotg210: remove KERN_WARNING from pr_info
  2015-09-21 15:01                 ` [PATCH 02/14] RFC: usb/host/fotg210: remove KERN_WARNING from pr_info Peter Senna Tschudin
  2015-09-21 18:54                   ` Sergei Shtylyov
@ 2015-10-02 17:30                   ` Felipe Balbi
  1 sibling, 0 replies; 61+ messages in thread
From: Felipe Balbi @ 2015-10-02 17:30 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh

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

On Mon, Sep 21, 2015 at 05:01:06PM +0200, Peter Senna Tschudin wrote:
> This patch remove KERN_WARNING from a call to pr_info().

s/pr_info/pr_warn/

other than that, looks good

> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
> ---
>  drivers/usb/host/fotg210-hcd.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
> index 48eac34..36413b2 100644
> --- a/drivers/usb/host/fotg210-hcd.c
> +++ b/drivers/usb/host/fotg210-hcd.c
> @@ -5740,7 +5740,7 @@ static int __init fotg210_hcd_init(void)
>  	set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
>  	if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
>  			test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
> -		pr_warn(KERN_WARNING "Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
> +		pr_warn("Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
>  
>  	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd\n",
>  		 hcd_name,
> -- 
> 2.1.0
> 

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 03/14] RFC: usb/host/fotg210: Remove useless else statement
  2015-09-21 15:01                 ` [PATCH 03/14] RFC: usb/host/fotg210: Remove useless else statement Peter Senna Tschudin
@ 2015-10-02 17:30                   ` Felipe Balbi
  0 siblings, 0 replies; 61+ messages in thread
From: Felipe Balbi @ 2015-10-02 17:30 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh

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

On Mon, Sep 21, 2015 at 05:01:07PM +0200, Peter Senna Tschudin wrote:
> This patch remove an else statement after a return to make the code
> easier to understand.
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>

looks good to me.

> ---
>  drivers/usb/host/fotg210-hcd.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
> index 36413b2..f574143 100644
> --- a/drivers/usb/host/fotg210-hcd.c
> +++ b/drivers/usb/host/fotg210-hcd.c
> @@ -1410,10 +1410,9 @@ static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
>  			"Failed to enable port %d on root hub TT\n",
>  			index+1);
>  		return port_status;
> -	} else {
> -		fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
> -			index + 1);
>  	}
> +	fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
> +		    index + 1);
>  
>  	return port_status;
>  }
> -- 
> 2.1.0
> 

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 04/14] RFC: usb/host/fotg210: Remove NULL checks dma_pool_destroy
  2015-09-21 15:01                 ` [PATCH 04/14] RFC: usb/host/fotg210: Remove NULL checks dma_pool_destroy Peter Senna Tschudin
@ 2015-10-02 17:30                   ` Felipe Balbi
  0 siblings, 0 replies; 61+ messages in thread
From: Felipe Balbi @ 2015-10-02 17:30 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh

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

On Mon, Sep 21, 2015 at 05:01:08PM +0200, Peter Senna Tschudin wrote:
> This patch remove NULL checks before calls to dma_pool_destroy() as the
> function now can handle NULL pointers.
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>

looks good to me

> ---
>  drivers/usb/host/fotg210-hcd.c | 12 ++++--------
>  1 file changed, 4 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
> index f574143..51feb61 100644
> --- a/drivers/usb/host/fotg210-hcd.c
> +++ b/drivers/usb/host/fotg210-hcd.c
> @@ -1925,17 +1925,13 @@ static void fotg210_mem_cleanup(struct fotg210_hcd *fotg210)
>  	fotg210->dummy = NULL;
>  
>  	/* DMA consistent memory and pools */
> -	if (fotg210->qtd_pool)
> -		dma_pool_destroy(fotg210->qtd_pool);
> +	dma_pool_destroy(fotg210->qtd_pool);
>  	fotg210->qtd_pool = NULL;
>  
> -	if (fotg210->qh_pool) {
> -		dma_pool_destroy(fotg210->qh_pool);
> -		fotg210->qh_pool = NULL;
> -	}
> +	dma_pool_destroy(fotg210->qh_pool);
> +	fotg210->qh_pool = NULL;
>  
> -	if (fotg210->itd_pool)
> -		dma_pool_destroy(fotg210->itd_pool);
> +	dma_pool_destroy(fotg210->itd_pool);
>  	fotg210->itd_pool = NULL;
>  
>  	if (fotg210->periodic)
> -- 
> 2.1.0
> 

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 05/14] RFC: usb/host/fotg210: change kmalloc by kmalloc_array
  2015-09-21 15:01                 ` [PATCH 05/14] RFC: usb/host/fotg210: change kmalloc by kmalloc_array Peter Senna Tschudin
  2015-09-21 18:56                   ` Sergei Shtylyov
@ 2015-10-02 17:30                   ` Felipe Balbi
  1 sibling, 0 replies; 61+ messages in thread
From: Felipe Balbi @ 2015-10-02 17:30 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh

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

On Mon, Sep 21, 2015 at 05:01:09PM +0200, Peter Senna Tschudin wrote:
> This patch change:
> 
> kmalloc(DBG_SCHED_LIMIT * sizeof(*seen), GFP_ATOMIC)
> 
> by:
> 
> kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC)
> 
> as kmalloc_array() should be used for allocating arrays.
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>

looks good to me

> ---
>  drivers/usb/host/fotg210-hcd.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
> index 51feb61..e7e9991 100644
> --- a/drivers/usb/host/fotg210-hcd.c
> +++ b/drivers/usb/host/fotg210-hcd.c
> @@ -501,7 +501,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
>  	unsigned i;
>  	__hc32 tag;
>  
> -	seen = kmalloc(DBG_SCHED_LIMIT * sizeof(*seen), GFP_ATOMIC);
> +	seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC);
>  	if (!seen)
>  		return 0;
>  
> -- 
> 2.1.0
> 

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 06/14] RFC: usb/host/fotg210: replace msleep by usleep_range
  2015-09-21 15:01                 ` [PATCH 06/14] RFC: usb/host/fotg210: replace msleep by usleep_range Peter Senna Tschudin
@ 2015-10-02 17:31                   ` Felipe Balbi
  2015-10-02 17:52                     ` Alan Stern
  0 siblings, 1 reply; 61+ messages in thread
From: Felipe Balbi @ 2015-10-02 17:31 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh

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

On Mon, Sep 21, 2015 at 05:01:10PM +0200, Peter Senna Tschudin wrote:
> msleep under 20ms can result in sleeping up to 20ms, which may not be
> intended. Replace msleep(5) by usleep_range(5000, 6000).
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>

good catch. I'd apply this straight away. Alan ?

> ---
>  drivers/usb/host/fotg210-hcd.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
> index e7e9991..55c2279 100644
> --- a/drivers/usb/host/fotg210-hcd.c
> +++ b/drivers/usb/host/fotg210-hcd.c
> @@ -5122,7 +5122,7 @@ static int fotg210_run(struct usb_hcd *hcd)
>  	fotg210->rh_state = FOTG210_RH_RUNNING;
>  	/* unblock posted writes */
>  	fotg210_readl(fotg210, &fotg210->regs->command);
> -	msleep(5);
> +	usleep_range(5000, 6000);
>  	up_write(&ehci_cf_port_reset_rwsem);
>  	fotg210->last_periodic_enable = ktime_get_real();
>  
> -- 
> 2.1.0
> 

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 07/14] RFC: usb/host/fotg210: Remove a macro from snprintf
  2015-09-21 15:01                 ` [PATCH 07/14] RFC: usb/host/fotg210: Remove a macro from snprintf Peter Senna Tschudin
@ 2015-10-02 17:31                   ` Felipe Balbi
  0 siblings, 0 replies; 61+ messages in thread
From: Felipe Balbi @ 2015-10-02 17:31 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh

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

On Mon, Sep 21, 2015 at 05:01:11PM +0200, Peter Senna Tschudin wrote:
> This patch removes a macro from a call to snprintf() and moves it's
> content to just before the call to snprintf() assigning a value to a new
> variable named tmp. The goal of this patch is to make the code easier to
> understand.
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>

it's a little unnecessary, but no objections.

> ---
>  drivers/usb/host/fotg210-hcd.c | 43 ++++++++++++++++++++++--------------------
>  1 file changed, 23 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
> index 55c2279..4032ed0 100644
> --- a/drivers/usb/host/fotg210-hcd.c
> +++ b/drivers/usb/host/fotg210-hcd.c
> @@ -367,6 +367,8 @@ static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
>  	unsigned size = *sizep;
>  	char *next = *nextp;
>  	char mark;
> +	char *tmp;
> +
>  	__le32 list_end = FOTG210_LIST_END(fotg210);
>  	struct fotg210_qh_hw *hw = qh->hw;
>  
> @@ -411,28 +413,29 @@ static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
>  			else if (td->hw_alt_next != list_end)
>  				mark = '/';
>  		}
> -		temp = snprintf(next, size,
> -				"\n\t%p%c%s len=%d %08x urb %p",
> -				td, mark, ({ char *tmp;
> -				 switch ((scratch>>8)&0x03) {
> -				 case 0:
> -					tmp = "out";
> -					break;
> -				 case 1:
> -					tmp = "in";
> -					break;
> -				 case 2:
> -					tmp = "setup";
> -					break;
> -				 default:
> -					tmp = "?";
> -					break;
> -				 } tmp; }),
> -				(scratch >> 16) & 0x7fff,
> -				scratch,
> -				td->urb);
> +
> +		switch ((scratch >> 8) & 0x03) {
> +		case 0:
> +			tmp = "out";
> +			break;
> +		case 1:
> +			tmp = "in";
> +			break;
> +		case 2:
> +			tmp = "setup";
> +			break;
> +		default:
> +			tmp = "?";
> +			break;
> +		}
> +
> +		temp = snprintf(next, size, "\n\t%p%c%s len=%d %08x urb %p",
> +				td, mark, tmp, (scratch >> 16) & 0x7fff,
> +				scratch, td->urb);
> +
>  		if (size < temp)
>  			temp = size;
> +
>  		size -= temp;
>  		next += temp;
>  		if (temp == size)
> -- 
> 2.1.0
> 

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 08/14] RFC: usb/host/fotg210: convert macro to inline function
  2015-09-21 15:01                 ` [PATCH 08/14] RFC: usb/host/fotg210: convert macro to inline function Peter Senna Tschudin
@ 2015-10-02 17:32                   ` Felipe Balbi
  0 siblings, 0 replies; 61+ messages in thread
From: Felipe Balbi @ 2015-10-02 17:32 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh

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

On Mon, Sep 21, 2015 at 05:01:12PM +0200, Peter Senna Tschudin wrote:
> This patch convert the macro speed_char in an inline function. The goal
> of this patch is to make the code easier to read.
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>

looks good

> ---
>  drivers/usb/host/fotg210-hcd.c | 27 ++++++++++++++++-----------
>  1 file changed, 16 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
> index 4032ed0..82cd5da 100644
> --- a/drivers/usb/host/fotg210-hcd.c
> +++ b/drivers/usb/host/fotg210-hcd.c
> @@ -331,17 +331,22 @@ struct debug_buffer {
>  	size_t alloc_size;
>  };
>  
> -#define speed_char(info1)({ char tmp; \
> -		switch (info1 & (3 << 12)) { \
> -		case QH_FULL_SPEED:	\
> -			tmp = 'f'; break; \
> -		case QH_LOW_SPEED:	\
> -			tmp = 'l'; break; \
> -		case QH_HIGH_SPEED:	\
> -			tmp = 'h'; break; \
> -		default:		\
> -			tmp = '?'; break; \
> -		} tmp; })
> +static inline char speed_char(u32 scratch)
> +{
> +	switch (scratch & (3 << 12)) {
> +	case QH_FULL_SPEED:
> +		return 'f';
> +
> +	case QH_LOW_SPEED:
> +		return 'l';
> +
> +	case QH_HIGH_SPEED:
> +		return 'h';
> +
> +	default:
> +		return '?';
> +	}
> +}
>  
>  static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
>  {
> -- 
> 2.1.0
> 

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 09/14] RFC: usb/host/fotg210: Add function: output_buf_tds_dir()
  2015-09-21 15:01                 ` [PATCH 09/14] RFC: usb/host/fotg210: Add function: output_buf_tds_dir() Peter Senna Tschudin
  2015-09-21 19:15                   ` Sergei Shtylyov
@ 2015-10-02 17:32                   ` Felipe Balbi
  1 sibling, 0 replies; 61+ messages in thread
From: Felipe Balbi @ 2015-10-02 17:32 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh

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

On Mon, Sep 21, 2015 at 05:01:13PM +0200, Peter Senna Tschudin wrote:
> checkpatch complains about too many leading tabs because the switch
> statement starts after 6 tabs.
> 
> fill_periodic_buffer() -> for() -> do -> switch() -> if() ->
> list_for_each_entry() and finally the last switch().
> 
> This patch moves the list_for_each_entry() and the last switch() to a
> new inline function named output_buf_tds_dir(). This change makes the
> code easier to read and calm down checkpatch. This patch changes it to:
> 
> fill_periodic_buffer() -> for() -> do -> switch() -> if() ->
> output_buf_tds_dir()
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>

if you fix Sergei's comment, then I'm okay with $subject

> ---
>  drivers/usb/host/fotg210-hcd.c | 64 ++++++++++++++++++++++--------------------
>  1 file changed, 33 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
> index 82cd5da..13cca41 100644
> --- a/drivers/usb/host/fotg210-hcd.c
> +++ b/drivers/usb/host/fotg210-hcd.c
> @@ -497,6 +497,36 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
>  	return strlen(buf->output_buf);
>  }
>  
> +/* count tds, get ep direction */
> +static inline unsigned output_buf_tds_dir(char *buf,
> +					  struct fotg210_hcd *fotg210,
> +					  struct fotg210_qh_hw *hw,
> +					  struct fotg210_qh *qh, unsigned size)
> +{
> +	u32 scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
> +	struct fotg210_qtd *qtd;
> +	char *type = "";
> +	unsigned temp = 0;
> +
> +	/* count tds, get ep direction */
> +	list_for_each_entry(qtd, &qh->qtd_list, qtd_list) {
> +		temp++;
> +		switch (0x03 & (hc32_to_cpu(fotg210, qtd->hw_token) >> 8)) {
> +		case 0:
> +			type = "out";
> +			continue;
> +		case 1:
> +			type = "in";
> +			continue;
> +		}
> +	}
> +
> +	return scnprintf(buf, size, "(%c%d ep%d%s [%d/%d] q%d p%d)",
> +			 speed_char(scratch), scratch & 0x007f,
> +			 (scratch >> 8) & 0x000f, type, qh->usecs,
> +			 qh->c_usecs, temp, 0x7ff & (scratch >> 16));
> +}
> +
>  #define DBG_SCHED_LIMIT 64
>  static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
>  {
> @@ -568,37 +598,9 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
>  				}
>  				/* show more info the first time around */
>  				if (temp == seen_count) {
> -					u32 scratch = hc32_to_cpup(fotg210,
> -								&hw->hw_info1);
> -					struct fotg210_qtd *qtd;
> -					char *type = "";
> -
> -					/* count tds, get ep direction */
> -					temp = 0;
> -					list_for_each_entry(qtd,
> -							&p.qh->qtd_list,
> -							qtd_list) {
> -						temp++;
> -						switch (0x03 & (hc32_to_cpu(
> -							fotg210,
> -							qtd->hw_token) >> 8)) {
> -						case 0:
> -							type = "out";
> -							continue;
> -						case 1:
> -							type = "in";
> -							continue;
> -						}
> -					}
> -
> -					temp = scnprintf(next, size,
> -						"(%c%d ep%d%s [%d/%d] q%d p%d)",
> -						speed_char(scratch),
> -						scratch & 0x007f,
> -						(scratch >> 8) & 0x000f, type,
> -						p.qh->usecs, p.qh->c_usecs,
> -						temp,
> -						0x7ff & (scratch >> 16));
> +					temp = output_buf_tds_dir(next,
> +								  fotg210, hw,
> +								  p.qh, size);
>  
>  					if (seen_count < DBG_SCHED_LIMIT)
>  						seen[seen_count++].qh = p.qh;
> -- 
> 2.1.0
> 

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 10/14] RFC: usb/host/fotg210: Add function scan_frame_queue()
  2015-09-21 15:01                 ` [PATCH 10/14] RFC: usb/host/fotg210: Add function scan_frame_queue() Peter Senna Tschudin
@ 2015-10-02 17:35                   ` Felipe Balbi
  0 siblings, 0 replies; 61+ messages in thread
From: Felipe Balbi @ 2015-10-02 17:35 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh

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

On Mon, Sep 21, 2015 at 05:01:14PM +0200, Peter Senna Tschudin wrote:
> checkpatch complains about too many leading tabs because the if
> statement starts after 6 tabs:
> 
> scan_iosoc() -> for() -> while() -> switch() -> if() -> for() -> if()
> 
> There is also a goto statement going backwards in case of failure. This
> patch creates a new inline function named scan_frame_queue() containing
> the last 4 nesting levels, and removes the need of backwards goto,
> making the code easier to read. After the patch it becomes:
> 
> scan_iosoc() -> for() -> while() -> scan_frame_queue()
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
> ---
>  drivers/usb/host/fotg210-hcd.c | 142 ++++++++++++++++++++++-------------------
>  1 file changed, 76 insertions(+), 66 deletions(-)
> 
> diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
> index 13cca41..e60a239 100644
> --- a/drivers/usb/host/fotg210-hcd.c
> +++ b/drivers/usb/host/fotg210-hcd.c
> @@ -4645,13 +4645,81 @@ done:
>  	return status;
>  }
>  
> -/*-------------------------------------------------------------------------*/
> +static inline int scan_frame_queue(struct fotg210_hcd *fotg210, unsigned frame,
> +				   unsigned now_frame, bool live)
> +{
> +	unsigned uf;
> +	bool modified;
> +	union fotg210_shadow q, *q_p;
> +	__hc32 type, *hw_p;
> +
> +	/* scan each element in frame's queue for completions */
> +	q_p = &fotg210->pshadow[frame];
> +	hw_p = &fotg210->periodic[frame];
> +	q.ptr = q_p->ptr;
> +	type = Q_NEXT_TYPE(fotg210, *hw_p);
> +	modified = false;
> +
> +	while (q.ptr != NULL) {

while (q.ptr) is enough

> +		switch (hc32_to_cpu(fotg210, type)) {
> +		case Q_TYPE_ITD:
> +			/* If this ITD is still active, leave it for

comment style

> +			 * later processing ... check the next entry.
> +			 * No need to check for activity unless the
> +			 * frame is current.
> +			 */
> +			if (frame == now_frame && live) {
> +				rmb();
> +				for (uf = 0; uf < 8; uf++) {
> +					if (q.itd->hw_transaction[uf] &
> +						    ITD_ACTIVE(fotg210))
> +						break;
> +				}
> +				if (uf < 8) {
> +					q_p = &q.itd->itd_next;
> +					hw_p = &q.itd->hw_next;
> +					type = Q_NEXT_TYPE(fotg210,
> +						q.itd->hw_next);
> +					q = *q_p;
> +					break;
> +				}
> +			}
> +
> +			/* Take finished ITDs out of the schedule

comment style

> +			 * and process them:  recycle, maybe report
> +			 * URB completion.  HC won't cache the
> +			 * pointer for much longer, if at all.
> +			 */
> +			*q_p = q.itd->itd_next;
> +			*hw_p = q.itd->hw_next;
> +			type = Q_NEXT_TYPE(fotg210, q.itd->hw_next);
> +			wmb();
> +			modified = itd_complete(fotg210, q.itd);
> +			q = *q_p;
> +			break;
> +		default:
> +			fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
> +				type, frame, q.ptr);
> +			/* FALL THROUGH */
> +		case Q_TYPE_QH:
> +		case Q_TYPE_FSTN:
> +			/* End of the iTDs and siTDs */
> +			q.ptr = NULL;
> +			break;
> +		}
> +
> +		/* assume completion callbacks modify the queue */
> +		if (unlikely(modified && fotg210->isoc_count > 0))
> +			return -1;

can't you add a proper error code here ?

other than these, patch looks good.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 11/14] RFC: usb/host: Rename fotg210-hcd to faraday-hcd
  2015-09-21 15:01                 ` [PATCH 11/14] RFC: usb/host: Rename fotg210-hcd to faraday-hcd Peter Senna Tschudin
@ 2015-10-02 17:35                   ` Felipe Balbi
  0 siblings, 0 replies; 61+ messages in thread
From: Felipe Balbi @ 2015-10-02 17:35 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh

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

On Mon, Sep 21, 2015 at 05:01:15PM +0200, Peter Senna Tschudin wrote:
> This patch renames fotg210-hcd to faraday-hcd as a first step of
> consolitating Faraday fotg210 and fusbh200 EHCI-like drivers.
> 
> The patch also updates Kconfig and Makefile.
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>

please regenerate the patch with -C -M added to git format-patch

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 12/14] RFC: usb/host/faraday-hcd: Replace fotg210 by fhcd2xx
  2015-09-21 15:01                 ` [PATCH 12/14] RFC: usb/host/faraday-hcd: Replace fotg210 by fhcd2xx Peter Senna Tschudin
@ 2015-10-02 17:36                   ` Felipe Balbi
  0 siblings, 0 replies; 61+ messages in thread
From: Felipe Balbi @ 2015-10-02 17:36 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh

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

On Mon, Sep 21, 2015 at 05:01:16PM +0200, Peter Senna Tschudin wrote:
> This patch replaces the strings:
> FOTG210 by FHCD2XX
> fotg210 by fhcd2xx
> 
> The goal is to remove all references to fotg210 as the driver will
> support both fotg210 and fusbh200.
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>

after a quick look, it looks okay. Keep in mind I don't have HW.


-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 13/14] RFC: usb/host/faraday-hcd: Move #defines outside struct
  2015-09-21 15:01                 ` [PATCH 13/14] RFC: usb/host/faraday-hcd: Move #defines outside struct Peter Senna Tschudin
@ 2015-10-02 17:37                   ` Felipe Balbi
  0 siblings, 0 replies; 61+ messages in thread
From: Felipe Balbi @ 2015-10-02 17:37 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh

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

On Mon, Sep 21, 2015 at 05:01:17PM +0200, Peter Senna Tschudin wrote:
> For making the code more readable and to facilitate supporting multiple
> hardware versions, move #defines to outside the struct declaration. This
> patch also renames fhcd2xx_regs to fotg210_regs as this struct is
> specific to fotg210.
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
> ---
>  drivers/usb/host/faraday-hcd.h | 137 ++++++++++++++++++++++-------------------
>  1 file changed, 74 insertions(+), 63 deletions(-)
> 
> diff --git a/drivers/usb/host/faraday-hcd.h b/drivers/usb/host/faraday-hcd.h
> index cf29edf..f75c467 100644
> --- a/drivers/usb/host/faraday-hcd.h
> +++ b/drivers/usb/host/faraday-hcd.h
> @@ -85,7 +85,7 @@ struct fhcd2xx_hcd {			/* one per controller */
>  
>  	/* glue to PCI and HCD framework */
>  	struct fhcd2xx_caps __iomem *caps;
> -	struct fhcd2xx_regs __iomem *regs;
> +	struct fotg210_regs __iomem *regs;

should this be in previous patch ?

personally, I don't see what's the benefit of this patch, however not against it
either.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 14/14] RFC: usb/host/faraday-hcd: Import FUSBH200 parameters
  2015-09-21 15:01                 ` [PATCH 14/14] RFC: usb/host/faraday-hcd: Import FUSBH200 parameters Peter Senna Tschudin
@ 2015-10-02 17:38                   ` Felipe Balbi
  0 siblings, 0 replies; 61+ messages in thread
From: Felipe Balbi @ 2015-10-02 17:38 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: balbi, stern, sergei.shtylyov, standby24x7, pmladek, linux-usb,
	linux-kernel, gregkh

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

On Mon, Sep 21, 2015 at 05:01:18PM +0200, Peter Senna Tschudin wrote:
> This patch adds FUSBH200 parameters to faraday-hcd.h.
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>

fine by me


-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH] usb-host: Remove fusbh200 driver
  2015-10-02 11:18                 ` [PATCH] usb-host: Remove fusbh200 driver Peter Senna Tschudin
@ 2015-10-02 17:39                   ` Felipe Balbi
  2015-10-03  9:56                     ` Peter Senna Tschudin
  0 siblings, 1 reply; 61+ messages in thread
From: Felipe Balbi @ 2015-10-02 17:39 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: john453, yuanlmm, gregkh, stern, mathias.nyman, ralf,
	alexandre.belloni, ramneek.mehresh, laurent.pinchart, abrestic,
	sboyd, zajec5, haokexin, balbi, pebolle, sergei.shtylyov,
	standby24x7, rdunlap, chris, linux-kernel, linux-usb

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

On Fri, Oct 02, 2015 at 01:18:27PM +0200, Peter Senna Tschudin wrote:
> fusbh200 and fotg210 are very similar. The initial idea was to consolidate
> both drivers but I'm afraid fusbh200 is not being used.
> 
> This patch remove the fusbh200 source code, update Kconfig and two
> Makefiles.
> 
> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>

after all this work on these previous patches, you just remove fusbh200 ?

that's a bit odd. Are you sure there are no users for this driver ? It has been
in tree since 2013.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 06/14] RFC: usb/host/fotg210: replace msleep by usleep_range
  2015-10-02 17:31                   ` Felipe Balbi
@ 2015-10-02 17:52                     ` Alan Stern
  2015-10-04  9:58                       ` Peter Senna Tschudin
  0 siblings, 1 reply; 61+ messages in thread
From: Alan Stern @ 2015-10-02 17:52 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: Peter Senna Tschudin, sergei.shtylyov, standby24x7, pmladek,
	linux-usb, linux-kernel, gregkh

On Fri, 2 Oct 2015, Felipe Balbi wrote:

> On Mon, Sep 21, 2015 at 05:01:10PM +0200, Peter Senna Tschudin wrote:
> > msleep under 20ms can result in sleeping up to 20ms, which may not be
> > intended. Replace msleep(5) by usleep_range(5000, 6000).
> > 
> > Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
> 
> good catch. I'd apply this straight away. Alan ?

It really doesn't matter.  As long as the delay is at least 5 ms, it
can be arbitrarily long.  This won't hurt, and if it prevents automated
tools from complaining then it's worthwhile.

Peter, a lot of the changes you have been making will also apply to the 
ehci-hcd driver.  Do you want to update it as well?  One caution: The 
style used for continuation lines is to add two extra tab stops, not to 
align things with an open paren on the original line.

Alan Stern


^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH] usb-host: Remove fusbh200 driver
  2015-10-02 17:39                   ` Felipe Balbi
@ 2015-10-03  9:56                     ` Peter Senna Tschudin
  2015-10-03 21:21                       ` Felipe Balbi
  0 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-10-03  9:56 UTC (permalink / raw)
  To: Felipe Balbi
  Cc: John Feng-Hsin Chiang(江峰興),
	Yuan-Hsin Chen, Greg Kroah-Hartman, Alan Stern, mathias.nyman,
	ralf, alexandre.belloni, ramneek.mehresh, Laurent Pinchart,
	abrestic, sboyd, Rafał Miłecki, haokexin, pebolle,
	Sergei Shtylyov, Masanari Iida, Randy Dunlap, chris,
	linux-kernel, linux-usb

On Fri, Oct 2, 2015 at 7:39 PM, Felipe Balbi <balbi@ti.com> wrote:
> On Fri, Oct 02, 2015 at 01:18:27PM +0200, Peter Senna Tschudin wrote:
>> fusbh200 and fotg210 are very similar. The initial idea was to consolidate
>> both drivers but I'm afraid fusbh200 is not being used.
>>
>> This patch remove the fusbh200 source code, update Kconfig and two
>> Makefiles.
>>
>> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
>
> after all this work on these previous patches, you just remove fusbh200 ?
>
> that's a bit odd. Are you sure there are no users for this driver ? It has been
> in tree since 2013.
I don't know about users, but I could not find devices using fusbh200.
The closest I got was:

http://www.ebay.fr/itm/Digital-Video-Langzeit-Recorder-H264-DVR-3G-4-Kanal-/370525106495

But it only says: Main Processor: Faraday. I don't know which usb host
controller it uses.

The idea of deleting fusbh200 came from contacting the driver authors.
I was asking where to find hw for testing, and I was told that the
fusbh200 driver can be deleted. Also at least Fedora and Ubuntu build
modules for these host controllers by default. If fusbh200 and fotg210
are only available integrated into SOCs, maybe building the modules by
default for x86 is not a good idea. But if there are users I'll be
happy to continue the integration work, even better if I find hardware
for testing.

John Feng-Hsin Chiang, can you confirm that from your side the
fusbh200 driver can be deleted?

For the patches I sent, 10 of 14 are for fotg210 which I'll fix and resend.

-- 
Peter

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH] usb-host: Remove fusbh200 driver
  2015-10-03  9:56                     ` Peter Senna Tschudin
@ 2015-10-03 21:21                       ` Felipe Balbi
  2015-10-05  0:25                         ` John Feng-Hsin Chiang(江峰興)
  0 siblings, 1 reply; 61+ messages in thread
From: Felipe Balbi @ 2015-10-03 21:21 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: John Feng-Hsin Chiang, Yuan-Hsin Chen, Greg Kroah-Hartman,
	Alan Stern, mathias.nyman, ralf, alexandre.belloni,
	ramneek.mehresh, Laurent Pinchart, abrestic, sboyd,
	Rafał Miłecki, haokexin, pebolle, Sergei Shtylyov,
	Masanari Iida, Randy Dunlap, chris, linux-kernel, linux-usb

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

Peter Senna Tschudin <peter.senna@gmail.com> writes:

> On Fri, Oct 2, 2015 at 7:39 PM, Felipe Balbi <balbi@ti.com> wrote:
>> On Fri, Oct 02, 2015 at 01:18:27PM +0200, Peter Senna Tschudin wrote:
>>> fusbh200 and fotg210 are very similar. The initial idea was to consolidate
>>> both drivers but I'm afraid fusbh200 is not being used.
>>>
>>> This patch remove the fusbh200 source code, update Kconfig and two
>>> Makefiles.
>>>
>>> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
>>
>> after all this work on these previous patches, you just remove fusbh200 ?
>>
>> that's a bit odd. Are you sure there are no users for this driver ? It has been
>> in tree since 2013.
> I don't know about users, but I could not find devices using fusbh200.
> The closest I got was:
>
> http://www.ebay.fr/itm/Digital-Video-Langzeit-Recorder-H264-DVR-3G-4-Kanal-/370525106495
>
> But it only says: Main Processor: Faraday. I don't know which usb host
> controller it uses.
>
> The idea of deleting fusbh200 came from contacting the driver authors.
> I was asking where to find hw for testing, and I was told that the
> fusbh200 driver can be deleted. Also at least Fedora and Ubuntu build
> modules for these host controllers by default. If fusbh200 and fotg210
> are only available integrated into SOCs, maybe building the modules by
> default for x86 is not a good idea. But if there are users I'll be
> happy to continue the integration work, even better if I find hardware
> for testing.

fair enough, if can be deleted it's fine...

> John Feng-Hsin Chiang, can you confirm that from your side the
> fusbh200 driver can be deleted?

... but let's get this confirmation.

> For the patches I sent, 10 of 14 are for fotg210 which I'll fix and resend.

cool, thanks

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 06/14] RFC: usb/host/fotg210: replace msleep by usleep_range
  2015-10-02 17:52                     ` Alan Stern
@ 2015-10-04  9:58                       ` Peter Senna Tschudin
  2015-10-04 15:20                         ` Alan Stern
  0 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-10-04  9:58 UTC (permalink / raw)
  To: Alan Stern
  Cc: Felipe Balbi, Sergei Shtylyov, Masanari Iida, pmladek, linux-usb,
	linux-kernel, Greg Kroah-Hartman

On Fri, Oct 2, 2015 at 7:52 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
> On Fri, 2 Oct 2015, Felipe Balbi wrote:
>
>> On Mon, Sep 21, 2015 at 05:01:10PM +0200, Peter Senna Tschudin wrote:
>> > msleep under 20ms can result in sleeping up to 20ms, which may not be
>> > intended. Replace msleep(5) by usleep_range(5000, 6000).
>> >
>> > Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
>>
>> good catch. I'd apply this straight away. Alan ?
>
> It really doesn't matter.  As long as the delay is at least 5 ms, it
> can be arbitrarily long.  This won't hurt, and if it prevents automated
> tools from complaining then it's worthwhile.
Then is it a good idea to increase the range to reduce chances of
creating an interrupt?

usleep_range(5000, 10000)?

>
> Peter, a lot of the changes you have been making will also apply to the
> ehci-hcd driver.  Do you want to update it as well?  One caution: The
> style used for continuation lines is to add two extra tab stops, not to
> align things with an open paren on the original line.
The drivers with more checkpatch errors and warnings are:

<number of errors> <number of warnings> <path>

117 586 drivers/usb/host/fusbh200-hcd.c
38 124 drivers/usb/host/ohci-q.c
38 122 drivers/usb/host/ehci-dbg.c
37 118 drivers/usb/host/ohci-dbg.c
36 129 drivers/usb/host/ehci-sched.c
24 136 drivers/usb/host/ohci-hcd.c
23 16 drivers/usb/host/sl811-hcd.c
20 105 drivers/usb/host/ohci-hub.c
18 48 drivers/usb/host/ehci-hub.c

17 70 drivers/usb/host/ehci-hcd.c

13 4 drivers/usb/host/uhci-debug.c
12 93 drivers/usb/host/ehci-q.c
9 83 drivers/usb/host/isp116x-hcd.c
9 32 drivers/usb/host/fotg210-hcd.c
7 29 drivers/usb/host/oxu210hp-hcd.c
6 4 drivers/usb/host/sl811_cs.c

I'll fix ehci-hcd. Do you want patches for the others?

I'll fix the alignment using two extra tabs instead of aligning with
opening parenthesis. Thank you.


-- 
Peter

^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: [PATCH 06/14] RFC: usb/host/fotg210: replace msleep by usleep_range
  2015-10-04  9:58                       ` Peter Senna Tschudin
@ 2015-10-04 15:20                         ` Alan Stern
  0 siblings, 0 replies; 61+ messages in thread
From: Alan Stern @ 2015-10-04 15:20 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: Felipe Balbi, Sergei Shtylyov, Masanari Iida, pmladek, linux-usb,
	linux-kernel, Greg Kroah-Hartman

On Sun, 4 Oct 2015, Peter Senna Tschudin wrote:

> On Fri, Oct 2, 2015 at 7:52 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
> > On Fri, 2 Oct 2015, Felipe Balbi wrote:
> >
> >> On Mon, Sep 21, 2015 at 05:01:10PM +0200, Peter Senna Tschudin wrote:
> >> > msleep under 20ms can result in sleeping up to 20ms, which may not be
> >> > intended. Replace msleep(5) by usleep_range(5000, 6000).
> >> >
> >> > Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
> >>
> >> good catch. I'd apply this straight away. Alan ?
> >
> > It really doesn't matter.  As long as the delay is at least 5 ms, it
> > can be arbitrarily long.  This won't hurt, and if it prevents automated
> > tools from complaining then it's worthwhile.
> Then is it a good idea to increase the range to reduce chances of
> creating an interrupt?
> 
> usleep_range(5000, 10000)?

That wold be okay.

> > Peter, a lot of the changes you have been making will also apply to the
> > ehci-hcd driver.  Do you want to update it as well?  One caution: The
> > style used for continuation lines is to add two extra tab stops, not to
> > align things with an open paren on the original line.
> The drivers with more checkpatch errors and warnings are:
> 
> <number of errors> <number of warnings> <path>
> 
> 117 586 drivers/usb/host/fusbh200-hcd.c
> 38 124 drivers/usb/host/ohci-q.c
> 38 122 drivers/usb/host/ehci-dbg.c
> 37 118 drivers/usb/host/ohci-dbg.c
> 36 129 drivers/usb/host/ehci-sched.c
> 24 136 drivers/usb/host/ohci-hcd.c
> 23 16 drivers/usb/host/sl811-hcd.c
> 20 105 drivers/usb/host/ohci-hub.c
> 18 48 drivers/usb/host/ehci-hub.c
> 
> 17 70 drivers/usb/host/ehci-hcd.c
> 
> 13 4 drivers/usb/host/uhci-debug.c
> 12 93 drivers/usb/host/ehci-q.c
> 9 83 drivers/usb/host/isp116x-hcd.c
> 9 32 drivers/usb/host/fotg210-hcd.c
> 7 29 drivers/usb/host/oxu210hp-hcd.c
> 6 4 drivers/usb/host/sl811_cs.c
> 
> I'll fix ehci-hcd. Do you want patches for the others?

I was speaking of ehci-*.c, because the code in there is extremely
similar to the code you've already been working on.

There's no point in trying to fix _all_ those checkpatch violations.  A 
lot of them are trivial things like an extra space character between a 
function name and the following left paren.

Alan Stern


^ permalink raw reply	[flat|nested] 61+ messages in thread

* RE: [PATCH] usb-host: Remove fusbh200 driver
  2015-10-03 21:21                       ` Felipe Balbi
@ 2015-10-05  0:25                         ` John Feng-Hsin Chiang(江峰興)
  0 siblings, 0 replies; 61+ messages in thread
From: John Feng-Hsin Chiang(江峰興) @ 2015-10-05  0:25 UTC (permalink / raw)
  To: Felipe Balbi, Peter Senna Tschudin
  Cc: Yuan-Hsin Chen, Greg Kroah-Hartman, Alan Stern, mathias.nyman,
	ralf, alexandre.belloni, ramneek.mehresh, Laurent Pinchart,
	abrestic, sboyd, Rafa? Mi?ecki, haokexin, pebolle,
	Sergei Shtylyov, Masanari Iida, Randy Dunlap, chris,
	linux-kernel, linux-usb

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="ks_c_5601-1987", Size: 2789 bytes --]

Hi Balbi,

>> John Feng-Hsin Chiang, can you confirm that from your side the
>> fusbh200 driver can be deleted?
>... but let's get this confirmation.

Yes, you can delete fusbh200.

Best Regards,
John Chiang

-----Original Message-----
From: Felipe Balbi [mailto:balbi@ti.com] 
Sent: Sunday, October 04, 2015 5:21 AM
To: Peter Senna Tschudin
Cc: John Feng-Hsin Chiang(Ë°Üèýé); Yuan-Hsin Chen; Greg Kroah-Hartman; Alan Stern; mathias.nyman@linux.intel.com; ralf@linux-mips.org; alexandre.belloni@free-electrons.com; ramneek.mehresh@freescale.com; Laurent Pinchart; abrestic@chromium.org; sboyd@codeaurora.org; Rafa©© Mi©©ecki; haokexin@gmail.com; pebolle@tiscali.nl; Sergei Shtylyov; Masanari Iida; Randy Dunlap; chris@rorvick.com; linux-kernel@vger.kernel.org; linux-usb@vger.kernel.org
Subject: Re: [PATCH] usb-host: Remove fusbh200 driver

Peter Senna Tschudin <peter.senna@gmail.com> writes:

> On Fri, Oct 2, 2015 at 7:39 PM, Felipe Balbi <balbi@ti.com> wrote:
>> On Fri, Oct 02, 2015 at 01:18:27PM +0200, Peter Senna Tschudin wrote:
>>> fusbh200 and fotg210 are very similar. The initial idea was to 
>>> consolidate both drivers but I'm afraid fusbh200 is not being used.
>>>
>>> This patch remove the fusbh200 source code, update Kconfig and two 
>>> Makefiles.
>>>
>>> Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
>>
>> after all this work on these previous patches, you just remove fusbh200 ?
>>
>> that's a bit odd. Are you sure there are no users for this driver ? 
>> It has been in tree since 2013.
> I don't know about users, but I could not find devices using fusbh200.
> The closest I got was:
>
> http://www.ebay.fr/itm/Digital-Video-Langzeit-Recorder-H264-DVR-3G-4-K
> anal-/370525106495
>
> But it only says: Main Processor: Faraday. I don't know which usb host 
> controller it uses.
>
> The idea of deleting fusbh200 came from contacting the driver authors.
> I was asking where to find hw for testing, and I was told that the
> fusbh200 driver can be deleted. Also at least Fedora and Ubuntu build 
> modules for these host controllers by default. If fusbh200 and fotg210 
> are only available integrated into SOCs, maybe building the modules by 
> default for x86 is not a good idea. But if there are users I'll be 
> happy to continue the integration work, even better if I find hardware 
> for testing.

fair enough, if can be deleted it's fine...

> John Feng-Hsin Chiang, can you confirm that from your side the
> fusbh200 driver can be deleted?

... but let's get this confirmation.

> For the patches I sent, 10 of 14 are for fotg210 which I'll fix and resend.

cool, thanks

--
balbi
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 61+ messages in thread

* [PATCH 0/9] usb/host/fotg210: code style and warning fixes
  2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
                                   ` (14 preceding siblings ...)
  2015-10-02 11:18                 ` [PATCH] usb-host: Remove fusbh200 driver Peter Senna Tschudin
@ 2015-10-12 21:22                 ` Peter Senna Tschudin
  2015-10-12 21:22                   ` [PATCH 1/9] usb/host/fotg210: Fix coding style issues Peter Senna Tschudin
                                     ` (8 more replies)
  15 siblings, 9 replies; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-10-12 21:22 UTC (permalink / raw)
  To: gregkh, peter.senna, sergei.shtylyov, jkosina, rdunlap, balbi,
	standby24x7, chris, stern, john453, linux-usb, linux-kernel

This patch series fix warnings reported by checkpatch on the
FOTG210 EHCI-like driver.

Peter Senna Tschudin (9):
  usb/host/fotg210: Fix coding style issues
  usb/host/fotg210: remove KERN_WARNING from pr_warn
  usb/host/fotg210: Remove useless else statement
  usb/host/fotg210: Remove NULL checks dma_pool_destroy
  usb/host/fotg210: change kmalloc by kmalloc_array
  usb/host/fotg210: replace msleep by usleep_range
  usb/host/fotg210: convert macro to inline function
  usb/host/fotg210: Add function: output_buf_tds_dir()
  usb/host/fotg210: Add function scan_frame_queue()

 drivers/usb/host/fotg210-hcd.c | 1955 ++++++++++++++++++----------------------
 drivers/usb/host/fotg210.h     |   36 +-
 2 files changed, 896 insertions(+), 1095 deletions(-)

-- 
2.1.0


^ permalink raw reply	[flat|nested] 61+ messages in thread

* [PATCH 1/9] usb/host/fotg210: Fix coding style issues
  2015-10-12 21:22                 ` [PATCH 0/9] usb/host/fotg210: code style and warning fixes Peter Senna Tschudin
@ 2015-10-12 21:22                   ` Peter Senna Tschudin
  2015-10-12 21:22                   ` [PATCH 2/9] usb/host/fotg210: remove KERN_WARNING from pr_warn Peter Senna Tschudin
                                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-10-12 21:22 UTC (permalink / raw)
  To: gregkh, peter.senna, sergei.shtylyov, jkosina, rdunlap, balbi,
	standby24x7, chris, stern, john453, linux-usb, linux-kernel

This patch fix coding style issues reported by checkpatch that do not
change semantics of the code.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
This patch introduces one checkpatch warning for line over 80
characters, but my personal feeling is that it looks better
and easier to read this way.

 drivers/usb/host/fotg210-hcd.c | 1710 ++++++++++++++++++----------------------
 drivers/usb/host/fotg210.h     |   36 +-
 2 files changed, 769 insertions(+), 977 deletions(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 000ed80..d80b2e8 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -1,5 +1,4 @@
-/*
- * Faraday FOTG210 EHCI-like driver
+/* Faraday FOTG210 EHCI-like driver
  *
  * Copyright (c) 2013 Faraday Technology Corporation
  *
@@ -50,32 +49,29 @@
 #include <asm/irq.h>
 #include <asm/unaligned.h>
 
-/*-------------------------------------------------------------------------*/
 #define DRIVER_AUTHOR "Yuan-Hsin Chen"
 #define DRIVER_DESC "FOTG210 Host Controller (EHCI) Driver"
-
-static const char	hcd_name[] = "fotg210_hcd";
+static const char hcd_name[] = "fotg210_hcd";
 
 #undef FOTG210_URB_TRACE
-
 #define FOTG210_STATS
 
 /* magic numbers that can affect system performance */
-#define	FOTG210_TUNE_CERR		3 /* 0-3 qtd retries; 0 == don't stop */
-#define	FOTG210_TUNE_RL_HS		4 /* nak throttle; see 4.9 */
-#define	FOTG210_TUNE_RL_TT		0
-#define	FOTG210_TUNE_MULT_HS	1	/* 1-3 transactions/uframe; 4.10.3 */
-#define	FOTG210_TUNE_MULT_TT	1
-/*
- * Some drivers think it's safe to schedule isochronous transfers more than
- * 256 ms into the future (partly as a result of an old bug in the scheduling
+#define FOTG210_TUNE_CERR	3 /* 0-3 qtd retries; 0 == don't stop */
+#define FOTG210_TUNE_RL_HS	4 /* nak throttle; see 4.9 */
+#define FOTG210_TUNE_RL_TT	0
+#define FOTG210_TUNE_MULT_HS	1 /* 1-3 transactions/uframe; 4.10.3 */
+#define FOTG210_TUNE_MULT_TT	1
+
+/* Some drivers think it's safe to schedule isochronous transfers more than 256
+ * ms into the future (partly as a result of an old bug in the scheduling
  * code).  In an attempt to avoid trouble, we will use a minimum scheduling
  * length of 512 frames instead of 256.
  */
-#define	FOTG210_TUNE_FLS		1 /* (medium) 512-frame schedule */
+#define FOTG210_TUNE_FLS 1 /* (medium) 512-frame schedule */
 
 /* Initial IRQ latency:  faster than hw default */
-static int log2_irq_thresh;		/* 0 to 6 */
+static int log2_irq_thresh; /* 0 to 6 */
 module_param(log2_irq_thresh, int, S_IRUGO);
 MODULE_PARM_DESC(log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
 
@@ -89,66 +85,57 @@ static unsigned int hird;
 module_param(hird, int, S_IRUGO);
 MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");
 
-#define	INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
+#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
 
 #include "fotg210.h"
 
-/*-------------------------------------------------------------------------*/
-
 #define fotg210_dbg(fotg210, fmt, args...) \
-	dev_dbg(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_dbg(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 #define fotg210_err(fotg210, fmt, args...) \
-	dev_err(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_err(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 #define fotg210_info(fotg210, fmt, args...) \
-	dev_info(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_info(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 #define fotg210_warn(fotg210, fmt, args...) \
-	dev_warn(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args)
+	dev_warn(fotg210_to_hcd(fotg210)->self.controller, fmt, ## args)
 
-/* check the values in the HCSPARAMS register
- * (host controller _Structural_ parameters)
- * see EHCI spec, Table 2-4 for each value
+/* check the values in the HCSPARAMS register (host controller _Structural_
+ * parameters) see EHCI spec, Table 2-4 for each value
  */
 static void dbg_hcs_params(struct fotg210_hcd *fotg210, char *label)
 {
-	u32	params = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
+	u32 params = fotg210_readl(fotg210, &fotg210->caps->hcs_params);
 
-	fotg210_dbg(fotg210,
-		"%s hcs_params 0x%x ports=%d\n",
-		label, params,
-		HCS_N_PORTS(params)
-		);
+	fotg210_dbg(fotg210, "%s hcs_params 0x%x ports=%d\n", label, params,
+			HCS_N_PORTS(params));
 }
 
-/* check the values in the HCCPARAMS register
- * (host controller _Capability_ parameters)
- * see EHCI Spec, Table 2-5 for each value
- * */
+/* check the values in the HCCPARAMS register (host controller _Capability_
+ * parameters) see EHCI Spec, Table 2-5 for each value
+ */
 static void dbg_hcc_params(struct fotg210_hcd *fotg210, char *label)
 {
-	u32	params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
+	u32 params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
 
-	fotg210_dbg(fotg210,
-		"%s hcc_params %04x uframes %s%s\n",
-		label,
-		params,
-		HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
-		HCC_CANPARK(params) ? " park" : "");
+	fotg210_dbg(fotg210, "%s hcc_params %04x uframes %s%s\n", label,
+			params,
+			HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
+			HCC_CANPARK(params) ? " park" : "");
 }
 
 static void __maybe_unused
 dbg_qtd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd)
 {
 	fotg210_dbg(fotg210, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
-		hc32_to_cpup(fotg210, &qtd->hw_next),
-		hc32_to_cpup(fotg210, &qtd->hw_alt_next),
-		hc32_to_cpup(fotg210, &qtd->hw_token),
-		hc32_to_cpup(fotg210, &qtd->hw_buf[0]));
+			hc32_to_cpup(fotg210, &qtd->hw_next),
+			hc32_to_cpup(fotg210, &qtd->hw_alt_next),
+			hc32_to_cpup(fotg210, &qtd->hw_token),
+			hc32_to_cpup(fotg210, &qtd->hw_buf[0]));
 	if (qtd->hw_buf[1])
 		fotg210_dbg(fotg210, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
-			hc32_to_cpup(fotg210, &qtd->hw_buf[1]),
-			hc32_to_cpup(fotg210, &qtd->hw_buf[2]),
-			hc32_to_cpup(fotg210, &qtd->hw_buf[3]),
-			hc32_to_cpup(fotg210, &qtd->hw_buf[4]));
+				hc32_to_cpup(fotg210, &qtd->hw_buf[1]),
+				hc32_to_cpup(fotg210, &qtd->hw_buf[2]),
+				hc32_to_cpup(fotg210, &qtd->hw_buf[3]),
+				hc32_to_cpup(fotg210, &qtd->hw_buf[4]));
 }
 
 static void __maybe_unused
@@ -156,101 +143,100 @@ dbg_qh(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
 	struct fotg210_qh_hw *hw = qh->hw;
 
-	fotg210_dbg(fotg210, "%s qh %p n%08x info %x %x qtd %x\n", label,
-		qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
+	fotg210_dbg(fotg210, "%s qh %p n%08x info %x %x qtd %x\n", label, qh,
+			hw->hw_next, hw->hw_info1, hw->hw_info2,
+			hw->hw_current);
+
 	dbg_qtd("overlay", fotg210, (struct fotg210_qtd *) &hw->hw_qtd_next);
 }
 
 static void __maybe_unused
 dbg_itd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 {
-	fotg210_dbg(fotg210, "%s[%d] itd %p, next %08x, urb %p\n",
-		label, itd->frame, itd, hc32_to_cpu(fotg210, itd->hw_next),
-		itd->urb);
+	fotg210_dbg(fotg210, "%s[%d] itd %p, next %08x, urb %p\n", label,
+			itd->frame, itd, hc32_to_cpu(fotg210, itd->hw_next),
+			itd->urb);
+
 	fotg210_dbg(fotg210,
-		"  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
-		hc32_to_cpu(fotg210, itd->hw_transaction[0]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[1]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[2]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[3]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[4]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[5]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[6]),
-		hc32_to_cpu(fotg210, itd->hw_transaction[7]));
+			"  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
+			hc32_to_cpu(fotg210, itd->hw_transaction[0]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[1]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[2]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[3]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[4]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[5]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[6]),
+			hc32_to_cpu(fotg210, itd->hw_transaction[7]));
+
 	fotg210_dbg(fotg210,
-		"  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
-		hc32_to_cpu(fotg210, itd->hw_bufp[0]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[1]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[2]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[3]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[4]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[5]),
-		hc32_to_cpu(fotg210, itd->hw_bufp[6]));
+			"  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
+			hc32_to_cpu(fotg210, itd->hw_bufp[0]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[1]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[2]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[3]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[4]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[5]),
+			hc32_to_cpu(fotg210, itd->hw_bufp[6]));
+
 	fotg210_dbg(fotg210, "  index: %d %d %d %d %d %d %d %d\n",
-		itd->index[0], itd->index[1], itd->index[2],
-		itd->index[3], itd->index[4], itd->index[5],
-		itd->index[6], itd->index[7]);
+			itd->index[0], itd->index[1], itd->index[2],
+			itd->index[3], itd->index[4], itd->index[5],
+			itd->index[6], itd->index[7]);
 }
 
 static int __maybe_unused
 dbg_status_buf(char *buf, unsigned len, const char *label, u32 status)
 {
-	return scnprintf(buf, len,
-		"%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
-		label, label[0] ? " " : "", status,
-		(status & STS_ASS) ? " Async" : "",
-		(status & STS_PSS) ? " Periodic" : "",
-		(status & STS_RECL) ? " Recl" : "",
-		(status & STS_HALT) ? " Halt" : "",
-		(status & STS_IAA) ? " IAA" : "",
-		(status & STS_FATAL) ? " FATAL" : "",
-		(status & STS_FLR) ? " FLR" : "",
-		(status & STS_PCD) ? " PCD" : "",
-		(status & STS_ERR) ? " ERR" : "",
-		(status & STS_INT) ? " INT" : ""
-		);
+	return scnprintf(buf, len, "%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s",
+			label, label[0] ? " " : "", status,
+			(status & STS_ASS) ? " Async" : "",
+			(status & STS_PSS) ? " Periodic" : "",
+			(status & STS_RECL) ? " Recl" : "",
+			(status & STS_HALT) ? " Halt" : "",
+			(status & STS_IAA) ? " IAA" : "",
+			(status & STS_FATAL) ? " FATAL" : "",
+			(status & STS_FLR) ? " FLR" : "",
+			(status & STS_PCD) ? " PCD" : "",
+			(status & STS_ERR) ? " ERR" : "",
+			(status & STS_INT) ? " INT" : "");
 }
 
 static int __maybe_unused
 dbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable)
 {
-	return scnprintf(buf, len,
-		"%s%sintrenable %02x%s%s%s%s%s%s",
-		label, label[0] ? " " : "", enable,
-		(enable & STS_IAA) ? " IAA" : "",
-		(enable & STS_FATAL) ? " FATAL" : "",
-		(enable & STS_FLR) ? " FLR" : "",
-		(enable & STS_PCD) ? " PCD" : "",
-		(enable & STS_ERR) ? " ERR" : "",
-		(enable & STS_INT) ? " INT" : ""
-		);
+	return scnprintf(buf, len, "%s%sintrenable %02x%s%s%s%s%s%s",
+			label, label[0] ? " " : "", enable,
+			(enable & STS_IAA) ? " IAA" : "",
+			(enable & STS_FATAL) ? " FATAL" : "",
+			(enable & STS_FLR) ? " FLR" : "",
+			(enable & STS_PCD) ? " PCD" : "",
+			(enable & STS_ERR) ? " ERR" : "",
+			(enable & STS_INT) ? " INT" : "");
 }
 
 static const char *const fls_strings[] = { "1024", "512", "256", "??" };
 
-static int
-dbg_command_buf(char *buf, unsigned len, const char *label, u32 command)
+static int dbg_command_buf(char *buf, unsigned len, const char *label,
+		u32 command)
 {
 	return scnprintf(buf, len,
-		"%s%scommand %07x %s=%d ithresh=%d%s%s%s "
-		"period=%s%s %s",
-		label, label[0] ? " " : "", command,
-		(command & CMD_PARK) ? " park" : "(park)",
-		CMD_PARK_CNT(command),
-		(command >> 16) & 0x3f,
-		(command & CMD_IAAD) ? " IAAD" : "",
-		(command & CMD_ASE) ? " Async" : "",
-		(command & CMD_PSE) ? " Periodic" : "",
-		fls_strings[(command >> 2) & 0x3],
-		(command & CMD_RESET) ? " Reset" : "",
-		(command & CMD_RUN) ? "RUN" : "HALT"
-		);
-}
-
-static char
-*dbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status)
-{
-	char	*sig;
+			"%s%scommand %07x %s=%d ithresh=%d%s%s%s period=%s%s %s",
+			label, label[0] ? " " : "", command,
+			(command & CMD_PARK) ? " park" : "(park)",
+			CMD_PARK_CNT(command),
+			(command >> 16) & 0x3f,
+			(command & CMD_IAAD) ? " IAAD" : "",
+			(command & CMD_ASE) ? " Async" : "",
+			(command & CMD_PSE) ? " Periodic" : "",
+			fls_strings[(command >> 2) & 0x3],
+			(command & CMD_RESET) ? " Reset" : "",
+			(command & CMD_RUN) ? "RUN" : "HALT");
+}
+
+static char *dbg_port_buf(char *buf, unsigned len, const char *label, int port,
+		u32 status)
+{
+	char *sig;
 
 	/* signaling state */
 	switch (status & (3 << 10)) {
@@ -268,44 +254,41 @@ static char
 		break;
 	}
 
-	scnprintf(buf, len,
-		"%s%sport:%d status %06x %d "
-		"sig=%s%s%s%s%s%s%s%s",
-		label, label[0] ? " " : "", port, status,
-		status>>25,/*device address */
-		sig,
-		(status & PORT_RESET) ? " RESET" : "",
-		(status & PORT_SUSPEND) ? " SUSPEND" : "",
-		(status & PORT_RESUME) ? " RESUME" : "",
-		(status & PORT_PEC) ? " PEC" : "",
-		(status & PORT_PE) ? " PE" : "",
-		(status & PORT_CSC) ? " CSC" : "",
-		(status & PORT_CONNECT) ? " CONNECT" : "");
+	scnprintf(buf, len, "%s%sport:%d status %06x %d sig=%s%s%s%s%s%s%s%s",
+			label, label[0] ? " " : "", port, status,
+			status >> 25, /*device address */
+			sig,
+			(status & PORT_RESET) ? " RESET" : "",
+			(status & PORT_SUSPEND) ? " SUSPEND" : "",
+			(status & PORT_RESUME) ? " RESUME" : "",
+			(status & PORT_PEC) ? " PEC" : "",
+			(status & PORT_PE) ? " PE" : "",
+			(status & PORT_CSC) ? " CSC" : "",
+			(status & PORT_CONNECT) ? " CONNECT" : "");
+
 	return buf;
 }
 
 /* functions have the "wrong" filename when they're output... */
-#define dbg_status(fotg210, label, status) { \
-	char _buf[80]; \
-	dbg_status_buf(_buf, sizeof(_buf), label, status); \
-	fotg210_dbg(fotg210, "%s\n", _buf); \
+#define dbg_status(fotg210, label, status) {			\
+	char _buf[80];						\
+	dbg_status_buf(_buf, sizeof(_buf), label, status);	\
+	fotg210_dbg(fotg210, "%s\n", _buf);			\
 }
 
-#define dbg_cmd(fotg210, label, command) { \
-	char _buf[80]; \
-	dbg_command_buf(_buf, sizeof(_buf), label, command); \
-	fotg210_dbg(fotg210, "%s\n", _buf); \
+#define dbg_cmd(fotg210, label, command) {			\
+	char _buf[80];						\
+	dbg_command_buf(_buf, sizeof(_buf), label, command);	\
+	fotg210_dbg(fotg210, "%s\n", _buf);			\
 }
 
-#define dbg_port(fotg210, label, port, status) { \
-	char _buf[80]; \
-	fotg210_dbg(fotg210, "%s\n", dbg_port_buf(_buf, sizeof(_buf), label, port, status) ); \
+#define dbg_port(fotg210, label, port, status) {			       \
+	char _buf[80];							       \
+	fotg210_dbg(fotg210, "%s\n",					       \
+			dbg_port_buf(_buf, sizeof(_buf), label, port, status));\
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* troubleshooting help: expose state in debugfs */
-
 static int debug_async_open(struct inode *, struct file *);
 static int debug_periodic_open(struct inode *, struct file *);
 static int debug_registers_open(struct inode *, struct file *);
@@ -373,33 +356,29 @@ static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
 	return '/';
 }
 
-static void qh_lines(
-	struct fotg210_hcd *fotg210,
-	struct fotg210_qh *qh,
-	char **nextp,
-	unsigned *sizep
-)
-{
-	u32			scratch;
-	u32			hw_curr;
-	struct fotg210_qtd	*td;
-	unsigned		temp;
-	unsigned		size = *sizep;
-	char			*next = *nextp;
-	char			mark;
-	__le32			list_end = FOTG210_LIST_END(fotg210);
-	struct fotg210_qh_hw	*hw = qh->hw;
-
-	if (hw->hw_qtd_next == list_end)	/* NEC does this */
+static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
+		char **nextp, unsigned *sizep)
+{
+	u32 scratch;
+	u32 hw_curr;
+	struct fotg210_qtd *td;
+	unsigned temp;
+	unsigned size = *sizep;
+	char *next = *nextp;
+	char mark;
+	__le32 list_end = FOTG210_LIST_END(fotg210);
+	struct fotg210_qh_hw *hw = qh->hw;
+
+	if (hw->hw_qtd_next == list_end) /* NEC does this */
 		mark = '@';
 	else
 		mark = token_mark(fotg210, hw->hw_token);
-	if (mark == '/') {	/* qh_alt_next controls qh advance? */
-		if ((hw->hw_alt_next & QTD_MASK(fotg210))
-				== fotg210->async->hw->hw_alt_next)
-			mark = '#';	/* blocked */
+	if (mark == '/') { /* qh_alt_next controls qh advance? */
+		if ((hw->hw_alt_next & QTD_MASK(fotg210)) ==
+		    fotg210->async->hw->hw_alt_next)
+			mark = '#'; /* blocked */
 		else if (hw->hw_alt_next == list_end)
-			mark = '.';	/* use hw_qtd_next */
+			mark = '.'; /* use hw_qtd_next */
 		/* else alt_next points to some other qtd */
 	}
 	scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
@@ -462,6 +441,7 @@ static void qh_lines(
 	temp = snprintf(next, size, "\n");
 	if (size < temp)
 		temp = size;
+
 	size -= temp;
 	next += temp;
 
@@ -472,12 +452,12 @@ done:
 
 static ssize_t fill_async_buffer(struct debug_buffer *buf)
 {
-	struct usb_hcd		*hcd;
-	struct fotg210_hcd	*fotg210;
-	unsigned long		flags;
-	unsigned		temp, size;
-	char			*next;
-	struct fotg210_qh		*qh;
+	struct usb_hcd *hcd;
+	struct fotg210_hcd *fotg210;
+	unsigned long flags;
+	unsigned temp, size;
+	char *next;
+	struct fotg210_qh *qh;
 
 	hcd = bus_to_hcd(buf->bus);
 	fotg210 = hcd_to_fotg210(hcd);
@@ -492,7 +472,7 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
 	 */
 	spin_lock_irqsave(&fotg210->lock, flags);
 	for (qh = fotg210->async->qh_next.qh; size > 0 && qh;
-	     qh = qh->qh_next.qh)
+			qh = qh->qh_next.qh)
 		qh_lines(fotg210, qh, &next, &size);
 	if (fotg210->async_unlink && size > 0) {
 		temp = scnprintf(next, size, "\nunlink =\n");
@@ -511,18 +491,19 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
 #define DBG_SCHED_LIMIT 64
 static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 {
-	struct usb_hcd		*hcd;
-	struct fotg210_hcd		*fotg210;
-	unsigned long		flags;
-	union fotg210_shadow	p, *seen;
-	unsigned		temp, size, seen_count;
-	char			*next;
-	unsigned		i;
-	__hc32			tag;
+	struct usb_hcd *hcd;
+	struct fotg210_hcd *fotg210;
+	unsigned long flags;
+	union fotg210_shadow p, *seen;
+	unsigned temp, size, seen_count;
+	char *next;
+	unsigned i;
+	__hc32 tag;
 
 	seen = kmalloc(DBG_SCHED_LIMIT * sizeof(*seen), GFP_ATOMIC);
 	if (!seen)
 		return 0;
+
 	seen_count = 0;
 
 	hcd = bus_to_hcd(buf->bus);
@@ -542,6 +523,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 		p = fotg210->pshadow[i];
 		if (likely(!p.ptr))
 			continue;
+
 		tag = Q_NEXT_TYPE(fotg210, fotg210->periodic[i]);
 
 		temp = scnprintf(next, size, "%4d: ", i);
@@ -569,7 +551,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 						continue;
 					if (p.qh->qh_next.ptr) {
 						temp = scnprintf(next, size,
-							" ...");
+								" ...");
 						size -= temp;
 						next += temp;
 					}
@@ -577,10 +559,10 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 				}
 				/* show more info the first time around */
 				if (temp == seen_count) {
-					u32	scratch = hc32_to_cpup(fotg210,
+					u32 scratch = hc32_to_cpup(fotg210,
 							&hw->hw_info1);
-					struct fotg210_qtd	*qtd;
-					char		*type = "";
+					struct fotg210_qtd *qtd;
+					char *type = "";
 
 					/* count tds, get ep direction */
 					temp = 0;
@@ -601,8 +583,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 					}
 
 					temp = scnprintf(next, size,
-						"(%c%d ep%d%s "
-						"[%d/%d] q%d p%d)",
+						"(%c%d ep%d%s [%d/%d] q%d p%d)",
 						speed_char(scratch),
 						scratch & 0x007f,
 						(scratch >> 8) & 0x000f, type,
@@ -619,14 +600,14 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 				break;
 			case Q_TYPE_FSTN:
 				temp = scnprintf(next, size,
-					" fstn-%8x/%p", p.fstn->hw_prev,
-					p.fstn);
+						" fstn-%8x/%p",
+						p.fstn->hw_prev, p.fstn);
 				tag = Q_NEXT_TYPE(fotg210, p.fstn->hw_next);
 				p = p.fstn->fstn_next;
 				break;
 			case Q_TYPE_ITD:
 				temp = scnprintf(next, size,
-					" itd/%p", p.itd);
+						" itd/%p", p.itd);
 				tag = Q_NEXT_TYPE(fotg210, p.itd->hw_next);
 				p = p.itd->itd_next;
 				break;
@@ -663,13 +644,13 @@ static const char *rh_state_string(struct fotg210_hcd *fotg210)
 
 static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 {
-	struct usb_hcd		*hcd;
-	struct fotg210_hcd	*fotg210;
-	unsigned long		flags;
-	unsigned		temp, size, i;
-	char			*next, scratch[80];
-	static const char	fmt[] = "%*s\n";
-	static const char	label[] = "";
+	struct usb_hcd *hcd;
+	struct fotg210_hcd *fotg210;
+	unsigned long flags;
+	unsigned temp, size, i;
+	char *next, scratch[80];
+	static const char fmt[] = "%*s\n";
+	static const char label[] = "";
 
 	hcd = bus_to_hcd(buf->bus);
 	fotg210 = hcd_to_fotg210(hcd);
@@ -680,26 +661,26 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 
 	if (!HCD_HW_ACCESSIBLE(hcd)) {
 		size = scnprintf(next, size,
-			"bus %s, device %s\n"
-			"%s\n"
-			"SUSPENDED(no register access)\n",
-			hcd->self.controller->bus->name,
-			dev_name(hcd->self.controller),
-			hcd->product_desc);
+				"bus %s, device %s\n"
+				"%s\n"
+				"SUSPENDED(no register access)\n",
+				hcd->self.controller->bus->name,
+				dev_name(hcd->self.controller),
+				hcd->product_desc);
 		goto done;
 	}
 
 	/* Capability Registers */
 	i = HC_VERSION(fotg210, fotg210_readl(fotg210,
-					      &fotg210->caps->hc_capbase));
+			&fotg210->caps->hc_capbase));
 	temp = scnprintf(next, size,
-		"bus %s, device %s\n"
-		"%s\n"
-		"EHCI %x.%02x, rh state %s\n",
-		hcd->self.controller->bus->name,
-		dev_name(hcd->self.controller),
-		hcd->product_desc,
-		i >> 8, i & 0x0ff, rh_state_string(fotg210));
+			"bus %s, device %s\n"
+			"%s\n"
+			"EHCI %x.%02x, rh state %s\n",
+			hcd->self.controller->bus->name,
+			dev_name(hcd->self.controller),
+			hcd->product_desc,
+			i >> 8, i & 0x0ff, rh_state_string(fotg210));
 	size -= temp;
 	next += temp;
 
@@ -747,14 +728,14 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 
 #ifdef FOTG210_STATS
 	temp = scnprintf(next, size,
-		"irq normal %ld err %ld iaa %ld(lost %ld)\n",
-		fotg210->stats.normal, fotg210->stats.error, fotg210->stats.iaa,
-		fotg210->stats.lost_iaa);
+			"irq normal %ld err %ld iaa %ld(lost %ld)\n",
+			fotg210->stats.normal, fotg210->stats.error,
+			fotg210->stats.iaa, fotg210->stats.lost_iaa);
 	size -= temp;
 	next += temp;
 
 	temp = scnprintf(next, size, "complete %ld unlink %ld\n",
-		fotg210->stats.complete, fotg210->stats.unlink);
+			fotg210->stats.complete, fotg210->stats.unlink);
 	size -= temp;
 	next += temp;
 #endif
@@ -765,8 +746,8 @@ done:
 	return buf->alloc_size - size;
 }
 
-static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
-				ssize_t (*fill_func)(struct debug_buffer *))
+static struct debug_buffer
+*alloc_buffer(struct usb_bus *bus, ssize_t (*fill_func)(struct debug_buffer *))
 {
 	struct debug_buffer *buf;
 
@@ -806,7 +787,7 @@ out:
 }
 
 static ssize_t debug_output(struct file *file, char __user *user_buf,
-			    size_t len, loff_t *offset)
+		size_t len, loff_t *offset)
 {
 	struct debug_buffer *buf = file->private_data;
 	int ret = 0;
@@ -822,7 +803,7 @@ static ssize_t debug_output(struct file *file, char __user *user_buf,
 	mutex_unlock(&buf->mutex);
 
 	ret = simple_read_from_buffer(user_buf, len, offset,
-				      buf->output_buf, buf->count);
+			buf->output_buf, buf->count);
 
 out:
 	return ret;
@@ -850,6 +831,7 @@ static int debug_async_open(struct inode *inode, struct file *file)
 static int debug_periodic_open(struct inode *inode, struct file *file)
 {
 	struct debug_buffer *buf;
+
 	buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
 	if (!buf)
 		return -ENOMEM;
@@ -862,7 +844,7 @@ static int debug_periodic_open(struct inode *inode, struct file *file)
 static int debug_registers_open(struct inode *inode, struct file *file)
 {
 	file->private_data = alloc_buffer(inode->i_private,
-					  fill_registers_buffer);
+			fill_registers_buffer);
 
 	return file->private_data ? 0 : -ENOMEM;
 }
@@ -872,20 +854,20 @@ static inline void create_debug_files(struct fotg210_hcd *fotg210)
 	struct usb_bus *bus = &fotg210_to_hcd(fotg210)->self;
 
 	fotg210->debug_dir = debugfs_create_dir(bus->bus_name,
-						fotg210_debug_root);
+			fotg210_debug_root);
 	if (!fotg210->debug_dir)
 		return;
 
 	if (!debugfs_create_file("async", S_IRUGO, fotg210->debug_dir, bus,
-						&debug_async_fops))
+			&debug_async_fops))
 		goto file_error;
 
 	if (!debugfs_create_file("periodic", S_IRUGO, fotg210->debug_dir, bus,
-						&debug_periodic_fops))
+			&debug_periodic_fops))
 		goto file_error;
 
 	if (!debugfs_create_file("registers", S_IRUGO, fotg210->debug_dir, bus,
-						    &debug_registers_fops))
+			&debug_registers_fops))
 		goto file_error;
 
 	return;
@@ -899,10 +881,7 @@ static inline void remove_debug_files(struct fotg210_hcd *fotg210)
 	debugfs_remove_recursive(fotg210->debug_dir);
 }
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * handshake - spin reading hc until handshake completes or fails
+/* handshake - spin reading hc until handshake completes or fails
  * @ptr: address of hc register to be read
  * @mask: bits to look at in result of read
  * @done: value of those bits when handshake succeeds
@@ -919,9 +898,9 @@ static inline void remove_debug_files(struct fotg210_hcd *fotg210)
  * bridge shutdown:  shutting down the bridge before the devices using it.
  */
 static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
-		      u32 mask, u32 done, int usec)
+		u32 mask, u32 done, int usec)
 {
-	u32	result;
+	u32 result;
 
 	do {
 		result = fotg210_readl(fotg210, ptr);
@@ -936,13 +915,12 @@ static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
 	return -ETIMEDOUT;
 }
 
-/*
- * Force HC to halt state from unknown (EHCI spec section 2.3).
+/* Force HC to halt state from unknown (EHCI spec section 2.3).
  * Must be called with interrupts enabled and the lock not held.
  */
 static int fotg210_halt(struct fotg210_hcd *fotg210)
 {
-	u32	temp;
+	u32 temp;
 
 	spin_lock_irq(&fotg210->lock);
 
@@ -962,20 +940,20 @@ static int fotg210_halt(struct fotg210_hcd *fotg210)
 	synchronize_irq(fotg210_to_hcd(fotg210)->irq);
 
 	return handshake(fotg210, &fotg210->regs->status,
-			  STS_HALT, STS_HALT, 16 * 125);
+			STS_HALT, STS_HALT, 16 * 125);
 }
 
-/*
- * Reset a non-running (STS_HALT == 1) controller.
+/* Reset a non-running (STS_HALT == 1) controller.
  * Must be called with interrupts enabled and the lock not held.
  */
 static int fotg210_reset(struct fotg210_hcd *fotg210)
 {
-	int	retval;
-	u32	command = fotg210_readl(fotg210, &fotg210->regs->command);
+	int retval;
+	u32 command = fotg210_readl(fotg210, &fotg210->regs->command);
 
 	/* If the EHCI debug controller is active, special care must be
-	 * taken before and after a host controller reset */
+	 * taken before and after a host controller reset
+	 */
 	if (fotg210->debug && !dbgp_reset_prep(fotg210_to_hcd(fotg210)))
 		fotg210->debug = NULL;
 
@@ -985,7 +963,7 @@ static int fotg210_reset(struct fotg210_hcd *fotg210)
 	fotg210->rh_state = FOTG210_RH_HALTED;
 	fotg210->next_statechange = jiffies;
 	retval = handshake(fotg210, &fotg210->regs->command,
-			    CMD_RESET, 0, 250 * 1000);
+			CMD_RESET, 0, 250 * 1000);
 
 	if (retval)
 		return retval;
@@ -998,13 +976,12 @@ static int fotg210_reset(struct fotg210_hcd *fotg210)
 	return retval;
 }
 
-/*
- * Idle the controller (turn off the schedules).
+/* Idle the controller (turn off the schedules).
  * Must be called with interrupts enabled and the lock not held.
  */
 static void fotg210_quiesce(struct fotg210_hcd *fotg210)
 {
-	u32	temp;
+	u32 temp;
 
 	if (fotg210->rh_state != FOTG210_RH_RUNNING)
 		return;
@@ -1012,7 +989,7 @@ static void fotg210_quiesce(struct fotg210_hcd *fotg210)
 	/* wait for any schedule enables/disables to take effect */
 	temp = (fotg210->command << 10) & (STS_ASS | STS_PSS);
 	handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, temp,
-		  16 * 125);
+			16 * 125);
 
 	/* then disable anything that's still active */
 	spin_lock_irq(&fotg210->lock);
@@ -1022,11 +999,9 @@ static void fotg210_quiesce(struct fotg210_hcd *fotg210)
 
 	/* hardware can take 16 microframes to turn off ... */
 	handshake(fotg210, &fotg210->regs->status, STS_ASS | STS_PSS, 0,
-		  16 * 125);
+			16 * 125);
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void end_unlink_async(struct fotg210_hcd *fotg210);
 static void unlink_empty_async(struct fotg210_hcd *fotg210);
 static void fotg210_work(struct fotg210_hcd *fotg210);
@@ -1034,8 +1009,6 @@ static void start_unlink_intr(struct fotg210_hcd *fotg210,
 			      struct fotg210_qh *qh);
 static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
 
-/*-------------------------------------------------------------------------*/
-
 /* Set a bit in the USBCMD register */
 static void fotg210_set_command_bit(struct fotg210_hcd *fotg210, u32 bit)
 {
@@ -1056,10 +1029,7 @@ static void fotg210_clear_command_bit(struct fotg210_hcd *fotg210, u32 bit)
 	fotg210_readl(fotg210, &fotg210->regs->command);
 }
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * EHCI timer support...  Now using hrtimers.
+/* EHCI timer support...  Now using hrtimers.
  *
  * Lots of different events are triggered from fotg210->hrtimer.  Whenever
  * the timer routine runs, it checks each possible event; events that are
@@ -1081,8 +1051,7 @@ static void fotg210_clear_command_bit(struct fotg210_hcd *fotg210, u32 bit)
  * allow for an expiration range of 1 ms.
  */
 
-/*
- * Delay lengths for the hrtimer event types.
+/* Delay lengths for the hrtimer event types.
  * Keep this list sorted by delay length, in the same order as
  * the event types indexed by enum fotg210_hrtimer_event in fotg210.h.
  */
@@ -1103,7 +1072,7 @@ static unsigned event_delays_ns[] = {
 static void fotg210_enable_event(struct fotg210_hcd *fotg210, unsigned event,
 		bool resched)
 {
-	ktime_t		*timeout = &fotg210->hr_timeouts[event];
+	ktime_t *timeout = &fotg210->hr_timeouts[event];
 
 	if (resched)
 		*timeout = ktime_add(ktime_get(),
@@ -1122,7 +1091,7 @@ static void fotg210_enable_event(struct fotg210_hcd *fotg210, unsigned event,
 /* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */
 static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
 {
-	unsigned	actual, want;
+	unsigned actual, want;
 
 	/* Don't enable anything if the controller isn't running (e.g., died) */
 	if (fotg210->rh_state != FOTG210_RH_RUNNING)
@@ -1136,7 +1105,7 @@ static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
 		/* Poll again later, but give up after about 20 ms */
 		if (fotg210->ASS_poll_count++ < 20) {
 			fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_ASS,
-					     true);
+					true);
 			return;
 		}
 		fotg210_dbg(fotg210, "Waited too long for the async schedule status (%x/%x), giving up\n",
@@ -1154,8 +1123,8 @@ static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
 
 			/* Turn off the schedule after a while */
 			fotg210_enable_event(fotg210,
-					     FOTG210_HRTIMER_DISABLE_ASYNC,
-					     true);
+					FOTG210_HRTIMER_DISABLE_ASYNC,
+					true);
 		}
 	}
 }
@@ -1170,7 +1139,7 @@ static void fotg210_disable_ASE(struct fotg210_hcd *fotg210)
 /* Poll the STS_PSS status bit; see when it agrees with CMD_PSE */
 static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
 {
-	unsigned	actual, want;
+	unsigned actual, want;
 
 	/* Don't do anything if the controller isn't running (e.g., died) */
 	if (fotg210->rh_state != FOTG210_RH_RUNNING)
@@ -1184,7 +1153,7 @@ static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
 		/* Poll again later, but give up after about 20 ms */
 		if (fotg210->PSS_poll_count++ < 20) {
 			fotg210_enable_event(fotg210, FOTG210_HRTIMER_POLL_PSS,
-					     true);
+					true);
 			return;
 		}
 		fotg210_dbg(fotg210, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
@@ -1202,8 +1171,8 @@ static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
 
 			/* Turn off the schedule after a while */
 			fotg210_enable_event(fotg210,
-					     FOTG210_HRTIMER_DISABLE_PERIODIC,
-					     true);
+					FOTG210_HRTIMER_DISABLE_PERIODIC,
+					true);
 		}
 	}
 }
@@ -1224,7 +1193,7 @@ static void fotg210_handle_controller_death(struct fotg210_hcd *fotg210)
 		if (fotg210->died_poll_count++ < 5) {
 			/* Try again later */
 			fotg210_enable_event(fotg210,
-					     FOTG210_HRTIMER_POLL_DEAD, true);
+					FOTG210_HRTIMER_POLL_DEAD, true);
 			return;
 		}
 		fotg210_warn(fotg210, "Waited too long for the controller to stop, giving up\n");
@@ -1243,7 +1212,7 @@ static void fotg210_handle_controller_death(struct fotg210_hcd *fotg210)
 /* Handle unlinked interrupt QHs once they are gone from the hardware */
 static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
 {
-	bool		stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
+	bool stopped = (fotg210->rh_state < FOTG210_RH_RUNNING);
 
 	/*
 	 * Process all the QHs on the intr_unlink list that were added
@@ -1254,7 +1223,7 @@ static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
 	 */
 	fotg210->intr_unlinking = true;
 	while (fotg210->intr_unlink) {
-		struct fotg210_qh	*qh = fotg210->intr_unlink;
+		struct fotg210_qh *qh = fotg210->intr_unlink;
 
 		if (!stopped && qh->unlink_cycle == fotg210->intr_unlink_cycle)
 			break;
@@ -1266,7 +1235,7 @@ static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
 	/* Handle remaining entries later */
 	if (fotg210->intr_unlink) {
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
-				     true);
+				true);
 		++fotg210->intr_unlink_cycle;
 	}
 	fotg210->intr_unlinking = false;
@@ -1288,7 +1257,7 @@ static void start_free_itds(struct fotg210_hcd *fotg210)
 /* Wait for controller to stop using old iTDs and siTDs */
 static void end_free_itds(struct fotg210_hcd *fotg210)
 {
-	struct fotg210_itd		*itd, *n;
+	struct fotg210_itd *itd, *n;
 
 	if (fotg210->rh_state < FOTG210_RH_RUNNING)
 		fotg210->last_itd_to_free = NULL;
@@ -1339,7 +1308,7 @@ static void fotg210_iaa_watchdog(struct fotg210_hcd *fotg210)
 		if ((status & STS_IAA) || !(cmd & CMD_IAAD)) {
 			COUNT(fotg210->stats.lost_iaa);
 			fotg210_writel(fotg210, STS_IAA,
-				       &fotg210->regs->status);
+					&fotg210->regs->status);
 		}
 
 		fotg210_dbg(fotg210, "IAA watchdog: status %x cmd %x\n",
@@ -1355,7 +1324,7 @@ static void turn_on_io_watchdog(struct fotg210_hcd *fotg210)
 	/* Not needed if the controller isn't running or it's already enabled */
 	if (fotg210->rh_state != FOTG210_RH_RUNNING ||
 			(fotg210->enabled_hrtimer_events &
-				BIT(FOTG210_HRTIMER_IO_WATCHDOG)))
+			BIT(FOTG210_HRTIMER_IO_WATCHDOG)))
 		return;
 
 	/*
@@ -1365,12 +1334,11 @@ static void turn_on_io_watchdog(struct fotg210_hcd *fotg210)
 	if (fotg210->isoc_count > 0 || (fotg210->need_io_watchdog &&
 			fotg210->async_count + fotg210->intr_count > 0))
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_IO_WATCHDOG,
-				     true);
+				true);
 }
 
 
-/*
- * Handler functions for the hrtimer event types.
+/* Handler functions for the hrtimer event types.
  * Keep this array in the same order as the event types indexed by
  * enum fotg210_hrtimer_event in fotg210.h.
  */
@@ -1391,10 +1359,10 @@ static enum hrtimer_restart fotg210_hrtimer_func(struct hrtimer *t)
 {
 	struct fotg210_hcd *fotg210 =
 			container_of(t, struct fotg210_hcd, hrtimer);
-	ktime_t		now;
-	unsigned long	events;
-	unsigned long	flags;
-	unsigned	e;
+	ktime_t now;
+	unsigned long events;
+	unsigned long flags;
+	unsigned e;
 
 	spin_lock_irqsave(&fotg210->lock, flags);
 
@@ -1418,19 +1386,12 @@ static enum hrtimer_restart fotg210_hrtimer_func(struct hrtimer *t)
 	return HRTIMER_NORESTART;
 }
 
-/*-------------------------------------------------------------------------*/
-
-#define fotg210_bus_suspend	NULL
-#define fotg210_bus_resume	NULL
-
-/*-------------------------------------------------------------------------*/
+#define fotg210_bus_suspend NULL
+#define fotg210_bus_resume NULL
 
-static int check_reset_complete(
-	struct fotg210_hcd	*fotg210,
-	int		index,
-	u32 __iomem	*status_reg,
-	int		port_status
-) {
+static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
+		u32 __iomem *status_reg, int port_status)
+{
 	if (!(port_status & PORT_CONNECT))
 		return port_status;
 
@@ -1438,30 +1399,27 @@ static int check_reset_complete(
 	if (!(port_status & PORT_PE)) {
 		/* with integrated TT, there's nobody to hand it to! */
 		fotg210_dbg(fotg210,
-			"Failed to enable port %d on root hub TT\n",
-			index+1);
+				"Failed to enable port %d on root hub TT\n",
+				index + 1);
 		return port_status;
 	} else {
 		fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
-			index + 1);
+				index + 1);
 	}
 
 	return port_status;
 }
 
-/*-------------------------------------------------------------------------*/
-
 
 /* build "status change" packet (one or two bytes) from HC registers */
 
-static int
-fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
+static int fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
 {
-	struct fotg210_hcd	*fotg210 = hcd_to_fotg210(hcd);
-	u32		temp, status;
-	u32		mask;
-	int		retval = 1;
-	unsigned long	flags;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 temp, status;
+	u32 mask;
+	int retval = 1;
+	unsigned long flags;
 
 	/* init status to no-changes */
 	buf[0] = 0;
@@ -1488,9 +1446,9 @@ fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
 	 * controller by the user.
 	 */
 
-	if ((temp & mask) != 0 || test_bit(0, &fotg210->port_c_suspend)
-			|| (fotg210->reset_done[0] && time_after_eq(
-				jiffies, fotg210->reset_done[0]))) {
+	if ((temp & mask) != 0 || test_bit(0, &fotg210->port_c_suspend) ||
+			(fotg210->reset_done[0] &&
+			time_after_eq(jiffies, fotg210->reset_done[0]))) {
 		buf[0] |= 1 << 1;
 		status = STS_PCD;
 	}
@@ -1499,15 +1457,11 @@ fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
 	return status ? retval : 0;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static void
-fotg210_hub_descriptor(
-	struct fotg210_hcd		*fotg210,
-	struct usb_hub_descriptor	*desc
-) {
-	int		ports = HCS_N_PORTS(fotg210->hcs_params);
-	u16		temp;
+static void fotg210_hub_descriptor(struct fotg210_hcd *fotg210,
+		struct usb_hub_descriptor *desc)
+{
+	int ports = HCS_N_PORTS(fotg210->hcs_params);
+	u16 temp;
 
 	desc->bDescriptorType = USB_DT_HUB;
 	desc->bPwrOn2PwrGood = 10;	/* fotg210 1.0, 2.3.9 says 20ms max */
@@ -1526,23 +1480,16 @@ fotg210_hub_descriptor(
 	desc->wHubCharacteristics = cpu_to_le16(temp);
 }
 
-/*-------------------------------------------------------------------------*/
-
-static int fotg210_hub_control(
-	struct usb_hcd	*hcd,
-	u16		typeReq,
-	u16		wValue,
-	u16		wIndex,
-	char		*buf,
-	u16		wLength
-) {
-	struct fotg210_hcd	*fotg210 = hcd_to_fotg210(hcd);
-	int		ports = HCS_N_PORTS(fotg210->hcs_params);
-	u32 __iomem	*status_reg = &fotg210->regs->port_status;
-	u32		temp, temp1, status;
-	unsigned long	flags;
-	int		retval = 0;
-	unsigned	selector;
+static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+		u16 wIndex, char *buf, u16 wLength)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	int ports = HCS_N_PORTS(fotg210->hcs_params);
+	u32 __iomem *status_reg = &fotg210->regs->port_status;
+	u32 temp, temp1, status;
+	unsigned long flags;
+	int retval = 0;
+	unsigned selector;
 
 	/*
 	 * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
@@ -1605,7 +1552,7 @@ static int fotg210_hub_control(
 			break;
 		case USB_PORT_FEAT_C_OVER_CURRENT:
 			fotg210_writel(fotg210, temp | OTGISR_OVC,
-				       &fotg210->regs->otgisr);
+					&fotg210->regs->otgisr);
 			break;
 		case USB_PORT_FEAT_C_RESET:
 			/* GetPortStatus clears reset */
@@ -1617,7 +1564,7 @@ static int fotg210_hub_control(
 		break;
 	case GetHubDescriptor:
 		fotg210_hub_descriptor(fotg210, (struct usb_hub_descriptor *)
-			buf);
+				buf);
 		break;
 	case GetHubStatus:
 		/* no hub-wide feature/status flags */
@@ -1663,16 +1610,16 @@ static int fotg210_hub_control(
 
 				/* stop resume signaling */
 				temp = fotg210_readl(fotg210, status_reg);
-				fotg210_writel(fotg210,
-					temp & ~(PORT_RWC_BITS | PORT_RESUME),
-					status_reg);
+				fotg210_writel(fotg210, temp &
+						~(PORT_RWC_BITS | PORT_RESUME),
+						status_reg);
 				clear_bit(wIndex, &fotg210->resuming_ports);
 				retval = handshake(fotg210, status_reg,
-					   PORT_RESUME, 0, 2000 /* 2msec */);
+						PORT_RESUME, 0, 2000);/* 2ms */
 				if (retval != 0) {
 					fotg210_err(fotg210,
-						"port %d resume error %d\n",
-						wIndex + 1, retval);
+							"port %d resume error %d\n",
+							wIndex + 1, retval);
 					goto error;
 				}
 				temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
@@ -1680,17 +1627,16 @@ static int fotg210_hub_control(
 		}
 
 		/* whoever resets must GetPortStatus to complete it!! */
-		if ((temp & PORT_RESET)
-				&& time_after_eq(jiffies,
-					fotg210->reset_done[wIndex])) {
+		if ((temp & PORT_RESET) && time_after_eq(jiffies,
+				fotg210->reset_done[wIndex])) {
 			status |= USB_PORT_STAT_C_RESET << 16;
 			fotg210->reset_done[wIndex] = 0;
 			clear_bit(wIndex, &fotg210->resuming_ports);
 
 			/* force reset to complete */
 			fotg210_writel(fotg210,
-				       temp & ~(PORT_RWC_BITS | PORT_RESET),
-				       status_reg);
+					temp & ~(PORT_RWC_BITS | PORT_RESET),
+					status_reg);
 			/* REVISIT:  some hardware needs 550+ usec to clear
 			 * this bit; seems too long to spin routinely...
 			 */
@@ -1698,7 +1644,7 @@ static int fotg210_hub_control(
 					PORT_RESET, 0, 1000);
 			if (retval != 0) {
 				fotg210_err(fotg210, "port %d reset error %d\n",
-					wIndex + 1, retval);
+						wIndex + 1, retval);
 				goto error;
 			}
 
@@ -1718,7 +1664,7 @@ static int fotg210_hub_control(
 			temp &= ~PORT_RWC_BITS;
 			fotg210_writel(fotg210, temp, status_reg);
 			fotg210_dbg(fotg210, "port %d --> companion\n",
-				    wIndex + 1);
+					wIndex + 1);
 			temp = fotg210_readl(fotg210, status_reg);
 		}
 
@@ -1788,7 +1734,7 @@ static int fotg210_hub_control(
 			 * mode if we have hostpc feature
 			 */
 			fotg210_writel(fotg210, temp | PORT_SUSPEND,
-				       status_reg);
+					status_reg);
 			set_bit(wIndex, &fotg210->suspended_ports);
 			break;
 		case USB_PORT_FEAT_RESET:
@@ -1866,9 +1812,8 @@ static int __maybe_unused fotg210_port_handed_over(struct usb_hcd *hcd,
 {
 	return 0;
 }
-/*-------------------------------------------------------------------------*/
-/*
- * There's basically three types of memory:
+
+/* There's basically three types of memory:
  *	- data used only by the HCD ... kmalloc is fine
  *	- async and periodic schedules, shared by HC and HCD ... these
  *	  need to use dma_pool or dma_alloc_coherent
@@ -1878,12 +1823,9 @@ static int __maybe_unused fotg210_port_handed_over(struct usb_hcd *hcd,
  * No memory seen by this driver is pageable.
  */
 
-/*-------------------------------------------------------------------------*/
-
 /* Allocate the key transfer structures from the previously allocated pool */
-
 static inline void fotg210_qtd_init(struct fotg210_hcd *fotg210,
-				    struct fotg210_qtd *qtd, dma_addr_t dma)
+		struct fotg210_qtd *qtd, dma_addr_t dma)
 {
 	memset(qtd, 0, sizeof(*qtd));
 	qtd->qtd_dma = dma;
@@ -1894,10 +1836,10 @@ static inline void fotg210_qtd_init(struct fotg210_hcd *fotg210,
 }
 
 static struct fotg210_qtd *fotg210_qtd_alloc(struct fotg210_hcd *fotg210,
-					     gfp_t flags)
+		gfp_t flags)
 {
-	struct fotg210_qtd		*qtd;
-	dma_addr_t		dma;
+	struct fotg210_qtd *qtd;
+	dma_addr_t dma;
 
 	qtd = dma_pool_alloc(fotg210->qtd_pool, flags, &dma);
 	if (qtd != NULL)
@@ -1907,7 +1849,7 @@ static struct fotg210_qtd *fotg210_qtd_alloc(struct fotg210_hcd *fotg210,
 }
 
 static inline void fotg210_qtd_free(struct fotg210_hcd *fotg210,
-				    struct fotg210_qtd *qtd)
+		struct fotg210_qtd *qtd)
 {
 	dma_pool_free(fotg210->qtd_pool, qtd, qtd->qtd_dma);
 }
@@ -1927,10 +1869,10 @@ static void qh_destroy(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 }
 
 static struct fotg210_qh *fotg210_qh_alloc(struct fotg210_hcd *fotg210,
-					   gfp_t flags)
+		gfp_t flags)
 {
-	struct fotg210_qh		*qh;
-	dma_addr_t		dma;
+	struct fotg210_qh *qh;
+	dma_addr_t dma;
 
 	qh = kzalloc(sizeof(*qh), GFP_ATOMIC);
 	if (!qh)
@@ -1958,8 +1900,6 @@ fail:
 	return NULL;
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* The queue heads and transfer descriptors are managed from pools tied
  * to each of the "per device" structures.
  * This is the initialisation and cleanup code.
@@ -1991,8 +1931,8 @@ static void fotg210_mem_cleanup(struct fotg210_hcd *fotg210)
 
 	if (fotg210->periodic)
 		dma_free_coherent(fotg210_to_hcd(fotg210)->self.controller,
-			fotg210->periodic_size * sizeof(u32),
-			fotg210->periodic, fotg210->periodic_dma);
+				fotg210->periodic_size * sizeof(u32),
+				fotg210->periodic, fotg210->periodic_dma);
 	fotg210->periodic = NULL;
 
 	/* shadow periodic table */
@@ -2039,8 +1979,8 @@ static int fotg210_mem_init(struct fotg210_hcd *fotg210, gfp_t flags)
 	/* Hardware periodic table */
 	fotg210->periodic = (__le32 *)
 		dma_alloc_coherent(fotg210_to_hcd(fotg210)->self.controller,
-			fotg210->periodic_size * sizeof(__le32),
-			&fotg210->periodic_dma, 0);
+				fotg210->periodic_size * sizeof(__le32),
+				&fotg210->periodic_dma, 0);
 	if (fotg210->periodic == NULL)
 		goto fail;
 
@@ -2049,7 +1989,7 @@ static int fotg210_mem_init(struct fotg210_hcd *fotg210, gfp_t flags)
 
 	/* software shadow of hardware table */
 	fotg210->pshadow = kcalloc(fotg210->periodic_size, sizeof(void *),
-				   flags);
+			flags);
 	if (fotg210->pshadow != NULL)
 		return 0;
 
@@ -2058,9 +1998,7 @@ fail:
 	fotg210_mem_cleanup(fotg210);
 	return -ENOMEM;
 }
-/*-------------------------------------------------------------------------*/
-/*
- * EHCI hardware queue manipulation ... the core.  QH/QTD manipulation.
+/* EHCI hardware queue manipulation ... the core.  QH/QTD manipulation.
  *
  * Control, bulk, and interrupt traffic all use "qh" lists.  They list "qtd"
  * entries describing USB transactions, max 16-20kB/entry (with 4kB-aligned
@@ -2077,16 +2015,12 @@ fail:
  * buffer low/full speed data so the host collects it at high speed.
  */
 
-/*-------------------------------------------------------------------------*/
-
 /* fill a qtd, returning how much of the buffer we were able to queue up */
-
-static int
-qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd, dma_addr_t buf,
-		  size_t len, int token, int maxpacket)
+static int qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd,
+		dma_addr_t buf, size_t len, int token, int maxpacket)
 {
-	int	i, count;
-	u64	addr = buf;
+	int i, count;
+	u64 addr = buf;
 
 	/* one buffer entry per 4K ... first might be short or unaligned */
 	qtd->hw_buf[0] = cpu_to_hc32(fotg210, (u32)addr);
@@ -2121,11 +2055,8 @@ qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd, dma_addr_t buf,
 	return count;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static inline void
-qh_update(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
-	  struct fotg210_qtd *qtd)
+static inline void qh_update(struct fotg210_hcd *fotg210,
+		struct fotg210_qh *qh, struct fotg210_qtd *qtd)
 {
 	struct fotg210_qh_hw *hw = qh->hw;
 
@@ -2141,7 +2072,7 @@ qh_update(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
 	 * ever clear it.
 	 */
 	if (!(hw->hw_info1 & cpu_to_hc32(fotg210, QH_TOGGLE_CTL))) {
-		unsigned	is_out, epnum;
+		unsigned is_out, epnum;
 
 		is_out = qh->is_out;
 		epnum = (hc32_to_cpup(fotg210, &hw->hw_info1) >> 8) & 0x0f;
@@ -2158,8 +2089,7 @@ qh_update(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
  * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault
  * recovery (including urb dequeue) would need software changes to a QH...
  */
-static void
-qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+static void qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
 	struct fotg210_qtd *qtd;
 
@@ -2185,16 +2115,14 @@ qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		qh_update(fotg210, qh, qtd);
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
 
 static void fotg210_clear_tt_buffer_complete(struct usb_hcd *hcd,
 		struct usb_host_endpoint *ep)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh		*qh = ep->hcpriv;
-	unsigned long		flags;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_qh *qh = ep->hcpriv;
+	unsigned long flags;
 
 	spin_lock_irqsave(&fotg210->lock, flags);
 	qh->clearing_tt = 0;
@@ -2205,8 +2133,7 @@ static void fotg210_clear_tt_buffer_complete(struct usb_hcd *hcd,
 }
 
 static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
-				    struct fotg210_qh *qh,
-				    struct urb *urb, u32 token)
+		struct fotg210_qh *qh, struct urb *urb, u32 token)
 {
 
 	/* If an async split transaction gets an error or is unlinked,
@@ -2217,27 +2144,24 @@ static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
 	 */
 	if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
 		struct usb_device *tt = urb->dev->tt->hub;
+
 		dev_dbg(&tt->dev,
-			"clear tt buffer port %d, a%d ep%d t%08x\n",
-			urb->dev->ttport, urb->dev->devnum,
-			usb_pipeendpoint(urb->pipe), token);
+				"clear tt buffer port %d, a%d ep%d t%08x\n",
+				urb->dev->ttport, urb->dev->devnum,
+				usb_pipeendpoint(urb->pipe), token);
 
 		if (urb->dev->tt->hub !=
-		    fotg210_to_hcd(fotg210)->self.root_hub) {
+				fotg210_to_hcd(fotg210)->self.root_hub) {
 			if (usb_hub_clear_tt_buffer(urb) == 0)
 				qh->clearing_tt = 1;
 		}
 	}
 }
 
-static int qtd_copy_status(
-	struct fotg210_hcd *fotg210,
-	struct urb *urb,
-	size_t length,
-	u32 token
-)
+static int qtd_copy_status(struct fotg210_hcd *fotg210, struct urb *urb,
+		size_t length, u32 token)
 {
-	int	status = -EINPROGRESS;
+	int status = -EINPROGRESS;
 
 	/* count IN/OUT bytes, not SETUP (even short packets) */
 	if (likely(QTD_PID(token) != 2))
@@ -2274,32 +2198,32 @@ static int qtd_copy_status(
 		} else if (token & QTD_STS_XACT) {
 			/* timeout, bad CRC, wrong PID, etc */
 			fotg210_dbg(fotg210, "devpath %s ep%d%s 3strikes\n",
-				urb->dev->devpath,
-				usb_pipeendpoint(urb->pipe),
-				usb_pipein(urb->pipe) ? "in" : "out");
+					urb->dev->devpath,
+					usb_pipeendpoint(urb->pipe),
+					usb_pipein(urb->pipe) ? "in" : "out");
 			status = -EPROTO;
 		} else {	/* unknown */
 			status = -EPROTO;
 		}
 
 		fotg210_dbg(fotg210,
-			"dev%d ep%d%s qtd token %08x --> status %d\n",
-			usb_pipedevice(urb->pipe),
-			usb_pipeendpoint(urb->pipe),
-			usb_pipein(urb->pipe) ? "in" : "out",
-			token, status);
+				"dev%d ep%d%s qtd token %08x --> status %d\n",
+				usb_pipedevice(urb->pipe),
+				usb_pipeendpoint(urb->pipe),
+				usb_pipein(urb->pipe) ? "in" : "out",
+				token, status);
 	}
 
 	return status;
 }
 
-static void
-fotg210_urb_done(struct fotg210_hcd *fotg210, struct urb *urb, int status)
+static void fotg210_urb_done(struct fotg210_hcd *fotg210, struct urb *urb,
+		int status)
 __releases(fotg210->lock)
 __acquires(fotg210->lock)
 {
 	if (likely(urb->hcpriv != NULL)) {
-		struct fotg210_qh	*qh = (struct fotg210_qh *) urb->hcpriv;
+		struct fotg210_qh *qh = (struct fotg210_qh *) urb->hcpriv;
 
 		/* S-mask in a QH means it's an interrupt urb */
 		if ((qh->hw->hw_info2 & cpu_to_hc32(fotg210, QH_SMASK)) != 0) {
@@ -2320,12 +2244,12 @@ __acquires(fotg210->lock)
 
 #ifdef FOTG210_URB_TRACE
 	fotg210_dbg(fotg210,
-		"%s %s urb %p ep%d%s status %d len %d/%d\n",
-		__func__, urb->dev->devpath, urb,
-		usb_pipeendpoint(urb->pipe),
-		usb_pipein(urb->pipe) ? "in" : "out",
-		status,
-		urb->actual_length, urb->transfer_buffer_length);
+			"%s %s urb %p ep%d%s status %d len %d/%d\n",
+			__func__, urb->dev->devpath, urb,
+			usb_pipeendpoint(urb->pipe),
+			usb_pipein(urb->pipe) ? "in" : "out",
+			status,
+			urb->actual_length, urb->transfer_buffer_length);
 #endif
 
 	/* complete() can reenter this HCD */
@@ -2337,21 +2261,20 @@ __acquires(fotg210->lock)
 
 static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);
 
-/*
- * Process and free completed qtds for a qh, returning URBs to drivers.
+/* Process and free completed qtds for a qh, returning URBs to drivers.
  * Chases up to qh->hw_current.  Returns number of completions called,
  * indicating how much "real" work we did.
  */
-static unsigned
-qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
+static unsigned qh_completions(struct fotg210_hcd *fotg210,
+		struct fotg210_qh *qh)
 {
-	struct fotg210_qtd		*last, *end = qh->dummy;
-	struct list_head	*entry, *tmp;
-	int			last_status;
-	int			stopped;
-	unsigned		count = 0;
-	u8			state;
-	struct fotg210_qh_hw	*hw = qh->hw;
+	struct fotg210_qtd *last, *end = qh->dummy;
+	struct list_head *entry, *tmp;
+	int last_status;
+	int stopped;
+	unsigned count = 0;
+	u8 state;
+	struct fotg210_qh_hw *hw = qh->hw;
 
 	if (unlikely(list_empty(&qh->qtd_list)))
 		return count;
@@ -2370,7 +2293,7 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	qh->qh_state = QH_STATE_COMPLETING;
 	stopped = (state == QH_STATE_IDLE);
 
- rescan:
+rescan:
 	last = NULL;
 	last_status = -EINPROGRESS;
 	qh->needs_rescan = 0;
@@ -2381,9 +2304,9 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	 * if queue is stopped, handles unlinks.
 	 */
 	list_for_each_safe(entry, tmp, &qh->qtd_list) {
-		struct fotg210_qtd	*qtd;
-		struct urb	*urb;
-		u32		token = 0;
+		struct fotg210_qtd *qtd;
+		struct urb *urb;
+		u32 token = 0;
 
 		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
 		urb = qtd->urb;
@@ -2392,7 +2315,7 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		if (last) {
 			if (likely(last->urb != urb)) {
 				fotg210_urb_done(fotg210, last->urb,
-						 last_status);
+						last_status);
 				count++;
 				last_status = -EINPROGRESS;
 			}
@@ -2409,20 +2332,17 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		token = hc32_to_cpu(fotg210, qtd->hw_token);
 
 		/* always clean up qtds the hc de-activated */
- retry_xacterr:
+retry_xacterr:
 		if ((token & QTD_STS_ACTIVE) == 0) {
 
 			/* Report Data Buffer Error: non-fatal but useful */
 			if (token & QTD_STS_DBE)
 				fotg210_dbg(fotg210,
 					"detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-					urb,
-					usb_endpoint_num(&urb->ep->desc),
+					urb, usb_endpoint_num(&urb->ep->desc),
 					usb_endpoint_dir_in(&urb->ep->desc)
 						? "in" : "out",
-					urb->transfer_buffer_length,
-					qtd,
-					qh);
+					urb->transfer_buffer_length, qtd, qh);
 
 			/* on STALL, error, and short reads this urb must
 			 * complete and all its qtds must be recycled.
@@ -2433,12 +2353,14 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 				 * reach the software xacterr limit
 				 */
 				if ((token & QTD_STS_XACT) &&
-					QTD_CERR(token) == 0 &&
-					++qh->xacterrs < QH_XACTERR_MAX &&
-					!urb->unlinked) {
+						QTD_CERR(token) == 0 &&
+						++qh->xacterrs < QH_XACTERR_MAX &&
+						!urb->unlinked) {
 					fotg210_dbg(fotg210,
-	"detected XactErr len %zu/%zu retry %d\n",
-	qtd->length - QTD_LENGTH(token), qtd->length, qh->xacterrs);
+						"detected XactErr len %zu/%zu retry %d\n",
+						qtd->length - QTD_LENGTH(token),
+						qtd->length,
+						qh->xacterrs);
 
 					/* reset the token in the qtd and the
 					 * qh overlay (which still contains
@@ -2466,9 +2388,9 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 			 * URB_SHORT_NOT_OK was set so the driver submitting
 			 * the urbs could clean it up.
 			 */
-			} else if (IS_SHORT_READ(token)
-					&& !(qtd->hw_alt_next
-						& FOTG210_LIST_END(fotg210))) {
+			} else if (IS_SHORT_READ(token) &&
+					!(qtd->hw_alt_next &
+					FOTG210_LIST_END(fotg210))) {
 				stopped = 1;
 			}
 
@@ -2492,9 +2414,9 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 				continue;
 
 			/* qh unlinked; token in overlay may be most current */
-			if (state == QH_STATE_IDLE
-					&& cpu_to_hc32(fotg210, qtd->qtd_dma)
-						== hw->hw_current) {
+			if (state == QH_STATE_IDLE &&
+					cpu_to_hc32(fotg210, qtd->qtd_dma)
+					== hw->hw_current) {
 				token = hc32_to_cpu(fotg210, hw->hw_token);
 
 				/* An unlink may leave an incomplete
@@ -2502,7 +2424,7 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 				 * We have to clear it.
 				 */
 				fotg210_clear_tt_buffer(fotg210, qh, urb,
-							token);
+						token);
 			}
 		}
 
@@ -2516,9 +2438,9 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		if (last_status == -EINPROGRESS) {
 			last_status = qtd_copy_status(fotg210, urb,
 					qtd->length, token);
-			if (last_status == -EREMOTEIO
-					&& (qtd->hw_alt_next
-						& FOTG210_LIST_END(fotg210)))
+			if (last_status == -EREMOTEIO &&
+					(qtd->hw_alt_next &
+					FOTG210_LIST_END(fotg210)))
 				last_status = -EINPROGRESS;
 
 			/* As part of low/full-speed endpoint-halt processing
@@ -2537,7 +2459,7 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 				 */
 				if (last_status != -EPIPE)
 					fotg210_clear_tt_buffer(fotg210, qh,
-								urb, token);
+							urb, token);
 			}
 		}
 
@@ -2615,26 +2537,21 @@ qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	return count;
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
 #define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
 /* ... and packet size, for any kind of endpoint descriptor */
 #define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
 
-/*
- * reverse of qh_urb_transaction:  free a list of TDs.
+/* reverse of qh_urb_transaction:  free a list of TDs.
  * used for cleanup after errors, before HC sees an URB's TDs.
  */
-static void qtd_list_free(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list
-) {
-	struct list_head	*entry, *temp;
+static void qtd_list_free(struct fotg210_hcd *fotg210, struct urb *urb,
+		struct list_head *qtd_list)
+{
+	struct list_head *entry, *temp;
 
 	list_for_each_safe(entry, temp, qtd_list) {
-		struct fotg210_qtd	*qtd;
+		struct fotg210_qtd *qtd;
 
 		qtd = list_entry(entry, struct fotg210_qtd, qtd_list);
 		list_del(&qtd->qtd_list);
@@ -2642,23 +2559,18 @@ static void qtd_list_free(
 	}
 }
 
-/*
- * create a list of filled qtds for this URB; won't link into qh.
+/* create a list of filled qtds for this URB; won't link into qh.
  */
-static struct list_head *
-qh_urb_transaction(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*head,
-	gfp_t			flags
-) {
-	struct fotg210_qtd		*qtd, *qtd_prev;
-	dma_addr_t		buf;
-	int			len, this_sg_len, maxpacket;
-	int			is_input;
-	u32			token;
-	int			i;
-	struct scatterlist	*sg;
+static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
+		struct urb *urb, struct list_head *head, gfp_t flags)
+{
+	struct fotg210_qtd *qtd, *qtd_prev;
+	dma_addr_t buf;
+	int len, this_sg_len, maxpacket;
+	int is_input;
+	u32 token;
+	int i;
+	struct scatterlist *sg;
 
 	/*
 	 * URBs map to sequences of QTDs:  one logical transaction
@@ -2768,8 +2680,8 @@ qh_urb_transaction(
 	 * have the alt_next mechanism keep the queue running after the
 	 * last data qtd (the only one, for control and most other cases).
 	 */
-	if (likely((urb->transfer_flags & URB_SHORT_NOT_OK) == 0
-				|| usb_pipecontrol(urb->pipe)))
+	if (likely((urb->transfer_flags & URB_SHORT_NOT_OK) == 0 ||
+			usb_pipecontrol(urb->pipe)))
 		qtd->hw_alt_next = FOTG210_LIST_END(fotg210);
 
 	/*
@@ -2778,7 +2690,7 @@ qh_urb_transaction(
 	 * (zero length).
 	 */
 	if (likely(urb->transfer_buffer_length != 0)) {
-		int	one_more = 0;
+		int one_more = 0;
 
 		if (usb_pipecontrol(urb->pipe)) {
 			one_more = 1;
@@ -2813,9 +2725,7 @@ cleanup:
 	return NULL;
 }
 
-/*-------------------------------------------------------------------------*/
-/*
- * Would be best to create all qh's from config descriptors,
+/* Would be best to create all qh's from config descriptors,
  * when each interface/altsetting is established.  Unlink
  * any previous qh and cancel its urbs first; endpoints are
  * implicitly reset then (data toggle too).
@@ -2823,26 +2733,22 @@ cleanup:
 */
 
 
-/*
- * Each QH holds a qtd list; a QH is used for everything except iso.
+/* Each QH holds a qtd list; a QH is used for everything except iso.
  *
  * For interrupt urbs, the scheduler must set the microframe scheduling
  * mask(s) each time the QH gets scheduled.  For highspeed, that's
  * just one microframe in the s-mask.  For split interrupt transactions
  * there are additional complications: c-mask, maybe FSTNs.
  */
-static struct fotg210_qh *
-qh_make(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	gfp_t			flags
-) {
-	struct fotg210_qh		*qh = fotg210_qh_alloc(fotg210, flags);
-	u32			info1 = 0, info2 = 0;
-	int			is_input, type;
-	int			maxp = 0;
-	struct usb_tt		*tt = urb->dev->tt;
-	struct fotg210_qh_hw	*hw;
+static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
+		gfp_t flags)
+{
+	struct fotg210_qh *qh = fotg210_qh_alloc(fotg210, flags);
+	u32 info1 = 0, info2 = 0;
+	int is_input, type;
+	int maxp = 0;
+	struct usb_tt *tt = urb->dev->tt;
+	struct fotg210_qh_hw *hw;
 
 	if (!qh)
 		return qh;
@@ -2862,7 +2768,7 @@ qh_make(
 	 */
 	if (max_packet(maxp) > 1024) {
 		fotg210_dbg(fotg210, "bogus qh maxpacket %d\n",
-			    max_packet(maxp));
+				max_packet(maxp));
 		goto done;
 	}
 
@@ -2896,7 +2802,7 @@ qh_make(
 				urb->interval = qh->period << 3;
 			}
 		} else {
-			int		think_time;
+			int think_time;
 
 			/* gap is f(FS/LS transfer times) */
 			qh->gap_uf = 1 + usb_calc_bus_time(urb->dev->speed,
@@ -2986,7 +2892,7 @@ qh_make(
 		break;
 	default:
 		fotg210_dbg(fotg210, "bogus dev %p speed %d\n", urb->dev,
-			urb->dev->speed);
+				urb->dev->speed);
 done:
 		qh_destroy(fotg210, qh);
 		return NULL;
@@ -3005,8 +2911,6 @@ done:
 	return qh;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void enable_async(struct fotg210_hcd *fotg210)
 {
 	if (fotg210->async_count++)
@@ -3036,8 +2940,8 @@ static void disable_async(struct fotg210_hcd *fotg210)
 
 static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
-	__hc32		dma = QH_NEXT(fotg210, qh->qh_dma);
-	struct fotg210_qh	*head;
+	__hc32 dma = QH_NEXT(fotg210, qh->qh_dma);
+	struct fotg210_qh *head;
 
 	/* Don't link a QH if there's a Clear-TT-Buffer pending */
 	if (unlikely(qh->clearing_tt))
@@ -3064,24 +2968,17 @@ static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	enable_async(fotg210);
 }
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * For control/bulk/interrupt, return QH with these TDs appended.
+/* For control/bulk/interrupt, return QH with these TDs appended.
  * Allocates and initializes the QH if necessary.
  * Returns null if it can't allocate a QH it needs to.
  * If the QH has TDs (urbs) already, that's great.
  */
-static struct fotg210_qh *qh_append_tds(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	int			epnum,
-	void			**ptr
-)
+static struct fotg210_qh *qh_append_tds(struct fotg210_hcd *fotg210,
+		struct urb *urb, struct list_head *qtd_list,
+		int epnum, void **ptr)
 {
-	struct fotg210_qh		*qh = NULL;
-	__hc32			qh_addr_mask = cpu_to_hc32(fotg210, 0x7f);
+	struct fotg210_qh *qh = NULL;
+	__hc32 qh_addr_mask = cpu_to_hc32(fotg210, 0x7f);
 
 	qh = (struct fotg210_qh *) *ptr;
 	if (unlikely(qh == NULL)) {
@@ -3090,7 +2987,7 @@ static struct fotg210_qh *qh_append_tds(
 		*ptr = qh;
 	}
 	if (likely(qh != NULL)) {
-		struct fotg210_qtd	*qtd;
+		struct fotg210_qtd *qtd;
 
 		if (unlikely(list_empty(qtd_list)))
 			qtd = NULL;
@@ -3109,9 +3006,9 @@ static struct fotg210_qh *qh_append_tds(
 		 * only hc or qh_refresh() ever modify the overlay.
 		 */
 		if (likely(qtd != NULL)) {
-			struct fotg210_qtd		*dummy;
-			dma_addr_t		dma;
-			__hc32			token;
+			struct fotg210_qtd *dummy;
+			dma_addr_t dma;
+			__hc32 token;
 
 			/* to avoid racing the HC, use the dummy td instead of
 			 * the first td of our list (becomes new dummy).  both
@@ -3150,32 +3047,28 @@ static struct fotg210_qh *qh_append_tds(
 	return qh;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static int
-submit_async(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	gfp_t			mem_flags
-) {
-	int			epnum;
-	unsigned long		flags;
-	struct fotg210_qh		*qh = NULL;
-	int			rc;
+static int submit_async(struct fotg210_hcd *fotg210, struct urb *urb,
+		struct list_head *qtd_list, gfp_t mem_flags)
+{
+	int epnum;
+	unsigned long flags;
+	struct fotg210_qh *qh = NULL;
+	int rc;
 
 	epnum = urb->ep->desc.bEndpointAddress;
 
 #ifdef FOTG210_URB_TRACE
 	{
 		struct fotg210_qtd *qtd;
+
 		qtd = list_entry(qtd_list->next, struct fotg210_qtd, qtd_list);
 		fotg210_dbg(fotg210,
-			 "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
-			 __func__, urb->dev->devpath, urb,
-			 epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
-			 urb->transfer_buffer_length,
-			 qtd, urb->ep->hcpriv);
+				"%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
+				__func__, urb->dev->devpath, urb,
+				epnum & 0x0f, (epnum & USB_DIR_IN)
+					? "in" : "out",
+				urb->transfer_buffer_length,
+				qtd, urb->ep->hcpriv);
 	}
 #endif
 
@@ -3200,19 +3093,17 @@ submit_async(
 	 */
 	if (likely(qh->qh_state == QH_STATE_IDLE))
 		qh_link_async(fotg210, qh);
- done:
+done:
 	spin_unlock_irqrestore(&fotg210->lock, flags);
 	if (unlikely(qh == NULL))
 		qtd_list_free(fotg210, urb, qtd_list);
 	return rc;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void single_unlink_async(struct fotg210_hcd *fotg210,
-				struct fotg210_qh *qh)
+		struct fotg210_qh *qh)
 {
-	struct fotg210_qh		*prev;
+	struct fotg210_qh *prev;
 
 	/* Add to the end of the list of QHs waiting for the next IAAD */
 	qh->qh_state = QH_STATE_UNLINK;
@@ -3260,7 +3151,7 @@ static void start_iaa_cycle(struct fotg210_hcd *fotg210, bool nested)
 				&fotg210->regs->command);
 		fotg210_readl(fotg210, &fotg210->regs->command);
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_IAA_WATCHDOG,
-				     true);
+				true);
 	}
 }
 
@@ -3268,10 +3159,10 @@ static void start_iaa_cycle(struct fotg210_hcd *fotg210, bool nested)
 
 static void end_unlink_async(struct fotg210_hcd *fotg210)
 {
-	struct fotg210_qh		*qh;
+	struct fotg210_qh *qh;
 
 	/* Process the idle QHs */
- restart:
+restart:
 	fotg210->async_unlinking = true;
 	while (fotg210->async_iaa) {
 		qh = fotg210->async_iaa;
@@ -3326,7 +3217,7 @@ static void unlink_empty_async(struct fotg210_hcd *fotg210)
 	/* QHs that haven't been empty for long enough will be handled later */
 	if (check_unlinks_later) {
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_ASYNC_UNLINKS,
-				     true);
+				true);
 		++fotg210->async_unlink_cycle;
 	}
 }
@@ -3335,7 +3226,7 @@ static void unlink_empty_async(struct fotg210_hcd *fotg210)
 /* caller must own fotg210->lock */
 
 static void start_unlink_async(struct fotg210_hcd *fotg210,
-			       struct fotg210_qh *qh)
+		struct fotg210_qh *qh)
 {
 	/*
 	 * If the QH isn't linked then there's nothing we can do
@@ -3352,18 +3243,16 @@ static void start_unlink_async(struct fotg210_hcd *fotg210,
 	start_iaa_cycle(fotg210, false);
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void scan_async(struct fotg210_hcd *fotg210)
 {
-	struct fotg210_qh		*qh;
-	bool			check_unlinks_later = false;
+	struct fotg210_qh *qh;
+	bool check_unlinks_later = false;
 
 	fotg210->qh_scan_next = fotg210->async->qh_next.qh;
 	while (fotg210->qh_scan_next) {
 		qh = fotg210->qh_scan_next;
 		fotg210->qh_scan_next = qh->qh_next.qh;
- rescan:
+rescan:
 		/* clean any finished work for this qh */
 		if (!list_empty(&qh->qtd_list)) {
 			int temp;
@@ -3395,15 +3284,13 @@ static void scan_async(struct fotg210_hcd *fotg210)
 	 */
 	if (check_unlinks_later && fotg210->rh_state == FOTG210_RH_RUNNING &&
 			!(fotg210->enabled_hrtimer_events &
-				BIT(FOTG210_HRTIMER_ASYNC_UNLINKS))) {
+			BIT(FOTG210_HRTIMER_ASYNC_UNLINKS))) {
 		fotg210_enable_event(fotg210,
-				     FOTG210_HRTIMER_ASYNC_UNLINKS, true);
+				FOTG210_HRTIMER_ASYNC_UNLINKS, true);
 		++fotg210->async_unlink_cycle;
 	}
 }
-/*-------------------------------------------------------------------------*/
-/*
- * EHCI scheduled transaction support:  interrupt, iso, split iso
+/* EHCI scheduled transaction support:  interrupt, iso, split iso
  * These are called "periodic" transactions in the EHCI spec.
  *
  * Note that for interrupt transfers, the QH/QTD manipulation is shared
@@ -3414,19 +3301,14 @@ static void scan_async(struct fotg210_hcd *fotg210)
  * It keeps track of every ITD (or SITD) that's linked, and holds enough
  * pre-calculated schedule data to make appending to the queue be quick.
  */
-
 static int fotg210_get_frame(struct usb_hcd *hcd);
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * periodic_next_shadow - return "next" pointer on shadow list
+/* periodic_next_shadow - return "next" pointer on shadow list
  * @periodic: host pointer to qh/itd
  * @tag: hardware tag for type of this record
  */
-static union fotg210_shadow *
-periodic_next_shadow(struct fotg210_hcd *fotg210,
-		     union fotg210_shadow *periodic, __hc32 tag)
+static union fotg210_shadow *periodic_next_shadow(struct fotg210_hcd *fotg210,
+		union fotg210_shadow *periodic, __hc32 tag)
 {
 	switch (hc32_to_cpu(fotg210, tag)) {
 	case Q_TYPE_QH:
@@ -3438,9 +3320,8 @@ periodic_next_shadow(struct fotg210_hcd *fotg210,
 	}
 }
 
-static __hc32 *
-shadow_next_periodic(struct fotg210_hcd *fotg210,
-		     union fotg210_shadow *periodic, __hc32 tag)
+static __hc32 *shadow_next_periodic(struct fotg210_hcd *fotg210,
+		union fotg210_shadow *periodic, __hc32 tag)
 {
 	switch (hc32_to_cpu(fotg210, tag)) {
 	/* our fotg210_shadow.qh is actually software part */
@@ -3454,11 +3335,11 @@ shadow_next_periodic(struct fotg210_hcd *fotg210,
 
 /* caller must hold fotg210->lock */
 static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
-			    void *ptr)
+		void *ptr)
 {
-	union fotg210_shadow	*prev_p = &fotg210->pshadow[frame];
-	__hc32			*hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow	here = *prev_p;
+	union fotg210_shadow *prev_p = &fotg210->pshadow[frame];
+	__hc32 *hw_p = &fotg210->periodic[frame];
+	union fotg210_shadow here = *prev_p;
 
 	/* find predecessor of "ptr"; hw and shadow lists are in sync */
 	while (here.ptr && here.ptr != ptr) {
@@ -3479,17 +3360,17 @@ static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
 			Q_NEXT_TYPE(fotg210, *hw_p));
 
 	*hw_p = *shadow_next_periodic(fotg210, &here,
-				Q_NEXT_TYPE(fotg210, *hw_p));
+			Q_NEXT_TYPE(fotg210, *hw_p));
 }
 
 /* how many of the uframe's 125 usecs are allocated? */
-static unsigned short
-periodic_usecs(struct fotg210_hcd *fotg210, unsigned frame, unsigned uframe)
+static unsigned short periodic_usecs(struct fotg210_hcd *fotg210,
+		unsigned frame, unsigned uframe)
 {
-	__hc32			*hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow	*q = &fotg210->pshadow[frame];
-	unsigned		usecs = 0;
-	struct fotg210_qh_hw	*hw;
+	__hc32 *hw_p = &fotg210->periodic[frame];
+	union fotg210_shadow *q = &fotg210->pshadow[frame];
+	unsigned usecs = 0;
+	struct fotg210_qh_hw *hw;
 
 	while (q->ptr) {
 		switch (hc32_to_cpu(fotg210, Q_NEXT_TYPE(fotg210, *hw_p))) {
@@ -3526,12 +3407,10 @@ periodic_usecs(struct fotg210_hcd *fotg210, unsigned frame, unsigned uframe)
 	}
 	if (usecs > fotg210->uframe_periodic_max)
 		fotg210_err(fotg210, "uframe %d sched overrun: %d usecs\n",
-			frame * 8 + uframe, usecs);
+				frame * 8 + uframe, usecs);
 	return usecs;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static int same_tt(struct usb_device *dev1, struct usb_device *dev2)
 {
 	if (!dev1->tt || !dev2->tt)
@@ -3548,13 +3427,8 @@ static int same_tt(struct usb_device *dev1, struct usb_device *dev2)
  * for a periodic transfer starting at the specified frame, using
  * all the uframes in the mask.
  */
-static int tt_no_collision(
-	struct fotg210_hcd		*fotg210,
-	unsigned		period,
-	struct usb_device	*dev,
-	unsigned		frame,
-	u32			uf_mask
-)
+static int tt_no_collision(struct fotg210_hcd *fotg210, unsigned period,
+		struct usb_device *dev, unsigned frame, u32 uf_mask)
 {
 	if (period == 0)	/* error */
 		return 0;
@@ -3564,9 +3438,9 @@ static int tt_no_collision(
 	 * calling convention doesn't make that distinction.
 	 */
 	for (; frame < fotg210->periodic_size; frame += period) {
-		union fotg210_shadow	here;
-		__hc32			type;
-		struct fotg210_qh_hw	*hw;
+		union fotg210_shadow here;
+		__hc32 type;
+		struct fotg210_qh_hw *hw;
 
 		here = fotg210->pshadow[frame];
 		type = Q_NEXT_TYPE(fotg210, fotg210->periodic[frame]);
@@ -3579,7 +3453,7 @@ static int tt_no_collision(
 			case Q_TYPE_QH:
 				hw = here.qh->hw;
 				if (same_tt(dev, here.qh->dev)) {
-					u32		mask;
+					u32 mask;
 
 					mask = hc32_to_cpu(fotg210,
 							hw->hw_info2);
@@ -3594,8 +3468,8 @@ static int tt_no_collision(
 			/* case Q_TYPE_FSTN: */
 			default:
 				fotg210_dbg(fotg210,
-					"periodic frame %d bogus type %d\n",
-					frame, type);
+						"periodic frame %d bogus type %d\n",
+						frame, type);
 			}
 
 			/* collision or error */
@@ -3607,8 +3481,6 @@ static int tt_no_collision(
 	return 1;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static void enable_periodic(struct fotg210_hcd *fotg210)
 {
 	if (fotg210->periodic_count++)
@@ -3632,8 +3504,6 @@ static void disable_periodic(struct fotg210_hcd *fotg210)
 	fotg210_poll_PSS(fotg210);
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* periodic schedule slots have iso tds (normal or split) first, then a
  * sparse tree for active interrupt transfers.
  *
@@ -3642,24 +3512,24 @@ static void disable_periodic(struct fotg210_hcd *fotg210)
  */
 static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
-	unsigned	i;
-	unsigned	period = qh->period;
+	unsigned i;
+	unsigned period = qh->period;
 
 	dev_dbg(&qh->dev->dev,
-		"link qh%d-%04x/%p start %d [%d/%d us]\n",
-		period, hc32_to_cpup(fotg210, &qh->hw->hw_info2)
-			& (QH_CMASK | QH_SMASK),
-		qh, qh->start, qh->usecs, qh->c_usecs);
+			"link qh%d-%04x/%p start %d [%d/%d us]\n", period,
+			hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
+			(QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs,
+			qh->c_usecs);
 
 	/* high bandwidth, or otherwise every microframe */
 	if (period == 0)
 		period = 1;
 
 	for (i = qh->start; i < fotg210->periodic_size; i += period) {
-		union fotg210_shadow	*prev = &fotg210->pshadow[i];
-		__hc32			*hw_p = &fotg210->periodic[i];
-		union fotg210_shadow	here = *prev;
-		__hc32			type = 0;
+		union fotg210_shadow *prev = &fotg210->pshadow[i];
+		__hc32 *hw_p = &fotg210->periodic[i];
+		union fotg210_shadow here = *prev;
+		__hc32 type = 0;
 
 		/* skip the iso nodes at list head */
 		while (here.ptr) {
@@ -3707,10 +3577,10 @@ static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 }
 
 static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
-			       struct fotg210_qh *qh)
+		struct fotg210_qh *qh)
 {
-	unsigned	i;
-	unsigned	period;
+	unsigned i;
+	unsigned period;
 
 	/*
 	 * If qh is for a low/full-speed device, simply unlinking it
@@ -3741,10 +3611,10 @@ static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
 		: (qh->usecs * 8);
 
 	dev_dbg(&qh->dev->dev,
-		"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
-		qh->period,
-		hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
-		(QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs, qh->c_usecs);
+			"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
+			qh->period, hc32_to_cpup(fotg210, &qh->hw->hw_info2) &
+			(QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs,
+			qh->c_usecs);
 
 	/* qh->qh_next still "live" to HC */
 	qh->qh_state = QH_STATE_UNLINK;
@@ -3757,7 +3627,7 @@ static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
 }
 
 static void start_unlink_intr(struct fotg210_hcd *fotg210,
-			      struct fotg210_qh *qh)
+		struct fotg210_qh *qh)
 {
 	/* If the QH isn't linked then there's nothing we can do
 	 * unless we were called during a giveback, in which case
@@ -3794,15 +3664,15 @@ static void start_unlink_intr(struct fotg210_hcd *fotg210,
 		fotg210_handle_intr_unlinks(fotg210);
 	else if (fotg210->intr_unlink == qh) {
 		fotg210_enable_event(fotg210, FOTG210_HRTIMER_UNLINK_INTR,
-				     true);
+				true);
 		++fotg210->intr_unlink_cycle;
 	}
 }
 
 static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
-	struct fotg210_qh_hw	*hw = qh->hw;
-	int			rc;
+	struct fotg210_qh_hw *hw = qh->hw;
+	int rc;
 
 	qh->qh_state = QH_STATE_IDLE;
 	hw->hw_next = FOTG210_LIST_END(fotg210);
@@ -3811,7 +3681,7 @@ static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 
 	/* reschedule QH iff another request is queued */
 	if (!list_empty(&qh->qtd_list) &&
-	    fotg210->rh_state == FOTG210_RH_RUNNING) {
+			fotg210->rh_state == FOTG210_RH_RUNNING) {
 		rc = qh_schedule(fotg210, qh);
 
 		/* An error here likely indicates handshake failure
@@ -3830,16 +3700,10 @@ static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	disable_periodic(fotg210);
 }
 
-/*-------------------------------------------------------------------------*/
-
-static int check_period(
-	struct fotg210_hcd *fotg210,
-	unsigned	frame,
-	unsigned	uframe,
-	unsigned	period,
-	unsigned	usecs
-) {
-	int		claimed;
+static int check_period(struct fotg210_hcd *fotg210, unsigned frame,
+		unsigned uframe, unsigned period, unsigned usecs)
+{
+	int claimed;
 
 	/* complete split running into next frame?
 	 * given FSTN support, we could sometimes check...
@@ -3857,7 +3721,7 @@ static int check_period(
 		do {
 			for (uframe = 0; uframe < 7; uframe++) {
 				claimed = periodic_usecs(fotg210, frame,
-							 uframe);
+						uframe);
 				if (claimed > usecs)
 					return 0;
 			}
@@ -3876,16 +3740,11 @@ static int check_period(
 	return 1;
 }
 
-static int check_intr_schedule(
-	struct fotg210_hcd		*fotg210,
-	unsigned		frame,
-	unsigned		uframe,
-	const struct fotg210_qh	*qh,
-	__hc32			*c_maskp
-)
+static int check_intr_schedule(struct fotg210_hcd *fotg210, unsigned frame,
+		unsigned uframe, const struct fotg210_qh *qh, __hc32 *c_maskp)
 {
-	int		retval = -ENOSPC;
-	u8		mask = 0;
+	int retval = -ENOSPC;
+	u8 mask = 0;
 
 	if (qh->c_usecs && uframe >= 6)		/* FSTN territory? */
 		goto done;
@@ -3911,10 +3770,10 @@ static int check_intr_schedule(
 	mask |= 1 << uframe;
 	if (tt_no_collision(fotg210, qh->period, qh->dev, frame, mask)) {
 		if (!check_period(fotg210, frame, uframe + qh->gap_uf + 1,
-					qh->period, qh->c_usecs))
+				qh->period, qh->c_usecs))
 			goto done;
 		if (!check_period(fotg210, frame, uframe + qh->gap_uf,
-					qh->period, qh->c_usecs))
+				qh->period, qh->c_usecs))
 			goto done;
 		retval = 0;
 	}
@@ -3927,11 +3786,11 @@ done:
  */
 static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 {
-	int		status;
-	unsigned	uframe;
-	__hc32		c_mask;
-	unsigned	frame;		/* 0..(qh->period - 1), or NO_FRAME */
-	struct fotg210_qh_hw	*hw = qh->hw;
+	int status;
+	unsigned uframe;
+	__hc32 c_mask;
+	unsigned frame;	/* 0..(qh->period - 1), or NO_FRAME */
+	struct fotg210_qh_hw *hw = qh->hw;
 
 	qh_refresh(fotg210, qh);
 	hw->hw_next = FOTG210_LIST_END(fotg210);
@@ -3954,7 +3813,7 @@ static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 	if (status) {
 		/* "normal" case, uframing flexible except with splits */
 		if (qh->period) {
-			int		i;
+			int i;
 
 			for (i = qh->period; status && i > 0; --i) {
 				frame = ++fotg210->random_frame % qh->period;
@@ -3971,7 +3830,7 @@ static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
 		} else {
 			frame = 0;
 			status = check_intr_schedule(fotg210, 0, 0, qh,
-						     &c_mask);
+					&c_mask);
 		}
 		if (status)
 			goto done;
@@ -3992,17 +3851,14 @@ done:
 	return status;
 }
 
-static int intr_submit(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct list_head	*qtd_list,
-	gfp_t			mem_flags
-) {
-	unsigned		epnum;
-	unsigned long		flags;
-	struct fotg210_qh		*qh;
-	int			status;
-	struct list_head	empty;
+static int intr_submit(struct fotg210_hcd *fotg210, struct urb *urb,
+		struct list_head *qtd_list, gfp_t mem_flags)
+{
+	unsigned epnum;
+	unsigned long flags;
+	struct fotg210_qh *qh;
+	int status;
+	struct list_head empty;
 
 	/* get endpoint and transfer/schedule data */
 	epnum = urb->ep->desc.bEndpointAddress;
@@ -4050,11 +3906,11 @@ done_not_linked:
 
 static void scan_intr(struct fotg210_hcd *fotg210)
 {
-	struct fotg210_qh		*qh;
+	struct fotg210_qh *qh;
 
 	list_for_each_entry_safe(qh, fotg210->qh_scan_next,
-				 &fotg210->intr_qh_list, intr_node) {
- rescan:
+			&fotg210->intr_qh_list, intr_node) {
+rescan:
 		/* clean any finished work for this qh */
 		if (!list_empty(&qh->qtd_list)) {
 			int temp;
@@ -4069,7 +3925,7 @@ static void scan_intr(struct fotg210_hcd *fotg210)
 			temp = qh_completions(fotg210, qh);
 			if (unlikely(qh->needs_rescan ||
 					(list_empty(&qh->qtd_list) &&
-					 qh->qh_state == QH_STATE_LINKED)))
+					qh->qh_state == QH_STATE_LINKED)))
 				start_unlink_intr(fotg210, qh);
 			else if (temp != 0)
 				goto rescan;
@@ -4077,12 +3933,9 @@ static void scan_intr(struct fotg210_hcd *fotg210)
 	}
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* fotg210_iso_stream ops work with both ITD and SITD */
 
-static struct fotg210_iso_stream *
-iso_stream_alloc(gfp_t mem_flags)
+static struct fotg210_iso_stream *iso_stream_alloc(gfp_t mem_flags)
 {
 	struct fotg210_iso_stream *stream;
 
@@ -4095,20 +3948,15 @@ iso_stream_alloc(gfp_t mem_flags)
 	return stream;
 }
 
-static void
-iso_stream_init(
-	struct fotg210_hcd		*fotg210,
-	struct fotg210_iso_stream	*stream,
-	struct usb_device	*dev,
-	int			pipe,
-	unsigned		interval
-)
+static void iso_stream_init(struct fotg210_hcd *fotg210,
+		struct fotg210_iso_stream *stream, struct usb_device *dev,
+		int pipe, unsigned interval)
 {
-	u32			buf1;
-	unsigned		epnum, maxp;
-	int			is_input;
-	long			bandwidth;
-	unsigned		multi;
+	u32 buf1;
+	unsigned epnum, maxp;
+	int is_input;
+	long bandwidth;
+	unsigned multi;
 
 	/*
 	 * this might be a "high bandwidth" highspeed endpoint,
@@ -4153,13 +4001,13 @@ iso_stream_init(
 	stream->maxp = maxp;
 }
 
-static struct fotg210_iso_stream *
-iso_stream_find(struct fotg210_hcd *fotg210, struct urb *urb)
+static struct fotg210_iso_stream *iso_stream_find(struct fotg210_hcd *fotg210,
+		struct urb *urb)
 {
-	unsigned		epnum;
-	struct fotg210_iso_stream	*stream;
+	unsigned epnum;
+	struct fotg210_iso_stream *stream;
 	struct usb_host_endpoint *ep;
-	unsigned long		flags;
+	unsigned long flags;
 
 	epnum = usb_pipeendpoint(urb->pipe);
 	if (usb_pipein(urb->pipe))
@@ -4182,8 +4030,8 @@ iso_stream_find(struct fotg210_hcd *fotg210, struct urb *urb)
 	/* if dev->ep[epnum] is a QH, hw is set */
 	} else if (unlikely(stream->hw != NULL)) {
 		fotg210_dbg(fotg210, "dev %s ep%d%s, not iso??\n",
-			urb->dev->devpath, epnum,
-			usb_pipein(urb->pipe) ? "in" : "out");
+				urb->dev->devpath, epnum,
+				usb_pipein(urb->pipe) ? "in" : "out");
 		stream = NULL;
 	}
 
@@ -4191,15 +4039,13 @@ iso_stream_find(struct fotg210_hcd *fotg210, struct urb *urb)
 	return stream;
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* fotg210_iso_sched ops can be ITD-only or SITD-only */
 
-static struct fotg210_iso_sched *
-iso_sched_alloc(unsigned packets, gfp_t mem_flags)
+static struct fotg210_iso_sched *iso_sched_alloc(unsigned packets,
+		gfp_t mem_flags)
 {
-	struct fotg210_iso_sched	*iso_sched;
-	int			size = sizeof(*iso_sched);
+	struct fotg210_iso_sched *iso_sched;
+	int size = sizeof(*iso_sched);
 
 	size += packets * sizeof(struct fotg210_iso_packet);
 	iso_sched = kzalloc(size, mem_flags);
@@ -4209,16 +4055,12 @@ iso_sched_alloc(unsigned packets, gfp_t mem_flags)
 	return iso_sched;
 }
 
-static inline void
-itd_sched_init(
-	struct fotg210_hcd		*fotg210,
-	struct fotg210_iso_sched	*iso_sched,
-	struct fotg210_iso_stream	*stream,
-	struct urb		*urb
-)
+static inline void itd_sched_init(struct fotg210_hcd *fotg210,
+		struct fotg210_iso_sched *iso_sched,
+		struct fotg210_iso_stream *stream, struct urb *urb)
 {
-	unsigned	i;
-	dma_addr_t	dma = urb->transfer_dma;
+	unsigned i;
+	dma_addr_t dma = urb->transfer_dma;
 
 	/* how many uframes are needed for these transfers */
 	iso_sched->span = urb->number_of_packets * stream->interval;
@@ -4227,10 +4069,10 @@ itd_sched_init(
 	 * when we fit new itds into the schedule.
 	 */
 	for (i = 0; i < urb->number_of_packets; i++) {
-		struct fotg210_iso_packet	*uframe = &iso_sched->packet[i];
-		unsigned		length;
-		dma_addr_t		buf;
-		u32			trans;
+		struct fotg210_iso_packet *uframe = &iso_sched->packet[i];
+		unsigned length;
+		dma_addr_t buf;
+		u32 trans;
 
 		length = urb->iso_frame_desc[i].length;
 		buf = dma + urb->iso_frame_desc[i].offset;
@@ -4251,11 +4093,8 @@ itd_sched_init(
 	}
 }
 
-static void
-iso_sched_free(
-	struct fotg210_iso_stream	*stream,
-	struct fotg210_iso_sched	*iso_sched
-)
+static void iso_sched_free(struct fotg210_iso_stream *stream,
+		struct fotg210_iso_sched *iso_sched)
 {
 	if (!iso_sched)
 		return;
@@ -4264,20 +4103,15 @@ iso_sched_free(
 	kfree(iso_sched);
 }
 
-static int
-itd_urb_transaction(
-	struct fotg210_iso_stream	*stream,
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	gfp_t			mem_flags
-)
+static int itd_urb_transaction(struct fotg210_iso_stream *stream,
+		struct fotg210_hcd *fotg210, struct urb *urb, gfp_t mem_flags)
 {
-	struct fotg210_itd		*itd;
-	dma_addr_t		itd_dma;
-	int			i;
-	unsigned		num_itds;
-	struct fotg210_iso_sched	*sched;
-	unsigned long		flags;
+	struct fotg210_itd *itd;
+	dma_addr_t itd_dma;
+	int i;
+	unsigned num_itds;
+	struct fotg210_iso_sched *sched;
+	unsigned long flags;
 
 	sched = iso_sched_alloc(urb->number_of_packets, mem_flags);
 	if (unlikely(sched == NULL))
@@ -4306,7 +4140,7 @@ itd_urb_transaction(
 			list_del(&itd->itd_list);
 			itd_dma = itd->itd_dma;
 		} else {
- alloc_itd:
+alloc_itd:
 			spin_unlock_irqrestore(&fotg210->lock, flags);
 			itd = dma_pool_alloc(fotg210->itd_pool, mem_flags,
 					&itd_dma);
@@ -4330,16 +4164,8 @@ itd_urb_transaction(
 	return 0;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static inline int
-itd_slot_ok(
-	struct fotg210_hcd		*fotg210,
-	u32			mod,
-	u32			uframe,
-	u8			usecs,
-	u32			period
-)
+static inline int itd_slot_ok(struct fotg210_hcd *fotg210, u32 mod, u32 uframe,
+		u8 usecs, u32 period)
 {
 	uframe %= period;
 	do {
@@ -4354,8 +4180,7 @@ itd_slot_ok(
 	return 1;
 }
 
-/*
- * This scheduler plans almost as far into the future as it has actual
+/* This scheduler plans almost as far into the future as it has actual
  * periodic schedule slots.  (Affected by TUNE_FLS, which defaults to
  * "as small as possible" to be cache-friendlier.)  That limits the size
  * transfers you can stream reliably; avoid more than 64 msec per urb.
@@ -4365,19 +4190,15 @@ itd_slot_ok(
  * given FOTG210_TUNE_FLS and the slop).  Or, write a smarter scheduler!
  */
 
-#define SCHEDULE_SLOP	80	/* microframes */
+#define SCHEDULE_SLOP 80 /* microframes */
 
-static int
-iso_stream_schedule(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	struct fotg210_iso_stream	*stream
-)
+static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
+		struct fotg210_iso_stream *stream)
 {
-	u32			now, next, start, period, span;
-	int			status;
-	unsigned		mod = fotg210->periodic_size << 3;
-	struct fotg210_iso_sched	*sched = urb->hcpriv;
+	u32 now, next, start, period, span;
+	int status;
+	unsigned mod = fotg210->periodic_size << 3;
+	struct fotg210_iso_sched *sched = urb->hcpriv;
 
 	period = urb->interval;
 	span = sched->span;
@@ -4396,7 +4217,7 @@ iso_stream_schedule(
 	 * slot in the schedule, implicitly assuming URB_ISO_ASAP.
 	 */
 	if (likely(!list_empty(&stream->td_list))) {
-		u32	excess;
+		u32 excess;
 
 		/* For high speed devices, allow scheduling within the
 		 * isochronous scheduling threshold.  For full speed devices
@@ -4435,6 +4256,7 @@ iso_stream_schedule(
 	 */
 	else {
 		int done = 0;
+
 		start = SCHEDULE_SLOP + (now & ~0x07);
 
 		/* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */
@@ -4457,15 +4279,15 @@ iso_stream_schedule(
 		/* no room in the schedule */
 		if (!done) {
 			fotg210_dbg(fotg210, "iso resched full %p (now %d max %d)\n",
-				urb, now, now + mod);
+					urb, now, now + mod);
 			status = -ENOSPC;
 			goto fail;
 		}
 	}
 
 	/* Tried to schedule too far into the future? */
-	if (unlikely(start - now + span - period
-				>= mod - 2 * SCHEDULE_SLOP)) {
+	if (unlikely(start - now + span - period >=
+			mod - 2 * SCHEDULE_SLOP)) {
 		fotg210_dbg(fotg210, "request %p would overflow (%d+%d >= %d)\n",
 				urb, start - now, span - period,
 				mod - 2 * SCHEDULE_SLOP);
@@ -4485,17 +4307,14 @@ iso_stream_schedule(
 		fotg210->next_frame = now >> 3;
 	return 0;
 
- fail:
+fail:
 	iso_sched_free(stream, sched);
 	urb->hcpriv = NULL;
 	return status;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static inline void
-itd_init(struct fotg210_hcd *fotg210, struct fotg210_iso_stream *stream,
-		struct fotg210_itd *itd)
+static inline void itd_init(struct fotg210_hcd *fotg210,
+		struct fotg210_iso_stream *stream, struct fotg210_itd *itd)
 {
 	int i;
 
@@ -4511,17 +4330,12 @@ itd_init(struct fotg210_hcd *fotg210, struct fotg210_iso_stream *stream,
 	/* All other fields are filled when scheduling */
 }
 
-static inline void
-itd_patch(
-	struct fotg210_hcd		*fotg210,
-	struct fotg210_itd		*itd,
-	struct fotg210_iso_sched	*iso_sched,
-	unsigned		index,
-	u16			uframe
-)
+static inline void itd_patch(struct fotg210_hcd *fotg210,
+		struct fotg210_itd *itd, struct fotg210_iso_sched *iso_sched,
+		unsigned index, u16 uframe)
 {
-	struct fotg210_iso_packet	*uf = &iso_sched->packet[index];
-	unsigned		pg = itd->pg;
+	struct fotg210_iso_packet *uf = &iso_sched->packet[index];
+	unsigned pg = itd->pg;
 
 	uframe &= 0x07;
 	itd->index[uframe] = index;
@@ -4533,7 +4347,7 @@ itd_patch(
 
 	/* iso_frame_desc[].offset must be strictly increasing */
 	if (unlikely(uf->cross)) {
-		u64	bufp = uf->bufp + 4096;
+		u64 bufp = uf->bufp + 4096;
 
 		itd->pg = ++pg;
 		itd->hw_bufp[pg] |= cpu_to_hc32(fotg210, bufp & ~(u32)0);
@@ -4541,13 +4355,13 @@ itd_patch(
 	}
 }
 
-static inline void
-itd_link(struct fotg210_hcd *fotg210, unsigned frame, struct fotg210_itd *itd)
+static inline void itd_link(struct fotg210_hcd *fotg210, unsigned frame,
+		struct fotg210_itd *itd)
 {
-	union fotg210_shadow	*prev = &fotg210->pshadow[frame];
-	__hc32			*hw_p = &fotg210->periodic[frame];
-	union fotg210_shadow	here = *prev;
-	__hc32			type = 0;
+	union fotg210_shadow *prev = &fotg210->pshadow[frame];
+	__hc32 *hw_p = &fotg210->periodic[frame];
+	union fotg210_shadow here = *prev;
+	__hc32 type = 0;
 
 	/* skip any iso nodes which might belong to previous microframes */
 	while (here.ptr) {
@@ -4568,17 +4382,13 @@ itd_link(struct fotg210_hcd *fotg210, unsigned frame, struct fotg210_itd *itd)
 }
 
 /* fit urb's itds into the selected schedule slot; activate as needed */
-static void itd_link_urb(
-	struct fotg210_hcd		*fotg210,
-	struct urb		*urb,
-	unsigned		mod,
-	struct fotg210_iso_stream	*stream
-)
-{
-	int			packet;
-	unsigned		next_uframe, uframe, frame;
-	struct fotg210_iso_sched	*iso_sched = urb->hcpriv;
-	struct fotg210_itd		*itd;
+static void itd_link_urb(struct fotg210_hcd *fotg210, struct urb *urb,
+		unsigned mod, struct fotg210_iso_stream *stream)
+{
+	int packet;
+	unsigned next_uframe, uframe, frame;
+	struct fotg210_iso_sched *iso_sched = urb->hcpriv;
+	struct fotg210_itd *itd;
 
 	next_uframe = stream->next_uframe & (mod - 1);
 
@@ -4621,7 +4431,7 @@ static void itd_link_urb(
 		if (((next_uframe >> 3) != frame)
 				|| packet == urb->number_of_packets) {
 			itd_link(fotg210, frame & (fotg210->periodic_size - 1),
-				 itd);
+					itd);
 			itd = NULL;
 		}
 	}
@@ -4635,8 +4445,8 @@ static void itd_link_urb(
 	enable_periodic(fotg210);
 }
 
-#define	ISO_ERRS (FOTG210_ISOC_BUF_ERR | FOTG210_ISOC_BABBLE |\
-		  FOTG210_ISOC_XACTERR)
+#define ISO_ERRS (FOTG210_ISOC_BUF_ERR | FOTG210_ISOC_BABBLE |\
+		FOTG210_ISOC_XACTERR)
 
 /* Process and recycle a completed ITD.  Return true iff its urb completed,
  * and hence its completion callback probably added things to the hardware
@@ -4650,14 +4460,14 @@ static void itd_link_urb(
  */
 static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 {
-	struct urb				*urb = itd->urb;
-	struct usb_iso_packet_descriptor	*desc;
-	u32					t;
-	unsigned				uframe;
-	int					urb_index = -1;
-	struct fotg210_iso_stream			*stream = itd->stream;
-	struct usb_device			*dev;
-	bool					retval = false;
+	struct urb *urb = itd->urb;
+	struct usb_iso_packet_descriptor *desc;
+	u32 t;
+	unsigned uframe;
+	int urb_index = -1;
+	struct fotg210_iso_stream *stream = itd->stream;
+	struct usb_device *dev;
+	bool retval = false;
 
 	/* for each uframe with a packet */
 	for (uframe = 0; uframe < 8; uframe++) {
@@ -4702,8 +4512,8 @@ static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
 		goto done;
 
 	/* ASSERT: it's really the last itd for this urb
-	list_for_each_entry (itd, &stream->td_list, itd_list)
-		BUG_ON (itd->urb == urb);
+	 * list_for_each_entry (itd, &stream->td_list, itd_list)
+	 *	BUG_ON (itd->urb == urb);
 	 */
 
 	/* give urb back to the driver; completion often (re)submits */
@@ -4740,14 +4550,12 @@ done:
 	return retval;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
-	gfp_t mem_flags)
+		gfp_t mem_flags)
 {
-	int			status = -EINVAL;
-	unsigned long		flags;
-	struct fotg210_iso_stream	*stream;
+	int status = -EINVAL;
+	unsigned long flags;
+	struct fotg210_iso_stream *stream;
 
 	/* Get iso_stream head */
 	stream = iso_stream_find(fotg210, urb);
@@ -4756,22 +4564,22 @@ static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
 		return -ENOMEM;
 	}
 	if (unlikely(urb->interval != stream->interval &&
-		      fotg210_port_speed(fotg210, 0) ==
-				USB_PORT_STAT_HIGH_SPEED)) {
-			fotg210_dbg(fotg210, "can't change iso interval %d --> %d\n",
+			fotg210_port_speed(fotg210, 0) ==
+			USB_PORT_STAT_HIGH_SPEED)) {
+		fotg210_dbg(fotg210, "can't change iso interval %d --> %d\n",
 				stream->interval, urb->interval);
-			goto done;
+		goto done;
 	}
 
 #ifdef FOTG210_URB_TRACE
 	fotg210_dbg(fotg210,
-		"%s %s urb %p ep%d%s len %d, %d pkts %d uframes[%p]\n",
-		__func__, urb->dev->devpath, urb,
-		usb_pipeendpoint(urb->pipe),
-		usb_pipein(urb->pipe) ? "in" : "out",
-		urb->transfer_buffer_length,
-		urb->number_of_packets, urb->interval,
-		stream);
+			"%s %s urb %p ep%d%s len %d, %d pkts %d uframes[%p]\n",
+			__func__, urb->dev->devpath, urb,
+			usb_pipeendpoint(urb->pipe),
+			usb_pipein(urb->pipe) ? "in" : "out",
+			urb->transfer_buffer_length,
+			urb->number_of_packets, urb->interval,
+			stream);
 #endif
 
 	/* allocate ITDs w/o locking anything */
@@ -4795,9 +4603,9 @@ static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
 		itd_link_urb(fotg210, urb, fotg210->periodic_size << 3, stream);
 	else
 		usb_hcd_unlink_urb_from_ep(fotg210_to_hcd(fotg210), urb);
- done_not_linked:
+done_not_linked:
 	spin_unlock_irqrestore(&fotg210->lock, flags);
- done:
+done:
 	return status;
 }
 
@@ -4876,7 +4684,7 @@ restart:
 				break;
 			default:
 				fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
-					type, frame, q.ptr);
+						type, frame, q.ptr);
 				/* FALL THROUGH */
 			case Q_TYPE_QH:
 			case Q_TYPE_FSTN:
@@ -4897,16 +4705,14 @@ restart:
 	}
 	fotg210->next_frame = now_frame;
 }
-/*-------------------------------------------------------------------------*/
-/*
- * Display / Set uframe_periodic_max
+
+/* Display / Set uframe_periodic_max
  */
 static ssize_t show_uframe_periodic_max(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
+		struct device_attribute *attr, char *buf)
 {
-	struct fotg210_hcd		*fotg210;
-	int			n;
+	struct fotg210_hcd *fotg210;
+	int n;
 
 	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
 	n = scnprintf(buf, PAGE_SIZE, "%d\n", fotg210->uframe_periodic_max);
@@ -4915,15 +4721,14 @@ static ssize_t show_uframe_periodic_max(struct device *dev,
 
 
 static ssize_t store_uframe_periodic_max(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf, size_t count)
+		struct device_attribute *attr, const char *buf, size_t count)
 {
-	struct fotg210_hcd	*fotg210;
-	unsigned		uframe_periodic_max;
-	unsigned		frame, uframe;
-	unsigned short		allocated_max;
-	unsigned long		flags;
-	ssize_t			ret;
+	struct fotg210_hcd *fotg210;
+	unsigned uframe_periodic_max;
+	unsigned frame, uframe;
+	unsigned short allocated_max;
+	unsigned long flags;
+	ssize_t ret;
 
 	fotg210 = hcd_to_fotg210(bus_to_hcd(dev_get_drvdata(dev)));
 	if (kstrtouint(buf, 0, &uframe_periodic_max) < 0)
@@ -4931,7 +4736,7 @@ static ssize_t store_uframe_periodic_max(struct device *dev,
 
 	if (uframe_periodic_max < 100 || uframe_periodic_max >= 125) {
 		fotg210_info(fotg210, "rejecting invalid request for uframe_periodic_max=%u\n",
-			     uframe_periodic_max);
+				uframe_periodic_max);
 		return -EINVAL;
 	}
 
@@ -4954,22 +4759,22 @@ static ssize_t store_uframe_periodic_max(struct device *dev,
 		for (frame = 0; frame < fotg210->periodic_size; ++frame)
 			for (uframe = 0; uframe < 7; ++uframe)
 				allocated_max = max(allocated_max,
-						    periodic_usecs(fotg210, frame, uframe));
+						periodic_usecs(fotg210, frame,
+						uframe));
 
 		if (allocated_max > uframe_periodic_max) {
 			fotg210_info(fotg210,
-				"cannot decrease uframe_periodic_max because "
-				"periodic bandwidth is already allocated "
-				"(%u > %u)\n",
-				allocated_max, uframe_periodic_max);
+					"cannot decrease uframe_periodic_max because periodic bandwidth is already allocated (%u > %u)\n",
+					allocated_max, uframe_periodic_max);
 			goto out_unlock;
 		}
 	}
 
 	/* increasing is always ok */
 
-	fotg210_info(fotg210, "setting max periodic bandwidth to %u%% (== %u usec/uframe)\n",
-		     100 * uframe_periodic_max/125, uframe_periodic_max);
+	fotg210_info(fotg210,
+			"setting max periodic bandwidth to %u%% (== %u usec/uframe)\n",
+			100 * uframe_periodic_max/125, uframe_periodic_max);
 
 	if (uframe_periodic_max != 100)
 		fotg210_warn(fotg210, "max periodic bandwidth set is non-standard\n");
@@ -4987,8 +4792,8 @@ static DEVICE_ATTR(uframe_periodic_max, 0644, show_uframe_periodic_max,
 
 static inline int create_sysfs_files(struct fotg210_hcd *fotg210)
 {
-	struct device	*controller = fotg210_to_hcd(fotg210)->self.controller;
-	int	i = 0;
+	struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
+	int i = 0;
 
 	if (i)
 		goto out;
@@ -5000,12 +4805,10 @@ out:
 
 static inline void remove_sysfs_files(struct fotg210_hcd *fotg210)
 {
-	struct device	*controller = fotg210_to_hcd(fotg210)->self.controller;
+	struct device *controller = fotg210_to_hcd(fotg210)->self.controller;
 
 	device_remove_file(controller, &dev_attr_uframe_periodic_max);
 }
-/*-------------------------------------------------------------------------*/
-
 /* On some systems, leaving remote wakeup enabled prevents system shutdown.
  * The firmware seems to think that powering off is a wakeup event!
  * This routine turns off remote wakeup and everything else, on all ports.
@@ -5017,8 +4820,7 @@ static void fotg210_turn_off_all_ports(struct fotg210_hcd *fotg210)
 	fotg210_writel(fotg210, PORT_RWC_BITS, status_reg);
 }
 
-/*
- * Halt HC, turn off all ports, and let the BIOS use the companion controllers.
+/* Halt HC, turn off all ports, and let the BIOS use the companion controllers.
  * Must be called with interrupts enabled and the lock not held.
  */
 static void fotg210_silence_controller(struct fotg210_hcd *fotg210)
@@ -5037,7 +4839,7 @@ static void fotg210_silence_controller(struct fotg210_hcd *fotg210)
  */
 static void fotg210_shutdown(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd	*fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
 
 	spin_lock_irq(&fotg210->lock);
 	fotg210->shutdown = true;
@@ -5050,10 +4852,7 @@ static void fotg210_shutdown(struct usb_hcd *hcd)
 	hrtimer_cancel(&fotg210->hrtimer);
 }
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * fotg210_work is called from some interrupts, timers, and so on.
+/* fotg210_work is called from some interrupts, timers, and so on.
  * it calls driver completion functions, after dropping fotg210->lock.
  */
 static void fotg210_work(struct fotg210_hcd *fotg210)
@@ -5068,7 +4867,7 @@ static void fotg210_work(struct fotg210_hcd *fotg210)
 	}
 	fotg210->scanning = true;
 
- rescan:
+rescan:
 	fotg210->need_rescan = false;
 	if (fotg210->async_count)
 		scan_async(fotg210);
@@ -5087,12 +4886,11 @@ static void fotg210_work(struct fotg210_hcd *fotg210)
 	turn_on_io_watchdog(fotg210);
 }
 
-/*
- * Called when the fotg210_hcd module is removed.
+/* Called when the fotg210_hcd module is removed.
  */
 static void fotg210_stop(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
 
 	fotg210_dbg(fotg210, "stop\n");
 
@@ -5116,26 +4914,26 @@ static void fotg210_stop(struct usb_hcd *hcd)
 	spin_unlock_irq(&fotg210->lock);
 	fotg210_mem_cleanup(fotg210);
 
-#ifdef	FOTG210_STATS
+#ifdef FOTG210_STATS
 	fotg210_dbg(fotg210, "irq normal %ld err %ld iaa %ld (lost %ld)\n",
-		fotg210->stats.normal, fotg210->stats.error, fotg210->stats.iaa,
-		fotg210->stats.lost_iaa);
+			fotg210->stats.normal, fotg210->stats.error,
+			fotg210->stats.iaa, fotg210->stats.lost_iaa);
 	fotg210_dbg(fotg210, "complete %ld unlink %ld\n",
-		fotg210->stats.complete, fotg210->stats.unlink);
+			fotg210->stats.complete, fotg210->stats.unlink);
 #endif
 
 	dbg_status(fotg210, "fotg210_stop completed",
-		    fotg210_readl(fotg210, &fotg210->regs->status));
+			fotg210_readl(fotg210, &fotg210->regs->status));
 }
 
 /* one-time init, only for memory state */
 static int hcd_fotg210_init(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	u32			temp;
-	int			retval;
-	u32			hcc_params;
-	struct fotg210_qh_hw	*hw;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 temp;
+	int retval;
+	u32 hcc_params;
+	struct fotg210_qh_hw *hw;
 
 	spin_lock_init(&fotg210->lock);
 
@@ -5238,18 +5036,18 @@ static int hcd_fotg210_init(struct usb_hcd *hcd)
 /* start HC running; it's halted, hcd_fotg210_init() has been run (once) */
 static int fotg210_run(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	u32			temp;
-	u32			hcc_params;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 temp;
+	u32 hcc_params;
 
 	hcd->uses_new_polling = 1;
 
 	/* EHCI spec section 4.1 */
 
 	fotg210_writel(fotg210, fotg210->periodic_dma,
-		       &fotg210->regs->frame_list);
+			&fotg210->regs->frame_list);
 	fotg210_writel(fotg210, (u32)fotg210->async->qh_dma,
-		       &fotg210->regs->async_next);
+			&fotg210->regs->async_next);
 
 	/*
 	 * hcc_params controls whether fotg210->regs->segment must (!!!)
@@ -5297,14 +5095,14 @@ static int fotg210_run(struct usb_hcd *hcd)
 	fotg210->last_periodic_enable = ktime_get_real();
 
 	temp = HC_VERSION(fotg210,
-			  fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
+			fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
 	fotg210_info(fotg210,
-		"USB %x.%x started, EHCI %x.%02x\n",
-		((fotg210->sbrn & 0xf0)>>4), (fotg210->sbrn & 0x0f),
-		temp >> 8, temp & 0xff);
+			"USB %x.%x started, EHCI %x.%02x\n",
+			((fotg210->sbrn & 0xf0) >> 4), (fotg210->sbrn & 0x0f),
+			temp >> 8, temp & 0xff);
 
 	fotg210_writel(fotg210, INTR_MASK,
-		    &fotg210->regs->intr_enable); /* Turn On Interrupts */
+			&fotg210->regs->intr_enable); /* Turn On Interrupts */
 
 	/* GRR this is run-once init(), being done every time the HC starts.
 	 * So long as they're part of class devices, we can't do it init()
@@ -5322,14 +5120,14 @@ static int fotg210_setup(struct usb_hcd *hcd)
 	int retval;
 
 	fotg210->regs = (void __iomem *)fotg210->caps +
-	    HC_LENGTH(fotg210,
-		      fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
+			HC_LENGTH(fotg210,
+			fotg210_readl(fotg210, &fotg210->caps->hc_capbase));
 	dbg_hcs_params(fotg210, "reset");
 	dbg_hcc_params(fotg210, "reset");
 
 	/* cache this readonly data; minimize chip reads */
 	fotg210->hcs_params = fotg210_readl(fotg210,
-					    &fotg210->caps->hcs_params);
+			&fotg210->caps->hcs_params);
 
 	fotg210->sbrn = HCD_USB2;
 
@@ -5347,13 +5145,11 @@ static int fotg210_setup(struct usb_hcd *hcd)
 	return 0;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	u32			status, masked_status, pcd_status = 0, cmd;
-	int			bh;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	u32 status, masked_status, pcd_status = 0, cmd;
+	int bh;
 
 	spin_lock(&fotg210->lock);
 
@@ -5373,7 +5169,7 @@ static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 
 	/* Shared IRQ? */
 	if (!masked_status ||
-	    unlikely(fotg210->rh_state == FOTG210_RH_HALTED)) {
+			unlikely(fotg210->rh_state == FOTG210_RH_HALTED)) {
 		spin_unlock(&fotg210->lock);
 		return IRQ_NONE;
 	}
@@ -5440,7 +5236,7 @@ static irqreturn_t fotg210_irq(struct usb_hcd *hcd)
 
 		if (test_bit(0, &fotg210->suspended_ports) &&
 				((pstatus & PORT_RESUME) ||
-					!(pstatus & PORT_SUSPEND)) &&
+				!(pstatus & PORT_SUSPEND)) &&
 				(pstatus & PORT_PE) &&
 				fotg210->reset_done[0] == 0) {
 
@@ -5469,7 +5265,7 @@ dead:
 		fotg210->rh_state = FOTG210_RH_STOPPING;
 		fotg210->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
 		fotg210_writel(fotg210, fotg210->command,
-			       &fotg210->regs->command);
+				&fotg210->regs->command);
 		fotg210_writel(fotg210, 0, &fotg210->regs->intr_enable);
 		fotg210_handle_controller_death(fotg210);
 
@@ -5485,10 +5281,7 @@ dead:
 	return IRQ_HANDLED;
 }
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * non-error returns are a promise to giveback() the urb later
+/* non-error returns are a promise to giveback() the urb later
  * we drop ownership so next owner (or urb unlink) can get it
  *
  * urb + dev is in hcd.self.controller.urb_list
@@ -5499,13 +5292,11 @@ dead:
  * NOTE:  control, bulk, and interrupt share the same code to append TDs
  * to a (possibly active) QH, and the same QH scanning code.
  */
-static int fotg210_urb_enqueue(
-	struct usb_hcd	*hcd,
-	struct urb	*urb,
-	gfp_t		mem_flags
-) {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct list_head	qtd_list;
+static int fotg210_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+		gfp_t mem_flags)
+{
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct list_head qtd_list;
 
 	INIT_LIST_HEAD(&qtd_list);
 
@@ -5539,10 +5330,10 @@ static int fotg210_urb_enqueue(
 
 static int fotg210_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh		*qh;
-	unsigned long		flags;
-	int			rc;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_qh *qh;
+	unsigned long flags;
+	int rc;
 
 	spin_lock_irqsave(&fotg210->lock, flags);
 	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
@@ -5603,16 +5394,14 @@ done:
 	return rc;
 }
 
-/*-------------------------------------------------------------------------*/
-
 /* bulk qh holds the data toggle */
 
-static void
-fotg210_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
+static void fotg210_endpoint_disable(struct usb_hcd *hcd,
+		struct usb_host_endpoint *ep)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	unsigned long		flags;
-	struct fotg210_qh		*qh, *tmp;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	unsigned long flags;
+	struct fotg210_qh *qh, *tmp;
 
 	/* ASSERT:  any requests/urbs are being unlinked */
 	/* ASSERT:  nobody can be submitting urbs for this any more */
@@ -5627,7 +5416,7 @@ rescan:
 	 * accelerate iso completions ... so spin a while.
 	 */
 	if (qh->hw == NULL) {
-		struct fotg210_iso_stream	*stream = ep->hcpriv;
+		struct fotg210_iso_stream *stream = ep->hcpriv;
 
 		if (!list_empty(&stream->td_list))
 			goto idle_timeout;
@@ -5671,24 +5460,24 @@ idle_timeout:
 		 * that's not our job.  just leak this memory.
 		 */
 		fotg210_err(fotg210, "qh %p (#%02x) state %d%s\n",
-			qh, ep->desc.bEndpointAddress, qh->qh_state,
-			list_empty(&qh->qtd_list) ? "" : "(has tds)");
+				qh, ep->desc.bEndpointAddress, qh->qh_state,
+				list_empty(&qh->qtd_list) ? "" : "(has tds)");
 		break;
 	}
- done:
+done:
 	ep->hcpriv = NULL;
 	spin_unlock_irqrestore(&fotg210->lock, flags);
 }
 
-static void
-fotg210_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
+static void fotg210_endpoint_reset(struct usb_hcd *hcd,
+		struct usb_host_endpoint *ep)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
-	struct fotg210_qh		*qh;
-	int			eptype = usb_endpoint_type(&ep->desc);
-	int			epnum = usb_endpoint_num(&ep->desc);
-	int			is_out = usb_endpoint_dir_out(&ep->desc);
-	unsigned long		flags;
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_qh *qh;
+	int eptype = usb_endpoint_type(&ep->desc);
+	int epnum = usb_endpoint_num(&ep->desc);
+	int is_out = usb_endpoint_dir_out(&ep->desc);
+	unsigned long flags;
 
 	if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
 		return;
@@ -5723,15 +5512,13 @@ fotg210_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
 
 static int fotg210_get_frame(struct usb_hcd *hcd)
 {
-	struct fotg210_hcd		*fotg210 = hcd_to_fotg210(hcd);
+	struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
+
 	return (fotg210_read_frame_index(fotg210) >> 3) %
 		fotg210->periodic_size;
 }
 
-/*-------------------------------------------------------------------------*/
-
-/*
- * The EHCI in ChipIdea HDRC cannot be a separate module or device,
+/* The EHCI in ChipIdea HDRC cannot be a separate module or device,
  * because its registers (and irq) are shared between host/gadget/otg
  * functions  and in order to facilitate role switching we cannot
  * give the fotg210 driver exclusive access to those.
@@ -5791,7 +5578,7 @@ static void fotg210_init(struct fotg210_hcd *fotg210)
 	u32 value;
 
 	iowrite32(GMIR_MDEV_INT | GMIR_MOTG_INT | GMIR_INT_POLARITY,
-		  &fotg210->regs->gmir);
+			&fotg210->regs->gmir);
 
 	value = ioread32(&fotg210->regs->otgcsr);
 	value &= ~OTGCSR_A_BUS_DROP;
@@ -5808,12 +5595,12 @@ static void fotg210_init(struct fotg210_hcd *fotg210)
  */
 static int fotg210_hcd_probe(struct platform_device *pdev)
 {
-	struct device			*dev = &pdev->dev;
-	struct usb_hcd			*hcd;
-	struct resource			*res;
-	int				irq;
-	int				retval = -ENODEV;
-	struct fotg210_hcd		*fotg210;
+	struct device *dev = &pdev->dev;
+	struct usb_hcd *hcd;
+	struct resource *res;
+	int irq;
+	int retval = -ENODEV;
+	struct fotg210_hcd *fotg210;
 
 	if (usb_disabled())
 		return -ENODEV;
@@ -5822,9 +5609,8 @@ static int fotg210_hcd_probe(struct platform_device *pdev)
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!res) {
-		dev_err(dev,
-			"Found HC with no IRQ. Check %s setup!\n",
-			dev_name(dev));
+		dev_err(dev, "Found HC with no IRQ. Check %s setup!\n",
+				dev_name(dev));
 		return -ENODEV;
 	}
 
@@ -5883,8 +5669,8 @@ fail_create_hcd:
  */
 static int fotg210_hcd_remove(struct platform_device *pdev)
 {
-	struct device *dev	= &pdev->dev;
-	struct usb_hcd *hcd	= dev_get_drvdata(dev);
+	struct device *dev = &pdev->dev;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
 
 	if (!hcd)
 		return 0;
@@ -5917,9 +5703,9 @@ static int __init fotg210_hcd_init(void)
 		pr_warn(KERN_WARNING "Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
 
 	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd\n",
-		 hcd_name,
-		 sizeof(struct fotg210_qh), sizeof(struct fotg210_qtd),
-		 sizeof(struct fotg210_itd));
+			hcd_name, sizeof(struct fotg210_qh),
+			sizeof(struct fotg210_qtd),
+			sizeof(struct fotg210_itd));
 
 	fotg210_debug_root = debugfs_create_dir("fotg210", usb_debug_root);
 	if (!fotg210_debug_root) {
diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/host/fotg210.h
index 3bad178..b5cfa7a 100644
--- a/drivers/usb/host/fotg210.h
+++ b/drivers/usb/host/fotg210.h
@@ -137,19 +137,25 @@ struct fotg210_hcd {			/* one per controller */
 	/* per root hub port */
 	unsigned long		reset_done[FOTG210_MAX_ROOT_PORTS];
 
-	/* bit vectors (one bit per port) */
-	unsigned long		bus_suspended;		/* which ports were
-			already suspended at the start of a bus suspend */
-	unsigned long		companion_ports;	/* which ports are
-			dedicated to the companion controller */
-	unsigned long		owned_ports;		/* which ports are
-			owned by the companion during a bus suspend */
-	unsigned long		port_c_suspend;		/* which ports have
-			the change-suspend feature turned on */
-	unsigned long		suspended_ports;	/* which ports are
-			suspended */
-	unsigned long		resuming_ports;		/* which ports have
-			started to resume */
+	/* bit vectors (one bit per port)
+	 * which ports were already suspended at the start of a bus suspend
+	 */
+	unsigned long		bus_suspended;
+
+	/* which ports are edicated to the companion controller */
+	unsigned long		companion_ports;
+
+	/* which ports are owned by the companion during a bus suspend */
+	unsigned long		owned_ports;
+
+	/* which ports have the change-suspend feature turned on */
+	unsigned long		port_c_suspend;
+
+	/* which ports are suspended */
+	unsigned long		suspended_ports;
+
+	/* which ports have started to resume */
+	unsigned long		resuming_ports;
 
 	/* per-HC memory pools (could be per-bus, but ...) */
 	struct dma_pool		*qh_pool;	/* qh per active urb */
@@ -585,10 +591,10 @@ struct fotg210_fstn {
 /* Prepare the PORTSC wakeup flags during controller suspend/resume */
 
 #define fotg210_prepare_ports_for_controller_suspend(fotg210, do_wakeup) \
-		fotg210_adjust_port_wakeup_flags(fotg210, true, do_wakeup);
+		fotg210_adjust_port_wakeup_flags(fotg210, true, do_wakeup)
 
 #define fotg210_prepare_ports_for_controller_resume(fotg210)		\
-		fotg210_adjust_port_wakeup_flags(fotg210, false, false);
+		fotg210_adjust_port_wakeup_flags(fotg210, false, false)
 
 /*-------------------------------------------------------------------------*/
 
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 2/9] usb/host/fotg210: remove KERN_WARNING from pr_warn
  2015-10-12 21:22                 ` [PATCH 0/9] usb/host/fotg210: code style and warning fixes Peter Senna Tschudin
  2015-10-12 21:22                   ` [PATCH 1/9] usb/host/fotg210: Fix coding style issues Peter Senna Tschudin
@ 2015-10-12 21:22                   ` Peter Senna Tschudin
  2015-10-12 21:22                   ` [PATCH 3/9] usb/host/fotg210: Remove useless else statement Peter Senna Tschudin
                                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-10-12 21:22 UTC (permalink / raw)
  To: gregkh, peter.senna, sergei.shtylyov, jkosina, rdunlap, balbi,
	standby24x7, chris, stern, john453, linux-usb, linux-kernel

This patch remove KERN_WARNING from a call to pr_warn().

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index d80b2e8..25885ef 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -5700,7 +5700,7 @@ static int __init fotg210_hcd_init(void)
 	set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
 	if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
 			test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
-		pr_warn(KERN_WARNING "Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
+		pr_warn("Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n");
 
 	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd\n",
 			hcd_name, sizeof(struct fotg210_qh),
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 3/9] usb/host/fotg210: Remove useless else statement
  2015-10-12 21:22                 ` [PATCH 0/9] usb/host/fotg210: code style and warning fixes Peter Senna Tschudin
  2015-10-12 21:22                   ` [PATCH 1/9] usb/host/fotg210: Fix coding style issues Peter Senna Tschudin
  2015-10-12 21:22                   ` [PATCH 2/9] usb/host/fotg210: remove KERN_WARNING from pr_warn Peter Senna Tschudin
@ 2015-10-12 21:22                   ` Peter Senna Tschudin
  2015-10-12 22:06                     ` Joe Perches
  2015-10-12 21:22                   ` [PATCH 4/9] usb/host/fotg210: Remove NULL checks dma_pool_destroy Peter Senna Tschudin
                                     ` (5 subsequent siblings)
  8 siblings, 1 reply; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-10-12 21:22 UTC (permalink / raw)
  To: gregkh, peter.senna, sergei.shtylyov, jkosina, rdunlap, balbi,
	standby24x7, chris, stern, john453, linux-usb, linux-kernel

This patch remove an else statement after a return to make the code
easier to understand.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 25885ef..7f6aa99 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -1402,10 +1402,9 @@ static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
 				"Failed to enable port %d on root hub TT\n",
 				index + 1);
 		return port_status;
-	} else {
-		fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
-				index + 1);
 	}
+	fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
+			index + 1);
 
 	return port_status;
 }
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 4/9] usb/host/fotg210: Remove NULL checks dma_pool_destroy
  2015-10-12 21:22                 ` [PATCH 0/9] usb/host/fotg210: code style and warning fixes Peter Senna Tschudin
                                     ` (2 preceding siblings ...)
  2015-10-12 21:22                   ` [PATCH 3/9] usb/host/fotg210: Remove useless else statement Peter Senna Tschudin
@ 2015-10-12 21:22                   ` Peter Senna Tschudin
  2015-10-12 21:22                   ` [PATCH 5/9] usb/host/fotg210: change kmalloc by kmalloc_array Peter Senna Tschudin
                                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-10-12 21:22 UTC (permalink / raw)
  To: gregkh, peter.senna, sergei.shtylyov, jkosina, rdunlap, balbi,
	standby24x7, chris, stern, john453, linux-usb, linux-kernel

This patch remove NULL checks before calls to dma_pool_destroy() as the
function now can handle NULL pointers.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 7f6aa99..54c2b05 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -1915,17 +1915,13 @@ static void fotg210_mem_cleanup(struct fotg210_hcd *fotg210)
 	fotg210->dummy = NULL;
 
 	/* DMA consistent memory and pools */
-	if (fotg210->qtd_pool)
-		dma_pool_destroy(fotg210->qtd_pool);
+	dma_pool_destroy(fotg210->qtd_pool);
 	fotg210->qtd_pool = NULL;
 
-	if (fotg210->qh_pool) {
-		dma_pool_destroy(fotg210->qh_pool);
-		fotg210->qh_pool = NULL;
-	}
+	dma_pool_destroy(fotg210->qh_pool);
+	fotg210->qh_pool = NULL;
 
-	if (fotg210->itd_pool)
-		dma_pool_destroy(fotg210->itd_pool);
+	dma_pool_destroy(fotg210->itd_pool);
 	fotg210->itd_pool = NULL;
 
 	if (fotg210->periodic)
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 5/9] usb/host/fotg210: change kmalloc by kmalloc_array
  2015-10-12 21:22                 ` [PATCH 0/9] usb/host/fotg210: code style and warning fixes Peter Senna Tschudin
                                     ` (3 preceding siblings ...)
  2015-10-12 21:22                   ` [PATCH 4/9] usb/host/fotg210: Remove NULL checks dma_pool_destroy Peter Senna Tschudin
@ 2015-10-12 21:22                   ` Peter Senna Tschudin
  2015-10-12 21:22                   ` [PATCH 6/9] usb/host/fotg210: replace msleep by usleep_range Peter Senna Tschudin
                                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-10-12 21:22 UTC (permalink / raw)
  To: gregkh, peter.senna, sergei.shtylyov, jkosina, rdunlap, balbi,
	standby24x7, chris, stern, john453, linux-usb, linux-kernel

This patch replaces:

kmalloc(DBG_SCHED_LIMIT * sizeof(*seen), GFP_ATOMIC)

by:

kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC)

as kmalloc_array() should be used for allocating arrays.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 54c2b05..ae3806d 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -500,7 +500,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 	unsigned i;
 	__hc32 tag;
 
-	seen = kmalloc(DBG_SCHED_LIMIT * sizeof(*seen), GFP_ATOMIC);
+	seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC);
 	if (!seen)
 		return 0;
 
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 6/9] usb/host/fotg210: replace msleep by usleep_range
  2015-10-12 21:22                 ` [PATCH 0/9] usb/host/fotg210: code style and warning fixes Peter Senna Tschudin
                                     ` (4 preceding siblings ...)
  2015-10-12 21:22                   ` [PATCH 5/9] usb/host/fotg210: change kmalloc by kmalloc_array Peter Senna Tschudin
@ 2015-10-12 21:22                   ` Peter Senna Tschudin
  2015-10-12 21:22                   ` [PATCH 7/9] usb/host/fotg210: convert macro to inline function Peter Senna Tschudin
                                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-10-12 21:22 UTC (permalink / raw)
  To: gregkh, peter.senna, sergei.shtylyov, jkosina, rdunlap, balbi,
	standby24x7, chris, stern, john453, linux-usb, linux-kernel

msleep under 20ms can result in sleeping up to 20ms, which may not be
intended. Replace msleep(5) by usleep_range(5000, 10000). The range of 5
ms is to reduce the chances of creating an interrupt while reducing the
maximum wait time in 50%.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index ae3806d..5413358 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -5085,7 +5085,7 @@ static int fotg210_run(struct usb_hcd *hcd)
 	fotg210->rh_state = FOTG210_RH_RUNNING;
 	/* unblock posted writes */
 	fotg210_readl(fotg210, &fotg210->regs->command);
-	msleep(5);
+	usleep_range(5000, 10000);
 	up_write(&ehci_cf_port_reset_rwsem);
 	fotg210->last_periodic_enable = ktime_get_real();
 
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 7/9] usb/host/fotg210: convert macro to inline function
  2015-10-12 21:22                 ` [PATCH 0/9] usb/host/fotg210: code style and warning fixes Peter Senna Tschudin
                                     ` (5 preceding siblings ...)
  2015-10-12 21:22                   ` [PATCH 6/9] usb/host/fotg210: replace msleep by usleep_range Peter Senna Tschudin
@ 2015-10-12 21:22                   ` Peter Senna Tschudin
  2015-10-12 21:22                   ` [PATCH 8/9] usb/host/fotg210: Add function: output_buf_tds_dir() Peter Senna Tschudin
  2015-10-12 21:22                   ` [PATCH 9/9] usb/host/fotg210: Add function scan_frame_queue() Peter Senna Tschudin
  8 siblings, 0 replies; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-10-12 21:22 UTC (permalink / raw)
  To: gregkh, peter.senna, sergei.shtylyov, jkosina, rdunlap, balbi,
	standby24x7, chris, stern, john453, linux-usb, linux-kernel

This patch convert the macro speed_char in an inline function. The goal
of this patch is to make the code easier to read.

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 5413358..c9ab27f 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -330,17 +330,22 @@ struct debug_buffer {
 	size_t alloc_size;
 };
 
-#define speed_char(info1)({ char tmp; \
-		switch (info1 & (3 << 12)) { \
-		case QH_FULL_SPEED:	\
-			tmp = 'f'; break; \
-		case QH_LOW_SPEED:	\
-			tmp = 'l'; break; \
-		case QH_HIGH_SPEED:	\
-			tmp = 'h'; break; \
-		default:		\
-			tmp = '?'; break; \
-		} tmp; })
+static inline char speed_char(u32 scratch)
+{
+	switch (scratch & (3 << 12)) {
+	case QH_FULL_SPEED:
+		return 'f';
+
+	case QH_LOW_SPEED:
+		return 'l';
+
+	case QH_HIGH_SPEED:
+		return 'h';
+
+	default:
+		return '?';
+	}
+}
 
 static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
 {
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 8/9] usb/host/fotg210: Add function: output_buf_tds_dir()
  2015-10-12 21:22                 ` [PATCH 0/9] usb/host/fotg210: code style and warning fixes Peter Senna Tschudin
                                     ` (6 preceding siblings ...)
  2015-10-12 21:22                   ` [PATCH 7/9] usb/host/fotg210: convert macro to inline function Peter Senna Tschudin
@ 2015-10-12 21:22                   ` Peter Senna Tschudin
  2015-10-12 21:22                   ` [PATCH 9/9] usb/host/fotg210: Add function scan_frame_queue() Peter Senna Tschudin
  8 siblings, 0 replies; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-10-12 21:22 UTC (permalink / raw)
  To: gregkh, peter.senna, sergei.shtylyov, jkosina, rdunlap, balbi,
	standby24x7, chris, stern, john453, linux-usb, linux-kernel

checkpatch complains about too many leading tabs because the switch
statement starts after 6 tabs.

fill_periodic_buffer() -> for() -> do -> switch() -> if() ->
list_for_each_entry() and finally the last switch().

This patch moves the list_for_each_entry() and the last switch() to a
new function named output_buf_tds_dir(). This change makes the code
easier to read and calm down checkpatch. This patch changes it to:

fill_periodic_buffer() -> for() -> do -> switch() -> if() ->
output_buf_tds_dir()

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 62 +++++++++++++++++++++---------------------
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index c9ab27f..fb9743e 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -493,6 +493,34 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
 	return strlen(buf->output_buf);
 }
 
+/* count tds, get ep direction */
+static unsigned output_buf_tds_dir(char *buf, struct fotg210_hcd *fotg210,
+		struct fotg210_qh_hw *hw, struct fotg210_qh *qh, unsigned size)
+{
+	u32 scratch = hc32_to_cpup(fotg210, &hw->hw_info1);
+	struct fotg210_qtd *qtd;
+	char *type = "";
+	unsigned temp = 0;
+
+	/* count tds, get ep direction */
+	list_for_each_entry(qtd, &qh->qtd_list, qtd_list) {
+		temp++;
+		switch ((hc32_to_cpu(fotg210, qtd->hw_token) >> 8) & 0x03) {
+		case 0:
+			type = "out";
+			continue;
+		case 1:
+			type = "in";
+			continue;
+		}
+	}
+
+	return scnprintf(buf, size, "(%c%d ep%d%s [%d/%d] q%d p%d)",
+			speed_char(scratch), scratch & 0x007f,
+			(scratch >> 8) & 0x000f, type, qh->usecs,
+			qh->c_usecs, temp, (scratch >> 16) & 0x7ff);
+}
+
 #define DBG_SCHED_LIMIT 64
 static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 {
@@ -564,37 +592,9 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 				}
 				/* show more info the first time around */
 				if (temp == seen_count) {
-					u32 scratch = hc32_to_cpup(fotg210,
-							&hw->hw_info1);
-					struct fotg210_qtd *qtd;
-					char *type = "";
-
-					/* count tds, get ep direction */
-					temp = 0;
-					list_for_each_entry(qtd,
-							&p.qh->qtd_list,
-							qtd_list) {
-						temp++;
-						switch (0x03 & (hc32_to_cpu(
-							fotg210,
-							qtd->hw_token) >> 8)) {
-						case 0:
-							type = "out";
-							continue;
-						case 1:
-							type = "in";
-							continue;
-						}
-					}
-
-					temp = scnprintf(next, size,
-						"(%c%d ep%d%s [%d/%d] q%d p%d)",
-						speed_char(scratch),
-						scratch & 0x007f,
-						(scratch >> 8) & 0x000f, type,
-						p.qh->usecs, p.qh->c_usecs,
-						temp,
-						0x7ff & (scratch >> 16));
+					temp = output_buf_tds_dir(next,
+							fotg210, hw,
+							p.qh, size);
 
 					if (seen_count < DBG_SCHED_LIMIT)
 						seen[seen_count++].qh = p.qh;
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* [PATCH 9/9] usb/host/fotg210: Add function scan_frame_queue()
  2015-10-12 21:22                 ` [PATCH 0/9] usb/host/fotg210: code style and warning fixes Peter Senna Tschudin
                                     ` (7 preceding siblings ...)
  2015-10-12 21:22                   ` [PATCH 8/9] usb/host/fotg210: Add function: output_buf_tds_dir() Peter Senna Tschudin
@ 2015-10-12 21:22                   ` Peter Senna Tschudin
  8 siblings, 0 replies; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-10-12 21:22 UTC (permalink / raw)
  To: gregkh, peter.senna, sergei.shtylyov, jkosina, rdunlap, balbi,
	standby24x7, chris, stern, john453, linux-usb, linux-kernel

checkpatch complains about too many leading tabs because the if
statement starts after 6 tabs:

scan_iosoc() -> for() -> while() -> switch() -> if() -> for() -> if()

There is also a goto statement going backwards in case of failure. This
patch creates a new inline function named scan_frame_queue() containing
the last 4 nesting levels, and removes the need of backwards goto,
making the code easier to read. After the patch it becomes:

scan_iosoc() -> for() -> while() -> scan_frame_queue()

Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
 drivers/usb/host/fotg210-hcd.c | 143 ++++++++++++++++++++++-------------------
 1 file changed, 76 insertions(+), 67 deletions(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index fb9743e..88d11a9 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -4609,13 +4609,81 @@ done:
 	return status;
 }
 
-/*-------------------------------------------------------------------------*/
+static inline int scan_frame_queue(struct fotg210_hcd *fotg210, unsigned frame,
+		unsigned now_frame, bool live)
+{
+	unsigned uf;
+	bool modified;
+	union fotg210_shadow q, *q_p;
+	__hc32 type, *hw_p;
+
+	/* scan each element in frame's queue for completions */
+	q_p = &fotg210->pshadow[frame];
+	hw_p = &fotg210->periodic[frame];
+	q.ptr = q_p->ptr;
+	type = Q_NEXT_TYPE(fotg210, *hw_p);
+	modified = false;
+
+	while (q.ptr) {
+		switch (hc32_to_cpu(fotg210, type)) {
+		case Q_TYPE_ITD:
+			/* If this ITD is still active, leave it for
+			 * later processing ... check the next entry.
+			 * No need to check for activity unless the
+			 * frame is current.
+			 */
+			if (frame == now_frame && live) {
+				rmb();
+				for (uf = 0; uf < 8; uf++) {
+					if (q.itd->hw_transaction[uf] &
+							ITD_ACTIVE(fotg210))
+						break;
+				}
+				if (uf < 8) {
+					q_p = &q.itd->itd_next;
+					hw_p = &q.itd->hw_next;
+					type = Q_NEXT_TYPE(fotg210,
+							q.itd->hw_next);
+					q = *q_p;
+					break;
+				}
+			}
+
+			/* Take finished ITDs out of the schedule
+			 * and process them:  recycle, maybe report
+			 * URB completion.  HC won't cache the
+			 * pointer for much longer, if at all.
+			 */
+			*q_p = q.itd->itd_next;
+			*hw_p = q.itd->hw_next;
+			type = Q_NEXT_TYPE(fotg210, q.itd->hw_next);
+			wmb();
+			modified = itd_complete(fotg210, q.itd);
+			q = *q_p;
+			break;
+		default:
+			fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
+					type, frame, q.ptr);
+			/* FALL THROUGH */
+		case Q_TYPE_QH:
+		case Q_TYPE_FSTN:
+			/* End of the iTDs and siTDs */
+			q.ptr = NULL;
+			break;
+		}
+
+		/* assume completion callbacks modify the queue */
+		if (unlikely(modified && fotg210->isoc_count > 0))
+			return -EINVAL;
+	}
+	return 0;
+}
 
 static void scan_isoc(struct fotg210_hcd *fotg210)
 {
-	unsigned	uf, now_frame, frame;
-	unsigned	fmask = fotg210->periodic_size - 1;
-	bool		modified, live;
+	unsigned uf, now_frame, frame, ret;
+	unsigned fmask = fotg210->periodic_size - 1;
+	bool live;
 
 	/*
 	 * When running, scan from last scan point up to "now"
@@ -4634,69 +4702,10 @@ static void scan_isoc(struct fotg210_hcd *fotg210)
 
 	frame = fotg210->next_frame;
 	for (;;) {
-		union fotg210_shadow	q, *q_p;
-		__hc32			type, *hw_p;
-
-restart:
-		/* scan each element in frame's queue for completions */
-		q_p = &fotg210->pshadow[frame];
-		hw_p = &fotg210->periodic[frame];
-		q.ptr = q_p->ptr;
-		type = Q_NEXT_TYPE(fotg210, *hw_p);
-		modified = false;
-
-		while (q.ptr != NULL) {
-			switch (hc32_to_cpu(fotg210, type)) {
-			case Q_TYPE_ITD:
-				/* If this ITD is still active, leave it for
-				 * later processing ... check the next entry.
-				 * No need to check for activity unless the
-				 * frame is current.
-				 */
-				if (frame == now_frame && live) {
-					rmb();
-					for (uf = 0; uf < 8; uf++) {
-						if (q.itd->hw_transaction[uf] &
-							    ITD_ACTIVE(fotg210))
-							break;
-					}
-					if (uf < 8) {
-						q_p = &q.itd->itd_next;
-						hw_p = &q.itd->hw_next;
-						type = Q_NEXT_TYPE(fotg210,
-							q.itd->hw_next);
-						q = *q_p;
-						break;
-					}
-				}
-
-				/* Take finished ITDs out of the schedule
-				 * and process them:  recycle, maybe report
-				 * URB completion.  HC won't cache the
-				 * pointer for much longer, if at all.
-				 */
-				*q_p = q.itd->itd_next;
-				*hw_p = q.itd->hw_next;
-				type = Q_NEXT_TYPE(fotg210, q.itd->hw_next);
-				wmb();
-				modified = itd_complete(fotg210, q.itd);
-				q = *q_p;
-				break;
-			default:
-				fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
-						type, frame, q.ptr);
-				/* FALL THROUGH */
-			case Q_TYPE_QH:
-			case Q_TYPE_FSTN:
-				/* End of the iTDs and siTDs */
-				q.ptr = NULL;
-				break;
-			}
-
-			/* assume completion callbacks modify the queue */
-			if (unlikely(modified && fotg210->isoc_count > 0))
-				goto restart;
-		}
+		ret = 1;
+		while (ret != 0)
+			ret = scan_frame_queue(fotg210, frame,
+					now_frame, live);
 
 		/* Stop when we have reached the current frame */
 		if (frame == now_frame)
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

* Re: [PATCH 3/9] usb/host/fotg210: Remove useless else statement
  2015-10-12 21:22                   ` [PATCH 3/9] usb/host/fotg210: Remove useless else statement Peter Senna Tschudin
@ 2015-10-12 22:06                     ` Joe Perches
  2015-10-17 19:28                       ` [PATCH 3/9 V2] usb/host/fotg210: Remove return statement inside if Peter Senna Tschudin
  0 siblings, 1 reply; 61+ messages in thread
From: Joe Perches @ 2015-10-12 22:06 UTC (permalink / raw)
  To: Peter Senna Tschudin
  Cc: gregkh, sergei.shtylyov, jkosina, rdunlap, balbi, standby24x7,
	chris, stern, john453, linux-usb, linux-kernel

On Mon, 2015-10-12 at 23:22 +0200, Peter Senna Tschudin wrote:
> This patch remove an else statement after a return to make the code
> easier to understand.
[]
> diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
[]
> @@ -1402,10 +1402,9 @@ static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
>  				"Failed to enable port %d on root hub TT\n",
>  				index + 1);
>  		return port_status;
> -	} else {
> -		fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
> -				index + 1);
>  	}
> +	fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
> +			index + 1);
>  
>  	return port_status;
>  }

Probably better written as:

	/* if reset finished and it's still not enabled -- handoff */
	if (!(port_status & PORT_PE))
		/* with integrated TT, there's nobody to hand it to! */
		fotg210_dbg(fotg210, "failed to enable port %d on root hub TT\n",
			    index + 1);
	else
		fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
			    index + 1);

	return port_status;



^ permalink raw reply	[flat|nested] 61+ messages in thread

* [PATCH 3/9 V2] usb/host/fotg210: Remove return statement inside if
  2015-10-12 22:06                     ` Joe Perches
@ 2015-10-17 19:28                       ` Peter Senna Tschudin
  0 siblings, 0 replies; 61+ messages in thread
From: Peter Senna Tschudin @ 2015-10-17 19:28 UTC (permalink / raw)
  To: gregkh, sergei.shtylyov, jkosina, rdunlap, balbi, standby24x7,
	chris, stern, john453, linux-usb, linux-kernel, joe
  Cc: Peter Senna Tschudin

This patch make changes to an if else statement which simplifies the code
allowing to remove a return.

CC: Joe Perches <joe@perches.com>
Signed-off-by: Peter Senna Tschudin <peter.senna@gmail.com>
---
Subject was: [PATCH 3/9] usb/host/fotg210: Remove useless else statement

To be applied on top of V1.

Changes from V1:
   Instead of just removing the else statement, remove the return inside
   the if statement so the code is even more readable.

 drivers/usb/host/fotg210-hcd.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 7f6aa99..064cd85 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -1396,15 +1396,13 @@ static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
 		return port_status;
 
 	/* if reset finished and it's still not enabled -- handoff */
-	if (!(port_status & PORT_PE)) {
+	if (!(port_status & PORT_PE))
 		/* with integrated TT, there's nobody to hand it to! */
-		fotg210_dbg(fotg210,
-				"Failed to enable port %d on root hub TT\n",
+		fotg210_dbg(fotg210, "Failed to enable port %d on root hub TT\n",
+				index + 1);
+	else
+		fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
 				index + 1);
-		return port_status;
-	}
-	fotg210_dbg(fotg210, "port %d reset complete, port enabled\n",
-			index + 1);
 
 	return port_status;
 }
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 61+ messages in thread

end of thread, other threads:[~2015-10-17 19:30 UTC | newest]

Thread overview: 61+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-07 14:47 similar files: fusbh200-hcd.c and fotg210-hcd.c Peter Senna Tschudin
2015-09-08 15:52 ` Felipe Balbi
2015-09-12 13:14   ` Peter Senna Tschudin
2015-09-14 15:01     ` Felipe Balbi
2015-09-14 17:50       ` Peter Senna Tschudin
2015-09-15 14:33         ` Felipe Balbi
2015-09-15 16:41           ` Peter Senna Tschudin
2015-09-15 16:50             ` Felipe Balbi
2015-09-21 15:01               ` [PATCH 00/14] RFC: Consolidation: FUSB200 and FOTG210 Peter Senna Tschudin
2015-09-21 15:01                 ` [PATCH 01/14] RFC: usb/host/fotg210: Fix coding style issues Peter Senna Tschudin
2015-10-02 17:29                   ` Felipe Balbi
2015-09-21 15:01                 ` [PATCH 02/14] RFC: usb/host/fotg210: remove KERN_WARNING from pr_info Peter Senna Tschudin
2015-09-21 18:54                   ` Sergei Shtylyov
2015-10-02 17:30                   ` Felipe Balbi
2015-09-21 15:01                 ` [PATCH 03/14] RFC: usb/host/fotg210: Remove useless else statement Peter Senna Tschudin
2015-10-02 17:30                   ` Felipe Balbi
2015-09-21 15:01                 ` [PATCH 04/14] RFC: usb/host/fotg210: Remove NULL checks dma_pool_destroy Peter Senna Tschudin
2015-10-02 17:30                   ` Felipe Balbi
2015-09-21 15:01                 ` [PATCH 05/14] RFC: usb/host/fotg210: change kmalloc by kmalloc_array Peter Senna Tschudin
2015-09-21 18:56                   ` Sergei Shtylyov
2015-10-02 17:30                   ` Felipe Balbi
2015-09-21 15:01                 ` [PATCH 06/14] RFC: usb/host/fotg210: replace msleep by usleep_range Peter Senna Tschudin
2015-10-02 17:31                   ` Felipe Balbi
2015-10-02 17:52                     ` Alan Stern
2015-10-04  9:58                       ` Peter Senna Tschudin
2015-10-04 15:20                         ` Alan Stern
2015-09-21 15:01                 ` [PATCH 07/14] RFC: usb/host/fotg210: Remove a macro from snprintf Peter Senna Tschudin
2015-10-02 17:31                   ` Felipe Balbi
2015-09-21 15:01                 ` [PATCH 08/14] RFC: usb/host/fotg210: convert macro to inline function Peter Senna Tschudin
2015-10-02 17:32                   ` Felipe Balbi
2015-09-21 15:01                 ` [PATCH 09/14] RFC: usb/host/fotg210: Add function: output_buf_tds_dir() Peter Senna Tschudin
2015-09-21 19:15                   ` Sergei Shtylyov
2015-10-02 17:32                   ` Felipe Balbi
2015-09-21 15:01                 ` [PATCH 10/14] RFC: usb/host/fotg210: Add function scan_frame_queue() Peter Senna Tschudin
2015-10-02 17:35                   ` Felipe Balbi
2015-09-21 15:01                 ` [PATCH 11/14] RFC: usb/host: Rename fotg210-hcd to faraday-hcd Peter Senna Tschudin
2015-10-02 17:35                   ` Felipe Balbi
2015-09-21 15:01                 ` [PATCH 12/14] RFC: usb/host/faraday-hcd: Replace fotg210 by fhcd2xx Peter Senna Tschudin
2015-10-02 17:36                   ` Felipe Balbi
2015-09-21 15:01                 ` [PATCH 13/14] RFC: usb/host/faraday-hcd: Move #defines outside struct Peter Senna Tschudin
2015-10-02 17:37                   ` Felipe Balbi
2015-09-21 15:01                 ` [PATCH 14/14] RFC: usb/host/faraday-hcd: Import FUSBH200 parameters Peter Senna Tschudin
2015-10-02 17:38                   ` Felipe Balbi
2015-10-02 11:18                 ` [PATCH] usb-host: Remove fusbh200 driver Peter Senna Tschudin
2015-10-02 17:39                   ` Felipe Balbi
2015-10-03  9:56                     ` Peter Senna Tschudin
2015-10-03 21:21                       ` Felipe Balbi
2015-10-05  0:25                         ` John Feng-Hsin Chiang(江峰興)
2015-10-12 21:22                 ` [PATCH 0/9] usb/host/fotg210: code style and warning fixes Peter Senna Tschudin
2015-10-12 21:22                   ` [PATCH 1/9] usb/host/fotg210: Fix coding style issues Peter Senna Tschudin
2015-10-12 21:22                   ` [PATCH 2/9] usb/host/fotg210: remove KERN_WARNING from pr_warn Peter Senna Tschudin
2015-10-12 21:22                   ` [PATCH 3/9] usb/host/fotg210: Remove useless else statement Peter Senna Tschudin
2015-10-12 22:06                     ` Joe Perches
2015-10-17 19:28                       ` [PATCH 3/9 V2] usb/host/fotg210: Remove return statement inside if Peter Senna Tschudin
2015-10-12 21:22                   ` [PATCH 4/9] usb/host/fotg210: Remove NULL checks dma_pool_destroy Peter Senna Tschudin
2015-10-12 21:22                   ` [PATCH 5/9] usb/host/fotg210: change kmalloc by kmalloc_array Peter Senna Tschudin
2015-10-12 21:22                   ` [PATCH 6/9] usb/host/fotg210: replace msleep by usleep_range Peter Senna Tschudin
2015-10-12 21:22                   ` [PATCH 7/9] usb/host/fotg210: convert macro to inline function Peter Senna Tschudin
2015-10-12 21:22                   ` [PATCH 8/9] usb/host/fotg210: Add function: output_buf_tds_dir() Peter Senna Tschudin
2015-10-12 21:22                   ` [PATCH 9/9] usb/host/fotg210: Add function scan_frame_queue() Peter Senna Tschudin
2015-09-25 13:04               ` similar files: fusbh200-hcd.c and fotg210-hcd.c Peter Senna Tschudin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).