diff mbox

[2/9] regulator: helper routine to extract regulator_init_data

Message ID 1317118372-17052-3-git-send-email-rnayak@ti.com
State New
Headers show

Commit Message

Rajendra Nayak Sept. 27, 2011, 10:12 a.m. UTC
The helper routine is meant to be used by regulator drivers
to extract the regulator_init_data structure from the data
that is passed from device tree.
'consumer_supplies' which is part of regulator_init_data is not extracted
as the regulator consumer mappings are passed through DT differently,
implemented in subsequent patches.

Also add documentation for regulator bindings to be used to pass
regulator_init_data struct information from device tree.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
 .../devicetree/bindings/regulator/regulator.txt    |   42 +++++++++
 drivers/regulator/Kconfig                          |    7 ++
 drivers/regulator/Makefile                         |    1 +
 drivers/regulator/of_regulator.c                   |   88 ++++++++++++++++++++
 include/linux/regulator/machine.h                  |   12 ++--
 include/linux/regulator/of_regulator.h             |   21 +++++
 6 files changed, 165 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/regulator/regulator.txt
 create mode 100644 drivers/regulator/of_regulator.c
 create mode 100644 include/linux/regulator/of_regulator.h

Comments

Mark Brown Sept. 27, 2011, 12:10 p.m. UTC | #1
On Tue, Sep 27, 2011 at 03:42:45PM +0530, Rajendra Nayak wrote:

> +	init_data = devm_kzalloc(dev, sizeof(struct regulator_init_data),
> +						 GFP_KERNEL);
> +	if (!init_data)
> +		return NULL; /* Out of memory? */

This means that the init data will be kept around for the entire
lifetime of the device rather than being discarded.

> +	init_data->supply_regulator = (char *)of_get_property(dev->of_node,
> +						"regulator-supplies", NULL);

I'd expect that in the device tree world the supply regulator would
reference the node for that regulator.

>  	/* voltage output range (inclusive) - for voltage control */
> -	int min_uV;
> -	int max_uV;
> +	u32 min_uV;
> +	u32 max_uV;
>  
> -	int uV_offset;
> +	u32 uV_offset;
>  
>  	/* current output range (inclusive) - for current control */
> -	int min_uA;
> -	int max_uA;
> +	u32 min_uA;
> +	u32 max_uA;

Hrm, I think loosing the signs here is bad karma - negative voltages do
exist after all.
Rajendra Nayak Sept. 27, 2011, 2:48 p.m. UTC | #2
On Tuesday 27 September 2011 05:40 PM, Mark Brown wrote:
> On Tue, Sep 27, 2011 at 03:42:45PM +0530, Rajendra Nayak wrote:
>
>> +	init_data = devm_kzalloc(dev, sizeof(struct regulator_init_data),
>> +						 GFP_KERNEL);
>> +	if (!init_data)
>> +		return NULL; /* Out of memory? */
>
> This means that the init data will be kept around for the entire
> lifetime of the device rather than being discarded.

Wasn't it the same while this was passed around as platform_data?

>
>> +	init_data->supply_regulator = (char *)of_get_property(dev->of_node,
>> +						"regulator-supplies", NULL);
>
> I'd expect that in the device tree world the supply regulator would
> reference the node for that regulator.

You mean using phandles? Thats what Grant proposed too but
I thought you instead had an inclination towards names? Or maybe
I misunderstood.

>
>>   	/* voltage output range (inclusive) - for voltage control */
>> -	int min_uV;
>> -	int max_uV;
>> +	u32 min_uV;
>> +	u32 max_uV;
>>
>> -	int uV_offset;
>> +	u32 uV_offset;
>>
>>   	/* current output range (inclusive) - for current control */
>> -	int min_uA;
>> -	int max_uA;
>> +	u32 min_uA;
>> +	u32 max_uA;
>
> Hrm, I think loosing the signs here is bad karma - negative voltages do
> exist after all.

Oops.. they do? didn't know about that.
Mark Brown Sept. 27, 2011, 3:05 p.m. UTC | #3
On Tue, Sep 27, 2011 at 08:18:04PM +0530, Rajendra Nayak wrote:
> On Tuesday 27 September 2011 05:40 PM, Mark Brown wrote:
> >On Tue, Sep 27, 2011 at 03:42:45PM +0530, Rajendra Nayak wrote:

