From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: Thomas Haschka <haschka@gmail.com>
Cc: linuxppc-dev@lists.ozlabs.org
Subject: Re: [PATCH 1/1]: thermal driver therm_adt746.c
Date: Fri, 27 Mar 2015 08:31:28 +1100 [thread overview]
Message-ID: <1427405488.6468.140.camel@kernel.crashing.org> (raw)
In-Reply-To: <20150326162358.GA1025@gmail.com>
On Thu, 2015-03-26 at 17:23 +0100, Thomas Haschka wrote:
> Hello,
>
> Here's an updated version taking your suggested changements into account
> (merged the two loops into one, changed a hardcoded value into a constant).
Can you still move the core of the loop into a helper function ? There
is still too much code duplication....
> Just to keep everything together, hereare the changements:
>
> 1. changes in sensors limits, we are down from 70, 50, 70
> to 45, 50, 70, where the first value is the environement sensor that is
> located on the bottumside of the Harddrive. Empirical testing
> shows that this speeds up the Fan almoast in the same moment as in OS X
>
> 2. A function has been added in order to take the environement sensor into
> account on SingleFan Apple Notebooks (i.e. those that have air inlets
> next to the harddrive and that are cooling, besides other components
> using the single fan in these machines.
>
> 3. Output values in /sys/devices/temperatures/ etc.. have been changed.
> First: All three sensors can be monitored right now instead of only the
> GPU and CPU sensors.
> Second: The units have been changed in order to correspond to the units
> given by other temperature sensors, such as the coretemp (intel) sensor.
> This allows to monitor them using several applications, notably xosview.
>
> Signed-off-by: Thomas Haschka <haschka@gmail.com>
> ---
> drivers/macintosh/therm_adt746x.c | 123 +++++++++++++++++++++++++++++++++++---
> 1 file changed, 114 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
> index f433521..1a36ea44 100644
> --- a/drivers/macintosh/therm_adt746x.c
> +++ b/drivers/macintosh/therm_adt746x.c
> @@ -1,7 +1,8 @@
> /*
> * Device driver for the i2c thermostat found on the iBook G4, Albook G4
> *
> - * Copyright (C) 2003, 2004 Colin Leroy, Rasmus Rohde, Benjamin Herrenschmidt
> + * Copyright (C) 2003, 2004, 2015
> + * Colin Leroy, Rasmus Rohde, Benjamin Herrenschmidt, Thomas Haschka
> *
> * Documentation from 115254175ADT7467_pra.pdf and 3686221171167ADT7460_b.pdf
> * http://www.onsemi.com/PowerSolutions/product.do?id=ADT7467
> @@ -45,8 +46,10 @@ static u8 REM_CONTROL[2] = {0x00, 0x40};
> static u8 FAN_SPEED[2] = {0x28, 0x2a};
> static u8 FAN_SPD_SET[2] = {0x30, 0x31};
>
> -static u8 default_limits_local[3] = {70, 50, 70}; /* local, sensor1, sensor2 */
> -static u8 default_limits_chip[3] = {80, 65, 80}; /* local, sensor1, sensor2 */
> +/* Local sensor is down to 45 in order to assure stable harddrive and
> + * components temperature on single fan machines */
> +static u8 default_limits_local[3] = {45, 50, 70}; /* local, sensor1, sensor2 */
> +static u8 default_limits_chip[3] = {80, 65, 80}; /* local, sensor1, sensor2 */
> static const char *sensor_location[3] = { "?", "?", "?" };
>
> static int limit_adjust;
> @@ -223,7 +226,7 @@ static void display_stats(struct thermostat *th)
> }
> #endif
>
> -static void update_fans_speed (struct thermostat *th)
> +static void update_fans_speed_multifan (struct thermostat *th)
> {
> int lastvar = 0; /* last variation, for iBook */
> int i = 0;
> @@ -278,6 +281,88 @@ static void update_fans_speed (struct thermostat *th)
> }
> }
>
> +static void update_fans_speed_singlefan (struct thermostat *th) {
> +
> + /* Single Fan Laptops i.e. 12 inch Powerbook, Ibook etc.
> + * Necessites the readout of all three thermal sensors
> + * in order to avoid the harddisk and other components to overheat
> + * in the case of cold CPU. */
> +
> + int lastvar = 0; /* last variation, for iBook */
> + int i = 0;
> + int var = 0;
> + int var_sensor[3];
> + int started = 0;
> + const int fan_number = 0;
> +
> + /* select the highest delta from all three sensors and store it to var
> + */
> +
> + var_sensor[0] = th->temps[0] - th->limits[0];
> + var = var_sensor[0];
> +
> + for (i = 1; i < 3; i++) {
> + var_sensor[i] = th->temps[i] - th->limits[i];
> + if (var_sensor[i] > var) {
> + var = var_sensor[i];
> + }
> + }
> +
> + if (var > -1) {
> + int step = (255 - fan_speed) / 7;
> + int new_speed = 0;
> + /* hysteresis : change fan speed only if variation is
> + * more than two degrees */
> + if (abs(var - th->last_var[fan_number]) > 2) {
> +
> + started = 1;
> + new_speed = fan_speed + ((var-1)*step);
> +
> + if (new_speed < fan_speed)
> + new_speed = fan_speed;
> + if (new_speed > 255)
> + new_speed = 255;
> +
> + if (verbose)
> + printk(KERN_DEBUG "adt746x:"
> + " Setting fans speed to %d "
> + "(limit exceeded by %d on %s)\n",
> + new_speed, var,
> + sensor_location[fan_number+1]);
> + write_both_fan_speed(th, new_speed);
> + th->last_var[fan_number] = var;
> + }
> + } else if (var < -2) {
> + /* don't stop fan if sensor2 is cold and sensor1 is not
> + * so cold (lastvar >= -1) */
> + if (i == 2 && lastvar < -1) {
> + if (th->last_speed[fan_number] != 0)
> + if (verbose)
> + printk(KERN_DEBUG "adt746x:"
> + " Stopping "
> + "fans.\n");
> + write_both_fan_speed(th, 0);
> + }
> + }
> +
> + lastvar = var;
> +
> + if (started)
> + return; /* we don't want to re-stop the fan
> + * if sensor1 is heating and sensor2 is not */
> +}
> +
> +static void update_fans_speed(struct thermostat *th) {
> +
> + if (th->type == ADT7460) {
> + /* Multifan Laptops */
> + update_fans_speed_multifan(th);
> + } else {
> + /* Singlefan Laptops i.e. 12 inch Powerbook, Ibook etc. */
> + update_fans_speed_singlefan(th);
> + }
> +}
> +
> static int monitor_task(void *arg)
> {
> struct thermostat* th = arg;
> @@ -371,10 +456,18 @@ static ssize_t store_##name(struct device *dev, struct device_attribute *attr, c
> return n; \
> }
>
> -BUILD_SHOW_FUNC_INT(sensor1_temperature, (read_reg(th, TEMP_REG[1])))
> -BUILD_SHOW_FUNC_INT(sensor2_temperature, (read_reg(th, TEMP_REG[2])))
> -BUILD_SHOW_FUNC_INT(sensor1_limit, th->limits[1])
> -BUILD_SHOW_FUNC_INT(sensor2_limit, th->limits[2])
> +/* Several units are multiplied by 1000 in order to have
> + * coherent readings with other
> + * temperature sensors such as intel coretemp. This further
> + * allows programs such as xosview to read these sensors correctly */
> +
> +BUILD_SHOW_FUNC_INT(sensor0_temperature, (read_reg(th, TEMP_REG[0]))*1000)
> +BUILD_SHOW_FUNC_INT(sensor1_temperature, (read_reg(th, TEMP_REG[1]))*1000)
> +BUILD_SHOW_FUNC_INT(sensor2_temperature, (read_reg(th, TEMP_REG[2]))*1000)
> +BUILD_SHOW_FUNC_INT(sensor0_limit, (th->limits[0])*1000)
> +BUILD_SHOW_FUNC_INT(sensor1_limit, (th->limits[1])*1000)
> +BUILD_SHOW_FUNC_INT(sensor2_limit, (th->limits[2])*1000)
> +BUILD_SHOW_FUNC_STR(sensor0_location, sensor_location[0])
> BUILD_SHOW_FUNC_STR(sensor1_location, sensor_location[1])
> BUILD_SHOW_FUNC_STR(sensor2_location, sensor_location[2])
>
> @@ -387,14 +480,20 @@ BUILD_SHOW_FUNC_FAN(sensor2_fan_speed, 1)
> BUILD_SHOW_FUNC_INT_LITE(limit_adjust, limit_adjust)
> BUILD_STORE_FUNC_DEG(limit_adjust, th)
>
> +static DEVICE_ATTR(sensor0_temperature, S_IRUGO,
> + show_sensor0_temperature,NULL);
> static DEVICE_ATTR(sensor1_temperature, S_IRUGO,
> show_sensor1_temperature,NULL);
> static DEVICE_ATTR(sensor2_temperature, S_IRUGO,
> show_sensor2_temperature,NULL);
> +static DEVICE_ATTR(sensor0_limit, S_IRUGO,
> + show_sensor0_limit, NULL);
> static DEVICE_ATTR(sensor1_limit, S_IRUGO,
> show_sensor1_limit, NULL);
> static DEVICE_ATTR(sensor2_limit, S_IRUGO,
> show_sensor2_limit, NULL);
> +static DEVICE_ATTR(sensor0_location, S_IRUGO,
> + show_sensor0_location, NULL);
> static DEVICE_ATTR(sensor1_location, S_IRUGO,
> show_sensor1_location, NULL);
> static DEVICE_ATTR(sensor2_location, S_IRUGO,
> @@ -426,10 +525,13 @@ static void thermostat_create_files(struct thermostat *th)
> return;
> dev = &th->pdev->dev;
> dev_set_drvdata(dev, th);
> - err = device_create_file(dev, &dev_attr_sensor1_temperature);
> + err = device_create_file(dev, &dev_attr_sensor0_temperature);
> + err |= device_create_file(dev, &dev_attr_sensor1_temperature);
> err |= device_create_file(dev, &dev_attr_sensor2_temperature);
> + err |= device_create_file(dev, &dev_attr_sensor0_limit);
> err |= device_create_file(dev, &dev_attr_sensor1_limit);
> err |= device_create_file(dev, &dev_attr_sensor2_limit);
> + err |= device_create_file(dev, &dev_attr_sensor0_location);
> err |= device_create_file(dev, &dev_attr_sensor1_location);
> err |= device_create_file(dev, &dev_attr_sensor2_location);
> err |= device_create_file(dev, &dev_attr_limit_adjust);
> @@ -449,10 +551,13 @@ static void thermostat_remove_files(struct thermostat *th)
> if (!th->pdev)
> return;
> dev = &th->pdev->dev;
> + device_remove_file(dev, &dev_attr_sensor0_temperature);
> device_remove_file(dev, &dev_attr_sensor1_temperature);
> device_remove_file(dev, &dev_attr_sensor2_temperature);
> + device_remove_file(dev, &dev_attr_sensor0_limit);
> device_remove_file(dev, &dev_attr_sensor1_limit);
> device_remove_file(dev, &dev_attr_sensor2_limit);
> + device_remove_file(dev, &dev_attr_sensor0_location);
> device_remove_file(dev, &dev_attr_sensor1_location);
> device_remove_file(dev, &dev_attr_sensor2_location);
> device_remove_file(dev, &dev_attr_limit_adjust);
prev parent reply other threads:[~2015-03-26 21:31 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-23 11:58 [PATCH 1/1]: thermal driver therm_adt746.c Thomas Haschka
2015-02-23 15:23 ` Cedric Le Goater
2015-02-23 21:18 ` Benjamin Herrenschmidt
2015-02-25 11:24 ` Thomas Haschka
2015-02-25 21:12 ` Benjamin Herrenschmidt
2015-02-26 9:48 ` Thomas Haschka
2015-03-25 5:36 ` Benjamin Herrenschmidt
2015-03-26 16:23 ` Thomas Haschka
2015-03-26 21:31 ` Benjamin Herrenschmidt [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1427405488.6468.140.camel@kernel.crashing.org \
--to=benh@kernel.crashing.org \
--cc=haschka@gmail.com \
--cc=linuxppc-dev@lists.ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.