.. | .. |
---|
115 | 115 | static void at91_stop_hc(struct platform_device *pdev) |
---|
116 | 116 | { |
---|
117 | 117 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
---|
118 | | - struct ohci_regs __iomem *regs = hcd->regs; |
---|
119 | 118 | struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); |
---|
120 | 119 | |
---|
121 | 120 | dev_dbg(&pdev->dev, "stop\n"); |
---|
.. | .. |
---|
123 | 122 | /* |
---|
124 | 123 | * Put the USB host controller into reset. |
---|
125 | 124 | */ |
---|
126 | | - writel(0, ®s->control); |
---|
| 125 | + usb_hcd_platform_shutdown(pdev); |
---|
127 | 126 | |
---|
128 | 127 | /* |
---|
129 | 128 | * Stop the USB clocks. |
---|
.. | .. |
---|
141 | 140 | struct regmap *regmap; |
---|
142 | 141 | |
---|
143 | 142 | regmap = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr"); |
---|
144 | | - if (IS_ERR(regmap)) |
---|
145 | | - regmap = NULL; |
---|
| 143 | + if (IS_ERR(regmap)) { |
---|
| 144 | + regmap = syscon_regmap_lookup_by_compatible("microchip,sam9x60-sfr"); |
---|
| 145 | + if (IS_ERR(regmap)) |
---|
| 146 | + regmap = NULL; |
---|
| 147 | + } |
---|
146 | 148 | |
---|
147 | 149 | return regmap; |
---|
148 | 150 | } |
---|
.. | .. |
---|
151 | 153 | /* always called with process context; sleeping is OK */ |
---|
152 | 154 | |
---|
153 | 155 | |
---|
154 | | -/** |
---|
| 156 | +/* |
---|
155 | 157 | * usb_hcd_at91_probe - initialize AT91-based HCDs |
---|
156 | 158 | * Context: !in_interrupt() |
---|
157 | 159 | * |
---|
.. | .. |
---|
242 | 244 | |
---|
243 | 245 | /* may be called with controller, bus, and devices active */ |
---|
244 | 246 | |
---|
245 | | -/** |
---|
| 247 | +/* |
---|
246 | 248 | * usb_hcd_at91_remove - shutdown processing for AT91-based HCDs |
---|
247 | | - * @dev: USB Host Controller being removed |
---|
248 | 249 | * Context: !in_interrupt() |
---|
249 | 250 | * |
---|
250 | 251 | * Reverses the effect of usb_hcd_at91_probe(), first invoking |
---|
.. | .. |
---|
605 | 606 | if (ohci_at91->wakeup) |
---|
606 | 607 | enable_irq_wake(hcd->irq); |
---|
607 | 608 | |
---|
608 | | - ohci_at91_port_suspend(ohci_at91->sfr_regmap, 1); |
---|
609 | | - |
---|
610 | 609 | ret = ohci_suspend(hcd, ohci_at91->wakeup); |
---|
611 | 610 | if (ret) { |
---|
612 | 611 | if (ohci_at91->wakeup) |
---|
.. | .. |
---|
625 | 624 | |
---|
626 | 625 | /* flush the writes */ |
---|
627 | 626 | (void) ohci_readl (ohci, &ohci->regs->control); |
---|
| 627 | + msleep(1); |
---|
| 628 | + ohci_at91_port_suspend(ohci_at91->sfr_regmap, 1); |
---|
628 | 629 | at91_stop_clock(ohci_at91); |
---|
| 630 | + } else { |
---|
| 631 | + ohci_at91_port_suspend(ohci_at91->sfr_regmap, 1); |
---|
629 | 632 | } |
---|
630 | 633 | |
---|
631 | 634 | return ret; |
---|
.. | .. |
---|
637 | 640 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
---|
638 | 641 | struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); |
---|
639 | 642 | |
---|
| 643 | + ohci_at91_port_suspend(ohci_at91->sfr_regmap, 0); |
---|
| 644 | + |
---|
640 | 645 | if (ohci_at91->wakeup) |
---|
641 | 646 | disable_irq_wake(hcd->irq); |
---|
| 647 | + else |
---|
| 648 | + at91_start_clock(ohci_at91); |
---|
642 | 649 | |
---|
643 | | - at91_start_clock(ohci_at91); |
---|
644 | | - |
---|
645 | | - ohci_resume(hcd, false); |
---|
646 | | - |
---|
647 | | - ohci_at91_port_suspend(ohci_at91->sfr_regmap, 0); |
---|
| 650 | + /* |
---|
| 651 | + * According to the comment in ohci_hcd_at91_drv_suspend() |
---|
| 652 | + * we need to do a reset if the 48Mhz clock was stopped, |
---|
| 653 | + * that is, if ohci_at91->wakeup is clear. Tell ohci_resume() |
---|
| 654 | + * to reset in this case by setting its "hibernated" flag. |
---|
| 655 | + */ |
---|
| 656 | + ohci_resume(hcd, !ohci_at91->wakeup); |
---|
648 | 657 | |
---|
649 | 658 | return 0; |
---|
650 | 659 | } |
---|