diff options
| author | Yuan Mu <ymu@winbond.com.tw> | 2006-02-05 17:24:16 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-23 17:21:53 -0500 |
| commit | 412fec8216bb71ecbe255af702b0daf7ad55a7c4 (patch) | |
| tree | d6995537f0a34932564250a664bb1cd60887a6a8 | |
| parent | 4c537fb287e68b84df685f4730348e83a163367b (diff) | |
[PATCH] w83627ehf: Refactor the sysfs interface
Use dynamic sysfs callbacks and array of attributes to reduce the
w83627ehf driver size.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
| -rw-r--r-- | drivers/hwmon/w83627ehf.c | 206 |
1 files changed, 80 insertions, 126 deletions
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 1affaf15beda..b6bd5685fd38 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | #include <linux/i2c.h> | 42 | #include <linux/i2c.h> |
| 43 | #include <linux/i2c-isa.h> | 43 | #include <linux/i2c-isa.h> |
| 44 | #include <linux/hwmon.h> | 44 | #include <linux/hwmon.h> |
| 45 | #include <linux/hwmon-sysfs.h> | ||
| 45 | #include <linux/err.h> | 46 | #include <linux/err.h> |
| 46 | #include <linux/mutex.h> | 47 | #include <linux/mutex.h> |
| 47 | #include <asm/io.h> | 48 | #include <asm/io.h> |
| @@ -408,9 +409,12 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
| 408 | 409 | ||
| 409 | #define show_fan_reg(reg) \ | 410 | #define show_fan_reg(reg) \ |
| 410 | static ssize_t \ | 411 | static ssize_t \ |
| 411 | show_##reg(struct device *dev, char *buf, int nr) \ | 412 | show_##reg(struct device *dev, struct device_attribute *attr, \ |
| 413 | char *buf) \ | ||
| 412 | { \ | 414 | { \ |
| 413 | struct w83627ehf_data *data = w83627ehf_update_device(dev); \ | 415 | struct w83627ehf_data *data = w83627ehf_update_device(dev); \ |
| 416 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | ||
| 417 | int nr = sensor_attr->index; \ | ||
| 414 | return sprintf(buf, "%d\n", \ | 418 | return sprintf(buf, "%d\n", \ |
| 415 | fan_from_reg(data->reg[nr], \ | 419 | fan_from_reg(data->reg[nr], \ |
| 416 | div_from_reg(data->fan_div[nr]))); \ | 420 | div_from_reg(data->fan_div[nr]))); \ |
| @@ -419,18 +423,23 @@ show_fan_reg(fan); | |||
| 419 | show_fan_reg(fan_min); | 423 | show_fan_reg(fan_min); |
| 420 | 424 | ||
| 421 | static ssize_t | 425 | static ssize_t |
| 422 | show_fan_div(struct device *dev, char *buf, int nr) | 426 | show_fan_div(struct device *dev, struct device_attribute *attr, |
| 427 | char *buf) | ||
| 423 | { | 428 | { |
| 424 | struct w83627ehf_data *data = w83627ehf_update_device(dev); | 429 | struct w83627ehf_data *data = w83627ehf_update_device(dev); |
| 425 | return sprintf(buf, "%u\n", | 430 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); |
| 426 | div_from_reg(data->fan_div[nr])); | 431 | int nr = sensor_attr->index; |
| 432 | return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr])); | ||
| 427 | } | 433 | } |
| 428 | 434 | ||
| 429 | static ssize_t | 435 | static ssize_t |
| 430 | store_fan_min(struct device *dev, const char *buf, size_t count, int nr) | 436 | store_fan_min(struct device *dev, struct device_attribute *attr, |
| 437 | const char *buf, size_t count) | ||
| 431 | { | 438 | { |
| 432 | struct i2c_client *client = to_i2c_client(dev); | 439 | struct i2c_client *client = to_i2c_client(dev); |
| 433 | struct w83627ehf_data *data = i2c_get_clientdata(client); | 440 | struct w83627ehf_data *data = i2c_get_clientdata(client); |
| 441 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
| 442 | int nr = sensor_attr->index; | ||
| 434 | unsigned int val = simple_strtoul(buf, NULL, 10); | 443 | unsigned int val = simple_strtoul(buf, NULL, 10); |
| 435 | unsigned int reg; | 444 | unsigned int reg; |
| 436 | u8 new_div; | 445 | u8 new_div; |
| @@ -488,58 +497,41 @@ store_fan_min(struct device *dev, const char *buf, size_t count, int nr) | |||
| 488 | return count; | 497 | return count; |
| 489 | } | 498 | } |
| 490 | 499 | ||
| 491 | #define sysfs_fan_offset(offset) \ | 500 | static struct sensor_device_attribute sda_fan_input[] = { |
| 492 | static ssize_t \ | 501 | SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), |
| 493 | show_reg_fan_##offset(struct device *dev, struct device_attribute *attr, \ | 502 | SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), |
| 494 | char *buf) \ | 503 | SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2), |
| 495 | { \ | 504 | SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3), |
| 496 | return show_fan(dev, buf, offset-1); \ | 505 | SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4), |
| 497 | } \ | 506 | }; |
| 498 | static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ | ||
| 499 | show_reg_fan_##offset, NULL); | ||
| 500 | 507 | ||
| 501 | #define sysfs_fan_min_offset(offset) \ | 508 | static struct sensor_device_attribute sda_fan_min[] = { |
| 502 | static ssize_t \ | 509 | SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, |
| 503 | show_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \ | 510 | store_fan_min, 0), |
| 504 | char *buf) \ | 511 | SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, |
| 505 | { \ | 512 | store_fan_min, 1), |
| 506 | return show_fan_min(dev, buf, offset-1); \ | 513 | SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, |
| 507 | } \ | 514 | store_fan_min, 2), |
| 508 | static ssize_t \ | 515 | SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, |
| 509 | store_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \ | 516 | store_fan_min, 3), |
| 510 | const char *buf, size_t count) \ | 517 | SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, |
| 511 | { \ | 518 | store_fan_min, 4), |
| 512 | return store_fan_min(dev, buf, count, offset-1); \ | 519 | }; |
| 513 | } \ | ||
| 514 | static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
| 515 | show_reg_fan##offset##_min, \ | ||
| 516 | store_reg_fan##offset##_min); | ||
| 517 | 520 | ||
| 518 | #define sysfs_fan_div_offset(offset) \ | 521 | static struct sensor_device_attribute sda_fan_div[] = { |
| 519 | static ssize_t \ | 522 | SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0), |
| 520 | show_reg_fan##offset##_div(struct device *dev, struct device_attribute *attr, \ | 523 | SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1), |
| 521 | char *buf) \ | 524 | SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2), |
| 522 | { \ | 525 | SENSOR_ATTR(fan4_div, S_IRUGO, show_fan_div, NULL, 3), |
| 523 | return show_fan_div(dev, buf, offset - 1); \ | 526 | SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4), |
| 524 | } \ | 527 | }; |
| 525 | static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \ | 528 | |
| 526 | show_reg_fan##offset##_div, NULL); | 529 | static void device_create_file_fan(struct device *dev, int i) |
| 527 | 530 | { | |
| 528 | sysfs_fan_offset(1); | 531 | device_create_file(dev, &sda_fan_input[i].dev_attr); |
| 529 | sysfs_fan_min_offset(1); | 532 | device_create_file(dev, &sda_fan_div[i].dev_attr); |
| 530 | sysfs_fan_div_offset(1); | 533 | device_create_file(dev, &sda_fan_min[i].dev_attr); |
| 531 | sysfs_fan_offset(2); | 534 | } |
| 532 | sysfs_fan_min_offset(2); | ||
| 533 | sysfs_fan_div_offset(2); | ||
| 534 | sysfs_fan_offset(3); | ||
| 535 | sysfs_fan_min_offset(3); | ||
| 536 | sysfs_fan_div_offset(3); | ||
| 537 | sysfs_fan_offset(4); | ||
| 538 | sysfs_fan_min_offset(4); | ||
| 539 | sysfs_fan_div_offset(4); | ||
| 540 | sysfs_fan_offset(5); | ||
| 541 | sysfs_fan_min_offset(5); | ||
| 542 | sysfs_fan_div_offset(5); | ||
| 543 | 535 | ||
| 544 | #define show_temp1_reg(reg) \ | 536 | #define show_temp1_reg(reg) \ |
| 545 | static ssize_t \ | 537 | static ssize_t \ |
| @@ -572,17 +564,14 @@ store_temp1_##reg(struct device *dev, struct device_attribute *attr, \ | |||
| 572 | store_temp1_reg(OVER, max); | 564 | store_temp1_reg(OVER, max); |
| 573 | store_temp1_reg(HYST, max_hyst); | 565 | store_temp1_reg(HYST, max_hyst); |
| 574 | 566 | ||
| 575 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL); | ||
| 576 | static DEVICE_ATTR(temp1_max, S_IRUGO| S_IWUSR, | ||
| 577 | show_temp1_max, store_temp1_max); | ||
| 578 | static DEVICE_ATTR(temp1_max_hyst, S_IRUGO| S_IWUSR, | ||
| 579 | show_temp1_max_hyst, store_temp1_max_hyst); | ||
| 580 | |||
| 581 | #define show_temp_reg(reg) \ | 567 | #define show_temp_reg(reg) \ |
| 582 | static ssize_t \ | 568 | static ssize_t \ |
| 583 | show_##reg (struct device *dev, char *buf, int nr) \ | 569 | show_##reg(struct device *dev, struct device_attribute *attr, \ |
| 570 | char *buf) \ | ||
| 584 | { \ | 571 | { \ |
| 585 | struct w83627ehf_data *data = w83627ehf_update_device(dev); \ | 572 | struct w83627ehf_data *data = w83627ehf_update_device(dev); \ |
| 573 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | ||
| 574 | int nr = sensor_attr->index; \ | ||
| 586 | return sprintf(buf, "%d\n", \ | 575 | return sprintf(buf, "%d\n", \ |
| 587 | LM75_TEMP_FROM_REG(data->reg[nr])); \ | 576 | LM75_TEMP_FROM_REG(data->reg[nr])); \ |
| 588 | } | 577 | } |
| @@ -592,10 +581,13 @@ show_temp_reg(temp_max_hyst); | |||
| 592 | 581 | ||
| 593 | #define store_temp_reg(REG, reg) \ | 582 | #define store_temp_reg(REG, reg) \ |
| 594 | static ssize_t \ | 583 | static ssize_t \ |
| 595 | store_##reg (struct device *dev, const char *buf, size_t count, int nr) \ | 584 | store_##reg(struct device *dev, struct device_attribute *attr, \ |
| 585 | const char *buf, size_t count) \ | ||
| 596 | { \ | 586 | { \ |
| 597 | struct i2c_client *client = to_i2c_client(dev); \ | 587 | struct i2c_client *client = to_i2c_client(dev); \ |
| 598 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ | 588 | struct w83627ehf_data *data = i2c_get_clientdata(client); \ |
| 589 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \ | ||
| 590 | int nr = sensor_attr->index; \ | ||
| 599 | u32 val = simple_strtoul(buf, NULL, 10); \ | 591 | u32 val = simple_strtoul(buf, NULL, 10); \ |
| 600 | \ | 592 | \ |
| 601 | mutex_lock(&data->update_lock); \ | 593 | mutex_lock(&data->update_lock); \ |
| @@ -608,39 +600,23 @@ store_##reg (struct device *dev, const char *buf, size_t count, int nr) \ | |||
| 608 | store_temp_reg(OVER, temp_max); | 600 | store_temp_reg(OVER, temp_max); |
| 609 | store_temp_reg(HYST, temp_max_hyst); | 601 | store_temp_reg(HYST, temp_max_hyst); |
| 610 | 602 | ||
| 611 | #define sysfs_temp_offset(offset) \ | 603 | static struct sensor_device_attribute sda_temp[] = { |
| 612 | static ssize_t \ | 604 | SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0), |
| 613 | show_reg_temp##offset (struct device *dev, struct device_attribute *attr, \ | 605 | SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0), |
| 614 | char *buf) \ | 606 | SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 1), |
| 615 | { \ | 607 | SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1_max, |
| 616 | return show_temp(dev, buf, offset - 2); \ | 608 | store_temp1_max, 0), |
| 617 | } \ | 609 | SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max, |
| 618 | static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ | 610 | store_temp_max, 0), |
| 619 | show_reg_temp##offset, NULL); | 611 | SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max, |
| 620 | 612 | store_temp_max, 1), | |
| 621 | #define sysfs_temp_reg_offset(reg, offset) \ | 613 | SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1_max_hyst, |
| 622 | static ssize_t \ | 614 | store_temp1_max_hyst, 0), |
| 623 | show_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \ | 615 | SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst, |
| 624 | char *buf) \ | 616 | store_temp_max_hyst, 0), |
| 625 | { \ | 617 | SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst, |
| 626 | return show_temp_##reg(dev, buf, offset - 2); \ | 618 | store_temp_max_hyst, 1), |
| 627 | } \ | 619 | }; |
| 628 | static ssize_t \ | ||
| 629 | store_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \ | ||
| 630 | const char *buf, size_t count) \ | ||
| 631 | { \ | ||
| 632 | return store_temp_##reg(dev, buf, count, offset - 2); \ | ||
| 633 | } \ | ||
| 634 | static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \ | ||
| 635 | show_reg_temp##offset##_##reg, \ | ||
| 636 | store_reg_temp##offset##_##reg); | ||
| 637 | |||
| 638 | sysfs_temp_offset(2); | ||
| 639 | sysfs_temp_reg_offset(max, 2); | ||
| 640 | sysfs_temp_reg_offset(max_hyst, 2); | ||
| 641 | sysfs_temp_offset(3); | ||
| 642 | sysfs_temp_reg_offset(max, 3); | ||
| 643 | sysfs_temp_reg_offset(max_hyst, 3); | ||
| 644 | 620 | ||
| 645 | /* | 621 | /* |
| 646 | * Driver and client management | 622 | * Driver and client management |
| @@ -674,6 +650,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
| 674 | { | 650 | { |
| 675 | struct i2c_client *client; | 651 | struct i2c_client *client; |
| 676 | struct w83627ehf_data *data; | 652 | struct w83627ehf_data *data; |
| 653 | struct device *dev; | ||
| 677 | int i, err = 0; | 654 | int i, err = 0; |
| 678 | 655 | ||
| 679 | if (!request_region(address + REGION_OFFSET, REGION_LENGTH, | 656 | if (!request_region(address + REGION_OFFSET, REGION_LENGTH, |
| @@ -694,6 +671,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
| 694 | client->adapter = adapter; | 671 | client->adapter = adapter; |
| 695 | client->driver = &w83627ehf_driver; | 672 | client->driver = &w83627ehf_driver; |
| 696 | client->flags = 0; | 673 | client->flags = 0; |
| 674 | dev = &client->dev; | ||
| 697 | 675 | ||
| 698 | strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE); | 676 | strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE); |
| 699 | data->valid = 0; | 677 | data->valid = 0; |
| @@ -721,42 +699,18 @@ static int w83627ehf_detect(struct i2c_adapter *adapter) | |||
| 721 | data->has_fan |= (1 << 4); | 699 | data->has_fan |= (1 << 4); |
| 722 | 700 | ||
| 723 | /* Register sysfs hooks */ | 701 | /* Register sysfs hooks */ |
| 724 | data->class_dev = hwmon_device_register(&client->dev); | 702 | data->class_dev = hwmon_device_register(dev); |
| 725 | if (IS_ERR(data->class_dev)) { | 703 | if (IS_ERR(data->class_dev)) { |
| 726 | err = PTR_ERR(data->class_dev); | 704 | err = PTR_ERR(data->class_dev); |
| 727 | goto exit_detach; | 705 | goto exit_detach; |
| 728 | } | 706 | } |
| 729 | 707 | ||
| 730 | device_create_file(&client->dev, &dev_attr_fan1_input); | 708 | for (i = 0; i < 5; i++) { |
| 731 | device_create_file(&client->dev, &dev_attr_fan1_min); | 709 | if (data->has_fan & (1 << i)) |
| 732 | device_create_file(&client->dev, &dev_attr_fan1_div); | 710 | device_create_file_fan(dev, i); |
| 733 | device_create_file(&client->dev, &dev_attr_fan2_input); | ||
| 734 | device_create_file(&client->dev, &dev_attr_fan2_min); | ||
| 735 | device_create_file(&client->dev, &dev_attr_fan2_div); | ||
| 736 | device_create_file(&client->dev, &dev_attr_fan3_input); | ||
| 737 | device_create_file(&client->dev, &dev_attr_fan3_min); | ||
| 738 | device_create_file(&client->dev, &dev_attr_fan3_div); | ||
| 739 | |||
| 740 | if (data->has_fan & (1 << 3)) { | ||
| 741 | device_create_file(&client->dev, &dev_attr_fan4_input); | ||
| 742 | device_create_file(&client->dev, &dev_attr_fan4_min); | ||
| 743 | device_create_file(&client->dev, &dev_attr_fan4_div); | ||
| 744 | } | ||
| 745 | if (data->has_fan & (1 << 4)) { | ||
| 746 | device_create_file(&client->dev, &dev_attr_fan5_input); | ||
| 747 | device_create_file(&client->dev, &dev_attr_fan5_min); | ||
| 748 | device_create_file(&client->dev, &dev_attr_fan5_div); | ||
| 749 | } | 711 | } |
| 750 | 712 | for (i = 0; i < ARRAY_SIZE(sda_temp); i++) | |
| 751 | device_create_file(&client->dev, &dev_attr_temp1_input); | 713 | device_create_file(dev, &sda_temp[i].dev_attr); |
| 752 | device_create_file(&client->dev, &dev_attr_temp1_max); | ||
| 753 | device_create_file(&client->dev, &dev_attr_temp1_max_hyst); | ||
| 754 | device_create_file(&client->dev, &dev_attr_temp2_input); | ||
| 755 | device_create_file(&client->dev, &dev_attr_temp2_max); | ||
| 756 | device_create_file(&client->dev, &dev_attr_temp2_max_hyst); | ||
| 757 | device_create_file(&client->dev, &dev_attr_temp3_input); | ||
| 758 | device_create_file(&client->dev, &dev_attr_temp3_max); | ||
| 759 | device_create_file(&client->dev, &dev_attr_temp3_max_hyst); | ||
| 760 | 714 | ||
| 761 | return 0; | 715 | return 0; |
| 762 | 716 | ||
