On Mon, Nov 12, 2012 at 01:02:11PM +0100, Rafael J. Wysocki wrote: > From: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> > > Currently, whoever wants to use ACPI device resources has to call > acpi_walk_resources() to browse the buffer returned by the _CRS > method for the given device and create filters passed to that > routine to apply to the individual resource items. This generally > is cumbersome, time-consuming and inefficient. Moreover, it may > be problematic if resource conflicts need to be resolved, because > the different users of _CRS will need to do that in a consistent > way. > > For this reason, add code to the ACPI core to execute _CRS once, > when the struct acpi_device object is created for a given device > node, and attach a list of ACPI resources returned by _CRS to that > object for future processing. > > Convert the ACPI code that creates platform device objects to using > the new resources list instead of executing acpi_walk_resources() by > itself, which makes it much more straightforward and easier to > follow. > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> > --- > drivers/acpi/acpi_platform.c | 90 ++++++++++++------------------------------- > drivers/acpi/resource.c | 12 +++++ > drivers/acpi/scan.c | 56 ++++++++++++++++++++++++++ > include/acpi/acpi_bus.h | 6 ++ > include/linux/acpi.h | 1 > 5 files changed, 102 insertions(+), 63 deletions(-) > > Index: linux/include/acpi/acpi_bus.h > =================================================================== > --- linux.orig/include/acpi/acpi_bus.h > +++ linux/include/acpi/acpi_bus.h > @@ -259,6 +259,11 @@ struct acpi_device_physical_node { > struct device *dev; > }; > > +struct acpi_resource_list_entry { > + struct list_head node; > + struct acpi_resource resource; > +}; > + > /* set maximum of physical nodes to 32 for expansibility */ > #define ACPI_MAX_PHYSICAL_NODE 32 > > @@ -268,6 +273,7 @@ struct acpi_device { > acpi_handle handle; /* no handle for fixed hardware */ > struct acpi_device *parent; > struct list_head children; > + struct list_head resources; /* Device resources. */ > struct list_head node; > struct list_head wakeup_list; > struct acpi_device_status status; > Index: linux/drivers/acpi/scan.c > =================================================================== > --- linux.orig/drivers/acpi/scan.c > +++ linux/drivers/acpi/scan.c > @@ -382,6 +382,52 @@ static void acpi_device_remove_files(str > ACPI Bus operations > -------------------------------------------------------------------------- */ > > +static void acpi_bus_drop_resources(struct acpi_device *adev) > +{ > + struct acpi_resource_list_entry *entry, *s; > + > + list_for_each_entry_safe(entry, s, &adev->resources, node) { > + list_del(&entry->node); > + kfree(entry); > + } > +} > + > +static acpi_status acpi_bus_add_resource(struct acpi_resource *res, > + void *context) > +{ > + struct list_head *list = context; > + struct acpi_resource_list_entry *entry; > + > + entry = kzalloc(sizeof(*entry), GFP_KERNEL); > + if (!entry) > + return AE_NO_MEMORY; > + > + entry->resource = *res; This does not work well with all resource types - specifically those that contain pointers, like acpi_resource_gpio and acpi_resource_source. The memory for the resources gets freed once acpi_walk_resources() is done. > + INIT_LIST_HEAD(&entry->node); > + list_add_tail(&entry->node, list); > + return AE_OK; > +} -- 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