All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [lm-sensors] New Asus board and multiple sensors
@ 2008-09-14  6:43 Hans de Goede
  2008-09-14 18:51 ` Marco Chiappero
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Hans de Goede @ 2008-09-14  6:43 UTC (permalink / raw)
  To: lm-sensors

Marco Chiappero wrote:
> Jean Delvare ha scritto:
>> Loading random drivers isn't going to help. The two interesting
>> things are:
>>
>> * What does sensors-detect see? Unidentified chips on the SMBus at
>>   addresses typically used by monitoring chips (0x2c-0x2f or
>>   0x48-0x4f)? Or nothing at all? If unidentified chips are seen then
>>   we need the output of i2cdump for these chips to find out what
>>   they are.
> 
> I attached the sensors-detect output, but I have never used i2cdump 
> before, so I don't know exactly which parameters I should pass to it. 
> Any help appreciated.
> 
>> * What makes you think there are "two other sensor chips" on the
>>   board? Can you see them physically on the board?
> 
> A little search through the web. Let me explain. This board I own (Asus
> Maximus II Formula) it's essentially a refreshment of the previous
> Maximus Formula / Rampage Formula motherboard (which are exactly the
> same board with different northbridge chip) and both share the same
> temperature & voltage readings, fan and optional sensors headers. So I
> think we can assume the hwmon section it's almost the same.
> Unfortunately the only chip clearly visible is the Winbond W83667HG also
> because the board comes with a wide heatsink that may cover some chips
> (as it is for the ICS clock generator, half visible). As soon as I can
> I'll try to get a closer look. However I've found these informations
> about those "older" models:
> 
> - Sensor Type W83627DHG + W83791D + ADT7475 + ADP3228 (ISA 290h, SMB
> 2Ch/2Eh/20h)
> 

When manufacturers change a board chances are high they will change more then 
just the northbridge. That seems to be the case here, as the smbus probe for 
your board shows no sensors IC's attached.

I have an asus M8N-SLI Deluxe which has an adt7475 and sensors-detect detects 
that just fine, so either you don't have an adt7475, or Asus has multiplexed 
the smbus, hiding the sensors in that way.

If you really want to know how the additional headers are hooked up you will 
need to go and look for hwmon IC's, and yes that means you might need to take 
the cooler of the motherboard. Are they actually all monitored, maybe some of 
them will drive a fan but do not monitor it? How many fans does windows allow 
you to monitor?.

Refards,

Hans

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

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

* Re: [lm-sensors] New Asus board and multiple sensors
  2008-09-14  6:43 [lm-sensors] New Asus board and multiple sensors Hans de Goede
@ 2008-09-14 18:51 ` Marco Chiappero
  2008-09-15 10:45 ` Marco Chiappero
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Marco Chiappero @ 2008-09-14 18:51 UTC (permalink / raw)
  To: lm-sensors

Hans de Goede ha scritto:
> When manufacturers change a board chances are high they will change more 
> then just the northbridge. That seems to be the case here, as the smbus 
> probe for your board shows no sensors IC's attached.
 > If you really want to know how the additional headers are hooked up
 > you will need to go and look for hwmon IC's, and yes that means you
 > might need to take the cooler of the motherboard.

I gave a quick look at the motherboard, you are right (and I was wrong, 
sorry).While the w83791d is clearly visible on the Maximus/Rampage Formula
(http://www.overclock3d.net/gfx/articles/2007/10/31181936232l.jpg) this
is not the case for the MIIF.
Unfortunately it's not that easy to remove the heatsink and it makes the
warranty void, but I have found some images of the "naked" board. I
modified them to show you the well know chips, but I need your help to
identify those unknown chips that might be hwmon IC. This is the picture:
http://i37.tinypic.com/29ofhmo.jpg
http://i33.tinypic.com/2m4rfqe.jpg
http://i35.tinypic.com/33e1vyr.jpg
I suspect them to be the iROG marked chips as I think this board is the 
first Asus mounting such ICs and being capable of showing 
temperatures/voltages/fan speeds on an external LCD, included with the 
board. Again, unfortunately no other information is printed.

> Are they actually all 
> monitored, maybe some of them will drive a fan but do not monitor it?
> How many fans does windows allow you to monitor?.

Both the BIOS and the Asus utility show the speed readings for every 
header but at this time I'm using only 3 fan headers (+ the CPU header). 
I'll give a try as soon as possible. However, as far as I know, no Asus 
utility can control this fans and other software only recognizes the 
winbond chip, but some regulations are still possibile in the BIOS. Is 
there a way to find out through a bus scan what chips are they? What can 
we do now? Should we try to contact Asus?

Thank you
Marco



_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

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

* Re: [lm-sensors] New Asus board and multiple sensors
  2008-09-14  6:43 [lm-sensors] New Asus board and multiple sensors Hans de Goede
  2008-09-14 18:51 ` Marco Chiappero
@ 2008-09-15 10:45 ` Marco Chiappero
  2008-09-15 12:17 ` Rudolf Marek
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Marco Chiappero @ 2008-09-15 10:45 UTC (permalink / raw)
  To: lm-sensors

Marco Chiappero ha scritto:
> I suspect them to be the iROG marked chips as I think this board is the 
> first Asus mounting such ICs and being capable of showing 
> temperatures/voltages/fan speeds on an external LCD, included with the 
> board. Again, unfortunately no other information is printed.

Sorry for flooding you and the mailing list, please don't hate me, but I 
think I have an interesting news. Today I upgraded a windows program 
called Everest since finally it claims support for the W83667HG chip (it 
was recognized as w83627 in the previous releases), and now it can read 
the whole system informations as the asus utility does. Here is a 
screenshot: http://i36.tinypic.com/9uulc3.png
Is it possibile that all those readings are provided by the single 
Winbond chip? Maybe the w83667hg is not so similar to the w83627dhg...


Marco


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

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

* Re: [lm-sensors] New Asus board and multiple sensors
  2008-09-14  6:43 [lm-sensors] New Asus board and multiple sensors Hans de Goede
  2008-09-14 18:51 ` Marco Chiappero
  2008-09-15 10:45 ` Marco Chiappero
@ 2008-09-15 12:17 ` Rudolf Marek
  2008-09-16 21:36 ` Rudolf Marek
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Rudolf Marek @ 2008-09-15 12:17 UTC (permalink / raw)
  To: lm-sensors

Hi,

Can you display a tree of sensors? To sort them by connection to right 
chips. Maybe it would help me the
DSDT of the ACPI.

Please can you post the text file obtained by iasl util.

cd /tmp
cat /proc/acpi/dsdt.bin >dsdt.bin
iasl -d dsdt.bin

It will be called dsdt.asl or dsdt.dsl

Thanks,
Rudolf

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

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

* Re: [lm-sensors] New Asus board and multiple sensors
  2008-09-14  6:43 [lm-sensors] New Asus board and multiple sensors Hans de Goede
                   ` (2 preceding siblings ...)
  2008-09-15 12:17 ` Rudolf Marek
@ 2008-09-16 21:36 ` Rudolf Marek
  2008-09-17 20:27 ` Marco Chiappero
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Rudolf Marek @ 2008-09-16 21:36 UTC (permalink / raw)
  To: lm-sensors

Hello,

Here is mine research:

DHG chip is wired as follows:

in0 is Vcore
in1 is 12V
in2 not used
in3 is 3.3V
in4 is 5V

temp1 is MB temp
fans are
fan2 is cpu,
fan5 is not, fan4 is not

There is some unknown i2c chip at 0x38 which measures voltages, and fans

It measures:
Cpu voltage, DDR voltage, SB 1.1V voltage SB 1.5V, CPU PLL voltage, NB 1.1V Dram 
VTT volrage, VTT CPU voltage,

And also fans:
Chasis fan1
Chasis fan2
Power Fan
And some Opt fans, I know what registers are there (mostly up 0xa0 for fans)

So we need to find out what chip it is, because it measures a lot too.

The NB temperature etc etc is measured by some chip at 0x40 it seems it also 
controls some fan temperature???

Definitely what is the output of

i2cdetect 0
i2cdump 0 0x40
i2cdump 0 0x38

Thanks,
Rudolf


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

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

* Re: [lm-sensors] New Asus board and multiple sensors
  2008-09-14  6:43 [lm-sensors] New Asus board and multiple sensors Hans de Goede
                   ` (3 preceding siblings ...)
  2008-09-16 21:36 ` Rudolf Marek
