ia64/linux-2.6.18-xen.hg

annotate drivers/acpi/processor_core.c @ 912:dd42cdb0ab89

[IA64] Build blktap2 driver by default in x86 builds.

add CONFIG_XEN_BLKDEV_TAP2=y to buildconfigs/linux-defconfig_xen_ia64.

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