> >>+	init_data = devm_kzalloc(dev, sizeof(struct regulator_init_data),
> >>+						 GFP_KERNEL);
> >>+	if (!init_data)
> >>+		return NULL; /* Out of memory? */

> >This means that the init data will be kept around for the entire
> >lifetime of the device rather than being discarded.

> Wasn't it the same while this was passed around as platform_data?

It was in the past but I remember fixing it at some point.  Perhaps I'm
imagining things.

> >>+	init_data->supply_regulator = (char *)of_get_property(dev->of_node,
> >>+						"regulator-supplies", NULL);

> >I'd expect that in the device tree world the supply regulator would
> >reference the node for that regulator.

> You mean using phandles? Thats what Grant proposed too but
> I thought you instead had an inclination towards names? Or maybe
> I misunderstood.

They need both.  We need to reference the device that provides the
supply and use a name to say which of the potentially multiple supplies
on the consumer device is which.

> >Hrm, I think loosing the signs here is bad karma - negative voltages do
> >exist after all.

> Oops.. they do? didn't know about that.

Yup, ground is just a reference point.
Cousson, Benoit Sept. 28, 2011, 8:06 a.m. UTC | #4
On 9/27/2011 5:05 PM, Mark Brown wrote:
> On Tue, Sep 27, 2011 at 08:18:04PM +0530, Rajendra Nayak wrote:
>> On Tuesday 27 September 2011 05:40 PM, Mark Brown wrote:
>>> On Tue, Sep 27, 2011 at 03:42:45PM +0530, Rajendra Nayak wrote:
>
>>>> +	init_data = devm_kzalloc(dev, sizeof(struct regulator_init_data),
>>>> +						 GFP_KERNEL);
>>>> +	if (!init_data)
>>>> +		return NULL; /* Out of memory? */
>
>>> This means that the init data will be kept around for the entire
>>> lifetime of the device rather than being discarded.
>
>> Wasn't it the same while this was passed around as platform_data?
>
> It was in the past but I remember fixing it at some point.  Perhaps I'm
> imagining things.
>
>>>> +	init_data->supply_regulator = (char *)of_get_property(dev->of_node,
>>>> +						"regulator-supplies", NULL);
>
>>> I'd expect that in the device tree world the supply regulator would
>>> reference the node for that regulator.
>
>> You mean using phandles? Thats what Grant proposed too but
>> I thought you instead had an inclination towards names? Or maybe
>> I misunderstood.
>
> They need both.  We need to reference the device that provides the
> supply and use a name to say which of the potentially multiple supplies
> on the consumer device is which.
>
>>> Hrm, I think loosing the signs here is bad karma - negative voltages do
>>> exist after all.
>
>> Oops.. they do? didn't know about that.
>
> Yup, ground is just a reference point.

Yep, we do have a negative charge pump to generate -1.9v from 3.8v to 
supply the audio power amplifier part in twl6040 for example.

Benoit
Grant Likely Sept. 30, 2011, 1:24 a.m. UTC | #5
On Tue, Sep 27, 2011 at 01:10:04PM +0100, Mark Brown wrote:
> On Tue, Sep 27, 2011 at 03:42:45PM +0530, Rajendra Nayak wrote:
> 
> > +	init_data = devm_kzalloc(dev, sizeof(struct regulator_init_data),
> > +						 GFP_KERNEL);
> > +	if (!init_data)
> > +		return NULL; /* Out of memory? */
> 
> This means that the init data will be kept around for the entire
> lifetime of the device rather than being discarded.
> 
> > +	init_data->supply_regulator = (char *)of_get_property(dev->of_node,
> > +						"regulator-supplies", NULL);
> 
> I'd expect that in the device tree world the supply regulator would
> reference the node for that regulator.

Yes, I would expect the same.
Rajendra Nayak Sept. 30, 2011, 4:27 a.m. UTC | #6
[]...
>
>>>> +	init_data->supply_regulator = (char *)of_get_property(dev->of_node,
>>>> +						"regulator-supplies", NULL);
>
>>> I'd expect that in the device tree world the supply regulator would
>>> reference the node for that regulator.
>
>> You mean using phandles? Thats what Grant proposed too but
>> I thought you instead had an inclination towards names? Or maybe
>> I misunderstood.
>
> They need both.  We need to reference the device that provides the
> supply and use a name to say which of the potentially multiple supplies
> on the consumer device is which.

