Merge tag 'hwmon-for-linus-v4.15' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 13 Nov 2017 16:55:46 +0000 (08:55 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 13 Nov 2017 16:55:46 +0000 (08:55 -0800)
Pull hwmon updates from Guenter Roeck:

 - drivers for MAX31785 and MAX6621

 - support for AMD family 17h (Ryzen, Threadripper) temperature sensors

 - various driver cleanups and minor improvements

* tag 'hwmon-for-linus-v4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (30 commits)
  dt-bindings: pmbus: Add Maxim MAX31785 documentation
  pmbus: Add driver for Maxim MAX31785 Intelligent Fan Controller
  hwmon: (aspeed-pwm-tacho) Sort headers
  hwmon: (xgene) Minor clean up of ifdef and acpi_match_table reference
  hwmon: (max6621) Inverted if condition in max6621_read()
  hwmon: (asc7621) remove redundant assignment to newval
  hwmon: (xgene) Support hwmon v2
  hwmon: (gpio-fan) Fix null pointer dereference at probe
  hwmon: (gpio-fan) Convert to use GPIO descriptors
  hwmon: (gpio-fan) Rename GPIO line state variables
  hwmon: (gpio-fan) Get rid of the gpio alarm struct
  hwmon: (gpio-fan) Get rid of platform data struct
  hwmon: (gpio-fan) Mandate OF_GPIO and cut pdata path
  hwmon: (gpio-fan) Send around device pointer
  hwmon: (gpio-fan) Localize platform data
  hwmon: (gpio-fan) Use local variable pointers
  hwmon: (gpio-fan) Move DT bindings to the right place
  Documentation: devicetree: add max6621 device
  hwmon: (max6621) Add support for Maxim MAX6621 temperature sensor
  hwmon: (w83793) make const array watchdog_minors static, reduces object code size
  ...

27 files changed:
Documentation/devicetree/bindings/gpio/gpio-fan.txt [deleted file]
Documentation/devicetree/bindings/hwmon/gpio-fan.txt [new file with mode: 0644]
Documentation/devicetree/bindings/hwmon/max1619.txt [new file with mode: 0644]
Documentation/devicetree/bindings/hwmon/max31785.txt [new file with mode: 0644]
Documentation/devicetree/bindings/trivial-devices.txt
Documentation/hwmon/max31785 [new file with mode: 0644]
Documentation/hwmon/sht15
arch/arm/mach-pxa/stargate2.c
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/asc7621.c
drivers/hwmon/aspeed-pwm-tacho.c
drivers/hwmon/gpio-fan.c
drivers/hwmon/k10temp.c
drivers/hwmon/max1619.c
drivers/hwmon/max6621.c [new file with mode: 0644]
drivers/hwmon/pmbus/Kconfig
drivers/hwmon/pmbus/Makefile
drivers/hwmon/pmbus/max31785.c [new file with mode: 0644]
drivers/hwmon/pmbus/pmbus.h
drivers/hwmon/pmbus/pmbus_core.c
drivers/hwmon/sht15.c
drivers/hwmon/stts751.c
drivers/hwmon/w83793.c
drivers/hwmon/xgene-hwmon.c
include/linux/gpio-fan.h [deleted file]
include/linux/platform_data/sht15.h [deleted file]

diff --git a/Documentation/devicetree/bindings/gpio/gpio-fan.txt b/Documentation/devicetree/bindings/gpio/gpio-fan.txt
deleted file mode 100644 (file)
index 439a743..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-Bindings for fan connected to GPIO lines
-
-Required properties:
-- compatible : "gpio-fan"
-
-Optional properties:
-- gpios: Specifies the pins that map to bits in the control value,
-  ordered MSB-->LSB.
-- gpio-fan,speed-map: A mapping of possible fan RPM speeds and the
-  control value that should be set to achieve them. This array
-  must have the RPM values in ascending order.
-- alarm-gpios: This pin going active indicates something is wrong with
-  the fan, and a udev event will be fired.
-- cooling-cells: If used as a cooling device, must be <2>
-  Also see: Documentation/devicetree/bindings/thermal/thermal.txt
-  min and max states are derived from the speed-map of the fan.
-
-Note: At least one the "gpios" or "alarm-gpios" properties must be set.
-
-Examples:
-
-       gpio_fan {
-               compatible = "gpio-fan";
-               gpios = <&gpio1 14 1
-                        &gpio1 13 1>;
-               gpio-fan,speed-map = <0    0
-                                     3000 1
-                                     6000 2>;
-               alarm-gpios = <&gpio1 15 1>;
-       };
-       gpio_fan_cool: gpio_fan {
-               compatible = "gpio-fan";
-               gpios = <&gpio2 14 1
-                        &gpio2 13 1>;
-               gpio-fan,speed-map =    <0    0>,
-                                       <3000 1>,
-                                       <6000 2>;
-               alarm-gpios = <&gpio2 15 1>;
-               #cooling-cells = <2>; /* min followed by max */
-       };
diff --git a/Documentation/devicetree/bindings/hwmon/gpio-fan.txt b/Documentation/devicetree/bindings/hwmon/gpio-fan.txt
new file mode 100644 (file)
index 0000000..439a743
--- /dev/null
@@ -0,0 +1,40 @@
+Bindings for fan connected to GPIO lines
+
+Required properties:
+- compatible : "gpio-fan"
+
+Optional properties:
+- gpios: Specifies the pins that map to bits in the control value,
+  ordered MSB-->LSB.
+- gpio-fan,speed-map: A mapping of possible fan RPM speeds and the
+  control value that should be set to achieve them. This array
+  must have the RPM values in ascending order.
+- alarm-gpios: This pin going active indicates something is wrong with
+  the fan, and a udev event will be fired.
+- cooling-cells: If used as a cooling device, must be <2>
+  Also see: Documentation/devicetree/bindings/thermal/thermal.txt
+  min and max states are derived from the speed-map of the fan.
+
+Note: At least one the "gpios" or "alarm-gpios" properties must be set.
+
+Examples:
+
+       gpio_fan {
+               compatible = "gpio-fan";
+               gpios = <&gpio1 14 1
+                        &gpio1 13 1>;
+               gpio-fan,speed-map = <0    0
+                                     3000 1
+                                     6000 2>;
+               alarm-gpios = <&gpio1 15 1>;
+       };
+       gpio_fan_cool: gpio_fan {
+               compatible = "gpio-fan";
+               gpios = <&gpio2 14 1
+                        &gpio2 13 1>;
+               gpio-fan,speed-map =    <0    0>,
+                                       <3000 1>,
+                                       <6000 2>;
+               alarm-gpios = <&gpio2 15 1>;
+               #cooling-cells = <2>; /* min followed by max */
+       };
diff --git a/Documentation/devicetree/bindings/hwmon/max1619.txt b/Documentation/devicetree/bindings/hwmon/max1619.txt
new file mode 100644 (file)
index 0000000..c70dbbe
--- /dev/null
@@ -0,0 +1,12 @@
+Bindings for MAX1619 Temperature Sensor
+
+Required properties:
+- compatible : "maxim,max1619"
+- reg        : I2C address, one of 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, or
+               0x4d, 0x4e
+
+Example:
+       temp@4c {
+               compatible = "maxim,max1619";
+               reg = <0x4c>;
+       };
diff --git a/Documentation/devicetree/bindings/hwmon/max31785.txt b/Documentation/devicetree/bindings/hwmon/max31785.txt
new file mode 100644 (file)
index 0000000..106e08c
--- /dev/null
@@ -0,0 +1,22 @@
+Bindings for the Maxim MAX31785 Intelligent Fan Controller
+==========================================================
+
+Reference:
+
+https://datasheets.maximintegrated.com/en/ds/MAX31785.pdf
+
+The Maxim MAX31785 is a PMBus device providing closed-loop, multi-channel fan
+management with temperature and remote voltage sensing. Various fan control
+features are provided, including PWM frequency control, temperature hysteresis,
+dual tachometer measurements, and fan health monitoring.
+
+Required properties:
+- compatible     : One of "maxim,max31785" or "maxim,max31785a"
+- reg            : I2C address, one of 0x52, 0x53, 0x54, 0x55.
+
+Example:
+
+        fans@52 {
+                compatible = "maxim,max31785";
+                reg = <0x52>;
+        };
index af284fbd4d238e4ce5b77e5d55c989c99366c8b0..8bcac6ee73daa54254aa32d96d9aeacdc93a966d 100644 (file)
@@ -71,6 +71,7 @@ isil,isl29028         Intersil ISL29028 Ambient Light and Proximity Sensor
 isil,isl29030          Intersil ISL29030 Ambient Light and Proximity Sensor
 maxim,ds1050           5 Bit Programmable, Pulse-Width Modulator
 maxim,max1237          Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
+maxim,max6621          PECI-to-I2C translator for PECI-to-SMBus/I2C protocol conversion
 maxim,max6625          9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
 mc,rv3029c2            Real Time Clock Module with I2C-Bus
 mcube,mc3230           mCube 3-axis 8-bit digital accelerometer
diff --git a/Documentation/hwmon/max31785 b/Documentation/hwmon/max31785
new file mode 100644 (file)
index 0000000..45fb609
--- /dev/null
@@ -0,0 +1,51 @@
+Kernel driver max31785
+======================
+
+Supported chips:
+  * Maxim MAX31785, MAX31785A
+    Prefix: 'max31785' or 'max31785a'
+    Addresses scanned: -
+    Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX31785.pdf
+
+Author: Andrew Jeffery <andrew@aj.id.au>
+
+Description
+-----------
+
+The Maxim MAX31785 is a PMBus device providing closed-loop, multi-channel fan
+management with temperature and remote voltage sensing. Various fan control
+features are provided, including PWM frequency control, temperature hysteresis,
+dual tachometer measurements, and fan health monitoring.
+
+For dual rotor fan configuration, the MAX31785 exposes the slowest rotor of the
+two in the fan[1-4]_input attributes.
+
+Usage Notes
+-----------
+
+This driver does not probe for PMBus devices. You will have to instantiate
+devices explicitly.
+
+Sysfs attributes
+----------------
+
+fan[1-4]_alarm         Fan alarm.
+fan[1-4]_fault         Fan fault.
+fan[1-4]_input         Fan RPM.
+
+in[1-6]_crit           Critical maximum output voltage
+in[1-6]_crit_alarm     Output voltage critical high alarm
+in[1-6]_input          Measured output voltage
+in[1-6]_label          "vout[18-23]"
+in[1-6]_lcrit          Critical minimum output voltage
+in[1-6]_lcrit_alarm    Output voltage critical low alarm
+in[1-6]_max            Maximum output voltage
+in[1-6]_max_alarm      Output voltage high alarm
+in[1-6]_min            Minimum output voltage
+in[1-6]_min_alarm      Output voltage low alarm
+
+temp[1-11]_crit                Critical high temperature
+temp[1-11]_crit_alarm  Chip temperature critical high alarm
+temp[1-11]_input       Measured temperature
+temp[1-11]_max         Maximum temperature
+temp[1-11]_max_alarm   Chip temperature high alarm
index 778987d1856fd2c117cb779c3ef988cb2127218d..5e3207c3b177d285722e82d86c02304995b9cf4f 100644 (file)
@@ -42,8 +42,7 @@ chip. These coefficients are used to internally calibrate the signals from the
 sensors. Disabling the reload of those coefficients allows saving 10ms for each
 measurement and decrease power consumption, while losing on precision.
 
-Some options may be set directly in the sht15_platform_data structure
-or via sysfs attributes.
+Some options may be set via sysfs attributes.
 
 Notes:
   * The regulator supply name is set to "vcc".
index 2d45d18b1a5e0a1b954fe3f691b933bb03488c08..6b7df6fd2448676e4814d7a93aeda8caa7301fbe 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/platform_data/pcf857x.h>
 #include <linux/platform_data/at24.h>
 #include <linux/smc91x.h>
+#include <linux/gpio/machine.h>
 #include <linux/gpio.h>
 #include <linux/leds.h>
 
@@ -52,7 +53,6 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/mfd/da903x.h>
-#include <linux/platform_data/sht15.h>
 
 #include "devices.h"
 #include "generic.h"
@@ -137,17 +137,18 @@ static unsigned long sg2_im2_unified_pin_config[] __initdata = {
        GPIO10_GPIO, /* large basic connector pin 23 */
 };
 
-static struct sht15_platform_data platform_data_sht15 = {
-       .gpio_data =  100,
-       .gpio_sck  =  98,
+static struct gpiod_lookup_table sht15_gpiod_table = {
+       .dev_id = "sht15",
+       .table = {
+               /* FIXME: should this have |GPIO_OPEN_DRAIN set? */
+               GPIO_LOOKUP("gpio-pxa", 100, "data", GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP("gpio-pxa", 98, "clk", GPIO_ACTIVE_HIGH),
+       },
 };
 
 static struct platform_device sht15 = {
        .name = "sht15",
        .id = -1,
-       .dev = {
-               .platform_data = &platform_data_sht15,
-       },
 };
 
 static struct regulator_consumer_supply stargate2_sensor_3_con[] = {
@@ -608,6 +609,7 @@ static void __init imote2_init(void)
 
        imote2_stargate2_init();
 
+       gpiod_add_lookup_table(&sht15_gpiod_table);
        platform_add_devices(imote2_devices, ARRAY_SIZE(imote2_devices));
 
        i2c_register_board_info(0, imote2_i2c_board_info,
@@ -988,6 +990,7 @@ static void __init stargate2_init(void)
 
        imote2_stargate2_init();
 
+       gpiod_add_lookup_table(&sht15_gpiod_table);
        platform_add_devices(ARRAY_AND_SIZE(stargate2_devices));
 
        i2c_register_board_info(0, ARRAY_AND_SIZE(stargate2_i2c_board_info));
index d65431417b17c4280ab791bef63fa5150dfcc34a..7ad017690e3a36f6ca880fa9ecd707a075085e9b 100644 (file)
@@ -552,6 +552,7 @@ config SENSORS_G762
 
 config SENSORS_GPIO_FAN
        tristate "GPIO fan"
+       depends on OF_GPIO
        depends on GPIOLIB || COMPILE_TEST
        depends on THERMAL || THERMAL=n
        help
@@ -862,6 +863,20 @@ tristate "MAX31722 temperature sensor"
          This driver can also be built as a module. If so, the module
          will be called max31722.
 
+config SENSORS_MAX6621
+       tristate "Maxim MAX6621 sensor chip"
+       depends on I2C
+       select REGMAP_I2C
+       help
+         If you say yes here you get support for MAX6621 sensor chip.
+         MAX6621 is a PECI-to-I2C translator provides an efficient,
+         low-cost solution for PECI-to-SMBus/I2C protocol conversion.
+         It allows reading the temperature from the PECI-compliant
+         host directly from up to four PECI-enabled CPUs.
+
+         This driver can also be built as a module. If so, the module
+         will be called max6621.
+
 config SENSORS_MAX6639
        tristate "Maxim MAX6639 sensor chip"
        depends on I2C
index 23e195a5a2f330f9873d9a460d265e6e5169d818..0fe489fab663f788175bf0e68d104e2b0fd18e84 100644 (file)
@@ -118,6 +118,7 @@ obj-$(CONFIG_SENSORS_MAX1619)       += max1619.o
 obj-$(CONFIG_SENSORS_MAX1668)  += max1668.o
 obj-$(CONFIG_SENSORS_MAX197)   += max197.o
 obj-$(CONFIG_SENSORS_MAX31722) += max31722.o
+obj-$(CONFIG_SENSORS_MAX6621)  += max6621.o
 obj-$(CONFIG_SENSORS_MAX6639)  += max6639.o
 obj-$(CONFIG_SENSORS_MAX6642)  += max6642.o
 obj-$(CONFIG_SENSORS_MAX6650)  += max6650.o
index 4875e99b59c97e52a80e453a8a04297152fb43ec..6d34c05a4f830496386240e2750cd0f20fbd4067 100644 (file)
@@ -579,7 +579,6 @@ static ssize_t show_pwm_enable(struct device *dev,
        mutex_unlock(&data->update_lock);
 
        val = config | (altbit << 3);
-       newval = 0;
 
        if (val == 3 || val >= 10)
                newval = 255;
index 69b97d45e3cbb459ccdf73321dc4c3ef8ae23488..63a95e23ca818038dac27324b5ee276895657250 100644 (file)
@@ -7,19 +7,19 @@
  */
 
 #include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/gpio/consumer.h>
-#include <linux/delay.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/of_platform.h>
 #include <linux/of_device.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
-#include <linux/sysfs.h>
 #include <linux/regmap.h>
+#include <linux/sysfs.h>
 #include <linux/thermal.h>
 
 /* ASPEED PWM & FAN Tach Register Definition */
  * 11: reserved.
  */
 #define M_TACH_MODE 0x02 /* 10b */
-#define M_TACH_UNIT 0x00c0
+#define M_TACH_UNIT 0x0210
 #define INIT_FAN_CTRL 0xFF
 
 /* How long we sleep in us while waiting for an RPM result. */
index 9c355b9d31c57ac23b663fe5d83460dd11130bba..5c9a52599cf68ff8d7dcb181ac3cfdc162ea3d1b 100644 (file)
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/hwmon.h>
-#include <linux/gpio.h>
-#include <linux/gpio-fan.h>
+#include <linux/gpio/consumer.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
-#include <linux/of_gpio.h>
 #include <linux/thermal.h>
 
+struct gpio_fan_speed {
+       int rpm;
+       int ctrl_val;
+};
+
 struct gpio_fan_data {
-       struct platform_device  *pdev;
+       struct device           *dev;
        struct device           *hwmon_dev;
        /* Cooling device if any */
        struct thermal_cooling_device *cdev;
        struct mutex            lock; /* lock GPIOs operations. */
-       int                     num_ctrl;
-       unsigned                *ctrl;
+       int                     num_gpios;
+       struct gpio_desc        **gpios;
        int                     num_speed;
        struct gpio_fan_speed   *speed;
        int                     speed_index;
@@ -51,7 +54,7 @@ struct gpio_fan_data {
        int                     resume_speed;
 #endif
        bool                    pwm_enable;
-       struct gpio_fan_alarm   *alarm;
+       struct gpio_desc        *alarm_gpio;
        struct work_struct      alarm_work;
 };
 
@@ -64,8 +67,8 @@ static void fan_alarm_notify(struct work_struct *ws)
        struct gpio_fan_data *fan_data =
                container_of(ws, struct gpio_fan_data, alarm_work);
 
-       sysfs_notify(&fan_data->pdev->dev.kobj, NULL, "fan1_alarm");
-       kobject_uevent(&fan_data->pdev->dev.kobj, KOBJ_CHANGE);
+       sysfs_notify(&fan_data->dev->kobj, NULL, "fan1_alarm");
+       kobject_uevent(&fan_data->dev->kobj, KOBJ_CHANGE);
 }
 
 static irqreturn_t fan_alarm_irq_handler(int irq, void *dev_id)
@@ -81,47 +84,30 @@ static ssize_t fan1_alarm_show(struct device *dev,
                               struct device_attribute *attr, char *buf)
 {
        struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
-       struct gpio_fan_alarm *alarm = fan_data->alarm;
-       int value = gpio_get_value_cansleep(alarm->gpio);
 
-       if (alarm->active_low)
-               value = !value;
-
-       return sprintf(buf, "%d\n", value);
+       return sprintf(buf, "%d\n",
+                      gpiod_get_value_cansleep(fan_data->alarm_gpio));
 }
 
 static DEVICE_ATTR_RO(fan1_alarm);
 
-static int fan_alarm_init(struct gpio_fan_data *fan_data,
-                         struct gpio_fan_alarm *alarm)
+static int fan_alarm_init(struct gpio_fan_data *fan_data)
 {
-       int err;
        int alarm_irq;
-       struct platform_device *pdev = fan_data->pdev;
-
-       fan_data->alarm = alarm;
-
-       err = devm_gpio_request(&pdev->dev, alarm->gpio, "GPIO fan alarm");
-       if (err)
-               return err;
-
-       err = gpio_direction_input(alarm->gpio);
-       if (err)
-               return err;
+       struct device *dev = fan_data->dev;
 
        /*
         * If the alarm GPIO don't support interrupts, just leave
         * without initializing the fail notification support.
         */
-       alarm_irq = gpio_to_irq(alarm->gpio);
-       if (alarm_irq < 0)
+       alarm_irq = gpiod_to_irq(fan_data->alarm_gpio);
+       if (alarm_irq <= 0)
                return 0;
 
        INIT_WORK(&fan_data->alarm_work, fan_alarm_notify);
        irq_set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH);
-       err = devm_request_irq(&pdev->dev, alarm_irq, fan_alarm_irq_handler,
-                              IRQF_SHARED, "GPIO fan alarm", fan_data);
-       return err;
+       return devm_request_irq(dev, alarm_irq, fan_alarm_irq_handler,
+                               IRQF_SHARED, "GPIO fan alarm", fan_data);
 }
 
 /*
@@ -133,8 +119,9 @@ static void __set_fan_ctrl(struct gpio_fan_data *fan_data, int ctrl_val)
 {
        int i;
 
-       for (i = 0; i < fan_data->num_ctrl; i++)
-               gpio_set_value_cansleep(fan_data->ctrl[i], (ctrl_val >> i) & 1);
+       for (i = 0; i < fan_data->num_gpios; i++)
+               gpiod_set_value_cansleep(fan_data->gpios[i],
+                                        (ctrl_val >> i) & 1);
 }
 
 static int __get_fan_ctrl(struct gpio_fan_data *fan_data)
@@ -142,10 +129,10 @@ static int __get_fan_ctrl(struct gpio_fan_data *fan_data)
        int i;
        int ctrl_val = 0;
 
-       for (i = 0; i < fan_data->num_ctrl; i++) {
+       for (i = 0; i < fan_data->num_gpios; i++) {
                int value;
 
-               value = gpio_get_value_cansleep(fan_data->ctrl[i]);
+               value = gpiod_get_value_cansleep(fan_data->gpios[i]);
                ctrl_val |= (value << i);
        }
        return ctrl_val;
@@ -170,7 +157,7 @@ static int get_fan_speed_index(struct gpio_fan_data *fan_data)
                if (fan_data->speed[i].ctrl_val == ctrl_val)
                        return i;
 
-       dev_warn(&fan_data->pdev->dev,
+       dev_warn(fan_data->dev,
                 "missing speed array entry for GPIO value 0x%x\n", ctrl_val);
 
        return -ENODEV;
@@ -328,9 +315,9 @@ static umode_t gpio_fan_is_visible(struct kobject *kobj,
        struct device *dev = container_of(kobj, struct device, kobj);
        struct gpio_fan_data *data = dev_get_drvdata(dev);
 
-       if (index == 0 && !data->alarm)
+       if (index == 0 && !data->alarm_gpio)
                return 0;
-       if (index > 0 && !data->ctrl)
+       if (index > 0 && !data->gpios)
                return 0;
 
        return attr->mode;
@@ -358,30 +345,25 @@ static const struct attribute_group *gpio_fan_groups[] = {
        NULL
 };
 
-static int fan_ctrl_init(struct gpio_fan_data *fan_data,
-                        struct gpio_fan_platform_data *pdata)
+static int fan_ctrl_init(struct gpio_fan_data *fan_data)
 {
-       struct platform_device *pdev = fan_data->pdev;
-       int num_ctrl = pdata->num_ctrl;
-       unsigned *ctrl = pdata->ctrl;
+       int num_gpios = fan_data->num_gpios;
+       struct gpio_desc **gpios = fan_data->gpios;
        int i, err;
 
-       for (i = 0; i < num_ctrl; i++) {
-               err = devm_gpio_request(&pdev->dev, ctrl[i],
-                                       "GPIO fan control");
-               if (err)
-                       return err;
-
-               err = gpio_direction_output(ctrl[i],
-                                           gpio_get_value_cansleep(ctrl[i]));
+       for (i = 0; i < num_gpios; i++) {
+               /*
+                * The GPIO descriptors were retrieved with GPIOD_ASIS so here
+                * we set the GPIO into output mode, carefully preserving the
+                * current value by setting it to whatever it is already set
+                * (no surprise changes in default fan speed).
+                */
+               err = gpiod_direction_output(gpios[i],
+                                       gpiod_get_value_cansleep(gpios[i]));
                if (err)
                        return err;
        }
 
-       fan_data->num_ctrl = num_ctrl;
-       fan_data->ctrl = ctrl;
-       fan_data->num_speed = pdata->num_speed;
-       fan_data->speed = pdata->speed;
        fan_data->pwm_enable = true; /* Enable manual fan speed control. */
        fan_data->speed_index = get_fan_speed_index(fan_data);
        if (fan_data->speed_index < 0)
@@ -432,67 +414,47 @@ static const struct thermal_cooling_device_ops gpio_fan_cool_ops = {
        .set_cur_state = gpio_fan_set_cur_state,
 };
 
-#ifdef CONFIG_OF_GPIO
 /*
  * Translate OpenFirmware node properties into platform_data
  */
-static int gpio_fan_get_of_pdata(struct device *dev,
-                           struct gpio_fan_platform_data *pdata)
+static int gpio_fan_get_of_data(struct gpio_fan_data *fan_data)
 {
-       struct device_node *node;
        struct gpio_fan_speed *speed;
-       unsigned *ctrl;
+       struct device *dev = fan_data->dev;
+       struct device_node *np = dev->of_node;
+       struct gpio_desc **gpios;
        unsigned i;
        u32 u;
        struct property *prop;
        const __be32 *p;
 
-       node = dev->of_node;
-
        /* Alarm GPIO if one exists */
-       if (of_gpio_named_count(node, "alarm-gpios") > 0) {
-               struct gpio_fan_alarm *alarm;
-               int val;
-               enum of_gpio_flags flags;
-
-               alarm = devm_kzalloc(dev, sizeof(struct gpio_fan_alarm),
-                                       GFP_KERNEL);
-               if (!alarm)
-                       return -ENOMEM;
-
-               val = of_get_named_gpio_flags(node, "alarm-gpios", 0, &flags);
-               if (val < 0)
-                       return val;
-               alarm->gpio = val;
-               alarm->active_low = flags & OF_GPIO_ACTIVE_LOW;
-
-               pdata->alarm = alarm;
-       }
+       fan_data->alarm_gpio = devm_gpiod_get_optional(dev, "alarm", GPIOD_IN);
+       if (IS_ERR(fan_data->alarm_gpio))
+               return PTR_ERR(fan_data->alarm_gpio);
 
        /* Fill GPIO pin array */
-       pdata->num_ctrl = of_gpio_count(node);
-       if (pdata->num_ctrl <= 0) {
-               if (pdata->alarm)
+       fan_data->num_gpios = gpiod_count(dev, NULL);
+       if (fan_data->num_gpios <= 0) {
+               if (fan_data->alarm_gpio)
                        return 0;
                dev_err(dev, "DT properties empty / missing");
                return -ENODEV;
        }
-       ctrl = devm_kzalloc(dev, pdata->num_ctrl * sizeof(unsigned),
-                               GFP_KERNEL);
-       if (!ctrl)
+       gpios = devm_kzalloc(dev,
+                            fan_data->num_gpios * sizeof(struct gpio_desc *),
+                            GFP_KERNEL);
+       if (!gpios)
                return -ENOMEM;
-       for (i = 0; i < pdata->num_ctrl; i++) {
-               int val;
-
-               val = of_get_gpio(node, i);
-               if (val < 0)
-                       return val;
-               ctrl[i] = val;
+       for (i = 0; i < fan_data->num_gpios; i++) {
+               gpios[i] = devm_gpiod_get_index(dev, NULL, i, GPIOD_ASIS);
+               if (IS_ERR(gpios[i]))
+                       return PTR_ERR(gpios[i]);
        }
-       pdata->ctrl = ctrl;
+       fan_data->gpios = gpios;
 
        /* Get number of RPM/ctrl_val pairs in speed map */
-       prop = of_find_property(node, "gpio-fan,speed-map", &i);
+       prop = of_find_property(np, "gpio-fan,speed-map", &i);
        if (!prop) {
                dev_err(dev, "gpio-fan,speed-map DT property missing");
                return -ENODEV;
@@ -502,7 +464,7 @@ static int gpio_fan_get_of_pdata(struct device *dev,
                dev_err(dev, "gpio-fan,speed-map contains zero/odd number of entries");
                return -ENODEV;
        }
-       pdata->num_speed = i / 2;
+       fan_data->num_speed = i / 2;
 
        /*
         * Populate speed map
@@ -510,12 +472,12 @@ static int gpio_fan_get_of_pdata(struct device *dev,
         * this needs splitting into pairs to create gpio_fan_speed structs
         */
        speed = devm_kzalloc(dev,
-                       pdata->num_speed * sizeof(struct gpio_fan_speed),
+                       fan_data->num_speed * sizeof(struct gpio_fan_speed),
                        GFP_KERNEL);
        if (!speed)
                return -ENOMEM;
        p = NULL;
-       for (i = 0; i < pdata->num_speed; i++) {
+       for (i = 0; i < fan_data->num_speed; i++) {
                p = of_prop_next_u32(prop, p, &u);
                if (!p)
                        return -ENODEV;
@@ -525,7 +487,7 @@ static int gpio_fan_get_of_pdata(struct device *dev,
                        return -ENODEV;
                speed[i].ctrl_val = u;
        }
-       pdata->speed = speed;
+       fan_data->speed = speed;
 
        return 0;
 }
@@ -535,76 +497,58 @@ static const struct of_device_id of_gpio_fan_match[] = {
        {},
 };
 MODULE_DEVICE_TABLE(of, of_gpio_fan_match);
-#endif /* CONFIG_OF_GPIO */
 
 static int gpio_fan_probe(struct platform_device *pdev)
 {
        int err;
        struct gpio_fan_data *fan_data;
-       struct gpio_fan_platform_data *pdata = dev_get_platdata(&pdev->dev);
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
 
-       fan_data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_fan_data),
+       fan_data = devm_kzalloc(dev, sizeof(struct gpio_fan_data),
                                GFP_KERNEL);
        if (!fan_data)
                return -ENOMEM;
 
-#ifdef CONFIG_OF_GPIO
-       if (!pdata) {
-               pdata = devm_kzalloc(&pdev->dev,
-                                       sizeof(struct gpio_fan_platform_data),
-                                       GFP_KERNEL);
-               if (!pdata)
-                       return -ENOMEM;
-
-               err = gpio_fan_get_of_pdata(&pdev->dev, pdata);
-               if (err)
-                       return err;
-       }
-#else /* CONFIG_OF_GPIO */
-       if (!pdata)
-               return -EINVAL;
-#endif /* CONFIG_OF_GPIO */
+       fan_data->dev = dev;
+       err = gpio_fan_get_of_data(fan_data);
+       if (err)
+               return err;
 
-       fan_data->pdev = pdev;
        platform_set_drvdata(pdev, fan_data);
        mutex_init(&fan_data->lock);
 
        /* Configure alarm GPIO if available. */
-       if (pdata->alarm) {
-               err = fan_alarm_init(fan_data, pdata->alarm);
+       if (fan_data->alarm_gpio) {
+               err = fan_alarm_init(fan_data);
                if (err)
                        return err;
        }
 
        /* Configure control GPIOs if available. */
-       if (pdata->ctrl && pdata->num_ctrl > 0) {
-               if (!pdata->speed || pdata->num_speed <= 1)
+       if (fan_data->gpios && fan_data->num_gpios > 0) {
+               if (!fan_data->speed || fan_data->num_speed <= 1)
                        return -EINVAL;
-               err = fan_ctrl_init(fan_data, pdata);
+               err = fan_ctrl_init(fan_data);
                if (err)
                        return err;
        }
 
        /* Make this driver part of hwmon class. */
        fan_data->hwmon_dev =
-               devm_hwmon_device_register_with_groups(&pdev->dev,
+               devm_hwmon_device_register_with_groups(dev,
                                                       "gpio_fan", fan_data,
                                                       gpio_fan_groups);
        if (IS_ERR(fan_data->hwmon_dev))
                return PTR_ERR(fan_data->hwmon_dev);
-#ifdef CONFIG_OF_GPIO
+
        /* Optional cooling device register for Device tree platforms */
-       fan_data->cdev = thermal_of_cooling_device_register(pdev->dev.of_node,
+       fan_data->cdev = thermal_of_cooling_device_register(np,
                                                            "gpio-fan",
                                                            fan_data,
                                                            &gpio_fan_cool_ops);
-#else /* CONFIG_OF_GPIO */
-       /* Optional cooling device register for non Device tree platforms */
-       fan_data->cdev = thermal_cooling_device_register("gpio-fan", fan_data,
-                                                        &gpio_fan_cool_ops);
-#endif /* CONFIG_OF_GPIO */
 
-       dev_info(&pdev->dev, "GPIO fan initialized\n");
+       dev_info(dev, "GPIO fan initialized\n");
 
        return 0;
 }
@@ -616,7 +560,7 @@ static int gpio_fan_remove(struct platform_device *pdev)
        if (!IS_ERR(fan_data->cdev))
                thermal_cooling_device_unregister(fan_data->cdev);
 
-       if (fan_data->ctrl)
+       if (fan_data->gpios)
                set_fan_speed(fan_data, 0);
 
        return 0;
@@ -632,7 +576,7 @@ static int gpio_fan_suspend(struct device *dev)
 {
        struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
 
-       if (fan_data->ctrl) {
+       if (fan_data->gpios) {
                fan_data->resume_speed = fan_data->speed_index;
                set_fan_speed(fan_data, 0);
        }
@@ -644,7 +588,7 @@ static int gpio_fan_resume(struct device *dev)
 {
        struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
 
-       if (fan_data->ctrl)
+       if (fan_data->gpios)
                set_fan_speed(fan_data, fan_data->resume_speed);
 
        return 0;
@@ -663,9 +607,7 @@ static struct platform_driver gpio_fan_driver = {
        .driver = {
                .name   = "gpio-fan",
                .pm     = GPIO_FAN_PM,
-#ifdef CONFIG_OF_GPIO
                .of_match_table = of_match_ptr(of_gpio_fan_match),
-#endif
        },
 };
 
index ce3b91f22e30afb474d81f981eca7f326c076e25..46a54ed234105040ecda4644cadeb48d6639aca2 100644 (file)
@@ -36,6 +36,10 @@ MODULE_PARM_DESC(force, "force loading on processors with erratum 319");
 /* Provide lock for writing to NB_SMU_IND_ADDR */
 static DEFINE_MUTEX(nb_smu_ind_mutex);
 
+#ifndef PCI_DEVICE_ID_AMD_17H_DF_F3
+#define PCI_DEVICE_ID_AMD_17H_DF_F3    0x1463
+#endif
+
 /* CPUID function 0x80000001, ebx */
 #define CPUID_PKGTYPE_MASK     0xf0000000
 #define CPUID_PKGTYPE_F                0x00000000
@@ -61,31 +65,72 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
  */
 #define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET    0xd8200ca4
 
-static void amd_nb_smu_index_read(struct pci_dev *pdev, unsigned int devfn,
-                                 int offset, u32 *val)
+/* F17h M01h Access througn SMN */
+#define F17H_M01H_REPORTED_TEMP_CTRL_OFFSET    0x00059800
+
+struct k10temp_data {
+       struct pci_dev *pdev;
+       void (*read_tempreg)(struct pci_dev *pdev, u32 *regval);
+       int temp_offset;
+};
+
+struct tctl_offset {
+       u8 model;
+       char const *id;
+       int offset;
+};
+
+static const struct tctl_offset tctl_offset_table[] = {
+       { 0x17, "AMD Ryzen 7 1600X", 20000 },
+       { 0x17, "AMD Ryzen 7 1700X", 20000 },
+       { 0x17, "AMD Ryzen 7 1800X", 20000 },
+       { 0x17, "AMD Ryzen Threadripper 1950X", 27000 },
+       { 0x17, "AMD Ryzen Threadripper 1920X", 27000 },
+       { 0x17, "AMD Ryzen Threadripper 1950", 10000 },
+       { 0x17, "AMD Ryzen Threadripper 1920", 10000 },
+       { 0x17, "AMD Ryzen Threadripper 1910", 10000 },
+};
+
+static void read_tempreg_pci(struct pci_dev *pdev, u32 *regval)
+{
+       pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, regval);
+}
+
+static void amd_nb_index_read(struct pci_dev *pdev, unsigned int devfn,
+                             unsigned int base, int offset, u32 *val)
 {
        mutex_lock(&nb_smu_ind_mutex);
        pci_bus_write_config_dword(pdev->bus, devfn,
-                                  0xb8, offset);
+                                  base, offset);
        pci_bus_read_config_dword(pdev->bus, devfn,
-                                 0xbc, val);
+                                 base + 4, val);
        mutex_unlock(&nb_smu_ind_mutex);
 }
 
+static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval)
+{
+       amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8,
+                         F15H_M60H_REPORTED_TEMP_CTRL_OFFSET, regval);
+}
+
+static void read_tempreg_nb_f17(struct pci_dev *pdev, u32 *regval)
+{
+       amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0x60,
+                         F17H_M01H_REPORTED_TEMP_CTRL_OFFSET, regval);
+}
+
 static ssize_t temp1_input_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
+       struct k10temp_data *data = dev_get_drvdata(dev);
        u32 regval;
-       struct pci_dev *pdev = dev_get_drvdata(dev);
-
-       if (boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model == 0x60) {
-               amd_nb_smu_index_read(pdev, PCI_DEVFN(0, 0),
-                                     F15H_M60H_REPORTED_TEMP_CTRL_OFFSET,
-                                     &regval);
-       } else {
-               pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, &regval);
-       }
-       return sprintf(buf, "%u\n", (regval >> 21) * 125);
+       unsigned int temp;
+
+       data->read_tempreg(data->pdev, &regval);
+       temp = (regval >> 21) * 125;
+       temp -= data->temp_offset;
+
+       return sprintf(buf, "%u\n", temp);
 }
 
 static ssize_t temp1_max_show(struct device *dev,
@@ -98,11 +143,12 @@ static ssize_t show_temp_crit(struct device *dev,
                              struct device_attribute *devattr, char *buf)
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       struct k10temp_data *data = dev_get_drvdata(dev);
        int show_hyst = attr->index;
        u32 regval;
        int value;
 
-       pci_read_config_dword(dev_get_drvdata(dev),
+       pci_read_config_dword(data->pdev,
                              REG_HARDWARE_THERMAL_CONTROL, &regval);
        value = ((regval >> 16) & 0x7f) * 500 + 52000;
        if (show_hyst)
@@ -119,7 +165,8 @@ static umode_t k10temp_is_visible(struct kobject *kobj,
                                  struct attribute *attr, int index)
 {
        struct device *dev = container_of(kobj, struct device, kobj);
-       struct pci_dev *pdev = dev_get_drvdata(dev);
+       struct k10temp_data *data = dev_get_drvdata(dev);
+       struct pci_dev *pdev = data->pdev;
 
        if (index >= 2) {
                u32 reg_caps, reg_htc;
@@ -187,7 +234,9 @@ static int k10temp_probe(struct pci_dev *pdev,
 {
        int unreliable = has_erratum_319(pdev);
        struct device *dev = &pdev->dev;
+       struct k10temp_data *data;
        struct device *hwmon_dev;
+       int i;
 
        if (unreliable) {
                if (!force) {
@@ -199,7 +248,31 @@ static int k10temp_probe(struct pci_dev *pdev,
                         "unreliable CPU thermal sensor; check erratum 319\n");
        }
 
-       hwmon_dev = devm_hwmon_device_register_with_groups(dev, "k10temp", pdev,
+       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       data->pdev = pdev;
+
+       if (boot_cpu_data.x86 == 0x15 && (boot_cpu_data.x86_model == 0x60 ||
+                                         boot_cpu_data.x86_model == 0x70))
+               data->read_tempreg = read_tempreg_nb_f15;
+       else if (boot_cpu_data.x86 == 0x17)
+               data->read_tempreg = read_tempreg_nb_f17;
+       else
+               data->read_tempreg = read_tempreg_pci;
+
+       for (i = 0; i < ARRAY_SIZE(tctl_offset_table); i++) {
+               const struct tctl_offset *entry = &tctl_offset_table[i];
+
+               if (boot_cpu_data.x86 == entry->model &&
+                   strstr(boot_cpu_data.x86_model_id, entry->id)) {
+                       data->temp_offset = entry->offset;
+                       break;
+               }
+       }
+
+       hwmon_dev = devm_hwmon_device_register_with_groups(dev, "k10temp", data,
                                                           k10temp_groups);
        return PTR_ERR_OR_ZERO(hwmon_dev);
 }
@@ -214,6 +287,7 @@ static const struct pci_device_id k10temp_id_table[] = {
        { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F3) },
        { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
        { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
+       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
        {}
 };
 MODULE_DEVICE_TABLE(pci, k10temp_id_table);
index a182789384948d2f08f6c11aee20b9fac7f8b20d..76d966932941dccdc96abd54a32d07750d4760eb 100644 (file)
@@ -303,10 +303,20 @@ static const struct i2c_device_id max1619_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, max1619_id);
 
+#ifdef CONFIG_OF
+static const struct of_device_id max1619_of_match[] = {
+       { .compatible = "maxim,max1619", },
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, max1619_of_match);
+#endif
+
 static struct i2c_driver max1619_driver = {
        .class          = I2C_CLASS_HWMON,
        .driver = {
                .name   = "max1619",
+               .of_match_table = of_match_ptr(max1619_of_match),
        },
        .probe          = max1619_probe,
        .id_table       = max1619_id,
diff --git a/drivers/hwmon/max6621.c b/drivers/hwmon/max6621.c
new file mode 100644 (file)
index 0000000..35555f0
--- /dev/null
@@ -0,0 +1,593 @@
+/*
+ * Hardware monitoring driver for Maxim MAX6621
+ *
+ * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2017 Vadim Pasternak <vadimp@mellanox.com>
+ *
+ * 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/bitops.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+
+#define MAX6621_DRV_NAME               "max6621"
+#define MAX6621_TEMP_INPUT_REG_NUM     9
+#define MAX6621_TEMP_INPUT_MIN         -127000
+#define MAX6621_TEMP_INPUT_MAX         128000
+#define MAX6621_TEMP_ALERT_CHAN_SHIFT  1
+
+#define MAX6621_TEMP_S0D0_REG          0x00
+#define MAX6621_TEMP_S0D1_REG          0x01
+#define MAX6621_TEMP_S1D0_REG          0x02
+#define MAX6621_TEMP_S1D1_REG          0x03
+#define MAX6621_TEMP_S2D0_REG          0x04
+#define MAX6621_TEMP_S2D1_REG          0x05
+#define MAX6621_TEMP_S3D0_REG          0x06
+#define MAX6621_TEMP_S3D1_REG          0x07
+#define MAX6621_TEMP_MAX_REG           0x08
+#define MAX6621_TEMP_MAX_ADDR_REG      0x0a
+#define MAX6621_TEMP_ALERT_CAUSE_REG   0x0b
+#define MAX6621_CONFIG0_REG            0x0c
+#define MAX6621_CONFIG1_REG            0x0d
+#define MAX6621_CONFIG2_REG            0x0e
+#define MAX6621_CONFIG3_REG            0x0f
+#define MAX6621_TEMP_S0_ALERT_REG      0x10
+#define MAX6621_TEMP_S1_ALERT_REG      0x11
+#define MAX6621_TEMP_S2_ALERT_REG      0x12
+#define MAX6621_TEMP_S3_ALERT_REG      0x13
+#define MAX6621_CLEAR_ALERT_REG                0x15
+#define MAX6621_REG_MAX                        (MAX6621_CLEAR_ALERT_REG + 1)
+#define MAX6621_REG_TEMP_SHIFT         0x06
+
+#define MAX6621_ENABLE_TEMP_ALERTS_BIT 4
+#define MAX6621_ENABLE_I2C_CRC_BIT     5
+#define MAX6621_ENABLE_ALTERNATE_DATA  6
+#define MAX6621_ENABLE_LOCKUP_TO       7
+#define MAX6621_ENABLE_S0D0_BIT                8
+#define MAX6621_ENABLE_S3D1_BIT                15
+#define MAX6621_ENABLE_TEMP_ALL                GENMASK(MAX6621_ENABLE_S3D1_BIT, \
+                                               MAX6621_ENABLE_S0D0_BIT)
+#define MAX6621_POLL_DELAY_MASK                0x5
+#define MAX6621_CONFIG0_INIT           (MAX6621_ENABLE_TEMP_ALL | \
+                                        BIT(MAX6621_ENABLE_LOCKUP_TO) | \
+                                        BIT(MAX6621_ENABLE_I2C_CRC_BIT) | \
+                                        MAX6621_POLL_DELAY_MASK)
+#define MAX6621_PECI_BIT_TIME          0x2
+#define MAX6621_PECI_RETRY_NUM         0x3
+#define MAX6621_CONFIG1_INIT           ((MAX6621_PECI_BIT_TIME << 8) | \
+                                        MAX6621_PECI_RETRY_NUM)
+
+/* Error codes */
+#define MAX6621_TRAN_FAILED    0x8100  /*
+                                        * PECI transaction failed for more
+                                        * than the configured number of
+                                        * consecutive retries.
+                                        */
+#define MAX6621_POOL_DIS       0x8101  /*
+                                        * Polling disabled for requested
+                                        * socket/domain.
+                                        */
+#define MAX6621_POOL_UNCOMPLETE        0x8102  /*
+                                        * First poll not yet completed for
+                                        * requested socket/domain (on
+                                        * startup).
+                                        */
+#define MAX6621_SD_DIS         0x8103  /*
+                                        * Read maximum temperature requested,
+                                        * but no sockets/domains enabled or
+                                        * all enabled sockets/domains have
+                                        * errors; or read maximum temperature
+                                        * address requested, but read maximum
+                                        * temperature was not called.
+                                        */
+#define MAX6621_ALERT_DIS      0x8104  /*
+                                        * Get alert socket/domain requested,
+                                        * but no alert active.
+                                        */
+#define MAX6621_PECI_ERR_MIN   0x8000  /* Intel spec PECI error min value. */
+#define MAX6621_PECI_ERR_MAX   0x80ff  /* Intel spec PECI error max value. */
+
+static const u32 max6621_temp_regs[] = {
+       MAX6621_TEMP_MAX_REG, MAX6621_TEMP_S0D0_REG, MAX6621_TEMP_S1D0_REG,
+       MAX6621_TEMP_S2D0_REG, MAX6621_TEMP_S3D0_REG, MAX6621_TEMP_S0D1_REG,
+       MAX6621_TEMP_S1D1_REG, MAX6621_TEMP_S2D1_REG, MAX6621_TEMP_S3D1_REG,
+};
+
+static const char *const max6621_temp_labels[] = {
+       "maximum",
+       "socket0_0",
+       "socket1_0",
+       "socket2_0",
+       "socket3_0",
+       "socket0_1",
+       "socket1_1",
+       "socket2_1",
+       "socket3_1",
+};
+
+static const int max6621_temp_alert_chan2reg[] = {
+       MAX6621_TEMP_S0_ALERT_REG,
+       MAX6621_TEMP_S1_ALERT_REG,
+       MAX6621_TEMP_S2_ALERT_REG,
+       MAX6621_TEMP_S3_ALERT_REG,
+};
+
+/**
+ * struct max6621_data - private data:
+ *
+ * @client: I2C client;
+ * @regmap: register map handle;
+ * @input_chan2reg: mapping from channel to register;
+ */
+struct max6621_data {
+       struct i2c_client       *client;
+       struct regmap           *regmap;
+       int                     input_chan2reg[MAX6621_TEMP_INPUT_REG_NUM + 1];
+};
+
+static long max6621_temp_mc2reg(long val)
+{
+       return (val / 1000L) << MAX6621_REG_TEMP_SHIFT;
+}
+
+static umode_t
+max6621_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
+                  int channel)
+{
+       /* Skip channels which are not physically conncted. */
+       if (((struct max6621_data *)data)->input_chan2reg[channel] < 0)
+               return 0;
+
+       switch (type) {
+       case hwmon_temp:
+               switch (attr) {
+               case hwmon_temp_input:
+               case hwmon_temp_label:
+               case hwmon_temp_crit_alarm:
+                       return 0444;
+               case hwmon_temp_offset:
+               case hwmon_temp_crit:
+                       return 0644;
+               default:
+                       break;
+               }
+
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+static int max6621_verify_reg_data(struct device *dev, int regval)
+{
+       if (regval >= MAX6621_PECI_ERR_MIN &&
+           regval <= MAX6621_PECI_ERR_MAX) {
+               dev_dbg(dev, "PECI error code - err 0x%04x.\n",
+                       regval);
+
+               return -EIO;
+       }
+
+       switch (regval) {
+       case MAX6621_TRAN_FAILED:
+               dev_dbg(dev, "PECI transaction failed - err 0x%04x.\n",
+                       regval);
+               return -EIO;
+       case MAX6621_POOL_DIS:
+               dev_dbg(dev, "Polling disabled - err 0x%04x.\n", regval);
+               return -EOPNOTSUPP;
+       case MAX6621_POOL_UNCOMPLETE:
+               dev_dbg(dev, "First poll not completed on startup - err 0x%04x.\n",
+                       regval);
+               return -EIO;
+       case MAX6621_SD_DIS:
+               dev_dbg(dev, "Resource is disabled - err 0x%04x.\n", regval);
+               return -EOPNOTSUPP;
+       case MAX6621_ALERT_DIS:
+               dev_dbg(dev, "No alert active - err 0x%04x.\n", regval);
+               return -EOPNOTSUPP;
+       default:
+               return 0;
+       }
+}
+
+static int
+max6621_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
+            int channel, long *val)
+{
+       struct max6621_data *data = dev_get_drvdata(dev);
+       u32 regval;
+       int reg;
+       s8 temp;
+       int ret;
+
+       switch (type) {
+       case hwmon_temp:
+               switch (attr) {
+               case hwmon_temp_input:
+                       reg = data->input_chan2reg[channel];
+                       ret = regmap_read(data->regmap, reg, &regval);
+                       if (ret)
+                               return ret;
+
+                       ret = max6621_verify_reg_data(dev, regval);
+                       if (ret)
+                               return ret;
+
+                       /*
+                        * Bit MAX6621_REG_TEMP_SHIFT represents 1 degree step.
+                        * The temperature is given in two's complement and 8
+                        * bits is used for the register conversion.
+                        */
+                       temp = (regval >> MAX6621_REG_TEMP_SHIFT);
+                       *val = temp * 1000L;
+
+                       break;
+               case hwmon_temp_offset:
+                       ret = regmap_read(data->regmap, MAX6621_CONFIG2_REG,
+                                         &regval);
+                       if (ret)
+                               return ret;
+
+                       ret = max6621_verify_reg_data(dev, regval);
+                       if (ret)
+                               return ret;
+
+                       *val = (regval >> MAX6621_REG_TEMP_SHIFT) *
+                              1000L;
+
+                       break;
+               case hwmon_temp_crit:
+                       channel -= MAX6621_TEMP_ALERT_CHAN_SHIFT;
+                       reg = max6621_temp_alert_chan2reg[channel];
+                       ret = regmap_read(data->regmap, reg, &regval);
+                       if (ret)
+                               return ret;
+
+                       ret = max6621_verify_reg_data(dev, regval);
+                       if (ret)
+                               return ret;
+
+                       *val = regval * 1000L;
+
+                       break;
+               case hwmon_temp_crit_alarm:
+                       /*
+                        * Set val to zero to recover the case, when reading
+                        * MAX6621_TEMP_ALERT_CAUSE_REG results in for example
+                        * MAX6621_ALERT_DIS. Reading will return with error,
+                        * but in such case alarm should be returned as 0.
+                        */
+                       *val = 0;
+                       ret = regmap_read(data->regmap,
+                                         MAX6621_TEMP_ALERT_CAUSE_REG,
+                                         &regval);
+                       if (ret)
+                               return ret;
+
+                       ret = max6621_verify_reg_data(dev, regval);
+                       if (ret) {
+                               /* Do not report error if alert is disabled. */
+                               if (regval == MAX6621_ALERT_DIS)
+                                       return 0;
+                               else
+                                       return ret;
+                       }
+
+                       /*
+                        * Clear the alert automatically, using send-byte
+                        * smbus protocol for clearing alert.
+                        */
+                       if (regval) {
+                               ret = i2c_smbus_write_byte(data->client,
+                                               MAX6621_CLEAR_ALERT_REG);
+                               if (ret)
+                                       return ret;
+                       }
+
+                       *val = !!regval;
+
+                       break;
+               default:
+                       return -EOPNOTSUPP;
+               }
+               break;
+
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       return 0;
+}
+
+static int
+max6621_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
+             int channel, long val)
+{
+       struct max6621_data *data = dev_get_drvdata(dev);
+       u32 reg;
+
+       switch (type) {
+       case hwmon_temp:
+               switch (attr) {
+               case hwmon_temp_offset:
+                       /* Clamp to allowed range to prevent overflow. */
+                       val = clamp_val(val, MAX6621_TEMP_INPUT_MIN,
+                                       MAX6621_TEMP_INPUT_MAX);
+                       val = max6621_temp_mc2reg(val);
+
+                       return regmap_write(data->regmap,
+                                           MAX6621_CONFIG2_REG, val);
+               case hwmon_temp_crit:
+                       channel -= MAX6621_TEMP_ALERT_CHAN_SHIFT;
+                       reg = max6621_temp_alert_chan2reg[channel];
+                       /* Clamp to allowed range to prevent overflow. */
+                       val = clamp_val(val, MAX6621_TEMP_INPUT_MIN,
+                                       MAX6621_TEMP_INPUT_MAX);
+                       val = val / 1000L;
+
+                       return regmap_write(data->regmap, reg, val);
+               default:
+                       return -EOPNOTSUPP;
+               }
+               break;
+
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       return -EOPNOTSUPP;
+}
+
+static int
+max6621_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
+                   int channel, const char **str)
+{
+       switch (type) {
+       case hwmon_temp:
+               switch (attr) {
+               case hwmon_temp_label:
+                       *str = max6621_temp_labels[channel];
+                       return 0;
+               default:
+                       return -EOPNOTSUPP;
+               }
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       return -EOPNOTSUPP;
+}
+
+static bool max6621_writeable_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case MAX6621_CONFIG0_REG:
+       case MAX6621_CONFIG1_REG:
+       case MAX6621_CONFIG2_REG:
+       case MAX6621_CONFIG3_REG:
+       case MAX6621_TEMP_S0_ALERT_REG:
+       case MAX6621_TEMP_S1_ALERT_REG:
+       case MAX6621_TEMP_S2_ALERT_REG:
+       case MAX6621_TEMP_S3_ALERT_REG:
+       case MAX6621_TEMP_ALERT_CAUSE_REG:
+               return true;
+       }
+       return false;
+}
+
+static bool max6621_readable_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case MAX6621_TEMP_S0D0_REG:
+       case MAX6621_TEMP_S0D1_REG:
+       case MAX6621_TEMP_S1D0_REG:
+       case MAX6621_TEMP_S1D1_REG:
+       case MAX6621_TEMP_S2D0_REG:
+       case MAX6621_TEMP_S2D1_REG:
+       case MAX6621_TEMP_S3D0_REG:
+       case MAX6621_TEMP_S3D1_REG:
+       case MAX6621_TEMP_MAX_REG:
+       case MAX6621_TEMP_MAX_ADDR_REG:
+       case MAX6621_CONFIG0_REG:
+       case MAX6621_CONFIG1_REG:
+       case MAX6621_CONFIG2_REG:
+       case MAX6621_CONFIG3_REG:
+       case MAX6621_TEMP_S0_ALERT_REG:
+       case MAX6621_TEMP_S1_ALERT_REG:
+       case MAX6621_TEMP_S2_ALERT_REG:
+       case MAX6621_TEMP_S3_ALERT_REG:
+               return true;
+       }
+       return false;
+}
+
+static bool max6621_volatile_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case MAX6621_TEMP_S0D0_REG:
+       case MAX6621_TEMP_S0D1_REG:
+       case MAX6621_TEMP_S1D0_REG:
+       case MAX6621_TEMP_S1D1_REG:
+       case MAX6621_TEMP_S2D0_REG:
+       case MAX6621_TEMP_S2D1_REG:
+       case MAX6621_TEMP_S3D0_REG:
+       case MAX6621_TEMP_S3D1_REG:
+       case MAX6621_TEMP_MAX_REG:
+       case MAX6621_TEMP_S0_ALERT_REG:
+       case MAX6621_TEMP_S1_ALERT_REG:
+       case MAX6621_TEMP_S2_ALERT_REG:
+       case MAX6621_TEMP_S3_ALERT_REG:
+       case MAX6621_TEMP_ALERT_CAUSE_REG:
+               return true;
+       }
+       return false;
+}
+
+static const struct reg_default max6621_regmap_default[] = {
+       { MAX6621_CONFIG0_REG, MAX6621_CONFIG0_INIT },
+       { MAX6621_CONFIG1_REG, MAX6621_CONFIG1_INIT },
+};
+
+static const struct regmap_config max6621_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 16,
+       .max_register = MAX6621_REG_MAX,
+       .val_format_endian = REGMAP_ENDIAN_LITTLE,
+       .cache_type = REGCACHE_FLAT,
+       .writeable_reg = max6621_writeable_reg,
+       .readable_reg = max6621_readable_reg,
+       .volatile_reg = max6621_volatile_reg,
+       .reg_defaults = max6621_regmap_default,
+       .num_reg_defaults = ARRAY_SIZE(max6621_regmap_default),
+};
+
+static u32 max6621_chip_config[] = {
+       HWMON_C_REGISTER_TZ,
+       0
+};
+
+static const struct hwmon_channel_info max6621_chip = {
+       .type = hwmon_chip,
+       .config = max6621_chip_config,
+};
+
+static const u32 max6621_temp_config[] = {
+       HWMON_T_INPUT | HWMON_T_LABEL | HWMON_T_OFFSET,
+       HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_LABEL,
+       HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_LABEL,
+       HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_LABEL,
+       HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_LABEL,
+       HWMON_T_INPUT | HWMON_T_LABEL,
+       HWMON_T_INPUT | HWMON_T_LABEL,
+       HWMON_T_INPUT | HWMON_T_LABEL,
+       HWMON_T_INPUT | HWMON_T_LABEL,
+       0
+};
+
+static const struct hwmon_channel_info max6621_temp = {
+       .type = hwmon_temp,
+       .config = max6621_temp_config,
+};
+
+static const struct hwmon_channel_info *max6621_info[] = {
+       &max6621_chip,
+       &max6621_temp,
+       NULL
+};
+
+static const struct hwmon_ops max6621_hwmon_ops = {
+       .read = max6621_read,
+       .write = max6621_write,
+       .read_string = max6621_read_string,
+       .is_visible = max6621_is_visible,
+};
+
+static const struct hwmon_chip_info max6621_chip_info = {
+       .ops = &max6621_hwmon_ops,
+       .info = max6621_info,
+};
+
+static int max6621_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
+{
+       struct device *dev = &client->dev;
+       struct max6621_data *data;
+       struct device *hwmon_dev;
+       int i;
+       int ret;
+
+       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       data->regmap = devm_regmap_init_i2c(client, &max6621_regmap_config);
+       if (IS_ERR(data->regmap))
+               return PTR_ERR(data->regmap);
+
+       i2c_set_clientdata(client, data);
+       data->client = client;
+
+       /* Set CONFIG0 register masking temperature alerts and PEC. */
+       ret = regmap_write(data->regmap, MAX6621_CONFIG0_REG,
+                          MAX6621_CONFIG0_INIT);
+       if (ret)
+               return ret;
+
+       /* Set CONFIG1 register for PEC access retry number. */
+       ret = regmap_write(data->regmap, MAX6621_CONFIG1_REG,
+                          MAX6621_CONFIG1_INIT);
+       if (ret)
+               return ret;
+
+       /* Sync registers with hardware. */
+       regcache_mark_dirty(data->regmap);
+       ret = regcache_sync(data->regmap);
+       if (ret)
+               return ret;
+
+       /* Verify which temperature input registers are enabled. */
+       for (i = 0; i < MAX6621_TEMP_INPUT_REG_NUM; i++) {
+               ret = i2c_smbus_read_word_data(client, max6621_temp_regs[i]);
+               if (ret < 0)
+                       return ret;
+               ret = max6621_verify_reg_data(dev, ret);
+               if (ret) {
+                       data->input_chan2reg[i] = -1;
+                       continue;
+               }
+
+               data->input_chan2reg[i] = max6621_temp_regs[i];
+       }
+
+       hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
+                                                        data,
+                                                        &max6621_chip_info,
+                                                        NULL);
+
+       return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static const struct i2c_device_id max6621_id[] = {
+       { MAX6621_DRV_NAME, 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, max6621_id);
+
+static const struct of_device_id max6621_of_match[] = {
+       { .compatible = "maxim,max6621" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, max6621_of_match);
+
+static struct i2c_driver max6621_driver = {
+       .class          = I2C_CLASS_HWMON,
+       .driver = {
+               .name = MAX6621_DRV_NAME,
+               .of_match_table = of_match_ptr(max6621_of_match),
+       },
+       .probe          = max6621_probe,
+       .id_table       = max6621_id,
+};
+
+module_i2c_driver(max6621_driver);
+
+MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
+MODULE_DESCRIPTION("Driver for Maxim MAX6621");
+MODULE_LICENSE("GPL");
index 40019325b517f413bf3fae5bf9561ebfb993bfd5..08479006c7f9e9f65e6deaebb6031e5e9e5d3ef5 100644 (file)
@@ -114,6 +114,16 @@ config SENSORS_MAX20751
          This driver can also be built as a module. If so, the module will
          be called max20751.
 
+config SENSORS_MAX31785
+       tristate "Maxim MAX31785 and compatibles"
+       default n
+       help
+         If you say yes here you get hardware monitoring support for Maxim
+         MAX31785.
+
+         This driver can also be built as a module. If so, the module will
+         be called max31785.
+
 config SENSORS_MAX34440
        tristate "Maxim MAX34440 and compatibles"
        default n
index e9364420a5123d9bfe4f0ae9b3b1fe8548acaa29..ea0e39518c2168a3c1e0150a8f7482c12f3c78e7 100644 (file)
@@ -13,6 +13,7 @@ obj-$(CONFIG_SENSORS_LTC2978) += ltc2978.o
 obj-$(CONFIG_SENSORS_LTC3815)  += ltc3815.o
 obj-$(CONFIG_SENSORS_MAX16064) += max16064.o
 obj-$(CONFIG_SENSORS_MAX20751) += max20751.o
+obj-$(CONFIG_SENSORS_MAX31785) += max31785.o
 obj-$(CONFIG_SENSORS_MAX34440) += max34440.o
 obj-$(CONFIG_SENSORS_MAX8688)  += max8688.o
 obj-$(CONFIG_SENSORS_TPS40422) += tps40422.o
diff --git a/drivers/hwmon/pmbus/max31785.c b/drivers/hwmon/pmbus/max31785.c
new file mode 100644 (file)
index 0000000..9313849
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include "pmbus.h"
+
+enum max31785_regs {
+       MFR_REVISION            = 0x9b,
+};
+
+#define MAX31785_NR_PAGES              23
+
+#define MAX31785_FAN_FUNCS \
+       (PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12)
+
+#define MAX31785_TEMP_FUNCS \
+       (PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP)
+
+#define MAX31785_VOUT_FUNCS \
+       (PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT)
+
+static const struct pmbus_driver_info max31785_info = {
+       .pages = MAX31785_NR_PAGES,
+
+       /* RPM */
+       .format[PSC_FAN] = direct,
+       .m[PSC_FAN] = 1,
+       .b[PSC_FAN] = 0,
+       .R[PSC_FAN] = 0,
+       .func[0] = MAX31785_FAN_FUNCS,
+       .func[1] = MAX31785_FAN_FUNCS,
+       .func[2] = MAX31785_FAN_FUNCS,
+       .func[3] = MAX31785_FAN_FUNCS,
+       .func[4] = MAX31785_FAN_FUNCS,
+       .func[5] = MAX31785_FAN_FUNCS,
+
+       .format[PSC_TEMPERATURE] = direct,
+       .m[PSC_TEMPERATURE] = 1,
+       .b[PSC_TEMPERATURE] = 0,
+       .R[PSC_TEMPERATURE] = 2,
+       .func[6]  = MAX31785_TEMP_FUNCS,
+       .func[7]  = MAX31785_TEMP_FUNCS,
+       .func[8]  = MAX31785_TEMP_FUNCS,
+       .func[9]  = MAX31785_TEMP_FUNCS,
+       .func[10] = MAX31785_TEMP_FUNCS,
+       .func[11] = MAX31785_TEMP_FUNCS,
+       .func[12] = MAX31785_TEMP_FUNCS,
+       .func[13] = MAX31785_TEMP_FUNCS,
+       .func[14] = MAX31785_TEMP_FUNCS,
+       .func[15] = MAX31785_TEMP_FUNCS,
+       .func[16] = MAX31785_TEMP_FUNCS,
+
+       .format[PSC_VOLTAGE_OUT] = direct,
+       .m[PSC_VOLTAGE_OUT] = 1,
+       .b[PSC_VOLTAGE_OUT] = 0,
+       .R[PSC_VOLTAGE_OUT] = 0,
+       .func[17] = MAX31785_VOUT_FUNCS,
+       .func[18] = MAX31785_VOUT_FUNCS,
+       .func[19] = MAX31785_VOUT_FUNCS,
+       .func[20] = MAX31785_VOUT_FUNCS,
+       .func[21] = MAX31785_VOUT_FUNCS,
+       .func[22] = MAX31785_VOUT_FUNCS,
+};
+
+static int max31785_probe(struct i2c_client *client,
+                         const struct i2c_device_id *id)
+{
+       struct device *dev = &client->dev;
+       struct pmbus_driver_info *info;
+       s64 ret;
+
+       info = devm_kzalloc(dev, sizeof(struct pmbus_driver_info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       *info = max31785_info;
+
+       ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 255);
+       if (ret < 0)
+               return ret;
+
+       return pmbus_do_probe(client, id, info);
+}
+
+static const struct i2c_device_id max31785_id[] = {
+       { "max31785", 0 },
+       { "max31785a", 0 },
+       { },
+};
+
+MODULE_DEVICE_TABLE(i2c, max31785_id);
+
+static struct i2c_driver max31785_driver = {
+       .driver = {
+               .name = "max31785",
+       },
+       .probe = max31785_probe,
+       .remove = pmbus_do_remove,
+       .id_table = max31785_id,
+};
+
+module_i2c_driver(max31785_driver);
+
+MODULE_AUTHOR("Andrew Jeffery <andrew@aj.id.au>");
+MODULE_DESCRIPTION("PMBus driver for the Maxim MAX31785");
+MODULE_LICENSE("GPL");
index 4efa2bd4f6d8aaa485367c0ff23d57a8d46678b3..fa613bd209e344d90349fc316c7e9db64088d991 100644 (file)
@@ -404,9 +404,9 @@ extern const struct regulator_ops pmbus_regulator_ops;
 /* Function declarations */
 
 void pmbus_clear_cache(struct i2c_client *client);
-int pmbus_set_page(struct i2c_client *client, u8 page);
-int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg);
-int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word);
+int pmbus_set_page(struct i2c_client *client, int page);
+int pmbus_read_word_data(struct i2c_client *client, int page, u8 reg);
+int pmbus_write_word_data(struct i2c_client *client, int page, u8 reg, u16 word);
 int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg);
 int pmbus_write_byte(struct i2c_client *client, int page, u8 value);
 int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg,
index 302f0aef59dede142a4c9618b17de9db6768a168..52a58b8b6e1bd002f6b91b17e1c06cda94a1069b 100644 (file)
@@ -136,13 +136,13 @@ void pmbus_clear_cache(struct i2c_client *client)
 }
 EXPORT_SYMBOL_GPL(pmbus_clear_cache);
 
-int pmbus_set_page(struct i2c_client *client, u8 page)
+int pmbus_set_page(struct i2c_client *client, int page)
 {
        struct pmbus_data *data = i2c_get_clientdata(client);
        int rv = 0;
        int newpage;
 
-       if (page != data->currpage) {
+       if (page >= 0 && page != data->currpage) {
                rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
                newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE);
                if (newpage != page)
@@ -158,11 +158,9 @@ int pmbus_write_byte(struct i2c_client *client, int page, u8 value)
 {
        int rv;
 
-       if (page >= 0) {
-               rv = pmbus_set_page(client, page);
-               if (rv < 0)
-                       return rv;
-       }
+       rv = pmbus_set_page(client, page);
+       if (rv < 0)
+               return rv;
 
        return i2c_smbus_write_byte(client, value);
 }
@@ -186,7 +184,8 @@ static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value)
        return pmbus_write_byte(client, page, value);
 }
 
-int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word)
+int pmbus_write_word_data(struct i2c_client *client, int page, u8 reg,
+                         u16 word)
 {
        int rv;
 
@@ -219,7 +218,7 @@ static int _pmbus_write_word_data(struct i2c_client *client, int page, int reg,
        return pmbus_write_word_data(client, page, reg, word);
 }
 
-int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg)
+int pmbus_read_word_data(struct i2c_client *client, int page, u8 reg)
 {
        int rv;
 
@@ -255,11 +254,9 @@ int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg)
 {
        int rv;
 
-       if (page >= 0) {
-               rv = pmbus_set_page(client, page);
-               if (rv < 0)
-                       return rv;
-       }
+       rv = pmbus_set_page(client, page);
+       if (rv < 0)
+               return rv;
 
        return i2c_smbus_read_byte_data(client, reg);
 }
index e4d642b673c6d9e5dfebb7bc23360f4d8f46fb3e..25d28343ba936f42c3de33272f6d8bef20dda2ac 100644 (file)
 
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/mutex.h>
-#include <linux/platform_data/sht15.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
@@ -34,7 +32,8 @@
 #include <linux/slab.h>
 #include <linux/atomic.h>
 #include <linux/bitrev.h>
-#include <linux/of_gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of.h>
 
 /* Commands */
 #define SHT15_MEASURE_TEMP             0x03
@@ -122,7 +121,8 @@ static const u8 sht15_crc8_table[] = {
 
 /**
  * struct sht15_data - device instance specific data
- * @pdata:             platform data (gpio's etc).
+ * @sck:               clock GPIO line
+ * @data:              data GPIO line
  * @read_work:         bh of interrupt handler.
  * @wait_queue:                wait queue for getting values from device.
  * @val_temp:          last temperature value read from device.
@@ -150,7 +150,8 @@ static const u8 sht15_crc8_table[] = {
  * @interrupt_handled: flag used to indicate a handler has been scheduled.
  */
 struct sht15_data {
-       struct sht15_platform_data      *pdata;
+       struct gpio_desc                *sck;
+       struct gpio_desc                *data;
        struct work_struct              read_work;
        wait_queue_head_t               wait_queue;
        uint16_t                        val_temp;
@@ -205,16 +206,16 @@ static int sht15_connection_reset(struct sht15_data *data)
 {
        int i, err;
 
-       err = gpio_direction_output(data->pdata->gpio_data, 1);
+       err = gpiod_direction_output(data->data, 1);
        if (err)
                return err;
        ndelay(SHT15_TSCKL);
-       gpio_set_value(data->pdata->gpio_sck, 0);
+       gpiod_set_value(data->sck, 0);
        ndelay(SHT15_TSCKL);
        for (i = 0; i < 9; ++i) {
-               gpio_set_value(data->pdata->gpio_sck, 1);
+               gpiod_set_value(data->sck, 1);
                ndelay(SHT15_TSCKH);
-               gpio_set_value(data->pdata->gpio_sck, 0);
+               gpiod_set_value(data->sck, 0);
                ndelay(SHT15_TSCKL);
        }
        return 0;
@@ -227,11 +228,11 @@ static int sht15_connection_reset(struct sht15_data *data)
  */
 static inline void sht15_send_bit(struct sht15_data *data, int val)
 {
-       gpio_set_value(data->pdata->gpio_data, val);
+       gpiod_set_value(data->data, val);
        ndelay(SHT15_TSU);
-       gpio_set_value(data->pdata->gpio_sck, 1);
+       gpiod_set_value(data->sck, 1);
        ndelay(SHT15_TSCKH);
-       gpio_set_value(data->pdata->gpio_sck, 0);
+       gpiod_set_value(data->sck, 0);
        ndelay(SHT15_TSCKL); /* clock low time */
 }
 
@@ -248,23 +249,23 @@ static int sht15_transmission_start(struct sht15_data *data)
        int err;
 
        /* ensure data is high and output */
-       err = gpio_direction_output(data->pdata->gpio_data, 1);
+       err = gpiod_direction_output(data->data, 1);
        if (err)
                return err;
        ndelay(SHT15_TSU);
-       gpio_set_value(data->pdata->gpio_sck, 0);
+       gpiod_set_value(data->sck, 0);
        ndelay(SHT15_TSCKL);
-       gpio_set_value(data->pdata->gpio_sck, 1);
+       gpiod_set_value(data->sck, 1);
        ndelay(SHT15_TSCKH);
-       gpio_set_value(data->pdata->gpio_data, 0);
+       gpiod_set_value(data->data, 0);
        ndelay(SHT15_TSU);
-       gpio_set_value(data->pdata->gpio_sck, 0);
+       gpiod_set_value(data->sck, 0);
        ndelay(SHT15_TSCKL);
-       gpio_set_value(data->pdata->gpio_sck, 1);
+       gpiod_set_value(data->sck, 1);
        ndelay(SHT15_TSCKH);
-       gpio_set_value(data->pdata->gpio_data, 1);
+       gpiod_set_value(data->data, 1);
        ndelay(SHT15_TSU);
-       gpio_set_value(data->pdata->gpio_sck, 0);
+       gpiod_set_value(data->sck, 0);
        ndelay(SHT15_TSCKL);
        return 0;
 }
@@ -292,20 +293,20 @@ static int sht15_wait_for_response(struct sht15_data *data)
 {
        int err;
 
-       err = gpio_direction_input(data->pdata->gpio_data);
+       err = gpiod_direction_input(data->data);
        if (err)
                return err;
-       gpio_set_value(data->pdata->gpio_sck, 1);
+       gpiod_set_value(data->sck, 1);
        ndelay(SHT15_TSCKH);
-       if (gpio_get_value(data->pdata->gpio_data)) {
-               gpio_set_value(data->pdata->gpio_sck, 0);
+       if (gpiod_get_value(data->data)) {
+               gpiod_set_value(data->sck, 0);
                dev_err(data->dev, "Command not acknowledged\n");
                err = sht15_connection_reset(data);
                if (err)
                        return err;
                return -EIO;
        }
-       gpio_set_value(data->pdata->gpio_sck, 0);
+       gpiod_set_value(data->sck, 0);
        ndelay(SHT15_TSCKL);
        return 0;
 }
@@ -360,17 +361,17 @@ static int sht15_ack(struct sht15_data *data)
 {
        int err;
 
-       err = gpio_direction_output(data->pdata->gpio_data, 0);
+       err = gpiod_direction_output(data->data, 0);
        if (err)
                return err;
        ndelay(SHT15_TSU);
-       gpio_set_value(data->pdata->gpio_sck, 1);
+       gpiod_set_value(data->sck, 1);
        ndelay(SHT15_TSU);
-       gpio_set_value(data->pdata->gpio_sck, 0);
+       gpiod_set_value(data->sck, 0);
        ndelay(SHT15_TSU);
-       gpio_set_value(data->pdata->gpio_data, 1);
+       gpiod_set_value(data->data, 1);
 
-       return gpio_direction_input(data->pdata->gpio_data);
+       return gpiod_direction_input(data->data);
 }
 
 /**
@@ -383,13 +384,13 @@ static int sht15_end_transmission(struct sht15_data *data)
 {
        int err;
 
-       err = gpio_direction_output(data->pdata->gpio_data, 1);
+       err = gpiod_direction_output(data->data, 1);
        if (err)
                return err;
        ndelay(SHT15_TSU);
-       gpio_set_value(data->pdata->gpio_sck, 1);
+       gpiod_set_value(data->sck, 1);
        ndelay(SHT15_TSCKH);
-       gpio_set_value(data->pdata->gpio_sck, 0);
+       gpiod_set_value(data->sck, 0);
        ndelay(SHT15_TSCKL);
        return 0;
 }
@@ -405,10 +406,10 @@ static u8 sht15_read_byte(struct sht15_data *data)
 
        for (i = 0; i < 8; ++i) {
                byte <<= 1;
-               gpio_set_value(data->pdata->gpio_sck, 1);
+               gpiod_set_value(data->sck, 1);
                ndelay(SHT15_TSCKH);
-               byte |= !!gpio_get_value(data->pdata->gpio_data);
-               gpio_set_value(data->pdata->gpio_sck, 0);
+               byte |= !!gpiod_get_value(data->data);
+               gpiod_set_value(data->sck, 0);
                ndelay(SHT15_TSCKL);
        }
        return byte;
@@ -428,7 +429,7 @@ static int sht15_send_status(struct sht15_data *data, u8 status)
        err = sht15_send_cmd(data, SHT15_WRITE_STATUS);
        if (err)
                return err;
-       err = gpio_direction_output(data->pdata->gpio_data, 1);
+       err = gpiod_direction_output(data->data, 1);
        if (err)
                return err;
        ndelay(SHT15_TSU);
@@ -528,14 +529,14 @@ static int sht15_measurement(struct sht15_data *data,
        if (ret)
                return ret;
 
-       ret = gpio_direction_input(data->pdata->gpio_data);
+       ret = gpiod_direction_input(data->data);
        if (ret)
                return ret;
        atomic_set(&data->interrupt_handled, 0);
 
-       enable_irq(gpio_to_irq(data->pdata->gpio_data));
-       if (gpio_get_value(data->pdata->gpio_data) == 0) {
-               disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
+       enable_irq(gpiod_to_irq(data->data));
+       if (gpiod_get_value(data->data) == 0) {
+               disable_irq_nosync(gpiod_to_irq(data->data));
                /* Only relevant if the interrupt hasn't occurred. */
                if (!atomic_read(&data->interrupt_handled))
                        schedule_work(&data->read_work);
@@ -547,7 +548,7 @@ static int sht15_measurement(struct sht15_data *data,
                data->state = SHT15_READING_NOTHING;
                return -EIO;
        } else if (ret == 0) { /* timeout occurred */
-               disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
+               disable_irq_nosync(gpiod_to_irq(data->data));
                ret = sht15_connection_reset(data);
                if (ret)
                        return ret;
@@ -826,15 +827,15 @@ static void sht15_bh_read_data(struct work_struct *work_s)
                               read_work);
 
        /* Firstly, verify the line is low */
-       if (gpio_get_value(data->pdata->gpio_data)) {
+       if (gpiod_get_value(data->data)) {
                /*
                 * If not, then start the interrupt again - care here as could
                 * have gone low in meantime so verify it hasn't!
                 */
                atomic_set(&data->interrupt_handled, 0);
-               enable_irq(gpio_to_irq(data->pdata->gpio_data));
+               enable_irq(gpiod_to_irq(data->data));
                /* If still not occurred or another handler was scheduled */
-               if (gpio_get_value(data->pdata->gpio_data)
+               if (gpiod_get_value(data->data)
                    || atomic_read(&data->interrupt_handled))
                        return;
        }
@@ -918,53 +919,12 @@ static const struct of_device_id sht15_dt_match[] = {
        { },
 };
 MODULE_DEVICE_TABLE(of, sht15_dt_match);
-
-/*
- * This function returns NULL if pdev isn't a device instatiated by dt,
- * a pointer to pdata if it could successfully get all information
- * from dt or a negative ERR_PTR() on error.
- */
-static struct sht15_platform_data *sht15_probe_dt(struct device *dev)
-{
-       struct device_node *np = dev->of_node;
-       struct sht15_platform_data *pdata;
-
-       /* no device tree device */
-       if (!np)
-               return NULL;
-
-       pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
-       if (!pdata)
-               return ERR_PTR(-ENOMEM);
-
-       pdata->gpio_data = of_get_named_gpio(np, "data-gpios", 0);
-       if (pdata->gpio_data < 0) {
-               if (pdata->gpio_data != -EPROBE_DEFER)
-                       dev_err(dev, "data-gpios not found\n");
-               return ERR_PTR(pdata->gpio_data);
-       }
-
-       pdata->gpio_sck = of_get_named_gpio(np, "clk-gpios", 0);
-       if (pdata->gpio_sck < 0) {
-               if (pdata->gpio_sck != -EPROBE_DEFER)
-                       dev_err(dev, "clk-gpios not found\n");
-               return ERR_PTR(pdata->gpio_sck);
-       }
-
-       return pdata;
-}
-#else
-static inline struct sht15_platform_data *sht15_probe_dt(struct device *dev)
-{
-       return NULL;
-}
 #endif
 
 static int sht15_probe(struct platform_device *pdev)
 {
        int ret;
        struct sht15_data *data;
-       u8 status = 0;
 
        data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
        if (!data)
@@ -977,25 +937,6 @@ static int sht15_probe(struct platform_device *pdev)
        data->dev = &pdev->dev;
        init_waitqueue_head(&data->wait_queue);
 
-       data->pdata = sht15_probe_dt(&pdev->dev);
-       if (IS_ERR(data->pdata))
-               return PTR_ERR(data->pdata);
-       if (data->pdata == NULL) {
-               data->pdata = dev_get_platdata(&pdev->dev);
-               if (data->pdata == NULL) {
-                       dev_err(&pdev->dev, "no platform data supplied\n");
-                       return -EINVAL;
-               }
-       }
-
-       data->supply_uv = data->pdata->supply_mv * 1000;
-       if (data->pdata->checksum)
-               data->checksumming = true;
-       if (data->pdata->no_otp_reload)
-               status |= SHT15_STATUS_NO_OTP_RELOAD;
-       if (data->pdata->low_resolution)
-               status |= SHT15_STATUS_LOW_RESOLUTION;
-
        /*
         * If a regulator is available,
         * query what the supply voltage actually is!
@@ -1030,21 +971,20 @@ static int sht15_probe(struct platform_device *pdev)
        }
 
        /* Try requesting the GPIOs */
-       ret = devm_gpio_request_one(&pdev->dev, data->pdata->gpio_sck,
-                       GPIOF_OUT_INIT_LOW, "SHT15 sck");
-       if (ret) {
+       data->sck = devm_gpiod_get(&pdev->dev, "clk", GPIOD_OUT_LOW);
+       if (IS_ERR(data->sck)) {
+               ret = PTR_ERR(data->sck);
                dev_err(&pdev->dev, "clock line GPIO request failed\n");
                goto err_release_reg;
        }
-
-       ret = devm_gpio_request(&pdev->dev, data->pdata->gpio_data,
-                               "SHT15 data");
-       if (ret) {
+       data->data = devm_gpiod_get(&pdev->dev, "data", GPIOD_IN);
+       if (IS_ERR(data->data)) {
+               ret = PTR_ERR(data->data);
                dev_err(&pdev->dev, "data line GPIO request failed\n");
                goto err_release_reg;
        }
 
-       ret = devm_request_irq(&pdev->dev, gpio_to_irq(data->pdata->gpio_data),
+       ret = devm_request_irq(&pdev->dev, gpiod_to_irq(data->data),
                               sht15_interrupt_fired,
                               IRQF_TRIGGER_FALLING,
                               "sht15 data",
@@ -1053,7 +993,7 @@ static int sht15_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to get irq for data line\n");
                goto err_release_reg;
        }
-       disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
+       disable_irq_nosync(gpiod_to_irq(data->data));
        ret = sht15_connection_reset(data);
        if (ret)
                goto err_release_reg;
@@ -1061,13 +1001,6 @@ static int sht15_probe(struct platform_device *pdev)
        if (ret)
                goto err_release_reg;
 
-       /* write status with platform data options */
-       if (status) {
-               ret = sht15_send_status(data, status);
-               if (ret)
-                       goto err_release_reg;
-       }
-
        ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group);
        if (ret) {
                dev_err(&pdev->dev, "sysfs create failed\n");
index 3f940fb67dc622cc096745b9e6950e68f73d6b73..7fe152d92350e18b6c972ebcf0a7f0be0bbf94e4 100644 (file)
@@ -396,7 +396,7 @@ static ssize_t show_max_alarm(struct device *dev, struct device_attribute *attr,
        if (ret < 0)
                return ret;
 
-       return snprintf(buf, PAGE_SIZE - 1, "%d\n", priv->max_alert);
+       return snprintf(buf, PAGE_SIZE, "%d\n", priv->max_alert);
 }
 
 static ssize_t show_min_alarm(struct device *dev, struct device_attribute *attr,
@@ -413,7 +413,7 @@ static ssize_t show_min_alarm(struct device *dev, struct device_attribute *attr,
        if (ret < 0)
                return ret;
 
-       return snprintf(buf, PAGE_SIZE - 1, "%d\n", priv->min_alert);
+       return snprintf(buf, PAGE_SIZE, "%d\n", priv->min_alert);
 }
 
 static ssize_t show_input(struct device *dev, struct device_attribute *attr,
@@ -428,7 +428,7 @@ static ssize_t show_input(struct device *dev, struct device_attribute *attr,
        if (ret < 0)
                return ret;
 
-       return snprintf(buf, PAGE_SIZE - 1, "%d\n", priv->temp);
+       return snprintf(buf, PAGE_SIZE, "%d\n", priv->temp);
 }
 
 static ssize_t show_therm(struct device *dev, struct device_attribute *attr,
@@ -436,7 +436,7 @@ static ssize_t show_therm(struct device *dev, struct device_attribute *attr,
 {
        struct stts751_priv *priv = dev_get_drvdata(dev);
 
-       return snprintf(buf, PAGE_SIZE - 1, "%d\n", priv->therm);
+       return snprintf(buf, PAGE_SIZE, "%d\n", priv->therm);
 }
 
 static ssize_t set_therm(struct device *dev, struct device_attribute *attr,
@@ -478,7 +478,7 @@ static ssize_t show_hyst(struct device *dev, struct device_attribute *attr,
 {
        struct stts751_priv *priv = dev_get_drvdata(dev);
 
-       return snprintf(buf, PAGE_SIZE - 1, "%d\n", priv->hyst);
+       return snprintf(buf, PAGE_SIZE, "%d\n", priv->hyst);
 }
 
 static ssize_t set_hyst(struct device *dev, struct device_attribute *attr,
@@ -518,7 +518,7 @@ static ssize_t show_therm_trip(struct device *dev,
        if (ret < 0)
                return ret;
 
-       return snprintf(buf, PAGE_SIZE - 1, "%d\n", priv->therm_trip);
+       return snprintf(buf, PAGE_SIZE, "%d\n", priv->therm_trip);
 }
 
 static ssize_t show_max(struct device *dev, struct device_attribute *attr,
@@ -526,7 +526,7 @@ static ssize_t show_max(struct device *dev, struct device_attribute *attr,
 {
        struct stts751_priv *priv = dev_get_drvdata(dev);
 
-       return snprintf(buf, PAGE_SIZE - 1, "%d\n", priv->event_max);
+       return snprintf(buf, PAGE_SIZE, "%d\n", priv->event_max);
 }
 
 static ssize_t set_max(struct device *dev, struct device_attribute *attr,
@@ -560,7 +560,7 @@ static ssize_t show_min(struct device *dev, struct device_attribute *attr,
 {
        struct stts751_priv *priv = dev_get_drvdata(dev);
 
-       return snprintf(buf, PAGE_SIZE - 1, "%d\n", priv->event_min);
+       return snprintf(buf, PAGE_SIZE, "%d\n", priv->event_min);
 }
 
 static ssize_t set_min(struct device *dev, struct device_attribute *attr,
@@ -594,7 +594,7 @@ static ssize_t show_interval(struct device *dev, struct device_attribute *attr,
 {
        struct stts751_priv *priv = dev_get_drvdata(dev);
 
-       return snprintf(buf, PAGE_SIZE - 1, "%d\n",
+       return snprintf(buf, PAGE_SIZE, "%d\n",
                        stts751_intervals[priv->interval]);
 }
 
index dab5c515d5a3d141449645717edbd35688b13fbb..5ba9d9f1daa1f5f65933edd58bc32adb8525e10b 100644 (file)
@@ -1676,7 +1676,9 @@ static int w83793_probe(struct i2c_client *client,
                        const struct i2c_device_id *id)
 {
        struct device *dev = &client->dev;
-       const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 };
+       static const int watchdog_minors[] = {
+               WATCHDOG_MINOR, 212, 213, 214, 215
+       };
        struct w83793_data *data;
        int i, tmp, val, err;
        int files_fan = ARRAY_SIZE(w83793_left_fan) / 7;
index e1be61095532f03dda79effe36fbde2147a31d66..a3cd91f232679afd21c9ebbd206be377f5394333 100644 (file)
 #define to_xgene_hwmon_dev(cl)         \
        container_of(cl, struct xgene_hwmon_dev, mbox_client)
 
+enum xgene_hwmon_version {
+       XGENE_HWMON_V1 = 0,
+       XGENE_HWMON_V2 = 1,
+};
+
 struct slimpro_resp_msg {
        u32 msg;
        u32 param1;
@@ -609,6 +614,15 @@ static void xgene_hwmon_tx_done(struct mbox_client *cl, void *msg, int ret)
        }
 }
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id xgene_hwmon_acpi_match[] = {
+       {"APMC0D29", XGENE_HWMON_V1},
+       {"APMC0D8A", XGENE_HWMON_V2},
+       {},
+};
+MODULE_DEVICE_TABLE(acpi, xgene_hwmon_acpi_match);
+#endif
+
 static int xgene_hwmon_probe(struct platform_device *pdev)
 {
        struct xgene_hwmon_dev *ctx;
@@ -651,6 +665,15 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
                }
        } else {
                struct acpi_pcct_hw_reduced *cppc_ss;
+               const struct acpi_device_id *acpi_id;
+               int version;
+
+               acpi_id = acpi_match_device(pdev->dev.driver->acpi_match_table,
+                                           &pdev->dev);
+               if (!acpi_id)
+                       return -EINVAL;
+
+               version = (int)acpi_id->driver_data;
 
                if (device_property_read_u32(&pdev->dev, "pcc-channel",
                                             &ctx->mbox_idx)) {
@@ -693,7 +716,13 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
                 */
                ctx->comm_base_addr = cppc_ss->base_address;
                if (ctx->comm_base_addr) {
-                       ctx->pcc_comm_addr = memremap(ctx->comm_base_addr,
+                       if (version == XGENE_HWMON_V2)
+                               ctx->pcc_comm_addr = (void __force *)ioremap(
+                                                       ctx->comm_base_addr,
+                                                       cppc_ss->length);
+                       else
+                               ctx->pcc_comm_addr = memremap(
+                                                       ctx->comm_base_addr,
                                                        cppc_ss->length,
                                                        MEMREMAP_WB);
                } else {
@@ -761,14 +790,6 @@ static int xgene_hwmon_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_ACPI
-static const struct acpi_device_id xgene_hwmon_acpi_match[] = {
-       {"APMC0D29", 0},
-       {},
-};
-MODULE_DEVICE_TABLE(acpi, xgene_hwmon_acpi_match);
-#endif
-
 static const struct of_device_id xgene_hwmon_of_match[] = {
        {.compatible = "apm,xgene-slimpro-hwmon"},
        {}
diff --git a/include/linux/gpio-fan.h b/include/linux/gpio-fan.h
deleted file mode 100644 (file)
index 0966591..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * include/linux/gpio-fan.h
- *
- * Platform data structure for GPIO fan driver
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __LINUX_GPIO_FAN_H
-#define __LINUX_GPIO_FAN_H
-
-struct gpio_fan_alarm {
-       unsigned        gpio;
-       unsigned        active_low;
-};
-
-struct gpio_fan_speed {
-       int rpm;
-       int ctrl_val;
-};
-
-struct gpio_fan_platform_data {
-       int                     num_ctrl;
-       unsigned                *ctrl;  /* fan control GPIOs. */
-       struct gpio_fan_alarm   *alarm; /* fan alarm GPIO. */
-       /*
-        * Speed conversion array: rpm from/to GPIO bit field.
-        * This array _must_ be sorted in ascending rpm order.
-        */
-       int                     num_speed;
-       struct gpio_fan_speed   *speed;
-};
-
-#endif /* __LINUX_GPIO_FAN_H */
diff --git a/include/linux/platform_data/sht15.h b/include/linux/platform_data/sht15.h
deleted file mode 100644 (file)
index 12289c1..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * sht15.h - support for the SHT15 Temperature and Humidity Sensor
- *
- * Copyright (c) 2009 Jonathan Cameron
- *
- * Copyright (c) 2007 Wouter Horre
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * For further information, see the Documentation/hwmon/sht15 file.
- */
-
-#ifndef _PDATA_SHT15_H
-#define _PDATA_SHT15_H
-
-/**
- * struct sht15_platform_data - sht15 connectivity info
- * @gpio_data:         no. of gpio to which bidirectional data line is
- *                     connected.
- * @gpio_sck:          no. of gpio to which the data clock is connected.
- * @supply_mv:         supply voltage in mv. Overridden by regulator if
- *                     available.
- * @checksum:          flag to indicate the checksum should be validated.
- * @no_otp_reload:     flag to indicate no reload from OTP.
- * @low_resolution:    flag to indicate the temp/humidity resolution to use.
- */
-struct sht15_platform_data {
-       int gpio_data;
-       int gpio_sck;
-       int supply_mv;
-       bool checksum;
-       bool no_otp_reload;
-       bool low_resolution;
-};
-
-#endif /* _PDATA_SHT15_H */