linux-hwmon.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/2] hwmon: scmi: Scale values to target desired HWMON units
@ 2019-05-07 23:09 Florian Fainelli
  2019-05-07 23:09 ` [PATCH v3 1/2] firmware: arm_scmi: Fetch and store sensor scale Florian Fainelli
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Florian Fainelli @ 2019-05-07 23:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: bcm-kernel-feedback-list, Florian Fainelli, Sudeep Holla,
	Jean Delvare, Guenter Roeck, linux-arm-kernel,
	open list:HARDWARE MONITORING

Hi Sudeep, Guenter,

This patch series adds support for scaling SCMI sensor values read from
firmware. Sudeep, let me know if you think we should be treating scale
== 0 as a special value to preserve some firmware compatibility (not
that this would be desired).

Changes in v3:

- add a local __pow10 function to scmi-hwmon.c while a plan to provide
  a generic function is figured out.
- add check on power > 18 which would overflow a 64-bit unsigned integer
- use div64_u64() to properly divide a 64-bit quantity with an unsigned
  64-bit quantity

Changes in v2:

- added a helper function in kernel.h: __pow10()
- made the scale in scmi_sensor_info an s8 type, added defines for
  checking the sign bit and sign extending with a mask
- simplify computations in hwmon driver


Florian Fainelli (2):
  firmware: arm_scmi: Fetch and store sensor scale
  hwmon: scmi: Scale values to target desired HWMON units

 drivers/firmware/arm_scmi/sensors.c |  6 ++++
 drivers/hwmon/scmi-hwmon.c          | 43 ++++++++++++++++++++++++++++-
 include/linux/scmi_protocol.h       |  1 +
 3 files changed, 49 insertions(+), 1 deletion(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 1/2] firmware: arm_scmi: Fetch and store sensor scale
  2019-05-07 23:09 [PATCH v3 0/2] hwmon: scmi: Scale values to target desired HWMON units Florian Fainelli
@ 2019-05-07 23:09 ` Florian Fainelli
  2019-05-07 23:09 ` [PATCH v3 2/2] hwmon: scmi: Scale values to target desired HWMON units Florian Fainelli
  2019-05-08 11:35 ` [PATCH v3 0/2] " Sudeep Holla
  2 siblings, 0 replies; 7+ messages in thread
From: Florian Fainelli @ 2019-05-07 23:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: bcm-kernel-feedback-list, Florian Fainelli, Sudeep Holla,
	Jean Delvare, Guenter Roeck, linux-arm-kernel,
	open list:HARDWARE MONITORING

In preparation for dealing with scales within the SCMI HWMON driver,
fetch and store the sensor unit scale into the scmi_sensor_info
structure. In order to simplify computations for upper layer, take care
of sign extending the scale to a full 8-bit signed value.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/firmware/arm_scmi/sensors.c | 6 ++++++
 include/linux/scmi_protocol.h       | 1 +
 2 files changed, 7 insertions(+)

