summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ohci-pci.c')
-rw-r--r--drivers/usb/host/ohci-pci.c60
1 files changed, 23 insertions, 37 deletions
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 7ce1d9e..1b09dde 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -14,15 +14,6 @@
* This file is licenced under the GPL.
*/
-#include <linux/jiffies.h>
-
-#ifdef CONFIG_PPC_PMAC
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/pci-bridge.h>
-#include <asm/prom.h>
-#endif
-
#ifndef CONFIG_PCI
#error "This file is PCI bus glue. CONFIG_PCI must be defined."
#endif
@@ -114,40 +105,36 @@ ohci_pci_start (struct usb_hcd *hcd)
static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
{
- /* root hub was already suspended */
-
- /* FIXME these PMAC things get called in the wrong places. ASIC
- * clocks should be turned off AFTER entering D3, and on BEFORE
- * trying to enter D0. Evidently the PCI layer doesn't currently
- * provide the right sort of platform hooks for this ...
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+ unsigned long flags;
+ int rc = 0;
+
+ /* Root hub was already suspended. Disable irq emission and
+ * mark HW unaccessible, bail out if RH has been resumed. Use
+ * the spinlock to properly synchronize with possible pending
+ * RH suspend or resume activity.
+ *
+ * This is still racy as hcd->state is manipulated outside of
+ * any locks =P But that will be a different fix.
*/
-#ifdef CONFIG_PPC_PMAC
- if (_machine == _MACH_Pmac) {
- struct device_node *of_node;
-
- /* Disable USB PAD & cell clock */
- of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller));
- if (of_node)
- pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
+ spin_lock_irqsave (&ohci->lock, flags);
+ if (hcd->state != HC_STATE_SUSPENDED) {
+ rc = -EINVAL;
+ goto bail;
}
-#endif /* CONFIG_PPC_PMAC */
- return 0;
+ ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
+ (void)ohci_readl(ohci, &ohci->regs->intrdisable);
+ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+ bail:
+ spin_unlock_irqrestore (&ohci->lock, flags);
+
+ return rc;
}
static int ohci_pci_resume (struct usb_hcd *hcd)
{
-#ifdef CONFIG_PPC_PMAC
- if (_machine == _MACH_Pmac) {
- struct device_node *of_node;
-
- /* Re-enable USB PAD & cell clock */
- of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller));
- if (of_node)
- pmac_call_feature (PMAC_FTR_USB_ENABLE, of_node, 0, 1);
- }
-#endif /* CONFIG_PPC_PMAC */
-
+ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
usb_hcd_resume_root_hub(hcd);
return 0;
}
@@ -218,7 +205,6 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
static struct pci_driver ohci_pci_driver = {
.name = (char *) hcd_name,
.id_table = pci_ids,
- .owner = THIS_MODULE,
.probe = usb_hcd_pci_probe,
.remove = usb_hcd_pci_remove,
OpenPOWER on IntegriCloud