Mark, I still seem to be a little confused with this one as to why
we would need a phandle *and* a supply-name to reference a parent
regulator/supply.
The phandle would point to a regulator dt node and that node internally
would have just one name associated with it.

>
>>> Hrm, I think loosing the signs here is bad karma - negative voltages do
>>> exist after all.
>
>> Oops.. they do? didn't know about that.
>
> Yup, ground is just a reference point.
Cousson, Benoit Sept. 30, 2011, 7:58 a.m. UTC | #7
On 9/30/2011 6:27 AM, Nayak, Rajendra wrote:

[...]

>> They need both.  We need to reference the device that provides the
>> supply and use a name to say which of the potentially multiple supplies
>> on the consumer device is which.
>
> Mark, I still seem to be a little confused with this one as to why
> we would need a phandle *and* a supply-name to reference a parent
> regulator/supply.
> The phandle would point to a regulator dt node and that node internally
> would have just one name associated with it.

I think as well that we should avoid considering a regulator with 
several outputs. I saw the same pattern used for the clock binding in DT 
as well.

A clock node like a regulator node should output only one signal.
These nodes should provide atomic functionality. And if extra 
functionality are needed we might consider adding some intermediate nodes.
Except for a regulator that will output several lines at the same 
voltage to spread the current load, assuming it does exist, I'm not sure 
to understand the need.

Mark,
What usage do you have in mind for such supply node with several outputs?

Regards,
Benoit
Mark Brown Sept. 30, 2011, 10:28 a.m. UTC | #8
On Fri, Sep 30, 2011 at 09:57:30AM +0530, Rajendra Nayak wrote:

> Mark, I still seem to be a little confused with this one as to why
> we would need a phandle *and* a supply-name to reference a parent
> regulator/supply.
> The phandle would point to a regulator dt node and that node internally
> would have just one name associated with it.

To repeat: the supply name is for the consumer.  It is needed so that
the consumer can tell which supply is provided by which regulator.
Almost all devices have more than one supply and if the device does
anything more complicated than just turning on all the supplies when the
device is active it's going to need to figure out which supply is which.

Also, please do remember to keep linux-kernel in the loop on all
regulator API discussion - you should always keep the relevant mailing
lists in the loop for any subsystem you're changing.
Mark Brown Sept. 30, 2011, 10:48 a.m. UTC | #9
On Fri, Sep 30, 2011 at 11:28:49AM +0100, Mark Brown wrote:
> On Fri, Sep 30, 2011 at 09:57:30AM +0530, Rajendra Nayak wrote:

>>>> +  init_data->supply_regulator = (char *)of_get_property(dev->of_node,
>>>> +                                          "regulator-supplies", NULL);

> > Mark, I still seem to be a little confused with this one as to why
> > we would need a phandle *and* a supply-name to reference a parent
> > regulator/supply.
> > The phandle would point to a regulator dt node and that node internally
> > would have just one name associated with it.

> To repeat: the supply name is for the consumer.  It is needed so that
> the consumer can tell which supply is provided by which regulator.
> Almost all devices have more than one supply and if the device does
> anything more complicated than just turning on all the supplies when the
> device is active it's going to need to figure out which supply is which.

Hang on, I now have no idea what this is supposed to be doing.  Later on
in the series you had examples in your commit logs with perfectly
sensible bindings for supplies:

                vmmc-supply = <&regulator1>;
                vpll-supply = <&regulator1>;

which have both a unique name and a direct reference to the supplying
regulator.  What are these "regulator-supplies" properties supposed to
be?
Mark Brown Sept. 30, 2011, 10:49 a.m. UTC | #10
On Fri, Sep 30, 2011 at 09:58:04AM +0200, Cousson, Benoit wrote:

> I think as well that we should avoid considering a regulator with
> several outputs. I saw the same pattern used for the clock binding
> in DT as well.

