Blame view

drivers/acpi/processor_driver.c 22.8 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  /*
   * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $)
   *
   *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
   *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
   *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
   *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
   *  			- Added processor hotplug support
   *
   * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   *
   *  This program is free software; you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation; either version 2 of the License, or (at
   *  your option) any later version.
   *
   *  This program is distributed in the hope that it will be useful, but
   *  WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   *  General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License along
   *  with this program; if not, write to the Free Software Foundation, Inc.,
   *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
   *
   * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   *  TBD:
   *	1. Make # power states dynamic.
   *	2. Support duty_cycle values that span bit 4.
   *	3. Optimize by having scheduler determine business instead of
   *	   having us try to calculate it here.
   *	4. Need C1 timing -- must modify kernel (IRQ handler) to get this.
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/types.h>
  #include <linux/pci.h>
  #include <linux/pm.h>
  #include <linux/cpufreq.h>
  #include <linux/cpu.h>
  #include <linux/proc_fs.h>
  #include <linux/seq_file.h>
  #include <linux/dmi.h>
  #include <linux/moduleparam.h>
4f86d3a8e   Len Brown   cpuidle: consolid...
47
  #include <linux/cpuidle.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
48
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
51
52
53
54
55
56
57
58
59
60
61
  
  #include <asm/io.h>
  #include <asm/system.h>
  #include <asm/cpu.h>
  #include <asm/delay.h>
  #include <asm/uaccess.h>
  #include <asm/processor.h>
  #include <asm/smp.h>
  #include <asm/acpi.h>
  
  #include <acpi/acpi_bus.h>
  #include <acpi/acpi_drivers.h>
  #include <acpi/processor.h>
a192a9580   Len Brown   ACPI: Move defini...
62
  #define PREFIX "ACPI: "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
  #define ACPI_PROCESSOR_CLASS		"processor"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
65
66
67
68
69
  #define ACPI_PROCESSOR_DEVICE_NAME	"Processor"
  #define ACPI_PROCESSOR_FILE_INFO	"info"
  #define ACPI_PROCESSOR_FILE_THROTTLING	"throttling"
  #define ACPI_PROCESSOR_FILE_LIMIT	"limit"
  #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
  #define ACPI_PROCESSOR_NOTIFY_POWER	0x81
01854e697   Luming Yu   ACPI: add ACPI 3....
70
  #define ACPI_PROCESSOR_NOTIFY_THROTTLING	0x82
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
72
73
  
  #define ACPI_PROCESSOR_LIMIT_USER	0
  #define ACPI_PROCESSOR_LIMIT_THERMAL	1
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
  #define _COMPONENT		ACPI_PROCESSOR_COMPONENT
0131aa3dd   Alex Chiang   ACPI: processor: ...
75
  ACPI_MODULE_NAME("processor_driver");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76

f52fd66d2   Len Brown   ACPI: clean up AC...
77
  MODULE_AUTHOR("Paul Diefenbaugh");
7cda93e00   Len Brown   ACPI: delete extr...
78
  MODULE_DESCRIPTION("ACPI Processor Driver");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
  MODULE_LICENSE("GPL");
4be44fcd3   Len Brown   [ACPI] Lindent al...
80
  static int acpi_processor_add(struct acpi_device *device);
4be44fcd3   Len Brown   [ACPI] Lindent al...
81
  static int acpi_processor_remove(struct acpi_device *device, int type);
7ec0a7290   Bjorn Helgaas   ACPI: processor: ...
82
  static void acpi_processor_notify(struct acpi_device *device, u32 event);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
84
  static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
  static int acpi_processor_handle_eject(struct acpi_processor *pr);
01854e697   Luming Yu   ACPI: add ACPI 3....
85

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86

1ba90e3a8   Thomas Renninger   ACPI: autoload mo...
87
  static const struct acpi_device_id processor_device_ids[] = {
ad93a765c   Myron Stowe   ACPI: Disambiguat...
88
  	{ACPI_PROCESSOR_OBJECT_HID, 0},
9eccbc2f6   Bjorn Helgaas   ACPI: processor: ...
89
  	{"ACPI0007", 0},
1ba90e3a8   Thomas Renninger   ACPI: autoload mo...
90
91
92
  	{"", 0},
  };
  MODULE_DEVICE_TABLE(acpi, processor_device_ids);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
  static struct acpi_driver acpi_processor_driver = {
c2b6705b7   Len Brown   ACPI: fix acpi_dr...
94
  	.name = "processor",
4be44fcd3   Len Brown   [ACPI] Lindent al...
95
  	.class = ACPI_PROCESSOR_CLASS,
1ba90e3a8   Thomas Renninger   ACPI: autoload mo...
96
  	.ids = processor_device_ids,
4be44fcd3   Len Brown   [ACPI] Lindent al...
97
98
99
  	.ops = {
  		.add = acpi_processor_add,
  		.remove = acpi_processor_remove,
b04e7bdb9   Thomas Gleixner   ACPI: disable low...
100
101
  		.suspend = acpi_processor_suspend,
  		.resume = acpi_processor_resume,
7ec0a7290   Bjorn Helgaas   ACPI: processor: ...
102
  		.notify = acpi_processor_notify,
4be44fcd3   Len Brown   [ACPI] Lindent al...
103
  		},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
105
106
107
  };
  
  #define INSTALL_NOTIFY_HANDLER		1
  #define UNINSTALL_NOTIFY_HANDLER	2
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108

706546d02   Mike Travis   ACPI: change proc...
109
  DEFINE_PER_CPU(struct acpi_processor *, processors);
0f1d683fb   Naga Chumbalkar   [CPUFREQ] Process...
110
  EXPORT_PER_CPU_SYMBOL(processors);
9f2227189   Andreas Mohr   [PATCH] make ACPI...
111
  struct acpi_processor_errata errata __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
115
  /* --------------------------------------------------------------------------
                                  Errata Handling
     -------------------------------------------------------------------------- */
