diff mbox

[1/3] phy: omap-usb2: Manage PHY 3.3V supply regulator

Message ID 1404126038-19974-2-git-send-email-rogerq@ti.com
State New
Headers show

Commit Message

Roger Quadros June 30, 2014, 11 a.m. UTC
On some SoCs e.g. J6 the 3.3V supply to the USB2 PHY can be
powered down when the PHY is not in use. Add regulator
management code to control this power line.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/phy/phy-omap-usb2.c  | 25 +++++++++++++++++++++++++
 include/linux/phy/omap_usb.h |  1 +
 2 files changed, 26 insertions(+)

Comments

Felipe Balbi June 30, 2014, 5:09 p.m. UTC | #1
Hi,

On Mon, Jun 30, 2014 at 02:00:36PM +0300, Roger Quadros wrote:
> On some SoCs e.g. J6 the 3.3V supply to the USB2 PHY can be
> powered down when the PHY is not in use. Add regulator
> management code to control this power line.
> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>

Reviewed-by: Felipe Balbi <balbi@ti.com>

> ---
>  drivers/phy/phy-omap-usb2.c  | 25 +++++++++++++++++++++++++
>  include/linux/phy/omap_usb.h |  1 +
>  2 files changed, 26 insertions(+)
> 
> diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c
> index 7007c11..2afc79c 100644
> --- a/drivers/phy/phy-omap-usb2.c
> +++ b/drivers/phy/phy-omap-usb2.c
> @@ -30,6 +30,7 @@
>  #include <linux/phy/omap_control_phy.h>
>  #include <linux/phy/phy.h>
>  #include <linux/of_platform.h>
> +#include <linux/regulator/consumer.h>
>  
>  #define USB2PHY_DISCON_BYP_LATCH (1 << 31)
>  #define USB2PHY_ANA_CONFIG1 0x4c
> @@ -107,6 +108,14 @@ static int omap_usb_power_off(struct phy *x)
>  
>  	omap_control_phy_power(phy->control_dev, 0);
>  
> +	if (phy->pwr) {
> +		int ret;
> +
> +		ret = regulator_disable(phy->pwr);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -114,6 +123,14 @@ static int omap_usb_power_on(struct phy *x)
>  {
>  	struct omap_usb *phy = phy_get_drvdata(x);
>  
> +	if (phy->pwr) {
> +		int ret;
> +
> +		ret = regulator_enable(phy->pwr);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	omap_control_phy_power(phy->control_dev, 1);
>  
>  	return 0;
> @@ -253,6 +270,14 @@ static int omap_usb2_probe(struct platform_device *pdev)
>  	phy->control_dev = &control_pdev->dev;
>  	omap_control_phy_power(phy->control_dev, 0);
>  
> +	/* phy-supply */
> +	phy->pwr = devm_regulator_get_optional(phy->dev, "phy");
> +	if (IS_ERR(phy->pwr)) {
> +		if (PTR_ERR(phy->pwr) == -EPROBE_DEFER)
> +			return -EPROBE_DEFER;
> +		phy->pwr = NULL;
> +	}
> +
>  	otg->set_host		= omap_usb_set_host;
>  	otg->set_peripheral	= omap_usb_set_peripheral;
>  	if (phy_data->flags & OMAP_USB2_HAS_SET_VBUS)
> diff --git a/include/linux/phy/omap_usb.h b/include/linux/phy/omap_usb.h
> index dc2c541..e2c46df 100644
> --- a/include/linux/phy/omap_usb.h
> +++ b/include/linux/phy/omap_usb.h
> @@ -40,6 +40,7 @@ struct omap_usb {
>  	struct clk		*wkupclk;
>  	struct clk		*optclk;
>  	u8			flags;
> +	struct regulator	*pwr;
>  };
>  
>  struct usb_phy_data {
> -- 
> 1.8.3.2
>
Kishon Vijay Abraham I July 1, 2014, 9:56 a.m. UTC | #2
Hi Roger,

On Monday 30 June 2014 04:30 PM, Roger Quadros wrote:
> On some SoCs e.g. J6 the 3.3V supply to the USB2 PHY can be
> powered down when the PHY is not in use. Add regulator
> management code to control this power line.
> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
>  drivers/phy/phy-omap-usb2.c  | 25 +++++++++++++++++++++++++
>  include/linux/phy/omap_usb.h |  1 +
>  2 files changed, 26 insertions(+)
> 
> diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c
> index 7007c11..2afc79c 100644
> --- a/drivers/phy/phy-omap-usb2.c
> +++ b/drivers/phy/phy-omap-usb2.c
> @@ -30,6 +30,7 @@
>  #include <linux/phy/omap_control_phy.h>
>  #include <linux/phy/phy.h>
>  #include <linux/of_platform.h>
> +#include <linux/regulator/consumer.h>
>  
>  #define USB2PHY_DISCON_BYP_LATCH (1 << 31)
>  #define USB2PHY_ANA_CONFIG1 0x4c
> @@ -107,6 +108,14 @@ static int omap_usb_power_off(struct phy *x)
>  
>  	omap_control_phy_power(phy->control_dev, 0);
>  
> +	if (phy->pwr) {
> +		int ret;
> +
> +		ret = regulator_disable(phy->pwr);
> +		if (ret)
> +			return ret;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -114,6 +123,14 @@ static int omap_usb_power_on(struct phy *x)
>  {
>  	struct omap_usb *phy = phy_get_drvdata(x);
>  
> +	if (phy->pwr) {
> +		int ret;
> +
> +		ret = regulator_enable(phy->pwr);
> +		if (ret)
> +			return ret;
> +	}
> +

Shouldn't we do this in phy_power_on/phy_power_off in phy-core?

Cheers
Kishon

>  	omap_control_phy_power(phy->control_dev, 1);
>  
>  	return 0;
> @@ -253,6 +270,14 @@ static int omap_usb2_probe(struct platform_device *pdev)
>  	phy->control_dev = &control_pdev->dev;
>  	omap_control_phy_power(phy->control_dev, 0);
>  
> +	/* phy-supply */
> +	phy->pwr = devm_regulator_get_optional(phy->dev, "phy");
> +	if (IS_ERR(phy->pwr)) {
> +		if (PTR_ERR(phy->pwr) == -EPROBE_DEFER)
> +			return -EPROBE_DEFER;
> +		phy->pwr = NULL;
> +	}
> +
>  	otg->set_host		= omap_usb_set_host;
>  	otg->set_peripheral	= omap_usb_set_peripheral;
>  	if (phy_data->flags & OMAP_USB2_HAS_SET_VBUS)
> diff --git a/include/linux/phy/omap_usb.h b/include/linux/phy/omap_usb.h
> index dc2c541..e2c46df 100644
> --- a/include/linux/phy/omap_usb.h
> +++ b/include/linux/phy/omap_usb.h
> @@ -40,6 +40,7 @@ struct omap_usb {
>  	struct clk		*wkupclk;
>  	struct clk		*optclk;
>  	u8			flags;
> +	struct regulator	*pwr;
>  };
>  
>  struct usb_phy_data {
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Roger Quadros July 1, 2014, 10:13 a.m. UTC | #3
On 07/01/2014 12:56 PM, Kishon Vijay Abraham I wrote:
> Hi Roger,
> 
> On Monday 30 June 2014 04:30 PM, Roger Quadros wrote:
>> On some SoCs e.g. J6 the 3.3V supply to the USB2 PHY can be
>> powered down when the PHY is not in use. Add regulator
>> management code to control this power line.
>>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>>  drivers/phy/phy-omap-usb2.c  | 25 +++++++++++++++++++++++++
>>  include/linux/phy/omap_usb.h |  1 +
>>  2 files changed, 26 insertions(+)
>>
>> diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c
>> index 7007c11..2afc79c 100644
>> --- a/drivers/phy/phy-omap-usb2.c
>> +++ b/drivers/phy/phy-omap-usb2.c
>> @@ -30,6 +30,7 @@
>>  #include <linux/phy/omap_control_phy.h>
>>  #include <linux/phy/phy.h>
>>  #include <linux/of_platform.h>
>> +#include <linux/regulator/consumer.h>
>>  
>>  #define USB2PHY_DISCON_BYP_LATCH (1 << 31)
>>  #define USB2PHY_ANA_CONFIG1 0x4c
>> @@ -107,6 +108,14 @@ static int omap_usb_power_off(struct phy *x)
>>  
>>  	omap_control_phy_power(phy->control_dev, 0);
>>  
>> +	if (phy->pwr) {
>> +		int ret;
>> +
>> +		ret = regulator_disable(phy->pwr);
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>>  	return 0;
>>  }
>>  
>> @@ -114,6 +123,14 @@ static int omap_usb_power_on(struct phy *x)
>>  {
>>  	struct omap_usb *phy = phy_get_drvdata(x);
>>  
>> +	if (phy->pwr) {
>> +		int ret;
>> +
>> +		ret = regulator_enable(phy->pwr);
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
> 
> Shouldn't we do this in phy_power_on/phy_power_off in phy-core?

I thought about that earlier, but could not find a way to defer probing if the regulator is not-yet probed.
Any clues how it could be done in phy-core?

cheers,
-roger

> 
>>  	omap_control_phy_power(phy->control_dev, 1);
>>  
>>  	return 0;
>> @@ -253,6 +270,14 @@ static int omap_usb2_probe(struct platform_device *pdev)
>>  	phy->control_dev = &control_pdev->dev;
>>  	omap_control_phy_power(phy->control_dev, 0);
>>  
>> +	/* phy-supply */
>> +	phy->pwr = devm_regulator_get_optional(phy->dev, "phy");
>> +	if (IS_ERR(phy->pwr)) {
>> +		if (PTR_ERR(phy->pwr) == -EPROBE_DEFER)
>> +			return -EPROBE_DEFER;
>> +		phy->pwr = NULL;
>> +	}
>> +
>>  	otg->set_host		= omap_usb_set_host;
>>  	otg->set_peripheral	= omap_usb_set_peripheral;
>>  	if (phy_data->flags & OMAP_USB2_HAS_SET_VBUS)
>> diff --git a/include/linux/phy/omap_usb.h b/include/linux/phy/omap_usb.h
>> index dc2c541..e2c46df 100644
>> --- a/include/linux/phy/omap_usb.h
>> +++ b/include/linux/phy/omap_usb.h
>> @@ -40,6 +40,7 @@ struct omap_usb {
>>  	struct clk		*wkupclk;
>>  	struct clk		*optclk;
>>  	u8			flags;
>> +	struct regulator	*pwr;
>>  };
>>  
>>  struct usb_phy_data {
>>

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kishon Vijay Abraham I July 1, 2014, 10:20 a.m. UTC | #4
Hi,

On Tuesday 01 July 2014 03:43 PM, Roger Quadros wrote:
> On 07/01/2014 12:56 PM, Kishon Vijay Abraham I wrote:
>> Hi Roger,
>>
>> On Monday 30 June 2014 04:30 PM, Roger Quadros wrote:
>>> On some SoCs e.g. J6 the 3.3V supply to the USB2 PHY can be
>>> powered down when the PHY is not in use. Add regulator
>>> management code to control this power line.
>>>
>>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>>> ---
>>>  drivers/phy/phy-omap-usb2.c  | 25 +++++++++++++++++++++++++
>>>  include/linux/phy/omap_usb.h |  1 +
>>>  2 files changed, 26 insertions(+)
>>>
>>> diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c
>>> index 7007c11..2afc79c 100644
>>> --- a/drivers/phy/phy-omap-usb2.c
>>> +++ b/drivers/phy/phy-omap-usb2.c
>>> @@ -30,6 +30,7 @@
>>>  #include <linux/phy/omap_control_phy.h>
>>>  #include <linux/phy/phy.h>
>>>  #include <linux/of_platform.h>
>>> +#include <linux/regulator/consumer.h>
>>>  
>>>  #define USB2PHY_DISCON_BYP_LATCH (1 << 31)
>>>  #define USB2PHY_ANA_CONFIG1 0x4c
>>> @@ -107,6 +108,14 @@ static int omap_usb_power_off(struct phy *x)
>>>  
>>>  	omap_control_phy_power(phy->control_dev, 0);
>>>  
>>> +	if (phy->pwr) {
>>> +		int ret;
>>> +
>>> +		ret = regulator_disable(phy->pwr);
>>> +		if (ret)
>>> +			return ret;
>>> +	}
>>> +
>>>  	return 0;
>>>  }
>>>  
>>> @@ -114,6 +123,14 @@ static int omap_usb_power_on(struct phy *x)
>>>  {
>>>  	struct omap_usb *phy = phy_get_drvdata(x);
>>>  
>>> +	if (phy->pwr) {
>>> +		int ret;
>>> +
>>> +		ret = regulator_enable(phy->pwr);
>>> +		if (ret)
>>> +			return ret;
>>> +	}
>>> +
>>
>> Shouldn't we do this in phy_power_on/phy_power_off in phy-core?
> 
> I thought about that earlier, but could not find a way to defer probing if the regulator is not-yet probed.
> Any clues how it could be done in phy-core?

We can try to do regulator_get in phy_create and return EPROBE_DEFER if the
regulator_get returns EPROBE_DEFER no?

Cheers
Kishon
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Roger Quadros July 1, 2014, 10:25 a.m. UTC | #5
On 07/01/2014 01:20 PM, Kishon Vijay Abraham I wrote:
> Hi,
> 
> On Tuesday 01 July 2014 03:43 PM, Roger Quadros wrote:
>> On 07/01/2014 12:56 PM, Kishon Vijay Abraham I wrote:
>>> Hi Roger,
>>>
>>> On Monday 30 June 2014 04:30 PM, Roger Quadros wrote:
>>>> On some SoCs e.g. J6 the 3.3V supply to the USB2 PHY can be
>>>> powered down when the PHY is not in use. Add regulator
>>>> management code to control this power line.
>>>>
>>>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>>>> ---
>>>>  drivers/phy/phy-omap-usb2.c  | 25 +++++++++++++++++++++++++
>>>>  include/linux/phy/omap_usb.h |  1 +
>>>>  2 files changed, 26 insertions(+)
>>>>
>>>> diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c
>>>> index 7007c11..2afc79c 100644
>>>> --- a/drivers/phy/phy-omap-usb2.c
>>>> +++ b/drivers/phy/phy-omap-usb2.c
>>>> @@ -30,6 +30,7 @@
>>>>  #include <linux/phy/omap_control_phy.h>
>>>>  #include <linux/phy/phy.h>
>>>>  #include <linux/of_platform.h>
>>>> +#include <linux/regulator/consumer.h>
>>>>  
>>>>  #define USB2PHY_DISCON_BYP_LATCH (1 << 31)
>>>>  #define USB2PHY_ANA_CONFIG1 0x4c
>>>> @@ -107,6 +108,14 @@ static int omap_usb_power_off(struct phy *x)
>>>>  
>>>>  	omap_control_phy_power(phy->control_dev, 0);
>>>>  
>>>> +	if (phy->pwr) {
>>>> +		int ret;
>>>> +
>>>> +		ret = regulator_disable(phy->pwr);
>>>> +		if (ret)
>>>> +			return ret;
>>>> +	}
>>>> +
>>>>  	return 0;
>>>>  }
>>>>  
>>>> @@ -114,6 +123,14 @@ static int omap_usb_power_on(struct phy *x)
>>>>  {
>>>>  	struct omap_usb *phy = phy_get_drvdata(x);
>>>>  
>>>> +	if (phy->pwr) {
>>>> +		int ret;
>>>> +
>>>> +		ret = regulator_enable(phy->pwr);
>>>> +		if (ret)
>>>> +			return ret;
>>>> +	}
>>>> +
>>>
>>> Shouldn't we do this in phy_power_on/phy_power_off in phy-core?
>>
>> I thought about that earlier, but could not find a way to defer probing if the regulator is not-yet probed.
>> Any clues how it could be done in phy-core?
> 
> We can try to do regulator_get in phy_create and return EPROBE_DEFER if the
> regulator_get returns EPROBE_DEFER no?

Yes indeed, we can. I missed the phy_create() and was only looking at phy_init() and phy_power_*() :P.
I'll post a v2 soon.

cheers,
-roger
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kishon Vijay Abraham I July 1, 2014, 10:37 a.m. UTC | #6
On Tuesday 01 July 2014 03:55 PM, Roger Quadros wrote:
> On 07/01/2014 01:20 PM, Kishon Vijay Abraham I wrote:
>> Hi,
>>
>> On Tuesday 01 July 2014 03:43 PM, Roger Quadros wrote:
>>> On 07/01/2014 12:56 PM, Kishon Vijay Abraham I wrote:
>>>> Hi Roger,
>>>>
>>>> On Monday 30 June 2014 04:30 PM, Roger Quadros wrote:
>>>>> On some SoCs e.g. J6 the 3.3V supply to the USB2 PHY can be
>>>>> powered down when the PHY is not in use. Add regulator
>>>>> management code to control this power line.
>>>>>
>>>>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>>>>> ---
>>>>>  drivers/phy/phy-omap-usb2.c  | 25 +++++++++++++++++++++++++
>>>>>  include/linux/phy/omap_usb.h |  1 +
>>>>>  2 files changed, 26 insertions(+)
>>>>>
>>>>> diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c
>>>>> index 7007c11..2afc79c 100644
>>>>> --- a/drivers/phy/phy-omap-usb2.c
>>>>> +++ b/drivers/phy/phy-omap-usb2.c
>>>>> @@ -30,6 +30,7 @@
>>>>>  #include <linux/phy/omap_control_phy.h>
>>>>>  #include <linux/phy/phy.h>
>>>>>  #include <linux/of_platform.h>
>>>>> +#include <linux/regulator/consumer.h>
>>>>>  
>>>>>  #define USB2PHY_DISCON_BYP_LATCH (1 << 31)
>>>>>  #define USB2PHY_ANA_CONFIG1 0x4c
>>>>> @@ -107,6 +108,14 @@ static int omap_usb_power_off(struct phy *x)
>>>>>  
>>>>>  	omap_control_phy_power(phy->control_dev, 0);
>>>>>  
>>>>> +	if (phy->pwr) {
>>>>> +		int ret;
>>>>> +
>>>>> +		ret = regulator_disable(phy->pwr);
>>>>> +		if (ret)
>>>>> +			return ret;
>>>>> +	}
>>>>> +
>>>>>  	return 0;
>>>>>  }
>>>>>  
>>>>> @@ -114,6 +123,14 @@ static int omap_usb_power_on(struct phy *x)
>>>>>  {
>>>>>  	struct omap_usb *phy = phy_get_drvdata(x);
>>>>>  
>>>>> +	if (phy->pwr) {
>>>>> +		int ret;
>>>>> +
>>>>> +		ret = regulator_enable(phy->pwr);
>>>>> +		if (ret)
>>>>> +			return ret;
>>>>> +	}
>>>>> +
>>>>
>>>> Shouldn't we do this in phy_power_on/phy_power_off in phy-core?
>>>
>>> I thought about that earlier, but could not find a way to defer probing if the regulator is not-yet probed.
>>> Any clues how it could be done in phy-core?
>>
>> We can try to do regulator_get in phy_create and return EPROBE_DEFER if the
>> regulator_get returns EPROBE_DEFER no?
> 
> Yes indeed, we can. I missed the phy_create() and was only looking at phy_init() and phy_power_*() :P.
> I'll post a v2 soon.

cool. Thanks :-)

-Kishon
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c
index 7007c11..2afc79c 100644
--- a/drivers/phy/phy-omap-usb2.c
+++ b/drivers/phy/phy-omap-usb2.c
@@ -30,6 +30,7 @@ 
 #include <linux/phy/omap_control_phy.h>
 #include <linux/phy/phy.h>
 #include <linux/of_platform.h>
+#include <linux/regulator/consumer.h>
 
 #define USB2PHY_DISCON_BYP_LATCH (1 << 31)
 #define USB2PHY_ANA_CONFIG1 0x4c
@@ -107,6 +108,14 @@  static int omap_usb_power_off(struct phy *x)
 
 	omap_control_phy_power(phy->control_dev, 0);
 
+	if (phy->pwr) {
+		int ret;
+
+		ret = regulator_disable(phy->pwr);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
@@ -114,6 +123,14 @@  static int omap_usb_power_on(struct phy *x)
 {
 	struct omap_usb *phy = phy_get_drvdata(x);
 
+	if (phy->pwr) {
+		int ret;
+
+		ret = regulator_enable(phy->pwr);
+		if (ret)
+			return ret;
+	}
+
 	omap_control_phy_power(phy->control_dev, 1);
 
 	return 0;
@@ -253,6 +270,14 @@  static int omap_usb2_probe(struct platform_device *pdev)
 	phy->control_dev = &control_pdev->dev;
 	omap_control_phy_power(phy->control_dev, 0);
 
+	/* phy-supply */
+	phy->pwr = devm_regulator_get_optional(phy->dev, "phy");
+	if (IS_ERR(phy->pwr)) {
+		if (PTR_ERR(phy->pwr) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		phy->pwr = NULL;
+	}
+
 	otg->set_host		= omap_usb_set_host;
 	otg->set_peripheral	= omap_usb_set_peripheral;
 	if (phy_data->flags & OMAP_USB2_HAS_SET_VBUS)
diff --git a/include/linux/phy/omap_usb.h b/include/linux/phy/omap_usb.h
index dc2c541..e2c46df 100644
--- a/include/linux/phy/omap_usb.h
+++ b/include/linux/phy/omap_usb.h
@@ -40,6 +40,7 @@  struct omap_usb {
 	struct clk		*wkupclk;
 	struct clk		*optclk;
 	u8			flags;
+	struct regulator	*pwr;
 };
 
 struct usb_phy_data {