aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/thinkpad_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/thinkpad_acpi.c')
-rw-r--r--drivers/misc/thinkpad_acpi.c98
1 files changed, 70 insertions, 28 deletions
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 44aa8c92f91f..99500af651c1 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -717,9 +717,19 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
717 printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION); 717 printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
718 printk(IBM_INFO "%s\n", IBM_URL); 718 printk(IBM_INFO "%s\n", IBM_URL);
719 719
720 if (ibm_thinkpad_ec_found) 720 printk(IBM_INFO "ThinkPad BIOS %s, EC %s\n",
721 printk(IBM_INFO "ThinkPad EC firmware %s\n", 721 (thinkpad_id.bios_version_str) ?
722 ibm_thinkpad_ec_found); 722 thinkpad_id.bios_version_str : "unknown",
723 (thinkpad_id.ec_version_str) ?
724 thinkpad_id.ec_version_str : "unknown");
725
726 if (thinkpad_id.vendor && thinkpad_id.model_str)
727 printk(IBM_INFO "%s %s\n",
728 (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?
729 "IBM" : ((thinkpad_id.vendor ==
730 PCI_VENDOR_ID_LENOVO) ?
731 "Lenovo" : "Unknown vendor"),
732 thinkpad_id.model_str);
723 733
724 return 0; 734 return 0;
725} 735}
@@ -2648,7 +2658,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
2648 2658
2649 acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); 2659 acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
2650 2660
2651 if (ibm_thinkpad_ec_found && experimental) { 2661 if (thinkpad_id.ec_model && experimental) {
2652 /* 2662 /*
2653 * Direct EC access mode: sensors at registers 2663 * Direct EC access mode: sensors at registers
2654 * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for 2664 * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for
@@ -3532,20 +3542,19 @@ static int __init fan_init(struct ibm_init_struct *iibm)
3532 * Enable for TP-1Y (T43), TP-78 (R51e), 3542 * Enable for TP-1Y (T43), TP-78 (R51e),
3533 * TP-76 (R52), TP-70 (T43, R52), which are known 3543 * TP-76 (R52), TP-70 (T43, R52), which are known
3534 * to be buggy. */ 3544 * to be buggy. */
3535 if (fan_control_initial_status == 0x07 && 3545 if (fan_control_initial_status == 0x07) {
3536 ibm_thinkpad_ec_found && 3546 switch (thinkpad_id.ec_model) {
3537 ((ibm_thinkpad_ec_found[0] == '1' && 3547 case 0x5931: /* TP-1Y */
3538 ibm_thinkpad_ec_found[1] == 'Y') || 3548 case 0x3837: /* TP-78 */
3539 (ibm_thinkpad_ec_found[0] == '7' && 3549 case 0x3637: /* TP-76 */
3540 (ibm_thinkpad_ec_found[1] == '6' || 3550 case 0x3037: /* TP-70 */
3541 ibm_thinkpad_ec_found[1] == '8' || 3551 printk(IBM_NOTICE
3542 ibm_thinkpad_ec_found[1] == '0')) 3552 "fan_init: initial fan status is "
3543 )) { 3553 "unknown, assuming it is in auto "
3544 printk(IBM_NOTICE 3554 "mode\n");
3545 "fan_init: initial fan status is " 3555 tp_features.fan_ctrl_status_undef = 1;
3546 "unknown, assuming it is in auto " 3556 ;;
3547 "mode\n"); 3557 }
3548 tp_features.fan_ctrl_status_undef = 1;
3549 } 3558 }
3550 } else { 3559 } else {
3551 printk(IBM_ERR 3560 printk(IBM_ERR
@@ -4279,13 +4288,30 @@ static void ibm_exit(struct ibm_struct *ibm)
4279 4288
4280/* Probing */ 4289/* Probing */
4281 4290
4282static char *ibm_thinkpad_ec_found; 4291static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp)
4283
4284static char* __init check_dmi_for_ec(void)
4285{ 4292{
4286 struct dmi_device *dev = NULL; 4293 struct dmi_device *dev = NULL;
4287 char ec_fw_string[18]; 4294 char ec_fw_string[18];
4288 4295
4296 if (!tp)
4297 return;
4298
4299 memset(tp, 0, sizeof(*tp));
4300
4301 if (dmi_name_in_vendors("IBM"))
4302 tp->vendor = PCI_VENDOR_ID_IBM;
4303 else if (dmi_name_in_vendors("LENOVO"))
4304 tp->vendor = PCI_VENDOR_ID_LENOVO;
4305 else
4306 return;
4307
4308 tp->bios_version_str = kstrdup(dmi_get_system_info(DMI_BIOS_VERSION),
4309 GFP_KERNEL);
4310 if (!tp->bios_version_str)
4311 return;
4312 tp->bios_model = tp->bios_version_str[0]
4313 | (tp->bios_version_str[1] << 8);
4314
4289 /* 4315 /*
4290 * ThinkPad T23 or newer, A31 or newer, R50e or newer, 4316 * ThinkPad T23 or newer, A31 or newer, R50e or newer,
4291 * X32 or newer, all Z series; Some models must have an 4317 * X32 or newer, all Z series; Some models must have an
@@ -4299,10 +4325,20 @@ static char* __init check_dmi_for_ec(void)
4299 ec_fw_string) == 1) { 4325 ec_fw_string) == 1) {
4300 ec_fw_string[sizeof(ec_fw_string) - 1] = 0; 4326 ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
4301 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0; 4327 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
4302 return kstrdup(ec_fw_string, GFP_KERNEL); 4328
4329 tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL);
4330 tp->ec_model = ec_fw_string[0]
4331 | (ec_fw_string[1] << 8);
4332 break;
4303 } 4333 }
4304 } 4334 }
4305 return NULL; 4335
4336 tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION),
4337 GFP_KERNEL);
4338 if (strnicmp(tp->model_str, "ThinkPad", 8) != 0) {
4339 kfree(tp->model_str);
4340 tp->model_str = NULL;
4341 }
4306} 4342}
4307 4343
4308static int __init probe_for_thinkpad(void) 4344static int __init probe_for_thinkpad(void)
@@ -4316,7 +4352,7 @@ static int __init probe_for_thinkpad(void)
4316 * Non-ancient models have better DMI tagging, but very old models 4352 * Non-ancient models have better DMI tagging, but very old models
4317 * don't. 4353 * don't.
4318 */ 4354 */
4319 is_thinkpad = dmi_name_in_vendors("ThinkPad"); 4355 is_thinkpad = (thinkpad_id.model_str != NULL);
4320 4356
4321 /* ec is required because many other handles are relative to it */ 4357 /* ec is required because many other handles are relative to it */
4322 IBM_ACPIHANDLE_INIT(ec); 4358 IBM_ACPIHANDLE_INIT(ec);
@@ -4332,7 +4368,7 @@ static int __init probe_for_thinkpad(void)
4332 * false positives a damn great deal 4368 * false positives a damn great deal
4333 */ 4369 */
4334 if (!is_thinkpad) 4370 if (!is_thinkpad)
4335 is_thinkpad = dmi_name_in_vendors("IBM"); 4371 is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM);
4336 4372
4337 if (!is_thinkpad && !force_load) 4373 if (!is_thinkpad && !force_load)
4338 return -ENODEV; 4374 return -ENODEV;
@@ -4475,12 +4511,16 @@ static int __init thinkpad_acpi_module_init(void)
4475 int ret, i; 4511 int ret, i;
4476 4512
4477 /* Driver-level probe */ 4513 /* Driver-level probe */
4514
4515 get_thinkpad_model_data(&thinkpad_id);
4478 ret = probe_for_thinkpad(); 4516 ret = probe_for_thinkpad();
4479 if (ret) 4517 if (ret) {
4518 thinkpad_acpi_module_exit();
4480 return ret; 4519 return ret;
4520 }
4481 4521
4482 /* Driver initialization */ 4522 /* Driver initialization */
4483 ibm_thinkpad_ec_found = check_dmi_for_ec(); 4523
4484 IBM_ACPIHANDLE_INIT(ecrd); 4524 IBM_ACPIHANDLE_INIT(ecrd);
4485 IBM_ACPIHANDLE_INIT(ecwr); 4525 IBM_ACPIHANDLE_INIT(ecwr);
4486 4526
@@ -4590,7 +4630,9 @@ static void thinkpad_acpi_module_exit(void)
4590 if (proc_dir) 4630 if (proc_dir)
4591 remove_proc_entry(IBM_PROC_DIR, acpi_root_dir); 4631 remove_proc_entry(IBM_PROC_DIR, acpi_root_dir);
4592 4632
4593 kfree(ibm_thinkpad_ec_found); 4633 kfree(thinkpad_id.bios_version_str);
4634 kfree(thinkpad_id.ec_version_str);
4635 kfree(thinkpad_id.model_str);
4594} 4636}
4595 4637
4596module_init(thinkpad_acpi_module_init); 4638module_init(thinkpad_acpi_module_init);