root/drivers/cpufreq/powernow-k7.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. check_fsb
  2. check_powernow
  3. invalidate_entry
  4. get_ranges
  5. change_FID
  6. change_VID
  7. powernow_target
  8. powernow_acpi_init
  9. powernow_acpi_init
  10. print_pst_entry
  11. powernow_decode_bios
  12. fixup_sgtc
  13. powernow_get
  14. acer_cpufreq_pst
  15. powernow_cpu_init
  16. powernow_cpu_exit
  17. powernow_init
  18. powernow_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  AMD K7 Powernow driver.
   4  *  (C) 2003 Dave Jones on behalf of SuSE Labs.
   5  *
   6  *  Based upon datasheets & sample CPUs kindly provided by AMD.
   7  *
   8  * Errata 5:
   9  *  CPU may fail to execute a FID/VID change in presence of interrupt.
  10  *  - We cli/sti on stepping A0 CPUs around the FID/VID transition.
  11  * Errata 15:
  12  *  CPU with half frequency multipliers may hang upon wakeup from disconnect.
  13  *  - We disable half multipliers if ACPI is used on A0 stepping CPUs.
  14  */
  15 
  16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  17 
  18 #include <linux/kernel.h>
  19 #include <linux/module.h>
  20 #include <linux/moduleparam.h>
  21 #include <linux/init.h>
  22 #include <linux/cpufreq.h>
  23 #include <linux/slab.h>
  24 #include <linux/string.h>
  25 #include <linux/dmi.h>
  26 #include <linux/timex.h>
  27 #include <linux/io.h>
  28 
  29 #include <asm/timer.h>          /* Needed for recalibrate_cpu_khz() */
  30 #include <asm/msr.h>
  31 #include <asm/cpu_device_id.h>
  32 
  33 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
  34 #include <linux/acpi.h>
  35 #include <acpi/processor.h>
  36 #endif
  37 
  38 #include "powernow-k7.h"
  39 
  40 struct psb_s {
  41         u8 signature[10];
  42         u8 tableversion;
  43         u8 flags;
  44         u16 settlingtime;
  45         u8 reserved1;
  46         u8 numpst;
  47 };
  48 
  49 struct pst_s {
  50         u32 cpuid;
  51         u8 fsbspeed;
  52         u8 maxfid;
  53         u8 startvid;
  54         u8 numpstates;
  55 };
  56 
  57 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
  58 union powernow_acpi_control_t {
  59         struct {
  60                 unsigned long fid:5,
  61                         vid:5,
  62                         sgtc:20,
  63                         res1:2;
  64         } bits;
  65         unsigned long val;
  66 };
  67 #endif
  68 
  69 /* divide by 1000 to get VCore voltage in V. */
  70 static const int mobile_vid_table[32] = {
  71     2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
  72     1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
  73     1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
  74     1075, 1050, 1025, 1000, 975, 950, 925, 0,
  75 };
  76 
  77 /* divide by 10 to get FID. */
  78 static const int fid_codes[32] = {
  79     110, 115, 120, 125, 50, 55, 60, 65,
  80     70, 75, 80, 85, 90, 95, 100, 105,
  81     30, 190, 40, 200, 130, 135, 140, 210,
  82     150, 225, 160, 165, 170, 180, -1, -1,
  83 };
  84 
  85 /* This parameter is used in order to force ACPI instead of legacy method for
  86  * configuration purpose.
  87  */
  88 
  89 static int acpi_force;
  90 
  91 static struct cpufreq_frequency_table *powernow_table;
  92 
  93 static unsigned int can_scale_bus;
  94 static unsigned int can_scale_vid;
  95 static unsigned int minimum_speed = -1;
  96 static unsigned int maximum_speed;
  97 static unsigned int number_scales;
  98 static unsigned int fsb;
  99 static unsigned int latency;
 100 static char have_a0;
 101 
 102 static int check_fsb(unsigned int fsbspeed)
 103 {
 104         int delta;
 105         unsigned int f = fsb / 1000;
 106 
 107         delta = (fsbspeed > f) ? fsbspeed - f : f - fsbspeed;
 108         return delta < 5;
 109 }
 110 
 111 static const struct x86_cpu_id powernow_k7_cpuids[] = {
 112         { X86_VENDOR_AMD, 6, },
 113         {}
 114 };
 115 MODULE_DEVICE_TABLE(x86cpu, powernow_k7_cpuids);
 116 
 117 static int check_powernow(void)
 118 {
 119         struct cpuinfo_x86 *c = &cpu_data(0);
 120         unsigned int maxei, eax, ebx, ecx, edx;
 121 
 122         if (!x86_match_cpu(powernow_k7_cpuids))
 123                 return 0;
 124 
 125         /* Get maximum capabilities */
 126         maxei = cpuid_eax(0x80000000);
 127         if (maxei < 0x80000007) {       /* Any powernow info ? */
 128 #ifdef MODULE
 129                 pr_info("No powernow capabilities detected\n");
 130 #endif
 131                 return 0;
 132         }
 133 
 134         if ((c->x86_model == 6) && (c->x86_stepping == 0)) {
 135                 pr_info("K7 660[A0] core detected, enabling errata workarounds\n");
 136                 have_a0 = 1;
 137         }
 138 
 139         cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
 140 
 141         /* Check we can actually do something before we say anything.*/
 142         if (!(edx & (1 << 1 | 1 << 2)))
 143                 return 0;
 144 
 145         pr_info("PowerNOW! Technology present. Can scale: ");
 146 
 147         if (edx & 1 << 1) {
 148                 pr_cont("frequency");
 149                 can_scale_bus = 1;
 150         }
 151 
 152         if ((edx & (1 << 1 | 1 << 2)) == 0x6)
 153                 pr_cont(" and ");
 154 
 155         if (edx & 1 << 2) {
 156                 pr_cont("voltage");
 157                 can_scale_vid = 1;
 158         }
 159 
 160         pr_cont("\n");
 161         return 1;
 162 }
 163 
 164 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
 165 static void invalidate_entry(unsigned int entry)
 166 {
 167         powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
 168 }
 169 #endif
 170 
 171 static int get_ranges(unsigned char *pst)
 172 {
 173         unsigned int j;
 174         unsigned int speed;
 175         u8 fid, vid;
 176 
 177         powernow_table = kzalloc((sizeof(*powernow_table) *
 178                                 (number_scales + 1)), GFP_KERNEL);
 179         if (!powernow_table)
 180                 return -ENOMEM;
 181 
 182         for (j = 0 ; j < number_scales; j++) {
 183                 fid = *pst++;
 184 
 185                 powernow_table[j].frequency = (fsb * fid_codes[fid]) / 10;
 186                 powernow_table[j].driver_data = fid; /* lower 8 bits */
 187 
 188                 speed = powernow_table[j].frequency;
 189 
 190                 if ((fid_codes[fid] % 10) == 5) {
 191 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
 192                         if (have_a0 == 1)
 193                                 invalidate_entry(j);
 194 #endif
 195                 }
 196 
 197                 if (speed < minimum_speed)
 198                         minimum_speed = speed;
 199                 if (speed > maximum_speed)
 200                         maximum_speed = speed;
 201 
 202                 vid = *pst++;
 203                 powernow_table[j].driver_data |= (vid << 8); /* upper 8 bits */
 204 
 205                 pr_debug("   FID: 0x%x (%d.%dx [%dMHz])  "
 206                          "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
 207                          fid_codes[fid] % 10, speed/1000, vid,
 208                          mobile_vid_table[vid]/1000,
 209                          mobile_vid_table[vid]%1000);
 210         }
 211         powernow_table[number_scales].frequency = CPUFREQ_TABLE_END;
 212         powernow_table[number_scales].driver_data = 0;
 213 
 214         return 0;
 215 }
 216 
 217 
 218 static void change_FID(int fid)
 219 {
 220         union msr_fidvidctl fidvidctl;
 221 
 222         rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
 223         if (fidvidctl.bits.FID != fid) {
 224                 fidvidctl.bits.SGTC = latency;
 225                 fidvidctl.bits.FID = fid;
 226                 fidvidctl.bits.VIDC = 0;
 227                 fidvidctl.bits.FIDC = 1;
 228                 wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
 229         }
 230 }
 231 
 232 
 233 static void change_VID(int vid)
 234 {
 235         union msr_fidvidctl fidvidctl;
 236 
 237         rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
 238         if (fidvidctl.bits.VID != vid) {
 239                 fidvidctl.bits.SGTC = latency;
 240                 fidvidctl.bits.VID = vid;
 241                 fidvidctl.bits.FIDC = 0;
 242                 fidvidctl.bits.VIDC = 1;
 243                 wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
 244         }
 245 }
 246 
 247 
 248 static int powernow_target(struct cpufreq_policy *policy, unsigned int index)
 249 {
 250         u8 fid, vid;
 251         struct cpufreq_freqs freqs;
 252         union msr_fidvidstatus fidvidstatus;
 253         int cfid;
 254 
 255         /* fid are the lower 8 bits of the index we stored into
 256          * the cpufreq frequency table in powernow_decode_bios,
 257          * vid are the upper 8 bits.
 258          */
 259 
 260         fid = powernow_table[index].driver_data & 0xFF;
 261         vid = (powernow_table[index].driver_data & 0xFF00) >> 8;
 262 
 263         rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
 264         cfid = fidvidstatus.bits.CFID;
 265         freqs.old = fsb * fid_codes[cfid] / 10;
 266 
 267         freqs.new = powernow_table[index].frequency;
 268 
 269         /* Now do the magic poking into the MSRs.  */
 270 
 271         if (have_a0 == 1)       /* A0 errata 5 */
 272                 local_irq_disable();
 273 
 274         if (freqs.old > freqs.new) {
 275                 /* Going down, so change FID first */
 276                 change_FID(fid);
 277                 change_VID(vid);
 278         } else {
 279                 /* Going up, so change VID first */
 280                 change_VID(vid);
 281                 change_FID(fid);
 282         }
 283 
 284 
 285         if (have_a0 == 1)
 286                 local_irq_enable();
 287 
 288         return 0;
 289 }
 290 
 291 
 292 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
 293 
 294 static struct acpi_processor_performance *acpi_processor_perf;
 295 
 296 static int powernow_acpi_init(void)
 297 {
 298         int i;
 299         int retval = 0;
 300         union powernow_acpi_control_t pc;
 301 
 302         if (acpi_processor_perf != NULL && powernow_table != NULL) {
 303                 retval = -EINVAL;
 304                 goto err0;
 305         }
 306 
 307         acpi_processor_perf = kzalloc(sizeof(*acpi_processor_perf), GFP_KERNEL);
 308         if (!acpi_processor_perf) {
 309                 retval = -ENOMEM;
 310                 goto err0;
 311         }
 312 
 313         if (!zalloc_cpumask_var(&acpi_processor_perf->shared_cpu_map,
 314                                                                 GFP_KERNEL)) {
 315                 retval = -ENOMEM;
 316                 goto err05;
 317         }
 318 
 319         if (acpi_processor_register_performance(acpi_processor_perf, 0)) {
 320                 retval = -EIO;
 321                 goto err1;
 322         }
 323 
 324         if (acpi_processor_perf->control_register.space_id !=
 325                         ACPI_ADR_SPACE_FIXED_HARDWARE) {
 326                 retval = -ENODEV;
 327                 goto err2;
 328         }
 329 
 330         if (acpi_processor_perf->status_register.space_id !=
 331                         ACPI_ADR_SPACE_FIXED_HARDWARE) {
 332                 retval = -ENODEV;
 333                 goto err2;
 334         }
 335 
 336         number_scales = acpi_processor_perf->state_count;
 337 
 338         if (number_scales < 2) {
 339                 retval = -ENODEV;
 340                 goto err2;
 341         }
 342 
 343         powernow_table = kzalloc((sizeof(*powernow_table) *
 344                                 (number_scales + 1)), GFP_KERNEL);
 345         if (!powernow_table) {
 346                 retval = -ENOMEM;
 347                 goto err2;
 348         }
 349 
 350         pc.val = (unsigned long) acpi_processor_perf->states[0].control;
 351         for (i = 0; i < number_scales; i++) {
 352                 u8 fid, vid;
 353                 struct acpi_processor_px *state =
 354                         &acpi_processor_perf->states[i];
 355                 unsigned int speed, speed_mhz;
 356 
 357                 pc.val = (unsigned long) state->control;
 358                 pr_debug("acpi:  P%d: %d MHz %d mW %d uS control %08x SGTC %d\n",
 359                          i,
 360                          (u32) state->core_frequency,
 361                          (u32) state->power,
 362                          (u32) state->transition_latency,
 363                          (u32) state->control,
 364                          pc.bits.sgtc);
 365 
 366                 vid = pc.bits.vid;
 367                 fid = pc.bits.fid;
 368 
 369                 powernow_table[i].frequency = fsb * fid_codes[fid] / 10;
 370                 powernow_table[i].driver_data = fid; /* lower 8 bits */
 371                 powernow_table[i].driver_data |= (vid << 8); /* upper 8 bits */
 372 
 373                 speed = powernow_table[i].frequency;
 374                 speed_mhz = speed / 1000;
 375 
 376                 /* processor_perflib will multiply the MHz value by 1000 to
 377                  * get a KHz value (e.g. 1266000). However, powernow-k7 works
 378                  * with true KHz values (e.g. 1266768). To ensure that all
 379                  * powernow frequencies are available, we must ensure that
 380                  * ACPI doesn't restrict them, so we round up the MHz value
 381                  * to ensure that perflib's computed KHz value is greater than
 382                  * or equal to powernow's KHz value.
 383                  */
 384                 if (speed % 1000 > 0)
 385                         speed_mhz++;
 386 
 387                 if ((fid_codes[fid] % 10) == 5) {
 388                         if (have_a0 == 1)
 389                                 invalidate_entry(i);
 390                 }
 391 
 392                 pr_debug("   FID: 0x%x (%d.%dx [%dMHz])  "
 393                          "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
 394                          fid_codes[fid] % 10, speed_mhz, vid,
 395                          mobile_vid_table[vid]/1000,
 396                          mobile_vid_table[vid]%1000);
 397 
 398                 if (state->core_frequency != speed_mhz) {
 399                         state->core_frequency = speed_mhz;
 400                         pr_debug("   Corrected ACPI frequency to %d\n",
 401                                 speed_mhz);
 402                 }
 403 
 404                 if (latency < pc.bits.sgtc)
 405                         latency = pc.bits.sgtc;
 406 
 407                 if (speed < minimum_speed)
 408                         minimum_speed = speed;
 409                 if (speed > maximum_speed)
 410                         maximum_speed = speed;
 411         }
 412 
 413         powernow_table[i].frequency = CPUFREQ_TABLE_END;
 414         powernow_table[i].driver_data = 0;
 415 
 416         /* notify BIOS that we exist */
 417         acpi_processor_notify_smm(THIS_MODULE);
 418 
 419         return 0;
 420 
 421 err2:
 422         acpi_processor_unregister_performance(0);
 423 err1:
 424         free_cpumask_var(acpi_processor_perf->shared_cpu_map);
 425 err05:
 426         kfree(acpi_processor_perf);
 427 err0:
 428         pr_warn("ACPI perflib can not be used on this platform\n");
 429         acpi_processor_perf = NULL;
 430         return retval;
 431 }
 432 #else
 433 static int powernow_acpi_init(void)
 434 {
 435         pr_info("no support for ACPI processor found - please recompile your kernel with ACPI processor\n");
 436         return -EINVAL;
 437 }
 438 #endif
 439 
 440 static void print_pst_entry(struct pst_s *pst, unsigned int j)
 441 {
 442         pr_debug("PST:%d (@%p)\n", j, pst);
 443         pr_debug(" cpuid: 0x%x  fsb: %d  maxFID: 0x%x  startvid: 0x%x\n",
 444                 pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid);
 445 }
 446 
 447 static int powernow_decode_bios(int maxfid, int startvid)
 448 {
 449         struct psb_s *psb;
 450         struct pst_s *pst;
 451         unsigned int i, j;
 452         unsigned char *p;
 453         unsigned int etuple;
 454         unsigned int ret;
 455 
 456         etuple = cpuid_eax(0x80000001);
 457 
 458         for (i = 0xC0000; i < 0xffff0 ; i += 16) {
 459 
 460                 p = phys_to_virt(i);
 461 
 462                 if (memcmp(p, "AMDK7PNOW!",  10) == 0) {
 463                         pr_debug("Found PSB header at %p\n", p);
 464                         psb = (struct psb_s *) p;
 465                         pr_debug("Table version: 0x%x\n", psb->tableversion);
 466                         if (psb->tableversion != 0x12) {
 467                                 pr_info("Sorry, only v1.2 tables supported right now\n");
 468                                 return -ENODEV;
 469                         }
 470 
 471                         pr_debug("Flags: 0x%x\n", psb->flags);
 472                         if ((psb->flags & 1) == 0)
 473                                 pr_debug("Mobile voltage regulator\n");
 474                         else
 475                                 pr_debug("Desktop voltage regulator\n");
 476 
 477                         latency = psb->settlingtime;
 478                         if (latency < 100) {
 479                                 pr_info("BIOS set settling time to %d microseconds. Should be at least 100. Correcting.\n",
 480                                         latency);
 481                                 latency = 100;
 482                         }
 483                         pr_debug("Settling Time: %d microseconds.\n",
 484                                         psb->settlingtime);
 485                         pr_debug("Has %d PST tables. (Only dumping ones "
 486                                         "relevant to this CPU).\n",
 487                                         psb->numpst);
 488 
 489                         p += sizeof(*psb);
 490 
 491                         pst = (struct pst_s *) p;
 492 
 493                         for (j = 0; j < psb->numpst; j++) {
 494                                 pst = (struct pst_s *) p;
 495                                 number_scales = pst->numpstates;
 496 
 497                                 if ((etuple == pst->cpuid) &&
 498                                     check_fsb(pst->fsbspeed) &&
 499                                     (maxfid == pst->maxfid) &&
 500                                     (startvid == pst->startvid)) {
 501                                         print_pst_entry(pst, j);
 502                                         p = (char *)pst + sizeof(*pst);
 503                                         ret = get_ranges(p);
 504                                         return ret;
 505                                 } else {
 506                                         unsigned int k;
 507                                         p = (char *)pst + sizeof(*pst);
 508                                         for (k = 0; k < number_scales; k++)
 509                                                 p += 2;
 510                                 }
 511                         }
 512                         pr_info("No PST tables match this cpuid (0x%x)\n",
 513                                 etuple);
 514                         pr_info("This is indicative of a broken BIOS\n");
 515 
 516                         return -EINVAL;
 517                 }
 518                 p++;
 519         }
 520 
 521         return -ENODEV;
 522 }
 523 
 524 
 525 /*
 526  * We use the fact that the bus frequency is somehow
 527  * a multiple of 100000/3 khz, then we compute sgtc according
 528  * to this multiple.
 529  * That way, we match more how AMD thinks all of that work.
 530  * We will then get the same kind of behaviour already tested under
 531  * the "well-known" other OS.
 532  */
 533 static int fixup_sgtc(void)
 534 {
 535         unsigned int sgtc;
 536         unsigned int m;
 537 
 538         m = fsb / 3333;
 539         if ((m % 10) >= 5)
 540                 m += 5;
 541 
 542         m /= 10;
 543 
 544         sgtc = 100 * m * latency;
 545         sgtc = sgtc / 3;
 546         if (sgtc > 0xfffff) {
 547                 pr_warn("SGTC too large %d\n", sgtc);
 548                 sgtc = 0xfffff;
 549         }
 550         return sgtc;
 551 }
 552 
 553 static unsigned int powernow_get(unsigned int cpu)
 554 {
 555         union msr_fidvidstatus fidvidstatus;
 556         unsigned int cfid;
 557 
 558         if (cpu)
 559                 return 0;
 560         rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
 561         cfid = fidvidstatus.bits.CFID;
 562 
 563         return fsb * fid_codes[cfid] / 10;
 564 }
 565 
 566 
 567 static int acer_cpufreq_pst(const struct dmi_system_id *d)
 568 {
 569         pr_warn("%s laptop with broken PST tables in BIOS detected\n",
 570                 d->ident);
 571         pr_warn("You need to downgrade to 3A21 (09/09/2002), or try a newer BIOS than 3A71 (01/20/2003)\n");
 572         pr_warn("cpufreq scaling has been disabled as a result of this\n");
 573         return 0;
 574 }
 575 
 576 /*
 577  * Some Athlon laptops have really fucked PST tables.
 578  * A BIOS update is all that can save them.
 579  * Mention this, and disable cpufreq.
 580  */
 581 static const struct dmi_system_id powernow_dmi_table[] = {
 582         {
 583                 .callback = acer_cpufreq_pst,
 584                 .ident = "Acer Aspire",
 585                 .matches = {
 586                         DMI_MATCH(DMI_SYS_VENDOR, "Insyde Software"),
 587                         DMI_MATCH(DMI_BIOS_VERSION, "3A71"),
 588                 },
 589         },
 590         { }
 591 };
 592 
 593 static int powernow_cpu_init(struct cpufreq_policy *policy)
 594 {
 595         union msr_fidvidstatus fidvidstatus;
 596         int result;
 597 
 598         if (policy->cpu != 0)
 599                 return -ENODEV;
 600 
 601         rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
 602 
 603         recalibrate_cpu_khz();
 604 
 605         fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID];
 606         if (!fsb) {
 607                 pr_warn("can not determine bus frequency\n");
 608                 return -EINVAL;
 609         }
 610         pr_debug("FSB: %3dMHz\n", fsb/1000);
 611 
 612         if (dmi_check_system(powernow_dmi_table) || acpi_force) {
 613                 pr_info("PSB/PST known to be broken - trying ACPI instead\n");
 614                 result = powernow_acpi_init();
 615         } else {
 616                 result = powernow_decode_bios(fidvidstatus.bits.MFID,
 617                                 fidvidstatus.bits.SVID);
 618                 if (result) {
 619                         pr_info("Trying ACPI perflib\n");
 620                         maximum_speed = 0;
 621                         minimum_speed = -1;
 622                         latency = 0;
 623                         result = powernow_acpi_init();
 624                         if (result) {
 625                                 pr_info("ACPI and legacy methods failed\n");
 626                         }
 627                 } else {
 628                         /* SGTC use the bus clock as timer */
 629                         latency = fixup_sgtc();
 630                         pr_info("SGTC: %d\n", latency);
 631                 }
 632         }
 633 
 634         if (result)
 635                 return result;
 636 
 637         pr_info("Minimum speed %d MHz - Maximum speed %d MHz\n",
 638                 minimum_speed/1000, maximum_speed/1000);
 639 
 640         policy->cpuinfo.transition_latency =
 641                 cpufreq_scale(2000000UL, fsb, latency);
 642         policy->freq_table = powernow_table;
 643 
 644         return 0;
 645 }
 646 
 647 static int powernow_cpu_exit(struct cpufreq_policy *policy)
 648 {
 649 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
 650         if (acpi_processor_perf) {
 651                 acpi_processor_unregister_performance(0);
 652                 free_cpumask_var(acpi_processor_perf->shared_cpu_map);
 653                 kfree(acpi_processor_perf);
 654         }
 655 #endif
 656 
 657         kfree(powernow_table);
 658         return 0;
 659 }
 660 
 661 static struct cpufreq_driver powernow_driver = {
 662         .verify         = cpufreq_generic_frequency_table_verify,
 663         .target_index   = powernow_target,
 664         .get            = powernow_get,
 665 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
 666         .bios_limit     = acpi_processor_get_bios_limit,
 667 #endif
 668         .init           = powernow_cpu_init,
 669         .exit           = powernow_cpu_exit,
 670         .name           = "powernow-k7",
 671         .attr           = cpufreq_generic_attr,
 672 };
 673 
 674 static int __init powernow_init(void)
 675 {
 676         if (check_powernow() == 0)
 677                 return -ENODEV;
 678         return cpufreq_register_driver(&powernow_driver);
 679 }
 680 
 681 
 682 static void __exit powernow_exit(void)
 683 {
 684         cpufreq_unregister_driver(&powernow_driver);
 685 }
 686 
 687 module_param(acpi_force,  int, 0444);
 688 MODULE_PARM_DESC(acpi_force, "Force ACPI to be used.");
 689 
 690 MODULE_AUTHOR("Dave Jones");
 691 MODULE_DESCRIPTION("Powernow driver for AMD K7 processors.");
 692 MODULE_LICENSE("GPL");
 693 
 694 late_initcall(powernow_init);
 695 module_exit(powernow_exit);
 696 

/* [<][>][^][v][top][bottom][index][help] */