4be44fcd3   Len Brown   [ACPI] Lindent al...
116
  static int acpi_processor_errata_piix4(struct pci_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
118
119
  	u8 value1 = 0;
  	u8 value2 = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
122
  
  	if (!dev)
d550d98d3   Patrick Mochel   ACPI: delete trac...
123
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
125
126
127
  
  	/*
  	 * Note that 'dev' references the PIIX4 ACPI Controller.
  	 */
44c10138f   Auke Kok   PCI: Change all d...
128
  	switch (dev->revision) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
  	case 0:
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step
  "));
  		break;
  	case 1:
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step
  "));
  		break;
  	case 2:
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E
  "));
  		break;
  	case 3:
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M
  "));
  		break;
  	default:
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4
  "));
  		break;
  	}
44c10138f   Auke Kok   PCI: Change all d...
150
  	switch (dev->revision) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
  
  	case 0:		/* PIIX4 A-step */
  	case 1:		/* PIIX4 B-step */
  		/*
  		 * See specification changes #13 ("Manual Throttle Duty Cycle")
  		 * and #14 ("Enabling and Disabling Manual Throttle"), plus
  		 * erratum #5 ("STPCLK# Deassertion Time") from the January
  		 * 2002 PIIX4 specification update.  Applies to only older
  		 * PIIX4 models.
  		 */
  		errata.piix4.throttle = 1;
  
  	case 2:		/* PIIX4E */
  	case 3:		/* PIIX4M */
  		/*
  		 * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA
  		 * Livelock") from the January 2002 PIIX4 specification update.
  		 * Applies to all PIIX4 models.
  		 */
  
  		/*
  		 * BM-IDE
  		 * ------
  		 * Find the PIIX4 IDE Controller and get the Bus Master IDE
  		 * Status register address.  We'll use this later to read
  		 * each IDE controller's DMA status to make sure we catch all
  		 * DMA activity.
  		 */
  		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
4be44fcd3   Len Brown   [ACPI] Lindent al...
180
181
  				     PCI_DEVICE_ID_INTEL_82371AB,
  				     PCI_ANY_ID, PCI_ANY_ID, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
  		if (dev) {
  			errata.piix4.bmisx = pci_resource_start(dev, 4);
  			pci_dev_put(dev);
  		}
  
  		/*
  		 * Type-F DMA
  		 * ----------
  		 * Find the PIIX4 ISA Controller and read the Motherboard
  		 * DMA controller's status to see if Type-F (Fast) DMA mode
  		 * is enabled (bit 7) on either channel.  Note that we'll
  		 * disable C3 support if this is enabled, as some legacy
  		 * devices won't operate well if fast DMA is disabled.
  		 */
  		dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
4be44fcd3   Len Brown   [ACPI] Lindent al...
197
198
  				     PCI_DEVICE_ID_INTEL_82371AB_0,
  				     PCI_ANY_ID, PCI_ANY_ID, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
200
201
202
203
204
205
206
207
208
209
210
211
  		if (dev) {
  			pci_read_config_byte(dev, 0x76, &value1);
  			pci_read_config_byte(dev, 0x77, &value2);
  			if ((value1 & 0x80) || (value2 & 0x80))
  				errata.piix4.fdma = 1;
  			pci_dev_put(dev);
  		}
  
  		break;
  	}
  
  	if (errata.piix4.bmisx)
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
4be44fcd3   Len Brown   [ACPI] Lindent al...
212
213
  				  "Bus master activity detection (BM-IDE) erratum enabled
  "));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
215
  	if (errata.piix4.fdma)
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
4be44fcd3   Len Brown   [ACPI] Lindent al...
216
217
  				  "Type-F DMA livelock erratum (C3 disabled)
  "));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218

d550d98d3   Patrick Mochel   ACPI: delete trac...
219
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220
  }
8713cbefa   Adrian Bunk   [ACPI] add static...
221
  static int acpi_processor_errata(struct acpi_processor *pr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
223
224
  	int result = 0;
  	struct pci_dev *dev = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226
227
  
  	if (!pr)
d550d98d3   Patrick Mochel   ACPI: delete trac...
228
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
230
231
232
233
  
  	/*
  	 * PIIX4
  	 */
  	dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
4be44fcd3   Len Brown   [ACPI] Lindent al...
234
235
  			     PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID,
  			     PCI_ANY_ID, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
237
238
239
  	if (dev) {
  		result = acpi_processor_errata_piix4(dev);
  		pci_dev_put(dev);
  	}
d550d98d3   Patrick Mochel   ACPI: delete trac...
240
  	return result;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
242
  static struct proc_dir_entry *acpi_processor_dir = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243

bf8b4542f   Thomas Renninger   ACPI processor: F...
244
  static int __cpuinit acpi_processor_add_fs(struct acpi_device *device)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
246
  	struct proc_dir_entry *entry = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
248
249
250
  
  	if (!acpi_device_dir(device)) {
  		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
4be44fcd3   Len Brown   [ACPI] Lindent al...
251
  						     acpi_processor_dir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252
  		if (!acpi_device_dir(device))
d550d98d3   Patrick Mochel   ACPI: delete trac...
253
  			return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
  	/* 'throttling' [R/W] */
cf7acfab0   Denis V. Lunev   acpi: use non-rac...
257
258
259
260
261
  	entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING,
  				 S_IFREG | S_IRUGO | S_IWUSR,
  				 acpi_device_dir(device),
  				 &acpi_processor_throttling_fops,
  				 acpi_driver_data(device));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
  	if (!entry)
d550d98d3   Patrick Mochel   ACPI: delete trac...
263
  		return -EIO;
d550d98d3   Patrick Mochel   ACPI: delete trac...
264
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
266
  static int acpi_processor_remove_fs(struct acpi_device *device)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
267
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
268
269
  
  	if (acpi_device_dir(device)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
  		remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
4be44fcd3   Len Brown   [ACPI] Lindent al...
271
  				  acpi_device_dir(device));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
273
274
  		remove_proc_entry(acpi_device_bid(device), acpi_processor_dir);
  		acpi_device_dir(device) = NULL;
  	}
