Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6

* 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6:
hwmon: Add Asus ATK0110 support
hwmon: (lm95241) Convert to new-style i2c driver

+1070 -69
+1 -2
drivers/acpi/acpica/nsxfeval.c
··· 53 53 /* Local prototypes */ 54 54 static void acpi_ns_resolve_references(struct acpi_evaluate_info *info); 55 55 56 - #ifdef ACPI_FUTURE_USAGE 57 56 /******************************************************************************* 58 57 * 59 58 * FUNCTION: acpi_evaluate_object_typed ··· 146 147 } 147 148 148 149 ACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed) 149 - #endif /* ACPI_FUTURE_USAGE */ 150 + 150 151 /******************************************************************************* 151 152 * 152 153 * FUNCTION: acpi_evaluate_object
+12
drivers/hwmon/Kconfig
··· 248 248 This driver can also be built as a module. If so, the module 249 249 will be called asb100. 250 250 251 + config SENSORS_ATK0110 252 + tristate "ASUS ATK0110 ACPI hwmon" 253 + depends on X86 && ACPI && EXPERIMENTAL 254 + help 255 + If you say yes here you get support for the ACPI hardware 256 + monitoring interface found in many ASUS motherboards. This 257 + driver will provide readings of fans, voltages and temperatures 258 + through the system firmware. 259 + 260 + This driver can also be built as a module. If so, the module 261 + will be called asus_atk0110. 262 + 251 263 config SENSORS_ATXP1 252 264 tristate "Attansic ATXP1 VID controller" 253 265 depends on I2C && EXPERIMENTAL
+1
drivers/hwmon/Makefile
··· 32 32 33 33 obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o 34 34 obj-$(CONFIG_SENSORS_AMS) += ams/ 35 + obj-$(CONFIG_SENSORS_ATK0110) += asus_atk0110.o 35 36 obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o 36 37 obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o 37 38 obj-$(CONFIG_SENSORS_DME1737) += dme1737.o
+1009
drivers/hwmon/asus_atk0110.c
··· 1 + /* 2 + * Copyright (C) 2007-2009 Luca Tettamanti <kronos.it@gmail.com> 3 + * 4 + * This file is released under the GPLv2 5 + * See COPYING in the top level directory of the kernel tree. 6 + */ 7 + 8 + #include <linux/kernel.h> 9 + #include <linux/hwmon.h> 10 + #include <linux/list.h> 11 + #include <linux/module.h> 12 + 13 + #include <acpi/acpi.h> 14 + #include <acpi/acpixf.h> 15 + #include <acpi/acpi_drivers.h> 16 + #include <acpi/acpi_bus.h> 17 + 18 + 19 + #define ATK_HID "ATK0110" 20 + 21 + /* Minimum time between readings, enforced in order to avoid 22 + * hogging the CPU. 23 + */ 24 + #define CACHE_TIME HZ 25 + 26 + #define BOARD_ID "MBIF" 27 + #define METHOD_ENUMERATE "GGRP" 28 + #define METHOD_READ "GITM" 29 + #define METHOD_WRITE "SITM" 30 + #define METHOD_OLD_READ_TMP "RTMP" 31 + #define METHOD_OLD_READ_VLT "RVLT" 32 + #define METHOD_OLD_READ_FAN "RFAN" 33 + #define METHOD_OLD_ENUM_TMP "TSIF" 34 + #define METHOD_OLD_ENUM_VLT "VSIF" 35 + #define METHOD_OLD_ENUM_FAN "FSIF" 36 + 37 + #define ATK_MUX_HWMON 0x00000006ULL 38 + 39 + #define ATK_CLASS_MASK 0xff000000ULL 40 + #define ATK_CLASS_FREQ_CTL 0x03000000ULL 41 + #define ATK_CLASS_FAN_CTL 0x04000000ULL 42 + #define ATK_CLASS_HWMON 0x06000000ULL 43 + 44 + #define ATK_TYPE_MASK 0x00ff0000ULL 45 + #define HWMON_TYPE_VOLT 0x00020000ULL 46 + #define HWMON_TYPE_TEMP 0x00030000ULL 47 + #define HWMON_TYPE_FAN 0x00040000ULL 48 + 49 + #define HWMON_SENSOR_ID_MASK 0x0000ffffULL 50 + 51 + enum atk_pack_member { 52 + HWMON_PACK_FLAGS, 53 + HWMON_PACK_NAME, 54 + HWMON_PACK_LIMIT1, 55 + HWMON_PACK_LIMIT2, 56 + HWMON_PACK_ENABLE 57 + }; 58 + 59 + /* New package format */ 60 + #define _HWMON_NEW_PACK_SIZE 7 61 + #define _HWMON_NEW_PACK_FLAGS 0 62 + #define _HWMON_NEW_PACK_NAME 1 63 + #define _HWMON_NEW_PACK_UNK1 2 64 + #define _HWMON_NEW_PACK_UNK2 3 65 + #define _HWMON_NEW_PACK_LIMIT1 4 66 + #define _HWMON_NEW_PACK_LIMIT2 5 67 + #define _HWMON_NEW_PACK_ENABLE 6 68 + 69 + /* Old package format */ 70 + #define _HWMON_OLD_PACK_SIZE 5 71 + #define _HWMON_OLD_PACK_FLAGS 0 72 + #define _HWMON_OLD_PACK_NAME 1 73 + #define _HWMON_OLD_PACK_LIMIT1 2 74 + #define _HWMON_OLD_PACK_LIMIT2 3 75 + #define _HWMON_OLD_PACK_ENABLE 4 76 + 77 + 78 + struct atk_data { 79 + struct device *hwmon_dev; 80 + acpi_handle atk_handle; 81 + struct acpi_device *acpi_dev; 82 + 83 + bool old_interface; 84 + 85 + /* old interface */ 86 + acpi_handle rtmp_handle; 87 + acpi_handle rvlt_handle; 88 + acpi_handle rfan_handle; 89 + /* new inteface */ 90 + acpi_handle enumerate_handle; 91 + acpi_handle read_handle; 92 + 93 + int voltage_count; 94 + int temperature_count; 95 + int fan_count; 96 + struct list_head sensor_list; 97 + }; 98 + 99 + 100 + typedef ssize_t (*sysfs_show_func)(struct device *dev, 101 + struct device_attribute *attr, char *buf); 102 + 103 + static const struct acpi_device_id atk_ids[] = { 104 + {ATK_HID, 0}, 105 + {"", 0}, 106 + }; 107 + MODULE_DEVICE_TABLE(acpi, atk_ids); 108 + 109 + #define ATTR_NAME_SIZE 16 /* Worst case is "tempN_input" */ 110 + 111 + struct atk_sensor_data { 112 + struct list_head list; 113 + struct atk_data *data; 114 + struct device_attribute label_attr; 115 + struct device_attribute input_attr; 116 + struct device_attribute limit1_attr; 117 + struct device_attribute limit2_attr; 118 + char label_attr_name[ATTR_NAME_SIZE]; 119 + char input_attr_name[ATTR_NAME_SIZE]; 120 + char limit1_attr_name[ATTR_NAME_SIZE]; 121 + char limit2_attr_name[ATTR_NAME_SIZE]; 122 + u64 id; 123 + u64 type; 124 + u64 limit1; 125 + u64 limit2; 126 + u64 cached_value; 127 + unsigned long last_updated; /* in jiffies */ 128 + bool is_valid; 129 + char const *acpi_name; 130 + }; 131 + 132 + struct atk_acpi_buffer_u64 { 133 + union acpi_object buf; 134 + u64 value; 135 + }; 136 + 137 + static int atk_add(struct acpi_device *device); 138 + static int atk_remove(struct acpi_device *device, int type); 139 + static void atk_print_sensor(struct atk_data *data, union acpi_object *obj); 140 + static int atk_read_value(struct atk_sensor_data *sensor, u64 *value); 141 + static void atk_free_sensors(struct atk_data *data); 142 + 143 + static struct acpi_driver atk_driver = { 144 + .name = ATK_HID, 145 + .class = "hwmon", 146 + .ids = atk_ids, 147 + .ops = { 148 + .add = atk_add, 149 + .remove = atk_remove, 150 + }, 151 + }; 152 + 153 + #define input_to_atk_sensor(attr) \ 154 + container_of(attr, struct atk_sensor_data, input_attr) 155 + 156 + #define label_to_atk_sensor(attr) \ 157 + container_of(attr, struct atk_sensor_data, label_attr) 158 + 159 + #define limit1_to_atk_sensor(attr) \ 160 + container_of(attr, struct atk_sensor_data, limit1_attr) 161 + 162 + #define limit2_to_atk_sensor(attr) \ 163 + container_of(attr, struct atk_sensor_data, limit2_attr) 164 + 165 + static ssize_t atk_input_show(struct device *dev, 166 + struct device_attribute *attr, char *buf) 167 + { 168 + struct atk_sensor_data *s = input_to_atk_sensor(attr); 169 + u64 value; 170 + int err; 171 + 172 + err = atk_read_value(s, &value); 173 + if (err) 174 + return err; 175 + 176 + if (s->type == HWMON_TYPE_TEMP) 177 + /* ACPI returns decidegree */ 178 + value *= 100; 179 + 180 + return sprintf(buf, "%llu\n", value); 181 + } 182 + 183 + static ssize_t atk_label_show(struct device *dev, 184 + struct device_attribute *attr, char *buf) 185 + { 186 + struct atk_sensor_data *s = label_to_atk_sensor(attr); 187 + 188 + return sprintf(buf, "%s\n", s->acpi_name); 189 + } 190 + 191 + static ssize_t atk_limit1_show(struct device *dev, 192 + struct device_attribute *attr, char *buf) 193 + { 194 + struct atk_sensor_data *s = limit1_to_atk_sensor(attr); 195 + u64 value = s->limit1; 196 + 197 + if (s->type == HWMON_TYPE_TEMP) 198 + value *= 100; 199 + 200 + return sprintf(buf, "%lld\n", value); 201 + } 202 + 203 + static ssize_t atk_limit2_show(struct device *dev, 204 + struct device_attribute *attr, char *buf) 205 + { 206 + struct atk_sensor_data *s = limit2_to_atk_sensor(attr); 207 + u64 value = s->limit2; 208 + 209 + if (s->type == HWMON_TYPE_TEMP) 210 + value *= 100; 211 + 212 + return sprintf(buf, "%lld\n", value); 213 + } 214 + 215 + static ssize_t atk_name_show(struct device *dev, 216 + struct device_attribute *attr, char *buf) 217 + { 218 + return sprintf(buf, "atk0110\n"); 219 + } 220 + static struct device_attribute atk_name_attr = 221 + __ATTR(name, 0444, atk_name_show, NULL); 222 + 223 + static void atk_init_attribute(struct device_attribute *attr, char *name, 224 + sysfs_show_func show) 225 + { 226 + attr->attr.name = name; 227 + attr->attr.mode = 0444; 228 + attr->show = show; 229 + attr->store = NULL; 230 + } 231 + 232 + 233 + static union acpi_object *atk_get_pack_member(struct atk_data *data, 234 + union acpi_object *pack, 235 + enum atk_pack_member m) 236 + { 237 + bool old_if = data->old_interface; 238 + int offset; 239 + 240 + switch (m) { 241 + case HWMON_PACK_FLAGS: 242 + offset = old_if ? _HWMON_OLD_PACK_FLAGS : _HWMON_NEW_PACK_FLAGS; 243 + break; 244 + case HWMON_PACK_NAME: 245 + offset = old_if ? _HWMON_OLD_PACK_NAME : _HWMON_NEW_PACK_NAME; 246 + break; 247 + case HWMON_PACK_LIMIT1: 248 + offset = old_if ? _HWMON_OLD_PACK_LIMIT1 : 249 + _HWMON_NEW_PACK_LIMIT1; 250 + break; 251 + case HWMON_PACK_LIMIT2: 252 + offset = old_if ? _HWMON_OLD_PACK_LIMIT2 : 253 + _HWMON_NEW_PACK_LIMIT2; 254 + break; 255 + case HWMON_PACK_ENABLE: 256 + offset = old_if ? _HWMON_OLD_PACK_ENABLE : 257 + _HWMON_NEW_PACK_ENABLE; 258 + break; 259 + default: 260 + return NULL; 261 + } 262 + 263 + return &pack->package.elements[offset]; 264 + } 265 + 266 + 267 + /* New package format is: 268 + * - flag (int) 269 + * class - used for de-muxing the request to the correct GITn 270 + * type (volt, temp, fan) 271 + * sensor id | 272 + * sensor id - used for de-muxing the request _inside_ the GITn 273 + * - name (str) 274 + * - unknown (int) 275 + * - unknown (int) 276 + * - limit1 (int) 277 + * - limit2 (int) 278 + * - enable (int) 279 + * 280 + * The old package has the same format but it's missing the two unknown fields. 281 + */ 282 + static int validate_hwmon_pack(struct atk_data *data, union acpi_object *obj) 283 + { 284 + struct device *dev = &data->acpi_dev->dev; 285 + union acpi_object *tmp; 286 + bool old_if = data->old_interface; 287 + int const expected_size = old_if ? _HWMON_OLD_PACK_SIZE : 288 + _HWMON_NEW_PACK_SIZE; 289 + 290 + if (obj->type != ACPI_TYPE_PACKAGE) { 291 + dev_warn(dev, "Invalid type: %d\n", obj->type); 292 + return -EINVAL; 293 + } 294 + 295 + if (obj->package.count != expected_size) { 296 + dev_warn(dev, "Invalid package size: %d, expected: %d\n", 297 + obj->package.count, expected_size); 298 + return -EINVAL; 299 + } 300 + 301 + tmp = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS); 302 + if (tmp->type != ACPI_TYPE_INTEGER) { 303 + dev_warn(dev, "Invalid type (flag): %d\n", tmp->type); 304 + return -EINVAL; 305 + } 306 + 307 + tmp = atk_get_pack_member(data, obj, HWMON_PACK_NAME); 308 + if (tmp->type != ACPI_TYPE_STRING) { 309 + dev_warn(dev, "Invalid type (name): %d\n", tmp->type); 310 + return -EINVAL; 311 + } 312 + 313 + /* Don't check... we don't know what they're useful for anyway */ 314 + #if 0 315 + tmp = &obj->package.elements[HWMON_PACK_UNK1]; 316 + if (tmp->type != ACPI_TYPE_INTEGER) { 317 + dev_warn(dev, "Invalid type (unk1): %d\n", tmp->type); 318 + return -EINVAL; 319 + } 320 + 321 + tmp = &obj->package.elements[HWMON_PACK_UNK2]; 322 + if (tmp->type != ACPI_TYPE_INTEGER) { 323 + dev_warn(dev, "Invalid type (unk2): %d\n", tmp->type); 324 + return -EINVAL; 325 + } 326 + #endif 327 + 328 + tmp = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1); 329 + if (tmp->type != ACPI_TYPE_INTEGER) { 330 + dev_warn(dev, "Invalid type (limit1): %d\n", tmp->type); 331 + return -EINVAL; 332 + } 333 + 334 + tmp = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2); 335 + if (tmp->type != ACPI_TYPE_INTEGER) { 336 + dev_warn(dev, "Invalid type (limit2): %d\n", tmp->type); 337 + return -EINVAL; 338 + } 339 + 340 + tmp = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE); 341 + if (tmp->type != ACPI_TYPE_INTEGER) { 342 + dev_warn(dev, "Invalid type (enable): %d\n", tmp->type); 343 + return -EINVAL; 344 + } 345 + 346 + atk_print_sensor(data, obj); 347 + 348 + return 0; 349 + } 350 + 351 + static char const *atk_sensor_type(union acpi_object *flags) 352 + { 353 + u64 type = flags->integer.value & ATK_TYPE_MASK; 354 + char const *what; 355 + 356 + switch (type) { 357 + case HWMON_TYPE_VOLT: 358 + what = "voltage"; 359 + break; 360 + case HWMON_TYPE_TEMP: 361 + what = "temperature"; 362 + break; 363 + case HWMON_TYPE_FAN: 364 + what = "fan"; 365 + break; 366 + default: 367 + what = "unknown"; 368 + break; 369 + } 370 + 371 + return what; 372 + } 373 + 374 + static void atk_print_sensor(struct atk_data *data, union acpi_object *obj) 375 + { 376 + #ifdef DEBUG 377 + struct device *dev = &data->acpi_dev->dev; 378 + union acpi_object *flags; 379 + union acpi_object *name; 380 + union acpi_object *limit1; 381 + union acpi_object *limit2; 382 + union acpi_object *enable; 383 + char const *what; 384 + 385 + flags = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS); 386 + name = atk_get_pack_member(data, obj, HWMON_PACK_NAME); 387 + limit1 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1); 388 + limit2 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2); 389 + enable = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE); 390 + 391 + what = atk_sensor_type(flags); 392 + 393 + dev_dbg(dev, "%s: %#llx %s [%llu-%llu] %s\n", what, 394 + flags->integer.value, 395 + name->string.pointer, 396 + limit1->integer.value, limit2->integer.value, 397 + enable->integer.value ? "enabled" : "disabled"); 398 + #endif 399 + } 400 + 401 + static int atk_read_value_old(struct atk_sensor_data *sensor, u64 *value) 402 + { 403 + struct atk_data *data = sensor->data; 404 + struct device *dev = &data->acpi_dev->dev; 405 + struct acpi_object_list params; 406 + union acpi_object id; 407 + acpi_status status; 408 + acpi_handle method; 409 + 410 + switch (sensor->type) { 411 + case HWMON_TYPE_VOLT: 412 + method = data->rvlt_handle; 413 + break; 414 + case HWMON_TYPE_TEMP: 415 + method = data->rtmp_handle; 416 + break; 417 + case HWMON_TYPE_FAN: 418 + method = data->rfan_handle; 419 + break; 420 + default: 421 + return -EINVAL; 422 + } 423 + 424 + id.type = ACPI_TYPE_INTEGER; 425 + id.integer.value = sensor->id; 426 + 427 + params.count = 1; 428 + params.pointer = &id; 429 + 430 + status = acpi_evaluate_integer(method, NULL, &params, value); 431 + if (status != AE_OK) { 432 + dev_warn(dev, "%s: ACPI exception: %s\n", __func__, 433 + acpi_format_exception(status)); 434 + return -EIO; 435 + } 436 + 437 + return 0; 438 + } 439 + 440 + static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value) 441 + { 442 + struct atk_data *data = sensor->data; 443 + struct device *dev = &data->acpi_dev->dev; 444 + struct acpi_object_list params; 445 + struct acpi_buffer ret; 446 + union acpi_object id; 447 + struct atk_acpi_buffer_u64 tmp; 448 + acpi_status status; 449 + 450 + id.type = ACPI_TYPE_INTEGER; 451 + id.integer.value = sensor->id; 452 + 453 + params.count = 1; 454 + params.pointer = &id; 455 + 456 + tmp.buf.type = ACPI_TYPE_BUFFER; 457 + tmp.buf.buffer.pointer = (u8 *)&tmp.value; 458 + tmp.buf.buffer.length = sizeof(u64); 459 + ret.length = sizeof(tmp); 460 + ret.pointer = &tmp; 461 + 462 + status = acpi_evaluate_object_typed(data->read_handle, NULL, &params, 463 + &ret, ACPI_TYPE_BUFFER); 464 + if (status != AE_OK) { 465 + dev_warn(dev, "%s: ACPI exception: %s\n", __func__, 466 + acpi_format_exception(status)); 467 + return -EIO; 468 + } 469 + 470 + /* Return buffer format: 471 + * [0-3] "value" is valid flag 472 + * [4-7] value 473 + */ 474 + if (!(tmp.value & 0xffffffff)) { 475 + /* The reading is not valid, possible causes: 476 + * - sensor failure 477 + * - enumeration was FUBAR (and we didn't notice) 478 + */ 479 + dev_info(dev, "Failure: %#llx\n", tmp.value); 480 + return -EIO; 481 + } 482 + 483 + *value = (tmp.value & 0xffffffff00000000ULL) >> 32; 484 + 485 + return 0; 486 + } 487 + 488 + static int atk_read_value(struct atk_sensor_data *sensor, u64 *value) 489 + { 490 + int err; 491 + 492 + if (!sensor->is_valid || 493 + time_after(jiffies, sensor->last_updated + CACHE_TIME)) { 494 + if (sensor->data->old_interface) 495 + err = atk_read_value_old(sensor, value); 496 + else 497 + err = atk_read_value_new(sensor, value); 498 + 499 + sensor->is_valid = true; 500 + sensor->last_updated = jiffies; 501 + sensor->cached_value = *value; 502 + } else { 503 + *value = sensor->cached_value; 504 + err = 0; 505 + } 506 + 507 + return err; 508 + } 509 + 510 + static int atk_add_sensor(struct atk_data *data, union acpi_object *obj) 511 + { 512 + struct device *dev = &data->acpi_dev->dev; 513 + union acpi_object *flags; 514 + union acpi_object *name; 515 + union acpi_object *limit1; 516 + union acpi_object *limit2; 517 + union acpi_object *enable; 518 + struct atk_sensor_data *sensor; 519 + char const *base_name; 520 + char const *limit1_name; 521 + char const *limit2_name; 522 + u64 type; 523 + int err; 524 + int *num; 525 + int start; 526 + 527 + if (obj->type != ACPI_TYPE_PACKAGE) { 528 + /* wft is this? */ 529 + dev_warn(dev, "Unknown type for ACPI object: (%d)\n", 530 + obj->type); 531 + return -EINVAL; 532 + } 533 + 534 + err = validate_hwmon_pack(data, obj); 535 + if (err) 536 + return err; 537 + 538 + /* Ok, we have a valid hwmon package */ 539 + type = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS)->integer.value 540 + & ATK_TYPE_MASK; 541 + 542 + switch (type) { 543 + case HWMON_TYPE_VOLT: 544 + base_name = "in"; 545 + limit1_name = "min"; 546 + limit2_name = "max"; 547 + num = &data->voltage_count; 548 + start = 0; 549 + break; 550 + case HWMON_TYPE_TEMP: 551 + base_name = "temp"; 552 + limit1_name = "max"; 553 + limit2_name = "crit"; 554 + num = &data->temperature_count; 555 + start = 1; 556 + break; 557 + case HWMON_TYPE_FAN: 558 + base_name = "fan"; 559 + limit1_name = "min"; 560 + limit2_name = "max"; 561 + num = &data->fan_count; 562 + start = 1; 563 + break; 564 + default: 565 + dev_warn(dev, "Unknown sensor type: %#llx\n", type); 566 + return -EINVAL; 567 + } 568 + 569 + enable = atk_get_pack_member(data, obj, HWMON_PACK_ENABLE); 570 + if (!enable->integer.value) 571 + /* sensor is disabled */ 572 + return 0; 573 + 574 + flags = atk_get_pack_member(data, obj, HWMON_PACK_FLAGS); 575 + name = atk_get_pack_member(data, obj, HWMON_PACK_NAME); 576 + limit1 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT1); 577 + limit2 = atk_get_pack_member(data, obj, HWMON_PACK_LIMIT2); 578 + 579 + sensor = kzalloc(sizeof(*sensor), GFP_KERNEL); 580 + if (!sensor) 581 + return -ENOMEM; 582 + 583 + sensor->acpi_name = kstrdup(name->string.pointer, GFP_KERNEL); 584 + if (!sensor->acpi_name) { 585 + err = -ENOMEM; 586 + goto out; 587 + } 588 + 589 + INIT_LIST_HEAD(&sensor->list); 590 + sensor->type = type; 591 + sensor->data = data; 592 + sensor->id = flags->integer.value; 593 + sensor->limit1 = limit1->integer.value; 594 + sensor->limit2 = limit2->integer.value; 595 + 596 + snprintf(sensor->input_attr_name, ATTR_NAME_SIZE, 597 + "%s%d_input", base_name, start + *num); 598 + atk_init_attribute(&sensor->input_attr, 599 + sensor->input_attr_name, 600 + atk_input_show); 601 + 602 + snprintf(sensor->label_attr_name, ATTR_NAME_SIZE, 603 + "%s%d_label", base_name, start + *num); 604 + atk_init_attribute(&sensor->label_attr, 605 + sensor->label_attr_name, 606 + atk_label_show); 607 + 608 + snprintf(sensor->limit1_attr_name, ATTR_NAME_SIZE, 609 + "%s%d_%s", base_name, start + *num, limit1_name); 610 + atk_init_attribute(&sensor->limit1_attr, 611 + sensor->limit1_attr_name, 612 + atk_limit1_show); 613 + 614 + snprintf(sensor->limit2_attr_name, ATTR_NAME_SIZE, 615 + "%s%d_%s", base_name, start + *num, limit2_name); 616 + atk_init_attribute(&sensor->limit2_attr, 617 + sensor->limit2_attr_name, 618 + atk_limit2_show); 619 + 620 + list_add(&sensor->list, &data->sensor_list); 621 + (*num)++; 622 + 623 + return 1; 624 + out: 625 + kfree(sensor->acpi_name); 626 + kfree(sensor); 627 + return err; 628 + } 629 + 630 + static int atk_enumerate_old_hwmon(struct atk_data *data) 631 + { 632 + struct device *dev = &data->acpi_dev->dev; 633 + struct acpi_buffer buf; 634 + union acpi_object *pack; 635 + acpi_status status; 636 + int i, ret; 637 + int count = 0; 638 + 639 + /* Voltages */ 640 + buf.length = ACPI_ALLOCATE_BUFFER; 641 + status = acpi_evaluate_object_typed(data->atk_handle, 642 + METHOD_OLD_ENUM_VLT, NULL, &buf, ACPI_TYPE_PACKAGE); 643 + if (status != AE_OK) { 644 + dev_warn(dev, METHOD_OLD_ENUM_VLT ": ACPI exception: %s\n", 645 + acpi_format_exception(status)); 646 + 647 + return -ENODEV; 648 + } 649 + 650 + pack = buf.pointer; 651 + for (i = 1; i < pack->package.count; i++) { 652 + union acpi_object *obj = &pack->package.elements[i]; 653 + 654 + ret = atk_add_sensor(data, obj); 655 + if (ret > 0) 656 + count++; 657 + } 658 + ACPI_FREE(buf.pointer); 659 + 660 + /* Temperatures */ 661 + buf.length = ACPI_ALLOCATE_BUFFER; 662 + status = acpi_evaluate_object_typed(data->atk_handle, 663 + METHOD_OLD_ENUM_TMP, NULL, &buf, ACPI_TYPE_PACKAGE); 664 + if (status != AE_OK) { 665 + dev_warn(dev, METHOD_OLD_ENUM_TMP ": ACPI exception: %s\n", 666 + acpi_format_exception(status)); 667 + 668 + ret = -ENODEV; 669 + goto cleanup; 670 + } 671 + 672 + pack = buf.pointer; 673 + for (i = 1; i < pack->package.count; i++) { 674 + union acpi_object *obj = &pack->package.elements[i]; 675 + 676 + ret = atk_add_sensor(data, obj); 677 + if (ret > 0) 678 + count++; 679 + } 680 + ACPI_FREE(buf.pointer); 681 + 682 + /* Fans */ 683 + buf.length = ACPI_ALLOCATE_BUFFER; 684 + status = acpi_evaluate_object_typed(data->atk_handle, 685 + METHOD_OLD_ENUM_FAN, NULL, &buf, ACPI_TYPE_PACKAGE); 686 + if (status != AE_OK) { 687 + dev_warn(dev, METHOD_OLD_ENUM_FAN ": ACPI exception: %s\n", 688 + acpi_format_exception(status)); 689 + 690 + ret = -ENODEV; 691 + goto cleanup; 692 + } 693 + 694 + pack = buf.pointer; 695 + for (i = 1; i < pack->package.count; i++) { 696 + union acpi_object *obj = &pack->package.elements[i]; 697 + 698 + ret = atk_add_sensor(data, obj); 699 + if (ret > 0) 700 + count++; 701 + } 702 + ACPI_FREE(buf.pointer); 703 + 704 + return count; 705 + cleanup: 706 + atk_free_sensors(data); 707 + return ret; 708 + } 709 + 710 + static int atk_enumerate_new_hwmon(struct atk_data *data) 711 + { 712 + struct device *dev = &data->acpi_dev->dev; 713 + struct acpi_buffer buf; 714 + acpi_status ret; 715 + struct acpi_object_list params; 716 + union acpi_object id; 717 + union acpi_object *pack; 718 + int err; 719 + int i; 720 + 721 + dev_dbg(dev, "Enumerating hwmon sensors\n"); 722 + 723 + id.type = ACPI_TYPE_INTEGER; 724 + id.integer.value = ATK_MUX_HWMON; 725 + params.count = 1; 726 + params.pointer = &id; 727 + 728 + buf.length = ACPI_ALLOCATE_BUFFER; 729 + ret = acpi_evaluate_object_typed(data->enumerate_handle, NULL, &params, 730 + &buf, ACPI_TYPE_PACKAGE); 731 + if (ret != AE_OK) { 732 + dev_warn(dev, METHOD_ENUMERATE ": ACPI exception: %s\n", 733 + acpi_format_exception(ret)); 734 + return -ENODEV; 735 + } 736 + 737 + /* Result must be a package */ 738 + pack = buf.pointer; 739 + 740 + if (pack->package.count < 1) { 741 + dev_dbg(dev, "%s: hwmon package is too small: %d\n", __func__, 742 + pack->package.count); 743 + err = -EINVAL; 744 + goto out; 745 + } 746 + 747 + for (i = 0; i < pack->package.count; i++) { 748 + union acpi_object *obj = &pack->package.elements[i]; 749 + 750 + atk_add_sensor(data, obj); 751 + } 752 + 753 + err = data->voltage_count + data->temperature_count + data->fan_count; 754 + 755 + out: 756 + ACPI_FREE(buf.pointer); 757 + return err; 758 + } 759 + 760 + static int atk_create_files(struct atk_data *data) 761 + { 762 + struct atk_sensor_data *s; 763 + int err; 764 + 765 + list_for_each_entry(s, &data->sensor_list, list) { 766 + err = device_create_file(data->hwmon_dev, &s->input_attr); 767 + if (err) 768 + return err; 769 + err = device_create_file(data->hwmon_dev, &s->label_attr); 770 + if (err) 771 + return err; 772 + err = device_create_file(data->hwmon_dev, &s->limit1_attr); 773 + if (err) 774 + return err; 775 + err = device_create_file(data->hwmon_dev, &s->limit2_attr); 776 + if (err) 777 + return err; 778 + } 779 + 780 + err = device_create_file(data->hwmon_dev, &atk_name_attr); 781 + 782 + return err; 783 + } 784 + 785 + static void atk_remove_files(struct atk_data *data) 786 + { 787 + struct atk_sensor_data *s; 788 + 789 + list_for_each_entry(s, &data->sensor_list, list) { 790 + device_remove_file(data->hwmon_dev, &s->input_attr); 791 + device_remove_file(data->hwmon_dev, &s->label_attr); 792 + device_remove_file(data->hwmon_dev, &s->limit1_attr); 793 + device_remove_file(data->hwmon_dev, &s->limit2_attr); 794 + } 795 + device_remove_file(data->hwmon_dev, &atk_name_attr); 796 + } 797 + 798 + static void atk_free_sensors(struct atk_data *data) 799 + { 800 + struct list_head *head = &data->sensor_list; 801 + struct atk_sensor_data *s, *tmp; 802 + 803 + list_for_each_entry_safe(s, tmp, head, list) { 804 + kfree(s->acpi_name); 805 + kfree(s); 806 + } 807 + } 808 + 809 + static int atk_register_hwmon(struct atk_data *data) 810 + { 811 + struct device *dev = &data->acpi_dev->dev; 812 + int err; 813 + 814 + dev_dbg(dev, "registering hwmon device\n"); 815 + data->hwmon_dev = hwmon_device_register(dev); 816 + if (IS_ERR(data->hwmon_dev)) 817 + return PTR_ERR(data->hwmon_dev); 818 + 819 + dev_dbg(dev, "populating sysfs directory\n"); 820 + err = atk_create_files(data); 821 + if (err) 822 + goto remove; 823 + 824 + return 0; 825 + remove: 826 + /* Cleanup the registered files */ 827 + atk_remove_files(data); 828 + hwmon_device_unregister(data->hwmon_dev); 829 + return err; 830 + } 831 + 832 + static int atk_check_old_if(struct atk_data *data) 833 + { 834 + struct device *dev = &data->acpi_dev->dev; 835 + acpi_handle ret; 836 + acpi_status status; 837 + 838 + /* RTMP: read temperature */ 839 + status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_TMP, &ret); 840 + if (status != AE_OK) { 841 + dev_dbg(dev, "method " METHOD_OLD_READ_TMP " not found: %s\n", 842 + acpi_format_exception(status)); 843 + return -ENODEV; 844 + } 845 + data->rtmp_handle = ret; 846 + 847 + /* RVLT: read voltage */ 848 + status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_VLT, &ret); 849 + if (status != AE_OK) { 850 + dev_dbg(dev, "method " METHOD_OLD_READ_VLT " not found: %s\n", 851 + acpi_format_exception(status)); 852 + return -ENODEV; 853 + } 854 + data->rvlt_handle = ret; 855 + 856 + /* RFAN: read fan status */ 857 + status = acpi_get_handle(data->atk_handle, METHOD_OLD_READ_FAN, &ret); 858 + if (status != AE_OK) { 859 + dev_dbg(dev, "method " METHOD_OLD_READ_FAN " not found: %s\n", 860 + acpi_format_exception(status)); 861 + return -ENODEV; 862 + } 863 + data->rfan_handle = ret; 864 + 865 + return 0; 866 + } 867 + 868 + static int atk_check_new_if(struct atk_data *data) 869 + { 870 + struct device *dev = &data->acpi_dev->dev; 871 + acpi_handle ret; 872 + acpi_status status; 873 + 874 + /* Enumeration */ 875 + status = acpi_get_handle(data->atk_handle, METHOD_ENUMERATE, &ret); 876 + if (status != AE_OK) { 877 + dev_dbg(dev, "method " METHOD_ENUMERATE " not found: %s\n", 878 + acpi_format_exception(status)); 879 + return -ENODEV; 880 + } 881 + data->enumerate_handle = ret; 882 + 883 + /* De-multiplexer (read) */ 884 + status = acpi_get_handle(data->atk_handle, METHOD_READ, &ret); 885 + if (status != AE_OK) { 886 + dev_dbg(dev, "method " METHOD_READ " not found: %s\n", 887 + acpi_format_exception(status)); 888 + return -ENODEV; 889 + } 890 + data->read_handle = ret; 891 + 892 + return 0; 893 + } 894 + 895 + static int atk_add(struct acpi_device *device) 896 + { 897 + acpi_status ret; 898 + int err; 899 + struct acpi_buffer buf; 900 + union acpi_object *obj; 901 + struct atk_data *data; 902 + 903 + dev_dbg(&device->dev, "adding...\n"); 904 + 905 + data = kzalloc(sizeof(*data), GFP_KERNEL); 906 + if (!data) 907 + return -ENOMEM; 908 + 909 + data->acpi_dev = device; 910 + data->atk_handle = device->handle; 911 + INIT_LIST_HEAD(&data->sensor_list); 912 + 913 + buf.length = ACPI_ALLOCATE_BUFFER; 914 + ret = acpi_evaluate_object_typed(data->atk_handle, BOARD_ID, NULL, 915 + &buf, ACPI_TYPE_PACKAGE); 916 + if (ret != AE_OK) { 917 + dev_dbg(&device->dev, "atk: method MBIF not found\n"); 918 + err = -ENODEV; 919 + goto out; 920 + } 921 + 922 + obj = buf.pointer; 923 + if (obj->package.count >= 2 && 924 + obj->package.elements[1].type == ACPI_TYPE_STRING) { 925 + dev_dbg(&device->dev, "board ID = %s\n", 926 + obj->package.elements[1].string.pointer); 927 + } 928 + ACPI_FREE(buf.pointer); 929 + 930 + /* Check for hwmon methods: first check "old" style methods; note that 931 + * both may be present: in this case we stick to the old interface; 932 + * analysis of multiple DSDTs indicates that when both interfaces 933 + * are present the new one (GGRP/GITM) is not functional. 934 + */ 935 + err = atk_check_old_if(data); 936 + if (!err) { 937 + dev_dbg(&device->dev, "Using old hwmon interface\n"); 938 + data->old_interface = true; 939 + } else { 940 + err = atk_check_new_if(data); 941 + if (err) 942 + goto out; 943 + 944 + dev_dbg(&device->dev, "Using new hwmon interface\n"); 945 + data->old_interface = false; 946 + } 947 + 948 + if (data->old_interface) 949 + err = atk_enumerate_old_hwmon(data); 950 + else 951 + err = atk_enumerate_new_hwmon(data); 952 + if (err < 0) 953 + goto out; 954 + if (err == 0) { 955 + dev_info(&device->dev, 956 + "No usable sensor detected, bailing out\n"); 957 + err = -ENODEV; 958 + goto out; 959 + } 960 + 961 + err = atk_register_hwmon(data); 962 + if (err) 963 + goto cleanup; 964 + 965 + device->driver_data = data; 966 + return 0; 967 + cleanup: 968 + atk_free_sensors(data); 969 + out: 970 + kfree(data); 971 + return err; 972 + } 973 + 974 + static int atk_remove(struct acpi_device *device, int type) 975 + { 976 + struct atk_data *data = device->driver_data; 977 + dev_dbg(&device->dev, "removing...\n"); 978 + 979 + device->driver_data = NULL; 980 + 981 + atk_remove_files(data); 982 + atk_free_sensors(data); 983 + hwmon_device_unregister(data->hwmon_dev); 984 + 985 + kfree(data); 986 + 987 + return 0; 988 + } 989 + 990 + static int __init atk0110_init(void) 991 + { 992 + int ret; 993 + 994 + ret = acpi_bus_register_driver(&atk_driver); 995 + if (ret) 996 + pr_info("atk: acpi_bus_register_driver failed: %d\n", ret); 997 + 998 + return ret; 999 + } 1000 + 1001 + static void __exit atk0110_exit(void) 1002 + { 1003 + acpi_bus_unregister_driver(&atk_driver); 1004 + } 1005 + 1006 + module_init(atk0110_init); 1007 + module_exit(atk0110_exit); 1008 + 1009 + MODULE_LICENSE("GPL");
+47 -65
drivers/hwmon/lm95241.c
··· 87 87 (val_h)) * 1000 + (val_l) * 1000 / 256) 88 88 89 89 /* Functions declaration */ 90 - static int lm95241_attach_adapter(struct i2c_adapter *adapter); 91 - static int lm95241_detect(struct i2c_adapter *adapter, int address, 92 - int kind); 93 90 static void lm95241_init_client(struct i2c_client *client); 94 - static int lm95241_detach_client(struct i2c_client *client); 95 91 static struct lm95241_data *lm95241_update_device(struct device *dev); 96 - 97 - /* Driver data (common to all clients) */ 98 - static struct i2c_driver lm95241_driver = { 99 - .driver = { 100 - .name = "lm95241", 101 - }, 102 - .attach_adapter = lm95241_attach_adapter, 103 - .detach_client = lm95241_detach_client, 104 - }; 105 92 106 93 /* Client data (each client gets its own) */ 107 94 struct lm95241_data { 108 - struct i2c_client client; 109 95 struct device *hwmon_dev; 110 96 struct mutex update_lock; 111 97 unsigned long last_updated, rate; /* in jiffies */ ··· 309 323 .attrs = lm95241_attributes, 310 324 }; 311 325 312 - /* Init/exit code */ 313 - static int lm95241_attach_adapter(struct i2c_adapter *adapter) 326 + /* Return 0 if detection is successful, -ENODEV otherwise */ 327 + static int lm95241_detect(struct i2c_client *new_client, int kind, 328 + struct i2c_board_info *info) 314 329 { 315 - if (!(adapter->class & I2C_CLASS_HWMON)) 316 - return 0; 317 - return i2c_probe(adapter, &addr_data, lm95241_detect); 318 - } 319 - 320 - /* 321 - * The following function does more than just detection. If detection 322 - * succeeds, it also registers the new chip. 323 - */ 324 - static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind) 325 - { 326 - struct i2c_client *new_client; 327 - struct lm95241_data *data; 328 - int err = 0; 330 + struct i2c_adapter *adapter = new_client->adapter; 331 + int address = new_client->addr; 329 332 const char *name = ""; 330 333 331 334 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 332 - goto exit; 333 - 334 - data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL); 335 - if (!data) { 336 - err = -ENOMEM; 337 - goto exit; 338 - } 339 - 340 - /* The common I2C client data is placed right before the 341 - LM95241-specific data. */ 342 - new_client = &data->client; 343 - i2c_set_clientdata(new_client, data); 344 - new_client->addr = address; 345 - new_client->adapter = adapter; 346 - new_client->driver = &lm95241_driver; 347 - new_client->flags = 0; 335 + return -ENODEV; 348 336 349 337 /* 350 338 * Now we do the remaining detection. A negative kind means that ··· 338 378 dev_dbg(&adapter->dev, 339 379 "LM95241 detection failed at 0x%02x.\n", 340 380 address); 341 - goto exit_free; 381 + return -ENODEV; 342 382 } 343 383 } 344 384 ··· 352 392 353 393 if (kind <= 0) { /* identification failed */ 354 394 dev_info(&adapter->dev, "Unsupported chip\n"); 355 - goto exit_free; 395 + return -ENODEV; 356 396 } 357 397 } 358 398 } 359 399 400 + /* Fill the i2c board info */ 360 401 if (kind == lm95241) 361 402 name = "lm95241"; 403 + strlcpy(info->type, name, I2C_NAME_SIZE); 404 + return 0; 405 + } 362 406 363 - /* We can fill in the remaining client fields */ 364 - strlcpy(new_client->name, name, I2C_NAME_SIZE); 365 - data->valid = 0; 407 + static int lm95241_probe(struct i2c_client *new_client, 408 + const struct i2c_device_id *id) 409 + { 410 + struct lm95241_data *data; 411 + int err; 412 + 413 + data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL); 414 + if (!data) { 415 + err = -ENOMEM; 416 + goto exit; 417 + } 418 + 419 + i2c_set_clientdata(new_client, data); 366 420 mutex_init(&data->update_lock); 367 - 368 - /* Tell the I2C layer a new client has arrived */ 369 - err = i2c_attach_client(new_client); 370 - if (err) 371 - goto exit_free; 372 421 373 422 /* Initialize the LM95241 chip */ 374 423 lm95241_init_client(new_client); ··· 385 416 /* Register sysfs hooks */ 386 417 err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group); 387 418 if (err) 388 - goto exit_detach; 419 + goto exit_free; 389 420 390 421 data->hwmon_dev = hwmon_device_register(&new_client->dev); 391 422 if (IS_ERR(data->hwmon_dev)) { ··· 397 428 398 429 exit_remove_files: 399 430 sysfs_remove_group(&new_client->dev.kobj, &lm95241_group); 400 - exit_detach: 401 - i2c_detach_client(new_client); 402 431 exit_free: 403 432 kfree(data); 404 433 exit: ··· 423 456 data->model); 424 457 } 425 458 426 - static int lm95241_detach_client(struct i2c_client *client) 459 + static int lm95241_remove(struct i2c_client *client) 427 460 { 428 461 struct lm95241_data *data = i2c_get_clientdata(client); 429 - int err; 430 462 431 463 hwmon_device_unregister(data->hwmon_dev); 432 464 sysfs_remove_group(&client->dev.kobj, &lm95241_group); 433 465 434 - err = i2c_detach_client(client); 435 - if (err) 436 - return err; 437 - 466 + i2c_set_clientdata(client, NULL); 438 467 kfree(data); 439 468 return 0; 440 469 } ··· 471 508 472 509 return data; 473 510 } 511 + 512 + /* Driver data (common to all clients) */ 513 + static const struct i2c_device_id lm95241_id[] = { 514 + { "lm95241", lm95241 }, 515 + { } 516 + }; 517 + MODULE_DEVICE_TABLE(i2c, lm95241_id); 518 + 519 + static struct i2c_driver lm95241_driver = { 520 + .class = I2C_CLASS_HWMON, 521 + .driver = { 522 + .name = "lm95241", 523 + }, 524 + .probe = lm95241_probe, 525 + .remove = lm95241_remove, 526 + .id_table = lm95241_id, 527 + .detect = lm95241_detect, 528 + .address_data = &addr_data, 529 + }; 474 530 475 531 static int __init sensors_lm95241_init(void) 476 532 {
-2
include/acpi/acpixf.h
··· 191 191 struct acpi_object_list *parameter_objects, 192 192 struct acpi_buffer *return_object_buffer); 193 193 194 - #ifdef ACPI_FUTURE_USAGE 195 194 acpi_status 196 195 acpi_evaluate_object_typed(acpi_handle object, 197 196 acpi_string pathname, 198 197 struct acpi_object_list *external_params, 199 198 struct acpi_buffer *return_buffer, 200 199 acpi_object_type return_type); 201 - #endif 202 200 203 201 acpi_status 204 202 acpi_get_object_info(acpi_handle handle, struct acpi_buffer *return_buffer);