This binding is for the consumer side, not the producer side.  A binding
which restricted us to a single consumer per regulator would obviously
not work for real systems.
Rajendra Nayak Sept. 30, 2011, 11:09 a.m. UTC | #11
On Friday 30 September 2011 04:18 PM, Mark Brown wrote:
> On Fri, Sep 30, 2011 at 11:28:49AM +0100, Mark Brown wrote:
>> On Fri, Sep 30, 2011 at 09:57:30AM +0530, Rajendra Nayak wrote:
>
>>>>> +  init_data->supply_regulator = (char *)of_get_property(dev->of_node,
>>>>> +                                          "regulator-supplies", NULL);
>
>>> Mark, I still seem to be a little confused with this one as to why
>>> we would need a phandle *and* a supply-name to reference a parent
>>> regulator/supply.
>>> The phandle would point to a regulator dt node and that node internally
>>> would have just one name associated with it.
>
>> To repeat: the supply name is for the consumer.  It is needed so that
>> the consumer can tell which supply is provided by which regulator.
>> Almost all devices have more than one supply and if the device does
>> anything more complicated than just turning on all the supplies when the
>> device is active it's going to need to figure out which supply is which.
>
> Hang on, I now have no idea what this is supposed to be doing.  Later on
> in the series you had examples in your commit logs with perfectly
> sensible bindings for supplies:
>
>                  vmmc-supply =<&regulator1>;
>                  vpll-supply =<&regulator1>;
>
> which have both a unique name and a direct reference to the supplying
> regulator.  What are these "regulator-supplies" properties supposed to
> be?

:-), yes, I was confused for a while as well after reading your response.

The "regulator-supplies" is used to specific the regulator *parent*.
Same as what was earlier passed by using the
"supply_regulator" field of regulator_init_data structure.
Grant wanted the bindings to support specifying multiple parents
and hence I was thinking of either a list of names *or*
a list of phandles to specify multiple parents to a regulator.
Cousson, Benoit Sept. 30, 2011, 11:35 a.m. UTC | #12
On 9/30/2011 1:09 PM, Nayak, Rajendra wrote:
> On Friday 30 September 2011 04:18 PM, Mark Brown wrote:
>> On Fri, Sep 30, 2011 at 11:28:49AM +0100, Mark Brown wrote:
>>> On Fri, Sep 30, 2011 at 09:57:30AM +0530, Rajendra Nayak wrote:
>>
>>>>>> +  init_data->supply_regulator = (char *)of_get_property(dev->of_node,
>>>>>> +                                          "regulator-supplies", NULL);
>>
>>>> Mark, I still seem to be a little confused with this one as to why
>>>> we would need a phandle *and* a supply-name to reference a parent
>>>> regulator/supply.
>>>> The phandle would point to a regulator dt node and that node internally
>>>> would have just one name associated with it.
>>
>>> To repeat: the supply name is for the consumer.  It is needed so that
>>> the consumer can tell which supply is provided by which regulator.
>>> Almost all devices have more than one supply and if the device does
>>> anything more complicated than just turning on all the supplies when the
>>> device is active it's going to need to figure out which supply is which.
>>
>> Hang on, I now have no idea what this is supposed to be doing.  Later on
>> in the series you had examples in your commit logs with perfectly
>> sensible bindings for supplies:
>>
>>                   vmmc-supply =<&regulator1>;
>>                   vpll-supply =<&regulator1>;
>>
>> which have both a unique name and a direct reference to the supplying
>> regulator.  What are these "regulator-supplies" properties supposed to
>> be?
>
> :-), yes, I was confused for a while as well after reading your response.
>
> The "regulator-supplies" is used to specific the regulator *parent*.
> Same as what was earlier passed by using the
> "supply_regulator" field of regulator_init_data structure.
> Grant wanted the bindings to support specifying multiple parents
> and hence I was thinking of either a list of names *or*
> a list of phandles to specify multiple parents to a regulator.

I'm confused too now :-)

You can not have multiple to one kind of connection from a power supply 
to a single power rail of an IP (vmmc, vpll...).
So I do not see the need for more any other binding that the one you did:
	vmmc-supply = <&regulator1>;

That kind of binding does not really exist in the real world:

	vmmc-supply = <&regulator1 &regulator2>;

At least not without a power switch in between.

Regards,
Benoit
Mark Brown Sept. 30, 2011, 12:18 p.m. UTC | #13
On Fri, Sep 30, 2011 at 04:39:02PM +0530, Rajendra Nayak wrote:

> The "regulator-supplies" is used to specific the regulator *parent*.
> Same as what was earlier passed by using the
> "supply_regulator" field of regulator_init_data structure.
> Grant wanted the bindings to support specifying multiple parents
> and hence I was thinking of either a list of names *or*
> a list of phandles to specify multiple parents to a regulator.

