diff options
author | Fabio Estevam <fabio.estevam@freescale.com> | 2012-06-15 17:39:02 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2012-06-22 06:09:52 -0400 |
commit | ba789170d251a3c47854cee8a492d8ba7345f468 (patch) | |
tree | 430b6634ad1da50e4fec9e2413cbf1966d6f8deb /drivers/usb/gadget | |
parent | 3d4eb9dfa3e89a09cdaaf3d0465479475e4afb0c (diff) |
usb: gadget: fsl_mxc_udc: do not depend on grouped clocks
With the new common clock infrastructure, the following clocks should be
used on i.MX drivers: ipg, per and ahb.
Adapt fsl_mxc_udc to follow this new behaviour to fix the following probe error:
Freescale High-Speed USB SOC Device Controller driver (Apr 20, 2007)
fsl-usb2-udc fsl-usb2-udc: clk_get("usb") failed
fsl-usb2-udc: probe of fsl-usb2-udc failed with error -2
Reported-by: Christoph Fritz <chf.fritz@googlemail.com>
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/fsl_mxc_udc.c | 74 |
1 files changed, 31 insertions, 43 deletions
diff --git a/drivers/usb/gadget/fsl_mxc_udc.c b/drivers/usb/gadget/fsl_mxc_udc.c index f4b5109feb3d..1b0f086426bd 100644 --- a/drivers/usb/gadget/fsl_mxc_udc.c +++ b/drivers/usb/gadget/fsl_mxc_udc.c | |||
@@ -21,7 +21,8 @@ | |||
21 | #include <mach/hardware.h> | 21 | #include <mach/hardware.h> |
22 | 22 | ||
23 | static struct clk *mxc_ahb_clk; | 23 | static struct clk *mxc_ahb_clk; |
24 | static struct clk *mxc_usb_clk; | 24 | static struct clk *mxc_per_clk; |
25 | static struct clk *mxc_ipg_clk; | ||
25 | 26 | ||
26 | /* workaround ENGcm09152 for i.MX35 */ | 27 | /* workaround ENGcm09152 for i.MX35 */ |
27 | #define USBPHYCTRL_OTGBASE_OFFSET 0x608 | 28 | #define USBPHYCTRL_OTGBASE_OFFSET 0x608 |
@@ -35,28 +36,31 @@ int fsl_udc_clk_init(struct platform_device *pdev) | |||
35 | 36 | ||
36 | pdata = pdev->dev.platform_data; | 37 | pdata = pdev->dev.platform_data; |
37 | 38 | ||
38 | if (!cpu_is_mx35() && !cpu_is_mx25()) { | 39 | mxc_ipg_clk = devm_clk_get(&pdev->dev, "ipg"); |
39 | mxc_ahb_clk = clk_get(&pdev->dev, "usb_ahb"); | 40 | if (IS_ERR(mxc_ipg_clk)) { |
40 | if (IS_ERR(mxc_ahb_clk)) | 41 | dev_err(&pdev->dev, "clk_get(\"ipg\") failed\n"); |
41 | return PTR_ERR(mxc_ahb_clk); | 42 | return PTR_ERR(mxc_ipg_clk); |
43 | } | ||
42 | 44 | ||
43 | ret = clk_prepare_enable(mxc_ahb_clk); | 45 | mxc_ahb_clk = devm_clk_get(&pdev->dev, "ahb"); |
44 | if (ret < 0) { | 46 | if (IS_ERR(mxc_ahb_clk)) { |
45 | dev_err(&pdev->dev, "clk_enable(\"usb_ahb\") failed\n"); | 47 | dev_err(&pdev->dev, "clk_get(\"ahb\") failed\n"); |
46 | goto eenahb; | 48 | return PTR_ERR(mxc_ahb_clk); |
47 | } | ||
48 | } | 49 | } |
49 | 50 | ||
50 | /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */ | 51 | mxc_per_clk = devm_clk_get(&pdev->dev, "per"); |
51 | mxc_usb_clk = clk_get(&pdev->dev, "usb"); | 52 | if (IS_ERR(mxc_per_clk)) { |
52 | if (IS_ERR(mxc_usb_clk)) { | 53 | dev_err(&pdev->dev, "clk_get(\"per\") failed\n"); |
53 | dev_err(&pdev->dev, "clk_get(\"usb\") failed\n"); | 54 | return PTR_ERR(mxc_per_clk); |
54 | ret = PTR_ERR(mxc_usb_clk); | ||
55 | goto egusb; | ||
56 | } | 55 | } |
57 | 56 | ||
57 | clk_prepare_enable(mxc_ipg_clk); | ||
58 | clk_prepare_enable(mxc_ahb_clk); | ||
59 | clk_prepare_enable(mxc_per_clk); | ||
60 | |||
61 | /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */ | ||
58 | if (!cpu_is_mx51()) { | 62 | if (!cpu_is_mx51()) { |
59 | freq = clk_get_rate(mxc_usb_clk); | 63 | freq = clk_get_rate(mxc_per_clk); |
60 | if (pdata->phy_mode != FSL_USB2_PHY_ULPI && | 64 | if (pdata->phy_mode != FSL_USB2_PHY_ULPI && |
61 | (freq < 59999000 || freq > 60001000)) { | 65 | (freq < 59999000 || freq > 60001000)) { |
62 | dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq); | 66 | dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq); |
@@ -65,24 +69,13 @@ int fsl_udc_clk_init(struct platform_device *pdev) | |||
65 | } | 69 | } |
66 | } | 70 | } |
67 | 71 | ||
68 | ret = clk_prepare_enable(mxc_usb_clk); | ||
69 | if (ret < 0) { | ||
70 | dev_err(&pdev->dev, "clk_enable(\"usb_clk\") failed\n"); | ||
71 | goto eenusb; | ||
72 | } | ||
73 | |||
74 | return 0; | 72 | return 0; |
75 | 73 | ||
76 | eenusb: | ||
77 | eclkrate: | 74 | eclkrate: |
78 | clk_put(mxc_usb_clk); | 75 | clk_disable_unprepare(mxc_ipg_clk); |
79 | mxc_usb_clk = NULL; | 76 | clk_disable_unprepare(mxc_ahb_clk); |
80 | egusb: | 77 | clk_disable_unprepare(mxc_per_clk); |
81 | if (!cpu_is_mx35()) | 78 | mxc_per_clk = NULL; |
82 | clk_disable_unprepare(mxc_ahb_clk); | ||
83 | eenahb: | ||
84 | if (!cpu_is_mx35()) | ||
85 | clk_put(mxc_ahb_clk); | ||
86 | return ret; | 79 | return ret; |
87 | } | 80 | } |
88 | 81 | ||
@@ -104,20 +97,15 @@ void fsl_udc_clk_finalize(struct platform_device *pdev) | |||
104 | 97 | ||
105 | /* ULPI transceivers don't need usbpll */ | 98 | /* ULPI transceivers don't need usbpll */ |
106 | if (pdata->phy_mode == FSL_USB2_PHY_ULPI) { | 99 | if (pdata->phy_mode == FSL_USB2_PHY_ULPI) { |
107 | clk_disable_unprepare(mxc_usb_clk); | 100 | clk_disable_unprepare(mxc_per_clk); |
108 | clk_put(mxc_usb_clk); | 101 | mxc_per_clk = NULL; |
109 | mxc_usb_clk = NULL; | ||
110 | } | 102 | } |
111 | } | 103 | } |
112 | 104 | ||
113 | void fsl_udc_clk_release(void) | 105 | void fsl_udc_clk_release(void) |
114 | { | 106 | { |
115 | if (mxc_usb_clk) { | 107 | if (mxc_per_clk) |
116 | clk_disable_unprepare(mxc_usb_clk); | 108 | clk_disable_unprepare(mxc_per_clk); |
117 | clk_put(mxc_usb_clk); | 109 | clk_disable_unprepare(mxc_ahb_clk); |
118 | } | 110 | clk_disable_unprepare(mxc_ipg_clk); |
119 | if (!cpu_is_mx35()) { | ||
120 | clk_disable_unprepare(mxc_ahb_clk); | ||
121 | clk_put(mxc_ahb_clk); | ||
122 | } | ||
123 | } | 111 | } |