@ 2008-09-17 20:27 ` Marco Chiappero
  2008-09-17 20:49 ` Rudolf Marek
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Marco Chiappero @ 2008-09-17 20:27 UTC (permalink / raw)
  To: lm-sensors

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

Rudolf Marek ha scritto:
> Hello,

Hi Rudolf, good to read you.

> DHG chip is wired as follows:
> 
> in0 is Vcore
> in1 is 12V
> in2 not used
> in3 is 3.3V
> in4 is 5V

Ok, maybe Stby +5V too?

> temp1 is MB temp
> fans are
> fan2 is cpu,
> fan5 is not, fan4 is not

Temp2 should be the CPU temp, fans1/fans4/fan5 should be cha1/cha2/cha3 
headers. I have created a file listing all the things I know and I'm 
able to manage with the w83627ehf driver. Take a look at:
http://www.absence.it/MIIF/sensors-output
http://www.absence.it/MIIF/w83667hg-report

> It measures:
> Cpu voltage, DDR voltage, SB 1.1V voltage SB 1.5V, CPU PLL voltage, NB 
> 1.1V Dram VTT volrage, VTT CPU voltage,

Right, these are the voltages show by the external LCD, so it makes 
sense to have these computed by another chip.

> So we need to find out what chip it is, because it measures a lot too.
> 
> The NB temperature etc etc is measured by some chip at 0x40 it seems it 
> also controls some fan temperature???

Don't know, since chassis1/2/3, CPU and Power Fan should be controlled 
by the w83667hg while the opt1/2/3 should be controlled by another chip, 
but can't say which one.

> Definitely what is the output of
> 
> i2cdetect 0
> i2cdump 0 0x40
> i2cdump 0 0x38

Output attached!
You may also read these and previous attachments by brousing 
http://www.absence.it/MIIF/

I have a question for you: are this probings harmless? Because I'm 
starting to experience a strange issue, and maybe you guys can help me 
to figure out why. But let me start from the beginning.
A few days ago, after many hours of uptime, the CPU temp (not the cores 
one) suddenly jumped to 110°C. Obviously it was a false positive, but it 
caused the sensors chip to push all my fans to the maximum speed and I 
had to reboot the computer to "solve" the problem. The day after exactly 
the same issue in the same way. Then reboot. The following day a really 
weird thing happened: suddenly many of the sensors of the board were no 
more available. Look at this screenshot I caught in that moment: 
http://www.absence.it/MIIF/errors.jpg
But this time after the OS closed all its stuff nor a reboot neither a 
reset made the computer boot again, so I had to press the power button. 
  A few hours later I have found a guy owning the same board and sharing 
almost the same issue that told me that this happens when running more 
than one sensors monitoring utility at time. It sounded strange to me 
but I was indeed running a couple of programs in those days (I've never 
used to do so before). Infact the day after the pc had no problems at 
all running just one monitoring tool as usual. However today, after 
using i2cdump for this attachment, I rebooted the computer to run these 
dumps on a newer kernel and that's the result: 
http://www.absence.it/MIIF/wrong-dumps
The same thing again! I rebooted but didn't work and I had to cut the 
power again. Have you got any idea about why this could happen? Is it an 
hardware (temporary?) fault or is it a software one? Or is it caused by 
any software? Above this the board has proven to be rock solid, so I 
don't know what to think: is the board defective? Is it normal?


Thank you again
Marco


[-- Attachment #2: MIIF-i2c-dumps --]
[-- Type: text/plain, Size: 3564 bytes --]

root@etna:/usr/src# i2cdetect 0
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0.
I will probe address range 0x03-0x77.
Continue? [Y/n] 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- 08 -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: 30 -- 32 33 -- 35 -- -- 38 -- -- -- -- -- -- -- 
40: 40 -- -- -- 44 -- -- -- -- -- -- -- -- -- -- -- 
50: 50 -- 52 -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- 69 -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
root@etna:/usr/src# i2cdump 0 0x38
No size specified (using byte-data access)
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0, address 0x38, mode byte
Continue? [Y/n] 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: ff 55 a0 55 74 72 55 3f ff ff ff 01 00 ff ff ff    .U?UtrU?...?....
10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
30: 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
80: ff ff ff ff ff ff ff ff ff ff 69 43 44 00 56 a1    ..........iCD.V?
90: 36 04 3e 08 64 04 dd 05 f8 05 5e 04 1c 04 5e 04    6?>?d?????^???^?
a0: e9 05 6f 03 ff 02 a5 02 ff ff ff ff 25 ff ff ff    ??o?.???....%...
b0: ff 08 00 07 23 00 00 00 20 ff ff ff ff ff ff ff    .?.?#... .......
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
root@etna:/usr/src# i2cdump 0 0x40
No size specified (using byte-data access)
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0, address 0x40, mode byte
Continue? [Y/n] 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: ff ff ff ff ff ff ff 00 00 00 82 ff ff ff ff ff    ..........?.....
10: ff 50 50 ff 5a 5a 5a ff ff ff ff ff ff ff ff ff    .PP.ZZZ.........
20: ff ff ff ff ff ff ff 00 ff ff ff ff ff ff ff ff    ................
30: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
80: ff ff ff ff ff ff ff ff ff ff 50 cc 29 00 56 ec    ..........P?).V?
90: 00 00 df 05 00 00 d3 02 ff ff ff ff ff ff ff ff    ..??..??........
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
c0: 24 2b 2c 23 20 1a 20 ff ff ff ff ff ff ff ff 00    $+,# ? .........
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................

