aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorLuca Tettamanti <kronos.it@gmail.com>2009-10-09 14:35:18 -0400
committerJean Delvare <khali@linux-fr.org>2009-10-09 14:35:18 -0400
commit18e255558574c5663c9d72fe82c099d2115aee55 (patch)
tree395c31badbb72a7da87871512b3c16eba9f07d11 /drivers/hwmon
parentcb0f1a1e77e4280c3138047ad5c16d88320a1fde (diff)
hwmon: (asus_atk0110) Refactor the code
Refactor the code of the new style interface around GGRP (enumeration) and GITM (read) helpers to mimic ASL code. Also switch the read path to use dynamic buffers (handled by ACPI core) since ASUS expanded the return buffer (ASBF) in newer boards (e.g. P7P55D). Signed-off-by: Luca Tettamanti <kronos.it@gmail.com> Tested-by: Robert Hancock <hancockrwd@gmail.com> Tested-by: Thomas Backlund <tmb@mandriva.org> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/asus_atk0110.c158
1 files changed, 102 insertions, 56 deletions
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index fe4fa29c9219..19f3fd32e10a 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -129,9 +129,22 @@ struct atk_sensor_data {
129 char const *acpi_name; 129 char const *acpi_name;
130}; 130};
131 131
132struct atk_acpi_buffer_u64 { 132/* Return buffer format:
133 union acpi_object buf; 133 * [0-3] "value" is valid flag
134 u64 value; 134 * [4-7] value
135 * [8- ] unknown stuff on newer mobos
136 */
137struct atk_acpi_ret_buffer {
138 u32 flags;
139 u32 value;
140 u8 data[];
141};
142
143/* Input buffer used for GITM and SITM methods */
144struct atk_acpi_input_buf {
145 u32 id;
146 u32 param1;
147 u32 param2;
135}; 148};
136 149
137static int atk_add(struct acpi_device *device); 150static int atk_add(struct acpi_device *device);
@@ -439,52 +452,110 @@ static int atk_read_value_old(struct atk_sensor_data *sensor, u64 *value)
439 return 0; 452 return 0;
440} 453}
441 454
442static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value) 455static union acpi_object *atk_ggrp(struct atk_data *data, u16 mux)
443{ 456{
444 struct atk_data *data = sensor->data;
445 struct device *dev = &data->acpi_dev->dev; 457 struct device *dev = &data->acpi_dev->dev;
458 struct acpi_buffer buf;
459 acpi_status ret;
446 struct acpi_object_list params; 460 struct acpi_object_list params;
447 struct acpi_buffer ret;
448 union acpi_object id; 461 union acpi_object id;
449 struct atk_acpi_buffer_u64 tmp; 462 union acpi_object *pack;
450 acpi_status status;
451 463
452 id.type = ACPI_TYPE_INTEGER; 464 id.type = ACPI_TYPE_INTEGER;
453 id.integer.value = sensor->id; 465 id.integer.value = mux;
454
455 params.count = 1; 466 params.count = 1;
456 params.pointer = &id; 467 params.pointer = &id;
457 468
458 tmp.buf.type = ACPI_TYPE_BUFFER; 469 buf.length = ACPI_ALLOCATE_BUFFER;
459 tmp.buf.buffer.pointer = (u8 *)&tmp.value; 470 ret = acpi_evaluate_object(data->enumerate_handle, NULL, &params, &buf);
460 tmp.buf.buffer.length = sizeof(u64); 471 if (ret != AE_OK) {
461 ret.length = sizeof(tmp); 472 dev_err(dev, "GGRP[%#x] ACPI exception: %s\n", mux,
462 ret.pointer = &tmp; 473 acpi_format_exception(ret));
474 return ERR_PTR(-EIO);
475 }
476 pack = buf.pointer;
477 if (pack->type != ACPI_TYPE_PACKAGE) {
478 /* Execution was successful, but the id was not found */
479 ACPI_FREE(pack);
480 return ERR_PTR(-ENOENT);
481 }
463 482
483 if (pack->package.count < 1) {
484 dev_err(dev, "GGRP[%#x] package is too small\n", mux);
485 ACPI_FREE(pack);
486 return ERR_PTR(-EIO);
487 }
488 return pack;
489}
490
491static union acpi_object *atk_gitm(struct atk_data *data, u64 id)
492{
493 struct device *dev = &data->acpi_dev->dev;
494 struct atk_acpi_input_buf buf;
495 union acpi_object tmp;
496 struct acpi_object_list params;
497 struct acpi_buffer ret;
498 union acpi_object *obj;
499 acpi_status status;
500
501 buf.id = id;
502 buf.param1 = 0;
503 buf.param2 = 0;
504
505 tmp.type = ACPI_TYPE_BUFFER;
506 tmp.buffer.pointer = (u8 *)&buf;
507 tmp.buffer.length = sizeof(buf);
508
509 params.count = 1;
510 params.pointer = (void *)&tmp;
511
512 ret.length = ACPI_ALLOCATE_BUFFER;
464 status = acpi_evaluate_object_typed(data->read_handle, NULL, &params, 513 status = acpi_evaluate_object_typed(data->read_handle, NULL, &params,
465 &ret, ACPI_TYPE_BUFFER); 514 &ret, ACPI_TYPE_BUFFER);
466 if (status != AE_OK) { 515 if (status != AE_OK) {
467 dev_warn(dev, "%s: ACPI exception: %s\n", __func__, 516 dev_warn(dev, "GITM[%#llx] ACPI exception: %s\n", id,
468 acpi_format_exception(status)); 517 acpi_format_exception(status));
469 return -EIO; 518 return ERR_PTR(-EIO);
519 }
520 obj = ret.pointer;
521
522 /* Sanity check */
523 if (obj->buffer.length < 8) {
524 dev_warn(dev, "Unexpected ASBF length: %u\n",
525 obj->buffer.length);
526 ACPI_FREE(obj);
527 return ERR_PTR(-EIO);
470 } 528 }
529 return obj;
530}
471 531
472 /* Return buffer format: 532static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
473 * [0-3] "value" is valid flag 533{
474 * [4-7] value 534 struct atk_data *data = sensor->data;
475 */ 535 struct device *dev = &data->acpi_dev->dev;
476 if (!(tmp.value & 0xffffffff)) { 536 union acpi_object *obj;
537 struct atk_acpi_ret_buffer *buf;
538 int err = 0;
539
540 obj = atk_gitm(data, sensor->id);
541 if (IS_ERR(obj))
542 return PTR_ERR(obj);
543
544 buf = (struct atk_acpi_ret_buffer *)obj->buffer.pointer;
545 if (buf->flags == 0) {
477 /* The reading is not valid, possible causes: 546 /* The reading is not valid, possible causes:
478 * - sensor failure 547 * - sensor failure
479 * - enumeration was FUBAR (and we didn't notice) 548 * - enumeration was FUBAR (and we didn't notice)
480 */ 549 */
481 dev_info(dev, "Failure: %#llx\n", tmp.value); 550 dev_warn(dev, "Read failed, sensor = %#llx\n", sensor->id);
482 return -EIO; 551 err = -EIO;
552 goto out;
483 } 553 }
484 554
485 *value = (tmp.value & 0xffffffff00000000ULL) >> 32; 555 *value = buf->value;
486 556out:
487 return 0; 557 ACPI_FREE(obj);
558 return err;
488} 559}
489 560
490static int atk_read_value(struct atk_sensor_data *sensor, u64 *value) 561static int atk_read_value(struct atk_sensor_data *sensor, u64 *value)
@@ -716,39 +787,15 @@ cleanup:
716static int atk_enumerate_new_hwmon(struct atk_data *data) 787static int atk_enumerate_new_hwmon(struct atk_data *data)
717{ 788{
718 struct device *dev = &data->acpi_dev->dev; 789 struct device *dev = &data->acpi_dev->dev;
719 struct acpi_buffer buf;
720 acpi_status ret;
721 struct acpi_object_list params;
722 union acpi_object id;
723 union acpi_object *pack; 790 union acpi_object *pack;
724 int err; 791 int err;
725 int i; 792 int i;
726 793
727 dev_dbg(dev, "Enumerating hwmon sensors\n"); 794 dev_dbg(dev, "Enumerating hwmon sensors\n");
728 795
729 id.type = ACPI_TYPE_INTEGER; 796 pack = atk_ggrp(data, ATK_MUX_HWMON);
730 id.integer.value = ATK_MUX_HWMON; 797 if (IS_ERR(pack))
731 params.count = 1; 798 return PTR_ERR(pack);
732 params.pointer = &id;
733
734 buf.length = ACPI_ALLOCATE_BUFFER;
735 ret = acpi_evaluate_object_typed(data->enumerate_handle, NULL, &params,
736 &buf, ACPI_TYPE_PACKAGE);
737 if (ret != AE_OK) {
738 dev_warn(dev, METHOD_ENUMERATE ": ACPI exception: %s\n",
739 acpi_format_exception(ret));
740 return -ENODEV;
741 }
742
743 /* Result must be a package */
744 pack = buf.pointer;
745
746 if (pack->package.count < 1) {
747 dev_dbg(dev, "%s: hwmon package is too small: %d\n", __func__,
748 pack->package.count);
749 err = -EINVAL;
750 goto out;
751 }
752 799
753 for (i = 0; i < pack->package.count; i++) { 800 for (i = 0; i < pack->package.count; i++) {
754 union acpi_object *obj = &pack->package.elements[i]; 801 union acpi_object *obj = &pack->package.elements[i];
@@ -758,8 +805,7 @@ static int atk_enumerate_new_hwmon(struct atk_data *data)
758 805
759 err = data->voltage_count + data->temperature_count + data->fan_count; 806 err = data->voltage_count + data->temperature_count + data->fan_count;
760 807
761out: 808 ACPI_FREE(pack);
762 ACPI_FREE(buf.pointer);
763 return err; 809 return err;
764} 810}
765 811