diff --git a/drivers/firmware/arm_scmi/sensors.c b/drivers/firmware/arm_scmi/sensors.c
index b53d5cc9c9f6..21353470a740 100644
--- a/drivers/firmware/arm_scmi/sensors.c
+++ b/drivers/firmware/arm_scmi/sensors.c
@@ -34,6 +34,8 @@ struct scmi_msg_resp_sensor_description {
 		__le32 attributes_high;
 #define SENSOR_TYPE(x)		((x) & 0xff)
 #define SENSOR_SCALE(x)		(((x) >> 11) & 0x3f)
+#define SENSOR_SCALE_SIGN	BIT(5)
+#define SENSOR_SCALE_EXTEND	GENMASK(7, 6)
 #define SENSOR_UPDATE_SCALE(x)	(((x) >> 22) & 0x1f)
 #define SENSOR_UPDATE_BASE(x)	(((x) >> 27) & 0x1f)
 		    u8 name[SCMI_MAX_STR_SIZE];
@@ -140,6 +142,10 @@ static int scmi_sensor_description_get(const struct scmi_handle *handle,
 			s = &si->sensors[desc_index + cnt];
 			s->id = le32_to_cpu(buf->desc[cnt].id);
 			s->type = SENSOR_TYPE(attrh);
+			s->scale = SENSOR_SCALE(attrh);
+			/* Sign extend to a full s8 */
+			if (s->scale & SENSOR_SCALE_SIGN)
+				s->scale |= SENSOR_SCALE_EXTEND;
 			strlcpy(s->name, buf->desc[cnt].name, SCMI_MAX_STR_SIZE);
 		}
 
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 3105055c00a7..9ff2e9357e9a 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -144,6 +144,7 @@ struct scmi_power_ops {
 struct scmi_sensor_info {
 	u32 id;
 	u8 type;
+	s8 scale;
 	char name[SCMI_MAX_STR_SIZE];
 };
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 2/2] hwmon: scmi: Scale values to target desired HWMON units
  2019-05-07 23:09 [PATCH v3 0/2] hwmon: scmi: Scale values to target desired HWMON units Florian Fainelli
  2019-05-07 23:09 ` [PATCH v3 1/2] firmware: arm_scmi: Fetch and store sensor scale Florian Fainelli
@ 2019-05-07 23:09 ` Florian Fainelli
  2019-05-07 23:41   ` Guenter Roeck
  2019-05-08 11:35 ` [PATCH v3 0/2] " Sudeep Holla
  2 siblings, 1 reply; 7+ messages in thread
From: Florian Fainelli @ 2019-05-07 23:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: bcm-kernel-feedback-list, Florian Fainelli, Sudeep Holla,
	Jean Delvare, Guenter Roeck, linux-arm-kernel,
	open list:HARDWARE MONITORING

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 | 43 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/hwmon/scmi-hwmon.c b/drivers/hwmon/scmi-hwmon.c
index a80183a488c5..7820854e5954 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;
+
+	if (unlikely(x > 18))
+		return r;
+
+	while (x--)
+		r *= 10;
+
+	return r;
+}
+
+static u64 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;
+	}
+
+	f = __pow10(abs(scale));
+	if (scale > 0)
+		value *= f;
+	else
+		value = div64_u64(value, f);
+
+        return value;
+}
+
 static int scmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
 			   u32 attr, int channel, long *val)
 {
@@ -30,7 +71,7 @@ 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)
-		*val = value;
+		*val = scmi_hwmon_scale(sensor, value);
 
 	return ret;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 2/2] hwmon: scmi: Scale values to target desired HWMON units
  2019-05-07 23:09 ` [PATCH v3 2/2] hwmon: scmi: Scale values to target desired HWMON units Florian Fainelli
@ 2019-05-07 23:41   ` Guenter Roeck
  0 siblings, 0 replies; 7+ messages in thread
From: Guenter Roeck @ 2019-05-07 23:41 UTC (permalink / raw)
  To: Florian Fainelli, linux-kernel
  Cc: bcm-kernel-feedback-list, Sudeep Holla, Jean Delvare,
	linux-arm-kernel, open list:HARDWARE MONITORING

On 5/7/19 4:09 PM, 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 | 43 +++++++++++++++++++++++++++++++++++++-
>   1 file changed, 42 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/hwmon/scmi-hwmon.c b/drivers/hwmon/scmi-hwmon.c
> index a80183a488c5..7820854e5954 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;
> +
> +	if (unlikely(x > 18))
> +		return r;
> +

Strictly speaking that would be 19 (10^19=0x8AC7230489E80000),
and I am not sure if returning 1 in that case is such a good idea.
If you really want to handle over/underflow situations, it should
be in the calling code.

Thanks,
Guenter