[-- Attachment #3: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

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

* Re: [lm-sensors] New Asus board and multiple sensors
  2008-09-14  6:43 [lm-sensors] New Asus board and multiple sensors Hans de Goede
                   ` (4 preceding siblings ...)
  2008-09-17 20:27 ` Marco Chiappero
@ 2008-09-17 20:49 ` Rudolf Marek
  2008-09-18 11:35 ` Marco Chiappero
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Rudolf Marek @ 2008-09-17 20:49 UTC (permalink / raw)
  To: lm-sensors

Hi,

Just a short note. The errors  you are experiencing is concurrent access issue. 
The Asus util use ACPI bytecode to manipulate the i2c bus. Bus other utils try 
this same time. It may happen that the i2c bus hangs. Then it reads all ffs. 
Power down with the power cord will reset all in chipset and fixes the problem.

So if you will use one util, it should not happen.

Btw what happen if you issue command in linux:

modprobe thermal
acpi -V


Thanks,
Rudolf

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

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

* Re: [lm-sensors] New Asus board and multiple sensors
  2008-09-14  6:43 [lm-sensors] New Asus board and multiple sensors Hans de Goede
                   ` (5 preceding siblings ...)
  2008-09-17 20:49 ` Rudolf Marek
@ 2008-09-18 11:35 ` Marco Chiappero
  2008-11-23 15:23 ` Marco Chiappero
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Marco Chiappero @ 2008-09-18 11:35 UTC (permalink / raw)
  To: lm-sensors

Rudolf Marek ha scritto:
> Hi,

Hi!

> Just a short note. The errors  you are experiencing is concurrent access 
> issue. The Asus util use ACPI bytecode to manipulate the i2c bus. Bus 
> other utils try this same time. It may happen that the i2c bus hangs. 
> Then it reads all ffs. Power down with the power cord will reset all in 
> chipset and fixes the problem.
> 
> So if you will use one util, it should not happen.

Ok, I just wanted to be sure there was no faulty hardware, thank you for 
the explanation.

> Btw what happen if you issue command in linux:
> 
> modprobe thermal
> acpi -V

Cooling 0: Processor 0 of 3
Cooling 1: Processor 0 of 3


Bye

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

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

* Re: [lm-sensors] New Asus board and multiple sensors
  2008-09-14  6:43 [lm-sensors] New Asus board and multiple sensors Hans de Goede
                   ` (6 preceding siblings ...)
  2008-09-18 11:35 ` Marco Chiappero
@ 2008-11-23 15:23 ` Marco Chiappero
  2008-11-23 16:50 ` Luca Tettamanti
  2008-11-23 23:22 ` Luca Tettamanti
  9 siblings, 0 replies; 11+ messages in thread
From: Marco Chiappero @ 2008-11-23 15:23 UTC (permalink / raw)
  To: lm-sensors

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

2008/11/20 Luca Tettamanti <kronos.it at gmail.com>:

 > I totally missed the original thread, but this gives me a good excuse
 > to jump on this issue again :)
 > Asus boards have two different ACPI interfaces for hwmon:
 > - an old one (based on RVLT/RFAN/RTMP)
 > - a new one (GGRP/GITM)
 > Both may be present but there a few cases (my board, sigh) where the
 > new interface is just an empty stub.

Hi Luca,
I've been talking a little bit more about my new Asus board with Rudolf 
and we got to the conclusion that the board is almost certainly using
two custom ICs with hwmon capabilities along with the W83667HG SuperIO
chip (with hwmon logic as well). So I gave a try to the only available
solution, your ATK0110 driver (the one posted here:
http://lists.lm-sensors.org/pipermail/lm-sensors/2008-June/023449.html
[1]) and it seemed to work fairly well although the possible issues with
some other ACPI drivers (as far as I can say it seems that even the Asus
PCProbe Utility for Windows works using the ATK0110 virtual device and
driver).

 > I've rewritten my old ATK driver for the third time so that it works
 > with both interfaces (and this time I _really_ intend to push it
 > upstream);

This is a *good* news, I'll be glad!

 > currently I'm not 100% sure of the output of the new
 > interface (the user that originally contacted me is not responsive...)
 > but the code is almost complete.
 > Thierry are you willing to test this _experimental_ driver?

Well, I'd like to understand how this ACPI interface works (and maybe
write some code), really, but don't know how, where to find
documentation... However, although I'm quite busy right now, here I am
if you need a tester, sure.
You can start having a look at my attached dsdt.dsl, if you need.

Marco


[1] By the way, I patched the lm-sensors package too, the compilation
runs fine but "sensors" is still unable to show the atk readings.


[-- Attachment #2: dsdt.dsl.gz --]
[-- Type: application/gzip, Size: 30994 bytes --]

[-- Attachment #3: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

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

* Re: [lm-sensors] New Asus board and multiple sensors
  2008-09-14  6:43 [lm-sensors] New Asus board and multiple sensors Hans de Goede
                   ` (7 preceding siblings ...)
  2008-11-23 15:23 ` Marco Chiappero
@ 2008-11-23 16:50 ` Luca Tettamanti
  2008-11-23 23:22 ` Luca Tettamanti
  9 siblings, 0 replies; 11+ messages in thread
From: Luca Tettamanti @ 2008-11-23 16:50 UTC (permalink / raw)
  To: lm-sensors

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

Il Sun, Nov 23, 2008 at 04:30:58PM +0100, Jean Delvare ha scritto: 
> On Sun, 23 Nov 2008 16:23:52 +0100, Marco Chiappero wrote:
> > [1] By the way, I patched the lm-sensors package too, the compilation
> > runs fine but "sensors" is still unable to show the atk readings.
> 
> If you use lm-sensors 3.0.2 or later and if the atk0110 driver
> implements the standard sysfs interface (it really should), then you
> shouldn't have to patch anything, it should work out of the box.

It does use the standard interface, but last time I checked the sensor
was ignored since it's attached to the ACPI subsys, I was proposing this
patch:

Index: lib/access.c
===================================================================
--- lib/access.c	(revision 5296)
+++ lib/access.c	(working copy)
@@ -349,6 +349,8 @@
 		return "SPI adapter";
 	case SENSORS_BUS_TYPE_VIRTUAL:
 		return "Virtual device";
+	case SENSORS_BUS_TYPE_ACPI:
+		return "ACPI device";
 	}
 
 	/* bus types with several instances */
Index: lib/sensors.h
===================================================================
--- lib/sensors.h	(revision 5296)
+++ lib/sensors.h	(working copy)
@@ -42,6 +42,7 @@
 #define SENSORS_BUS_TYPE_PCI		2
 #define SENSORS_BUS_TYPE_SPI		3
 #define SENSORS_BUS_TYPE_VIRTUAL	4
+#define SENSORS_BUS_TYPE_ACPI		5
 #define SENSORS_BUS_NR_ANY		(-1)
 #define SENSORS_BUS_NR_IGNORE		(-2)
 
Index: lib/sysfs.c
===================================================================
--- lib/sysfs.c	(revision 5296)
+++ lib/sysfs.c	(working copy)
@@ -579,6 +579,11 @@
 			entry.chip.addr = 0;
 		entry.chip.bus.type = SENSORS_BUS_TYPE_ISA;
 		entry.chip.bus.nr = 0;
+	} else
+	if ((!subsys || !strcmp(subsys, "acpi")) &&
+	    sscanf(dev_name, "%*[a-zA-Z0-9_]:%d", &entry.chip.addr) == 1) {
+		entry.chip.bus.type = SENSORS_BUS_TYPE_ACPI;
+		entry.chip.bus.nr = 0;
 	} else {
 		/* Ignore unknown device */
 		err = 0;
Index: lib/data.c
===================================================================
--- lib/data.c	(revision 5296)
+++ lib/data.c	(working copy)
@@ -111,6 +111,8 @@
 		res->bus.type = SENSORS_BUS_TYPE_SPI;
 	else if (!strncmp(name, "virtual", dash - name))
 		res->bus.type = SENSORS_BUS_TYPE_VIRTUAL;
+	else if (!strncmp(name, "acpi", dash - name))
+		res->bus.type = SENSORS_BUS_TYPE_ACPI;
 	else
 		goto ERROR;
 	name = dash + 1;
@@ -174,6 +176,9 @@
 	case SENSORS_BUS_TYPE_VIRTUAL:
 		return snprintf(str, size, "%s-virtual-%x", chip->prefix,
 				chip->addr);
+	case SENSORS_BUS_TYPE_ACPI:
+		return snprintf(str, size, "%s-acpi-%x", chip->prefix,
+				chip->addr);
 	}
 
 	return -SENSORS_ERR_CHIP_NAME;


Luca
-- 
"Perch� � cos� che ti frega, la vita. Ti piglia quando hai ancora l'anima
 addormentata e ti semina dentro un'immagine, o un odore, o un suono che
 poi non te lo togli pi�. E quella l� era la felicit�."


[-- Attachment #2: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

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

* Re: [lm-sensors] New Asus board and multiple sensors
  2008-09-14  6:43 [lm-sensors] New Asus board and multiple sensors Hans de Goede
                   ` (8 preceding siblings ...)
  2008-11-23 16:50 ` Luca Tettamanti
@ 2008-11-23 23:22 ` Luca Tettamanti
  9 siblings, 0 replies; 11+ messages in thread
From: Luca Tettamanti @ 2008-11-23 23:22 UTC (permalink / raw)
  To: lm-sensors

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

Il Sun, Nov 23, 2008 at 04:23:52PM +0100, Marco Chiappero ha scritto: 
> > currently I'm not 100% sure of the output of the new
> > interface (the user that originally contacted me is not responsive...)
> > but the code is almost complete.
> > Thierry are you willing to test this _experimental_ driver?
>
> Well, I'd like to understand how this ACPI interface works (and maybe
> write some code), really, but don't know how, where to find
> documentation...

I'm just reading the DSDT and did a quick check on windows driver to see
if it was using the same methods.

> However, although I'm quite busy right now, here I am
> if you need a tester, sure.
> You can start having a look at my attached dsdt.dsl, if you need.

Ok, it's similar to my board. The "old style" interface is based on 3
methods for each class of sensors:
- enumeration (VSIF for voltage, TSIF for temperature, FSIF for fan)
- reading (RVLT/RTMP/RFAN)
- setter (SVLT/STMP/SFAN); they can be used to overwrite the label and
  the limits but it seems that's only cosmetic
The new interface is based on 3 generic method:
- GGRP for enumeration
- GITM is the getter
- SITM is the setter
Sensors and whatnot are divided into a number of classes, hwmon being
0x6 (and e.g. 0x4 is for Q-FAN, 0x5 is the auto-overclock stuff, etc.)
Each data point has an ID (discovered with the enumeration methods) where
bytes [0-1] are the ID of the sensor (unique inside the class), byte 2
is type of the sensor (0x2 is a voltage, 0x3 is a temperature, 0x4 is a
fan) and byte 3 is the class itself. With the old interface you just the
ID as a cookie that gets passed to the correspoding RVLT/RTMP/RFAN (you
enumerate each type separately, so you already known which sensor is
what). With the new interface you have to parse the IDs returned by GGRP
to discover what are the available sensors; then - when you want to read
something - you pass the ID to GITM, which uses byte 3 to dispatch the
call to a class-specific method; this method in turn uses bytes [0-1]
(sensor id) to read the desired value.

Note the in your DSDT both interfaces are present, but the new one is
just a stub (GITM calls GIT6 for hwmon, and GIT6 does nothing).

