hwmon: occ: Add callbacks for parsing P8 OCC datastructures
Subsystems (2)
PATCH 4/7 hwmon: occ: Add callbacks for parsing P8 OCC datastructures
From: "Edward A. James" <[email protected]>
Add functions to parse the data structures that are specific to the OCC on the POWER8 processor. These are the sensor data structures, including temperature, frequency, power, and "caps."
--- Documentation/hwmon/occ | 9 ++ drivers/hwmon/occ/occ_p8.c | 217 +++++++++++++++++++++++++++++++++++++++++++++ drivers/hwmon/occ/occ_p8.h | 30 +++++++ 3 files changed, 256 insertions(+) create mode 100644 drivers/hwmon/occ/occ_p8.c create mode 100644 drivers/hwmon/occ/occ_p8.h
Documentation/hwmon/occ +9 -0
@@ -25,6 +25,15 @@ Currently, all versions of the OCC support four types of sensor data: power, temperature, frequency, and "caps," which indicate limits and thresholds used internally on the OCC. +The format for the POWER8 OCC sensor data can be found in the P8 OCC +specification: +github.com/open-power/docs/blob/master/occ/OCC_OpenPwr_FW_Interfaces.pdf +This document provides the details of the OCC sensors: power, frequency, +temperature, and caps. These sensor formats are specific to the POWER8 OCC. A +number of data structures, such as command format, response headers, and the +like, are also defined in this specification, and are common to both POWER8 and +POWER9 OCCs. + sysfs Entries -------------
drivers/hwmon/occ/occ_p8.c new file +217 -0
217 lines not on this page · raw message
drivers/hwmon/occ/occ_p8.h new file +30 -0
@@ -0,0 +1,30 @@ +/* +* occ_p8.h - OCC hwmon driver +* +* This file contains Power8-specific function prototypes +* +* Copyright 2016 IBM Corp. +* +* 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. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#ifndef __OCC_P8_H__ +#define __OCC_P8_H__ + +#include "scom.h" + +struct device ; + +struct occ *p8_occ_start (struct device *dev,void *bus, +struct occ_bus_ops *bus_ops); +int p8_occ_stop (struct occ *occ); + +#endif /* __OCC_P8_H__ */
Signature · 1 line
1.9.1
Hi Eddie,
Quoted 8 lines · On Fri, 2016-12-16 at 14:35 -0600, [email protected] wrote:
Quoted 1 line
From: "Edward A. James" <[email protected]>
Add functions to parse the data structures that are specific to the OCC on the POWER8 processor. These are the sensor data structures, including temperature, frequency, power, and "caps."
Quoted 1 line
Signed-off-by Edward A. James <[email protected]>Signed-off-by Andrew Jeffery <[email protected]>
Looks good, considered it tagged Reviewed-by.
Similarly for the last reviewed-by I sent, as I've already supplied a Signed-off-by tag here don't worry about adding the reviewed-by tag to the patch.
Quoted 131 lines
---
Documentation/hwmon/occ | 9 ++
drivers/hwmon/occ/occ_p8.c | 217 +++++++++++++++++++++++++++++++++++++++++++++drivers/hwmon/occ/occ_p8.h| 30 +++++++3 files changed, 256 insertions(+)create mode 100644
drivers/hwmon/occ/occ_p8.c
create mode 100644drivers/hwmon/occ/occ_p8.hDocumentation/hwmon/occ +0
-0@@ -25,6 +25,15 @@ Currently, all versions of the OCC support four types of sensor data: power,temperature, frequency, and "caps," which indicate limits and thresholds used internally on the OCC.
Documentation/hwmon/occ +9
-0+The format for the POWER8 OCC sensor data can be found in the P8 OCC +specification: +github.com/open-power/docs/blob/master/occ/OCC_OpenPwr_FW_Interfaces.pdf +This document provides the details of the OCC sensors: power, frequency, +temperature, and caps. These sensor formats are specific to the POWER8 OCC. A +number of data structures, such as command format, response headers, and the +like, are also defined in this specification, and are common to both POWER8 and +POWER9 OCCs. +sysfs Entries
-------------drivers/hwmon/occ/occ_p8.c new file +34
-0@@ -0,0 +1,217 @@ +/* +* occ_p8.c - OCC hwmon driver +* +* This file contains the Power8-specific methods and data structures for +* the OCC hwmon driver. +* +* Copyright 2016 IBM Corp. +* +* 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. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/err.h> +#include <linux/of.h> +#include <linux/kernel.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <asm/unaligned.h> + +#include "occ.h" +#include "occ_p8.h" + +/* P8 OCC sensor data format */ +struct p8_occ_sensor {Quoted 2 lines
(quoted diff) +2
-0+ u16 sensor_id; + u16 value;drivers/hwmon/occ/occ_p8.c new file +3
-0+}; + +struct p8_power_sensor {Quoted 4 lines
drivers/hwmon/occ/occ_p8.c new file +4
-0+u16 sensor_id; +u32 update_tag; +u32 accumulator; +u16 value;drivers/hwmon/occ/occ_p8.c new file +3
-0+}; + +struct p8_caps_sensor {Quoted 6 lines
drivers/hwmon/occ/occ_p8.c new file +6
-0+u16 curr_powercap; +u16 curr_powerreading; +u16 norm_powercap; +u16 max_powercap; +u16 min_powercap; +u16 user_powerlimit;drivers/hwmon/occ/occ_p8.c new file +3
-0+}; + +void p8_parse_sensor(u8 *data, void *sensor, int sensor_type, int off,drivers/hwmon/occ/occ_p8.c line 56
Quoted 1 line
drivers/hwmon/occ/occ_p8.c new file +1
-0+ int snum)+{
drivers/hwmon/occ/occ_p8.c line 63
Quoted 6 lines
drivers/hwmon/occ/occ_p8.c new file +6
-0+switch (sensor_type) { +case FREQ : +case TEMP : + { +struct p8_occ_sensor *os = + &(((struct p8_occ_sensor *)sensor)[snum]);+
drivers/hwmon/occ/occ_p8.c line 72
Quoted 8 lines
drivers/hwmon/occ/occ_p8.c new file +8
-0+ os->sensor_id =be16_to_cpu (get_unaligned ((u16 *)&data[off])); + os->value =be16_to_cpu (get_unaligned ((u16 *)&data[off +2 ])); + } +break ; +case POWER : + { +struct p8_power_sensor *ps = + &(((struct p8_power_sensor *)sensor)[snum]);+
drivers/hwmon/occ/occ_p8.c line 85
Quoted 12 lines
drivers/hwmon/occ/occ_p8.c new file +12
-0+ ps->sensor_id =be16_to_cpu (get_unaligned ((u16 *)&data[off])); + ps->update_tag = +be32_to_cpu (get_unaligned ((u32 *)&data[off +2 ])); + ps->accumulator = +be32_to_cpu (get_unaligned ((u32 *)&data[off +6 ])); + ps->value =be16_to_cpu (get_unaligned ((u16 *)&data[off +10 ])); + } +break ; +case CAPS : + { +struct p8_caps_sensor *cs = + &(((struct p8_caps_sensor *)sensor)[snum]);+
Quoted 11 lines
drivers/hwmon/occ/occ_p8.c new file +11
-0+ cs->curr_powercap = +be16_to_cpu (get_unaligned ((u16 *)&data[off])); + cs->curr_powerreading = +be16_to_cpu (get_unaligned ((u16 *)&data[off +2 ])); + cs->norm_powercap = +be16_to_cpu (get_unaligned ((u16 *)&data[off +4 ])); + cs->max_powercap = +be16_to_cpu (get_unaligned ((u16 *)&data[off +6 ])); + cs->min_powercap = +be16_to_cpu (get_unaligned ((u16 *)&data[off +8 ])); + cs->user_powerlimit =
drivers/hwmon/occ/occ_p8.c line 98
Quoted 1 line
drivers/hwmon/occ/occ_p8.c new file +1
-0+be16_to_cpu (get_unaligned ((u16 *)&data[off +10 ]));
Conservative, but reasonable with the get_unaligned()s. From the perspective of the function we can't guarantee the value of 'off'.
Quoted 155 lines
drivers/hwmon/occ/occ_p8.c new file +1
-0+ }Quoted 2 lines
(quoted diff) +2
-0+ break; + };drivers/hwmon/occ/occ_p8.c new file +4
-0+} + +void *p8_alloc_sensor (int sensor_type,int num_sensors) +{Quoted 14 lines
drivers/hwmon/occ/occ_p8.c new file +14
-0+switch (sensor_type) { +case FREQ : +case TEMP : +return kcalloc (num_sensors,sizeof (struct p8_occ_sensor ), + GFP_KERNEL); +case POWER : +return kcalloc (num_sensors,sizeof (struct p8_power_sensor ), + GFP_KERNEL); +case CAPS : +return kcalloc (num_sensors,sizeof (struct p8_caps_sensor ), + GFP_KERNEL); +default : +return NULL ; + }drivers/hwmon/occ/occ_p8.c new file +4
-0+} + +int p8_get_sensor_value (struct occ *driver,int sensor_type,int snum) +{Review
Quoted 1 line
(quoted diff) +1
-0+ void *sensor;+
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (sensor_type == CAPS) + return -EINVAL;+
drivers/hwmon/occ/occ_p8.c line 131
Quoted 3 lines
drivers/hwmon/occ/occ_p8.c new file +3
-0+ sensor =occ_get_sensor (driver, sensor_type); +if (!sensor) +return -ENODEV ;+
Quoted 9 lines
drivers/hwmon/occ/occ_p8.c new file +9
-0+switch (sensor_type) { +case FREQ : +case TEMP : +return ((struct p8_occ_sensor *)sensor)[snum].value; +case POWER : +return ((struct p8_power_sensor *)sensor)[snum].value; +default : +return -EINVAL ; + }drivers/hwmon/occ/occ_p8.c new file +4
-0+} + +int p8_get_sensor_id (struct occ *driver,int sensor_type,int snum) +{Review
Quoted 2 lines
(quoted diff) +2
-0+ void *sensor; + int i = snum;+
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (sensor_type == CAPS) + return -EINVAL;+
drivers/hwmon/occ/occ_p8.c line 131
Quoted 3 lines
drivers/hwmon/occ/occ_p8.c new file +3
-0+ sensor =occ_get_sensor (driver, sensor_type); +if (!sensor) +return -ENODEV ;+
Quoted 9 lines
drivers/hwmon/occ/occ_p8.c new file +9
-0+switch (sensor_type) { +case FREQ : +case TEMP : +return ((struct p8_occ_sensor *)sensor)[i].sensor_id; +case POWER : +return ((struct p8_power_sensor *)sensor)[i].sensor_id; +default : +return -EINVAL ; + }drivers/hwmon/occ/occ_p8.c new file +4
-0+} + +int p8_get_caps_value (void *sensor,int snum,int caps_field) +{drivers/hwmon/occ/occ_p8.c line 169
Quoted 1 line
drivers/hwmon/occ/occ_p8.c new file +1
-0+struct p8_caps_sensor *caps_sensor = sensor;+
Quoted 16 lines
drivers/hwmon/occ/occ_p8.c new file +16
-0+switch (caps_field) { +case 0 : +return caps_sensor[snum].curr_powercap; +case 1 : +return caps_sensor[snum].curr_powerreading; +case 2 : +return caps_sensor[snum].norm_powercap; +case 3 : +return caps_sensor[snum].max_powercap; +case 4 : +return caps_sensor[snum].min_powercap; +case 5 : +return caps_sensor[snum].user_powerlimit; +default : +return -EINVAL ; + }drivers/hwmon/occ/occ_p8.c new file +3
-0+} + +static const struct occ_ops p8_ops = {Quoted 5 lines
drivers/hwmon/occ/occ_p8.c new file +5
-0+ .parse_sensor = p8_parse_sensor, + .alloc_sensor = p8_alloc_sensor, + .get_sensor_value = p8_get_sensor_value, + .get_sensor_id = p8_get_sensor_id, + .get_caps_value = p8_get_caps_value,drivers/hwmon/occ/occ_p8.c new file +3
-0+}; + +static const struct occ_config p8_config = {Quoted 2 lines
drivers/hwmon/occ/occ_p8.c new file +2
-0+ .command_addr = 0xFFFF6000, + .response_addr = 0xFFFF7000,drivers/hwmon/occ/occ_p8.c new file +3
-0+}; + +struct occ *p8_occ_start(struct device *dev, void *bus,drivers/hwmon/occ/occ_p8.c line 203
Quoted 1 line
drivers/hwmon/occ/occ_p8.c new file +1
-0+ struct occ_bus_ops *bus_ops)+{
Quoted 1 line
drivers/hwmon/occ/occ_p8.c new file +1
-0+return occ_start (dev, bus, bus_ops, &p8_ops, &p8_config);drivers/hwmon/occ/occ_p8.c new file +5
-0+} +EXPORT_SYMBOL (p8_occ_start); + +int p8_occ_stop (struct occ *occ) +{Quoted 1 line
drivers/hwmon/occ/occ_p8.c new file +1
-0+return occ_stop (occ);drivers/hwmon/occ/occ_p8.c new file +3
-0+} +EXPORT_SYMBOL (p8_occ_stop); +Quoted 1 line
+MODULE_AUTHOR("Eddie James <[email protected]>");
drivers/hwmon/occ/occ_p8.c new file +2
-0+MODULE_DESCRIPTION ("P8 OCC sensors" ); +MODULE_LICENSE ("GPL" );drivers/hwmon/occ/occ_p8.h new file +26
-0@@ -0,0 +1,30 @@ +/* +* occ_p8.h - OCC hwmon driver +* +* This file contains Power8-specific function prototypes +* +* Copyright 2016 IBM Corp. +* +* 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. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#ifndef __OCC_P8_H__ +#define __OCC_P8_H__ + +#include "scom.h" + +struct device ; + +struct occ *p8_occ_start(struct device *dev, void *bus,Quoted 1 line
drivers/hwmon/occ/occ_p8.h new file +1
-0+ struct occ_bus_ops *bus_ops);drivers/hwmon/occ/occ_p8.h new file +3
-0+int p8_occ_stop (struct occ *occ); + +#endif /* __OCC_P8_H__ */