All of lore.kernel.org
 help / color / mirror / Atom feed
* [lm-sensors] Any idea to support Fintek F71808A
@ 2011-04-06  6:54 D.B. Tsai
  2011-04-06  8:54 ` D.B. Tsai
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: D.B. Tsai @ 2011-04-06  6:54 UTC (permalink / raw)
  To: lm-sensors

Hi guys

I just got an interesting board, ECS HDC-I2 AMD E350. I'm gonna use it
as my use server, but I found out that lm-sensors doesn't support it.
The chip used by the board is Fintek F71808A. Will it be supported in
the nearly future?

Thank you.

Sincerely,

D.B. Tsai    蔡東邦
Ph.D. Student
Department of Applied Physics
Stanford University
-----------------------------------
Web: http://www.dbtsai.com
Phone : +1-650-383-8392   (USA)
              +886-910-008-392 (Taiwan)

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

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

* Re: [lm-sensors] Any idea to support Fintek F71808A
  2011-04-06  6:54 [lm-sensors] Any idea to support Fintek F71808A D.B. Tsai
@ 2011-04-06  8:54 ` D.B. Tsai
  2011-04-06  9:24 ` Jean Delvare
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: D.B. Tsai @ 2011-04-06  8:54 UTC (permalink / raw)
  To: lm-sensors

Hi

Since Fintek F71808E seems to be quick closed to F71808A, I copy
everything related to 71808E into F71808A in the f71882fg.c. The code
can be compiled, but when I try to modprobe, I got the error message
"FATAL: Error inserting f71882fg
(/lib/modules/2.6.38-8-server/kernel/drivers/hwmon/f71882fg.ko):
Device or resource busy
"

Anything I should notice?

Sincerely,

D.B. Tsai    蔡東邦
Ph.D. Student
Department of Applied Physics
Stanford University
-----------------------------------
Web: http://www.dbtsai.com
Phone : +1-650-383-8392   (USA)
              +886-910-008-392 (Taiwan)



On Tue, Apr 5, 2011 at 11:54 PM, D.B. Tsai <dbtsai@stanford.edu> wrote:
> Hi guys
>
> I just got an interesting board, ECS HDC-I2 AMD E350. I'm gonna use it
> as my use server, but I found out that lm-sensors doesn't support it.
> The chip used by the board is Fintek F71808A. Will it be supported in
> the nearly future?
>
> Thank you.
>
> Sincerely,
>
> D.B. Tsai    蔡東邦
> Ph.D. Student
> Department of Applied Physics
> Stanford University
> -----------------------------------
> Web: http://www.dbtsai.com
> Phone : +1-650-383-8392   (USA)
>               +886-910-008-392 (Taiwan)
>

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

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

* Re: [lm-sensors] Any idea to support Fintek F71808A
  2011-04-06  6:54 [lm-sensors] Any idea to support Fintek F71808A D.B. Tsai
  2011-04-06  8:54 ` D.B. Tsai
@ 2011-04-06  9:24 ` Jean Delvare
  2011-04-06  9:34 ` D.B. Tsai
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Jean Delvare @ 2011-04-06  9:24 UTC (permalink / raw)
  To: lm-sensors

On Wed, 6 Apr 2011 01:54:56 -0700, D.B. Tsai wrote:
> Hi
> 
> Since Fintek F71808E seems to be quick closed to F71808A, I copy

How can you tell? Similar numbers are no guarantee of compatibility.

> everything related to 71808E into F71808A in the f71882fg.c. The code
> can be compiled, but when I try to modprobe, I got the error message
> "FATAL: Error inserting f71882fg
> (/lib/modules/2.6.38-8-server/kernel/drivers/hwmon/f71882fg.ko):
> Device or resource busy
> "
> 
> Anything I should notice?

Read the kernel logs (dmesg | tail). Most likely ACPI requested the I/O
ports in question for its own use.

http://www.lm-sensors.org/wiki/FAQ/Chapter3#Mysensorshavestoppedworkinginkernel2.6.31

-- 
Jean Delvare

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

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

* Re: [lm-sensors] Any idea to support Fintek F71808A
  2011-04-06  6:54 [lm-sensors] Any idea to support Fintek F71808A D.B. Tsai
  2011-04-06  8:54 ` D.B. Tsai
  2011-04-06  9:24 ` Jean Delvare
@ 2011-04-06  9:34 ` D.B. Tsai
  2011-04-06 10:09 ` Hans de Goede
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: D.B. Tsai @ 2011-04-06  9:34 UTC (permalink / raw)
  To: lm-sensors

Hey

This is the error message I got. I hope that help.

[ 2338.411723] ACPI: If an ACPI driver is available for this device,
you should use it instead of the native driver
[ 4594.391901] f71882fg: Found f71808a chip at 0xe80, revision 33
[ 4594.392414] ACPI: resource f71882fg [io  0x0e80-0x0e87] conflicts
with ACPI region HMIO [io 0xe80-0xf7f]
[ 4594.392423] ACPI: If an ACPI driver is available for this device,
you should use it instead of the native driver

Thanks.

Best Wishes,

Dong-Bang Tsai    蔡東邦
Ph.D. Student in Applied Physics at Stanford University
史丹佛大學應用物理所博士班
-----------------------------------
Web : http://www.dbtsai.com
Phone : +1-650-383-8392  (USA)
            +886-910-008-392 (Taiwan)



On Wed, Apr 6, 2011 at 2:24 AM, Jean Delvare <khali@linux-fr.org> wrote:
> On Wed, 6 Apr 2011 01:54:56 -0700, D.B. Tsai wrote:
>> Hi
>>
>> Since Fintek F71808E seems to be quick closed to F71808A, I copy
>
> How can you tell? Similar numbers are no guarantee of compatibility.
>
>> everything related to 71808E into F71808A in the f71882fg.c. The code
>> can be compiled, but when I try to modprobe, I got the error message
>> "FATAL: Error inserting f71882fg
>> (/lib/modules/2.6.38-8-server/kernel/drivers/hwmon/f71882fg.ko):
>> Device or resource busy
>> "
>>
>> Anything I should notice?
>
> Read the kernel logs (dmesg | tail). Most likely ACPI requested the I/O
> ports in question for its own use.
>
> http://www.lm-sensors.org/wiki/FAQ/Chapter3#Mysensorshavestoppedworkinginkernel2.6.31
>
> --
> Jean Delvare
>
> _______________________________________________
> lm-sensors mailing list
> lm-sensors@lm-sensors.org
> http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
>

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

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

* Re: [lm-sensors] Any idea to support Fintek F71808A
  2011-04-06  6:54 [lm-sensors] Any idea to support Fintek F71808A D.B. Tsai
                   ` (2 preceding siblings ...)
  2011-04-06  9:34 ` D.B. Tsai
@ 2011-04-06 10:09 ` Hans de Goede
  2011-04-06 10:15 ` D.B. Tsai
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Hans de Goede @ 2011-04-06 10:09 UTC (permalink / raw)
  To: lm-sensors

Hi,

On 04/06/2011 10:54 AM, D.B. Tsai wrote:
> Hi
>
> Since Fintek F71808E seems to be quick closed to F71808A, I copy
> everything related to 71808E into F71808A in the f71882fg.c. The code
> can be compiled, but when I try to modprobe, I got the error message
> "FATAL: Error inserting f71882fg
> (/lib/modules/2.6.38-8-server/kernel/drivers/hwmon/f71882fg.ko):
> Device or resource busy
> "
>
> Anything I should notice?

The F71808A is not 100% compatible with the F71808E, at it has less
voltage inputs for one. I've not yet checked the entire datasheet of
the F71808A to see if there are any other differences.

I saw further down the thread that your BIOS ACPI tables / code claims
to own the io ranges which are used for the hwmon part. May I ask on which
kind of device / motherboard you have a F71808A, is this in a laptop or
on a regular motherboard, and which model?

Regards,

Hans

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

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

* Re: [lm-sensors] Any idea to support Fintek F71808A
  2011-04-06  6:54 [lm-sensors] Any idea to support Fintek F71808A D.B. Tsai
                   ` (3 preceding siblings ...)
  2011-04-06 10:09 ` Hans de Goede
@ 2011-04-06 10:15 ` D.B. Tsai
  2011-04-06 17:11 ` Hans de Goede
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: D.B. Tsai @ 2011-04-06 10:15 UTC (permalink / raw)
  To: lm-sensors

Hi Hans

It's regular mainboard.

The motherboard I have is this one
http://www.ecs.com.tw/ECSWebSite/Product/Product_Detail.aspx?DetailID\x1231&CategoryID=1&MenuID\x106&LanID=0

Do you want to test it? I can create an account with sudo permission for you.

Thanks.

Best Wishes,

Dong-Bang Tsai    蔡東邦
Ph.D. Student in Applied Physics at Stanford University
史丹佛大學應用物理所博士班
-----------------------------------
Web : http://www.dbtsai.com
Phone : +1-650-383-8392  (USA)
            +886-910-008-392 (Taiwan)



On Wed, Apr 6, 2011 at 3:09 AM, Hans de Goede <hdegoede@redhat.com> wrote:
> Hi,
>
> On 04/06/2011 10:54 AM, D.B. Tsai wrote:
>>
>> Hi
>>
>> Since Fintek F71808E seems to be quick closed to F71808A, I copy
>> everything related to 71808E into F71808A in the f71882fg.c. The code
>> can be compiled, but when I try to modprobe, I got the error message
>> "FATAL: Error inserting f71882fg
>> (/lib/modules/2.6.38-8-server/kernel/drivers/hwmon/f71882fg.ko):
>> Device or resource busy
>> "
>>
>> Anything I should notice?
>
> The F71808A is not 100% compatible with the F71808E, at it has less
> voltage inputs for one. I've not yet checked the entire datasheet of
> the F71808A to see if there are any other differences.
>
> I saw further down the thread that your BIOS ACPI tables / code claims
> to own the io ranges which are used for the hwmon part. May I ask on which
> kind of device / motherboard you have a F71808A, is this in a laptop or
> on a regular motherboard, and which model?
>
> Regards,
>
> Hans
>
> _______________________________________________
> lm-sensors mailing list
> lm-sensors@lm-sensors.org
> http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
>

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

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

* Re: [lm-sensors] Any idea to support Fintek F71808A
  2011-04-06  6:54 [lm-sensors] Any idea to support Fintek F71808A D.B. Tsai
                   ` (4 preceding siblings ...)
  2011-04-06 10:15 ` D.B. Tsai
@ 2011-04-06 17:11 ` Hans de Goede
  2011-04-06 20:47 ` D.B. Tsai
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Hans de Goede @ 2011-04-06 17:11 UTC (permalink / raw)
  To: lm-sensors

Hi,

On 04/06/2011 12:15 PM, D.B. Tsai wrote:
> Hi Hans
>
> It's regular mainboard.
>
> The motherboard I have is this one
> http://www.ecs.com.tw/ECSWebSite/Product/Product_Detail.aspx?DetailID\x1231&CategoryID=1&MenuID\x106&LanID=0
>
> Do you want to test it? I can create an account with sudo permission for you.

No that won't be necessary. Ok, so with a regular motherboard, chances are
that ignoring the acpi resource conflict and loading the driver anyways will work
fine.

Please read:
http://www.lm-sensors.org/wiki/FAQ/Chapter3#Mysensorshavestoppedworkinginkernel2.6.31

And notice that there are risks to disabling the acpi resource conflict check!

If you're willing to take that risk, let me know and I'll work on an update
for the f71882fg driver to properly support the f71808a as time permits, and
get back to you when I have something for you to test.

Regards,

Hans

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

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

* Re: [lm-sensors] Any idea to support Fintek F71808A
  2011-04-06  6:54 [lm-sensors] Any idea to support Fintek F71808A D.B. Tsai
                   ` (5 preceding siblings ...)
  2011-04-06 17:11 ` Hans de Goede
@ 2011-04-06 20:47 ` D.B. Tsai
  2011-04-06 21:15 ` D.B. Tsai
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: D.B. Tsai @ 2011-04-06 20:47 UTC (permalink / raw)
  To: lm-sensors

Hi

Sure, I can take the risk of the disabling acpi resource conflict
check, and I'm willing to test your code. Please let send me the code
when you finish it. By the way, I'm using Ubuntu 11.04 with kernel
2.6.38-8-server, and wondering to know that when will the mainline
kernel fix this conflict issue?

Thanks.

Best Wishes,

Dong-Bang Tsai    蔡東邦
Ph.D. Student in Applied Physics at Stanford University
史丹佛大學應用物理所博士班
-----------------------------------
Web : http://www.dbtsai.com
Phone : +1-650-383-8392  (USA)
            +886-910-008-392 (Taiwan)



On Wed, Apr 6, 2011 at 10:11 AM, Hans de Goede <hdegoede@redhat.com> wrote:
> Hi,
>
> On 04/06/2011 12:15 PM, D.B. Tsai wrote:
>>
>> Hi Hans
>>
>> It's regular mainboard.
>>
>> The motherboard I have is this one
>>
>> http://www.ecs.com.tw/ECSWebSite/Product/Product_Detail.aspx?DetailID\x1231&CategoryID=1&MenuID\x106&LanID=0
>>
>> Do you want to test it? I can create an account with sudo permission for
>> you.
>
> No that won't be necessary. Ok, so with a regular motherboard, chances are
> that ignoring the acpi resource conflict and loading the driver anyways will
> work
> fine.
>
> Please read:
> http://www.lm-sensors.org/wiki/FAQ/Chapter3#Mysensorshavestoppedworkinginkernel2.6.31
>
> And notice that there are risks to disabling the acpi resource conflict
> check!
>
> If you're willing to take that risk, let me know and I'll work on an update
> for the f71882fg driver to properly support the f71808a as time permits, and
> get back to you when I have something for you to test.
>
> Regards,
>
> Hans
>

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

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

* Re: [lm-sensors] Any idea to support Fintek F71808A
  2011-04-06  6:54 [lm-sensors] Any idea to support Fintek F71808A D.B. Tsai
                   ` (6 preceding siblings ...)
  2011-04-06 20:47 ` D.B. Tsai
@ 2011-04-06 21:15 ` D.B. Tsai
  2011-04-07  7:29 ` Jean Delvare
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: D.B. Tsai @ 2011-04-06 21:15 UTC (permalink / raw)
  To: lm-sensors

Hi

With simply copying all the code from F71808E and disabling the
conflict resource check in the boot loader, I can get the partially
working result now. It seems that the fan speed is working tho.

root@www:~/lm-sensors# sensors
k10temp-pci-00c3
Adapter: PCI adapter
temp1:       +50.5°C  (high = +70.0°C, crit = +100.0°C)

radeon-pci-0008
Adapter: PCI adapter
temp1:       +50.0°C

f71808a-isa-0e80
Adapter: ISA adapter
in0:         +1.75 V
in1:         +0.99 V
in2:         +0.99 V
in3:         +1.51 V
in4:         +2.04 V
in5:         +2.04 V
in7:         +1.66 V
in8:         +1.77 V
fan1:          0 RPM  ALARM
fan2:       3836 RPM
fan3:          0 RPM  ALARM
temp1:       +37.0°C  (high = +85.0°C, hyst = +81.0°C)
                      (crit = +100.0°C, hyst = +96.0°C)  sensor = thermistor
temp2:         FAULT  (high = +85.0°C, hyst = +81.0°C)
                      (crit = +100.0°C, hyst = +96.0°C)  sensor = transistor


Best Wishes,

Dong-Bang Tsai    蔡東邦
Ph.D. Student in Applied Physics at Stanford University
史丹佛大學應用物理所博士班
-----------------------------------
Web : http://www.dbtsai.com
Phone : +1-650-383-8392  (USA)
            +886-910-008-392 (Taiwan)



On Wed, Apr 6, 2011 at 1:47 PM, D.B. Tsai <dbtsai@gmail.com> wrote:
> Hi
>
> Sure, I can take the risk of the disabling acpi resource conflict
> check, and I'm willing to test your code. Please let send me the code
> when you finish it. By the way, I'm using Ubuntu 11.04 with kernel
> 2.6.38-8-server, and wondering to know that when will the mainline
> kernel fix this conflict issue?
>
> Thanks.
>
> Best Wishes,
>
> Dong-Bang Tsai    蔡東邦
> Ph.D. Student in Applied Physics at Stanford University
> 史丹佛大學應用物理所博士班
> -----------------------------------
> Web : http://www.dbtsai.com
> Phone : +1-650-383-8392  (USA)
>             +886-910-008-392 (Taiwan)
>
>
>
> On Wed, Apr 6, 2011 at 10:11 AM, Hans de Goede <hdegoede@redhat.com> wrote:
>> Hi,
>>
>> On 04/06/2011 12:15 PM, D.B. Tsai wrote:
>>>
>>> Hi Hans
>>>
>>> It's regular mainboard.
>>>
>>> The motherboard I have is this one
>>>
>>> http://www.ecs.com.tw/ECSWebSite/Product/Product_Detail.aspx?DetailID\x1231&CategoryID=1&MenuID\x106&LanID=0
>>>
>>> Do you want to test it? I can create an account with sudo permission for
>>> you.
>>
>> No that won't be necessary. Ok, so with a regular motherboard, chances are
>> that ignoring the acpi resource conflict and loading the driver anyways will
>> work
>> fine.
>>
>> Please read:
>> http://www.lm-sensors.org/wiki/FAQ/Chapter3#Mysensorshavestoppedworkinginkernel2.6.31
>>
>> And notice that there are risks to disabling the acpi resource conflict
>> check!
>>
>> If you're willing to take that risk, let me know and I'll work on an update
>> for the f71882fg driver to properly support the f71808a as time permits, and
>> get back to you when I have something for you to test.
>>
>> Regards,
>>
>> Hans
>>
>

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

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

* Re: [lm-sensors] Any idea to support Fintek F71808A
  2011-04-06  6:54 [lm-sensors] Any idea to support Fintek F71808A D.B. Tsai
                   ` (7 preceding siblings ...)
  2011-04-06 21:15 ` D.B. Tsai
@ 2011-04-07  7:29 ` Jean Delvare
  2011-04-07  8:01 ` D.B. Tsai
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Jean Delvare @ 2011-04-07  7:29 UTC (permalink / raw)
  To: lm-sensors

On Wed, 6 Apr 2011 13:47:45 -0700, D.B. Tsai wrote:
> Hi
> 
> Sure, I can take the risk of the disabling acpi resource conflict
> check, and I'm willing to test your code. Please let send me the code
> when you finish it. By the way, I'm using Ubuntu 11.04 with kernel
> 2.6.38-8-server, and wondering to know that when will the mainline
> kernel fix this conflict issue?

Never, as this isn't a bug per se. Your ACPI BIOS wants to control the
I/O ports, the kernels wants them too, and that's about it. If your
BIOS requests the I/O ports but doesn't use them, then it's a bug in
your BIOS.

Some vendors (Asus) request the I/O ports for a reason, and they
implement a proprietary interface on top of the hardware monitoring
chip. In this case it is possible to write an ACPI driver as a
replacement for the native driver. Unfortunately, most other vendors
which request the I/O ports don't implement anything like this.

-- 
Jean Delvare

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

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

* Re: [lm-sensors] Any idea to support Fintek F71808A
  2011-04-06  6:54 [lm-sensors] Any idea to support Fintek F71808A D.B. Tsai
                   ` (8 preceding siblings ...)
  2011-04-07  7:29 ` Jean Delvare
@ 2011-04-07  8:01 ` D.B. Tsai
  2011-04-07  8:36 ` Jean Delvare
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: D.B. Tsai @ 2011-04-07  8:01 UTC (permalink / raw)
  To: lm-sensors

Hi Jean

Thank you for clarification. But is it possible that when I/O ports is
controlled by motherboard, the kernels can still "read" the
information from the I/O ports rather than read and write data to I/O
ports? I think in this case, at least, I can monitor my fan speed
without really controlling the ports, and I think it's still safe.

Thanks.

Best Wishes,

Dong-Bang Tsai    蔡東邦
Ph.D. Student in Applied Physics at Stanford University
史丹佛大學應用物理所博士班
-----------------------------------
Web : http://www.dbtsai.com
Phone : +1-650-383-8392  (USA)
            +886-910-008-392 (Taiwan)