d550d98d3   Patrick Mochel   ACPI: delete trac...
275
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
276
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
277
278
279
  /* --------------------------------------------------------------------------
                                   Driver Interface
     -------------------------------------------------------------------------- */
b26e9286f   Myron Stowe   ACPI: Behave uniq...
280
  static int acpi_processor_get_info(struct acpi_device *device)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
281
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
282
283
284
  	acpi_status status = 0;
  	union acpi_object object = { 0 };
  	struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
b26e9286f   Myron Stowe   ACPI: Behave uniq...
285
286
  	struct acpi_processor *pr;
  	int cpu_index, device_declaration = 0;
4be44fcd3   Len Brown   [ACPI] Lindent al...
287
  	static int cpu0_initialized;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288

b26e9286f   Myron Stowe   ACPI: Behave uniq...
289
  	pr = acpi_driver_data(device);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290
  	if (!pr)
d550d98d3   Patrick Mochel   ACPI: delete trac...
291
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
293
294
295
296
297
298
299
300
301
  
  	if (num_online_cpus() > 1)
  		errata.smp = TRUE;
  
  	acpi_processor_errata(pr);
  
  	/*
  	 * Check to see if we have bus mastering arbitration control.  This
  	 * is required for proper C3 usage (to maintain cache coherency).
  	 */
cee324b14   Alexey Starikovskiy   ACPICA: use new A...
302
  	if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
304
  		pr->flags.bm_control = 1;
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
4be44fcd3   Len Brown   [ACPI] Lindent al...
305
306
307
  				  "Bus mastering arbitration control present
  "));
  	} else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
308
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
4be44fcd3   Len Brown   [ACPI] Lindent al...
309
310
  				  "No bus mastering arbitration control
  "));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
311

6cc73b480   Bjorn Helgaas   ACPI: processor: ...
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
  	if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) {
  		/* Declared with "Processor" statement; match ProcessorID */
  		status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
  		if (ACPI_FAILURE(status)) {
  			printk(KERN_ERR PREFIX "Evaluating processor object
  ");
  			return -ENODEV;
  		}
  
  		/*
  		 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
  		 *      >>> 'acpi_get_processor_id(acpi_id, &id)' in
  		 *      arch/xxx/acpi.c
  		 */
  		pr->acpi_id = object.processor.proc_id;
  	} else {
b26e9286f   Myron Stowe   ACPI: Behave uniq...
328
329
330
331
  		/*
  		 * Declared with "Device" statement; match _UID.
  		 * Note that we don't handle string _UIDs yet.
  		 */
27663c585   Matthew Wilcox   ACPI: Change acpi...
332
  		unsigned long long value;
11bf04c44   Alexey Starikovskiy   ACPICA: Allow pro...
333
334
335
  		status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
  						NULL, &value);
  		if (ACPI_FAILURE(status)) {
b26e9286f   Myron Stowe   ACPI: Behave uniq...
336
337
338
  			printk(KERN_ERR PREFIX
  			    "Evaluating processor _UID [%#x]
  ", status);
11bf04c44   Alexey Starikovskiy   ACPICA: Allow pro...
339
340
  			return -ENODEV;
  		}
b26e9286f   Myron Stowe   ACPI: Behave uniq...
341
  		device_declaration = 1;
11bf04c44   Alexey Starikovskiy   ACPICA: Allow pro...
342
  		pr->acpi_id = value;
11bf04c44   Alexey Starikovskiy   ACPICA: Allow pro...
343
  	}
2e9d5e4ef   Alex Chiang   ACPI: processor: ...
344
  	cpu_index = acpi_get_cpuid(pr->handle, device_declaration, pr->acpi_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345

4be44fcd3   Len Brown   [ACPI] Lindent al...
346
  	/* Handle UP system running SMP kernel, with no LAPIC in MADT */
df42baa0d   Ashok Raj   ACPI: build fix f...
347
  	if (!cpu0_initialized && (cpu_index == -1) &&
4be44fcd3   Len Brown   [ACPI] Lindent al...
348
349
350
351
352
353
354
355
356
357
358
359
360
  	    (num_online_cpus() == 1)) {
  		cpu_index = 0;
  	}
  
  	cpu0_initialized = 1;
  
  	pr->id = cpu_index;
  
  	/*
  	 *  Extra Processor objects may be enumerated on MP systems with
  	 *  less than the max # of CPUs. They should be ignored _iff
  	 *  they are physically not present.
  	 */
f18c5a08b   Alexey Starikovskiy   ACPICA: Allow ACP...
361
  	if (pr->id == -1) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
362
363
  		if (ACPI_FAILURE
  		    (acpi_processor_hotadd_init(pr->handle, &pr->id))) {
d550d98d3   Patrick Mochel   ACPI: delete trac...
364
  			return -ENODEV;
4be44fcd3   Len Brown   [ACPI] Lindent al...
365
366
  		}
  	}
7a04b8491   Zhao Yakui   ACPI: Rename ACPI...
367
368
369
370
371
372
373
374
375
376
  	/*
  	 * On some boxes several processors use the same processor bus id.
  	 * But they are located in different scope. For example:
  	 * \_SB.SCK0.CPU0
  	 * \_SB.SCK1.CPU0
  	 * Rename the processor device bus id. And the new bus id will be
  	 * generated as the following format:
  	 * CPU+CPU ID.
  	 */
  	sprintf(acpi_device_bid(device), "CPU%X", pr->id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
378
  	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]
  ", pr->id,
4be44fcd3   Len Brown   [ACPI] Lindent al...
379
  			  pr->acpi_id));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
