diff mbox series

[v5,2/2] hwmon: scmi: Scale values to target desired HWMON units

Message ID 20190508184635.5054-3-f.fainelli@gmail.com (mailing list archive)
State Not Applicable
Headers show
Series hwmon: scmi: Scale values to target desired HWMON units | expand

Commit Message

Florian Fainelli May 8, 2019, 6:46 p.m. UTC
If the SCMI firmware implementation is reporting values in a scale that
is different from the HWMON units, we need to scale up or down the value
according to how far appart they are.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/hwmon/scmi-hwmon.c | 45 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

Comments

Guenter Roeck May 8, 2019, 9:10 p.m. UTC | #1
On Wed, May 08, 2019 at 11:46:35AM -0700, Florian Fainelli wrote:
> If the SCMI firmware implementation is reporting values in a scale that
> is different from the HWMON units, we need to scale up or down the value
> according to how far appart they are.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>

Reviewed-by: Guenter Roeck <linux@roeck-us.net>

Question is which tree this series should go through. I am fine with arm.

Thanks,
Guenter

> ---
>  drivers/hwmon/scmi-hwmon.c | 45 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
> 
> diff --git a/drivers/hwmon/scmi-hwmon.c b/drivers/hwmon/scmi-hwmon.c
> index a80183a488c5..2c7b87edf5aa 100644
> --- a/drivers/hwmon/scmi-hwmon.c
> +++ b/drivers/hwmon/scmi-hwmon.c
> @@ -18,6 +18,47 @@ struct scmi_sensors {
>  	const struct scmi_sensor_info **info[hwmon_max];
>  };
>  
> +static inline u64 __pow10(u8 x)
> +{
> +	u64 r = 1;
> +
> +	while (x--)
> +		r *= 10;
> +
> +	return r;
> +}
> +
> +static int scmi_hwmon_scale(const struct scmi_sensor_info *sensor, u64 *value)
> +{
> +	s8 scale = sensor->scale;
> +	u64 f;
> +
> +	switch (sensor->type) {
> +	case TEMPERATURE_C:
> +	case VOLTAGE:
> +	case CURRENT:
> +		scale += 3;
> +		break;
> +	case POWER:
> +	case ENERGY:
> +		scale += 6;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	if (abs(scale) > 19)
> +		return -E2BIG;
> +
> +	f = __pow10(abs(scale));
> +	if (scale > 0)
> +		*value *= f;
> +	else
> +		*value = div64_u64(*value, f);
> +
> +        return 0;
> +}
> +
>  static int scmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
>  			   u32 attr, int channel, long *val)
>  {
> @@ -29,6 +70,10 @@ static int scmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
>  
>  	sensor = *(scmi_sensors->info[type] + channel);
>  	ret = h->sensor_ops->reading_get(h, sensor->id, false, &value);
> +	if (ret)
> +		return ret;
> +
> +	ret = scmi_hwmon_scale(sensor, &value);
>  	if (!ret)
>  		*val = value;
>  
> -- 
> 2.17.1
>
Florian Fainelli May 13, 2019, 6:10 p.m. UTC | #2
On 5/8/19 2:10 PM, Guenter Roeck wrote:
> On Wed, May 08, 2019 at 11:46:35AM -0700, Florian Fainelli wrote:
>> If the SCMI firmware implementation is reporting values in a scale that
>> is different from the HWMON units, we need to scale up or down the value
>> according to how far appart they are.
>>
>> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> 
> Reviewed-by: Guenter Roeck <linux@roeck-us.net>
> 
> Question is which tree this series should go through. I am fine with arm.

Fine with me as well, Sudeep are you picking up these patches or should
they go through HWMON and Guenter?
Sudeep Holla May 14, 2019, 10:38 a.m. UTC | #3
On Mon, May 13, 2019 at 11:10:28AM -0700, Florian Fainelli wrote:
> On 5/8/19 2:10 PM, Guenter Roeck wrote:
> > On Wed, May 08, 2019 at 11:46:35AM -0700, Florian Fainelli wrote:
> >> If the SCMI firmware implementation is reporting values in a scale that
> >> is different from the HWMON units, we need to scale up or down the value
> >> according to how far appart they are.
> >>
> >> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> > 
> > Reviewed-by: Guenter Roeck <linux@roeck-us.net>
> > 
> > Question is which tree this series should go through. I am fine with arm.
> 
> Fine with me as well, Sudeep are you picking up these patches or should
> they go through HWMON and Guenter?

Sure I can pick and send it to arm-soc for v5.3

--
Regards,
Sudeep
Sudeep Holla May 14, 2019, 4:37 p.m. UTC | #4
On Wed, May 08, 2019 at 11:46:35AM -0700, Florian Fainelli wrote:
> If the SCMI firmware implementation is reporting values in a scale that
> is different from the HWMON units, we need to scale up or down the value
> according to how far appart they are.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
>  drivers/hwmon/scmi-hwmon.c | 45 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
> 
> diff --git a/drivers/hwmon/scmi-hwmon.c b/drivers/hwmon/scmi-hwmon.c
> index a80183a488c5..2c7b87edf5aa 100644
> --- a/drivers/hwmon/scmi-hwmon.c
> +++ b/drivers/hwmon/scmi-hwmon.c
> @@ -18,6 +18,47 @@ struct scmi_sensors {
>  	const struct scmi_sensor_info **info[hwmon_max];
>  };
>  
> +static inline u64 __pow10(u8 x)
> +{
> +	u64 r = 1;
> +
> +	while (x--)
> +		r *= 10;
> +
> +	return r;
> +}
> +
> +static int scmi_hwmon_scale(const struct scmi_sensor_info *sensor, u64 *value)
> +{
> +	s8 scale = sensor->scale;
> +	u64 f;
> +
> +	switch (sensor->type) {
> +	case TEMPERATURE_C:
> +	case VOLTAGE:
> +	case CURRENT:
> +		scale += 3;
> +		break;
> +	case POWER:
> +	case ENERGY:
> +		scale += 6;
> +		break;
> +	default:
> +		break;
> +	}
> +

I was applying this and wanted to check if we can add a check for scale=0
here and return early here to above the below check and __pow10(0) ?

Let me know if you agree. I can fix up. Also I will try to test it on
Juno if firmware behaves correctly :)

--
Regards,
Sudeep
Florian Fainelli May 14, 2019, 4:44 p.m. UTC | #5
On 5/14/19 9:37 AM, Sudeep Holla wrote:
> On Wed, May 08, 2019 at 11:46:35AM -0700, Florian Fainelli wrote:
>> If the SCMI firmware implementation is reporting values in a scale that
>> is different from the HWMON units, we need to scale up or down the value
>> according to how far appart they are.
>>
>> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
>> ---
>>  drivers/hwmon/scmi-hwmon.c | 45 ++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 45 insertions(+)
>>
>> diff --git a/drivers/hwmon/scmi-hwmon.c b/drivers/hwmon/scmi-hwmon.c
>> index a80183a488c5..2c7b87edf5aa 100644
>> --- a/drivers/hwmon/scmi-hwmon.c
>> +++ b/drivers/hwmon/scmi-hwmon.c
>> @@ -18,6 +18,47 @@ struct scmi_sensors {
>>  	const struct scmi_sensor_info **info[hwmon_max];
>>  };
>>  
>> +static inline u64 __pow10(u8 x)
>> +{
>> +	u64 r = 1;
>> +
>> +	while (x--)
>> +		r *= 10;
>> +
>> +	return r;
>> +}
>> +
>> +static int scmi_hwmon_scale(const struct scmi_sensor_info *sensor, u64 *value)
>> +{
>> +	s8 scale = sensor->scale;
>> +	u64 f;
>> +
>> +	switch (sensor->type) {
>> +	case TEMPERATURE_C:
>> +	case VOLTAGE:
>> +	case CURRENT:
>> +		scale += 3;
>> +		break;
>> +	case POWER:
>> +	case ENERGY:
>> +		scale += 6;
>> +		break;
>> +	default:
>> +		break;
>> +	}
>> +
> 
> I was applying this and wanted to check if we can add a check for scale=0
> here and return early here to above the below check and __pow10(0) ?

Doing an early check for scale == 0 sounds like a good idea,good catch!
Feel free to amend the patch directly when you apply it.

> 
> Let me know if you agree. I can fix up. Also I will try to test it on
> Juno if firmware behaves correctly :)

Great, thanks.
Guenter Roeck May 14, 2019, 4:58 p.m. UTC | #6
On Tue, May 14, 2019 at 09:44:02AM -0700, Florian Fainelli wrote:
> On 5/14/19 9:37 AM, Sudeep Holla wrote:
> > On Wed, May 08, 2019 at 11:46:35AM -0700, Florian Fainelli wrote:
> >> If the SCMI firmware implementation is reporting values in a scale that
> >> is different from the HWMON units, we need to scale up or down the value
> >> according to how far appart they are.
> >>
> >> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> >> ---
> >>  drivers/hwmon/scmi-hwmon.c | 45 ++++++++++++++++++++++++++++++++++++++
> >>  1 file changed, 45 insertions(+)
> >>
> >> diff --git a/drivers/hwmon/scmi-hwmon.c b/drivers/hwmon/scmi-hwmon.c
> >> index a80183a488c5..2c7b87edf5aa 100644
> >> --- a/drivers/hwmon/scmi-hwmon.c
> >> +++ b/drivers/hwmon/scmi-hwmon.c
> >> @@ -18,6 +18,47 @@ struct scmi_sensors {
> >>  	const struct scmi_sensor_info **info[hwmon_max];
> >>  };
> >>  
> >> +static inline u64 __pow10(u8 x)
> >> +{
> >> +	u64 r = 1;
> >> +
> >> +	while (x--)
> >> +		r *= 10;
> >> +
> >> +	return r;
> >> +}
> >> +
> >> +static int scmi_hwmon_scale(const struct scmi_sensor_info *sensor, u64 *value)
> >> +{
> >> +	s8 scale = sensor->scale;
> >> +	u64 f;
> >> +
> >> +	switch (sensor->type) {
> >> +	case TEMPERATURE_C:
> >> +	case VOLTAGE:
> >> +	case CURRENT:
> >> +		scale += 3;
> >> +		break;
> >> +	case POWER:
> >> +	case ENERGY:
> >> +		scale += 6;
> >> +		break;
> >> +	default:
> >> +		break;
> >> +	}
> >> +
> > 
> > I was applying this and wanted to check if we can add a check for scale=0
> > here and return early here to above the below check and __pow10(0) ?
> 
> Doing an early check for scale == 0 sounds like a good idea,good catch!
> Feel free to amend the patch directly when you apply it.
> 

Ok with me. Just make it == 0 :-).

Guenter

> > 
> > Let me know if you agree. I can fix up. Also I will try to test it on
> > Juno if firmware behaves correctly :)
> 
> Great, thanks.
> -- 
> Florian
Sudeep Holla May 14, 2019, 5 p.m. UTC | #7
On Tue, May 14, 2019 at 09:58:06AM -0700, Guenter Roeck wrote:
> On Tue, May 14, 2019 at 09:44:02AM -0700, Florian Fainelli wrote:
> > On 5/14/19 9:37 AM, Sudeep Holla wrote:
> > > On Wed, May 08, 2019 at 11:46:35AM -0700, Florian Fainelli wrote:
> > >> If the SCMI firmware implementation is reporting values in a scale that
> > >> is different from the HWMON units, we need to scale up or down the value
> > >> according to how far appart they are.
> > >>
> > >> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> > >> ---
> > >>  drivers/hwmon/scmi-hwmon.c | 45 ++++++++++++++++++++++++++++++++++++++
> > >>  1 file changed, 45 insertions(+)
> > >>
> > >> diff --git a/drivers/hwmon/scmi-hwmon.c b/drivers/hwmon/scmi-hwmon.c
> > >> index a80183a488c5..2c7b87edf5aa 100644
> > >> --- a/drivers/hwmon/scmi-hwmon.c
> > >> +++ b/drivers/hwmon/scmi-hwmon.c
> > >> @@ -18,6 +18,47 @@ struct scmi_sensors {
> > >>  	const struct scmi_sensor_info **info[hwmon_max];
> > >>  };
> > >>
> > >> +static inline u64 __pow10(u8 x)
> > >> +{
> > >> +	u64 r = 1;
> > >> +
> > >> +	while (x--)
> > >> +		r *= 10;
> > >> +
> > >> +	return r;
> > >> +}
> > >> +
> > >> +static int scmi_hwmon_scale(const struct scmi_sensor_info *sensor, u64 *value)
> > >> +{
> > >> +	s8 scale = sensor->scale;
> > >> +	u64 f;
> > >> +
> > >> +	switch (sensor->type) {
> > >> +	case TEMPERATURE_C:
> > >> +	case VOLTAGE:
> > >> +	case CURRENT:
> > >> +		scale += 3;
> > >> +		break;
> > >> +	case POWER:
> > >> +	case ENERGY:
> > >> +		scale += 6;
> > >> +		break;
> > >> +	default:
> > >> +		break;
> > >> +	}
> > >> +
> > >
> > > I was applying this and wanted to check if we can add a check for scale=0
> > > here and return early here to above the below check and __pow10(0) ?
> >
> > Doing an early check for scale == 0 sounds like a good idea,good catch!
> > Feel free to amend the patch directly when you apply it.
> >
>
> Ok with me. Just make it == 0 :-).
>

