[PATCH] USB: ohci, move ppc asic tweaks nearer pci
authorDavid Brownell <david-b@pacbell.net>
Wed, 23 Nov 2005 23:45:42 +0000 (15:45 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 24 Nov 2005 07:04:28 +0000 (23:04 -0800)
This should fix a suspend/resume issues that appear with OHCI on some
PPC hardware.  The PCI layer should doesn't have the hooks needed for
such ASIC-specific hooks (in this case, software clock gating), so
this moves the code to do that into hcd-pci.c ... where it can be
done after the relevant PCI PM state transition (to/from D3).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/usb/core/hcd-pci.c
drivers/usb/host/ohci-pci.c

index 7feb829362d63212d5383e6aba652373036e5150..5131d88e8c5bd7c5b39b0e9b1f27d3a2c5a85eda 100644 (file)
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/usb.h>
+
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <linux/usb.h>
+
+#ifdef CONFIG_PPC_PMAC
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/pci-bridge.h>
+#include <asm/prom.h>
+#endif
 
 #include "usb.h"
 #include "hcd.h"
@@ -277,8 +285,22 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message)
        }
 
 done:
-       if (retval == 0)
+       if (retval == 0) {
                dev->dev.power.power_state = PMSG_SUSPEND;
+
+#ifdef CONFIG_PPC_PMAC
+               /* Disable ASIC clocks for USB */
+               if (_machine == _MACH_Pmac) {
+                       struct device_node      *of_node;
+
+                       of_node = pci_device_to_OF_node (dev);
+                       if (of_node)
+                               pmac_call_feature(PMAC_FTR_USB_ENABLE,
+                                                       of_node, 0, 0);
+               }
+#endif
+       }
+
        return retval;
 }
 EXPORT_SYMBOL (usb_hcd_pci_suspend);
@@ -301,6 +323,18 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
                return 0;
        }
 
+#ifdef CONFIG_PPC_PMAC
+       /* Reenable ASIC clocks for USB */
+       if (_machine == _MACH_Pmac) {
+               struct device_node *of_node;
+
+               of_node = pci_device_to_OF_node (dev);
+               if (of_node)
+                       pmac_call_feature (PMAC_FTR_USB_ENABLE,
+                                               of_node, 0, 1);
+       }
+#endif
+
        /* NOTE:  chip docs cover clean "real suspend" cases (what Linux
         * calls "standby", "suspend to RAM", and so on).  There are also
         * dirty cases when swsusp fakes a suspend in "shutdown" mode.
index a59e536441e14771d95463982ccdbc4c050f751e..5f22e6590cd12b82141fe2724c21d9acaf15465a 100644 (file)
  * 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
@@ -115,39 +106,12 @@ 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 ...
-        */
-#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);
-       }
-#endif /* CONFIG_PPC_PMAC */
        return 0;
 }
 
 
 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 */
-
        usb_hcd_resume_root_hub(hcd);
        return 0;
 }