So, as I'm fairly sure I said last time these are just standard
supplies.  It just happens to be that the consumer is a regulator.  The
fact that Linux chooses to have core framework handling for this is an
implementation detail of Linux (and indeed many devices ignore this for
their on board regulators).
Rajendra Nayak Oct. 4, 2011, 5:28 a.m. UTC | #14
On Friday 30 September 2011 05:48 PM, Mark Brown wrote:
> On Fri, Sep 30, 2011 at 04:39:02PM +0530, Rajendra Nayak wrote:
>
>> The "regulator-supplies" is used to specific the regulator *parent*.
>> Same as what was earlier passed by using the
>> "supply_regulator" field of regulator_init_data structure.
>> Grant wanted the bindings to support specifying multiple parents
>> and hence I was thinking of either a list of names *or*
>> a list of phandles to specify multiple parents to a regulator.
>
> So, as I'm fairly sure I said last time these are just standard
> supplies.  It just happens to be that the consumer is a regulator.  The
> fact that Linux chooses to have core framework handling for this is an
> implementation detail of Linux (and indeed many devices ignore this for
> their on board regulators).

Yes, the implementation details of linux is what is making me using
these bindings difficult, and maybe you can help me how I can work
around the framework. The binding themselves, I agree should not care
if the consumer is a device/IP or a regulator itself.

So here's my problem:

I use the <name-supply> = <&reg_phandle> binding to define
a device/IP using one/more regulators on one/more rails.

device mmc {
	...
	...
	vmmc-supply = <&vmmc>;
	vpll-supply = <&vpll>;
};

The parsing of the "vmmc-supply" or the "vpll-supply" property
happens only when a mmc drivers makes a call to
regulator_get() passing the supply-name as "vmmc" or "vpll".
For ex:
regulator_get(dev, "vmmc"); or regulator_get(dev, "vpll");

Its easy to just append the "-supply" to a "vmmc" or "vpll"
and derive a property name like "vmm-supply" or "vpll-supply".

Now lets take the case of a regulator as a consumer:

regulator vmmc {
	...
	...
	vin-supply = <&vin>;
};

Now I need to parse the "vin-supply" property during a
regulator_register(), so I could do a set_supply() and
create the parent/child relationship between a vin and
vmmc.
The problem is I don't know if the property in the regulator dt
node is called "vin-supply" or "vxyz-supply" and hence I
can parse the property based on a substring alone, which is
"-supply" because all I know is the property name is expected
to end with a "-supply".

I can always add a new of_find_property_substr() which finds
me property based on a substring value passed rather than the
exact property-name string.
However I don;t know if this is the best way to handle it.
Any thoughts?
Mark Brown Oct. 4, 2011, 10:18 a.m. UTC | #15
On Tue, Oct 04, 2011 at 10:58:40AM +0530, Rajendra Nayak wrote:

> The problem is I don't know if the property in the regulator dt
> node is called "vin-supply" or "vxyz-supply" and hence I
> can parse the property based on a substring alone, which is
> "-supply" because all I know is the property name is expected
> to end with a "-supply".

This seems fairly straightforward though it will require some changes
within Linux, all we have to do is have the regulators name their
supplies.
Rajendra Nayak Oct. 4, 2011, 11:40 a.m. UTC | #16
On Tuesday 04 October 2011 03:48 PM, Mark Brown wrote:
> On Tue, Oct 04, 2011 at 10:58:40AM +0530, Rajendra Nayak wrote:
>
>> The problem is I don't know if the property in the regulator dt
>> node is called "vin-supply" or "vxyz-supply" and hence I
>> can parse the property based on a substring alone, which is
>> "-supply" because all I know is the property name is expected
>> to end with a "-supply".
>
> This seems fairly straightforward though it will require some changes
> within Linux, all we have to do is have the regulators name their
> supplies.

through dt? thats what the original bindings was doing.
Mark Brown Oct. 4, 2011, 11:51 a.m. UTC | #17
On Tue, Oct 04, 2011 at 05:10:00PM +0530, Rajendra Nayak wrote:
> On Tuesday 04 October 2011 03:48 PM, Mark Brown wrote:

