Showing error 1265

User: Jiri Slaby
Error type: Leaving function in locked state
Error type description: Some lock is not unlocked on all paths of a function, so it is leaked
File location: drivers/hwmon/abituguru3.c
Line in file: 1100
Project: Linux Kernel
Project version: 2.6.28
Tools: Stanse (1.2)
Entered: 2012-05-21 20:30:05 UTC


Source:

   1/*
   2    abituguru3.c
   3
   4    Copyright (c) 2006-2008 Hans de Goede <j.w.r.degoede@hhs.nl>
   5    Copyright (c) 2008 Alistair John Strachan <alistair@devzero.co.uk>
   6
   7    This program is free software; you can redistribute it and/or modify
   8    it under the terms of the GNU General Public License as published by
   9    the Free Software Foundation; either version 2 of the License, or
  10    (at your option) any later version.
  11
  12    This program is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15    GNU General Public License for more details.
  16
  17    You should have received a copy of the GNU General Public License
  18    along with this program; if not, write to the Free Software
  19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20*/
  21/*
  22    This driver supports the sensor part of revision 3 of the custom Abit uGuru
  23    chip found on newer Abit uGuru motherboards. Note: because of lack of specs
  24    only reading the sensors and their settings is supported.
  25*/
  26#include <linux/module.h>
  27#include <linux/init.h>
  28#include <linux/slab.h>
  29#include <linux/jiffies.h>
  30#include <linux/mutex.h>
  31#include <linux/err.h>
  32#include <linux/delay.h>
  33#include <linux/platform_device.h>
  34#include <linux/hwmon.h>
  35#include <linux/hwmon-sysfs.h>
  36#include <linux/dmi.h>
  37#include <asm/io.h>
  38
  39/* uGuru3 bank addresses */
  40#define ABIT_UGURU3_SETTINGS_BANK                0x01
  41#define ABIT_UGURU3_SENSORS_BANK                0x08
  42#define ABIT_UGURU3_MISC_BANK                        0x09
  43#define ABIT_UGURU3_ALARMS_START                0x1E
  44#define ABIT_UGURU3_SETTINGS_START                0x24
  45#define ABIT_UGURU3_VALUES_START                0x80
  46#define ABIT_UGURU3_BOARD_ID                        0x0A
  47/* uGuru3 sensor bank flags */                             /* Alarm if: */
  48#define ABIT_UGURU3_TEMP_HIGH_ALARM_ENABLE        0x01 /*  temp over warn */
  49#define ABIT_UGURU3_VOLT_HIGH_ALARM_ENABLE        0x02 /*  volt over max */
  50#define ABIT_UGURU3_VOLT_LOW_ALARM_ENABLE        0x04 /*  volt under min */
  51#define ABIT_UGURU3_TEMP_HIGH_ALARM_FLAG        0x10 /* temp is over warn */
  52#define ABIT_UGURU3_VOLT_HIGH_ALARM_FLAG        0x20 /* volt is over max */
  53#define ABIT_UGURU3_VOLT_LOW_ALARM_FLAG                0x40 /* volt is under min */
  54#define ABIT_UGURU3_FAN_LOW_ALARM_ENABLE        0x01 /*   fan under min */
  55#define ABIT_UGURU3_BEEP_ENABLE                        0x08 /* beep if alarm */
  56#define ABIT_UGURU3_SHUTDOWN_ENABLE                0x80 /* shutdown if alarm */
  57/* sensor types */
  58#define ABIT_UGURU3_IN_SENSOR                        0
  59#define ABIT_UGURU3_TEMP_SENSOR                        1
  60#define ABIT_UGURU3_FAN_SENSOR                        2
  61
  62/* Timeouts / Retries, if these turn out to need a lot of fiddling we could
  63   convert them to params. Determined by trial and error. I assume this is
  64   cpu-speed independent, since the ISA-bus and not the CPU should be the
  65   bottleneck. */
  66#define ABIT_UGURU3_WAIT_TIMEOUT                250
  67/* Normally the 0xAC at the end of synchronize() is reported after the
  68   first read, but sometimes not and we need to poll */
  69#define ABIT_UGURU3_SYNCHRONIZE_TIMEOUT                5
  70/* utility macros */
  71#define ABIT_UGURU3_NAME                        "abituguru3"
  72#define ABIT_UGURU3_DEBUG(format, arg...)        \
  73        if (verbose)                                \
  74                printk(KERN_DEBUG ABIT_UGURU3_NAME ": "        format , ## arg)
  75
  76/* Macros to help calculate the sysfs_names array length */
  77#define ABIT_UGURU3_MAX_NO_SENSORS 26
  78/* sum of strlen +1 of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0,
  79   in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0, in??_label\0 */
  80#define ABIT_UGURU3_IN_NAMES_LENGTH (11 + 2 * 9 + 2 * 15 + 2 * 22 + 10 + 14 + 11)
  81/* sum of strlen +1 of: temp??_input\0, temp??_max\0, temp??_crit\0,
  82   temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0,
  83   temp??_label\0 */
  84#define ABIT_UGURU3_TEMP_NAMES_LENGTH (13 + 11 + 12 + 13 + 20 + 12 + 16 + 13)
  85/* sum of strlen +1 of: fan??_input\0, fan??_min\0, fan??_alarm\0,
  86   fan??_alarm_enable\0, fan??_beep\0, fan??_shutdown\0, fan??_label\0 */
  87#define ABIT_UGURU3_FAN_NAMES_LENGTH (12 + 10 + 12 + 19 + 11 + 15 + 12)
  88/* Worst case scenario 16 in sensors (longest names_length) and the rest
  89   temp sensors (second longest names_length). */
  90#define ABIT_UGURU3_SYSFS_NAMES_LENGTH (16 * ABIT_UGURU3_IN_NAMES_LENGTH + \
  91        (ABIT_UGURU3_MAX_NO_SENSORS - 16) * ABIT_UGURU3_TEMP_NAMES_LENGTH)
  92
  93/* All the macros below are named identical to the openguru2 program
  94   reverse engineered by Louis Kruger, hence the names might not be 100%
  95   logical. I could come up with better names, but I prefer keeping the names
  96   identical so that this driver can be compared with his work more easily. */
  97/* Two i/o-ports are used by uGuru */
  98#define ABIT_UGURU3_BASE                        0x00E0
  99#define ABIT_UGURU3_CMD                                0x00
 100#define ABIT_UGURU3_DATA                        0x04
 101#define ABIT_UGURU3_REGION_LENGTH                5
 102/* The wait_xxx functions return this on success and the last contents
 103   of the DATA register (0-255) on failure. */
 104#define ABIT_UGURU3_SUCCESS                        -1
 105/* uGuru status flags */
 106#define ABIT_UGURU3_STATUS_READY_FOR_READ        0x01
 107#define ABIT_UGURU3_STATUS_BUSY                        0x02
 108
 109
 110/* Structures */
 111struct abituguru3_sensor_info {
 112        const char* name;
 113        int port;
 114        int type;
 115        int multiplier;
 116        int divisor;
 117        int offset;
 118};
 119
 120struct abituguru3_motherboard_info {
 121        u16 id;
 122        const char *dmi_name;
 123        /* + 1 -> end of sensors indicated by a sensor with name == NULL */
 124        struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1];
 125};
 126
 127/* For the Abit uGuru, we need to keep some data in memory.
 128   The structure is dynamically allocated, at the same time when a new
 129   abituguru3 device is allocated. */
 130struct abituguru3_data {
 131        struct device *hwmon_dev;        /* hwmon registered device */
 132        struct mutex update_lock;        /* protect access to data and uGuru */
 133        unsigned short addr;                /* uguru base address */
 134        char valid;                        /* !=0 if following fields are valid */
 135        unsigned long last_updated;        /* In jiffies */
 136
 137        /* For convenience the sysfs attr and their names are generated
 138           automatically. We have max 10 entries per sensor (for in sensors) */
 139        struct sensor_device_attribute_2 sysfs_attr[ABIT_UGURU3_MAX_NO_SENSORS
 140                * 10];
 141
 142        /* Buffer to store the dynamically generated sysfs names */
 143        char sysfs_names[ABIT_UGURU3_SYSFS_NAMES_LENGTH];
 144
 145        /* Pointer to the sensors info for the detected motherboard */
 146        const struct abituguru3_sensor_info *sensors;
 147
 148        /* The abituguru3 supports upto 48 sensors, and thus has registers
 149           sets for 48 sensors, for convienence reasons / simplicity of the
 150           code we always read and store all registers for all 48 sensors */
 151
 152        /* Alarms for all 48 sensors (1 bit per sensor) */
 153        u8 alarms[48/8];
 154
 155        /* Value of all 48 sensors */
 156        u8 value[48];
 157
 158        /* Settings of all 48 sensors, note in and temp sensors (the first 32
 159           sensors) have 3 bytes of settings, while fans only have 2 bytes,
 160           for convenience we use 3 bytes for all sensors */
 161        u8 settings[48][3];
 162};
 163
 164
 165/* Constants */
 166static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 167        { 0x000C, NULL /* Unknown, need DMI string */, {
 168                { "CPU Core",                 0, 0, 10, 1, 0 },
 169                { "DDR",                 1, 0, 10, 1, 0 },
 170                { "DDR VTT",                 2, 0, 10, 1, 0 },
 171                { "CPU VTT 1.2V",         3, 0, 10, 1, 0 },
 172                { "MCH & PCIE 1.5V",         4, 0, 10, 1, 0 },
 173                { "MCH 2.5V",                 5, 0, 20, 1, 0 },
 174                { "ICH 1.05V",                 6, 0, 10, 1, 0 },
 175                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 176                { "ATX +12V (4-pin)",         8, 0, 60, 1, 0 },
 177                { "ATX +5V",                 9, 0, 30, 1, 0 },
 178                { "+3.3V",                10, 0, 20, 1, 0 },
 179                { "5VSB",                11, 0, 30, 1, 0 },
 180                { "CPU",                24, 1, 1, 1, 0 },
 181                { "System",                25, 1, 1, 1, 0 },
 182                { "PWM",                26, 1, 1, 1, 0 },
 183                { "CPU Fan",                32, 2, 60, 1, 0 },
 184                { "NB Fan",                33, 2, 60, 1, 0 },
 185                { "SYS FAN",                34, 2, 60, 1, 0 },
 186                { "AUX1 Fan",                35, 2, 60, 1, 0 },
 187                { NULL, 0, 0, 0, 0, 0 } }
 188        },
 189        { 0x000D, NULL /* Abit AW8, need DMI string */, {
 190                { "CPU Core",                 0, 0, 10, 1, 0 },
 191                { "DDR",                 1, 0, 10, 1, 0 },
 192                { "DDR VTT",                 2, 0, 10, 1, 0 },
 193                { "CPU VTT 1.2V",         3, 0, 10, 1, 0 },
 194                { "MCH & PCIE 1.5V",         4, 0, 10, 1, 0 },
 195                { "MCH 2.5V",                 5, 0, 20, 1, 0 },
 196                { "ICH 1.05V",                 6, 0, 10, 1, 0 },
 197                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 198                { "ATX +12V (4-pin)",         8, 0, 60, 1, 0 },
 199                { "ATX +5V",                 9, 0, 30, 1, 0 },
 200                { "+3.3V",                10, 0, 20, 1, 0 },
 201                { "5VSB",                11, 0, 30, 1, 0 },
 202                { "CPU",                24, 1, 1, 1, 0 },
 203                { "System",                25, 1, 1, 1, 0 },
 204                { "PWM1",                26, 1, 1, 1, 0 },
 205                { "PWM2",                27, 1, 1, 1, 0 },
 206                { "PWM3",                28, 1, 1, 1, 0 },
 207                { "PWM4",                29, 1, 1, 1, 0 },
 208                { "CPU Fan",                32, 2, 60, 1, 0 },
 209                { "NB Fan",                33, 2, 60, 1, 0 },
 210                { "SYS Fan",                34, 2, 60, 1, 0 },
 211                { "AUX1 Fan",                35, 2, 60, 1, 0 },
 212                { "AUX2 Fan",                36, 2, 60, 1, 0 },
 213                { "AUX3 Fan",                37, 2, 60, 1, 0 },
 214                { "AUX4 Fan",                38, 2, 60, 1, 0 },
 215                { "AUX5 Fan",                39, 2, 60, 1, 0 },
 216                { NULL, 0, 0, 0, 0, 0 } }
 217        },
 218        { 0x000E, NULL /* AL-8, need DMI string */, {
 219                { "CPU Core",                 0, 0, 10, 1, 0 },
 220                { "DDR",                 1, 0, 10, 1, 0 },
 221                { "DDR VTT",                 2, 0, 10, 1, 0 },
 222                { "CPU VTT 1.2V",         3, 0, 10, 1, 0 },
 223                { "MCH & PCIE 1.5V",         4, 0, 10, 1, 0 },
 224                { "MCH 2.5V",                 5, 0, 20, 1, 0 },
 225                { "ICH 1.05V",                 6, 0, 10, 1, 0 },
 226                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 227                { "ATX +12V (4-pin)",         8, 0, 60, 1, 0 },
 228                { "ATX +5V",                 9, 0, 30, 1, 0 },
 229                { "+3.3V",                10, 0, 20, 1, 0 },
 230                { "5VSB",                11, 0, 30, 1, 0 },
 231                { "CPU",                24, 1, 1, 1, 0 },
 232                { "System",                25, 1, 1, 1, 0 },
 233                { "PWM",                26, 1, 1, 1, 0 },
 234                { "CPU Fan",                32, 2, 60, 1, 0 },
 235                { "NB Fan",                33, 2, 60, 1, 0 },
 236                { "SYS Fan",                34, 2, 60, 1, 0 },
 237                { NULL, 0, 0, 0, 0, 0 } }
 238        },
 239        { 0x000F, NULL /* Unknown, need DMI string */, {
 240                { "CPU Core",                 0, 0, 10, 1, 0 },
 241                { "DDR",                 1, 0, 10, 1, 0 },
 242                { "DDR VTT",                 2, 0, 10, 1, 0 },
 243                { "CPU VTT 1.2V",         3, 0, 10, 1, 0 },
 244                { "MCH & PCIE 1.5V",         4, 0, 10, 1, 0 },
 245                { "MCH 2.5V",                 5, 0, 20, 1, 0 },
 246                { "ICH 1.05V",                 6, 0, 10, 1, 0 },
 247                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 248                { "ATX +12V (4-pin)",         8, 0, 60, 1, 0 },
 249                { "ATX +5V",                 9, 0, 30, 1, 0 },
 250                { "+3.3V",                10, 0, 20, 1, 0 },
 251                { "5VSB",                11, 0, 30, 1, 0 },
 252                { "CPU",                24, 1, 1, 1, 0 },
 253                { "System",                25, 1, 1, 1, 0 },
 254                { "PWM",                26, 1, 1, 1, 0 },
 255                { "CPU Fan",                32, 2, 60, 1, 0 },
 256                { "NB Fan",                33, 2, 60, 1, 0 },
 257                { "SYS Fan",                34, 2, 60, 1, 0 },
 258                { NULL, 0, 0, 0, 0, 0 } }
 259        },
 260        { 0x0010, NULL /* Abit NI8 SLI GR, need DMI string */, {
 261                { "CPU Core",                 0, 0, 10, 1, 0 },
 262                { "DDR",                 1, 0, 10, 1, 0 },
 263                { "DDR VTT",                 2, 0, 10, 1, 0 },
 264                { "CPU VTT 1.2V",         3, 0, 10, 1, 0 },
 265                { "NB 1.4V",                 4, 0, 10, 1, 0 },
 266                { "SB 1.5V",                 6, 0, 10, 1, 0 },
 267                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 268                { "ATX +12V (4-pin)",         8, 0, 60, 1, 0 },
 269                { "ATX +5V",                 9, 0, 30, 1, 0 },
 270                { "+3.3V",                10, 0, 20, 1, 0 },
 271                { "5VSB",                11, 0, 30, 1, 0 },
 272                { "CPU",                24, 1, 1, 1, 0 },
 273                { "SYS",                25, 1, 1, 1, 0 },
 274                { "PWM",                26, 1, 1, 1, 0 },
 275                { "CPU Fan",                32, 2, 60, 1, 0 },
 276                { "NB Fan",                33, 2, 60, 1, 0 },
 277                { "SYS Fan",                34, 2, 60, 1, 0 },
 278                { "AUX1 Fan",                35, 2, 60, 1, 0 },
 279                { "OTES1 Fan",                36, 2, 60, 1, 0 },
 280                { NULL, 0, 0, 0, 0, 0 } }
 281        },
 282        { 0x0011, "AT8 32X(ATI RD580-ULI M1575)", {
 283                { "CPU Core",                 0, 0, 10, 1, 0 },
 284                { "DDR",                 1, 0, 20, 1, 0 },
 285                { "DDR VTT",                 2, 0, 10, 1, 0 },
 286                { "CPU VDDA 2.5V",         6, 0, 20, 1, 0 },
 287                { "NB 1.8V",                 4, 0, 10, 1, 0 },
 288                { "NB 1.8V Dual",         5, 0, 10, 1, 0 },
 289                { "HTV 1.2",                 3, 0, 10, 1, 0 },
 290                { "PCIE 1.2V",                12, 0, 10, 1, 0 },
 291                { "NB 1.2V",                13, 0, 10, 1, 0 },
 292                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 293                { "ATX +12V (4-pin)",         8, 0, 60, 1, 0 },
 294                { "ATX +5V",                 9, 0, 30, 1, 0 },
 295                { "+3.3V",                10, 0, 20, 1, 0 },
 296                { "5VSB",                11, 0, 30, 1, 0 },
 297                { "CPU",                24, 1, 1, 1, 0 },
 298                { "NB",                        25, 1, 1, 1, 0 },
 299                { "System",                26, 1, 1, 1, 0 },
 300                { "PWM",                27, 1, 1, 1, 0 },
 301                { "CPU Fan",                32, 2, 60, 1, 0 },
 302                { "NB Fan",                33, 2, 60, 1, 0 },
 303                { "SYS Fan",                34, 2, 60, 1, 0 },
 304                { "AUX1 Fan",                35, 2, 60, 1, 0 },
 305                { "AUX2 Fan",                36, 2, 60, 1, 0 },
 306                { "AUX3 Fan",                37, 2, 60, 1, 0 },
 307                { NULL, 0, 0, 0, 0, 0 } }
 308        },
 309        { 0x0012, NULL /* Abit AN8 32X, need DMI string */, {
 310                { "CPU Core",                 0, 0, 10, 1, 0 },
 311                { "DDR",                 1, 0, 20, 1, 0 },
 312                { "DDR VTT",                 2, 0, 10, 1, 0 },
 313                { "HyperTransport",         3, 0, 10, 1, 0 },
 314                { "CPU VDDA 2.5V",         5, 0, 20, 1, 0 },
 315                { "NB",                         4, 0, 10, 1, 0 },
 316                { "SB",                         6, 0, 10, 1, 0 },
 317                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 318                { "ATX +12V (4-pin)",         8, 0, 60, 1, 0 },
 319                { "ATX +5V",                 9, 0, 30, 1, 0 },
 320                { "+3.3V",                10, 0, 20, 1, 0 },
 321                { "5VSB",                11, 0, 30, 1, 0 },
 322                { "CPU",                24, 1, 1, 1, 0 },
 323                { "SYS",                25, 1, 1, 1, 0 },
 324                { "PWM",                26, 1, 1, 1, 0 },
 325                { "CPU Fan",                32, 2, 60, 1, 0 },
 326                { "NB Fan",                33, 2, 60, 1, 0 },
 327                { "SYS Fan",                34, 2, 60, 1, 0 },
 328                { "AUX1 Fan",                36, 2, 60, 1, 0 },
 329                { NULL, 0, 0, 0, 0, 0 } }
 330        },
 331        { 0x0013, NULL /* Abit AW8D, need DMI string */, {
 332                { "CPU Core",                 0, 0, 10, 1, 0 },
 333                { "DDR",                 1, 0, 10, 1, 0 },
 334                { "DDR VTT",                 2, 0, 10, 1, 0 },
 335                { "CPU VTT 1.2V",         3, 0, 10, 1, 0 },
 336                { "MCH & PCIE 1.5V",         4, 0, 10, 1, 0 },
 337                { "MCH 2.5V",                 5, 0, 20, 1, 0 },
 338                { "ICH 1.05V",                 6, 0, 10, 1, 0 },
 339                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 340                { "ATX +12V (4-pin)",         8, 0, 60, 1, 0 },
 341                { "ATX +5V",                 9, 0, 30, 1, 0 },
 342                { "+3.3V",                10, 0, 20, 1, 0 },
 343                { "5VSB",                11, 0, 30, 1, 0 },
 344                { "CPU",                24, 1, 1, 1, 0 },
 345                { "System",                25, 1, 1, 1, 0 },
 346                { "PWM1",                26, 1, 1, 1, 0 },
 347                { "PWM2",                27, 1, 1, 1, 0 },
 348                { "PWM3",                28, 1, 1, 1, 0 },
 349                { "PWM4",                29, 1, 1, 1, 0 },
 350                { "CPU Fan",                32, 2, 60, 1, 0 },
 351                { "NB Fan",                33, 2, 60, 1, 0 },
 352                { "SYS Fan",                34, 2, 60, 1, 0 },
 353                { "AUX1 Fan",                35, 2, 60, 1, 0 },
 354                { "AUX2 Fan",                36, 2, 60, 1, 0 },
 355                { "AUX3 Fan",                37, 2, 60, 1, 0 },
 356                { "AUX4 Fan",                38, 2, 60, 1, 0 },
 357                { "AUX5 Fan",                39, 2, 60, 1, 0 },
 358                { NULL, 0, 0, 0, 0, 0 } }
 359        },
 360        { 0x0014, NULL /* Abit AB9 Pro, need DMI string */, {
 361                { "CPU Core",                 0, 0, 10, 1, 0 },
 362                { "DDR",                 1, 0, 10, 1, 0 },
 363                { "DDR VTT",                 2, 0, 10, 1, 0 },
 364                { "CPU VTT 1.2V",         3, 0, 10, 1, 0 },
 365                { "MCH & PCIE 1.5V",         4, 0, 10, 1, 0 },
 366                { "MCH 2.5V",                 5, 0, 20, 1, 0 },
 367                { "ICH 1.05V",                 6, 0, 10, 1, 0 },
 368                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 369                { "ATX +12V (4-pin)",         8, 0, 60, 1, 0 },
 370                { "ATX +5V",                 9, 0, 30, 1, 0 },
 371                { "+3.3V",                10, 0, 20, 1, 0 },
 372                { "5VSB",                11, 0, 30, 1, 0 },
 373                { "CPU",                24, 1, 1, 1, 0 },
 374                { "System",                25, 1, 1, 1, 0 },
 375                { "PWM",                26, 1, 1, 1, 0 },
 376                { "CPU Fan",                32, 2, 60, 1, 0 },
 377                { "NB Fan",                33, 2, 60, 1, 0 },
 378                { "SYS Fan",                34, 2, 60, 1, 0 },
 379                { NULL, 0, 0, 0, 0, 0 } }
 380        },
 381        { 0x0015, NULL /* Unknown, need DMI string */, {
 382                { "CPU Core",                 0, 0, 10, 1, 0 },
 383                { "DDR",                 1, 0, 20, 1, 0 },
 384                { "DDR VTT",                 2, 0, 10, 1, 0 },
 385                { "HyperTransport",         3, 0, 10, 1, 0 },
 386                { "CPU VDDA 2.5V",         5, 0, 20, 1, 0 },
 387                { "NB",                         4, 0, 10, 1, 0 },
 388                { "SB",                         6, 0, 10, 1, 0 },
 389                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 390                { "ATX +12V (4-pin)",         8, 0, 60, 1, 0 },
 391                { "ATX +5V",                 9, 0, 30, 1, 0 },
 392                { "+3.3V",                10, 0, 20, 1, 0 },
 393                { "5VSB",                11, 0, 30, 1, 0 },
 394                { "CPU",                24, 1, 1, 1, 0 },
 395                { "SYS",                25, 1, 1, 1, 0 },
 396                { "PWM",                26, 1, 1, 1, 0 },
 397                { "CPU Fan",                32, 2, 60, 1, 0 },
 398                { "NB Fan",                33, 2, 60, 1, 0 },
 399                { "SYS Fan",                34, 2, 60, 1, 0 },
 400                { "AUX1 Fan",                33, 2, 60, 1, 0 },
 401                { "AUX2 Fan",                35, 2, 60, 1, 0 },
 402                { "AUX3 Fan",                36, 2, 60, 1, 0 },
 403                { NULL, 0, 0, 0, 0, 0 } }
 404        },
 405        { 0x0016, "AW9D-MAX       (Intel i975-ICH7)", {
 406                { "CPU Core",                 0, 0, 10, 1, 0 },
 407                { "DDR2",                 1, 0, 20, 1, 0 },
 408                { "DDR2 VTT",                 2, 0, 10, 1, 0 },
 409                { "CPU VTT 1.2V",         3, 0, 10, 1, 0 },
 410                { "MCH & PCIE 1.5V",         4, 0, 10, 1, 0 },
 411                { "MCH 2.5V",                 5, 0, 20, 1, 0 },
 412                { "ICH 1.05V",                 6, 0, 10, 1, 0 },
 413                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 414                { "ATX +12V (4-pin)",         8, 0, 60, 1, 0 },
 415                { "ATX +5V",                 9, 0, 30, 1, 0 },
 416                { "+3.3V",                10, 0, 20, 1, 0 },
 417                { "5VSB",                11, 0, 30, 1, 0 },
 418                { "CPU",                24, 1, 1, 1, 0 },
 419                { "System",                25, 1, 1, 1, 0 },
 420                { "PWM1",                26, 1, 1, 1, 0 },
 421                { "PWM2",                27, 1, 1, 1, 0 },
 422                { "PWM3",                28, 1, 1, 1, 0 },
 423                { "PWM4",                29, 1, 1, 1, 0 },
 424                { "CPU Fan",                32, 2, 60, 1, 0 },
 425                { "NB Fan",                33, 2, 60, 1, 0 },
 426                { "SYS Fan",                34, 2, 60, 1, 0 },
 427                { "AUX1 Fan",                35, 2, 60, 1, 0 },
 428                { "AUX2 Fan",                36, 2, 60, 1, 0 },
 429                { "AUX3 Fan",                37, 2, 60, 1, 0 },
 430                { "OTES1 Fan",                38, 2, 60, 1, 0 },
 431                { NULL, 0, 0, 0, 0, 0 } }
 432        },
 433        { 0x0017, NULL /* Unknown, need DMI string */, {
 434                { "CPU Core",                 0, 0, 10, 1, 0 },
 435                { "DDR2",                 1, 0, 20, 1, 0 },
 436                { "DDR2 VTT",                 2, 0, 10, 1, 0 },
 437                { "HyperTransport",         3, 0, 10, 1, 0 },
 438                { "CPU VDDA 2.5V",         6, 0, 20, 1, 0 },
 439                { "NB 1.8V",                 4, 0, 10, 1, 0 },
 440                { "NB 1.2V ",                13, 0, 10, 1, 0 },
 441                { "SB 1.2V",                 5, 0, 10, 1, 0 },
 442                { "PCIE 1.2V",                12, 0, 10, 1, 0 },
 443                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 444                { "ATX +12V (4-pin)",         8, 0, 60, 1, 0 },
 445                { "ATX +5V",                 9, 0, 30, 1, 0 },
 446                { "ATX +3.3V",                10, 0, 20, 1, 0 },
 447                { "ATX 5VSB",                11, 0, 30, 1, 0 },
 448                { "CPU",                24, 1, 1, 1, 0 },
 449                { "System",                26, 1, 1, 1, 0 },
 450                { "PWM",                27, 1, 1, 1, 0 },
 451                { "CPU FAN",                32, 2, 60, 1, 0 },
 452                { "SYS FAN",                34, 2, 60, 1, 0 },
 453                { "AUX1 FAN",                35, 2, 60, 1, 0 },
 454                { "AUX2 FAN",                36, 2, 60, 1, 0 },
 455                { "AUX3 FAN",                37, 2, 60, 1, 0 },
 456                { NULL, 0, 0, 0, 0, 0 } }
 457        },
 458        { 0x0018, NULL /* Unknown, need DMI string */, {
 459                { "CPU Core",                 0, 0, 10, 1, 0 },
 460                { "DDR2",                 1, 0, 20, 1, 0 },
 461                { "DDR2 VTT",                 2, 0, 10, 1, 0 },
 462                { "CPU VTT",                 3, 0, 10, 1, 0 },
 463                { "MCH 1.25V",                 4, 0, 10, 1, 0 },
 464                { "ICHIO 1.5V",                 5, 0, 10, 1, 0 },
 465                { "ICH 1.05V",                 6, 0, 10, 1, 0 },
 466                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 467                { "ATX +12V (4-pin)",         8, 0, 60, 1, 0 },
 468                { "ATX +5V",                 9, 0, 30, 1, 0 },
 469                { "+3.3V",                10, 0, 20, 1, 0 },
 470                { "5VSB",                11, 0, 30, 1, 0 },
 471                { "CPU",                24, 1, 1, 1, 0 },
 472                { "System",                25, 1, 1, 1, 0 },
 473                { "PWM Phase1",                26, 1, 1, 1, 0 },
 474                { "PWM Phase2",                27, 1, 1, 1, 0 },
 475                { "PWM Phase3",                28, 1, 1, 1, 0 },
 476                { "PWM Phase4",                29, 1, 1, 1, 0 },
 477                { "PWM Phase5",                30, 1, 1, 1, 0 },
 478                { "CPU Fan",                32, 2, 60, 1, 0 },
 479                { "SYS Fan",                34, 2, 60, 1, 0 },
 480                { "AUX1 Fan",                33, 2, 60, 1, 0 },
 481                { "AUX2 Fan",                35, 2, 60, 1, 0 },
 482                { "AUX3 Fan",                36, 2, 60, 1, 0 },
 483                { NULL, 0, 0, 0, 0, 0 } }
 484        },
 485        { 0x0019, NULL /* Unknown, need DMI string */, {
 486                { "CPU Core",                 7, 0, 10, 1, 0 },
 487                { "DDR2",                13, 0, 20, 1, 0 },
 488                { "DDR2 VTT",                14, 0, 10, 1, 0 },
 489                { "CPU VTT",                 3, 0, 20, 1, 0 },
 490                { "NB 1.2V",                 4, 0, 10, 1, 0 },
 491                { "SB 1.5V",                 6, 0, 10, 1, 0 },
 492                { "HyperTransport",         5, 0, 10, 1, 0 },
 493                { "ATX +12V (24-Pin)",        12, 0, 60, 1, 0 },
 494                { "ATX +12V (4-pin)",         8, 0, 60, 1, 0 },
 495                { "ATX +5V",                 9, 0, 30, 1, 0 },
 496                { "ATX +3.3V",                10, 0, 20, 1, 0 },
 497                { "ATX 5VSB",                11, 0, 30, 1, 0 },
 498                { "CPU",                24, 1, 1, 1, 0 },
 499                { "System",                25, 1, 1, 1, 0 },
 500                { "PWM Phase1",                26, 1, 1, 1, 0 },
 501                { "PWM Phase2",                27, 1, 1, 1, 0 },
 502                { "PWM Phase3",                28, 1, 1, 1, 0 },
 503                { "PWM Phase4",                29, 1, 1, 1, 0 },
 504                { "PWM Phase5",                30, 1, 1, 1, 0 },
 505                { "CPU FAN",                32, 2, 60, 1, 0 },
 506                { "SYS FAN",                34, 2, 60, 1, 0 },
 507                { "AUX1 FAN",                33, 2, 60, 1, 0 },
 508                { "AUX2 FAN",                35, 2, 60, 1, 0 },
 509                { "AUX3 FAN",                36, 2, 60, 1, 0 },
 510                { NULL, 0, 0, 0, 0, 0 } }
 511        },
 512        { 0x001A, "IP35 Pro(Intel P35-ICH9R)", {
 513                { "CPU Core",                 0, 0, 10, 1, 0 },
 514                { "DDR2",                 1, 0, 20, 1, 0 },
 515                { "DDR2 VTT",                 2, 0, 10, 1, 0 },
 516                { "CPU VTT 1.2V",         3, 0, 10, 1, 0 },
 517                { "MCH 1.25V",                 4, 0, 10, 1, 0 },
 518                { "ICHIO 1.5V",                 5, 0, 10, 1, 0 },
 519                { "ICH 1.05V",                 6, 0, 10, 1, 0 },
 520                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 521                { "ATX +12V (8-pin)",         8, 0, 60, 1, 0 },
 522                { "ATX +5V",                 9, 0, 30, 1, 0 },
 523                { "+3.3V",                10, 0, 20, 1, 0 },
 524                { "5VSB",                11, 0, 30, 1, 0 },
 525                { "CPU",                24, 1, 1, 1, 0 },
 526                { "System",                25, 1, 1, 1, 0 },
 527                { "PWM",                26, 1, 1, 1, 0 },
 528                { "PWM Phase2",                27, 1, 1, 1, 0 },
 529                { "PWM Phase3",                28, 1, 1, 1, 0 },
 530                { "PWM Phase4",                29, 1, 1, 1, 0 },
 531                { "PWM Phase5",                30, 1, 1, 1, 0 },
 532                { "CPU Fan",                32, 2, 60, 1, 0 },
 533                { "SYS Fan",                34, 2, 60, 1, 0 },
 534                { "AUX1 Fan",                33, 2, 60, 1, 0 },
 535                { "AUX2 Fan",                35, 2, 60, 1, 0 },
 536                { "AUX3 Fan",                36, 2, 60, 1, 0 },
 537                { "AUX4 Fan",                37, 2, 60, 1, 0 },
 538                { NULL, 0, 0, 0, 0, 0 } }
 539        },
 540        { 0x001B, NULL /* Unknown, need DMI string */, {
 541                { "CPU Core",                 0, 0, 10, 1, 0 },
 542                { "DDR3",                 1, 0, 20, 1, 0 },
 543                { "DDR3 VTT",                 2, 0, 10, 1, 0 },
 544                { "CPU VTT",                 3, 0, 10, 1, 0 },
 545                { "MCH 1.25V",                 4, 0, 10, 1, 0 },
 546                { "ICHIO 1.5V",                 5, 0, 10, 1, 0 },
 547                { "ICH 1.05V",                 6, 0, 10, 1, 0 },
 548                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 549                { "ATX +12V (8-pin)",         8, 0, 60, 1, 0 },
 550                { "ATX +5V",                 9, 0, 30, 1, 0 },
 551                { "+3.3V",                10, 0, 20, 1, 0 },
 552                { "5VSB",                11, 0, 30, 1, 0 },
 553                { "CPU",                24, 1, 1, 1, 0 },
 554                { "System",                25, 1, 1, 1, 0 },
 555                { "PWM Phase1",                26, 1, 1, 1, 0 },
 556                { "PWM Phase2",                27, 1, 1, 1, 0 },
 557                { "PWM Phase3",                28, 1, 1, 1, 0 },
 558                { "PWM Phase4",                29, 1, 1, 1, 0 },
 559                { "PWM Phase5",                30, 1, 1, 1, 0 },
 560                { "CPU Fan",                32, 2, 60, 1, 0 },
 561                { "SYS Fan",                34, 2, 60, 1, 0 },
 562                { "AUX1 Fan",                33, 2, 60, 1, 0 },
 563                { "AUX2 Fan",                35, 2, 60, 1, 0 },
 564                { "AUX3 Fan",                36, 2, 60, 1, 0 },
 565                { NULL, 0, 0, 0, 0, 0 } }
 566        },
 567        { 0x001C, NULL /* Unknown, need DMI string */, {
 568                { "CPU Core",                 0, 0, 10, 1, 0 },
 569                { "DDR2",                 1, 0, 20, 1, 0 },
 570                { "DDR2 VTT",                 2, 0, 10, 1, 0 },
 571                { "CPU VTT",                 3, 0, 10, 1, 0 },
 572                { "MCH 1.25V",                 4, 0, 10, 1, 0 },
 573                { "ICHIO 1.5V",                 5, 0, 10, 1, 0 },
 574                { "ICH 1.05V",                 6, 0, 10, 1, 0 },
 575                { "ATX +12V (24-Pin)",         7, 0, 60, 1, 0 },
 576                { "ATX +12V (8-pin)",         8, 0, 60, 1, 0 },
 577                { "ATX +5V",                 9, 0, 30, 1, 0 },
 578                { "+3.3V",                10, 0, 20, 1, 0 },
 579                { "5VSB",                11, 0, 30, 1, 0 },
 580                { "CPU",                24, 1, 1, 1, 0 },
 581                { "System",                25, 1, 1, 1, 0 },
 582                { "PWM Phase1",                26, 1, 1, 1, 0 },
 583                { "PWM Phase2",                27, 1, 1, 1, 0 },
 584                { "PWM Phase3",                28, 1, 1, 1, 0 },
 585                { "PWM Phase4",                29, 1, 1, 1, 0 },
 586                { "PWM Phase5",                30, 1, 1, 1, 0 },
 587                { "CPU Fan",                32, 2, 60, 1, 0 },
 588                { "SYS Fan",                34, 2, 60, 1, 0 },
 589                { "AUX1 Fan",                33, 2, 60, 1, 0 },
 590                { "AUX2 Fan",                35, 2, 60, 1, 0 },
 591                { "AUX3 Fan",                36, 2, 60, 1, 0 },
 592                { NULL, 0, 0, 0, 0, 0 } }
 593        },
 594        { 0x0000, NULL, { { NULL, 0, 0, 0, 0, 0 } } }
 595};
 596
 597
 598/* Insmod parameters */
 599static int force;
 600module_param(force, bool, 0);
 601MODULE_PARM_DESC(force, "Set to one to force detection.");
 602/* Default verbose is 1, since this driver is still in the testing phase */
 603static int verbose = 1;
 604module_param(verbose, bool, 0644);
 605MODULE_PARM_DESC(verbose, "Enable/disable verbose error reporting");
 606
 607
 608/* wait while the uguru is busy (usually after a write) */
 609static int abituguru3_wait_while_busy(struct abituguru3_data *data)
 610{
 611        u8 x;
 612        int timeout = ABIT_UGURU3_WAIT_TIMEOUT;
 613
 614        while ((x = inb_p(data->addr + ABIT_UGURU3_DATA)) &
 615                        ABIT_UGURU3_STATUS_BUSY) {
 616                timeout--;
 617                if (timeout == 0)
 618                        return x;
 619                /* sleep a bit before our last try, to give the uGuru3 one
 620                   last chance to respond. */
 621                if (timeout == 1)
 622                        msleep(1);
 623        }
 624        return ABIT_UGURU3_SUCCESS;
 625}
 626
 627/* wait till uguru is ready to be read */
 628static int abituguru3_wait_for_read(struct abituguru3_data *data)
 629{
 630        u8 x;
 631        int timeout = ABIT_UGURU3_WAIT_TIMEOUT;
 632
 633        while (!((x = inb_p(data->addr + ABIT_UGURU3_DATA)) &
 634                        ABIT_UGURU3_STATUS_READY_FOR_READ)) {
 635                timeout--;
 636                if (timeout == 0)
 637                        return x;
 638                /* sleep a bit before our last try, to give the uGuru3 one
 639                   last chance to respond. */
 640                if (timeout == 1)
 641                        msleep(1);
 642        }
 643        return ABIT_UGURU3_SUCCESS;
 644}
 645
 646/* This synchronizes us with the uGuru3's protocol state machine, this
 647   must be done before each command. */
 648static int abituguru3_synchronize(struct abituguru3_data *data)
 649{
 650        int x, timeout = ABIT_UGURU3_SYNCHRONIZE_TIMEOUT;
 651
 652        if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
 653                ABIT_UGURU3_DEBUG("synchronize timeout during initial busy "
 654                        "wait, status: 0x%02x\n", x);
 655                return -EIO;
 656        }
 657
 658        outb(0x20, data->addr + ABIT_UGURU3_DATA);
 659        if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
 660                ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x20, "
 661                        "status: 0x%02x\n", x);
 662                return -EIO;
 663        }
 664
 665        outb(0x10, data->addr + ABIT_UGURU3_CMD);
 666        if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
 667                ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x10, "
 668                        "status: 0x%02x\n", x);
 669                return -EIO;
 670        }
 671
 672        outb(0x00, data->addr + ABIT_UGURU3_CMD);
 673        if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
 674                ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x00, "
 675                        "status: 0x%02x\n", x);
 676                return -EIO;
 677        }
 678
 679        if ((x = abituguru3_wait_for_read(data)) != ABIT_UGURU3_SUCCESS) {
 680                ABIT_UGURU3_DEBUG("synchronize timeout waiting for read, "
 681                        "status: 0x%02x\n", x);
 682                return -EIO;
 683        }
 684
 685        while ((x = inb(data->addr + ABIT_UGURU3_CMD)) != 0xAC) {
 686                timeout--;
 687                if (timeout == 0) {
 688                        ABIT_UGURU3_DEBUG("synchronize timeout cmd does not "
 689                                "hold 0xAC after synchronize, cmd: 0x%02x\n",
 690                                x);
 691                        return -EIO;
 692                }
 693                msleep(1);
 694        }
 695        return 0;
 696}
 697
 698/* Read count bytes from sensor sensor_addr in bank bank_addr and store the
 699   result in buf */
 700static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset,
 701        u8 count, u8 *buf)
 702{
 703        int i, x;
 704
 705        if ((x = abituguru3_synchronize(data)))
 706                return x;
 707
 708        outb(0x1A, data->addr + ABIT_UGURU3_DATA);
 709        if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
 710                ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after "
 711                        "sending 0x1A, status: 0x%02x\n", (unsigned int)bank,
 712                        (unsigned int)offset, x);
 713                return -EIO;
 714        }
 715
 716        outb(bank, data->addr + ABIT_UGURU3_CMD);
 717        if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
 718                ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after "
 719                        "sending the bank, status: 0x%02x\n",
 720                        (unsigned int)bank, (unsigned int)offset, x);
 721                return -EIO;
 722        }
 723
 724        outb(offset, data->addr + ABIT_UGURU3_CMD);
 725        if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
 726                ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after "
 727                        "sending the offset, status: 0x%02x\n",
 728                        (unsigned int)bank, (unsigned int)offset, x);
 729                return -EIO;
 730        }
 731
 732        outb(count, data->addr + ABIT_UGURU3_CMD);
 733        if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
 734                ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after "
 735                        "sending the count, status: 0x%02x\n",
 736                        (unsigned int)bank, (unsigned int)offset, x);
 737                return -EIO;
 738        }
 739
 740        for (i = 0; i < count; i++) {
 741                if ((x = abituguru3_wait_for_read(data)) !=
 742                                ABIT_UGURU3_SUCCESS) {
 743                        ABIT_UGURU3_DEBUG("timeout reading byte %d from "
 744                                "0x%02x:0x%02x, status: 0x%02x\n", i,
 745                                (unsigned int)bank, (unsigned int)offset, x);
 746                        break;
 747                }
 748                buf[i] = inb(data->addr + ABIT_UGURU3_CMD);
 749        }
 750        return i;
 751}
 752
 753/* Sensor settings are stored 1 byte per offset with the bytes
 754   placed add consecutive offsets. */
 755static int abituguru3_read_increment_offset(struct abituguru3_data *data,
 756                                            u8 bank, u8 offset, u8 count,
 757                                            u8 *buf, int offset_count)
 758{
 759        int i, x;
 760
 761        for (i = 0; i < offset_count; i++)
 762                if ((x = abituguru3_read(data, bank, offset + i, count,
 763                                buf + i * count)) != count)
 764                        return i * count + (i && (x < 0)) ? 0 : x;
 765
 766        return i * count;
 767}
 768
 769/* Following are the sysfs callback functions. These functions expect:
 770   sensor_device_attribute_2->index:   index into the data->sensors array
 771   sensor_device_attribute_2->nr:      register offset, bitmask or NA. */
 772static struct abituguru3_data *abituguru3_update_device(struct device *dev);
 773
 774static ssize_t show_value(struct device *dev,
 775        struct device_attribute *devattr, char *buf)
 776{
 777        int value;
 778        struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
 779        struct abituguru3_data *data = abituguru3_update_device(dev);
 780        const struct abituguru3_sensor_info *sensor;
 781
 782        if (!data)
 783                return -EIO;
 784
 785        sensor = &data->sensors[attr->index];
 786
 787        /* are we reading a setting, or is this a normal read? */
 788        if (attr->nr)
 789                value = data->settings[sensor->port][attr->nr];
 790        else
 791                value = data->value[sensor->port];
 792
 793        /* convert the value */
 794        value = (value * sensor->multiplier) / sensor->divisor +
 795                sensor->offset;
 796
 797        /* alternatively we could update the sensors settings struct for this,
 798           but then its contents would differ from the windows sw ini files */
 799        if (sensor->type == ABIT_UGURU3_TEMP_SENSOR)
 800                value *= 1000;
 801
 802        return sprintf(buf, "%d\n", value);
 803}
 804
 805static ssize_t show_alarm(struct device *dev,
 806        struct device_attribute *devattr, char *buf)
 807{
 808        int port;
 809        struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
 810        struct abituguru3_data *data = abituguru3_update_device(dev);
 811
 812        if (!data)
 813                return -EIO;
 814
 815        port = data->sensors[attr->index].port;
 816
 817        /* See if the alarm bit for this sensor is set and if a bitmask is
 818           given in attr->nr also check if the alarm matches the type of alarm
 819           we're looking for (for volt it can be either low or high). The type
 820           is stored in a few readonly bits in the settings of the sensor. */
 821        if ((data->alarms[port / 8] & (0x01 << (port % 8))) &&
 822                        (!attr->nr || (data->settings[port][0] & attr->nr)))
 823                return sprintf(buf, "1\n");
 824        else
 825                return sprintf(buf, "0\n");
 826}
 827
 828static ssize_t show_mask(struct device *dev,
 829        struct device_attribute *devattr, char *buf)
 830{
 831        struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
 832        struct abituguru3_data *data = dev_get_drvdata(dev);
 833
 834        if (data->settings[data->sensors[attr->index].port][0] & attr->nr)
 835                return sprintf(buf, "1\n");
 836        else
 837                return sprintf(buf, "0\n");
 838}
 839
 840static ssize_t show_label(struct device *dev,
 841        struct device_attribute *devattr, char *buf)
 842{
 843        struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
 844        struct abituguru3_data *data = dev_get_drvdata(dev);
 845
 846        return sprintf(buf, "%s\n", data->sensors[attr->index].name);
 847}
 848
 849static ssize_t show_name(struct device *dev,
 850        struct device_attribute *devattr, char *buf)
 851{
 852        return sprintf(buf, "%s\n", ABIT_UGURU3_NAME);
 853}
 854
 855/* Sysfs attr templates, the real entries are generated automatically. */
 856static const
 857struct sensor_device_attribute_2 abituguru3_sysfs_templ[3][10] = { {
 858        SENSOR_ATTR_2(in%d_input, 0444, show_value, NULL, 0, 0),
 859        SENSOR_ATTR_2(in%d_min, 0444, show_value, NULL, 1, 0),
 860        SENSOR_ATTR_2(in%d_max, 0444, show_value, NULL, 2, 0),
 861        SENSOR_ATTR_2(in%d_min_alarm, 0444, show_alarm, NULL,
 862                ABIT_UGURU3_VOLT_LOW_ALARM_FLAG, 0),
 863        SENSOR_ATTR_2(in%d_max_alarm, 0444, show_alarm, NULL,
 864                ABIT_UGURU3_VOLT_HIGH_ALARM_FLAG, 0),
 865        SENSOR_ATTR_2(in%d_beep, 0444, show_mask, NULL,
 866                ABIT_UGURU3_BEEP_ENABLE, 0),
 867        SENSOR_ATTR_2(in%d_shutdown, 0444, show_mask, NULL,
 868                ABIT_UGURU3_SHUTDOWN_ENABLE, 0),
 869        SENSOR_ATTR_2(in%d_min_alarm_enable, 0444, show_mask, NULL,
 870                ABIT_UGURU3_VOLT_LOW_ALARM_ENABLE, 0),
 871        SENSOR_ATTR_2(in%d_max_alarm_enable, 0444, show_mask, NULL,
 872                ABIT_UGURU3_VOLT_HIGH_ALARM_ENABLE, 0),
 873        SENSOR_ATTR_2(in%d_label, 0444, show_label, NULL, 0, 0)
 874        }, {
 875        SENSOR_ATTR_2(temp%d_input, 0444, show_value, NULL, 0, 0),
 876        SENSOR_ATTR_2(temp%d_max, 0444, show_value, NULL, 1, 0),
 877        SENSOR_ATTR_2(temp%d_crit, 0444, show_value, NULL, 2, 0),
 878        SENSOR_ATTR_2(temp%d_alarm, 0444, show_alarm, NULL, 0, 0),
 879        SENSOR_ATTR_2(temp%d_beep, 0444, show_mask, NULL,
 880                ABIT_UGURU3_BEEP_ENABLE, 0),
 881        SENSOR_ATTR_2(temp%d_shutdown, 0444, show_mask, NULL,
 882                ABIT_UGURU3_SHUTDOWN_ENABLE, 0),
 883        SENSOR_ATTR_2(temp%d_alarm_enable, 0444, show_mask, NULL,
 884                ABIT_UGURU3_TEMP_HIGH_ALARM_ENABLE, 0),
 885        SENSOR_ATTR_2(temp%d_label, 0444, show_label, NULL, 0, 0)
 886        }, {
 887        SENSOR_ATTR_2(fan%d_input, 0444, show_value, NULL, 0, 0),
 888        SENSOR_ATTR_2(fan%d_min, 0444, show_value, NULL, 1, 0),
 889        SENSOR_ATTR_2(fan%d_alarm, 0444, show_alarm, NULL, 0, 0),
 890        SENSOR_ATTR_2(fan%d_beep, 0444, show_mask, NULL,
 891                ABIT_UGURU3_BEEP_ENABLE, 0),
 892        SENSOR_ATTR_2(fan%d_shutdown, 0444, show_mask, NULL,
 893                ABIT_UGURU3_SHUTDOWN_ENABLE, 0),
 894        SENSOR_ATTR_2(fan%d_alarm_enable, 0444, show_mask, NULL,
 895                ABIT_UGURU3_FAN_LOW_ALARM_ENABLE, 0),
 896        SENSOR_ATTR_2(fan%d_label, 0444, show_label, NULL, 0, 0)
 897} };
 898
 899static struct sensor_device_attribute_2 abituguru3_sysfs_attr[] = {
 900        SENSOR_ATTR_2(name, 0444, show_name, NULL, 0, 0),
 901};
 902
 903static int __devinit abituguru3_probe(struct platform_device *pdev)
 904{
 905        const int no_sysfs_attr[3] = { 10, 8, 7 };
 906        int sensor_index[3] = { 0, 1, 1 };
 907        struct abituguru3_data *data;
 908        int i, j, type, used, sysfs_names_free, sysfs_attr_i, res = -ENODEV;
 909        char *sysfs_filename;
 910        u8 buf[2];
 911        u16 id;
 912
 913        if (!(data = kzalloc(sizeof(struct abituguru3_data), GFP_KERNEL)))
 914                return -ENOMEM;
 915
 916        data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
 917        mutex_init(&data->update_lock);
 918        platform_set_drvdata(pdev, data);
 919
 920        /* Read the motherboard ID */
 921        if ((i = abituguru3_read(data, ABIT_UGURU3_MISC_BANK,
 922                        ABIT_UGURU3_BOARD_ID, 2, buf)) != 2) {
 923                goto abituguru3_probe_error;
 924        }
 925
 926        /* Completely read the uGuru to see if one really is there */
 927        if (!abituguru3_update_device(&pdev->dev))
 928                goto abituguru3_probe_error;
 929
 930        /* lookup the ID in our motherboard table */
 931        id = ((u16)buf[0] << 8) | (u16)buf[1];
 932        for (i = 0; abituguru3_motherboards[i].id; i++)
 933                if (abituguru3_motherboards[i].id == id)
 934                        break;
 935        if (!abituguru3_motherboards[i].id) {
 936                printk(KERN_ERR ABIT_UGURU3_NAME ": error unknown motherboard "
 937                        "ID: %04X. Please report this to the abituguru3 "
 938                        "maintainer (see MAINTAINERS)\n", (unsigned int)id);
 939                goto abituguru3_probe_error;
 940        }
 941        data->sensors = abituguru3_motherboards[i].sensors;
 942
 943        printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard "
 944                "ID: %04X\n", (unsigned int)id);
 945
 946#ifdef CONFIG_DMI
 947        if (!abituguru3_motherboards[i].dmi_name) {
 948                printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was "
 949                        "not detected using DMI. Please send the output of "
 950                        "\"dmidecode\" to the abituguru3 maintainer "
 951                        "(see MAINTAINERS)\n");
 952        }
 953#endif
 954
 955        /* Fill the sysfs attr array */
 956        sysfs_attr_i = 0;
 957        sysfs_filename = data->sysfs_names;
 958        sysfs_names_free = ABIT_UGURU3_SYSFS_NAMES_LENGTH;
 959        for (i = 0; data->sensors[i].name; i++) {
 960                /* Fail safe check, this should never happen! */
 961                if (i >= ABIT_UGURU3_MAX_NO_SENSORS) {
 962                        printk(KERN_ERR ABIT_UGURU3_NAME
 963                                ": Fatal error motherboard has more sensors "
 964                                "then ABIT_UGURU3_MAX_NO_SENSORS. This should "
 965                                "never happen please report to the abituguru3 "
 966                                "maintainer (see MAINTAINERS)\n");
 967                        res = -ENAMETOOLONG;
 968                        goto abituguru3_probe_error;
 969                }
 970                type = data->sensors[i].type;
 971                for (j = 0; j < no_sysfs_attr[type]; j++) {
 972                        used = snprintf(sysfs_filename, sysfs_names_free,
 973                                abituguru3_sysfs_templ[type][j].dev_attr.attr.
 974                                name, sensor_index[type]) + 1;
 975                        data->sysfs_attr[sysfs_attr_i] =
 976                                abituguru3_sysfs_templ[type][j];
 977                        data->sysfs_attr[sysfs_attr_i].dev_attr.attr.name =
 978                                sysfs_filename;
 979                        data->sysfs_attr[sysfs_attr_i].index = i;
 980                        sysfs_filename += used;
 981                        sysfs_names_free -= used;
 982                        sysfs_attr_i++;
 983                }
 984                sensor_index[type]++;
 985        }
 986        /* Fail safe check, this should never happen! */
 987        if (sysfs_names_free < 0) {
 988                printk(KERN_ERR ABIT_UGURU3_NAME
 989                        ": Fatal error ran out of space for sysfs attr names. "
 990                        "This should never happen please report to the "
 991                        "abituguru3 maintainer (see MAINTAINERS)\n");
 992                res = -ENAMETOOLONG;
 993                goto abituguru3_probe_error;
 994        }
 995
 996        /* Register sysfs hooks */
 997        for (i = 0; i < sysfs_attr_i; i++)
 998                if (device_create_file(&pdev->dev,
 999                                &data->sysfs_attr[i].dev_attr))
