From f4e1e43c607b5ead89b2135c348392810420de69 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 23 Sep 2007 11:39:00 -0300 Subject: ACPI: thinkpad-acpi: issue EV_SYNC after EV_SWITCH We were missing a input_sync on the radio switch event report path. Add it. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/misc/thinkpad_acpi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/misc/thinkpad_acpi.c') diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 0222bbaf7b76..8aa0f9694b87 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -1149,9 +1149,11 @@ static void tpacpi_input_send_radiosw(void) { int wlsw; - if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) + if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) { input_report_switch(tpacpi_inputdev, SW_RADIO, !!wlsw); + input_sync(tpacpi_inputdev); + } } static void hotkey_notify(struct ibm_struct *ibm, u32 event) -- cgit v1.2.2 From 8523ed6fb2ca04973fe759fda8ab4af72492fc7e Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 23 Sep 2007 11:39:01 -0300 Subject: ACPI: thinkpad-acpi: add mutex-based locking to input device event send path Protect the input device event sending path with a mutex, since hot key input events are not atomic and require an cohesive event block to be sent together. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/misc/thinkpad_acpi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/misc/thinkpad_acpi.c') diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 8aa0f9694b87..0ced9d65c6be 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -519,6 +519,7 @@ static char *next_cmd(char **cmds) static struct platform_device *tpacpi_pdev; static struct class_device *tpacpi_hwmon; static struct input_dev *tpacpi_inputdev; +static struct mutex tpacpi_inputdev_send_mutex; static int tpacpi_resume_handler(struct platform_device *pdev) @@ -1131,6 +1132,8 @@ static void tpacpi_input_send_key(unsigned int scancode, unsigned int keycode) { if (keycode != KEY_RESERVED) { + mutex_lock(&tpacpi_inputdev_send_mutex); + input_report_key(tpacpi_inputdev, keycode, 1); if (keycode == KEY_UNKNOWN) input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, @@ -1142,6 +1145,8 @@ static void tpacpi_input_send_key(unsigned int scancode, input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, scancode); input_sync(tpacpi_inputdev); + + mutex_unlock(&tpacpi_inputdev_send_mutex); } } @@ -1149,11 +1154,15 @@ static void tpacpi_input_send_radiosw(void) { int wlsw; + mutex_lock(&tpacpi_inputdev_send_mutex); + if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) { input_report_switch(tpacpi_inputdev, SW_RADIO, !!wlsw); input_sync(tpacpi_inputdev); } + + mutex_unlock(&tpacpi_inputdev_send_mutex); } static void hotkey_notify(struct ibm_struct *ibm, u32 event) @@ -4737,6 +4746,7 @@ static int __init thinkpad_acpi_module_init(void) thinkpad_acpi_module_exit(); return ret; } + mutex_init(&tpacpi_inputdev_send_mutex); tpacpi_inputdev = input_allocate_device(); if (!tpacpi_inputdev) { printk(IBM_ERR "unable to allocate input device\n"); -- cgit v1.2.2 From 8fef502e5a14df05f1e755edc9175e01c9814080 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 23 Sep 2007 11:39:02 -0300 Subject: ACPI: thinkpad-acpi: keep track of module state Keep track of module state (init, running, exit). This makes it trivially easy to avoid running any interrupt handlers, threads, or any other async activity before we are ready, or when we want to go away. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/misc/thinkpad_acpi.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'drivers/misc/thinkpad_acpi.c') diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 0ced9d65c6be..2155139793b1 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -117,6 +117,12 @@ IBM_BIOS_MODULE_ALIAS("K[U,X-Z]"); #define __unused __attribute__ ((unused)) +static enum { + TPACPI_LIFE_INIT = 0, + TPACPI_LIFE_RUNNING, + TPACPI_LIFE_EXITING, +} tpacpi_lifecycle; + /**************************************************************************** **************************************************************************** * @@ -342,6 +348,9 @@ static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data) { struct ibm_struct *ibm = data; + if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING) + return; + if (!ibm || !ibm->acpi || !ibm->acpi->notify) return; @@ -3899,6 +3908,9 @@ static void fan_watchdog_fire(struct work_struct *ignored) { int rc; + if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING) + return; + printk(IBM_NOTICE "fan watchdog: enabling fan\n"); rc = fan_set_enable(); if (rc < 0) { @@ -3919,7 +3931,8 @@ static void fan_watchdog_reset(void) if (fan_watchdog_active) cancel_delayed_work(&fan_watchdog_task); - if (fan_watchdog_maxinterval > 0) { + if (fan_watchdog_maxinterval > 0 && + tpacpi_lifecycle != TPACPI_LIFE_EXITING) { fan_watchdog_active = 1; if (!schedule_delayed_work(&fan_watchdog_task, msecs_to_jiffies(fan_watchdog_maxinterval @@ -4685,6 +4698,8 @@ static int __init thinkpad_acpi_module_init(void) { int ret, i; + tpacpi_lifecycle = TPACPI_LIFE_INIT; + /* Parameter checking */ if (hotkey_report_mode > 2) return -EINVAL; @@ -4781,6 +4796,7 @@ static int __init thinkpad_acpi_module_init(void) tp_features.input_device_registered = 1; } + tpacpi_lifecycle = TPACPI_LIFE_RUNNING; return 0; } @@ -4788,6 +4804,8 @@ static void thinkpad_acpi_module_exit(void) { struct ibm_struct *ibm, *itmp; + tpacpi_lifecycle = TPACPI_LIFE_EXITING; + list_for_each_entry_safe_reverse(ibm, itmp, &tpacpi_all_drivers, all_drivers) { -- cgit v1.2.2 From 1b6521dc84f372dd92a96381fbeeebb01173d050 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 23 Sep 2007 11:39:03 -0300 Subject: ACPI: thinkpad-acpi: check version of hot key firmware Check the HKEY firmware version (HKEY.MHKV handler), and refuse to load if it is unknown. Use this instead of the presence of HKEY.DHKV to detect hot key mask capability. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/misc/thinkpad_acpi.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'drivers/misc/thinkpad_acpi.c') diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 2155139793b1..9a611402ee9d 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -999,6 +999,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) int res, i; int status; + int hkeyv; vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n"); @@ -1024,18 +1025,35 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) return res; /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, - A30, R30, R31, T20-22, X20-21, X22-24 */ - tp_features.hotkey_mask = - acpi_evalf(hkey_handle, NULL, "DHKN", "qv"); + A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking + for HKEY interface version 0x100 */ + if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { + if ((hkeyv >> 8) != 1) { + printk(IBM_ERR "unknown version of the " + "HKEY interface: 0x%x\n", hkeyv); + printk(IBM_ERR "please report this to %s\n", + IBM_MAIL); + } else { + /* + * MHKV 0x100 in A31, R40, R40e, + * T4x, X31, and later + * */ + tp_features.hotkey_mask = 1; + } + } vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", str_supported(tp_features.hotkey_mask)); if (tp_features.hotkey_mask) { - /* MHKA available in A31, R40, R40e, T4x, X31, and later */ if (!acpi_evalf(hkey_handle, &hotkey_all_mask, - "MHKA", "qd")) + "MHKA", "qd")) { + printk(IBM_ERR + "missing MHKA handler, " + "please report this to %s\n", + IBM_MAIL); hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */ + } } res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask); -- cgit v1.2.2 From 3eea123df1637a88d0899626a67b83dca959efff Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 23 Sep 2007 11:39:04 -0300 Subject: ACPI: thinkpad-acpi: dequeue all pending hot key events at once (v2.2) Receive all pending HKEY events at once from a single notification, and don't complain if the queue is empty. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/misc/thinkpad_acpi.c | 51 +++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 17 deletions(-) (limited to 'drivers/misc/thinkpad_acpi.c') diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 9a611402ee9d..3efe81b1b73c 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -1196,9 +1196,30 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) { u32 hkey; unsigned int keycode, scancode; - int send_acpi_ev = 0; + int send_acpi_ev; + + if (event != 0x80) { + printk(IBM_ERR "unknown HKEY notification event %d\n", event); + /* forward it to userspace, maybe it knows how to handle it */ + acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, + ibm->acpi->device->dev.bus_id, + event, 0); + return; + } + + while (1) { + if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { + printk(IBM_ERR "failed to retrieve HKEY event\n"); + return; + } + + if (hkey == 0) { + /* queue empty */ + return; + } + + send_acpi_ev = 0; - if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { switch (hkey >> 12) { case 1: /* 0x1000-0x1FFF: key presses */ @@ -1220,8 +1241,8 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) * eat up known LID events */ if (hkey != 0x5001 && hkey != 0x5002) { printk(IBM_ERR - "unknown LID-related hotkey event: 0x%04x\n", - hkey); + "unknown LID-related HKEY event: 0x%04x\n", + hkey); send_acpi_ev = 1; } break; @@ -1240,21 +1261,17 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) printk(IBM_NOTICE "unhandled HKEY event 0x%04x\n", hkey); send_acpi_ev = 1; } - } else { - printk(IBM_ERR "unknown hotkey notification event %d\n", event); - hkey = 0; - send_acpi_ev = 1; - } - /* Legacy events */ - if (send_acpi_ev || hotkey_report_mode < 2) - acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey); + /* Legacy events */ + if (send_acpi_ev || hotkey_report_mode < 2) + acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey); - /* netlink events */ - if (send_acpi_ev) { - acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, - ibm->acpi->device->dev.bus_id, - event, hkey); + /* netlink events */ + if (send_acpi_ev) { + acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, + ibm->acpi->device->dev.bus_id, + event, hkey); + } } } -- cgit v1.2.2 From 3e5ce914bd17335ca74a7c7b06a776c6be6ca434 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 23 Sep 2007 11:39:05 -0300 Subject: ACPI: thinkpad-acpi: fix regression on HKEY LID event handling We were letting ThinkPad-specific LID events through to userspace again, instead of dropping them. Fix it. We don't want to give userspace the option of not using generic LID handling. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/misc/thinkpad_acpi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/misc/thinkpad_acpi.c') diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 3efe81b1b73c..0a33c6ee4508 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -1197,6 +1197,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) u32 hkey; unsigned int keycode, scancode; int send_acpi_ev; + int ignore_acpi_ev; if (event != 0x80) { printk(IBM_ERR "unknown HKEY notification event %d\n", event); @@ -1219,6 +1220,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) } send_acpi_ev = 0; + ignore_acpi_ev = 0; switch (hkey >> 12) { case 1: @@ -1244,6 +1246,8 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) "unknown LID-related HKEY event: 0x%04x\n", hkey); send_acpi_ev = 1; + } else { + ignore_acpi_ev = 1; } break; case 7: @@ -1263,11 +1267,12 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) } /* Legacy events */ - if (send_acpi_ev || hotkey_report_mode < 2) + if (!ignore_acpi_ev && (send_acpi_ev || hotkey_report_mode < 2)) { acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey); + } /* netlink events */ - if (send_acpi_ev) { + if (!ignore_acpi_ev && send_acpi_ev) { acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, ibm->acpi->device->dev.bus_id, event, hkey); -- cgit v1.2.2 From 7fd400297978a2cf7a74344fb22020e9479b4f69 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Tue, 25 Sep 2007 06:38:03 -0300 Subject: ACPI: thinkpad-acpi: use a separate platform device for hwmon and name it (v2) Use a separate platform device and driver ("thinkpad_hwmon") to attach hwmon attributes and class, and add a name attribute of "thinkpad" to it, which defines the hwmon device name for libsensors4. This makes thinkpad-acpi compatible with libsensors4 from lm-sensors, and the platform driver and device split will make it much easier to separate hwmon functionality into its own module later on. Signed-off-by: Henrique de Moraes Holschuh Cc: Jean Delvare Signed-off-by: Len Brown --- drivers/misc/thinkpad_acpi.c | 79 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 12 deletions(-) (limited to 'drivers/misc/thinkpad_acpi.c') 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 @@ */ #define IBM_VERSION "0.16" -#define TPACPI_SYSFS_VERSION 0x010000 +#define TPACPI_SYSFS_VERSION 0x020000 /* * Changelog: @@ -526,6 +526,7 @@ static char *next_cmd(char **cmds) ****************************************************************************/ static struct platform_device *tpacpi_pdev; +static struct platform_device *tpacpi_sensors_pdev; static struct class_device *tpacpi_hwmon; static struct input_dev *tpacpi_inputdev; static struct mutex tpacpi_inputdev_send_mutex; @@ -553,6 +554,12 @@ static struct platform_driver tpacpi_pdriver = { .resume = tpacpi_resume_handler, }; +static struct platform_driver tpacpi_hwmon_pdriver = { + .driver = { + .name = IBM_HWMON_DRVR_NAME, + .owner = THIS_MODULE, + }, +}; /************************************************************************* * thinkpad-acpi driver attributes @@ -2872,7 +2879,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm) switch(thermal_read_mode) { case TPACPI_THERMAL_TPEC_16: - res = sysfs_create_group(&tpacpi_pdev->dev.kobj, + res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, &thermal_temp_input16_group); if (res) return res; @@ -2880,7 +2887,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm) case TPACPI_THERMAL_TPEC_8: case TPACPI_THERMAL_ACPI_TMP07: case TPACPI_THERMAL_ACPI_UPDT: - res = sysfs_create_group(&tpacpi_pdev->dev.kobj, + res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, &thermal_temp_input8_group); if (res) return res; @@ -2897,13 +2904,13 @@ static void thermal_exit(void) { switch(thermal_read_mode) { case TPACPI_THERMAL_TPEC_16: - sysfs_remove_group(&tpacpi_pdev->dev.kobj, + sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &thermal_temp_input16_group); break; case TPACPI_THERMAL_TPEC_8: case TPACPI_THERMAL_ACPI_TMP07: case TPACPI_THERMAL_ACPI_UPDT: - sysfs_remove_group(&tpacpi_pdev->dev.kobj, + sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &thermal_temp_input16_group); break; case TPACPI_THERMAL_NONE: @@ -3686,7 +3693,7 @@ static struct device_attribute dev_attr_fan_fan1_input = __ATTR(fan1_input, S_IRUGO, fan_fan1_input_show, NULL); -/* sysfs fan fan_watchdog (driver) ------------------------------------- */ +/* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */ static ssize_t fan_fan_watchdog_show(struct device_driver *drv, char *buf) { @@ -3828,10 +3835,10 @@ static int __init fan_init(struct ibm_init_struct *iibm) if (fan_status_access_mode != TPACPI_FAN_NONE || fan_control_access_mode != TPACPI_FAN_WR_NONE) { - rc = sysfs_create_group(&tpacpi_pdev->dev.kobj, + rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group); if (!(rc < 0)) - rc = driver_create_file(&tpacpi_pdriver.driver, + rc = driver_create_file(&tpacpi_hwmon_pdriver.driver, &driver_attr_fan_watchdog); if (rc < 0) return rc; @@ -3914,8 +3921,8 @@ static void fan_exit(void) vdbg_printk(TPACPI_DBG_EXIT, "cancelling any pending fan watchdog tasks\n"); /* FIXME: can we really do this unconditionally? */ - sysfs_remove_group(&tpacpi_pdev->dev.kobj, &fan_attr_group); - driver_remove_file(&tpacpi_pdriver.driver, &driver_attr_fan_watchdog); + sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group); + driver_remove_file(&tpacpi_hwmon_pdriver.driver, &driver_attr_fan_watchdog); cancel_delayed_work(&fan_watchdog_task); flush_scheduled_work(); @@ -4366,6 +4373,19 @@ static struct ibm_struct fan_driver_data = { **************************************************************************** ****************************************************************************/ +/* sysfs name ---------------------------------------------------------- */ +static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", IBM_NAME); +} + +static struct device_attribute dev_attr_thinkpad_acpi_pdev_name = + __ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL); + +/* --------------------------------------------------------------------- */ + /* /proc support */ static struct proc_dir_entry *proc_dir; @@ -4768,12 +4788,20 @@ static int __init thinkpad_acpi_module_init(void) ret = platform_driver_register(&tpacpi_pdriver); if (ret) { - printk(IBM_ERR "unable to register platform driver\n"); + printk(IBM_ERR "unable to register main platform driver\n"); thinkpad_acpi_module_exit(); return ret; } tp_features.platform_drv_registered = 1; + ret = platform_driver_register(&tpacpi_hwmon_pdriver); + if (ret) { + printk(IBM_ERR "unable to register hwmon platform driver\n"); + thinkpad_acpi_module_exit(); + return ret; + } + tp_features.sensors_pdrv_registered = 1; + ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver); if (ret) { printk(IBM_ERR "unable to create sysfs driver attributes\n"); @@ -4793,7 +4821,26 @@ static int __init thinkpad_acpi_module_init(void) thinkpad_acpi_module_exit(); return ret; } - tpacpi_hwmon = hwmon_device_register(&tpacpi_pdev->dev); + tpacpi_sensors_pdev = platform_device_register_simple( + IBM_HWMON_DRVR_NAME, + -1, NULL, 0); + if (IS_ERR(tpacpi_sensors_pdev)) { + ret = PTR_ERR(tpacpi_sensors_pdev); + tpacpi_sensors_pdev = NULL; + printk(IBM_ERR "unable to register hwmon platform device\n"); + thinkpad_acpi_module_exit(); + return ret; + } + ret = device_create_file(&tpacpi_sensors_pdev->dev, + &dev_attr_thinkpad_acpi_pdev_name); + if (ret) { + printk(IBM_ERR + "unable to create sysfs hwmon device attributes\n"); + thinkpad_acpi_module_exit(); + return ret; + } + tp_features.sensors_pdev_attrs_registered = 1; + tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev); if (IS_ERR(tpacpi_hwmon)) { ret = PTR_ERR(tpacpi_hwmon); tpacpi_hwmon = NULL; @@ -4864,12 +4911,20 @@ static void thinkpad_acpi_module_exit(void) if (tpacpi_hwmon) hwmon_device_unregister(tpacpi_hwmon); + if (tp_features.sensors_pdev_attrs_registered) + device_remove_file(&tpacpi_sensors_pdev->dev, + &dev_attr_thinkpad_acpi_pdev_name); + if (tpacpi_sensors_pdev) + platform_device_unregister(tpacpi_sensors_pdev); if (tpacpi_pdev) platform_device_unregister(tpacpi_pdev); if (tp_features.platform_drv_attrs_registered) tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver); + if (tp_features.sensors_pdrv_registered) + platform_driver_unregister(&tpacpi_hwmon_pdriver); + if (tp_features.platform_drv_registered) platform_driver_unregister(&tpacpi_pdriver); -- cgit v1.2.2 From 2369cc9492a462285f9eec9d2bbfa730cc2ab5ac Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sun, 23 Sep 2007 11:39:07 -0300 Subject: ACPI: thinkpad-acpi: duplicate driver attributes to new hwmon pdrv Thinkpad-acpi has some driver attributes (debug level, sysfs interface version, etc) that also belong to the new hwmon driver. Duplicate them there. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/misc/thinkpad_acpi.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/misc/thinkpad_acpi.c') diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index d5fb93ed04f0..81693b4c23b8 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -4803,12 +4803,16 @@ static int __init thinkpad_acpi_module_init(void) tp_features.sensors_pdrv_registered = 1; ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver); + if (!ret) { + tp_features.platform_drv_attrs_registered = 1; + ret = tpacpi_create_driver_attributes(&tpacpi_hwmon_pdriver.driver); + } if (ret) { printk(IBM_ERR "unable to create sysfs driver attributes\n"); thinkpad_acpi_module_exit(); return ret; } - tp_features.platform_drv_attrs_registered = 1; + tp_features.sensors_pdrv_attrs_registered = 1; /* Device initialization */ @@ -4919,6 +4923,8 @@ static void thinkpad_acpi_module_exit(void) if (tpacpi_pdev) platform_device_unregister(tpacpi_pdev); + if (tp_features.sensors_pdrv_attrs_registered) + tpacpi_remove_driver_attributes(&tpacpi_hwmon_pdriver.driver); if (tp_features.platform_drv_attrs_registered) tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver); -- cgit v1.2.2 From 32afbf07aa53120c0e3fe1881b948ded99f4fc35 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Mon, 8 Oct 2007 10:12:56 -0300 Subject: ACPI: thinkpad-acpi: skip blanks before the data when parsing sysfs Skip blanks not just at the tail of sysfs writes, but also at the head. Signed-off-by: Henrique de Moraes Holschuh Signed-off-by: Len Brown --- drivers/misc/thinkpad_acpi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/misc/thinkpad_acpi.c') diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 81693b4c23b8..37891a8c030a 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -709,6 +709,8 @@ static int parse_strtoul(const char *buf, { char *endp; + while (*buf && isspace(*buf)) + buf++; *value = simple_strtoul(buf, &endp, 0); while (*endp && isspace(*endp)) endp++; -- cgit v1.2.2