linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 1/3] hwmon: (adt7475) fan stall prevention
       [not found] <20170515013029.31397-1-chris.packham@alliedtelesis.co.nz>
@ 2017-05-15  1:30 ` Chris Packham
  2017-05-15 13:16   ` Guenter Roeck
  2017-05-15  1:30 ` [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing Chris Packham
  2017-05-15  1:30 ` [PATCH v4 3/3] hwmon: (adt7475) add high frequency support Chris Packham
  2 siblings, 1 reply; 16+ messages in thread
From: Chris Packham @ 2017-05-15  1:30 UTC (permalink / raw)
  To: linux, linux-hwmon, jdelvare
  Cc: Chris Packham, Jonathan Corbet, linux-doc, linux-kernel

By default adt7475 will stop the fans (pwm duty cycle 0%) when the
temperature drops past Tmin - hysteresis. Some systems want to keep the
fans moving even when the temperature drops so add new sysfs attributes
that configure the enhanced acoustics min 1-3 which allows the fans to
run at the minimum configure pwm duty cycle.

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
Changes in v2:
- use pwmN_stall_dis as the attribute name. I think this describes the purpose
  pretty well. I went with a new attribute instead of overloading
  pwmN_auto_point1_pwm so this doesn't affect existing users.
Changes in v3:
- Fix grammar.
- change enh_acou to enh_acoustics
Changes in v4:
- Change sysfs attribute to pwmN_stall_disable

 Documentation/hwmon/adt7475 |  5 +++++
 drivers/hwmon/adt7475.c     | 50 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/Documentation/hwmon/adt7475 b/Documentation/hwmon/adt7475
index 0502f2b464e1..dc0b55794c47 100644
--- a/Documentation/hwmon/adt7475
+++ b/Documentation/hwmon/adt7475
@@ -109,6 +109,11 @@ fan speed) is applied. PWM values range from 0 (off) to 255 (full speed).
 Fan speed may be set to maximum when the temperature sensor associated with
 the PWM control exceeds temp#_max.
 
+At Tmin - hysteresis the PWM output can either be off (0% duty cycle) or at the
+minimum (i.e. auto_point1_pwm). This behaviour can be configured using the
+pwm[1-*]_stall_disable sysfs attribute. A value of 0 means the fans will shut
+off. A value of 1 means the fans will run at auto_point1_pwm.
+
 Notes
 -----
 
diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
index ec0c43fbcdce..3eb8c5c2f8af 100644
--- a/drivers/hwmon/adt7475.c
+++ b/drivers/hwmon/adt7475.c
@@ -79,6 +79,9 @@
 
 #define REG_TEMP_TRANGE_BASE	0x5F
 
+#define REG_ENHANCE_ACOUSTICS1	0x62
+#define REG_ENHANCE_ACOUSTICS2	0x63
+
 #define REG_PWM_MIN_BASE	0x64
 
 #define REG_TEMP_TMIN_BASE	0x67
@@ -209,6 +212,7 @@ struct adt7475_data {
 	u8 range[3];
 	u8 pwmctl[3];
 	u8 pwmchan[3];
+	u8 enh_acoustics[2];
 
 	u8 vid;
 	u8 vrm;
@@ -700,6 +704,43 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 	data->pwm[sattr->nr][sattr->index] = clamp_val(val, 0, 0xFF);
 	i2c_smbus_write_byte_data(client, reg,
 				  data->pwm[sattr->nr][sattr->index]);
+	mutex_unlock(&data->lock);
+
+	return count;
+}
+
+static ssize_t show_stall_disable(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adt7475_data *data = i2c_get_clientdata(client);
+	u8 mask = BIT(5 + sattr->index);
+
+	return sprintf(buf, "%d\n", !!(data->enh_acoustics[0] & mask));
+}
+
+static ssize_t set_stall_disable(struct device *dev,
+				 struct device_attribute *attr, const char *buf,
+				 size_t count)
+{
+	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adt7475_data *data = i2c_get_clientdata(client);
+	long val;
+	u8 mask = BIT(5 + sattr->index);
+
+	if (kstrtol(buf, 10, &val))
+		return -EINVAL;
+
+	mutex_lock(&data->lock);
+
+	data->enh_acoustics[0] &= ~mask;
+	if (val)
+		data->enh_acoustics[0] |= mask;
+
+	i2c_smbus_write_byte_data(client, REG_ENHANCE_ACOUSTICS1,
+				  data->enh_acoustics[0]);
 
 	mutex_unlock(&data->lock);
 
@@ -1028,6 +1069,8 @@ static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm,
 			    set_pwm, MIN, 0);
 static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm,
 			    set_pwm, MAX, 0);
+static SENSOR_DEVICE_ATTR_2(pwm1_stall_disable, S_IRUGO | S_IWUSR,
+			    show_stall_disable, set_stall_disable, 0, 0);
 static SENSOR_DEVICE_ATTR_2(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, INPUT,
 			    1);
 static SENSOR_DEVICE_ATTR_2(pwm2_freq, S_IRUGO | S_IWUSR, show_pwmfreq,
@@ -1040,6 +1083,8 @@ static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm,
 			    set_pwm, MIN, 1);
 static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm,
 			    set_pwm, MAX, 1);
+static SENSOR_DEVICE_ATTR_2(pwm2_stall_disable, S_IRUGO | S_IWUSR,
+			    show_stall_disable, set_stall_disable, 0, 1);
 static SENSOR_DEVICE_ATTR_2(pwm3, S_IRUGO | S_IWUSR, show_pwm, set_pwm, INPUT,
 			    2);
 static SENSOR_DEVICE_ATTR_2(pwm3_freq, S_IRUGO | S_IWUSR, show_pwmfreq,
@@ -1052,6 +1097,8 @@ static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm,
 			    set_pwm, MIN, 2);
 static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm,
 			    set_pwm, MAX, 2);
+static SENSOR_DEVICE_ATTR_2(pwm3_stall_disable, S_IRUGO | S_IWUSR,
+			    show_stall_disable, set_stall_disable, 0, 2);
 
 /* Non-standard name, might need revisiting */
 static DEVICE_ATTR_RW(pwm_use_point2_pwm_at_crit);
@@ -1112,12 +1159,14 @@ static struct attribute *adt7475_attrs[] = {
 	&sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
 	&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
 	&sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm1_stall_disable.dev_attr.attr,
 	&sensor_dev_attr_pwm3.dev_attr.attr,
 	&sensor_dev_attr_pwm3_freq.dev_attr.attr,
 	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
 	&sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
 	&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
 	&sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm3_stall_disable.dev_attr.attr,
 	&dev_attr_pwm_use_point2_pwm_at_crit.attr,
 	NULL,
 };
@@ -1136,6 +1185,7 @@ static struct attribute *pwm2_attrs[] = {
 	&sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
 	&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
 	&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
+	&sensor_dev_attr_pwm2_stall_disable.dev_attr.attr,
 	NULL
 };
 
