From: Guenter Roeck <linux@roeck-us.net>
To: Goffredo Baroncelli <kreijack@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>,
LKML <linux-kernel@vger.kernel.org>,
Jean Delvare <jdelvare@suse.de>,
Goffredo Baroncelli <kreijack@iniwnd.it>,
Goffredo Baroncelli <kreijack@inwind.it>
Subject: Re: [PATCH 5/5] Export the temperatures via hwmon
Date: Wed, 6 Aug 2014 16:18:03 -0700 [thread overview]
Message-ID: <20140806231803.GA5643@roeck-us.net> (raw)
In-Reply-To: <1407359103-6012-6-git-send-email-kreijack@inwind.it>
On Wed, Aug 06, 2014 at 09:05:03PM +0000, Goffredo Baroncelli wrote:
> From: Goffredo Baroncelli <kreijack@iniwnd.it>
>
> Export the temperature via the hwmon subsystem.
> See the list below for the sensors exported:
>
> $ cd /sys/devices/temperature/hwmon/hwmon0
> $ echo "name: $(cat name)"; for i in temp*; do echo "$i: $(cat $i)"; done
> name: therm_windtunnel
> temp1_input: 59312
> temp1_label: CPU
> temp2_input: 36750
> temp2_label: Case
> temp3_input: 37750
> temp3_label: Case2
>
Makes me wonder why you don't report the fan speed through hwmon.
> The Case2 temperature is the sensor temperature inside the adm1030.
>
There are standard hwmon drivers for lm75, ds1775, and adm1030.
Personally I think it would make more sense to use those directly.
But I guess that would be for another day.
> Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
> ---
> drivers/macintosh/therm_windtunnel.c | 103 +++++++++++++++++++++++++++++++++--
> 1 file changed, 99 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
> index b6cba98..a6757d7 100644
> --- a/drivers/macintosh/therm_windtunnel.c
> +++ b/drivers/macintosh/therm_windtunnel.c
> @@ -37,6 +37,8 @@
> #include <linux/init.h>
> #include <linux/kthread.h>
> #include <linux/of_platform.h>
> +#include <linux/hwmon.h>
> +#include <linux/hwmon-sysfs.h>
>
> #include <asm/prom.h>
> #include <asm/machdep.h>
> @@ -58,9 +60,12 @@ static struct {
> struct i2c_client *thermostat;
> struct i2c_client *fan;
>
> + struct device *hwmon;
> +
> int overheat_temp; /* 100% fan at this temp */
> int overheat_hyst;
> int temp;
> + int casetemp2;
> int casetemp;
> int fan_level; /* active fan_table setting */
>
> @@ -120,6 +125,75 @@ static DEVICE_ATTR(case_temperature, S_IRUGO, show_case_temperature, NULL );
> static DEVICE_ATTR(fan_level, S_IRUGO, show_fan_level, NULL);
>
>
> +static ssize_t
> +show_temp1(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> + return sprintf(buf, "%d%03d\n", x.temp>>8, (x.temp & 0xff)*1000>>8);
I personally prefer if code follows coding style, with spaces around operands,
and if calculations are less cryptic.
> +}
> +
> +static ssize_t
> +show_temp1_label(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> + return sprintf(buf, "CPU\n");
> +}
> +
> +static ssize_t
> +show_temp2(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> + return sprintf(buf, "%d%03d\n", x.casetemp>>8,
> + (x.casetemp & 0xff)*1000>>8);
> +}
> +
> +static ssize_t
> +show_temp2_label(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> + return sprintf(buf, "Case\n");
> +}
> +
> +
> +static ssize_t
> +show_temp3(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> + return sprintf(buf, "%d%03d\n", x.casetemp2>>8,
> + (x.casetemp2 & 0xff)*1000>>8);
... and aligned second lines.
> +}
> +
> +static ssize_t
> +show_temp3_label(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> + return sprintf(buf, "Case2\n");
> +}
> +
> +#define TWT_ATTRIB(name, func) \
> + static SENSOR_DEVICE_ATTR(name##_input, S_IRUGO, func, NULL, 0); \
> + static SENSOR_DEVICE_ATTR(name##_label, S_IRUGO, func##_label, \
> + NULL, 0)
> +
> +TWT_ATTRIB(temp1, show_temp1);
> +TWT_ATTRIB(temp2, show_temp2);
> +TWT_ATTRIB(temp3, show_temp3);
> +
> +
A single empty line should be sufficient. Personally I am also not
a fan of such macros (and neither is checkpatch), and prefer the use
of direct macros as less confusing.
Also, using three different functions for three different attributes
where the only difference is the variable name defeats the purpose
of using SENSOR_DEVICE_ATTR, which has an index variable for exactly
that reason. I would suggest to either use an indexed array to access
the temperatures, or use DEVICE_ATTR.
> +static struct attribute *therm_windtunnel_attributes[] = {
> + &sensor_dev_attr_temp1_input.dev_attr.attr,
> + &sensor_dev_attr_temp1_label.dev_attr.attr,
> + &sensor_dev_attr_temp2_input.dev_attr.attr,
> + &sensor_dev_attr_temp2_label.dev_attr.attr,
> + &sensor_dev_attr_temp3_input.dev_attr.attr,
> + &sensor_dev_attr_temp3_label.dev_attr.attr,
> +
> + NULL,
> +};
> +
> +static const struct attribute_group therm_windtunnel_attr_group = {
> + .attrs = therm_windtunnel_attributes,
> +};
> +
> +static const struct attribute_group *therm_windtunnel_attr_groups[] = {
> + &therm_windtunnel_attr_group,
> + NULL,
> +};
ATTRIBUTE_GROUPS() is a nice and useful macro.
> +
> /************************************************************************/
> /* controller thread */
> /************************************************************************/
> @@ -172,16 +246,23 @@ tune_fan( int fan_setting )
> static void
> poll_temp( void )
> {
> - int temp, i, level, casetemp, tempchanged;
> + int temp, i, level, casetemp, tempchanged, casetemp2, reg06;
>
> + /* temperature read from ds1775 */
> temp = read_reg( x.thermostat, 0, 2 );
>
> /* this actually occurs when the computer is loaded */
> if( temp < 0 )
> return;
>
> - casetemp = read_reg(x.fan, 0x0b, 1) << 8;
> - casetemp |= (read_reg(x.fan, 0x06, 1) & 0x7) << 5;
> + /*
> + * temperatures read from the adm1030
> + * casetemp is the external temperature sensor
> + * casetemp2 is the internal temperature sensor
> + */
What if there is no adm1030 ? Or is that always there ?
Just wondering.
> + reg06 = read_reg(x.fan, 0x06, 1);
> + casetemp = (read_reg(x.fan, 0x0b, 1) << 8) | (reg06 & 0x07 << 5);
> + casetemp2 = (read_reg(x.fan, 0x0a, 1) << 8) | (reg06 & 0xc0);
>
> level = -1;
> for( i=0; (temp & 0xffff) > fan_table[i].temp ; i++ )
> @@ -200,13 +281,16 @@ poll_temp( void )
> * if verbose >0 log each fan tuning
> * if verbose >1 log each cpu temperature change
> */
> - tempchanged = x.temp != temp || x.casetemp != casetemp;
> + tempchanged = x.temp != temp || x.casetemp != casetemp ||
> + x.casetemp2 != casetemp2;
> if ((verbose > 1 && tempchanged) ||
> (verbose > 0 && level >= 0)) {
> printk(KERN_INFO);
> print_temp("CPU-temp: ", temp);
> if (casetemp)
> print_temp(", Case: ", casetemp);
> + if (casetemp2)
> + print_temp(", Case2: ", casetemp2);
> if (level >= 0)
> printk(", Fan: %d (tuned %+d)\n", 11-level,
> x.fan_level-level);
Wow, this logging must clutter the kernel log quite substantially
if enabled.
> @@ -216,6 +300,7 @@ poll_temp( void )
>
> x.temp = temp;
> x.casetemp = casetemp;
> + x.casetemp2 = casetemp2;
>
> if( level >= 0 )
> tune_fan( level );
> @@ -275,11 +360,21 @@ setup_hardware( void )
> if (err)
> printk(KERN_WARNING
> "Failed to create temperature attribute file(s).\n");
> +
> + x.hwmon = hwmon_device_register_with_groups(&x.of_dev->dev,
> + "therm_windtunnel", NULL,
> + therm_windtunnel_attr_groups);
> + if (!x.hwmon)
> + dev_warn(&x.of_dev->dev, "Failed to create the hwmon device\n");
> }
>
> static void
> restore_regs( void )
> {
> + if (x.hwmon)
> + hwmon_device_unregister(x.hwmon);
> + x.hwmon = NULL;
> +
> device_remove_file( &x.of_dev->dev, &dev_attr_cpu_temperature );
> device_remove_file( &x.of_dev->dev, &dev_attr_case_temperature );
> device_remove_file(&x.of_dev->dev, &dev_attr_fan_level);
> --
> 2.0.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
>
>
next prev parent reply other threads:[~2014-08-06 23:18 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-06 21:04 [PATCH][v3] therm_windtunnel doesn't work properly on PowerMac G4 Goffredo Baroncelli
2014-08-06 21:04 ` [PATCH 1/5] Update drivers names to the ones invoked by i2c-powermac Goffredo Baroncelli
2014-08-06 21:05 ` [PATCH 2/5] Remove attach_method because un-used Goffredo Baroncelli
2014-08-07 8:39 ` Jean Delvare
2014-08-06 21:05 ` [PATCH 3/5] Add the "verbose" module option Goffredo Baroncelli
2014-08-07 8:52 ` Jean Delvare
2014-08-07 16:29 ` Goffredo Baroncelli
2014-08-07 16:43 ` Jean Delvare
2014-08-07 16:52 ` Goffredo Baroncelli
2014-08-06 21:05 ` [PATCH 4/5] Return the fan speed via sysfs Goffredo Baroncelli
2014-08-06 21:05 ` [PATCH 5/5] Export the temperatures via hwmon Goffredo Baroncelli
2014-08-06 23:18 ` Guenter Roeck [this message]
2014-08-07 6:03 ` Goffredo Baroncelli
2014-08-07 6:20 ` Guenter Roeck
2014-08-07 6:52 ` Jean Delvare
2014-08-07 7:36 ` Guenter Roeck
2014-08-07 8:35 ` Jean Delvare
2014-08-07 14:19 ` Guenter Roeck
2014-08-07 17:50 ` Goffredo Baroncelli
2014-08-07 18:16 ` Guenter Roeck
2014-08-07 19:27 ` Goffredo Baroncelli
2014-08-07 21:19 ` Matt Helsley
2014-08-08 14:54 ` Goffredo Baroncelli
2014-08-08 16:30 ` Guenter Roeck
2014-08-08 16:58 ` Goffredo Baroncelli
-- strict thread matches above, loose matches on Subject: below --
2014-08-07 19:08 [PATCH][v4] therm_windtunnel does not work properly on PowerMac G4 Goffredo Baroncelli
2014-08-07 19:08 ` [PATCH 5/5] Export the temperatures via hwmon Goffredo Baroncelli
2014-08-09 6:49 [PATCH][v5] therm_windtunnel does not work properly on PowerMac G4 Goffredo Baroncelli
2014-08-09 6:50 ` [PATCH 5/5] Export the temperatures via hwmon Goffredo Baroncelli
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=20140806231803.GA5643@roeck-us.net \
--to=linux@roeck-us.net \
--cc=benh@kernel.crashing.org \
--cc=jdelvare@suse.de \
--cc=kreijack@gmail.com \
--cc=kreijack@iniwnd.it \
--cc=kreijack@inwind.it \
--cc=linux-kernel@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox