aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-au1xxx.c
diff options
context:
space:
mode:
authorManuel Lauss <manuel.lauss@googlemail.com>2011-08-12 14:12:33 -0400
committerRalf Baechle <ralf@linux-mips.org>2011-10-24 18:34:23 -0400
commitce6bc92285cabd0df1f154a9ef5aeb937b6de57e (patch)
treefc2313d5a921624d512020ab5825861b6b3e1f8b /drivers/usb/host/ehci-au1xxx.c
parent694b8c35e95078bfe1cb1388bf0cf7942e32f009 (diff)
MIPS: Alchemy: abstract USB block control register access
Alchemy chips have one or more registers which control access to the usb blocks as well as PHY configuration. I don't want the OHCI/EHCI glues to know about the different registers and bits; new code hides the gory details of USB configuration from them. Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com> To: Linux-MIPS <linux-mips@linux-mips.org> Cc: linux-usb@vger.kernel.org Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Patchwork: https://patchwork.linux-mips.org/patch/2709/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org> create mode 100644 drivers/usb/host/alchemy-common.c
Diffstat (limited to 'drivers/usb/host/ehci-au1xxx.c')
-rw-r--r--drivers/usb/host/ehci-au1xxx.c77
1 files changed, 10 insertions, 67 deletions
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c
index 42ae57409908..e480dc17394d 100644
--- a/drivers/usb/host/ehci-au1xxx.c
+++ b/drivers/usb/host/ehci-au1xxx.c
@@ -14,61 +14,9 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <asm/mach-au1x00/au1000.h> 15#include <asm/mach-au1x00/au1000.h>
16 16
17#define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG)
18#define USB_MCFG_PFEN (1<<31)
19#define USB_MCFG_RDCOMB (1<<30)
20#define USB_MCFG_SSDEN (1<<23)
21#define USB_MCFG_PHYPLLEN (1<<19)
22#define USB_MCFG_UCECLKEN (1<<18)
23#define USB_MCFG_EHCCLKEN (1<<17)
24#ifdef CONFIG_DMA_COHERENT
25#define USB_MCFG_UCAM (1<<7)
26#else
27#define USB_MCFG_UCAM (0)
28#endif
29#define USB_MCFG_EBMEN (1<<3)
30#define USB_MCFG_EMEMEN (1<<2)
31
32#define USBH_ENABLE_CE (USB_MCFG_PHYPLLEN | USB_MCFG_EHCCLKEN)
33#define USBH_ENABLE_INIT (USB_MCFG_PFEN | USB_MCFG_RDCOMB | \
34 USBH_ENABLE_CE | USB_MCFG_SSDEN | \
35 USB_MCFG_UCAM | USB_MCFG_EBMEN | \
36 USB_MCFG_EMEMEN)
37
38#define USBH_DISABLE (USB_MCFG_EBMEN | USB_MCFG_EMEMEN)
39 17
40extern int usb_disabled(void); 18extern int usb_disabled(void);
41 19
42static void au1xxx_start_ehc(void)
43{
44 /* enable clock to EHCI block and HS PHY PLL*/
45 au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_CE, USB_HOST_CONFIG);
46 au_sync();
47 udelay(1000);
48
49 /* enable EHCI mmio */
50 au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG);
51 au_sync();
52 udelay(1000);
53}
54
55static void au1xxx_stop_ehc(void)
56{
57 unsigned long c;
58
59 /* Disable mem */
60 au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_DISABLE, USB_HOST_CONFIG);
61 au_sync();
62 udelay(1000);
63
64 /* Disable EHC clock. If the HS PHY is unused disable it too. */
65 c = au_readl(USB_HOST_CONFIG) & ~USB_MCFG_EHCCLKEN;
66 if (!(c & USB_MCFG_UCECLKEN)) /* UDC disabled? */
67 c &= ~USB_MCFG_PHYPLLEN; /* yes: disable HS PHY PLL */
68 au_writel(c, USB_HOST_CONFIG);
69 au_sync();
70}
71
72static int au1xxx_ehci_setup(struct usb_hcd *hcd) 20static int au1xxx_ehci_setup(struct usb_hcd *hcd)
73{ 21{
74 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 22 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
@@ -136,16 +84,6 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
136 if (usb_disabled()) 84 if (usb_disabled())
137 return -ENODEV; 85 return -ENODEV;
138 86
139#if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT)
140 /* Au1200 AB USB does not support coherent memory */
141 if (!(read_c0_prid() & 0xff)) {
142 printk(KERN_INFO "%s: this is chip revision AB!\n", pdev->name);
143 printk(KERN_INFO "%s: update your board or re-configure"
144 " the kernel\n", pdev->name);
145 return -ENODEV;
146 }
147#endif
148
149 if (pdev->resource[1].flags != IORESOURCE_IRQ) { 87 if (pdev->resource[1].flags != IORESOURCE_IRQ) {
150 pr_debug("resource[1] is not IORESOURCE_IRQ"); 88 pr_debug("resource[1] is not IORESOURCE_IRQ");
151 return -ENOMEM; 89 return -ENOMEM;
@@ -171,7 +109,11 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
171 goto err2; 109 goto err2;
172 } 110 }
173 111
174 au1xxx_start_ehc(); 112 if (alchemy_usb_control(ALCHEMY_USB_EHCI0, 1)) {
113 printk(KERN_INFO "%s: controller init failed!\n", pdev->name);
114 ret = -ENODEV;
115 goto err3;
116 }
175 117
176 ehci = hcd_to_ehci(hcd); 118 ehci = hcd_to_ehci(hcd);
177 ehci->caps = hcd->regs; 119 ehci->caps = hcd->regs;
@@ -187,7 +129,8 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
187 return ret; 129 return ret;
188 } 130 }
189 131
190 au1xxx_stop_ehc(); 132 alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
133err3:
191 iounmap(hcd->regs); 134 iounmap(hcd->regs);
192err2: 135err2:
193 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 136 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
@@ -201,10 +144,10 @@ static int ehci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
201 struct usb_hcd *hcd = platform_get_drvdata(pdev); 144 struct usb_hcd *hcd = platform_get_drvdata(pdev);
202 145
203 usb_remove_hcd(hcd); 146 usb_remove_hcd(hcd);
147 alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
204 iounmap(hcd->regs); 148 iounmap(hcd->regs);
205 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 149 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
206 usb_put_hcd(hcd); 150 usb_put_hcd(hcd);
207 au1xxx_stop_ehc();
208 platform_set_drvdata(pdev, NULL); 151 platform_set_drvdata(pdev, NULL);
209 152
210 return 0; 153 return 0;
@@ -236,7 +179,7 @@ static int ehci_hcd_au1xxx_drv_suspend(struct device *dev)
236 // could save FLADJ in case of Vaux power loss 179 // could save FLADJ in case of Vaux power loss
237 // ... we'd only use it to handle clock skew 180 // ... we'd only use it to handle clock skew
238 181
239 au1xxx_stop_ehc(); 182 alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
240 183
241 return rc; 184 return rc;
242} 185}
@@ -246,7 +189,7 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
246 struct usb_hcd *hcd = dev_get_drvdata(dev); 189 struct usb_hcd *hcd = dev_get_drvdata(dev);
247 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 190 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
248 191
249 au1xxx_start_ehc(); 192 alchemy_usb_control(ALCHEMY_USB_EHCI0, 1);
250 193
251 // maybe restore FLADJ 194 // maybe restore FLADJ
252 195