On Thu, Apr 7, 2011 at 12:29 AM, Jean Delvare <khali@linux-fr.org> wrote:
> On Wed, 6 Apr 2011 13:47:45 -0700, D.B. Tsai wrote:
>> Hi
>>
>> Sure, I can take the risk of the disabling acpi resource conflict
>> check, and I'm willing to test your code. Please let send me the code
>> when you finish it. By the way, I'm using Ubuntu 11.04 with kernel
>> 2.6.38-8-server, and wondering to know that when will the mainline
>> kernel fix this conflict issue?
>
> Never, as this isn't a bug per se. Your ACPI BIOS wants to control the
> I/O ports, the kernels wants them too, and that's about it. If your
> BIOS requests the I/O ports but doesn't use them, then it's a bug in
> your BIOS.
>
> Some vendors (Asus) request the I/O ports for a reason, and they
> implement a proprietary interface on top of the hardware monitoring
> chip. In this case it is possible to write an ACPI driver as a
> replacement for the native driver. Unfortunately, most other vendors
> which request the I/O ports don't implement anything like this.
>
> --
> Jean Delvare
>

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

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

* Re: [lm-sensors] Any idea to support Fintek F71808A
  2011-04-06  6:54 [lm-sensors] Any idea to support Fintek F71808A D.B. Tsai
                   ` (9 preceding siblings ...)
  2011-04-07  8:01 ` D.B. Tsai
@ 2011-04-07  8:36 ` Jean Delvare
  2011-04-21  9:36 ` Hans de Goede
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Jean Delvare @ 2011-04-07  8:36 UTC (permalink / raw)
  To: lm-sensors

On Thu, 7 Apr 2011 01:01:18 -0700, D.B. Tsai wrote:
> Thank you for clarification. But is it possible that when I/O ports is
> controlled by motherboard, the kernels can still "read" the
> information from the I/O ports rather than read and write data to I/O
> ports? I think in this case, at least, I can monitor my fan speed
> without really controlling the ports, and I think it's still safe.

Please don't top-post.

Unfortunately not, because almost all hwmon chips use an index/data I/O
port pair for register access. So you need to write to the index I/O
port even for register reads. And non-synchronized concurrent access to
such I/O port pair is disastrous.

-- 
Jean Delvare

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

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

* Re: [lm-sensors] Any idea to support Fintek F71808A
  2011-04-06  6:54 [lm-sensors] Any idea to support Fintek F71808A D.B. Tsai
                   ` (10 preceding siblings ...)
  2011-04-07  8:36 ` Jean Delvare