> [1] By the way, I patched the lm-sensors package too, the compilation
> runs fine but "sensors" is still unable to show the atk readings.

Hum, anything in dmesg?
Anyway I'm attacching the new version (plus patch for ACPI - diffed
against git-current, but it's easily adapted to older kernels).

Luca
-- 
Il tempo speso
a coltivare sogni
non � sprecato.

[-- Attachment #2: atk.c --]
[-- Type: text/x-csrc, Size: 32019 bytes --]

/*
 * Copyright (C) 2007-2008 Luca Tettamanti <kronos.it@gmail.com>
 *
 * This file is released under the GPLv2
 * See COPYING in the top level directory of the kernel tree.
 */

#define DEBUG

#include <linux/kernel.h>
#include <linux/hwmon.h>
#include <linux/list.h>
#include <linux/module.h>

#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>


#define ATK_HID "ATK0110"
#define ATK_DRV "atk-hwmon"
#define ASOC "_SB.PCI0.SBRG.ASOC"

#define BOARD_ID		"MBIF"
#define METHOD_ENUMERATE	"GGRP"
#define METHOD_READ		"GITM"
#define METHOD_WRITE		"SITM"
#define METHOD_OLD_READ_TMP	"RTMP"
#define METHOD_OLD_READ_VLT	"RVLT"
#define METHOD_OLD_READ_FAN	"RFAN"
#define METHOD_OLD_ENUM_TMP	"TSIF"
#define METHOD_OLD_ENUM_VLT	"VSIF"
#define METHOD_OLD_ENUM_FAN	"FSIF"

#define ATK_MUX_HWMON		0x00000006ULL

#define ATK_CLASS_MASK		0xff000000ULL
#define ATK_CLASS_FREQ_CTL	0x03000000ULL
#define ATK_CLASS_FAN_CTL	0x04000000ULL
#define	ATK_CLASS_HWMON		0x06000000ULL

#define ATK_TYPE_MASK		0x00ff0000ULL
#define HWMON_TYPE_VOLT		0x00020000ULL
#define HWMON_TYPE_TEMP		0x00030000ULL
#define HWMON_TYPE_FAN		0x00040000ULL

#define HWMON_SENSORS_ID_MASK	0x0000ffffULL

enum atk_pack_member {
	HWMON_PACK_FLAGS,
	HWMON_PACK_NAME,
	HWMON_PACK_LIMIT1,
	HWMON_PACK_LIMIT2,
	HWMON_PACK_ENABLE
};

/* New package format */
#define _HWMON_NEW_PACK_SIZE	7
#define	_HWMON_NEW_PACK_FLAGS	0
#define	_HWMON_NEW_PACK_NAME	1
#define	_HWMON_NEW_PACK_UNK1	2
#define	_HWMON_NEW_PACK_UNK2	3
#define	_HWMON_NEW_PACK_LIMIT1	4
#define	_HWMON_NEW_PACK_LIMIT2	5
#define	_HWMON_NEW_PACK_ENABLE	6

/* Old package format */
#define _HWMON_OLD_PACK_SIZE	5
#define	_HWMON_OLD_PACK_FLAGS	0
#define	_HWMON_OLD_PACK_NAME	1
#define	_HWMON_OLD_PACK_LIMIT1	2
#define	_HWMON_OLD_PACK_LIMIT2	3
#define	_HWMON_OLD_PACK_ENABLE	4


struct atk_data {
	struct device *hwmon_dev;
	acpi_handle atk_handle;
	struct acpi_device *acpi_dev;

	bool old_interface;

	/* old interface */
	acpi_handle rtmp_handle;
	acpi_handle rvlt_handle;
	acpi_handle rfan_handle;
	/* new inteface */
	acpi_handle enumerate_handle;
	acpi_handle read_handle;

	struct list_head voltage_list;
	int voltage_count;
	struct list_head temperature_list;
	int temperature_count;
	struct list_head fan_list;
	int fan_count;
};


typedef ssize_t (*sysfs_show_func)(struct device *dev,
			struct device_attribute *attr, char *buf);

typedef ssize_t (*sysfs_store_func)(struct device *dev,
			struct device_attribute *attr, const char *buf,
			size_t count);

static const struct acpi_device_id atk_ids[] = {
	{ATK_HID, 0},
	{"", 0},
};
MODULE_DEVICE_TABLE(acpi, atk_ids);

#define ATTR_NAME_SIZE 16 /* Worst case is "tempN_input" */

struct atk_sensor_data {
	struct list_head list;
	struct atk_data *data;
	struct device_attribute label_attr;
	struct device_attribute input_attr;
	struct device_attribute limit1_attr;
	struct device_attribute limit2_attr;
	char label_attr_name[ATTR_NAME_SIZE];
	char input_attr_name[ATTR_NAME_SIZE];
	char limit1_attr_name[ATTR_NAME_SIZE];
	char limit2_attr_name[ATTR_NAME_SIZE];
	u64 id;
	u64 limit1;
	u64 limit2;
	char const *acpi_name;
};

struct atk_acpi_buffer_u64 {
	union acpi_object buf;
	u64 value;
};

static int atk_add(struct acpi_device *device);
static int atk_remove(struct acpi_device *device, int type);
static void atk_print_sensor(struct atk_data *data, union acpi_object *obj);
static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value);
static int atk_read_value_old(struct atk_sensor_data *sensor, int type, u64 *value);
static void atk_free_sensors(struct atk_data *data);

static struct acpi_driver atk_driver = {
	.name	= ATK_HID,
	.class	= "hwmon",
	.ids	= atk_ids,
	.ops	= {
		.add	= atk_add,
		.remove	= atk_remove,
	},
};

#define input_to_atk_sensor(attr) \
	container_of(attr, struct atk_sensor_data, input_attr)

#define label_to_atk_sensor(attr) \
	container_of(attr, struct atk_sensor_data, label_attr)

#define limit1_to_atk_sensor(attr) \
	container_of(attr, struct atk_sensor_data, limit1_attr)

#define limit2_to_atk_sensor(attr) \
	container_of(attr, struct atk_sensor_data, limit2_attr)

/* Voltages */

static ssize_t atk_volt_input_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = input_to_atk_sensor(attr);
	u64 voltage;
	int err;

	if (s->data->old_interface)
		err = atk_read_value_old(s, HWMON_TYPE_VOLT, &voltage);
	else
		err = atk_read_value_new(s, &voltage);
	if (err)
		return err;

	return sprintf(buf, "%llu\n", voltage);
}

static ssize_t atk_volt_label_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = label_to_atk_sensor(attr);

	return sprintf(buf, "%s\n", s->acpi_name);
}

static ssize_t atk_volt_min_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = limit1_to_atk_sensor(attr);

	return sprintf(buf, "%lld\n", s->limit1);
}

static ssize_t atk_volt_max_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = limit2_to_atk_sensor(attr);

	return sprintf(buf, "%lld\n", s->limit2);
}

/* Temperatures */

static ssize_t atk_temp_input_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = input_to_atk_sensor(attr);
	u64 temp;
	ssize_t count;
	int err;

	if (s->data->old_interface)
		err = atk_read_value_old(s, HWMON_TYPE_TEMP, &temp);
	else
		err = atk_read_value_new(s, &temp);
	if (err)
		return err;

	/* ACPI returns decidegree */
	count = sprintf(buf, "%llu\n", temp * 100);

	return count;
}

static ssize_t atk_temp_label_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = label_to_atk_sensor(attr);

	return sprintf(buf, "%s\n", s->acpi_name);
}

static ssize_t atk_temp_max_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = limit1_to_atk_sensor(attr);

	return sprintf(buf, "%lld\n", s->limit1 * 100);
}

static ssize_t atk_temp_crit_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = limit2_to_atk_sensor(attr);

	return sprintf(buf, "%lld\n", s->limit2 * 100);
}

/* Fans */

static ssize_t atk_fan_input_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = input_to_atk_sensor(attr);
	u64 rot;
	int err;

	if (s->data->old_interface)
		err = atk_read_value_old(s, HWMON_TYPE_FAN, &rot);
	else
		err = atk_read_value_new(s, &rot);
	if (err)
		return err;

	return sprintf(buf, "%llu\n", rot);
}

static ssize_t atk_fan_label_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = label_to_atk_sensor(attr);

	return sprintf(buf, "%s\n", s->acpi_name);
}

static ssize_t atk_fan_min_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = limit1_to_atk_sensor(attr);

	return sprintf(buf, "%lld\n", s->limit1);
}