-- 
2.11.0.24.ge6920cf

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing
       [not found] <20170515013029.31397-1-chris.packham@alliedtelesis.co.nz>
  2017-05-15  1:30 ` [PATCH v4 1/3] hwmon: (adt7475) fan stall prevention Chris Packham
@ 2017-05-15  1:30 ` Chris Packham
  2017-05-15 13:18   ` Guenter Roeck
  2017-05-16  8:17   ` kbuild test robot
  2017-05-15  1:30 ` [PATCH v4 3/3] hwmon: (adt7475) add high frequency support Chris Packham
  2 siblings, 2 replies; 16+ messages in thread
From: Chris Packham @ 2017-05-15  1:30 UTC (permalink / raw)
  To: linux, linux-hwmon, jdelvare
  Cc: Chris Packham, Jonathan Corbet, linux-doc, linux-kernel

When enabled temperature smoothing allows ramping the fan speed over a
configurable period of time instead of jumping to the new speed
instantaneously.

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
Changes in v2:
- use a single tempN_smoothing attribute
Changes in v3:
- change enh_acou to enh_acoustics
- simplify show_temp_st()
Changes in v4:
- removed dead code.
- Make the order of the smoothing attributes match the other temperature
  attributes.

Guenter,

We'd previously discussed making the smoothing values set CONFIG6[SLOW] to
expose the other set of potential values. I wasn't sure where you wanted to go
on that one.

Personally I was on the fence since the difference would only be noticeable for
the higher values. If we do want to add support for the other values it could
be done as a subsequent patch (or a v5 if you want it).

 Documentation/hwmon/adt7475 |  4 ++
 drivers/hwmon/adt7475.c     | 91 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+)

diff --git a/Documentation/hwmon/adt7475 b/Documentation/hwmon/adt7475
index dc0b55794c47..09d73a10644c 100644
--- a/Documentation/hwmon/adt7475
+++ b/Documentation/hwmon/adt7475
@@ -114,6 +114,10 @@ minimum (i.e. auto_point1_pwm). This behaviour can be configured using the
 pwm[1-*]_stall_disable sysfs attribute. A value of 0 means the fans will shut
 off. A value of 1 means the fans will run at auto_point1_pwm.
 
+The responsiveness of the ADT747x to temperature changes can be configured.
+This allows smoothing of the fan speed transition. To set the transition time
+set the value in ms in the temp[1-*]_smoothing sysfs attribute.
+
 Notes
 -----
 
diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
index 3eb8c5c2f8af..3056076fae27 100644
--- a/drivers/hwmon/adt7475.c
+++ b/drivers/hwmon/adt7475.c
@@ -526,6 +526,88 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
+/* Assuming CONFIG6[SLOW] is 0 */
+static const int ad7475_st_map[] = {
+	37500, 18800, 12500, 7500, 4700, 3100, 1600, 800,
+};
+
+static ssize_t show_temp_st(struct device *dev, struct device_attribute *attr,
+				  char *buf)
+{
+	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adt7475_data *data = i2c_get_clientdata(client);
+	long val;
+
+	switch (sattr->index) {
+	case 0:
+		val = data->enh_acoustics[0] & 0xf;
+		break;
+	case 1:
+		val = (data->enh_acoustics[1] >> 4) & 0xf;
+		break;
+	case 2:
+	default:
+		val = data->enh_acoustics[1] & 0xf;
+		break;
+	}
+
+	if (val & 0x8)
+		return sprintf(buf, "%d\n", ad7475_st_map[val & 0x7]);
+	else
+		return sprintf(buf, "0\n");
+}
+
+static ssize_t set_temp_st(struct device *dev, struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adt7475_data *data = i2c_get_clientdata(client);
+	unsigned char reg;
+	int shift, idx;
+	ulong val;
+
+	if (kstrtoul(buf, 10, &val))
+		return -EINVAL;
+
+	switch (sattr->index) {
+	case 0:
+		reg = REG_ENHANCE_ACOUSTICS1;
+		shift = 0;
+		idx = 0;
+		break;
+	case 1:
+		reg = REG_ENHANCE_ACOUSTICS2;
+		shift = 0;
+		idx = 1;
+		break;
+	case 2:
+	default:
+		reg = REG_ENHANCE_ACOUSTICS2;
+		shift = 4;
+		idx = 1;
+		break;
+	}
+
+	if (val > 0) {
+		val = find_closest_descending(val, ad7475_st_map,
+					      ARRAY_SIZE(ad7475_st_map));
+		val |= 0x8;
+	}
+
+	mutex_lock(&data->lock);
+
+	data->enh_acoustics[idx] &= ~(0xf << shift);
+	data->enh_acoustics[idx] |= (val << shift);
+
+	i2c_smbus_write_byte_data(client, reg, data->enh_acoustics[idx]);
+
+	mutex_unlock(&data->lock);
+
+	return count;
+}
+
 /*
  * Table of autorange values - the user will write the value in millidegrees,
  * and we'll convert it
@@ -1008,6 +1090,8 @@ static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
 			    THERM, 0);
 static SENSOR_DEVICE_ATTR_2(temp1_crit_hyst, S_IRUGO | S_IWUSR, show_temp,
 			    set_temp, HYSTERSIS, 0);
+static SENSOR_DEVICE_ATTR_2(temp1_smoothing, S_IRUGO | S_IWUSR, show_temp_st,
+			    set_temp_st, 0, 0);
 static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, INPUT, 1);
 static SENSOR_DEVICE_ATTR_2(temp2_alarm, S_IRUGO, show_temp, NULL, ALARM, 1);
 static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
@@ -1024,6 +1108,8 @@ static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
 			    THERM, 1);
 static SENSOR_DEVICE_ATTR_2(temp2_crit_hyst, S_IRUGO | S_IWUSR, show_temp,
 			    set_temp, HYSTERSIS, 1);
+static SENSOR_DEVICE_ATTR_2(temp2_smoothing, S_IRUGO | S_IWUSR, show_temp_st,
+			    set_temp_st, 0, 1);
 static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, INPUT, 2);
 static SENSOR_DEVICE_ATTR_2(temp3_alarm, S_IRUGO, show_temp, NULL, ALARM, 2);
 static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_temp, NULL, FAULT, 2);
@@ -1041,6 +1127,8 @@ static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
 			    THERM, 2);
 static SENSOR_DEVICE_ATTR_2(temp3_crit_hyst, S_IRUGO | S_IWUSR, show_temp,
 			    set_temp, HYSTERSIS, 2);
+static SENSOR_DEVICE_ATTR_2(temp3_smoothing, S_IRUGO | S_IWUSR, show_temp_st,
+			    set_temp_st, 0, 2);
 static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_tach, NULL, INPUT, 0);
 static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_tach, set_tach,
 			    MIN, 0);
@@ -1125,6 +1213,7 @@ static struct attribute *adt7475_attrs[] = {
 	&sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr,
 	&sensor_dev_attr_temp1_crit.dev_attr.attr,
 	&sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
+	&sensor_dev_attr_temp1_smoothing.dev_attr.attr,
 	&sensor_dev_attr_temp2_input.dev_attr.attr,
 	&sensor_dev_attr_temp2_alarm.dev_attr.attr,
 	&sensor_dev_attr_temp2_max.dev_attr.attr,
@@ -1134,6 +1223,7 @@ static struct attribute *adt7475_attrs[] = {
 	&sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr,
 	&sensor_dev_attr_temp2_crit.dev_attr.attr,
 	&sensor_dev_attr_temp2_crit_hyst.dev_attr.attr,
+	&sensor_dev_attr_temp2_smoothing.dev_attr.attr,
 	&sensor_dev_attr_temp3_input.dev_attr.attr,
 	&sensor_dev_attr_temp3_fault.dev_attr.attr,
 	&sensor_dev_attr_temp3_alarm.dev_attr.attr,
@@ -1144,6 +1234,7 @@ static struct attribute *adt7475_attrs[] = {
 	&sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr,
 	&sensor_dev_attr_temp3_crit.dev_attr.attr,
 	&sensor_dev_attr_temp3_crit_hyst.dev_attr.attr,
+	&sensor_dev_attr_temp3_smoothing.dev_attr.attr,
 	&sensor_dev_attr_fan1_input.dev_attr.attr,
 	&sensor_dev_attr_fan1_min.dev_attr.attr,
 	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
-- 
2.11.0.24.ge6920cf

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v4 3/3] hwmon: (adt7475) add high frequency support
       [not found] <20170515013029.31397-1-chris.packham@alliedtelesis.co.nz>
  2017-05-15  1:30 ` [PATCH v4 1/3] hwmon: (adt7475) fan stall prevention Chris Packham
  2017-05-15  1:30 ` [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing Chris Packham
@ 2017-05-15  1:30 ` Chris Packham
  2017-05-15 13:26   ` Guenter Roeck
  2 siblings, 1 reply; 16+ messages in thread
From: Chris Packham @ 2017-05-15  1:30 UTC (permalink / raw)
  To: linux, linux-hwmon, jdelvare; +Cc: Chris Packham, linux-kernel

Systems using 4-wire fans usually require high frequency (22.5kHz)
output on the pwm. Add 22500 as a valid option in the pwmfreq_table. In
high frequency mode the low-order bit are ignored so they can safely be
set to 0.

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
Changes in v3:
- New
Changes in v4:
- Fix pwmfreq_table array indexing

 drivers/hwmon/adt7475.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
index 3056076fae27..1baa213a60bd 100644
--- a/drivers/hwmon/adt7475.c
+++ b/drivers/hwmon/adt7475.c
@@ -934,7 +934,7 @@ static ssize_t set_pwmctrl(struct device *dev, struct device_attribute *attr,
 
 /* List of frequencies for the PWM */
 static const int pwmfreq_table[] = {
-	11, 14, 22, 29, 35, 44, 58, 88
+	11, 14, 22, 29, 35, 44, 58, 88, 22500
 };
 
 static ssize_t show_pwmfreq(struct device *dev, struct device_attribute *attr,
@@ -942,9 +942,10 @@ static ssize_t show_pwmfreq(struct device *dev, struct device_attribute *attr,
 {
 	struct adt7475_data *data = adt7475_update_device(dev);
 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+	int i = clamp_val(data->range[sattr->index] & 0xf, 0,
+			  ARRAY_SIZE(pwmfreq_table) - 1);
 
-	return sprintf(buf, "%d\n",
-		       pwmfreq_table[data->range[sattr->index] & 7]);
+	return sprintf(buf, "%d\n", pwmfreq_table[i]);
 }
 
 static ssize_t set_pwmfreq(struct device *dev, struct device_attribute *attr,
@@ -965,7 +966,7 @@ static ssize_t set_pwmfreq(struct device *dev, struct device_attribute *attr,
 
 	data->range[sattr->index] =
 		adt7475_read(TEMP_TRANGE_REG(sattr->index));
-	data->range[sattr->index] &= ~7;
+	data->range[sattr->index] &= ~0xf;
 	data->range[sattr->index] |= out;
 
 	i2c_smbus_write_byte_data(client, TEMP_TRANGE_REG(sattr->index),
-- 
2.11.0.24.ge6920cf

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v4 1/3] hwmon: (adt7475) fan stall prevention
  2017-05-15  1:30 ` [PATCH v4 1/3] hwmon: (adt7475) fan stall prevention Chris Packham
