diff options
Diffstat (limited to 'drivers/usb/host/ehci-fsl.c')
-rw-r--r-- | drivers/usb/host/ehci-fsl.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index d0a84bd3f3e..43362577b54 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2005-2009 MontaVista Software, Inc. | 2 | * Copyright 2005-2009 MontaVista Software, Inc. |
3 | * Copyright 2008 Freescale Semiconductor, Inc. | 3 | * Copyright 2008,2012 Freescale Semiconductor, Inc. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License as published by the | 6 | * under the terms of the GNU General Public License as published by the |
@@ -150,8 +150,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, | |||
150 | retval = otg_set_host(ehci->transceiver->otg, | 150 | retval = otg_set_host(ehci->transceiver->otg, |
151 | &ehci_to_hcd(ehci)->self); | 151 | &ehci_to_hcd(ehci)->self); |
152 | if (retval) { | 152 | if (retval) { |
153 | if (ehci->transceiver) | 153 | usb_put_transceiver(ehci->transceiver); |
154 | put_device(ehci->transceiver->dev); | ||
155 | goto err4; | 154 | goto err4; |
156 | } | 155 | } |
157 | } else { | 156 | } else { |
@@ -195,7 +194,7 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd, | |||
195 | 194 | ||
196 | if (ehci->transceiver) { | 195 | if (ehci->transceiver) { |
197 | otg_set_host(ehci->transceiver->otg, NULL); | 196 | otg_set_host(ehci->transceiver->otg, NULL); |
198 | put_device(ehci->transceiver->dev); | 197 | usb_put_transceiver(ehci->transceiver); |
199 | } | 198 | } |
200 | 199 | ||
201 | usb_remove_hcd(hcd); | 200 | usb_remove_hcd(hcd); |
@@ -211,22 +210,32 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd, | |||
211 | usb_put_hcd(hcd); | 210 | usb_put_hcd(hcd); |
212 | } | 211 | } |
213 | 212 | ||
214 | static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, | 213 | static void ehci_fsl_setup_phy(struct usb_hcd *hcd, |
215 | enum fsl_usb2_phy_modes phy_mode, | 214 | enum fsl_usb2_phy_modes phy_mode, |
216 | unsigned int port_offset) | 215 | unsigned int port_offset) |
217 | { | 216 | { |
218 | u32 portsc; | 217 | u32 portsc, temp; |
219 | struct usb_hcd *hcd = ehci_to_hcd(ehci); | 218 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
220 | void __iomem *non_ehci = hcd->regs; | 219 | void __iomem *non_ehci = hcd->regs; |
221 | struct fsl_usb2_platform_data *pdata; | 220 | struct device *dev = hcd->self.controller; |
221 | struct fsl_usb2_platform_data *pdata = dev->platform_data; | ||
222 | 222 | ||
223 | pdata = hcd->self.controller->platform_data; | 223 | if (pdata->controller_ver < 0) { |
224 | dev_warn(hcd->self.controller, "Could not get controller version\n"); | ||
225 | return; | ||
226 | } | ||
224 | 227 | ||
225 | portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); | 228 | portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); |
226 | portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); | 229 | portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); |
227 | 230 | ||
228 | switch (phy_mode) { | 231 | switch (phy_mode) { |
229 | case FSL_USB2_PHY_ULPI: | 232 | case FSL_USB2_PHY_ULPI: |
233 | if (pdata->controller_ver) { | ||
234 | /* controller version 1.6 or above */ | ||
235 | temp = in_be32(non_ehci + FSL_SOC_USB_CTRL); | ||
236 | out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | | ||
237 | USB_CTRL_USB_EN | ULPI_PHY_CLK_SEL); | ||
238 | } | ||
230 | portsc |= PORT_PTS_ULPI; | 239 | portsc |= PORT_PTS_ULPI; |
231 | break; | 240 | break; |
232 | case FSL_USB2_PHY_SERIAL: | 241 | case FSL_USB2_PHY_SERIAL: |
@@ -236,6 +245,14 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, | |||
236 | portsc |= PORT_PTS_PTW; | 245 | portsc |= PORT_PTS_PTW; |
237 | /* fall through */ | 246 | /* fall through */ |
238 | case FSL_USB2_PHY_UTMI: | 247 | case FSL_USB2_PHY_UTMI: |
248 | if (pdata->controller_ver) { | ||
249 | /* controller version 1.6 or above */ | ||
250 | temp = in_be32(non_ehci + FSL_SOC_USB_CTRL); | ||
251 | out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | | ||
252 | UTMI_PHY_EN | USB_CTRL_USB_EN); | ||
253 | mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI PHY CLK to | ||
254 | become stable - 10ms*/ | ||
255 | } | ||
239 | /* enable UTMI PHY */ | 256 | /* enable UTMI PHY */ |
240 | if (pdata->have_sysif_regs) | 257 | if (pdata->have_sysif_regs) |
241 | setbits32(non_ehci + FSL_SOC_USB_CTRL, | 258 | setbits32(non_ehci + FSL_SOC_USB_CTRL, |
@@ -276,7 +293,7 @@ static void ehci_fsl_usb_setup(struct ehci_hcd *ehci) | |||
276 | 293 | ||
277 | if ((pdata->operating_mode == FSL_USB2_DR_HOST) || | 294 | if ((pdata->operating_mode == FSL_USB2_DR_HOST) || |
278 | (pdata->operating_mode == FSL_USB2_DR_OTG)) | 295 | (pdata->operating_mode == FSL_USB2_DR_OTG)) |
279 | ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0); | 296 | ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0); |
280 | 297 | ||
281 | if (pdata->operating_mode == FSL_USB2_MPH_HOST) { | 298 | if (pdata->operating_mode == FSL_USB2_MPH_HOST) { |
282 | unsigned int chip, rev, svr; | 299 | unsigned int chip, rev, svr; |
@@ -290,9 +307,9 @@ static void ehci_fsl_usb_setup(struct ehci_hcd *ehci) | |||
290 | ehci->has_fsl_port_bug = 1; | 307 | ehci->has_fsl_port_bug = 1; |
291 | 308 | ||
292 | if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) | 309 | if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) |
293 | ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0); | 310 | ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0); |
294 | if (pdata->port_enables & FSL_USB2_PORT1_ENABLED) | 311 | if (pdata->port_enables & FSL_USB2_PORT1_ENABLED) |
295 | ehci_fsl_setup_phy(ehci, pdata->phy_mode, 1); | 312 | ehci_fsl_setup_phy(hcd, pdata->phy_mode, 1); |
296 | } | 313 | } |
297 | 314 | ||
298 | if (pdata->have_sysif_regs) { | 315 | if (pdata->have_sysif_regs) { |