26 #include <linux/kernel.h>
27 #include <linux/types.h>
48 static int usb_hcd_fsl_probe(
const struct hc_driver *
driver,
57 pr_debug(
"initializing FSL-SOC USB Controller\n");
63 "No platform data for %s.\n", dev_name(&pdev->
dev));
75 "Non Host Mode configured for %s. Wrong driver linked.\n",
76 dev_name(&pdev->
dev));
83 "Found HC with no IRQ. Check %s setup!\n",
84 dev_name(&pdev->
dev));
98 "Found HC with no register addr. Check %s setup!\n",
99 dev_name(&pdev->
dev));
103 hcd->rsrc_start = res->
start;
104 hcd->rsrc_len = resource_size(res);
106 driver->description)) {
107 dev_dbg(&pdev->
dev,
"controller already in use\n");
111 hcd->regs =
ioremap(hcd->rsrc_start, hcd->rsrc_len);
113 if (hcd->regs ==
NULL) {
114 dev_dbg(&pdev->
dev,
"error mapping memory\n");
119 pdata->
regs = hcd->regs;
127 if (pdata->
init && pdata->
init(pdev)) {
142 #ifdef CONFIG_USB_OTG
144 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
147 dev_dbg(&pdev->
dev,
"hcd=0x%p ehci=0x%p, phy=0x%p\n",
148 hcd, ehci, hcd->phy);
150 if (!IS_ERR_OR_NULL(hcd->phy)) {
151 retval = otg_set_host(hcd->phy->otg,
152 &ehci_to_hcd(ehci)->
self);
173 dev_err(&pdev->
dev,
"init %s fail, %d\n", dev_name(&pdev->
dev), retval);
190 static void usb_hcd_fsl_remove(
struct usb_hcd *hcd,
195 if (!IS_ERR_OR_NULL(hcd->phy)) {
196 otg_set_host(hcd->phy->otg,
NULL);
213 static int ehci_fsl_setup_phy(
struct usb_hcd *hcd,
215 unsigned int port_offset)
218 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
219 void __iomem *non_ehci = hcd->regs;
220 struct device *
dev = hcd->self.controller;
224 dev_warn(hcd->self.controller,
"Could not get controller version\n");
228 portsc = ehci_readl(ehci, &ehci->
regs->port_status[port_offset]);
279 ehci_writel(ehci, portsc, &ehci->
regs->port_status[port_offset]);
287 static int ehci_fsl_usb_setup(
struct ehci_hcd *ehci)
289 struct usb_hcd *hcd = ehci_to_hcd(ehci);
291 void __iomem *non_ehci = hcd->regs;
293 pdata = hcd->self.controller->platform_data;
310 if (ehci_fsl_setup_phy(hcd, pdata->
phy_mode, 0))
316 svr =
mfspr(SPRN_SVR);
318 rev = (svr >> 4) & 0xf;
321 if ((rev == 1) && (chip >= 0x8050) && (chip <= 0x8055))
325 if (ehci_fsl_setup_phy(hcd, pdata->
phy_mode, 0))
329 if (ehci_fsl_setup_phy(hcd, pdata->
phy_mode, 1))
334 #ifdef CONFIG_FSL_SOC_BOOKE
348 static int ehci_fsl_reinit(
struct ehci_hcd *ehci)
350 if (ehci_fsl_usb_setup(ehci))
352 ehci_port_power(ehci, 0);
358 static int ehci_fsl_setup(
struct usb_hcd *hcd)
360 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
365 dev = hcd->self.controller;
366 pdata = hcd->self.controller->platform_data;
371 ehci->
caps = hcd->regs + 0x100;
375 retval = ehci_setup(hcd);
380 "fsl,mpc5121-usb2-dr")) {
389 retval = ehci_fsl_reinit(ehci);
404 #ifdef CONFIG_PPC_MPC512x
405 static int ehci_fsl_mpc512x_drv_suspend(
struct device *dev)
408 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
415 tmp = ehci_readl(ehci, hcd->
regs + 0x140);
417 dev_dbg(dev,
"suspend=%d already_suspended=%d "
418 "mode=%d usbcmd %08x\n", pdata->
suspended,
428 dev_dbg(dev,
"already suspended, leaving early\n");
433 dev_dbg(dev,
"suspending...\n");
439 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
442 tmp = ehci_readl(ehci, &ehci->
regs->command);
444 ehci_writel(ehci, tmp, &ehci->
regs->command);
456 ehci_readl(ehci, &ehci->
regs->configured_flag);
457 pdata->
pm_portsc = ehci_readl(ehci, &ehci->
regs->port_status[0]);
467 tmp = ehci_readl(ehci, &ehci->
regs->port_status[0]);
469 ehci_writel(ehci, tmp, &ehci->
regs->port_status[0]);
474 static int ehci_fsl_mpc512x_drv_resume(
struct device *dev)
477 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
481 dev_dbg(dev,
"suspend=%d already_suspended=%d\n",
489 dev_dbg(dev,
"already suspended, leaving early\n");
495 dev_dbg(dev,
"not suspended, leaving early\n");
522 &ehci->
regs->configured_flag);
523 ehci_writel(ehci, pdata->
pm_portsc, &ehci->
regs->port_status[0]);
525 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
529 tmp = ehci_readl(ehci, &ehci->
regs->command);
531 ehci_writel(ehci, tmp, &ehci->
regs->command);
533 usb_hcd_resume_root_hub(hcd);
538 static inline int ehci_fsl_mpc512x_drv_suspend(
struct device *dev)
543 static inline int ehci_fsl_mpc512x_drv_resume(
struct device *dev)
549 static struct ehci_fsl *hcd_to_ehci_fsl(
struct usb_hcd *hcd)
551 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
556 static int ehci_fsl_drv_suspend(
struct device *dev)
560 void __iomem *non_ehci = hcd->regs;
563 "fsl,mpc5121-usb2-dr")) {
564 return ehci_fsl_mpc512x_drv_suspend(dev);
568 device_may_wakeup(dev));
576 static int ehci_fsl_drv_resume(
struct device *dev)
579 struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd);
580 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
581 void __iomem *non_ehci = hcd->regs;
584 "fsl,mpc5121-usb2-dr")) {
585 return ehci_fsl_mpc512x_drv_resume(dev);
592 usb_root_hub_lost_power(hcd->self.root_hub);
598 ehci_fsl_reinit(ehci);
603 static int ehci_fsl_drv_restore(
struct device *dev)
607 usb_root_hub_lost_power(hcd->self.root_hub);
612 .
suspend = ehci_fsl_drv_suspend,
613 .resume = ehci_fsl_drv_resume,
614 .restore = ehci_fsl_drv_restore,
617 #define EHCI_FSL_PM_OPS (&ehci_fsl_pm_ops)
619 #define EHCI_FSL_PM_OPS NULL
622 #ifdef CONFIG_USB_OTG
625 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
634 status =
readl(&ehci->
regs->port_status[port]);
642 &ehci->
regs->port_status[port]);
650 #define ehci_start_port_reset NULL
654 static const struct hc_driver ehci_fsl_hc_driver = {
655 .description = hcd_name,
656 .product_desc =
"Freescale On-Chip EHCI Host Controller",
657 .hcd_priv_size =
sizeof(
struct ehci_fsl),
663 .flags = HCD_USB2 | HCD_MEMORY,
668 .reset = ehci_fsl_setup,
671 .shutdown = ehci_shutdown,
676 .urb_enqueue = ehci_urb_enqueue,
677 .urb_dequeue = ehci_urb_dequeue,
678 .endpoint_disable = ehci_endpoint_disable,
679 .endpoint_reset = ehci_endpoint_reset,
684 .get_frame_number = ehci_get_frame,
689 .hub_status_data = ehci_hub_status_data,
690 .hub_control = ehci_hub_control,
694 .relinquish_port = ehci_relinquish_port,
695 .port_handed_over = ehci_port_handed_over,
697 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
706 return usb_hcd_fsl_probe(&ehci_fsl_hc_driver, pdev);
711 struct usb_hcd *hcd = platform_get_drvdata(pdev);
714 usb_hcd_fsl_remove(hcd, pdev);
721 .probe = ehci_fsl_drv_probe,
722 .remove = ehci_fsl_drv_remove,