Esempio n. 1
0
static int
acpicpu_once_detach(void)
{
	struct acpicpu_softc *sc;

	if (acpicpu_count != 0)
		return EDEADLK;

	cpufreq_deregister();

	if (acpicpu_log != NULL)
		sysctl_teardown(&acpicpu_log);

	if (acpicpu_sc != NULL)
		kmem_free(acpicpu_sc, maxcpus * sizeof(*sc));

	return 0;
}
int
cpufreq_register(struct cpufreq *cf)
{
	uint32_t c, i, j, k, m;
	int rv;

	if (cold != 0)
		return EBUSY;

	KASSERT(cf != NULL);
	KASSERT(cf_backend != NULL);
	KASSERT(cf->cf_get_freq != NULL);
	KASSERT(cf->cf_set_freq != NULL);
	KASSERT(cf->cf_state_count > 0);
	KASSERT(cf->cf_state_count < CPUFREQ_STATE_MAX);

	mutex_enter(&cpufreq_lock);

	if (cf_backend->cf_init != false) {
		mutex_exit(&cpufreq_lock);
		return EALREADY;
	}

	cf_backend->cf_init = true;
	cf_backend->cf_mp = cf->cf_mp;
	cf_backend->cf_cookie = cf->cf_cookie;
	cf_backend->cf_get_freq = cf->cf_get_freq;
	cf_backend->cf_set_freq = cf->cf_set_freq;

	(void)strlcpy(cf_backend->cf_name, cf->cf_name, sizeof(cf->cf_name));

	/*
	 * Sanity check the values and verify descending order.
	 */
	for (c = i = 0; i < cf->cf_state_count; i++) {

		CTASSERT(CPUFREQ_STATE_ENABLED != 0);
		CTASSERT(CPUFREQ_STATE_DISABLED != 0);

		if (cf->cf_state[i].cfs_freq == 0)
			continue;

		if (cf->cf_state[i].cfs_freq > 9999 &&
		    cf->cf_state[i].cfs_freq != CPUFREQ_STATE_ENABLED &&
		    cf->cf_state[i].cfs_freq != CPUFREQ_STATE_DISABLED)
			continue;

		for (j = k = 0; j < i; j++) {

			if (cf->cf_state[i].cfs_freq >=
			    cf->cf_state[j].cfs_freq) {
				k = 1;
				break;
			}
		}

		if (k != 0)
			continue;

		cf_backend->cf_state[c].cfs_index = c;
		cf_backend->cf_state[c].cfs_freq = cf->cf_state[i].cfs_freq;
		cf_backend->cf_state[c].cfs_power = cf->cf_state[i].cfs_power;

		c++;
	}

	cf_backend->cf_state_count = c;

	if (cf_backend->cf_state_count == 0) {
		mutex_exit(&cpufreq_lock);
		cpufreq_deregister();
		return EINVAL;
	}

	rv = cpufreq_latency();

	if (rv != 0) {
		mutex_exit(&cpufreq_lock);
		cpufreq_deregister();
		return rv;
	}

	m = cpufreq_get_max();
	cpufreq_set_all_raw(m);
	mutex_exit(&cpufreq_lock);

	return 0;
}