diff options
-rw-r--r-- | Documentation/devicetree/bindings/phy/samsung-phy.txt | 3 | ||||
-rw-r--r-- | drivers/phy/phy-samsung-usb2.c | 25 | ||||
-rw-r--r-- | drivers/phy/phy-samsung-usb2.h | 2 |
3 files changed, 28 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index 60c6f2a633e0..0289d3b07853 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt | |||
@@ -44,6 +44,9 @@ Required properties: | |||
44 | - the "ref" clock is used to get the rate of the clock provided to the | 44 | - the "ref" clock is used to get the rate of the clock provided to the |
45 | PHY module | 45 | PHY module |
46 | 46 | ||
47 | Optional properties: | ||
48 | - vbus-supply: power-supply phandle for vbus power source | ||
49 | |||
47 | The first phandle argument in the PHY specifier identifies the PHY, its | 50 | The first phandle argument in the PHY specifier identifies the PHY, its |
48 | meaning is compatible dependent. For the currently supported SoCs (Exynos 4210 | 51 | meaning is compatible dependent. For the currently supported SoCs (Exynos 4210 |
49 | and Exynos 4212) it is as follows: | 52 | and Exynos 4212) it is as follows: |
diff --git a/drivers/phy/phy-samsung-usb2.c b/drivers/phy/phy-samsung-usb2.c index f278a9c547e1..1d22d93b552d 100644 --- a/drivers/phy/phy-samsung-usb2.c +++ b/drivers/phy/phy-samsung-usb2.c | |||
@@ -27,6 +27,13 @@ static int samsung_usb2_phy_power_on(struct phy *phy) | |||
27 | 27 | ||
28 | dev_dbg(drv->dev, "Request to power_on \"%s\" usb phy\n", | 28 | dev_dbg(drv->dev, "Request to power_on \"%s\" usb phy\n", |
29 | inst->cfg->label); | 29 | inst->cfg->label); |
30 | |||
31 | if (drv->vbus) { | ||
32 | ret = regulator_enable(drv->vbus); | ||
33 | if (ret) | ||
34 | goto err_regulator; | ||
35 | } | ||
36 | |||
30 | ret = clk_prepare_enable(drv->clk); | 37 | ret = clk_prepare_enable(drv->clk); |
31 | if (ret) | 38 | if (ret) |
32 | goto err_main_clk; | 39 | goto err_main_clk; |
@@ -48,6 +55,9 @@ err_power_on: | |||
48 | err_instance_clk: | 55 | err_instance_clk: |
49 | clk_disable_unprepare(drv->clk); | 56 | clk_disable_unprepare(drv->clk); |
50 | err_main_clk: | 57 | err_main_clk: |
58 | if (drv->vbus) | ||
59 | regulator_disable(drv->vbus); | ||
60 | err_regulator: | ||
51 | return ret; | 61 | return ret; |
52 | } | 62 | } |
53 | 63 | ||
@@ -55,7 +65,7 @@ static int samsung_usb2_phy_power_off(struct phy *phy) | |||
55 | { | 65 | { |
56 | struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy); | 66 | struct samsung_usb2_phy_instance *inst = phy_get_drvdata(phy); |
57 | struct samsung_usb2_phy_driver *drv = inst->drv; | 67 | struct samsung_usb2_phy_driver *drv = inst->drv; |
58 | int ret; | 68 | int ret = 0; |
59 | 69 | ||
60 | dev_dbg(drv->dev, "Request to power_off \"%s\" usb phy\n", | 70 | dev_dbg(drv->dev, "Request to power_off \"%s\" usb phy\n", |
61 | inst->cfg->label); | 71 | inst->cfg->label); |
@@ -68,7 +78,10 @@ static int samsung_usb2_phy_power_off(struct phy *phy) | |||
68 | } | 78 | } |
69 | clk_disable_unprepare(drv->ref_clk); | 79 | clk_disable_unprepare(drv->ref_clk); |
70 | clk_disable_unprepare(drv->clk); | 80 | clk_disable_unprepare(drv->clk); |
71 | return 0; | 81 | if (drv->vbus) |
82 | ret = regulator_disable(drv->vbus); | ||
83 | |||
84 | return ret; | ||
72 | } | 85 | } |
73 | 86 | ||
74 | static const struct phy_ops samsung_usb2_phy_ops = { | 87 | static const struct phy_ops samsung_usb2_phy_ops = { |
@@ -203,6 +216,14 @@ static int samsung_usb2_phy_probe(struct platform_device *pdev) | |||
203 | return ret; | 216 | return ret; |
204 | } | 217 | } |
205 | 218 | ||
219 | drv->vbus = devm_regulator_get(dev, "vbus"); | ||
220 | if (IS_ERR(drv->vbus)) { | ||
221 | ret = PTR_ERR(drv->vbus); | ||
222 | if (ret == -EPROBE_DEFER) | ||
223 | return ret; | ||
224 | drv->vbus = NULL; | ||
225 | } | ||
226 | |||
206 | for (i = 0; i < drv->cfg->num_phys; i++) { | 227 | for (i = 0; i < drv->cfg->num_phys; i++) { |
207 | char *label = drv->cfg->phys[i].label; | 228 | char *label = drv->cfg->phys[i].label; |
208 | struct samsung_usb2_phy_instance *p = &drv->instances[i]; | 229 | struct samsung_usb2_phy_instance *p = &drv->instances[i]; |
diff --git a/drivers/phy/phy-samsung-usb2.h b/drivers/phy/phy-samsung-usb2.h index 44bead9b8f34..6563e7ca0ac4 100644 --- a/drivers/phy/phy-samsung-usb2.h +++ b/drivers/phy/phy-samsung-usb2.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
18 | #include <linux/regmap.h> | 18 | #include <linux/regmap.h> |
19 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
20 | #include <linux/regulator/consumer.h> | ||
20 | 21 | ||
21 | #define KHZ 1000 | 22 | #define KHZ 1000 |
22 | #define MHZ (KHZ * KHZ) | 23 | #define MHZ (KHZ * KHZ) |
@@ -37,6 +38,7 @@ struct samsung_usb2_phy_driver { | |||
37 | const struct samsung_usb2_phy_config *cfg; | 38 | const struct samsung_usb2_phy_config *cfg; |
38 | struct clk *clk; | 39 | struct clk *clk; |
39 | struct clk *ref_clk; | 40 | struct clk *ref_clk; |
41 | struct regulator *vbus; | ||
40 | unsigned long ref_rate; | 42 | unsigned long ref_rate; |
41 | u32 ref_reg_val; | 43 | u32 ref_reg_val; |
42 | struct device *dev; | 44 | struct device *dev; |