@ 2017-05-15 13:16   ` Guenter Roeck
  0 siblings, 0 replies; 16+ messages in thread
From: Guenter Roeck @ 2017-05-15 13:16 UTC (permalink / raw)
  To: Chris Packham, linux-hwmon, jdelvare
  Cc: Jonathan Corbet, linux-doc, linux-kernel

On 05/14/2017 06:30 PM, Chris Packham wrote:
> By default adt7475 will stop the fans (pwm duty cycle 0%) when the
> temperature drops past Tmin - hysteresis. Some systems want to keep the
> fans moving even when the temperature drops so add new sysfs attributes
> that configure the enhanced acoustics min 1-3 which allows the fans to
> run at the minimum configure pwm duty cycle.
>
> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>

Applied to hwmon-next.

Thanks,
Guenter

> ---
> Changes in v2:
> - use pwmN_stall_dis as the attribute name. I think this describes the purpose
>   pretty well. I went with a new attribute instead of overloading
>   pwmN_auto_point1_pwm so this doesn't affect existing users.
> Changes in v3:
> - Fix grammar.
> - change enh_acou to enh_acoustics
> Changes in v4:
> - Change sysfs attribute to pwmN_stall_disable
>
>  Documentation/hwmon/adt7475 |  5 +++++
>  drivers/hwmon/adt7475.c     | 50 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 55 insertions(+)
>
> diff --git a/Documentation/hwmon/adt7475 b/Documentation/hwmon/adt7475
> index 0502f2b464e1..dc0b55794c47 100644
> --- a/Documentation/hwmon/adt7475
> +++ b/Documentation/hwmon/adt7475
> @@ -109,6 +109,11 @@ fan speed) is applied. PWM values range from 0 (off) to 255 (full speed).
>  Fan speed may be set to maximum when the temperature sensor associated with
>  the PWM control exceeds temp#_max.
>
> +At Tmin - hysteresis the PWM output can either be off (0% duty cycle) or at the
> +minimum (i.e. auto_point1_pwm). This behaviour can be configured using the
> +pwm[1-*]_stall_disable sysfs attribute. A value of 0 means the fans will shut
> +off. A value of 1 means the fans will run at auto_point1_pwm.
> +
>  Notes
>  -----
>
> diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
> index ec0c43fbcdce..3eb8c5c2f8af 100644
> --- a/drivers/hwmon/adt7475.c
> +++ b/drivers/hwmon/adt7475.c
> @@ -79,6 +79,9 @@
>
>  #define REG_TEMP_TRANGE_BASE	0x5F
>
> +#define REG_ENHANCE_ACOUSTICS1	0x62
> +#define REG_ENHANCE_ACOUSTICS2	0x63
> +
>  #define REG_PWM_MIN_BASE	0x64
>
>  #define REG_TEMP_TMIN_BASE	0x67
> @@ -209,6 +212,7 @@ struct adt7475_data {
>  	u8 range[3];
>  	u8 pwmctl[3];
>  	u8 pwmchan[3];
> +	u8 enh_acoustics[2];
>
>  	u8 vid;
>  	u8 vrm;
> @@ -700,6 +704,43 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
>  	data->pwm[sattr->nr][sattr->index] = clamp_val(val, 0, 0xFF);
>  	i2c_smbus_write_byte_data(client, reg,
>  				  data->pwm[sattr->nr][sattr->index]);
> +	mutex_unlock(&data->lock);
> +
> +	return count;
> +}
> +
> +static ssize_t show_stall_disable(struct device *dev,
> +				  struct device_attribute *attr, char *buf)
> +{
> +	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct adt7475_data *data = i2c_get_clientdata(client);
> +	u8 mask = BIT(5 + sattr->index);
> +
> +	return sprintf(buf, "%d\n", !!(data->enh_acoustics[0] & mask));
> +}
> +
> +static ssize_t set_stall_disable(struct device *dev,
> +				 struct device_attribute *attr, const char *buf,
> +				 size_t count)
> +{
> +	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct adt7475_data *data = i2c_get_clientdata(client);
> +	long val;
> +	u8 mask = BIT(5 + sattr->index);
> +
> +	if (kstrtol(buf, 10, &val))
> +		return -EINVAL;
> +
> +	mutex_lock(&data->lock);
> +
> +	data->enh_acoustics[0] &= ~mask;
> +	if (val)
> +		data->enh_acoustics[0] |= mask;
> +
> +	i2c_smbus_write_byte_data(client, REG_ENHANCE_ACOUSTICS1,
> +				  data->enh_acoustics[0]);
>
>  	mutex_unlock(&data->lock);
>
> @@ -1028,6 +1069,8 @@ static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm,
>  			    set_pwm, MIN, 0);
>  static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm,
>  			    set_pwm, MAX, 0);
> +static SENSOR_DEVICE_ATTR_2(pwm1_stall_disable, S_IRUGO | S_IWUSR,
> +			    show_stall_disable, set_stall_disable, 0, 0);
>  static SENSOR_DEVICE_ATTR_2(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, INPUT,
>  			    1);
>  static SENSOR_DEVICE_ATTR_2(pwm2_freq, S_IRUGO | S_IWUSR, show_pwmfreq,
> @@ -1040,6 +1083,8 @@ static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm,
>  			    set_pwm, MIN, 1);
>  static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm,
>  			    set_pwm, MAX, 1);
> +static SENSOR_DEVICE_ATTR_2(pwm2_stall_disable, S_IRUGO | S_IWUSR,
> +			    show_stall_disable, set_stall_disable, 0, 1);
>  static SENSOR_DEVICE_ATTR_2(pwm3, S_IRUGO | S_IWUSR, show_pwm, set_pwm, INPUT,
>  			    2);
>  static SENSOR_DEVICE_ATTR_2(pwm3_freq, S_IRUGO | S_IWUSR, show_pwmfreq,
> @@ -1052,6 +1097,8 @@ static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm,
>  			    set_pwm, MIN, 2);
>  static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO | S_IWUSR, show_pwm,
>  			    set_pwm, MAX, 2);
> +static SENSOR_DEVICE_ATTR_2(pwm3_stall_disable, S_IRUGO | S_IWUSR,
> +			    show_stall_disable, set_stall_disable, 0, 2);
>
>  /* Non-standard name, might need revisiting */
>  static DEVICE_ATTR_RW(pwm_use_point2_pwm_at_crit);
> @@ -1112,12 +1159,14 @@ static struct attribute *adt7475_attrs[] = {
>  	&sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
>  	&sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
>  	&sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
> +	&sensor_dev_attr_pwm1_stall_disable.dev_attr.attr,
>  	&sensor_dev_attr_pwm3.dev_attr.attr,
>  	&sensor_dev_attr_pwm3_freq.dev_attr.attr,
>  	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
>  	&sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
>  	&sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
>  	&sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
> +	&sensor_dev_attr_pwm3_stall_disable.dev_attr.attr,
>  	&dev_attr_pwm_use_point2_pwm_at_crit.attr,
>  	NULL,
>  };
> @@ -1136,6 +1185,7 @@ static struct attribute *pwm2_attrs[] = {
>  	&sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
>  	&sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
>  	&sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
> +	&sensor_dev_attr_pwm2_stall_disable.dev_attr.attr,
>  	NULL
>  };
>
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing
  2017-05-15  1:30 ` [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing Chris Packham
@ 2017-05-15 13:18   ` Guenter Roeck
  2017-05-16  8:17   ` kbuild test robot
  1 sibling, 0 replies; 16+ messages in thread
From: Guenter Roeck @ 2017-05-15 13:18 UTC (permalink / raw)
  To: Chris Packham, linux-hwmon, jdelvare
  Cc: Jonathan Corbet, linux-doc, linux-kernel

On 05/14/2017 06:30 PM, Chris Packham wrote:
> When enabled temperature smoothing allows ramping the fan speed over a
> configurable period of time instead of jumping to the new speed
> instantaneously.
>
> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>

Applied to -next.

> ---
> Changes in v2:
> - use a single tempN_smoothing attribute
> Changes in v3:
> - change enh_acou to enh_acoustics
> - simplify show_temp_st()
> Changes in v4:
> - removed dead code.
> - Make the order of the smoothing attributes match the other temperature
>   attributes.
>
> Guenter,
>
> We'd previously discussed making the smoothing values set CONFIG6[SLOW] to
> expose the other set of potential values. I wasn't sure where you wanted to go
> on that one.
>
> Personally I was on the fence since the difference would only be noticeable for
> the higher values. If we do want to add support for the other values it could
> be done as a subsequent patch (or a v5 if you want it).
>
It can be added later if anyone cares.

Thanks,
Guenter

>  Documentation/hwmon/adt7475 |  4 ++
>  drivers/hwmon/adt7475.c     | 91 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 95 insertions(+)
>
> diff --git a/Documentation/hwmon/adt7475 b/Documentation/hwmon/adt7475
> index dc0b55794c47..09d73a10644c 100644
> --- a/Documentation/hwmon/adt7475
> +++ b/Documentation/hwmon/adt7475
> @@ -114,6 +114,10 @@ minimum (i.e. auto_point1_pwm). This behaviour can be configured using the
>  pwm[1-*]_stall_disable sysfs attribute. A value of 0 means the fans will shut
>  off. A value of 1 means the fans will run at auto_point1_pwm.
>
> +The responsiveness of the ADT747x to temperature changes can be configured.
> +This allows smoothing of the fan speed transition. To set the transition time
> +set the value in ms in the temp[1-*]_smoothing sysfs attribute.
> +
>  Notes
>  -----
>
> diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
> index 3eb8c5c2f8af..3056076fae27 100644
> --- a/drivers/hwmon/adt7475.c
> +++ b/drivers/hwmon/adt7475.c
> @@ -526,6 +526,88 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
>  	return count;
>  }
>
> +/* Assuming CONFIG6[SLOW] is 0 */
> +static const int ad7475_st_map[] = {
> +	37500, 18800, 12500, 7500, 4700, 3100, 1600, 800,
> +};
> +
> +static ssize_t show_temp_st(struct device *dev, struct device_attribute *attr,
> +				  char *buf)
> +{
> +	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct adt7475_data *data = i2c_get_clientdata(client);
> +	long val;
> +
> +	switch (sattr->index) {
> +	case 0:
> +		val = data->enh_acoustics[0] & 0xf;
> +		break;
> +	case 1:
> +		val = (data->enh_acoustics[1] >> 4) & 0xf;
> +		break;
> +	case 2:
> +	default:
> +		val = data->enh_acoustics[1] & 0xf;
> +		break;
> +	}
> +
> +	if (val & 0x8)
> +		return sprintf(buf, "%d\n", ad7475_st_map[val & 0x7]);
> +	else
> +		return sprintf(buf, "0\n");
> +}
> +
> +static ssize_t set_temp_st(struct device *dev, struct device_attribute *attr,
> +				 const char *buf, size_t count)
> +{
> +	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct adt7475_data *data = i2c_get_clientdata(client);
> +	unsigned char reg;
> +	int shift, idx;
> +	ulong val;
> +
> +	if (kstrtoul(buf, 10, &val))
> +		return -EINVAL;
> +
> +	switch (sattr->index) {
> +	case 0:
> +		reg = REG_ENHANCE_ACOUSTICS1;
> +		shift = 0;
> +		idx = 0;
> +		break;
> +	case 1:
> +		reg = REG_ENHANCE_ACOUSTICS2;
> +		shift = 0;
> +		idx = 1;
> +		break;
> +	case 2:
> +	default:
> +		reg = REG_ENHANCE_ACOUSTICS2;
> +		shift = 4;
> +		idx = 1;
> +		break;
> +	}
> +
> +	if (val > 0) {
> +		val = find_closest_descending(val, ad7475_st_map,
> +					      ARRAY_SIZE(ad7475_st_map));
> +		val |= 0x8;
> +	}
> +
> +	mutex_lock(&data->lock);
> +
> +	data->enh_acoustics[idx] &= ~(0xf << shift);
> +	data->enh_acoustics[idx] |= (val << shift);
> +
> +	i2c_smbus_write_byte_data(client, reg, data->enh_acoustics[idx]);
> +
> +	mutex_unlock(&data->lock);
> +
> +	return count;
> +}
> +
>  /*
>   * Table of autorange values - the user will write the value in millidegrees,
>   * and we'll convert it
> @@ -1008,6 +1090,8 @@ static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
>  			    THERM, 0);
>  static SENSOR_DEVICE_ATTR_2(temp1_crit_hyst, S_IRUGO | S_IWUSR, show_temp,
>  			    set_temp, HYSTERSIS, 0);
> +static SENSOR_DEVICE_ATTR_2(temp1_smoothing, S_IRUGO | S_IWUSR, show_temp_st,
> +			    set_temp_st, 0, 0);
>  static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, INPUT, 1);
>  static SENSOR_DEVICE_ATTR_2(temp2_alarm, S_IRUGO, show_temp, NULL, ALARM, 1);
>  static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
> @@ -1024,6 +1108,8 @@ static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
>  			    THERM, 1);
>  static SENSOR_DEVICE_ATTR_2(temp2_crit_hyst, S_IRUGO | S_IWUSR, show_temp,
>  			    set_temp, HYSTERSIS, 1);
> +static SENSOR_DEVICE_ATTR_2(temp2_smoothing, S_IRUGO | S_IWUSR, show_temp_st,
> +			    set_temp_st, 0, 1);
>  static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, INPUT, 2);
>  static SENSOR_DEVICE_ATTR_2(temp3_alarm, S_IRUGO, show_temp, NULL, ALARM, 2);
>  static SENSOR_DEVICE_ATTR_2(temp3_fault, S_IRUGO, show_temp, NULL, FAULT, 2);
> @@ -1041,6 +1127,8 @@ static SENSOR_DEVICE_ATTR_2(temp3_crit, S_IRUGO | S_IWUSR, show_temp, set_temp,
>  			    THERM, 2);
>  static SENSOR_DEVICE_ATTR_2(temp3_crit_hyst, S_IRUGO | S_IWUSR, show_temp,
>  			    set_temp, HYSTERSIS, 2);
> +static SENSOR_DEVICE_ATTR_2(temp3_smoothing, S_IRUGO | S_IWUSR, show_temp_st,
> +			    set_temp_st, 0, 2);
>  static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_tach, NULL, INPUT, 0);
>  static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_tach, set_tach,
>  			    MIN, 0);
> @@ -1125,6 +1213,7 @@ static struct attribute *adt7475_attrs[] = {
>  	&sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr,
>  	&sensor_dev_attr_temp1_crit.dev_attr.attr,
>  	&sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
> +	&sensor_dev_attr_temp1_smoothing.dev_attr.attr,
>  	&sensor_dev_attr_temp2_input.dev_attr.attr,
>  	&sensor_dev_attr_temp2_alarm.dev_attr.attr,
>  	&sensor_dev_attr_temp2_max.dev_attr.attr,
> @@ -1134,6 +1223,7 @@ static struct attribute *adt7475_attrs[] = {
>  	&sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr,
>  	&sensor_dev_attr_temp2_crit.dev_attr.attr,
>  	&sensor_dev_attr_temp2_crit_hyst.dev_attr.attr,
> +	&sensor_dev_attr_temp2_smoothing.dev_attr.attr,
>  	&sensor_dev_attr_temp3_input.dev_attr.attr,
>  	&sensor_dev_attr_temp3_fault.dev_attr.attr,
>  	&sensor_dev_attr_temp3_alarm.dev_attr.attr,
> @@ -1144,6 +1234,7 @@ static struct attribute *adt7475_attrs[] = {
>  	&sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr,
>  	&sensor_dev_attr_temp3_crit.dev_attr.attr,
>  	&sensor_dev_attr_temp3_crit_hyst.dev_attr.attr,
> +	&sensor_dev_attr_temp3_smoothing.dev_attr.attr,
>  	&sensor_dev_attr_fan1_input.dev_attr.attr,
>  	&sensor_dev_attr_fan1_min.dev_attr.attr,
>  	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v4 3/3] hwmon: (adt7475) add high frequency support
  2017-05-15  1:30 ` [PATCH v4 3/3] hwmon: (adt7475) add high frequency support Chris Packham
@ 2017-05-15 13:26   ` Guenter Roeck
  2017-05-15 21:02     ` Chris Packham
  0 siblings, 1 reply; 16+ messages in thread
From: Guenter Roeck @ 2017-05-15 13:26 UTC (permalink / raw)
  To: Chris Packham, linux-hwmon, jdelvare; +Cc: linux-kernel

On 05/14/2017 06:30 PM, Chris Packham wrote:
> Systems using 4-wire fans usually require high frequency (22.5kHz)
> output on the pwm. Add 22500 as a valid option in the pwmfreq_table. In
> high frequency mode the low-order bit are ignored so they can safely be
> set to 0.
>
> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>

Applied to hwmon-next.

Thanks,
Guenter

> ---
> Changes in v3:
> - New
> Changes in v4:
> - Fix pwmfreq_table array indexing
>
>  drivers/hwmon/adt7475.c | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
> index 3056076fae27..1baa213a60bd 100644
> --- a/drivers/hwmon/adt7475.c
> +++ b/drivers/hwmon/adt7475.c
> @@ -934,7 +934,7 @@ static ssize_t set_pwmctrl(struct device *dev, struct device_attribute *attr,
>
>  /* List of frequencies for the PWM */
>  static const int pwmfreq_table[] = {
> -	11, 14, 22, 29, 35, 44, 58, 88
> +	11, 14, 22, 29, 35, 44, 58, 88, 22500
>  };
>
>  static ssize_t show_pwmfreq(struct device *dev, struct device_attribute *attr,
> @@ -942,9 +942,10 @@ static ssize_t show_pwmfreq(struct device *dev, struct device_attribute *attr,
>  {
>  	struct adt7475_data *data = adt7475_update_device(dev);
>  	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
> +	int i = clamp_val(data->range[sattr->index] & 0xf, 0,
> +			  ARRAY_SIZE(pwmfreq_table) - 1);
>
> -	return sprintf(buf, "%d\n",
> -		       pwmfreq_table[data->range[sattr->index] & 7]);
> +	return sprintf(buf, "%d\n", pwmfreq_table[i]);
>  }
>
>  static ssize_t set_pwmfreq(struct device *dev, struct device_attribute *attr,
> @@ -965,7 +966,7 @@ static ssize_t set_pwmfreq(struct device *dev, struct device_attribute *attr,
>
>  	data->range[sattr->index] =
>  		adt7475_read(TEMP_TRANGE_REG(sattr->index));
> -	data->range[sattr->index] &= ~7;
> +	data->range[sattr->index] &= ~0xf;
>  	data->range[sattr->index] |= out;
>
>  	i2c_smbus_write_byte_data(client, TEMP_TRANGE_REG(sattr->index),
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v4 3/3] hwmon: (adt7475) add high frequency support
  2017-05-15 13:26   ` Guenter Roeck
@ 2017-05-15 21:02     ` Chris Packham
  0 siblings, 0 replies; 16+ messages in thread
From: Chris Packham @ 2017-05-15 21:02 UTC (permalink / raw)
  To: Guenter Roeck, linux-hwmon, jdelvare; +Cc: linux-kernel

On 16/05/17 01:26, Guenter Roeck wrote:
> On 05/14/2017 06:30 PM, Chris Packham wrote:
>> Systems using 4-wire fans usually require high frequency (22.5kHz)
>> output on the pwm. Add 22500 as a valid option in the pwmfreq_table. In
>> high frequency mode the low-order bit are ignored so they can safely be
>> set to 0.
>>
>> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
>
> Applied to hwmon-next.
>
> Thanks,
> Guenter
>

Thank you for your feedback (and patience).

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing
  2017-05-15  1:30 ` [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing Chris Packham
  2017-05-15 13:18   ` Guenter Roeck
@ 2017-05-16  8:17   ` kbuild test robot
  2017-05-16 20:30     ` Chris Packham
  1 sibling, 1 reply; 16+ messages in thread
From: kbuild test robot @ 2017-05-16  8:17 UTC (permalink / raw)
  To: Chris Packham
  Cc: kbuild-all, linux, linux-hwmon, jdelvare, Chris Packham,
	Jonathan Corbet, linux-doc, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1421 bytes --]

Hi Chris,

[auto build test ERROR on hwmon/hwmon-next]
[also build test ERROR on v4.12-rc1 next-20170516]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Chris-Packham/hwmon-adt7475-fan-stall-prevention/20170515-093530
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
config: x86_64-rhel (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/hwmon/adt7475.c: In function 'set_temp_st':
>> drivers/hwmon/adt7475.c:622:9: error: implicit declaration of function 'find_closest_descending' [-Werror=implicit-function-declaration]
      val = find_closest_descending(val, ad7475_st_map,
            ^~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/find_closest_descending +622 drivers/hwmon/adt7475.c

   616			shift = 4;
   617			idx = 1;
   618			break;
   619		}
   620	
   621		if (val > 0) {
 > 622			val = find_closest_descending(val, ad7475_st_map,
   623						      ARRAY_SIZE(ad7475_st_map));
   624			val |= 0x8;
   625		}

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 38872 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing
  2017-05-16  8:17   ` kbuild test robot
@ 2017-05-16 20:30     ` Chris Packham
  2017-05-16 22:00       ` Guenter Roeck
  2017-05-17  3:06       ` [kbuild-all] " Ye Xiaolong
  0 siblings, 2 replies; 16+ messages in thread
From: Chris Packham @ 2017-05-16 20:30 UTC (permalink / raw)
  To: kbuild test robot
  Cc: kbuild-all, linux, linux-hwmon, jdelvare, Jonathan Corbet,
	linux-doc, linux-kernel

On 16/05/17 20:23, kbuild test robot wrote:
> Hi Chris,
>
> [auto build test ERROR on hwmon/hwmon-next]
> [also build test ERROR on v4.12-rc1 next-20170516]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url:    https://github.com/0day-ci/linux/commits/Chris-Packham/hwmon-adt7475-fan-stall-prevention/20170515-093530
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
> config: x86_64-rhel (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64
>
> All errors (new ones prefixed by >>):
>
>    drivers/hwmon/adt7475.c: In function 'set_temp_st':
>>> drivers/hwmon/adt7475.c:622:9: error: implicit declaration of function 'find_closest_descending' [-Werror=implicit-function-declaration]
>       val = find_closest_descending(val, ad7475_st_map,
>             ^~~~~~~~~~~~~~~~~~~~~~~
>    cc1: some warnings being treated as errors
>
> vim +/find_closest_descending +622 drivers/hwmon/adt7475.c
>
>    616			shift = 4;
>    617			idx = 1;
>    618			break;
>    619		}
>    620	
>    621		if (val > 0) {
>  > 622			val = find_closest_descending(val, ad7475_st_map,
>    623						      ARRAY_SIZE(ad7475_st_map));
>    624			val |= 0x8;
>    625		}
>
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
>

I'm not sure how this is failing. find_closest_descending() is a macro 
defined in linux/util_macros.h which is explicitly included in 
drivers/hwmon/adt7475.c. Aside from the include guards there's nothing 
conditional about it.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing
  2017-05-16 20:30     ` Chris Packham
@ 2017-05-16 22:00       ` Guenter Roeck
  2017-05-17  3:06       ` [kbuild-all] " Ye Xiaolong
  1 sibling, 0 replies; 16+ messages in thread
From: Guenter Roeck @ 2017-05-16 22:00 UTC (permalink / raw)
  To: Chris Packham
  Cc: kbuild test robot, kbuild-all, linux-hwmon, jdelvare,
	Jonathan Corbet, linux-doc, linux-kernel

On Tue, May 16, 2017 at 08:30:52PM +0000, Chris Packham wrote:
> On 16/05/17 20:23, kbuild test robot wrote:
> > Hi Chris,
> >
> > [auto build test ERROR on hwmon/hwmon-next]
> > [also build test ERROR on v4.12-rc1 next-20170516]
> > [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> >
> > url:    https://github.com/0day-ci/linux/commits/Chris-Packham/hwmon-adt7475-fan-stall-prevention/20170515-093530
> > base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
> > config: x86_64-rhel (attached as .config)
> > compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> > reproduce:
> >         # save the attached .config to linux build tree
> >         make ARCH=x86_64
> >
> > All errors (new ones prefixed by >>):
> >
> >    drivers/hwmon/adt7475.c: In function 'set_temp_st':
> >>> drivers/hwmon/adt7475.c:622:9: error: implicit declaration of function 'find_closest_descending' [-Werror=implicit-function-declaration]
> >       val = find_closest_descending(val, ad7475_st_map,
> >             ^~~~~~~~~~~~~~~~~~~~~~~
> >    cc1: some warnings being treated as errors
> >
> > vim +/find_closest_descending +622 drivers/hwmon/adt7475.c
> >
> >    616			shift = 4;
> >    617			idx = 1;
> >    618			break;
> >    619		}
> >    620	
> >    621		if (val > 0) {
> >  > 622			val = find_closest_descending(val, ad7475_st_map,
> >    623						      ARRAY_SIZE(ad7475_st_map));
> >    624			val |= 0x8;
> >    625		}
> >
> > ---
> > 0-DAY kernel test infrastructure                Open Source Technology Center
> > https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
> >
> 
> I'm not sure how this is failing. find_closest_descending() is a macro 
> defined in linux/util_macros.h which is explicitly included in 
> drivers/hwmon/adt7475.c. Aside from the include guards there's nothing 
> conditional about it.

I suspect it was tested out of sequence, without the preceding patches,
and the header file include was missing.

Guenter

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [kbuild-all] [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing
  2017-05-16 20:30     ` Chris Packham
  2017-05-16 22:00       ` Guenter Roeck
@ 2017-05-17  3:06       ` Ye Xiaolong
  2017-05-17  3:26         ` Chris Packham
  1 sibling, 1 reply; 16+ messages in thread
From: Ye Xiaolong @ 2017-05-17  3:06 UTC (permalink / raw)
  To: Chris Packham
  Cc: kbuild test robot, linux-hwmon, jdelvare, linux-doc,
	Jonathan Corbet, linux-kernel, kbuild-all, linux

On 05/16, Chris Packham wrote:
>On 16/05/17 20:23, kbuild test robot wrote:
>> Hi Chris,
>>
>> [auto build test ERROR on hwmon/hwmon-next]
>> [also build test ERROR on v4.12-rc1 next-20170516]
>> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>>
>> url:    https://github.com/0day-ci/linux/commits/Chris-Packham/hwmon-adt7475-fan-stall-prevention/20170515-093530
>> base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
>> config: x86_64-rhel (attached as .config)
>> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
>> reproduce:
>>         # save the attached .config to linux build tree
>>         make ARCH=x86_64
>>
>> All errors (new ones prefixed by >>):
>>
>>    drivers/hwmon/adt7475.c: In function 'set_temp_st':
>>>> drivers/hwmon/adt7475.c:622:9: error: implicit declaration of function 'find_closest_descending' [-Werror=implicit-function-declaration]
>>       val = find_closest_descending(val, ad7475_st_map,
>>             ^~~~~~~~~~~~~~~~~~~~~~~
>>    cc1: some warnings being treated as errors
>>
>> vim +/find_closest_descending +622 drivers/hwmon/adt7475.c
>>
>>    616			shift = 4;
>>    617			idx = 1;
>>    618			break;
>>    619		}
>>    620	
>>    621		if (val > 0) {
>>  > 622			val = find_closest_descending(val, ad7475_st_map,
>>    623						      ARRAY_SIZE(ad7475_st_map));
>>    624			val |= 0x8;
>>    625		}
>>
>> ---
>> 0-DAY kernel test infrastructure                Open Source Technology Center
>> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
>>
>
>I'm not sure how this is failing. find_closest_descending() is a macro 
>defined in linux/util_macros.h which is explicitly included in 
>drivers/hwmon/adt7475.c. Aside from the include guards there's nothing 
>conditional about it.

Hi,

0day bot applied your patchset on top of commit 6eaaea1 ("hwmon: (pmbus) Add client driver for IR35221"),
is it wrong or you have some prerequisite patches?

Thanks,
Xiaolong
>_______________________________________________
>kbuild-all mailing list
>kbuild-all@lists.01.org
>https://lists.01.org/mailman/listinfo/kbuild-all

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [kbuild-all] [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing
  2017-05-17  3:06       ` [kbuild-all] " Ye Xiaolong
@ 2017-05-17  3:26         ` Chris Packham
  2017-05-17  4:39           ` Ye Xiaolong
  0 siblings, 1 reply; 16+ messages in thread
From: Chris Packham @ 2017-05-17  3:26 UTC (permalink / raw)
  To: Ye Xiaolong
  Cc: kbuild test robot, linux-hwmon, jdelvare, linux-doc,
	Jonathan Corbet, linux-kernel, kbuild-all, linux

On 17/05/17 15:09, Ye Xiaolong wrote:
> On 05/16, Chris Packham wrote:
>> On 16/05/17 20:23, kbuild test robot wrote:
>>> Hi Chris,
>>>
>>> [auto build test ERROR on hwmon/hwmon-next]
>>> [also build test ERROR on v4.12-rc1 next-20170516]
>>> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>>>
>>> url:    https://github.com/0day-ci/linux/commits/Chris-Packham/hwmon-adt7475-fan-stall-prevention/20170515-093530
>>> base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
>>> config: x86_64-rhel (attached as .config)
>>> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
>>> reproduce:
>>>         # save the attached .config to linux build tree
>>>         make ARCH=x86_64
>>>
>>> All errors (new ones prefixed by >>):
>>>
>>>    drivers/hwmon/adt7475.c: In function 'set_temp_st':
>>>>> drivers/hwmon/adt7475.c:622:9: error: implicit declaration of function 'find_closest_descending' [-Werror=implicit-function-declaration]
>>>       val = find_closest_descending(val, ad7475_st_map,
>>>             ^~~~~~~~~~~~~~~~~~~~~~~
>>>    cc1: some warnings being treated as errors
>>>
>>> vim +/find_closest_descending +622 drivers/hwmon/adt7475.c
>>>
>>>    616			shift = 4;
>>>    617			idx = 1;
>>>    618			break;
>>>    619		}
>>>    620	
>>>    621		if (val > 0) {
>>>  > 622			val = find_closest_descending(val, ad7475_st_map,
>>>    623						      ARRAY_SIZE(ad7475_st_map));
>>>    624			val |= 0x8;
>>>    625		}
>>>
>>> ---
>>> 0-DAY kernel test infrastructure                Open Source Technology Center
>>> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
>>>
>>
>> I'm not sure how this is failing. find_closest_descending() is a macro
>> defined in linux/util_macros.h which is explicitly included in
>> drivers/hwmon/adt7475.c. Aside from the include guards there's nothing
>> conditional about it.
>
> Hi,
>
> 0day bot applied your patchset on top of commit 6eaaea1 ("hwmon: (pmbus) Add client driver for IR35221"),
> is it wrong or you have some prerequisite patches?
>

Looks like it's missing 
https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git/commit/?h=hwmon-next&id=bbb4dd0ff 
which was part of the series but was applied after v3 so I didn't send 
it out with v4.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [kbuild-all] [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing
  2017-05-17  3:26         ` Chris Packham
@ 2017-05-17  4:39           ` Ye Xiaolong
  2017-05-17  5:24             ` Guenter Roeck
  0 siblings, 1 reply; 16+ messages in thread
From: Ye Xiaolong @ 2017-05-17  4:39 UTC (permalink / raw)
  To: Chris Packham
  Cc: kbuild test robot, linux-hwmon, jdelvare, linux-doc,
	Jonathan Corbet, linux-kernel, kbuild-all, linux

On 05/17, Chris Packham wrote:
>On 17/05/17 15:09, Ye Xiaolong wrote:
>> On 05/16, Chris Packham wrote:
>>> On 16/05/17 20:23, kbuild test robot wrote:
>>>> Hi Chris,
>>>>
>>>> [auto build test ERROR on hwmon/hwmon-next]
>>>> [also build test ERROR on v4.12-rc1 next-20170516]
>>>> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>>>>
>>>> url:    https://github.com/0day-ci/linux/commits/Chris-Packham/hwmon-adt7475-fan-stall-prevention/20170515-093530
>>>> base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
>>>> config: x86_64-rhel (attached as .config)
>>>> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
>>>> reproduce:
>>>>         # save the attached .config to linux build tree
>>>>         make ARCH=x86_64
>>>>
>>>> All errors (new ones prefixed by >>):
>>>>
>>>>    drivers/hwmon/adt7475.c: In function 'set_temp_st':
>>>>>> drivers/hwmon/adt7475.c:622:9: error: implicit declaration of function 'find_closest_descending' [-Werror=implicit-function-declaration]
>>>>       val = find_closest_descending(val, ad7475_st_map,
>>>>             ^~~~~~~~~~~~~~~~~~~~~~~
>>>>    cc1: some warnings being treated as errors
>>>>
>>>> vim +/find_closest_descending +622 drivers/hwmon/adt7475.c
>>>>
>>>>    616			shift = 4;
>>>>    617			idx = 1;
>>>>    618			break;
>>>>    619		}
>>>>    620	
>>>>    621		if (val > 0) {
>>>>  > 622			val = find_closest_descending(val, ad7475_st_map,
>>>>    623						      ARRAY_SIZE(ad7475_st_map));
>>>>    624			val |= 0x8;
>>>>    625		}
>>>>
>>>> ---
>>>> 0-DAY kernel test infrastructure                Open Source Technology Center
>>>> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
>>>>
>>>
>>> I'm not sure how this is failing. find_closest_descending() is a macro
>>> defined in linux/util_macros.h which is explicitly included in
>>> drivers/hwmon/adt7475.c. Aside from the include guards there's nothing
>>> conditional about it.
>>
>> Hi,
>>
>> 0day bot applied your patchset on top of commit 6eaaea1 ("hwmon: (pmbus) Add client driver for IR35221"),
>> is it wrong or you have some prerequisite patches?

Thanks for the info, seems we need to improve the kbuild bot by pulling the
latest tree before applying new patches.

Thanks,
Xiaolong
>>
>
>Looks like it's missing 
>https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git/commit/?h=hwmon-next&id=bbb4dd0ff 
>which was part of the series but was applied after v3 so I didn't send 
>it out with v4.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [kbuild-all] [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing
  2017-05-17  4:39           ` Ye Xiaolong
@ 2017-05-17  5:24             ` Guenter Roeck
  2017-05-18  3:05               ` Ye Xiaolong
  0 siblings, 1 reply; 16+ messages in thread
From: Guenter Roeck @ 2017-05-17  5:24 UTC (permalink / raw)
  To: Ye Xiaolong, Chris Packham
  Cc: kbuild test robot, linux-hwmon, jdelvare, linux-doc,
	Jonathan Corbet, linux-kernel, kbuild-all

On 05/16/2017 09:39 PM, Ye Xiaolong wrote:
> On 05/17, Chris Packham wrote:
>> On 17/05/17 15:09, Ye Xiaolong wrote:
>>> On 05/16, Chris Packham wrote:
>>>> On 16/05/17 20:23, kbuild test robot wrote:
>>>>> Hi Chris,
>>>>>
>>>>> [auto build test ERROR on hwmon/hwmon-next]
>>>>> [also build test ERROR on v4.12-rc1 next-20170516]
>>>>> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>>>>>
>>>>> url:    https://github.com/0day-ci/linux/commits/Chris-Packham/hwmon-adt7475-fan-stall-prevention/20170515-093530
>>>>> base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
>>>>> config: x86_64-rhel (attached as .config)
>>>>> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
>>>>> reproduce:
>>>>>         # save the attached .config to linux build tree
>>>>>         make ARCH=x86_64
>>>>>
>>>>> All errors (new ones prefixed by >>):
>>>>>
>>>>>    drivers/hwmon/adt7475.c: In function 'set_temp_st':
>>>>>>> drivers/hwmon/adt7475.c:622:9: error: implicit declaration of function 'find_closest_descending' [-Werror=implicit-function-declaration]
>>>>>       val = find_closest_descending(val, ad7475_st_map,
>>>>>             ^~~~~~~~~~~~~~~~~~~~~~~
>>>>>    cc1: some warnings being treated as errors
>>>>>
>>>>> vim +/find_closest_descending +622 drivers/hwmon/adt7475.c
>>>>>
>>>>>    616			shift = 4;
>>>>>    617			idx = 1;
>>>>>    618			break;
>>>>>    619		}
>>>>>    620	
>>>>>    621		if (val > 0) {
>>>>>  > 622			val = find_closest_descending(val, ad7475_st_map,
>>>>>    623						      ARRAY_SIZE(ad7475_st_map));
>>>>>    624			val |= 0x8;
>>>>>    625		}
>>>>>
>>>>> ---
>>>>> 0-DAY kernel test infrastructure                Open Source Technology Center
>>>>> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
>>>>>
>>>>
>>>> I'm not sure how this is failing. find_closest_descending() is a macro
>>>> defined in linux/util_macros.h which is explicitly included in
>>>> drivers/hwmon/adt7475.c. Aside from the include guards there's nothing
>>>> conditional about it.
>>>
>>> Hi,
>>>
>>> 0day bot applied your patchset on top of commit 6eaaea1 ("hwmon: (pmbus) Add client driver for IR35221"),
>>> is it wrong or you have some prerequisite patches?
>
> Thanks for the info, seems we need to improve the kbuild bot by pulling the
> latest tree before applying new patches.
>

No worries. I don't mind the occasional false positive. Better a false positive than a missed bug.

Guenter

> Thanks,
> Xiaolong
>>>
>>
>> Looks like it's missing
>> https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git/commit/?h=hwmon-next&id=bbb4dd0ff
>> which was part of the series but was applied after v3 so I didn't send
>> it out with v4.
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [kbuild-all] [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing
  2017-05-17  5:24             ` Guenter Roeck
@ 2017-05-18  3:05               ` Ye Xiaolong
  2017-05-18  4:09                 ` Guenter Roeck
  0 siblings, 1 reply; 16+ messages in thread
From: Ye Xiaolong @ 2017-05-18  3:05 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Chris Packham, kbuild test robot, linux-hwmon, jdelvare,
	linux-doc, Jonathan Corbet, linux-kernel, kbuild-all

On 05/16, Guenter Roeck wrote:
>>>>0day bot applied your patchset on top of commit 6eaaea1 ("hwmon: (pmbus) Add client driver for IR35221"),
>>>>is it wrong or you have some prerequisite patches?
>>
>>Thanks for the info, seems we need to improve the kbuild bot by pulling the
>>latest tree before applying new patches.
>>
>
>No worries. I don't mind the occasional false positive. Better a false positive than a missed bug.
>

Just curiosity, I noticed you committed the missing patch bbb4dd0fff ("hwmon:
(adt7475) replace find_nearest() with find_closest()") at May 14, did you push
it to git.kernel.org immediately or sometime after that? Since 0day makes
mirror based on repos in git.kernel.org in this case.

Thanks,
Xiaolong

>Guenter
>
>>Thanks,
>>Xiaolong
>>>>
>>>
>>>Looks like it's missing
>>>https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git/commit/?h=hwmon-next&id=bbb4dd0ff
>>>which was part of the series but was applied after v3 so I didn't send
>>>it out with v4.
>>
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [kbuild-all] [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing
  2017-05-18  3:05               ` Ye Xiaolong
@ 2017-05-18  4:09                 ` Guenter Roeck
  0 siblings, 0 replies; 16+ messages in thread
From: Guenter Roeck @ 2017-05-18  4:09 UTC (permalink / raw)
  To: Ye Xiaolong
  Cc: Chris Packham, kbuild test robot, linux-hwmon, jdelvare,
	linux-doc, Jonathan Corbet, linux-kernel, kbuild-all

On 05/17/2017 08:05 PM, Ye Xiaolong wrote:
> On 05/16, Guenter Roeck wrote:
>>>>> 0day bot applied your patchset on top of commit 6eaaea1 ("hwmon: (pmbus) Add client driver for IR35221"),
>>>>> is it wrong or you have some prerequisite patches?
>>>
>>> Thanks for the info, seems we need to improve the kbuild bot by pulling the
>>> latest tree before applying new patches.
>>>
>>
>> No worries. I don't mind the occasional false positive. Better a false positive than a missed bug.
>>
>
> Just curiosity, I noticed you committed the missing patch bbb4dd0fff ("hwmon:
> (adt7475) replace find_nearest() with find_closest()") at May 14, did you push
> it to git.kernel.org immediately or sometime after that? Since 0day makes
> mirror based on repos in git.kernel.org in this case.
>

I don't recall, sorry. Most likely I didn't push it immediately.

Guenter

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2017-05-18  4:09 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20170515013029.31397-1-chris.packham@alliedtelesis.co.nz>
2017-05-15  1:30 ` [PATCH v4 1/3] hwmon: (adt7475) fan stall prevention Chris Packham
2017-05-15 13:16   ` Guenter Roeck
2017-05-15  1:30 ` [PATCH v4 2/3] hwmon: (adt7475) temperature smoothing Chris Packham
2017-05-15 13:18   ` Guenter Roeck
2017-05-16  8:17   ` kbuild test robot
2017-05-16 20:30     ` Chris Packham
2017-05-16 22:00       ` Guenter Roeck
2017-05-17  3:06       ` [kbuild-all] " Ye Xiaolong
2017-05-17  3:26         ` Chris Packham
2017-05-17  4:39           ` Ye Xiaolong
2017-05-17  5:24             ` Guenter Roeck
2017-05-18  3:05               ` Ye Xiaolong
2017-05-18  4:09                 ` Guenter Roeck
2017-05-15  1:30 ` [PATCH v4 3/3] hwmon: (adt7475) add high frequency support Chris Packham
2017-05-15 13:26   ` Guenter Roeck
2017-05-15 21:02     ` Chris Packham

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).