@ 2011-04-21  9:36 ` Hans de Goede
  2011-04-25 16:19 ` D.B. Tsai
  2011-04-26  8:09 ` Hans de Goede
  13 siblings, 0 replies; 15+ messages in thread
From: Hans de Goede @ 2011-04-21  9:36 UTC (permalink / raw)
  To: lm-sensors

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

Hi,

On 04/06/2011 10:47 PM, D.B. Tsai wrote:
> Hi
>
> Sure, I can take the risk of the disabling acpi resource conflict
> check, and I'm willing to test your code. Please let send me the code
> when you finish it.

Attached is an updated f71862fg driver which supports the f71808a to test,
boot with "acpi_enforce_resources=lax", drop the 2 attached files in a
dir, and do:
make
rmmod f71882fg
insmod f71882fg.ko
sensors

Please let me know if this works properly for you, also I would
appreciate a mail with the output of the sensors and dmesg
commands.

Regards,

Hans

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

obj-m += f71882fg.o

all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean


[-- Attachment #3: f71882fg.c --]
[-- Type: text/plain, Size: 84168 bytes --]

/***************************************************************************
 *   Copyright (C) 2006 by Hans Edgington <hans@edgington.nl>              *
 *   Copyright (C) 2007-2011 Hans de Goede <hdegoede@redhat.com>           *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#define pr_warn pr_warning

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/platform_device.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/io.h>
#include <linux/acpi.h>

#define DRVNAME "f71882fg"

#define SIO_F71858FG_LD_HWM	0x02	/* Hardware monitor logical device */
#define SIO_F71882FG_LD_HWM	0x04	/* Hardware monitor logical device */
#define SIO_UNLOCK_KEY		0x87	/* Key to enable Super-I/O */
#define SIO_LOCK_KEY		0xAA	/* Key to disable Super-I/O */

#define SIO_REG_LDSEL		0x07	/* Logical device select */
#define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */
#define SIO_REG_DEVREV		0x22	/* Device revision */
#define SIO_REG_MANID		0x23	/* Fintek ID (2 bytes) */
#define SIO_REG_ENABLE		0x30	/* Logical device enable */
#define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */

#define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
#define SIO_F71808E_ID		0x0901	/* Chipset ID */
#define SIO_F71808A_ID		0x1001	/* Chipset ID */
#define SIO_F71858_ID		0x0507  /* Chipset ID */
#define SIO_F71862_ID		0x0601	/* Chipset ID */
#define SIO_F71869_ID		0x0814	/* Chipset ID */
#define SIO_F71882_ID		0x0541	/* Chipset ID */
#define SIO_F71889_ID		0x0723	/* Chipset ID */
#define SIO_F71889E_ID		0x0909	/* Chipset ID */
#define SIO_F71889A_ID		0x1005	/* Chipset ID */
#define SIO_F8000_ID		0x0581	/* Chipset ID */
#define SIO_F81865_ID		0x0704	/* Chipset ID */

#define REGION_LENGTH		8
#define ADDR_REG_OFFSET		5
#define DATA_REG_OFFSET		6

#define F71882FG_REG_IN_STATUS		0x12 /* f7188x only */
#define F71882FG_REG_IN_BEEP		0x13 /* f7188x only */
#define F71882FG_REG_IN(nr)		(0x20  + (nr))
#define F71882FG_REG_IN1_HIGH		0x32 /* f7188x only */

#define F71882FG_REG_FAN(nr)		(0xA0 + (16 * (nr)))
#define F71882FG_REG_FAN_TARGET(nr)	(0xA2 + (16 * (nr)))
#define F71882FG_REG_FAN_FULL_SPEED(nr)	(0xA4 + (16 * (nr)))
#define F71882FG_REG_FAN_STATUS		0x92
#define F71882FG_REG_FAN_BEEP		0x93

#define F71882FG_REG_TEMP(nr)		(0x70 + 2 * (nr))
#define F71882FG_REG_TEMP_OVT(nr)	(0x80 + 2 * (nr))
#define F71882FG_REG_TEMP_HIGH(nr)	(0x81 + 2 * (nr))
#define F71882FG_REG_TEMP_STATUS	0x62
#define F71882FG_REG_TEMP_BEEP		0x63
#define F71882FG_REG_TEMP_CONFIG	0x69
#define F71882FG_REG_TEMP_HYST(nr)	(0x6C + (nr))
#define F71882FG_REG_TEMP_TYPE		0x6B
#define F71882FG_REG_TEMP_DIODE_OPEN	0x6F

#define F71882FG_REG_PWM(nr)		(0xA3 + (16 * (nr)))
#define F71882FG_REG_PWM_TYPE		0x94
#define F71882FG_REG_PWM_ENABLE		0x96

#define F71882FG_REG_FAN_HYST(nr)	(0x98 + (nr))

#define F71882FG_REG_FAN_FAULT_T	0x9F
#define F71882FG_FAN_NEG_TEMP_EN	0x20
#define F71882FG_FAN_PROG_SEL		0x80

#define F71882FG_REG_POINT_PWM(pwm, point)	(0xAA + (point) + (16 * (pwm)))
#define F71882FG_REG_POINT_TEMP(pwm, point)	(0xA6 + (point) + (16 * (pwm)))
#define F71882FG_REG_POINT_MAPPING(nr)		(0xAF + 16 * (nr))

#define	F71882FG_REG_START		0x01

#define F71882FG_MAX_INS		9

#define FAN_MIN_DETECT			366 /* Lowest detectable fanspeed */

static unsigned short force_id;
module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");

enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71882fg, f71889fg,
	     f71889ed, f71889a, f8000, f81865f };

static const char *f71882fg_names[] = {
	"f71808e",
	"f71808a",
	"f71858fg",
	"f71862fg",
	"f71869", /* Both f71869f and f71869e, reg. compatible and same id */
	"f71882fg",
	"f71889fg", /* f81801u too, same id */
	"f71889ed",
	"f71889a",
	"f8000",
	"f81865f",
};

static const char f71882fg_has_in[][F71882FG_MAX_INS] = {
	[f71808e]	= { 1, 1, 1, 1, 1, 1, 0, 1, 1 },
	[f71808a]	= { 1, 1, 1, 1, 0, 0, 0, 1, 1 },
	[f71858fg]	= { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
	[f71862fg]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
	[f71869]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
	[f71882fg]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
	[f71889fg]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
	[f71889ed]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
	[f71889a]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
	[f8000]		= { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
	[f81865f]	= { 1, 1, 1, 1, 1, 1, 1, 0, 0 },
};

static const char f71882fg_has_in1_alarm[] = {
	[f71808e]	= 0,
	[f71808a]	= 0,
	[f71858fg]	= 0,
	[f71862fg]	= 0,
	[f71869]	= 0,
	[f71882fg]	= 1,
	[f71889fg]	= 1,
	[f71889ed]	= 1,
	[f71889a]	= 1,
	[f8000]		= 0,
	[f81865f]	= 1,
};

static const char f71882fg_fan_has_beep[] = {
	[f71808e]	= 0,
	[f71808a]	= 0,
	[f71858fg]	= 0,
	[f71862fg]	= 1,
	[f71869]	= 1,
	[f71882fg]	= 1,
	[f71889fg]	= 1,
	[f71889ed]	= 1,
	[f71889a]	= 1,
	[f8000]		= 0,
	[f81865f]	= 1,
};

static const char f71882fg_nr_fans[] = {
	[f71808e]	= 3,
	[f71808a]	= 2, /* +1 fan which is monitor + simple pwm only */
	[f71858fg]	= 3,
	[f71862fg]	= 3,
	[f71869]	= 3,
	[f71882fg]	= 4,
	[f71889fg]	= 3,
	[f71889ed]	= 3,
	[f71889a]	= 3,
	[f8000]		= 3, /* +1 fan which is monitor only */
	[f81865f]	= 2,
};

static const char f71882fg_temp_has_beep[] = {
	[f71808e]	= 0,
	[f71808a]	= 1,
	[f71858fg]	= 0,
	[f71862fg]	= 1,
	[f71869]	= 1,
	[f71882fg]	= 1,
	[f71889fg]	= 1,
	[f71889ed]	= 1,
	[f71889a]	= 1,
	[f8000]		= 0,
	[f81865f]	= 1,
};

static const char f71882fg_nr_temps[] = {
	[f71808e]	= 2,
	[f71808a]	= 2,
	[f71858fg]	= 3,
	[f71862fg]	= 3,
	[f71869]	= 3,
	[f71882fg]	= 3,
	[f71889fg]	= 3,
	[f71889ed]	= 3,
	[f71889a]	= 3,
	[f8000]		= 3,
	[f81865f]	= 2,
};

static struct platform_device *f71882fg_pdev;

/* Super-I/O Function prototypes */
static inline int superio_inb(int base, int reg);
static inline int superio_inw(int base, int reg);
static inline int superio_enter(int base);
static inline void superio_select(int base, int ld);
static inline void superio_exit(int base);

struct f71882fg_sio_data {
	enum chips type;
};

struct f71882fg_data {
	unsigned short addr;
	enum chips type;
	struct device *hwmon_dev;

	struct mutex update_lock;
	int temp_start;			/* temp numbering start (0 or 1) */
	char valid;			/* !=0 if following fields are valid */
	char auto_point_temp_signed;
	unsigned long last_updated;	/* In jiffies */
	unsigned long last_limits;	/* In jiffies */

	/* Register Values */
	u8	in[F71882FG_MAX_INS];
	u8	in1_max;
	u8	in_status;
	u8	in_beep;
	u16	fan[4];
	u16	fan_target[4];
	u16	fan_full_speed[4];
	u8	fan_status;
	u8	fan_beep;
	/* Note: all models have max 3 temperature channels, but on some
	   they are addressed as 0-2 and on others as 1-3, so for coding
	   convenience we reserve space for 4 channels */
	u16	temp[4];
	u8	temp_ovt[4];
	u8	temp_high[4];
	u8	temp_hyst[2]; /* 2 hysts stored per reg */
	u8	temp_type[4];
	u8	temp_status;
	u8	temp_beep;
	u8	temp_diode_open;
	u8	temp_config;
	u8	pwm[4];
	u8	pwm_enable;
	u8	pwm_auto_point_hyst[2];
	u8	pwm_auto_point_mapping[4];
	u8	pwm_auto_point_pwm[4][5];
	s8	pwm_auto_point_temp[4][4];
};

/* Sysfs in */
static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
	char *buf);
static ssize_t show_in_max(struct device *dev, struct device_attribute
	*devattr, char *buf);
static ssize_t store_in_max(struct device *dev, struct device_attribute
	*devattr, const char *buf, size_t count);
static ssize_t show_in_beep(struct device *dev, struct device_attribute
	*devattr, char *buf);
static ssize_t store_in_beep(struct device *dev, struct device_attribute
	*devattr, const char *buf, size_t count);
static ssize_t show_in_alarm(struct device *dev, struct device_attribute
	*devattr, char *buf);
/* Sysfs Fan */
static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
	char *buf);
static ssize_t show_fan_full_speed(struct device *dev,
	struct device_attribute *devattr, char *buf);
static ssize_t store_fan_full_speed(struct device *dev,
	struct device_attribute *devattr, const char *buf, size_t count);
static ssize_t show_fan_beep(struct device *dev, struct device_attribute
	*devattr, char *buf);
static ssize_t store_fan_beep(struct device *dev, struct device_attribute
	*devattr, const char *buf, size_t count);
static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
	*devattr, char *buf);
/* Sysfs Temp */
static ssize_t show_temp(struct device *dev, struct device_attribute
	*devattr, char *buf);
static ssize_t show_temp_max(struct device *dev, struct device_attribute
	*devattr, char *buf);
static ssize_t store_temp_max(struct device *dev, struct device_attribute
	*devattr, const char *buf, size_t count);
static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
	*devattr, char *buf);
static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
	*devattr, const char *buf, size_t count);
static ssize_t show_temp_crit(struct device *dev, struct device_attribute
	*devattr, char *buf);
static ssize_t store_temp_crit(struct device *dev, struct device_attribute
	*devattr, const char *buf, size_t count);
static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
	*devattr, char *buf);
static ssize_t show_temp_type(struct device *dev, struct device_attribute
	*devattr, char *buf);
static ssize_t show_temp_beep(struct device *dev, struct device_attribute
	*devattr, char *buf);
static ssize_t store_temp_beep(struct device *dev, struct device_attribute
	*devattr, const char *buf, size_t count);
static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
	*devattr, char *buf);
static ssize_t show_temp_fault(struct device *dev, struct device_attribute
	*devattr, char *buf);
/* PWM and Auto point control */
static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
	char *buf);
static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr,
	const char *buf, size_t count);
static ssize_t show_simple_pwm(struct device *dev,
	struct device_attribute *devattr, char *buf);
static ssize_t store_simple_pwm(struct device *dev,
	struct device_attribute *devattr, const char *buf, size_t count);
static ssize_t show_pwm_enable(struct device *dev,
	struct device_attribute *devattr, char *buf);
static ssize_t store_pwm_enable(struct device *dev,
	struct device_attribute	*devattr, const char *buf, size_t count);
static ssize_t show_pwm_interpolate(struct device *dev,
	struct device_attribute *devattr, char *buf);
static ssize_t store_pwm_interpolate(struct device *dev,
	struct device_attribute *devattr, const char *buf, size_t count);
static ssize_t show_pwm_auto_point_channel(struct device *dev,
	struct device_attribute *devattr, char *buf);
static ssize_t store_pwm_auto_point_channel(struct device *dev,
	struct device_attribute *devattr, const char *buf, size_t count);
static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
	struct device_attribute *devattr, char *buf);
static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
	struct device_attribute *devattr, const char *buf, size_t count);
static ssize_t show_pwm_auto_point_pwm(struct device *dev,
	struct device_attribute *devattr, char *buf);
static ssize_t store_pwm_auto_point_pwm(struct device *dev,
	struct device_attribute *devattr, const char *buf, size_t count);
static ssize_t show_pwm_auto_point_temp(struct device *dev,
	struct device_attribute *devattr, char *buf);
static ssize_t store_pwm_auto_point_temp(struct device *dev,
	struct device_attribute *devattr, const char *buf, size_t count);
/* Sysfs misc */
static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
	char *buf);

static int __devinit f71882fg_probe(struct platform_device * pdev);
static int f71882fg_remove(struct platform_device *pdev);

static struct platform_driver f71882fg_driver = {
	.driver = {
		.owner	= THIS_MODULE,
		.name	= DRVNAME,
	},
	.probe		= f71882fg_probe,
	.remove		= f71882fg_remove,
};

static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);

/* Temp attr for the f71858fg, the f71858fg is special as it has its
   temperature indexes start at 0 (the others start at 1) */
static struct sensor_device_attribute_2 f71858fg_temp_attr[] = {
	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
		store_temp_max, 0, 0),
	SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
		store_temp_max_hyst, 0, 0),
	SENSOR_ATTR_2(temp1_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 0),
	SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
		store_temp_crit, 0, 0),
	SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
		0, 0),
	SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
	SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
	SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
	SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
		store_temp_max, 0, 1),
	SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
		store_temp_max_hyst, 0, 1),
	SENSOR_ATTR_2(temp2_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
	SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
		store_temp_crit, 0, 1),
	SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
		0, 1),
	SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
	SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
	SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
		store_temp_max, 0, 2),
	SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
		store_temp_max_hyst, 0, 2),
	SENSOR_ATTR_2(temp3_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
	SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
		store_temp_crit, 0, 2),
	SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
		0, 2),
	SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
};

/* Temp attr for the standard models */
static struct sensor_device_attribute_2 fxxxx_temp_attr[3][9] = { {
	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
		store_temp_max, 0, 1),
	SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
		store_temp_max_hyst, 0, 1),
	/* Should really be temp1_max_alarm, but older versions did not handle
	   the max and crit alarms separately and lm_sensors v2 depends on the
	   presence of temp#_alarm files. The same goes for temp2/3 _alarm. */
	SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
	SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
		store_temp_crit, 0, 1),
	SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
		0, 1),
	SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
	SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1),
	SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
}, {
	SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2),
	SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
		store_temp_max, 0, 2),
	SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
		store_temp_max_hyst, 0, 2),
	/* Should be temp2_max_alarm, see temp1_alarm note */
	SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
	SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
		store_temp_crit, 0, 2),
	SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
		0, 2),
	SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
	SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
	SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
}, {
	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
	SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
		store_temp_max, 0, 3),
	SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
		store_temp_max_hyst, 0, 3),
	/* Should be temp3_max_alarm, see temp1_alarm note */
	SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3),
	SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
		store_temp_crit, 0, 3),
	SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
		0, 3),
	SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7),
	SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3),
	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),
} };

/* Temp attr for models which can beep on temp alarm */
static struct sensor_device_attribute_2 fxxxx_temp_beep_attr[3][2] = { {
	SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
		store_temp_beep, 0, 1),
	SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
		store_temp_beep, 0, 5),
}, {
	SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
		store_temp_beep, 0, 2),
	SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
		store_temp_beep, 0, 6),
}, {
	SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
		store_temp_beep, 0, 3),
	SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
		store_temp_beep, 0, 7),
} };

/* Temp attr for the f8000
   Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
   is used as hysteresis value to clear alarms
   Also like the f71858fg its temperature indexes start at 0
 */
static struct sensor_device_attribute_2 f8000_temp_attr[] = {
	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit,
		store_temp_crit, 0, 0),
	SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
		store_temp_max, 0, 0),
	SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
	SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
	SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
	SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit,
		store_temp_crit, 0, 1),
	SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
		store_temp_max, 0, 1),
	SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
	SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
	SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit,
		store_temp_crit, 0, 2),
	SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
		store_temp_max, 0, 2),
	SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
};

/* in attr for all models */
static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
	SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
	SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
	SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
	SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
};

/* For models with in1 alarm capability */
static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = {
	SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
		0, 1),
	SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,
		0, 1),
	SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1),
};

/* Fan / PWM attr common to all models */
static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { {
	SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
	SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,
		      show_fan_full_speed,
		      store_fan_full_speed, 0, 0),
	SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
	SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),
	SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
		      store_pwm_enable, 0, 0),
	SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR,
		      show_pwm_interpolate, store_pwm_interpolate, 0, 0),
}, {
	SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
	SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
		      show_fan_full_speed,
		      store_fan_full_speed, 0, 1),
	SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
	SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1),
	SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
		      store_pwm_enable, 0, 1),
	SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR,
		      show_pwm_interpolate, store_pwm_interpolate, 0, 1),
}, {
	SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
	SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
		      show_fan_full_speed,
		      store_fan_full_speed, 0, 2),
	SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
	SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
	SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
		      store_pwm_enable, 0, 2),
	SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
		      show_pwm_interpolate, store_pwm_interpolate, 0, 2),
}, {
	SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
	SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
		      show_fan_full_speed,
		      store_fan_full_speed, 0, 3),
	SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
	SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
	SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
		      store_pwm_enable, 0, 3),
	SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
		      show_pwm_interpolate, store_pwm_interpolate, 0, 3),
} };

/* Attr for the third fan of the f71808a, which only has manual pwm */
static struct sensor_device_attribute_2 f71808a_fan3_attr[] = {
	SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
	SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
	SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR,
		      show_simple_pwm, store_simple_pwm, 0, 2),
};

/* Attr for models which can beep on Fan alarm */
static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = {
	SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
		store_fan_beep, 0, 0),
	SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
		store_fan_beep, 0, 1),
	SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
		store_fan_beep, 0, 2),
	SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
		store_fan_beep, 0, 3),
};

/* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the
   standard models */
static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = {
	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_channel,
		      store_pwm_auto_point_channel, 0, 0),
	SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      1, 0),
	SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      4, 0),
	SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      0, 0),
	SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      3, 0),
	SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp_hyst,
		      store_pwm_auto_point_temp_hyst,
		      0, 0),
	SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 3, 0),

	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_channel,
		      store_pwm_auto_point_channel, 0, 1),
	SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      1, 1),
	SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      4, 1),
	SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      0, 1),
	SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      3, 1),
	SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp_hyst,
		      store_pwm_auto_point_temp_hyst,
		      0, 1),
	SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 3, 1),

	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_channel,
		      store_pwm_auto_point_channel, 0, 2),
	SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      1, 2),
	SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      4, 2),
	SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      0, 2),
	SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      3, 2),
	SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp_hyst,
		      store_pwm_auto_point_temp_hyst,
		      0, 2),
	SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),
};

/* PWM attr for the f71808e/f71869, almost identical to the f71862fg, but the
   pwm setting when the temperature is above the pwmX_auto_point1_temp can be
   programmed instead of being hardcoded to 0xff */
static struct sensor_device_attribute_2 f71869_auto_pwm_attr[] = {
	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_channel,
		      store_pwm_auto_point_channel, 0, 0),
	SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      0, 0),
	SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      1, 0),
	SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      4, 0),
	SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      0, 0),
	SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      3, 0),
	SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp_hyst,
		      store_pwm_auto_point_temp_hyst,
		      0, 0),
	SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 3, 0),

	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_channel,
		      store_pwm_auto_point_channel, 0, 1),
	SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      0, 1),
	SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      1, 1),
	SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      4, 1),
	SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      0, 1),
	SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      3, 1),
	SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp_hyst,
		      store_pwm_auto_point_temp_hyst,
		      0, 1),
	SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 3, 1),

	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_channel,
		      store_pwm_auto_point_channel, 0, 2),
	SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      0, 2),
	SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      1, 2),
	SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      4, 2),
	SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      0, 2),
	SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      3, 2),
	SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp_hyst,
		      store_pwm_auto_point_temp_hyst,
		      0, 2),
	SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),
};

/* PWM attr for the standard models */
static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { {
	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_channel,
		      store_pwm_auto_point_channel, 0, 0),
	SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      0, 0),
	SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      1, 0),
	SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      2, 0),
	SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      3, 0),
	SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      4, 0),
	SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      0, 0),
	SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      1, 0),
	SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      2, 0),
	SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      3, 0),
	SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp_hyst,
		      store_pwm_auto_point_temp_hyst,
		      0, 0),
	SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 1, 0),
	SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 2, 0),
	SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 3, 0),
}, {
	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_channel,
		      store_pwm_auto_point_channel, 0, 1),
	SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      0, 1),
	SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      1, 1),
	SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      2, 1),
	SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      3, 1),
	SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      4, 1),
	SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      0, 1),
	SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      1, 1),
	SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      2, 1),
	SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      3, 1),
	SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp_hyst,
		      store_pwm_auto_point_temp_hyst,
		      0, 1),
	SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 1, 1),
	SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 2, 1),
	SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 3, 1),
}, {
	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_channel,
		      store_pwm_auto_point_channel, 0, 2),
	SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      0, 2),
	SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      1, 2),
	SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      2, 2),
	SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      3, 2),
	SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      4, 2),
	SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      0, 2),
	SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      1, 2),
	SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      2, 2),
	SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      3, 2),
	SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp_hyst,
		      store_pwm_auto_point_temp_hyst,
		      0, 2),
	SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 1, 2),
	SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 2, 2),
	SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),
}, {
	SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_channel,
		      store_pwm_auto_point_channel, 0, 3),
	SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      0, 3),
	SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      1, 3),
	SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      2, 3),
	SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      3, 3),
	SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      4, 3),
	SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      0, 3),
	SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      1, 3),
	SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      2, 3),
	SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      3, 3),
	SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp_hyst,
		      store_pwm_auto_point_temp_hyst,
		      0, 3),
	SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 1, 3),
	SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 2, 3),
	SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 3, 3),
} };

/* Fan attr specific to the f8000 (4th fan input can only measure speed) */
static struct sensor_device_attribute_2 f8000_fan_attr[] = {
	SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
};

/* PWM attr for the f8000, zones mapped to temp instead of to pwm!
   Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
   F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
static struct sensor_device_attribute_2 f8000_auto_pwm_attr[] = {
	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_channel,
		      store_pwm_auto_point_channel, 0, 0),
	SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      0, 2),
	SENSOR_ATTR_2(temp1_auto_point2_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      1, 2),
	SENSOR_ATTR_2(temp1_auto_point3_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      2, 2),
	SENSOR_ATTR_2(temp1_auto_point4_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      3, 2),
	SENSOR_ATTR_2(temp1_auto_point5_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      4, 2),
	SENSOR_ATTR_2(temp1_auto_point1_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      0, 2),
	SENSOR_ATTR_2(temp1_auto_point2_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      1, 2),
	SENSOR_ATTR_2(temp1_auto_point3_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      2, 2),
	SENSOR_ATTR_2(temp1_auto_point4_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      3, 2),
	SENSOR_ATTR_2(temp1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp_hyst,
		      store_pwm_auto_point_temp_hyst,
		      0, 2),
	SENSOR_ATTR_2(temp1_auto_point2_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 1, 2),
	SENSOR_ATTR_2(temp1_auto_point3_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 2, 2),
	SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),

	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_channel,
		      store_pwm_auto_point_channel, 0, 1),
	SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      0, 0),
	SENSOR_ATTR_2(temp2_auto_point2_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      1, 0),
	SENSOR_ATTR_2(temp2_auto_point3_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      2, 0),
	SENSOR_ATTR_2(temp2_auto_point4_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      3, 0),
	SENSOR_ATTR_2(temp2_auto_point5_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      4, 0),
	SENSOR_ATTR_2(temp2_auto_point1_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      0, 0),
	SENSOR_ATTR_2(temp2_auto_point2_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      1, 0),
	SENSOR_ATTR_2(temp2_auto_point3_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      2, 0),
	SENSOR_ATTR_2(temp2_auto_point4_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      3, 0),
	SENSOR_ATTR_2(temp2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp_hyst,
		      store_pwm_auto_point_temp_hyst,
		      0, 0),
	SENSOR_ATTR_2(temp2_auto_point2_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 1, 0),
	SENSOR_ATTR_2(temp2_auto_point3_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 2, 0),
	SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 3, 0),

	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_channel,
		      store_pwm_auto_point_channel, 0, 2),
	SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      0, 1),
	SENSOR_ATTR_2(temp3_auto_point2_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      1, 1),
	SENSOR_ATTR_2(temp3_auto_point3_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      2, 1),
	SENSOR_ATTR_2(temp3_auto_point4_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      3, 1),
	SENSOR_ATTR_2(temp3_auto_point5_pwm, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
		      4, 1),
	SENSOR_ATTR_2(temp3_auto_point1_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      0, 1),
	SENSOR_ATTR_2(temp3_auto_point2_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      1, 1),
	SENSOR_ATTR_2(temp3_auto_point3_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      2, 1),
	SENSOR_ATTR_2(temp3_auto_point4_temp, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
		      3, 1),
	SENSOR_ATTR_2(temp3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
		      show_pwm_auto_point_temp_hyst,
		      store_pwm_auto_point_temp_hyst,
		      0, 1),
	SENSOR_ATTR_2(temp3_auto_point2_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 1, 1),
	SENSOR_ATTR_2(temp3_auto_point3_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 2, 1),
	SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO,
		      show_pwm_auto_point_temp_hyst, NULL, 3, 1),
};

/* Super I/O functions */
static inline int superio_inb(int base, int reg)
{
	outb(reg, base);
	return inb(base + 1);
}

static int superio_inw(int base, int reg)
{
	int val;
	val  = superio_inb(base, reg) << 8;
	val |= superio_inb(base, reg + 1);
	return val;
}

static inline int superio_enter(int base)
{
	/* Don't step on other drivers' I/O space by accident */
	if (!request_region(base, 2, DRVNAME)) {
		pr_err("I/O address 0x%04x already in use\n", base);
		return -EBUSY;
	}

	/* according to the datasheet the key must be send twice! */
	outb(SIO_UNLOCK_KEY, base);
	outb(SIO_UNLOCK_KEY, base);

	return 0;
}

static inline void superio_select(int base, int ld)
{
	outb(SIO_REG_LDSEL, base);
	outb(ld, base + 1);
}

static inline void superio_exit(int base)
{
	outb(SIO_LOCK_KEY, base);
	release_region(base, 2);
}

static inline int fan_from_reg(u16 reg)
{
	return reg ? (1500000 / reg) : 0;
}

static inline u16 fan_to_reg(int fan)
{
	return fan ? (1500000 / fan) : 0;
}

static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg)
{
	u8 val;

	outb(reg, data->addr + ADDR_REG_OFFSET);
	val = inb(data->addr + DATA_REG_OFFSET);

	return val;
}

static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
{
	u16 val;

	val  = f71882fg_read8(data, reg) << 8;
	val |= f71882fg_read8(data, reg + 1);

	return val;
}

static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
{
	outb(reg, data->addr + ADDR_REG_OFFSET);
	outb(val, data->addr + DATA_REG_OFFSET);
}

static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
{
	f71882fg_write8(data, reg,     val >> 8);
	f71882fg_write8(data, reg + 1, val & 0xff);
}

static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
{
	if (data->type == f71858fg)
		return f71882fg_read16(data, F71882FG_REG_TEMP(nr));
	else
		return f71882fg_read8(data, F71882FG_REG_TEMP(nr));
}

static struct f71882fg_data *f71882fg_update_device(struct device *dev)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int nr_fans = f71882fg_nr_fans[data->type];
	int nr_temps = f71882fg_nr_temps[data->type];
	int nr, reg, point;

	mutex_lock(&data->update_lock);

	/* Update once every 60 seconds */
	if (time_after(jiffies, data->last_limits + 60 * HZ) ||
			!data->valid) {
		if (f71882fg_has_in1_alarm[data->type]) {
			data->in1_max =
				f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
			data->in_beep =
				f71882fg_read8(data, F71882FG_REG_IN_BEEP);
		}

		/* Get High & boundary temps*/
		for (nr = data->temp_start; nr < nr_temps + data->temp_start;
									nr++) {
			data->temp_ovt[nr] = f71882fg_read8(data,
						F71882FG_REG_TEMP_OVT(nr));
			data->temp_high[nr] = f71882fg_read8(data,
						F71882FG_REG_TEMP_HIGH(nr));
		}

		if (data->type != f8000) {
			data->temp_hyst[0] = f71882fg_read8(data,
						F71882FG_REG_TEMP_HYST(0));
			data->temp_hyst[1] = f71882fg_read8(data,
						F71882FG_REG_TEMP_HYST(1));
		}
		/* All but the f71858fg / f8000 have this register */
		if ((data->type != f71858fg) && (data->type != f8000)) {
			reg  = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
			data->temp_type[1] = (reg & 0x02) ? 2 : 4;
			data->temp_type[2] = (reg & 0x04) ? 2 : 4;
			data->temp_type[3] = (reg & 0x08) ? 2 : 4;
		}

		if (f71882fg_fan_has_beep[data->type])
			data->fan_beep = f71882fg_read8(data,
						F71882FG_REG_FAN_BEEP);

		if (f71882fg_temp_has_beep[data->type])
			data->temp_beep = f71882fg_read8(data,
						F71882FG_REG_TEMP_BEEP);

		data->pwm_enable = f71882fg_read8(data,
						  F71882FG_REG_PWM_ENABLE);
		data->pwm_auto_point_hyst[0] =
			f71882fg_read8(data, F71882FG_REG_FAN_HYST(0));
		data->pwm_auto_point_hyst[1] =
			f71882fg_read8(data, F71882FG_REG_FAN_HYST(1));

		for (nr = 0; nr < nr_fans; nr++) {
			data->pwm_auto_point_mapping[nr] =
			    f71882fg_read8(data,
					   F71882FG_REG_POINT_MAPPING(nr));

			switch (data->type) {
			default:
				for (point = 0; point < 5; point++) {
					data->pwm_auto_point_pwm[nr][point] =
						f71882fg_read8(data,
							F71882FG_REG_POINT_PWM
							(nr, point));
				}
				for (point = 0; point < 4; point++) {
					data->pwm_auto_point_temp[nr][point] =
						f71882fg_read8(data,
							F71882FG_REG_POINT_TEMP
							(nr, point));
				}
				break;
			case f71808e:
			case f71869:
				data->pwm_auto_point_pwm[nr][0] =
					f71882fg_read8(data,
						F71882FG_REG_POINT_PWM(nr, 0));
				/* Fall through */
			case f71862fg:
				data->pwm_auto_point_pwm[nr][1] =
					f71882fg_read8(data,
						F71882FG_REG_POINT_PWM
						(nr, 1));
				data->pwm_auto_point_pwm[nr][4] =
					f71882fg_read8(data,
						F71882FG_REG_POINT_PWM
						(nr, 4));
				data->pwm_auto_point_temp[nr][0] =
					f71882fg_read8(data,
						F71882FG_REG_POINT_TEMP
						(nr, 0));
				data->pwm_auto_point_temp[nr][3] =
					f71882fg_read8(data,
						F71882FG_REG_POINT_TEMP
						(nr, 3));
				break;
			}
		}
		data->last_limits = jiffies;
	}

	/* Update every second */
	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
		data->temp_status = f71882fg_read8(data,
						F71882FG_REG_TEMP_STATUS);
		data->temp_diode_open = f71882fg_read8(data,
						F71882FG_REG_TEMP_DIODE_OPEN);
		for (nr = data->temp_start; nr < nr_temps + data->temp_start;
									nr++)
			data->temp[nr] = f71882fg_read_temp(data, nr);

		data->fan_status = f71882fg_read8(data,
						F71882FG_REG_FAN_STATUS);
		for (nr = 0; nr < nr_fans; nr++) {
			data->fan[nr] = f71882fg_read16(data,
						F71882FG_REG_FAN(nr));
			data->fan_target[nr] =
			    f71882fg_read16(data, F71882FG_REG_FAN_TARGET(nr));
			data->fan_full_speed[nr] =
			    f71882fg_read16(data,
					    F71882FG_REG_FAN_FULL_SPEED(nr));
			data->pwm[nr] =
			    f71882fg_read8(data, F71882FG_REG_PWM(nr));
		}
		/* The f8000 can monitor 1 more fan, but has no pwm for it */
		if (data->type == f8000)
			data->fan[3] = f71882fg_read16(data,
						F71882FG_REG_FAN(3));

		if (f71882fg_has_in1_alarm[data->type])
			data->in_status = f71882fg_read8(data,
						F71882FG_REG_IN_STATUS);
		for (nr = 0; nr < F71882FG_MAX_INS; nr++)
			if (f71882fg_has_in[data->type][nr])
				data->in[nr] = f71882fg_read8(data,
							F71882FG_REG_IN(nr));

		data->last_updated = jiffies;
		data->valid = 1;
	}

	mutex_unlock(&data->update_lock);

	return data;
}

/* Sysfs Interface */
static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
	char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;
	int speed = fan_from_reg(data->fan[nr]);

	if (speed == FAN_MIN_DETECT)
		speed = 0;

	return sprintf(buf, "%d\n", speed);
}

static ssize_t show_fan_full_speed(struct device *dev,
				   struct device_attribute *devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;
	int speed = fan_from_reg(data->fan_full_speed[nr]);
	return sprintf(buf, "%d\n", speed);
}

static ssize_t store_fan_full_speed(struct device *dev,
				    struct device_attribute *devattr,
				    const char *buf, size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err, nr = to_sensor_dev_attr_2(devattr)->index;
	long val;

	err = strict_strtol(buf, 10, &val);
	if (err)
		return err;

	val = SENSORS_LIMIT(val, 23, 1500000);
	val = fan_to_reg(val);

	mutex_lock(&data->update_lock);
	f71882fg_write16(data, F71882FG_REG_FAN_FULL_SPEED(nr), val);
	data->fan_full_speed[nr] = val;
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t show_fan_beep(struct device *dev, struct device_attribute
	*devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;

	if (data->fan_beep & (1 << nr))
		return sprintf(buf, "1\n");
	else
		return sprintf(buf, "0\n");
}

static ssize_t store_fan_beep(struct device *dev, struct device_attribute
	*devattr, const char *buf, size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err, nr = to_sensor_dev_attr_2(devattr)->index;
	unsigned long val;

	err = strict_strtoul(buf, 10, &val);
	if (err)
		return err;

	mutex_lock(&data->update_lock);
	data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
	if (val)
		data->fan_beep |= 1 << nr;
	else
		data->fan_beep &= ~(1 << nr);

	f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep);
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
	*devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;

	if (data->fan_status & (1 << nr))
		return sprintf(buf, "1\n");
	else
		return sprintf(buf, "0\n");
}

static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
	char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;

	return sprintf(buf, "%d\n", data->in[nr] * 8);
}

static ssize_t show_in_max(struct device *dev, struct device_attribute
	*devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);

	return sprintf(buf, "%d\n", data->in1_max * 8);
}

static ssize_t store_in_max(struct device *dev, struct device_attribute
	*devattr, const char *buf, size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err;
	long val;

	err = strict_strtol(buf, 10, &val);
	if (err)
		return err;

	val /= 8;
	val = SENSORS_LIMIT(val, 0, 255);

	mutex_lock(&data->update_lock);
	f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
	data->in1_max = val;
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t show_in_beep(struct device *dev, struct device_attribute
	*devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;

	if (data->in_beep & (1 << nr))
		return sprintf(buf, "1\n");
	else
		return sprintf(buf, "0\n");
}

static ssize_t store_in_beep(struct device *dev, struct device_attribute
	*devattr, const char *buf, size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err, nr = to_sensor_dev_attr_2(devattr)->index;
	unsigned long val;

	err = strict_strtoul(buf, 10, &val);
	if (err)
		return err;

	mutex_lock(&data->update_lock);
	data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
	if (val)
		data->in_beep |= 1 << nr;
	else
		data->in_beep &= ~(1 << nr);

	f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t show_in_alarm(struct device *dev, struct device_attribute
	*devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;

	if (data->in_status & (1 << nr))
		return sprintf(buf, "1\n");
	else
		return sprintf(buf, "0\n");
}

static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
	char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;
	int sign, temp;

	if (data->type == f71858fg) {
		/* TEMP_TABLE_SEL 1 or 3 ? */
		if (data->temp_config & 1) {
			sign = data->temp[nr] & 0x0001;
			temp = (data->temp[nr] >> 5) & 0x7ff;
		} else {
			sign = data->temp[nr] & 0x8000;
			temp = (data->temp[nr] >> 5) & 0x3ff;
		}
		temp *= 125;
		if (sign)
			temp -= 128000;
	} else
		temp = data->temp[nr] * 1000;

	return sprintf(buf, "%d\n", temp);
}

static ssize_t show_temp_max(struct device *dev, struct device_attribute
	*devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;

	return sprintf(buf, "%d\n", data->temp_high[nr] * 1000);
}

static ssize_t store_temp_max(struct device *dev, struct device_attribute
	*devattr, const char *buf, size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err, nr = to_sensor_dev_attr_2(devattr)->index;
	long val;

	err = strict_strtol(buf, 10, &val);
	if (err)
		return err;

	val /= 1000;
	val = SENSORS_LIMIT(val, 0, 255);

	mutex_lock(&data->update_lock);
	f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val);
	data->temp_high[nr] = val;
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
	*devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;
	int temp_max_hyst;

	mutex_lock(&data->update_lock);
	if (nr & 1)
		temp_max_hyst = data->temp_hyst[nr / 2] >> 4;
	else
		temp_max_hyst = data->temp_hyst[nr / 2] & 0x0f;
	temp_max_hyst = (data->temp_high[nr] - temp_max_hyst) * 1000;
	mutex_unlock(&data->update_lock);

	return sprintf(buf, "%d\n", temp_max_hyst);
}

static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
	*devattr, const char *buf, size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err, nr = to_sensor_dev_attr_2(devattr)->index;
	ssize_t ret = count;
	u8 reg;
	long val;

	err = strict_strtol(buf, 10, &val);
	if (err)
		return err;

	val /= 1000;

	mutex_lock(&data->update_lock);

	/* convert abs to relative and check */
	data->temp_high[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_HIGH(nr));
	val = SENSORS_LIMIT(val, data->temp_high[nr] - 15,
			    data->temp_high[nr]);
	val = data->temp_high[nr] - val;

	/* convert value to register contents */
	reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(nr / 2));
	if (nr & 1)
		reg = (reg & 0x0f) | (val << 4);
	else
		reg = (reg & 0xf0) | val;
	f71882fg_write8(data, F71882FG_REG_TEMP_HYST(nr / 2), reg);
	data->temp_hyst[nr / 2] = reg;

	mutex_unlock(&data->update_lock);
	return ret;
}

static ssize_t show_temp_crit(struct device *dev, struct device_attribute
	*devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;

	return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000);
}

static ssize_t store_temp_crit(struct device *dev, struct device_attribute
	*devattr, const char *buf, size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err, nr = to_sensor_dev_attr_2(devattr)->index;
	long val;

	err = strict_strtol(buf, 10, &val);
	if (err)
		return err;

	val /= 1000;
	val = SENSORS_LIMIT(val, 0, 255);

	mutex_lock(&data->update_lock);
	f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val);
	data->temp_ovt[nr] = val;
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
	*devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;
	int temp_crit_hyst;

	mutex_lock(&data->update_lock);
	if (nr & 1)
		temp_crit_hyst = data->temp_hyst[nr / 2] >> 4;
	else
		temp_crit_hyst = data->temp_hyst[nr / 2] & 0x0f;
	temp_crit_hyst = (data->temp_ovt[nr] - temp_crit_hyst) * 1000;
	mutex_unlock(&data->update_lock);

	return sprintf(buf, "%d\n", temp_crit_hyst);
}

static ssize_t show_temp_type(struct device *dev, struct device_attribute
	*devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;

	return sprintf(buf, "%d\n", data->temp_type[nr]);
}

static ssize_t show_temp_beep(struct device *dev, struct device_attribute
	*devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;

	if (data->temp_beep & (1 << nr))
		return sprintf(buf, "1\n");
	else
		return sprintf(buf, "0\n");
}

static ssize_t store_temp_beep(struct device *dev, struct device_attribute
	*devattr, const char *buf, size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err, nr = to_sensor_dev_attr_2(devattr)->index;
	unsigned long val;

	err = strict_strtoul(buf, 10, &val);
	if (err)
		return err;

	mutex_lock(&data->update_lock);
	data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);
	if (val)
		data->temp_beep |= 1 << nr;
	else
		data->temp_beep &= ~(1 << nr);

	f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep);
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
	*devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;

	if (data->temp_status & (1 << nr))
		return sprintf(buf, "1\n");
	else
		return sprintf(buf, "0\n");
}

static ssize_t show_temp_fault(struct device *dev, struct device_attribute
	*devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;

	if (data->temp_diode_open & (1 << nr))
		return sprintf(buf, "1\n");
	else
		return sprintf(buf, "0\n");
}

static ssize_t show_pwm(struct device *dev,
			struct device_attribute *devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int val, nr = to_sensor_dev_attr_2(devattr)->index;
	mutex_lock(&data->update_lock);
	if (data->pwm_enable & (1 << (2 * nr)))
		/* PWM mode */
		val = data->pwm[nr];
	else {
		/* RPM mode */
		val = 255 * fan_from_reg(data->fan_target[nr])
			/ fan_from_reg(data->fan_full_speed[nr]);
	}
	mutex_unlock(&data->update_lock);
	return sprintf(buf, "%d\n", val);
}

static ssize_t store_pwm(struct device *dev,
			 struct device_attribute *devattr, const char *buf,
			 size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err, nr = to_sensor_dev_attr_2(devattr)->index;
	long val;

	err = strict_strtol(buf, 10, &val);
	if (err)
		return err;

	val = SENSORS_LIMIT(val, 0, 255);

	mutex_lock(&data->update_lock);
	data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
	if ((data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 3) != 2) ||
	    (data->type != f8000 && !((data->pwm_enable >> 2 * nr) & 2))) {
		count = -EROFS;
		goto leave;
	}
	if (data->pwm_enable & (1 << (2 * nr))) {
		/* PWM mode */
		f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
		data->pwm[nr] = val;
	} else {
		/* RPM mode */
		int target, full_speed;
		full_speed = f71882fg_read16(data,
					     F71882FG_REG_FAN_FULL_SPEED(nr));
		target = fan_to_reg(val * fan_from_reg(full_speed) / 255);
		f71882fg_write16(data, F71882FG_REG_FAN_TARGET(nr), target);
		data->fan_target[nr] = target;
		data->fan_full_speed[nr] = full_speed;
	}
leave:
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t show_simple_pwm(struct device *dev,
			       struct device_attribute *devattr, char *buf)
{
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int val, nr = to_sensor_dev_attr_2(devattr)->index;

	val = data->pwm[nr];
	return sprintf(buf, "%d\n", val);
}

static ssize_t store_simple_pwm(struct device *dev,
				struct device_attribute *devattr,
				const char *buf, size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err, nr = to_sensor_dev_attr_2(devattr)->index;
	long val;

	err = strict_strtol(buf, 10, &val);
	if (err)
		return err;

	val = SENSORS_LIMIT(val, 0, 255);

	mutex_lock(&data->update_lock);
	f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
	data->pwm[nr] = val;
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t show_pwm_enable(struct device *dev,
			       struct device_attribute *devattr, char *buf)
{
	int result = 0;
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;

	switch ((data->pwm_enable >> 2 * nr) & 3) {
	case 0:
	case 1:
		result = 2; /* Normal auto mode */
		break;
	case 2:
		result = 1; /* Manual mode */
		break;
	case 3:
		if (data->type == f8000)
			result = 3; /* Thermostat mode */
		else
			result = 1; /* Manual mode */
		break;
	}

	return sprintf(buf, "%d\n", result);
}

static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
				*devattr, const char *buf, size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err, nr = to_sensor_dev_attr_2(devattr)->index;
	long val;

	err = strict_strtol(buf, 10, &val);
	if (err)
		return err;

	/* Special case for F8000 pwm channel 3 which only does auto mode */
	if (data->type == f8000 && nr == 2 && val != 2)
		return -EINVAL;

	mutex_lock(&data->update_lock);
	data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
	/* Special case for F8000 auto PWM mode / Thermostat mode */
	if (data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 1)) {
		switch (val) {
		case 2:
			data->pwm_enable &= ~(2 << (2 * nr));
			break;		/* Normal auto mode */
		case 3:
			data->pwm_enable |= 2 << (2 * nr);
			break;		/* Thermostat mode */
		default:
			count = -EINVAL;
			goto leave;
		}
	} else {
		switch (val) {
		case 1:
			/* The f71858fg does not support manual RPM mode */
			if (data->type == f71858fg &&
			    ((data->pwm_enable >> (2 * nr)) & 1)) {
				count = -EINVAL;
				goto leave;
			}
			data->pwm_enable |= 2 << (2 * nr);
			break;		/* Manual */
		case 2:
			data->pwm_enable &= ~(2 << (2 * nr));
			break;		/* Normal auto mode */
		default:
			count = -EINVAL;
			goto leave;
		}
	}
	f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable);
leave:
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t show_pwm_auto_point_pwm(struct device *dev,
				       struct device_attribute *devattr,
				       char *buf)
{
	int result;
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int pwm = to_sensor_dev_attr_2(devattr)->index;
	int point = to_sensor_dev_attr_2(devattr)->nr;

	mutex_lock(&data->update_lock);
	if (data->pwm_enable & (1 << (2 * pwm))) {
		/* PWM mode */
		result = data->pwm_auto_point_pwm[pwm][point];
	} else {
		/* RPM mode */
		result = 32 * 255 / (32 + data->pwm_auto_point_pwm[pwm][point]);
	}
	mutex_unlock(&data->update_lock);

	return sprintf(buf, "%d\n", result);
}

static ssize_t store_pwm_auto_point_pwm(struct device *dev,
					struct device_attribute *devattr,
					const char *buf, size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err, pwm = to_sensor_dev_attr_2(devattr)->index;
	int point = to_sensor_dev_attr_2(devattr)->nr;
	long val;

	err = strict_strtol(buf, 10, &val);
	if (err)
		return err;

	val = SENSORS_LIMIT(val, 0, 255);

	mutex_lock(&data->update_lock);
	data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
	if (data->pwm_enable & (1 << (2 * pwm))) {
		/* PWM mode */
	} else {
		/* RPM mode */
		if (val < 29)	/* Prevent negative numbers */
			val = 255;
		else
			val = (255 - val) * 32 / val;
	}
	f71882fg_write8(data, F71882FG_REG_POINT_PWM(pwm, point), val);
	data->pwm_auto_point_pwm[pwm][point] = val;
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
					     struct device_attribute *devattr,
					     char *buf)
{
	int result = 0;
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;
	int point = to_sensor_dev_attr_2(devattr)->nr;

	mutex_lock(&data->update_lock);
	if (nr & 1)
		result = data->pwm_auto_point_hyst[nr / 2] >> 4;
	else
		result = data->pwm_auto_point_hyst[nr / 2] & 0x0f;
	result = 1000 * (data->pwm_auto_point_temp[nr][point] - result);
	mutex_unlock(&data->update_lock);

	return sprintf(buf, "%d\n", result);
}

static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
					      struct device_attribute *devattr,
					      const char *buf, size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err, nr = to_sensor_dev_attr_2(devattr)->index;
	int point = to_sensor_dev_attr_2(devattr)->nr;
	u8 reg;
	long val;

	err = strict_strtol(buf, 10, &val);
	if (err)
		return err;

	val /= 1000;

	mutex_lock(&data->update_lock);
	data->pwm_auto_point_temp[nr][point] =
		f71882fg_read8(data, F71882FG_REG_POINT_TEMP(nr, point));
	val = SENSORS_LIMIT(val, data->pwm_auto_point_temp[nr][point] - 15,
				data->pwm_auto_point_temp[nr][point]);
	val = data->pwm_auto_point_temp[nr][point] - val;

	reg = f71882fg_read8(data, F71882FG_REG_FAN_HYST(nr / 2));
	if (nr & 1)
		reg = (reg & 0x0f) | (val << 4);
	else
		reg = (reg & 0xf0) | val;

	f71882fg_write8(data, F71882FG_REG_FAN_HYST(nr / 2), reg);
	data->pwm_auto_point_hyst[nr / 2] = reg;
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t show_pwm_interpolate(struct device *dev,
				    struct device_attribute *devattr, char *buf)
{
	int result;
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;

	result = (data->pwm_auto_point_mapping[nr] >> 4) & 1;

	return sprintf(buf, "%d\n", result);
}

static ssize_t store_pwm_interpolate(struct device *dev,
				     struct device_attribute *devattr,
				     const char *buf, size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err, nr = to_sensor_dev_attr_2(devattr)->index;
	unsigned long val;

	err = strict_strtoul(buf, 10, &val);
	if (err)
		return err;

	mutex_lock(&data->update_lock);
	data->pwm_auto_point_mapping[nr] =
		f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
	if (val)
		val = data->pwm_auto_point_mapping[nr] | (1 << 4);
	else
		val = data->pwm_auto_point_mapping[nr] & (~(1 << 4));
	f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
	data->pwm_auto_point_mapping[nr] = val;
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t show_pwm_auto_point_channel(struct device *dev,
					   struct device_attribute *devattr,
					   char *buf)
{
	int result;
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int nr = to_sensor_dev_attr_2(devattr)->index;

	result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) -
		       data->temp_start);

	return sprintf(buf, "%d\n", result);
}

static ssize_t store_pwm_auto_point_channel(struct device *dev,
					    struct device_attribute *devattr,
					    const char *buf, size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err, nr = to_sensor_dev_attr_2(devattr)->index;
	long val;

	err = strict_strtol(buf, 10, &val);
	if (err)
		return err;

	switch (val) {
	case 1:
		val = 0;
		break;
	case 2:
		val = 1;
		break;
	case 4:
		val = 2;
		break;
	default:
		return -EINVAL;
	}
	val += data->temp_start;
	mutex_lock(&data->update_lock);
	data->pwm_auto_point_mapping[nr] =
		f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
	val = (data->pwm_auto_point_mapping[nr] & 0xfc) | val;
	f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
	data->pwm_auto_point_mapping[nr] = val;
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t show_pwm_auto_point_temp(struct device *dev,
					struct device_attribute *devattr,
					char *buf)
{
	int result;
	struct f71882fg_data *data = f71882fg_update_device(dev);
	int pwm = to_sensor_dev_attr_2(devattr)->index;
	int point = to_sensor_dev_attr_2(devattr)->nr;

	result = data->pwm_auto_point_temp[pwm][point];
	return sprintf(buf, "%d\n", 1000 * result);
}

static ssize_t store_pwm_auto_point_temp(struct device *dev,
					 struct device_attribute *devattr,
					 const char *buf, size_t count)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	int err, pwm = to_sensor_dev_attr_2(devattr)->index;
	int point = to_sensor_dev_attr_2(devattr)->nr;
	long val;

	err = strict_strtol(buf, 10, &val);
	if (err)
		return err;

	val /= 1000;

	if (data->auto_point_temp_signed)
		val = SENSORS_LIMIT(val, -128, 127);
	else
		val = SENSORS_LIMIT(val, 0, 127);

	mutex_lock(&data->update_lock);
	f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
	data->pwm_auto_point_temp[pwm][point] = val;
	mutex_unlock(&data->update_lock);

	return count;
}

static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
	char *buf)
{
	struct f71882fg_data *data = dev_get_drvdata(dev);
	return sprintf(buf, "%s\n", f71882fg_names[data->type]);
}

static int __devinit f71882fg_create_sysfs_files(struct platform_device *pdev,
	struct sensor_device_attribute_2 *attr, int count)
{
	int err, i;

	for (i = 0; i < count; i++) {
		err = device_create_file(&pdev->dev, &attr[i].dev_attr);
		if (err)
			return err;
	}
	return 0;
}

static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
	struct sensor_device_attribute_2 *attr, int count)
{
	int i;

	for (i = 0; i < count; i++)
		device_remove_file(&pdev->dev, &attr[i].dev_attr);
}

static int __devinit f71882fg_probe(struct platform_device *pdev)
{
	struct f71882fg_data *data;
	struct f71882fg_sio_data *sio_data = pdev->dev.platform_data;
	int nr_fans = f71882fg_nr_fans[sio_data->type];
	int nr_temps = f71882fg_nr_temps[sio_data->type];
	int err, i;
	u8 start_reg, reg;

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

	data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
	data->type = sio_data->type;
	data->temp_start =
	    (data->type == f71858fg || data->type == f8000) ? 0 : 1;
	mutex_init(&data->update_lock);
	platform_set_drvdata(pdev, data);

	start_reg = f71882fg_read8(data, F71882FG_REG_START);
	if (start_reg & 0x04) {
		dev_warn(&pdev->dev, "Hardware monitor is powered down\n");
		err = -ENODEV;
		goto exit_free;
	}
	if (!(start_reg & 0x03)) {
		dev_warn(&pdev->dev, "Hardware monitoring not activated\n");
		err = -ENODEV;
		goto exit_free;
	}

	/* Register sysfs interface files */
	err = device_create_file(&pdev->dev, &dev_attr_name);
	if (err)
		goto exit_unregister_sysfs;

	if (start_reg & 0x01) {
		switch (data->type) {
		case f71858fg:
			data->temp_config =
				f71882fg_read8(data, F71882FG_REG_TEMP_CONFIG);
			if (data->temp_config & 0x10)
				/* The f71858fg temperature alarms behave as
				   the f8000 alarms in this mode */
				err = f71882fg_create_sysfs_files(pdev,
					f8000_temp_attr,
					ARRAY_SIZE(f8000_temp_attr));
			else
				err = f71882fg_create_sysfs_files(pdev,
					f71858fg_temp_attr,
					ARRAY_SIZE(f71858fg_temp_attr));
			break;
		case f8000:
			err = f71882fg_create_sysfs_files(pdev,
					f8000_temp_attr,
					ARRAY_SIZE(f8000_temp_attr));
			break;
		default:
			err = f71882fg_create_sysfs_files(pdev,
				&fxxxx_temp_attr[0][0],
				ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps);
		}
		if (err)
			goto exit_unregister_sysfs;

		if (f71882fg_temp_has_beep[data->type]) {
			err = f71882fg_create_sysfs_files(pdev,
					&fxxxx_temp_beep_attr[0][0],
					ARRAY_SIZE(fxxxx_temp_beep_attr[0])
						* nr_temps);
			if (err)
				goto exit_unregister_sysfs;
		}

		for (i = 0; i < F71882FG_MAX_INS; i++) {
			if (f71882fg_has_in[data->type][i]) {
				err = device_create_file(&pdev->dev,
						&fxxxx_in_attr[i].dev_attr);
				if (err)
					goto exit_unregister_sysfs;
			}
		}
		if (f71882fg_has_in1_alarm[data->type]) {
			err = f71882fg_create_sysfs_files(pdev,
					fxxxx_in1_alarm_attr,
					ARRAY_SIZE(fxxxx_in1_alarm_attr));
			if (err)
				goto exit_unregister_sysfs;
		}
	}

	if (start_reg & 0x02) {
		switch (data->type) {
		case f71808a:
		case f71808e:
		case f71869:
			/* These always have signed auto point temps */
			data->auto_point_temp_signed = 1;
			/* Fall through to select correct fan/pwm reg bank! */
		case f71889fg:
		case f71889ed:
		case f71889a:
			reg = f71882fg_read8(data, F71882FG_REG_FAN_FAULT_T);
			if (reg & F71882FG_FAN_NEG_TEMP_EN)
				data->auto_point_temp_signed = 1;
			/* Ensure banked pwm registers point to right bank */
			reg &= ~F71882FG_FAN_PROG_SEL;
			f71882fg_write8(data, F71882FG_REG_FAN_FAULT_T, reg);
			break;
		default:
			break;
		}

		data->pwm_enable =
			f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);

		/* Sanity check the pwm settings */
		switch (data->type) {
		case f71858fg:
			err = 0;
			for (i = 0; i < nr_fans; i++)
				if (((data->pwm_enable >> (i * 2)) & 3) == 3)
					err = 1;
			break;
		case f71862fg:
			err = (data->pwm_enable & 0x15) != 0x15;
			break;
		case f8000:
			err = data->pwm_enable & 0x20;
			break;
		default:
			err = 0;
			break;
		}
		if (err) {
			dev_err(&pdev->dev,
				"Invalid (reserved) pwm settings: 0x%02x\n",
				(unsigned int)data->pwm_enable);
			err = -ENODEV;
			goto exit_unregister_sysfs;
		}

		err = f71882fg_create_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
				ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
		if (err)
			goto exit_unregister_sysfs;

		if (f71882fg_fan_has_beep[data->type]) {
			err = f71882fg_create_sysfs_files(pdev,
					fxxxx_fan_beep_attr, nr_fans);
			if (err)
				goto exit_unregister_sysfs;
		}

		switch (data->type) {
		case f71808a:
		case f71808e:
		case f71869:
		case f71889fg:
		case f71889ed:
		case f71889a:
			for (i = 0; i < nr_fans; i++) {
				data->pwm_auto_point_mapping[i] =
					f71882fg_read8(data,
						F71882FG_REG_POINT_MAPPING(i));
				if ((data->pwm_auto_point_mapping[i] & 0x80) ||
				    (data->pwm_auto_point_mapping[i] & 3) == 0)
					break;
			}
			if (i != nr_fans) {
				dev_warn(&pdev->dev,
					 "Auto pwm controlled by raw digital "
					 "data, disabling pwm auto_point "
					 "sysfs attributes\n");
				goto no_pwm_auto_point;
			}
			break;
		default:
			break;
		}

		switch (data->type) {
		case f71808a:
			err = f71882fg_create_sysfs_files(pdev,
				&fxxxx_auto_pwm_attr[0][0],
				ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
			if (err)
				goto exit_unregister_sysfs;
			err = f71882fg_create_sysfs_files(pdev,
					f71808a_fan3_attr,
					ARRAY_SIZE(f71808a_fan3_attr));
			break;
		case f71862fg:
			err = f71882fg_create_sysfs_files(pdev,
					f71862fg_auto_pwm_attr,
					ARRAY_SIZE(f71862fg_auto_pwm_attr));
			break;
		case f71808e:
		case f71869:
			err = f71882fg_create_sysfs_files(pdev,
					f71869_auto_pwm_attr,
					ARRAY_SIZE(f71869_auto_pwm_attr));
			break;
		case f8000:
			err = f71882fg_create_sysfs_files(pdev,
					f8000_fan_attr,
					ARRAY_SIZE(f8000_fan_attr));
			if (err)
				goto exit_unregister_sysfs;
			err = f71882fg_create_sysfs_files(pdev,
					f8000_auto_pwm_attr,
					ARRAY_SIZE(f8000_auto_pwm_attr));
			break;
		default:
			err = f71882fg_create_sysfs_files(pdev,
				&fxxxx_auto_pwm_attr[0][0],
				ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
		}
		if (err)
			goto exit_unregister_sysfs;

no_pwm_auto_point:
		for (i = 0; i < nr_fans; i++)
			dev_info(&pdev->dev, "Fan: %d is in %s mode\n", i + 1,
				 (data->pwm_enable & (1 << 2 * i)) ?
				 "duty-cycle" : "RPM");
	}

	data->hwmon_dev = hwmon_device_register(&pdev->dev);
	if (IS_ERR(data->hwmon_dev)) {
		err = PTR_ERR(data->hwmon_dev);
		data->hwmon_dev = NULL;
		goto exit_unregister_sysfs;
	}

	return 0;

exit_unregister_sysfs:
	f71882fg_remove(pdev); /* Will unregister the sysfs files for us */
	return err; /* f71882fg_remove() also frees our data */
exit_free:
	kfree(data);
	return err;
}

static int f71882fg_remove(struct platform_device *pdev)
{
	struct f71882fg_data *data = platform_get_drvdata(pdev);
	int nr_fans = f71882fg_nr_fans[data->type];
	int nr_temps = f71882fg_nr_temps[data->type];
	int i;
	u8 start_reg = f71882fg_read8(data, F71882FG_REG_START);

	if (data->hwmon_dev)
		hwmon_device_unregister(data->hwmon_dev);

	device_remove_file(&pdev->dev, &dev_attr_name);

	if (start_reg & 0x01) {
		switch (data->type) {
		case f71858fg:
			if (data->temp_config & 0x10)
				f71882fg_remove_sysfs_files(pdev,
					f8000_temp_attr,
					ARRAY_SIZE(f8000_temp_attr));
			else
				f71882fg_remove_sysfs_files(pdev,
					f71858fg_temp_attr,
					ARRAY_SIZE(f71858fg_temp_attr));
			break;
		case f8000:
			f71882fg_remove_sysfs_files(pdev,
					f8000_temp_attr,
					ARRAY_SIZE(f8000_temp_attr));
			break;
		default:
			f71882fg_remove_sysfs_files(pdev,
				&fxxxx_temp_attr[0][0],
				ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps);
		}
		if (f71882fg_temp_has_beep[data->type]) {
			f71882fg_remove_sysfs_files(pdev,
			       &fxxxx_temp_beep_attr[0][0],
			       ARRAY_SIZE(fxxxx_temp_beep_attr[0]) * nr_temps);
		}

		for (i = 0; i < F71882FG_MAX_INS; i++) {
			if (f71882fg_has_in[data->type][i]) {
				device_remove_file(&pdev->dev,
						&fxxxx_in_attr[i].dev_attr);
			}
		}
		if (f71882fg_has_in1_alarm[data->type]) {
			f71882fg_remove_sysfs_files(pdev,
					fxxxx_in1_alarm_attr,
					ARRAY_SIZE(fxxxx_in1_alarm_attr));
		}
	}

	if (start_reg & 0x02) {
		f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
				ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);

		if (f71882fg_fan_has_beep[data->type]) {
			f71882fg_remove_sysfs_files(pdev,
					fxxxx_fan_beep_attr, nr_fans);
		}

		switch (data->type) {
		case f71808a:
			f71882fg_remove_sysfs_files(pdev,
				&fxxxx_auto_pwm_attr[0][0],
				ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
			f71882fg_remove_sysfs_files(pdev,
					f71808a_fan3_attr,
					ARRAY_SIZE(f71808a_fan3_attr));
			break;			
		case f71862fg:
			f71882fg_remove_sysfs_files(pdev,
					f71862fg_auto_pwm_attr,
					ARRAY_SIZE(f71862fg_auto_pwm_attr));
			break;
		case f71808e:
		case f71869:
			f71882fg_remove_sysfs_files(pdev,
					f71869_auto_pwm_attr,
					ARRAY_SIZE(f71869_auto_pwm_attr));
			break;
		case f8000:
			f71882fg_remove_sysfs_files(pdev,
					f8000_fan_attr,
					ARRAY_SIZE(f8000_fan_attr));
			f71882fg_remove_sysfs_files(pdev,
					f8000_auto_pwm_attr,
					ARRAY_SIZE(f8000_auto_pwm_attr));
			break;
		default:
			f71882fg_remove_sysfs_files(pdev,
				&fxxxx_auto_pwm_attr[0][0],
				ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
		}
	}

	platform_set_drvdata(pdev, NULL);
	kfree(data);

	return 0;
}

static int __init f71882fg_find(int sioaddr, unsigned short *address,
	struct f71882fg_sio_data *sio_data)
{
	u16 devid;
	int err = superio_enter(sioaddr);
	if (err)
		return err;

	devid = superio_inw(sioaddr, SIO_REG_MANID);
	if (devid != SIO_FINTEK_ID) {
		pr_debug("Not a Fintek device\n");
		err = -ENODEV;
		goto exit;
	}

	devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
	switch (devid) {
	case SIO_F71808E_ID:
		sio_data->type = f71808e;
		break;
	case SIO_F71808A_ID:
		sio_data->type = f71808a;
		break;
	case SIO_F71858_ID:
		sio_data->type = f71858fg;
		break;
	case SIO_F71862_ID:
		sio_data->type = f71862fg;
		break;
	case SIO_F71869_ID:
		sio_data->type = f71869;
		break;
	case SIO_F71882_ID:
		sio_data->type = f71882fg;
		break;
	case SIO_F71889_ID:
		sio_data->type = f71889fg;
		break;
	case SIO_F71889E_ID:
		sio_data->type = f71889ed;
		break;
	case SIO_F71889A_ID:
		sio_data->type = f71889a;
		break;
	case SIO_F8000_ID:
		sio_data->type = f8000;
		break;
	case SIO_F81865_ID:
		sio_data->type = f81865f;
		break;
	default:
		pr_info("Unsupported Fintek device: %04x\n",
			(unsigned int)devid);
		err = -ENODEV;
		goto exit;
	}

	if (sio_data->type == f71858fg)
		superio_select(sioaddr, SIO_F71858FG_LD_HWM);
	else
		superio_select(sioaddr, SIO_F71882FG_LD_HWM);

	if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
		pr_warn("Device not activated\n");
		err = -ENODEV;
		goto exit;
	}

	*address = superio_inw(sioaddr, SIO_REG_ADDR);
	if (*address == 0) {
		pr_warn("Base address not set\n");
		err = -ENODEV;
		goto exit;
	}
	*address &= ~(REGION_LENGTH - 1);	/* Ignore 3 LSB */

	err = 0;
	pr_info("Found %s chip at %#x, revision %d\n",
		f71882fg_names[sio_data->type],	(unsigned int)*address,
		(int)superio_inb(sioaddr, SIO_REG_DEVREV));
exit:
	superio_exit(sioaddr);
	return err;
}

static int __init f71882fg_device_add(unsigned short address,
	const struct f71882fg_sio_data *sio_data)
{
	struct resource res = {
		.start	= address,
		.end	= address + REGION_LENGTH - 1,
		.flags	= IORESOURCE_IO,
	};
	int err;

	f71882fg_pdev = platform_device_alloc(DRVNAME, address);
	if (!f71882fg_pdev)
		return -ENOMEM;

	res.name = f71882fg_pdev->name;
	err = acpi_check_resource_conflict(&res);
	if (err)
		goto exit_device_put;

	err = platform_device_add_resources(f71882fg_pdev, &res, 1);
	if (err) {
		pr_err("Device resource addition failed\n");
		goto exit_device_put;
	}

	err = platform_device_add_data(f71882fg_pdev, sio_data,
				       sizeof(struct f71882fg_sio_data));
	if (err) {
		pr_err("Platform data allocation failed\n");
		goto exit_device_put;
	}

	err = platform_device_add(f71882fg_pdev);
	if (err) {
		pr_err("Device addition failed\n");
		goto exit_device_put;
	}

	return 0;

exit_device_put:
	platform_device_put(f71882fg_pdev);

	return err;
}

static int __init f71882fg_init(void)
{
	int err = -ENODEV;
	unsigned short address;
	struct f71882fg_sio_data sio_data;

	memset(&sio_data, 0, sizeof(sio_data));

	if (f71882fg_find(0x2e, &address, &sio_data) &&
	    f71882fg_find(0x4e, &address, &sio_data))
		goto exit;

	err = platform_driver_register(&f71882fg_driver);
	if (err)
		goto exit;

	err = f71882fg_device_add(address, &sio_data);
	if (err)
		goto exit_driver;

	return 0;

exit_driver:
	platform_driver_unregister(&f71882fg_driver);
exit:
	return err;
}

static void __exit f71882fg_exit(void)
{
	platform_device_unregister(f71882fg_pdev);
	platform_driver_unregister(&f71882fg_driver);
}

MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
MODULE_LICENSE("GPL");

module_init(f71882fg_init);
module_exit(f71882fg_exit);

[-- 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	[flat|nested] 15+ messages in thread

* Re: [lm-sensors] Any idea to support Fintek F71808A
  2011-04-06  6:54 [lm-sensors] Any idea to support Fintek F71808A D.B. Tsai
                   ` (11 preceding siblings ...)
  2011-04-21  9:36 ` Hans de Goede
@ 2011-04-25 16:19 ` D.B. Tsai
  2011-04-26  8:09 ` Hans de Goede
  13 siblings, 0 replies; 15+ messages in thread
From: D.B. Tsai @ 2011-04-25 16:19 UTC (permalink / raw)
  To: lm-sensors

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

Hi Hans

Sorry for the late reply, since I only can access this board in the
working day.
Thank you for your driver, and it seems that it's working correctly in
my motherboard. The attachment is the output of dmesg and sensors.

Best Wishes,

Dong-Bang Tsai    蔡東邦
Ph.D. Student in Applied Physics at Stanford University
史丹佛大學應用物理所博士班
-----------------------------------
Web : http://www.dbtsai.com
Phone : +1-650-383-8392  (USA)
            +886-910-008-392 (Taiwan)



On Thu, Apr 21, 2011 at 2:36 AM, Hans de Goede <hdegoede@redhat.com> wrote:
> Hi,
>
> On 04/06/2011 10:47 PM, D.B. Tsai wrote:
>>
>> Hi
>>
>> Sure, I can take the risk of the disabling acpi resource conflict
>> check, and I'm willing to test your code. Please let send me the code
>> when you finish it.
>
> Attached is an updated f71862fg driver which supports the f71808a to test,
> boot with "acpi_enforce_resources=lax", drop the 2 attached files in a
> dir, and do:
> make
> rmmod f71882fg
> insmod f71882fg.ko
> sensors
>
> Please let me know if this works properly for you, also I would
> appreciate a mail with the output of the sensors and dmesg
> commands.
>
> Regards,
>
> Hans
>

[-- Attachment #2: dmesg.txt --]
[-- Type: text/plain, Size: 50840 bytes --]

[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 2.6.38-8-server (buildd@allspice) (gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-7ubuntu1) ) #40-Ubuntu SMP Thu Mar 31 21:43:58 UTC 2011 (Ubuntu 2.6.38-8.40-server 2.6.38.2)
[    0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-2.6.38-8-server root=UUID=990a97a6-865a-4e87-9dac-599b42ce256a ro acpi_enforce_resources=lax quiet
[    0.000000] BIOS-provided physical RAM map:
[    0.000000]  BIOS-e820: 0000000000000000 - 000000000009ec00 (usable)
[    0.000000]  BIOS-e820: 000000000009ec00 - 00000000000a0000 (reserved)
[    0.000000]  BIOS-e820: 00000000000e0000 - 0000000000100000 (reserved)
[    0.000000]  BIOS-e820: 0000000000100000 - 00000000b7981000 (usable)
[    0.000000]  BIOS-e820: 00000000b7981000 - 00000000b79ca000 (ACPI NVS)
[    0.000000]  BIOS-e820: 00000000b79ca000 - 00000000b79d4000 (ACPI data)
[    0.000000]  BIOS-e820: 00000000b79d4000 - 00000000b79d7000 (ACPI NVS)
[    0.000000]  BIOS-e820: 00000000b79d7000 - 00000000b79d8000 (reserved)
[    0.000000]  BIOS-e820: 00000000b79d8000 - 00000000b79d9000 (ACPI NVS)
[    0.000000]  BIOS-e820: 00000000b79d9000 - 00000000b79fc000 (reserved)
[    0.000000]  BIOS-e820: 00000000b79fc000 - 00000000b79fd000 (usable)
[    0.000000]  BIOS-e820: 00000000b79fd000 - 00000000b7a0d000 (reserved)
[    0.000000]  BIOS-e820: 00000000b7a0d000 - 00000000b7a15000 (ACPI NVS)
[    0.000000]  BIOS-e820: 00000000b7a15000 - 00000000b7a3b000 (reserved)
[    0.000000]  BIOS-e820: 00000000b7a3b000 - 00000000b7a7e000 (ACPI NVS)
[    0.000000]  BIOS-e820: 00000000b7a7e000 - 00000000b7cf7000 (usable)
[    0.000000]  BIOS-e820: 00000000b7cf7000 - 00000000b7ef7000 (reserved)
[    0.000000]  BIOS-e820: 00000000b7ef7000 - 00000000b7f00000 (usable)
[    0.000000]  BIOS-e820: 00000000e0000000 - 00000000f0000000 (reserved)
[    0.000000]  BIOS-e820: 00000000fec00000 - 00000000fec01000 (reserved)
[    0.000000]  BIOS-e820: 00000000fec10000 - 00000000fec11000 (reserved)
[    0.000000]  BIOS-e820: 00000000fed00000 - 00000000fed01000 (reserved)
[    0.000000]  BIOS-e820: 00000000fed61000 - 00000000fed71000 (reserved)
[    0.000000]  BIOS-e820: 00000000fed80000 - 00000000fed90000 (reserved)
[    0.000000]  BIOS-e820: 00000000fef00000 - 0000000100000000 (reserved)
[    0.000000]  BIOS-e820: 0000000100001000 - 000000012f000000 (usable)
[    0.000000] NX (Execute Disable) protection: active
[    0.000000] DMI 2.7 present.
[    0.000000] DMI: ECS HDC-I2/HDC-I2, BIOS 4.6.4 02/14/2011
[    0.000000] e820 update range: 0000000000000000 - 0000000000010000 (usable) ==> (reserved)
[    0.000000] e820 remove range: 00000000000a0000 - 0000000000100000 (usable)
[    0.000000] No AGP bridge found
[    0.000000] last_pfn = 0x12f000 max_arch_pfn = 0x400000000
[    0.000000] MTRR default type: uncachable
[    0.000000] MTRR fixed ranges enabled:
[    0.000000]   00000-9FFFF write-back
[    0.000000]   A0000-BFFFF write-through
[    0.000000]   C0000-CEFFF write-protect
[    0.000000]   CF000-E7FFF uncachable
[    0.000000]   E8000-FFFFF write-protect
[    0.000000] MTRR variable ranges enabled:
[    0.000000]   0 base 000000000 mask F00000000 write-back
[    0.000000]   1 base 0B7F00000 mask FFFF00000 uncachable
[    0.000000]   2 base 0B8000000 mask FF8000000 uncachable
[    0.000000]   3 base 0C0000000 mask FC0000000 uncachable
[    0.000000]   4 disabled
[    0.000000]   5 disabled
[    0.000000]   6 disabled
[    0.000000]   7 disabled
[    0.000000] TOM2: 000000012f000000 aka 4848M
[    0.000000] x86 PAT enabled: cpu 0, old 0x7040600070406, new 0x7010600070106
[    0.000000] e820 update range: 00000000b7f00000 - 0000000100000000 (usable) ==> (reserved)
[    0.000000] last_pfn = 0xb7f00 max_arch_pfn = 0x400000000
[    0.000000] found SMP MP-table at [ffff8800000fcdd0] fcdd0
[    0.000000] initial memory mapped : 0 - 20000000
[    0.000000] Using GB pages for direct mapping
[    0.000000] init_memory_mapping: 0000000000000000-00000000b7f00000
[    0.000000]  0000000000 - 0080000000 page 1G
[    0.000000]  0080000000 - 00b7e00000 page 2M
[    0.000000]  00b7e00000 - 00b7f00000 page 4k
[    0.000000] kernel direct mapping tables up to b7f00000 @ 1fffd000-20000000
[    0.000000] init_memory_mapping: 0000000100000000-000000012f000000
[    0.000000]  0100000000 - 012f000000 page 2M
[    0.000000] kernel direct mapping tables up to 12f000000 @ b7efe000-b7f00000
[    0.000000] RAMDISK: 366f0000 - 37370000
[    0.000000] ACPI: RSDP 00000000000f0430 00024 (v02 ALASKA)
[    0.000000] ACPI: XSDT 00000000b79ca068 00054 (v01 ALASKA    A M I 01072009 AMI  00010013)
[    0.000000] ACPI: FACP 00000000b79d1cf8 000F4 (v04 ALASKA    A M I 01072009 AMI  00010013)
[    0.000000] ACPI Warning: Optional field Pm2ControlBlock has zero address or length: 0x0000000000000000/0x1 (20110112/tbfadt-557)
[    0.000000] ACPI: DSDT 00000000b79ca150 07BA3 (v02 ALASKA    A M I 00000000 INTL 20051117)
[    0.000000] ACPI: FACS 00000000b7a14f80 00040
[    0.000000] ACPI: APIC 00000000b79d1df0 00062 (v03 ALASKA    A M I 01072009 AMI  00010013)
[    0.000000] ACPI: MCFG 00000000b79d1e58 0003C (v01 ALASKA    A M I 01072009 MSFT 00010013)
[    0.000000] ACPI: HPET 00000000b79d1e98 00038 (v01 ALASKA    A M I 01072009 AMI  00000004)
[    0.000000] ACPI: SSDT 00000000b79d1ed0 003DE (v01 AMD    POWERNOW 00000001 AMD  00000001)
[    0.000000] ACPI: SSDT 00000000b79d22b0 012FA (v02    AMD     ALIB 00000001 MSFT 04000000)
[    0.000000] ACPI: Local APIC address 0xfee00000
[    0.000000] No NUMA configuration found
[    0.000000] Faking a node at 0000000000000000-000000012f000000
[    0.000000] Initmem setup node 0 0000000000000000-000000012f000000
[    0.000000]   NODE_DATA [000000012effb000 - 000000012effffff]
[    0.000000]  [ffffea0000000000-ffffea00043fffff] PMD -> [ffff88012b400000-ffff88012e9fffff] on node 0
[    0.000000] Zone PFN ranges:
[    0.000000]   DMA      0x00000010 -> 0x00001000
[    0.000000]   DMA32    0x00001000 -> 0x00100000
[    0.000000]   Normal   0x00100000 -> 0x0012f000
[    0.000000] Movable zone start PFN for each node
[    0.000000] early_node_map[6] active PFN ranges
[    0.000000]     0: 0x00000010 -> 0x0000009e
[    0.000000]     0: 0x00000100 -> 0x000b7981
[    0.000000]     0: 0x000b79fc -> 0x000b79fd
[    0.000000]     0: 0x000b7a7e -> 0x000b7cf7
[    0.000000]     0: 0x000b7ef7 -> 0x000b7f00
[    0.000000]     0: 0x00100001 -> 0x0012f000
[    0.000000] On node 0 totalpages: 945041
[    0.000000]   DMA zone: 56 pages used for memmap
[    0.000000]   DMA zone: 6 pages reserved
[    0.000000]   DMA zone: 3920 pages, LIFO batch:0
[    0.000000]   DMA32 zone: 14280 pages used for memmap
[    0.000000]   DMA32 zone: 734268 pages, LIFO batch:31
[    0.000000]   Normal zone: 2632 pages used for memmap
[    0.000000]   Normal zone: 189879 pages, LIFO batch:31
[    0.000000] ACPI: PM-Timer IO Port: 0x808
[    0.000000] ACPI: Local APIC address 0xfee00000
[    0.000000] ACPI: LAPIC (acpi_id[0x01] lapic_id[0x00] enabled)
[    0.000000] ACPI: LAPIC (acpi_id[0x02] lapic_id[0x01] enabled)
[    0.000000] ACPI: LAPIC_NMI (acpi_id[0xff] high edge lint[0x1])
[    0.000000] ACPI: IOAPIC (id[0x00] address[0xfec00000] gsi_base[0])
[    0.000000] IOAPIC[0]: apic_id 0, version 33, address 0xfec00000, GSI 0-23
[    0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
[    0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level)
[    0.000000] ACPI: IRQ0 used by override.
[    0.000000] ACPI: IRQ2 used by override.
[    0.000000] ACPI: IRQ9 used by override.
[    0.000000] Using ACPI (MADT) for SMP configuration information
[    0.000000] ACPI: HPET id: 0xffffffff base: 0xfed00000
[    0.000000] SMP: Allowing 2 CPUs, 0 hotplug CPUs
[    0.000000] nr_irqs_gsi: 40
[    0.000000] PM: Registered nosave memory: 000000000009e000 - 000000000009f000
[    0.000000] PM: Registered nosave memory: 000000000009f000 - 00000000000a0000
[    0.000000] PM: Registered nosave memory: 00000000000a0000 - 00000000000e0000
[    0.000000] PM: Registered nosave memory: 00000000000e0000 - 0000000000100000
[    0.000000] PM: Registered nosave memory: 00000000b7981000 - 00000000b79ca000
[    0.000000] PM: Registered nosave memory: 00000000b79ca000 - 00000000b79d4000
[    0.000000] PM: Registered nosave memory: 00000000b79d4000 - 00000000b79d7000
[    0.000000] PM: Registered nosave memory: 00000000b79d7000 - 00000000b79d8000
[    0.000000] PM: Registered nosave memory: 00000000b79d8000 - 00000000b79d9000
[    0.000000] PM: Registered nosave memory: 00000000b79d9000 - 00000000b79fc000
[    0.000000] PM: Registered nosave memory: 00000000b79fd000 - 00000000b7a0d000
[    0.000000] PM: Registered nosave memory: 00000000b7a0d000 - 00000000b7a15000
[    0.000000] PM: Registered nosave memory: 00000000b7a15000 - 00000000b7a3b000
[    0.000000] PM: Registered nosave memory: 00000000b7a3b000 - 00000000b7a7e000
[    0.000000] PM: Registered nosave memory: 00000000b7cf7000 - 00000000b7ef7000
[    0.000000] PM: Registered nosave memory: 00000000b7f00000 - 00000000e0000000
[    0.000000] PM: Registered nosave memory: 00000000e0000000 - 00000000f0000000
[    0.000000] PM: Registered nosave memory: 00000000f0000000 - 00000000fec00000
[    0.000000] PM: Registered nosave memory: 00000000fec00000 - 00000000fec01000
[    0.000000] PM: Registered nosave memory: 00000000fec01000 - 00000000fec10000
[    0.000000] PM: Registered nosave memory: 00000000fec10000 - 00000000fec11000
[    0.000000] PM: Registered nosave memory: 00000000fec11000 - 00000000fed00000
[    0.000000] PM: Registered nosave memory: 00000000fed00000 - 00000000fed01000
[    0.000000] PM: Registered nosave memory: 00000000fed01000 - 00000000fed61000
[    0.000000] PM: Registered nosave memory: 00000000fed61000 - 00000000fed71000
[    0.000000] PM: Registered nosave memory: 00000000fed71000 - 00000000fed80000
[    0.000000] PM: Registered nosave memory: 00000000fed80000 - 00000000fed90000
[    0.000000] PM: Registered nosave memory: 00000000fed90000 - 00000000fef00000
[    0.000000] PM: Registered nosave memory: 00000000fef00000 - 0000000100000000
[    0.000000] PM: Registered nosave memory: 0000000100000000 - 0000000100001000
[    0.000000] Allocating PCI resources starting at b7f00000 (gap: b7f00000:28100000)
[    0.000000] Booting paravirtualized kernel on bare hardware
[    0.000000] setup_percpu: NR_CPUS:256 nr_cpumask_bits:256 nr_cpu_ids:2 nr_node_ids:1
[    0.000000] PERCPU: Embedded 28 pages/cpu @ffff8800b7600000 s84416 r8192 d22080 u1048576
[    0.000000] pcpu-alloc: s84416 r8192 d22080 u1048576 alloc=1*2097152
[    0.000000] pcpu-alloc: [0] 0 1 
[    0.000000] Built 1 zonelists in Node order, mobility grouping on.  Total pages: 928067
[    0.000000] Policy zone: Normal
[    0.000000] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-2.6.38-8-server root=UUID=990a97a6-865a-4e87-9dac-599b42ce256a ro acpi_enforce_resources=lax quiet
[    0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
[    0.000000] Checking aperture...
[    0.000000] No AGP bridge found
[    0.000000] Calgary: detecting Calgary via BIOS EBDA area
[    0.000000] Calgary: Unable to locate Rio Grande table in EBDA - bailing!
[    0.000000] Memory: 3632152k/4964352k available (6023k kernel code, 1184188k absent, 148012k reserved, 5024k data, 880k init)
[    0.000000] SLUB: Genslabs=15, HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
[    0.000000] Hierarchical RCU implementation.
[    0.000000] 	RCU dyntick-idle grace-period acceleration is enabled.
[    0.000000] 	RCU-based detection of stalled CPUs is disabled.
[    0.000000] NR_IRQS:16640 nr_irqs:512 16
[    0.000000] Extended CMOS year: 2000
[    0.000000] spurious 8259A interrupt: IRQ7.
[    0.000000] Console: colour VGA+ 80x25
[    0.000000] console [tty0] enabled
[    0.000000] allocated 38010880 bytes of page_cgroup
[    0.000000] please try 'cgroup_disable=memory' option if you don't want memory cgroups
[    0.000000] hpet clockevent registered
[    0.000000] Fast TSC calibration using PIT
[    0.000000] Detected 1600.028 MHz processor.
[    0.010006] Calibrating delay loop (skipped), value calculated using timer frequency.. 3200.05 BogoMIPS (lpj=16000280)
[    0.010014] pid_max: default: 32768 minimum: 301
[    0.010058] Security Framework initialized
[    0.010091] AppArmor: AppArmor initialized
[    0.010095] Yama: becoming mindful.
[    0.010961] Dentry cache hash table entries: 524288 (order: 10, 4194304 bytes)
[    0.013868] Inode-cache hash table entries: 262144 (order: 9, 2097152 bytes)
[    0.015136] Mount-cache hash table entries: 256
[    0.015402] Initializing cgroup subsys ns
[    0.015411] ns_cgroup deprecated: consider using the 'clone_children' flag without the ns_cgroup.
[    0.015416] Initializing cgroup subsys cpuacct
[    0.015425] Initializing cgroup subsys memory
[    0.015442] Initializing cgroup subsys devices
[    0.015446] Initializing cgroup subsys freezer
[    0.015449] Initializing cgroup subsys net_cls
[    0.015453] Initializing cgroup subsys blkio
[    0.015518] tseg: 00b7f00000
[    0.015522] CPU: Physical Processor ID: 0
[    0.015525] CPU: Processor Core ID: 0
[    0.015528] mce: CPU supports 6 MCE banks
[    0.020513] ACPI: Core revision 20110112
[    0.029832] ftrace: allocating 24611 entries in 97 pages
[    0.040141] Setting APIC routing to flat
[    0.040507] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
[    0.147742] CPU0: AMD E-350 Processor stepping 00
[    0.150000] Performance Events: AMD PMU driver.
[    0.150000] ... version:                0
[    0.150000] ... bit width:              48
[    0.150000] ... generic registers:      4
[    0.150000] ... value mask:             0000ffffffffffff
[    0.150000] ... max period:             00007fffffffffff
[    0.150000] ... fixed-purpose events:   0
[    0.150000] ... event mask:             000000000000000f
[    0.150000] Booting Node   0, Processors  #1 Ok.
[    0.310022] Brought up 2 CPUs
[    0.310026] Total of 2 processors activated (6397.67 BogoMIPS).
[    0.310297] devtmpfs: initialized
[    0.312479] print_constraints: dummy: 
[    0.312479] Time: 15:54:18  Date: 04/25/11
[    0.312479] NET: Registered protocol family 16
[    0.312479] Extended Config Space enabled on 0 nodes
[    0.312479] ACPI: bus type pci registered
[    0.312563] PCI: MMCONFIG for domain 0000 [bus 00-ff] at [mem 0xe0000000-0xefffffff] (base 0xe0000000)
[    0.312569] PCI: MMCONFIG at [mem 0xe0000000-0xefffffff] reserved in E820
[    0.377800] PCI: Using configuration type 1 for base access
[    0.379283] Trying to unpack rootfs image as initramfs...
[    0.379477] bio: create slab <bio-0> at 0
[    0.381668] ACPI: EC: Look up EC in DSDT
[    0.384143] ACPI: Executed 3 blocks of module-level executable AML code
[    0.460828] ACPI: Interpreter enabled
[    0.460836] ACPI: (supports S0 S3 S4 S5)
[    0.460878] ACPI: Using IOAPIC for interrupt routing
[    0.770252] ACPI: No dock devices found.
[    0.770263] HEST: Table not found.
[    0.770272] PCI: Using host bridge windows from ACPI; if necessary, use "pci=nocrs" and report a bug
[    0.770696] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
[    0.771230] pci_root PNP0A08:00: host bridge window [io  0x0000-0x03af]
[    0.771236] pci_root PNP0A08:00: host bridge window [io  0x03e0-0x0cf7]
[    0.771241] pci_root PNP0A08:00: host bridge window [io  0x03b0-0x03df]
[    0.771245] pci_root PNP0A08:00: host bridge window [io  0x0d00-0xffff]
[    0.771250] pci_root PNP0A08:00: host bridge window [mem 0x000a0000-0x000bffff]
[    0.771254] pci_root PNP0A08:00: host bridge window [mem 0x000c0000-0x000dffff]
[    0.771259] pci_root PNP0A08:00: host bridge window [mem 0xd0000000-0xffffffff]
[    0.771283] pci 0000:00:00.0: [1022:1510] type 0 class 0x000600
[    0.771342] pci 0000:00:01.0: [1002:9802] type 0 class 0x000300
[    0.771357] pci 0000:00:01.0: reg 10: [mem 0xd0000000-0xdfffffff pref]
[    0.771368] pci 0000:00:01.0: reg 14: [io  0xf000-0xf0ff]
[    0.771378] pci 0000:00:01.0: reg 18: [mem 0xfeb00000-0xfeb3ffff]
[    0.771426] pci 0000:00:01.0: supports D1 D2
[    0.771450] pci 0000:00:01.1: [1002:1314] type 0 class 0x000403
[    0.771463] pci 0000:00:01.1: reg 10: [mem 0xfeb44000-0xfeb47fff]
[    0.771523] pci 0000:00:01.1: supports D1 D2
[    0.771613] pci 0000:00:04.0: [1022:1512] type 1 class 0x000604
[    0.771677] pci 0000:00:04.0: PME# supported from D0 D3hot D3cold
[    0.771684] pci 0000:00:04.0: PME# disabled
[    0.771802] pci 0000:00:11.0: [1002:4390] type 0 class 0x000101
[    0.771829] pci 0000:00:11.0: reg 10: [io  0xf190-0xf197]
[    0.771843] pci 0000:00:11.0: reg 14: [io  0xf180-0xf183]
[    0.771858] pci 0000:00:11.0: reg 18: [io  0xf170-0xf177]
[    0.771872] pci 0000:00:11.0: reg 1c: [io  0xf160-0xf163]
[    0.771886] pci 0000:00:11.0: reg 20: [io  0xf150-0xf15f]
[    0.771900] pci 0000:00:11.0: reg 24: [mem 0xfeb4f000-0xfeb4f3ff]
[    0.771930] pci 0000:00:11.0: set SATA to AHCI mode
[    0.771980] pci 0000:00:12.0: [1002:4397] type 0 class 0x000c03
[    0.772000] pci 0000:00:12.0: reg 10: [mem 0xfeb4e000-0xfeb4efff]
[    0.772096] pci 0000:00:12.2: [1002:4396] type 0 class 0x000c03
[    0.772122] pci 0000:00:12.2: reg 10: [mem 0xfeb4d000-0xfeb4d0ff]
[    0.772216] pci 0000:00:12.2: supports D1 D2
[    0.772220] pci 0000:00:12.2: PME# supported from D0 D1 D2 D3hot
[    0.772226] pci 0000:00:12.2: PME# disabled
[    0.772257] pci 0000:00:13.0: [1002:4397] type 0 class 0x000c03
[    0.772276] pci 0000:00:13.0: reg 10: [mem 0xfeb4c000-0xfeb4cfff]
[    0.772372] pci 0000:00:13.2: [1002:4396] type 0 class 0x000c03
[    0.772399] pci 0000:00:13.2: reg 10: [mem 0xfeb4b000-0xfeb4b0ff]
[    0.772492] pci 0000:00:13.2: supports D1 D2
[    0.772496] pci 0000:00:13.2: PME# supported from D0 D1 D2 D3hot
[    0.772502] pci 0000:00:13.2: PME# disabled
[    0.772533] pci 0000:00:14.0: [1002:4385] type 0 class 0x000c05
[    0.772633] pci 0000:00:14.1: [1002:439c] type 0 class 0x000101
[    0.772652] pci 0000:00:14.1: reg 10: [io  0xf140-0xf147]
[    0.772666] pci 0000:00:14.1: reg 14: [io  0xf130-0xf133]
[    0.772681] pci 0000:00:14.1: reg 18: [io  0xf120-0xf127]
[    0.772695] pci 0000:00:14.1: reg 1c: [io  0xf110-0xf113]
[    0.772709] pci 0000:00:14.1: reg 20: [io  0xf100-0xf10f]
[    0.772760] pci 0000:00:14.2: [1002:4383] type 0 class 0x000403
[    0.772790] pci 0000:00:14.2: reg 10: [mem 0xfeb40000-0xfeb43fff 64bit]
[    0.772868] pci 0000:00:14.2: PME# supported from D0 D3hot D3cold
[    0.772875] pci 0000:00:14.2: PME# disabled
[    0.772899] pci 0000:00:14.3: [1002:439d] type 0 class 0x000601
[    0.773001] pci 0000:00:14.4: [1002:4384] type 1 class 0x000604
[    0.773058] pci 0000:00:14.5: [1002:4399] type 0 class 0x000c03
[    0.773077] pci 0000:00:14.5: reg 10: [mem 0xfeb4a000-0xfeb4afff]
[    0.773174] pci 0000:00:15.0: [1002:43a0] type 1 class 0x000604
[    0.773254] pci 0000:00:15.0: supports D1 D2
[    0.773293] pci 0000:00:15.2: [1002:43a2] type 1 class 0x000604
[    0.773373] pci 0000:00:15.2: supports D1 D2
[    0.773413] pci 0000:00:16.0: [1002:4397] type 0 class 0x000c03
[    0.773432] pci 0000:00:16.0: reg 10: [mem 0xfeb49000-0xfeb49fff]
[    0.773528] pci 0000:00:16.2: [1002:4396] type 0 class 0x000c03
[    0.773554] pci 0000:00:16.2: reg 10: [mem 0xfeb48000-0xfeb480ff]
[    0.773648] pci 0000:00:16.2: supports D1 D2
[    0.773651] pci 0000:00:16.2: PME# supported from D0 D1 D2 D3hot
[    0.773658] pci 0000:00:16.2: PME# disabled
[    0.773690] pci 0000:00:18.0: [1022:1700] type 0 class 0x000600
[    0.773741] pci 0000:00:18.1: [1022:1701] type 0 class 0x000600
[    0.773785] pci 0000:00:18.2: [1022:1702] type 0 class 0x000600
[    0.773831] pci 0000:00:18.3: [1022:1703] type 0 class 0x000600
[    0.773884] pci 0000:00:18.4: [1022:1704] type 0 class 0x000600
[    0.773935] pci 0000:00:18.5: [1022:1718] type 0 class 0x000600
[    0.773978] pci 0000:00:18.6: [1022:1716] type 0 class 0x000600
[    0.774022] pci 0000:00:18.7: [1022:1719] type 0 class 0x000600
[    0.774126] pci 0000:00:04.0: PCI bridge to [bus 01-01]
[    0.774134] pci 0000:00:04.0:   bridge window [io  0xfff000-0x0000] (disabled)
[    0.774141] pci 0000:00:04.0:   bridge window [mem 0xfff00000-0x000fffff] (disabled)
[    0.774149] pci 0000:00:04.0:   bridge window [mem 0xfff00000-0x000fffff pref] (disabled)
[    0.774229] pci 0000:00:14.4: PCI bridge to [bus 02-02] (subtractive decode)
[    0.774236] pci 0000:00:14.4:   bridge window [io  0xf000-0x0000] (disabled)
[    0.774243] pci 0000:00:14.4:   bridge window [mem 0xfff00000-0x000fffff] (disabled)
[    0.774250] pci 0000:00:14.4:   bridge window [mem 0xfff00000-0x000fffff pref] (disabled)
[    0.774254] pci 0000:00:14.4:   bridge window [io  0x0000-0x03af] (subtractive decode)
[    0.774259] pci 0000:00:14.4:   bridge window [io  0x03e0-0x0cf7] (subtractive decode)
[    0.774263] pci 0000:00:14.4:   bridge window [io  0x03b0-0x03df] (subtractive decode)
[    0.774267] pci 0000:00:14.4:   bridge window [io  0x0d00-0xffff] (subtractive decode)
[    0.774272] pci 0000:00:14.4:   bridge window [mem 0x000a0000-0x000bffff] (subtractive decode)
[    0.774276] pci 0000:00:14.4:   bridge window [mem 0x000c0000-0x000dffff] (subtractive decode)
[    0.774281] pci 0000:00:14.4:   bridge window [mem 0xd0000000-0xffffffff] (subtractive decode)
[    0.774352] pci 0000:00:15.0: PCI bridge to [bus 03-03]
[    0.774361] pci 0000:00:15.0:   bridge window [io  0xfff000-0x0000] (disabled)
[    0.774368] pci 0000:00:15.0:   bridge window [mem 0xfff00000-0x000fffff] (disabled)
[    0.774377] pci 0000:00:15.0:   bridge window [mem 0xfff00000-0x000fffff pref] (disabled)
[    0.774472] pci 0000:04:00.0: [1969:1083] type 0 class 0x000200
[    0.774504] pci 0000:04:00.0: reg 10: [mem 0xfea00000-0xfea3ffff 64bit]
[    0.774523] pci 0000:04:00.0: reg 18: [io  0xe000-0xe07f]
[    0.774631] pci 0000:04:00.0: PME# supported from D0 D1 D2 D3hot D3cold
[    0.774638] pci 0000:04:00.0: PME# disabled
[    0.790072] pci 0000:00:15.2: PCI bridge to [bus 04-04]
[    0.790089] pci 0000:00:15.2:   bridge window [io  0xe000-0xefff]
[    0.790096] pci 0000:00:15.2:   bridge window [mem 0xfea00000-0xfeafffff]
[    0.790107] pci 0000:00:15.2:   bridge window [mem 0xfff00000-0x000fffff pref] (disabled)
[    0.790151] ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
[    0.790395] ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.P0PC._PRT]
[    0.790458] ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.PE20._PRT]
[    0.790516] ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.PE22._PRT]
[    0.790594] ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.BR14._PRT]
[    0.790674]  pci0000:00: Requesting ACPI _OSC control (0x1d)
[    0.796074] Freeing initrd memory: 12800k freed
[    0.800893] ACPI: PCI Interrupt Link [LNKA] (IRQs 4 7 10 11 14 15) *0
[    0.801117] ACPI: PCI Interrupt Link [LNKB] (IRQs 4 7 10 11 14 15) *0
[    0.801251] ACPI: PCI Interrupt Link [LNKC] (IRQs 4 7 10 11 14 15) *0
[    0.801382] ACPI: PCI Interrupt Link [LNKD] (IRQs 4 7 10 11 14 15) *0
[    0.801627] ACPI: PCI Interrupt Link [LNKE] (IRQs 3 4 5 6 7 10 11 12 14 15) *0
[    0.801713] ACPI: PCI Interrupt Link [LNKF] (IRQs 4 7 10 11 14 15) *0
[    0.801880] ACPI: PCI Interrupt Link [LNKG] (IRQs 4 7 10 11 14 15) *0
[    0.802038] ACPI: PCI Interrupt Link [LNKH] (IRQs 4 7 10 11 14 15) *0
[    0.802263] vgaarb: device added: PCI:0000:00:01.0,decodes=io+mem,owns=io+mem,locks=none
[    0.802289] vgaarb: loaded
[    0.802624] SCSI subsystem initialized
[    0.802765] libata version 3.00 loaded.
[    0.802854] usbcore: registered new interface driver usbfs
[    0.802874] usbcore: registered new interface driver hub
[    0.802939] usbcore: registered new device driver usb
[    0.803481] wmi: Mapper loaded
[    0.803485] PCI: Using ACPI for IRQ routing
[    0.803490] PCI: pci_cache_line_size set to 64 bytes
[    0.803651] reserve RAM buffer: 000000000009ec00 - 000000000009ffff 
[    0.803656] reserve RAM buffer: 00000000b7981000 - 00000000b7ffffff 
[    0.803662] reserve RAM buffer: 00000000b79fd000 - 00000000b7ffffff 
[    0.803668] reserve RAM buffer: 00000000b7cf7000 - 00000000b7ffffff 
[    0.803672] reserve RAM buffer: 00000000b7f00000 - 00000000b7ffffff 
[    0.803676] reserve RAM buffer: 000000012f000000 - 000000012fffffff 
[    0.803893] NetLabel: Initializing
[    0.803897] NetLabel:  domain hash size = 128
[    0.803900] NetLabel:  protocols = UNLABELED CIPSOv4
[    0.803919] NetLabel:  unlabeled traffic allowed by default
[    0.804051] hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0
[    0.804059] hpet0: 3 comparators, 32-bit 14.318180 MHz counter
[    0.806092] Switching to clocksource hpet
[    0.806149] Switched to NOHz mode on CPU #0
[    0.806149] Switched to NOHz mode on CPU #1
[    0.811708] AppArmor: AppArmor Filesystem Enabled
[    0.811769] pnp: PnP ACPI init
[    0.811809] ACPI: bus type pnp registered
[    0.812162] pnp 00:00: [bus 00-ff]
[    0.812168] pnp 00:00: [io  0x0cf8-0x0cff]
[    0.812173] pnp 00:00: [io  0x0000-0x03af window]
[    0.812177] pnp 00:00: [io  0x03e0-0x0cf7 window]
[    0.812181] pnp 00:00: [io  0x03b0-0x03df window]
[    0.812185] pnp 00:00: [io  0x0d00-0xffff window]
[    0.812194] pnp 00:00: [mem 0x000a0000-0x000bffff window]
[    0.812199] pnp 00:00: [mem 0x000c0000-0x000dffff window]
[    0.812203] pnp 00:00: [mem 0xd0000000-0xffffffff window]
[    0.812207] pnp 00:00: [mem 0x00000000 window]
[    0.812303] pnp 00:00: Plug and Play ACPI device, IDs PNP0a08 PNP0a03 (active)
[    0.812373] pnp 00:01: [mem 0xe0000000-0xefffffff]
[    0.812473] system 00:01: [mem 0xe0000000-0xefffffff] has been reserved
[    0.812481] system 00:01: Plug and Play ACPI device, IDs PNP0c01 (active)
[    0.812966] pnp 00:02: [io  0x040b]
[    0.812970] pnp 00:02: [io  0x04d6]
[    0.812973] pnp 00:02: [io  0x0c00-0x0c01]
[    0.812977] pnp 00:02: [io  0x0c14]
[    0.812980] pnp 00:02: [io  0x0c50-0x0c51]
[    0.812983] pnp 00:02: [io  0x0c52]
[    0.812986] pnp 00:02: [io  0x0c6c]
[    0.812989] pnp 00:02: [io  0x0c6f]
[    0.812992] pnp 00:02: [io  0x0cd0-0x0cd1]
[    0.812995] pnp 00:02: [io  0x0cd2-0x0cd3]
[    0.812999] pnp 00:02: [io  0x0cd4-0x0cd5]
[    0.813002] pnp 00:02: [io  0x0cd6-0x0cd7]
[    0.813005] pnp 00:02: [io  0x0cd8-0x0cdf]
[    0.813008] pnp 00:02: [io  0x0800-0x089f]
[    0.813012] pnp 00:02: [io  0x0000-0xffffffffffffffff disabled]
[    0.813016] pnp 00:02: [io  0x0000-0x000f]
[    0.813019] pnp 00:02: [io  0x0b20-0x0b3f]
[    0.813022] pnp 00:02: [io  0x0900-0x090f]
[    0.813025] pnp 00:02: [io  0x0910-0x091f]
[    0.813029] pnp 00:02: [io  0xfe00-0xfefe]
[    0.813032] pnp 00:02: [io  0x0060-0x005f disabled]
[    0.813036] pnp 00:02: [io  0x0064-0x0063 disabled]
[    0.813039] pnp 00:02: [mem 0xfec00000-0xfec00fff]
[    0.813043] pnp 00:02: [mem 0xfee00000-0xfee00fff]
[    0.813046] pnp 00:02: [mem 0xfed80000-0xfed8ffff]
[    0.813050] pnp 00:02: [mem 0xfed61000-0xfed70fff]
[    0.813053] pnp 00:02: [mem 0xfec10000-0xfec10fff]
[    0.813057] pnp 00:02: [mem 0xfed00000-0xfed00fff]
[    0.813060] pnp 00:02: [mem 0xffe00000-0xffffffff]
[    0.813173] system 00:02: [io  0x040b] has been reserved
[    0.813178] system 00:02: [io  0x04d6] has been reserved
[    0.813182] system 00:02: [io  0x0c00-0x0c01] has been reserved
[    0.813186] system 00:02: [io  0x0c14] has been reserved
[    0.813191] system 00:02: [io  0x0c50-0x0c51] has been reserved
[    0.813195] system 00:02: [io  0x0c52] has been reserved
[    0.813199] system 00:02: [io  0x0c6c] has been reserved
[    0.813203] system 00:02: [io  0x0c6f] has been reserved
[    0.813207] system 00:02: [io  0x0cd0-0x0cd1] has been reserved
[    0.813212] system 00:02: [io  0x0cd2-0x0cd3] has been reserved
[    0.813216] system 00:02: [io  0x0cd4-0x0cd5] has been reserved
[    0.813220] system 00:02: [io  0x0cd6-0x0cd7] has been reserved
[    0.813224] system 00:02: [io  0x0cd8-0x0cdf] has been reserved
[    0.813229] system 00:02: [io  0x0800-0x089f] has been reserved
[    0.813233] system 00:02: [io  0x0b20-0x0b3f] has been reserved
[    0.813237] system 00:02: [io  0x0900-0x090f] has been reserved
[    0.813242] system 00:02: [io  0x0910-0x091f] has been reserved
[    0.813246] system 00:02: [io  0xfe00-0xfefe] has been reserved
[    0.813252] system 00:02: [mem 0xfec00000-0xfec00fff] could not be reserved
[    0.813258] system 00:02: [mem 0xfee00000-0xfee00fff] has been reserved
[    0.813263] system 00:02: [mem 0xfed80000-0xfed8ffff] has been reserved
[    0.813268] system 00:02: [mem 0xfed61000-0xfed70fff] has been reserved
[    0.813273] system 00:02: [mem 0xfec10000-0xfec10fff] has been reserved
[    0.813278] system 00:02: [mem 0xfed00000-0xfed00fff] has been reserved
[    0.813283] system 00:02: [mem 0xffe00000-0xffffffff] has been reserved
[    0.813289] system 00:02: Plug and Play ACPI device, IDs PNP0c02 (active)
[    0.813456] pnp 00:03: [io  0x0000-0xffffffffffffffff disabled]
[    0.813461] pnp 00:03: [io  0x0e80-0x0e8f]
[    0.813464] pnp 00:03: [io  0x0a10-0x0a1f]
[    0.813542] system 00:03: [io  0x0e80-0x0e8f] has been reserved
[    0.813547] system 00:03: [io  0x0a10-0x0a1f] has been reserved
[    0.813553] system 00:03: Plug and Play ACPI device, IDs PNP0c02 (active)
[    0.813657] pnp 00:04: [dma 4]
[    0.813661] pnp 00:04: [io  0x0000-0x000f]
[    0.813664] pnp 00:04: [io  0x0081-0x0083]
[    0.813667] pnp 00:04: [io  0x0087]
[    0.813670] pnp 00:04: [io  0x0089-0x008b]
[    0.813678] pnp 00:04: [io  0x008f]
[    0.813681] pnp 00:04: [io  0x00c0-0x00df]
[    0.813733] pnp 00:04: Plug and Play ACPI device, IDs PNP0200 (active)
[    0.813753] pnp 00:05: [io  0x0070-0x0071]
[    0.813862] pnp 00:05: [irq 8]
[    0.813905] pnp 00:05: Plug and Play ACPI device, IDs PNP0b00 (active)
[    0.813922] pnp 00:06: [io  0x0061]
[    0.813968] pnp 00:06: Plug and Play ACPI device, IDs PNP0800 (active)
[    0.814021] pnp 00:07: [io  0x0010-0x001f]
[    0.814025] pnp 00:07: [io  0x0022-0x003f]
[    0.814028] pnp 00:07: [io  0x0044-0x005f]
[    0.814032] pnp 00:07: [io  0x0062-0x0063]
[    0.814035] pnp 00:07: [io  0x0065-0x006f]
[    0.814038] pnp 00:07: [io  0x0072-0x007f]
[    0.814041] pnp 00:07: [io  0x0080]
[    0.814044] pnp 00:07: [io  0x0084-0x0086]
[    0.814047] pnp 00:07: [io  0x0088]
[    0.814050] pnp 00:07: [io  0x008c-0x008e]
[    0.814054] pnp 00:07: [io  0x0090-0x009f]
[    0.814057] pnp 00:07: [io  0x00a2-0x00bf]
[    0.814060] pnp 00:07: [io  0x00e0-0x00ef]
[    0.814063] pnp 00:07: [io  0x04d0-0x04d1]
[    0.814150] system 00:07: [io  0x04d0-0x04d1] has been reserved
[    0.814157] system 00:07: Plug and Play ACPI device, IDs PNP0c02 (active)
[    0.814174] pnp 00:08: [io  0x00f0-0x00ff]
[    0.814183] pnp 00:08: [irq 13]
[    0.814231] pnp 00:08: Plug and Play ACPI device, IDs PNP0c04 (active)
[    0.814328] system 00:09: Plug and Play ACPI device, IDs PNP0c02 (active)
[    0.831750] pnp 00:0a: [mem 0xb8000000-0xcfffffff]
[    0.831907] system 00:0a: [mem 0xb8000000-0xcfffffff] has been reserved
[    0.831917] system 00:0a: Plug and Play ACPI device, IDs PNP0c02 (active)
[    0.832177] pnp 00:0b: [mem 0xfed00000-0xfed003ff]
[    0.832240] pnp 00:0b: Plug and Play ACPI device, IDs PNP0103 (active)
[    0.832255] pnp: PnP ACPI: found 12 devices
[    0.832258] ACPI: ACPI bus type pnp unregistered
[    0.840142] pci 0000:00:04.0: BAR 14: assigned [mem 0xf0000000-0xf01fffff]
[    0.840153] pci 0000:00:04.0: BAR 15: assigned [mem 0xf0200000-0xf03fffff 64bit pref]
[    0.840162] pci 0000:00:04.0: BAR 13: assigned [io  0x1000-0x1fff]
[    0.840167] pci 0000:00:04.0: PCI bridge to [bus 01-01]
[    0.840172] pci 0000:00:04.0:   bridge window [io  0x1000-0x1fff]
[    0.840179] pci 0000:00:04.0:   bridge window [mem 0xf0000000-0xf01fffff]
[    0.840186] pci 0000:00:04.0:   bridge window [mem 0xf0200000-0xf03fffff 64bit pref]
[    0.840194] pci 0000:00:14.4: PCI bridge to [bus 02-02]
[    0.840197] pci 0000:00:14.4:   bridge window [io  disabled]
[    0.840205] pci 0000:00:14.4:   bridge window [mem disabled]
[    0.840211] pci 0000:00:14.4:   bridge window [mem pref disabled]
[    0.840220] pci 0000:00:15.0: PCI bridge to [bus 03-03]
[    0.840223] pci 0000:00:15.0:   bridge window [io  disabled]
[    0.840230] pci 0000:00:15.0:   bridge window [mem disabled]
[    0.840236] pci 0000:00:15.0:   bridge window [mem pref disabled]
[    0.840245] pci 0000:00:15.2: PCI bridge to [bus 04-04]
[    0.840250] pci 0000:00:15.2:   bridge window [io  0xe000-0xefff]
[    0.840258] pci 0000:00:15.2:   bridge window [mem 0xfea00000-0xfeafffff]
[    0.840264] pci 0000:00:15.2:   bridge window [mem pref disabled]
[    0.840305] pci 0000:00:04.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16
[    0.840313] pci 0000:00:04.0: setting latency timer to 64
[    0.840330] pci 0000:00:15.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16
[    0.840337] pci 0000:00:15.0: setting latency timer to 64
[    0.840347] pci 0000:00:15.2: PCI INT A -> GSI 16 (level, low) -> IRQ 16
[    0.840353] pci 0000:00:15.2: setting latency timer to 64
[    0.840360] pci_bus 0000:00: resource 4 [io  0x0000-0x03af]
[    0.840364] pci_bus 0000:00: resource 5 [io  0x03e0-0x0cf7]
[    0.840368] pci_bus 0000:00: resource 6 [io  0x03b0-0x03df]
[    0.840372] pci_bus 0000:00: resource 7 [io  0x0d00-0xffff]
[    0.840376] pci_bus 0000:00: resource 8 [mem 0x000a0000-0x000bffff]
[    0.840380] pci_bus 0000:00: resource 9 [mem 0x000c0000-0x000dffff]
[    0.840384] pci_bus 0000:00: resource 10 [mem 0xd0000000-0xffffffff]
[    0.840388] pci_bus 0000:01: resource 0 [io  0x1000-0x1fff]
[    0.840392] pci_bus 0000:01: resource 1 [mem 0xf0000000-0xf01fffff]
[    0.840396] pci_bus 0000:01: resource 2 [mem 0xf0200000-0xf03fffff 64bit pref]
[    0.840401] pci_bus 0000:02: resource 4 [io  0x0000-0x03af]
[    0.840404] pci_bus 0000:02: resource 5 [io  0x03e0-0x0cf7]
[    0.840408] pci_bus 0000:02: resource 6 [io  0x03b0-0x03df]
[    0.840412] pci_bus 0000:02: resource 7 [io  0x0d00-0xffff]
[    0.840416] pci_bus 0000:02: resource 8 [mem 0x000a0000-0x000bffff]
[    0.840419] pci_bus 0000:02: resource 9 [mem 0x000c0000-0x000dffff]
[    0.840423] pci_bus 0000:02: resource 10 [mem 0xd0000000-0xffffffff]
[    0.840428] pci_bus 0000:04: resource 0 [io  0xe000-0xefff]
[    0.840431] pci_bus 0000:04: resource 1 [mem 0xfea00000-0xfeafffff]
[    0.840496] NET: Registered protocol family 2
[    0.840758] IP route cache hash table entries: 131072 (order: 8, 1048576 bytes)
[    0.842865] TCP established hash table entries: 524288 (order: 11, 8388608 bytes)
[    0.847873] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes)
[    0.848463] TCP: Hash tables configured (established 524288 bind 65536)
[    0.848468] TCP reno registered
[    0.848503] UDP hash table entries: 2048 (order: 4, 65536 bytes)
[    0.848564] UDP-Lite hash table entries: 2048 (order: 4, 65536 bytes)
[    0.848761] NET: Registered protocol family 1
[    0.848799] pci 0000:00:01.0: Boot video device
[    1.700540] PCI: CLS 64 bytes, default 64
[    1.700549] PCI-DMA: Using software bounce buffering for IO (SWIOTLB)
[    1.700554] Placing 64MB software IO TLB between ffff8800b3600000 - ffff8800b7600000
[    1.700559] software IO TLB at phys 0xb3600000 - 0xb7600000
[    1.701275] audit: initializing netlink socket (disabled)
[    1.701294] type=2000 audit(1303746858.700:1): initialized
[    1.722684] HugeTLB registered 2 MB page size, pre-allocated 0 pages
[    1.727024] VFS: Disk quotas dquot_6.5.2
[    1.727186] Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    1.728893] fuse init (API version 7.16)
[    1.729120] msgmni has been set to 7119
[    1.730756] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
[    1.730996] io scheduler noop registered
[    1.731004] io scheduler deadline registered (default)
[    1.731143] io scheduler cfq registered
[    1.731644] pci_hotplug: PCI Hot Plug PCI Core version: 0.5
[    1.731684] pciehp: PCI Express Hot Plug Controller Driver version: 0.4
[    1.731915] input: Power Button as /devices/LNXSYSTM:00/device:00/PNP0C0C:00/input/input0
[    1.770595] ACPI: Power Button [PWRB]
[    1.770752] input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input1
[    1.770761] ACPI: Power Button [PWRF]
[    1.771156] ACPI: acpi_idle registered with cpuidle
[    1.782995] ERST: Table is not found!
[    1.783187] Serial: 8250/16550 driver, 32 ports, IRQ sharing enabled
[    2.111309] Linux agpgart interface v0.103
[    2.113270] brd: module loaded
[    2.114172] loop: module loaded
[    2.114357] i2c-core: driver [adp5520] using legacy suspend method
[    2.114361] i2c-core: driver [adp5520] using legacy resume method
[    2.114755] pata_acpi 0000:00:14.1: PCI INT B -> GSI 17 (level, low) -> IRQ 17
[    2.115406] Fixed MDIO Bus: probed
[    2.115458] PPP generic driver version 2.4.2
[    2.115540] tun: Universal TUN/TAP device driver, 1.6
[    2.115543] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
[    2.115697] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    2.115809] ehci_hcd 0000:00:12.2: PCI INT B -> GSI 17 (level, low) -> IRQ 17
[    2.115982] ehci_hcd 0000:00:12.2: EHCI Host Controller
[    2.116051] ehci_hcd 0000:00:12.2: new USB bus registered, assigned bus number 1
[    2.120408] ehci_hcd 0000:00:12.2: QUIRK: Enable exception for AMD Hudson ASPM
[    2.120420] ehci_hcd 0000:00:12.2: applying AMD SB700/SB800/Hudson-2/3 EHCI dummy qh workaround
[    2.120470] ehci_hcd 0000:00:12.2: debug port 1
[    2.120516] ehci_hcd 0000:00:12.2: irq 17, io mem 0xfeb4d000
[    2.140328] ehci_hcd 0000:00:12.2: USB 2.0 started, EHCI 1.00
[    2.140618] hub 1-0:1.0: USB hub found
[    2.140627] hub 1-0:1.0: 5 ports detected
[    2.140946] ehci_hcd 0000:00:13.2: PCI INT B -> GSI 17 (level, low) -> IRQ 17
[    2.141074] ehci_hcd 0000:00:13.2: EHCI Host Controller
[    2.141148] ehci_hcd 0000:00:13.2: new USB bus registered, assigned bus number 2
[    2.141362] ehci_hcd 0000:00:13.2: QUIRK: Enable exception for AMD Hudson ASPM
[    2.141374] ehci_hcd 0000:00:13.2: applying AMD SB700/SB800/Hudson-2/3 EHCI dummy qh workaround
[    2.141421] ehci_hcd 0000:00:13.2: debug port 1
[    2.141450] ehci_hcd 0000:00:13.2: irq 17, io mem 0xfeb4b000
[    2.160328] ehci_hcd 0000:00:13.2: USB 2.0 started, EHCI 1.00
[    2.160628] hub 2-0:1.0: USB hub found
[    2.160637] hub 2-0:1.0: 5 ports detected
[    2.160954] ehci_hcd 0000:00:16.2: PCI INT B -> GSI 17 (level, low) -> IRQ 17
[    2.161085] ehci_hcd 0000:00:16.2: EHCI Host Controller
[    2.161161] ehci_hcd 0000:00:16.2: new USB bus registered, assigned bus number 3
[    2.161399] ehci_hcd 0000:00:16.2: QUIRK: Enable exception for AMD Hudson ASPM
[    2.161412] ehci_hcd 0000:00:16.2: applying AMD SB700/SB800/Hudson-2/3 EHCI dummy qh workaround
[    2.161464] ehci_hcd 0000:00:16.2: debug port 1
[    2.161494] ehci_hcd 0000:00:16.2: irq 17, io mem 0xfeb48000
[    2.180328] ehci_hcd 0000:00:16.2: USB 2.0 started, EHCI 1.00
[    2.180610] hub 3-0:1.0: USB hub found
[    2.180619] hub 3-0:1.0: 4 ports detected
[    2.180848] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[    2.180988] ohci_hcd 0000:00:12.0: PCI INT A -> GSI 18 (level, low) -> IRQ 18
[    2.181125] ohci_hcd 0000:00:12.0: OHCI Host Controller
[    2.181205] ohci_hcd 0000:00:12.0: new USB bus registered, assigned bus number 4
[    2.190474] ohci_hcd 0000:00:12.0: irq 18, io mem 0xfeb4e000
[    2.254601] hub 4-0:1.0: USB hub found
[    2.254703] hub 4-0:1.0: 5 ports detected
[    2.255019] ohci_hcd 0000:00:13.0: PCI INT A -> GSI 18 (level, low) -> IRQ 18
[    2.255149] ohci_hcd 0000:00:13.0: OHCI Host Controller
[    2.255231] ohci_hcd 0000:00:13.0: new USB bus registered, assigned bus number 5
[    2.260438] ohci_hcd 0000:00:13.0: irq 18, io mem 0xfeb4c000
[    2.323671] hub 5-0:1.0: USB hub found
[    2.323773] hub 5-0:1.0: 5 ports detected
[    2.324091] ohci_hcd 0000:00:14.5: PCI INT C -> GSI 18 (level, low) -> IRQ 18
[    2.324222] ohci_hcd 0000:00:14.5: OHCI Host Controller
[    2.324299] ohci_hcd 0000:00:14.5: new USB bus registered, assigned bus number 6
[    2.324537] ohci_hcd 0000:00:14.5: irq 18, io mem 0xfeb4a000
[    2.384607] hub 6-0:1.0: USB hub found
[    2.384709] hub 6-0:1.0: 2 ports detected
[    2.385020] ohci_hcd 0000:00:16.0: PCI INT A -> GSI 18 (level, low) -> IRQ 18
[    2.385152] ohci_hcd 0000:00:16.0: OHCI Host Controller
[    2.385226] ohci_hcd 0000:00:16.0: new USB bus registered, assigned bus number 7
[    2.385492] ohci_hcd 0000:00:16.0: irq 18, io mem 0xfeb49000
[    2.444651] hub 7-0:1.0: USB hub found
[    2.444754] hub 7-0:1.0: 4 ports detected
[    2.444979] uhci_hcd: USB Universal Host Controller Interface driver
[    2.445175] i8042: PNP: No PS/2 controller found. Probing ports directly.
[    2.445930] serio: i8042 KBD port at 0x60,0x64 irq 1
[    2.445943] serio: i8042 AUX port at 0x60,0x64 irq 12
[    2.446075] mousedev: PS/2 mouse device common for all mice
[    2.446338] rtc_cmos 00:05: RTC can wake from S4
[    2.446860] rtc_cmos 00:05: rtc core: registered rtc_cmos as rtc0
[    2.446990] rtc0: alarms up to one month, y3k, 114 bytes nvram, hpet irqs
[    2.447212] device-mapper: uevent: version 1.0.3
[    2.447358] device-mapper: ioctl: 4.19.1-ioctl (2011-01-07) initialised: dm-devel@redhat.com
[    2.447943] device-mapper: multipath: version 1.2.0 loaded
[    2.447953] device-mapper: multipath round-robin: version 1.0.0 loaded
[    2.448838] cpuidle: using governor ladder
[    2.448957] cpuidle: using governor menu
[    2.449390] TCP cubic registered
[    2.449643] NET: Registered protocol family 10
[    2.450545] NET: Registered protocol family 17
[    2.450580] Registering the dns_resolver key type
[    2.450751] powernow-k8: Found 1 AMD E-350 Processor (2 cpu cores) (version 2.20.00)
[    2.450843] powernow-k8:    0 : pstate 0 (1600 MHz)
[    2.450847] powernow-k8:    1 : pstate 1 (1280 MHz)
[    2.450850] powernow-k8:    2 : pstate 2 (800 MHz)
[    2.451674] PM: Hibernation image not present or could not be loaded.
[    2.451698] registered taskstats version 1
[    2.452278]   Magic number: 7:348:943
[    2.452336] tty tty0: hash matches
[    2.452339] tty console: hash matches
[    2.452434] rtc_cmos 00:05: setting system clock to 2011-04-25 15:54:20 UTC (1303746860)
[    2.452439] BIOS EDD facility v0.16 2004-Jun-25, 0 devices found
[    2.452442] EDD information not available.
[    2.455561] Freeing unused kernel memory: 880k freed
[    2.456026] Write protecting the kernel read-only data: 10240k
[    2.457294] Freeing unused kernel memory: 100k freed
[    2.466580] Freeing unused kernel memory: 1416k freed
[    2.513580] <30>udev[63]: starting version 167
[    2.589092] Btrfs loaded
[    2.627670] ahci 0000:00:11.0: version 3.0
[    2.627804] ahci 0000:00:11.0: PCI INT A -> GSI 19 (level, low) -> IRQ 19
[    2.628052] ahci 0000:00:11.0: AHCI 0001.0200 32 slots 4 ports 3 Gbps 0xf impl SATA mode
[    2.628059] ahci 0000:00:11.0: flags: 64bit ncq sntf ilck pm led clo pmp pio slum part sxs 
[    2.636297] scsi0 : ahci
[    2.640572] scsi1 : ahci
[    2.644118] scsi2 : ahci
[    2.648766] scsi3 : ahci
[    2.649132] ata1: SATA max UDMA/133 abar m1024@0xfeb4f000 port 0xfeb4f100 irq 19
[    2.649139] ata2: SATA max UDMA/133 abar m1024@0xfeb4f000 port 0xfeb4f180 irq 19
[    2.649144] ata3: SATA max UDMA/133 abar m1024@0xfeb4f000 port 0xfeb4f200 irq 19
[    2.649150] ata4: SATA max UDMA/133 abar m1024@0xfeb4f000 port 0xfeb4f280 irq 19
[    2.650149] usb 4-3: new low speed USB device using ohci_hcd and address 2
[    2.678747] scsi4 : pata_atiixp
[    2.681677] scsi5 : pata_atiixp
[    2.683289] ata5: PATA max UDMA/100 cmd 0x1f0 ctl 0x3f6 bmdma 0xf100 irq 14
[    2.683295] ata6: PATA max UDMA/100 cmd 0x170 ctl 0x376 bmdma 0xf108 irq 15
[    2.695677] atl1c 0000:04:00.0: PCI INT A -> GSI 18 (level, low) -> IRQ 18
[    2.695698] atl1c 0000:04:00.0: setting latency timer to 64
[    2.720278] Refined TSC clocksource calibration: 1599.999 MHz.
[    2.720287] Switching to clocksource tsc
[    2.911689] atl1c 0000:04:00.0: version 1.0.1.0-NAPI
[    2.990666] ata1: SATA link down (SStatus 0 SControl 300)
[    3.000592] ata2: SATA link down (SStatus 0 SControl 300)
[    3.000654] ata3: SATA link down (SStatus 0 SControl 300)
[    3.200690] ata4: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
[    3.202635] ata4.00: ATA-8: Hitachi HTS725050A9A364, PC4OC70E, max UDMA/133
[    3.202643] ata4.00: 976773168 sectors, multi 16: LBA48 NCQ (depth 31/32), AA
[    3.205101] ata4.00: configured for UDMA/133
[    3.205869] scsi 3:0:0:0: Direct-Access     ATA      Hitachi HTS72505 PC4O PQ: 0 ANSI: 5
[    3.206239] sd 3:0:0:0: Attached scsi generic sg0 type 0
[    3.206248] sd 3:0:0:0: [sda] 976773168 512-byte logical blocks: (500 GB/465 GiB)
[    3.206356] sd 3:0:0:0: [sda] Write Protect is off
[    3.206364] sd 3:0:0:0: [sda] Mode Sense: 00 3a 00 00
[    3.206453] sd 3:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[    3.258767]  sda: sda1 sda2 sda3
[    3.260123] sd 3:0:0:0: [sda] Attached SCSI disk
[    3.320680] input: HID 046a:0011 as /devices/pci0000:00/0000:00:12.0/usb4/4-3/4-3:1.0/input/input2
[    3.320863] generic-usb 0003:046A:0011.0001: input,hidraw0: USB HID v1.11 Keyboard [HID 046a:0011] on usb-0000:00:12.0-3/input0
[    3.320896] usbcore: registered new interface driver usbhid
[    3.320900] usbhid: USB HID core driver
[    3.796312] device fsid e74690fd2ec63661-55af15bca128e293 devid 1 transid 282 /dev/sda2
[    3.913085] EXT4-fs (sda1): mounted filesystem with ordered data mode. Opts: (null)
[    8.095526] <30>udev[309]: starting version 167
[    8.163248] lp: driver loaded but no devices found
[    8.187768] f71882fg: Found f71808a chip at 0xe80, revision 33
[    8.187829] ACPI: resource f71882fg [io  0x0e80-0x0e87] conflicts with ACPI region HMIO [io 0xe80-0xf7f]
[    8.187834] ACPI: This conflict may cause random problems and system instability
[    8.187837] ACPI: If an ACPI driver is available for this device, you should use it instead of the native driver
[    8.188064] f71882fg f71882fg.3712: Auto pwm controlled by raw digital data, disabling pwm auto_point sysfs attributes
[    8.188070] f71882fg f71882fg.3712: Fan: 1 is in duty-cycle mode
[    8.188074] f71882fg f71882fg.3712: Fan: 2 is in duty-cycle mode
[    8.188077] f71882fg f71882fg.3712: Fan: 3 is in RPM mode
[    8.236932] piix4_smbus 0000:00:14.0: SMBus Host Controller at 0xb00, revision 0
[    8.279170] [drm] Initialized drm 1.1.0 20060810
[    8.286273] Adding 4889596k swap on /dev/sda3.  Priority:-1 extents:1 across:4889596k 
[    8.381988] SP5100 TCO timer: SP5100 TCO WatchDog Timer Driver v0.01
[    8.382222] SP5100 TCO timer: failed to get tcobase address
[    8.627232] atl1c 0000:04:00.0: irq 40 for MSI/MSI-X
[    8.627341] atl1c 0000:04:00.0: atl1c: eth0 NIC Link is Up<1000 Mbps Full Duplex>
[    8.658772] HDA Intel 0000:00:01.1: PCI INT B -> GSI 19 (level, low) -> IRQ 19
[    8.658882] HDA Intel 0000:00:01.1: irq 41 for MSI/MSI-X
[    8.658921] HDA Intel 0000:00:01.1: setting latency timer to 64
[    8.713079] EXT4-fs (sda1): re-mounted. Opts: errors=remount-ro
[    8.726974] [drm] radeon defaulting to kernel modesetting.
[    8.726982] [drm] radeon kernel modesetting enabled.
[    8.766674] HDA Intel 0000:00:14.2: PCI INT A -> GSI 16 (level, low) -> IRQ 16
[    8.977876] radeon 0000:00:01.0: PCI INT A -> GSI 18 (level, low) -> IRQ 18
[    8.977888] radeon 0000:00:01.0: setting latency timer to 64
[    8.981685] [drm] initializing kernel modesetting (PALM 0x1002:0x9802).
[    8.981822] [drm] register mmio base: 0xFEB00000
[    8.981825] [drm] register mmio size: 262144
[    8.982026] ATOM BIOS: AMD
[    8.982077] radeon 0000:00:01.0: VRAM: 384M 0x0000000000000000 - 0x0000000017FFFFFF (384M used)
[    8.982084] radeon 0000:00:01.0: GTT: 512M 0x0000000018000000 - 0x0000000037FFFFFF
[    8.982097] mtrr: type mismatch for d0000000,10000000 old: write-back new: write-combining
[    8.982102] [drm] Detected VRAM RAM=384M, BAR=256M
[    8.982105] [drm] RAM width 16bits DDR
[    8.987481] [TTM] Zone  kernel: Available graphics memory: 1823674 kiB.
[    8.987487] [TTM] Initializing pool allocator.
[    8.987528] [drm] radeon: 384M of VRAM memory ready
[    8.987533] [drm] radeon: 512M of GTT memory ready.
[    8.987566] [drm] Supports vblank timestamp caching Rev 1 (10.10.2010).
[    8.987569] [drm] Driver supports precise vblank timestamp query.
[    8.987635] radeon 0000:00:01.0: irq 42 for MSI/MSI-X
[    8.987644] radeon 0000:00:01.0: radeon: using MSI.
[    8.987693] [drm] radeon: irq initialized.
[    8.987698] [drm] GART: num cpu pages 131072, num gpu pages 131072
[    8.989614] [drm] Loading PALM Microcode
[    9.511242] radeon 0000:00:01.0: WB enabled
[    9.527832] [drm] ring test succeeded in 1 usecs
[    9.528038] [drm] radeon: ib pool ready.
[    9.528158] [drm] ib test succeeded in 0 usecs
[    9.528171] failed to evaluate ATIF got AE_BAD_PARAMETER
[    9.528668] [drm] Radeon Display Connectors
[    9.528671] [drm] Connector 0:
[    9.528674] [drm]   HDMI-A
[    9.528677] [drm]   HPD2
[    9.528681] [drm]   DDC: 0x6440 0x6440 0x6444 0x6444 0x6448 0x6448 0x644c 0x644c
[    9.528684] [drm]   Encoders:
[    9.528687] [drm]     DFP1: INTERNAL_UNIPHY
[    9.528689] [drm] Connector 1:
[    9.528692] [drm]   VGA
[    9.528695] [drm]   DDC: 0x64d8 0x64d8 0x64dc 0x64dc 0x64e0 0x64e0 0x64e4 0x64e4
[    9.528698] [drm]   Encoders:
[    9.528701] [drm]     CRT1: INTERNAL_KLDSCP_DAC1
[    9.585115] [drm] Internal thermal controller without fan control
[    9.585187] [drm] radeon: power management initialized
[    9.658427] [drm] fb mappable at 0xD0141000
[    9.658430] [drm] vram apper at 0xD0000000
[    9.658433] [drm] size 8294400
[    9.658435] [drm] fb depth is 24
[    9.658437] [drm]    pitch is 7680
[    9.682603] Console: switching to colour frame buffer device 240x67
[    9.694722] fb0: radeondrmfb frame buffer device
[    9.694726] drm: registered panic notifier
[    9.694739] [drm] Initialized radeon 2.8.0 20080528 for 0000:00:01.0 on minor 0
[   10.907762] device fsid e74690fd2ec63661-55af15bca128e293 devid 1 transid 282 /dev/sda2
[   18.750451] eth0: no IPv6 routers present
[  916.480151] f71882fg: Found f71808a chip at 0xe80, revision 33
[  916.480235] ACPI: resource f71882fg [io  0x0e80-0x0e87] conflicts with ACPI region HMIO [io 0xe80-0xf7f]
[  916.480244] ACPI: This conflict may cause random problems and system instability
[  916.480251] ACPI: If an ACPI driver is available for this device, you should use it instead of the native driver
[  916.481129] f71882fg f71882fg.3712: Fan: 1 is in duty-cycle mode
[  916.481138] f71882fg f71882fg.3712: Fan: 2 is in duty-cycle mode

[-- Attachment #3: sensors.txt --]
[-- Type: text/plain, Size: 702 bytes --]

k10temp-pci-00c3
Adapter: PCI adapter
temp1:       +51.5 C  (high = +70.0 C, crit = +100.0 C)  

radeon-pci-0008
Adapter: PCI adapter
temp1:       +51.0 C                                    

f71808a-isa-0e80
Adapter: ISA adapter
in0:         +1.65 V
in1:         +0.99 V
in2:         +0.99 V
in3:         +1.50 V
in7:         +1.65 V
in8:         +1.72 V
fan1:          0 RPM  ALARM
fan2:       4373 RPM
fan3:          0 RPM  ALARM
temp1:       +39.0 C  (high = +85.0 C, hyst = +81.0 C)  
                      (crit = +100.0 C, hyst = +96.0 C)  sensor = thermistor
temp2:         FAULT  (high = +85.0 C, hyst = +81.0 C)  
                      (crit = +100.0 C, hyst = +96.0 C)  sensor = transistor


[-- 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	[flat|nested] 15+ messages in thread

* Re: [lm-sensors] Any idea to support Fintek F71808A
  2011-04-06  6:54 [lm-sensors] Any idea to support Fintek F71808A D.B. Tsai
                   ` (12 preceding siblings ...)
  2011-04-25 16:19 ` D.B. Tsai
@ 2011-04-26  8:09 ` Hans de Goede
  13 siblings, 0 replies; 15+ messages in thread
