Commit 1e19bded authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'hwmon-for-linus-v4.15' of...

Merge tag 'hwmon-for-linus-v4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging

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
  ...
parents 1ec16991 ded0eb83
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>;
};
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>;
};
......@@ -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
......
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
......@@ -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".
......
......@@ -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));
......
......@@ -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
......
......@@ -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
......
......@@ -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;
......
......@@ -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 */
......@@ -161,7 +161,7 @@
* 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. */
......
This diff is collapsed.
......@@ -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);
......
......@@ -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,
......
This diff is collapsed.
......@@ -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
......
......@@ -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
......
/*
* 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");
......@@ -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,
......
......@@ -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);
}
......
This diff is collapsed.
......@@ -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]);
}
......
......@@ -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;
......
......@@ -91,6 +91,11 @@
#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"},
{}
......
/*
* 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 */
/*
* 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 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment