Add patches accepted for 2.6.23-rc1
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / releases / upstream / 2.6.23-rc1 / 0018-ACPI-thinkpad-acpi-store-ThinkPad-model-informatio.patch
blob51cf1a501490ddcc5ee3a1c34777f9babb11e90a
1 From d5a2f2f1d68e2da538ac28540cddd9ccc733b001 Mon Sep 17 00:00:00 2001
2 From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
3 Date: Wed, 18 Jul 2007 23:45:42 -0300
4 Subject: ACPI: thinkpad-acpi: store ThinkPad model information
6 Keep note of ThinkPad model, BIOS and EC firmware information, and log it
7 on startup. Makes for far more readable code in places, too.
9 This patch also adds Lenovo's PCI ID to the pci ids table.
11 Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
12 Signed-off-by: Len Brown <len.brown@intel.com>
13 ---
14 drivers/misc/thinkpad_acpi.c | 98 ++++++++++++++++++++++++++++++------------
15 drivers/misc/thinkpad_acpi.h | 17 ++++++-
16 include/linux/pci_ids.h | 2 +
17 3 files changed, 87 insertions(+), 30 deletions(-)
19 diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
20 index 44aa8c9..99500af 100644
21 --- a/drivers/misc/thinkpad_acpi.c
22 +++ b/drivers/misc/thinkpad_acpi.c
23 @@ -717,9 +717,19 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
24 printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
25 printk(IBM_INFO "%s\n", IBM_URL);
27 - if (ibm_thinkpad_ec_found)
28 - printk(IBM_INFO "ThinkPad EC firmware %s\n",
29 - ibm_thinkpad_ec_found);
30 + printk(IBM_INFO "ThinkPad BIOS %s, EC %s\n",
31 + (thinkpad_id.bios_version_str) ?
32 + thinkpad_id.bios_version_str : "unknown",
33 + (thinkpad_id.ec_version_str) ?
34 + thinkpad_id.ec_version_str : "unknown");
36 + if (thinkpad_id.vendor && thinkpad_id.model_str)
37 + printk(IBM_INFO "%s %s\n",
38 + (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?
39 + "IBM" : ((thinkpad_id.vendor ==
40 + PCI_VENDOR_ID_LENOVO) ?
41 + "Lenovo" : "Unknown vendor"),
42 + thinkpad_id.model_str);
44 return 0;
46 @@ -2648,7 +2658,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
48 acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
50 - if (ibm_thinkpad_ec_found && experimental) {
51 + if (thinkpad_id.ec_model && experimental) {
53 * Direct EC access mode: sensors at registers
54 * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for
55 @@ -3532,20 +3542,19 @@ static int __init fan_init(struct ibm_init_struct *iibm)
56 * Enable for TP-1Y (T43), TP-78 (R51e),
57 * TP-76 (R52), TP-70 (T43, R52), which are known
58 * to be buggy. */
59 - if (fan_control_initial_status == 0x07 &&
60 - ibm_thinkpad_ec_found &&
61 - ((ibm_thinkpad_ec_found[0] == '1' &&
62 - ibm_thinkpad_ec_found[1] == 'Y') ||
63 - (ibm_thinkpad_ec_found[0] == '7' &&
64 - (ibm_thinkpad_ec_found[1] == '6' ||
65 - ibm_thinkpad_ec_found[1] == '8' ||
66 - ibm_thinkpad_ec_found[1] == '0'))
67 - )) {
68 - printk(IBM_NOTICE
69 - "fan_init: initial fan status is "
70 - "unknown, assuming it is in auto "
71 - "mode\n");
72 - tp_features.fan_ctrl_status_undef = 1;
73 + if (fan_control_initial_status == 0x07) {
74 + switch (thinkpad_id.ec_model) {
75 + case 0x5931: /* TP-1Y */
76 + case 0x3837: /* TP-78 */
77 + case 0x3637: /* TP-76 */
78 + case 0x3037: /* TP-70 */
79 + printk(IBM_NOTICE
80 + "fan_init: initial fan status is "
81 + "unknown, assuming it is in auto "
82 + "mode\n");
83 + tp_features.fan_ctrl_status_undef = 1;
84 + ;;
85 + }
87 } else {
88 printk(IBM_ERR
89 @@ -4279,13 +4288,30 @@ static void ibm_exit(struct ibm_struct *ibm)
91 /* Probing */
93 -static char *ibm_thinkpad_ec_found;
95 -static char* __init check_dmi_for_ec(void)
96 +static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp)
98 struct dmi_device *dev = NULL;
99 char ec_fw_string[18];
101 + if (!tp)
102 + return;
104 + memset(tp, 0, sizeof(*tp));
106 + if (dmi_name_in_vendors("IBM"))
107 + tp->vendor = PCI_VENDOR_ID_IBM;
108 + else if (dmi_name_in_vendors("LENOVO"))
109 + tp->vendor = PCI_VENDOR_ID_LENOVO;
110 + else
111 + return;
113 + tp->bios_version_str = kstrdup(dmi_get_system_info(DMI_BIOS_VERSION),
114 + GFP_KERNEL);
115 + if (!tp->bios_version_str)
116 + return;
117 + tp->bios_model = tp->bios_version_str[0]
118 + | (tp->bios_version_str[1] << 8);
121 * ThinkPad T23 or newer, A31 or newer, R50e or newer,
122 * X32 or newer, all Z series; Some models must have an
123 @@ -4299,10 +4325,20 @@ static char* __init check_dmi_for_ec(void)
124 ec_fw_string) == 1) {
125 ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
126 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
127 - return kstrdup(ec_fw_string, GFP_KERNEL);
129 + tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL);
130 + tp->ec_model = ec_fw_string[0]
131 + | (ec_fw_string[1] << 8);
132 + break;
135 - return NULL;
137 + tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION),
138 + GFP_KERNEL);
139 + if (strnicmp(tp->model_str, "ThinkPad", 8) != 0) {
140 + kfree(tp->model_str);
141 + tp->model_str = NULL;
145 static int __init probe_for_thinkpad(void)
146 @@ -4316,7 +4352,7 @@ static int __init probe_for_thinkpad(void)
147 * Non-ancient models have better DMI tagging, but very old models
148 * don't.
150 - is_thinkpad = dmi_name_in_vendors("ThinkPad");
151 + is_thinkpad = (thinkpad_id.model_str != NULL);
153 /* ec is required because many other handles are relative to it */
154 IBM_ACPIHANDLE_INIT(ec);
155 @@ -4332,7 +4368,7 @@ static int __init probe_for_thinkpad(void)
156 * false positives a damn great deal
158 if (!is_thinkpad)
159 - is_thinkpad = dmi_name_in_vendors("IBM");
160 + is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM);
162 if (!is_thinkpad && !force_load)
163 return -ENODEV;
164 @@ -4475,12 +4511,16 @@ static int __init thinkpad_acpi_module_init(void)
165 int ret, i;
167 /* Driver-level probe */
169 + get_thinkpad_model_data(&thinkpad_id);
170 ret = probe_for_thinkpad();
171 - if (ret)
172 + if (ret) {
173 + thinkpad_acpi_module_exit();
174 return ret;
177 /* Driver initialization */
178 - ibm_thinkpad_ec_found = check_dmi_for_ec();
180 IBM_ACPIHANDLE_INIT(ecrd);
181 IBM_ACPIHANDLE_INIT(ecwr);
183 @@ -4590,7 +4630,9 @@ static void thinkpad_acpi_module_exit(void)
184 if (proc_dir)
185 remove_proc_entry(IBM_PROC_DIR, acpi_root_dir);
187 - kfree(ibm_thinkpad_ec_found);
188 + kfree(thinkpad_id.bios_version_str);
189 + kfree(thinkpad_id.ec_version_str);
190 + kfree(thinkpad_id.model_str);
193 module_init(thinkpad_acpi_module_init);
194 diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
195 index fee0421..09b2282 100644
196 --- a/drivers/misc/thinkpad_acpi.h
197 +++ b/drivers/misc/thinkpad_acpi.h
198 @@ -175,9 +175,7 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv);
199 static int experimental;
200 static u32 dbg_level;
201 static int force_load;
202 -static char *ibm_thinkpad_ec_found;
204 -static char* check_dmi_for_ec(void);
205 static int thinkpad_acpi_module_init(void);
206 static void thinkpad_acpi_module_exit(void);
208 @@ -244,6 +242,21 @@ static struct {
209 u16 input_device_registered:1;
210 } tp_features;
212 +struct thinkpad_id_data {
213 + unsigned int vendor; /* ThinkPad vendor:
214 + * PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */
216 + char *bios_version_str; /* Something like 1ZET51WW (1.03z) */
217 + char *ec_version_str; /* Something like 1ZHT51WW-1.04a */
219 + u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */
220 + u16 ec_model;
222 + char *model_str;
225 +static struct thinkpad_id_data thinkpad_id;
227 static struct list_head tpacpi_all_drivers;
229 static struct ibm_init_struct ibms_init[];
230 diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
231 index b15c649..ced4d3f 100644
232 --- a/include/linux/pci_ids.h
233 +++ b/include/linux/pci_ids.h
234 @@ -2040,6 +2040,8 @@
235 #define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea
236 #define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb
238 +#define PCI_VENDOR_ID_LENOVO 0x17aa
240 #define PCI_VENDOR_ID_ARECA 0x17d3
241 #define PCI_DEVICE_ID_ARECA_1110 0x1110
242 #define PCI_DEVICE_ID_ARECA_1120 0x1120
244 1.5.2.1