diff mbox series

[v2,3/4] hwmon/ltc2990: Add platform_data support

Message ID 20190812235237.21797-3-max@enpas.org (mailing list archive)
State Changes Requested
Headers show
Series [v2,1/4] i2c/busses: Add i2c-icy for I2C on m68k/Amiga | expand

Commit Message

Max Staudt Aug. 12, 2019, 11:52 p.m. UTC
This allows code using i2c_new_device() to specify a measurement mode.

Signed-off-by: Max Staudt <max@enpas.org>
---
 drivers/hwmon/ltc2990.c               |  9 +++++++++
 include/linux/platform_data/ltc2990.h | 11 +++++++++++
 2 files changed, 20 insertions(+)
 create mode 100644 include/linux/platform_data/ltc2990.h

Comments

Geert Uytterhoeven Aug. 13, 2019, 6:59 a.m. UTC | #1
On Tue, Aug 13, 2019 at 1:53 AM Max Staudt <max@enpas.org> wrote:
> This allows code using i2c_new_device() to specify a measurement mode.
>
> Signed-off-by: Max Staudt <max@enpas.org>

Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>

Gr{oetje,eeting}s,

                        Geert
Guenter Roeck Aug. 13, 2019, 8:02 a.m. UTC | #2
On Tue, Aug 13, 2019 at 01:52:36AM +0200, Max Staudt wrote:
> This allows code using i2c_new_device() to specify a measurement mode.
> 
> Signed-off-by: Max Staudt <max@enpas.org>
> Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
> ---
>  drivers/hwmon/ltc2990.c               |  9 +++++++++
>  include/linux/platform_data/ltc2990.h | 11 +++++++++++
>  2 files changed, 20 insertions(+)
>  create mode 100644 include/linux/platform_data/ltc2990.h
> 
> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
> index f9431ad43..f19b9c50c 100644
> --- a/drivers/hwmon/ltc2990.c
> +++ b/drivers/hwmon/ltc2990.c
> @@ -14,6 +14,7 @@
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> +#include <linux/platform_data/ltc2990.h>
>  
>  #define LTC2990_STATUS	0x00
>  #define LTC2990_CONTROL	0x01
> @@ -206,6 +207,7 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
>  	int ret;
>  	struct device *hwmon_dev;
>  	struct ltc2990_data *data;
> +	struct ltc2990_platform_data *pdata = dev_get_platdata(&i2c->dev);
>  	struct device_node *of_node = i2c->dev.of_node;
>  
>  	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
> @@ -227,6 +229,13 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
>  		if (data->mode[0] & ~LTC2990_MODE0_MASK ||
>  		    data->mode[1] & ~LTC2990_MODE1_MASK)
>  			return -EINVAL;
> +	} else if (pdata) {
> +		data->mode[0] = pdata->meas_mode[0];
> +		data->mode[1] = pdata->meas_mode[1];
> +
> +		if (data->mode[0] & ~LTC2990_MODE0_MASK ||
> +		    data->mode[1] & ~LTC2990_MODE1_MASK)
> +			return -EINVAL;

I would prefer if the driver was modified to accept device
properties, and if those were set using the appropriate
fwnode function. Any reason for not doing that ?

Thanks,
Guenter
Geert Uytterhoeven Aug. 13, 2019, 8:27 a.m. UTC | #3
Hi Günter,

On Tue, Aug 13, 2019 at 10:02 AM Guenter Roeck <linux@roeck-us.net> wrote:
> On Tue, Aug 13, 2019 at 01:52:36AM +0200, Max Staudt wrote:
> > This allows code using i2c_new_device() to specify a measurement mode.
> >
> > Signed-off-by: Max Staudt <max@enpas.org>
> > Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
> > ---
> >  drivers/hwmon/ltc2990.c               |  9 +++++++++
> >  include/linux/platform_data/ltc2990.h | 11 +++++++++++
> >  2 files changed, 20 insertions(+)
> >  create mode 100644 include/linux/platform_data/ltc2990.h
> >
> > diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
> > index f9431ad43..f19b9c50c 100644
> > --- a/drivers/hwmon/ltc2990.c
> > +++ b/drivers/hwmon/ltc2990.c
> > @@ -14,6 +14,7 @@
> >  #include <linux/kernel.h>
> >  #include <linux/module.h>
> >  #include <linux/of.h>
> > +#include <linux/platform_data/ltc2990.h>
> >
> >  #define LTC2990_STATUS       0x00
> >  #define LTC2990_CONTROL      0x01
> > @@ -206,6 +207,7 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
> >       int ret;
> >       struct device *hwmon_dev;
> >       struct ltc2990_data *data;
> > +     struct ltc2990_platform_data *pdata = dev_get_platdata(&i2c->dev);
> >       struct device_node *of_node = i2c->dev.of_node;
> >
> >       if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
> > @@ -227,6 +229,13 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
> >               if (data->mode[0] & ~LTC2990_MODE0_MASK ||
> >                   data->mode[1] & ~LTC2990_MODE1_MASK)
> >                       return -EINVAL;
> > +     } else if (pdata) {
> > +             data->mode[0] = pdata->meas_mode[0];
> > +             data->mode[1] = pdata->meas_mode[1];
> > +
> > +             if (data->mode[0] & ~LTC2990_MODE0_MASK ||
> > +                 data->mode[1] & ~LTC2990_MODE1_MASK)
> > +                     return -EINVAL;
>
> I would prefer if the driver was modified to accept device
> properties, and if those were set using the appropriate
> fwnode function. Any reason for not doing that ?

That was my first thought as well, but isn't that limited to DT and ACPI
properties (for now)?

Gr{oetje,eeting}s,

                        Geert
Max Staudt Aug. 13, 2019, 10:10 a.m. UTC | #4
On 08/13/2019 10:02 AM, Guenter Roeck wrote:
> On Tue, Aug 13, 2019 at 01:52:36AM +0200, Max Staudt wrote:
>> This allows code using i2c_new_device() to specify a measurement mode.
>>
>> Signed-off-by: Max Staudt <max@enpas.org>
>> Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
>> ---
>>  drivers/hwmon/ltc2990.c               |  9 +++++++++
>>  include/linux/platform_data/ltc2990.h | 11 +++++++++++
>>  2 files changed, 20 insertions(+)
>>  create mode 100644 include/linux/platform_data/ltc2990.h
>>
>> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
>> index f9431ad43..f19b9c50c 100644
>> --- a/drivers/hwmon/ltc2990.c
>> +++ b/drivers/hwmon/ltc2990.c
>> @@ -14,6 +14,7 @@
>>  #include <linux/kernel.h>
>>  #include <linux/module.h>
>>  #include <linux/of.h>
>> +#include <linux/platform_data/ltc2990.h>
>>  
>>  #define LTC2990_STATUS	0x00
>>  #define LTC2990_CONTROL	0x01
>> @@ -206,6 +207,7 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
>>  	int ret;
>>  	struct device *hwmon_dev;
>>  	struct ltc2990_data *data;
>> +	struct ltc2990_platform_data *pdata = dev_get_platdata(&i2c->dev);
>>  	struct device_node *of_node = i2c->dev.of_node;
>>  
>>  	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
>> @@ -227,6 +229,13 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
>>  		if (data->mode[0] & ~LTC2990_MODE0_MASK ||
>>  		    data->mode[1] & ~LTC2990_MODE1_MASK)
>>  			return -EINVAL;
>> +	} else if (pdata) {
>> +		data->mode[0] = pdata->meas_mode[0];
>> +		data->mode[1] = pdata->meas_mode[1];
>> +
>> +		if (data->mode[0] & ~LTC2990_MODE0_MASK ||
>> +		    data->mode[1] & ~LTC2990_MODE1_MASK)
>> +			return -EINVAL;
> 
> I would prefer if the driver was modified to accept device
> properties, and if those were set using the appropriate
> fwnode function. Any reason for not doing that ?

The driver does have DT support implemented right above my new platform_data code, and DT takes precedence. However, I can't set DT data programatically when instantiating the client using i2c_new_device() - hence the platform_data support.

Max
Guenter Roeck Aug. 13, 2019, 1:24 p.m. UTC | #5
On 8/13/19 3:10 AM, Max Staudt wrote:
> On 08/13/2019 10:02 AM, Guenter Roeck wrote:
>> On Tue, Aug 13, 2019 at 01:52:36AM +0200, Max Staudt wrote:
>>> This allows code using i2c_new_device() to specify a measurement mode.
>>>
>>> Signed-off-by: Max Staudt <max@enpas.org>
>>> Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
>>> ---
>>>   drivers/hwmon/ltc2990.c               |  9 +++++++++
>>>   include/linux/platform_data/ltc2990.h | 11 +++++++++++
>>>   2 files changed, 20 insertions(+)
>>>   create mode 100644 include/linux/platform_data/ltc2990.h
>>>
>>> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
>>> index f9431ad43..f19b9c50c 100644
>>> --- a/drivers/hwmon/ltc2990.c
>>> +++ b/drivers/hwmon/ltc2990.c
>>> @@ -14,6 +14,7 @@
>>>   #include <linux/kernel.h>
>>>   #include <linux/module.h>
>>>   #include <linux/of.h>
>>> +#include <linux/platform_data/ltc2990.h>
>>>   
>>>   #define LTC2990_STATUS	0x00
>>>   #define LTC2990_CONTROL	0x01
>>> @@ -206,6 +207,7 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
>>>   	int ret;
>>>   	struct device *hwmon_dev;
>>>   	struct ltc2990_data *data;
>>> +	struct ltc2990_platform_data *pdata = dev_get_platdata(&i2c->dev);
>>>   	struct device_node *of_node = i2c->dev.of_node;
>>>   
>>>   	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
>>> @@ -227,6 +229,13 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
>>>   		if (data->mode[0] & ~LTC2990_MODE0_MASK ||
>>>   		    data->mode[1] & ~LTC2990_MODE1_MASK)
>>>   			return -EINVAL;
>>> +	} else if (pdata) {
>>> +		data->mode[0] = pdata->meas_mode[0];
>>> +		data->mode[1] = pdata->meas_mode[1];
>>> +
>>> +		if (data->mode[0] & ~LTC2990_MODE0_MASK ||
>>> +		    data->mode[1] & ~LTC2990_MODE1_MASK)
>>> +			return -EINVAL;
>>
>> I would prefer if the driver was modified to accept device
>> properties, and if those were set using the appropriate
>> fwnode function. Any reason for not doing that ?
> 
> The driver does have DT support implemented right above my new platform_data code, and DT takes precedence. However, I can't set DT data programatically when instantiating the client using i2c_new_device() - hence the platform_data support.
> 

Sorry, I don't understand. Why exactly can't you replace of_property_read_u32_array()
with device_property_read_u32_array() and use fwnode_create_software_node()
in the calling code to set the properties ?

Guenter
Guenter Roeck Aug. 13, 2019, 1:27 p.m. UTC | #6
On 8/13/19 1:27 AM, Geert Uytterhoeven wrote:
> Hi Günter,
> 
> On Tue, Aug 13, 2019 at 10:02 AM Guenter Roeck <linux@roeck-us.net> wrote:
>> On Tue, Aug 13, 2019 at 01:52:36AM +0200, Max Staudt wrote:
>>> This allows code using i2c_new_device() to specify a measurement mode.
>>>
>>> Signed-off-by: Max Staudt <max@enpas.org>
>>> Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
>>> ---
>>>   drivers/hwmon/ltc2990.c               |  9 +++++++++
>>>   include/linux/platform_data/ltc2990.h | 11 +++++++++++
>>>   2 files changed, 20 insertions(+)
>>>   create mode 100644 include/linux/platform_data/ltc2990.h
>>>
>>> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
>>> index f9431ad43..f19b9c50c 100644
>>> --- a/drivers/hwmon/ltc2990.c
>>> +++ b/drivers/hwmon/ltc2990.c
>>> @@ -14,6 +14,7 @@
>>>   #include <linux/kernel.h>
>>>   #include <linux/module.h>
>>>   #include <linux/of.h>
>>> +#include <linux/platform_data/ltc2990.h>
>>>
>>>   #define LTC2990_STATUS       0x00
>>>   #define LTC2990_CONTROL      0x01
>>> @@ -206,6 +207,7 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
>>>        int ret;
>>>        struct device *hwmon_dev;
>>>        struct ltc2990_data *data;
>>> +     struct ltc2990_platform_data *pdata = dev_get_platdata(&i2c->dev);
>>>        struct device_node *of_node = i2c->dev.of_node;
>>>
>>>        if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
>>> @@ -227,6 +229,13 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
>>>                if (data->mode[0] & ~LTC2990_MODE0_MASK ||
>>>                    data->mode[1] & ~LTC2990_MODE1_MASK)
>>>                        return -EINVAL;
>>> +     } else if (pdata) {
>>> +             data->mode[0] = pdata->meas_mode[0];
>>> +             data->mode[1] = pdata->meas_mode[1];
>>> +
>>> +             if (data->mode[0] & ~LTC2990_MODE0_MASK ||
>>> +                 data->mode[1] & ~LTC2990_MODE1_MASK)
>>> +                     return -EINVAL;
>>
>> I would prefer if the driver was modified to accept device
>> properties, and if those were set using the appropriate
>> fwnode function. Any reason for not doing that ?
> 
> That was my first thought as well, but isn't that limited to DT and ACPI
> properties (for now)?
> 

tcpm and, for example, the wcove driver don't seem to have a problem using
it, I don't see acpi involved there. Also, the code resides in the core driver
code and is always enabled unless I am missing something. What am I missing ?

Guenter
Max Staudt Aug. 13, 2019, 1:31 p.m. UTC | #7
On 08/13/2019 03:24 PM, Guenter Roeck wrote:
> Sorry, I don't understand. Why exactly can't you replace of_property_read_u32_array()
> with device_property_read_u32_array() and use fwnode_create_software_node()
> in the calling code to set the properties ?

Sorry, I was unaware of this option. This sounds good, I'll look into it.

Max
Geert Uytterhoeven Aug. 13, 2019, 1:32 p.m. UTC | #8
Hi Günter,

On Tue, Aug 13, 2019 at 3:27 PM Guenter Roeck <linux@roeck-us.net> wrote:
> On 8/13/19 1:27 AM, Geert Uytterhoeven wrote:
> > On Tue, Aug 13, 2019 at 10:02 AM Guenter Roeck <linux@roeck-us.net> wrote:
> >> On Tue, Aug 13, 2019 at 01:52:36AM +0200, Max Staudt wrote:
> >>> This allows code using i2c_new_device() to specify a measurement mode.
> >>>
> >>> Signed-off-by: Max Staudt <max@enpas.org>
> >>> Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
> >>> ---
> >>>   drivers/hwmon/ltc2990.c               |  9 +++++++++
> >>>   include/linux/platform_data/ltc2990.h | 11 +++++++++++
> >>>   2 files changed, 20 insertions(+)
> >>>   create mode 100644 include/linux/platform_data/ltc2990.h
> >>>
> >>> diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
> >>> index f9431ad43..f19b9c50c 100644
> >>> --- a/drivers/hwmon/ltc2990.c
> >>> +++ b/drivers/hwmon/ltc2990.c
> >>> @@ -14,6 +14,7 @@
> >>>   #include <linux/kernel.h>
> >>>   #include <linux/module.h>
> >>>   #include <linux/of.h>
> >>> +#include <linux/platform_data/ltc2990.h>
> >>>
> >>>   #define LTC2990_STATUS       0x00
> >>>   #define LTC2990_CONTROL      0x01
> >>> @@ -206,6 +207,7 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
> >>>        int ret;
> >>>        struct device *hwmon_dev;
> >>>        struct ltc2990_data *data;
> >>> +     struct ltc2990_platform_data *pdata = dev_get_platdata(&i2c->dev);
> >>>        struct device_node *of_node = i2c->dev.of_node;
> >>>
> >>>        if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
> >>> @@ -227,6 +229,13 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
> >>>                if (data->mode[0] & ~LTC2990_MODE0_MASK ||
> >>>                    data->mode[1] & ~LTC2990_MODE1_MASK)
> >>>                        return -EINVAL;
> >>> +     } else if (pdata) {
> >>> +             data->mode[0] = pdata->meas_mode[0];
> >>> +             data->mode[1] = pdata->meas_mode[1];
> >>> +
> >>> +             if (data->mode[0] & ~LTC2990_MODE0_MASK ||
> >>> +                 data->mode[1] & ~LTC2990_MODE1_MASK)
> >>> +                     return -EINVAL;
> >>
> >> I would prefer if the driver was modified to accept device
> >> properties, and if those were set using the appropriate
> >> fwnode function. Any reason for not doing that ?
> >
> > That was my first thought as well, but isn't that limited to DT and ACPI
> > properties (for now)?
>
> tcpm and, for example, the wcove driver don't seem to have a problem using
> it, I don't see acpi involved there. Also, the code resides in the core driver

Cool, just discovered that, following your other fwnode_create_software_node()
pointer...

> code and is always enabled unless I am missing something. What am I missing ?

You're missing that I'm not up-to-date w.r.t. the latest fwnode properties
development ;-)

