aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/thinkpad_acpi.c
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2007-07-18 22:45:42 -0400
committerLen Brown <len.brown@intel.com>2007-07-21 23:48:42 -0400
commitd5a2f2f1d68e2da538ac28540cddd9ccc733b001 (patch)
tree659c3706c386af185581aefecc9fa2ea0f448df8 /drivers/misc/thinkpad_acpi.c
parent86cc9445e86bef9da44f933e3849e6eb43cbf626 (diff)
ACPI: thinkpad-acpi: store ThinkPad model information
Keep note of ThinkPad model, BIOS and EC firmware information, and log it on startup. Makes for far more readable code in places, too. This patch also adds Lenovo's PCI ID to the pci ids table. Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Signed-off-by: Len Brown <len.brown@intel.com>
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);