diff options
Diffstat (limited to 'drivers/platform/x86/thinkpad_acpi.c')
| -rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 1181 | 
1 files changed, 678 insertions, 503 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 2d61186ad5a..d82f196e3cf 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -21,7 +21,9 @@   *  02110-1301, USA.   */ -#define TPACPI_VERSION "0.24" +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#define TPACPI_VERSION "0.25"  #define TPACPI_SYSFS_VERSION 0x020700  /* @@ -59,7 +61,6 @@  #include <linux/freezer.h>  #include <linux/delay.h>  #include <linux/slab.h> -  #include <linux/nvram.h>  #include <linux/proc_fs.h>  #include <linux/seq_file.h> @@ -72,20 +73,16 @@  #include <linux/input.h>  #include <linux/leds.h>  #include <linux/rfkill.h> -#include <asm/uaccess.h> -  #include <linux/dmi.h>  #include <linux/jiffies.h>  #include <linux/workqueue.h> - +#include <linux/acpi.h> +#include <linux/pci_ids.h> +#include <linux/thinkpad_acpi.h>  #include <sound/core.h>  #include <sound/control.h>  #include <sound/initval.h> - -#include <acpi/acpi_drivers.h> - -#include <linux/pci_ids.h> - +#include <asm/uaccess.h>  /* ThinkPad CMOS commands */  #define TP_CMOS_VOLUME_DOWN	0 @@ -128,7 +125,8 @@ enum {  };  /* ACPI HIDs */ -#define TPACPI_ACPI_HKEY_HID		"IBM0068" +#define TPACPI_ACPI_IBM_HKEY_HID	"IBM0068" +#define TPACPI_ACPI_LENOVO_HKEY_HID	"LEN0068"  #define TPACPI_ACPI_EC_HID		"PNP0C09"  /* Input IDs */ @@ -181,6 +179,10 @@ enum tpacpi_hkey_event_t {  	/* Misc bay events */  	TP_HKEY_EV_OPTDRV_EJ		= 0x3006, /* opt. drive tray ejected */ +	TP_HKEY_EV_HOTPLUG_DOCK		= 0x4010, /* docked into hotplug dock +						     or port replicator */ +	TP_HKEY_EV_HOTPLUG_UNDOCK	= 0x4011, /* undocked from hotplug +						     dock or port replicator */  	/* User-interface events */  	TP_HKEY_EV_LID_CLOSE		= 0x5001, /* laptop lid closed */ @@ -191,6 +193,10 @@ enum tpacpi_hkey_event_t {  	TP_HKEY_EV_PEN_REMOVED		= 0x500c, /* tablet pen removed */  	TP_HKEY_EV_BRGHT_CHANGED	= 0x5010, /* backlight control event */ +	/* Key-related user-interface events */ +	TP_HKEY_EV_KEY_NUMLOCK		= 0x6000, /* NumLock key pressed */ +	TP_HKEY_EV_KEY_FN		= 0x6005, /* Fn key pressed? E420 */ +  	/* Thermal events */  	TP_HKEY_EV_ALARM_BAT_HOT	= 0x6011, /* battery too hot */  	TP_HKEY_EV_ALARM_BAT_XHOT	= 0x6012, /* battery critically hot */ @@ -198,6 +204,9 @@ enum tpacpi_hkey_event_t {  	TP_HKEY_EV_ALARM_SENSOR_XHOT	= 0x6022, /* sensor critically hot */  	TP_HKEY_EV_THM_TABLE_CHANGED	= 0x6030, /* thermal table changed */ +	/* AC-related events */ +	TP_HKEY_EV_AC_CHANGED		= 0x6040, /* AC status changed */ +  	/* Misc */  	TP_HKEY_EV_RFKILL_CHANGED	= 0x7000, /* rfkill switch changed */  }; @@ -223,17 +232,6 @@ enum tpacpi_hkey_event_t {  #define TPACPI_MAX_ACPI_ARGS 3 -/* printk headers */ -#define TPACPI_LOG TPACPI_FILE ": " -#define TPACPI_EMERG	KERN_EMERG	TPACPI_LOG -#define TPACPI_ALERT	KERN_ALERT	TPACPI_LOG -#define TPACPI_CRIT	KERN_CRIT	TPACPI_LOG -#define TPACPI_ERR	KERN_ERR	TPACPI_LOG -#define TPACPI_WARN	KERN_WARNING	TPACPI_LOG -#define TPACPI_NOTICE	KERN_NOTICE	TPACPI_LOG -#define TPACPI_INFO	KERN_INFO	TPACPI_LOG -#define TPACPI_DEBUG	KERN_DEBUG	TPACPI_LOG -  /* Debugging printk groups */  #define TPACPI_DBG_ALL		0xffff  #define TPACPI_DBG_DISCLOSETASK	0x8000 @@ -273,7 +271,7 @@ struct ibm_struct {  	int (*write) (char *);  	void (*exit) (void);  	void (*resume) (void); -	void (*suspend) (pm_message_t state); +	void (*suspend) (void);  	void (*shutdown) (void);  	struct list_head all_drivers; @@ -293,7 +291,7 @@ struct ibm_init_struct {  	char param[32];  	int (*init) (struct ibm_init_struct *); -	mode_t base_procfs_mode; +	umode_t base_procfs_mode;  	struct ibm_struct *data;  }; @@ -366,7 +364,7 @@ struct tpacpi_led_classdev {  	struct led_classdev led_classdev;  	struct work_struct work;  	enum led_status_t new_state; -	unsigned int led; +	int led;  };  /* brightness level capabilities */ @@ -374,13 +372,13 @@ static unsigned int bright_maxlvl;	/* 0 = unknown */  #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES  static int dbg_wlswemul; -static int tpacpi_wlsw_emulstate; +static bool tpacpi_wlsw_emulstate;  static int dbg_bluetoothemul; -static int tpacpi_bluetooth_emulstate; +static bool tpacpi_bluetooth_emulstate;  static int dbg_wwanemul; -static int tpacpi_wwan_emulstate; +static bool tpacpi_wwan_emulstate;  static int dbg_uwbemul; -static int tpacpi_uwb_emulstate; +static bool tpacpi_uwb_emulstate;  #endif @@ -388,34 +386,36 @@ static int tpacpi_uwb_emulstate;   *  Debugging helpers   */ -#define dbg_printk(a_dbg_level, format, arg...) \ -	do { if (dbg_level & (a_dbg_level)) \ -		printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \ -	} while (0) +#define dbg_printk(a_dbg_level, format, arg...)				\ +do {									\ +	if (dbg_level & (a_dbg_level))					\ +		printk(KERN_DEBUG pr_fmt("%s: " format),		\ +		       __func__, ##arg);				\ +} while (0)  #ifdef CONFIG_THINKPAD_ACPI_DEBUG  #define vdbg_printk dbg_printk  static const char *str_supported(int is_supported);  #else -#define vdbg_printk(a_dbg_level, format, arg...) \ -	do { } while (0) +static inline const char *str_supported(int is_supported) { return ""; } +#define vdbg_printk(a_dbg_level, format, arg...)	\ +	no_printk(format, ##arg)  #endif  static void tpacpi_log_usertask(const char * const what)  { -	printk(TPACPI_DEBUG "%s: access by process with PID %d\n", -		what, task_tgid_vnr(current)); +	printk(KERN_DEBUG pr_fmt("%s: access by process with PID %d\n"), +	       what, task_tgid_vnr(current));  } -#define tpacpi_disclose_usertask(what, format, arg...) \ -	do { \ -		if (unlikely( \ -		    (dbg_level & TPACPI_DBG_DISCLOSETASK) && \ -		    (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \ -			printk(TPACPI_DEBUG "%s: PID %d: " format, \ -				what, task_tgid_vnr(current), ## arg); \ -		} \ -	} while (0) +#define tpacpi_disclose_usertask(what, format, arg...)			\ +do {									\ +	if (unlikely((dbg_level & TPACPI_DBG_DISCLOSETASK) &&		\ +		     (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) {	\ +		printk(KERN_DEBUG pr_fmt("%s: PID %d: " format),	\ +		       what, task_tgid_vnr(current), ## arg);		\ +	}								\ +} while (0)  /*   * Quirk handling helpers @@ -516,7 +516,7 @@ static acpi_handle ec_handle;  #define TPACPI_HANDLE(object, parent, paths...)			\  	static acpi_handle  object##_handle;			\ -	static const acpi_handle *object##_parent __initdata =	\ +	static const acpi_handle * const object##_parent __initconst =	\  						&parent##_handle; \  	static char *object##_paths[] __initdata = { paths } @@ -534,21 +534,12 @@ TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY",	/* 600e/x, 770e, 770x */  	   "HKEY",		/* all others */  	   );			/* 570 */ -TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA",	/* 570 */ -	   "\\_SB.PCI0.AGP0.VID0",	/* 600e/x, 770x */ -	   "\\_SB.PCI0.VID0",	/* 770e */ -	   "\\_SB.PCI0.VID",	/* A21e, G4x, R50e, X30, X40 */ -	   "\\_SB.PCI0.AGP.VGA",	/* X100e and a few others */ -	   "\\_SB.PCI0.AGP.VID",	/* all others */ -	   );				/* R30, R31 */ - -  /*************************************************************************   * ACPI helpers   */  static int acpi_evalf(acpi_handle handle, -		      void *res, char *method, char *fmt, ...) +		      int *res, char *method, char *fmt, ...)  {  	char *fmt0 = fmt;  	struct acpi_object_list params; @@ -562,7 +553,7 @@ static int acpi_evalf(acpi_handle handle,  	int quiet;  	if (!*fmt) { -		printk(TPACPI_ERR "acpi_evalf() called with empty format\n"); +		pr_err("acpi_evalf() called with empty format\n");  		return 0;  	} @@ -587,8 +578,9 @@ static int acpi_evalf(acpi_handle handle,  			break;  			/* add more types as needed */  		default: -			printk(TPACPI_ERR "acpi_evalf() called " +			pr_err("acpi_evalf() called "  			       "with invalid format character '%c'\n", c); +			va_end(ap);  			return 0;  		}  	} @@ -608,20 +600,20 @@ static int acpi_evalf(acpi_handle handle,  		success = (status == AE_OK &&  			   out_obj.type == ACPI_TYPE_INTEGER);  		if (success && res) -			*(int *)res = out_obj.integer.value; +			*res = out_obj.integer.value;  		break;  	case 'v':		/* void */  		success = status == AE_OK;  		break;  		/* add more types as needed */  	default: -		printk(TPACPI_ERR "acpi_evalf() called " +		pr_err("acpi_evalf() called "  		       "with invalid format character '%c'\n", res_type);  		return 0;  	}  	if (!success && !quiet) -		printk(TPACPI_ERR "acpi_evalf(%s, %s, ...) failed: %s\n", +		pr_err("acpi_evalf(%s, %s, ...) failed: %s\n",  		       method, fmt0, acpi_format_exception(status));  	return success; @@ -703,6 +695,14 @@ static void __init drv_acpi_handle_init(const char *name,  static acpi_status __init tpacpi_acpi_handle_locate_callback(acpi_handle handle,  			u32 level, void *context, void **return_value)  { +	struct acpi_device *dev; +	if (!strcmp(context, "video")) { +		if (acpi_bus_get_device(handle, &dev)) +			return AE_OK; +		if (strcmp(ACPI_VIDEO_HID, acpi_device_hid(dev))) +			return AE_OK; +	} +  	*(acpi_handle *)return_value = handle;  	return AE_CTRL_TERMINATE; @@ -715,10 +715,10 @@ static void __init tpacpi_acpi_handle_locate(const char *name,  	acpi_status status;  	acpi_handle device_found; -	BUG_ON(!name || !hid || !handle); +	BUG_ON(!name || !handle);  	vdbg_printk(TPACPI_DBG_INIT,  			"trying to locate ACPI handle for %s, using HID %s\n", -			name, hid); +			name, hid ? hid : "NULL");  	memset(&device_found, 0, sizeof(device_found));  	status = acpi_get_devices(hid, tpacpi_acpi_handle_locate_callback, @@ -765,8 +765,7 @@ static int __init setup_acpi_notify(struct ibm_struct *ibm)  	rc = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device);  	if (rc < 0) { -		printk(TPACPI_ERR "acpi_bus_get_device(%s) failed: %d\n", -			ibm->name, rc); +		pr_err("acpi_bus_get_device(%s) failed: %d\n", ibm->name, rc);  		return -ENODEV;  	} @@ -779,12 +778,10 @@ static int __init setup_acpi_notify(struct ibm_struct *ibm)  			ibm->acpi->type, dispatch_acpi_notify, ibm);  	if (ACPI_FAILURE(status)) {  		if (status == AE_ALREADY_EXISTS) { -			printk(TPACPI_NOTICE -			       "another device driver is already " -			       "handling %s events\n", ibm->name); +			pr_notice("another device driver is already " +				  "handling %s events\n", ibm->name);  		} else { -			printk(TPACPI_ERR -			       "acpi_install_notify_handler(%s) failed: %s\n", +			pr_err("acpi_install_notify_handler(%s) failed: %s\n",  			       ibm->name, acpi_format_exception(status));  		}  		return -ENODEV; @@ -809,8 +806,7 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)  	ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);  	if (!ibm->acpi->driver) { -		printk(TPACPI_ERR -		       "failed to allocate memory for ibm->acpi->driver\n"); +		pr_err("failed to allocate memory for ibm->acpi->driver\n");  		return -ENOMEM;  	} @@ -821,7 +817,7 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)  	rc = acpi_bus_register_driver(ibm->acpi->driver);  	if (rc < 0) { -		printk(TPACPI_ERR "acpi_bus_register_driver(%s) failed: %d\n", +		pr_err("acpi_bus_register_driver(%s) failed: %d\n",  		       ibm->name, rc);  		kfree(ibm->acpi->driver);  		ibm->acpi->driver = NULL; @@ -851,14 +847,14 @@ static int dispatch_proc_show(struct seq_file *m, void *v)  static int dispatch_proc_open(struct inode *inode, struct file *file)  { -	return single_open(file, dispatch_proc_show, PDE(inode)->data); +	return single_open(file, dispatch_proc_show, PDE_DATA(inode));  }  static ssize_t dispatch_proc_write(struct file *file,  			const char __user *userbuf,  			size_t count, loff_t *pos)  { -	struct ibm_struct *ibm = PDE(file->f_path.dentry->d_inode)->data; +	struct ibm_struct *ibm = PDE_DATA(file_inode(file));  	char *kernbuf;  	int ret; @@ -928,8 +924,8 @@ static struct input_dev *tpacpi_inputdev;  static struct mutex tpacpi_inputdev_send_mutex;  static LIST_HEAD(tpacpi_all_drivers); -static int tpacpi_suspend_handler(struct platform_device *pdev, -				  pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int tpacpi_suspend_handler(struct device *dev)  {  	struct ibm_struct *ibm, *itmp; @@ -937,13 +933,13 @@ static int tpacpi_suspend_handler(struct platform_device *pdev,  				 &tpacpi_all_drivers,  				 all_drivers) {  		if (ibm->suspend) -			(ibm->suspend)(state); +			(ibm->suspend)();  	}  	return 0;  } -static int tpacpi_resume_handler(struct platform_device *pdev) +static int tpacpi_resume_handler(struct device *dev)  {  	struct ibm_struct *ibm, *itmp; @@ -956,6 +952,10 @@ static int tpacpi_resume_handler(struct platform_device *pdev)  	return 0;  } +#endif + +static SIMPLE_DEV_PM_OPS(tpacpi_pm, +			 tpacpi_suspend_handler, tpacpi_resume_handler);  static void tpacpi_shutdown_handler(struct platform_device *pdev)  { @@ -973,9 +973,8 @@ static struct platform_driver tpacpi_pdriver = {  	.driver = {  		.name = TPACPI_DRVR_NAME,  		.owner = THIS_MODULE, +		.pm = &tpacpi_pm,  	}, -	.suspend = tpacpi_suspend_handler, -	.resume = tpacpi_resume_handler,  	.shutdown = tpacpi_shutdown_handler,  }; @@ -1079,15 +1078,14 @@ static int parse_strtoul(const char *buf,  static void tpacpi_disable_brightness_delay(void)  {  	if (acpi_evalf(hkey_handle, NULL, "PWMS", "qvd", 0)) -		printk(TPACPI_NOTICE -			"ACPI backlight control delay disabled\n"); +		pr_notice("ACPI backlight control delay disabled\n");  }  static void printk_deprecated_attribute(const char * const what,  					const char * const details)  {  	tpacpi_log_usertask("deprecated sysfs attribute"); -	printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and " +	pr_warn("WARNING: sysfs attribute %s is deprecated and "  		"will be removed. %s\n",  		what, details);  } @@ -1262,8 +1260,7 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,  						&tpacpi_rfk_rfkill_ops,  						atp_rfk);  	if (!atp_rfk || !atp_rfk->rfkill) { -		printk(TPACPI_ERR -			"failed to allocate memory for rfkill class\n"); +		pr_err("failed to allocate memory for rfkill class\n");  		kfree(atp_rfk);  		return -ENOMEM;  	} @@ -1273,9 +1270,8 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,  	sw_status = (tp_rfkops->get_status)();  	if (sw_status < 0) { -		printk(TPACPI_ERR -			"failed to read initial state for %s, error %d\n", -			name, sw_status); +		pr_err("failed to read initial state for %s, error %d\n", +		       name, sw_status);  	} else {  		sw_state = (sw_status == TPACPI_RFK_RADIO_OFF);  		if (set_default) { @@ -1289,9 +1285,7 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,  	res = rfkill_register(atp_rfk->rfkill);  	if (res < 0) { -		printk(TPACPI_ERR -			"failed to register %s rfkill switch: %d\n", -			name, res); +		pr_err("failed to register %s rfkill switch: %d\n", name, res);  		rfkill_destroy(atp_rfk->rfkill);  		kfree(atp_rfk);  		return res; @@ -1299,7 +1293,7 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,  	tpacpi_rfkill_switches[id] = atp_rfk; -	printk(TPACPI_INFO "rfkill switch %s: radio is %sblocked\n", +	pr_info("rfkill switch %s: radio is %sblocked\n",  		name, (sw_state || hw_state) ? "" : "un");  	return 0;  } @@ -1823,10 +1817,8 @@ static void __init tpacpi_check_outdated_fw(void)  		 * broken, or really stable to begin with, so it is  		 * best if the user upgrades the firmware anyway.  		 */ -		printk(TPACPI_WARN -			"WARNING: Outdated ThinkPad BIOS/EC firmware\n"); -		printk(TPACPI_WARN -			"WARNING: This firmware may be missing critical bug " +		pr_warn("WARNING: Outdated ThinkPad BIOS/EC firmware\n"); +		pr_warn("WARNING: This firmware may be missing critical bug "  			"fixes and/or important features\n");  	}  } @@ -1975,9 +1967,6 @@ struct tp_nvram_state {  /* kthread for the hotkey poller */  static struct task_struct *tpacpi_hotkey_task; -/* Acquired while the poller kthread is running, use to sync start/stop */ -static struct mutex hotkey_thread_mutex; -  /*   * Acquire mutex to write poller control variables as an   * atomic block. @@ -2036,8 +2025,6 @@ static u32 hotkey_driver_mask;		/* events needed by the driver */  static u32 hotkey_user_mask;		/* events visible to userspace */  static u32 hotkey_acpi_mask;		/* events enabled in firmware */ -static unsigned int hotkey_report_mode; -  static u16 *hotkey_keycode_map;  static struct attribute_set *hotkey_dev_attributes; @@ -2115,9 +2102,7 @@ void static hotkey_mask_warn_incomplete_mask(void)  		(hotkey_all_mask | TPACPI_HKEY_NVRAM_KNOWN_MASK);  	if (wantedmask) -		printk(TPACPI_NOTICE -			"required events 0x%08x not enabled!\n", -			wantedmask); +		pr_notice("required events 0x%08x not enabled!\n", wantedmask);  }  /* @@ -2155,10 +2140,9 @@ static int hotkey_mask_set(u32 mask)  	 * a given event.  	 */  	if (!hotkey_mask_get() && !rc && (fwmask & ~hotkey_acpi_mask)) { -		printk(TPACPI_NOTICE -		       "asked for hotkey mask 0x%08x, but " -		       "firmware forced it to 0x%08x\n", -		       fwmask, hotkey_acpi_mask); +		pr_notice("asked for hotkey mask 0x%08x, but " +			  "firmware forced it to 0x%08x\n", +			  fwmask, hotkey_acpi_mask);  	}  	if (tpacpi_lifecycle != TPACPI_LIFE_EXITING) @@ -2182,13 +2166,11 @@ static int hotkey_user_mask_set(const u32 mask)  	    (mask == 0xffff || mask == 0xffffff ||  	     mask == 0xffffffff)) {  		tp_warned.hotkey_mask_ff = 1; -		printk(TPACPI_NOTICE -		       "setting the hotkey mask to 0x%08x is likely " -		       "not the best way to go about it\n", mask); -		printk(TPACPI_NOTICE -		       "please consider using the driver defaults, " -		       "and refer to up-to-date thinkpad-acpi " -		       "documentation\n"); +		pr_notice("setting the hotkey mask to 0x%08x is likely " +			  "not the best way to go about it\n", mask); +		pr_notice("please consider using the driver defaults, " +			  "and refer to up-to-date thinkpad-acpi " +			  "documentation\n");  	}  	/* Try to enable what the user asked for, plus whatever we need. @@ -2274,16 +2256,12 @@ static void tpacpi_input_send_key(const unsigned int scancode)  	if (keycode != KEY_RESERVED) {  		mutex_lock(&tpacpi_inputdev_send_mutex); +		input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, scancode);  		input_report_key(tpacpi_inputdev, keycode, 1); -		if (keycode == KEY_UNKNOWN) -			input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, -				    scancode);  		input_sync(tpacpi_inputdev); +		input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, scancode);  		input_report_key(tpacpi_inputdev, keycode, 0); -		if (keycode == KEY_UNKNOWN) -			input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, -				    scancode);  		input_sync(tpacpi_inputdev);  		mutex_unlock(&tpacpi_inputdev_send_mutex); @@ -2305,10 +2283,6 @@ static struct tp_acpi_drv_struct ibm_hotkey_acpidriver;  static void tpacpi_hotkey_send_key(unsigned int scancode)  {  	tpacpi_input_send_key_masked(scancode); -	if (hotkey_report_mode < 2) { -		acpi_bus_generate_proc_event(ibm_hotkey_acpidriver.device, -				0x80, TP_HKEY_EV_HOTKEY_BASE + scancode); -	}  }  static void hotkey_read_nvram(struct tp_nvram_state *n, const u32 m) @@ -2347,53 +2321,55 @@ static void hotkey_read_nvram(struct tp_nvram_state *n, const u32 m)  	}  } -static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn, -					   struct tp_nvram_state *newn, -					   const u32 event_mask) -{ -  #define TPACPI_COMPARE_KEY(__scancode, __member) \ -	do { \ -		if ((event_mask & (1 << __scancode)) && \ -		    oldn->__member != newn->__member) \ -			tpacpi_hotkey_send_key(__scancode); \ -	} while (0) +do { \ +	if ((event_mask & (1 << __scancode)) && \ +	    oldn->__member != newn->__member) \ +		tpacpi_hotkey_send_key(__scancode); \ +} while (0)  #define TPACPI_MAY_SEND_KEY(__scancode) \ -	do { \ -		if (event_mask & (1 << __scancode)) \ -			tpacpi_hotkey_send_key(__scancode); \ -	} while (0) +do { \ +	if (event_mask & (1 << __scancode)) \ +		tpacpi_hotkey_send_key(__scancode); \ +} while (0) -	void issue_volchange(const unsigned int oldvol, -			     const unsigned int newvol) -	{ -		unsigned int i = oldvol; +static void issue_volchange(const unsigned int oldvol, +			    const unsigned int newvol, +			    const u32 event_mask) +{ +	unsigned int i = oldvol; -		while (i > newvol) { -			TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN); -			i--; -		} -		while (i < newvol) { -			TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP); -			i++; -		} +	while (i > newvol) { +		TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEDOWN); +		i--;  	} +	while (i < newvol) { +		TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP); +		i++; +	} +} -	void issue_brightnesschange(const unsigned int oldbrt, -				    const unsigned int newbrt) -	{ -		unsigned int i = oldbrt; +static void issue_brightnesschange(const unsigned int oldbrt, +				   const unsigned int newbrt, +				   const u32 event_mask) +{ +	unsigned int i = oldbrt; -		while (i > newbrt) { -			TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND); -			i--; -		} -		while (i < newbrt) { -			TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME); -			i++; -		} +	while (i > newbrt) { +		TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNEND); +		i--; +	} +	while (i < newbrt) { +		TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_FNHOME); +		i++;  	} +} + +static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn, +					   struct tp_nvram_state *newn, +					   const u32 event_mask) +{  	TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle);  	TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle); @@ -2410,7 +2386,7 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,  	 * This code is supposed to duplicate the IBM firmware behaviour:  	 * - Pressing MUTE issues mute hotkey message, even when already mute  	 * - Pressing Volume up/down issues volume up/down hotkey messages, -	 *   even when already at maximum or minumum volume +	 *   even when already at maximum or minimum volume  	 * - The act of unmuting issues volume up/down notification,  	 *   depending which key was used to unmute  	 * @@ -2428,7 +2404,8 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,  		    oldn->volume_level != newn->volume_level) {  			/* recently muted, or repeated mute keypress, or  			 * multiple presses ending in mute */ -			issue_volchange(oldn->volume_level, newn->volume_level); +			issue_volchange(oldn->volume_level, newn->volume_level, +				event_mask);  			TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_MUTE);  		}  	} else { @@ -2438,7 +2415,8 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,  			TPACPI_MAY_SEND_KEY(TP_ACPI_HOTKEYSCAN_VOLUMEUP);  		}  		if (oldn->volume_level != newn->volume_level) { -			issue_volchange(oldn->volume_level, newn->volume_level); +			issue_volchange(oldn->volume_level, newn->volume_level, +				event_mask);  		} else if (oldn->volume_toggle != newn->volume_toggle) {  			/* repeated vol up/down keypress at end of scale ? */  			if (newn->volume_level == 0) @@ -2451,7 +2429,7 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,  	/* handle brightness */  	if (oldn->brightness_level != newn->brightness_level) {  		issue_brightnesschange(oldn->brightness_level, -				       newn->brightness_level); +				       newn->brightness_level, event_mask);  	} else if (oldn->brightness_toggle != newn->brightness_toggle) {  		/* repeated key presses that didn't change state */  		if (newn->brightness_level == 0) @@ -2478,10 +2456,9 @@ static int hotkey_kthread(void *data)  	u32 poll_mask, event_mask;  	unsigned int si, so;  	unsigned long t; -	unsigned int change_detector, must_reset; +	unsigned int change_detector;  	unsigned int poll_freq; - -	mutex_lock(&hotkey_thread_mutex); +	bool was_frozen;  	if (tpacpi_lifecycle == TPACPI_LIFE_EXITING)  		goto exit; @@ -2510,14 +2487,14 @@ static int hotkey_kthread(void *data)  				t = 100;	/* should never happen... */  		}  		t = msleep_interruptible(t); -		if (unlikely(kthread_should_stop())) +		if (unlikely(kthread_freezable_should_stop(&was_frozen)))  			break; -		must_reset = try_to_freeze(); -		if (t > 0 && !must_reset) + +		if (t > 0 && !was_frozen)  			continue;  		mutex_lock(&hotkey_thread_data_mutex); -		if (must_reset || hotkey_config_change != change_detector) { +		if (was_frozen || hotkey_config_change != change_detector) {  			/* forget old state on thaw or config change */  			si = so;  			t = 0; @@ -2542,7 +2519,6 @@ static int hotkey_kthread(void *data)  	}  exit: -	mutex_unlock(&hotkey_thread_mutex);  	return 0;  } @@ -2550,15 +2526,8 @@ exit:  static void hotkey_poll_stop_sync(void)  {  	if (tpacpi_hotkey_task) { -		if (frozen(tpacpi_hotkey_task) || -		    freezing(tpacpi_hotkey_task)) -			thaw_process(tpacpi_hotkey_task); -  		kthread_stop(tpacpi_hotkey_task);  		tpacpi_hotkey_task = NULL; -		mutex_lock(&hotkey_thread_mutex); -		/* at this point, the thread did exit */ -		mutex_unlock(&hotkey_thread_mutex);  	}  } @@ -2576,8 +2545,7 @@ static void hotkey_poll_setup(const bool may_warn)  					NULL, TPACPI_NVRAM_KTHREAD_NAME);  			if (IS_ERR(tpacpi_hotkey_task)) {  				tpacpi_hotkey_task = NULL; -				printk(TPACPI_ERR -				       "could not create kernel thread " +				pr_err("could not create kernel thread "  				       "for hotkey polling\n");  			}  		} @@ -2585,11 +2553,10 @@ static void hotkey_poll_setup(const bool may_warn)  		hotkey_poll_stop_sync();  		if (may_warn && (poll_driver_mask || poll_user_mask) &&  		    hotkey_poll_freq == 0) { -			printk(TPACPI_NOTICE -				"hot keys 0x%08x and/or events 0x%08x " -				"require polling, which is currently " -				"disabled\n", -				poll_user_mask, poll_driver_mask); +			pr_notice("hot keys 0x%08x and/or events 0x%08x " +				  "require polling, which is currently " +				  "disabled\n", +				  poll_user_mask, poll_driver_mask);  		}  	}  } @@ -2813,13 +2780,13 @@ static ssize_t hotkey_source_mask_store(struct device *dev,  	mutex_unlock(&hotkey_mutex);  	if (rc < 0) -		printk(TPACPI_ERR "hotkey_source_mask: failed to update the" -			"firmware event mask!\n"); +		pr_err("hotkey_source_mask: " +		       "failed to update the firmware event mask!\n");  	if (r_ev) -		printk(TPACPI_NOTICE "hotkey_source_mask: " -			"some important events were disabled: " -			"0x%04x\n", r_ev); +		pr_notice("hotkey_source_mask: " +			  "some important events were disabled: 0x%04x\n", +			  r_ev);  	tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t); @@ -2916,18 +2883,6 @@ static void hotkey_tablet_mode_notify_change(void)  			     "hotkey_tablet_mode");  } -/* sysfs hotkey report_mode -------------------------------------------- */ -static ssize_t hotkey_report_mode_show(struct device *dev, -			   struct device_attribute *attr, -			   char *buf) -{ -	return snprintf(buf, PAGE_SIZE, "%d\n", -		(hotkey_report_mode != 0) ? hotkey_report_mode : 1); -} - -static struct device_attribute dev_attr_hotkey_report_mode = -	__ATTR(hotkey_report_mode, S_IRUGO, hotkey_report_mode_show, NULL); -  /* sysfs wakeup reason (pollable) -------------------------------------- */  static ssize_t hotkey_wakeup_reason_show(struct device *dev,  			   struct device_attribute *attr, @@ -2969,7 +2924,6 @@ static struct attribute *hotkey_attributes[] __initdata = {  	&dev_attr_hotkey_enable.attr,  	&dev_attr_hotkey_bios_enabled.attr,  	&dev_attr_hotkey_bios_mask.attr, -	&dev_attr_hotkey_report_mode.attr,  	&dev_attr_hotkey_wakeup_reason.attr,  	&dev_attr_hotkey_wakeup_hotunplug_complete.attr,  	&dev_attr_hotkey_mask.attr, @@ -2993,7 +2947,7 @@ static void tpacpi_send_radiosw_update(void)  	 * rfkill input events, or we will race the rfkill core input  	 * handler.  	 * -	 * tpacpi_inputdev_send_mutex works as a syncronization point +	 * tpacpi_inputdev_send_mutex works as a synchronization point  	 * for the above.  	 *  	 * We optimize to avoid numerous calls to hotkey_get_wlsw. @@ -3041,8 +2995,6 @@ static void hotkey_exit(void)  	if (hotkey_dev_attributes)  		delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); -	kfree(hotkey_keycode_map); -  	dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY,  		   "restoring original HKEY status and mask\n");  	/* yes, there is a bitwise or below, we want the @@ -3050,8 +3002,7 @@ static void hotkey_exit(void)  	if (((tp_features.hotkey_mask &&  	      hotkey_mask_set(hotkey_orig_mask)) |  	     hotkey_status_set(false)) != 0) -		printk(TPACPI_ERR -		       "failed to restore hot key mask " +		pr_err("failed to restore hot key mask "  		       "to BIOS defaults\n");  } @@ -3211,8 +3162,19 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)  		KEY_VENDOR,	/* 0x17: Thinkpad/AccessIBM/Lenovo */  		/* (assignments unknown, please report if found) */ -		KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, -		KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, +		KEY_UNKNOWN, KEY_UNKNOWN, + +		/* +		 * The mic mute button only sends 0x1a.  It does not +		 * automatically mute the mic or change the mute light. +		 */ +		KEY_MICMUTE,	/* 0x1a: Mic mute (since ?400 or so) */ + +		/* (assignments unknown, please report if found) */ +		KEY_UNKNOWN, + +		/* Extra keys in use since the X240 / T440 / T540 */ +		KEY_CONFIG, KEY_SEARCH, KEY_SCALE, KEY_COMPUTER,  		},  	}; @@ -3253,7 +3215,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)  	mutex_init(&hotkey_mutex);  #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL -	mutex_init(&hotkey_thread_mutex);  	mutex_init(&hotkey_thread_data_mutex);  #endif @@ -3290,10 +3251,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)  	   for HKEY interface version 0x100 */  	if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {  		if ((hkeyv >> 8) != 1) { -			printk(TPACPI_ERR "unknown version of the " -			       "HKEY interface: 0x%x\n", hkeyv); -			printk(TPACPI_ERR "please report this to %s\n", -			       TPACPI_MAIL); +			pr_err("unknown version of the HKEY interface: 0x%x\n", +			       hkeyv); +			pr_err("please report this to %s\n", TPACPI_MAIL);  		} else {  			/*  			 * MHKV 0x100 in A31, R40, R40e, @@ -3306,8 +3266,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)  			/* Paranoia check AND init hotkey_all_mask */  			if (!acpi_evalf(hkey_handle, &hotkey_all_mask,  					"MHKA", "qd")) { -				printk(TPACPI_ERR -				       "missing MHKA handler, " +				pr_err("missing MHKA handler, "  				       "please report this to %s\n",  				       TPACPI_MAIL);  				/* Fallback: pre-init for FN+F3,F4,F12 */ @@ -3345,16 +3304,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)  	if (dbg_wlswemul) {  		tp_features.hotkey_wlsw = 1;  		radiosw_state = !!tpacpi_wlsw_emulstate; -		printk(TPACPI_INFO -			"radio switch emulation enabled\n"); +		pr_info("radio switch emulation enabled\n");  	} else  #endif  	/* Not all thinkpads have a hardware radio switch */  	if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {  		tp_features.hotkey_wlsw = 1;  		radiosw_state = !!status; -		printk(TPACPI_INFO -			"radio switch found; radios are %s\n", +		pr_info("radio switch found; radios are %s\n",  			enabled(status, 0));  	}  	if (tp_features.hotkey_wlsw) @@ -3365,8 +3322,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)  	if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) {  		tp_features.hotkey_tablet = 1;  		tabletsw_state = !!(status & TP_HOTKEY_TABLET_MASK); -		printk(TPACPI_INFO -			"possible tablet mode switch found; " +		pr_info("possible tablet mode switch found; "  			"ThinkPad in %s mode\n",  			(tabletsw_state) ? "tablet" : "laptop");  		res = add_to_attr_set(hotkey_dev_attributes, @@ -3384,8 +3340,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)  	hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,  					GFP_KERNEL);  	if (!hotkey_keycode_map) { -		printk(TPACPI_ERR -			"failed to allocate memory for key map\n"); +		pr_err("failed to allocate memory for key map\n");  		res = -ENOMEM;  		goto err_exit;  	} @@ -3427,14 +3382,12 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)  	/* Do not issue duplicate brightness change events to  	 * userspace. tpacpi_detect_brightness_capabilities() must have  	 * been called before this point  */ -	if (tp_features.bright_acpimode && acpi_video_backlight_support()) { -		printk(TPACPI_INFO -		       "This ThinkPad has standard ACPI backlight " -		       "brightness control, supported by the ACPI " -		       "video driver\n"); -		printk(TPACPI_NOTICE -		       "Disabling thinkpad-acpi brightness events " -		       "by default...\n"); +	if (acpi_video_backlight_support()) { +		pr_info("This ThinkPad has standard ACPI backlight " +			"brightness control, supported by the ACPI " +			"video driver\n"); +		pr_notice("Disabling thinkpad-acpi brightness events " +			  "by default...\n");  		/* Disable brightness up/down on Lenovo thinkpads when  		 * ACPI is handling them, otherwise it is plain impossible @@ -3476,11 +3429,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)  		"initial masks: user=0x%08x, fw=0x%08x, poll=0x%08x\n",  		hotkey_user_mask, hotkey_acpi_mask, hotkey_source_mask); -	dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, -			"legacy ibm/hotkey event reporting over procfs %s\n", -			(hotkey_report_mode < 2) ? -				"enabled" : "disabled"); -  	tpacpi_inputdev->open = &hotkey_inputdev_open;  	tpacpi_inputdev->close = &hotkey_inputdev_close; @@ -3495,6 +3443,106 @@ err_exit:  	return (res < 0)? res : 1;  } +/* Thinkpad X1 Carbon support 5 modes including Home mode, Web browser + * mode, Web conference mode, Function mode and Lay-flat mode. + * We support Home mode and Function mode currently. + * + * Will consider support rest of modes in future. + * + */ +enum ADAPTIVE_KEY_MODE { +	HOME_MODE, +	WEB_BROWSER_MODE, +	WEB_CONFERENCE_MODE, +	FUNCTION_MODE, +	LAYFLAT_MODE +}; + +const int adaptive_keyboard_modes[] = { +	HOME_MODE, +/*	WEB_BROWSER_MODE = 2, +	WEB_CONFERENCE_MODE = 3, */ +	FUNCTION_MODE +}; + +#define DFR_CHANGE_ROW			0x101 +#define DFR_SHOW_QUICKVIEW_ROW		0x102 + +/* press Fn key a while second, it will switch to Function Mode. Then + * release Fn key, previous mode be restored. + */ +static bool adaptive_keyboard_mode_is_saved; +static int adaptive_keyboard_prev_mode; + +static int adaptive_keyboard_get_next_mode(int mode) +{ +	size_t i; +	size_t max_mode = ARRAY_SIZE(adaptive_keyboard_modes) - 1; + +	for (i = 0; i <= max_mode; i++) { +		if (adaptive_keyboard_modes[i] == mode) +			break; +	} + +	if (i >= max_mode) +		i = 0; +	else +		i++; + +	return adaptive_keyboard_modes[i]; +} + +static bool adaptive_keyboard_hotkey_notify_hotkey(unsigned int scancode) +{ +	u32 current_mode = 0; +	int new_mode = 0; + +	switch (scancode) { +	case DFR_CHANGE_ROW: +		if (adaptive_keyboard_mode_is_saved) { +			new_mode = adaptive_keyboard_prev_mode; +			adaptive_keyboard_mode_is_saved = false; +		} else { +			if (!acpi_evalf( +					hkey_handle, ¤t_mode, +					"GTRW", "dd", 0)) { +				pr_err("Cannot read adaptive keyboard mode\n"); +				return false; +			} else { +				new_mode = adaptive_keyboard_get_next_mode( +						current_mode); +			} +		} + +		if (!acpi_evalf(hkey_handle, NULL, "STRW", "vd", new_mode)) { +			pr_err("Cannot set adaptive keyboard mode\n"); +			return false; +		} + +		return true; + +	case DFR_SHOW_QUICKVIEW_ROW: +		if (!acpi_evalf(hkey_handle, +				&adaptive_keyboard_prev_mode, +				"GTRW", "dd", 0)) { +			pr_err("Cannot read adaptive keyboard mode\n"); +			return false; +		} else { +			adaptive_keyboard_mode_is_saved = true; + +			if (!acpi_evalf(hkey_handle, +					NULL, "STRW", "vd", FUNCTION_MODE)) { +				pr_err("Cannot set adaptive keyboard mode\n"); +				return false; +			} +		} +		return true; + +	default: +		return false; +	} +} +  static bool hotkey_notify_hotkey(const u32 hkey,  				 bool *send_acpi_ev,  				 bool *ignore_acpi_ev) @@ -3514,6 +3562,8 @@ static bool hotkey_notify_hotkey(const u32 hkey,  			*ignore_acpi_ev = true;  		}  		return true; +	} else { +		return adaptive_keyboard_hotkey_notify_hotkey(scancode);  	}  	return false;  } @@ -3541,8 +3591,7 @@ static bool hotkey_notify_wakeup(const u32 hkey,  	case TP_HKEY_EV_WKUP_S3_BATLOW: /* Battery on critical low level/S3 */  	case TP_HKEY_EV_WKUP_S4_BATLOW: /* Battery on critical low level/S4 */ -		printk(TPACPI_ALERT -			"EMERGENCY WAKEUP: battery almost empty\n"); +		pr_alert("EMERGENCY WAKEUP: battery almost empty\n");  		/* how to auto-heal: */  		/* 2313: woke up from S3, go to S4/S5 */  		/* 2413: woke up from S4, go to S5 */ @@ -3553,14 +3602,40 @@ static bool hotkey_notify_wakeup(const u32 hkey,  	}  	if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) { -		printk(TPACPI_INFO -		       "woke up due to a hot-unplug " -		       "request...\n"); +		pr_info("woke up due to a hot-unplug request...\n");  		hotkey_wakeup_reason_notify_change();  	}  	return true;  } +static bool hotkey_notify_dockevent(const u32 hkey, +				 bool *send_acpi_ev, +				 bool *ignore_acpi_ev) +{ +	/* 0x4000-0x4FFF: dock-related events */ +	*send_acpi_ev = true; +	*ignore_acpi_ev = false; + +	switch (hkey) { +	case TP_HKEY_EV_UNDOCK_ACK: +		/* ACPI undock operation completed after wakeup */ +		hotkey_autosleep_ack = 1; +		pr_info("undocked\n"); +		hotkey_wakeup_hotunplug_complete_notify_change(); +		return true; + +	case TP_HKEY_EV_HOTPLUG_DOCK: /* docked to port replicator */ +		pr_info("docked into hotplug port replicator\n"); +		return true; +	case TP_HKEY_EV_HOTPLUG_UNDOCK: /* undocked from port replicator */ +		pr_info("undocked from hotplug port replicator\n"); +		return true; + +	default: +		return false; +	} +} +  static bool hotkey_notify_usrevent(const u32 hkey,  				 bool *send_acpi_ev,  				 bool *ignore_acpi_ev) @@ -3595,49 +3670,58 @@ static bool hotkey_notify_usrevent(const u32 hkey,  static void thermal_dump_all_sensors(void); -static bool hotkey_notify_thermal(const u32 hkey, +static bool hotkey_notify_6xxx(const u32 hkey,  				 bool *send_acpi_ev,  				 bool *ignore_acpi_ev)  {  	bool known = true; -	/* 0x6000-0x6FFF: thermal alarms */ +	/* 0x6000-0x6FFF: thermal alarms/notices and keyboard events */  	*send_acpi_ev = true;  	*ignore_acpi_ev = false;  	switch (hkey) {  	case TP_HKEY_EV_THM_TABLE_CHANGED: -		printk(TPACPI_INFO -			"EC reports that Thermal Table has changed\n"); +		pr_info("EC reports that Thermal Table has changed\n");  		/* recommended action: do nothing, we don't have  		 * Lenovo ATM information */  		return true;  	case TP_HKEY_EV_ALARM_BAT_HOT: -		printk(TPACPI_CRIT -			"THERMAL ALARM: battery is too hot!\n"); +		pr_crit("THERMAL ALARM: battery is too hot!\n");  		/* recommended action: warn user through gui */  		break;  	case TP_HKEY_EV_ALARM_BAT_XHOT: -		printk(TPACPI_ALERT -			"THERMAL EMERGENCY: battery is extremely hot!\n"); +		pr_alert("THERMAL EMERGENCY: battery is extremely hot!\n");  		/* recommended action: immediate sleep/hibernate */  		break;  	case TP_HKEY_EV_ALARM_SENSOR_HOT: -		printk(TPACPI_CRIT -			"THERMAL ALARM: " +		pr_crit("THERMAL ALARM: "  			"a sensor reports something is too hot!\n");  		/* recommended action: warn user through gui, that */  		/* some internal component is too hot */  		break;  	case TP_HKEY_EV_ALARM_SENSOR_XHOT: -		printk(TPACPI_ALERT -			"THERMAL EMERGENCY: " -			"a sensor reports something is extremely hot!\n"); +		pr_alert("THERMAL EMERGENCY: " +			 "a sensor reports something is extremely hot!\n");  		/* recommended action: immediate sleep/hibernate */  		break; +	case TP_HKEY_EV_AC_CHANGED: +		/* X120e, X121e, X220, X220i, X220t, X230, T420, T420s, W520: +		 * AC status changed; can be triggered by plugging or +		 * unplugging AC adapter, docking or undocking. */ + +		/* fallthrough */ + +	case TP_HKEY_EV_KEY_NUMLOCK: +	case TP_HKEY_EV_KEY_FN: +		/* key press events, we just ignore them as long as the EC +		 * is still reporting them in the normal keyboard stream */ +		*send_acpi_ev = false; +		*ignore_acpi_ev = true; +		return true; +  	default: -		printk(TPACPI_ALERT -			 "THERMAL ALERT: unknown thermal alarm received\n"); +		pr_warn("unknown possible thermal alarm or keyboard event received\n");  		known = false;  	} @@ -3654,8 +3738,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)  	bool known_ev;  	if (event != 0x80) { -		printk(TPACPI_ERR -		       "unknown HKEY notification event %d\n", event); +		pr_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, @@ -3666,7 +3749,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)  	while (1) {  		if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { -			printk(TPACPI_ERR "failed to retrieve HKEY event\n"); +			pr_err("failed to retrieve HKEY event\n");  			return;  		} @@ -3694,8 +3777,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)  			switch (hkey) {  			case TP_HKEY_EV_BAYEJ_ACK:  				hotkey_autosleep_ack = 1; -				printk(TPACPI_INFO -				       "bay ejected\n"); +				pr_info("bay ejected\n");  				hotkey_wakeup_hotunplug_complete_notify_change();  				known_ev = true;  				break; @@ -3708,16 +3790,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)  			}  			break;  		case 4: -			/* 0x4000-0x4FFF: dock-related wakeups */ -			if (hkey == TP_HKEY_EV_UNDOCK_ACK) { -				hotkey_autosleep_ack = 1; -				printk(TPACPI_INFO -				       "undocked\n"); -				hotkey_wakeup_hotunplug_complete_notify_change(); -				known_ev = true; -			} else { -				known_ev = false; -			} +			/* 0x4000-0x4FFF: dock-related events */ +			known_ev = hotkey_notify_dockevent(hkey, &send_acpi_ev, +						&ignore_acpi_ev);  			break;  		case 5:  			/* 0x5000-0x5FFF: human interface helpers */ @@ -3725,8 +3800,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)  						 &ignore_acpi_ev);  			break;  		case 6: -			/* 0x6000-0x6FFF: thermal alarms */ -			known_ev = hotkey_notify_thermal(hkey, &send_acpi_ev, +			/* 0x6000-0x6FFF: thermal alarms/notices and +			 *                keyboard events */ +			known_ev = hotkey_notify_6xxx(hkey, &send_acpi_ev,  						 &ignore_acpi_ev);  			break;  		case 7: @@ -3743,18 +3819,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)  			known_ev = false;  		}  		if (!known_ev) { -			printk(TPACPI_NOTICE -			       "unhandled HKEY event 0x%04x\n", hkey); -			printk(TPACPI_NOTICE -			       "please report the conditions when this " -			       "event happened to %s\n", TPACPI_MAIL); -		} - -		/* Legacy events */ -		if (!ignore_acpi_ev && -		    (send_acpi_ev || hotkey_report_mode < 2)) { -			acpi_bus_generate_proc_event(ibm->acpi->device, -						     event, hkey); +			pr_notice("unhandled HKEY event 0x%04x\n", hkey); +			pr_notice("please report the conditions when this " +				  "event happened to %s\n", TPACPI_MAIL);  		}  		/* netlink events */ @@ -3767,21 +3834,35 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)  	}  } -static void hotkey_suspend(pm_message_t state) +static void hotkey_suspend(void)  { +	int hkeyv; +  	/* Do these on suspend, we get the events on early resume! */  	hotkey_wakeup_reason = TP_ACPI_WAKEUP_NONE;  	hotkey_autosleep_ack = 0; + +	/* save previous mode of adaptive keyboard of X1 Carbon */ +	if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { +		if ((hkeyv >> 8) == 2) { +			if (!acpi_evalf(hkey_handle, +						&adaptive_keyboard_prev_mode, +						"GTRW", "dd", 0)) { +				pr_err("Cannot read adaptive keyboard mode.\n"); +			} +		} +	}  }  static void hotkey_resume(void)  { +	int hkeyv; +  	tpacpi_disable_brightness_delay();  	if (hotkey_status_set(true) < 0 ||  	    hotkey_mask_set(hotkey_acpi_mask) < 0) -		printk(TPACPI_ERR -		       "error while attempting to reset the event " +		pr_err("error while attempting to reset the event "  		       "firmware interface\n");  	tpacpi_send_radiosw_update(); @@ -3789,6 +3870,18 @@ static void hotkey_resume(void)  	hotkey_wakeup_reason_notify_change();  	hotkey_wakeup_hotunplug_complete_notify_change();  	hotkey_poll_setup_safe(false); + +	/* restore previous mode of adapive keyboard of X1 Carbon */ +	if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { +		if ((hkeyv >> 8) == 2) { +			if (!acpi_evalf(hkey_handle, +						NULL, +						"STRW", "vd", +						adaptive_keyboard_prev_mode)) { +				pr_err("Cannot set adaptive keyboard mode.\n"); +			} +		} +	}  }  /* procfs -------------------------------------------------------------- */ @@ -3826,14 +3919,12 @@ static void hotkey_enabledisable_warn(bool enable)  {  	tpacpi_log_usertask("procfs hotkey enable/disable");  	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"); +		  pr_fmt("hotkey enable/disable functionality has been " +			 "removed from the driver.  " +			 "Hotkeys are always enabled.\n"))) +		pr_err("Please remove the hotkey=enable module " +		       "parameter, it is deprecated.  " +		       "Hotkeys are always enabled.\n");  }  static int hotkey_write(char *buf) @@ -3882,7 +3973,8 @@ errexit:  }  static const struct acpi_device_id ibm_htk_device_ids[] = { -	{TPACPI_ACPI_HKEY_HID, 0}, +	{TPACPI_ACPI_IBM_HKEY_HID, 0}, +	{TPACPI_ACPI_LENOVO_HKEY_HID, 0},  	{"", 0},  }; @@ -4012,11 +4104,10 @@ static void bluetooth_shutdown(void)  	/* Order firmware to save current state to NVRAM */  	if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",  			TP_ACPI_BLTH_SAVE_STATE)) -		printk(TPACPI_NOTICE -			"failed to save bluetooth state to NVRAM\n"); +		pr_notice("failed to save bluetooth state to NVRAM\n");  	else  		vdbg_printk(TPACPI_DBG_RFKILL, -			"bluestooth state saved to NVRAM\n"); +			"bluetooth state saved to NVRAM\n");  }  static void bluetooth_exit(void) @@ -4052,8 +4143,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)  #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES  	if (dbg_bluetoothemul) {  		tp_features.bluetooth = 1; -		printk(TPACPI_INFO -			"bluetooth switch emulation enabled\n"); +		pr_info("bluetooth switch emulation enabled\n");  	} else  #endif  	if (tp_features.bluetooth && @@ -4204,8 +4294,7 @@ static void wan_shutdown(void)  	/* Order firmware to save current state to NVRAM */  	if (!acpi_evalf(NULL, NULL, "\\WGSV", "vd",  			TP_ACPI_WGSV_SAVE_STATE)) -		printk(TPACPI_NOTICE -			"failed to save WWAN state to NVRAM\n"); +		pr_notice("failed to save WWAN state to NVRAM\n");  	else  		vdbg_printk(TPACPI_DBG_RFKILL,  			"WWAN state saved to NVRAM\n"); @@ -4242,8 +4331,7 @@ static int __init wan_init(struct ibm_init_struct *iibm)  #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES  	if (dbg_wwanemul) {  		tp_features.wan = 1; -		printk(TPACPI_INFO -			"wwan switch emulation enabled\n"); +		pr_info("wwan switch emulation enabled\n");  	} else  #endif  	if (tp_features.wan && @@ -4383,8 +4471,7 @@ static int __init uwb_init(struct ibm_init_struct *iibm)  #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES  	if (dbg_uwbemul) {  		tp_features.uwb = 1; -		printk(TPACPI_INFO -			"uwb switch emulation enabled\n"); +		pr_info("uwb switch emulation enabled\n");  	} else  #endif  	if (tp_features.uwb && @@ -4445,6 +4532,15 @@ static int video_orig_autosw;  static int video_autosw_get(void);  static int video_autosw_set(int enable); +TPACPI_HANDLE(vid, root, +	      "\\_SB.PCI.AGP.VGA",	/* 570 */ +	      "\\_SB.PCI0.AGP0.VID0",	/* 600e/x, 770x */ +	      "\\_SB.PCI0.VID0",	/* 770e */ +	      "\\_SB.PCI0.VID",		/* A21e, G4x, R50e, X30, X40 */ +	      "\\_SB.PCI0.AGP.VGA",	/* X100e and a few others */ +	      "\\_SB.PCI0.AGP.VID",	/* all others */ +	);				/* R30, R31 */ +  TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID");	/* G41 */  static int __init video_init(struct ibm_init_struct *iibm) @@ -4488,7 +4584,7 @@ static void video_exit(void)  	dbg_printk(TPACPI_DBG_EXIT,  		   "restoring original video autoswitch mode\n");  	if (video_autosw_set(video_orig_autosw)) -		printk(TPACPI_ERR "error while trying to restore original " +		pr_err("error while trying to restore original "  			"video autoswitch mode\n");  } @@ -4561,8 +4657,7 @@ static int video_outputsw_set(int status)  		res = acpi_evalf(vid_handle, NULL,  				 "ASWT", "vdd", status * 0x100, 0);  		if (!autosw && video_autosw_set(autosw)) { -			printk(TPACPI_ERR -			       "video auto-switch left enabled due to error\n"); +			pr_err("video auto-switch left enabled due to error\n");  			return -EIO;  		}  		break; @@ -4631,8 +4726,7 @@ static int video_outputsw_cycle(void)  		return -ENOSYS;  	}  	if (!autosw && video_autosw_set(autosw)) { -		printk(TPACPI_ERR -		       "video auto-switch left enabled due to error\n"); +		pr_err("video auto-switch left enabled due to error\n");  		return -EIO;  	} @@ -4885,8 +4979,7 @@ static int __init light_init(struct ibm_init_struct *iibm)  static void light_exit(void)  {  	led_classdev_unregister(&tpacpi_led_thinklight.led_classdev); -	if (work_pending(&tpacpi_led_thinklight.work)) -		flush_workqueue(tpacpi_wq); +	flush_workqueue(tpacpi_wq);  }  static int light_read(struct seq_file *m) @@ -5225,6 +5318,7 @@ static void led_exit(void)  			led_classdev_unregister(&tpacpi_leds[i].led_classdev);  	} +	flush_workqueue(tpacpi_wq);  	kfree(tpacpi_leds);  } @@ -5340,6 +5434,16 @@ static int __init led_init(struct ibm_init_struct *iibm)  	led_supported = led_init_detect_mode(); +	if (led_supported != TPACPI_LED_NONE) { +		useful_leds = tpacpi_check_quirks(led_useful_qtable, +				ARRAY_SIZE(led_useful_qtable)); + +		if (!useful_leds) { +			led_handle = NULL; +			led_supported = TPACPI_LED_NONE; +		} +	} +  	vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n",  		str_supported(led_supported), led_supported); @@ -5349,14 +5453,13 @@ static int __init led_init(struct ibm_init_struct *iibm)  	tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS,  			      GFP_KERNEL);  	if (!tpacpi_leds) { -		printk(TPACPI_ERR "Out of memory for LED data\n"); +		pr_err("Out of memory for LED data\n");  		return -ENOMEM;  	} -	useful_leds = tpacpi_check_quirks(led_useful_qtable, -					  ARRAY_SIZE(led_useful_qtable)); -  	for (i = 0; i < TPACPI_LED_NUMLEDS; i++) { +		tpacpi_leds[i].led = -1; +  		if (!tpacpi_is_led_restricted(i) &&  		    test_bit(i, &useful_leds)) {  			rc = tpacpi_init_led(i); @@ -5368,9 +5471,8 @@ static int __init led_init(struct ibm_init_struct *iibm)  	}  #ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS -	printk(TPACPI_NOTICE -		"warning: userspace override of important " -		"firmware LEDs is enabled\n"); +	pr_notice("warning: userspace override of important " +		  "firmware LEDs is enabled\n");  #endif  	return 0;  } @@ -5415,9 +5517,13 @@ static int led_write(char *buf)  		return -ENODEV;  	while ((cmd = next_cmd(&buf))) { -		if (sscanf(cmd, "%d", &led) != 1 || led < 0 || led > 15) +		if (sscanf(cmd, "%d", &led) != 1)  			return -EINVAL; +		if (led < 0 || led > (TPACPI_LED_NUMLEDS - 1) || +				tpacpi_leds[led].led < 0) +			return -ENODEV; +  		if (strstr(cmd, "off")) {  			s = TPACPI_LED_OFF;  		} else if (strstr(cmd, "on")) { @@ -5640,17 +5746,16 @@ static void thermal_dump_all_sensors(void)  	if (n <= 0)  		return; -	printk(TPACPI_NOTICE -		"temperatures (Celsius):"); +	pr_notice("temperatures (Celsius):");  	for (i = 0; i < n; i++) {  		if (t.temp[i] != TPACPI_THERMAL_SENSOR_NA) -			printk(KERN_CONT " %d", (int)(t.temp[i] / 1000)); +			pr_cont(" %d", (int)(t.temp[i] / 1000));  		else -			printk(KERN_CONT " N/A"); +			pr_cont(" N/A");  	} -	printk(KERN_CONT "\n"); +	pr_cont("\n");  }  /* sysfs temp##_input -------------------------------------------------- */ @@ -5770,14 +5875,12 @@ static int __init thermal_init(struct ibm_init_struct *iibm)  		if (ta1 == 0) {  			/* This is sheer paranoia, but we handle it anyway */  			if (acpi_tmp7) { -				printk(TPACPI_ERR -				       "ThinkPad ACPI EC access misbehaving, " +				pr_err("ThinkPad ACPI EC access misbehaving, "  				       "falling back to ACPI TMPx access "  				       "mode\n");  				thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07;  			} else { -				printk(TPACPI_ERR -				       "ThinkPad ACPI EC access misbehaving, " +				pr_err("ThinkPad ACPI EC access misbehaving, "  				       "disabling thermal sensors access\n");  				thermal_read_mode = TPACPI_THERMAL_NONE;  			} @@ -6109,7 +6212,7 @@ static void tpacpi_brightness_notify_change(void)  			       BACKLIGHT_UPDATE_HOTKEY);  } -static struct backlight_ops ibm_backlight_data = { +static const struct backlight_ops ibm_backlight_data = {  	.get_brightness = brightness_get,  	.update_status  = brightness_update_status,  }; @@ -6125,19 +6228,28 @@ static int __init tpacpi_query_bcl_levels(acpi_handle handle)  {  	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };  	union acpi_object *obj; +	struct acpi_device *device, *child;  	int rc; -	if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) { +	if (acpi_bus_get_device(handle, &device)) +		return 0; + +	rc = 0; +	list_for_each_entry(child, &device->children, node) { +		acpi_status status = acpi_evaluate_object(child->handle, "_BCL", +							  NULL, &buffer); +		if (ACPI_FAILURE(status)) +			continue; +  		obj = (union acpi_object *)buffer.pointer;  		if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { -			printk(TPACPI_ERR "Unknown _BCL data, " -			       "please report this to %s\n", TPACPI_MAIL); +			pr_err("Unknown _BCL data, please report this to %s\n", +				TPACPI_MAIL);  			rc = 0;  		} else {  			rc = obj->package.count;  		} -	} else { -		return 0; +		break;  	}  	kfree(buffer.pointer); @@ -6153,7 +6265,7 @@ static unsigned int __init tpacpi_check_std_acpi_brightness_support(void)  	acpi_handle video_device;  	int bcl_levels = 0; -	tpacpi_acpi_handle_locate("video", ACPI_VIDEO_HID, &video_device); +	tpacpi_acpi_handle_locate("video", NULL, &video_device);  	if (video_device)  		bcl_levels = tpacpi_query_bcl_levels(video_device); @@ -6215,18 +6327,15 @@ static void __init tpacpi_detect_brightness_capabilities(void)  	switch (b) {  	case 16:  		bright_maxlvl = 15; -		printk(TPACPI_INFO -		       "detected a 16-level brightness capable ThinkPad\n"); +		pr_info("detected a 16-level brightness capable ThinkPad\n");  		break;  	case 8:  	case 0:  		bright_maxlvl = 7; -		printk(TPACPI_INFO -		       "detected a 8-level brightness capable ThinkPad\n"); +		pr_info("detected a 8-level brightness capable ThinkPad\n");  		break;  	default: -		printk(TPACPI_ERR -		       "Unsupported brightness interface, " +		pr_err("Unsupported brightness interface, "  		       "please contact %s\n", TPACPI_MAIL);  		tp_features.bright_unkfw = 1;  		bright_maxlvl = b - 1; @@ -6261,22 +6370,19 @@ static int __init brightness_init(struct ibm_init_struct *iibm)  	if (acpi_video_backlight_support()) {  		if (brightness_enable > 1) { -			printk(TPACPI_INFO -			       "Standard ACPI backlight interface " -			       "available, not loading native one.\n"); +			pr_info("Standard ACPI backlight interface " +				"available, not loading native one\n");  			return 1;  		} else if (brightness_enable == 1) { -			printk(TPACPI_WARN -				"Cannot enable backlight brightness support, " +			pr_warn("Cannot enable backlight brightness support, "  				"ACPI is already handling it.  Refer to the " -				"acpi_backlight kernel parameter\n"); +				"acpi_backlight kernel parameter.\n");  			return 1;  		}  	} else if (tp_features.bright_acpimode && brightness_enable > 1) { -		printk(TPACPI_NOTICE -			"Standard ACPI backlight interface not " -			"available, thinkpad_acpi native " -			"brightness control enabled\n"); +		pr_notice("Standard ACPI backlight interface not " +			  "available, thinkpad_acpi native " +			  "brightness control enabled\n");  	}  	/* @@ -6310,6 +6416,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm)  		return 1;  	memset(&props, 0, sizeof(struct backlight_properties)); +	props.type = BACKLIGHT_PLATFORM;  	props.max_brightness = bright_maxlvl;  	props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;  	ibm_backlight_device = backlight_device_register(TPACPI_BACKLIGHT_DEV_NAME, @@ -6319,19 +6426,17 @@ static int __init brightness_init(struct ibm_init_struct *iibm)  	if (IS_ERR(ibm_backlight_device)) {  		int rc = PTR_ERR(ibm_backlight_device);  		ibm_backlight_device = NULL; -		printk(TPACPI_ERR "Could not register backlight device\n"); +		pr_err("Could not register backlight device\n");  		return rc;  	}  	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,  			"brightness is supported\n");  	if (quirks & TPACPI_BRGHT_Q_ASK) { -		printk(TPACPI_NOTICE -			"brightness: will use unverified default: " -			"brightness_mode=%d\n", brightness_mode); -		printk(TPACPI_NOTICE -			"brightness: please report to %s whether it works well " -			"or not on your ThinkPad\n", TPACPI_MAIL); +		pr_notice("brightness: will use unverified default: " +			  "brightness_mode=%d\n", brightness_mode); +		pr_notice("brightness: please report to %s whether it works well " +			  "or not on your ThinkPad\n", TPACPI_MAIL);  	}  	/* Added by mistake in early 2007.  Probably useless, but it could @@ -6345,11 +6450,11 @@ static int __init brightness_init(struct ibm_init_struct *iibm)  			"as change notification\n");  	tpacpi_hotkey_driver_mask_set(hotkey_driver_mask  				| TP_ACPI_HKEY_BRGHTUP_MASK -				| TP_ACPI_HKEY_BRGHTDWN_MASK);; +				| TP_ACPI_HKEY_BRGHTDWN_MASK);  	return 0;  } -static void brightness_suspend(pm_message_t state) +static void brightness_suspend(void)  {  	tpacpi_brightness_checkpoint_nvram();  } @@ -6462,9 +6567,14 @@ static struct ibm_struct brightness_driver_data = {  #define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control"  #define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME -static int alsa_index = ~((1 << (SNDRV_CARDS - 3)) - 1); /* last three slots */ +#if SNDRV_CARDS <= 32 +#define DEFAULT_ALSA_IDX		~((1 << (SNDRV_CARDS - 3)) - 1) +#else +#define DEFAULT_ALSA_IDX		~((1 << (32 - 3)) - 1) +#endif +static int alsa_index = DEFAULT_ALSA_IDX; /* last three slots */  static char *alsa_id = "ThinkPadEC"; -static int alsa_enable = SNDRV_DEFAULT_ENABLE1; +static bool alsa_enable = SNDRV_DEFAULT_ENABLE1;  struct tpacpi_alsa_data {  	struct snd_card *card; @@ -6507,7 +6617,7 @@ static enum tpacpi_volume_access_mode volume_mode =  	TPACPI_VOL_MODE_MAX;  static enum tpacpi_volume_capabilities volume_capabilities; -static int volume_control_allowed; +static bool volume_control_allowed;  /*   * Used to syncronize writers to TP_EC_AUDIO and @@ -6750,7 +6860,7 @@ static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol,  	return volume_alsa_set_mute(!ucontrol->value.integer.value[0]);  } -static struct snd_kcontrol_new volume_alsa_control_vol __devinitdata = { +static struct snd_kcontrol_new volume_alsa_control_vol = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "Console Playback Volume",  	.index = 0, @@ -6759,7 +6869,7 @@ static struct snd_kcontrol_new volume_alsa_control_vol __devinitdata = {  	.get = volume_alsa_vol_get,  }; -static struct snd_kcontrol_new volume_alsa_control_mute __devinitdata = { +static struct snd_kcontrol_new volume_alsa_control_mute = {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "Console Playback Switch",  	.index = 0, @@ -6768,7 +6878,7 @@ static struct snd_kcontrol_new volume_alsa_control_mute __devinitdata = {  	.get = volume_alsa_mute_get,  }; -static void volume_suspend(pm_message_t state) +static void volume_suspend(void)  {  	tpacpi_volume_checkpoint_nvram();  } @@ -6801,11 +6911,11 @@ static int __init volume_create_alsa_mixer(void)  	struct snd_kcontrol *ctl_mute;  	int rc; -	rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE, -			    sizeof(struct tpacpi_alsa_data), &card); +	rc = snd_card_new(&tpacpi_pdev->dev, +			  alsa_index, alsa_id, THIS_MODULE, +			  sizeof(struct tpacpi_alsa_data), &card);  	if (rc < 0 || !card) { -		printk(TPACPI_ERR -			"Failed to create ALSA card structures: %d\n", rc); +		pr_err("Failed to create ALSA card structures: %d\n", rc);  		return 1;  	} @@ -6839,9 +6949,8 @@ static int __init volume_create_alsa_mixer(void)  		ctl_vol = snd_ctl_new1(&volume_alsa_control_vol, NULL);  		rc = snd_ctl_add(card, ctl_vol);  		if (rc < 0) { -			printk(TPACPI_ERR -				"Failed to create ALSA volume control: %d\n", -				rc); +			pr_err("Failed to create ALSA volume control: %d\n", +			       rc);  			goto err_exit;  		}  		data->ctl_vol_id = &ctl_vol->id; @@ -6850,16 +6959,14 @@ static int __init volume_create_alsa_mixer(void)  	ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL);  	rc = snd_ctl_add(card, ctl_mute);  	if (rc < 0) { -		printk(TPACPI_ERR "Failed to create ALSA mute control: %d\n", -			rc); +		pr_err("Failed to create ALSA mute control: %d\n", rc);  		goto err_exit;  	}  	data->ctl_mute_id = &ctl_mute->id; -	snd_card_set_dev(card, &tpacpi_pdev->dev);  	rc = snd_card_register(card);  	if (rc < 0) { -		printk(TPACPI_ERR "Failed to register ALSA card: %d\n", rc); +		pr_err("Failed to register ALSA card: %d\n", rc);  		goto err_exit;  	} @@ -6915,9 +7022,8 @@ static int __init volume_init(struct ibm_init_struct *iibm)  		return -EINVAL;  	if (volume_mode == TPACPI_VOL_MODE_UCMS_STEP) { -		printk(TPACPI_ERR -			"UCMS step volume mode not implemented, " -			"please contact %s\n", TPACPI_MAIL); +		pr_err("UCMS step volume mode not implemented, " +		       "please contact %s\n", TPACPI_MAIL);  		return 1;  	} @@ -6981,13 +7087,11 @@ static int __init volume_init(struct ibm_init_struct *iibm)  	rc = volume_create_alsa_mixer();  	if (rc) { -		printk(TPACPI_ERR -			"Could not create the ALSA mixer interface\n"); +		pr_err("Could not create the ALSA mixer interface\n");  		return rc;  	} -	printk(TPACPI_INFO -		"Console audio control enabled, mode: %s\n", +	pr_info("Console audio control enabled, mode: %s\n",  		(volume_control_allowed) ?  			"override (read/write)" :  			"monitor (read only)"); @@ -7049,12 +7153,10 @@ static int volume_write(char *buf)  	if (!volume_control_allowed && tpacpi_lifecycle != TPACPI_LIFE_INIT) {  		if (unlikely(!tp_warned.volume_ctrl_forbidden)) {  			tp_warned.volume_ctrl_forbidden = 1; -			printk(TPACPI_NOTICE -				"Console audio control in monitor mode, " -				"changes are not allowed.\n"); -			printk(TPACPI_NOTICE -				"Use the volume_control=1 module parameter " -				"to enable volume control\n"); +			pr_notice("Console audio control in monitor mode, " +				  "changes are not allowed\n"); +			pr_notice("Use the volume_control=1 module parameter " +				  "to enable volume control\n");  		}  		return -EPERM;  	} @@ -7129,8 +7231,7 @@ static void inline volume_alsa_notify_change(void)  static int __init volume_init(struct ibm_init_struct *iibm)  { -	printk(TPACPI_INFO -		"volume: disabled as there is no ALSA support in this kernel\n"); +	pr_info("volume: disabled as there is no ALSA support in this kernel\n");  	return 1;  } @@ -7193,7 +7294,7 @@ static struct ibm_struct volume_driver_data = {   * 		TPACPI_FAN_WR_ACPI_FANS (X31/X40/X41)   *   *	FIRMWARE BUG: on some models, EC 0x2f might not be initialized at - *	boot. Apparently the EC does not intialize it, so unless ACPI DSDT + *	boot. Apparently the EC does not initialize it, so unless ACPI DSDT   *	does so, its initial value is meaningless (0x07).   *   *	For firmware bugs, refer to: @@ -7294,7 +7395,7 @@ enum fan_control_commands {  						 * and also watchdog cmd */  }; -static int fan_control_allowed; +static bool fan_control_allowed;  static enum fan_status_access_mode fan_status_access_mode;  static enum fan_control_access_mode fan_control_access_mode; @@ -7337,9 +7438,8 @@ TPACPI_HANDLE(sfan, ec, "SFAN",	/* 570 */  static void fan_quirk1_setup(void)  {  	if (fan_control_initial_status == 0x07) { -		printk(TPACPI_NOTICE -		       "fan_init: initial fan status is unknown, " -		       "assuming it is in auto mode\n"); +		pr_notice("fan_init: initial fan status is unknown, " +			  "assuming it is in auto mode\n");  		tp_features.fan_ctrl_status_undef = 1;  	}  } @@ -7414,17 +7514,18 @@ static int fan_get_status(u8 *status)  	 * Add TPACPI_FAN_RD_ACPI_FANS ? */  	switch (fan_status_access_mode) { -	case TPACPI_FAN_RD_ACPI_GFAN: +	case TPACPI_FAN_RD_ACPI_GFAN: {  		/* 570, 600e/x, 770e, 770x */ +		int res; -		if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d"))) +		if (unlikely(!acpi_evalf(gfan_handle, &res, NULL, "d")))  			return -EIO;  		if (likely(status)) -			*status = s & 0x07; +			*status = res & 0x07;  		break; - +	}  	case TPACPI_FAN_RD_TPEC:  		/* all except 570, 600e/x, 770e, 770x */  		if (unlikely(!acpi_ec_read(fan_status_offset, &s))) @@ -7712,26 +7813,15 @@ static int fan_set_speed(int speed)  static void fan_watchdog_reset(void)  { -	static int fan_watchdog_active; -  	if (fan_control_access_mode == TPACPI_FAN_WR_NONE)  		return; -	if (fan_watchdog_active) -		cancel_delayed_work(&fan_watchdog_task); -  	if (fan_watchdog_maxinterval > 0 && -	    tpacpi_lifecycle != TPACPI_LIFE_EXITING) { -		fan_watchdog_active = 1; -		if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task, -				msecs_to_jiffies(fan_watchdog_maxinterval -						 * 1000))) { -			printk(TPACPI_ERR -			       "failed to queue the fan watchdog, " -			       "watchdog will not trigger\n"); -		} -	} else -		fan_watchdog_active = 0; +	    tpacpi_lifecycle != TPACPI_LIFE_EXITING) +		mod_delayed_work(tpacpi_wq, &fan_watchdog_task, +			msecs_to_jiffies(fan_watchdog_maxinterval * 1000)); +	else +		cancel_delayed_work(&fan_watchdog_task);  }  static void fan_watchdog_fire(struct work_struct *ignored) @@ -7741,11 +7831,11 @@ static void fan_watchdog_fire(struct work_struct *ignored)  	if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)  		return; -	printk(TPACPI_NOTICE "fan watchdog: enabling fan\n"); +	pr_notice("fan watchdog: enabling fan\n");  	rc = fan_set_enable();  	if (rc < 0) { -		printk(TPACPI_ERR "fan watchdog: error %d while enabling fan, " -			"will try again later...\n", -rc); +		pr_err("fan watchdog: error %d while enabling fan, " +		       "will try again later...\n", -rc);  		/* reschedule for later */  		fan_watchdog_reset();  	} @@ -8049,8 +8139,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)  					"secondary fan support enabled\n");  			}  		} else { -			printk(TPACPI_ERR -			       "ThinkPad ACPI EC access misbehaving, " +			pr_err("ThinkPad ACPI EC access misbehaving, "  			       "fan status and control unavailable\n");  			return 1;  		} @@ -8139,7 +8228,7 @@ static void fan_exit(void)  	flush_workqueue(tpacpi_wq);  } -static void fan_suspend(pm_message_t state) +static void fan_suspend(void)  {  	int rc; @@ -8150,9 +8239,8 @@ static void fan_suspend(pm_message_t state)  	fan_control_resume_level = 0;  	rc = fan_get_status_safe(&fan_control_resume_level);  	if (rc < 0) -		printk(TPACPI_NOTICE -			"failed to read fan level for later " -			"restore during resume: %d\n", rc); +		pr_notice("failed to read fan level for later " +			  "restore during resume: %d\n", rc);  	/* if it is undefined, don't attempt to restore it.  	 * KEEP THIS LAST */ @@ -8207,13 +8295,11 @@ static void fan_resume(void)  		return;  	}  	if (do_set) { -		printk(TPACPI_NOTICE -			"restoring fan level to 0x%02x\n", -			fan_control_resume_level); +		pr_notice("restoring fan level to 0x%02x\n", +			  fan_control_resume_level);  		rc = fan_set_level_safe(fan_control_resume_level);  		if (rc < 0) -			printk(TPACPI_NOTICE -				"failed to restore fan level: %d\n", rc); +			pr_notice("failed to restore fan level: %d\n", rc);  	}  } @@ -8305,8 +8391,8 @@ static int fan_write_cmd_level(const char *cmd, int *rc)  	*rc = fan_set_level_safe(level);  	if (*rc == -ENXIO) -		printk(TPACPI_ERR "level command accepted for unsupported " -		       "access mode %d", fan_control_access_mode); +		pr_err("level command accepted for unsupported access mode %d\n", +		       fan_control_access_mode);  	else if (!*rc)  		tpacpi_disclose_usertask("procfs fan",  			"set level to %d\n", level); @@ -8321,8 +8407,8 @@ static int fan_write_cmd_enable(const char *cmd, int *rc)  	*rc = fan_set_enable();  	if (*rc == -ENXIO) -		printk(TPACPI_ERR "enable command accepted for unsupported " -		       "access mode %d", fan_control_access_mode); +		pr_err("enable command accepted for unsupported access mode %d\n", +		       fan_control_access_mode);  	else if (!*rc)  		tpacpi_disclose_usertask("procfs fan", "enable\n"); @@ -8336,8 +8422,8 @@ static int fan_write_cmd_disable(const char *cmd, int *rc)  	*rc = fan_set_disable();  	if (*rc == -ENXIO) -		printk(TPACPI_ERR "disable command accepted for unsupported " -		       "access mode %d", fan_control_access_mode); +		pr_err("disable command accepted for unsupported access mode %d\n", +		       fan_control_access_mode);  	else if (!*rc)  		tpacpi_disclose_usertask("procfs fan", "disable\n"); @@ -8356,8 +8442,8 @@ static int fan_write_cmd_speed(const char *cmd, int *rc)  	*rc = fan_set_speed(speed);  	if (*rc == -ENXIO) -		printk(TPACPI_ERR "speed command accepted for unsupported " -		       "access mode %d", fan_control_access_mode); +		pr_err("speed command accepted for unsupported access mode %d\n", +		       fan_control_access_mode);  	else if (!*rc)  		tpacpi_disclose_usertask("procfs fan",  			"set speed to %d\n", speed); @@ -8416,6 +8502,103 @@ static struct ibm_struct fan_driver_data = {  	.resume = fan_resume,  }; +/************************************************************************* + * Mute LED subdriver + */ + + +struct tp_led_table { +	acpi_string name; +	int on_value; +	int off_value; +	int state; +}; + +static struct tp_led_table led_tables[] = { +	[TPACPI_LED_MUTE] = { +		.name = "SSMS", +		.on_value = 1, +		.off_value = 0, +	}, +	[TPACPI_LED_MICMUTE] = { +		.name = "MMTS", +		.on_value = 2, +		.off_value = 0, +	}, +}; + +static int mute_led_on_off(struct tp_led_table *t, bool state) +{ +	acpi_handle temp; +	int output; + +	if (!ACPI_SUCCESS(acpi_get_handle(hkey_handle, t->name, &temp))) { +		pr_warn("Thinkpad ACPI has no %s interface.\n", t->name); +		return -EIO; +	} + +	if (!acpi_evalf(hkey_handle, &output, t->name, "dd", +			state ? t->on_value : t->off_value)) +		return -EIO; + +	t->state = state; +	return state; +} + +int tpacpi_led_set(int whichled, bool on) +{ +	struct tp_led_table *t; + +	if (whichled < 0 || whichled >= TPACPI_LED_MAX) +		return -EINVAL; + +	t = &led_tables[whichled]; +	if (t->state < 0 || t->state == on) +		return t->state; +	return mute_led_on_off(t, on); +} +EXPORT_SYMBOL_GPL(tpacpi_led_set); + +static int mute_led_init(struct ibm_init_struct *iibm) +{ +	acpi_handle temp; +	int i; + +	for (i = 0; i < TPACPI_LED_MAX; i++) { +		struct tp_led_table *t = &led_tables[i]; +		if (ACPI_SUCCESS(acpi_get_handle(hkey_handle, t->name, &temp))) +			mute_led_on_off(t, false); +		else +			t->state = -ENODEV; +	} +	return 0; +} + +static void mute_led_exit(void) +{ +	int i; + +	for (i = 0; i < TPACPI_LED_MAX; i++) +		tpacpi_led_set(i, false); +} + +static void mute_led_resume(void) +{ +	int i; + +	for (i = 0; i < TPACPI_LED_MAX; i++) { +		struct tp_led_table *t = &led_tables[i]; +		if (t->state >= 0) +			mute_led_on_off(t, t->state); +	} +} + +static struct ibm_struct mute_led_driver_data = { +	.name = "mute_led", +	.exit = mute_led_exit, +	.resume = mute_led_resume, +}; +  /****************************************************************************   ****************************************************************************   * @@ -8472,7 +8655,7 @@ static struct proc_dir_entry *proc_dir;   * Module and infrastructure proble, init and exit handling   */ -static int force_load; +static bool force_load;  #ifdef CONFIG_THINKPAD_ACPI_DEBUG  static const char * __init str_supported(int is_supported) @@ -8497,7 +8680,6 @@ static void ibm_exit(struct ibm_struct *ibm)  					   ibm->acpi->type,  					   dispatch_acpi_notify);  		ibm->flags.acpi_notify_installed = 0; -		ibm->flags.acpi_notify_installed = 0;  	}  	if (ibm->flags.proc_created) { @@ -8561,8 +8743,8 @@ static int __init ibm_init(struct ibm_init_struct *iibm)  		if (ibm->acpi->notify) {  			ret = setup_acpi_notify(ibm);  			if (ret == -ENODEV) { -				printk(TPACPI_NOTICE "disabling subdriver %s\n", -					ibm->name); +				pr_notice("disabling subdriver %s\n", +					  ibm->name);  				ret = 0;  				goto err_out;  			} @@ -8575,7 +8757,7 @@ static int __init ibm_init(struct ibm_init_struct *iibm)  		"%s installed\n", ibm->name);  	if (ibm->read) { -		mode_t mode = iibm->base_procfs_mode; +		umode_t mode = iibm->base_procfs_mode;  		if (!mode)  			mode = S_IRUGO; @@ -8584,8 +8766,7 @@ static int __init ibm_init(struct ibm_init_struct *iibm)  		entry = proc_create_data(ibm->name, mode, proc_dir,  					 &dispatch_proc_fops, ibm);  		if (!entry) { -			printk(TPACPI_ERR "unable to create proc entry %s\n", -			       ibm->name); +			pr_err("unable to create proc entry %s\n", ibm->name);  			ret = -ENODEV;  			goto err_out;  		} @@ -8619,10 +8800,10 @@ static bool __pure __init tpacpi_is_valid_fw_id(const char* const s,  	return s && strlen(s) >= 8 &&  		tpacpi_is_fw_digit(s[0]) &&  		tpacpi_is_fw_digit(s[1]) && -		s[2] == t && s[3] == 'T' && +		s[2] == t && +		(s[3] == 'T' || s[3] == 'N') &&  		tpacpi_is_fw_digit(s[4]) && -		tpacpi_is_fw_digit(s[5]) && -		s[6] == 'W' && s[7] == 'W'; +		tpacpi_is_fw_digit(s[5]);  }  /* returns 0 - probe ok, or < 0 - probe error. @@ -8653,7 +8834,8 @@ static int __must_check __init get_thinkpad_model_data(  		return -ENOMEM;  	/* Really ancient ThinkPad 240X will fail this, which is fine */ -	if (!tpacpi_is_valid_fw_id(tp->bios_version_str, 'E')) +	if (!(tpacpi_is_valid_fw_id(tp->bios_version_str, 'E') || +	      tpacpi_is_valid_fw_id(tp->bios_version_str, 'C')))  		return 0;  	tp->bios_model = tp->bios_version_str[0] @@ -8685,23 +8867,28 @@ static int __must_check __init get_thinkpad_model_data(  				tp->ec_release = (ec_fw_string[4] << 8)  						| ec_fw_string[5];  			} else { -				printk(TPACPI_NOTICE -					"ThinkPad firmware release %s " -					"doesn't match the known patterns\n", -					ec_fw_string); -				printk(TPACPI_NOTICE -					"please report this to %s\n", -					TPACPI_MAIL); +				pr_notice("ThinkPad firmware release %s " +					  "doesn't match the known patterns\n", +					  ec_fw_string); +				pr_notice("please report this to %s\n", +					  TPACPI_MAIL);  			}  			break;  		}  	}  	s = dmi_get_system_info(DMI_PRODUCT_VERSION); -	if (s && !strnicmp(s, "ThinkPad", 8)) { +	if (s && !(strnicmp(s, "ThinkPad", 8) && strnicmp(s, "Lenovo", 6))) {  		tp->model_str = kstrdup(s, GFP_KERNEL);  		if (!tp->model_str)  			return -ENOMEM; +	} else { +		s = dmi_get_system_info(DMI_BIOS_VENDOR); +		if (s && !(strnicmp(s, "Lenovo", 6))) { +			tp->model_str = kstrdup(s, GFP_KERNEL); +			if (!tp->model_str) +				return -ENOMEM; +		}  	}  	s = dmi_get_system_info(DMI_PRODUCT_NAME); @@ -8735,8 +8922,7 @@ static int __init probe_for_thinkpad(void)  	tpacpi_acpi_handle_locate("ec", TPACPI_ACPI_EC_HID, &ec_handle);  	if (!ec_handle) {  		if (is_thinkpad) -			printk(TPACPI_ERR -				"Not yet supported ThinkPad detected!\n"); +			pr_err("Not yet supported ThinkPad detected!\n");  		return -ENODEV;  	} @@ -8748,10 +8934,10 @@ static int __init probe_for_thinkpad(void)  static void __init thinkpad_acpi_init_banner(void)  { -	printk(TPACPI_INFO "%s v%s\n", TPACPI_DESC, TPACPI_VERSION); -	printk(TPACPI_INFO "%s\n", TPACPI_URL); +	pr_info("%s v%s\n", TPACPI_DESC, TPACPI_VERSION); +	pr_info("%s\n", TPACPI_URL); -	printk(TPACPI_INFO "ThinkPad BIOS %s, EC %s\n", +	pr_info("ThinkPad BIOS %s, EC %s\n",  		(thinkpad_id.bios_version_str) ?  			thinkpad_id.bios_version_str : "unknown",  		(thinkpad_id.ec_version_str) ? @@ -8760,7 +8946,7 @@ static void __init thinkpad_acpi_init_banner(void)  	BUG_ON(!thinkpad_id.vendor);  	if (thinkpad_id.model_str) -		printk(TPACPI_INFO "%s %s, model %s\n", +		pr_info("%s %s, model %s\n",  			(thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?  				"IBM" : ((thinkpad_id.vendor ==  						PCI_VENDOR_ID_LENOVO) ? @@ -8831,6 +9017,10 @@ static struct ibm_init_struct ibms_init[] __initdata = {  		.init = fan_init,  		.data = &fan_driver_data,  	}, +	{ +		.init = mute_led_init, +		.data = &mute_led_driver_data, +	},  };  static int __init set_ibm_param(const char *val, struct kernel_param *kp) @@ -8885,11 +9075,6 @@ module_param(brightness_enable, uint, 0444);  MODULE_PARM_DESC(brightness_enable,  		 "Enables backlight control when 1, disables when 0"); -module_param(hotkey_report_mode, uint, 0444); -MODULE_PARM_DESC(hotkey_report_mode, -		 "used for backwards compatibility with userspace, " -		 "see documentation"); -  #ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT  module_param_named(volume_mode, volume_mode, uint, 0444);  MODULE_PARM_DESC(volume_mode, @@ -8976,6 +9161,7 @@ static void thinkpad_acpi_module_exit(void)  			input_unregister_device(tpacpi_inputdev);  		else  			input_free_device(tpacpi_inputdev); +		kfree(hotkey_keycode_map);  	}  	if (tpacpi_hwmon) @@ -9009,6 +9195,7 @@ static void thinkpad_acpi_module_exit(void)  	kfree(thinkpad_id.bios_version_str);  	kfree(thinkpad_id.ec_version_str);  	kfree(thinkpad_id.model_str); +	kfree(thinkpad_id.nummodel_str);  } @@ -9018,16 +9205,11 @@ static int __init thinkpad_acpi_module_init(void)  	tpacpi_lifecycle = TPACPI_LIFE_INIT; -	/* Parameter checking */ -	if (hotkey_report_mode > 2) -		return -EINVAL; -  	/* Driver-level probe */  	ret = get_thinkpad_model_data(&thinkpad_id);  	if (ret) { -		printk(TPACPI_ERR -			"unable to get DMI data: %d\n", ret); +		pr_err("unable to get DMI data: %d\n", ret);  		thinkpad_acpi_module_exit();  		return ret;  	} @@ -9053,16 +9235,14 @@ static int __init thinkpad_acpi_module_init(void)  	proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir);  	if (!proc_dir) { -		printk(TPACPI_ERR -		       "unable to create proc dir " TPACPI_PROC_DIR); +		pr_err("unable to create proc dir " TPACPI_PROC_DIR "\n");  		thinkpad_acpi_module_exit();  		return -ENODEV;  	}  	ret = platform_driver_register(&tpacpi_pdriver);  	if (ret) { -		printk(TPACPI_ERR -		       "unable to register main platform driver\n"); +		pr_err("unable to register main platform driver\n");  		thinkpad_acpi_module_exit();  		return ret;  	} @@ -9070,8 +9250,7 @@ static int __init thinkpad_acpi_module_init(void)  	ret = platform_driver_register(&tpacpi_hwmon_pdriver);  	if (ret) { -		printk(TPACPI_ERR -		       "unable to register hwmon platform driver\n"); +		pr_err("unable to register hwmon platform driver\n");  		thinkpad_acpi_module_exit();  		return ret;  	} @@ -9084,8 +9263,7 @@ static int __init thinkpad_acpi_module_init(void)  					&tpacpi_hwmon_pdriver.driver);  	}  	if (ret) { -		printk(TPACPI_ERR -		       "unable to create sysfs driver attributes\n"); +		pr_err("unable to create sysfs driver attributes\n");  		thinkpad_acpi_module_exit();  		return ret;  	} @@ -9098,7 +9276,7 @@ static int __init thinkpad_acpi_module_init(void)  	if (IS_ERR(tpacpi_pdev)) {  		ret = PTR_ERR(tpacpi_pdev);  		tpacpi_pdev = NULL; -		printk(TPACPI_ERR "unable to register platform device\n"); +		pr_err("unable to register platform device\n");  		thinkpad_acpi_module_exit();  		return ret;  	} @@ -9108,16 +9286,14 @@ static int __init thinkpad_acpi_module_init(void)  	if (IS_ERR(tpacpi_sensors_pdev)) {  		ret = PTR_ERR(tpacpi_sensors_pdev);  		tpacpi_sensors_pdev = NULL; -		printk(TPACPI_ERR -		       "unable to register hwmon platform device\n"); +		pr_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(TPACPI_ERR -		       "unable to create sysfs hwmon device attributes\n"); +		pr_err("unable to create sysfs hwmon device attributes\n");  		thinkpad_acpi_module_exit();  		return ret;  	} @@ -9126,14 +9302,13 @@ static int __init thinkpad_acpi_module_init(void)  	if (IS_ERR(tpacpi_hwmon)) {  		ret = PTR_ERR(tpacpi_hwmon);  		tpacpi_hwmon = NULL; -		printk(TPACPI_ERR "unable to register hwmon device\n"); +		pr_err("unable to register hwmon device\n");  		thinkpad_acpi_module_exit();  		return ret;  	}  	mutex_init(&tpacpi_inputdev_send_mutex);  	tpacpi_inputdev = input_allocate_device();  	if (!tpacpi_inputdev) { -		printk(TPACPI_ERR "unable to allocate input device\n");  		thinkpad_acpi_module_exit();  		return -ENOMEM;  	} else { @@ -9165,7 +9340,7 @@ static int __init thinkpad_acpi_module_init(void)  	ret = input_register_device(tpacpi_inputdev);  	if (ret < 0) { -		printk(TPACPI_ERR "unable to register input device\n"); +		pr_err("unable to register input device\n");  		thinkpad_acpi_module_exit();  		return ret;  	} else {  | 