Thanks a lot!

Gr{oetje,eeting}s,

                        Geert
Max Staudt Aug. 14, 2019, 6:11 p.m. UTC | #9
Hi Guenter,

Thanks for your feedback!
Reply below.


On 08/13/2019 03:24 PM, Guenter Roeck wrote:
> Sorry, I don't understand. Why exactly can't you replace of_property_read_u32_array()
> with device_property_read_u32_array() and use fwnode_create_software_node()
> in the calling code to set the properties ?

Thanks for this hint.

Turns out wcove is the only user of fwnode_create_software_node(), and intel_cht_int33fe is the only other driver to contain the string "software_node". Please bear with us if we didn't know about this handy trick yet. And handy it is!

device_property_read_*() is also really helpful to know about, as it covers both the DT case, as well as other firmware interfaces - thanks for the hint. Is there any reason to ever use of_property_read_*() anymore?

I've applied your suggested changes, and will send another patch round soon (I want to try one last thing). Please let me/us know what you think once it's on the list.


Max
diff mbox series

Patch

diff --git a/drivers/hwmon/ltc2990.c b/drivers/hwmon/ltc2990.c
index f9431ad43..f19b9c50c 100644
--- a/drivers/hwmon/ltc2990.c
+++ b/drivers/hwmon/ltc2990.c
@@ -14,6 +14,7 @@ 
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_data/ltc2990.h>
 
 #define LTC2990_STATUS	0x00
 #define LTC2990_CONTROL	0x01
