diff options
-rw-r--r-- | Documentation/thinkpad-acpi.txt | 25 | ||||
-rw-r--r-- | drivers/misc/thinkpad_acpi.c | 79 | ||||
-rw-r--r-- | drivers/misc/thinkpad_acpi.h | 6 |
3 files changed, 91 insertions, 19 deletions
diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt index 60953d6c919d..3b95bbacc775 100644 --- a/Documentation/thinkpad-acpi.txt +++ b/Documentation/thinkpad-acpi.txt | |||
@@ -105,10 +105,15 @@ The version of thinkpad-acpi's sysfs interface is exported by the driver | |||
105 | as a driver attribute (see below). | 105 | as a driver attribute (see below). |
106 | 106 | ||
107 | Sysfs driver attributes are on the driver's sysfs attribute space, | 107 | Sysfs driver attributes are on the driver's sysfs attribute space, |
108 | for 2.6.20 this is /sys/bus/platform/drivers/thinkpad_acpi/. | 108 | for 2.6.23 this is /sys/bus/platform/drivers/thinkpad_acpi/ and |
109 | /sys/bus/platform/drivers/thinkpad_hwmon/ | ||
109 | 110 | ||
110 | Sysfs device attributes are on the driver's sysfs attribute space, | 111 | Sysfs device attributes are on the thinkpad_acpi device sysfs attribute |
111 | for 2.6.20 this is /sys/devices/platform/thinkpad_acpi/. | 112 | space, for 2.6.23 this is /sys/devices/platform/thinkpad_acpi/. |
113 | |||
114 | Sysfs device attributes for the sensors and fan are on the | ||
115 | thinkpad_hwmon device's sysfs attribute space, but you should locate it | ||
116 | looking for a hwmon device with the name attribute of "thinkpad". | ||
112 | 117 | ||
113 | Driver version | 118 | Driver version |
114 | -------------- | 119 | -------------- |
@@ -766,7 +771,7 @@ Temperature sensors | |||
766 | ------------------- | 771 | ------------------- |
767 | 772 | ||
768 | procfs: /proc/acpi/ibm/thermal | 773 | procfs: /proc/acpi/ibm/thermal |
769 | sysfs device attributes: (hwmon) temp*_input | 774 | sysfs device attributes: (hwmon "thinkpad") temp*_input |
770 | 775 | ||
771 | Most ThinkPads include six or more separate temperature sensors but only | 776 | Most ThinkPads include six or more separate temperature sensors but only |
772 | expose the CPU temperature through the standard ACPI methods. This | 777 | expose the CPU temperature through the standard ACPI methods. This |
@@ -989,7 +994,9 @@ Fan control and monitoring: fan speed, fan enable/disable | |||
989 | --------------------------------------------------------- | 994 | --------------------------------------------------------- |
990 | 995 | ||
991 | procfs: /proc/acpi/ibm/fan | 996 | procfs: /proc/acpi/ibm/fan |
992 | sysfs device attributes: (hwmon) fan_input, pwm1, pwm1_enable | 997 | sysfs device attributes: (hwmon "thinkpad") fan1_input, pwm1, |
998 | pwm1_enable | ||
999 | sysfs hwmon driver attributes: fan_watchdog | ||
993 | 1000 | ||
994 | NOTE NOTE NOTE: fan control operations are disabled by default for | 1001 | NOTE NOTE NOTE: fan control operations are disabled by default for |
995 | safety reasons. To enable them, the module parameter "fan_control=1" | 1002 | safety reasons. To enable them, the module parameter "fan_control=1" |
@@ -1131,7 +1138,7 @@ hwmon device attribute fan1_input: | |||
1131 | which can take up to two minutes. May return rubbish on older | 1138 | which can take up to two minutes. May return rubbish on older |
1132 | ThinkPads. | 1139 | ThinkPads. |
1133 | 1140 | ||
1134 | driver attribute fan_watchdog: | 1141 | hwmon driver attribute fan_watchdog: |
1135 | Fan safety watchdog timer interval, in seconds. Minimum is | 1142 | Fan safety watchdog timer interval, in seconds. Minimum is |
1136 | 1 second, maximum is 120 seconds. 0 disables the watchdog. | 1143 | 1 second, maximum is 120 seconds. 0 disables the watchdog. |
1137 | 1144 | ||
@@ -1233,3 +1240,9 @@ Sysfs interface changelog: | |||
1233 | layer, the radio switch generates input event EV_RADIO, | 1240 | layer, the radio switch generates input event EV_RADIO, |
1234 | and the driver enables hot key handling by default in | 1241 | and the driver enables hot key handling by default in |
1235 | the firmware. | 1242 | the firmware. |
1243 | |||
1244 | 0x020000: ABI fix: added a separate hwmon platform device and | ||
1245 | driver, which must be located by name (thinkpad) | ||
1246 | and the hwmon class for libsensors4 (lm-sensors 3) | ||
1247 | compatibility. Moved all hwmon attributes to this | ||
1248 | new platform device. | ||
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 0a33c6ee4508..d5fb93ed04f0 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
@@ -22,7 +22,7 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #define IBM_VERSION "0.16" | 24 | #define IBM_VERSION "0.16" |
25 | #define TPACPI_SYSFS_VERSION 0x010000 | 25 | #define TPACPI_SYSFS_VERSION 0x020000 |
26 | 26 | ||
27 | /* | 27 | /* |
28 | * Changelog: | 28 | * Changelog: |
@@ -526,6 +526,7 @@ static char *next_cmd(char **cmds) | |||
526 | ****************************************************************************/ | 526 | ****************************************************************************/ |
527 | 527 | ||
528 | static struct platform_device *tpacpi_pdev; | 528 | static struct platform_device *tpacpi_pdev; |
529 | static struct platform_device *tpacpi_sensors_pdev; | ||
529 | static struct class_device *tpacpi_hwmon; | 530 | static struct class_device *tpacpi_hwmon; |
530 | static struct input_dev *tpacpi_inputdev; | 531 | static struct input_dev *tpacpi_inputdev; |
531 | static struct mutex tpacpi_inputdev_send_mutex; | 532 | static struct mutex tpacpi_inputdev_send_mutex; |
@@ -553,6 +554,12 @@ static struct platform_driver tpacpi_pdriver = { | |||
553 | .resume = tpacpi_resume_handler, | 554 | .resume = tpacpi_resume_handler, |
554 | }; | 555 | }; |
555 | 556 | ||
557 | static struct platform_driver tpacpi_hwmon_pdriver = { | ||
558 | .driver = { | ||
559 | .name = IBM_HWMON_DRVR_NAME, | ||
560 | .owner = THIS_MODULE, | ||
561 | }, | ||
562 | }; | ||
556 | 563 | ||
557 | /************************************************************************* | 564 | /************************************************************************* |
558 | * thinkpad-acpi driver attributes | 565 | * thinkpad-acpi driver attributes |
@@ -2872,7 +2879,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm) | |||
2872 | 2879 | ||
2873 | switch(thermal_read_mode) { | 2880 | switch(thermal_read_mode) { |
2874 | case TPACPI_THERMAL_TPEC_16: | 2881 | case TPACPI_THERMAL_TPEC_16: |
2875 | res = sysfs_create_group(&tpacpi_pdev->dev.kobj, | 2882 | res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, |
2876 | &thermal_temp_input16_group); | 2883 | &thermal_temp_input16_group); |
2877 | if (res) | 2884 | if (res) |
2878 | return res; | 2885 | return res; |
@@ -2880,7 +2887,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm) | |||
2880 | case TPACPI_THERMAL_TPEC_8: | 2887 | case TPACPI_THERMAL_TPEC_8: |
2881 | case TPACPI_THERMAL_ACPI_TMP07: | 2888 | case TPACPI_THERMAL_ACPI_TMP07: |
2882 | case TPACPI_THERMAL_ACPI_UPDT: | 2889 | case TPACPI_THERMAL_ACPI_UPDT: |
2883 | res = sysfs_create_group(&tpacpi_pdev->dev.kobj, | 2890 | res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, |
2884 | &thermal_temp_input8_group); | 2891 | &thermal_temp_input8_group); |
2885 | if (res) | 2892 | if (res) |
2886 | return res; | 2893 | return res; |
@@ -2897,13 +2904,13 @@ static void thermal_exit(void) | |||
2897 | { | 2904 | { |
2898 | switch(thermal_read_mode) { | 2905 | switch(thermal_read_mode) { |
2899 | case TPACPI_THERMAL_TPEC_16: | 2906 | case TPACPI_THERMAL_TPEC_16: |
2900 | sysfs_remove_group(&tpacpi_pdev->dev.kobj, | 2907 | sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, |
2901 | &thermal_temp_input16_group); | 2908 | &thermal_temp_input16_group); |
2902 | break; | 2909 | break; |
2903 | case TPACPI_THERMAL_TPEC_8: | 2910 | case TPACPI_THERMAL_TPEC_8: |
2904 | case TPACPI_THERMAL_ACPI_TMP07: | 2911 | case TPACPI_THERMAL_ACPI_TMP07: |
2905 | case TPACPI_THERMAL_ACPI_UPDT: | 2912 | case TPACPI_THERMAL_ACPI_UPDT: |
2906 | sysfs_remove_group(&tpacpi_pdev->dev.kobj, | 2913 | sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, |
2907 | &thermal_temp_input16_group); | 2914 | &thermal_temp_input16_group); |
2908 | break; | 2915 | break; |
2909 | case TPACPI_THERMAL_NONE: | 2916 | case TPACPI_THERMAL_NONE: |
@@ -3686,7 +3693,7 @@ static struct device_attribute dev_attr_fan_fan1_input = | |||
3686 | __ATTR(fan1_input, S_IRUGO, | 3693 | __ATTR(fan1_input, S_IRUGO, |
3687 | fan_fan1_input_show, NULL); | 3694 | fan_fan1_input_show, NULL); |
3688 | 3695 | ||
3689 | /* sysfs fan fan_watchdog (driver) ------------------------------------- */ | 3696 | /* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */ |
3690 | static ssize_t fan_fan_watchdog_show(struct device_driver *drv, | 3697 | static ssize_t fan_fan_watchdog_show(struct device_driver *drv, |
3691 | char *buf) | 3698 | char *buf) |
3692 | { | 3699 | { |
@@ -3828,10 +3835,10 @@ static int __init fan_init(struct ibm_init_struct *iibm) | |||
3828 | 3835 | ||
3829 | if (fan_status_access_mode != TPACPI_FAN_NONE || | 3836 | if (fan_status_access_mode != TPACPI_FAN_NONE || |
3830 | fan_control_access_mode != TPACPI_FAN_WR_NONE) { | 3837 | fan_control_access_mode != TPACPI_FAN_WR_NONE) { |
3831 | rc = sysfs_create_group(&tpacpi_pdev->dev.kobj, | 3838 | rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, |
3832 | &fan_attr_group); | 3839 | &fan_attr_group); |
3833 | if (!(rc < 0)) | 3840 | if (!(rc < 0)) |
3834 | rc = driver_create_file(&tpacpi_pdriver.driver, | 3841 | rc = driver_create_file(&tpacpi_hwmon_pdriver.driver, |
3835 | &driver_attr_fan_watchdog); | 3842 | &driver_attr_fan_watchdog); |
3836 | if (rc < 0) | 3843 | if (rc < 0) |
3837 | return rc; | 3844 | return rc; |
@@ -3914,8 +3921,8 @@ static void fan_exit(void) | |||
3914 | vdbg_printk(TPACPI_DBG_EXIT, "cancelling any pending fan watchdog tasks\n"); | 3921 | vdbg_printk(TPACPI_DBG_EXIT, "cancelling any pending fan watchdog tasks\n"); |
3915 | 3922 | ||
3916 | /* FIXME: can we really do this unconditionally? */ | 3923 | /* FIXME: can we really do this unconditionally? */ |
3917 | sysfs_remove_group(&tpacpi_pdev->dev.kobj, &fan_attr_group); | 3924 | sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group); |
3918 | driver_remove_file(&tpacpi_pdriver.driver, &driver_attr_fan_watchdog); | 3925 | driver_remove_file(&tpacpi_hwmon_pdriver.driver, &driver_attr_fan_watchdog); |
3919 | 3926 | ||
3920 | cancel_delayed_work(&fan_watchdog_task); | 3927 | cancel_delayed_work(&fan_watchdog_task); |
3921 | flush_scheduled_work(); | 3928 | flush_scheduled_work(); |
@@ -4366,6 +4373,19 @@ static struct ibm_struct fan_driver_data = { | |||
4366 | **************************************************************************** | 4373 | **************************************************************************** |
4367 | ****************************************************************************/ | 4374 | ****************************************************************************/ |
4368 | 4375 | ||
4376 | /* sysfs name ---------------------------------------------------------- */ | ||
4377 | static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev, | ||
4378 | struct device_attribute *attr, | ||
4379 | char *buf) | ||
4380 | { | ||
4381 | return snprintf(buf, PAGE_SIZE, "%s\n", IBM_NAME); | ||
4382 | } | ||
4383 | |||
4384 | static struct device_attribute dev_attr_thinkpad_acpi_pdev_name = | ||
4385 | __ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL); | ||
4386 | |||
4387 | /* --------------------------------------------------------------------- */ | ||
4388 | |||
4369 | /* /proc support */ | 4389 | /* /proc support */ |
4370 | static struct proc_dir_entry *proc_dir; | 4390 | static struct proc_dir_entry *proc_dir; |
4371 | 4391 | ||
@@ -4768,12 +4788,20 @@ static int __init thinkpad_acpi_module_init(void) | |||
4768 | 4788 | ||
4769 | ret = platform_driver_register(&tpacpi_pdriver); | 4789 | ret = platform_driver_register(&tpacpi_pdriver); |
4770 | if (ret) { | 4790 | if (ret) { |
4771 | printk(IBM_ERR "unable to register platform driver\n"); | 4791 | printk(IBM_ERR "unable to register main platform driver\n"); |
4772 | thinkpad_acpi_module_exit(); | 4792 | thinkpad_acpi_module_exit(); |
4773 | return ret; | 4793 | return ret; |
4774 | } | 4794 | } |
4775 | tp_features.platform_drv_registered = 1; | 4795 | tp_features.platform_drv_registered = 1; |
4776 | 4796 | ||
4797 | ret = platform_driver_register(&tpacpi_hwmon_pdriver); | ||
4798 | if (ret) { | ||
4799 | printk(IBM_ERR "unable to register hwmon platform driver\n"); | ||
4800 | thinkpad_acpi_module_exit(); | ||
4801 | return ret; | ||
4802 | } | ||
4803 | tp_features.sensors_pdrv_registered = 1; | ||
4804 | |||
4777 | ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver); | 4805 | ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver); |
4778 | if (ret) { | 4806 | if (ret) { |
4779 | printk(IBM_ERR "unable to create sysfs driver attributes\n"); | 4807 | printk(IBM_ERR "unable to create sysfs driver attributes\n"); |
@@ -4793,7 +4821,26 @@ static int __init thinkpad_acpi_module_init(void) | |||
4793 | thinkpad_acpi_module_exit(); | 4821 | thinkpad_acpi_module_exit(); |
4794 | return ret; | 4822 | return ret; |
4795 | } | 4823 | } |
4796 | tpacpi_hwmon = hwmon_device_register(&tpacpi_pdev->dev); | 4824 | tpacpi_sensors_pdev = platform_device_register_simple( |
4825 | IBM_HWMON_DRVR_NAME, | ||
4826 | -1, NULL, 0); | ||
4827 | if (IS_ERR(tpacpi_sensors_pdev)) { | ||
4828 | ret = PTR_ERR(tpacpi_sensors_pdev); | ||
4829 | tpacpi_sensors_pdev = NULL; | ||
4830 | printk(IBM_ERR "unable to register hwmon platform device\n"); | ||
4831 | thinkpad_acpi_module_exit(); | ||
4832 | return ret; | ||
4833 | } | ||
4834 | ret = device_create_file(&tpacpi_sensors_pdev->dev, | ||
4835 | &dev_attr_thinkpad_acpi_pdev_name); | ||
4836 | if (ret) { | ||
4837 | printk(IBM_ERR | ||
4838 | "unable to create sysfs hwmon device attributes\n"); | ||
4839 | thinkpad_acpi_module_exit(); | ||
4840 | return ret; | ||
4841 | } | ||
4842 | tp_features.sensors_pdev_attrs_registered = 1; | ||
4843 | tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev); | ||
4797 | if (IS_ERR(tpacpi_hwmon)) { | 4844 | if (IS_ERR(tpacpi_hwmon)) { |
4798 | ret = PTR_ERR(tpacpi_hwmon); | 4845 | ret = PTR_ERR(tpacpi_hwmon); |
4799 | tpacpi_hwmon = NULL; | 4846 | tpacpi_hwmon = NULL; |
@@ -4864,12 +4911,20 @@ static void thinkpad_acpi_module_exit(void) | |||
4864 | if (tpacpi_hwmon) | 4911 | if (tpacpi_hwmon) |
4865 | hwmon_device_unregister(tpacpi_hwmon); | 4912 | hwmon_device_unregister(tpacpi_hwmon); |
4866 | 4913 | ||
4914 | if (tp_features.sensors_pdev_attrs_registered) | ||
4915 | device_remove_file(&tpacpi_sensors_pdev->dev, | ||
4916 | &dev_attr_thinkpad_acpi_pdev_name); | ||
4917 | if (tpacpi_sensors_pdev) | ||
4918 | platform_device_unregister(tpacpi_sensors_pdev); | ||
4867 | if (tpacpi_pdev) | 4919 | if (tpacpi_pdev) |
4868 | platform_device_unregister(tpacpi_pdev); | 4920 | platform_device_unregister(tpacpi_pdev); |
4869 | 4921 | ||
4870 | if (tp_features.platform_drv_attrs_registered) | 4922 | if (tp_features.platform_drv_attrs_registered) |
4871 | tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver); | 4923 | tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver); |
4872 | 4924 | ||
4925 | if (tp_features.sensors_pdrv_registered) | ||
4926 | platform_driver_unregister(&tpacpi_hwmon_pdriver); | ||
4927 | |||
4873 | if (tp_features.platform_drv_registered) | 4928 | if (tp_features.platform_drv_registered) |
4874 | platform_driver_unregister(&tpacpi_pdriver); | 4929 | platform_driver_unregister(&tpacpi_pdriver); |
4875 | 4930 | ||
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h index fa64dedd26d9..791b8ca4bca5 100644 --- a/drivers/misc/thinkpad_acpi.h +++ b/drivers/misc/thinkpad_acpi.h | |||
@@ -58,13 +58,14 @@ | |||
58 | 58 | ||
59 | #define IBM_NAME "thinkpad" | 59 | #define IBM_NAME "thinkpad" |
60 | #define IBM_DESC "ThinkPad ACPI Extras" | 60 | #define IBM_DESC "ThinkPad ACPI Extras" |
61 | #define IBM_FILE "thinkpad_acpi" | 61 | #define IBM_FILE IBM_NAME "_acpi" |
62 | #define IBM_URL "http://ibm-acpi.sf.net/" | 62 | #define IBM_URL "http://ibm-acpi.sf.net/" |
63 | #define IBM_MAIL "ibm-acpi-devel@lists.sourceforge.net" | 63 | #define IBM_MAIL "ibm-acpi-devel@lists.sourceforge.net" |
64 | 64 | ||
65 | #define IBM_PROC_DIR "ibm" | 65 | #define IBM_PROC_DIR "ibm" |
66 | #define IBM_ACPI_EVENT_PREFIX "ibm" | 66 | #define IBM_ACPI_EVENT_PREFIX "ibm" |
67 | #define IBM_DRVR_NAME IBM_FILE | 67 | #define IBM_DRVR_NAME IBM_FILE |
68 | #define IBM_HWMON_DRVR_NAME IBM_NAME "_hwmon" | ||
68 | 69 | ||
69 | #define IBM_LOG IBM_FILE ": " | 70 | #define IBM_LOG IBM_FILE ": " |
70 | #define IBM_ERR KERN_ERR IBM_LOG | 71 | #define IBM_ERR KERN_ERR IBM_LOG |
@@ -171,6 +172,7 @@ static int parse_strtoul(const char *buf, unsigned long max, | |||
171 | 172 | ||
172 | /* Device model */ | 173 | /* Device model */ |
173 | static struct platform_device *tpacpi_pdev; | 174 | static struct platform_device *tpacpi_pdev; |
175 | static struct platform_device *tpacpi_sensors_pdev; | ||
174 | static struct class_device *tpacpi_hwmon; | 176 | static struct class_device *tpacpi_hwmon; |
175 | static struct platform_driver tpacpi_pdriver; | 177 | static struct platform_driver tpacpi_pdriver; |
176 | static struct input_dev *tpacpi_inputdev; | 178 | static struct input_dev *tpacpi_inputdev; |
@@ -249,6 +251,8 @@ static struct { | |||
249 | u32 input_device_registered:1; | 251 | u32 input_device_registered:1; |
250 | u32 platform_drv_registered:1; | 252 | u32 platform_drv_registered:1; |
251 | u32 platform_drv_attrs_registered:1; | 253 | u32 platform_drv_attrs_registered:1; |
254 | u32 sensors_pdrv_registered:1; | ||
255 | u32 sensors_pdev_attrs_registered:1; | ||
252 | } tp_features; | 256 | } tp_features; |
253 | 257 | ||
254 | struct thinkpad_id_data { | 258 | struct thinkpad_id_data { |