static ssize_t atk_fan_max_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct atk_sensor_data *s = limit2_to_atk_sensor(attr);

	return sprintf(buf, "%lld\n", s->limit2);
}

static ssize_t atk_name_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "atk0110\n");
}
static struct device_attribute atk_name_attr = __ATTR(name, 0444, atk_name_show, NULL);

static void atk_init_attribute(struct device_attribute *attr, char *name,
		mode_t mode, sysfs_show_func show, sysfs_store_func store)
{
	attr->attr.name = name;
	attr->attr.mode = mode;
	attr->show = show;
	attr->store = store;
}


static union acpi_object *atk_get_pack_member(struct atk_data *data,
						union acpi_object *pack,
						enum atk_pack_member m)
{
	bool old_if = data->old_interface;
	int offset;

	switch (m) {
	case HWMON_PACK_FLAGS:
		offset = old_if ? _HWMON_OLD_PACK_FLAGS : _HWMON_NEW_PACK_FLAGS;
		break;
	case HWMON_PACK_NAME:
		offset = old_if ? _HWMON_OLD_PACK_NAME : _HWMON_NEW_PACK_NAME;
		break;
	case HWMON_PACK_LIMIT1:
		offset = old_if ? _HWMON_OLD_PACK_LIMIT1 : _HWMON_NEW_PACK_LIMIT1;
		break;
	case HWMON_PACK_LIMIT2:
		offset = old_if ? _HWMON_OLD_PACK_LIMIT2 : _HWMON_NEW_PACK_LIMIT2;
		break;
	case HWMON_PACK_ENABLE:
		offset = old_if ? _HWMON_OLD_PACK_ENABLE : _HWMON_NEW_PACK_ENABLE;
		break;
	default:
		return NULL;
	}

	return &pack->package.elements[offset];
}


/* New package format is:
 * - flag (int)
 *	class - used for de-muxing the request to the correct GITn
 *	type (volt, temp, fan)
 *	sensor id |
 *	sensor id - used for de-muxing the request _inside_ the GITn
 * - name (str)
 * - unknown (int)
 * - unknown (int)
 * - limit1 (int)
 * - limit2 (int)
 * - enable (int)
 *
 * The old package has the same format but it's missing the two unknown fields.
 */
static int validate_hwmon_pack(struct atk_data *data, union acpi_object *obj)
{
	struct device *dev = &data->acpi_dev->dev;
	union acpi_object *tmp;
	bool old_if = data->old_interface;
	int const expected_size = old_if ? _HWMON_OLD_PACK_SIZE : _HWMON_NEW_PACK_SIZE;

	if (obj->type != ACPI_TYPE_PACKAGE) {
		dev_warn(dev, "Invalid type: %d\n", obj->type);
		return -EINVAL;
	}

	if (obj->package.count != expected_size) {
		dev_warn(dev, "Invalid package size: %d, expected: %d\n",
				obj->package.count, expected_size);
		return -EINVAL;
	}

	tmp = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS);
	if (tmp->type != ACPI_TYPE_INTEGER) {
		dev_warn(dev, "Invalid type (flag): %d\n", tmp->type);
		return -EINVAL;
	}

	tmp = atk_get_pack_member(data, obj, HWMON_PACK_NAME);
	if (tmp->type != ACPI_TYPE_STRING) {
		dev_warn(dev, "Invalid type (name): %d\n", tmp->type);
		return -EINVAL;
	}

	/* Don't check... we don't know what they're useful for anyway */
#if 0
	tmp = &obj->package.elements[HWMON_PACK_UNK1];
	if (tmp->type != ACPI_TYPE_INTEGER) {
		dev_warn(dev, "Invalid type (unk1): %d\n", tmp->type);
		return -EINVAL;
	}

	tmp = &obj->package.elements[HWMON_PACK_UNK2];
	if (tmp->type != ACPI_TYPE_INTEGER) {
		dev_warn(dev, "Invalid type (unk2): %d\n", tmp->type);
		return -EINVAL;
	}
#endif

	tmp = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1);
	if (tmp->type != ACPI_TYPE_INTEGER) {
		dev_warn(dev, "Invalid type (limit1): %d\n", tmp->type);
		return -EINVAL;
	}

	tmp = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2);
	if (tmp->type != ACPI_TYPE_INTEGER) {
		dev_warn(dev, "Invalid type (limit2): %d\n", tmp->type);
		return -EINVAL;
	}

	tmp = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE);
	if (tmp->type != ACPI_TYPE_INTEGER) {
		dev_warn(dev, "Invalid type (enable): %d\n", tmp->type);
		return -EINVAL;
	}

	atk_print_sensor(data, obj);

	return 0;
}

static char const *atk_sensor_type(union acpi_object *flags)
{
	u64 type = flags->integer.value & ATK_TYPE_MASK;
	char const *what;

	switch (type) {
	case HWMON_TYPE_VOLT:
		what = "voltage";
		break;
	case HWMON_TYPE_TEMP:
		what = "temperature";
		break;
	case HWMON_TYPE_FAN:
		what = "fan";
		break;
	default:
		what = "unknown";
		break;
	}

	return what;
}

#ifdef DEBUG

static void atk_print_sensor(struct atk_data *data, union acpi_object *obj)
{
	struct device *dev = &data->acpi_dev->dev;
	union acpi_object *flags;
	union acpi_object *name;
	union acpi_object *limit1;
	union acpi_object *limit2;
	union acpi_object *enable;
	char const *what;

	flags = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS);
	name = atk_get_pack_member(data, obj, HWMON_PACK_NAME);
	limit1 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1);
	limit2 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2);
	enable = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE);

	what = atk_sensor_type(flags);

	dev_dbg(dev, "%s: %#llx %s [%llu-%llu] %s\n", what,
			flags->integer.value,
			name->string.pointer,
			limit1->integer.value, limit2->integer.value,
			enable->integer.value ? "enabled" : "disabled");
}

#else

static void atk_print_sensor(struct atk_data *data, union acpi_object *obj)
{
}

#endif

static int atk_read_value_old(struct atk_sensor_data *sensor, int type, u64 *value)
{
	struct atk_data *data = sensor->data;
	struct device *dev = &data->acpi_dev->dev;
	struct acpi_object_list params;
	union acpi_object id;
	acpi_status status;
	acpi_handle method;

	switch (type) {
	case HWMON_TYPE_VOLT:
		method = data->rvlt_handle;
		break;
	case HWMON_TYPE_TEMP:
		method = data->rtmp_handle;
		break;
	case HWMON_TYPE_FAN:
		method = data->rfan_handle;
		break;
	default:
		return -EINVAL;
	}

	id.type = ACPI_TYPE_INTEGER;
	id.integer.value = sensor->id;

	params.count = 1;
	params.pointer = &id;

	status = acpi_evaluate_integer(method, NULL, &params, value);
	if (status != AE_OK) {
		dev_warn(dev, "%s: ACPI exception: %s\n", __func__,
				acpi_format_exception(status));
		return -EIO;
	}

	return 0;
}

static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
{
	struct atk_data *data = sensor->data;
	struct device *dev = &data->acpi_dev->dev;
	struct acpi_object_list params;
	struct acpi_buffer ret;
	union acpi_object id;
	struct atk_acpi_buffer_u64 tmp;
	acpi_status status;
	union acpi_object *o;
	int i;

	id.type = ACPI_TYPE_INTEGER;
	id.integer.value = sensor->id;

	params.count = 1;
	params.pointer = &id;

	tmp.buf.type = ACPI_TYPE_BUFFER;
	tmp.buf.buffer.pointer = (u8 *)&tmp.value;
	tmp.buf.buffer.length = sizeof(u64);
	ret.length = sizeof(tmp);
	ret.pointer = &tmp;

	status = acpi_evaluate_object_typed(data->read_handle, NULL, &params,
			&ret, ACPI_TYPE_BUFFER);
	if (status != AE_OK) {
		dev_warn(dev, "%s: ACPI exception: %s\n", __func__,
				acpi_format_exception(status));
		return -EIO;
	}

	o = ret.pointer;
	dev_dbg(dev, "type = %d\n", o->type);
	dev_dbg(dev, "size = %d\n", o->buffer.length);

	for (i = 0; i < o->buffer.length; i++)
		dev_dbg(dev, "  [%#x] %d\n", (u32)(o->buffer.pointer[i]),
				(u32)(o->buffer.pointer[i]));

	/* Return buffer format:
	 * [0-3] "value" is valid flag
	 * [4-7] value
	 */

	if (!(tmp.value & 0xffffffff)) {
		/* The reading is not valid, possible causes:
		 * - sensor failure
		 * - enumeration was FUBAR (and we didn't notice)
		 */
		dev_info(dev, "Failure: %#llx\n", tmp.value);
		return -EIO;
	}

	*value = (tmp.value & 0xffffffff00000000ULL) >> 32;

	return 0;
}