380
381
382
383
384
  
  	if (!object.processor.pblk_address)
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)
  "));
  	else if (object.processor.pblk_length != 6)
6468463ab   Len Brown   ACPI: un-export A...
385
386
387
  		printk(KERN_ERR PREFIX "Invalid PBLK length [%d]
  ",
  			    object.processor.pblk_length);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
388
389
  	else {
  		pr->throttling.address = object.processor.pblk_address;
cee324b14   Alexey Starikovskiy   ACPICA: use new A...
390
391
  		pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset;
  		pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
392
393
394
395
396
397
398
399
400
401
402
403
  
  		pr->pblk = object.processor.pblk_address;
  
  		/*
  		 * We don't care about error returns - we just try to mark
  		 * these reserved so that nobody else is confused into thinking
  		 * that this region might be unused..
  		 *
  		 * (In particular, allocating the IO range for Cardbus)
  		 */
  		request_region(pr->throttling.address, 6, "ACPI CPU throttle");
  	}
fe086a7be   Alex Chiang   [IA64] Provide AC...
404
405
406
407
408
409
410
411
  	/*
  	 * If ACPI describes a slot number for this CPU, we can use it
  	 * ensure we get the right value in the "physical id" field
  	 * of /proc/cpuinfo
  	 */
  	status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer);
  	if (ACPI_SUCCESS(status))
  		arch_fix_phys_package_id(pr->id, object.integer.value);
d550d98d3   Patrick Mochel   ACPI: delete trac...
412
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
413
  }
706546d02   Mike Travis   ACPI: change proc...
414
  static DEFINE_PER_CPU(void *, processor_device_array);
cd8e2b48d   Venkatesh Pallipadi   [ACPI] fix 2.6.13...
415

7ec0a7290   Bjorn Helgaas   ACPI: processor: ...
416
  static void acpi_processor_notify(struct acpi_device *device, u32 event)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
