xref: /openbmc/linux/drivers/platform/x86/think-lmi.c (revision 85f856f7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Think LMI BIOS configuration driver
4  *
5  * Copyright(C) 2019-2021 Lenovo
6  *
7  * Original code from Thinkpad-wmi project https://github.com/iksaif/thinkpad-wmi
8  * Copyright(C) 2017 Corentin Chary <corentin.chary@gmail.com>
9  * Distributed under the GPL-2.0 license
10  */
11 
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 
14 #include <linux/acpi.h>
15 #include <linux/errno.h>
16 #include <linux/fs.h>
17 #include <linux/string.h>
18 #include <linux/types.h>
19 #include <linux/wmi.h>
20 #include "firmware_attributes_class.h"
21 #include "think-lmi.h"
22 
23 static bool debug_support;
24 module_param(debug_support, bool, 0444);
25 MODULE_PARM_DESC(debug_support, "Enable debug command support");
26 
27 /*
28  * Name:
29  *  Lenovo_BiosSetting
30  * Description:
31  *  Get item name and settings for current LMI instance.
32  * Type:
33  *  Query
34  * Returns:
35  *  "Item,Value"
36  * Example:
37  *  "WakeOnLAN,Enable"
38  */
39 #define LENOVO_BIOS_SETTING_GUID "51F5230E-9677-46CD-A1CF-C0B23EE34DB7"
40 
41 /*
42  * Name:
43  *  Lenovo_SetBiosSetting
44  * Description:
45  *  Change the BIOS setting to the desired value using the Lenovo_SetBiosSetting
46  *  class. To save the settings, use the Lenovo_SaveBiosSetting class.
47  *  BIOS settings and values are case sensitive.
48  *  After making changes to the BIOS settings, you must reboot the computer
49  *  before the changes will take effect.
50  * Type:
51  *  Method
52  * Arguments:
53  *  "Item,Value,Password,Encoding,KbdLang;"
54  * Example:
55  *  "WakeOnLAN,Disable,pa55w0rd,ascii,us;"
56  */
57 #define LENOVO_SET_BIOS_SETTINGS_GUID "98479A64-33F5-4E33-A707-8E251EBBC3A1"
58 
59 /*
60  * Name:
61  *  Lenovo_SaveBiosSettings
62  * Description:
63  *  Save any pending changes in settings.
64  * Type:
65  *  Method
66  * Arguments:
67  *  "Password,Encoding,KbdLang;"
68  * Example:
69  * "pa55w0rd,ascii,us;"
70  */
71 #define LENOVO_SAVE_BIOS_SETTINGS_GUID "6A4B54EF-A5ED-4D33-9455-B0D9B48DF4B3"
72 
73 /*
74  * Name:
75  *  Lenovo_BiosPasswordSettings
76  * Description:
77  *  Return BIOS Password settings
78  * Type:
79  *  Query
80  * Returns:
81  *  PasswordMode, PasswordState, MinLength, MaxLength,
82  *  SupportedEncoding, SupportedKeyboard
83  */
84 #define LENOVO_BIOS_PASSWORD_SETTINGS_GUID "8ADB159E-1E32-455C-BC93-308A7ED98246"
85 
86 /*
87  * Name:
88  *  Lenovo_SetBiosPassword
89  * Description:
90  *  Change a specific password.
91  *  - BIOS settings cannot be changed at the same boot as power-on
92  *    passwords (POP) and hard disk passwords (HDP). If you want to change
93  *    BIOS settings and POP or HDP, you must reboot the system after changing
94  *    one of them.
95  *  - A password cannot be set using this method when one does not already
96  *    exist. Passwords can only be updated or cleared.
97  * Type:
98  *  Method
99  * Arguments:
100  *  "PasswordType,CurrentPassword,NewPassword,Encoding,KbdLang;"
101  * Example:
102  *  "pop,pa55w0rd,newpa55w0rd,ascii,us;”
103  */
104 #define LENOVO_SET_BIOS_PASSWORD_GUID "2651D9FD-911C-4B69-B94E-D0DED5963BD7"
105 
106 /*
107  * Name:
108  *  Lenovo_GetBiosSelections
109  * Description:
110  *  Return a list of valid settings for a given item.
111  * Type:
112  *  Method
113  * Arguments:
114  *  "Item"
115  * Returns:
116  *  "Value1,Value2,Value3,..."
117  * Example:
118  *  -> "FlashOverLAN"
119  *  <- "Enabled,Disabled"
120  */
121 #define LENOVO_GET_BIOS_SELECTIONS_GUID	"7364651A-132F-4FE7-ADAA-40C6C7EE2E3B"
122 
123 /*
124  * Name:
125  *  Lenovo_DebugCmdGUID
126  * Description
127  *  Debug entry GUID method for entering debug commands to the BIOS
128  */
129 #define LENOVO_DEBUG_CMD_GUID "7FF47003-3B6C-4E5E-A227-E979824A85D1"
130 
131 /*
132  * Name:
133  *  Lenovo_OpcodeIF
134  * Description:
135  *  Opcode interface which provides the ability to set multiple
136  *  parameters and then trigger an action with a final command.
137  *  This is particularly useful for simplifying setting passwords.
138  *  With this support comes the ability to set System, HDD and NVMe
139  *  passwords.
140  *  This is currently available on ThinkCenter and ThinkStations platforms
141  */
142 #define LENOVO_OPCODE_IF_GUID "DFDDEF2C-57D4-48ce-B196-0FB787D90836"
143 
144 #define TLMI_POP_PWD (1 << 0)
145 #define TLMI_PAP_PWD (1 << 1)
146 #define TLMI_HDD_PWD (1 << 2)
147 #define TLMI_SYS_PWD (1 << 3)
148 #define to_tlmi_pwd_setting(kobj)  container_of(kobj, struct tlmi_pwd_setting, kobj)
149 #define to_tlmi_attr_setting(kobj)  container_of(kobj, struct tlmi_attr_setting, kobj)
150 
151 static const struct tlmi_err_codes tlmi_errs[] = {
152 	{"Success", 0},
153 	{"Not Supported", -EOPNOTSUPP},
154 	{"Invalid Parameter", -EINVAL},
155 	{"Access Denied", -EACCES},
156 	{"System Busy", -EBUSY},
157 };
158 
159 static const char * const encoding_options[] = {
160 	[TLMI_ENCODING_ASCII] = "ascii",
161 	[TLMI_ENCODING_SCANCODE] = "scancode",
162 };
163 static const char * const level_options[] = {
164 	[TLMI_LEVEL_USER] = "user",
165 	[TLMI_LEVEL_MASTER] = "master",
166 };
167 static struct think_lmi tlmi_priv;
168 static struct class *fw_attr_class;
169 
170 /* ------ Utility functions ------------*/
171 /* Convert BIOS WMI error string to suitable error code */
172 static int tlmi_errstr_to_err(const char *errstr)
173 {
174 	int i;
175 
176 	for (i = 0; i < sizeof(tlmi_errs)/sizeof(struct tlmi_err_codes); i++) {
177 		if (!strcmp(tlmi_errs[i].err_str, errstr))
178 			return tlmi_errs[i].err_code;
179 	}
180 	return -EPERM;
181 }
182 
183 /* Extract error string from WMI return buffer */
184 static int tlmi_extract_error(const struct acpi_buffer *output)
185 {
186 	const union acpi_object *obj;
187 
188 	obj = output->pointer;
189 	if (!obj)
190 		return -ENOMEM;
191 	if (obj->type != ACPI_TYPE_STRING || !obj->string.pointer)
192 		return -EIO;
193 
194 	return tlmi_errstr_to_err(obj->string.pointer);
195 }
196 
197 /* Utility function to execute WMI call to BIOS */
198 static int tlmi_simple_call(const char *guid, const char *arg)
199 {
200 	const struct acpi_buffer input = { strlen(arg), (char *)arg };
201 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
202 	acpi_status status;
203 	int i, err;
204 
205 	/*
206 	 * Duplicated call required to match BIOS workaround for behavior
207 	 * seen when WMI accessed via scripting on other OS.
208 	 */
209 	for (i = 0; i < 2; i++) {
210 		/* (re)initialize output buffer to default state */
211 		output.length = ACPI_ALLOCATE_BUFFER;
212 		output.pointer = NULL;
213 
214 		status = wmi_evaluate_method(guid, 0, 0, &input, &output);
215 		if (ACPI_FAILURE(status)) {
216 			kfree(output.pointer);
217 			return -EIO;
218 		}
219 		err = tlmi_extract_error(&output);
220 		kfree(output.pointer);
221 		if (err)
222 			return err;
223 	}
224 	return 0;
225 }
226 
227 /* Extract output string from WMI return buffer */
228 static int tlmi_extract_output_string(const struct acpi_buffer *output,
229 				      char **string)
230 {
231 	const union acpi_object *obj;
232 	char *s;
233 
234 	obj = output->pointer;
235 	if (!obj)
236 		return -ENOMEM;
237 	if (obj->type != ACPI_TYPE_STRING || !obj->string.pointer)
238 		return -EIO;
239 
240 	s = kstrdup(obj->string.pointer, GFP_KERNEL);
241 	if (!s)
242 		return -ENOMEM;
243 	*string = s;
244 	return 0;
245 }
246 
247 /* ------ Core interface functions ------------*/
248 
249 /* Get password settings from BIOS */
250 static int tlmi_get_pwd_settings(struct tlmi_pwdcfg *pwdcfg)
251 {
252 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
253 	const union acpi_object *obj;
254 	acpi_status status;
255 	int copy_size;
256 
257 	if (!tlmi_priv.can_get_password_settings)
258 		return -EOPNOTSUPP;
259 
260 	status = wmi_query_block(LENOVO_BIOS_PASSWORD_SETTINGS_GUID, 0,
261 				 &output);
262 	if (ACPI_FAILURE(status))
263 		return -EIO;
264 
265 	obj = output.pointer;
266 	if (!obj)
267 		return -ENOMEM;
268 	if (obj->type != ACPI_TYPE_BUFFER || !obj->buffer.pointer) {
269 		kfree(obj);
270 		return -EIO;
271 	}
272 	/*
273 	 * The size of thinkpad_wmi_pcfg on ThinkStation is larger than ThinkPad.
274 	 * To make the driver compatible on different brands, we permit it to get
275 	 * the data in below case.
276 	 * Settings must have at minimum the core fields available
277 	 */
278 	if (obj->buffer.length < sizeof(struct tlmi_pwdcfg_core)) {
279 		pr_warn("Unknown pwdcfg buffer length %d\n", obj->buffer.length);
280 		kfree(obj);
281 		return -EIO;
282 	}
283 
284 	copy_size = obj->buffer.length < sizeof(struct tlmi_pwdcfg) ?
285 		obj->buffer.length : sizeof(struct tlmi_pwdcfg);
286 	memcpy(pwdcfg, obj->buffer.pointer, copy_size);
287 	kfree(obj);
288 
289 	if (WARN_ON(pwdcfg->core.max_length >= TLMI_PWD_BUFSIZE))
290 		pwdcfg->core.max_length = TLMI_PWD_BUFSIZE - 1;
291 	return 0;
292 }
293 
294 static int tlmi_save_bios_settings(const char *password)
295 {
296 	return tlmi_simple_call(LENOVO_SAVE_BIOS_SETTINGS_GUID,
297 				password);
298 }
299 
300 static int tlmi_opcode_setting(char *setting, const char *value)
301 {
302 	char *opcode_str;
303 	int ret;
304 
305 	opcode_str = kasprintf(GFP_KERNEL, "%s:%s;", setting, value);
306 	if (!opcode_str)
307 		return -ENOMEM;
308 
309 	ret = tlmi_simple_call(LENOVO_OPCODE_IF_GUID, opcode_str);
310 	kfree(opcode_str);
311 	return ret;
312 }
313 
314 static int tlmi_setting(int item, char **value, const char *guid_string)
315 {
316 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
317 	acpi_status status;
318 	int ret;
319 
320 	status = wmi_query_block(guid_string, item, &output);
321 	if (ACPI_FAILURE(status)) {
322 		kfree(output.pointer);
323 		return -EIO;
324 	}
325 
326 	ret = tlmi_extract_output_string(&output, value);
327 	kfree(output.pointer);
328 	return ret;
329 }
330 
331 static int tlmi_get_bios_selections(const char *item, char **value)
332 {
333 	const struct acpi_buffer input = { strlen(item), (char *)item };
334 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
335 	acpi_status status;
336 	int ret;
337 
338 	status = wmi_evaluate_method(LENOVO_GET_BIOS_SELECTIONS_GUID,
339 				     0, 0, &input, &output);
340 
341 	if (ACPI_FAILURE(status)) {
342 		kfree(output.pointer);
343 		return -EIO;
344 	}
345 
346 	ret = tlmi_extract_output_string(&output, value);
347 	kfree(output.pointer);
348 	return ret;
349 }
350 
351 /* ---- Authentication sysfs --------------------------------------------------------- */
352 static ssize_t is_enabled_show(struct kobject *kobj, struct kobj_attribute *attr,
353 					  char *buf)
354 {
355 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
356 
357 	return sysfs_emit(buf, "%d\n", setting->valid);
358 }
359 
360 static struct kobj_attribute auth_is_pass_set = __ATTR_RO(is_enabled);
361 
362 static ssize_t current_password_store(struct kobject *kobj,
363 				      struct kobj_attribute *attr,
364 				      const char *buf, size_t count)
365 {
366 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
367 	size_t pwdlen;
368 	char *p;
369 
370 	pwdlen = strlen(buf);
371 	/* pwdlen == 0 is allowed to clear the password */
372 	if (pwdlen && ((pwdlen < setting->minlen) || (pwdlen > setting->maxlen)))
373 		return -EINVAL;
374 
375 	strscpy(setting->password, buf, setting->maxlen);
376 	/* Strip out CR if one is present, setting password won't work if it is present */
377 	p = strchrnul(setting->password, '\n');
378 	*p = '\0';
379 	return count;
380 }
381 
382 static struct kobj_attribute auth_current_password = __ATTR_WO(current_password);
383 
384 static ssize_t new_password_store(struct kobject *kobj,
385 				  struct kobj_attribute *attr,
386 				  const char *buf, size_t count)
387 {
388 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
389 	char *auth_str, *new_pwd, *p;
390 	size_t pwdlen;
391 	int ret;
392 
393 	if (!capable(CAP_SYS_ADMIN))
394 		return -EPERM;
395 
396 	if (!tlmi_priv.can_set_bios_password)
397 		return -EOPNOTSUPP;
398 
399 	new_pwd = kstrdup(buf, GFP_KERNEL);
400 	if (!new_pwd)
401 		return -ENOMEM;
402 
403 	/* Strip out CR if one is present, setting password won't work if it is present */
404 	p = strchrnul(new_pwd, '\n');
405 	*p = '\0';
406 
407 	pwdlen = strlen(new_pwd);
408 	/* pwdlen == 0 is allowed to clear the password */
409 	if (pwdlen && ((pwdlen < setting->minlen) || (pwdlen > setting->maxlen))) {
410 		ret = -EINVAL;
411 		goto out;
412 	}
413 
414 	/* If opcode support is present use that interface */
415 	if (tlmi_priv.opcode_support) {
416 		char pwd_type[8];
417 
418 		/* Special handling required for HDD and NVMe passwords */
419 		if (setting == tlmi_priv.pwd_hdd) {
420 			if (setting->level == TLMI_LEVEL_USER)
421 				sprintf(pwd_type, "uhdp%d", setting->index);
422 			else
423 				sprintf(pwd_type, "mhdp%d", setting->index);
424 		} else if (setting == tlmi_priv.pwd_nvme) {
425 			if (setting->level == TLMI_LEVEL_USER)
426 				sprintf(pwd_type, "unvp%d", setting->index);
427 			else
428 				sprintf(pwd_type, "mnvp%d", setting->index);
429 		} else {
430 			sprintf(pwd_type, "%s", setting->pwd_type);
431 		}
432 
433 		ret = tlmi_opcode_setting("WmiOpcodePasswordType", pwd_type);
434 		if (ret)
435 			goto out;
436 
437 		if (tlmi_priv.pwd_admin->valid) {
438 			ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin",
439 					tlmi_priv.pwd_admin->password);
440 			if (ret)
441 				goto out;
442 		}
443 		ret = tlmi_opcode_setting("WmiOpcodePasswordCurrent01", setting->password);
444 		if (ret)
445 			goto out;
446 		ret = tlmi_opcode_setting("WmiOpcodePasswordNew01", new_pwd);
447 		if (ret)
448 			goto out;
449 		ret = tlmi_simple_call(LENOVO_OPCODE_IF_GUID, "WmiOpcodePasswordSetUpdate;");
450 	} else {
451 		/* Format: 'PasswordType,CurrentPw,NewPw,Encoding,KbdLang;' */
452 		auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s,%s,%s;",
453 				setting->pwd_type, setting->password, new_pwd,
454 				encoding_options[setting->encoding], setting->kbdlang);
455 		if (!auth_str) {
456 			ret = -ENOMEM;
457 			goto out;
458 		}
459 		ret = tlmi_simple_call(LENOVO_SET_BIOS_PASSWORD_GUID, auth_str);
460 		kfree(auth_str);
461 	}
462 out:
463 	kfree(new_pwd);
464 	return ret ?: count;
465 }
466 
467 static struct kobj_attribute auth_new_password = __ATTR_WO(new_password);
468 
469 static ssize_t min_password_length_show(struct kobject *kobj, struct kobj_attribute *attr,
470 			 char *buf)
471 {
472 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
473 
474 	return sysfs_emit(buf, "%d\n", setting->minlen);
475 }
476 
477 static struct kobj_attribute auth_min_pass_length = __ATTR_RO(min_password_length);
478 
479 static ssize_t max_password_length_show(struct kobject *kobj, struct kobj_attribute *attr,
480 			 char *buf)
481 {
482 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
483 
484 	return sysfs_emit(buf, "%d\n", setting->maxlen);
485 }
486 static struct kobj_attribute auth_max_pass_length = __ATTR_RO(max_password_length);
487 
488 static ssize_t mechanism_show(struct kobject *kobj, struct kobj_attribute *attr,
489 			 char *buf)
490 {
491 	return sysfs_emit(buf, "password\n");
492 }
493 static struct kobj_attribute auth_mechanism = __ATTR_RO(mechanism);
494 
495 static ssize_t encoding_show(struct kobject *kobj, struct kobj_attribute *attr,
496 			 char *buf)
497 {
498 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
499 
500 	return sysfs_emit(buf, "%s\n", encoding_options[setting->encoding]);
501 }
502 
503 static ssize_t encoding_store(struct kobject *kobj,
504 				  struct kobj_attribute *attr,
505 				  const char *buf, size_t count)
506 {
507 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
508 	int i;
509 
510 	/* Scan for a matching profile */
511 	i = sysfs_match_string(encoding_options, buf);
512 	if (i < 0)
513 		return -EINVAL;
514 
515 	setting->encoding = i;
516 	return count;
517 }
518 
519 static struct kobj_attribute auth_encoding = __ATTR_RW(encoding);
520 
521 static ssize_t kbdlang_show(struct kobject *kobj, struct kobj_attribute *attr,
522 			 char *buf)
523 {
524 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
525 
526 	return sysfs_emit(buf, "%s\n", setting->kbdlang);
527 }
528 
529 static ssize_t kbdlang_store(struct kobject *kobj,
530 				  struct kobj_attribute *attr,
531 				  const char *buf, size_t count)
532 {
533 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
534 	int length;
535 
536 	/* Calculate length till '\n' or terminating 0 */
537 	length = strchrnul(buf, '\n') - buf;
538 	if (!length || length >= TLMI_LANG_MAXLEN)
539 		return -EINVAL;
540 
541 	memcpy(setting->kbdlang, buf, length);
542 	setting->kbdlang[length] = '\0';
543 	return count;
544 }
545 
546 static struct kobj_attribute auth_kbdlang = __ATTR_RW(kbdlang);
547 
548 static ssize_t role_show(struct kobject *kobj, struct kobj_attribute *attr,
549 			 char *buf)
550 {
551 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
552 
553 	return sysfs_emit(buf, "%s\n", setting->role);
554 }
555 static struct kobj_attribute auth_role = __ATTR_RO(role);
556 
557 static ssize_t index_show(struct kobject *kobj, struct kobj_attribute *attr,
558 			 char *buf)
559 {
560 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
561 
562 	return sysfs_emit(buf, "%d\n", setting->index);
563 }
564 
565 static ssize_t index_store(struct kobject *kobj,
566 				  struct kobj_attribute *attr,
567 				  const char *buf, size_t count)
568 {
569 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
570 	int err, val;
571 
572 	err = kstrtoint(buf, 10, &val);
573 	if (err < 0)
574 		return err;
575 
576 	if (val < 0 || val > TLMI_INDEX_MAX)
577 		return -EINVAL;
578 
579 	setting->index = val;
580 	return count;
581 }
582 
583 static struct kobj_attribute auth_index = __ATTR_RW(index);
584 
585 static ssize_t level_show(struct kobject *kobj, struct kobj_attribute *attr,
586 			 char *buf)
587 {
588 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
589 
590 	return sysfs_emit(buf, "%s\n", level_options[setting->level]);
591 }
592 
593 static ssize_t level_store(struct kobject *kobj,
594 				  struct kobj_attribute *attr,
595 				  const char *buf, size_t count)
596 {
597 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
598 	int i;
599 
600 	/* Scan for a matching profile */
601 	i = sysfs_match_string(level_options, buf);
602 	if (i < 0)
603 		return -EINVAL;
604 
605 	setting->level = i;
606 	return count;
607 }
608 
609 static struct kobj_attribute auth_level = __ATTR_RW(level);
610 
611 static umode_t auth_attr_is_visible(struct kobject *kobj,
612 					     struct attribute *attr, int n)
613 {
614 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
615 
616 	/*We only want to display level and index settings on HDD/NVMe */
617 	if ((attr == (struct attribute *)&auth_index) ||
618 			(attr == (struct attribute *)&auth_level)) {
619 		if ((setting == tlmi_priv.pwd_hdd) || (setting == tlmi_priv.pwd_nvme))
620 			return attr->mode;
621 		return 0;
622 	}
623 	return attr->mode;
624 }
625 
626 static struct attribute *auth_attrs[] = {
627 	&auth_is_pass_set.attr,
628 	&auth_min_pass_length.attr,
629 	&auth_max_pass_length.attr,
630 	&auth_current_password.attr,
631 	&auth_new_password.attr,
632 	&auth_role.attr,
633 	&auth_mechanism.attr,
634 	&auth_encoding.attr,
635 	&auth_kbdlang.attr,
636 	&auth_index.attr,
637 	&auth_level.attr,
638 	NULL
639 };
640 
641 static const struct attribute_group auth_attr_group = {
642 	.is_visible = auth_attr_is_visible,
643 	.attrs = auth_attrs,
644 };
645 
646 /* ---- Attributes sysfs --------------------------------------------------------- */
647 static ssize_t display_name_show(struct kobject *kobj, struct kobj_attribute *attr,
648 		char *buf)
649 {
650 	struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
651 
652 	return sysfs_emit(buf, "%s\n", setting->display_name);
653 }
654 
655 static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
656 {
657 	struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
658 	char *item, *value;
659 	int ret;
660 
661 	ret = tlmi_setting(setting->index, &item, LENOVO_BIOS_SETTING_GUID);
662 	if (ret)
663 		return ret;
664 
665 	/* validate and split from `item,value` -> `value` */
666 	value = strpbrk(item, ",");
667 	if (!value || value == item || !strlen(value + 1))
668 		return -EINVAL;
669 
670 	ret = sysfs_emit(buf, "%s\n", value + 1);
671 	kfree(item);
672 	return ret;
673 }
674 
675 static ssize_t possible_values_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
676 {
677 	struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
678 
679 	if (!tlmi_priv.can_get_bios_selections)
680 		return -EOPNOTSUPP;
681 
682 	return sysfs_emit(buf, "%s\n", setting->possible_values);
683 }
684 
685 static ssize_t current_value_store(struct kobject *kobj,
686 		struct kobj_attribute *attr,
687 		const char *buf, size_t count)
688 {
689 	struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
690 	char *set_str = NULL, *new_setting = NULL;
691 	char *auth_str = NULL;
692 	char *p;
693 	int ret;
694 
695 	if (!tlmi_priv.can_set_bios_settings)
696 		return -EOPNOTSUPP;
697 
698 	new_setting = kstrdup(buf, GFP_KERNEL);
699 	if (!new_setting)
700 		return -ENOMEM;
701 
702 	/* Strip out CR if one is present */
703 	p = strchrnul(new_setting, '\n');
704 	*p = '\0';
705 
706 	if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
707 		auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",
708 				tlmi_priv.pwd_admin->password,
709 				encoding_options[tlmi_priv.pwd_admin->encoding],
710 				tlmi_priv.pwd_admin->kbdlang);
711 		if (!auth_str) {
712 			ret = -ENOMEM;
713 			goto out;
714 		}
715 	}
716 
717 	if (auth_str)
718 		set_str = kasprintf(GFP_KERNEL, "%s,%s,%s", setting->display_name,
719 				new_setting, auth_str);
720 	else
721 		set_str = kasprintf(GFP_KERNEL, "%s,%s;", setting->display_name,
722 				new_setting);
723 	if (!set_str) {
724 		ret = -ENOMEM;
725 		goto out;
726 	}
727 
728 	ret = tlmi_simple_call(LENOVO_SET_BIOS_SETTINGS_GUID, set_str);
729 	if (ret)
730 		goto out;
731 
732 	if (auth_str)
733 		ret = tlmi_save_bios_settings(auth_str);
734 	else
735 		ret = tlmi_save_bios_settings("");
736 
737 	if (!ret && !tlmi_priv.pending_changes) {
738 		tlmi_priv.pending_changes = true;
739 		/* let userland know it may need to check reboot pending again */
740 		kobject_uevent(&tlmi_priv.class_dev->kobj, KOBJ_CHANGE);
741 	}
742 out:
743 	kfree(auth_str);
744 	kfree(set_str);
745 	kfree(new_setting);
746 	return ret ?: count;
747 }
748 
749 static struct kobj_attribute attr_displ_name = __ATTR_RO(display_name);
750 
751 static struct kobj_attribute attr_possible_values = __ATTR_RO(possible_values);
752 
753 static struct kobj_attribute attr_current_val = __ATTR_RW_MODE(current_value, 0600);
754 
755 static struct attribute *tlmi_attrs[] = {
756 	&attr_displ_name.attr,
757 	&attr_current_val.attr,
758 	&attr_possible_values.attr,
759 	NULL
760 };
761 
762 static const struct attribute_group tlmi_attr_group = {
763 	.attrs = tlmi_attrs,
764 };
765 
766 static ssize_t tlmi_attr_show(struct kobject *kobj, struct attribute *attr,
767 				    char *buf)
768 {
769 	struct kobj_attribute *kattr;
770 
771 	kattr = container_of(attr, struct kobj_attribute, attr);
772 	if (kattr->show)
773 		return kattr->show(kobj, kattr, buf);
774 	return -EIO;
775 }
776 
777 static ssize_t tlmi_attr_store(struct kobject *kobj, struct attribute *attr,
778 				     const char *buf, size_t count)
779 {
780 	struct kobj_attribute *kattr;
781 
782 	kattr = container_of(attr, struct kobj_attribute, attr);
783 	if (kattr->store)
784 		return kattr->store(kobj, kattr, buf, count);
785 	return -EIO;
786 }
787 
788 static const struct sysfs_ops tlmi_kobj_sysfs_ops = {
789 	.show	= tlmi_attr_show,
790 	.store	= tlmi_attr_store,
791 };
792 
793 static void tlmi_attr_setting_release(struct kobject *kobj)
794 {
795 	struct tlmi_attr_setting *setting = to_tlmi_attr_setting(kobj);
796 
797 	kfree(setting->possible_values);
798 	kfree(setting);
799 }
800 
801 static void tlmi_pwd_setting_release(struct kobject *kobj)
802 {
803 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
804 
805 	kfree(setting);
806 }
807 
808 static struct kobj_type tlmi_attr_setting_ktype = {
809 	.release        = &tlmi_attr_setting_release,
810 	.sysfs_ops	= &tlmi_kobj_sysfs_ops,
811 };
812 
813 static struct kobj_type tlmi_pwd_setting_ktype = {
814 	.release        = &tlmi_pwd_setting_release,
815 	.sysfs_ops	= &tlmi_kobj_sysfs_ops,
816 };
817 
818 static ssize_t pending_reboot_show(struct kobject *kobj, struct kobj_attribute *attr,
819 				   char *buf)
820 {
821 	return sprintf(buf, "%d\n", tlmi_priv.pending_changes);
822 }
823 
824 static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot);
825 
826 /* ---- Debug interface--------------------------------------------------------- */
827 static ssize_t debug_cmd_store(struct kobject *kobj, struct kobj_attribute *attr,
828 				const char *buf, size_t count)
829 {
830 	char *set_str = NULL, *new_setting = NULL;
831 	char *auth_str = NULL;
832 	char *p;
833 	int ret;
834 
835 	if (!tlmi_priv.can_debug_cmd)
836 		return -EOPNOTSUPP;
837 
838 	new_setting = kstrdup(buf, GFP_KERNEL);
839 	if (!new_setting)
840 		return -ENOMEM;
841 
842 	/* Strip out CR if one is present */
843 	p = strchrnul(new_setting, '\n');
844 	*p = '\0';
845 
846 	if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
847 		auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",
848 				tlmi_priv.pwd_admin->password,
849 				encoding_options[tlmi_priv.pwd_admin->encoding],
850 				tlmi_priv.pwd_admin->kbdlang);
851 		if (!auth_str) {
852 			ret = -ENOMEM;
853 			goto out;
854 		}
855 	}
856 
857 	if (auth_str)
858 		set_str = kasprintf(GFP_KERNEL, "%s,%s", new_setting, auth_str);
859 	else
860 		set_str = kasprintf(GFP_KERNEL, "%s;", new_setting);
861 	if (!set_str) {
862 		ret = -ENOMEM;
863 		goto out;
864 	}
865 
866 	ret = tlmi_simple_call(LENOVO_DEBUG_CMD_GUID, set_str);
867 	if (ret)
868 		goto out;
869 
870 	if (!ret && !tlmi_priv.pending_changes) {
871 		tlmi_priv.pending_changes = true;
872 		/* let userland know it may need to check reboot pending again */
873 		kobject_uevent(&tlmi_priv.class_dev->kobj, KOBJ_CHANGE);
874 	}
875 out:
876 	kfree(auth_str);
877 	kfree(set_str);
878 	kfree(new_setting);
879 	return ret ?: count;
880 }
881 
882 static struct kobj_attribute debug_cmd = __ATTR_WO(debug_cmd);
883 
884 /* ---- Initialisation --------------------------------------------------------- */
885 static void tlmi_release_attr(void)
886 {
887 	int i;
888 
889 	/* Attribute structures */
890 	for (i = 0; i < TLMI_SETTINGS_COUNT; i++) {
891 		if (tlmi_priv.setting[i]) {
892 			sysfs_remove_group(&tlmi_priv.setting[i]->kobj, &tlmi_attr_group);
893 			kobject_put(&tlmi_priv.setting[i]->kobj);
894 		}
895 	}
896 	sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr);
897 	if (tlmi_priv.can_debug_cmd && debug_support)
898 		sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &debug_cmd.attr);
899 	kset_unregister(tlmi_priv.attribute_kset);
900 
901 	/* Authentication structures */
902 	sysfs_remove_group(&tlmi_priv.pwd_admin->kobj, &auth_attr_group);
903 	kobject_put(&tlmi_priv.pwd_admin->kobj);
904 	sysfs_remove_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group);
905 	kobject_put(&tlmi_priv.pwd_power->kobj);
906 
907 	if (tlmi_priv.opcode_support) {
908 		sysfs_remove_group(&tlmi_priv.pwd_system->kobj, &auth_attr_group);
909 		kobject_put(&tlmi_priv.pwd_system->kobj);
910 		sysfs_remove_group(&tlmi_priv.pwd_hdd->kobj, &auth_attr_group);
911 		kobject_put(&tlmi_priv.pwd_hdd->kobj);
912 		sysfs_remove_group(&tlmi_priv.pwd_nvme->kobj, &auth_attr_group);
913 		kobject_put(&tlmi_priv.pwd_nvme->kobj);
914 	}
915 
916 	kset_unregister(tlmi_priv.authentication_kset);
917 }
918 
919 static int tlmi_sysfs_init(void)
920 {
921 	int i, ret;
922 
923 	ret = fw_attributes_class_get(&fw_attr_class);
924 	if (ret)
925 		return ret;
926 
927 	tlmi_priv.class_dev = device_create(fw_attr_class, NULL, MKDEV(0, 0),
928 			NULL, "%s", "thinklmi");
929 	if (IS_ERR(tlmi_priv.class_dev)) {
930 		ret = PTR_ERR(tlmi_priv.class_dev);
931 		goto fail_class_created;
932 	}
933 
934 	tlmi_priv.attribute_kset = kset_create_and_add("attributes", NULL,
935 			&tlmi_priv.class_dev->kobj);
936 	if (!tlmi_priv.attribute_kset) {
937 		ret = -ENOMEM;
938 		goto fail_device_created;
939 	}
940 
941 	for (i = 0; i < TLMI_SETTINGS_COUNT; i++) {
942 		/* Check if index is a valid setting - skip if it isn't */
943 		if (!tlmi_priv.setting[i])
944 			continue;
945 
946 		/* check for duplicate or reserved values */
947 		if (kset_find_obj(tlmi_priv.attribute_kset, tlmi_priv.setting[i]->display_name) ||
948 		    !strcmp(tlmi_priv.setting[i]->display_name, "Reserved")) {
949 			pr_debug("duplicate or reserved attribute name found - %s\n",
950 				tlmi_priv.setting[i]->display_name);
951 			kfree(tlmi_priv.setting[i]->possible_values);
952 			kfree(tlmi_priv.setting[i]);
953 			tlmi_priv.setting[i] = NULL;
954 			continue;
955 		}
956 
957 		/* Build attribute */
958 		tlmi_priv.setting[i]->kobj.kset = tlmi_priv.attribute_kset;
959 		ret = kobject_add(&tlmi_priv.setting[i]->kobj, NULL,
960 				  "%s", tlmi_priv.setting[i]->display_name);
961 		if (ret)
962 			goto fail_create_attr;
963 
964 		ret = sysfs_create_group(&tlmi_priv.setting[i]->kobj, &tlmi_attr_group);
965 		if (ret)
966 			goto fail_create_attr;
967 	}
968 
969 	ret = sysfs_create_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr);
970 	if (ret)
971 		goto fail_create_attr;
972 
973 	if (tlmi_priv.can_debug_cmd && debug_support) {
974 		ret = sysfs_create_file(&tlmi_priv.attribute_kset->kobj, &debug_cmd.attr);
975 		if (ret)
976 			goto fail_create_attr;
977 	}
978 	/* Create authentication entries */
979 	tlmi_priv.authentication_kset = kset_create_and_add("authentication", NULL,
980 								&tlmi_priv.class_dev->kobj);
981 	if (!tlmi_priv.authentication_kset) {
982 		ret = -ENOMEM;
983 		goto fail_create_attr;
984 	}
985 	tlmi_priv.pwd_admin->kobj.kset = tlmi_priv.authentication_kset;
986 	ret = kobject_add(&tlmi_priv.pwd_admin->kobj, NULL, "%s", "Admin");
987 	if (ret)
988 		goto fail_create_attr;
989 
990 	ret = sysfs_create_group(&tlmi_priv.pwd_admin->kobj, &auth_attr_group);
991 	if (ret)
992 		goto fail_create_attr;
993 
994 	tlmi_priv.pwd_power->kobj.kset = tlmi_priv.authentication_kset;
995 	ret = kobject_add(&tlmi_priv.pwd_power->kobj, NULL, "%s", "Power-on");
996 	if (ret)
997 		goto fail_create_attr;
998 
999 	ret = sysfs_create_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group);
1000 	if (ret)
1001 		goto fail_create_attr;
1002 
1003 	if (tlmi_priv.opcode_support) {
1004 		tlmi_priv.pwd_system->kobj.kset = tlmi_priv.authentication_kset;
1005 		ret = kobject_add(&tlmi_priv.pwd_system->kobj, NULL, "%s", "System");
1006 		if (ret)
1007 			goto fail_create_attr;
1008 
1009 		ret = sysfs_create_group(&tlmi_priv.pwd_system->kobj, &auth_attr_group);
1010 		if (ret)
1011 			goto fail_create_attr;
1012 
1013 		tlmi_priv.pwd_hdd->kobj.kset = tlmi_priv.authentication_kset;
1014 		ret = kobject_add(&tlmi_priv.pwd_hdd->kobj, NULL, "%s", "HDD");
1015 		if (ret)
1016 			goto fail_create_attr;
1017 
1018 		ret = sysfs_create_group(&tlmi_priv.pwd_hdd->kobj, &auth_attr_group);
1019 		if (ret)
1020 			goto fail_create_attr;
1021 
1022 		tlmi_priv.pwd_nvme->kobj.kset = tlmi_priv.authentication_kset;
1023 		ret = kobject_add(&tlmi_priv.pwd_nvme->kobj, NULL, "%s", "NVMe");
1024 		if (ret)
1025 			goto fail_create_attr;
1026 
1027 		ret = sysfs_create_group(&tlmi_priv.pwd_nvme->kobj, &auth_attr_group);
1028 		if (ret)
1029 			goto fail_create_attr;
1030 	}
1031 
1032 	return ret;
1033 
1034 fail_create_attr:
1035 	tlmi_release_attr();
1036 fail_device_created:
1037 	device_destroy(fw_attr_class, MKDEV(0, 0));
1038 fail_class_created:
1039 	fw_attributes_class_put();
1040 	return ret;
1041 }
1042 
1043 /* ---- Base Driver -------------------------------------------------------- */
1044 static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type,
1045 			    const char *pwd_role)
1046 {
1047 	struct tlmi_pwd_setting *new_pwd;
1048 
1049 	new_pwd = kzalloc(sizeof(struct tlmi_pwd_setting), GFP_KERNEL);
1050 	if (!new_pwd)
1051 		return NULL;
1052 
1053 	strscpy(new_pwd->kbdlang, "us", TLMI_LANG_MAXLEN);
1054 	new_pwd->encoding = TLMI_ENCODING_ASCII;
1055 	new_pwd->pwd_type = pwd_type;
1056 	new_pwd->role = pwd_role;
1057 	new_pwd->minlen = tlmi_priv.pwdcfg.core.min_length;
1058 	new_pwd->maxlen = tlmi_priv.pwdcfg.core.max_length;
1059 	new_pwd->index = 0;
1060 
1061 	kobject_init(&new_pwd->kobj, &tlmi_pwd_setting_ktype);
1062 
1063 	return new_pwd;
1064 }
1065 
1066 static int tlmi_analyze(void)
1067 {
1068 	acpi_status status;
1069 	int i, ret;
1070 
1071 	if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) &&
1072 	    wmi_has_guid(LENOVO_SAVE_BIOS_SETTINGS_GUID))
1073 		tlmi_priv.can_set_bios_settings = true;
1074 
1075 	if (wmi_has_guid(LENOVO_GET_BIOS_SELECTIONS_GUID))
1076 		tlmi_priv.can_get_bios_selections = true;
1077 
1078 	if (wmi_has_guid(LENOVO_SET_BIOS_PASSWORD_GUID))
1079 		tlmi_priv.can_set_bios_password = true;
1080 
1081 	if (wmi_has_guid(LENOVO_BIOS_PASSWORD_SETTINGS_GUID))
1082 		tlmi_priv.can_get_password_settings = true;
1083 
1084 	if (wmi_has_guid(LENOVO_DEBUG_CMD_GUID))
1085 		tlmi_priv.can_debug_cmd = true;
1086 
1087 	if (wmi_has_guid(LENOVO_OPCODE_IF_GUID))
1088 		tlmi_priv.opcode_support = true;
1089 
1090 	/*
1091 	 * Try to find the number of valid settings of this machine
1092 	 * and use it to create sysfs attributes.
1093 	 */
1094 	for (i = 0; i < TLMI_SETTINGS_COUNT; ++i) {
1095 		struct tlmi_attr_setting *setting;
1096 		char *item = NULL;
1097 		char *p;
1098 
1099 		tlmi_priv.setting[i] = NULL;
1100 		status = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID);
1101 		if (ACPI_FAILURE(status))
1102 			break;
1103 		if (!item)
1104 			break;
1105 		if (!*item) {
1106 			kfree(item);
1107 			continue;
1108 		}
1109 
1110 		/* It is not allowed to have '/' for file name. Convert it into '\'. */
1111 		strreplace(item, '/', '\\');
1112 
1113 		/* Remove the value part */
1114 		p = strchrnul(item, ',');
1115 		*p = '\0';
1116 
1117 		/* Create a setting entry */
1118 		setting = kzalloc(sizeof(*setting), GFP_KERNEL);
1119 		if (!setting) {
1120 			ret = -ENOMEM;
1121 			kfree(item);
1122 			goto fail_clear_attr;
1123 		}
1124 		setting->index = i;
1125 		strscpy(setting->display_name, item, TLMI_SETTINGS_MAXLEN);
1126 		/* If BIOS selections supported, load those */
1127 		if (tlmi_priv.can_get_bios_selections) {
1128 			ret = tlmi_get_bios_selections(setting->display_name,
1129 					&setting->possible_values);
1130 			if (ret || !setting->possible_values)
1131 				pr_info("Error retrieving possible values for %d : %s\n",
1132 						i, setting->display_name);
1133 		}
1134 		kobject_init(&setting->kobj, &tlmi_attr_setting_ktype);
1135 		tlmi_priv.setting[i] = setting;
1136 		kfree(item);
1137 	}
1138 
1139 	/* Create password setting structure */
1140 	ret = tlmi_get_pwd_settings(&tlmi_priv.pwdcfg);
1141 	if (ret)
1142 		goto fail_clear_attr;
1143 
1144 	/* All failures below boil down to kmalloc failures */
1145 	ret = -ENOMEM;
1146 
1147 	tlmi_priv.pwd_admin = tlmi_create_auth("pap", "bios-admin");
1148 	if (!tlmi_priv.pwd_admin)
1149 		goto fail_clear_attr;
1150 
1151 	if (tlmi_priv.pwdcfg.core.password_state & TLMI_PAP_PWD)
1152 		tlmi_priv.pwd_admin->valid = true;
1153 
1154 	tlmi_priv.pwd_power = tlmi_create_auth("pop", "power-on");
1155 	if (!tlmi_priv.pwd_power)
1156 		goto fail_clear_attr;
1157 
1158 	if (tlmi_priv.pwdcfg.core.password_state & TLMI_POP_PWD)
1159 		tlmi_priv.pwd_power->valid = true;
1160 
1161 	if (tlmi_priv.opcode_support) {
1162 		tlmi_priv.pwd_system = tlmi_create_auth("sys", "system");
1163 		if (!tlmi_priv.pwd_system)
1164 			goto fail_clear_attr;
1165 
1166 		if (tlmi_priv.pwdcfg.core.password_state & TLMI_SYS_PWD)
1167 			tlmi_priv.pwd_system->valid = true;
1168 
1169 		tlmi_priv.pwd_hdd = tlmi_create_auth("hdd", "hdd");
1170 		if (!tlmi_priv.pwd_hdd)
1171 			goto fail_clear_attr;
1172 
1173 		tlmi_priv.pwd_nvme = tlmi_create_auth("nvm", "nvme");
1174 		if (!tlmi_priv.pwd_nvme)
1175 			goto fail_clear_attr;
1176 
1177 		if (tlmi_priv.pwdcfg.core.password_state & TLMI_HDD_PWD) {
1178 			/* Check if PWD is configured and set index to first drive found */
1179 			if (tlmi_priv.pwdcfg.ext.hdd_user_password ||
1180 					tlmi_priv.pwdcfg.ext.hdd_master_password) {
1181 				tlmi_priv.pwd_hdd->valid = true;
1182 				if (tlmi_priv.pwdcfg.ext.hdd_master_password)
1183 					tlmi_priv.pwd_hdd->index =
1184 						ffs(tlmi_priv.pwdcfg.ext.hdd_master_password) - 1;
1185 				else
1186 					tlmi_priv.pwd_hdd->index =
1187 						ffs(tlmi_priv.pwdcfg.ext.hdd_user_password) - 1;
1188 			}
1189 			if (tlmi_priv.pwdcfg.ext.nvme_user_password ||
1190 					tlmi_priv.pwdcfg.ext.nvme_master_password) {
1191 				tlmi_priv.pwd_nvme->valid = true;
1192 				if (tlmi_priv.pwdcfg.ext.nvme_master_password)
1193 					tlmi_priv.pwd_nvme->index =
1194 						ffs(tlmi_priv.pwdcfg.ext.nvme_master_password) - 1;
1195 				else
1196 					tlmi_priv.pwd_nvme->index =
1197 						ffs(tlmi_priv.pwdcfg.ext.nvme_user_password) - 1;
1198 			}
1199 		}
1200 	}
1201 	return 0;
1202 
1203 fail_clear_attr:
1204 	for (i = 0; i < TLMI_SETTINGS_COUNT; ++i) {
1205 		if (tlmi_priv.setting[i]) {
1206 			kfree(tlmi_priv.setting[i]->possible_values);
1207 			kfree(tlmi_priv.setting[i]);
1208 		}
1209 	}
1210 	kfree(tlmi_priv.pwd_admin);
1211 	kfree(tlmi_priv.pwd_power);
1212 	kfree(tlmi_priv.pwd_system);
1213 	kfree(tlmi_priv.pwd_hdd);
1214 	kfree(tlmi_priv.pwd_nvme);
1215 	return ret;
1216 }
1217 
1218 static void tlmi_remove(struct wmi_device *wdev)
1219 {
1220 	tlmi_release_attr();
1221 	device_destroy(fw_attr_class, MKDEV(0, 0));
1222 	fw_attributes_class_put();
1223 }
1224 
1225 static int tlmi_probe(struct wmi_device *wdev, const void *context)
1226 {
1227 	int ret;
1228 
1229 	ret = tlmi_analyze();
1230 	if (ret)
1231 		return ret;
1232 
1233 	return tlmi_sysfs_init();
1234 }
1235 
1236 static const struct wmi_device_id tlmi_id_table[] = {
1237 	{ .guid_string = LENOVO_BIOS_SETTING_GUID },
1238 	{ }
1239 };
1240 MODULE_DEVICE_TABLE(wmi, tlmi_id_table);
1241 
1242 static struct wmi_driver tlmi_driver = {
1243 	.driver = {
1244 		.name = "think-lmi",
1245 	},
1246 	.id_table = tlmi_id_table,
1247 	.probe = tlmi_probe,
1248 	.remove = tlmi_remove,
1249 };
1250 
1251 MODULE_AUTHOR("Sugumaran L <slacshiminar@lenovo.com>");
1252 MODULE_AUTHOR("Mark Pearson <markpearson@lenovo.com>");
1253 MODULE_AUTHOR("Corentin Chary <corentin.chary@gmail.com>");
1254 MODULE_DESCRIPTION("ThinkLMI Driver");
1255 MODULE_LICENSE("GPL");
1256 
1257 module_wmi_driver(tlmi_driver);
1258