1000                        goto abituguru3_probe_error;
1001        for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++)
1002                if (device_create_file(&pdev->dev,
1003                                &abituguru3_sysfs_attr[i].dev_attr))
1004                        goto abituguru3_probe_error;
1005
1006        data->hwmon_dev = hwmon_device_register(&pdev->dev);
1007        if (IS_ERR(data->hwmon_dev)) {
1008                res = PTR_ERR(data->hwmon_dev);
1009                goto abituguru3_probe_error;
1010        }
1011
1012        return 0; /* success */
1013
1014abituguru3_probe_error:
1015        for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++)
1016                device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr);
1017        for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++)
1018                device_remove_file(&pdev->dev,
1019                        &abituguru3_sysfs_attr[i].dev_attr);
1020        kfree(data);
1021        return res;
1022}
1023
1024static int __devexit abituguru3_remove(struct platform_device *pdev)
1025{
1026        int i;
1027        struct abituguru3_data *data = platform_get_drvdata(pdev);
1028
1029        platform_set_drvdata(pdev, NULL);
1030        hwmon_device_unregister(data->hwmon_dev);
1031        for (i = 0; data->sysfs_attr[i].dev_attr.attr.name; i++)
1032                device_remove_file(&pdev->dev, &data->sysfs_attr[i].dev_attr);
1033        for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++)
1034                device_remove_file(&pdev->dev,
1035                        &abituguru3_sysfs_attr[i].dev_attr);
1036        kfree(data);
1037
1038        return 0;
1039}
1040
1041static struct abituguru3_data *abituguru3_update_device(struct device *dev)
1042{
1043        int i;
1044        struct abituguru3_data *data = dev_get_drvdata(dev);
1045
1046        mutex_lock(&data->update_lock);
1047        if (!data->valid || time_after(jiffies, data->last_updated + HZ)) {
1048                /* Clear data->valid while updating */
1049                data->valid = 0;
1050                /* Read alarms */
1051                if (abituguru3_read_increment_offset(data,
1052                                ABIT_UGURU3_SETTINGS_BANK,
1053                                ABIT_UGURU3_ALARMS_START,
1054                                1, data->alarms, 48/8) != (48/8))
1055                        goto LEAVE_UPDATE;
1056                /* Read in and temp sensors (3 byte settings / sensor) */
1057                for (i = 0; i < 32; i++) {
1058                        if (abituguru3_read(data, ABIT_UGURU3_SENSORS_BANK,
1059                                        ABIT_UGURU3_VALUES_START + i,
1060                                        1, &data->value[i]) != 1)
1061                                goto LEAVE_UPDATE;
1062                        if (abituguru3_read_increment_offset(data,
1063                                        ABIT_UGURU3_SETTINGS_BANK,
1064                                        ABIT_UGURU3_SETTINGS_START + i * 3,
1065                                        1,
1066                                        data->settings[i], 3) != 3)
1067                                goto LEAVE_UPDATE;
1068                }
1069                /* Read temp sensors (2 byte settings / sensor) */
1070                for (i = 0; i < 16; i++) {
1071                        if (abituguru3_read(data, ABIT_UGURU3_SENSORS_BANK,
1072                                        ABIT_UGURU3_VALUES_START + 32 + i,
1073                                        1, &data->value[32 + i]) != 1)
1074                                goto LEAVE_UPDATE;
1075                        if (abituguru3_read_increment_offset(data,
1076                                        ABIT_UGURU3_SETTINGS_BANK,
1077                                        ABIT_UGURU3_SETTINGS_START + 32 * 3 +
1078                                                i * 2, 1,
1079                                        data->settings[32 + i], 2) != 2)
1080                                goto LEAVE_UPDATE;
1081                }
1082                data->last_updated = jiffies;
1083                data->valid = 1;
1084        }
1085LEAVE_UPDATE:
1086        mutex_unlock(&data->update_lock);
1087        if (data->valid)
1088                return data;
1089        else
1090                return NULL;
1091}
1092
1093#ifdef CONFIG_PM
1094static int abituguru3_suspend(struct platform_device *pdev, pm_message_t state)
1095{
1096        struct abituguru3_data *data = platform_get_drvdata(pdev);
1097        /* make sure all communications with the uguru3 are done and no new
1098           ones are started */
1099        mutex_lock(&data->update_lock);
1100        return 0;
1101}
1102
1103static int abituguru3_resume(struct platform_device *pdev)
1104{
1105        struct abituguru3_data *data = platform_get_drvdata(pdev);
1106        mutex_unlock(&data->update_lock);
1107        return 0;
1108}
1109#else
1110#define abituguru3_suspend        NULL
1111#define abituguru3_resume        NULL
1112#endif /* CONFIG_PM */
1113
1114static struct platform_driver abituguru3_driver = {
1115        .driver = {
1116                .owner        = THIS_MODULE,
1117                .name        = ABIT_UGURU3_NAME,
1118        },
1119        .probe        = abituguru3_probe,
1120        .remove        = __devexit_p(abituguru3_remove),
1121        .suspend = abituguru3_suspend,
1122        .resume = abituguru3_resume
1123};
1124
1125#ifdef CONFIG_DMI
1126
1127static int __init abituguru3_dmi_detect(void)
1128{
1129        const char *board_vendor, *board_name;
1130        int i, err = (force) ? 1 : -ENODEV;
1131
1132        board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
1133        if (!board_vendor || strcmp(board_vendor, "http://www.abit.com.tw/"))
1134                return err;
1135
1136        board_name = dmi_get_system_info(DMI_BOARD_NAME);
1137        if (!board_name)
1138                return err;
1139
1140        for (i = 0; abituguru3_motherboards[i].id; i++) {
1141                const char *dmi_name = abituguru3_motherboards[i].dmi_name;
1142                if (dmi_name && !strcmp(dmi_name, board_name))
1143                        break;
1144        }
1145
1146        if (!abituguru3_motherboards[i].id)
1147                return 1;
1148
1149        return 0;
1150}
1151
1152#else /* !CONFIG_DMI */
1153
1154static inline int abituguru3_dmi_detect(void)
1155{
1156        return -ENODEV;
1157}
1158
1159#endif /* CONFIG_DMI */
1160
1161/* FIXME: Manual detection should die eventually; we need to collect stable
1162 *        DMI model names first before we can rely entirely on CONFIG_DMI.
1163 */
1164
1165static int __init abituguru3_detect(void)
1166{
1167        /* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or
1168           0x08 at DATA and 0xAC at CMD. Sometimes the uGuru3 will hold 0x05
1169           or 0x55 at CMD instead, why is unknown. */
1170        u8 data_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_DATA);
1171        u8 cmd_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_CMD);
1172        if (((data_val == 0x00) || (data_val == 0x08)) &&
1173                        ((cmd_val == 0xAC) || (cmd_val == 0x05) ||
1174                         (cmd_val == 0x55)))
1175                return 0;
1176
1177        ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = "
1178                "0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val);
1179
1180        if (force) {
1181                printk(KERN_INFO ABIT_UGURU3_NAME ": Assuming Abit uGuru3 is "
1182                                "present because of \"force\" parameter\n");
1183                return 0;
1184        }
1185
1186        /* No uGuru3 found */
1187        return -ENODEV;
1188}
1189
1190static struct platform_device *abituguru3_pdev;
1191
1192static int __init abituguru3_init(void)
1193{
1194        struct resource res = { .flags = IORESOURCE_IO };
1195        int err;
1196
1197        /* Attempt DMI detection first */
1198        err = abituguru3_dmi_detect();
1199        if (err < 0)
1200                return err;
1201
1202        /* Fall back to manual detection if there was no exact
1203         * board name match, or force was specified.
1204         */
1205        if (err > 0) {
1206                err = abituguru3_detect();
1207                if (err)
1208                        return err;
1209        }
1210
1211        err = platform_driver_register(&abituguru3_driver);
1212        if (err)
1213                goto exit;
1214
1215        abituguru3_pdev = platform_device_alloc(ABIT_UGURU3_NAME,
1216                                                ABIT_UGURU3_BASE);
1217        if (!abituguru3_pdev) {
1218                printk(KERN_ERR ABIT_UGURU3_NAME
1219                        ": Device allocation failed\n");
1220                err = -ENOMEM;
1221                goto exit_driver_unregister;
1222        }
1223
1224        res.start = ABIT_UGURU3_BASE;
1225        res.end = ABIT_UGURU3_BASE + ABIT_UGURU3_REGION_LENGTH - 1;
1226        res.name = ABIT_UGURU3_NAME;
1227
1228        err = platform_device_add_resources(abituguru3_pdev, &res, 1);
1229        if (err) {
1230                printk(KERN_ERR ABIT_UGURU3_NAME
1231                        ": Device resource addition failed (%d)\n", err);
1232                goto exit_device_put;
1233        }
1234
1235        err = platform_device_add(abituguru3_pdev);
1236        if (err) {
1237                printk(KERN_ERR ABIT_UGURU3_NAME
1238                        ": Device addition failed (%d)\n", err);
1239                goto exit_device_put;
1240        }
1241
1242        return 0;
1243
1244exit_device_put:
1245        platform_device_put(abituguru3_pdev);
1246exit_driver_unregister:
1247        platform_driver_unregister(&abituguru3_driver);
1248exit:
1249        return err;
1250}
1251
1252static void __exit abituguru3_exit(void)
1253{
1254        platform_device_unregister(abituguru3_pdev);
1255        platform_driver_unregister(&abituguru3_driver);
1256}
1257
1258MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>");
1259MODULE_DESCRIPTION("Abit uGuru3 Sensor device");
1260MODULE_LICENSE("GPL");
1261
1262module_init(abituguru3_init);
1263module_exit(abituguru3_exit);