417
  {
7ec0a7290   Bjorn Helgaas   ACPI: processor: ...
418
  	struct acpi_processor *pr = acpi_driver_data(device);
e790cc8bb   Alexey Starikovskiy   ACPI: EC: Workaro...
419
  	int saved;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420
421
  
  	if (!pr)
d550d98d3   Patrick Mochel   ACPI: delete trac...
422
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
424
425
  	switch (event) {
  	case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
e790cc8bb   Alexey Starikovskiy   ACPI: EC: Workaro...
426
  		saved = pr->performance_platform_limit;
d81c45e1c   Zhao Yakui   ACPI: Notify the ...
427
  		acpi_processor_ppc_has_changed(pr, 1);
e790cc8bb   Alexey Starikovskiy   ACPI: EC: Workaro...
428
429
  		if (saved == pr->performance_platform_limit)
  			break;
14e04fb34   Len Brown   ACPI: Schedule /p...
430
  		acpi_bus_generate_proc_event(device, event,
4be44fcd3   Len Brown   [ACPI] Lindent al...
431
  					pr->performance_platform_limit);
962ce8ca0   Zhang Rui   ACPI: don't dupli...
432
  		acpi_bus_generate_netlink_event(device->pnp.device_class,
0794469da   Kay Sievers   ACPI: struct devi...
433
  						  dev_name(&device->dev), event,
962ce8ca0   Zhang Rui   ACPI: don't dupli...
434
  						  pr->performance_platform_limit);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
435
436
437
  		break;
  	case ACPI_PROCESSOR_NOTIFY_POWER:
  		acpi_processor_cst_has_changed(pr);
14e04fb34   Len Brown   ACPI: Schedule /p...
438
  		acpi_bus_generate_proc_event(device, event, 0);
962ce8ca0   Zhang Rui   ACPI: don't dupli...
439
  		acpi_bus_generate_netlink_event(device->pnp.device_class,
0794469da   Kay Sievers   ACPI: struct devi...
440
  						  dev_name(&device->dev), event, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
441
  		break;
01854e697   Luming Yu   ACPI: add ACPI 3....
442
443
  	case ACPI_PROCESSOR_NOTIFY_THROTTLING:
  		acpi_processor_tstate_has_changed(pr);
14e04fb34   Len Brown   ACPI: Schedule /p...
444
  		acpi_bus_generate_proc_event(device, event, 0);
962ce8ca0   Zhang Rui   ACPI: don't dupli...
445
  		acpi_bus_generate_netlink_event(device->pnp.device_class,
0794469da   Kay Sievers   ACPI: struct devi...
446
  						  dev_name(&device->dev), event, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
448
  	default:
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
4be44fcd3   Len Brown   [ACPI] Lindent al...
449
450
  				  "Unsupported event [0x%x]
  ", event));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
451
452
  		break;
  	}
d550d98d3   Patrick Mochel   ACPI: delete trac...
453
  	return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
454
  }
729c6ba33   Venkatesh Pallipadi   ACPI: Reevaluate ...
455
456
457
458
  static int acpi_cpu_soft_notify(struct notifier_block *nfb,
  		unsigned long action, void *hcpu)
  {
  	unsigned int cpu = (unsigned long)hcpu;
706546d02   Mike Travis   ACPI: change proc...
459
  	struct acpi_processor *pr = per_cpu(processors, cpu);
729c6ba33   Venkatesh Pallipadi   ACPI: Reevaluate ...
460
461
  
  	if (action == CPU_ONLINE && pr) {
d81c45e1c   Zhao Yakui   ACPI: Notify the ...
462
  		acpi_processor_ppc_has_changed(pr, 0);
729c6ba33   Venkatesh Pallipadi   ACPI: Reevaluate ...
463
464
465
466
467
468
469
470
471
472
  		acpi_processor_cst_has_changed(pr);
  		acpi_processor_tstate_has_changed(pr);
  	}
  	return NOTIFY_OK;
  }
  
  static struct notifier_block acpi_cpu_notifier =
  {
  	    .notifier_call = acpi_cpu_soft_notify,
  };
941b10fab   Rakib Mullick   ACPI: add __cpuin...
473
  static int __cpuinit acpi_processor_add(struct acpi_device *device)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
474
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
475
  	struct acpi_processor *pr = NULL;
970b04929   Bjorn Helgaas   ACPI: processor: ...
476
477
  	int result = 0;
  	struct sys_device *sysdev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
478

36bcbec7c   Burman Yan   ACPI: replace kma...
479
  	pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
480
  	if (!pr)
d550d98d3   Patrick Mochel   ACPI: delete trac...
481
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
482

eaa958402   Yinghai Lu   cpumask: alloc ze...
483
  	if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
2fdf66b49   Rusty Russell   cpumask: convert ...
484
485
486
  		kfree(pr);
  		return -ENOMEM;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
487
488
489
  	pr->handle = device->handle;
  	strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
  	strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
db89b4f0d   Pavel Machek   ACPI: catch calls...
490
  	device->driver_data = pr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491

b26e9286f   Myron Stowe   ACPI: Behave uniq...
492
  	result = acpi_processor_get_info(device);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
493
494
  	if (result) {
  		/* Processor is physically not present */
d550d98d3   Patrick Mochel   ACPI: delete trac...
495
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
496
  	}
75cbfb97a   Thomas Renninger   ACPI: Do not try ...
497
498
499
500
  #ifdef CONFIG_SMP
  	if (pr->id >= setup_max_cpus && pr->id != 0)
  		return 0;
  #endif
fbb43ab03   Christoph Lameter   ACPI: avoid refer...
501
  	BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502

cd8e2b48d   Venkatesh Pallipadi   [ACPI] fix 2.6.13...
503
504
505
506
507
  	/*
  	 * Buggy BIOS check
  	 * ACPI id of processors can be reported wrongly by the BIOS.
  	 * Don't trust it blindly
  	 */
706546d02   Mike Travis   ACPI: change proc...
508
509
  	if (per_cpu(processor_device_array, pr->id) != NULL &&
  	    per_cpu(processor_device_array, pr->id) != device) {
4fdb2a05e   Joe Perches   ACPI: Add missing...
510
  		printk(KERN_WARNING "BIOS reported wrong ACPI id "
0eacee585   Len Brown   ACPI: enable BIOS...
511
512
  			"for the processor
  ");
970b04929   Bjorn Helgaas   ACPI: processor: ...
513
514
  		result = -ENODEV;
  		goto err_free_cpumask;
cd8e2b48d   Venkatesh Pallipadi   [ACPI] fix 2.6.13...
515
  	}
706546d02   Mike Travis   ACPI: change proc...
516
  	per_cpu(processor_device_array, pr->id) = device;
cd8e2b48d   Venkatesh Pallipadi   [ACPI] fix 2.6.13...
517

706546d02   Mike Travis   ACPI: change proc...
518
  	per_cpu(processors, pr->id) = pr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
519
520
521
  
  	result = acpi_processor_add_fs(device);
  	if (result)
970b04929   Bjorn Helgaas   ACPI: processor: ...
522
  		goto err_free_cpumask;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
523

9f1eb99c7   Zhang Rui   create sysfs link...
524
  	sysdev = get_cpu_sysdev(pr->id);
d4e052618   Bjorn Helgaas   ACPI: processor: ...
525
526
527
528
  	if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) {
  		result = -EFAULT;
  		goto err_remove_fs;
  	}
9f1eb99c7   Zhang Rui   create sysfs link...
529

0ac3c5713   Zhao Yakui   ACPI: Get throttl...
530
  #ifdef CONFIG_CPU_FREQ
d81c45e1c   Zhao Yakui   ACPI: Notify the ...
531
  	acpi_processor_ppc_has_changed(pr, 0);
0ac3c5713   Zhao Yakui   ACPI: Get throttl...
532
533
534
  #endif
  	acpi_processor_get_throttling_info(pr);
  	acpi_processor_get_limit_info(pr);
05131ecc9   Venkatesh Pallipadi   [ACPI] Avoid BIOS...
535

541adf7cd   Len Brown   ACPI: allow a nat...
536
537
  	if (cpuidle_get_driver() == &acpi_idle_driver)
  		acpi_processor_power_init(pr, device);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
538

d9460fd22   Zhang Rui   ACPI: register AC...
539
540
  	pr->cdev = thermal_cooling_device_register("Processor", device,
  						&processor_cooling_ops);
d76628c67   Thomas Sujith   ACPI thermal: ext...
541
542
  	if (IS_ERR(pr->cdev)) {
  		result = PTR_ERR(pr->cdev);
d4e052618   Bjorn Helgaas   ACPI: processor: ...
543
  		goto err_power_exit;
d76628c67   Thomas Sujith   ACPI thermal: ext...
544
  	}
9030062f3   Julia Lawall   ACPI: elide a non...
545

13c411570   Mike Travis   ACPI: Remove repe...
546
547
  	dev_dbg(&device->dev, "registered as cooling_device%d
  ",
fc3a8828b   Greg Kroah-Hartman   driver core: fix ...
548
  		 pr->cdev->id);
9030062f3   Julia Lawall   ACPI: elide a non...
549
550
551
552
  
  	result = sysfs_create_link(&device->dev.kobj,
  				   &pr->cdev->device.kobj,
  				   "thermal_cooling");
d4e052618   Bjorn Helgaas   ACPI: processor: ...
553
  	if (result) {
9030062f3   Julia Lawall   ACPI: elide a non...
554
555
  		printk(KERN_ERR PREFIX "Create sysfs link
  ");
d4e052618   Bjorn Helgaas   ACPI: processor: ...
556
557
  		goto err_thermal_unregister;
  	}
9030062f3   Julia Lawall   ACPI: elide a non...
558
559
560
  	result = sysfs_create_link(&pr->cdev->device.kobj,
  				   &device->dev.kobj,
  				   "device");
d4e052618   Bjorn Helgaas   ACPI: processor: ...
561
  	if (result) {
9030062f3   Julia Lawall   ACPI: elide a non...
562
563
  		printk(KERN_ERR PREFIX "Create sysfs link
  ");
d4e052618   Bjorn Helgaas   ACPI: processor: ...
564
565
  		goto err_remove_sysfs;
  	}
d9460fd22   Zhang Rui   ACPI: register AC...
566

d550d98d3   Patrick Mochel   ACPI: delete trac...
567
  	return 0;
d4e052618   Bjorn Helgaas   ACPI: processor: ...
568
569
570
571
572
573
574
575
576
  
  err_remove_sysfs:
  	sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
  err_thermal_unregister:
  	thermal_cooling_device_unregister(pr->cdev);
  err_power_exit:
  	acpi_processor_power_exit(pr, device);
  err_remove_fs:
  	acpi_processor_remove_fs(device);
970b04929   Bjorn Helgaas   ACPI: processor: ...
577
578
  err_free_cpumask:
  	free_cpumask_var(pr->throttling.shared_cpu_map);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
579

d550d98d3   Patrick Mochel   ACPI: delete trac...
580
  	return result;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
582
  static int acpi_processor_remove(struct acpi_device *device, int type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
583
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
584
  	struct acpi_processor *pr = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
585

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
586
587
  
  	if (!device || !acpi_driver_data(device))
d550d98d3   Patrick Mochel   ACPI: delete trac...
588
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
589

50dd09697   Jan Engelhardt   ACPI: Remove unne...
590
  	pr = acpi_driver_data(device);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
591

2fdf66b49   Rusty Russell   cpumask: convert ...
592
593
  	if (pr->id >= nr_cpu_ids)
  		goto free;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
594
595
596
  
  	if (type == ACPI_BUS_REMOVAL_EJECT) {
  		if (acpi_processor_handle_eject(pr))
d550d98d3   Patrick Mochel   ACPI: delete trac...
597
  			return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
598
599
600
  	}
  
  	acpi_processor_power_exit(pr, device);
9f1eb99c7   Zhang Rui   create sysfs link...
601
  	sysfs_remove_link(&device->dev.kobj, "sysdev");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
602
  	acpi_processor_remove_fs(device);
f28bb45e2   Zhao Yakui   ACPI: thermal: Ch...
603
604
605
606
607
608
  	if (pr->cdev) {
  		sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
  		sysfs_remove_link(&pr->cdev->device.kobj, "device");
  		thermal_cooling_device_unregister(pr->cdev);
  		pr->cdev = NULL;
  	}
d9460fd22   Zhang Rui   ACPI: register AC...
609

706546d02   Mike Travis   ACPI: change proc...
610
611
  	per_cpu(processors, pr->id) = NULL;
  	per_cpu(processor_device_array, pr->id) = NULL;
2fdf66b49   Rusty Russell   cpumask: convert ...
612
613
614
  
  free:
  	free_cpumask_var(pr->throttling.shared_cpu_map);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
615
  	kfree(pr);
d550d98d3   Patrick Mochel   ACPI: delete trac...
616
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
617
618
619
620
621
622
  }
  
  #ifdef CONFIG_ACPI_HOTPLUG_CPU
  /****************************************************************************
   * 	Acpi processor hotplug support 				       	    *
   ****************************************************************************/
4be44fcd3   Len Brown   [ACPI] Lindent al...
623
  static int is_processor_present(acpi_handle handle)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
624
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
625
  	acpi_status status;
27663c585   Matthew Wilcox   ACPI: Change acpi...
626
  	unsigned long long sta = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
627

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
628
629
  
  	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
cfaf3747f   Zhang Rui   ACPI: ACPI Except...
630
631
632
  
  	if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
  		return 1;
d0ce46f55   Zhang Rui   ACPI Exception ()...
633
634
635
636
637
638
639
640
641
642
  	/*
  	 * _STA is mandatory for a processor that supports hot plug
  	 */
  	if (status == AE_NOT_FOUND)
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  				"Processor does not support hot plug
  "));
  	else
  		ACPI_EXCEPTION((AE_INFO, status,
  				"Processor Device is not present"));
cfaf3747f   Zhang Rui   ACPI: ACPI Except...
643
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
644
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
645
  static
4be44fcd3   Len Brown   [ACPI] Lindent al...
646
  int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
647
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
648
649
  	acpi_handle phandle;
  	struct acpi_device *pdev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
651
652
  
  	if (acpi_get_parent(handle, &phandle)) {
d550d98d3   Patrick Mochel   ACPI: delete trac...
653
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654
655
656
  	}
  
  	if (acpi_bus_get_device(phandle, &pdev)) {
d550d98d3   Patrick Mochel   ACPI: delete trac...
657
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
658
659
660
  	}
  
  	if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) {
d550d98d3   Patrick Mochel   ACPI: delete trac...
661
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
  	}
d550d98d3   Patrick Mochel   ACPI: delete trac...
663
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
664
  }
b95e9e8d9   Sam Ravnborg   ACPI: fix section...
665
666
  static void __ref acpi_processor_hotplug_notify(acpi_handle handle,
  						u32 event, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
667
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
668
669
  	struct acpi_processor *pr;
  	struct acpi_device *device = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
670
  	int result;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
671
672
673
674
  
  	switch (event) {
  	case ACPI_NOTIFY_BUS_CHECK:
  	case ACPI_NOTIFY_DEVICE_CHECK:
d6f882e10   Glauber Costa   ACPI: use ACPI_DE...
675
676
677
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  		"Processor driver received %s event
  ",
4be44fcd3   Len Brown   [ACPI] Lindent al...
678
  		       (event == ACPI_NOTIFY_BUS_CHECK) ?
d6f882e10   Glauber Costa   ACPI: use ACPI_DE...
679
  		       "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
680
681
682
683
684
685
686
  
  		if (!is_processor_present(handle))
  			break;
  
  		if (acpi_bus_get_device(handle, &device)) {
  			result = acpi_processor_device_add(handle, &device);
  			if (result)
6468463ab   Len Brown   ACPI: un-export A...
687
688
689
  				printk(KERN_ERR PREFIX
  					    "Unable to add the device
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
690
691
  			break;
  		}
4be44fcd3   Len Brown   [ACPI] Lindent al...
692
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
693
  	case ACPI_NOTIFY_EJECT_REQUEST:
4be44fcd3   Len Brown   [ACPI] Lindent al...
694
695
696
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  				  "received ACPI_NOTIFY_EJECT_REQUEST
  "));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
697
698
  
  		if (acpi_bus_get_device(handle, &device)) {
6468463ab   Len Brown   ACPI: un-export A...
699
700
701
  			printk(KERN_ERR PREFIX
  				    "Device don't exist, dropping EJECT
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
702
703
704
705
  			break;
  		}
  		pr = acpi_driver_data(device);
  		if (!pr) {
6468463ab   Len Brown   ACPI: un-export A...
706
707
708
  			printk(KERN_ERR PREFIX
  				    "Driver data is NULL, dropping EJECT
  ");
d550d98d3   Patrick Mochel   ACPI: delete trac...
709
  			return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
710
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
711
712
713
  		break;
  	default:
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
4be44fcd3   Len Brown   [ACPI] Lindent al...
714
715
  				  "Unsupported event [0x%x]
  ", event));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
716
717
  		break;
  	}
d550d98d3   Patrick Mochel   ACPI: delete trac...
718
  	return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
719
720
721
722
  }
  
  static acpi_status
  processor_walk_namespace_cb(acpi_handle handle,
4be44fcd3   Len Brown   [ACPI] Lindent al...
723
  			    u32 lvl, void *context, void **rv)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
724
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
725
  	acpi_status status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
726
  	int *action = context;
4be44fcd3   Len Brown   [ACPI] Lindent al...
727
  	acpi_object_type type = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
728
729
730
  
  	status = acpi_get_type(handle, &type);
  	if (ACPI_FAILURE(status))
4be44fcd3   Len Brown   [ACPI] Lindent al...
731
  		return (AE_OK);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
732
733
  
  	if (type != ACPI_TYPE_PROCESSOR)
4be44fcd3   Len Brown   [ACPI] Lindent al...
734
  		return (AE_OK);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
735

4be44fcd3   Len Brown   [ACPI] Lindent al...
736
  	switch (*action) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
737
738
  	case INSTALL_NOTIFY_HANDLER:
  		acpi_install_notify_handler(handle,
4be44fcd3   Len Brown   [ACPI] Lindent al...
739
740
741
  					    ACPI_SYSTEM_NOTIFY,
  					    acpi_processor_hotplug_notify,
  					    NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
742
743
744
  		break;
  	case UNINSTALL_NOTIFY_HANDLER:
  		acpi_remove_notify_handler(handle,
4be44fcd3   Len Brown   [ACPI] Lindent al...
745
746
  					   ACPI_SYSTEM_NOTIFY,
  					   acpi_processor_hotplug_notify);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
747
748
749
750
  		break;
  	default:
  		break;
  	}
4be44fcd3   Len Brown   [ACPI] Lindent al...
751
  	return (AE_OK);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
752
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
753
  static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
754
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
755
756
  
  	if (!is_processor_present(handle)) {
d550d98d3   Patrick Mochel   ACPI: delete trac...
757
  		return AE_ERROR;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
758
759
760
  	}
  
  	if (acpi_map_lsapic(handle, p_cpu))
d550d98d3   Patrick Mochel   ACPI: delete trac...
761
  		return AE_ERROR;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
762
763
764
  
  	if (arch_register_cpu(*p_cpu)) {
  		acpi_unmap_lsapic(*p_cpu);
d550d98d3   Patrick Mochel   ACPI: delete trac...
765
  		return AE_ERROR;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
766
  	}
d550d98d3   Patrick Mochel   ACPI: delete trac...
767
  	return AE_OK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
768
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
769
  static int acpi_processor_handle_eject(struct acpi_processor *pr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
770
  {
b62b8ef90   Zhang Rui   force offline the...
771
772
  	if (cpu_online(pr->id))
  		cpu_down(pr->id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
773
774
  	arch_unregister_cpu(pr->id);
  	acpi_unmap_lsapic(pr->id);
4be44fcd3   Len Brown   [ACPI] Lindent al...
775
  	return (0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
776
777
  }
  #else
4be44fcd3   Len Brown   [ACPI] Lindent al...
778
  static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
779
780
781
  {
  	return AE_ERROR;
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
782
  static int acpi_processor_handle_eject(struct acpi_processor *pr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
783
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
784
  	return (-EINVAL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
785
786
  }
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
787
788
789
790
791
792
  static
  void acpi_processor_install_hotplug_notify(void)
  {
  #ifdef CONFIG_ACPI_HOTPLUG_CPU
  	int action = INSTALL_NOTIFY_HANDLER;
  	acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
4be44fcd3   Len Brown   [ACPI] Lindent al...
793
794
  			    ACPI_ROOT_OBJECT,
  			    ACPI_UINT32_MAX,
2263576cf   Lin Ming   ACPICA: Add post-...
795
  			    processor_walk_namespace_cb, NULL, &action, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
796
  #endif
729c6ba33   Venkatesh Pallipadi   ACPI: Reevaluate ...
797
  	register_hotcpu_notifier(&acpi_cpu_notifier);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
798
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
799
800
801
802
803
804
  static
  void acpi_processor_uninstall_hotplug_notify(void)
  {
  #ifdef CONFIG_ACPI_HOTPLUG_CPU
  	int action = UNINSTALL_NOTIFY_HANDLER;
  	acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
4be44fcd3   Len Brown   [ACPI] Lindent al...
805
806
  			    ACPI_ROOT_OBJECT,
  			    ACPI_UINT32_MAX,
2263576cf   Lin Ming   ACPICA: Add post-...
807
  			    processor_walk_namespace_cb, NULL, &action, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
808
  #endif
729c6ba33   Venkatesh Pallipadi   ACPI: Reevaluate ...
809
  	unregister_hotcpu_notifier(&acpi_cpu_notifier);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
810
811
812
813
814
815
816
  }
  
  /*
   * We keep the driver loaded even when ACPI is not running.
   * This is needed for the powernow-k8 driver, that works even without
   * ACPI, but needs symbols from this driver
   */
4be44fcd3   Len Brown   [ACPI] Lindent al...
817
  static int __init acpi_processor_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
818
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
819
  	int result = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
820

ce8442b55   Yinghai Lu   acpi: don't call ...
821
822
  	if (acpi_disabled)
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
823
824
825
826
  	memset(&errata, 0, sizeof(errata));
  
  	acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
  	if (!acpi_processor_dir)
83822fc9e   Akinobu Mita   ACPI: prevent pro...
827
  		return -ENOMEM;
541adf7cd   Len Brown   ACPI: allow a nat...
828

267171726   Len Brown   intel_idle: nativ...
829
  	if (!cpuidle_register_driver(&acpi_idle_driver)) {
541adf7cd   Len Brown   ACPI: allow a nat...
830
831
832
  		printk(KERN_DEBUG "ACPI: %s registered with cpuidle
  ",
  			acpi_idle_driver.name);
267171726   Len Brown   intel_idle: nativ...
833
834
835
836
  	} else {
  		printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s",
  			cpuidle_get_driver()->name);
  	}
4f86d3a8e   Len Brown   cpuidle: consolid...
837

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
838
  	result = acpi_bus_register_driver(&acpi_processor_driver);
4f86d3a8e   Len Brown   cpuidle: consolid...
839
840
  	if (result < 0)
  		goto out_cpuidle;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
841
842
843
844
845
846
  
  	acpi_processor_install_hotplug_notify();
  
  	acpi_thermal_cpufreq_init();
  
  	acpi_processor_ppc_init();
1180509f6   Zhao Yakui   ACPI : Update T-s...
847
  	acpi_processor_throttling_init();
d550d98d3   Patrick Mochel   ACPI: delete trac...
848
  	return 0;
4f86d3a8e   Len Brown   cpuidle: consolid...
849
850
851
  
  out_cpuidle:
  	cpuidle_unregister_driver(&acpi_idle_driver);
4f86d3a8e   Len Brown   cpuidle: consolid...
852
853
854
  	remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
  
  	return result;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
855
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
856
  static void __exit acpi_processor_exit(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
857
  {
ce8442b55   Yinghai Lu   acpi: don't call ...
858
859
  	if (acpi_disabled)
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
860
861
862
863
864
865
866
  	acpi_processor_ppc_exit();
  
  	acpi_thermal_cpufreq_exit();
  
  	acpi_processor_uninstall_hotplug_notify();
  
  	acpi_bus_unregister_driver(&acpi_processor_driver);
4f86d3a8e   Len Brown   cpuidle: consolid...
867
  	cpuidle_unregister_driver(&acpi_idle_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
868
  	remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
d550d98d3   Patrick Mochel   ACPI: delete trac...
869
  	return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
870
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
871
872
873
874
875
876
  module_init(acpi_processor_init);
  module_exit(acpi_processor_exit);
  
  EXPORT_SYMBOL(acpi_processor_set_thermal_limit);
  
  MODULE_ALIAS("processor");