diff options
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 36 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/isp116x-hcd.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/ohci-at91.c | 50 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 18 |
5 files changed, 79 insertions, 29 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 185721dba42b..a74056488234 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -42,6 +42,9 @@ | |||
42 | #include <asm/irq.h> | 42 | #include <asm/irq.h> |
43 | #include <asm/system.h> | 43 | #include <asm/system.h> |
44 | #include <asm/unaligned.h> | 44 | #include <asm/unaligned.h> |
45 | #ifdef CONFIG_PPC_PS3 | ||
46 | #include <asm/firmware.h> | ||
47 | #endif | ||
45 | 48 | ||
46 | 49 | ||
47 | /*-------------------------------------------------------------------------*/ | 50 | /*-------------------------------------------------------------------------*/ |
@@ -299,6 +302,19 @@ static void ehci_watchdog (unsigned long param) | |||
299 | spin_unlock_irqrestore (&ehci->lock, flags); | 302 | spin_unlock_irqrestore (&ehci->lock, flags); |
300 | } | 303 | } |
301 | 304 | ||
305 | /* On some systems, leaving remote wakeup enabled prevents system shutdown. | ||
306 | * The firmware seems to think that powering off is a wakeup event! | ||
307 | * This routine turns off remote wakeup and everything else, on all ports. | ||
308 | */ | ||
309 | static void ehci_turn_off_all_ports(struct ehci_hcd *ehci) | ||
310 | { | ||
311 | int port = HCS_N_PORTS(ehci->hcs_params); | ||
312 | |||
313 | while (port--) | ||
314 | ehci_writel(ehci, PORT_RWC_BITS, | ||
315 | &ehci->regs->port_status[port]); | ||
316 | } | ||
317 | |||
302 | /* ehci_shutdown kick in for silicon on any bus (not just pci, etc). | 318 | /* ehci_shutdown kick in for silicon on any bus (not just pci, etc). |
303 | * This forcibly disables dma and IRQs, helping kexec and other cases | 319 | * This forcibly disables dma and IRQs, helping kexec and other cases |
304 | * where the next system software may expect clean state. | 320 | * where the next system software may expect clean state. |
@@ -310,9 +326,13 @@ ehci_shutdown (struct usb_hcd *hcd) | |||
310 | 326 | ||
311 | ehci = hcd_to_ehci (hcd); | 327 | ehci = hcd_to_ehci (hcd); |
312 | (void) ehci_halt (ehci); | 328 | (void) ehci_halt (ehci); |
329 | ehci_turn_off_all_ports(ehci); | ||
313 | 330 | ||
314 | /* make BIOS/etc use companion controller during reboot */ | 331 | /* make BIOS/etc use companion controller during reboot */ |
315 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); | 332 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
333 | |||
334 | /* unblock posted writes */ | ||
335 | ehci_readl(ehci, &ehci->regs->configured_flag); | ||
316 | } | 336 | } |
317 | 337 | ||
318 | static void ehci_port_power (struct ehci_hcd *ehci, int is_on) | 338 | static void ehci_port_power (struct ehci_hcd *ehci, int is_on) |
@@ -951,15 +971,18 @@ static int __init ehci_hcd_init(void) | |||
951 | #endif | 971 | #endif |
952 | 972 | ||
953 | #ifdef PS3_SYSTEM_BUS_DRIVER | 973 | #ifdef PS3_SYSTEM_BUS_DRIVER |
954 | retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER); | 974 | if (firmware_has_feature(FW_FEATURE_PS3_LV1)) { |
955 | if (retval < 0) { | 975 | retval = ps3_system_bus_driver_register( |
976 | &PS3_SYSTEM_BUS_DRIVER); | ||
977 | if (retval < 0) { | ||
956 | #ifdef PLATFORM_DRIVER | 978 | #ifdef PLATFORM_DRIVER |
957 | platform_driver_unregister(&PLATFORM_DRIVER); | 979 | platform_driver_unregister(&PLATFORM_DRIVER); |
958 | #endif | 980 | #endif |
959 | #ifdef PCI_DRIVER | 981 | #ifdef PCI_DRIVER |
960 | pci_unregister_driver(&PCI_DRIVER); | 982 | pci_unregister_driver(&PCI_DRIVER); |
961 | #endif | 983 | #endif |
962 | return retval; | 984 | return retval; |
985 | } | ||
963 | } | 986 | } |
964 | #endif | 987 | #endif |
965 | 988 | ||
@@ -976,7 +999,8 @@ static void __exit ehci_hcd_cleanup(void) | |||
976 | pci_unregister_driver(&PCI_DRIVER); | 999 | pci_unregister_driver(&PCI_DRIVER); |
977 | #endif | 1000 | #endif |
978 | #ifdef PS3_SYSTEM_BUS_DRIVER | 1001 | #ifdef PS3_SYSTEM_BUS_DRIVER |
979 | ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | 1002 | if (firmware_has_feature(FW_FEATURE_PS3_LV1)) |
1003 | ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | ||
980 | #endif | 1004 | #endif |
981 | } | 1005 | } |
982 | module_exit(ehci_hcd_cleanup); | 1006 | module_exit(ehci_hcd_cleanup); |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 0d83c6df1a3b..9af529d22b3e 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -36,6 +36,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
36 | int port; | 36 | int port; |
37 | int mask; | 37 | int mask; |
38 | 38 | ||
39 | ehci_dbg(ehci, "suspend root hub\n"); | ||
40 | |||
39 | if (time_before (jiffies, ehci->next_statechange)) | 41 | if (time_before (jiffies, ehci->next_statechange)) |
40 | msleep(5); | 42 | msleep(5); |
41 | 43 | ||
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 2718b5dc4ec1..46873f2534b5 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -1577,7 +1577,7 @@ static int isp116x_remove(struct platform_device *pdev) | |||
1577 | 1577 | ||
1578 | #define resource_len(r) (((r)->end - (r)->start) + 1) | 1578 | #define resource_len(r) (((r)->end - (r)->start) + 1) |
1579 | 1579 | ||
1580 | static int __init isp116x_probe(struct platform_device *pdev) | 1580 | static int __devinit isp116x_probe(struct platform_device *pdev) |
1581 | { | 1581 | { |
1582 | struct usb_hcd *hcd; | 1582 | struct usb_hcd *hcd; |
1583 | struct isp116x *isp116x; | 1583 | struct isp116x *isp116x; |
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 930346487278..d849c809acbd 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -18,19 +18,38 @@ | |||
18 | #include <asm/mach-types.h> | 18 | #include <asm/mach-types.h> |
19 | #include <asm/hardware.h> | 19 | #include <asm/hardware.h> |
20 | #include <asm/arch/board.h> | 20 | #include <asm/arch/board.h> |
21 | #include <asm/arch/cpu.h> | ||
21 | 22 | ||
22 | #ifndef CONFIG_ARCH_AT91 | 23 | #ifndef CONFIG_ARCH_AT91 |
23 | #error "CONFIG_ARCH_AT91 must be defined." | 24 | #error "CONFIG_ARCH_AT91 must be defined." |
24 | #endif | 25 | #endif |
25 | 26 | ||
26 | /* interface and function clocks */ | 27 | /* interface and function clocks; sometimes also an AHB clock */ |
27 | static struct clk *iclk, *fclk; | 28 | static struct clk *iclk, *fclk, *hclk; |
28 | static int clocked; | 29 | static int clocked; |
29 | 30 | ||
30 | extern int usb_disabled(void); | 31 | extern int usb_disabled(void); |
31 | 32 | ||
32 | /*-------------------------------------------------------------------------*/ | 33 | /*-------------------------------------------------------------------------*/ |
33 | 34 | ||
35 | static void at91_start_clock(void) | ||
36 | { | ||
37 | if (cpu_is_at91sam9261()) | ||
38 | clk_enable(hclk); | ||
39 | clk_enable(iclk); | ||
40 | clk_enable(fclk); | ||
41 | clocked = 1; | ||
42 | } | ||
43 | |||
44 | static void at91_stop_clock(void) | ||
45 | { | ||
46 | clk_disable(fclk); | ||
47 | clk_disable(iclk); | ||
48 | if (cpu_is_at91sam9261()) | ||
49 | clk_disable(hclk); | ||
50 | clocked = 0; | ||
51 | } | ||
52 | |||
34 | static void at91_start_hc(struct platform_device *pdev) | 53 | static void at91_start_hc(struct platform_device *pdev) |
35 | { | 54 | { |
36 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 55 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
@@ -41,9 +60,7 @@ static void at91_start_hc(struct platform_device *pdev) | |||
41 | /* | 60 | /* |
42 | * Start the USB clocks. | 61 | * Start the USB clocks. |
43 | */ | 62 | */ |
44 | clk_enable(iclk); | 63 | at91_start_clock(); |
45 | clk_enable(fclk); | ||
46 | clocked = 1; | ||
47 | 64 | ||
48 | /* | 65 | /* |
49 | * The USB host controller must remain in reset. | 66 | * The USB host controller must remain in reset. |
@@ -66,9 +83,7 @@ static void at91_stop_hc(struct platform_device *pdev) | |||
66 | /* | 83 | /* |
67 | * Stop the USB clocks. | 84 | * Stop the USB clocks. |
68 | */ | 85 | */ |
69 | clk_disable(fclk); | 86 | at91_stop_clock(); |
70 | clk_disable(iclk); | ||
71 | clocked = 0; | ||
72 | } | 87 | } |
73 | 88 | ||
74 | 89 | ||
@@ -126,6 +141,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, | |||
126 | 141 | ||
127 | iclk = clk_get(&pdev->dev, "ohci_clk"); | 142 | iclk = clk_get(&pdev->dev, "ohci_clk"); |
128 | fclk = clk_get(&pdev->dev, "uhpck"); | 143 | fclk = clk_get(&pdev->dev, "uhpck"); |
144 | if (cpu_is_at91sam9261()) | ||
145 | hclk = clk_get(&pdev->dev, "hck0"); | ||
129 | 146 | ||
130 | at91_start_hc(pdev); | 147 | at91_start_hc(pdev); |
131 | ohci_hcd_init(hcd_to_ohci(hcd)); | 148 | ohci_hcd_init(hcd_to_ohci(hcd)); |
@@ -137,6 +154,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, | |||
137 | /* Error handling */ | 154 | /* Error handling */ |
138 | at91_stop_hc(pdev); | 155 | at91_stop_hc(pdev); |
139 | 156 | ||
157 | if (cpu_is_at91sam9261()) | ||
158 | clk_put(hclk); | ||
140 | clk_put(fclk); | 159 | clk_put(fclk); |
141 | clk_put(iclk); | 160 | clk_put(iclk); |
142 | 161 | ||
@@ -171,9 +190,11 @@ static int usb_hcd_at91_remove(struct usb_hcd *hcd, | |||
171 | iounmap(hcd->regs); | 190 | iounmap(hcd->regs); |
172 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 191 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
173 | 192 | ||
193 | if (cpu_is_at91sam9261()) | ||
194 | clk_put(hclk); | ||
174 | clk_put(fclk); | 195 | clk_put(fclk); |
175 | clk_put(iclk); | 196 | clk_put(iclk); |
176 | fclk = iclk = NULL; | 197 | fclk = iclk = hclk = NULL; |
177 | 198 | ||
178 | dev_set_drvdata(&pdev->dev, NULL); | 199 | dev_set_drvdata(&pdev->dev, NULL); |
179 | return 0; | 200 | return 0; |
@@ -280,9 +301,7 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
280 | */ | 301 | */ |
281 | if (at91_suspend_entering_slow_clock()) { | 302 | if (at91_suspend_entering_slow_clock()) { |
282 | ohci_usb_reset (ohci); | 303 | ohci_usb_reset (ohci); |
283 | clk_disable(fclk); | 304 | at91_stop_clock(); |
284 | clk_disable(iclk); | ||
285 | clocked = 0; | ||
286 | } | 305 | } |
287 | 306 | ||
288 | return 0; | 307 | return 0; |
@@ -295,11 +314,8 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) | |||
295 | if (device_may_wakeup(&pdev->dev)) | 314 | if (device_may_wakeup(&pdev->dev)) |
296 | disable_irq_wake(hcd->irq); | 315 | disable_irq_wake(hcd->irq); |
297 | 316 | ||
298 | if (!clocked) { | 317 | if (!clocked) |
299 | clk_enable(iclk); | 318 | at91_start_clock(); |
300 | clk_enable(fclk); | ||
301 | clocked = 1; | ||
302 | } | ||
303 | 319 | ||
304 | return 0; | 320 | return 0; |
305 | } | 321 | } |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index fa6a7ceaa0db..f0d29eda3c6d 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -42,6 +42,9 @@ | |||
42 | #include <asm/system.h> | 42 | #include <asm/system.h> |
43 | #include <asm/unaligned.h> | 43 | #include <asm/unaligned.h> |
44 | #include <asm/byteorder.h> | 44 | #include <asm/byteorder.h> |
45 | #ifdef CONFIG_PPC_PS3 | ||
46 | #include <asm/firmware.h> | ||
47 | #endif | ||
45 | 48 | ||
46 | #include "../core/hcd.h" | 49 | #include "../core/hcd.h" |
47 | 50 | ||
@@ -944,9 +947,12 @@ static int __init ohci_hcd_mod_init(void) | |||
944 | sizeof (struct ed), sizeof (struct td)); | 947 | sizeof (struct ed), sizeof (struct td)); |
945 | 948 | ||
946 | #ifdef PS3_SYSTEM_BUS_DRIVER | 949 | #ifdef PS3_SYSTEM_BUS_DRIVER |
947 | retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER); | 950 | if (firmware_has_feature(FW_FEATURE_PS3_LV1)) { |
948 | if (retval < 0) | 951 | retval = ps3_system_bus_driver_register( |
949 | goto error_ps3; | 952 | &PS3_SYSTEM_BUS_DRIVER); |
953 | if (retval < 0) | ||
954 | goto error_ps3; | ||
955 | } | ||
950 | #endif | 956 | #endif |
951 | 957 | ||
952 | #ifdef PLATFORM_DRIVER | 958 | #ifdef PLATFORM_DRIVER |
@@ -992,7 +998,8 @@ static int __init ohci_hcd_mod_init(void) | |||
992 | error_platform: | 998 | error_platform: |
993 | #endif | 999 | #endif |
994 | #ifdef PS3_SYSTEM_BUS_DRIVER | 1000 | #ifdef PS3_SYSTEM_BUS_DRIVER |
995 | ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | 1001 | if (firmware_has_feature(FW_FEATURE_PS3_LV1)) |
1002 | ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | ||
996 | error_ps3: | 1003 | error_ps3: |
997 | #endif | 1004 | #endif |
998 | return retval; | 1005 | return retval; |
@@ -1014,7 +1021,8 @@ static void __exit ohci_hcd_mod_exit(void) | |||
1014 | platform_driver_unregister(&PLATFORM_DRIVER); | 1021 | platform_driver_unregister(&PLATFORM_DRIVER); |
1015 | #endif | 1022 | #endif |
1016 | #ifdef PS3_SYSTEM_BUS_DRIVER | 1023 | #ifdef PS3_SYSTEM_BUS_DRIVER |
1017 | ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | 1024 | if (firmware_has_feature(FW_FEATURE_PS3_LV1)) |
1025 | ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | ||
1018 | #endif | 1026 | #endif |
1019 | } | 1027 | } |
1020 | module_exit(ohci_hcd_mod_exit); | 1028 | module_exit(ohci_hcd_mod_exit); |