> >This seems fairly straightforward though it will require some changes
> >within Linux, all we have to do is have the regulators name their
> >supplies.

> through dt? thats what the original bindings was doing.

I wouldn't expect it done through DT (except for things like the fixed
voltage regulator) - the driver should just know.
Rajendra Nayak Oct. 4, 2011, 12:02 p.m. UTC | #18
On Tuesday 04 October 2011 05:21 PM, Mark Brown wrote:
> On Tue, Oct 04, 2011 at 05:10:00PM +0530, Rajendra Nayak wrote:
>> On Tuesday 04 October 2011 03:48 PM, Mark Brown wrote:
>
>>> This seems fairly straightforward though it will require some changes
>>> within Linux, all we have to do is have the regulators name their
>>> supplies.
>
>> through dt? thats what the original bindings was doing.
>
> I wouldn't expect it done through DT (except for things like the fixed
> voltage regulator) - the driver should just know.

something like a
int regulator_set_supply(struct regulator_dev *rdev, char *supply_name);
to be called from drivers makes sense?
Mark Brown Oct. 4, 2011, 12:11 p.m. UTC | #19
On Tue, Oct 04, 2011 at 05:32:47PM +0530, Rajendra Nayak wrote:
> On Tuesday 04 October 2011 05:21 PM, Mark Brown wrote:

> >I wouldn't expect it done through DT (except for things like the fixed
> >voltage regulator) - the driver should just know.

> something like a
> int regulator_set_supply(struct regulator_dev *rdev, char *supply_name);
> to be called from drivers makes sense?

Just put a member in the driver struct, much simpler that way, no code
in the individual drivers.
Rajendra Nayak Oct. 4, 2011, 12:40 p.m. UTC | #20
On Tue, Oct 4, 2011 at 5:41 PM, Mark Brown
<broonie@opensource.wolfsonmicro.com> wrote:
>
> On Tue, Oct 04, 2011 at 05:32:47PM +0530, Rajendra Nayak wrote:
> > On Tuesday 04 October 2011 05:21 PM, Mark Brown wrote:
>
> > >I wouldn't expect it done through DT (except for things like the fixed
> > >voltage regulator) - the driver should just know.
>
> > something like a
> > int regulator_set_supply(struct regulator_dev *rdev, char *supply_name);
> > to be called from drivers makes sense?
>
> Just put a member in the driver struct, much simpler that way, no code
> in the individual drivers.

okay, makes sense. I will add it to struct regulator_desc.
Thanks.
Russell King - ARM Linux Oct. 4, 2011, 11:01 p.m. UTC | #21
On Tue, Sep 27, 2011 at 01:10:04PM +0100, Mark Brown wrote:
> On Tue, Sep 27, 2011 at 03:42:45PM +0530, Rajendra Nayak wrote:
> 
> > +	init_data = devm_kzalloc(dev, sizeof(struct regulator_init_data),
> > +						 GFP_KERNEL);
> > +	if (!init_data)
> > +		return NULL; /* Out of memory? */
> 
> This means that the init data will be kept around for the entire
> lifetime of the device rather than being discarded.

May I remind you that devm_* lifetime expires whenever the associated
driver is unbound, which can be much shorter than the lifetime of the
struct device.

It expires when any of the following occurs:
1. userspace asks the associated driver to be unbound
2. the driver is removed
3. any driver probe for this struct device fails
4. the struct device is unregistered.

So: don't use devm_* for anything other than stuff inside a driver being
associated with the struct device itself.  Other uses are a bug waiting
to happen.
Grant Likely Oct. 4, 2011, 11:48 p.m. UTC | #22
On Wed, Oct 05, 2011 at 12:01:27AM +0100, Russell King - ARM Linux wrote:
> On Tue, Sep 27, 2011 at 01:10:04PM +0100, Mark Brown wrote:
> > On Tue, Sep 27, 2011 at 03:42:45PM +0530, Rajendra Nayak wrote:
> > 
> > > +	init_data = devm_kzalloc(dev, sizeof(struct regulator_init_data),
> > > +						 GFP_KERNEL);
> > > +	if (!init_data)
> > > +		return NULL; /* Out of memory? */
> > 
> > This means that the init data will be kept around for the entire
> > lifetime of the device rather than being discarded.
> 
> May I remind you that devm_* lifetime expires whenever the associated
> driver is unbound, which can be much shorter than the lifetime of the
> struct device.
> 
> It expires when any of the following occurs:
> 1. userspace asks the associated driver to be unbound
> 2. the driver is removed
> 3. any driver probe for this struct device fails
> 4. the struct device is unregistered.
> 
> So: don't use devm_* for anything other than stuff inside a driver being
> associated with the struct device itself.  Other uses are a bug waiting
> to happen.