static int atk_add_voltage(struct atk_data *data, union acpi_object *obj, int cnt)
{
	union acpi_object *flags;
	union acpi_object *name;
	union acpi_object *limit1;
	union acpi_object *limit2;
	union acpi_object *enable;
	struct atk_sensor_data *sensor;
	int err;

	enable = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE);
	if (!enable->integer.value)
		return 0;

	flags = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS);
	name = atk_get_pack_member(data, obj, HWMON_PACK_NAME);
	limit1 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1);
	limit2 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2);

	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
	if (!sensor)
		return -ENOMEM;

	sensor->acpi_name = kstrdup(name->string.pointer, GFP_KERNEL);
	if (!sensor->acpi_name) {
		err = -ENOMEM;
		goto out;
	}

	INIT_LIST_HEAD(&sensor->list);
	sensor->data = data;
	sensor->id = flags->integer.value;
	sensor->limit1 = limit1->integer.value;
	sensor->limit2 = limit2->integer.value;

	snprintf(sensor->input_attr_name, ATTR_NAME_SIZE,
			"in%d_input", cnt);
	atk_init_attribute(&sensor->input_attr,
			sensor->input_attr_name,
			0444, atk_volt_input_show, NULL);

	snprintf(sensor->label_attr_name, ATTR_NAME_SIZE,
			"in%d_label", cnt);
	atk_init_attribute(&sensor->label_attr,
			sensor->label_attr_name,
			0444, atk_volt_label_show, NULL);

	snprintf(sensor->limit1_attr_name, ATTR_NAME_SIZE,
			"in%d_min", cnt);
	atk_init_attribute(&sensor->limit1_attr,
			sensor->limit1_attr_name,
			0444, atk_volt_min_show, NULL);

	snprintf(sensor->limit2_attr_name, ATTR_NAME_SIZE,
			"in%d_max", cnt);
	atk_init_attribute(&sensor->limit2_attr,
			sensor->limit2_attr_name,
			0444, atk_volt_max_show, NULL);

	list_add(&sensor->list, &data->voltage_list);

	return 1;
out:
	kfree(sensor->acpi_name);
	kfree(sensor);
	return err;
}

static int atk_add_temperature(struct atk_data *data, union acpi_object *obj, int cnt)
{
	union acpi_object *flags;
	union acpi_object *name;
	union acpi_object *limit1;
	union acpi_object *limit2;
	union acpi_object *enable;
	struct atk_sensor_data *sensor;
	int err;

	enable = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE);
	if (!enable->integer.value)
		return 0;

	flags = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS);
	name = atk_get_pack_member(data, obj, HWMON_PACK_NAME);
	limit1 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1);
	limit2 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2);

	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
	if (!sensor)
		return -ENOMEM;

	sensor->acpi_name = kstrdup(name->string.pointer, GFP_KERNEL);
	if (!sensor->acpi_name) {
		err = -ENOMEM;
		goto out;
	}

	INIT_LIST_HEAD(&sensor->list);
	sensor->data = data;
	sensor->id = flags->integer.value;
	sensor->limit1 = limit1->integer.value;
	sensor->limit2 = limit2->integer.value;

	snprintf(sensor->input_attr_name, ATTR_NAME_SIZE,
			"temp%d_input", cnt);
	atk_init_attribute(&sensor->input_attr,
			sensor->input_attr_name,
			0444, atk_temp_input_show, NULL);

	snprintf(sensor->label_attr_name, ATTR_NAME_SIZE,
			"temp%d_label", cnt);
	atk_init_attribute(&sensor->label_attr,
			sensor->label_attr_name,
			0444, atk_temp_label_show, NULL);

	snprintf(sensor->limit1_attr_name, ATTR_NAME_SIZE,
			"temp%d_max", cnt);
	atk_init_attribute(&sensor->limit1_attr,
			sensor->limit1_attr_name,
			0444, atk_temp_max_show, NULL);

	snprintf(sensor->limit2_attr_name, ATTR_NAME_SIZE,
			"temp%d_crit", cnt);
	atk_init_attribute(&sensor->limit2_attr,
			sensor->limit2_attr_name,
			0444, atk_temp_crit_show, NULL);

	list_add(&sensor->list, &data->temperature_list);

	return 1;
out:
	kfree(sensor->acpi_name);
	kfree(sensor);
	return err;
}

static int atk_add_fan(struct atk_data *data, union acpi_object *obj, int cnt)
{
	union acpi_object *flags;
	union acpi_object *name;
	union acpi_object *limit1;
	union acpi_object *limit2;
	union acpi_object *enable;
	struct atk_sensor_data *sensor;
	int err;

	enable = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE);
	if (!enable->integer.value)
		return 0;

	flags = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS);
	name = atk_get_pack_member(data, obj, HWMON_PACK_NAME);
	limit1 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1);
	limit2 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2);

	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
	if (!sensor)
		return -ENOMEM;

	sensor->acpi_name = kstrdup(name->string.pointer, GFP_KERNEL);
	if (!sensor->acpi_name) {
		err = -ENOMEM;
		goto out;
	}

	INIT_LIST_HEAD(&sensor->list);
	sensor->data = data;
	sensor->id = flags->integer.value;
	sensor->limit1 = limit1->integer.value;
	sensor->limit2 = limit2->integer.value;

	snprintf(sensor->input_attr_name, ATTR_NAME_SIZE,
			"fan%d_input", cnt);
	atk_init_attribute(&sensor->input_attr,
			sensor->input_attr_name,
			0444, atk_fan_input_show, NULL);

	snprintf(sensor->label_attr_name, ATTR_NAME_SIZE,
			"fan%d_label", cnt);
	atk_init_attribute(&sensor->label_attr,
			sensor->label_attr_name,
			0444, atk_fan_label_show, NULL);

	snprintf(sensor->limit1_attr_name, ATTR_NAME_SIZE,
			"fan%d_min", cnt);
	atk_init_attribute(&sensor->limit1_attr,
			sensor->limit1_attr_name,
			0444, atk_fan_min_show, NULL);

	snprintf(sensor->limit2_attr_name, ATTR_NAME_SIZE,
			"fan%d_max", cnt);
	atk_init_attribute(&sensor->limit2_attr,
			sensor->limit2_attr_name,
			0444, atk_fan_max_show, NULL);

	list_add(&sensor->list, &data->fan_list);

	return 1;
out:
	kfree(sensor->acpi_name);
	kfree(sensor);
	return err;
}

static int atk_add_sensor(struct atk_data *data, union acpi_object *obj, int i)
{
	struct device *dev = &data->acpi_dev->dev;
	unsigned long long type;
	int ret;

	if (obj->type != ACPI_TYPE_PACKAGE) {
		/* wft is this? */
		dev_warn(dev, "Unknown type for element %d: (%d)\n",
				i, obj->type);
		return -EINVAL;
	}

	ret = validate_hwmon_pack(data, obj);
	if (ret)
		return ret;

	/* Ok, we have a valid hwmon package */
	type = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS)->integer.value & ATK_TYPE_MASK;
	dev_dbg(dev, "Sensor %d is valid, type %#llx\n", i, type >> 16);

	switch (type) {
	case HWMON_TYPE_VOLT:
		ret = atk_add_voltage(data, obj, data->voltage_count);
		if (ret > 0)
			data->voltage_count++;
		break;
	case HWMON_TYPE_TEMP:
		/* temp%d entries are numbered starting from 1 */
		ret = atk_add_temperature(data, obj, data->temperature_count + 1);
		if (ret > 0)
			data->temperature_count++;
		break;
	case HWMON_TYPE_FAN:
		/* fan%d entries are numbered starting from 1 */
		ret = atk_add_fan(data, obj, data->fan_count + 1);
		if (ret > 0)
			data->fan_count++;
		break;
	default:
		dev_warn(dev, "Unknown sensor type: %#llx\n", type);
		break;
	}

	return ret;
}

