diff options
Diffstat (limited to 'drivers/cpufreq/longhaul.c')
| -rw-r--r-- | drivers/cpufreq/longhaul.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index d00e5d1abd25..5c4369b5d834 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c | |||
| @@ -242,7 +242,7 @@ static void do_powersaver(int cx_address, unsigned int mults_index, | |||
| 242 | * Sets a new clock ratio. | 242 | * Sets a new clock ratio. |
| 243 | */ | 243 | */ |
| 244 | 244 | ||
| 245 | static void longhaul_setstate(struct cpufreq_policy *policy, | 245 | static int longhaul_setstate(struct cpufreq_policy *policy, |
| 246 | unsigned int table_index) | 246 | unsigned int table_index) |
| 247 | { | 247 | { |
| 248 | unsigned int mults_index; | 248 | unsigned int mults_index; |
| @@ -258,10 +258,12 @@ static void longhaul_setstate(struct cpufreq_policy *policy, | |||
| 258 | /* Safety precautions */ | 258 | /* Safety precautions */ |
| 259 | mult = mults[mults_index & 0x1f]; | 259 | mult = mults[mults_index & 0x1f]; |
| 260 | if (mult == -1) | 260 | if (mult == -1) |
| 261 | return; | 261 | return -EINVAL; |
| 262 | |||
| 262 | speed = calc_speed(mult); | 263 | speed = calc_speed(mult); |
| 263 | if ((speed > highest_speed) || (speed < lowest_speed)) | 264 | if ((speed > highest_speed) || (speed < lowest_speed)) |
| 264 | return; | 265 | return -EINVAL; |
| 266 | |||
| 265 | /* Voltage transition before frequency transition? */ | 267 | /* Voltage transition before frequency transition? */ |
| 266 | if (can_scale_voltage && longhaul_index < table_index) | 268 | if (can_scale_voltage && longhaul_index < table_index) |
| 267 | dir = 1; | 269 | dir = 1; |
| @@ -269,8 +271,6 @@ static void longhaul_setstate(struct cpufreq_policy *policy, | |||
| 269 | freqs.old = calc_speed(longhaul_get_cpu_mult()); | 271 | freqs.old = calc_speed(longhaul_get_cpu_mult()); |
| 270 | freqs.new = speed; | 272 | freqs.new = speed; |
| 271 | 273 | ||
| 272 | cpufreq_freq_transition_begin(policy, &freqs); | ||
| 273 | |||
| 274 | pr_debug("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n", | 274 | pr_debug("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n", |
| 275 | fsb, mult/10, mult%10, print_speed(speed/1000)); | 275 | fsb, mult/10, mult%10, print_speed(speed/1000)); |
| 276 | retry_loop: | 276 | retry_loop: |
| @@ -385,12 +385,14 @@ retry_loop: | |||
| 385 | goto retry_loop; | 385 | goto retry_loop; |
| 386 | } | 386 | } |
| 387 | } | 387 | } |
| 388 | /* Report true CPU frequency */ | ||
| 389 | cpufreq_freq_transition_end(policy, &freqs, 0); | ||
| 390 | 388 | ||
| 391 | if (!bm_timeout) | 389 | if (!bm_timeout) { |
| 392 | printk(KERN_INFO PFX "Warning: Timeout while waiting for " | 390 | printk(KERN_INFO PFX "Warning: Timeout while waiting for " |
| 393 | "idle PCI bus.\n"); | 391 | "idle PCI bus.\n"); |
| 392 | return -EBUSY; | ||
| 393 | } | ||
| 394 | |||
| 395 | return 0; | ||
| 394 | } | 396 | } |
| 395 | 397 | ||
| 396 | /* | 398 | /* |
| @@ -631,9 +633,10 @@ static int longhaul_target(struct cpufreq_policy *policy, | |||
| 631 | unsigned int i; | 633 | unsigned int i; |
| 632 | unsigned int dir = 0; | 634 | unsigned int dir = 0; |
| 633 | u8 vid, current_vid; | 635 | u8 vid, current_vid; |
| 636 | int retval = 0; | ||
| 634 | 637 | ||
| 635 | if (!can_scale_voltage) | 638 | if (!can_scale_voltage) |
| 636 | longhaul_setstate(policy, table_index); | 639 | retval = longhaul_setstate(policy, table_index); |
| 637 | else { | 640 | else { |
| 638 | /* On test system voltage transitions exceeding single | 641 | /* On test system voltage transitions exceeding single |
| 639 | * step up or down were turning motherboard off. Both | 642 | * step up or down were turning motherboard off. Both |
| @@ -648,7 +651,7 @@ static int longhaul_target(struct cpufreq_policy *policy, | |||
| 648 | while (i != table_index) { | 651 | while (i != table_index) { |
| 649 | vid = (longhaul_table[i].driver_data >> 8) & 0x1f; | 652 | vid = (longhaul_table[i].driver_data >> 8) & 0x1f; |
| 650 | if (vid != current_vid) { | 653 | if (vid != current_vid) { |
| 651 | longhaul_setstate(policy, i); | 654 | retval = longhaul_setstate(policy, i); |
| 652 | current_vid = vid; | 655 | current_vid = vid; |
| 653 | msleep(200); | 656 | msleep(200); |
| 654 | } | 657 | } |
| @@ -657,10 +660,11 @@ static int longhaul_target(struct cpufreq_policy *policy, | |||
| 657 | else | 660 | else |
| 658 | i--; | 661 | i--; |
| 659 | } | 662 | } |
| 660 | longhaul_setstate(policy, table_index); | 663 | retval = longhaul_setstate(policy, table_index); |
| 661 | } | 664 | } |
| 665 | |||
| 662 | longhaul_index = table_index; | 666 | longhaul_index = table_index; |
| 663 | return 0; | 667 | return retval; |
| 664 | } | 668 | } |
| 665 | 669 | ||
| 666 | 670 | ||
| @@ -968,7 +972,15 @@ static void __exit longhaul_exit(void) | |||
| 968 | 972 | ||
| 969 | for (i = 0; i < numscales; i++) { | 973 | for (i = 0; i < numscales; i++) { |
| 970 | if (mults[i] == maxmult) { | 974 | if (mults[i] == maxmult) { |
| 975 | struct cpufreq_freqs freqs; | ||
| 976 | |||
| 977 | freqs.old = policy->cur; | ||
| 978 | freqs.new = longhaul_table[i].frequency; | ||
| 979 | freqs.flags = 0; | ||
| 980 | |||
| 981 | cpufreq_freq_transition_begin(policy, &freqs); | ||
| 971 | longhaul_setstate(policy, i); | 982 | longhaul_setstate(policy, i); |
| 983 | cpufreq_freq_transition_end(policy, &freqs, 0); | ||
| 972 | break; | 984 | break; |
| 973 | } | 985 | } |
| 974 | } | 986 | } |
