diff options
Diffstat (limited to 'drivers/platform/x86/thinkpad_acpi.c')
| -rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 81 | 
1 files changed, 44 insertions, 37 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index a40b075743d..912be65b626 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -21,7 +21,7 @@   *  02110-1301, USA.   */ -#define TPACPI_VERSION "0.22" +#define TPACPI_VERSION "0.23"  #define TPACPI_SYSFS_VERSION 0x020300  /* @@ -303,11 +303,17 @@ static u32 dbg_level;  static struct workqueue_struct *tpacpi_wq; +enum led_status_t { +	TPACPI_LED_OFF = 0, +	TPACPI_LED_ON, +	TPACPI_LED_BLINK, +}; +  /* Special LED class that can defer work */  struct tpacpi_led_classdev {  	struct led_classdev led_classdev;  	struct work_struct work; -	enum led_brightness new_brightness; +	enum led_status_t new_state;  	unsigned int led;  }; @@ -2946,12 +2952,18 @@ static int hotkey_read(char *p)  	return len;  } -static void hotkey_enabledisable_warn(void) +static void hotkey_enabledisable_warn(bool enable)  {  	tpacpi_log_usertask("procfs hotkey enable/disable"); -	WARN(1, TPACPI_WARN -	     "hotkey enable/disable functionality has been " -	     "removed from the driver. Hotkeys are always enabled.\n"); +	if (!WARN((tpacpi_lifecycle == TPACPI_LIFE_RUNNING || !enable), +			TPACPI_WARN +			"hotkey enable/disable functionality has been " +			"removed from the driver.  Hotkeys are always " +			"enabled\n")) +		printk(TPACPI_ERR +			"Please remove the hotkey=enable module " +			"parameter, it is deprecated.  Hotkeys are always " +			"enabled\n");  }  static int hotkey_write(char *buf) @@ -2971,9 +2983,9 @@ static int hotkey_write(char *buf)  	res = 0;  	while ((cmd = next_cmd(&buf))) {  		if (strlencmp(cmd, "enable") == 0) { -			hotkey_enabledisable_warn(); +			hotkey_enabledisable_warn(1);  		} else if (strlencmp(cmd, "disable") == 0) { -			hotkey_enabledisable_warn(); +			hotkey_enabledisable_warn(0);  			res = -EPERM;  		} else if (strlencmp(cmd, "reset") == 0) {  			mask = hotkey_orig_mask; @@ -4207,7 +4219,7 @@ static void light_set_status_worker(struct work_struct *work)  			container_of(work, struct tpacpi_led_classdev, work);  	if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) -		light_set_status((data->new_brightness != LED_OFF)); +		light_set_status((data->new_state != TPACPI_LED_OFF));  }  static void light_sysfs_set(struct led_classdev *led_cdev, @@ -4217,7 +4229,8 @@ static void light_sysfs_set(struct led_classdev *led_cdev,  		container_of(led_cdev,  			     struct tpacpi_led_classdev,  			     led_classdev); -	data->new_brightness = brightness; +	data->new_state = (brightness != LED_OFF) ? +				TPACPI_LED_ON : TPACPI_LED_OFF;  	queue_work(tpacpi_wq, &data->work);  } @@ -4724,12 +4737,6 @@ enum {	/* For TPACPI_LED_OLD */  	TPACPI_LED_EC_HLMS = 0x0e,	/* EC reg to select led to command */  }; -enum led_status_t { -	TPACPI_LED_OFF = 0, -	TPACPI_LED_ON, -	TPACPI_LED_BLINK, -}; -  static enum led_access_mode led_supported;  TPACPI_HANDLE(led, ec, "SLED",	/* 570 */ @@ -4841,23 +4848,13 @@ static int led_set_status(const unsigned int led,  	return rc;  } -static void led_sysfs_set_status(unsigned int led, -				 enum led_brightness brightness) -{ -	led_set_status(led, -			(brightness == LED_OFF) ? -			TPACPI_LED_OFF : -			(tpacpi_led_state_cache[led] == TPACPI_LED_BLINK) ? -				TPACPI_LED_BLINK : TPACPI_LED_ON); -} -  static void led_set_status_worker(struct work_struct *work)  {  	struct tpacpi_led_classdev *data =  		container_of(work, struct tpacpi_led_classdev, work);  	if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) -		led_sysfs_set_status(data->led, data->new_brightness); +		led_set_status(data->led, data->new_state);  }  static void led_sysfs_set(struct led_classdev *led_cdev, @@ -4866,7 +4863,13 @@ static void led_sysfs_set(struct led_classdev *led_cdev,  	struct tpacpi_led_classdev *data = container_of(led_cdev,  			     struct tpacpi_led_classdev, led_classdev); -	data->new_brightness = brightness; +	if (brightness == LED_OFF) +		data->new_state = TPACPI_LED_OFF; +	else if (tpacpi_led_state_cache[data->led] != TPACPI_LED_BLINK) +		data->new_state = TPACPI_LED_ON; +	else +		data->new_state = TPACPI_LED_BLINK; +  	queue_work(tpacpi_wq, &data->work);  } @@ -4884,7 +4887,7 @@ static int led_sysfs_blink_set(struct led_classdev *led_cdev,  	} else if ((*delay_on != 500) || (*delay_off != 500))  		return -EINVAL; -	data->new_brightness = TPACPI_LED_BLINK; +	data->new_state = TPACPI_LED_BLINK;  	queue_work(tpacpi_wq, &data->work);  	return 0; @@ -7858,6 +7861,15 @@ static int __init thinkpad_acpi_module_init(void)  MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);  /* + * This will autoload the driver in almost every ThinkPad + * in widespread use. + * + * Only _VERY_ old models, like the 240, 240x and 570 lack + * the HKEY event interface. + */ +MODULE_DEVICE_TABLE(acpi, ibm_htk_device_ids); + +/*   * DMI matching for module autoloading   *   * See http://thinkwiki.org/wiki/List_of_DMI_IDs @@ -7869,18 +7881,13 @@ MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);  #define IBM_BIOS_MODULE_ALIAS(__type) \  	MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW*") -/* Non-ancient thinkpads */ -MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*"); -MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*"); -  /* Ancient thinkpad BIOSes have to be identified by   * BIOS type or model number, and there are far less   * BIOS types than model numbers... */ -IBM_BIOS_MODULE_ALIAS("I[BDHIMNOTWVYZ]"); -IBM_BIOS_MODULE_ALIAS("1[0368A-GIKM-PST]"); -IBM_BIOS_MODULE_ALIAS("K[UX-Z]"); +IBM_BIOS_MODULE_ALIAS("I[MU]");		/* 570, 570e */ -MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh"); +MODULE_AUTHOR("Borislav Deianov <borislav@users.sf.net>"); +MODULE_AUTHOR("Henrique de Moraes Holschuh <hmh@hmh.eng.br>");  MODULE_DESCRIPTION(TPACPI_DESC);  MODULE_VERSION(TPACPI_VERSION);  MODULE_LICENSE("GPL");  |