[PATCH] hwmon: (npcm-750-pwm-fan): Change initial pwm target to 255

2018-10-08 Thread Kun Yi
Change initial PWM target to 255 to prevent overheating, for example
when BMC hangs in userspace or when userspace fan control application is
not implemented yet.

Signed-off-by: Kun Yi 
---
 drivers/hwmon/npcm750-pwm-fan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwmon/npcm750-pwm-fan.c b/drivers/hwmon/npcm750-pwm-fan.c
index 96634fd54e0b..c0fab54c0094 100644
--- a/drivers/hwmon/npcm750-pwm-fan.c
+++ b/drivers/hwmon/npcm750-pwm-fan.c
@@ -52,7 +52,7 @@
 
 /* Define the Counter Register, value = 100 for match 100% */
 #define NPCM7XX_PWM_COUNTER_DEFAULT_NUM255
-#define NPCM7XX_PWM_CMR_DEFAULT_NUM127
+#define NPCM7XX_PWM_CMR_DEFAULT_NUM255
 #define NPCM7XX_PWM_CMR_MAX255
 
 /* default all PWM channels PRESCALE2 = 1 */
-- 
2.19.0.605.g01d371f741-goog



[PATCH v2] hwmon: (ina3221) Validate shunt resistor value from DT

2018-10-08 Thread Nicolin Chen
The input->shunt_resistor is int type while the value from DT is
unsigned int. Meanwhile, a divide-by-zero error would happen if
the value is 0. So this patch just simply validates the value.

Signed-off-by: Nicolin Chen 
---
Changelog
v1->v2:
 * Validate the value and error out

 drivers/hwmon/ina3221.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c
index c3a497aed345..4f3ed24efe8e 100644
--- a/drivers/hwmon/ina3221.c
+++ b/drivers/hwmon/ina3221.c
@@ -536,8 +536,14 @@ static int ina3221_probe_child_from_dt(struct device *dev,
of_property_read_string(child, "label", >label);
 
/* Overwrite default shunt resistor value optionally */
-   if (!of_property_read_u32(child, "shunt-resistor-micro-ohms", ))
+   if (!of_property_read_u32(child, "shunt-resistor-micro-ohms", )) {
+   if (val < 1 || val > INT_MAX) {
+   dev_err(dev, "invalid shunt resistor value %u of %s\n",
+   val, child->name);
+   return -EINVAL;
+   }
input->shunt_resistor = val;
+   }
 
return 0;
 }
-- 
2.17.1



Re: [PATCH] hwmon: (ina3221) Clamp shunt resistor value from DT

2018-10-08 Thread Guenter Roeck
On Mon, Oct 08, 2018 at 01:05:37PM -0700, Nicolin Chen wrote:
> The input->shunt_resistor is int type while the value from DT is
> unsigned int. Meanwhile, a divide-by-zero error would happen if
> the value is 0. So this patch just simply clamps the value.
> 

I think it would be better to validate the numbers here instead of 
silently accepting bad values, and return -EINVAL if the property value
is bad.

Thanks,
Guenter

> Signed-off-by: Nicolin Chen 
> ---
>  drivers/hwmon/ina3221.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c
> index c3a497aed345..ce8f0a8c4982 100644
> --- a/drivers/hwmon/ina3221.c
> +++ b/drivers/hwmon/ina3221.c
> @@ -536,8 +536,10 @@ static int ina3221_probe_child_from_dt(struct device 
> *dev,
>   of_property_read_string(child, "label", >label);
>  
>   /* Overwrite default shunt resistor value optionally */
> - if (!of_property_read_u32(child, "shunt-resistor-micro-ohms", ))
> + if (!of_property_read_u32(child, "shunt-resistor-micro-ohms", )) {
> + val = clamp_val(val, 1, INT_MAX);
>   input->shunt_resistor = val;
> + }
>  
>   return 0;
>  }
> -- 
> 2.17.1
> 


[PATCH v2] hwmon: (ina3221) Use _info API to register hwmon device

2018-10-08 Thread Nicolin Chen
The hwmon core has a newer API which abstracts most of common
things in the core so as to simplify the hwmon device drivers.

