diff options
author | Manuel Lauss <manuel.lauss@googlemail.com> | 2011-08-12 14:12:33 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2011-10-24 18:34:23 -0400 |
commit | ce6bc92285cabd0df1f154a9ef5aeb937b6de57e (patch) | |
tree | fc2313d5a921624d512020ab5825861b6b3e1f8b /drivers/usb/host/ohci-au1xxx.c | |
parent | 694b8c35e95078bfe1cb1388bf0cf7942e32f009 (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/ohci-au1xxx.c')
-rw-r--r-- | drivers/usb/host/ohci-au1xxx.c | 110 |
1 files changed, 11 insertions, 99 deletions
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 958d985f2951..299d719495f1 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c | |||
@@ -23,92 +23,9 @@ | |||
23 | 23 | ||
24 | #include <asm/mach-au1x00/au1000.h> | 24 | #include <asm/mach-au1x00/au1000.h> |
25 | 25 | ||
26 | #ifndef CONFIG_SOC_AU1200 | ||
27 | |||
28 | #define USBH_ENABLE_BE (1<<0) | ||
29 | #define USBH_ENABLE_C (1<<1) | ||
30 | #define USBH_ENABLE_E (1<<2) | ||
31 | #define USBH_ENABLE_CE (1<<3) | ||
32 | #define USBH_ENABLE_RD (1<<4) | ||
33 | |||
34 | #ifdef __LITTLE_ENDIAN | ||
35 | #define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C) | ||
36 | #elif defined(__BIG_ENDIAN) | ||
37 | #define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | \ | ||
38 | USBH_ENABLE_BE) | ||
39 | #else | ||
40 | #error not byte order defined | ||
41 | #endif | ||
42 | |||
43 | #else /* Au1200 */ | ||
44 | |||
45 | #define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG) | ||
46 | #define USB_MCFG_PFEN (1<<31) | ||
47 | #define USB_MCFG_RDCOMB (1<<30) | ||
48 | #define USB_MCFG_SSDEN (1<<23) | ||
49 | #define USB_MCFG_OHCCLKEN (1<<16) | ||
50 | #ifdef CONFIG_DMA_COHERENT | ||
51 | #define USB_MCFG_UCAM (1<<7) | ||
52 | #else | ||
53 | #define USB_MCFG_UCAM (0) | ||
54 | #endif | ||
55 | #define USB_MCFG_OBMEN (1<<1) | ||
56 | #define USB_MCFG_OMEMEN (1<<0) | ||
57 | |||
58 | #define USBH_ENABLE_CE USB_MCFG_OHCCLKEN | ||
59 | |||
60 | #define USBH_ENABLE_INIT (USB_MCFG_PFEN | USB_MCFG_RDCOMB | \ | ||
61 | USBH_ENABLE_CE | USB_MCFG_SSDEN | \ | ||
62 | USB_MCFG_UCAM | \ | ||
63 | USB_MCFG_OBMEN | USB_MCFG_OMEMEN) | ||
64 | |||
65 | #define USBH_DISABLE (USB_MCFG_OBMEN | USB_MCFG_OMEMEN) | ||
66 | |||
67 | #endif /* Au1200 */ | ||
68 | 26 | ||
69 | extern int usb_disabled(void); | 27 | extern int usb_disabled(void); |
70 | 28 | ||
71 | static void au1xxx_start_ohc(void) | ||
72 | { | ||
73 | /* enable host controller */ | ||
74 | #ifndef CONFIG_SOC_AU1200 | ||
75 | au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG); | ||
76 | au_sync(); | ||
77 | udelay(1000); | ||
78 | |||
79 | au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG); | ||
80 | au_sync(); | ||
81 | udelay(1000); | ||
82 | |||
83 | /* wait for reset complete (read register twice; see au1500 errata) */ | ||
84 | while (au_readl(USB_HOST_CONFIG), | ||
85 | !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD)) | ||
86 | udelay(1000); | ||
87 | |||
88 | #else /* Au1200 */ | ||
89 | au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_CE, USB_HOST_CONFIG); | ||
90 | au_sync(); | ||
91 | udelay(1000); | ||
92 | |||
93 | au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG); | ||
94 | au_sync(); | ||
95 | udelay(2000); | ||
96 | #endif /* Au1200 */ | ||
97 | } | ||
98 | |||
99 | static void au1xxx_stop_ohc(void) | ||
100 | { | ||
101 | #ifdef CONFIG_SOC_AU1200 | ||
102 | /* Disable mem */ | ||
103 | au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_DISABLE, USB_HOST_CONFIG); | ||
104 | au_sync(); | ||
105 | udelay(1000); | ||
106 | #endif | ||
107 | /* Disable clock */ | ||
108 | au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG); | ||
109 | au_sync(); | ||
110 | } | ||
111 | |||
112 | static int __devinit ohci_au1xxx_start(struct usb_hcd *hcd) | 29 | static int __devinit ohci_au1xxx_start(struct usb_hcd *hcd) |
113 | { | 30 | { |
114 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | 31 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
@@ -178,17 +95,6 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | |||
178 | if (usb_disabled()) | 95 | if (usb_disabled()) |
179 | return -ENODEV; | 96 | return -ENODEV; |
180 | 97 | ||
181 | #if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT) | ||
182 | /* Au1200 AB USB does not support coherent memory */ | ||
183 | if (!(read_c0_prid() & 0xff)) { | ||
184 | printk(KERN_INFO "%s: this is chip revision AB !!\n", | ||
185 | pdev->name); | ||
186 | printk(KERN_INFO "%s: update your board or re-configure " | ||
187 | "the kernel\n", pdev->name); | ||
188 | return -ENODEV; | ||
189 | } | ||
190 | #endif | ||
191 | |||
192 | if (pdev->resource[1].flags != IORESOURCE_IRQ) { | 98 | if (pdev->resource[1].flags != IORESOURCE_IRQ) { |
193 | pr_debug("resource[1] is not IORESOURCE_IRQ\n"); | 99 | pr_debug("resource[1] is not IORESOURCE_IRQ\n"); |
194 | return -ENOMEM; | 100 | return -ENOMEM; |
@@ -214,7 +120,12 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | |||
214 | goto err2; | 120 | goto err2; |
215 | } | 121 | } |
216 | 122 | ||
217 | au1xxx_start_ohc(); | 123 | if (alchemy_usb_control(ALCHEMY_USB_OHCI0, 1)) { |
124 | printk(KERN_INFO "%s: controller init failed!\n", pdev->name); | ||
125 | ret = -ENODEV; | ||
126 | goto err3; | ||
127 | } | ||
128 | |||
218 | ohci_hcd_init(hcd_to_ohci(hcd)); | 129 | ohci_hcd_init(hcd_to_ohci(hcd)); |
219 | 130 | ||
220 | ret = usb_add_hcd(hcd, pdev->resource[1].start, | 131 | ret = usb_add_hcd(hcd, pdev->resource[1].start, |
@@ -224,7 +135,8 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | |||
224 | return ret; | 135 | return ret; |
225 | } | 136 | } |
226 | 137 | ||
227 | au1xxx_stop_ohc(); | 138 | alchemy_usb_control(ALCHEMY_USB_OHCI0, 0); |
139 | err3: | ||
228 | iounmap(hcd->regs); | 140 | iounmap(hcd->regs); |
229 | err2: | 141 | err2: |
230 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 142 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
@@ -238,7 +150,7 @@ static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev) | |||
238 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 150 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
239 | 151 | ||
240 | usb_remove_hcd(hcd); | 152 | usb_remove_hcd(hcd); |
241 | au1xxx_stop_ohc(); | 153 | alchemy_usb_control(ALCHEMY_USB_OHCI0, 0); |
242 | iounmap(hcd->regs); | 154 | iounmap(hcd->regs); |
243 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 155 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
244 | usb_put_hcd(hcd); | 156 | usb_put_hcd(hcd); |
@@ -275,7 +187,7 @@ static int ohci_hcd_au1xxx_drv_suspend(struct device *dev) | |||
275 | 187 | ||
276 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 188 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
277 | 189 | ||
278 | au1xxx_stop_ohc(); | 190 | alchemy_usb_control(ALCHEMY_USB_OHCI0, 0); |
279 | bail: | 191 | bail: |
280 | spin_unlock_irqrestore(&ohci->lock, flags); | 192 | spin_unlock_irqrestore(&ohci->lock, flags); |
281 | 193 | ||
@@ -286,7 +198,7 @@ static int ohci_hcd_au1xxx_drv_resume(struct device *dev) | |||
286 | { | 198 | { |
287 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 199 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
288 | 200 | ||
289 | au1xxx_start_ohc(); | 201 | alchemy_usb_control(ALCHEMY_USB_OHCI0, 1); |
290 | 202 | ||
291 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 203 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
292 | ohci_finish_controller_resume(hcd); | 204 | ohci_finish_controller_resume(hcd); |