Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: at91-ohci, handle extra at91sam9261 ahb clock

The AT91SAM9261 needs to activate an AHB clock (HCK0) to use the USB Host
controller. Previously clock.c would just enable it at startup, but now
all the unused clocks are automatically disabled.

Based on patch from Nicolas Ferre.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Andrew Victor and committed by
Greg Kroah-Hartman
ed077bb7 ebaf494e

+33 -17
+33 -17
drivers/usb/host/ohci-at91.c
··· 18 18 #include <asm/mach-types.h> 19 19 #include <asm/hardware.h> 20 20 #include <asm/arch/board.h> 21 + #include <asm/arch/cpu.h> 21 22 22 23 #ifndef CONFIG_ARCH_AT91 23 24 #error "CONFIG_ARCH_AT91 must be defined." 24 25 #endif 25 26 26 - /* interface and function clocks */ 27 - static struct clk *iclk, *fclk; 27 + /* interface and function clocks; sometimes also an AHB clock */ 28 + static struct clk *iclk, *fclk, *hclk; 28 29 static int clocked; 29 30 30 31 extern int usb_disabled(void); 31 32 32 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 + } 33 52 34 53 static void at91_start_hc(struct platform_device *pdev) 35 54 { ··· 60 41 /* 61 42 * Start the USB clocks. 62 43 */ 63 - clk_enable(iclk); 64 - clk_enable(fclk); 65 - clocked = 1; 44 + at91_start_clock(); 66 45 67 46 /* 68 47 * The USB host controller must remain in reset. ··· 83 66 /* 84 67 * Stop the USB clocks. 85 68 */ 86 - clk_disable(fclk); 87 - clk_disable(iclk); 88 - clocked = 0; 69 + at91_stop_clock(); 89 70 } 90 71 91 72 ··· 141 126 142 127 iclk = clk_get(&pdev->dev, "ohci_clk"); 143 128 fclk = clk_get(&pdev->dev, "uhpck"); 129 + if (cpu_is_at91sam9261()) 130 + hclk = clk_get(&pdev->dev, "hck0"); 144 131 145 132 at91_start_hc(pdev); 146 133 ohci_hcd_init(hcd_to_ohci(hcd)); ··· 154 137 /* Error handling */ 155 138 at91_stop_hc(pdev); 156 139 140 + if (cpu_is_at91sam9261()) 141 + clk_put(hclk); 157 142 clk_put(fclk); 158 143 clk_put(iclk); 159 144 ··· 190 171 iounmap(hcd->regs); 191 172 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 192 173 174 + if (cpu_is_at91sam9261()) 175 + clk_put(hclk); 193 176 clk_put(fclk); 194 177 clk_put(iclk); 195 - fclk = iclk = NULL; 178 + fclk = iclk = hclk = NULL; 196 179 197 180 dev_set_drvdata(&pdev->dev, NULL); 198 181 return 0; ··· 301 280 */ 302 281 if (at91_suspend_entering_slow_clock()) { 303 282 ohci_usb_reset (ohci); 304 - clk_disable(fclk); 305 - clk_disable(iclk); 306 - clocked = 0; 283 + at91_stop_clock(); 307 284 } 308 285 309 286 return 0; ··· 314 295 if (device_may_wakeup(&pdev->dev)) 315 296 disable_irq_wake(hcd->irq); 316 297 317 - if (!clocked) { 318 - clk_enable(iclk); 319 - clk_enable(fclk); 320 - clocked = 1; 321 - } 298 + if (!clocked) 299 + at91_start_clock(); 322 300 323 301 return 0; 324 302 }