aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/phy
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-03-07 19:47:36 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-03-07 19:47:36 -0500
commit7338a0659365ec0fbdc6f79de8b9fba2280fd155 (patch)
tree876358e9d7187cad93d41b9e9918653fc24fa38a /drivers/usb/phy
parentc9050b64940a1b47dfa623630431fec400edbf33 (diff)
parent4b76e14d95f7b69e71eabc002dcb0dcb9ebb5340 (diff)
Merge tag 'usb-for-v3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
Felipe writes: usb: patches for v3.15 another substantial pull request with new features all over the place. dwc3 got a bit closer towards hibernation support with after a few patches re-factoring code to be reused for hibernation. Also in dwc3 two new workarounds for known silicon bugs have been implemented, some randconfig build errors have been fixed, and it was taught about the new generic phy layer. MUSB on AM335x now supports isochronous transfers thanks to George Cherian's work. The atmel_usba driver got two crash fixes: one when no endpoint was specified in DeviceTree data and another when stopping the UDC in DEBUG builds. Function FS got a much needed fix to ffs_epfile_io() which was copying too much data to userspace in some cases. The printer gadget got a fix for a possible deadlock and plugged a memory leak. Ethernet drivers now use NAPI for RX which gives improved throughput. Other than that, the usual miscelaneous fixes, cleanups, and the like. Signed-of-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/phy')
-rw-r--r--drivers/usb/phy/phy-fsm-usb.c9
-rw-r--r--drivers/usb/phy/phy-mxs-usb.c310
-rw-r--r--drivers/usb/phy/phy-rcar-gen2-usb.c6
3 files changed, 304 insertions, 21 deletions
diff --git a/drivers/usb/phy/phy-fsm-usb.c b/drivers/usb/phy/phy-fsm-usb.c
index 7aa314ef4a8a..c47e5a6edde2 100644
--- a/drivers/usb/phy/phy-fsm-usb.c
+++ b/drivers/usb/phy/phy-fsm-usb.c
@@ -317,10 +317,12 @@ int otg_statemachine(struct otg_fsm *fsm)
317 otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); 317 otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL);
318 break; 318 break;
319 case OTG_STATE_A_HOST: 319 case OTG_STATE_A_HOST:
320 if ((!fsm->a_bus_req || fsm->a_suspend_req_inf) && 320 if (fsm->id || fsm->a_bus_drop)
321 otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL);
322 else if ((!fsm->a_bus_req || fsm->a_suspend_req_inf) &&
321 fsm->otg->host->b_hnp_enable) 323 fsm->otg->host->b_hnp_enable)
322 otg_set_state(fsm, OTG_STATE_A_SUSPEND); 324 otg_set_state(fsm, OTG_STATE_A_SUSPEND);
323 else if (fsm->id || !fsm->b_conn || fsm->a_bus_drop) 325 else if (!fsm->b_conn)
324 otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); 326 otg_set_state(fsm, OTG_STATE_A_WAIT_BCON);
325 else if (!fsm->a_vbus_vld) 327 else if (!fsm->a_vbus_vld)
326 otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); 328 otg_set_state(fsm, OTG_STATE_A_VBUS_ERR);
@@ -346,8 +348,7 @@ int otg_statemachine(struct otg_fsm *fsm)
346 otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); 348 otg_set_state(fsm, OTG_STATE_A_VBUS_ERR);
347 break; 349 break;
348 case OTG_STATE_A_WAIT_VFALL: 350 case OTG_STATE_A_WAIT_VFALL:
349 if (fsm->a_wait_vfall_tmout || fsm->id || fsm->a_bus_req || 351 if (fsm->a_wait_vfall_tmout)
350 (!fsm->a_sess_vld && !fsm->b_conn))
351 otg_set_state(fsm, OTG_STATE_A_IDLE); 352 otg_set_state(fsm, OTG_STATE_A_IDLE);
352 break; 353 break;
353 case OTG_STATE_A_VBUS_ERR: 354 case OTG_STATE_A_VBUS_ERR:
diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
index b42897b6474c..c42bdf0c4a1f 100644
--- a/drivers/usb/phy/phy-mxs-usb.c
+++ b/drivers/usb/phy/phy-mxs-usb.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2012 Freescale Semiconductor, Inc. 2 * Copyright 2012-2013 Freescale Semiconductor, Inc.
3 * Copyright (C) 2012 Marek Vasut <marex@denx.de> 3 * Copyright (C) 2012 Marek Vasut <marex@denx.de>
4 * on behalf of DENX Software Engineering GmbH 4 * on behalf of DENX Software Engineering GmbH
5 * 5 *
@@ -20,6 +20,9 @@
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/of_device.h>
24#include <linux/regmap.h>
25#include <linux/mfd/syscon.h>
23 26
24#define DRIVER_NAME "mxs_phy" 27#define DRIVER_NAME "mxs_phy"
25 28
@@ -28,18 +31,134 @@
28#define HW_USBPHY_CTRL_SET 0x34 31#define HW_USBPHY_CTRL_SET 0x34
29#define HW_USBPHY_CTRL_CLR 0x38 32#define HW_USBPHY_CTRL_CLR 0x38
30 33
34#define HW_USBPHY_DEBUG_SET 0x54
35#define HW_USBPHY_DEBUG_CLR 0x58
36
37#define HW_USBPHY_IP 0x90
38#define HW_USBPHY_IP_SET 0x94
39#define HW_USBPHY_IP_CLR 0x98
40
31#define BM_USBPHY_CTRL_SFTRST BIT(31) 41#define BM_USBPHY_CTRL_SFTRST BIT(31)
32#define BM_USBPHY_CTRL_CLKGATE BIT(30) 42#define BM_USBPHY_CTRL_CLKGATE BIT(30)
43#define BM_USBPHY_CTRL_ENAUTOSET_USBCLKS BIT(26)
44#define BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE BIT(25)
45#define BM_USBPHY_CTRL_ENVBUSCHG_WKUP BIT(23)
46#define BM_USBPHY_CTRL_ENIDCHG_WKUP BIT(22)
47#define BM_USBPHY_CTRL_ENDPDMCHG_WKUP BIT(21)
48#define BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD BIT(20)
49#define BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE BIT(19)
50#define BM_USBPHY_CTRL_ENAUTO_PWRON_PLL BIT(18)
33#define BM_USBPHY_CTRL_ENUTMILEVEL3 BIT(15) 51#define BM_USBPHY_CTRL_ENUTMILEVEL3 BIT(15)
34#define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14) 52#define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14)
35#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1) 53#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1)
36 54
55#define BM_USBPHY_IP_FIX (BIT(17) | BIT(18))
56
57#define BM_USBPHY_DEBUG_CLKGATE BIT(30)
58
59/* Anatop Registers */
60#define ANADIG_ANA_MISC0 0x150
61#define ANADIG_ANA_MISC0_SET 0x154
62#define ANADIG_ANA_MISC0_CLR 0x158
63
64#define ANADIG_USB1_VBUS_DET_STAT 0x1c0
65#define ANADIG_USB2_VBUS_DET_STAT 0x220
66
67#define ANADIG_USB1_LOOPBACK_SET 0x1e4
68#define ANADIG_USB1_LOOPBACK_CLR 0x1e8
69#define ANADIG_USB2_LOOPBACK_SET 0x244
70#define ANADIG_USB2_LOOPBACK_CLR 0x248
71
72#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG BIT(12)
73#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL BIT(11)
74
75#define BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID BIT(3)
76#define BM_ANADIG_USB2_VBUS_DET_STAT_VBUS_VALID BIT(3)
77
78#define BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 BIT(2)
79#define BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN BIT(5)
80#define BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 BIT(2)
81#define BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN BIT(5)
82
83#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
84
85/* Do disconnection between PHY and controller without vbus */
86#define MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS BIT(0)
87
88/*
89 * The PHY will be in messy if there is a wakeup after putting
90 * bus to suspend (set portsc.suspendM) but before setting PHY to low
91 * power mode (set portsc.phcd).
92 */
93#define MXS_PHY_ABNORMAL_IN_SUSPEND BIT(1)
94
95/*
96 * The SOF sends too fast after resuming, it will cause disconnection
97 * between host and high speed device.
98 */
99#define MXS_PHY_SENDING_SOF_TOO_FAST BIT(2)
100
101/*
102 * IC has bug fixes logic, they include
103 * MXS_PHY_ABNORMAL_IN_SUSPEND and MXS_PHY_SENDING_SOF_TOO_FAST
104 * which are described at above flags, the RTL will handle it
105 * according to different versions.
106 */
107#define MXS_PHY_NEED_IP_FIX BIT(3)
108
109struct mxs_phy_data {
110 unsigned int flags;
111};
112
113static const struct mxs_phy_data imx23_phy_data = {
114 .flags = MXS_PHY_ABNORMAL_IN_SUSPEND | MXS_PHY_SENDING_SOF_TOO_FAST,
115};
116
117static const struct mxs_phy_data imx6q_phy_data = {
118 .flags = MXS_PHY_SENDING_SOF_TOO_FAST |
119 MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
120 MXS_PHY_NEED_IP_FIX,
121};
122
123static const struct mxs_phy_data imx6sl_phy_data = {
124 .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
125 MXS_PHY_NEED_IP_FIX,
126};
127
128static const struct of_device_id mxs_phy_dt_ids[] = {
129 { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },
130 { .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, },
131 { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, },
132 { /* sentinel */ }
133};
134MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
135
37struct mxs_phy { 136struct mxs_phy {
38 struct usb_phy phy; 137 struct usb_phy phy;
39 struct clk *clk; 138 struct clk *clk;
139 const struct mxs_phy_data *data;
140 struct regmap *regmap_anatop;
141 int port_id;
40}; 142};
41 143
42#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) 144static inline bool is_imx6q_phy(struct mxs_phy *mxs_phy)
145{
146 return mxs_phy->data == &imx6q_phy_data;
147}
148
149static inline bool is_imx6sl_phy(struct mxs_phy *mxs_phy)
150{
151 return mxs_phy->data == &imx6sl_phy_data;
152}
153
154/*
155 * PHY needs some 32K cycles to switch from 32K clock to
156 * bus (such as AHB/AXI, etc) clock.
157 */
158static void mxs_phy_clock_switch_delay(void)
159{
160 usleep_range(300, 400);
161}
43 162
44static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) 163static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
45{ 164{
@@ -53,19 +172,105 @@ static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
53 /* Power up the PHY */ 172 /* Power up the PHY */
54 writel(0, base + HW_USBPHY_PWD); 173 writel(0, base + HW_USBPHY_PWD);
55 174
56 /* enable FS/LS device */ 175 /*
57 writel(BM_USBPHY_CTRL_ENUTMILEVEL2 | 176 * USB PHY Ctrl Setting
58 BM_USBPHY_CTRL_ENUTMILEVEL3, 177 * - Auto clock/power on
178 * - Enable full/low speed support
179 */
180 writel(BM_USBPHY_CTRL_ENAUTOSET_USBCLKS |
181 BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE |
182 BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD |
183 BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE |
184 BM_USBPHY_CTRL_ENAUTO_PWRON_PLL |
185 BM_USBPHY_CTRL_ENUTMILEVEL2 |
186 BM_USBPHY_CTRL_ENUTMILEVEL3,
59 base + HW_USBPHY_CTRL_SET); 187 base + HW_USBPHY_CTRL_SET);
60 188
189 if (mxs_phy->data->flags & MXS_PHY_NEED_IP_FIX)
190 writel(BM_USBPHY_IP_FIX, base + HW_USBPHY_IP_SET);
191
61 return 0; 192 return 0;
62} 193}
63 194
195/* Return true if the vbus is there */
196static bool mxs_phy_get_vbus_status(struct mxs_phy *mxs_phy)
197{
198 unsigned int vbus_value;
199
200 if (mxs_phy->port_id == 0)
201 regmap_read(mxs_phy->regmap_anatop,
202 ANADIG_USB1_VBUS_DET_STAT,
203 &vbus_value);
204 else if (mxs_phy->port_id == 1)
205 regmap_read(mxs_phy->regmap_anatop,
206 ANADIG_USB2_VBUS_DET_STAT,
207 &vbus_value);
208
209 if (vbus_value & BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID)
210 return true;
211 else
212 return false;
213}
214
215static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect)
216{
217 void __iomem *base = mxs_phy->phy.io_priv;
218 u32 reg;
219
220 if (disconnect)
221 writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
222 base + HW_USBPHY_DEBUG_CLR);
223
224 if (mxs_phy->port_id == 0) {
225 reg = disconnect ? ANADIG_USB1_LOOPBACK_SET
226 : ANADIG_USB1_LOOPBACK_CLR;
227 regmap_write(mxs_phy->regmap_anatop, reg,
228 BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 |
229 BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN);
230 } else if (mxs_phy->port_id == 1) {
231 reg = disconnect ? ANADIG_USB2_LOOPBACK_SET
232 : ANADIG_USB2_LOOPBACK_CLR;
233 regmap_write(mxs_phy->regmap_anatop, reg,
234 BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 |
235 BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN);
236 }
237
238 if (!disconnect)
239 writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
240 base + HW_USBPHY_DEBUG_SET);
241
242 /* Delay some time, and let Linestate be SE0 for controller */
243 if (disconnect)
244 usleep_range(500, 1000);
245}
246
247static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
248{
249 bool vbus_is_on = false;
250
251 /* If the SoCs don't need to disconnect line without vbus, quit */
252 if (!(mxs_phy->data->flags & MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS))
253 return;
254
255 /* If the SoCs don't have anatop, quit */
256 if (!mxs_phy->regmap_anatop)
257 return;
258
259 vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
260
261 if (on && !vbus_is_on)
262 __mxs_phy_disconnect_line(mxs_phy, true);
263 else
264 __mxs_phy_disconnect_line(mxs_phy, false);
265
266}
267
64static int mxs_phy_init(struct usb_phy *phy) 268static int mxs_phy_init(struct usb_phy *phy)
65{ 269{
66 int ret; 270 int ret;
67 struct mxs_phy *mxs_phy = to_mxs_phy(phy); 271 struct mxs_phy *mxs_phy = to_mxs_phy(phy);
68 272
273 mxs_phy_clock_switch_delay();
69 ret = clk_prepare_enable(mxs_phy->clk); 274 ret = clk_prepare_enable(mxs_phy->clk);
70 if (ret) 275 if (ret)
71 return ret; 276 return ret;
@@ -94,6 +299,7 @@ static int mxs_phy_suspend(struct usb_phy *x, int suspend)
94 x->io_priv + HW_USBPHY_CTRL_SET); 299 x->io_priv + HW_USBPHY_CTRL_SET);
95 clk_disable_unprepare(mxs_phy->clk); 300 clk_disable_unprepare(mxs_phy->clk);
96 } else { 301 } else {
302 mxs_phy_clock_switch_delay();
97 ret = clk_prepare_enable(mxs_phy->clk); 303 ret = clk_prepare_enable(mxs_phy->clk);
98 if (ret) 304 if (ret)
99 return ret; 305 return ret;
@@ -105,11 +311,28 @@ static int mxs_phy_suspend(struct usb_phy *x, int suspend)
105 return 0; 311 return 0;
106} 312}
107 313
314static int mxs_phy_set_wakeup(struct usb_phy *x, bool enabled)
315{
316 struct mxs_phy *mxs_phy = to_mxs_phy(x);
317 u32 value = BM_USBPHY_CTRL_ENVBUSCHG_WKUP |
318 BM_USBPHY_CTRL_ENDPDMCHG_WKUP |
319 BM_USBPHY_CTRL_ENIDCHG_WKUP;
320 if (enabled) {
321 mxs_phy_disconnect_line(mxs_phy, true);
322 writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_SET);
323 } else {
324 writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_CLR);
325 mxs_phy_disconnect_line(mxs_phy, false);
326 }
327
328 return 0;
329}
330
108static int mxs_phy_on_connect(struct usb_phy *phy, 331static int mxs_phy_on_connect(struct usb_phy *phy,
109 enum usb_device_speed speed) 332 enum usb_device_speed speed)
110{ 333{
111 dev_dbg(phy->dev, "%s speed device has connected\n", 334 dev_dbg(phy->dev, "%s device has connected\n",
112 (speed == USB_SPEED_HIGH) ? "high" : "non-high"); 335 (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
113 336
114 if (speed == USB_SPEED_HIGH) 337 if (speed == USB_SPEED_HIGH)
115 writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, 338 writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
@@ -121,8 +344,8 @@ static int mxs_phy_on_connect(struct usb_phy *phy,
121static int mxs_phy_on_disconnect(struct usb_phy *phy, 344static int mxs_phy_on_disconnect(struct usb_phy *phy,
122 enum usb_device_speed speed) 345 enum usb_device_speed speed)
123{ 346{
124 dev_dbg(phy->dev, "%s speed device has disconnected\n", 347 dev_dbg(phy->dev, "%s device has disconnected\n",
125 (speed == USB_SPEED_HIGH) ? "high" : "non-high"); 348 (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
126 349
127 if (speed == USB_SPEED_HIGH) 350 if (speed == USB_SPEED_HIGH)
128 writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, 351 writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
@@ -138,6 +361,9 @@ static int mxs_phy_probe(struct platform_device *pdev)
138 struct clk *clk; 361 struct clk *clk;
139 struct mxs_phy *mxs_phy; 362 struct mxs_phy *mxs_phy;
140 int ret; 363 int ret;
364 const struct of_device_id *of_id =
365 of_match_device(mxs_phy_dt_ids, &pdev->dev);
366 struct device_node *np = pdev->dev.of_node;
141 367
142 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 368 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
143 base = devm_ioremap_resource(&pdev->dev, res); 369 base = devm_ioremap_resource(&pdev->dev, res);
@@ -157,6 +383,22 @@ static int mxs_phy_probe(struct platform_device *pdev)
157 return -ENOMEM; 383 return -ENOMEM;
158 } 384 }
159 385
386 /* Some SoCs don't have anatop registers */
387 if (of_get_property(np, "fsl,anatop", NULL)) {
388 mxs_phy->regmap_anatop = syscon_regmap_lookup_by_phandle
389 (np, "fsl,anatop");
390 if (IS_ERR(mxs_phy->regmap_anatop)) {
391 dev_dbg(&pdev->dev,
392 "failed to find regmap for anatop\n");
393 return PTR_ERR(mxs_phy->regmap_anatop);
394 }
395 }
396
397 ret = of_alias_get_id(np, "usbphy");
398 if (ret < 0)
399 dev_dbg(&pdev->dev, "failed to get alias id, errno %d\n", ret);
400 mxs_phy->port_id = ret;
401
160 mxs_phy->phy.io_priv = base; 402 mxs_phy->phy.io_priv = base;
161 mxs_phy->phy.dev = &pdev->dev; 403 mxs_phy->phy.dev = &pdev->dev;
162 mxs_phy->phy.label = DRIVER_NAME; 404 mxs_phy->phy.label = DRIVER_NAME;
@@ -166,11 +408,15 @@ static int mxs_phy_probe(struct platform_device *pdev)
166 mxs_phy->phy.notify_connect = mxs_phy_on_connect; 408 mxs_phy->phy.notify_connect = mxs_phy_on_connect;
167 mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect; 409 mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect;
168 mxs_phy->phy.type = USB_PHY_TYPE_USB2; 410 mxs_phy->phy.type = USB_PHY_TYPE_USB2;
411 mxs_phy->phy.set_wakeup = mxs_phy_set_wakeup;
169 412
170 mxs_phy->clk = clk; 413 mxs_phy->clk = clk;
414 mxs_phy->data = of_id->data;
171 415
172 platform_set_drvdata(pdev, mxs_phy); 416 platform_set_drvdata(pdev, mxs_phy);
173 417
418 device_set_wakeup_capable(&pdev->dev, true);
419
174 ret = usb_add_phy_dev(&mxs_phy->phy); 420 ret = usb_add_phy_dev(&mxs_phy->phy);
175 if (ret) 421 if (ret)
176 return ret; 422 return ret;
@@ -187,11 +433,46 @@ static int mxs_phy_remove(struct platform_device *pdev)
187 return 0; 433 return 0;
188} 434}
189 435
190static const struct of_device_id mxs_phy_dt_ids[] = { 436#ifdef CONFIG_PM_SLEEP
191 { .compatible = "fsl,imx23-usbphy", }, 437static void mxs_phy_enable_ldo_in_suspend(struct mxs_phy *mxs_phy, bool on)
192 { /* sentinel */ } 438{
193}; 439 unsigned int reg = on ? ANADIG_ANA_MISC0_SET : ANADIG_ANA_MISC0_CLR;
194MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids); 440
441 /* If the SoCs don't have anatop, quit */
442 if (!mxs_phy->regmap_anatop)
443 return;
444
445 if (is_imx6q_phy(mxs_phy))
446 regmap_write(mxs_phy->regmap_anatop, reg,
447 BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG);
448 else if (is_imx6sl_phy(mxs_phy))
449 regmap_write(mxs_phy->regmap_anatop,
450 reg, BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL);
451}
452
453static int mxs_phy_system_suspend(struct device *dev)
454{
455 struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
456
457 if (device_may_wakeup(dev))
458 mxs_phy_enable_ldo_in_suspend(mxs_phy, true);
459
460 return 0;
461}
462
463static int mxs_phy_system_resume(struct device *dev)
464{
465 struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
466
467 if (device_may_wakeup(dev))
468 mxs_phy_enable_ldo_in_suspend(mxs_phy, false);
469
470 return 0;
471}
472#endif /* CONFIG_PM_SLEEP */
473
474static SIMPLE_DEV_PM_OPS(mxs_phy_pm, mxs_phy_system_suspend,
475 mxs_phy_system_resume);
195 476
196static struct platform_driver mxs_phy_driver = { 477static struct platform_driver mxs_phy_driver = {
197 .probe = mxs_phy_probe, 478 .probe = mxs_phy_probe,
@@ -200,6 +481,7 @@ static struct platform_driver mxs_phy_driver = {
200 .name = DRIVER_NAME, 481 .name = DRIVER_NAME,
201 .owner = THIS_MODULE, 482 .owner = THIS_MODULE,
202 .of_match_table = mxs_phy_dt_ids, 483 .of_match_table = mxs_phy_dt_ids,
484 .pm = &mxs_phy_pm,
203 }, 485 },
204}; 486};
205 487
diff --git a/drivers/usb/phy/phy-rcar-gen2-usb.c b/drivers/usb/phy/phy-rcar-gen2-usb.c
index 551e0a6c0e22..388d89f6b141 100644
--- a/drivers/usb/phy/phy-rcar-gen2-usb.c
+++ b/drivers/usb/phy/phy-rcar-gen2-usb.c
@@ -177,15 +177,15 @@ static int rcar_gen2_usb_phy_probe(struct platform_device *pdev)
177 struct clk *clk; 177 struct clk *clk;
178 int retval; 178 int retval;
179 179
180 pdata = dev_get_platdata(&pdev->dev); 180 pdata = dev_get_platdata(dev);
181 if (!pdata) { 181 if (!pdata) {
182 dev_err(dev, "No platform data\n"); 182 dev_err(dev, "No platform data\n");
183 return -EINVAL; 183 return -EINVAL;
184 } 184 }
185 185
186 clk = devm_clk_get(&pdev->dev, "usbhs"); 186 clk = devm_clk_get(dev, "usbhs");
187 if (IS_ERR(clk)) { 187 if (IS_ERR(clk)) {
188 dev_err(&pdev->dev, "Can't get the clock\n"); 188 dev_err(dev, "Can't get the clock\n");
189 return PTR_ERR(clk); 189 return PTR_ERR(clk);
190 } 190 }
191 191