static int atk_enumerate_old_hwmon(struct atk_data *data)
{
	struct device *dev = &data->acpi_dev->dev;
	struct acpi_buffer buf;
	union acpi_object *pack;
	acpi_status status;
	int i, ret;
	int count = 0;
	int num = 0;

	/* Voltages */
	buf.length = ACPI_ALLOCATE_BUFFER;
	status = acpi_evaluate_object_typed(data->atk_handle, METHOD_OLD_ENUM_VLT, NULL,
			&buf, ACPI_TYPE_PACKAGE);
	if (status != AE_OK) {
		dev_warn(dev, METHOD_OLD_ENUM_VLT ": ACPI exception: %s\n",
				acpi_format_exception(status));

		return -ENODEV;
	}

	pack = buf.pointer;
	for (i = 1; i < pack->package.count; i++) {
		union acpi_object *obj = &pack->package.elements[i];

		ret = atk_add_sensor(data, obj, num);
		if (ret > 0)
			count++;
		num++;
	}
	ACPI_FREE(buf.pointer);

	/* Temperatures */
	buf.length = ACPI_ALLOCATE_BUFFER;
	status = acpi_evaluate_object_typed(data->atk_handle, METHOD_OLD_ENUM_TMP, NULL,
			&buf, ACPI_TYPE_PACKAGE);
	if (status != AE_OK) {
		dev_warn(dev, METHOD_OLD_ENUM_TMP ": ACPI exception: %s\n",
				acpi_format_exception(status));

		ret = -ENODEV;
		goto cleanup;
	}

	pack = buf.pointer;
	for (i = 1; i < pack->package.count; i++) {
		union acpi_object *obj = &pack->package.elements[i];

		ret = atk_add_sensor(data, obj, num);
		if (ret > 0)
			count++;
		num++;
	}
	ACPI_FREE(buf.pointer);

	/* Fans */
	buf.length = ACPI_ALLOCATE_BUFFER;
	status = acpi_evaluate_object_typed(data->atk_handle, METHOD_OLD_ENUM_FAN, NULL,
			&buf, ACPI_TYPE_PACKAGE);
	if (status != AE_OK) {
		dev_warn(dev, METHOD_OLD_ENUM_FAN ": ACPI exception: %s\n",
				acpi_format_exception(status));

		ret = -ENODEV;
		goto cleanup;
	}

	pack = buf.pointer;
	for (i = 1; i < pack->package.count; i++) {
		union acpi_object *obj = &pack->package.elements[i];

		ret = atk_add_sensor(data, obj, num);
		if (ret > 0)
			count++;
		num++;
	}
	ACPI_FREE(buf.pointer);

	return count;
cleanup:
	atk_free_sensors(data);
	return ret;
}

static int atk_enumerate_new_hwmon(struct atk_data *data)
{
	struct device *dev = &data->acpi_dev->dev;
	struct acpi_buffer buf;
	acpi_status ret;
	struct acpi_object_list params;
	union acpi_object id;
	union acpi_object *pack;
	int err;
	int i;

	dev_dbg(dev, "Enumerating hwmon sensors\n");

	id.type = ACPI_TYPE_INTEGER;
	id.integer.value = ATK_MUX_HWMON;
	params.count = 1;
	params.pointer = &id;

	buf.length = ACPI_ALLOCATE_BUFFER;
	ret = acpi_evaluate_object_typed(data->enumerate_handle, NULL, &params,
			&buf, ACPI_TYPE_PACKAGE);
	if (ret != AE_OK) {
		dev_warn(dev, METHOD_ENUMERATE ": ACPI exception: %s\n",
				acpi_format_exception(ret));
		return -ENODEV;
	}

	/* Result must be a package */
	pack = buf.pointer;

	if (pack->package.count < 1) {
		dev_dbg(dev, "%s: hwmon package is too small: %d\n", __func__,
				pack->package.count);
		err = -EINVAL;
		goto out;
	}

	for (i = 0; i < pack->package.count; i++) {
		union acpi_object *obj = &pack->package.elements[i];
		unsigned long long type;

		if (obj->type != ACPI_TYPE_PACKAGE) {
			/* wft is this? */
			dev_warn(dev, "Unknown type for element %d: (%d)\n",
					i, obj->type);
			continue;
		}

		err = validate_hwmon_pack(data, obj);
		if (err)
			continue;

		/* Ok, we have a valid hwmon package */
		type = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS)->integer.value & ATK_TYPE_MASK;
		dev_dbg(dev, "Sensor %d is valid, type %#llx\n", i, type >> 16);

		switch (type) {
		case HWMON_TYPE_VOLT:
			ret = atk_add_voltage(data, obj, data->voltage_count);
			if (ret > 0)
				data->voltage_count++;
			break;
		case HWMON_TYPE_TEMP:
			ret = atk_add_temperature(data, obj, data->temperature_count + 1);
			if (ret > 0)
				data->temperature_count++;
			break;
		case HWMON_TYPE_FAN:
			ret = atk_add_fan(data, obj, data->fan_count + 1);
			if (ret > 0)
				data->fan_count++;
			break;
		default:
			dev_warn(dev, "Unknown sensor type: %#llx\n", type);
			break;
		}
	}

	err = data->voltage_count + data->temperature_count + data->fan_count;

out:
	ACPI_FREE(buf.pointer);
	return err;
}

static int atk_create_file_list(struct atk_data *data, struct list_head *head)
{
	struct device *hwmon_dev = data->hwmon_dev;
	struct atk_sensor_data *s;
	int ret;

	list_for_each_entry(s, head, list) {
		ret = device_create_file(hwmon_dev, &s->input_attr);
		if (ret)
			return ret;
		ret = device_create_file(hwmon_dev, &s->label_attr);
		if (ret)
			return ret;
		ret = device_create_file(hwmon_dev, &s->limit1_attr);
		if (ret)
			return ret;
		ret = device_create_file(hwmon_dev, &s->limit2_attr);
		if (ret)
			return ret;
	}

	return 0;
}

static int atk_create_files(struct atk_data *data)
{
	int err;

	err = atk_create_file_list(data, &data->voltage_list);
	if (err)
		return err;

	err = atk_create_file_list(data, &data->temperature_list);
	if (err)
		return err;

	err = atk_create_file_list(data, &data->fan_list);
	if (err)
		return err;

	err = device_create_file(data->hwmon_dev, &atk_name_attr);

	return err;
}

static void atk_remove_file_list(struct atk_data *data, struct list_head *head)
{
	struct device *hwmon_dev = data->hwmon_dev;
	struct atk_sensor_data *s;

	list_for_each_entry(s, head, list) {
		device_remove_file(hwmon_dev, &s->input_attr);
		device_remove_file(hwmon_dev, &s->label_attr);
		device_remove_file(hwmon_dev, &s->limit1_attr);
		device_remove_file(hwmon_dev, &s->limit2_attr);
	}
}

static void atk_remove_files(struct atk_data *data)
{
	atk_remove_file_list(data, &data->voltage_list);
	atk_remove_file_list(data, &data->temperature_list);
	atk_remove_file_list(data, &data->fan_list);
	device_remove_file(data->hwmon_dev, &atk_name_attr);
}

static void atk_free_sensor_list(struct list_head *head)
{
	struct atk_sensor_data *s, *tmp;

	list_for_each_entry_safe(s, tmp, head, list) {
		kfree(s->acpi_name);
		kfree(s);
	}
}

static void atk_free_sensors(struct atk_data *data)
{
	atk_free_sensor_list(&data->voltage_list);
	atk_free_sensor_list(&data->temperature_list);
	atk_free_sensor_list(&data->fan_list);
}

static int atk_register_hwmon(struct atk_data *data)
{
	struct device *dev = &data->acpi_dev->dev;
	int err;

	dev_dbg(dev, "registering hwmon device\n");
	data->hwmon_dev = hwmon_device_register(dev);
	if (IS_ERR(data->hwmon_dev))
		return PTR_ERR(data->hwmon_dev);

	dev_dbg(dev, "populating sysfs directory\n");
	err = atk_create_files(data);
	if (err)
		goto remove;

	return 0;
remove:
	/* Cleanup the registered files */
	atk_remove_files(data);
	hwmon_device_unregister(data->hwmon_dev);
	return err;
}

