diff options
Diffstat (limited to 'drivers/usb/host/ohci-nxp.c')
-rw-r--r-- | drivers/usb/host/ohci-nxp.c | 88 |
1 files changed, 55 insertions, 33 deletions
diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c index 1e364ec962fb..a446386bf779 100644 --- a/drivers/usb/host/ohci-nxp.c +++ b/drivers/usb/host/ohci-nxp.c | |||
@@ -43,16 +43,6 @@ | |||
43 | #define USB_HOST_NEED_CLK_EN (1 << 21) | 43 | #define USB_HOST_NEED_CLK_EN (1 << 21) |
44 | #define PAD_CONTROL_LAST_DRIVEN (1 << 19) | 44 | #define PAD_CONTROL_LAST_DRIVEN (1 << 19) |
45 | 45 | ||
46 | #define USB_OTG_CLK_CTRL IO_ADDRESS(USB_CONFIG_BASE + 0xFF4) | ||
47 | #define USB_OTG_CLK_STAT IO_ADDRESS(USB_CONFIG_BASE + 0xFF8) | ||
48 | |||
49 | /* USB_OTG_CLK_CTRL bit defines */ | ||
50 | #define AHB_M_CLOCK_ON (1 << 4) | ||
51 | #define OTG_CLOCK_ON (1 << 3) | ||
52 | #define I2C_CLOCK_ON (1 << 2) | ||
53 | #define DEV_CLOCK_ON (1 << 1) | ||
54 | #define HOST_CLOCK_ON (1 << 0) | ||
55 | |||
56 | #define USB_OTG_STAT_CONTROL IO_ADDRESS(USB_CONFIG_BASE + 0x110) | 46 | #define USB_OTG_STAT_CONTROL IO_ADDRESS(USB_CONFIG_BASE + 0x110) |
57 | 47 | ||
58 | /* USB_OTG_STAT_CONTROL bit defines */ | 48 | /* USB_OTG_STAT_CONTROL bit defines */ |
@@ -72,7 +62,9 @@ static struct i2c_client *isp1301_i2c_client; | |||
72 | 62 | ||
73 | extern int usb_disabled(void); | 63 | extern int usb_disabled(void); |
74 | 64 | ||
75 | static struct clk *usb_clk; | 65 | static struct clk *usb_pll_clk; |
66 | static struct clk *usb_dev_clk; | ||
67 | static struct clk *usb_otg_clk; | ||
76 | 68 | ||
77 | static void isp1301_configure_pnx4008(void) | 69 | static void isp1301_configure_pnx4008(void) |
78 | { | 70 | { |
@@ -249,8 +241,6 @@ static const struct hc_driver ohci_nxp_hc_driver = { | |||
249 | .start_port_reset = ohci_start_port_reset, | 241 | .start_port_reset = ohci_start_port_reset, |
250 | }; | 242 | }; |
251 | 243 | ||
252 | #define USB_CLOCK_MASK (AHB_M_CLOCK_ON| OTG_CLOCK_ON | HOST_CLOCK_ON | I2C_CLOCK_ON) | ||
253 | |||
254 | static void nxp_set_usb_bits(void) | 244 | static void nxp_set_usb_bits(void) |
255 | { | 245 | { |
256 | if (machine_is_pnx4008()) { | 246 | if (machine_is_pnx4008()) { |
@@ -327,41 +317,63 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) | |||
327 | /* Enable AHB slave USB clock, needed for further USB clock control */ | 317 | /* Enable AHB slave USB clock, needed for further USB clock control */ |
328 | __raw_writel(USB_SLAVE_HCLK_EN | PAD_CONTROL_LAST_DRIVEN, USB_CTRL); | 318 | __raw_writel(USB_SLAVE_HCLK_EN | PAD_CONTROL_LAST_DRIVEN, USB_CTRL); |
329 | 319 | ||
330 | isp1301_configure(); | ||
331 | |||
332 | /* Enable USB PLL */ | 320 | /* Enable USB PLL */ |
333 | usb_clk = clk_get(&pdev->dev, "ck_pll5"); | 321 | usb_pll_clk = clk_get(&pdev->dev, "ck_pll5"); |
334 | if (IS_ERR(usb_clk)) { | 322 | if (IS_ERR(usb_pll_clk)) { |
335 | dev_err(&pdev->dev, "failed to acquire USB PLL\n"); | 323 | dev_err(&pdev->dev, "failed to acquire USB PLL\n"); |
336 | ret = PTR_ERR(usb_clk); | 324 | ret = PTR_ERR(usb_pll_clk); |
337 | goto out1; | 325 | goto out1; |
338 | } | 326 | } |
339 | 327 | ||
340 | ret = clk_enable(usb_clk); | 328 | ret = clk_enable(usb_pll_clk); |
341 | if (ret < 0) { | 329 | if (ret < 0) { |
342 | dev_err(&pdev->dev, "failed to start USB PLL\n"); | 330 | dev_err(&pdev->dev, "failed to start USB PLL\n"); |
343 | goto out2; | 331 | goto out2; |
344 | } | 332 | } |
345 | 333 | ||
346 | ret = clk_set_rate(usb_clk, 48000); | 334 | ret = clk_set_rate(usb_pll_clk, 48000); |
347 | if (ret < 0) { | 335 | if (ret < 0) { |
348 | dev_err(&pdev->dev, "failed to set USB clock rate\n"); | 336 | dev_err(&pdev->dev, "failed to set USB clock rate\n"); |
349 | goto out3; | 337 | goto out3; |
350 | } | 338 | } |
351 | 339 | ||
340 | /* Enable USB device clock */ | ||
341 | usb_dev_clk = clk_get(&pdev->dev, "ck_usbd"); | ||
342 | if (IS_ERR(usb_dev_clk)) { | ||
343 | dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n"); | ||
344 | ret = PTR_ERR(usb_dev_clk); | ||
345 | goto out4; | ||
346 | } | ||
347 | |||
348 | ret = clk_enable(usb_dev_clk); | ||
349 | if (ret < 0) { | ||
350 | dev_err(&pdev->dev, "failed to start USB DEV Clock\n"); | ||
351 | goto out5; | ||
352 | } | ||
353 | |||
354 | /* Enable USB otg clocks */ | ||
355 | usb_otg_clk = clk_get(&pdev->dev, "ck_usb_otg"); | ||
356 | if (IS_ERR(usb_otg_clk)) { | ||
357 | dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n"); | ||
358 | ret = PTR_ERR(usb_dev_clk); | ||
359 | goto out6; | ||
360 | } | ||
361 | |||
352 | __raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL); | 362 | __raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL); |
353 | 363 | ||
354 | /* Set to enable all needed USB clocks */ | 364 | ret = clk_enable(usb_otg_clk); |
355 | __raw_writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL); | 365 | if (ret < 0) { |
366 | dev_err(&pdev->dev, "failed to start USB DEV Clock\n"); | ||
367 | goto out7; | ||
368 | } | ||
356 | 369 | ||
357 | while ((__raw_readl(USB_OTG_CLK_STAT) & USB_CLOCK_MASK) != | 370 | isp1301_configure(); |
358 | USB_CLOCK_MASK) ; | ||
359 | 371 | ||
360 | hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); | 372 | hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); |
361 | if (!hcd) { | 373 | if (!hcd) { |
362 | dev_err(&pdev->dev, "Failed to allocate HC buffer\n"); | 374 | dev_err(&pdev->dev, "Failed to allocate HC buffer\n"); |
363 | ret = -ENOMEM; | 375 | ret = -ENOMEM; |
364 | goto out3; | 376 | goto out8; |
365 | } | 377 | } |
366 | 378 | ||
367 | /* Set all USB bits in the Start Enable register */ | 379 | /* Set all USB bits in the Start Enable register */ |
@@ -371,14 +383,14 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) | |||
371 | if (!res) { | 383 | if (!res) { |
372 | dev_err(&pdev->dev, "Failed to get MEM resource\n"); | 384 | dev_err(&pdev->dev, "Failed to get MEM resource\n"); |
373 | ret = -ENOMEM; | 385 | ret = -ENOMEM; |
374 | goto out4; | 386 | goto out8; |
375 | } | 387 | } |
376 | 388 | ||
377 | hcd->regs = devm_request_and_ioremap(&pdev->dev, res); | 389 | hcd->regs = devm_request_and_ioremap(&pdev->dev, res); |
378 | if (!hcd->regs) { | 390 | if (!hcd->regs) { |
379 | dev_err(&pdev->dev, "Failed to devm_request_and_ioremap\n"); | 391 | dev_err(&pdev->dev, "Failed to devm_request_and_ioremap\n"); |
380 | ret = -ENOMEM; | 392 | ret = -ENOMEM; |
381 | goto out4; | 393 | goto out8; |
382 | } | 394 | } |
383 | hcd->rsrc_start = res->start; | 395 | hcd->rsrc_start = res->start; |
384 | hcd->rsrc_len = resource_size(res); | 396 | hcd->rsrc_len = resource_size(res); |
@@ -386,7 +398,7 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) | |||
386 | irq = platform_get_irq(pdev, 0); | 398 | irq = platform_get_irq(pdev, 0); |
387 | if (irq < 0) { | 399 | if (irq < 0) { |
388 | ret = -ENXIO; | 400 | ret = -ENXIO; |
389 | goto out4; | 401 | goto out8; |
390 | } | 402 | } |
391 | 403 | ||
392 | nxp_start_hc(); | 404 | nxp_start_hc(); |
@@ -400,13 +412,21 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) | |||
400 | return ret; | 412 | return ret; |
401 | 413 | ||
402 | nxp_stop_hc(); | 414 | nxp_stop_hc(); |
403 | out4: | 415 | out8: |
404 | nxp_unset_usb_bits(); | 416 | nxp_unset_usb_bits(); |
405 | usb_put_hcd(hcd); | 417 | usb_put_hcd(hcd); |
418 | out7: | ||
419 | clk_disable(usb_otg_clk); | ||
420 | out6: | ||
421 | clk_put(usb_otg_clk); | ||
422 | out5: | ||
423 | clk_disable(usb_dev_clk); | ||
424 | out4: | ||
425 | clk_put(usb_dev_clk); | ||
406 | out3: | 426 | out3: |
407 | clk_disable(usb_clk); | 427 | clk_disable(usb_pll_clk); |
408 | out2: | 428 | out2: |
409 | clk_put(usb_clk); | 429 | clk_put(usb_pll_clk); |
410 | out1: | 430 | out1: |
411 | isp1301_i2c_client = NULL; | 431 | isp1301_i2c_client = NULL; |
412 | out: | 432 | out: |
@@ -422,8 +442,10 @@ static int usb_hcd_nxp_remove(struct platform_device *pdev) | |||
422 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 442 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
423 | usb_put_hcd(hcd); | 443 | usb_put_hcd(hcd); |
424 | nxp_unset_usb_bits(); | 444 | nxp_unset_usb_bits(); |
425 | clk_disable(usb_clk); | 445 | clk_disable(usb_pll_clk); |
426 | clk_put(usb_clk); | 446 | clk_put(usb_pll_clk); |
447 | clk_disable(usb_dev_clk); | ||
448 | clk_put(usb_dev_clk); | ||
427 | i2c_unregister_device(isp1301_i2c_client); | 449 | i2c_unregister_device(isp1301_i2c_client); |
428 | isp1301_i2c_client = NULL; | 450 | isp1301_i2c_client = NULL; |
429 | 451 | ||