From: Hans de Goede @ 2011-04-26  8:09 UTC (permalink / raw)
  To: lm-sensors

Hi,

On 04/25/2011 06:19 PM, D.B. Tsai wrote:
> Hi Hans
>
> Sorry for the late reply, since I only can access this board in the
> working day.
> Thank you for your driver, and it seems that it's working correctly in
> my motherboard. The attachment is the output of dmesg and sensors.
>
> Best Wishes,
>
> Dong-Bang Tsai    蔡東邦
> Ph.D. Student in Applied Physics at Stanford University
> 史丹佛大學應用物理所博士班
> -----------------------------------
> Web : http://www.dbtsai.com
> Phone : +1-650-383-8392  (USA)
>              +886-910-008-392 (Taiwan)
>

Thanks, everything looks good.

Regards,

Hans

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

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

end of thread, other threads:[~2011-04-26  8:09 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-06  6:54 [lm-sensors] Any idea to support Fintek F71808A D.B. Tsai
2011-04-06  8:54 ` D.B. Tsai
2011-04-06  9:24 ` Jean Delvare
2011-04-06  9:34 ` D.B. Tsai
2011-04-06 10:09 ` Hans de Goede
2011-04-06 10:15 ` D.B. Tsai
2011-04-06 17:11 ` Hans de Goede
2011-04-06 20:47 ` D.B. Tsai
2011-04-06 21:15 ` D.B. Tsai
2011-04-07  7:29 ` Jean Delvare
2011-04-07  8:01 ` D.B. Tsai
2011-04-07  8:36 ` Jean Delvare
2011-04-21  9:36 ` Hans de Goede
2011-04-25 16:19 ` D.B. Tsai
2011-04-26  8:09 ` Hans de Goede

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.