> +	while (x--)
> +		r *= 10;
> +
> +	return r;
> +}
> +
> +static u64 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;
> +	}
> +
> +	f = __pow10(abs(scale));
> +	if (scale > 0)
> +		value *= f;
> +	else
> +		value = div64_u64(value, f);
> +
> +        return value;
> +}
> +
>   static int scmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
>   			   u32 attr, int channel, long *val)
>   {
> @@ -30,7 +71,7 @@ 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)
> -		*val = value;
> +		*val = scmi_hwmon_scale(sensor, value);
>   
>   	return ret;
>   }
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 0/2] hwmon: scmi: Scale values to target desired HWMON units
  2019-05-07 23:09 [PATCH v3 0/2] hwmon: scmi: Scale values to target desired HWMON units Florian Fainelli
  2019-05-07 23:09 ` [PATCH v3 1/2] firmware: arm_scmi: Fetch and store sensor scale Florian Fainelli
  2019-05-07 23:09 ` [PATCH v3 2/2] hwmon: scmi: Scale values to target desired HWMON units Florian Fainelli
@ 2019-05-08 11:35 ` Sudeep Holla
  2019-05-08 16:26   ` Florian Fainelli
  2 siblings, 1 reply; 7+ messages in thread
From: Sudeep Holla @ 2019-05-08 11:35 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: linux-kernel, bcm-kernel-feedback-list, Jean Delvare,
	Guenter Roeck, linux-arm-kernel, open list:HARDWARE MONITORING,
	Sudeep Holla

On Tue, May 07, 2019 at 04:09:15PM -0700, Florian Fainelli wrote:
> Hi Sudeep, Guenter,
> 
> This patch series adds support for scaling SCMI sensor values read from
> firmware. Sudeep, let me know if you think we should be treating scale
> == 0 as a special value to preserve some firmware compatibility (not
> that this would be desired).

So are we providing raw values from sensors.c and handling conversion
in hwmon layer ? I was thinking of just providing converted values
to hwmon just in case if the scaling thing change in future with
newer versions of SCMI. I am fine either way, just trying to keep
hwmon-scmi simpler. I will check if scale = 0 needs to be treated as
special(I don't think so, but will read the spec)

--
Regards,
Sudeep

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 0/2] hwmon: scmi: Scale values to target desired HWMON units
  2019-05-08 11:35 ` [PATCH v3 0/2] " Sudeep Holla
@ 2019-05-08 16:26   ` Florian Fainelli
  2019-05-08 16:37     ` Guenter Roeck
  0 siblings, 1 reply; 7+ messages in thread
From: Florian Fainelli @ 2019-05-08 16:26 UTC (permalink / raw)
  To: Sudeep Holla, Florian Fainelli
  Cc: linux-kernel, bcm-kernel-feedback-list, Jean Delvare,
	Guenter Roeck, linux-arm-kernel, open list:HARDWARE MONITORING

On 5/8/19 4:35 AM, Sudeep Holla wrote:
> On Tue, May 07, 2019 at 04:09:15PM -0700, Florian Fainelli wrote:
>> Hi Sudeep, Guenter,
>>
>> This patch series adds support for scaling SCMI sensor values read from
>> firmware. Sudeep, let me know if you think we should be treating scale
>> == 0 as a special value to preserve some firmware compatibility (not
>> that this would be desired).
> 
> So are we providing raw values from sensors.c and handling conversion
> in hwmon layer ? I was thinking of just providing converted values
> to hwmon just in case if the scaling thing change in future with
> newer versions of SCMI.

These are the reasons why I went with doing the scaling in scmi-hwmon.c:

- scmi-hwmon.c is where we know the target units that should be matching
the HWMON conventions, if we put that scaling into sensors.c that would
be a layering violation IMHO

- within sensors.c we don't have a struct scmi_sensor_info to work with
when called with reading_get, we have a sensor_id, so we would have to
look up the id to struct scmi_sensor_info which is an additional loop,
doing this in scmi-hwmon.c gives us access to that structure directly

- scmi-sensors.c is also the location where the mapping between SCMI
sensor type to HWMON sensor type is done, so if we need to update the
scale from one to the other, we would rather do that where the mapping
is already done, which goes back to the first item.

> I am fine either way, just trying to keep
> hwmon-scmi simpler. I will check if scale = 0 needs to be treated as
> special(I don't think so, but will read the spec)

My concern is not so much with the spec but with assumptions SCMI
firmware writes might have made while populating sensor values. The spec
does not indicate any special treatment about a particular unit power of
10 scale being done or not, and a power of 0 = 1, so that should work okay.

Thanks for taking a look!
-- 
Florian

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 0/2] hwmon: scmi: Scale values to target desired HWMON units
  2019-05-08 16:26   ` Florian Fainelli
