Skip to content

Commit

Permalink
[PATCH] USB: OHCI relies less on NDP register
Browse files Browse the repository at this point in the history
Some OHCI implementations have differences in the way the NDP register
(in roothub_a) reports the number of ports present. This patch allows the
platform specific code to optionally supply the number of ports. The
driver just reads the value at init (if not supplied) instead of reading
it every time its needed (except for an AMD756 bug workaround).

It also sets the value correctly for the ARM pxa27x architecture.

Signed-Off-By: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
David Brownell authored and Greg Kroah-Hartman committed Sep 12, 2005
1 parent e0fd3cb commit fdd13b3
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 20 deletions.
9 changes: 4 additions & 5 deletions drivers/usb/host/ohci-dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,23 +228,22 @@ ohci_dump_roothub (
char **next,
unsigned *size)
{
u32 temp, ndp, i;
u32 temp, i;

temp = roothub_a (controller);
if (temp == ~(u32)0)
return;
ndp = (temp & RH_A_NDP);

if (verbose) {
ohci_dbg_sw (controller, next, size,
"roothub.a %08x POTPGT=%d%s%s%s%s%s NDP=%d\n", temp,
"roothub.a %08x POTPGT=%d%s%s%s%s%s NDP=%d(%d)\n", temp,
((temp & RH_A_POTPGT) >> 24) & 0xff,
(temp & RH_A_NOCP) ? " NOCP" : "",
(temp & RH_A_OCPM) ? " OCPM" : "",
(temp & RH_A_DT) ? " DT" : "",
(temp & RH_A_NPS) ? " NPS" : "",
(temp & RH_A_PSM) ? " PSM" : "",
ndp
(temp & RH_A_NDP), controller->num_ports
);
temp = roothub_b (controller);
ohci_dbg_sw (controller, next, size,
Expand All @@ -266,7 +265,7 @@ ohci_dump_roothub (
);
}

for (i = 0; i < ndp; i++) {
for (i = 0; i < controller->num_ports; i++) {
temp = roothub_portstatus (controller, i);
dbg_port_sw (controller, i, temp, next, size);
}
Expand Down
10 changes: 6 additions & 4 deletions drivers/usb/host/ohci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,10 @@ static int ohci_init (struct ohci_hcd *ohci)
// flush the writes
(void) ohci_readl (ohci, &ohci->regs->control);

/* Read the number of ports unless overridden */
if (ohci->num_ports == 0)
ohci->num_ports = roothub_a(ohci) & RH_A_NDP;

if (ohci->hcca)
return 0;

Expand Down Expand Up @@ -560,10 +564,8 @@ static int ohci_run (struct ohci_hcd *ohci)
msleep(temp);
temp = roothub_a (ohci);
if (!(temp & RH_A_NPS)) {
unsigned ports = temp & RH_A_NDP;

/* power down each port */
for (temp = 0; temp < ports; temp++)
for (temp = 0; temp < ohci->num_ports; temp++)
ohci_writel (ohci, RH_PS_LSDA,
&ohci->regs->roothub.portstatus [temp]);
}
Expand Down Expand Up @@ -861,7 +863,7 @@ static int ohci_restart (struct ohci_hcd *ohci)
* and that if we try to turn them back on the root hub
* will respond to CSC processing.
*/
i = roothub_a (ohci) & RH_A_NDP;
i = ohci->num_ports;
while (i--)
ohci_writel (ohci, RH_PS_PSS,
&ohci->regs->roothub.portstatus [temp]);
Expand Down
22 changes: 11 additions & 11 deletions drivers/usb/host/ohci-hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd)
if (status != -EINPROGRESS)
return status;

temp = roothub_a (ohci) & RH_A_NDP;
temp = ohci->num_ports;
enables = 0;
while (temp--) {
u32 stat = ohci_readl (ohci,
Expand Down Expand Up @@ -304,7 +304,7 @@ static int
ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int ports, i, changed = 0, length = 1;
int i, changed = 0, length = 1;
int can_suspend = hcd->can_wakeup;
unsigned long flags;

Expand All @@ -319,9 +319,10 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
goto done;
}

ports = roothub_a (ohci) & RH_A_NDP;
if (ports > MAX_ROOT_PORTS) {
ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n", ports,
/* undocumented erratum seen on at least rev D */
if ((ohci->flags & OHCI_QUIRK_AMD756)
&& (roothub_a (ohci) & RH_A_NDP) > MAX_ROOT_PORTS) {
ohci_warn (ohci, "bogus NDP, rereads as NDP=%d\n",
ohci_readl (ohci, &ohci->regs->roothub.a) & RH_A_NDP);
/* retry later; "should not happen" */
goto done;
Expand All @@ -332,13 +333,13 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
buf [0] = changed = 1;
else
buf [0] = 0;
if (ports > 7) {
if (ohci->num_ports > 7) {
buf [1] = 0;
length++;
}

/* look at each port */
for (i = 0; i < ports; i++) {
for (i = 0; i < ohci->num_ports; i++) {
u32 status = roothub_portstatus (ohci, i);

if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
Expand Down Expand Up @@ -395,15 +396,14 @@ ohci_hub_descriptor (
struct usb_hub_descriptor *desc
) {
u32 rh = roothub_a (ohci);
int ports = rh & RH_A_NDP;
u16 temp;

desc->bDescriptorType = 0x29;
desc->bPwrOn2PwrGood = (rh & RH_A_POTPGT) >> 24;
desc->bHubContrCurrent = 0;

desc->bNbrPorts = ports;
temp = 1 + (ports / 8);
desc->bNbrPorts = ohci->num_ports;
temp = 1 + (ohci->num_ports / 8);
desc->bDescLength = 7 + 2 * temp;

temp = 0;
Expand All @@ -421,7 +421,7 @@ ohci_hub_descriptor (
rh = roothub_b (ohci);
memset(desc->bitmap, 0xff, sizeof(desc->bitmap));
desc->bitmap [0] = rh & RH_B_DR;
if (ports > 7) {
if (ohci->num_ports > 7) {
desc->bitmap [1] = (rh & RH_B_DR) >> 8;
desc->bitmap [2] = 0xff;
} else
Expand Down
3 changes: 3 additions & 0 deletions drivers/usb/host/ohci-pxa27x.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ ohci_pxa27x_start (struct usb_hcd *hcd)

ohci_dbg (ohci, "ohci_pxa27x_start, ohci:%p", ohci);

/* The value of NDP in roothub_a is incorrect on this hardware */
ohci->num_ports = 3;

if ((ret = ohci_init(ohci)) < 0)
return ret;

Expand Down
1 change: 1 addition & 0 deletions drivers/usb/host/ohci.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ struct ohci_hcd {
/*
* driver state
*/
int num_ports;
int load [NUM_INTS];
u32 hc_control; /* copy of hc control reg */
unsigned long next_statechange; /* suspend/resume */
Expand Down

0 comments on commit fdd13b3

Please sign in to comment.