MCPcopy Create free account
hub / github.com/F-Stack/f-stack / cpufreq_attach

Function cpufreq_attach

freebsd/kern/kern_cpu.c:151–202  ·  view source on GitHub ↗

* This is called as the result of a hardware specific frequency control driver * calling cpufreq_register. It provides a general interface for system wide * frequency controls and operates on a per cpu basis. */

Source from the content-addressed store, hash-verified

149 * frequency controls and operates on a per cpu basis.
150 */
151static int
152cpufreq_attach(device_t dev)
153{
154 struct cpufreq_softc *sc;
155 struct pcpu *pc;
156 device_t parent;
157 uint64_t rate;
158
159 CF_DEBUG("initializing %s\n", device_get_nameunit(dev));
160 sc = device_get_softc(dev);
161 parent = device_get_parent(dev);
162 sc->dev = dev;
163 sysctl_ctx_init(&sc->sysctl_ctx);
164 TAILQ_INIT(&sc->all_levels);
165 CF_MTX_INIT(&sc->lock);
166 sc->curr_level.total_set.freq = CPUFREQ_VAL_UNKNOWN;
167 SLIST_INIT(&sc->saved_freq);
168 /* Try to get nominal CPU freq to use it as maximum later if needed */
169 sc->max_mhz = cpu_get_nominal_mhz(dev);
170 /* If that fails, try to measure the current rate */
171 if (sc->max_mhz <= 0) {
172 CF_DEBUG("Unable to obtain nominal frequency.\n");
173 pc = cpu_get_pcpu(dev);
174 if (cpu_est_clockrate(pc->pc_cpuid, &rate) == 0)
175 sc->max_mhz = rate / 1000000;
176 else
177 sc->max_mhz = CPUFREQ_VAL_UNKNOWN;
178 }
179
180 CF_DEBUG("initializing one-time data for %s\n",
181 device_get_nameunit(dev));
182 sc->levels_buf = malloc(CF_MAX_LEVELS * sizeof(*sc->levels_buf),
183 M_DEVBUF, M_WAITOK);
184 SYSCTL_ADD_PROC(&sc->sysctl_ctx,
185 SYSCTL_CHILDREN(device_get_sysctl_tree(parent)),
186 OID_AUTO, "freq", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
187 sc, 0, cpufreq_curr_sysctl, "I", "Current CPU frequency");
188 SYSCTL_ADD_PROC(&sc->sysctl_ctx,
189 SYSCTL_CHILDREN(device_get_sysctl_tree(parent)),
190 OID_AUTO, "freq_levels",
191 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT, sc, 0,
192 cpufreq_levels_sysctl, "A", "CPU frequency levels");
193
194 /*
195 * Queue a one-shot broadcast that levels have changed.
196 * It will run once the system has completed booting.
197 */
198 TASK_INIT(&sc->startup_task, 0, cpufreq_startup_task, dev);
199 taskqueue_enqueue(taskqueue_thread, &sc->startup_task);
200
201 return (0);
202}
203
204/* Handle any work to be done for all drivers that attached during boot. */
205static void

Callers

nothing calls this directly

Calls 10

device_get_nameunitFunction · 0.85
device_get_softcFunction · 0.85
device_get_parentFunction · 0.85
sysctl_ctx_initFunction · 0.85
cpu_get_nominal_mhzFunction · 0.85
cpu_get_pcpuFunction · 0.85
mallocFunction · 0.85
device_get_sysctl_treeFunction · 0.85
taskqueue_enqueueFunction · 0.85
cpu_est_clockrateFunction · 0.50

Tested by

no test coverage detected