|
@@ -717,9 +717,19 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
|
|
|
printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
|
|
|
printk(IBM_INFO "%s\n", IBM_URL);
|
|
|
|
|
|
- if (ibm_thinkpad_ec_found)
|
|
|
- printk(IBM_INFO "ThinkPad EC firmware %s\n",
|
|
|
- ibm_thinkpad_ec_found);
|
|
|
+ printk(IBM_INFO "ThinkPad BIOS %s, EC %s\n",
|
|
|
+ (thinkpad_id.bios_version_str) ?
|
|
|
+ thinkpad_id.bios_version_str : "unknown",
|
|
|
+ (thinkpad_id.ec_version_str) ?
|
|
|
+ thinkpad_id.ec_version_str : "unknown");
|
|
|
+
|
|
|
+ if (thinkpad_id.vendor && thinkpad_id.model_str)
|
|
|
+ printk(IBM_INFO "%s %s\n",
|
|
|
+ (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?
|
|
|
+ "IBM" : ((thinkpad_id.vendor ==
|
|
|
+ PCI_VENDOR_ID_LENOVO) ?
|
|
|
+ "Lenovo" : "Unknown vendor"),
|
|
|
+ thinkpad_id.model_str);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -2648,7 +2658,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
|
|
|
|
|
|
acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
|
|
|
|
|
|
- if (ibm_thinkpad_ec_found && experimental) {
|
|
|
+ if (thinkpad_id.ec_model && experimental) {
|
|
|
/*
|
|
|
* Direct EC access mode: sensors at registers
|
|
|
* 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for
|
|
@@ -3532,20 +3542,19 @@ static int __init fan_init(struct ibm_init_struct *iibm)
|
|
|
* Enable for TP-1Y (T43), TP-78 (R51e),
|
|
|
* TP-76 (R52), TP-70 (T43, R52), which are known
|
|
|
* to be buggy. */
|
|
|
- if (fan_control_initial_status == 0x07 &&
|
|
|
- ibm_thinkpad_ec_found &&
|
|
|
- ((ibm_thinkpad_ec_found[0] == '1' &&
|
|
|
- ibm_thinkpad_ec_found[1] == 'Y') ||
|
|
|
- (ibm_thinkpad_ec_found[0] == '7' &&
|
|
|
- (ibm_thinkpad_ec_found[1] == '6' ||
|
|
|
- ibm_thinkpad_ec_found[1] == '8' ||
|
|
|
- ibm_thinkpad_ec_found[1] == '0'))
|
|
|
- )) {
|
|
|
- printk(IBM_NOTICE
|
|
|
- "fan_init: initial fan status is "
|
|
|
- "unknown, assuming it is in auto "
|
|
|
- "mode\n");
|
|
|
- tp_features.fan_ctrl_status_undef = 1;
|
|
|
+ if (fan_control_initial_status == 0x07) {
|
|
|
+ switch (thinkpad_id.ec_model) {
|
|
|
+ case 0x5931: /* TP-1Y */
|
|
|
+ case 0x3837: /* TP-78 */
|
|
|
+ case 0x3637: /* TP-76 */
|
|
|
+ case 0x3037: /* TP-70 */
|
|
|
+ printk(IBM_NOTICE
|
|
|
+ "fan_init: initial fan status is "
|
|
|
+ "unknown, assuming it is in auto "
|
|
|
+ "mode\n");
|
|
|
+ tp_features.fan_ctrl_status_undef = 1;
|
|
|
+ ;;
|
|
|
+ }
|
|
|
}
|
|
|
} else {
|
|
|
printk(IBM_ERR
|
|
@@ -4279,13 +4288,30 @@ static void ibm_exit(struct ibm_struct *ibm)
|
|
|
|
|
|
/* Probing */
|
|
|
|
|
|
-static char *ibm_thinkpad_ec_found;
|
|
|
-
|
|
|
-static char* __init check_dmi_for_ec(void)
|
|
|
+static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp)
|
|
|
{
|
|
|
struct dmi_device *dev = NULL;
|
|
|
char ec_fw_string[18];
|
|
|
|
|
|
+ if (!tp)
|
|
|
+ return;
|
|
|
+
|
|
|
+ memset(tp, 0, sizeof(*tp));
|
|
|
+
|
|
|
+ if (dmi_name_in_vendors("IBM"))
|
|
|
+ tp->vendor = PCI_VENDOR_ID_IBM;
|
|
|
+ else if (dmi_name_in_vendors("LENOVO"))
|
|
|
+ tp->vendor = PCI_VENDOR_ID_LENOVO;
|
|
|
+ else
|
|
|
+ return;
|
|
|
+
|
|
|
+ tp->bios_version_str = kstrdup(dmi_get_system_info(DMI_BIOS_VERSION),
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (!tp->bios_version_str)
|
|
|
+ return;
|
|
|
+ tp->bios_model = tp->bios_version_str[0]
|
|
|
+ | (tp->bios_version_str[1] << 8);
|
|
|
+
|
|
|
/*
|
|
|
* ThinkPad T23 or newer, A31 or newer, R50e or newer,
|
|
|
* X32 or newer, all Z series; Some models must have an
|
|
@@ -4299,10 +4325,20 @@ static char* __init check_dmi_for_ec(void)
|
|
|
ec_fw_string) == 1) {
|
|
|
ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
|
|
|
ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
|
|
|
- return kstrdup(ec_fw_string, GFP_KERNEL);
|
|
|
+
|
|
|
+ tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL);
|
|
|
+ tp->ec_model = ec_fw_string[0]
|
|
|
+ | (ec_fw_string[1] << 8);
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
- return NULL;
|
|
|
+
|
|
|
+ tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION),
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (strnicmp(tp->model_str, "ThinkPad", 8) != 0) {
|
|
|
+ kfree(tp->model_str);
|
|
|
+ tp->model_str = NULL;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static int __init probe_for_thinkpad(void)
|
|
@@ -4316,7 +4352,7 @@ static int __init probe_for_thinkpad(void)
|
|
|
* Non-ancient models have better DMI tagging, but very old models
|
|
|
* don't.
|
|
|
*/
|
|
|
- is_thinkpad = dmi_name_in_vendors("ThinkPad");
|
|
|
+ is_thinkpad = (thinkpad_id.model_str != NULL);
|
|
|
|
|
|
/* ec is required because many other handles are relative to it */
|
|
|
IBM_ACPIHANDLE_INIT(ec);
|
|
@@ -4332,7 +4368,7 @@ static int __init probe_for_thinkpad(void)
|
|
|
* false positives a damn great deal
|
|
|
*/
|
|
|
if (!is_thinkpad)
|
|
|
- is_thinkpad = dmi_name_in_vendors("IBM");
|
|
|
+ is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM);
|
|
|
|
|
|
if (!is_thinkpad && !force_load)
|
|
|
return -ENODEV;
|
|
@@ -4475,12 +4511,16 @@ static int __init thinkpad_acpi_module_init(void)
|
|
|
int ret, i;
|
|
|
|
|
|
/* Driver-level probe */
|
|
|
+
|
|
|
+ get_thinkpad_model_data(&thinkpad_id);
|
|
|
ret = probe_for_thinkpad();
|
|
|
- if (ret)
|
|
|
+ if (ret) {
|
|
|
+ thinkpad_acpi_module_exit();
|
|
|
return ret;
|
|
|
+ }
|
|
|
|
|
|
/* Driver initialization */
|
|
|
- ibm_thinkpad_ec_found = check_dmi_for_ec();
|
|
|
+
|
|
|
IBM_ACPIHANDLE_INIT(ecrd);
|
|
|
IBM_ACPIHANDLE_INIT(ecwr);
|
|
|
|
|
@@ -4590,7 +4630,9 @@ static void thinkpad_acpi_module_exit(void)
|
|
|
if (proc_dir)
|
|
|
remove_proc_entry(IBM_PROC_DIR, acpi_root_dir);
|
|
|
|
|
|
- kfree(ibm_thinkpad_ec_found);
|
|
|
+ kfree(thinkpad_id.bios_version_str);
|
|
|
+ kfree(thinkpad_id.ec_version_str);
|
|
|
+ kfree(thinkpad_id.model_str);
|
|
|
}
|
|
|
|
|
|
module_init(thinkpad_acpi_module_init);
|