aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/cpu/cpufreq/longhaul.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/cpu/cpufreq/longhaul.c')
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c209
1 files changed, 138 insertions, 71 deletions
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index a3df9c039bd4..8eca59d4c8f4 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -29,6 +29,7 @@
29#include <linux/pci.h> 29#include <linux/pci.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/string.h> 31#include <linux/string.h>
32#include <linux/delay.h>
32 33
33#include <asm/msr.h> 34#include <asm/msr.h>
34#include <asm/timex.h> 35#include <asm/timex.h>
@@ -55,7 +56,6 @@
55/* Flags */ 56/* Flags */
56#define USE_ACPI_C3 (1 << 1) 57#define USE_ACPI_C3 (1 << 1)
57#define USE_NORTHBRIDGE (1 << 2) 58#define USE_NORTHBRIDGE (1 << 2)
58#define USE_VT8235 (1 << 3)
59 59
60static int cpu_model; 60static int cpu_model;
61static unsigned int numscales=16; 61static unsigned int numscales=16;
@@ -63,19 +63,15 @@ static unsigned int fsb;
63 63
64static const struct mV_pos *vrm_mV_table; 64static const struct mV_pos *vrm_mV_table;
65static const unsigned char *mV_vrm_table; 65static const unsigned char *mV_vrm_table;
66struct f_msr {
67 u8 vrm;
68 u8 pos;
69};
70static struct f_msr f_msr_table[32];
71 66
72static unsigned int highest_speed, lowest_speed; /* kHz */ 67static unsigned int highest_speed, lowest_speed; /* kHz */
73static unsigned int minmult, maxmult; 68static unsigned int minmult, maxmult;
74static int can_scale_voltage; 69static int can_scale_voltage;
75static struct acpi_processor *pr = NULL; 70static struct acpi_processor *pr = NULL;
76static struct acpi_processor_cx *cx = NULL; 71static struct acpi_processor_cx *cx = NULL;
72static u32 acpi_regs_addr;
77static u8 longhaul_flags; 73static u8 longhaul_flags;
78static u8 longhaul_pos; 74static unsigned int longhaul_index;
79 75
80/* Module parameters */ 76/* Module parameters */
81static int scale_voltage; 77static int scale_voltage;
@@ -144,7 +140,7 @@ static void do_longhaul1(unsigned int clock_ratio_index)
144 rdmsrl(MSR_VIA_BCR2, bcr2.val); 140 rdmsrl(MSR_VIA_BCR2, bcr2.val);
145 /* Enable software clock multiplier */ 141 /* Enable software clock multiplier */
146 bcr2.bits.ESOFTBF = 1; 142 bcr2.bits.ESOFTBF = 1;
147 bcr2.bits.CLOCKMUL = clock_ratio_index; 143 bcr2.bits.CLOCKMUL = clock_ratio_index & 0xff;
148 144
149 /* Sync to timer tick */ 145 /* Sync to timer tick */
150 safe_halt(); 146 safe_halt();
@@ -163,14 +159,12 @@ static void do_longhaul1(unsigned int clock_ratio_index)
163 159
164/* For processor with Longhaul MSR */ 160/* For processor with Longhaul MSR */
165 161
166static void do_powersaver(int cx_address, unsigned int clock_ratio_index) 162static void do_powersaver(int cx_address, unsigned int clock_ratio_index,
163 unsigned int dir)
167{ 164{
168 union msr_longhaul longhaul; 165 union msr_longhaul longhaul;
169 u8 dest_pos;
170 u32 t; 166 u32 t;
171 167
172 dest_pos = f_msr_table[clock_ratio_index].pos;
173
174 rdmsrl(MSR_VIA_LONGHAUL, longhaul.val); 168 rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
175 /* Setup new frequency */ 169 /* Setup new frequency */
176 longhaul.bits.RevisionKey = longhaul.bits.RevisionID; 170 longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
@@ -178,11 +172,11 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
178 longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; 172 longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
179 /* Setup new voltage */ 173 /* Setup new voltage */
180 if (can_scale_voltage) 174 if (can_scale_voltage)
181 longhaul.bits.SoftVID = f_msr_table[clock_ratio_index].vrm; 175 longhaul.bits.SoftVID = (clock_ratio_index >> 8) & 0x1f;
182 /* Sync to timer tick */ 176 /* Sync to timer tick */
183 safe_halt(); 177 safe_halt();
184 /* Raise voltage if necessary */ 178 /* Raise voltage if necessary */
185 if (can_scale_voltage && longhaul_pos < dest_pos) { 179 if (can_scale_voltage && dir) {
186 longhaul.bits.EnableSoftVID = 1; 180 longhaul.bits.EnableSoftVID = 1;
187 wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); 181 wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
188 /* Change voltage */ 182 /* Change voltage */
@@ -199,7 +193,6 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
199 } 193 }
200 longhaul.bits.EnableSoftVID = 0; 194 longhaul.bits.EnableSoftVID = 0;
201 wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); 195 wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
202 longhaul_pos = dest_pos;
203 } 196 }
204 197
205 /* Change frequency on next halt or sleep */ 198 /* Change frequency on next halt or sleep */
@@ -220,7 +213,7 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
220 wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); 213 wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
221 214
222 /* Reduce voltage if necessary */ 215 /* Reduce voltage if necessary */
223 if (can_scale_voltage && longhaul_pos > dest_pos) { 216 if (can_scale_voltage && !dir) {
224 longhaul.bits.EnableSoftVID = 1; 217 longhaul.bits.EnableSoftVID = 1;
225 wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); 218 wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
226 /* Change voltage */ 219 /* Change voltage */
@@ -237,7 +230,6 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
237 } 230 }
238 longhaul.bits.EnableSoftVID = 0; 231 longhaul.bits.EnableSoftVID = 0;
239 wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); 232 wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
240 longhaul_pos = dest_pos;
241 } 233 }
242} 234}
243 235
@@ -248,25 +240,28 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
248 * Sets a new clock ratio. 240 * Sets a new clock ratio.
249 */ 241 */
250 242
251static void longhaul_setstate(unsigned int clock_ratio_index) 243static void longhaul_setstate(unsigned int table_index)
252{ 244{
245 unsigned int clock_ratio_index;
253 int speed, mult; 246 int speed, mult;
254 struct cpufreq_freqs freqs; 247 struct cpufreq_freqs freqs;
255 static unsigned int old_ratio=-1;
256 unsigned long flags; 248 unsigned long flags;
257 unsigned int pic1_mask, pic2_mask; 249 unsigned int pic1_mask, pic2_mask;
250 u16 bm_status = 0;
251 u32 bm_timeout = 1000;
252 unsigned int dir = 0;
258 253
259 if (old_ratio == clock_ratio_index) 254 clock_ratio_index = longhaul_table[table_index].index;
260 return; 255 /* Safety precautions */
261 old_ratio = clock_ratio_index; 256 mult = clock_ratio[clock_ratio_index & 0x1f];
262
263 mult = clock_ratio[clock_ratio_index];
264 if (mult == -1) 257 if (mult == -1)
265 return; 258 return;
266
267 speed = calc_speed(mult); 259 speed = calc_speed(mult);
268 if ((speed > highest_speed) || (speed < lowest_speed)) 260 if ((speed > highest_speed) || (speed < lowest_speed))
269 return; 261 return;
262 /* Voltage transition before frequency transition? */
263 if (can_scale_voltage && longhaul_index < table_index)
264 dir = 1;
270 265
271 freqs.old = calc_speed(longhaul_get_cpu_mult()); 266 freqs.old = calc_speed(longhaul_get_cpu_mult());
272 freqs.new = speed; 267 freqs.new = speed;
@@ -285,11 +280,24 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
285 outb(0xFF,0xA1); /* Overkill */ 280 outb(0xFF,0xA1); /* Overkill */
286 outb(0xFE,0x21); /* TMR0 only */ 281 outb(0xFE,0x21); /* TMR0 only */
287 282
283 /* Wait while PCI bus is busy. */
284 if (acpi_regs_addr && (longhaul_flags & USE_NORTHBRIDGE
285 || ((pr != NULL) && pr->flags.bm_control))) {
286 bm_status = inw(acpi_regs_addr);
287 bm_status &= 1 << 4;
288 while (bm_status && bm_timeout) {
289 outw(1 << 4, acpi_regs_addr);
290 bm_timeout--;
291 bm_status = inw(acpi_regs_addr);
292 bm_status &= 1 << 4;
293 }
294 }
295
288 if (longhaul_flags & USE_NORTHBRIDGE) { 296 if (longhaul_flags & USE_NORTHBRIDGE) {
289 /* Disable AGP and PCI arbiters */ 297 /* Disable AGP and PCI arbiters */
290 outb(3, 0x22); 298 outb(3, 0x22);
291 } else if ((pr != NULL) && pr->flags.bm_control) { 299 } else if ((pr != NULL) && pr->flags.bm_control) {
292 /* Disable bus master arbitration */ 300 /* Disable bus master arbitration */
293 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); 301 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
294 } 302 }
295 switch (longhaul_version) { 303 switch (longhaul_version) {
@@ -314,9 +322,9 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
314 if (longhaul_flags & USE_ACPI_C3) { 322 if (longhaul_flags & USE_ACPI_C3) {
315 /* Don't allow wakeup */ 323 /* Don't allow wakeup */
316 acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); 324 acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
317 do_powersaver(cx->address, clock_ratio_index); 325 do_powersaver(cx->address, clock_ratio_index, dir);
318 } else { 326 } else {
319 do_powersaver(0, clock_ratio_index); 327 do_powersaver(0, clock_ratio_index, dir);
320 } 328 }
321 break; 329 break;
322 } 330 }
@@ -336,6 +344,9 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
336 344
337 freqs.new = calc_speed(longhaul_get_cpu_mult()); 345 freqs.new = calc_speed(longhaul_get_cpu_mult());
338 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 346 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
347
348 if (!bm_timeout)
349 printk(KERN_INFO PFX "Warning: Timeout while waiting for idle PCI bus.\n");
339} 350}
340 351
341/* 352/*
@@ -369,7 +380,8 @@ static int guess_fsb(int mult)
369 380
370static int __init longhaul_get_ranges(void) 381static int __init longhaul_get_ranges(void)
371{ 382{
372 unsigned int j, k = 0; 383 unsigned int i, j, k = 0;
384 unsigned int ratio;
373 int mult; 385 int mult;
374 386
375 /* Get current frequency */ 387 /* Get current frequency */
@@ -423,8 +435,7 @@ static int __init longhaul_get_ranges(void)
423 if(!longhaul_table) 435 if(!longhaul_table)
424 return -ENOMEM; 436 return -ENOMEM;
425 437
426 for (j=0; j < numscales; j++) { 438 for (j = 0; j < numscales; j++) {
427 unsigned int ratio;
428 ratio = clock_ratio[j]; 439 ratio = clock_ratio[j];
429 if (ratio == -1) 440 if (ratio == -1)
430 continue; 441 continue;
@@ -434,13 +445,41 @@ static int __init longhaul_get_ranges(void)
434 longhaul_table[k].index = j; 445 longhaul_table[k].index = j;
435 k++; 446 k++;
436 } 447 }
448 if (k <= 1) {
449 kfree(longhaul_table);
450 return -ENODEV;
451 }
452 /* Sort */
453 for (j = 0; j < k - 1; j++) {
454 unsigned int min_f, min_i;
455 min_f = longhaul_table[j].frequency;
456 min_i = j;
457 for (i = j + 1; i < k; i++) {
458 if (longhaul_table[i].frequency < min_f) {
459 min_f = longhaul_table[i].frequency;
460 min_i = i;
461 }
462 }
463 if (min_i != j) {
464 unsigned int temp;
465 temp = longhaul_table[j].frequency;
466 longhaul_table[j].frequency = longhaul_table[min_i].frequency;
467 longhaul_table[min_i].frequency = temp;
468 temp = longhaul_table[j].index;
469 longhaul_table[j].index = longhaul_table[min_i].index;
470 longhaul_table[min_i].index = temp;
471 }
472 }
437 473
438 longhaul_table[k].frequency = CPUFREQ_TABLE_END; 474 longhaul_table[k].frequency = CPUFREQ_TABLE_END;
439 if (!k) {
440 kfree (longhaul_table);
441 return -EINVAL;
442 }
443 475
476 /* Find index we are running on */
477 for (j = 0; j < k; j++) {
478 if (clock_ratio[longhaul_table[j].index & 0x1f] == mult) {
479 longhaul_index = j;
480 break;
481 }
482 }
444 return 0; 483 return 0;
445} 484}
446 485
@@ -448,7 +487,7 @@ static int __init longhaul_get_ranges(void)
448static void __init longhaul_setup_voltagescaling(void) 487static void __init longhaul_setup_voltagescaling(void)
449{ 488{
450 union msr_longhaul longhaul; 489 union msr_longhaul longhaul;
451 struct mV_pos minvid, maxvid; 490 struct mV_pos minvid, maxvid, vid;
452 unsigned int j, speed, pos, kHz_step, numvscales; 491 unsigned int j, speed, pos, kHz_step, numvscales;
453 int min_vid_speed; 492 int min_vid_speed;
454 493
@@ -459,11 +498,11 @@ static void __init longhaul_setup_voltagescaling(void)
459 } 498 }
460 499
461 if (!longhaul.bits.VRMRev) { 500 if (!longhaul.bits.VRMRev) {
462 printk (KERN_INFO PFX "VRM 8.5\n"); 501 printk(KERN_INFO PFX "VRM 8.5\n");
463 vrm_mV_table = &vrm85_mV[0]; 502 vrm_mV_table = &vrm85_mV[0];
464 mV_vrm_table = &mV_vrm85[0]; 503 mV_vrm_table = &mV_vrm85[0];
465 } else { 504 } else {
466 printk (KERN_INFO PFX "Mobile VRM\n"); 505 printk(KERN_INFO PFX "Mobile VRM\n");
467 if (cpu_model < CPU_NEHEMIAH) 506 if (cpu_model < CPU_NEHEMIAH)
468 return; 507 return;
469 vrm_mV_table = &mobilevrm_mV[0]; 508 vrm_mV_table = &mobilevrm_mV[0];
@@ -523,7 +562,6 @@ static void __init longhaul_setup_voltagescaling(void)
523 /* Calculate kHz for one voltage step */ 562 /* Calculate kHz for one voltage step */
524 kHz_step = (highest_speed - min_vid_speed) / numvscales; 563 kHz_step = (highest_speed - min_vid_speed) / numvscales;
525 564
526
527 j = 0; 565 j = 0;
528 while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) { 566 while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) {
529 speed = longhaul_table[j].frequency; 567 speed = longhaul_table[j].frequency;
@@ -531,15 +569,14 @@ static void __init longhaul_setup_voltagescaling(void)
531 pos = (speed - min_vid_speed) / kHz_step + minvid.pos; 569 pos = (speed - min_vid_speed) / kHz_step + minvid.pos;
532 else 570 else
533 pos = minvid.pos; 571 pos = minvid.pos;
534 f_msr_table[longhaul_table[j].index].vrm = mV_vrm_table[pos]; 572 longhaul_table[j].index |= mV_vrm_table[pos] << 8;
535 f_msr_table[longhaul_table[j].index].pos = pos; 573 vid = vrm_mV_table[mV_vrm_table[pos]];
574 printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n", speed, j, vid.mV);
536 j++; 575 j++;
537 } 576 }
538 577
539 longhaul_pos = maxvid.pos;
540 can_scale_voltage = 1; 578 can_scale_voltage = 1;
541 printk(KERN_INFO PFX "Voltage scaling enabled. " 579 printk(KERN_INFO PFX "Voltage scaling enabled.\n");
542 "Use of \"conservative\" governor is highly recommended.\n");
543} 580}
544 581
545 582
@@ -553,15 +590,44 @@ static int longhaul_target(struct cpufreq_policy *policy,
553 unsigned int target_freq, unsigned int relation) 590 unsigned int target_freq, unsigned int relation)
554{ 591{
555 unsigned int table_index = 0; 592 unsigned int table_index = 0;
556 unsigned int new_clock_ratio = 0; 593 unsigned int i;
594 unsigned int dir = 0;
595 u8 vid, current_vid;
557 596
558 if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, relation, &table_index)) 597 if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, relation, &table_index))
559 return -EINVAL; 598 return -EINVAL;
560 599
561 new_clock_ratio = longhaul_table[table_index].index & 0xFF; 600 /* Don't set same frequency again */
562 601 if (longhaul_index == table_index)
563 longhaul_setstate(new_clock_ratio); 602 return 0;
564 603
604 if (!can_scale_voltage)
605 longhaul_setstate(table_index);
606 else {
607 /* On test system voltage transitions exceeding single
608 * step up or down were turning motherboard off. Both
609 * "ondemand" and "userspace" are unsafe. C7 is doing
610 * this in hardware, C3 is old and we need to do this
611 * in software. */
612 i = longhaul_index;
613 current_vid = (longhaul_table[longhaul_index].index >> 8) & 0x1f;
614 if (table_index > longhaul_index)
615 dir = 1;
616 while (i != table_index) {
617 vid = (longhaul_table[i].index >> 8) & 0x1f;
618 if (vid != current_vid) {
619 longhaul_setstate(i);
620 current_vid = vid;
621 msleep(200);
622 }
623 if (dir)
624 i++;
625 else
626 i--;
627 }
628 longhaul_setstate(table_index);
629 }
630 longhaul_index = table_index;
565 return 0; 631 return 0;
566} 632}
567 633
@@ -590,11 +656,10 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
590static int enable_arbiter_disable(void) 656static int enable_arbiter_disable(void)
591{ 657{
592 struct pci_dev *dev; 658 struct pci_dev *dev;
593 int status; 659 int status = 1;
594 int reg; 660 int reg;
595 u8 pci_cmd; 661 u8 pci_cmd;
596 662
597 status = 1;
598 /* Find PLE133 host bridge */ 663 /* Find PLE133 host bridge */
599 reg = 0x78; 664 reg = 0x78;
600 dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, 665 dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0,
@@ -627,13 +692,17 @@ static int enable_arbiter_disable(void)
627 return 0; 692 return 0;
628} 693}
629 694
630static int longhaul_setup_vt8235(void) 695static int longhaul_setup_southbridge(void)
631{ 696{
632 struct pci_dev *dev; 697 struct pci_dev *dev;
633 u8 pci_cmd; 698 u8 pci_cmd;
634 699
635 /* Find VT8235 southbridge */ 700 /* Find VT8235 southbridge */
636 dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL); 701 dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL);
702 if (dev == NULL)
703 /* Find VT8237 southbridge */
704 dev = pci_get_device(PCI_VENDOR_ID_VIA,
705 PCI_DEVICE_ID_VIA_8237, NULL);
637 if (dev != NULL) { 706 if (dev != NULL) {
638 /* Set transition time to max */ 707 /* Set transition time to max */
639 pci_read_config_byte(dev, 0xec, &pci_cmd); 708 pci_read_config_byte(dev, 0xec, &pci_cmd);
@@ -645,6 +714,14 @@ static int longhaul_setup_vt8235(void)
645 pci_read_config_byte(dev, 0xe5, &pci_cmd); 714 pci_read_config_byte(dev, 0xe5, &pci_cmd);
646 pci_cmd |= 1 << 7; 715 pci_cmd |= 1 << 7;
647 pci_write_config_byte(dev, 0xe5, pci_cmd); 716 pci_write_config_byte(dev, 0xe5, pci_cmd);
717 /* Get address of ACPI registers block*/
718 pci_read_config_byte(dev, 0x81, &pci_cmd);
719 if (pci_cmd & 1 << 7) {
720 pci_read_config_dword(dev, 0x88, &acpi_regs_addr);
721 acpi_regs_addr &= 0xff00;
722 printk(KERN_INFO PFX "ACPI I/O at 0x%x\n", acpi_regs_addr);
723 }
724
648 pci_dev_put(dev); 725 pci_dev_put(dev);
649 return 1; 726 return 1;
650 } 727 }
@@ -657,7 +734,6 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
657 char *cpuname=NULL; 734 char *cpuname=NULL;
658 int ret; 735 int ret;
659 u32 lo, hi; 736 u32 lo, hi;
660 int vt8235_present;
661 737
662 /* Check what we have on this motherboard */ 738 /* Check what we have on this motherboard */
663 switch (c->x86_model) { 739 switch (c->x86_model) {
@@ -755,7 +831,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
755 }; 831 };
756 832
757 /* Doesn't hurt */ 833 /* Doesn't hurt */
758 vt8235_present = longhaul_setup_vt8235(); 834 longhaul_setup_southbridge();
759 835
760 /* Find ACPI data for processor */ 836 /* Find ACPI data for processor */
761 acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, 837 acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
@@ -765,35 +841,26 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
765 /* Check ACPI support for C3 state */ 841 /* Check ACPI support for C3 state */
766 if (pr != NULL && longhaul_version == TYPE_POWERSAVER) { 842 if (pr != NULL && longhaul_version == TYPE_POWERSAVER) {
767 cx = &pr->power.states[ACPI_STATE_C3]; 843 cx = &pr->power.states[ACPI_STATE_C3];
768 if (cx->address > 0 && cx->latency <= 1000) { 844 if (cx->address > 0 && cx->latency <= 1000)
769 longhaul_flags |= USE_ACPI_C3; 845 longhaul_flags |= USE_ACPI_C3;
770 goto print_support_type;
771 }
772 } 846 }
773 /* Check if northbridge is friendly */ 847 /* Check if northbridge is friendly */
774 if (enable_arbiter_disable()) { 848 if (enable_arbiter_disable())
775 longhaul_flags |= USE_NORTHBRIDGE; 849 longhaul_flags |= USE_NORTHBRIDGE;
776 goto print_support_type; 850
777 }
778 /* Use VT8235 southbridge if present */
779 if (longhaul_version == TYPE_POWERSAVER && vt8235_present) {
780 longhaul_flags |= USE_VT8235;
781 goto print_support_type;
782 }
783 /* Check ACPI support for bus master arbiter disable */ 851 /* Check ACPI support for bus master arbiter disable */
784 if ((pr == NULL) || !(pr->flags.bm_control)) { 852 if (!(longhaul_flags & USE_ACPI_C3
853 || longhaul_flags & USE_NORTHBRIDGE)
854 && ((pr == NULL) || !(pr->flags.bm_control))) {
785 printk(KERN_ERR PFX 855 printk(KERN_ERR PFX
786 "No ACPI support. Unsupported northbridge.\n"); 856 "No ACPI support. Unsupported northbridge.\n");
787 return -ENODEV; 857 return -ENODEV;
788 } 858 }
789 859
790print_support_type:
791 if (longhaul_flags & USE_NORTHBRIDGE) 860 if (longhaul_flags & USE_NORTHBRIDGE)
792 printk (KERN_INFO PFX "Using northbridge support.\n"); 861 printk(KERN_INFO PFX "Using northbridge support.\n");
793 else if (longhaul_flags & USE_VT8235) 862 if (longhaul_flags & USE_ACPI_C3)
794 printk (KERN_INFO PFX "Using VT8235 support.\n"); 863 printk(KERN_INFO PFX "Using ACPI support.\n");
795 else
796 printk (KERN_INFO PFX "Using ACPI support.\n");
797 864
798 ret = longhaul_get_ranges(); 865 ret = longhaul_get_ranges();
799 if (ret != 0) 866 if (ret != 0)