Skip to contentSkip to conversation

hwmon: occ: Add hwmon implementation for the P8 OCC

PATCH In review [email protected] 2 participants 2 messages Dec 16, 2016 – Dec 20, 2016

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

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
new file mode 100644
index 0000000..b0d2b36
@@ -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
index cdb64a7..e690001 100644
@@ -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
index a6881f9..05a84e9 100644
@@ -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
#1 lore raw
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

---
 .../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 +7 -0
new file mode 100644
index 0000000..b0d2b36
@@ -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
index cdb64a7..e690001 100644
@@ -13,3 +13,17 @@ menuconfig SENSORS_PPC_OCC

Quoted 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_I2C

drivers/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
+
+endif
drivers/hwmon/occ/Makefile +0 -0
index a6881f9..05a84e9 100644
@@ -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.o
drivers/hwmon/occ/occ_p8_i2c.c new file +33 -0
new file mode 100644
index 0000000..a151b3a
@@ -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");