Yes, Russell is right.  There were a number of places where I
suggested using devm_* in entirely the wrong places.  Double check
anyplace where you've added devm_ calls.

g.
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt
new file mode 100644
index 0000000..91b8d8f
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/regulator.txt
@@ -0,0 +1,42 @@ 
+Voltage/Current Regulators
+
+Optional properties:
+- regulator-supplies: Names of the regulator supplies
+- regulator-min-uV: smallest voltage consumers may set
+- regulator-max-uV: largest voltage consumers may set
+- regulator-uV-offset: Offset applied to voltages to compensate for voltage drops
+- regulator-min-uA: smallest current consumers may set
+- regulator-max-uA: largest current consumers may set
+- regulator-change-voltage: boolean, Output voltage can be changed by software
+- regulator-change-current: boolean, Output current can be chnaged by software
+- regulator-change-mode: boolean, Operating mode can be changed by software
+- regulator-change-status: boolean, Enable/Disable control for regulator exists
+- regulator-change-drms: boolean, Dynamic regulator mode switching is enabled
+- regulator-mode-fast: boolean, allow/set fast mode for the regulator
+- regulator-mode-normal: boolean, allow/set normal mode for the regulator
+- regulator-mode-idle: boolean, allow/set idle mode for the regulator
+- regulator-mode-standby: boolean, allow/set standby mode for the regulator
+- regulator-input-uV: Input voltage for regulator when supplied by another regulator
+- regulator-always-on: boolean, regulator should never be disabled
+- regulator-boot-on: bootloader/firmware enabled regulator
+
+Example:
+
+	xyzreg: regulator@0 {
+		regulator-min-uV = <1000000>;
+		regulator-max-uV = <2500000>;
+		regulator-mode-fast;
+		regulator-change-voltage;
+		regulator-always-on;
+	};
+
+Example of a device node referencing a regulator node:
+
+	devicenode: node@0x0 {
+		...
+		...
+		<name>-supply = <&xyzreg>;
+	};
+
+	where <name> is the supply name or regulator id passed
+	as part of regulator_get(dev, <name>);
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index c7fd2c0..2b684aa 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -64,6 +64,13 @@  config REGULATOR_USERSPACE_CONSUMER
 
           If unsure, say no.
 
+config OF_REGULATOR
+	tristate "OF regulator helpers"
+	depends on OF
+	help
+	  OpenFirmware regulator framework helper routines that can
+	  used by regulator drivers to extract data from device tree.
+
 config REGULATOR_BQ24022
 	tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC"
 	help
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 040d5aa..e6bc009 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -7,6 +7,7 @@  obj-$(CONFIG_REGULATOR) += core.o dummy.o
 obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
 obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
 obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
+obj-$(CONFIG_OF_REGULATOR) += of_regulator.o
 
 obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o
 obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
