[PATCH] USB: ohci, move ppc asic tweaks nearer pci

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>

authored by David Brownell and committed by Linus Torvalds 21b1861f 18807521

+36 -38
+36 -2
drivers/usb/core/hcd-pci.c
··· 20 20 #include <linux/kernel.h> 21 21 #include <linux/module.h> 22 22 #include <linux/pci.h> 23 + #include <linux/usb.h> 24 + 23 25 #include <asm/io.h> 24 26 #include <asm/irq.h> 25 - #include <linux/usb.h> 27 + 28 + #ifdef CONFIG_PPC_PMAC 29 + #include <asm/machdep.h> 30 + #include <asm/pmac_feature.h> 31 + #include <asm/pci-bridge.h> 32 + #include <asm/prom.h> 33 + #endif 26 34 27 35 #include "usb.h" 28 36 #include "hcd.h" ··· 285 277 } 286 278 287 279 done: 288 - if (retval == 0) 280 + if (retval == 0) { 289 281 dev->dev.power.power_state = PMSG_SUSPEND; 282 + 283 + #ifdef CONFIG_PPC_PMAC 284 + /* Disable ASIC clocks for USB */ 285 + if (_machine == _MACH_Pmac) { 286 + struct device_node *of_node; 287 + 288 + of_node = pci_device_to_OF_node (dev); 289 + if (of_node) 290 + pmac_call_feature(PMAC_FTR_USB_ENABLE, 291 + of_node, 0, 0); 292 + } 293 + #endif 294 + } 295 + 290 296 return retval; 291 297 } 292 298 EXPORT_SYMBOL (usb_hcd_pci_suspend); ··· 322 300 "can't resume, not suspended!\n"); 323 301 return 0; 324 302 } 303 + 304 + #ifdef CONFIG_PPC_PMAC 305 + /* Reenable ASIC clocks for USB */ 306 + if (_machine == _MACH_Pmac) { 307 + struct device_node *of_node; 308 + 309 + of_node = pci_device_to_OF_node (dev); 310 + if (of_node) 311 + pmac_call_feature (PMAC_FTR_USB_ENABLE, 312 + of_node, 0, 1); 313 + } 314 + #endif 325 315 326 316 /* NOTE: chip docs cover clean "real suspend" cases (what Linux 327 317 * calls "standby", "suspend to RAM", and so on). There are also
-36
drivers/usb/host/ohci-pci.c
··· 14 14 * This file is licenced under the GPL. 15 15 */ 16 16 17 - #include <linux/jiffies.h> 18 - 19 - #ifdef CONFIG_PPC_PMAC 20 - #include <asm/machdep.h> 21 - #include <asm/pmac_feature.h> 22 - #include <asm/pci-bridge.h> 23 - #include <asm/prom.h> 24 - #endif 25 - 26 17 #ifndef CONFIG_PCI 27 18 #error "This file is PCI bus glue. CONFIG_PCI must be defined." 28 19 #endif ··· 106 115 static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) 107 116 { 108 117 /* root hub was already suspended */ 109 - 110 - /* FIXME these PMAC things get called in the wrong places. ASIC 111 - * clocks should be turned off AFTER entering D3, and on BEFORE 112 - * trying to enter D0. Evidently the PCI layer doesn't currently 113 - * provide the right sort of platform hooks for this ... 114 - */ 115 - #ifdef CONFIG_PPC_PMAC 116 - if (_machine == _MACH_Pmac) { 117 - struct device_node *of_node; 118 - 119 - /* Disable USB PAD & cell clock */ 120 - of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller)); 121 - if (of_node) 122 - pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0); 123 - } 124 - #endif /* CONFIG_PPC_PMAC */ 125 118 return 0; 126 119 } 127 120 128 121 129 122 static int ohci_pci_resume (struct usb_hcd *hcd) 130 123 { 131 - #ifdef CONFIG_PPC_PMAC 132 - if (_machine == _MACH_Pmac) { 133 - struct device_node *of_node; 134 - 135 - /* Re-enable USB PAD & cell clock */ 136 - of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller)); 137 - if (of_node) 138 - pmac_call_feature (PMAC_FTR_USB_ENABLE, of_node, 0, 1); 139 - } 140 - #endif /* CONFIG_PPC_PMAC */ 141 - 142 124 usb_hcd_resume_root_hub(hcd); 143 125 return 0; 144 126 }