static int atk_check_old_if(struct atk_data *data, struct acpi_namespace_node *ns)
{
	struct device *dev = &data->acpi_dev->dev;
	struct acpi_namespace_node *ret;
	acpi_status status;

	/* RTMP: read temperature */
	status = acpi_ns_get_node(ns, METHOD_OLD_READ_TMP, ACPI_NS_NO_UPSEARCH, &ret);
	if (status != AE_OK) {
		dev_dbg(dev, "method " METHOD_OLD_READ_TMP " not found: %s\n",
				acpi_format_exception(status));
		return -ENODEV;
	}
	data->rtmp_handle = acpi_ns_convert_entry_to_handle(ret);

	/* RVLT: read voltage */
	status = acpi_ns_get_node(ns, METHOD_OLD_READ_VLT, ACPI_NS_NO_UPSEARCH, &ret);
	if (status != AE_OK) {
		dev_dbg(dev, "method " METHOD_OLD_READ_VLT " not found: %s\n",
				acpi_format_exception(status));
		return -ENODEV;
	}
	data->rvlt_handle = acpi_ns_convert_entry_to_handle(ret);

	/* RFAN: read fan status */
	status = acpi_ns_get_node(ns, METHOD_OLD_READ_FAN, ACPI_NS_NO_UPSEARCH, &ret);
	if (status != AE_OK) {
		dev_dbg(dev, "method " METHOD_OLD_READ_FAN " not found: %s\n",
				acpi_format_exception(status));
		return -ENODEV;
	}
	data->rfan_handle = acpi_ns_convert_entry_to_handle(ret);

	return 0;
}

static int atk_check_new_if(struct atk_data *data, struct acpi_namespace_node *ns)
{
	struct device *dev = &data->acpi_dev->dev;
	struct acpi_namespace_node *ret;
	acpi_status status;

	/* Enumeration */
	status = acpi_ns_get_node(ns, METHOD_ENUMERATE, ACPI_NS_NO_UPSEARCH, &ret);
	if (status != AE_OK) {
		dev_dbg(dev, "method " METHOD_ENUMERATE " not found\n");
		return -ENODEV;
	}
	data->enumerate_handle = acpi_ns_convert_entry_to_handle(ret);

	/* De-multiplexer (read) */
	status = acpi_ns_get_node(ns, METHOD_READ, ACPI_NS_NO_UPSEARCH, &ret);
	if (status != AE_OK) {
		dev_dbg(dev, "method " METHOD_READ " not found\n");
		return -ENODEV;
	}
	data->read_handle = acpi_ns_convert_entry_to_handle(ret);

	return 0;
}

static int atk_add(struct acpi_device *device)
{
	acpi_status ret;
	int err;
	struct acpi_buffer buf;
	union acpi_object *obj;
	struct acpi_namespace_node *search_ns;
	struct atk_data *data;

	dev_dbg(&device->dev, "adding...\n");

	data = kzalloc(sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->acpi_dev = device;
	data->atk_handle = device->handle;
	INIT_LIST_HEAD(&data->voltage_list);
	INIT_LIST_HEAD(&data->temperature_list);
	INIT_LIST_HEAD(&data->fan_list);

	buf.length = ACPI_ALLOCATE_BUFFER;
	ret = acpi_evaluate_object_typed(data->atk_handle, BOARD_ID, NULL,
			&buf, ACPI_TYPE_PACKAGE);
	if (ret != AE_OK) {
		dev_dbg(&device->dev, "atk: method MBIF not found\n");
		err = -ENODEV;
		goto out;
	}

	obj = buf.pointer;
	if (obj->package.count >= 2 &&
			obj->package.elements[1].type == ACPI_TYPE_STRING) {
		dev_dbg(&device->dev, "board ID = %s\n",
				obj->package.elements[1].string.pointer);
	}
	ACPI_FREE(buf.pointer);

	/* Check for hwmon methods */
	search_ns = acpi_ns_map_handle_to_node(device->handle);
	if (!search_ns) {
		err = -ENODEV;
		goto out;
	}

	/* First check "old" style methods; note that both may be present: in
	 * this case we stick to the old interface; analysis of multiple DSDTs
	 * indicates that when both interfaces are present the new one
	 * (GGRP/GITM) is not functional.
	 */
	err = atk_check_old_if(data, search_ns);
	if (!err) {
		dev_dbg(&device->dev, "Using old hwmon interface\n");
		data->old_interface = true;
	} else {
		err = atk_check_new_if(data, search_ns);
		if (err)
			goto out;

		dev_dbg(&device->dev, "Using new hwmon interface\n");
		data->old_interface = false;
	}

	if (data->old_interface)
		err = atk_enumerate_old_hwmon(data);
	else
		err = atk_enumerate_new_hwmon(data);
	if (err < 0)
		goto out;
	if (err == 0) {
		dev_info(&device->dev, "No usable sensor detected, bailing out\n");
		err = -ENODEV;
		goto out;
	}

	err = atk_register_hwmon(data);
	if (err)
		goto cleanup;

	device->driver_data = data;
	return 0;
cleanup:
	atk_free_sensors(data);
out:
	kfree(data);
	return err;
}

static int atk_remove(struct acpi_device *device, int type)
{
	struct atk_data *data = device->driver_data;
	dev_dbg(&device->dev, "removing...\n");

	device->driver_data = NULL;

	atk_remove_files(data);
	atk_free_sensors(data);
	hwmon_device_unregister(data->hwmon_dev);

	kfree(data);

	return 0;
}

int atk_init(void)
{
	int ret;

	ret = acpi_bus_register_driver(&atk_driver);
	if (ret)
		pr_info("atk: acpi_bus_register_driver failed: %d\n", ret);

	return ret;
}

void atk_exit(void)
{
	acpi_bus_unregister_driver(&atk_driver);
}

module_init(atk_init);
module_exit(atk_exit);

MODULE_LICENSE("GPL");

[-- Attachment #3: acpi.diff --]
[-- Type: text/x-diff, Size: 2509 bytes --]

diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 33bc0e3..1816513 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -169,14 +169,12 @@ acpi_evaluate_object(acpi_handle object,
 		     struct acpi_object_list *parameter_objects,
 		     struct acpi_buffer *return_object_buffer);
 
-#ifdef ACPI_FUTURE_USAGE
 acpi_status
 acpi_evaluate_object_typed(acpi_handle object,
 			   acpi_string pathname,
 			   struct acpi_object_list *external_params,
 			   struct acpi_buffer *return_buffer,
 			   acpi_object_type return_type);
-#endif
 
 acpi_status
 acpi_get_object_info(acpi_handle handle, struct acpi_buffer *return_buffer);
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
index b0817e1..2245593 100644
--- a/drivers/acpi/namespace/nsutils.c
+++ b/drivers/acpi/namespace/nsutils.c
@@ -700,6 +700,7 @@ struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
 
 	return (ACPI_CAST_PTR(struct acpi_namespace_node, handle));
 }
+EXPORT_SYMBOL(acpi_ns_map_handle_to_node);
 
 /*******************************************************************************
  *
@@ -736,6 +737,7 @@ acpi_handle acpi_ns_convert_entry_to_handle(struct acpi_namespace_node *node)
 	return ((acpi_handle) Node);
 ------------------------------------------------------*/
 }
+EXPORT_SYMBOL(acpi_ns_convert_entry_to_handle);
 
 /*******************************************************************************
  *
@@ -875,6 +877,7 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
 	ACPI_FREE(internal_path);
 	return_ACPI_STATUS(status);
 }
+EXPORT_SYMBOL(acpi_ns_get_node);
 
 /*******************************************************************************
  *
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index a085cc3..a7f81eb 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -52,7 +52,6 @@ ACPI_MODULE_NAME("nsxfeval")
 /* Local prototypes */
 static void acpi_ns_resolve_references(struct acpi_evaluate_info *info);
 
-#ifdef ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_evaluate_object_typed
@@ -146,7 +145,7 @@ acpi_evaluate_object_typed(acpi_handle handle,
 }
 
 ACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed)
-#endif				/*  ACPI_FUTURE_USAGE  */
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_evaluate_object

[-- Attachment #4: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

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

end of thread, other threads:[~2008-11-23 23:22 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-14  6:43 [lm-sensors] New Asus board and multiple sensors Hans de Goede
2008-09-14 18:51 ` Marco Chiappero
2008-09-15 10:45 ` Marco Chiappero
2008-09-15 12:17 ` Rudolf Marek
2008-09-16 21:36 ` Rudolf Marek
2008-09-17 20:27 ` Marco Chiappero
2008-09-17 20:49 ` Rudolf Marek
2008-09-18 11:35 ` Marco Chiappero
2008-11-23 15:23 ` Marco Chiappero
2008-11-23 16:50 ` Luca Tettamanti
2008-11-23 23:22 ` Luca Tettamanti

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.