Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cpufreq: Add and use cpufreq_for_each_{valid_,}entry_idx()

Pointer subtraction is slow and tedious. Therefore, replace all instances
where cpufreq_for_each_{valid_,}entry loops contained such substractions
with an iteration macro providing an index to the frequency_table entry.

Suggested-by: Al Viro <viro@ZenIV.linux.org.uk>
Link: http://lkml.kernel.org/r/20180120020237.GM13338@ZenIV.linux.org.uk
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Dominik Brodowski and committed by
Rafael J. Wysocki
ffd81dcf 70f6bf2a

+100 -63
+4
Documentation/cpu-freq/cpu-drivers.txt
··· 291 291 /* Do something with pos */ 292 292 pos->frequency = ... 293 293 } 294 + 295 + If you need to work with the position of pos within driver_freq_table, 296 + do not subtract the pointers, as it is quite costly. Instead, use the 297 + macros cpufreq_for_each_entry_idx() and cpufreq_for_each_valid_entry_idx().
+3 -4
drivers/cpufreq/exynos5440-cpufreq.c
··· 115 115 static int init_div_table(void) 116 116 { 117 117 struct cpufreq_frequency_table *pos, *freq_tbl = dvfs_info->freq_table; 118 - unsigned int tmp, clk_div, ema_div, freq, volt_id; 118 + unsigned int tmp, clk_div, ema_div, freq, volt_id, idx; 119 119 struct dev_pm_opp *opp; 120 120 121 - cpufreq_for_each_entry(pos, freq_tbl) { 121 + cpufreq_for_each_entry_idx(pos, freq_tbl, idx) { 122 122 opp = dev_pm_opp_find_freq_exact(dvfs_info->dev, 123 123 pos->frequency * 1000, true); 124 124 if (IS_ERR(opp)) { ··· 154 154 tmp = (clk_div | ema_div | (volt_id << P0_7_VDD_SHIFT) 155 155 | ((freq / FREQ_UNIT) << P0_7_FREQ_SHIFT)); 156 156 157 - __raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 * 158 - (pos - freq_tbl)); 157 + __raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 * idx); 159 158 dev_pm_opp_put(opp); 160 159 } 161 160
+4 -4
drivers/cpufreq/freq_table.c
··· 143 143 break; 144 144 } 145 145 146 - cpufreq_for_each_valid_entry(pos, table) { 146 + cpufreq_for_each_valid_entry_idx(pos, table, i) { 147 147 freq = pos->frequency; 148 148 149 - i = pos - table; 150 149 if ((freq < policy->min) || (freq > policy->max)) 151 150 continue; 152 151 if (freq == target_freq) { ··· 210 211 unsigned int freq) 211 212 { 212 213 struct cpufreq_frequency_table *pos, *table = policy->freq_table; 214 + int idx; 213 215 214 216 if (unlikely(!table)) { 215 217 pr_debug("%s: Unable to find frequency table\n", __func__); 216 218 return -ENOENT; 217 219 } 218 220 219 - cpufreq_for_each_valid_entry(pos, table) 221 + cpufreq_for_each_valid_entry_idx(pos, table, idx) 220 222 if (pos->frequency == freq) 221 - return pos - table; 223 + return idx; 222 224 223 225 return -EINVAL; 224 226 }
+2 -2
drivers/cpufreq/longhaul.c
··· 600 600 /* Calculate kHz for one voltage step */ 601 601 kHz_step = (highest_speed - min_vid_speed) / numvscales; 602 602 603 - cpufreq_for_each_entry(freq_pos, longhaul_table) { 603 + cpufreq_for_each_entry_idx(freq_pos, longhaul_table, j) { 604 604 speed = freq_pos->frequency; 605 605 if (speed > min_vid_speed) 606 606 pos = (speed - min_vid_speed) / kHz_step + minvid.pos; ··· 609 609 freq_pos->driver_data |= mV_vrm_table[pos] << 8; 610 610 vid = vrm_mV_table[mV_vrm_table[pos]]; 611 611 pr_info("f: %d kHz, index: %d, vid: %d mV\n", 612 - speed, (int)(freq_pos - longhaul_table), vid.mV); 612 + speed, j, vid.mV); 613 613 } 614 614 615 615 can_scale_voltage = 1;
+3 -3
drivers/cpufreq/pasemi-cpufreq.c
··· 139 139 struct cpufreq_frequency_table *pos; 140 140 const u32 *max_freqp; 141 141 u32 max_freq; 142 - int cur_astate; 142 + int cur_astate, idx; 143 143 struct resource res; 144 144 struct device_node *cpu, *dn; 145 145 int err = -ENODEV; ··· 198 198 pr_debug("initializing frequency table\n"); 199 199 200 200 /* initialize frequency table */ 201 - cpufreq_for_each_entry(pos, pas_freqs) { 201 + cpufreq_for_each_entry_idx(pos, pas_freqs, idx) { 202 202 pos->frequency = get_astate_freq(pos->driver_data) * 100000; 203 - pr_debug("%d: %d\n", (int)(pos - pas_freqs), pos->frequency); 203 + pr_debug("%d: %d\n", idx, pos->frequency); 204 204 } 205 205 206 206 cur_astate = get_cur_astate(policy->cpu);
+3 -2
drivers/sh/clk/core.c
··· 197 197 unsigned long rate) 198 198 { 199 199 struct cpufreq_frequency_table *pos; 200 + int idx; 200 201 201 - cpufreq_for_each_valid_entry(pos, freq_table) 202 + cpufreq_for_each_valid_entry_idx(pos, freq_table, idx) 202 203 if (pos->frequency == rate) 203 - return pos - freq_table; 204 + return idx; 204 205 205 206 return -ENOENT; 206 207 }
+2 -2
drivers/staging/irda/drivers/sh_sir.c
··· 226 226 clk_put(pclk); 227 227 228 228 /* IrDA can not set over peripheral_clk */ 229 - cpufreq_for_each_valid_entry(pos, freq_table) { 229 + cpufreq_for_each_valid_entry_idx(pos, freq_table, index) { 230 230 u32 freq = pos->frequency; 231 231 232 232 /* IrDA should not over peripheral_clk */ ··· 236 236 tmp = freq % SCLK_BASE; 237 237 if (tmp < min) { 238 238 min = tmp; 239 - index = pos - freq_table; 239 + break; 240 240 } 241 241 } 242 242
+79 -46
include/linux/cpufreq.h
··· 629 629 for (pos = table; pos->frequency != CPUFREQ_TABLE_END; pos++) 630 630 631 631 /* 632 + * cpufreq_for_each_entry_idx - iterate over a cpufreq_frequency_table 633 + * with index 634 + * @pos: the cpufreq_frequency_table * to use as a loop cursor. 635 + * @table: the cpufreq_frequency_table * to iterate over. 636 + * @idx: the table entry currently being processed 637 + */ 638 + 639 + #define cpufreq_for_each_entry_idx(pos, table, idx) \ 640 + for (pos = table, idx = 0; pos->frequency != CPUFREQ_TABLE_END; \ 641 + pos++, idx++) 642 + 643 + /* 632 644 * cpufreq_for_each_valid_entry - iterate over a cpufreq_frequency_table 633 645 * excluding CPUFREQ_ENTRY_INVALID frequencies. 634 646 * @pos: the cpufreq_frequency_table * to use as a loop cursor. ··· 652 640 if (pos->frequency == CPUFREQ_ENTRY_INVALID) \ 653 641 continue; \ 654 642 else 643 + 644 + /* 645 + * cpufreq_for_each_valid_entry_idx - iterate with index over a cpufreq 646 + * frequency_table excluding CPUFREQ_ENTRY_INVALID frequencies. 647 + * @pos: the cpufreq_frequency_table * to use as a loop cursor. 648 + * @table: the cpufreq_frequency_table * to iterate over. 649 + * @idx: the table entry currently being processed 650 + */ 651 + 652 + #define cpufreq_for_each_valid_entry_idx(pos, table, idx) \ 653 + cpufreq_for_each_entry_idx(pos, table, idx) \ 654 + if (pos->frequency == CPUFREQ_ENTRY_INVALID) \ 655 + continue; \ 656 + else 657 + 655 658 656 659 int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, 657 660 struct cpufreq_frequency_table *table); ··· 694 667 unsigned int target_freq) 695 668 { 696 669 struct cpufreq_frequency_table *table = policy->freq_table; 697 - struct cpufreq_frequency_table *pos, *best = table - 1; 670 + struct cpufreq_frequency_table *pos; 698 671 unsigned int freq; 672 + int idx, best = -1; 699 673 700 - cpufreq_for_each_valid_entry(pos, table) { 674 + cpufreq_for_each_valid_entry_idx(pos, table, idx) { 701 675 freq = pos->frequency; 702 676 703 677 if (freq >= target_freq) 704 - return pos - table; 678 + return idx; 705 679 706 - best = pos; 680 + best = idx; 707 681 } 708 682 709 - return best - table; 683 + return best; 710 684 } 711 685 712 686 /* Find lowest freq at or above target in a table in descending order */ ··· 715 687 unsigned int target_freq) 716 688 { 717 689 struct cpufreq_frequency_table *table = policy->freq_table; 718 - struct cpufreq_frequency_table *pos, *best = table - 1; 690 + struct cpufreq_frequency_table *pos; 719 691 unsigned int freq; 692 + int idx, best = -1; 720 693 721 - cpufreq_for_each_valid_entry(pos, table) { 694 + cpufreq_for_each_valid_entry_idx(pos, table, idx) { 722 695 freq = pos->frequency; 723 696 724 697 if (freq == target_freq) 725 - return pos - table; 698 + return idx; 726 699 727 700 if (freq > target_freq) { 728 - best = pos; 701 + best = idx; 729 702 continue; 730 703 } 731 704 732 705 /* No freq found above target_freq */ 733 - if (best == table - 1) 734 - return pos - table; 706 + if (best == -1) 707 + return idx; 735 708 736 - return best - table; 709 + return best; 737 710 } 738 711 739 - return best - table; 712 + return best; 740 713 } 741 714 742 715 /* Works only on sorted freq-tables */ ··· 757 728 unsigned int target_freq) 758 729 { 759 730 struct cpufreq_frequency_table *table = policy->freq_table; 760 - struct cpufreq_frequency_table *pos, *best = table - 1; 731 + struct cpufreq_frequency_table *pos; 761 732 unsigned int freq; 733 + int idx, best = -1; 762 734 763 - cpufreq_for_each_valid_entry(pos, table) { 735 + cpufreq_for_each_valid_entry_idx(pos, table, idx) { 764 736 freq = pos->frequency; 765 737 766 738 if (freq == target_freq) 767 - return pos - table; 739 + return idx; 768 740 769 741 if (freq < target_freq) { 770 - best = pos; 742 + best = idx; 771 743 continue; 772 744 } 773 745 774 746 /* No freq found below target_freq */ 775 - if (best == table - 1) 776 - return pos - table; 747 + if (best == -1) 748 + return idx; 777 749 778 - return best - table; 750 + return best; 779 751 } 780 752 781 - return best - table; 753 + return best; 782 754 } 783 755 784 756 /* Find highest freq at or below target in a table in descending order */ ··· 787 757 unsigned int target_freq) 788 758 { 789 759 struct cpufreq_frequency_table *table = policy->freq_table; 790 - struct cpufreq_frequency_table *pos, *best = table - 1; 760 + struct cpufreq_frequency_table *pos; 791 761 unsigned int freq; 762 + int idx, best = -1; 792 763 793 - cpufreq_for_each_valid_entry(pos, table) { 764 + cpufreq_for_each_valid_entry_idx(pos, table, idx) { 794 765 freq = pos->frequency; 795 766 796 767 if (freq <= target_freq) 797 - return pos - table; 768 + return idx; 798 769 799 - best = pos; 770 + best = idx; 800 771 } 801 772 802 - return best - table; 773 + return best; 803 774 } 804 775 805 776 /* Works only on sorted freq-tables */ ··· 820 789 unsigned int target_freq) 821 790 { 822 791 struct cpufreq_frequency_table *table = policy->freq_table; 823 - struct cpufreq_frequency_table *pos, *best = table - 1; 792 + struct cpufreq_frequency_table *pos; 824 793 unsigned int freq; 794 + int idx, best = -1; 825 795 826 - cpufreq_for_each_valid_entry(pos, table) { 796 + cpufreq_for_each_valid_entry_idx(pos, table, idx) { 827 797 freq = pos->frequency; 828 798 829 799 if (freq == target_freq) 830 - return pos - table; 800 + return idx; 831 801 832 802 if (freq < target_freq) { 833 - best = pos; 803 + best = idx; 834 804 continue; 835 805 } 836 806 837 807 /* No freq found below target_freq */ 838 - if (best == table - 1) 839 - return pos - table; 808 + if (best == -1) 809 + return idx; 840 810 841 811 /* Choose the closest freq */ 842 - if (target_freq - best->frequency > freq - target_freq) 843 - return pos - table; 812 + if (target_freq - table[best].frequency > freq - target_freq) 813 + return idx; 844 814 845 - return best - table; 815 + return best; 846 816 } 847 817 848 - return best - table; 818 + return best; 849 819 } 850 820 851 821 /* Find closest freq to target in a table in descending order */ ··· 854 822 unsigned int target_freq) 855 823 { 856 824 struct cpufreq_frequency_table *table = policy->freq_table; 857 - struct cpufreq_frequency_table *pos, *best = table - 1; 825 + struct cpufreq_frequency_table *pos; 858 826 unsigned int freq; 827 + int idx, best = -1; 859 828 860 - cpufreq_for_each_valid_entry(pos, table) { 829 + cpufreq_for_each_valid_entry_idx(pos, table, idx) { 861 830 freq = pos->frequency; 862 831 863 832 if (freq == target_freq) 864 - return pos - table; 833 + return idx; 865 834 866 835 if (freq > target_freq) { 867 - best = pos; 836 + best = idx; 868 837 continue; 869 838 } 870 839 871 840 /* No freq found above target_freq */ 872 - if (best == table - 1) 873 - return pos - table; 841 + if (best == -1) 842 + return idx; 874 843 875 844 /* Choose the closest freq */ 876 - if (best->frequency - target_freq > target_freq - freq) 877 - return pos - table; 845 + if (table[best].frequency - target_freq > target_freq - freq) 846 + return idx; 878 847 879 - return best - table; 848 + return best; 880 849 } 881 850 882 - return best - table; 851 + return best; 883 852 } 884 853 885 854 /* Works only on sorted freq-tables */