* Either directly obtain settings from the cpufreq driver, or build a list of * relative settings to be integrated later against an absolute max. */
| 567 | * relative settings to be integrated later against an absolute max. |
| 568 | */ |
| 569 | static int |
| 570 | cpufreq_add_levels(device_t cf_dev, struct cf_setting_lst *rel_sets) |
| 571 | { |
| 572 | struct cf_setting_array *set_arr; |
| 573 | struct cf_setting *sets; |
| 574 | device_t dev; |
| 575 | struct cpufreq_softc *sc; |
| 576 | int type, set_count, error; |
| 577 | |
| 578 | sc = device_get_softc(cf_dev); |
| 579 | dev = sc->cf_drv_dev; |
| 580 | |
| 581 | /* Skip devices that aren't ready. */ |
| 582 | if (!device_is_attached(cf_dev)) |
| 583 | return (0); |
| 584 | |
| 585 | /* |
| 586 | * Get settings, skipping drivers that offer no settings or |
| 587 | * provide settings for informational purposes only. |
| 588 | */ |
| 589 | error = CPUFREQ_DRV_TYPE(dev, &type); |
| 590 | if (error != 0 || (type & CPUFREQ_FLAG_INFO_ONLY)) { |
| 591 | if (error == 0) { |
| 592 | CF_DEBUG("skipping info-only driver %s\n", |
| 593 | device_get_nameunit(cf_dev)); |
| 594 | } |
| 595 | return (error); |
| 596 | } |
| 597 | |
| 598 | sets = malloc(MAX_SETTINGS * sizeof(*sets), M_TEMP, M_NOWAIT); |
| 599 | if (sets == NULL) |
| 600 | return (ENOMEM); |
| 601 | |
| 602 | set_count = MAX_SETTINGS; |
| 603 | error = CPUFREQ_DRV_SETTINGS(dev, sets, &set_count); |
| 604 | if (error != 0 || set_count == 0) |
| 605 | goto out; |
| 606 | |
| 607 | /* Add the settings to our absolute/relative lists. */ |
| 608 | switch (type & CPUFREQ_TYPE_MASK) { |
| 609 | case CPUFREQ_TYPE_ABSOLUTE: |
| 610 | error = cpufreq_insert_abs(sc, sets, set_count); |
| 611 | break; |
| 612 | case CPUFREQ_TYPE_RELATIVE: |
| 613 | CF_DEBUG("adding %d relative settings\n", set_count); |
| 614 | set_arr = malloc(sizeof(*set_arr), M_TEMP, M_NOWAIT); |
| 615 | if (set_arr == NULL) { |
| 616 | error = ENOMEM; |
| 617 | goto out; |
| 618 | } |
| 619 | bcopy(sets, set_arr->sets, set_count * sizeof(*sets)); |
| 620 | set_arr->count = set_count; |
| 621 | TAILQ_INSERT_TAIL(rel_sets, set_arr, link); |
| 622 | break; |
| 623 | default: |
| 624 | error = EINVAL; |
| 625 | } |
| 626 |
no test coverage detected