@@ -206,6 +207,7 @@  static int ltc2990_i2c_probe(struct i2c_client *i2c,
 	int ret;
 	struct device *hwmon_dev;
 	struct ltc2990_data *data;
+	struct ltc2990_platform_data *pdata = dev_get_platdata(&i2c->dev);
 	struct device_node *of_node = i2c->dev.of_node;
 
 	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
@@ -227,6 +229,13 @@  static int ltc2990_i2c_probe(struct i2c_client *i2c,
 		if (data->mode[0] & ~LTC2990_MODE0_MASK ||
 		    data->mode[1] & ~LTC2990_MODE1_MASK)
 			return -EINVAL;
+	} else if (pdata) {
+		data->mode[0] = pdata->meas_mode[0];
+		data->mode[1] = pdata->meas_mode[1];
+
+		if (data->mode[0] & ~LTC2990_MODE0_MASK ||
+		    data->mode[1] & ~LTC2990_MODE1_MASK)
+			return -EINVAL;
 	} else {
 		ret = i2c_smbus_read_byte_data(i2c, LTC2990_CONTROL);
 		if (ret < 0)
diff --git a/include/linux/platform_data/ltc2990.h b/include/linux/platform_data/ltc2990.h
new file mode 100644
index 000000000..7ec89e784
--- /dev/null
+++ b/include/linux/platform_data/ltc2990.h
@@ -0,0 +1,11 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef LTC2990_PDATA_H
+#define LTC2990_PDATA_H
+
+#include <linux/types.h>
+
+struct ltc2990_platform_data {
+	u8 meas_mode[2];
+};
+
+#endif /* LTC2990_PDATA_H */