svn commit: r301518 - head/sys/dev/acpica
John Baldwin
jhb at FreeBSD.org
Mon Jun 6 20:28:55 UTC 2016
Author: jhb
Date: Mon Jun 6 20:28:53 2016
New Revision: 301518
URL: https://svnweb.freebsd.org/changeset/base/301518
Log:
Defer the creation of ACPI thermal kthreads to a startup sysinit.
The SYSINIT runs at SI_SUB_KICK_SCHEDULER after the scheduler is fully
initialized and timers are working. This fixes booting in the
EARLY_AP_STARTUP case.
Modified:
head/sys/dev/acpica/acpi_thermal.c
Modified: head/sys/dev/acpica/acpi_thermal.c
==============================================================================
--- head/sys/dev/acpica/acpi_thermal.c Mon Jun 6 20:00:13 2016 (r301517)
+++ head/sys/dev/acpica/acpi_thermal.c Mon Jun 6 20:28:53 2016 (r301518)
@@ -311,19 +311,40 @@ acpi_tz_attach(device_t dev)
"thermal sampling period for passive cooling");
/*
- * Create thread to service all of the thermal zones. Register
- * our power profile event handler.
+ * Register our power profile event handler.
*/
sc->tz_event = EVENTHANDLER_REGISTER(power_profile_change,
acpi_tz_power_profile, sc, 0);
- if (acpi_tz_proc == NULL) {
- error = kproc_create(acpi_tz_thread, NULL, &acpi_tz_proc,
- RFHIGHPID, 0, "acpi_thermal");
- if (error != 0) {
- device_printf(sc->tz_dev, "could not create thread - %d", error);
- goto out;
- }
- }
+
+ /*
+ * Flag the event handler for a manual invocation by our timeout.
+ * We defer it like this so that the rest of the subsystem has time
+ * to come up. Don't bother evaluating/printing the temperature at
+ * this point; on many systems it'll be bogus until the EC is running.
+ */
+ sc->tz_flags |= TZ_FLAG_GETPROFILE;
+
+ return_VALUE (0);
+}
+
+static void
+acpi_tz_startup(void *arg __unused)
+{
+ struct acpi_tz_softc *sc;
+ device_t *devs;
+ int devcount, error, i;
+
+ devclass_get_devices(acpi_tz_devclass, &devs, &devcount);
+ if (devcount == 0)
+ return;
+
+ /*
+ * Create thread to service all of the thermal zones.
+ */
+ error = kproc_create(acpi_tz_thread, NULL, &acpi_tz_proc, RFHIGHPID, 0,
+ "acpi_thermal");
+ if (error != 0)
+ printf("acpi_tz: could not create thread - %d", error);
/*
* Create a thread to handle passive cooling for 1st zone which
@@ -335,34 +356,22 @@ acpi_tz_attach(device_t dev)
* given frequency whereas it's possible for different thermal
* zones to specify independent settings for multiple CPUs.
*/
- if (acpi_tz_cooling_unit < 0 && acpi_tz_cooling_is_available(sc))
- sc->tz_cooling_enabled = TRUE;
- if (sc->tz_cooling_enabled) {
- error = acpi_tz_cooling_thread_start(sc);
- if (error != 0) {
- sc->tz_cooling_enabled = FALSE;
- goto out;
+ for (i = 0; i < devcount; i++) {
+ sc = device_get_softc(devs[i]);
+ if (acpi_tz_cooling_is_available(sc)) {
+ sc->tz_cooling_enabled = TRUE;
+ error = acpi_tz_cooling_thread_start(sc);
+ if (error != 0) {
+ sc->tz_cooling_enabled = FALSE;
+ break;
+ }
+ acpi_tz_cooling_unit = device_get_unit(devs[i]);
+ break;
}
- acpi_tz_cooling_unit = device_get_unit(dev);
- }
-
- /*
- * Flag the event handler for a manual invocation by our timeout.
- * We defer it like this so that the rest of the subsystem has time
- * to come up. Don't bother evaluating/printing the temperature at
- * this point; on many systems it'll be bogus until the EC is running.
- */
- sc->tz_flags |= TZ_FLAG_GETPROFILE;
-
-out:
- if (error != 0) {
- EVENTHANDLER_DEREGISTER(power_profile_change, sc->tz_event);
- AcpiRemoveNotifyHandler(sc->tz_handle, ACPI_DEVICE_NOTIFY,
- acpi_tz_notify_handler);
- sysctl_ctx_free(&sc->tz_sysctl_ctx);
}
- return_VALUE (error);
+ free(devs, M_TEMP);
}
+SYSINIT(acpi_tz, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, acpi_tz_startup, NULL);
/*
* Parse the current state of this thermal zone and set up to use it.
More information about the svn-src-head
mailing list