Commit d5a2f2f1 authored by Henrique de Moraes Holschuh's avatar Henrique de Moraes Holschuh Committed by Len Brown

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: default avatarHenrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 86cc9445
...@@ -717,9 +717,19 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm) ...@@ -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 v%s\n", IBM_DESC, IBM_VERSION);
printk(IBM_INFO "%s\n", IBM_URL); printk(IBM_INFO "%s\n", IBM_URL);
if (ibm_thinkpad_ec_found) printk(IBM_INFO "ThinkPad BIOS %s, EC %s\n",
printk(IBM_INFO "ThinkPad EC firmware %s\n", (thinkpad_id.bios_version_str) ?
ibm_thinkpad_ec_found); 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; return 0;
} }
...@@ -2648,7 +2658,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm) ...@@ -2648,7 +2658,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); 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 * Direct EC access mode: sensors at registers
* 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for
...@@ -3532,20 +3542,19 @@ static int __init fan_init(struct ibm_init_struct *iibm) ...@@ -3532,20 +3542,19 @@ static int __init fan_init(struct ibm_init_struct *iibm)
* Enable for TP-1Y (T43), TP-78 (R51e), * Enable for TP-1Y (T43), TP-78 (R51e),
* TP-76 (R52), TP-70 (T43, R52), which are known * TP-76 (R52), TP-70 (T43, R52), which are known
* to be buggy. */ * to be buggy. */
if (fan_control_initial_status == 0x07 && if (fan_control_initial_status == 0x07) {
ibm_thinkpad_ec_found && switch (thinkpad_id.ec_model) {
((ibm_thinkpad_ec_found[0] == '1' && case 0x5931: /* TP-1Y */
ibm_thinkpad_ec_found[1] == 'Y') || case 0x3837: /* TP-78 */
(ibm_thinkpad_ec_found[0] == '7' && case 0x3637: /* TP-76 */
(ibm_thinkpad_ec_found[1] == '6' || case 0x3037: /* TP-70 */
ibm_thinkpad_ec_found[1] == '8' || printk(IBM_NOTICE
ibm_thinkpad_ec_found[1] == '0')) "fan_init: initial fan status is "
)) { "unknown, assuming it is in auto "
printk(IBM_NOTICE "mode\n");
"fan_init: initial fan status is " tp_features.fan_ctrl_status_undef = 1;
"unknown, assuming it is in auto " ;;
"mode\n"); }
tp_features.fan_ctrl_status_undef = 1;
} }
} else { } else {
printk(IBM_ERR printk(IBM_ERR
...@@ -4279,13 +4288,30 @@ static void ibm_exit(struct ibm_struct *ibm) ...@@ -4279,13 +4288,30 @@ static void ibm_exit(struct ibm_struct *ibm)
/* Probing */ /* Probing */
static char *ibm_thinkpad_ec_found; static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp)
static char* __init check_dmi_for_ec(void)
{ {
struct dmi_device *dev = NULL; struct dmi_device *dev = NULL;
char ec_fw_string[18]; 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, * ThinkPad T23 or newer, A31 or newer, R50e or newer,
* X32 or newer, all Z series; Some models must have an * X32 or newer, all Z series; Some models must have an
...@@ -4299,10 +4325,20 @@ static char* __init check_dmi_for_ec(void) ...@@ -4299,10 +4325,20 @@ static char* __init check_dmi_for_ec(void)
ec_fw_string) == 1) { ec_fw_string) == 1) {
ec_fw_string[sizeof(ec_fw_string) - 1] = 0; ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
ec_fw_string[strcspn(ec_fw_string, " ]")] = 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) static int __init probe_for_thinkpad(void)
...@@ -4316,7 +4352,7 @@ 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 * Non-ancient models have better DMI tagging, but very old models
* don't. * 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 */ /* ec is required because many other handles are relative to it */
IBM_ACPIHANDLE_INIT(ec); IBM_ACPIHANDLE_INIT(ec);
...@@ -4332,7 +4368,7 @@ static int __init probe_for_thinkpad(void) ...@@ -4332,7 +4368,7 @@ static int __init probe_for_thinkpad(void)
* false positives a damn great deal * false positives a damn great deal
*/ */
if (!is_thinkpad) if (!is_thinkpad)
is_thinkpad = dmi_name_in_vendors("IBM"); is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM);
if (!is_thinkpad && !force_load) if (!is_thinkpad && !force_load)
return -ENODEV; return -ENODEV;
...@@ -4475,12 +4511,16 @@ static int __init thinkpad_acpi_module_init(void) ...@@ -4475,12 +4511,16 @@ static int __init thinkpad_acpi_module_init(void)
int ret, i; int ret, i;
/* Driver-level probe */ /* Driver-level probe */
get_thinkpad_model_data(&thinkpad_id);
ret = probe_for_thinkpad(); ret = probe_for_thinkpad();
if (ret) if (ret) {
thinkpad_acpi_module_exit();
return ret; return ret;
}
/* Driver initialization */ /* Driver initialization */
ibm_thinkpad_ec_found = check_dmi_for_ec();
IBM_ACPIHANDLE_INIT(ecrd); IBM_ACPIHANDLE_INIT(ecrd);
IBM_ACPIHANDLE_INIT(ecwr); IBM_ACPIHANDLE_INIT(ecwr);
...@@ -4590,7 +4630,9 @@ static void thinkpad_acpi_module_exit(void) ...@@ -4590,7 +4630,9 @@ static void thinkpad_acpi_module_exit(void)
if (proc_dir) if (proc_dir)
remove_proc_entry(IBM_PROC_DIR, acpi_root_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); module_init(thinkpad_acpi_module_init);
......
...@@ -175,9 +175,7 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv); ...@@ -175,9 +175,7 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv);
static int experimental; static int experimental;
static u32 dbg_level; static u32 dbg_level;
static int force_load; static int force_load;
static char *ibm_thinkpad_ec_found;
static char* check_dmi_for_ec(void);
static int thinkpad_acpi_module_init(void); static int thinkpad_acpi_module_init(void);
static void thinkpad_acpi_module_exit(void); static void thinkpad_acpi_module_exit(void);
...@@ -244,6 +242,21 @@ static struct { ...@@ -244,6 +242,21 @@ static struct {
u16 input_device_registered:1; u16 input_device_registered:1;
} tp_features; } tp_features;
struct thinkpad_id_data {
unsigned int vendor; /* ThinkPad vendor:
* PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */
char *bios_version_str; /* Something like 1ZET51WW (1.03z) */
char *ec_version_str; /* Something like 1ZHT51WW-1.04a */
u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */
u16 ec_model;
char *model_str;
};
static struct thinkpad_id_data thinkpad_id;
static struct list_head tpacpi_all_drivers; static struct list_head tpacpi_all_drivers;
static struct ibm_init_struct ibms_init[]; static struct ibm_init_struct ibms_init[];
......
...@@ -2040,6 +2040,8 @@ ...@@ -2040,6 +2040,8 @@
#define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea #define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea
#define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb #define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb
#define PCI_VENDOR_ID_LENOVO 0x17aa
#define PCI_VENDOR_ID_ARECA 0x17d3 #define PCI_VENDOR_ID_ARECA 0x17d3
#define PCI_DEVICE_ID_ARECA_1110 0x1110 #define PCI_DEVICE_ID_ARECA_1110 0x1110
#define PCI_DEVICE_ID_ARECA_1120 0x1120 #define PCI_DEVICE_ID_ARECA_1120 0x1120
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment