lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 20 Nov 2012 02:01:01 +0100
From:	"Rafael J. Wysocki" <rjw@...k.pl>
To:	Mika Westerberg <mika.westerberg@...ux.intel.com>,
	Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Cc:	Bjorn Helgaas <bhelgaas@...gle.com>,
	Jean Delvare <khali@...ux-fr.org>, ben-linux@...ff.org,
	w.sang@...gutronix.de, linux-kernel@...r.kernel.org,
	lenb@...nel.org, rafael.j.wysocki@...el.com,
	broonie@...nsource.wolfsonmicro.com, grant.likely@...retlab.ca,
	linus.walleij@...aro.org, mathias.nyman@...ux.intel.com,
	linux-acpi@...r.kernel.org
Subject: [Update][PATCH 3/3] ACPI / platform: Initialize ACPI handles of platform devices in advance

From: Rafael J. Wysocki <rafael.j.wysocki@...el.com>

The current platform device creation and registration code in
acpi_create_platform_device() is quite convoluted.  This function
takes an ACPI device node as an argument and eventually calls
platform_device_register_resndata() to create and register a
platform device object on the basis of the information contained
in that code.  However, it doesn't associate the new platform
device with the ACPI node directly, but instead it relies on
acpi_platform_notify(), called from within device_add(), to find
that ACPI node again with the help of acpi_platform_find_device()
and acpi_platform_match() and then attach the new platform device
to it.  This causes an additional ACPI namespace walk to happen and
is clearly suboptimal.

Use the observation that it is now possible to initialize the ACPI
handle of a device before calling device_add() for it to make this
code more straightforward.  Namely, add a new field to struct
platform_device_info allowing us to pass the ACPI handle of interest
to platform_device_register_full(), which will then use it to
initialize the new device's ACPI handle before registering it.
This will cause acpi_platform_notify() to use the ACPI handle from
the device structure directly instead of using the .find_device()
routine provided by the device's bus type.  In consequence,
acpi_platform_bus, acpi_platform_find_device(), and
acpi_platform_match() are not necessary any more, so remove them.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@...el.com>
Reviewed-by: Mika Westerberg <mika.westerberg@...ux.intel.com>
---
 drivers/acpi/acpi_platform.c    |   76 +++++-----------------------------------
 drivers/base/platform.c         |    2 +
 include/linux/platform_device.h |    1 
 3 files changed, 13 insertions(+), 66 deletions(-)

Index: linux/include/linux/platform_device.h
===================================================================
--- linux.orig/include/linux/platform_device.h
+++ linux/include/linux/platform_device.h
@@ -55,6 +55,7 @@ extern int platform_add_devices(struct p
 
 struct platform_device_info {
 		struct device *parent;
+		struct acpi_dev_node acpi_node;
 
 		const char *name;
 		int id;
Index: linux/drivers/acpi/acpi_platform.c
===================================================================
--- linux.orig/drivers/acpi/acpi_platform.c
+++ linux/drivers/acpi/acpi_platform.c
@@ -33,7 +33,7 @@ struct platform_device *acpi_create_plat
 {
 	struct platform_device *pdev = NULL;
 	struct acpi_device *acpi_parent;
-	struct device *parent = NULL;
+	struct platform_device_info pdevinfo;
 	struct resource_list_entry *rentry;
 	struct list_head resource_list;
 	struct resource *resources;
@@ -60,11 +60,13 @@ struct platform_device *acpi_create_plat
 
 	acpi_dev_free_resource_list(&resource_list);
 
+	memset(&pdevinfo, 0, sizeof(pdevinfo));
 	/*
 	 * If the ACPI node has a parent and that parent has a physical device
 	 * attached to it, that physical device should be the parent of the
 	 * platform device we are about to create.
 	 */
+	pdevinfo.parent = NULL;
 	acpi_parent = adev->parent;
 	if (acpi_parent) {
 		struct acpi_device_physical_node *entry;
@@ -76,12 +78,16 @@ struct platform_device *acpi_create_plat
 			entry = list_first_entry(list,
 					struct acpi_device_physical_node,
 					node);
-			parent = entry->dev;
+			pdevinfo.parent = entry->dev;
 		}
 		mutex_unlock(&acpi_parent->physical_node_lock);
 	}
-	pdev = platform_device_register_resndata(parent, dev_name(&adev->dev),
-						 -1, resources, count, NULL, 0);
+	pdevinfo.name = dev_name(&adev->dev);
+	pdevinfo.id = -1;
+	pdevinfo.res = resources;
+	pdevinfo.num_res = count;
+	pdevinfo.acpi_node.handle = adev->handle;
+	pdev = platform_device_register_full(&pdevinfo);
 	if (IS_ERR(pdev)) {
 		dev_err(&adev->dev, "platform device creation failed: %ld\n",
 			PTR_ERR(pdev));
@@ -94,65 +100,3 @@ struct platform_device *acpi_create_plat
 	kfree(resources);
 	return pdev;
 }
-
-static acpi_status acpi_platform_match(acpi_handle handle, u32 depth,
-				       void *data, void **return_value)
-{
-	struct platform_device *pdev = data;
-	struct acpi_device *adev;
-	acpi_status status;
-
-	status = acpi_bus_get_device(handle, &adev);
-	if (ACPI_FAILURE(status))
-		return status;
-
-	/* Skip ACPI devices that have physical device attached */
-	if (adev->physical_node_count)
-		return AE_OK;
-
-	if (!strcmp(dev_name(&pdev->dev), dev_name(&adev->dev))) {
-		*(acpi_handle *)return_value = handle;
-		return AE_CTRL_TERMINATE;
-	}
-
-	return AE_OK;
-}
-
-static int acpi_platform_find_device(struct device *dev, acpi_handle *handle)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	char *name, *tmp, *hid;
-
-	/*
-	 * The platform device is named using the ACPI device name
-	 * _HID:INSTANCE so we strip the INSTANCE out in order to find the
-	 * correct device using its _HID.
-	 */
-	name = kstrdup(dev_name(dev), GFP_KERNEL);
-	if (!name)
-		return -ENOMEM;
-
-	tmp = name;
-	hid = strsep(&tmp, ":");
-	if (!hid) {
-		kfree(name);
-		return -ENODEV;
-	}
-
-	*handle = NULL;
-	acpi_get_devices(hid, acpi_platform_match, pdev, handle);
-
-	kfree(name);
-	return *handle ? 0 : -ENODEV;
-}
-
-static struct acpi_bus_type acpi_platform_bus = {
-	.bus = &platform_bus_type,
-	.find_device = acpi_platform_find_device,
-};
-
-static int __init acpi_platform_init(void)
-{
-	return register_acpi_bus_type(&acpi_platform_bus);
-}
-arch_initcall(acpi_platform_init);
Index: linux/drivers/base/platform.c
===================================================================
--- linux.orig/drivers/base/platform.c
+++ linux/drivers/base/platform.c
@@ -437,6 +437,7 @@ struct platform_device *platform_device_
 		goto err_alloc;
 
 	pdev->dev.parent = pdevinfo->parent;
+	ACPI_HANDLE_SET(&pdev->dev, pdevinfo->acpi_node.handle);
 
 	if (pdevinfo->dma_mask) {
 		/*
@@ -467,6 +468,7 @@ struct platform_device *platform_device_
 	ret = platform_device_add(pdev);
 	if (ret) {
 err:
+		ACPI_HANDLE_SET(&pdev->dev, NULL);
 		kfree(pdev->dev.dma_mask);
 
 err_alloc:

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