ia64/linux-2.6.18-xen.hg

annotate drivers/acpi/processor_core.c @ 531:3c564f80f2ef

Notify ACPI processor events to external logic, including C/P/T and hotplug, etc.

Signed-off-by: Tian Kevin <kevin.tian@intel.com>
Signed-off-by: Wei Gang <gang.wei@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu May 01 10:52:31 2008 +0100 (2008-05-01)
parents 831230e53067
children d62d60eaba6e
rev   line source
ian@0 1 /*
ian@0 2 * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $)
ian@0 3 *
ian@0 4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
ian@0 5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
ian@0 6 * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de>
ian@0 7 * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
ian@0 8 * - Added processor hotplug support
ian@0 9 *
ian@0 10 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ian@0 11 *
ian@0 12 * This program is free software; you can redistribute it and/or modify
ian@0 13 * it under the terms of the GNU General Public License as published by
ian@0 14 * the Free Software Foundation; either version 2 of the License, or (at
ian@0 15 * your option) any later version.
ian@0 16 *
ian@0 17 * This program is distributed in the hope that it will be useful, but
ian@0 18 * WITHOUT ANY WARRANTY; without even the implied warranty of
ian@0 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
ian@0 20 * General Public License for more details.
ian@0 21 *
ian@0 22 * You should have received a copy of the GNU General Public License along
ian@0 23 * with this program; if not, write to the Free Software Foundation, Inc.,
ian@0 24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
ian@0 25 *
ian@0 26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ian@0 27 * TBD:
ian@0 28 * 1. Make # power states dynamic.
ian@0 29 * 2. Support duty_cycle values that span bit 4.
ian@0 30 * 3. Optimize by having scheduler determine business instead of
ian@0 31 * having us try to calculate it here.
ian@0 32 * 4. Need C1 timing -- must modify kernel (IRQ handler) to get this.
ian@0 33 */
ian@0 34
ian@0 35 #include <linux/kernel.h>
ian@0 36 #include <linux/module.h>
ian@0 37 #include <linux/init.h>
ian@0 38 #include <linux/types.h>
ian@0 39 #include <linux/pci.h>
ian@0 40 #include <linux/pm.h>
ian@0 41 #include <linux/cpufreq.h>
ian@0 42 #include <linux/cpu.h>
ian@0 43 #include <linux/proc_fs.h>
ian@0 44 #include <linux/seq_file.h>
ian@0 45 #include <linux/dmi.h>
ian@0 46 #include <linux/moduleparam.h>
ian@0 47
ian@0 48 #include <asm/io.h>
ian@0 49 #include <asm/system.h>
ian@0 50 #include <asm/cpu.h>
ian@0 51 #include <asm/delay.h>
ian@0 52 #include <asm/uaccess.h>
ian@0 53 #include <asm/processor.h>
ian@0 54 #include <asm/smp.h>
ian@0 55 #include <asm/acpi.h>
ian@0 56
ian@0 57 #include <acpi/acpi_bus.h>
ian@0 58 #include <acpi/acpi_drivers.h>
ian@0 59 #include <acpi/processor.h>
ian@0 60
ian@0 61 #define ACPI_PROCESSOR_COMPONENT 0x01000000
ian@0 62 #define ACPI_PROCESSOR_CLASS "processor"
ian@0 63 #define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver"
ian@0 64 #define ACPI_PROCESSOR_DEVICE_NAME "Processor"
ian@0 65 #define ACPI_PROCESSOR_FILE_INFO "info"
ian@0 66 #define ACPI_PROCESSOR_FILE_THROTTLING "throttling"
ian@0 67 #define ACPI_PROCESSOR_FILE_LIMIT "limit"
ian@0 68 #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
ian@0 69 #define ACPI_PROCESSOR_NOTIFY_POWER 0x81
ian@0 70
ian@0 71 #define ACPI_PROCESSOR_LIMIT_USER 0
ian@0 72 #define ACPI_PROCESSOR_LIMIT_THERMAL 1
ian@0 73
ian@0 74 #define ACPI_STA_PRESENT 0x00000001
ian@0 75
ian@0 76 #define _COMPONENT ACPI_PROCESSOR_COMPONENT
ian@0 77 ACPI_MODULE_NAME("acpi_processor")
ian@0 78
ian@0 79 MODULE_AUTHOR("Paul Diefenbaugh");
ian@0 80 MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME);
ian@0 81 MODULE_LICENSE("GPL");
ian@0 82
ian@0 83 static int acpi_processor_add(struct acpi_device *device);
ian@0 84 static int acpi_processor_start(struct acpi_device *device);
ian@0 85 static int acpi_processor_remove(struct acpi_device *device, int type);
ian@0 86 static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
ian@0 87 static void acpi_processor_notify(acpi_handle handle, u32 event, void *data);
ian@0 88 static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
ian@0 89 static int acpi_processor_handle_eject(struct acpi_processor *pr);
ian@0 90
ian@0 91 static struct acpi_driver acpi_processor_driver = {
ian@0 92 .name = ACPI_PROCESSOR_DRIVER_NAME,
ian@0 93 .class = ACPI_PROCESSOR_CLASS,
ian@0 94 .ids = ACPI_PROCESSOR_HID,
ian@0 95 .ops = {
ian@0 96 .add = acpi_processor_add,
ian@0 97 .remove = acpi_processor_remove,
ian@0 98 .start = acpi_processor_start,
ian@0 99 },
ian@0 100 };
ian@0 101
ian@0 102 #define INSTALL_NOTIFY_HANDLER 1
ian@0 103 #define UNINSTALL_NOTIFY_HANDLER 2
ian@0 104
ian@0 105 static const struct file_operations acpi_processor_info_fops = {
ian@0 106 .open = acpi_processor_info_open_fs,
ian@0 107 .read = seq_read,
ian@0 108 .llseek = seq_lseek,
ian@0 109 .release = single_release,
ian@0 110 };
ian@0 111
ian@0 112 struct acpi_processor *processors[NR_CPUS];
ian@0 113 struct acpi_processor_errata errata __read_mostly;
ian@0 114
ian@0 115 /* --------------------------------------------------------------------------
ian@0 116 Errata Handling
ian@0 117 -------------------------------------------------------------------------- */
ian@0 118
ian@0 119 static int acpi_processor_errata_piix4(struct pci_dev *dev)
ian@0 120 {
ian@0 121 u8 rev = 0;
ian@0 122 u8 value1 = 0;
ian@0 123 u8 value2 = 0;
ian@0 124
ian@0 125
ian@0 126 if (!dev)
ian@0 127 return -EINVAL;
ian@0 128
ian@0 129 /*
ian@0 130 * Note that 'dev' references the PIIX4 ACPI Controller.
ian@0 131 */
ian@0 132
ian@0 133 pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
ian@0 134
ian@0 135 switch (rev) {
ian@0 136 case 0:
ian@0 137 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n"));
ian@0 138 break;
ian@0 139 case 1:
ian@0 140 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n"));
ian@0 141 break;
ian@0 142 case 2:
ian@0 143 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n"));
ian@0 144 break;
ian@0 145 case 3:
ian@0 146 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n"));
ian@0 147 break;
ian@0 148 default:
ian@0 149 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n"));
ian@0 150 break;
ian@0 151 }
ian@0 152
ian@0 153 switch (rev) {
ian@0 154
ian@0 155 case 0: /* PIIX4 A-step */
ian@0 156 case 1: /* PIIX4 B-step */
ian@0 157 /*
ian@0 158 * See specification changes #13 ("Manual Throttle Duty Cycle")
ian@0 159 * and #14 ("Enabling and Disabling Manual Throttle"), plus
ian@0 160 * erratum #5 ("STPCLK# Deassertion Time") from the January
ian@0 161 * 2002 PIIX4 specification update. Applies to only older
ian@0 162 * PIIX4 models.
ian@0 163 */
ian@0 164 errata.piix4.throttle = 1;
ian@0 165
ian@0 166 case 2: /* PIIX4E */
ian@0 167 case 3: /* PIIX4M */
ian@0 168 /*
ian@0 169 * See erratum #18 ("C3 Power State/BMIDE and Type-F DMA
ian@0 170 * Livelock") from the January 2002 PIIX4 specification update.
ian@0 171 * Applies to all PIIX4 models.
ian@0 172 */
ian@0 173
ian@0 174 /*
ian@0 175 * BM-IDE
ian@0 176 * ------
ian@0 177 * Find the PIIX4 IDE Controller and get the Bus Master IDE
ian@0 178 * Status register address. We'll use this later to read
ian@0 179 * each IDE controller's DMA status to make sure we catch all
ian@0 180 * DMA activity.
ian@0 181 */
ian@0 182 dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
ian@0 183 PCI_DEVICE_ID_INTEL_82371AB,
ian@0 184 PCI_ANY_ID, PCI_ANY_ID, NULL);
ian@0 185 if (dev) {
ian@0 186 errata.piix4.bmisx = pci_resource_start(dev, 4);
ian@0 187 pci_dev_put(dev);
ian@0 188 }
ian@0 189
ian@0 190 /*
ian@0 191 * Type-F DMA
ian@0 192 * ----------
ian@0 193 * Find the PIIX4 ISA Controller and read the Motherboard
ian@0 194 * DMA controller's status to see if Type-F (Fast) DMA mode
ian@0 195 * is enabled (bit 7) on either channel. Note that we'll
ian@0 196 * disable C3 support if this is enabled, as some legacy
ian@0 197 * devices won't operate well if fast DMA is disabled.
ian@0 198 */
ian@0 199 dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
ian@0 200 PCI_DEVICE_ID_INTEL_82371AB_0,
ian@0 201 PCI_ANY_ID, PCI_ANY_ID, NULL);
ian@0 202 if (dev) {
ian@0 203 pci_read_config_byte(dev, 0x76, &value1);
ian@0 204 pci_read_config_byte(dev, 0x77, &value2);
ian@0 205 if ((value1 & 0x80) || (value2 & 0x80))
ian@0 206 errata.piix4.fdma = 1;
ian@0 207 pci_dev_put(dev);
ian@0 208 }
ian@0 209
ian@0 210 break;
ian@0 211 }
ian@0 212
ian@0 213 if (errata.piix4.bmisx)
ian@0 214 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
ian@0 215 "Bus master activity detection (BM-IDE) erratum enabled\n"));
ian@0 216 if (errata.piix4.fdma)
ian@0 217 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
ian@0 218 "Type-F DMA livelock erratum (C3 disabled)\n"));
ian@0 219
ian@0 220 return 0;
ian@0 221 }
ian@0 222
ian@0 223 static int acpi_processor_errata(struct acpi_processor *pr)
ian@0 224 {
ian@0 225 int result = 0;
ian@0 226 struct pci_dev *dev = NULL;
ian@0 227
ian@0 228
ian@0 229 if (!pr)
ian@0 230 return -EINVAL;
ian@0 231
ian@0 232 /*
ian@0 233 * PIIX4
ian@0 234 */
ian@0 235 dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
ian@0 236 PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID,
ian@0 237 PCI_ANY_ID, NULL);
ian@0 238 if (dev) {
ian@0 239 result = acpi_processor_errata_piix4(dev);
ian@0 240 pci_dev_put(dev);
ian@0 241 }
ian@0 242
ian@0 243 return result;
ian@0 244 }
ian@0 245
ian@0 246 /* --------------------------------------------------------------------------
ian@0 247 Common ACPI processor functions
ian@0 248 -------------------------------------------------------------------------- */
ian@0 249
ian@0 250 /*
ian@0 251 * _PDC is required for a BIOS-OS handshake for most of the newer
ian@0 252 * ACPI processor features.
ian@0 253 */
ian@0 254 static int acpi_processor_set_pdc(struct acpi_processor *pr)
ian@0 255 {
ian@0 256 struct acpi_object_list *pdc_in = pr->pdc;
ian@0 257 acpi_status status = AE_OK;
ian@0 258
ian@0 259
ian@0 260 if (!pdc_in)
ian@0 261 return status;
ian@0 262
ian@0 263 status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL);
ian@0 264
ian@0 265 if (ACPI_FAILURE(status))
ian@0 266 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
ian@0 267 "Could not evaluate _PDC, using legacy perf. control...\n"));
ian@0 268
ian@0 269 return status;
ian@0 270 }
ian@0 271
ian@0 272 /* --------------------------------------------------------------------------
ian@0 273 FS Interface (/proc)
ian@0 274 -------------------------------------------------------------------------- */
ian@0 275
ian@0 276 static struct proc_dir_entry *acpi_processor_dir = NULL;
ian@0 277
ian@0 278 static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
ian@0 279 {
ian@0 280 struct acpi_processor *pr = (struct acpi_processor *)seq->private;
ian@0 281
ian@0 282
ian@0 283 if (!pr)
ian@0 284 goto end;
ian@0 285
ian@0 286 seq_printf(seq, "processor id: %d\n"
ian@0 287 "acpi id: %d\n"
ian@0 288 "bus mastering control: %s\n"
ian@0 289 "power management: %s\n"
ian@0 290 "throttling control: %s\n"
ian@0 291 "limit interface: %s\n",
ian@0 292 pr->id,
ian@0 293 pr->acpi_id,
ian@0 294 pr->flags.bm_control ? "yes" : "no",
ian@0 295 pr->flags.power ? "yes" : "no",
ian@0 296 pr->flags.throttling ? "yes" : "no",
ian@0 297 pr->flags.limit ? "yes" : "no");
ian@0 298
ian@0 299 end:
ian@0 300 return 0;
ian@0 301 }
ian@0 302
ian@0 303 static int acpi_processor_info_open_fs(struct inode *inode, struct file *file)
ian@0 304 {
ian@0 305 return single_open(file, acpi_processor_info_seq_show,
ian@0 306 PDE(inode)->data);
ian@0 307 }
ian@0 308
ian@0 309 static int acpi_processor_add_fs(struct acpi_device *device)
ian@0 310 {
ian@0 311 struct proc_dir_entry *entry = NULL;
ian@0 312
ian@0 313
ian@0 314 if (!acpi_device_dir(device)) {
ian@0 315 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
ian@0 316 acpi_processor_dir);
ian@0 317 if (!acpi_device_dir(device))
ian@0 318 return -ENODEV;
ian@0 319 }
ian@0 320 acpi_device_dir(device)->owner = THIS_MODULE;
ian@0 321
ian@0 322 /* 'info' [R] */
ian@0 323 entry = create_proc_entry(ACPI_PROCESSOR_FILE_INFO,
ian@0 324 S_IRUGO, acpi_device_dir(device));
ian@0 325 if (!entry)
ian@0 326 return -EIO;
ian@0 327 else {
ian@0 328 entry->proc_fops = &acpi_processor_info_fops;
ian@0 329 entry->data = acpi_driver_data(device);
ian@0 330 entry->owner = THIS_MODULE;
ian@0 331 }
ian@0 332
ian@0 333 /* 'throttling' [R/W] */
ian@0 334 entry = create_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
ian@0 335 S_IFREG | S_IRUGO | S_IWUSR,
ian@0 336 acpi_device_dir(device));
ian@0 337 if (!entry)
ian@0 338 return -EIO;
ian@0 339 else {
ian@0 340 entry->proc_fops = &acpi_processor_throttling_fops;
ian@0 341 entry->data = acpi_driver_data(device);
ian@0 342 entry->owner = THIS_MODULE;
ian@0 343 }
ian@0 344
ian@0 345 /* 'limit' [R/W] */
ian@0 346 entry = create_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,
ian@0 347 S_IFREG | S_IRUGO | S_IWUSR,
ian@0 348 acpi_device_dir(device));
ian@0 349 if (!entry)
ian@0 350 return -EIO;
ian@0 351 else {
ian@0 352 entry->proc_fops = &acpi_processor_limit_fops;
ian@0 353 entry->data = acpi_driver_data(device);
ian@0 354 entry->owner = THIS_MODULE;
ian@0 355 }
ian@0 356
ian@0 357 return 0;
ian@0 358 }
ian@0 359
ian@0 360 static int acpi_processor_remove_fs(struct acpi_device *device)
ian@0 361 {
ian@0 362
ian@0 363 if (acpi_device_dir(device)) {
ian@0 364 remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,
ian@0 365 acpi_device_dir(device));
ian@0 366 remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
ian@0 367 acpi_device_dir(device));
ian@0 368 remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,
ian@0 369 acpi_device_dir(device));
ian@0 370 remove_proc_entry(acpi_device_bid(device), acpi_processor_dir);
ian@0 371 acpi_device_dir(device) = NULL;
ian@0 372 }
ian@0 373
ian@0 374 return 0;
ian@0 375 }
ian@0 376
ian@0 377 /* Use the acpiid in MADT to map cpus in case of SMP */
ian@0 378 #ifndef CONFIG_SMP
ian@0 379 #define convert_acpiid_to_cpu(acpi_id) (-1)
ian@0 380 #else
ian@0 381
ian@0 382 #ifdef CONFIG_IA64
ian@0 383 #define arch_acpiid_to_apicid ia64_acpiid_to_sapicid
ian@0 384 #define arch_cpu_to_apicid ia64_cpu_to_sapicid
ian@0 385 #define ARCH_BAD_APICID (0xffff)
ian@0 386 #else
ian@0 387 #define arch_acpiid_to_apicid x86_acpiid_to_apicid
ian@0 388 #define arch_cpu_to_apicid x86_cpu_to_apicid
ian@0 389 #define ARCH_BAD_APICID (0xff)
ian@0 390 #endif
ian@0 391
ian@0 392 static int convert_acpiid_to_cpu(u8 acpi_id)
ian@0 393 {
ian@0 394 u16 apic_id;
ian@0 395 int i;
ian@0 396
ian@0 397 apic_id = arch_acpiid_to_apicid[acpi_id];
ian@0 398 if (apic_id == ARCH_BAD_APICID)
ian@0 399 return -1;
ian@0 400
ian@0 401 for (i = 0; i < NR_CPUS; i++) {
ian@0 402 if (arch_cpu_to_apicid[i] == apic_id)
ian@0 403 return i;
ian@0 404 }
ian@0 405 return -1;
ian@0 406 }
ian@0 407 #endif
ian@0 408
ian@0 409 /* --------------------------------------------------------------------------
ian@0 410 Driver Interface
ian@0 411 -------------------------------------------------------------------------- */
ian@0 412
ian@0 413 static int acpi_processor_get_info(struct acpi_processor *pr)
ian@0 414 {
ian@0 415 acpi_status status = 0;
ian@0 416 union acpi_object object = { 0 };
ian@0 417 struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
ian@0 418 int cpu_index;
ian@0 419 static int cpu0_initialized;
ian@0 420
ian@0 421
ian@0 422 if (!pr)
ian@0 423 return -EINVAL;
ian@0 424
ian@0 425 if (num_online_cpus() > 1)
ian@0 426 errata.smp = TRUE;
ian@0 427
ian@0 428 acpi_processor_errata(pr);
ian@0 429
ian@0 430 /*
ian@0 431 * Check to see if we have bus mastering arbitration control. This
ian@0 432 * is required for proper C3 usage (to maintain cache coherency).
ian@0 433 */
ian@0 434 if (acpi_fadt.V1_pm2_cnt_blk && acpi_fadt.pm2_cnt_len) {
ian@0 435 pr->flags.bm_control = 1;
ian@0 436 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
ian@0 437 "Bus mastering arbitration control present\n"));
ian@0 438 } else
ian@0 439 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
ian@0 440 "No bus mastering arbitration control\n"));
ian@0 441
ian@0 442 /*
ian@0 443 * Evalute the processor object. Note that it is common on SMP to
ian@0 444 * have the first (boot) processor with a valid PBLK address while
ian@0 445 * all others have a NULL address.
ian@0 446 */
ian@0 447 status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
ian@0 448 if (ACPI_FAILURE(status)) {
ian@0 449 printk(KERN_ERR PREFIX "Evaluating processor object\n");
ian@0 450 return -ENODEV;
ian@0 451 }
ian@0 452
ian@0 453 /*
ian@0 454 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
ian@0 455 * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c
ian@0 456 */
ian@0 457 pr->acpi_id = object.processor.proc_id;
ian@0 458
ian@0 459 cpu_index = convert_acpiid_to_cpu(pr->acpi_id);
ian@0 460
ian@0 461 /* Handle UP system running SMP kernel, with no LAPIC in MADT */
ian@0 462 if (!cpu0_initialized && (cpu_index == -1) &&
ian@0 463 (num_online_cpus() == 1)) {
ian@0 464 cpu_index = 0;
ian@0 465 }
ian@0 466
ian@0 467 cpu0_initialized = 1;
ian@0 468
ian@0 469 pr->id = cpu_index;
ian@0 470
ian@0 471 /*
ian@0 472 * Extra Processor objects may be enumerated on MP systems with
ian@0 473 * less than the max # of CPUs. They should be ignored _iff
ian@0 474 * they are physically not present.
ian@0 475 */
ian@0 476 if (cpu_index == -1) {
ian@0 477 if (ACPI_FAILURE
ian@0 478 (acpi_processor_hotadd_init(pr->handle, &pr->id))) {
ian@0 479 printk(KERN_ERR PREFIX
ian@0 480 "Getting cpuindex for acpiid 0x%x\n",
ian@0 481 pr->acpi_id);
ian@0 482 return -ENODEV;
ian@0 483 }
ian@0 484 }
ian@0 485
ian@0 486 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
ian@0 487 pr->acpi_id));
ian@0 488
ian@0 489 if (!object.processor.pblk_address)
ian@0 490 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
ian@0 491 else if (object.processor.pblk_length != 6)
ian@0 492 printk(KERN_ERR PREFIX "Invalid PBLK length [%d]\n",
ian@0 493 object.processor.pblk_length);
ian@0 494 else {
ian@0 495 pr->throttling.address = object.processor.pblk_address;
ian@0 496 pr->throttling.duty_offset = acpi_fadt.duty_offset;
ian@0 497 pr->throttling.duty_width = acpi_fadt.duty_width;
ian@0 498
ian@0 499 pr->pblk = object.processor.pblk_address;
ian@0 500
ian@0 501 /*
ian@0 502 * We don't care about error returns - we just try to mark
ian@0 503 * these reserved so that nobody else is confused into thinking
ian@0 504 * that this region might be unused..
ian@0 505 *
ian@0 506 * (In particular, allocating the IO range for Cardbus)
ian@0 507 */
ian@0 508 request_region(pr->throttling.address, 6, "ACPI CPU throttle");
ian@0 509 }
ian@0 510
ian@0 511 #ifdef CONFIG_CPU_FREQ
ian@0 512 acpi_processor_ppc_has_changed(pr);
ian@0 513 #endif
ian@0 514 acpi_processor_get_throttling_info(pr);
ian@0 515 acpi_processor_get_limit_info(pr);
ian@0 516
ian@0 517 return 0;
ian@0 518 }
ian@0 519
ian@0 520 static void *processor_device_array[NR_CPUS];
ian@0 521
ian@0 522 static int acpi_processor_start(struct acpi_device *device)
ian@0 523 {
ian@0 524 int result = 0;
ian@0 525 acpi_status status = AE_OK;
ian@0 526 struct acpi_processor *pr;
ian@0 527
ian@0 528
ian@0 529 pr = acpi_driver_data(device);
ian@0 530
ian@0 531 result = acpi_processor_get_info(pr);
ian@0 532 if (result) {
ian@0 533 /* Processor is physically not present */
ian@0 534 return 0;
ian@0 535 }
ian@0 536
ian@0 537 BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
ian@0 538
ian@0 539 /*
ian@0 540 * Buggy BIOS check
ian@0 541 * ACPI id of processors can be reported wrongly by the BIOS.
ian@0 542 * Don't trust it blindly
ian@0 543 */
ian@0 544 if (processor_device_array[pr->id] != NULL &&
ian@0 545 processor_device_array[pr->id] != (void *)device) {
ian@0 546 printk(KERN_WARNING "BIOS reported wrong ACPI id"
ian@0 547 "for the processor\n");
ian@0 548 return -ENODEV;
ian@0 549 }
ian@0 550 processor_device_array[pr->id] = (void *)device;
ian@0 551
ian@0 552 processors[pr->id] = pr;
ian@0 553
ian@0 554 result = acpi_processor_add_fs(device);
ian@0 555 if (result)
ian@0 556 goto end;
ian@0 557
ian@0 558 status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
ian@0 559 acpi_processor_notify, pr);
ian@0 560
ian@0 561 /* _PDC call should be done before doing anything else (if reqd.). */
ian@0 562 arch_acpi_processor_init_pdc(pr);
ian@0 563 acpi_processor_set_pdc(pr);
ian@0 564
ian@0 565 acpi_processor_power_init(pr, device);
ian@0 566
keir@531 567 #ifdef CONFIG_PROCESSOR_EXTERNAL_CONTROL
keir@531 568 processor_extcntl_init(pr);
keir@531 569 #endif
keir@531 570
ian@0 571 if (pr->flags.throttling) {
ian@0 572 printk(KERN_INFO PREFIX "%s [%s] (supports",
ian@0 573 acpi_device_name(device), acpi_device_bid(device));
ian@0 574 printk(" %d throttling states", pr->throttling.state_count);
ian@0 575 printk(")\n");
ian@0 576 }
ian@0 577
ian@0 578 end:
ian@0 579
ian@0 580 return result;
ian@0 581 }
ian@0 582
ian@0 583 static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
ian@0 584 {
ian@0 585 struct acpi_processor *pr = (struct acpi_processor *)data;
ian@0 586 struct acpi_device *device = NULL;
ian@0 587
ian@0 588
ian@0 589 if (!pr)
ian@0 590 return;
ian@0 591
ian@0 592 if (acpi_bus_get_device(pr->handle, &device))
ian@0 593 return;
ian@0 594
ian@0 595 switch (event) {
ian@0 596 case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
ian@0 597 acpi_processor_ppc_has_changed(pr);
ian@0 598 acpi_bus_generate_event(device, event,
ian@0 599 pr->performance_platform_limit);
ian@0 600 break;
ian@0 601 case ACPI_PROCESSOR_NOTIFY_POWER:
ian@0 602 acpi_processor_cst_has_changed(pr);
ian@0 603 acpi_bus_generate_event(device, event, 0);
ian@0 604 break;
ian@0 605 default:
ian@0 606 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
ian@0 607 "Unsupported event [0x%x]\n", event));
ian@0 608 break;
ian@0 609 }
ian@0 610
ian@0 611 return;
ian@0 612 }
ian@0 613
ian@0 614 static int acpi_processor_add(struct acpi_device *device)
ian@0 615 {
ian@0 616 struct acpi_processor *pr = NULL;
ian@0 617
ian@0 618
ian@0 619 if (!device)
ian@0 620 return -EINVAL;
ian@0 621
ian@0 622 pr = kmalloc(sizeof(struct acpi_processor), GFP_KERNEL);
ian@0 623 if (!pr)
ian@0 624 return -ENOMEM;
ian@0 625 memset(pr, 0, sizeof(struct acpi_processor));
ian@0 626
ian@0 627 pr->handle = device->handle;
ian@0 628 strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
ian@0 629 strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
ian@0 630 acpi_driver_data(device) = pr;
ian@0 631
ian@0 632 return 0;
ian@0 633 }
ian@0 634
ian@0 635 static int acpi_processor_remove(struct acpi_device *device, int type)
ian@0 636 {
ian@0 637 acpi_status status = AE_OK;
ian@0 638 struct acpi_processor *pr = NULL;
ian@0 639
ian@0 640
ian@0 641 if (!device || !acpi_driver_data(device))
ian@0 642 return -EINVAL;
ian@0 643
ian@0 644 pr = (struct acpi_processor *)acpi_driver_data(device);
ian@0 645
ian@0 646 if (pr->id >= NR_CPUS) {
ian@0 647 kfree(pr);
ian@0 648 return 0;
ian@0 649 }
ian@0 650
ian@0 651 if (type == ACPI_BUS_REMOVAL_EJECT) {
ian@0 652 if (acpi_processor_handle_eject(pr))
ian@0 653 return -EINVAL;
ian@0 654 }
ian@0 655
ian@0 656 acpi_processor_power_exit(pr, device);
ian@0 657
ian@0 658 status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
ian@0 659 acpi_processor_notify);
ian@0 660
ian@0 661 acpi_processor_remove_fs(device);
ian@0 662
ian@0 663 processors[pr->id] = NULL;
ian@0 664
ian@0 665 kfree(pr);
ian@0 666
ian@0 667 return 0;
ian@0 668 }
ian@0 669
ian@0 670 #ifdef CONFIG_ACPI_HOTPLUG_CPU
ian@0 671 /****************************************************************************
ian@0 672 * Acpi processor hotplug support *
ian@0 673 ****************************************************************************/
ian@0 674
ian@0 675 static int is_processor_present(acpi_handle handle);
ian@0 676
ian@0 677 static int is_processor_present(acpi_handle handle)
ian@0 678 {
ian@0 679 acpi_status status;
ian@0 680 unsigned long sta = 0;
ian@0 681
ian@0 682
ian@0 683 status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
ian@0 684 if (ACPI_FAILURE(status) || !(sta & ACPI_STA_PRESENT)) {
ian@0 685 ACPI_EXCEPTION((AE_INFO, status, "Processor Device is not present"));
ian@0 686 return 0;
ian@0 687 }
ian@0 688 return 1;
ian@0 689 }
ian@0 690
ian@0 691 static
ian@0 692 int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
ian@0 693 {
ian@0 694 acpi_handle phandle;
ian@0 695 struct acpi_device *pdev;
ian@0 696 struct acpi_processor *pr;
ian@0 697
ian@0 698
ian@0 699 if (acpi_get_parent(handle, &phandle)) {
ian@0 700 return -ENODEV;
ian@0 701 }
ian@0 702
ian@0 703 if (acpi_bus_get_device(phandle, &pdev)) {
ian@0 704 return -ENODEV;
ian@0 705 }
ian@0 706
ian@0 707 if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) {
ian@0 708 return -ENODEV;
ian@0 709 }
ian@0 710
ian@0 711 acpi_bus_start(*device);
ian@0 712
ian@0 713 pr = acpi_driver_data(*device);
ian@0 714 if (!pr)
ian@0 715 return -ENODEV;
ian@0 716
keir@531 717 if (processor_cntl_external())
keir@531 718 processor_notify_external(pr,
keir@531 719 PROCESSOR_HOTPLUG, HOTPLUG_TYPE_ADD);
keir@531 720
ian@0 721 if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
ian@0 722 kobject_uevent(&(*device)->kobj, KOBJ_ONLINE);
ian@0 723 }
ian@0 724 return 0;
ian@0 725 }
ian@0 726
ian@0 727 static void
ian@0 728 acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
ian@0 729 {
ian@0 730 struct acpi_processor *pr;
ian@0 731 struct acpi_device *device = NULL;
ian@0 732 int result;
ian@0 733
ian@0 734
ian@0 735 switch (event) {
ian@0 736 case ACPI_NOTIFY_BUS_CHECK:
ian@0 737 case ACPI_NOTIFY_DEVICE_CHECK:
ian@0 738 printk("Processor driver received %s event\n",
ian@0 739 (event == ACPI_NOTIFY_BUS_CHECK) ?
ian@0 740 "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK");
ian@0 741
ian@0 742 if (!is_processor_present(handle))
ian@0 743 break;
ian@0 744
ian@0 745 if (acpi_bus_get_device(handle, &device)) {
ian@0 746 result = acpi_processor_device_add(handle, &device);
ian@0 747 if (result)
ian@0 748 printk(KERN_ERR PREFIX
ian@0 749 "Unable to add the device\n");
ian@0 750 break;
ian@0 751 }
ian@0 752
ian@0 753 pr = acpi_driver_data(device);
ian@0 754 if (!pr) {
ian@0 755 printk(KERN_ERR PREFIX "Driver data is NULL\n");
ian@0 756 break;
ian@0 757 }
ian@0 758
keir@531 759 if (processor_cntl_external())
keir@531 760 processor_notify_external(pr,
keir@531 761 PROCESSOR_HOTPLUG, HOTPLUG_TYPE_ADD);
keir@531 762
ian@0 763 if (pr->id >= 0 && (pr->id < NR_CPUS)) {
ian@0 764 kobject_uevent(&device->kobj, KOBJ_OFFLINE);
ian@0 765 break;
ian@0 766 }
ian@0 767
ian@0 768 result = acpi_processor_start(device);
ian@0 769 if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
ian@0 770 kobject_uevent(&device->kobj, KOBJ_ONLINE);
ian@0 771 } else {
ian@0 772 printk(KERN_ERR PREFIX "Device [%s] failed to start\n",
ian@0 773 acpi_device_bid(device));
ian@0 774 }
ian@0 775 break;
ian@0 776 case ACPI_NOTIFY_EJECT_REQUEST:
ian@0 777 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
ian@0 778 "received ACPI_NOTIFY_EJECT_REQUEST\n"));
ian@0 779
ian@0 780 if (acpi_bus_get_device(handle, &device)) {
ian@0 781 printk(KERN_ERR PREFIX
ian@0 782 "Device don't exist, dropping EJECT\n");
ian@0 783 break;
ian@0 784 }
ian@0 785 pr = acpi_driver_data(device);
ian@0 786 if (!pr) {
ian@0 787 printk(KERN_ERR PREFIX
ian@0 788 "Driver data is NULL, dropping EJECT\n");
ian@0 789 return;
ian@0 790 }
ian@0 791
ian@0 792 if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
ian@0 793 kobject_uevent(&device->kobj, KOBJ_OFFLINE);
keir@531 794
keir@531 795 if (processor_cntl_external())
keir@531 796 processor_notify_external(pr, PROCESSOR_HOTPLUG,
keir@531 797 HOTPLUG_TYPE_REMOVE);
keir@531 798
ian@0 799 break;
ian@0 800 default:
ian@0 801 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
ian@0 802 "Unsupported event [0x%x]\n", event));
ian@0 803 break;
ian@0 804 }
ian@0 805
ian@0 806 return;
ian@0 807 }
ian@0 808
ian@0 809 static acpi_status
ian@0 810 processor_walk_namespace_cb(acpi_handle handle,
ian@0 811 u32 lvl, void *context, void **rv)
ian@0 812 {
ian@0 813 acpi_status status;
ian@0 814 int *action = context;
ian@0 815 acpi_object_type type = 0;
ian@0 816
ian@0 817 status = acpi_get_type(handle, &type);
ian@0 818 if (ACPI_FAILURE(status))
ian@0 819 return (AE_OK);
ian@0 820
ian@0 821 if (type != ACPI_TYPE_PROCESSOR)
ian@0 822 return (AE_OK);
ian@0 823
ian@0 824 switch (*action) {
ian@0 825 case INSTALL_NOTIFY_HANDLER:
ian@0 826 acpi_install_notify_handler(handle,
ian@0 827 ACPI_SYSTEM_NOTIFY,
ian@0 828 acpi_processor_hotplug_notify,
ian@0 829 NULL);
ian@0 830 break;
ian@0 831 case UNINSTALL_NOTIFY_HANDLER:
ian@0 832 acpi_remove_notify_handler(handle,
ian@0 833 ACPI_SYSTEM_NOTIFY,
ian@0 834 acpi_processor_hotplug_notify);
ian@0 835 break;
ian@0 836 default:
ian@0 837 break;
ian@0 838 }
ian@0 839
ian@0 840 return (AE_OK);
ian@0 841 }
ian@0 842
ian@0 843 static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
ian@0 844 {
ian@0 845
ian@0 846 if (!is_processor_present(handle)) {
ian@0 847 return AE_ERROR;
ian@0 848 }
ian@0 849
ian@0 850 if (acpi_map_lsapic(handle, p_cpu))
ian@0 851 return AE_ERROR;
ian@0 852
ian@0 853 if (arch_register_cpu(*p_cpu)) {
ian@0 854 acpi_unmap_lsapic(*p_cpu);
ian@0 855 return AE_ERROR;
ian@0 856 }
ian@0 857
ian@0 858 return AE_OK;
ian@0 859 }
ian@0 860
ian@0 861 static int acpi_processor_handle_eject(struct acpi_processor *pr)
ian@0 862 {
ian@0 863 if (cpu_online(pr->id)) {
ian@0 864 return (-EINVAL);
ian@0 865 }
ian@0 866 arch_unregister_cpu(pr->id);
ian@0 867 acpi_unmap_lsapic(pr->id);
ian@0 868 return (0);
ian@0 869 }
ian@0 870 #else
ian@0 871 static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
ian@0 872 {
ian@0 873 return AE_ERROR;
ian@0 874 }
ian@0 875 static int acpi_processor_handle_eject(struct acpi_processor *pr)
ian@0 876 {
ian@0 877 return (-EINVAL);
ian@0 878 }
ian@0 879 #endif
ian@0 880
ian@0 881 static
ian@0 882 void acpi_processor_install_hotplug_notify(void)
ian@0 883 {
ian@0 884 #ifdef CONFIG_ACPI_HOTPLUG_CPU
ian@0 885 int action = INSTALL_NOTIFY_HANDLER;
ian@0 886 acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
ian@0 887 ACPI_ROOT_OBJECT,
ian@0 888 ACPI_UINT32_MAX,
ian@0 889 processor_walk_namespace_cb, &action, NULL);
ian@0 890 #endif
ian@0 891 }
ian@0 892
ian@0 893 static
ian@0 894 void acpi_processor_uninstall_hotplug_notify(void)
ian@0 895 {
ian@0 896 #ifdef CONFIG_ACPI_HOTPLUG_CPU
ian@0 897 int action = UNINSTALL_NOTIFY_HANDLER;
ian@0 898 acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
ian@0 899 ACPI_ROOT_OBJECT,
ian@0 900 ACPI_UINT32_MAX,
ian@0 901 processor_walk_namespace_cb, &action, NULL);
ian@0 902 #endif
ian@0 903 }
ian@0 904
ian@0 905 /*
ian@0 906 * We keep the driver loaded even when ACPI is not running.
ian@0 907 * This is needed for the powernow-k8 driver, that works even without
ian@0 908 * ACPI, but needs symbols from this driver
ian@0 909 */
ian@0 910
ian@0 911 static int __init acpi_processor_init(void)
ian@0 912 {
ian@0 913 int result = 0;
ian@0 914
ian@0 915
ian@0 916 memset(&processors, 0, sizeof(processors));
ian@0 917 memset(&errata, 0, sizeof(errata));
ian@0 918
ian@0 919 acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
ian@0 920 if (!acpi_processor_dir)
ian@0 921 return 0;
ian@0 922 acpi_processor_dir->owner = THIS_MODULE;
ian@0 923
ian@0 924 result = acpi_bus_register_driver(&acpi_processor_driver);
ian@0 925 if (result < 0) {
ian@0 926 remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
ian@0 927 return 0;
ian@0 928 }
ian@0 929
ian@0 930 acpi_processor_install_hotplug_notify();
ian@0 931
ian@0 932 acpi_thermal_cpufreq_init();
ian@0 933
ian@0 934 acpi_processor_ppc_init();
ian@0 935
ian@0 936 return 0;
ian@0 937 }
ian@0 938
ian@0 939 static void __exit acpi_processor_exit(void)
ian@0 940 {
ian@0 941
ian@0 942 acpi_processor_ppc_exit();
ian@0 943
ian@0 944 acpi_thermal_cpufreq_exit();
ian@0 945
ian@0 946 acpi_processor_uninstall_hotplug_notify();
ian@0 947
ian@0 948 acpi_bus_unregister_driver(&acpi_processor_driver);
ian@0 949
ian@0 950 remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
ian@0 951
ian@0 952 return;
ian@0 953 }
ian@0 954
ian@0 955 module_init(acpi_processor_init);
ian@0 956 module_exit(acpi_processor_exit);
ian@0 957
ian@0 958 EXPORT_SYMBOL(acpi_processor_set_thermal_limit);
ian@0 959
ian@0 960 MODULE_ALIAS("processor");