This patch implements this _info API to ina3221 hwmon driver.

It also reduces the binary size:
   textdata bss dec hex filename
   51141712   068261aaa drivers/hwmon/ina3221_before.o
   4456 440   048961320 drivers/hwmon/ina3221.o

Signed-off-by: Nicolin Chen 
---
Changelog
v1->v2:
 * Added a binary size comparison in commit message
 * Dropped unnecessary checks
 * Dropped misleading ID conversion in the comments
 * Added two comments to indicate 0-align channel indexes
 * Used "fall through" instead of "fallthrough"

 drivers/hwmon/ina3221.c | 520 ++--
 1 file changed, 236 insertions(+), 284 deletions(-)

diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c
index ce8f0a8c4982..973fc4af0ddf 100644
--- a/drivers/hwmon/ina3221.c
+++ b/drivers/hwmon/ina3221.c
@@ -77,21 +77,6 @@ enum ina3221_channels {
INA3221_NUM_CHANNELS
 };
 
-static const unsigned int register_channel[] = {
-   [INA3221_BUS1] = INA3221_CHANNEL1,
-   [INA3221_BUS2] = INA3221_CHANNEL2,
-   [INA3221_BUS3] = INA3221_CHANNEL3,
-   [INA3221_SHUNT1] = INA3221_CHANNEL1,
-   [INA3221_SHUNT2] = INA3221_CHANNEL2,
-   [INA3221_SHUNT3] = INA3221_CHANNEL3,
-   [INA3221_CRIT1] = INA3221_CHANNEL1,
-   [INA3221_CRIT2] = INA3221_CHANNEL2,
-   [INA3221_CRIT3] = INA3221_CHANNEL3,
-   [INA3221_WARN1] = INA3221_CHANNEL1,
-   [INA3221_WARN2] = INA3221_CHANNEL2,
-   [INA3221_WARN3] = INA3221_CHANNEL3,
-};
-
 /**
  * struct ina3221_input - channel input source specific information
  * @label: label of channel input source
@@ -123,58 +108,6 @@ static inline bool ina3221_is_enabled(struct ina3221_data 
*ina, int channel)
return ina->reg_config & INA3221_CONFIG_CHx_EN(channel);
 }
 
-static ssize_t ina3221_show_label(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
-   struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr);
-   struct ina3221_data *ina = dev_get_drvdata(dev);
-   unsigned int channel = sd_attr->index;
-   struct ina3221_input *input = >inputs[channel];
-
-   return snprintf(buf, PAGE_SIZE, "%s\n", input->label);
-}
-
-static ssize_t ina3221_show_enable(struct device *dev,
-  struct device_attribute *attr, char *buf)
-{
-   struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr);
-   struct ina3221_data *ina = dev_get_drvdata(dev);
-   unsigned int channel = sd_attr->index;
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-   ina3221_is_enabled(ina, channel));
-}
-
-static ssize_t ina3221_set_enable(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
-   struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr);
-   struct ina3221_data *ina = dev_get_drvdata(dev);
-   unsigned int channel = sd_attr->index;
-   u16 config, mask = INA3221_CONFIG_CHx_EN(channel);
-   bool enable;
-   int ret;
-
-   ret = kstrtobool(buf, );
-   if (ret)
-   return ret;
-
-   config = enable ? mask : 0;
-
-   /* Enable or disable the channel */
-   ret = regmap_update_bits(ina->regmap, INA3221_CONFIG, mask, config);
-   if (ret)
-   return ret;
-
-   /* Cache the latest config register value */
-   ret = regmap_read(ina->regmap, INA3221_CONFIG, >reg_config);
-   if (ret)
-   return ret;
-
-   return count;
-}
-
 static int ina3221_read_value(struct ina3221_data *ina, unsigned int reg,
  int *val)
 {
@@ -190,94 +123,104 @@ static int ina3221_read_value(struct ina3221_data *ina, 
unsigned int reg,
return 0;
 }
 
-static ssize_t ina3221_show_bus_voltage(struct device *dev,
-   struct device_attribute *attr,
-   char *buf)
+static const u8 ina3221_in_reg[] = {
+   INA3221_BUS1,
+   INA3221_BUS2,
+   INA3221_BUS3,
+   INA3221_SHUNT1,
+   INA3221_SHUNT2,
+   INA3221_SHUNT3,
+};
+
+static int ina3221_read_in(struct device *dev, u32 attr, int channel, long 
*val)
 {
-   struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr);
+   const bool is_shunt = channel > INA3221_CHANNEL3;
struct ina3221_data *ina = dev_get_drvdata(dev);
-   unsigned int reg = sd_attr->index;
-   unsigned int channel = register_channel[reg];
-   int val, voltage_mv, ret;
+   u8 reg = ina3221_in_reg[channel];
+   int regval, ret;
 
-   /* No data for read-only attribute if channel is disabled */
-   if (!attr->store && !ina3221_is_enabled(ina, channel))
-   return 

[PATCH] hwmon: (ina3221) Clamp shunt resistor value from DT

2018-10-08 Thread Nicolin Chen
The input->shunt_resistor is int type while the value from DT is
unsigned int. Meanwhile, a divide-by-zero error would happen if
the value is 0. So this patch just simply clamps the value.

Signed-off-by: Nicolin Chen 
---
 drivers/hwmon/ina3221.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c
index c3a497aed345..ce8f0a8c4982 100644
--- a/drivers/hwmon/ina3221.c
+++ b/drivers/hwmon/ina3221.c
@@ -536,8 +536,10 @@ static int ina3221_probe_child_from_dt(struct device *dev,
of_property_read_string(child, "label", >label);
 
/* Overwrite default shunt resistor value optionally */
-   if (!of_property_read_u32(child, "shunt-resistor-micro-ohms", ))
+   if (!of_property_read_u32(child, "shunt-resistor-micro-ohms", )) {
+   val = clamp_val(val, 1, INT_MAX);
input->shunt_resistor = val;
+   }
 
return 0;
 }
-- 
2.17.1



Re: [PATCH v5] scsi: Add hwmon support for SMART temperature sensors

2018-10-08 Thread Hannes Reinecke

On 10/7/18 10:49 PM, Linus Walleij wrote:

S.M.A.R.T. temperature sensors have been supported for
years by userspace tools such as smarttools. This adds
support to read it from the kernel and adds a temperature
zone for the drive.

The temperature readout is however also a good fit for
Linux' hwmon subsystem. By adding a hwmon interface to dig
out SMART parameters, we can expose the drive temperature
as a standard hwmon sensor.

The idea came about when experimenting with NAS enclosures
that lack their own on-board sensors but instead piggy-back
the sensor found in the harddrive, if any, to decide on a
policy for driving the on-board fan.

The kernel thermal subsystem supports defining a thermal
policy for the enclosure using the device tree, see e.g.:
arch/arm/boot/dts/gemini-dlink-dns-313.dts
but this requires a proper hwmon sensor integrated with
the kernel.

With this driver, the hard disk temperatur can be read from
sysfs:

  > cd /sys/class/hwmon/hwmon0/
  > cat temp1_input
  38

If the harddrive supports one of the detected vendor
extensions for providing min/max temperatures we also
provide attributes for displaying that.

This means that they can also be handled by userspace
tools such as lm_sensors in a uniform way without need
for any special tools such as "hddtemp" (which seems
dormant).

This driver does not block any simultaneous use of
other SMART userspace tools, it's a both/and approach,
not either/or.

Reviewed-by: Guenter Roeck  # HWMON
Signed-off-by: Linus Walleij 
---
Hmm. I might be getting something wrong here, but the main problem with 
SMART values is that they are _not_ really standardized; plus any drive 
is free to implement whatever they want.
Plus there are tons of SMART attribute values, and decoding just one 
seems to be a bit poor. At the same time having them in the kernel will 
just require us to implement lots of decoding, which I really would 
leave to userland.

So overall I'm not sure if that the right approach.

Cheers,

Hannes
--
Dr. Hannes ReineckeTeamlead Storage & Networking
h...@suse.de   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)