aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/usb.txt22
-rw-r--r--drivers/usb/Kconfig1
-rw-r--r--drivers/usb/host/Kconfig6
-rw-r--r--drivers/usb/host/ehci-fsl.c99
-rw-r--r--drivers/usb/host/ehci-fsl.h13
-rw-r--r--drivers/usb/host/ehci-mem.c2
-rw-r--r--drivers/usb/host/fsl-mph-dr-of.c89
-rw-r--r--include/linux/fsl_devices.h15
8 files changed, 215 insertions, 32 deletions
diff --git a/Documentation/powerpc/dts-bindings/fsl/usb.txt b/Documentation/powerpc/dts-bindings/fsl/usb.txt
index b00152402694..bd5723f0b67e 100644
--- a/Documentation/powerpc/dts-bindings/fsl/usb.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/usb.txt
@@ -8,6 +8,7 @@ and additions :
8Required properties : 8Required properties :
9 - compatible : Should be "fsl-usb2-mph" for multi port host USB 9 - compatible : Should be "fsl-usb2-mph" for multi port host USB
10 controllers, or "fsl-usb2-dr" for dual role USB controllers 10 controllers, or "fsl-usb2-dr" for dual role USB controllers
11 or "fsl,mpc5121-usb2-dr" for dual role USB controllers of MPC5121
11 - phy_type : For multi port host USB controllers, should be one of 12 - phy_type : For multi port host USB controllers, should be one of
12 "ulpi", or "serial". For dual role USB controllers, should be 13 "ulpi", or "serial". For dual role USB controllers, should be
13 one of "ulpi", "utmi", "utmi_wide", or "serial". 14 one of "ulpi", "utmi", "utmi_wide", or "serial".
@@ -33,6 +34,12 @@ Recommended properties :
33 - interrupt-parent : the phandle for the interrupt controller that 34 - interrupt-parent : the phandle for the interrupt controller that
34 services interrupts for this device. 35 services interrupts for this device.
35 36
37Optional properties :
38 - fsl,invert-drvvbus : boolean; for MPC5121 USB0 only. Indicates the
39 port power polarity of internal PHY signal DRVVBUS is inverted.
40 - fsl,invert-pwr-fault : boolean; for MPC5121 USB0 only. Indicates
41 the PWR_FAULT signal polarity is inverted.
42
36Example multi port host USB controller device node : 43Example multi port host USB controller device node :
37 usb@22000 { 44 usb@22000 {
38 compatible = "fsl-usb2-mph"; 45 compatible = "fsl-usb2-mph";
@@ -57,3 +64,18 @@ Example dual role USB controller device node :
57 dr_mode = "otg"; 64 dr_mode = "otg";
58 phy = "ulpi"; 65 phy = "ulpi";
59 }; 66 };
67
68Example dual role USB controller device node for MPC5121ADS:
69
70 usb@4000 {
71 compatible = "fsl,mpc5121-usb2-dr";
72 reg = <0x4000 0x1000>;
73 #address-cells = <1>;
74 #size-cells = <0>;
75 interrupt-parent = < &ipic >;
76 interrupts = <44 0x8>;
77 dr_mode = "otg";
78 phy_type = "utmi_wide";
79 fsl,invert-drvvbus;
80 fsl,invert-pwr-fault;
81 };
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 4aa00e6e57ad..67eb3770868f 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -59,6 +59,7 @@ config USB_ARCH_HAS_OHCI
59config USB_ARCH_HAS_EHCI 59config USB_ARCH_HAS_EHCI
60 boolean 60 boolean
61 default y if PPC_83xx 61 default y if PPC_83xx
62 default y if PPC_MPC512x
62 default y if SOC_AU1200 63 default y if SOC_AU1200
63 default y if ARCH_IXP4XX 64 default y if ARCH_IXP4XX
64 default y if ARCH_W90X900 65 default y if ARCH_W90X900
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index f3a90b0fc422..bf2e7d234533 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -93,12 +93,14 @@ config USB_EHCI_TT_NEWSCHED
93 93
94config USB_EHCI_BIG_ENDIAN_MMIO 94config USB_EHCI_BIG_ENDIAN_MMIO
95 bool 95 bool
96 depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX) 96 depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX || \
97 XPS_USB_HCD_XILINX || PPC_MPC512x)
97 default y 98 default y
98 99
99config USB_EHCI_BIG_ENDIAN_DESC 100config USB_EHCI_BIG_ENDIAN_DESC
100 bool 101 bool
101 depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX) 102 depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
103 PPC_MPC512x)
102 default y 104 default y
103 105
104config XPS_USB_HCD_XILINX 106config XPS_USB_HCD_XILINX
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 8600317bd60b..86e42892016d 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -116,13 +116,33 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
116 goto err3; 116 goto err3;
117 } 117 }
118 118
119 /* Enable USB controller */ 119 pdata->regs = hcd->regs;
120 temp = in_be32(hcd->regs + 0x500);
121 out_be32(hcd->regs + 0x500, temp | 0x4);
122 120
123 /* Set to Host mode */ 121 /*
124 temp = in_le32(hcd->regs + 0x1a8); 122 * do platform specific init: check the clock, grab/config pins, etc.
125 out_le32(hcd->regs + 0x1a8, temp | 0x3); 123 */
124 if (pdata->init && pdata->init(pdev)) {
125 retval = -ENODEV;
126 goto err3;
127 }
128
129 /*
130 * Check if it is MPC5121 SoC, otherwise set pdata->have_sysif_regs
131 * flag for 83xx or 8536 system interface registers.
132 */
133 if (pdata->big_endian_mmio)
134 temp = in_be32(hcd->regs + FSL_SOC_USB_ID);
135 else
136 temp = in_le32(hcd->regs + FSL_SOC_USB_ID);
137
138 if ((temp & ID_MSK) != (~((temp & NID_MSK) >> 8) & ID_MSK))
139 pdata->have_sysif_regs = 1;
140
141 /* Enable USB controller, 83xx or 8536 */
142 if (pdata->have_sysif_regs)
143 setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4);
144
145 /* Don't need to set host mode here. It will be done by tdi_reset() */
126 146
127 retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); 147 retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
128 if (retval != 0) 148 if (retval != 0)
@@ -137,6 +157,8 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
137 usb_put_hcd(hcd); 157 usb_put_hcd(hcd);
138 err1: 158 err1:
139 dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval); 159 dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
160 if (pdata->exit)
161 pdata->exit(pdev);
140 return retval; 162 return retval;
141} 163}
142 164
@@ -154,17 +176,30 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
154static void usb_hcd_fsl_remove(struct usb_hcd *hcd, 176static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
155 struct platform_device *pdev) 177 struct platform_device *pdev)
156{ 178{
179 struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
180
157 usb_remove_hcd(hcd); 181 usb_remove_hcd(hcd);
182
183 /*
184 * do platform specific un-initialization:
185 * release iomux pins, disable clock, etc.
186 */
187 if (pdata->exit)
188 pdata->exit(pdev);
158 iounmap(hcd->regs); 189 iounmap(hcd->regs);
159 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 190 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
160 usb_put_hcd(hcd); 191 usb_put_hcd(hcd);
161} 192}
162 193
163static void mpc83xx_setup_phy(struct ehci_hcd *ehci, 194static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
164 enum fsl_usb2_phy_modes phy_mode, 195 enum fsl_usb2_phy_modes phy_mode,
165 unsigned int port_offset) 196 unsigned int port_offset)
166{ 197{
167 u32 portsc = 0; 198 u32 portsc;
199
200 portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
201 portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
202
168 switch (phy_mode) { 203 switch (phy_mode) {
169 case FSL_USB2_PHY_ULPI: 204 case FSL_USB2_PHY_ULPI:
170 portsc |= PORT_PTS_ULPI; 205 portsc |= PORT_PTS_ULPI;
@@ -184,20 +219,21 @@ static void mpc83xx_setup_phy(struct ehci_hcd *ehci,
184 ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); 219 ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]);
185} 220}
186 221
187static void mpc83xx_usb_setup(struct usb_hcd *hcd) 222static void ehci_fsl_usb_setup(struct ehci_hcd *ehci)
188{ 223{
189 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 224 struct usb_hcd *hcd = ehci_to_hcd(ehci);
190 struct fsl_usb2_platform_data *pdata; 225 struct fsl_usb2_platform_data *pdata;
191 void __iomem *non_ehci = hcd->regs; 226 void __iomem *non_ehci = hcd->regs;
192 u32 temp; 227 u32 temp;
193 228
194 pdata = 229 pdata = hcd->self.controller->platform_data;
195 (struct fsl_usb2_platform_data *)hcd->self.controller-> 230
196 platform_data;
197 /* Enable PHY interface in the control reg. */ 231 /* Enable PHY interface in the control reg. */
198 temp = in_be32(non_ehci + FSL_SOC_USB_CTRL); 232 if (pdata->have_sysif_regs) {
199 out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | 0x00000004); 233 temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
200 out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b); 234 out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | 0x00000004);
235 out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b);
236 }
201 237
202#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) 238#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
203 /* 239 /*
@@ -214,7 +250,7 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
214 250
215 if ((pdata->operating_mode == FSL_USB2_DR_HOST) || 251 if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
216 (pdata->operating_mode == FSL_USB2_DR_OTG)) 252 (pdata->operating_mode == FSL_USB2_DR_OTG))
217 mpc83xx_setup_phy(ehci, pdata->phy_mode, 0); 253 ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
218 254
219 if (pdata->operating_mode == FSL_USB2_MPH_HOST) { 255 if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
220 unsigned int chip, rev, svr; 256 unsigned int chip, rev, svr;
@@ -228,25 +264,27 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
228 ehci->has_fsl_port_bug = 1; 264 ehci->has_fsl_port_bug = 1;
229 265
230 if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) 266 if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
231 mpc83xx_setup_phy(ehci, pdata->phy_mode, 0); 267 ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0);
232 if (pdata->port_enables & FSL_USB2_PORT1_ENABLED) 268 if (pdata->port_enables & FSL_USB2_PORT1_ENABLED)
233 mpc83xx_setup_phy(ehci, pdata->phy_mode, 1); 269 ehci_fsl_setup_phy(ehci, pdata->phy_mode, 1);
234 } 270 }
235 271
272 if (pdata->have_sysif_regs) {
236#ifdef CONFIG_PPC_85xx 273#ifdef CONFIG_PPC_85xx
237 out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x00000008); 274 out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x00000008);
238 out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000080); 275 out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000080);
239#else 276#else
240 out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c); 277 out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c);
241 out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040); 278 out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040);
242#endif 279#endif
243 out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001); 280 out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001);
281 }
244} 282}
245 283
246/* called after powerup, by probe or system-pm "wakeup" */ 284/* called after powerup, by probe or system-pm "wakeup" */
247static int ehci_fsl_reinit(struct ehci_hcd *ehci) 285static int ehci_fsl_reinit(struct ehci_hcd *ehci)
248{ 286{
249 mpc83xx_usb_setup(ehci_to_hcd(ehci)); 287 ehci_fsl_usb_setup(ehci);
250 ehci_port_power(ehci, 0); 288 ehci_port_power(ehci, 0);
251 289
252 return 0; 290 return 0;
@@ -257,6 +295,11 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
257{ 295{
258 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 296 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
259 int retval; 297 int retval;
298 struct fsl_usb2_platform_data *pdata;
299
300 pdata = hcd->self.controller->platform_data;
301 ehci->big_endian_desc = pdata->big_endian_desc;
302 ehci->big_endian_mmio = pdata->big_endian_mmio;
260 303
261 /* EHCI registers start at offset 0x100 */ 304 /* EHCI registers start at offset 0x100 */
262 ehci->caps = hcd->regs + 0x100; 305 ehci->caps = hcd->regs + 0x100;
@@ -370,7 +413,7 @@ static const struct hc_driver ehci_fsl_hc_driver = {
370 * generic hardware linkage 413 * generic hardware linkage
371 */ 414 */
372 .irq = ehci_irq, 415 .irq = ehci_irq,
373 .flags = HCD_USB2, 416 .flags = HCD_USB2 | HCD_MEMORY,
374 417
375 /* 418 /*
376 * basic lifecycle operations 419 * basic lifecycle operations
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h
index eb537aa54610..2c8353795226 100644
--- a/drivers/usb/host/ehci-fsl.h
+++ b/drivers/usb/host/ehci-fsl.h
@@ -1,4 +1,4 @@
1/* Copyright (c) 2005 freescale semiconductor 1/* Copyright (C) 2005-2010 Freescale Semiconductor, Inc.
2 * Copyright (c) 2005 MontaVista Software 2 * Copyright (c) 2005 MontaVista Software
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
@@ -19,6 +19,9 @@
19#define _EHCI_FSL_H 19#define _EHCI_FSL_H
20 20
21/* offsets for the non-ehci registers in the FSL SOC USB controller */ 21/* offsets for the non-ehci registers in the FSL SOC USB controller */
22#define FSL_SOC_USB_ID 0x0
23#define ID_MSK 0x3f
24#define NID_MSK 0x3f00
22#define FSL_SOC_USB_ULPIVP 0x170 25#define FSL_SOC_USB_ULPIVP 0x170
23#define FSL_SOC_USB_PORTSC1 0x184 26#define FSL_SOC_USB_PORTSC1 0x184
24#define PORT_PTS_MSK (3<<30) 27#define PORT_PTS_MSK (3<<30)
@@ -27,6 +30,14 @@
27#define PORT_PTS_SERIAL (3<<30) 30#define PORT_PTS_SERIAL (3<<30)
28#define PORT_PTS_PTW (1<<28) 31#define PORT_PTS_PTW (1<<28)
29#define FSL_SOC_USB_PORTSC2 0x188 32#define FSL_SOC_USB_PORTSC2 0x188
33
34#define FSL_SOC_USB_USBGENCTRL 0x200
35#define USBGENCTRL_PPP (1 << 3)
36#define USBGENCTRL_PFP (1 << 2)
37#define FSL_SOC_USB_ISIPHYCTRL 0x204
38#define ISIPHYCTRL_PXE (1)
39#define ISIPHYCTRL_PHYE (1 << 4)
40
30#define FSL_SOC_USB_SNOOP1 0x400 /* NOTE: big-endian */ 41#define FSL_SOC_USB_SNOOP1 0x400 /* NOTE: big-endian */
31#define FSL_SOC_USB_SNOOP2 0x404 /* NOTE: big-endian */ 42#define FSL_SOC_USB_SNOOP2 0x404 /* NOTE: big-endian */
32#define FSL_SOC_USB_AGECNTTHRSH 0x408 /* NOTE: big-endian */ 43#define FSL_SOC_USB_AGECNTTHRSH 0x408 /* NOTE: big-endian */
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
index 1f3f01eacaf0..d36e4e75e08d 100644
--- a/drivers/usb/host/ehci-mem.c
+++ b/drivers/usb/host/ehci-mem.c
@@ -40,7 +40,7 @@ static inline void ehci_qtd_init(struct ehci_hcd *ehci, struct ehci_qtd *qtd,
40{ 40{
41 memset (qtd, 0, sizeof *qtd); 41 memset (qtd, 0, sizeof *qtd);
42 qtd->qtd_dma = dma; 42 qtd->qtd_dma = dma;
43 qtd->hw_token = cpu_to_le32 (QTD_STS_HALT); 43 qtd->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT);
44 qtd->hw_next = EHCI_LIST_END(ehci); 44 qtd->hw_next = EHCI_LIST_END(ehci);
45 qtd->hw_alt_next = EHCI_LIST_END(ehci); 45 qtd->hw_alt_next = EHCI_LIST_END(ehci);
46 INIT_LIST_HEAD (&qtd->qtd_list); 46 INIT_LIST_HEAD (&qtd->qtd_list);
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
index 12db5d5cb0bc..574b99ea0700 100644
--- a/drivers/usb/host/fsl-mph-dr-of.c
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -15,6 +15,7 @@
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/of_platform.h> 17#include <linux/of_platform.h>
18#include <linux/clk.h>
18 19
19struct fsl_usb2_dev_data { 20struct fsl_usb2_dev_data {
20 char *dr_mode; /* controller mode */ 21 char *dr_mode; /* controller mode */
@@ -153,6 +154,12 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
153 154
154 pdata->operating_mode = FSL_USB2_MPH_HOST; 155 pdata->operating_mode = FSL_USB2_MPH_HOST;
155 } else { 156 } else {
157 if (of_get_property(np, "fsl,invert-drvvbus", NULL))
158 pdata->invert_drvvbus = 1;
159
160 if (of_get_property(np, "fsl,invert-pwr-fault", NULL))
161 pdata->invert_pwr_fault = 1;
162
156 /* setup mode selected in the device tree */ 163 /* setup mode selected in the device tree */
157 pdata->operating_mode = dev_data->op_mode; 164 pdata->operating_mode = dev_data->op_mode;
158 } 165 }
@@ -186,9 +193,91 @@ static int __devexit fsl_usb2_mph_dr_of_remove(struct platform_device *ofdev)
186 return 0; 193 return 0;
187} 194}
188 195
196#ifdef CONFIG_PPC_MPC512x
197
198#define USBGENCTRL 0x200 /* NOTE: big endian */
199#define GC_WU_INT_CLR (1 << 5) /* Wakeup int clear */
200#define GC_ULPI_SEL (1 << 4) /* ULPI i/f select (usb0 only)*/
201#define GC_PPP (1 << 3) /* Inv. Port Power Polarity */
202#define GC_PFP (1 << 2) /* Inv. Power Fault Polarity */
203#define GC_WU_ULPI_EN (1 << 1) /* Wakeup on ULPI event */
204#define GC_WU_IE (1 << 1) /* Wakeup interrupt enable */
205
206#define ISIPHYCTRL 0x204 /* NOTE: big endian */
207#define PHYCTRL_PHYE (1 << 4) /* On-chip UTMI PHY enable */
208#define PHYCTRL_BSENH (1 << 3) /* Bit Stuff Enable High */
209#define PHYCTRL_BSEN (1 << 2) /* Bit Stuff Enable */
210#define PHYCTRL_LSFE (1 << 1) /* Line State Filter Enable */
211#define PHYCTRL_PXE (1 << 0) /* PHY oscillator enable */
212
213int fsl_usb2_mpc5121_init(struct platform_device *pdev)
214{
215 struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
216 struct clk *clk;
217 char clk_name[10];
218 int base, clk_num;
219
220 base = pdev->resource->start & 0xf000;
221 if (base == 0x3000)
222 clk_num = 1;
223 else if (base == 0x4000)
224 clk_num = 2;
225 else
226 return -ENODEV;
227
228 snprintf(clk_name, sizeof(clk_name), "usb%d_clk", clk_num);
229 clk = clk_get(&pdev->dev, clk_name);
230 if (IS_ERR(clk)) {
231 dev_err(&pdev->dev, "failed to get clk\n");
232 return PTR_ERR(clk);
233 }
234
235 clk_enable(clk);
236 pdata->clk = clk;
237
238 if (pdata->phy_mode == FSL_USB2_PHY_UTMI_WIDE) {
239 u32 reg = 0;
240
241 if (pdata->invert_drvvbus)
242 reg |= GC_PPP;
243
244 if (pdata->invert_pwr_fault)
245 reg |= GC_PFP;
246
247 out_be32(pdata->regs + ISIPHYCTRL, PHYCTRL_PHYE | PHYCTRL_PXE);
248 out_be32(pdata->regs + USBGENCTRL, reg);
249 }
250 return 0;
251}
252
253static void fsl_usb2_mpc5121_exit(struct platform_device *pdev)
254{
255 struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
256
257 pdata->regs = NULL;
258
259 if (pdata->clk) {
260 clk_disable(pdata->clk);
261 clk_put(pdata->clk);
262 }
263}
264
265struct fsl_usb2_platform_data fsl_usb2_mpc5121_pd = {
266 .big_endian_desc = 1,
267 .big_endian_mmio = 1,
268 .es = 1,
269 .le_setup_buf = 1,
270 .init = fsl_usb2_mpc5121_init,
271 .exit = fsl_usb2_mpc5121_exit,
272};
273#endif /* CONFIG_PPC_MPC512x */
274
189static const struct of_device_id fsl_usb2_mph_dr_of_match[] = { 275static const struct of_device_id fsl_usb2_mph_dr_of_match[] = {
190 { .compatible = "fsl-usb2-mph", }, 276 { .compatible = "fsl-usb2-mph", },
191 { .compatible = "fsl-usb2-dr", }, 277 { .compatible = "fsl-usb2-dr", },
278#ifdef CONFIG_PPC_MPC512x
279 { .compatible = "fsl,mpc5121-usb2-dr", .data = &fsl_usb2_mpc5121_pd, },
280#endif
192 {}, 281 {},
193}; 282};
194 283
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 28e33fea5107..d5f9a7431bd0 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -58,11 +58,26 @@ enum fsl_usb2_phy_modes {
58 FSL_USB2_PHY_SERIAL, 58 FSL_USB2_PHY_SERIAL,
59}; 59};
60 60
61struct clk;
62struct platform_device;
63
61struct fsl_usb2_platform_data { 64struct fsl_usb2_platform_data {
62 /* board specific information */ 65 /* board specific information */
63 enum fsl_usb2_operating_modes operating_mode; 66 enum fsl_usb2_operating_modes operating_mode;
64 enum fsl_usb2_phy_modes phy_mode; 67 enum fsl_usb2_phy_modes phy_mode;
65 unsigned int port_enables; 68 unsigned int port_enables;
69
70 int (*init)(struct platform_device *);
71 void (*exit)(struct platform_device *);
72 void __iomem *regs; /* ioremap'd register base */
73 struct clk *clk;
74 unsigned big_endian_mmio:1;
75 unsigned big_endian_desc:1;
76 unsigned es:1; /* need USBMODE:ES */
77 unsigned le_setup_buf:1;
78 unsigned have_sysif_regs:1;
79 unsigned invert_drvvbus:1;
80 unsigned invert_pwr_fault:1;
66}; 81};
67 82
68/* Flags in fsl_usb2_mph_platform_data */ 83/* Flags in fsl_usb2_mph_platform_data */