hwmon: occ: Add hwmon implementation for the P8 OCC
PATCH 5/7 hwmon: occ: Add hwmon implementation for the P8 OCC
From: "Edward A. James" <[email protected]>
Add code to tie the hwmon sysfs code and the POWER8 OCC code together, as well as probe the entire driver from the I2C bus. I2C is the communication method between the BMC and the P8 OCC.
--- .../devicetree/bindings/i2c/i2c-ibm-occ.txt | 13 ++ drivers/hwmon/occ/Kconfig | 14 ++ drivers/hwmon/occ/Makefile | 1 + drivers/hwmon/occ/occ_p8_i2c.c | 141 +++++++++++++++++++++ 4 files changed, 169 insertions(+) create mode 100644 Documentation/devicetree/bindings/i2c/i2c-ibm-occ.txt create mode 100644 drivers/hwmon/occ/occ_p8_i2c.c
Documentation/devicetree/bindings/i2c/i2c-ibm-occ.txt new file +13 -0
@@ -0,0 +1,13 @@ +HWMON I2C driver for IBM POWER CPU OCC (On Chip Controller) + +Required properties: + - compatible: must be "ibm,p8-occ-i2c" + - reg: physical address + +Example: +i2c3: i2c-bus@100 { + occ@50 { + compatible = "ibm,p8-occ-i2c"; + reg = <0x50>; + }; +};
drivers/hwmon/occ/Kconfig +14 -0
@@ -13,3 +13,17 @@ menuconfig SENSORS_PPC_OCC This driver can also be built as a module. If so, the module will be called occ. + +if SENSORS_PPC_OCC + +config SENSORS_PPC_OCC_P8_I2C + tristate "POWER8 OCC hwmon support" + depends on I2C + help + Provide a hwmon sysfs interface for the POWER8 On-Chip Controller, + exposing temperature, frequency and power measurements. + + This driver can also be built as a module. If so, the module will be + called occ-p8-i2c. + +endif
drivers/hwmon/occ/Makefile +1 -0
@@ -1 +1,2 @@ obj-$(CONFIG_SENSORS_PPC_OCC) += occ.o occ_sysfs.o +obj-$(CONFIG_SENSORS_PPC_OCC_P8_I2C) += occ_scom_i2c.o occ_p8.o occ_p8_i2c.o
drivers/hwmon/occ/occ_p8_i2c.c new file +141 -0
141 lines not on this page · raw message
Signature · 1 line
1.9.1
Quoted 55 lines · On Fri, 2016-12-16 at 14:35 -0600, [email protected] wrote:
Quoted 1 line
From: "Edward A. James" <[email protected]>
Add code to tie the hwmon sysfs code and the POWER8 OCC code together, as well as probe the entire driver from the I2C bus. I2C is the communication method between the BMC and the P8 OCC.
Quoted 2 lines
Signed-off-by Edward A. James <[email protected]>Signed-off-by Andrew Jeffery <[email protected]>---
.../devicetree/bindings/i2c/i2c-ibm-occ.txt | 13 ++ drivers/hwmon/occ/Kconfig | 14 ++ drivers/hwmon/occ/Makefile | 1 + drivers/hwmon/occ/occ_p8_i2c.c | 141 +++++++++++++++++++++4 files changed, 169 insertions(+)create mode 100644
Documentation/devicetree/bindings/i2c/i2c-ibm-occ.txtcreate mode 100644drivers/hwmon/occ/occ_p8_i2c.cDocumentation/devicetree/bindings/i2c/i2c-ibm-occ.txt new file +7
-0@@ -0,0 +1,13 @@ +HWMON I2C driver for IBM POWER CPU OCC (On Chip Controller) + +Required properties: + - compatible: must be "ibm,p8-occ-i2c" + - reg: physical address + +Example:Quoted 5 lines
Documentation/devicetree/bindings/i2c/i2c-ibm-occ.txt new file +5
-0+i2c3: i2c-bus@100 { + occ@50 { + compatible = "ibm,p8-occ-i2c"; + reg = <0x50>; + };Documentation/devicetree/bindings/i2c/i2c-ibm-occ.txt new file +1
-0+};drivers/hwmon/occ/Kconfig +0
-0@@ -13,3 +13,17 @@ menuconfig SENSORS_PPC_OCCQuoted 2 lines
This driver can also be built as a module. If so, the module will be called occ.
drivers/hwmon/occ/Kconfig +4
-0+ +if SENSORS_PPC_OCC + +config SENSORS_PPC_OCC_P8_I2Cdrivers/hwmon/occ/Kconfig menuconfig SENSORS_PPC_OCC · line 24
Quoted 5 lines
drivers/hwmon/occ/Kconfig +5
-0+ tristate "POWER8 OCC hwmon support" + depends on I2C + help + Provide a hwmon sysfs interface for the POWER8 On-Chip Controller, + exposing temperature, frequency and power measurements.+
Quoted 1 line
drivers/hwmon/occ/Kconfig +1
-0+ This driver can also be built as a module. If so, the module will be
drivers/hwmon/occ/Kconfig menuconfig SENSORS_PPC_OCC · line 27
Quoted 1 line
drivers/hwmon/occ/Kconfig +1
-0+ called occ-p8-i2c.
I think this should be p8-occ-i2c by the #define below and your compatible string. Though the C file is called 'occ_p8_i2c.c' as well; maybe it should be renamed? Other than that, consider it tagged with reviewed-by, these are minor issues.
Quoted 156 lines
drivers/hwmon/occ/Kconfig +2
-0+ +endifdrivers/hwmon/occ/Makefile +0
-0@@ -1 +1,2 @@obj-$(CONFIG_SENSORS_PPC_OCC) += occ.o occ_sysfs.o
drivers/hwmon/occ/Makefile +1
-0+obj-$(CONFIG_SENSORS_PPC_OCC_P8_I2C) += occ_scom_i2c.o occ_p8.o occ_p8_i2c.odrivers/hwmon/occ/occ_p8_i2c.c new file +33
-0@@ -0,0 +1,141 @@ +/* +* occ_p8_i2c.c - hwmon OCC driver +* +* This file contains the i2c layer for accessing the P8 OCC over i2c bus. +* +* 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/err.h> +#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 "scom.h" +#include "occ_scom_i2c.h" +#include "occ_p8.h" +#include "occ_sysfs.h" +Quoted 1 line
+#define
P8_OCC_I2C_NAME"p8-occ-i2c"drivers/hwmon/occ/occ_p8_i2c.c new file +2
-0+ +static char *caps_sensor_names[] = {Quoted 6 lines
drivers/hwmon/occ/occ_p8_i2c.c new file +6
-0+"curr_powercap" , +"curr_powerreading" , +"norm_powercap" , +"max_powercap" , +"min_powercap" , +"user_powerlimit" drivers/hwmon/occ/occ_p8_i2c.c new file +4
-0+}; + +int p8_i2c_getscom (void *bus,u32 address,u8 *data) +{Review
Quoted 2 lines
(quoted diff) +2
-0+ /* P8 i2c slave requires address to be shifted by 1 */ + address = address << 1;+
Quoted 1 line
drivers/hwmon/occ/occ_p8_i2c.c new file +1
-0+return occ_i2c_getscom (bus, address, data);drivers/hwmon/occ/occ_p8_i2c.c new file +4
-0+} + +int p8_i2c_putscom (void *bus,u32 address,u32 data0,u32 data1) +{Review
Quoted 2 lines
(quoted diff) +2
-0+ /* P8 i2c slave requires address to be shifted by 1 */ + address = address << 1;+
Quoted 1 line
drivers/hwmon/occ/occ_p8_i2c.c new file +1
-0+return occ_i2c_putscom (bus, address, data0, data1);drivers/hwmon/occ/occ_p8_i2c.c new file +3
-0+} + +static struct occ_bus_ops p8_bus_ops = {Quoted 2 lines
drivers/hwmon/occ/occ_p8_i2c.c new file +2
-0+ .getscom = p8_i2c_getscom, + .putscom = p8_i2c_putscom,drivers/hwmon/occ/occ_p8_i2c.c new file +3
-0+}; + +static struct occ_sysfs_config p8_sysfs_config = {Quoted 2 lines
drivers/hwmon/occ/occ_p8_i2c.c new file +2
-0+ .num_caps_fields = ARRAY_SIZE(caps_sensor_names), + .caps_names = caps_sensor_names,drivers/hwmon/occ/occ_p8_i2c.c new file +3
-0+}; + +static int p8_occ_probe(struct i2c_client *client,drivers/hwmon/occ/occ_p8_i2c.c line 72
Quoted 1 line
drivers/hwmon/occ/occ_p8_i2c.c new file +1
-0+ const struct i2c_device_id *id)+{
drivers/hwmon/occ/occ_p8_i2c.c line 75
Quoted 2 lines
drivers/hwmon/occ/occ_p8_i2c.c new file +2
-0+struct occ *occ; +struct occ_sysfs *hwmon;+
drivers/hwmon/occ/occ_p8_i2c.c line 79
Quoted 3 lines
drivers/hwmon/occ/occ_p8_i2c.c new file +3
-0+ occ =p8_occ_start (&client->dev, client, &p8_bus_ops); +if (IS_ERR (occ)) +return PTR_ERR (occ);+
drivers/hwmon/occ/occ_p8_i2c.c line 83
Quoted 3 lines
drivers/hwmon/occ/occ_p8_i2c.c new file +3
-0+ hwmon =occ_sysfs_start (&client->dev, occ, &p8_sysfs_config); +if (IS_ERR (hwmon)) +return PTR_ERR (hwmon);+
drivers/hwmon/occ/occ_p8_i2c.c line 85
Quoted 1 line
drivers/hwmon/occ/occ_p8_i2c.c new file +1
-0+i2c_set_clientdata (client, hwmon);+
Quoted 1 line
drivers/hwmon/occ/occ_p8_i2c.c new file +1
-0+return 0 ;drivers/hwmon/occ/occ_p8_i2c.c new file +4
-0+} + +static int p8_occ_remove (struct i2c_client *client) +{drivers/hwmon/occ/occ_p8_i2c.c line 94
Quoted 3 lines
drivers/hwmon/occ/occ_p8_i2c.c new file +3
-0+int rc; +struct occ_sysfs *hwmon =i2c_get_clientdata (client); +struct occ *occ = hwmon->occ;+
drivers/hwmon/occ/occ_p8_i2c.c line 96
Quoted 1 line
drivers/hwmon/occ/occ_p8_i2c.c new file +1
-0+ rc =occ_sysfs_stop (&client->dev, hwmon);+
drivers/hwmon/occ/occ_p8_i2c.c line 98
Quoted 1 line
drivers/hwmon/occ/occ_p8_i2c.c new file +1
-0+ rc = rc ||p8_occ_stop (occ);+
Quoted 1 line
drivers/hwmon/occ/occ_p8_i2c.c new file +1
-0+return rc;drivers/hwmon/occ/occ_p8_i2c.c new file +4
-0+} + +/* used by old-style board info. */ +static const struct i2c_device_id occ_ids[] = {Quoted 2 lines
(quoted diff) +2
-0+ { P8_OCC_I2C_NAME, 0 }, + {}drivers/hwmon/occ/occ_p8_i2c.c new file +5
-0+}; +MODULE_DEVICE_TABLE (i2c, occ_ids); + +/* used by device table */ +static const struct of_device_id occ_of_match[] = {Quoted 2 lines
drivers/hwmon/occ/occ_p8_i2c.c new file +2
-0+ { .compatible = "ibm,p8-occ-i2c" }, + {}drivers/hwmon/occ/occ_p8_i2c.c new file +11
-0+}; +MODULE_DEVICE_TABLE (of, occ_of_match); + +/* +* i2c-core uses i2c-detect() to detect device in below address list. +* If exists, address will be assigned to client. +* It is also possible to read address from device table. +*/ +static const unsigned short normal_i2c[] = {0x50 ,0x51 ,I2C_CLIENT_END }; + +static struct i2c_driver p8_occ_driver = {Quoted 10 lines
drivers/hwmon/occ/occ_p8_i2c.c new file +10
-0+ .class = I2C_CLASS_HWMON, + .driver = { + .name = P8_OCC_I2C_NAME, + .pm = NULL, + .of_match_table = occ_of_match, + }, + .probe = p8_occ_probe, + .remove = p8_occ_remove, + .id_table = occ_ids, + .address_list = normal_i2c,drivers/hwmon/occ/occ_p8_i2c.c new file +4
-0+}; + +module_i2c_driver (p8_occ_driver); +Quoted 1 line
+MODULE_AUTHOR("Eddie James <[email protected]>");
drivers/hwmon/occ/occ_p8_i2c.c new file +2
-0+MODULE_DESCRIPTION ("BMC P8 OCC hwmon driver" ); +MODULE_LICENSE ("GPL" );