On Sun, Nov 18, 2012 at 10:12:52PM +0100, Rafael J. Wysocki wrote: > From: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> > > Currently, the ACPI handles of devices are initialized from within > device_add(), by acpi_bind_one() called from acpi_platform_notify() > which first uses the .find_device() routine provided by the device's > bus type to find the matching device node in the ACPI namespace. > This is a source of some computational overhead and, moreover, the > correctness of the result depends on the implementation of > .find_device() which is known to fail occasionally for some bus types > (e.g. PCI). In some cases, however, the corresponding ACPI device > node is known already before calling device_add() for the given > struct device object and the whole .find_device() dance in > acpi_platform_notify() is then simply unnecessary. > > For this reason, make it possible to initialize the ACPI handles of > devices before calling device_add() for them. Modify > acpi_platform_notify() to call acpi_bind_one() in advance to check > the device's existing ACPI handle and skip the .find_device() > search if that is successful. Change acpi_bind_one() accordingly. > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> > --- > drivers/acpi/glue.c | 42 +++++++++++++++++++++++++++++++++--------- > 1 file changed, 33 insertions(+), 9 deletions(-) > > Index: linux/drivers/acpi/glue.c > =================================================================== > --- linux.orig/drivers/acpi/glue.c > +++ linux/drivers/acpi/glue.c > @@ -135,41 +135,54 @@ static int acpi_bind_one(struct device * > int retval = -EINVAL; > > if (dev->acpi_handle) { > - dev_warn(dev, "Drivers changed 'acpi_handle'\n"); > - return -EINVAL; > + if (handle) { > + dev_warn(dev, "ACPI handle is already set\n"); > + return -EINVAL; > + } else { > + handle = dev->acpi_handle; > + } > } > + if (!handle) > + return -EINVAL; > > get_device(dev); > status = acpi_bus_get_device(handle, &acpi_dev); > if (ACPI_FAILURE(status)) > goto err; > > - physical_node = kzalloc(sizeof(struct acpi_device_physical_node), > - GFP_KERNEL); > + physical_node = kzalloc(sizeof(*physical_node), GFP_KERNEL); Here we allocate memory for the physical node... > if (!physical_node) { > retval = -ENOMEM; > goto err; > } > > mutex_lock(&acpi_dev->physical_node_lock); > + > + /* Sanity check. */ > + list_for_each_entry(physical_node, &acpi_dev->physical_node_list, node) .. and overwrite it here ;-) Maybe using a different variable for the sanity check? I've changed the SPI/I2C patches to use this as well and they got a lot smaller as we don't have to do the .find_device() magic. Once you have fixed the above, you can add my Reviewed-by: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx> to these two patches, if you like. -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html