aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/ohci-dbg.c9
-rw-r--r--drivers/usb/host/ohci-hcd.c10
-rw-r--r--drivers/usb/host/ohci-hub.c22
-rw-r--r--drivers/usb/host/ohci-pxa27x.c3
-rw-r--r--drivers/usb/host/ohci.h1
5 files changed, 25 insertions, 20 deletions
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index 447f488f5d9..7924c74f958 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -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,
@@ -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);
}
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 6efb69f7c07..67c1aa5eb1c 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -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;
@@ -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]);
}
@@ -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]);
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 83ca4549a50..ce7b28da7a1 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -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,
@@ -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;
@@ -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;
@@ -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
@@ -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;
@@ -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
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index e5bc1789d18..5dd20dbe852 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -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;
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index 71cdd226286..8a9b9d9209e 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -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 */