acpi_cpu: promote Processor's order

Andriy Gapon avg at freebsd.org
Tue Feb 9 17:22:22 UTC 2010



Please review the following patch for doing acpu_cpu's probe+attach ealier.
There are several arguments in favor of this:

1. Theoretical: it's natural to attach to Processor before any other devices in
ACPI namespace, because a processor is a central resource and a root of all action.

2. Practical: there are systems with DSDT defined in such a way that other devices
 depend on objects that get dynamically loaded (via Load) when Processor control
methods are executed (e.g. _PDC/_OSC).  Those devices may include devices that are
themselves pretty essential to a system, for example, EC.
Some links:
http://lkml.org/lkml/2009/12/20/146
http://bugzilla.kernel.org/show_bug.cgi?id=14824
http://patchwork.kernel.org/patch/69039/

Of course, there is a reason why we give a low priority to acpi_cpu driver now.
(In fact, I remember being somehow involved in that).
The drivers on cpu (acpi_cpu) buses (child devices) expect to be probed and
attached at the time when some other system resources are already made available,
for example, PCI configuration space.
So, I think that before proper multi-pass is available, we could use currently
available approximation/emulation of multi-pass, that is SYSINIT with order of
SI_SUB_CONFIGURE+SI_ORDER_MIDDLE.
With that acpu_cpu child devices will be probed around the same time as they do now.

Legacy systems (non-ACPI) are not affected by the suggested changes.

P.S.
Since I mentioned EC, I'd like to add a couple of words on ECDT.
Currently we handle ECDT so early that AcpiInstallAddressSpaceHandler wouldn't and
shouldn't call _REG method (or any other methods), so this case should not cause
problems.  And EC device in ACPI namespace would have a later order than
Processor, so that's OK too.


Index: sys/dev/acpica/acpi.c
===================================================================
--- sys/dev/acpica/acpi.c	(revision 203670)
+++ sys/dev/acpica/acpi.c	(working copy)
@@ -1685,14 +1685,14 @@
      * 100000. CPUs
      */
     AcpiGetType(handle, &type);
-    if (acpi_MatchHid(handle, "PNP0C01") || acpi_MatchHid(handle, "PNP0C02"))
+    if (type == ACPI_TYPE_PROCESSOR)
 	*order = 1;
+    else if (acpi_MatchHid(handle, "PNP0C01") || acpi_MatchHid(handle, "PNP0C02"))
+	*order = 2;
     else if (acpi_MatchHid(handle, "PNP0C09"))
-	*order = 2;
+	*order = 3;
     else if (acpi_MatchHid(handle, "PNP0C0F"))
-	*order = 3;
-    else if (type == ACPI_TYPE_PROCESSOR)
-	*order = 100000;
+	*order = 4;
 }

 /*
Index: sys/dev/acpica/acpi_cpu.c
===================================================================
--- sys/dev/acpica/acpi_cpu.c	(revision 203670)
+++ sys/dev/acpica/acpi_cpu.c	(working copy)
@@ -384,13 +384,30 @@
     /* Probe for Cx state support. */
     acpi_cpu_cx_probe(sc);

-    /* Finally,  call identify and probe/attach for child devices. */
-    bus_generic_probe(dev);
-    bus_generic_attach(dev);
-
     return (0);
 }

+static void
+acpi_cpu_postattach(void *unused __unused)
+{
+    device_t *devices;
+    int err;
+    int i, n;
+
+    err = devclass_get_devices(acpi_cpu_devclass, &devices, &n);
+    if (err != 0) {
+	printf("devclass_get_devices(acpi_cpu_devclass) failed\n");
+	return;
+    }
+    for (i = 0; i < n; i++)
+	bus_generic_probe(devices[i]);
+    for (i = 0; i < n; i++)
+	bus_generic_attach(devices[i]);
+    free(devices, M_TEMP);
+}
+SYSINIT(acpi_cpu, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE,
+    acpi_cpu_postattach, NULL);
+
 /*
  * Disable any entry to the idle function during suspend and re-enable it
  * during resume.


-- 
Andriy Gapon



More information about the freebsd-acpi mailing list