aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/phy/omap-usb2.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 15:20:00 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 15:20:00 -0500
commit74e1a2a39355b2d3ae8c60c78d8add162c6d7183 (patch)
tree1ce09f285c505a774838a95cff7327a750dc85fc /drivers/usb/phy/omap-usb2.c
parentb5c78e04dd061b776978dad61dd85357081147b0 (diff)
parent6166805c3de539a41cfcae39026c5bc273d7c6aa (diff)
Merge tag 'usb-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB patches from Greg Kroah-Hartman: "Here's the big USB merge for 3.9-rc1 Nothing major, lots of gadget fixes, and of course, xhci stuff. All of this has been in linux-next for a while, with the exception of the last 3 patches, which were reverts of patches in the tree that caused problems, they went in yesterday." * tag 'usb-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (190 commits) Revert "USB: EHCI: make ehci-vt8500 a separate driver" Revert "USB: EHCI: make ehci-orion a separate driver" Revert "USB: update host controller Kconfig entries" USB: update host controller Kconfig entries USB: EHCI: make ehci-orion a separate driver USB: EHCI: make ehci-vt8500 a separate driver USB: usb-storage: unusual_devs update for Super TOP SATA bridge USB: ehci-omap: Fix autoloading of module USB: ehci-omap: Don't free gpios that we didn't request USB: option: add Huawei "ACM" devices using protocol = vendor USB: serial: fix null-pointer dereferences on disconnect USB: option: add Yota / Megafon M100-1 4g modem drivers/usb: add missing GENERIC_HARDIRQS dependencies USB: storage: properly handle the endian issues of idProduct testusb: remove all mentions of 'usbfs' usb: gadget: imx_udc: make it depend on BROKEN usb: omap_control_usb: fix compile warning ARM: OMAP: USB: Add phy binding information ARM: OMAP2: MUSB: Specify omap4 has mailbox ARM: OMAP: devices: create device for usb part of control module ...
Diffstat (limited to 'drivers/usb/phy/omap-usb2.c')
-rw-r--r--drivers/usb/phy/omap-usb2.c72
1 files changed, 38 insertions, 34 deletions
diff --git a/drivers/usb/phy/omap-usb2.c b/drivers/usb/phy/omap-usb2.c
index 2fdb8ede5f1c..844ab68f08d0 100644
--- a/drivers/usb/phy/omap-usb2.c
+++ b/drivers/usb/phy/omap-usb2.c
@@ -27,6 +27,7 @@
27#include <linux/err.h> 27#include <linux/err.h>
28#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/usb/omap_control_usb.h>
30 31
31/** 32/**
32 * omap_usb2_set_comparator - links the comparator present in the sytem with 33 * omap_usb2_set_comparator - links the comparator present in the sytem with
@@ -52,29 +53,6 @@ int omap_usb2_set_comparator(struct phy_companion *comparator)
52} 53}
53EXPORT_SYMBOL_GPL(omap_usb2_set_comparator); 54EXPORT_SYMBOL_GPL(omap_usb2_set_comparator);
54 55
55/**
56 * omap_usb_phy_power - power on/off the phy using control module reg
57 * @phy: struct omap_usb *
58 * @on: 0 or 1, based on powering on or off the PHY
59 *
60 * XXX: Remove this function once control module driver gets merged
61 */
62static void omap_usb_phy_power(struct omap_usb *phy, int on)
63{
64 u32 val;
65
66 if (on) {
67 val = readl(phy->control_dev);
68 if (val & PHY_PD) {
69 writel(~PHY_PD, phy->control_dev);
70 /* XXX: add proper documentation for this delay */
71 mdelay(200);
72 }
73 } else {
74 writel(PHY_PD, phy->control_dev);
75 }
76}
77
78static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled) 56static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled)
79{ 57{
80 struct omap_usb *phy = phy_to_omapusb(otg->phy); 58 struct omap_usb *phy = phy_to_omapusb(otg->phy);
@@ -124,7 +102,7 @@ static int omap_usb2_suspend(struct usb_phy *x, int suspend)
124 struct omap_usb *phy = phy_to_omapusb(x); 102 struct omap_usb *phy = phy_to_omapusb(x);
125 103
126 if (suspend && !phy->is_suspended) { 104 if (suspend && !phy->is_suspended) {
127 omap_usb_phy_power(phy, 0); 105 omap_control_usb_phy_power(phy->control_dev, 0);
128 pm_runtime_put_sync(phy->dev); 106 pm_runtime_put_sync(phy->dev);
129 phy->is_suspended = 1; 107 phy->is_suspended = 1;
130 } else if (!suspend && phy->is_suspended) { 108 } else if (!suspend && phy->is_suspended) {
@@ -134,7 +112,7 @@ static int omap_usb2_suspend(struct usb_phy *x, int suspend)
134 ret); 112 ret);
135 return ret; 113 return ret;
136 } 114 }
137 omap_usb_phy_power(phy, 1); 115 omap_control_usb_phy_power(phy->control_dev, 1);
138 phy->is_suspended = 0; 116 phy->is_suspended = 0;
139 } 117 }
140 118
@@ -145,7 +123,6 @@ static int omap_usb2_probe(struct platform_device *pdev)
145{ 123{
146 struct omap_usb *phy; 124 struct omap_usb *phy;
147 struct usb_otg *otg; 125 struct usb_otg *otg;
148 struct resource *res;
149 126
150 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); 127 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
151 if (!phy) { 128 if (!phy) {
@@ -165,15 +142,16 @@ static int omap_usb2_probe(struct platform_device *pdev)
165 phy->phy.label = "omap-usb2"; 142 phy->phy.label = "omap-usb2";
166 phy->phy.set_suspend = omap_usb2_suspend; 143 phy->phy.set_suspend = omap_usb2_suspend;
167 phy->phy.otg = otg; 144 phy->phy.otg = otg;
145 phy->phy.type = USB_PHY_TYPE_USB2;
168 146
169 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 147 phy->control_dev = omap_get_control_dev();
170 148 if (IS_ERR(phy->control_dev)) {
171 phy->control_dev = devm_ioremap_resource(&pdev->dev, res); 149 dev_dbg(&pdev->dev, "Failed to get control device\n");
172 if (IS_ERR(phy->control_dev)) 150 return -ENODEV;
173 return PTR_ERR(phy->control_dev); 151 }
174 152
175 phy->is_suspended = 1; 153 phy->is_suspended = 1;
176 omap_usb_phy_power(phy, 0); 154 omap_control_usb_phy_power(phy->control_dev, 0);
177 155
178 otg->set_host = omap_usb_set_host; 156 otg->set_host = omap_usb_set_host;
179 otg->set_peripheral = omap_usb_set_peripheral; 157 otg->set_peripheral = omap_usb_set_peripheral;
@@ -188,7 +166,13 @@ static int omap_usb2_probe(struct platform_device *pdev)
188 } 166 }
189 clk_prepare(phy->wkupclk); 167 clk_prepare(phy->wkupclk);
190 168
191 usb_add_phy(&phy->phy, USB_PHY_TYPE_USB2); 169 phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m");
170 if (IS_ERR(phy->optclk))
171 dev_vdbg(&pdev->dev, "unable to get refclk960m\n");
172 else
173 clk_prepare(phy->optclk);
174
175 usb_add_phy_dev(&phy->phy);
192 176
193 platform_set_drvdata(pdev, phy); 177 platform_set_drvdata(pdev, phy);
194 178
@@ -202,6 +186,8 @@ static int omap_usb2_remove(struct platform_device *pdev)
202 struct omap_usb *phy = platform_get_drvdata(pdev); 186 struct omap_usb *phy = platform_get_drvdata(pdev);
203 187
204 clk_unprepare(phy->wkupclk); 188 clk_unprepare(phy->wkupclk);
189 if (!IS_ERR(phy->optclk))
190 clk_unprepare(phy->optclk);
205 usb_remove_phy(&phy->phy); 191 usb_remove_phy(&phy->phy);
206 192
207 return 0; 193 return 0;
@@ -215,6 +201,8 @@ static int omap_usb2_runtime_suspend(struct device *dev)
215 struct omap_usb *phy = platform_get_drvdata(pdev); 201 struct omap_usb *phy = platform_get_drvdata(pdev);
216 202
217 clk_disable(phy->wkupclk); 203 clk_disable(phy->wkupclk);
204 if (!IS_ERR(phy->optclk))
205 clk_disable(phy->optclk);
218 206
219 return 0; 207 return 0;
220} 208}
@@ -226,9 +214,25 @@ static int omap_usb2_runtime_resume(struct device *dev)
226 struct omap_usb *phy = platform_get_drvdata(pdev); 214 struct omap_usb *phy = platform_get_drvdata(pdev);
227 215
228 ret = clk_enable(phy->wkupclk); 216 ret = clk_enable(phy->wkupclk);
229 if (ret < 0) 217 if (ret < 0) {
230 dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); 218 dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret);
219 goto err0;
220 }
221
222 if (!IS_ERR(phy->optclk)) {
223 ret = clk_enable(phy->optclk);
224 if (ret < 0) {
225 dev_err(phy->dev, "Failed to enable optclk %d\n", ret);
226 goto err1;
227 }
228 }
229
230 return 0;
231
232err1:
233 clk_disable(phy->wkupclk);
231 234
235err0:
232 return ret; 236 return ret;
233} 237}
234 238