OHCI: remove existing autosuspend code
The autosuspend technique used by ohci-hcd doesn't mesh well with the newer USB core autosuspend code. This patch (as789) removes ohci-hcd's autosuspend support. Now the driver will be usable, but it won't automatically go into a low-power state when no devices are connected. That's for a later patch. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
d19ac7da72
commit
1f7e1a3b7e
1 changed files with 6 additions and 44 deletions
|
@ -41,6 +41,7 @@ static void ohci_rhsc_enable (struct usb_hcd *hcd)
|
||||||
{
|
{
|
||||||
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
|
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
|
||||||
|
|
||||||
|
hcd->poll_rh = 0;
|
||||||
ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
|
ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,8 +118,10 @@ static int ohci_bus_suspend (struct usb_hcd *hcd)
|
||||||
/* maybe resume can wake root hub */
|
/* maybe resume can wake root hub */
|
||||||
if (device_may_wakeup(&ohci_to_hcd(ohci)->self.root_hub->dev))
|
if (device_may_wakeup(&ohci_to_hcd(ohci)->self.root_hub->dev))
|
||||||
ohci->hc_control |= OHCI_CTRL_RWE;
|
ohci->hc_control |= OHCI_CTRL_RWE;
|
||||||
else
|
else {
|
||||||
|
ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrdisable);
|
||||||
ohci->hc_control &= ~OHCI_CTRL_RWE;
|
ohci->hc_control &= ~OHCI_CTRL_RWE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Suspend hub ... this is the "global (to this bus) suspend" mode,
|
/* Suspend hub ... this is the "global (to this bus) suspend" mode,
|
||||||
* which doesn't imply ports will first be individually suspended.
|
* which doesn't imply ports will first be individually suspended.
|
||||||
|
@ -310,20 +313,16 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
|
||||||
{
|
{
|
||||||
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
|
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
|
||||||
int i, changed = 0, length = 1;
|
int i, changed = 0, length = 1;
|
||||||
int can_suspend;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
can_suspend = device_may_wakeup(&hcd->self.root_hub->dev);
|
|
||||||
spin_lock_irqsave (&ohci->lock, flags);
|
spin_lock_irqsave (&ohci->lock, flags);
|
||||||
|
|
||||||
/* handle autosuspended root: finish resuming before
|
/* handle autosuspended root: finish resuming before
|
||||||
* letting khubd or root hub timer see state changes.
|
* letting khubd or root hub timer see state changes.
|
||||||
*/
|
*/
|
||||||
if (unlikely((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER
|
if (unlikely((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER
|
||||||
|| !HC_IS_RUNNING(hcd->state))) {
|
|| !HC_IS_RUNNING(hcd->state)))
|
||||||
can_suspend = 0;
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
|
||||||
|
|
||||||
/* undocumented erratum seen on at least rev D */
|
/* undocumented erratum seen on at least rev D */
|
||||||
if ((ohci->flags & OHCI_QUIRK_AMD756)
|
if ((ohci->flags & OHCI_QUIRK_AMD756)
|
||||||
|
@ -348,10 +347,6 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
|
||||||
for (i = 0; i < ohci->num_ports; i++) {
|
for (i = 0; i < ohci->num_ports; i++) {
|
||||||
u32 status = roothub_portstatus (ohci, i);
|
u32 status = roothub_portstatus (ohci, i);
|
||||||
|
|
||||||
/* can't autosuspend with active ports */
|
|
||||||
if ((status & RH_PS_PES) && !(status & RH_PS_PSS))
|
|
||||||
can_suspend = 0;
|
|
||||||
|
|
||||||
if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
|
if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
|
||||||
| RH_PS_OCIC | RH_PS_PRSC)) {
|
| RH_PS_OCIC | RH_PS_PRSC)) {
|
||||||
changed = 1;
|
changed = 1;
|
||||||
|
@ -366,42 +361,12 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
|
||||||
/* after root hub changes, stop polling after debouncing
|
/* after root hub changes, stop polling after debouncing
|
||||||
* for a while and maybe kicking in autosuspend
|
* for a while and maybe kicking in autosuspend
|
||||||
*/
|
*/
|
||||||
if (changed) {
|
if (changed)
|
||||||
ohci->next_statechange = jiffies + STATECHANGE_DELAY;
|
ohci->next_statechange = jiffies + STATECHANGE_DELAY;
|
||||||
can_suspend = 0;
|
|
||||||
} else if (time_before (jiffies, ohci->next_statechange)) {
|
|
||||||
can_suspend = 0;
|
|
||||||
} else {
|
|
||||||
#ifdef CONFIG_PM
|
|
||||||
can_suspend = can_suspend
|
|
||||||
&& !ohci->ed_rm_list
|
|
||||||
&& ((OHCI_CTRL_HCFS | OHCI_SCHED_ENABLES)
|
|
||||||
& ohci->hc_control)
|
|
||||||
== OHCI_USB_OPER;
|
|
||||||
#endif
|
|
||||||
if (hcd->uses_new_polling) {
|
|
||||||
hcd->poll_rh = 0;
|
|
||||||
/* use INTR_RHSC iff INTR_RD won't apply */
|
|
||||||
if (!can_suspend)
|
|
||||||
ohci_writel (ohci, OHCI_INTR_RHSC,
|
|
||||||
&ohci->regs->intrenable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
spin_unlock_irqrestore (&ohci->lock, flags);
|
spin_unlock_irqrestore (&ohci->lock, flags);
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
|
||||||
/* save power by autosuspending idle root hubs;
|
|
||||||
* INTR_RD wakes us when there's work
|
|
||||||
*/
|
|
||||||
if (can_suspend && usb_trylock_device (hcd->self.root_hub) == 0) {
|
|
||||||
ohci_vdbg (ohci, "autosuspend\n");
|
|
||||||
(void) ohci_bus_suspend (hcd);
|
|
||||||
usb_unlock_device (hcd->self.root_hub);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return changed ? length : 0;
|
return changed ? length : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,9 +537,6 @@ static int ohci_hub_control (
|
||||||
break;
|
break;
|
||||||
case USB_PORT_FEAT_SUSPEND:
|
case USB_PORT_FEAT_SUSPEND:
|
||||||
temp = RH_PS_POCI;
|
temp = RH_PS_POCI;
|
||||||
if ((ohci->hc_control & OHCI_CTRL_HCFS)
|
|
||||||
!= OHCI_USB_OPER)
|
|
||||||
usb_hcd_resume_root_hub(hcd);
|
|
||||||
break;
|
break;
|
||||||
case USB_PORT_FEAT_C_SUSPEND:
|
case USB_PORT_FEAT_C_SUSPEND:
|
||||||
temp = RH_PS_PSSC;
|
temp = RH_PS_PSSC;
|
||||||
|
|
Loading…
Reference in a new issue