new file mode 100644
index 0000000..7fa63ff
--- /dev/null
+++ b/drivers/regulator/of_regulator.c
@@ -0,0 +1,88 @@ 
+/*
+ * OF helpers for regulator framework
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/regulator/machine.h>
+
+static void of_get_regulation_constraints(struct device_node *np,
+					struct regulator_init_data **init_data)
+{
+	unsigned int valid_modes_mask = 0, valid_ops_mask = 0;
+
+	of_property_read_u32(np, "regulator-min-uV",
+				&(*init_data)->constraints.min_uV);
+	of_property_read_u32(np, "regulator-max-uV",
+				&(*init_data)->constraints.max_uV);
+	of_property_read_u32(np, "regulator-uV-offset",
+				&(*init_data)->constraints.uV_offset);
+	of_property_read_u32(np, "regulator-min-uA",
+				&(*init_data)->constraints.min_uA);
+	of_property_read_u32(np, "regulator-max-uA",
+				&(*init_data)->constraints.max_uA);
+	of_property_read_u32(np, "regulator-input-uV",
+				&(*init_data)->constraints.input_uV);
+
+	/* valid modes mask */
+	if (of_find_property(np, "regulator-mode-fast", NULL))
+				valid_modes_mask |= REGULATOR_MODE_FAST;
+	if (of_find_property(np, "regulator-mode-normal", NULL))
+				valid_modes_mask |= REGULATOR_MODE_NORMAL;
+	if (of_find_property(np, "regulator-mode-idle", NULL))
+				valid_modes_mask |= REGULATOR_MODE_IDLE;
+	if (of_find_property(np, "regulator-mode-standby", NULL))
+				valid_modes_mask |= REGULATOR_MODE_STANDBY;
+
+	/* valid ops mask */
+	if (of_find_property(np, "regulator-change-voltage", NULL))
+				valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE;
+	if (of_find_property(np, "regulator-change-current", NULL))
+				valid_ops_mask |= REGULATOR_CHANGE_CURRENT;
+	if (of_find_property(np, "regulator-change-mode", NULL))
+				valid_ops_mask |= REGULATOR_CHANGE_MODE;
+	if (of_find_property(np, "regulator-change-status", NULL))
+				valid_ops_mask |= REGULATOR_CHANGE_STATUS;
+
+	(*init_data)->constraints.valid_modes_mask = valid_modes_mask;
+	(*init_data)->constraints.valid_ops_mask = valid_ops_mask;
+
+	if (of_find_property(np, "regulator-always-on", NULL))
+				(*init_data)->constraints.always_on = true;
+	if (of_find_property(np, "regulator-boot-on", NULL))
+				(*init_data)->constraints.boot_on = true;
+}
+
+/**
+ * of_get_regulator_init_data - extract regulator_init_data structure info
+ * @dev: device requesting for regulator_init_data
+ *
+ * Populates regulator_init_data structure by extracting data from device
+ * tree node, returns a pointer to the populated struture or NULL if memory
+ * alloc fails.
+ */
+struct regulator_init_data *of_get_regulator_init_data(struct device *dev)
+{
+	struct regulator_init_data *init_data;
+
+	if (!dev->of_node)
+		return NULL;
+
+	init_data = devm_kzalloc(dev, sizeof(struct regulator_init_data),
+						 GFP_KERNEL);
+	if (!init_data)
+		return NULL; /* Out of memory? */
+
+	init_data->supply_regulator = (char *)of_get_property(dev->of_node,
+						"regulator-supplies", NULL);
+	of_get_regulation_constraints(dev->of_node, &init_data);
+	return init_data;
+}
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index ce3127a..d2d921b 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -98,14 +98,14 @@  struct regulation_constraints {
 	char *name;
 
 	/* voltage output range (inclusive) - for voltage control */
-	int min_uV;
-	int max_uV;
+	u32 min_uV;
+	u32 max_uV;
 
-	int uV_offset;
+	u32 uV_offset;
 
 	/* current output range (inclusive) - for current control */
-	int min_uA;
-	int max_uA;
+	u32 min_uA;
+	u32 max_uA;
 
 	/* valid regulator operating modes for this machine */
 	unsigned int valid_modes_mask;
@@ -114,7 +114,7 @@  struct regulation_constraints {
 	unsigned int valid_ops_mask;
 
 	/* regulator input voltage - only if supply is another regulator */
-	int input_uV;
+	u32 input_uV;
 
 	/* regulator suspend states for global PMIC STANDBY/HIBERNATE */
 	struct regulator_state state_disk;
diff --git a/include/linux/regulator/of_regulator.h b/include/linux/regulator/of_regulator.h
new file mode 100644
index 0000000..3f63be9
--- /dev/null
+++ b/include/linux/regulator/of_regulator.h
@@ -0,0 +1,21 @@ 
+/*
+ * OpenFirmware regulator support routines
+ *
+ */
+
+#ifndef __LINUX_OF_REG_H
+#define __LINUX_OF_REG_H
+
+#if defined(CONFIG_OF_REGULATOR)
+extern struct regulator_init_data
+	*of_get_regulator_init_data(struct device *dev);
+#else
+static inline struct regulator_init_data
+	*of_get_regulator_init_data(struct device_node *np)
+{
+	return NULL;
+}
+#endif /* CONFIG_OF_REGULATOR */
+
+#endif /* __LINUX_OF_REG_H */
+