Introduce a new method, cpufreq_drv_type(), that returns the type of the
driver. This used to be handled by cpufreq_drv_settings() but it's useful to get the type/flags separately from getting the settings. (For example, you don't have to pass an array of cf_setting just to find the driver type.) Use this new method in our in-tree drivers to detect reliably if acpi_perf is present and owns the hardware. This simplifies logic in drivers as well as fixing a bug introduced in my last commit where too many drivers attached.
This commit is contained in:
parent
7643c37cf2
commit
e94a0c1a18
@ -101,9 +101,10 @@ static void acpi_px_available(struct acpi_perf_softc *sc);
|
||||
static void acpi_px_startup(void *arg);
|
||||
static void acpi_px_notify(ACPI_HANDLE h, UINT32 notify, void *context);
|
||||
static int acpi_px_settings(device_t dev, struct cf_setting *sets,
|
||||
int *count, int *type);
|
||||
int *count);
|
||||
static int acpi_px_set(device_t dev, const struct cf_setting *set);
|
||||
static int acpi_px_get(device_t dev, struct cf_setting *set);
|
||||
static int acpi_px_type(device_t dev, int *type);
|
||||
|
||||
static device_method_t acpi_perf_methods[] = {
|
||||
/* Device interface */
|
||||
@ -115,6 +116,7 @@ static device_method_t acpi_perf_methods[] = {
|
||||
/* cpufreq interface */
|
||||
DEVMETHOD(cpufreq_drv_set, acpi_px_set),
|
||||
DEVMETHOD(cpufreq_drv_get, acpi_px_get),
|
||||
DEVMETHOD(cpufreq_drv_type, acpi_px_type),
|
||||
DEVMETHOD(cpufreq_drv_settings, acpi_px_settings),
|
||||
{0, 0}
|
||||
};
|
||||
@ -392,7 +394,7 @@ acpi_px_to_set(device_t dev, struct acpi_px *px, struct cf_setting *set)
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_px_settings(device_t dev, struct cf_setting *sets, int *count, int *type)
|
||||
acpi_px_settings(device_t dev, struct cf_setting *sets, int *count)
|
||||
{
|
||||
struct acpi_perf_softc *sc;
|
||||
int x, y;
|
||||
@ -408,9 +410,6 @@ acpi_px_settings(device_t dev, struct cf_setting *sets, int *count, int *type)
|
||||
for (x = sc->px_max_avail; x < sc->px_count; x++, y++)
|
||||
acpi_px_to_set(dev, &sc->px_states[x], &sets[y]);
|
||||
*count = sc->px_count - sc->px_max_avail;
|
||||
*type = CPUFREQ_TYPE_ABSOLUTE;
|
||||
if (sc->info_only)
|
||||
*type |= CPUFREQ_FLAG_INFO_ONLY;
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -502,3 +501,18 @@ acpi_px_get(device_t dev, struct cf_setting *set)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_px_type(device_t dev, int *type)
|
||||
{
|
||||
struct acpi_perf_softc *sc;
|
||||
|
||||
if (type == NULL)
|
||||
return (EINVAL);
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
*type = CPUFREQ_TYPE_ABSOLUTE;
|
||||
if (sc->info_only)
|
||||
*type |= CPUFREQ_FLAG_INFO_ONLY;
|
||||
return (0);
|
||||
}
|
||||
|
@ -97,9 +97,10 @@ static int acpi_throttle_attach(device_t dev);
|
||||
static int acpi_throttle_evaluate(struct acpi_throttle_softc *sc);
|
||||
static int acpi_throttle_quirks(struct acpi_throttle_softc *sc);
|
||||
static int acpi_thr_settings(device_t dev, struct cf_setting *sets,
|
||||
int *count, int *type);
|
||||
int *count);
|
||||
static int acpi_thr_set(device_t dev, const struct cf_setting *set);
|
||||
static int acpi_thr_get(device_t dev, struct cf_setting *set);
|
||||
static int acpi_thr_type(device_t dev, int *type);
|
||||
|
||||
static device_method_t acpi_throttle_methods[] = {
|
||||
/* Device interface */
|
||||
@ -110,6 +111,7 @@ static device_method_t acpi_throttle_methods[] = {
|
||||
/* cpufreq interface */
|
||||
DEVMETHOD(cpufreq_drv_set, acpi_thr_set),
|
||||
DEVMETHOD(cpufreq_drv_get, acpi_thr_get),
|
||||
DEVMETHOD(cpufreq_drv_type, acpi_thr_type),
|
||||
DEVMETHOD(cpufreq_drv_settings, acpi_thr_settings),
|
||||
{0, 0}
|
||||
};
|
||||
@ -320,7 +322,7 @@ acpi_throttle_quirks(struct acpi_throttle_softc *sc)
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_thr_settings(device_t dev, struct cf_setting *sets, int *count, int *type)
|
||||
acpi_thr_settings(device_t dev, struct cf_setting *sets, int *count)
|
||||
{
|
||||
struct acpi_throttle_softc *sc;
|
||||
int i, speed;
|
||||
@ -338,7 +340,6 @@ acpi_thr_settings(device_t dev, struct cf_setting *sets, int *count, int *type)
|
||||
sets[i].dev = dev;
|
||||
}
|
||||
*count = CPU_MAX_SPEED;
|
||||
*type = CPUFREQ_TYPE_RELATIVE;
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -409,3 +410,14 @@ acpi_thr_get(device_t dev, struct cf_setting *set)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_thr_type(device_t dev, int *type)
|
||||
{
|
||||
|
||||
if (type == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
*type = CPUFREQ_TYPE_RELATIVE;
|
||||
return (0);
|
||||
}
|
||||
|
@ -97,9 +97,10 @@ static int ichss_probe(device_t dev);
|
||||
static int ichss_attach(device_t dev);
|
||||
static int ichss_detach(device_t dev);
|
||||
static int ichss_settings(device_t dev, struct cf_setting *sets,
|
||||
int *count, int *type);
|
||||
int *count);
|
||||
static int ichss_set(device_t dev, const struct cf_setting *set);
|
||||
static int ichss_get(device_t dev, struct cf_setting *set);
|
||||
static int ichss_type(device_t dev, int *type);
|
||||
|
||||
static device_method_t ichss_methods[] = {
|
||||
/* Device interface */
|
||||
@ -110,6 +111,7 @@ static device_method_t ichss_methods[] = {
|
||||
/* cpufreq interface */
|
||||
DEVMETHOD(cpufreq_drv_set, ichss_set),
|
||||
DEVMETHOD(cpufreq_drv_get, ichss_get),
|
||||
DEVMETHOD(cpufreq_drv_type, ichss_type),
|
||||
DEVMETHOD(cpufreq_drv_settings, ichss_settings),
|
||||
{0, 0}
|
||||
};
|
||||
@ -209,9 +211,8 @@ ichss_pci_probe(device_t dev)
|
||||
static int
|
||||
ichss_probe(device_t dev)
|
||||
{
|
||||
struct cf_setting set;
|
||||
device_t perf_dev;
|
||||
int count, type;
|
||||
int error, type;
|
||||
|
||||
/*
|
||||
* If the ACPI perf driver has attached and is not just offering
|
||||
@ -219,10 +220,8 @@ ichss_probe(device_t dev)
|
||||
*/
|
||||
perf_dev = device_find_child(device_get_parent(dev), "acpi_perf", -1);
|
||||
if (perf_dev && device_is_attached(perf_dev)) {
|
||||
type = 0;
|
||||
count = 1;
|
||||
CPUFREQ_DRV_SETTINGS(perf_dev, &set, &count, &type);
|
||||
if ((type & CPUFREQ_FLAG_INFO_ONLY) == 0)
|
||||
error = CPUFREQ_DRV_TYPE(perf_dev, &type);
|
||||
if (error == 0 && (type & CPUFREQ_FLAG_INFO_ONLY) == 0)
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
@ -275,7 +274,7 @@ ichss_detach(device_t dev)
|
||||
}
|
||||
|
||||
static int
|
||||
ichss_settings(device_t dev, struct cf_setting *sets, int *count, int *type)
|
||||
ichss_settings(device_t dev, struct cf_setting *sets, int *count)
|
||||
{
|
||||
struct ichss_softc *sc;
|
||||
struct cf_setting set;
|
||||
@ -304,7 +303,6 @@ ichss_settings(device_t dev, struct cf_setting *sets, int *count, int *type)
|
||||
|
||||
bcopy(sc->sets, sets, sizeof(sc->sets));
|
||||
*count = 2;
|
||||
*type = CPUFREQ_TYPE_ABSOLUTE;
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -382,3 +380,14 @@ ichss_get(device_t dev, struct cf_setting *set)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ichss_type(device_t dev, int *type)
|
||||
{
|
||||
|
||||
if (type == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
*type = CPUFREQ_TYPE_ABSOLUTE;
|
||||
return (0);
|
||||
}
|
||||
|
@ -88,5 +88,13 @@ METHOD int drv_settings {
|
||||
device_t dev;
|
||||
struct cf_setting *sets;
|
||||
int *count;
|
||||
};
|
||||
|
||||
#
|
||||
# Get an individual driver's type.
|
||||
#
|
||||
METHOD int drv_type {
|
||||
device_t dev;
|
||||
int *type;
|
||||
};
|
||||
|
||||
|
@ -404,9 +404,12 @@ cf_levels_method(device_t dev, struct cf_level *levels, int *count)
|
||||
* Get settings, skipping drivers that offer no settings or
|
||||
* provide settings for informational purposes only.
|
||||
*/
|
||||
error = CPUFREQ_DRV_TYPE(devs[i], &type);
|
||||
if (error || (type & CPUFREQ_FLAG_INFO_ONLY))
|
||||
continue;
|
||||
set_count = MAX_SETTINGS;
|
||||
error = CPUFREQ_DRV_SETTINGS(devs[i], sets, &set_count, &type);
|
||||
if (error || set_count == 0 || (type & CPUFREQ_FLAG_INFO_ONLY))
|
||||
error = CPUFREQ_DRV_SETTINGS(devs[i], sets, &set_count);
|
||||
if (error || set_count == 0)
|
||||
continue;
|
||||
|
||||
/* Add the settings to our absolute/relative lists. */
|
||||
@ -772,8 +775,7 @@ int
|
||||
cpufreq_unregister(device_t dev)
|
||||
{
|
||||
device_t cf_dev, *devs;
|
||||
int cfcount, count, devcount, error, i, type;
|
||||
struct cf_setting set;
|
||||
int cfcount, devcount, error, i, type;
|
||||
|
||||
/*
|
||||
* If this is the last cpufreq child device, remove the control
|
||||
@ -788,8 +790,7 @@ cpufreq_unregister(device_t dev)
|
||||
for (i = 0; i < devcount; i++) {
|
||||
if (!device_is_attached(devs[i]))
|
||||
continue;
|
||||
count = 1;
|
||||
if (CPUFREQ_DRV_SETTINGS(devs[i], &set, &count, &type) == 0)
|
||||
if (CPUFREQ_DRV_TYPE(devs[i], &type) == 0)
|
||||
cfcount++;
|
||||
}
|
||||
if (cfcount <= 1)
|
||||
|
Loading…
Reference in New Issue
Block a user