aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-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/ohci-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/ohci-au1xxx.c')
-rw-r--r--drivers/usb/host/ohci-au1xxx.c110
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
69extern int usb_disabled(void); 27extern int usb_disabled(void);
70 28
71static 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
99static 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
112static int __devinit ohci_au1xxx_start(struct usb_hcd *hcd) 29static 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);
139err3:
228 iounmap(hcd->regs); 140 iounmap(hcd->regs);
229err2: 141err2:
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);
279bail: 191bail:
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);