diff options
Diffstat (limited to 'drivers/usb/host/fsl-mph-dr-of.c')
-rw-r--r-- | drivers/usb/host/fsl-mph-dr-of.c | 89 |
1 files changed, 89 insertions, 0 deletions
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 | ||
19 | struct fsl_usb2_dev_data { | 20 | struct 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 | |||
213 | int 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 | |||
253 | static 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 | |||
265 | struct 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 | |||
189 | static const struct of_device_id fsl_usb2_mph_dr_of_match[] = { | 275 | static 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 | ||