hwmon: occ: Add callbacks for parsing P9 OCC datastructures
Subsystems (2)
PATCH 7/7 hwmon: occ: Add callbacks for parsing P9 OCC datastructures
From: "Edward A. James" <[email protected]>
Add functions to parse the data structures that are specific to the OCC on the POWER9 processor. These are the sensor data structures, including temperature, frequency, power, and "caps."
--- Documentation/hwmon/occ | 3 + drivers/hwmon/occ/occ_p9.c | 243 +++++++++++++++++++++++++++++++++++++++++++++ drivers/hwmon/occ/occ_p9.h | 30 ++++++ 3 files changed, 276 insertions(+) create mode 100644 drivers/hwmon/occ/occ_p9.c create mode 100644 drivers/hwmon/occ/occ_p9.h
Documentation/hwmon/occ +3 -0
@@ -34,6 +34,9 @@ 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. +There is currently no public P9 OCC specification, and the data structures +defined in the POWER9 OCC driver are subject to change. + sysfs Entries -------------
drivers/hwmon/occ/occ_p9.c new file +243 -0
243 lines not on this page · raw message
drivers/hwmon/occ/occ_p9.h new file +30 -0
@@ -0,0 +1,30 @@ +/* +* occ_p9.h - OCC hwmon driver +* +* This file contains Power9-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_P9_H__ +#define __OCC_P9_H__ + +#include "scom.h" + +struct device ; + +struct occ *p9_occ_start (struct device *dev,void *bus, +struct occ_bus_ops *bus_ops); +int p9_occ_stop (struct occ *occ); + +#endif /* __OCC_P9_H__ */
Signature · 1 line
1.9.1
Quoted 107 lines · On Fri, 2016-12-16 at 14:36 -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 POWER9 processor. These are the sensor data structures, including temperature, frequency, power, and "caps."
Quoted 2 lines
Signed-off-by Edward A. James <[email protected]>Signed-off-by Andrew Jeffery <[email protected]>---
Documentation/hwmon/occ | 3 +
drivers/hwmon/occ/occ_p9.c | 243 +++++++++++++++++++++++++++++++++++++++++++++drivers/hwmon/occ/occ_p9.h| 30 ++++++3 files changed, 276 insertions(+)create mode 100644
drivers/hwmon/occ/occ_p9.c
create mode 100644drivers/hwmon/occ/occ_p9.hDocumentation/hwmon/occ +0
-0@@ -34,6 +34,9 @@ number of data structures, such as command format, response headers, and thelike, are also defined in this specification, and are common to both POWER8 and POWER9 OCCs.
Documentation/hwmon/occ +3
-0+There is currently no public P9 OCC specification, and the data structures +defined in the POWER9 OCC driver are subject to change. +sysfs Entries
-------------drivers/hwmon/occ/occ_p9.c new file +34
-0@@ -0,0 +1,243 @@ +/* +* p9.c - OCC hwmon driver +* +* This file contains the Power9-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/i2c.h> +#include <linux/err.h> +#include <linux/of.h> +#include <linux/kernel.h> +#include <linux/device.h> +#include <asm/unaligned.h> + +#include "occ.h" +#include "occ_p9.h" + +/* P9 OCC sensor data format */ +struct p9_temp_sensor {Quoted 3 lines
drivers/hwmon/occ/occ_p9.c new file +3
-0+u32 sensor_id; +u8 fru_type; +u8 value;drivers/hwmon/occ/occ_p9.c new file +3
-0+}; + +struct p8_freq_sensor {Quoted 2 lines
(quoted diff) +2
-0+ u32 sensor_id; + u16 value;drivers/hwmon/occ/occ_p9.c new file +3
-0+}; + +struct p9_power_sensor {Quoted 7 lines
drivers/hwmon/occ/occ_p9.c new file +7
-0+u32 sensor_id; +u8 function_id; +u8 apss_channel; +u16 reserved; +u32 update_tag; +u64 accumulator; +u16 value;drivers/hwmon/occ/occ_p9.c new file +3
-0+}; + +struct p9_caps_sensor {Quoted 7 lines
drivers/hwmon/occ/occ_p9.c new file +7
-0+u16 curr_powercap; +u16 curr_powerreading; +u16 norm_powercap; +u16 max_powercap; +u16 min_powercap; +u16 user_powerlimit; +u8 user_powerlimit_source;drivers/hwmon/occ/occ_p9.c new file +3
-0+}; + +void p9_parse_sensor(u8 *data, void *sensor, int sensor_type, int off,drivers/hwmon/occ/occ_p9.c line 66
Quoted 1 line
drivers/hwmon/occ/occ_p9.c new file +1
-0+ int snum)+{
Quoted 4 lines
drivers/hwmon/occ/occ_p9.c new file +4
-0+switch (sensor_type) { +case FREQ : + { + struct p8_freq_sensor *fs =
drivers/hwmon/occ/occ_p9.c line 72
Quoted 1 line
drivers/hwmon/occ/occ_p9.c new file +1
-0+ &(((struct p8_freq_sensor *)sensor)[snum]);
Looks like your search/replace might have gone wrong here, as this is referencing a *p8* type, not p9.
Quoted 57 lines
+
drivers/hwmon/occ/occ_p9.c line 81
Quoted 8 lines
drivers/hwmon/occ/occ_p9.c new file +8
-0+ fs->sensor_id =be32_to_cpu (get_unaligned ((u32 *)&data[off])); + fs->value =be16_to_cpu (get_unaligned ((u16 *)&data[off +4 ])); + } +break ; +case TEMP : + { +struct p9_temp_sensor *ts = + &(((struct p9_temp_sensor *)sensor)[snum]);+
drivers/hwmon/occ/occ_p9.c line 91
Quoted 9 lines
drivers/hwmon/occ/occ_p9.c new file +9
-0+ ts->sensor_id =be32_to_cpu (get_unaligned ((u32 *)&data[off])); + fs->fru_type = data[off +4 ]; + fs->value = data[off +5 ]; + } +break ; +case POWER : + { +struct p9_power_sensor *ps = + &(((struct p9_power_sensor *)sensor)[snum]);+
Quoted 4 lines
drivers/hwmon/occ/occ_p9.c new file +4
-0+ ps->sensor_id =be32_to_cpu (get_unaligned ((u32 *)&data[off])); + ps->function_id = data[off +4 ]; + ps->apss_channel = data[off +5 ]; + ps->update_tag =drivers/hwmon/occ/occ_p9.c line 106
Quoted 10 lines
drivers/hwmon/occ/occ_p9.c new file +10
-0+be32_to_cpu (get_unaligned ((u32 *)&data[off +8 ])); + ps->accumulator = +be64_to_cpu (get_unaligned ((u64 *)&data[off +12 ])); + ps->value =be16_to_cpu (get_unaligned ((u16 *)&data[off +20 ])); + } +break ; +case CAPS : + { +struct p9_caps_sensor *cs = + &(((struct p9_caps_sensor *)sensor)[snum]);+
Quoted 16 lines
drivers/hwmon/occ/occ_p9.c new file +16
-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 = +be16_to_cpu (get_unaligned ((u16 *)&data[off +10 ])); + cs->user_powerlimit_source = data[off +12 ]; + } +break ; + };drivers/hwmon/occ/occ_p9.c new file +4
-0+} + +void *p9_alloc_sensor (int sensor_type,int num_sensors) +{Quoted 2 lines
(quoted diff) +2
-0+ switch (sensor_type) { + case FREQ:
drivers/hwmon/occ/occ_p9.c line 130
Quoted 1 line
drivers/hwmon/occ/occ_p9.c new file +1
-0+ return kcalloc(num_sensors, sizeof(struct p8_freq_sensor),
p8 again here, should be p9.
Other than that, looks good. Consider it tagged reviewed-by when you have applied these fixes.
Quoted 149 lines
drivers/hwmon/occ/occ_p9.c new file +1
-0+ GFP_KERNEL);Quoted 12 lines
drivers/hwmon/occ/occ_p9.c new file +12
-0+case TEMP : +return kcalloc (num_sensors,sizeof (struct p9_temp_sensor ), + GFP_KERNEL); +case POWER : +return kcalloc (num_sensors,sizeof (struct p9_power_sensor ), + GFP_KERNEL); +case CAPS : +return kcalloc (num_sensors,sizeof (struct p9_caps_sensor ), + GFP_KERNEL); +default : +return NULL ; + }drivers/hwmon/occ/occ_p9.c new file +4
-0+} + +int p9_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_p9.c line 155
Quoted 3 lines
drivers/hwmon/occ/occ_p9.c new file +3
-0+ sensor =occ_get_sensor (driver, sensor_type); +if (!sensor) +return -ENODEV ;+
Quoted 10 lines
drivers/hwmon/occ/occ_p9.c new file +10
-0+switch (sensor_type) { +case FREQ : +return ((struct p8_freq_sensor *)sensor)[snum].value; +case TEMP : +return ((struct p9_temp_sensor *)sensor)[snum].value; +case POWER : +return ((struct p9_power_sensor *)sensor)[snum].value; +default : +return -EINVAL ; + }drivers/hwmon/occ/occ_p9.c new file +4
-0+} + +int p9_get_sensor_id (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_p9.c line 155
Quoted 3 lines
drivers/hwmon/occ/occ_p9.c new file +3
-0+ sensor =occ_get_sensor (driver, sensor_type); +if (!sensor) +return -ENODEV ;+
Quoted 10 lines
drivers/hwmon/occ/occ_p9.c new file +10
-0+switch (sensor_type) { +case FREQ : +return ((struct p8_freq_sensor *)sensor)[snum].sensor_id; +case TEMP : +return ((struct p9_temp_sensor *)sensor)[snum].sensor_id; +case POWER : +return ((struct p9_power_sensor *)sensor)[snum].sensor_id; +default : +return -EINVAL ; + }drivers/hwmon/occ/occ_p9.c new file +4
-0+} + +int p9_get_caps_value (void *sensor,int snum,int caps_field) +{drivers/hwmon/occ/occ_p9.c line 194
Quoted 1 line
drivers/hwmon/occ/occ_p9.c new file +1
-0+struct p9_caps_sensor *caps_sensor = sensor;+
Quoted 18 lines
drivers/hwmon/occ/occ_p9.c new file +18
-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; +case 6 : +return caps_sensor[snum].user_powerlimit_source; +default : +return -EINVAL ; + }drivers/hwmon/occ/occ_p9.c new file +2
-0+} +static const struct occ_ops p9_ops = {Quoted 5 lines
drivers/hwmon/occ/occ_p9.c new file +5
-0+ .parse_sensor = p9_parse_sensor, + .alloc_sensor = p9_alloc_sensor, + .get_sensor_value = p9_get_sensor_value, + .get_sensor_id = p9_get_sensor_id, + .get_caps_value = p9_get_caps_value,drivers/hwmon/occ/occ_p9.c new file +3
-0+}; + +static const struct occ_config p9_config = {Quoted 2 lines
drivers/hwmon/occ/occ_p9.c new file +2
-0+ .command_addr = 0xFFFBE000, + .response_addr = 0xFFFBF000,drivers/hwmon/occ/occ_p9.c new file +3
-0+}; + +struct occ *p9_occ_start(struct device *dev, void *bus,drivers/hwmon/occ/occ_p9.c line 229
Quoted 1 line
drivers/hwmon/occ/occ_p9.c new file +1
-0+ struct occ_bus_ops *bus_ops)+{
Quoted 1 line
drivers/hwmon/occ/occ_p9.c new file +1
-0+return occ_start (dev, bus, bus_ops, &p9_ops, &p9_config);drivers/hwmon/occ/occ_p9.c new file +5
-0+} +EXPORT_SYMBOL (occ_p9_start); + +int p9_occ_stop (struct occ *occ) +{Quoted 1 line
drivers/hwmon/occ/occ_p9.c new file +1
-0+return occ_stop (occ);drivers/hwmon/occ/occ_p9.c new file +3
-0+} +EXPORT_SYMBOL (occ_p9_stop); +Quoted 1 line
+MODULE_AUTHOR("Eddie James <[email protected]>");
drivers/hwmon/occ/occ_p9.c new file +2
-0+MODULE_DESCRIPTION ("P9 OCC sensors" ); +MODULE_LICENSE ("GPL" );drivers/hwmon/occ/occ_p9.h new file +26
-0@@ -0,0 +1,30 @@ +/* +* occ_p9.h - OCC hwmon driver +* +* This file contains Power9-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_P9_H__ +#define __OCC_P9_H__ + +#include "scom.h" + +struct device ; + +struct occ *p9_occ_start(struct device *dev, void *bus,Quoted 1 line
drivers/hwmon/occ/occ_p9.h new file +1
-0+ struct occ_bus_ops *bus_ops);drivers/hwmon/occ/occ_p9.h new file +3
-0+int p9_occ_stop (struct occ *occ); + +#endif /* __OCC_P9_H__ */