Thanks Guenter and Florian for quick response, done now.

--
Regards,
Sudeep
diff mbox series

Patch

diff --git a/drivers/hwmon/scmi-hwmon.c b/drivers/hwmon/scmi-hwmon.c
index a80183a488c5..2c7b87edf5aa 100644
--- a/drivers/hwmon/scmi-hwmon.c
+++ b/drivers/hwmon/scmi-hwmon.c
@@ -18,6 +18,47 @@  struct scmi_sensors {
 	const struct scmi_sensor_info **info[hwmon_max];
 };
 
+static inline u64 __pow10(u8 x)
+{
+	u64 r = 1;
+
+	while (x--)
+		r *= 10;
+
+	return r;
+}
+
+static int scmi_hwmon_scale(const struct scmi_sensor_info *sensor, u64 *value)
+{
+	s8 scale = sensor->scale;
+	u64 f;
+
+	switch (sensor->type) {
+	case TEMPERATURE_C:
+	case VOLTAGE:
+	case CURRENT:
+		scale += 3;
+		break;
+	case POWER:
+	case ENERGY:
+		scale += 6;
+		break;
+	default:
+		break;
+	}
+
+	if (abs(scale) > 19)
+		return -E2BIG;
+
+	f = __pow10(abs(scale));
+	if (scale > 0)
+		*value *= f;
+	else
+		*value = div64_u64(*value, f);
+
+        return 0;
+}
+
 static int scmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
 			   u32 attr, int channel, long *val)
 {
@@ -29,6 +70,10 @@  static int scmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
 
 	sensor = *(scmi_sensors->info[type] + channel);
 	ret = h->sensor_ops->reading_get(h, sensor->id, false, &value);
+	if (ret)
+		return ret;
+
+	ret = scmi_hwmon_scale(sensor, &value);
 	if (!ret)
 		*val = value;