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;
 }
 
        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
                         * 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
 
 /* 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
                           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)
         * 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);
         * 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;
        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);
 
        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);