* Create levels for an array of absolute settings and insert them in * sorted order in the specified list. */
| 728 | * sorted order in the specified list. |
| 729 | */ |
| 730 | static int |
| 731 | cpufreq_insert_abs(struct cpufreq_softc *sc, struct cf_setting *sets, |
| 732 | int count) |
| 733 | { |
| 734 | struct cf_level_lst *list; |
| 735 | struct cf_level *level, *search; |
| 736 | int i, inserted; |
| 737 | |
| 738 | CF_MTX_ASSERT(&sc->lock); |
| 739 | |
| 740 | list = &sc->all_levels; |
| 741 | for (i = 0; i < count; i++) { |
| 742 | level = malloc(sizeof(*level), M_TEMP, M_NOWAIT | M_ZERO); |
| 743 | if (level == NULL) |
| 744 | return (ENOMEM); |
| 745 | level->abs_set = sets[i]; |
| 746 | level->total_set = sets[i]; |
| 747 | level->total_set.dev = NULL; |
| 748 | sc->all_count++; |
| 749 | inserted = 0; |
| 750 | |
| 751 | if (TAILQ_EMPTY(list)) { |
| 752 | CF_DEBUG("adding abs setting %d at head\n", |
| 753 | sets[i].freq); |
| 754 | TAILQ_INSERT_HEAD(list, level, link); |
| 755 | continue; |
| 756 | } |
| 757 | |
| 758 | TAILQ_FOREACH_REVERSE(search, list, cf_level_lst, link) |
| 759 | if (sets[i].freq <= search->total_set.freq) { |
| 760 | CF_DEBUG("adding abs setting %d after %d\n", |
| 761 | sets[i].freq, search->total_set.freq); |
| 762 | TAILQ_INSERT_AFTER(list, search, level, link); |
| 763 | inserted = 1; |
| 764 | break; |
| 765 | } |
| 766 | |
| 767 | if (inserted == 0) { |
| 768 | TAILQ_FOREACH(search, list, link) |
| 769 | if (sets[i].freq >= search->total_set.freq) { |
| 770 | CF_DEBUG("adding abs setting %d before %d\n", |
| 771 | sets[i].freq, search->total_set.freq); |
| 772 | TAILQ_INSERT_BEFORE(search, level, link); |
| 773 | break; |
| 774 | } |
| 775 | } |
| 776 | } |
| 777 | |
| 778 | return (0); |
| 779 | } |
| 780 | |
| 781 | /* |
| 782 | * Expand a group of relative settings, creating derived levels from them. |
no test coverage detected