| 838 | } |
| 839 | |
| 840 | static struct cf_level * |
| 841 | cpufreq_dup_set(struct cpufreq_softc *sc, struct cf_level *dup, |
| 842 | struct cf_setting *set) |
| 843 | { |
| 844 | struct cf_level_lst *list; |
| 845 | struct cf_level *fill, *itr; |
| 846 | struct cf_setting *fill_set, *itr_set; |
| 847 | int i; |
| 848 | |
| 849 | CF_MTX_ASSERT(&sc->lock); |
| 850 | |
| 851 | /* |
| 852 | * Create a new level, copy it from the old one, and update the |
| 853 | * total frequency and power by the percentage specified in the |
| 854 | * relative setting. |
| 855 | */ |
| 856 | fill = malloc(sizeof(*fill), M_TEMP, M_NOWAIT); |
| 857 | if (fill == NULL) |
| 858 | return (NULL); |
| 859 | *fill = *dup; |
| 860 | fill_set = &fill->total_set; |
| 861 | fill_set->freq = |
| 862 | ((uint64_t)fill_set->freq * set->freq) / 10000; |
| 863 | if (fill_set->power != CPUFREQ_VAL_UNKNOWN) { |
| 864 | fill_set->power = ((uint64_t)fill_set->power * set->freq) |
| 865 | / 10000; |
| 866 | } |
| 867 | if (set->lat != CPUFREQ_VAL_UNKNOWN) { |
| 868 | if (fill_set->lat != CPUFREQ_VAL_UNKNOWN) |
| 869 | fill_set->lat += set->lat; |
| 870 | else |
| 871 | fill_set->lat = set->lat; |
| 872 | } |
| 873 | CF_DEBUG("dup set considering derived setting %d\n", fill_set->freq); |
| 874 | |
| 875 | /* |
| 876 | * If we copied an old level that we already modified (say, at 100%), |
| 877 | * we need to remove that setting before adding this one. Since we |
| 878 | * process each setting array in order, we know any settings for this |
| 879 | * driver will be found at the end. |
| 880 | */ |
| 881 | for (i = fill->rel_count; i != 0; i--) { |
| 882 | if (fill->rel_set[i - 1].dev != set->dev) |
| 883 | break; |
| 884 | CF_DEBUG("removed last relative driver: %s\n", |
| 885 | device_get_nameunit(set->dev)); |
| 886 | fill->rel_count--; |
| 887 | } |
| 888 | |
| 889 | /* |
| 890 | * Insert the new level in sorted order. If it is a duplicate of an |
| 891 | * existing level (1) or has an absolute setting higher than the |
| 892 | * existing level (2), do not add it. We can do this since any such |
| 893 | * level is guaranteed use less power. For example (1), a level with |
| 894 | * one absolute setting of 800 Mhz uses less power than one composed |
| 895 | * of an absolute setting of 1600 Mhz and a relative setting at 50%. |
| 896 | * Also for example (2), a level of 800 Mhz/75% is preferable to |
| 897 | * 1600 Mhz/25% even though the latter has a lower total frequency. |
no test coverage detected