Message ID | 1501708633-2964-2-git-send-email-eajames@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Hi Edward, [auto build test ERROR on hwmon/hwmon-next] [also build test ERROR on v4.13-rc3 next-20170803] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Eddie-James/drivers-hwmon-pmbus-Add-IBM-power-supply-hwmon-driver/20170803-122545 base: https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next config: x86_64-allmodconfig (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All error/warnings (new ones prefixed by >>): In file included from drivers/hwmon/pmbus/ibmps.c:13:0: >> drivers/hwmon/pmbus/ibmps.c:148:25: error: 'p8_i2c_occ_of_match' undeclared here (not in a function) MODULE_DEVICE_TABLE(of, p8_i2c_occ_of_match); ^ include/linux/module.h:212:21: note: in definition of macro 'MODULE_DEVICE_TABLE' extern const typeof(name) __mod_##type##__##name##_device_table \ ^~~~ >> include/linux/module.h:212:27: error: '__mod_of__p8_i2c_occ_of_match_device_table' aliased to undefined symbol 'p8_i2c_occ_of_match' extern const typeof(name) __mod_##type##__##name##_device_table \ ^ >> drivers/hwmon/pmbus/ibmps.c:148:1: note: in expansion of macro 'MODULE_DEVICE_TABLE' MODULE_DEVICE_TABLE(of, p8_i2c_occ_of_match); ^~~~~~~~~~~~~~~~~~~ -- In file included from drivers/hwmon//pmbus/ibmps.c:13:0: drivers/hwmon//pmbus/ibmps.c:148:25: error: 'p8_i2c_occ_of_match' undeclared here (not in a function) MODULE_DEVICE_TABLE(of, p8_i2c_occ_of_match); ^ include/linux/module.h:212:21: note: in definition of macro 'MODULE_DEVICE_TABLE' extern const typeof(name) __mod_##type##__##name##_device_table \ ^~~~ >> include/linux/module.h:212:27: error: '__mod_of__p8_i2c_occ_of_match_device_table' aliased to undefined symbol 'p8_i2c_occ_of_match' extern const typeof(name) __mod_##type##__##name##_device_table \ ^ drivers/hwmon//pmbus/ibmps.c:148:1: note: in expansion of macro 'MODULE_DEVICE_TABLE' MODULE_DEVICE_TABLE(of, p8_i2c_occ_of_match); ^~~~~~~~~~~~~~~~~~~ vim +/p8_i2c_occ_of_match +148 drivers/hwmon/pmbus/ibmps.c > 13 #include <linux/module.h> 14 15 #include "pmbus.h" 16 17 #define IBMPS_MFR_FAN_FAULT BIT(0) 18 #define IBMPS_MFR_THERMAL_FAULT BIT(1) 19 #define IBMPS_MFR_OV_FAULT BIT(2) 20 #define IBMPS_MFR_UV_FAULT BIT(3) 21 #define IBMPS_MFR_PS_KILL BIT(4) 22 #define IBMPS_MFR_OC_FAULT BIT(5) 23 #define IBMPS_MFR_VAUX_FAULT BIT(6) 24 #define IBMPS_MFR_CURRENT_SHARE_WARNING BIT(7) 25 26 static int ibmps_read_word_data(struct i2c_client *client, int page, int reg); 27 28 static int ibmps_read_byte_data(struct i2c_client *client, int page, int reg) 29 { 30 int rc, mfr; 31 32 switch (reg) { 33 case PMBUS_STATUS_BYTE: 34 case PMBUS_STATUS_WORD: 35 rc = ibmps_read_word_data(client, page, PMBUS_STATUS_WORD); 36 break; 37 case PMBUS_STATUS_VOUT: 38 case PMBUS_STATUS_IOUT: 39 case PMBUS_STATUS_TEMPERATURE: 40 case PMBUS_STATUS_FAN_12: 41 rc = pmbus_read_byte_data(client, page, reg); 42 if (rc < 0) 43 return rc; 44 45 mfr = pmbus_read_byte_data(client, page, 46 PMBUS_STATUS_MFR_SPECIFIC); 47 if (mfr < 0) 48 return rc; 49 50 if (reg == PMBUS_STATUS_FAN_12) { 51 if (mfr & IBMPS_MFR_FAN_FAULT) 52 rc |= PB_FAN_FAN1_FAULT; 53 } else if (reg == PMBUS_STATUS_TEMPERATURE) { 54 if (mfr & IBMPS_MFR_THERMAL_FAULT) 55 rc |= PB_TEMP_OT_FAULT; 56 } else if (reg == PMBUS_STATUS_VOUT) { 57 if (mfr & (IBMPS_MFR_OV_FAULT | IBMPS_MFR_VAUX_FAULT)) 58 rc |= PB_VOLTAGE_OV_FAULT; 59 if (mfr & IBMPS_MFR_UV_FAULT) 60 rc |= PB_VOLTAGE_UV_FAULT; 61 } else if (reg == PMBUS_STATUS_IOUT) { 62 if (mfr & IBMPS_MFR_OC_FAULT) 63 rc |= PB_IOUT_OC_FAULT; 64 if (mfr & IBMPS_MFR_CURRENT_SHARE_WARNING) 65 rc |= PB_CURRENT_SHARE_FAULT; 66 } 67 break; 68 default: 69 if (reg >= PMBUS_VIRT_BASE) 70 return -ENXIO; 71 72 rc = pmbus_read_byte_data(client, page, reg); 73 break; 74 } 75 76 return rc; 77 } 78 79 static int ibmps_read_word_data(struct i2c_client *client, int page, int reg) 80 { 81 int rc, mfr; 82 83 switch (reg) { 84 case PMBUS_STATUS_BYTE: 85 case PMBUS_STATUS_WORD: 86 rc = pmbus_read_word_data(client, page, PMBUS_STATUS_WORD); 87 if (rc < 0) 88 return rc; 89 90 mfr = pmbus_read_byte_data(client, page, 91 PMBUS_STATUS_MFR_SPECIFIC); 92 if (mfr < 0) 93 return rc; 94 95 if (mfr & IBMPS_MFR_PS_KILL) 96 rc |= PB_STATUS_OFF; 97 98 if (mfr) 99 rc |= PB_STATUS_WORD_MFR; 100 break; 101 default: 102 if (reg >= PMBUS_VIRT_BASE) 103 return -ENXIO; 104 105 rc = pmbus_read_word_data(client, page, reg); 106 if (rc < 0) 107 rc = ibmps_read_byte_data(client, page, reg); 108 break; 109 } 110 111 return rc; 112 } 113 114 static struct pmbus_driver_info ibmps_info = { 115 .pages = 1, 116 .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | 117 PMBUS_HAVE_PIN | PMBUS_HAVE_FAN12 | PMBUS_HAVE_TEMP | 118 PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_VOUT | 119 PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_STATUS_INPUT | 120 PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_FAN12, 121 .read_byte_data = ibmps_read_byte_data, 122 .read_word_data = ibmps_read_word_data, 123 }; 124 125 static int ibmps_probe(struct i2c_client *client, 126 const struct i2c_device_id *id) 127 { 128 return pmbus_do_probe(client, id, &ibmps_info); 129 } 130 131 static int ibmps_remove(struct i2c_client *client) 132 { 133 return pmbus_do_remove(client); 134 } 135 136 enum chips { witherspoon }; 137 138 static const struct i2c_device_id ibmps_id[] = { 139 { "witherspoon", witherspoon }, 140 { } 141 }; 142 MODULE_DEVICE_TABLE(i2c, ibmps_id); 143 144 static const struct of_device_id ibmps_of_match[] = { 145 { .compatible = "ibm,ibmps" }, 146 {} 147 }; > 148 MODULE_DEVICE_TABLE(of, p8_i2c_occ_of_match); 149 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
On Wed, Aug 02, 2017 at 04:17:10PM -0500, Eddie James wrote: > From: "Edward A. James" <eajames@us.ibm.com> > > Add the driver to monitor power supplies with hwmon over pmbus. > > Signed-off-by: Edward A. James <eajames@us.ibm.com> > --- > drivers/hwmon/pmbus/Kconfig | 10 +++ > drivers/hwmon/pmbus/Makefile | 1 + > drivers/hwmon/pmbus/ibmps.c | 164 +++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 175 insertions(+) > create mode 100644 drivers/hwmon/pmbus/ibmps.c > > diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig > index 68d717a..4eba657 100644 > --- a/drivers/hwmon/pmbus/Kconfig > +++ b/drivers/hwmon/pmbus/Kconfig > @@ -37,6 +37,16 @@ config SENSORS_ADM1275 > This driver can also be built as a module. If so, the module will > be called adm1275. > > +config SENSORS_IBMPS > + tristate "IBM Power Supply" What if IBM ever produces another power supply ? I think this should be more specific. Similar, ibmps/IBMPS is way too generic. > + default n > + help > + If you say yes here you get hardware monitoring support for IBM > + power supply. > + > + This driver can also be built as a module. If so, the module will > + be called ibmps. > + > config SENSORS_IR35221 > tristate "Infineon IR35221" > default n > diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile > index 75bb7ca..e37b715 100644 > --- a/drivers/hwmon/pmbus/Makefile > +++ b/drivers/hwmon/pmbus/Makefile > @@ -5,6 +5,7 @@ > obj-$(CONFIG_PMBUS) += pmbus_core.o > obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o > obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o > +obj-$(CONFIG_SENSORS_IBMPS) += ibmps.o > obj-$(CONFIG_SENSORS_IR35221) += ir35221.o > obj-$(CONFIG_SENSORS_LM25066) += lm25066.o > obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o > diff --git a/drivers/hwmon/pmbus/ibmps.c b/drivers/hwmon/pmbus/ibmps.c > new file mode 100644 > index 0000000..1928dd9 > --- /dev/null > +++ b/drivers/hwmon/pmbus/ibmps.c > @@ -0,0 +1,164 @@ > +/* > + * Copyright 2017 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. > + */ > + > +#include <linux/device.h> > +#include <linux/i2c.h> > +#include <linux/jiffies.h> > +#include <linux/module.h> > + > +#include "pmbus.h" > + > +#define IBMPS_MFR_FAN_FAULT BIT(0) > +#define IBMPS_MFR_THERMAL_FAULT BIT(1) > +#define IBMPS_MFR_OV_FAULT BIT(2) > +#define IBMPS_MFR_UV_FAULT BIT(3) > +#define IBMPS_MFR_PS_KILL BIT(4) > +#define IBMPS_MFR_OC_FAULT BIT(5) > +#define IBMPS_MFR_VAUX_FAULT BIT(6) > +#define IBMPS_MFR_CURRENT_SHARE_WARNING BIT(7) > + > +static int ibmps_read_word_data(struct i2c_client *client, int page, int reg); > + I don't see why this would require a forward declaration. Why not just move the function ? > +static int ibmps_read_byte_data(struct i2c_client *client, int page, int reg) > +{ > + int rc, mfr; > + > + switch (reg) { > + case PMBUS_STATUS_BYTE: Is the byte part still needed with the upcoming core changes ? > + case PMBUS_STATUS_WORD: > + rc = ibmps_read_word_data(client, page, PMBUS_STATUS_WORD); > + break; > + case PMBUS_STATUS_VOUT: > + case PMBUS_STATUS_IOUT: > + case PMBUS_STATUS_TEMPERATURE: > + case PMBUS_STATUS_FAN_12: > + rc = pmbus_read_byte_data(client, page, reg); > + if (rc < 0) > + return rc; > + > + mfr = pmbus_read_byte_data(client, page, > + PMBUS_STATUS_MFR_SPECIFIC); > + if (mfr < 0) > + return rc; > + > + if (reg == PMBUS_STATUS_FAN_12) { > + if (mfr & IBMPS_MFR_FAN_FAULT) > + rc |= PB_FAN_FAN1_FAULT; > + } else if (reg == PMBUS_STATUS_TEMPERATURE) { > + if (mfr & IBMPS_MFR_THERMAL_FAULT) > + rc |= PB_TEMP_OT_FAULT; > + } else if (reg == PMBUS_STATUS_VOUT) { > + if (mfr & (IBMPS_MFR_OV_FAULT | IBMPS_MFR_VAUX_FAULT)) > + rc |= PB_VOLTAGE_OV_FAULT; > + if (mfr & IBMPS_MFR_UV_FAULT) > + rc |= PB_VOLTAGE_UV_FAULT; > + } else if (reg == PMBUS_STATUS_IOUT) { > + if (mfr & IBMPS_MFR_OC_FAULT) > + rc |= PB_IOUT_OC_FAULT; > + if (mfr & IBMPS_MFR_CURRENT_SHARE_WARNING) > + rc |= PB_CURRENT_SHARE_FAULT; Is changing a warning to a fault a good idea ? > + } > + break; > + default: > + if (reg >= PMBUS_VIRT_BASE) > + return -ENXIO; > + > + rc = pmbus_read_byte_data(client, page, reg); > + break; The idea here is to return -ENODATA to let the core handle it. Please see similar drivers. > + } > + > + return rc; > +} > + > +static int ibmps_read_word_data(struct i2c_client *client, int page, int reg) > +{ > + int rc, mfr; > + > + switch (reg) { > + case PMBUS_STATUS_BYTE: > + case PMBUS_STATUS_WORD: > + rc = pmbus_read_word_data(client, page, PMBUS_STATUS_WORD); > + if (rc < 0) > + return rc; > + > + mfr = pmbus_read_byte_data(client, page, > + PMBUS_STATUS_MFR_SPECIFIC); > + if (mfr < 0) > + return rc; > + > + if (mfr & IBMPS_MFR_PS_KILL) > + rc |= PB_STATUS_OFF; > + > + if (mfr) > + rc |= PB_STATUS_WORD_MFR; > + break; > + default: > + if (reg >= PMBUS_VIRT_BASE) > + return -ENXIO; -ENODATA > + > + rc = pmbus_read_word_data(client, page, reg); > + if (rc < 0) > + rc = ibmps_read_byte_data(client, page, reg); I am a bit at loss here. Why ? > + break; > + } > + > + return rc; > +} > + > +static struct pmbus_driver_info ibmps_info = { > + .pages = 1, > + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | > + PMBUS_HAVE_PIN | PMBUS_HAVE_FAN12 | PMBUS_HAVE_TEMP | > + PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_VOUT | > + PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_STATUS_INPUT | > + PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_FAN12, > + .read_byte_data = ibmps_read_byte_data, > + .read_word_data = ibmps_read_word_data, > +}; > + > +static int ibmps_probe(struct i2c_client *client, > + const struct i2c_device_id *id) > +{ > + return pmbus_do_probe(client, id, &ibmps_info); > +} > + > +static int ibmps_remove(struct i2c_client *client) > +{ > + return pmbus_do_remove(client); > +} > + > +enum chips { witherspoon }; > + > +static const struct i2c_device_id ibmps_id[] = { > + { "witherspoon", witherspoon }, This is confusing. ibmps everywhere but witherspoon here ? > + { } > +}; > +MODULE_DEVICE_TABLE(i2c, ibmps_id); > + > +static const struct of_device_id ibmps_of_match[] = { > + { .compatible = "ibm,ibmps" }, > + {} > +}; > +MODULE_DEVICE_TABLE(of, p8_i2c_occ_of_match); > + > +static struct i2c_driver ibmps_driver = { > + .driver = { > + .name = "ibmps", > + .of_match_table = ibmps_of_match, > + }, > + .probe = ibmps_probe, > + .remove = ibmps_remove, > + .id_table = ibmps_id, > +}; > + > +module_i2c_driver(ibmps_driver); > + > +MODULE_AUTHOR("Eddie James"); > +MODULE_DESCRIPTION("PMBus driver for IBM power supply"); > +MODULE_LICENSE("GPL"); > -- > 1.8.3.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-hwmon" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-hwmon" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Aug 02, 2017 at 04:17:10PM -0500, Eddie James wrote: > From: "Edward A. James" <eajames@us.ibm.com> > > Add the driver to monitor power supplies with hwmon over pmbus. > > Signed-off-by: Edward A. James <eajames@us.ibm.com> > --- > drivers/hwmon/pmbus/Kconfig | 10 +++ > drivers/hwmon/pmbus/Makefile | 1 + > drivers/hwmon/pmbus/ibmps.c | 164 +++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 175 insertions(+) > create mode 100644 drivers/hwmon/pmbus/ibmps.c > > diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig > index 68d717a..4eba657 100644 > --- a/drivers/hwmon/pmbus/Kconfig > +++ b/drivers/hwmon/pmbus/Kconfig > @@ -37,6 +37,16 @@ config SENSORS_ADM1275 > This driver can also be built as a module. If so, the module will > be called adm1275. > > +config SENSORS_IBMPS > + tristate "IBM Power Supply" > + default n > + help > + If you say yes here you get hardware monitoring support for IBM > + power supply. > + > + This driver can also be built as a module. If so, the module will > + be called ibmps. > + > config SENSORS_IR35221 > tristate "Infineon IR35221" > default n > diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile > index 75bb7ca..e37b715 100644 > --- a/drivers/hwmon/pmbus/Makefile > +++ b/drivers/hwmon/pmbus/Makefile > @@ -5,6 +5,7 @@ > obj-$(CONFIG_PMBUS) += pmbus_core.o > obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o > obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o > +obj-$(CONFIG_SENSORS_IBMPS) += ibmps.o > obj-$(CONFIG_SENSORS_IR35221) += ir35221.o > obj-$(CONFIG_SENSORS_LM25066) += lm25066.o > obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o > diff --git a/drivers/hwmon/pmbus/ibmps.c b/drivers/hwmon/pmbus/ibmps.c > new file mode 100644 > index 0000000..1928dd9 > --- /dev/null > +++ b/drivers/hwmon/pmbus/ibmps.c > @@ -0,0 +1,164 @@ > +/* > + * Copyright 2017 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. > + */ > + > +#include <linux/device.h> > +#include <linux/i2c.h> > +#include <linux/jiffies.h> > +#include <linux/module.h> > + > +#include "pmbus.h" > + > +#define IBMPS_MFR_FAN_FAULT BIT(0) > +#define IBMPS_MFR_THERMAL_FAULT BIT(1) > +#define IBMPS_MFR_OV_FAULT BIT(2) > +#define IBMPS_MFR_UV_FAULT BIT(3) > +#define IBMPS_MFR_PS_KILL BIT(4) > +#define IBMPS_MFR_OC_FAULT BIT(5) > +#define IBMPS_MFR_VAUX_FAULT BIT(6) > +#define IBMPS_MFR_CURRENT_SHARE_WARNING BIT(7) > + > +static int ibmps_read_word_data(struct i2c_client *client, int page, int reg); > + > +static int ibmps_read_byte_data(struct i2c_client *client, int page, int reg) > +{ > + int rc, mfr; > + > + switch (reg) { > + case PMBUS_STATUS_BYTE: > + case PMBUS_STATUS_WORD: > + rc = ibmps_read_word_data(client, page, PMBUS_STATUS_WORD); > + break; > + case PMBUS_STATUS_VOUT: > + case PMBUS_STATUS_IOUT: > + case PMBUS_STATUS_TEMPERATURE: > + case PMBUS_STATUS_FAN_12: > + rc = pmbus_read_byte_data(client, page, reg); > + if (rc < 0) > + return rc; > + > + mfr = pmbus_read_byte_data(client, page, > + PMBUS_STATUS_MFR_SPECIFIC); > + if (mfr < 0) > + return rc; > + > + if (reg == PMBUS_STATUS_FAN_12) { > + if (mfr & IBMPS_MFR_FAN_FAULT) > + rc |= PB_FAN_FAN1_FAULT; > + } else if (reg == PMBUS_STATUS_TEMPERATURE) { > + if (mfr & IBMPS_MFR_THERMAL_FAULT) > + rc |= PB_TEMP_OT_FAULT; > + } else if (reg == PMBUS_STATUS_VOUT) { > + if (mfr & (IBMPS_MFR_OV_FAULT | IBMPS_MFR_VAUX_FAULT)) > + rc |= PB_VOLTAGE_OV_FAULT; > + if (mfr & IBMPS_MFR_UV_FAULT) > + rc |= PB_VOLTAGE_UV_FAULT; > + } else if (reg == PMBUS_STATUS_IOUT) { > + if (mfr & IBMPS_MFR_OC_FAULT) > + rc |= PB_IOUT_OC_FAULT; > + if (mfr & IBMPS_MFR_CURRENT_SHARE_WARNING) > + rc |= PB_CURRENT_SHARE_FAULT; > + } > + break; > + default: > + if (reg >= PMBUS_VIRT_BASE) > + return -ENXIO; > + > + rc = pmbus_read_byte_data(client, page, reg); > + break; > + } > + > + return rc; > +} > + > +static int ibmps_read_word_data(struct i2c_client *client, int page, int reg) > +{ > + int rc, mfr; > + > + switch (reg) { > + case PMBUS_STATUS_BYTE: > + case PMBUS_STATUS_WORD: > + rc = pmbus_read_word_data(client, page, PMBUS_STATUS_WORD); > + if (rc < 0) > + return rc; > + > + mfr = pmbus_read_byte_data(client, page, > + PMBUS_STATUS_MFR_SPECIFIC); > + if (mfr < 0) > + return rc; > + > + if (mfr & IBMPS_MFR_PS_KILL) > + rc |= PB_STATUS_OFF; > + > + if (mfr) > + rc |= PB_STATUS_WORD_MFR; > + break; > + default: > + if (reg >= PMBUS_VIRT_BASE) > + return -ENXIO; > + > + rc = pmbus_read_word_data(client, page, reg); > + if (rc < 0) > + rc = ibmps_read_byte_data(client, page, reg); > + break; > + } > + > + return rc; > +} > + > +static struct pmbus_driver_info ibmps_info = { > + .pages = 1, > + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | > + PMBUS_HAVE_PIN | PMBUS_HAVE_FAN12 | PMBUS_HAVE_TEMP | > + PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_VOUT | > + PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_STATUS_INPUT | > + PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_FAN12, > + .read_byte_data = ibmps_read_byte_data, > + .read_word_data = ibmps_read_word_data, > +}; > + > +static int ibmps_probe(struct i2c_client *client, > + const struct i2c_device_id *id) > +{ > + return pmbus_do_probe(client, id, &ibmps_info); > +} > + > +static int ibmps_remove(struct i2c_client *client) > +{ > + return pmbus_do_remove(client); > +} > + > +enum chips { witherspoon }; > + > +static const struct i2c_device_id ibmps_id[] = { > + { "witherspoon", witherspoon }, > + { } > +}; > +MODULE_DEVICE_TABLE(i2c, ibmps_id); > + > +static const struct of_device_id ibmps_of_match[] = { > + { .compatible = "ibm,ibmps" }, > + {} > +}; > +MODULE_DEVICE_TABLE(of, p8_i2c_occ_of_match); Ah yes, as 0day points out, this won't compile. Hmmm ..... makes me wonder if and how you tested this. Can you provide output from the "sensors" command ? Guenter > + > +static struct i2c_driver ibmps_driver = { > + .driver = { > + .name = "ibmps", > + .of_match_table = ibmps_of_match, > + }, > + .probe = ibmps_probe, > + .remove = ibmps_remove, > + .id_table = ibmps_id, > +}; > + > +module_i2c_driver(ibmps_driver); > + > +MODULE_AUTHOR("Eddie James"); > +MODULE_DESCRIPTION("PMBus driver for IBM power supply"); > +MODULE_LICENSE("GPL"); > -- > 1.8.3.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-hwmon" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-hwmon" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 08/10/2017 10:00 AM, Guenter Roeck wrote: > On Wed, Aug 02, 2017 at 04:17:10PM -0500, Eddie James wrote: >> From: "Edward A. James" <eajames@us.ibm.com> >> >> Add the driver to monitor power supplies with hwmon over pmbus. >> >> Signed-off-by: Edward A. James <eajames@us.ibm.com> >> --- >> drivers/hwmon/pmbus/Kconfig | 10 +++ >> drivers/hwmon/pmbus/Makefile | 1 + >> drivers/hwmon/pmbus/ibmps.c | 164 +++++++++++++++++++++++++++++++++++++++++++ >> 3 files changed, 175 insertions(+) >> create mode 100644 drivers/hwmon/pmbus/ibmps.c >> >> diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig >> index 68d717a..4eba657 100644 >> --- a/drivers/hwmon/pmbus/Kconfig >> +++ b/drivers/hwmon/pmbus/Kconfig >> @@ -37,6 +37,16 @@ config SENSORS_ADM1275 >> This driver can also be built as a module. If so, the module will >> be called adm1275. >> >> +config SENSORS_IBMPS >> + tristate "IBM Power Supply" >> + default n >> + help >> + If you say yes here you get hardware monitoring support for IBM >> + power supply. >> + >> + This driver can also be built as a module. If so, the module will >> + be called ibmps. >> + >> config SENSORS_IR35221 >> tristate "Infineon IR35221" >> default n >> diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile >> index 75bb7ca..e37b715 100644 >> --- a/drivers/hwmon/pmbus/Makefile >> +++ b/drivers/hwmon/pmbus/Makefile >> @@ -5,6 +5,7 @@ >> obj-$(CONFIG_PMBUS) += pmbus_core.o >> obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o >> obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o >> +obj-$(CONFIG_SENSORS_IBMPS) += ibmps.o >> obj-$(CONFIG_SENSORS_IR35221) += ir35221.o >> obj-$(CONFIG_SENSORS_LM25066) += lm25066.o >> obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o >> diff --git a/drivers/hwmon/pmbus/ibmps.c b/drivers/hwmon/pmbus/ibmps.c >> new file mode 100644 >> index 0000000..1928dd9 >> --- /dev/null >> +++ b/drivers/hwmon/pmbus/ibmps.c >> @@ -0,0 +1,164 @@ >> +/* >> + * Copyright 2017 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. >> + */ >> + >> +#include <linux/device.h> >> +#include <linux/i2c.h> >> +#include <linux/jiffies.h> >> +#include <linux/module.h> >> + >> +#include "pmbus.h" >> + >> +#define IBMPS_MFR_FAN_FAULT BIT(0) >> +#define IBMPS_MFR_THERMAL_FAULT BIT(1) >> +#define IBMPS_MFR_OV_FAULT BIT(2) >> +#define IBMPS_MFR_UV_FAULT BIT(3) >> +#define IBMPS_MFR_PS_KILL BIT(4) >> +#define IBMPS_MFR_OC_FAULT BIT(5) >> +#define IBMPS_MFR_VAUX_FAULT BIT(6) >> +#define IBMPS_MFR_CURRENT_SHARE_WARNING BIT(7) >> + >> +static int ibmps_read_word_data(struct i2c_client *client, int page, int reg); >> + >> +static int ibmps_read_byte_data(struct i2c_client *client, int page, int reg) >> +{ >> + int rc, mfr; >> + >> + switch (reg) { >> + case PMBUS_STATUS_BYTE: >> + case PMBUS_STATUS_WORD: >> + rc = ibmps_read_word_data(client, page, PMBUS_STATUS_WORD); >> + break; >> + case PMBUS_STATUS_VOUT: >> + case PMBUS_STATUS_IOUT: >> + case PMBUS_STATUS_TEMPERATURE: >> + case PMBUS_STATUS_FAN_12: >> + rc = pmbus_read_byte_data(client, page, reg); >> + if (rc < 0) >> + return rc; >> + >> + mfr = pmbus_read_byte_data(client, page, >> + PMBUS_STATUS_MFR_SPECIFIC); >> + if (mfr < 0) >> + return rc; >> + >> + if (reg == PMBUS_STATUS_FAN_12) { >> + if (mfr & IBMPS_MFR_FAN_FAULT) >> + rc |= PB_FAN_FAN1_FAULT; >> + } else if (reg == PMBUS_STATUS_TEMPERATURE) { >> + if (mfr & IBMPS_MFR_THERMAL_FAULT) >> + rc |= PB_TEMP_OT_FAULT; >> + } else if (reg == PMBUS_STATUS_VOUT) { >> + if (mfr & (IBMPS_MFR_OV_FAULT | IBMPS_MFR_VAUX_FAULT)) >> + rc |= PB_VOLTAGE_OV_FAULT; >> + if (mfr & IBMPS_MFR_UV_FAULT) >> + rc |= PB_VOLTAGE_UV_FAULT; >> + } else if (reg == PMBUS_STATUS_IOUT) { >> + if (mfr & IBMPS_MFR_OC_FAULT) >> + rc |= PB_IOUT_OC_FAULT; >> + if (mfr & IBMPS_MFR_CURRENT_SHARE_WARNING) >> + rc |= PB_CURRENT_SHARE_FAULT; >> + } >> + break; >> + default: >> + if (reg >= PMBUS_VIRT_BASE) >> + return -ENXIO; >> + >> + rc = pmbus_read_byte_data(client, page, reg); >> + break; >> + } >> + >> + return rc; >> +} >> + >> +static int ibmps_read_word_data(struct i2c_client *client, int page, int reg) >> +{ >> + int rc, mfr; >> + >> + switch (reg) { >> + case PMBUS_STATUS_BYTE: >> + case PMBUS_STATUS_WORD: >> + rc = pmbus_read_word_data(client, page, PMBUS_STATUS_WORD); >> + if (rc < 0) >> + return rc; >> + >> + mfr = pmbus_read_byte_data(client, page, >> + PMBUS_STATUS_MFR_SPECIFIC); >> + if (mfr < 0) >> + return rc; >> + >> + if (mfr & IBMPS_MFR_PS_KILL) >> + rc |= PB_STATUS_OFF; >> + >> + if (mfr) >> + rc |= PB_STATUS_WORD_MFR; >> + break; >> + default: >> + if (reg >= PMBUS_VIRT_BASE) >> + return -ENXIO; >> + >> + rc = pmbus_read_word_data(client, page, reg); >> + if (rc < 0) >> + rc = ibmps_read_byte_data(client, page, reg); >> + break; >> + } >> + >> + return rc; >> +} >> + >> +static struct pmbus_driver_info ibmps_info = { >> + .pages = 1, >> + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | >> + PMBUS_HAVE_PIN | PMBUS_HAVE_FAN12 | PMBUS_HAVE_TEMP | >> + PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_VOUT | >> + PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_STATUS_INPUT | >> + PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_FAN12, >> + .read_byte_data = ibmps_read_byte_data, >> + .read_word_data = ibmps_read_word_data, >> +}; >> + >> +static int ibmps_probe(struct i2c_client *client, >> + const struct i2c_device_id *id) >> +{ >> + return pmbus_do_probe(client, id, &ibmps_info); >> +} >> + >> +static int ibmps_remove(struct i2c_client *client) >> +{ >> + return pmbus_do_remove(client); >> +} >> + >> +enum chips { witherspoon }; >> + >> +static const struct i2c_device_id ibmps_id[] = { >> + { "witherspoon", witherspoon }, >> + { } >> +}; >> +MODULE_DEVICE_TABLE(i2c, ibmps_id); >> + >> +static const struct of_device_id ibmps_of_match[] = { >> + { .compatible = "ibm,ibmps" }, >> + {} >> +}; >> +MODULE_DEVICE_TABLE(of, p8_i2c_occ_of_match); > Ah yes, as 0day points out, this won't compile. > Hmmm ..... makes me wonder if and how you tested this. > Can you provide output from the "sensors" command ? > > Guenter Just a copy/paste goof on my part. It compiled in my development tree, as that symbol is defined elsewhere... I'll fix this in the next patch set. This has been tested with the real power supply. I'm not sure what the sensors command is; I don't think I can use it on our test machines. Here: # ls /sys/bus/i2c/devices/3-0068/hwmon/hwmon10 curr1_alarm fan1_fault fan2_input in2_input power1_input temp2_alarm curr1_input fan1_input in1_alarm in2_label power1_label temp2_input curr1_label fan1_target in1_input name subsystem temp3_alarm device fan2_alarm in1_label power temp1_alarm temp3_input fan1_alarm fan2_fault in2_alarm power1_alarm temp1_input uevent # cat /sys/bus/i2c/devices/3-0068/hwmon/hwmon10/* 0 6125 iout1 cat: read error: Is a directory 0 0 3200 cat: read error: No such device or address 0 0 1568 0 204000 vin 0 12250 vout1 witherspoon_ps cat: read error: Is a directory 0 120000000 pin cat: read error: Is a directory 0 31000 0 34000 0 23000 Thanks, Eddie > >> + >> +static struct i2c_driver ibmps_driver = { >> + .driver = { >> + .name = "ibmps", >> + .of_match_table = ibmps_of_match, >> + }, >> + .probe = ibmps_probe, >> + .remove = ibmps_remove, >> + .id_table = ibmps_id, >> +}; >> + >> +module_i2c_driver(ibmps_driver); >> + >> +MODULE_AUTHOR("Eddie James"); >> +MODULE_DESCRIPTION("PMBus driver for IBM power supply"); >> +MODULE_LICENSE("GPL"); >> -- >> 1.8.3.1 >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-hwmon" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-hwmon" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig index 68d717a..4eba657 100644 --- a/drivers/hwmon/pmbus/Kconfig +++ b/drivers/hwmon/pmbus/Kconfig @@ -37,6 +37,16 @@ config SENSORS_ADM1275 This driver can also be built as a module. If so, the module will be called adm1275. +config SENSORS_IBMPS + tristate "IBM Power Supply" + default n + help + If you say yes here you get hardware monitoring support for IBM + power supply. + + This driver can also be built as a module. If so, the module will + be called ibmps. + config SENSORS_IR35221 tristate "Infineon IR35221" default n diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile index 75bb7ca..e37b715 100644 --- a/drivers/hwmon/pmbus/Makefile +++ b/drivers/hwmon/pmbus/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_PMBUS) += pmbus_core.o obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o +obj-$(CONFIG_SENSORS_IBMPS) += ibmps.o obj-$(CONFIG_SENSORS_IR35221) += ir35221.o obj-$(CONFIG_SENSORS_LM25066) += lm25066.o obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o diff --git a/drivers/hwmon/pmbus/ibmps.c b/drivers/hwmon/pmbus/ibmps.c new file mode 100644 index 0000000..1928dd9 --- /dev/null +++ b/drivers/hwmon/pmbus/ibmps.c @@ -0,0 +1,164 @@ +/* + * Copyright 2017 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. + */ + +#include <linux/device.h> +#include <linux/i2c.h> +#include <linux/jiffies.h> +#include <linux/module.h> + +#include "pmbus.h" + +#define IBMPS_MFR_FAN_FAULT BIT(0) +#define IBMPS_MFR_THERMAL_FAULT BIT(1) +#define IBMPS_MFR_OV_FAULT BIT(2) +#define IBMPS_MFR_UV_FAULT BIT(3) +#define IBMPS_MFR_PS_KILL BIT(4) +#define IBMPS_MFR_OC_FAULT BIT(5) +#define IBMPS_MFR_VAUX_FAULT BIT(6) +#define IBMPS_MFR_CURRENT_SHARE_WARNING BIT(7) + +static int ibmps_read_word_data(struct i2c_client *client, int page, int reg); + +static int ibmps_read_byte_data(struct i2c_client *client, int page, int reg) +{ + int rc, mfr; + + switch (reg) { + case PMBUS_STATUS_BYTE: + case PMBUS_STATUS_WORD: + rc = ibmps_read_word_data(client, page, PMBUS_STATUS_WORD); + break; + case PMBUS_STATUS_VOUT: + case PMBUS_STATUS_IOUT: + case PMBUS_STATUS_TEMPERATURE: + case PMBUS_STATUS_FAN_12: + rc = pmbus_read_byte_data(client, page, reg); + if (rc < 0) + return rc; + + mfr = pmbus_read_byte_data(client, page, + PMBUS_STATUS_MFR_SPECIFIC); + if (mfr < 0) + return rc; + + if (reg == PMBUS_STATUS_FAN_12) { + if (mfr & IBMPS_MFR_FAN_FAULT) + rc |= PB_FAN_FAN1_FAULT; + } else if (reg == PMBUS_STATUS_TEMPERATURE) { + if (mfr & IBMPS_MFR_THERMAL_FAULT) + rc |= PB_TEMP_OT_FAULT; + } else if (reg == PMBUS_STATUS_VOUT) { + if (mfr & (IBMPS_MFR_OV_FAULT | IBMPS_MFR_VAUX_FAULT)) + rc |= PB_VOLTAGE_OV_FAULT; + if (mfr & IBMPS_MFR_UV_FAULT) + rc |= PB_VOLTAGE_UV_FAULT; + } else if (reg == PMBUS_STATUS_IOUT) { + if (mfr & IBMPS_MFR_OC_FAULT) + rc |= PB_IOUT_OC_FAULT; + if (mfr & IBMPS_MFR_CURRENT_SHARE_WARNING) + rc |= PB_CURRENT_SHARE_FAULT; + } + break; + default: + if (reg >= PMBUS_VIRT_BASE) + return -ENXIO; + + rc = pmbus_read_byte_data(client, page, reg); + break; + } + + return rc; +} + +static int ibmps_read_word_data(struct i2c_client *client, int page, int reg) +{ + int rc, mfr; + + switch (reg) { + case PMBUS_STATUS_BYTE: + case PMBUS_STATUS_WORD: + rc = pmbus_read_word_data(client, page, PMBUS_STATUS_WORD); + if (rc < 0) + return rc; + + mfr = pmbus_read_byte_data(client, page, + PMBUS_STATUS_MFR_SPECIFIC); + if (mfr < 0) + return rc; + + if (mfr & IBMPS_MFR_PS_KILL) + rc |= PB_STATUS_OFF; + + if (mfr) + rc |= PB_STATUS_WORD_MFR; + break; + default: + if (reg >= PMBUS_VIRT_BASE) + return -ENXIO; + + rc = pmbus_read_word_data(client, page, reg); + if (rc < 0) + rc = ibmps_read_byte_data(client, page, reg); + break; + } + + return rc; +} + +static struct pmbus_driver_info ibmps_info = { + .pages = 1, + .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | + PMBUS_HAVE_PIN | PMBUS_HAVE_FAN12 | PMBUS_HAVE_TEMP | + PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_VOUT | + PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_STATUS_INPUT | + PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_FAN12, + .read_byte_data = ibmps_read_byte_data, + .read_word_data = ibmps_read_word_data, +}; + +static int ibmps_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + return pmbus_do_probe(client, id, &ibmps_info); +} + +static int ibmps_remove(struct i2c_client *client) +{ + return pmbus_do_remove(client); +} + +enum chips { witherspoon }; + +static const struct i2c_device_id ibmps_id[] = { + { "witherspoon", witherspoon }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ibmps_id); + +static const struct of_device_id ibmps_of_match[] = { + { .compatible = "ibm,ibmps" }, + {} +}; +MODULE_DEVICE_TABLE(of, p8_i2c_occ_of_match); + +static struct i2c_driver ibmps_driver = { + .driver = { + .name = "ibmps", + .of_match_table = ibmps_of_match, + }, + .probe = ibmps_probe, + .remove = ibmps_remove, + .id_table = ibmps_id, +}; + +module_i2c_driver(ibmps_driver); + +MODULE_AUTHOR("Eddie James"); +MODULE_DESCRIPTION("PMBus driver for IBM power supply"); +MODULE_LICENSE("GPL");