@ 2019-05-08 16:37     ` Guenter Roeck
  0 siblings, 0 replies; 7+ messages in thread
From: Guenter Roeck @ 2019-05-08 16:37 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Sudeep Holla, linux-kernel, bcm-kernel-feedback-list,
	Jean Delvare, linux-arm-kernel, open list:HARDWARE MONITORING

On Wed, May 08, 2019 at 09:26:10AM -0700, Florian Fainelli wrote:
> On 5/8/19 4:35 AM, Sudeep Holla wrote:
> > On Tue, May 07, 2019 at 04:09:15PM -0700, Florian Fainelli wrote:
> >> Hi Sudeep, Guenter,
> >>
> >> This patch series adds support for scaling SCMI sensor values read from
> >> firmware. Sudeep, let me know if you think we should be treating scale
> >> == 0 as a special value to preserve some firmware compatibility (not
> >> that this would be desired).
> > 
> > So are we providing raw values from sensors.c and handling conversion
> > in hwmon layer ? I was thinking of just providing converted values
> > to hwmon just in case if the scaling thing change in future with
> > newer versions of SCMI.
> 
> These are the reasons why I went with doing the scaling in scmi-hwmon.c:
> 
> - scmi-hwmon.c is where we know the target units that should be matching
> the HWMON conventions, if we put that scaling into sensors.c that would
> be a layering violation IMHO
> 
> - within sensors.c we don't have a struct scmi_sensor_info to work with
> when called with reading_get, we have a sensor_id, so we would have to
> look up the id to struct scmi_sensor_info which is an additional loop,
> doing this in scmi-hwmon.c gives us access to that structure directly
> 
> - scmi-sensors.c is also the location where the mapping between SCMI
> sensor type to HWMON sensor type is done, so if we need to update the
> scale from one to the other, we would rather do that where the mapping
> is already done, which goes back to the first item.
> 
> > I am fine either way, just trying to keep
> > hwmon-scmi simpler. I will check if scale = 0 needs to be treated as
> > special(I don't think so, but will read the spec)
> 
> My concern is not so much with the spec but with assumptions SCMI
> firmware writes might have made while populating sensor values. The spec
> does not indicate any special treatment about a particular unit power of
> 10 scale being done or not, and a power of 0 = 1, so that should work okay.
> 

FWIW, I agree with Florian. hwmon decides which units it wants to use.
Anything else would have to be more complicated: hwmon would have to request
the scale from SCMI, and SCMI would have to adjust its reported value based
on that. It is much easier to just take what we get and adjust internally.

Thanks,
Guenter

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-05-08 16:37 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-07 23:09 [PATCH v3 0/2] hwmon: scmi: Scale values to target desired HWMON units Florian Fainelli
2019-05-07 23:09 ` [PATCH v3 1/2] firmware: arm_scmi: Fetch and store sensor scale Florian Fainelli
2019-05-07 23:09 ` [PATCH v3 2/2] hwmon: scmi: Scale values to target desired HWMON units Florian Fainelli
2019-05-07 23:41   ` Guenter Roeck
2019-05-08 11:35 ` [PATCH v3 0/2] " Sudeep Holla
2019-05-08 16:26   ` Florian Fainelli
2019-05-08 16:37     ` Guenter Roeck

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).