aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/acpi_platform.c76
-rw-r--r--drivers/base/platform.c2
-rw-r--r--include/linux/platform_device.h1
3 files changed, 13 insertions, 66 deletions
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 7ac20d8b8f07..b7df9b197bcf 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -33,7 +33,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
33{ 33{
34 struct platform_device *pdev = NULL; 34 struct platform_device *pdev = NULL;
35 struct acpi_device *acpi_parent; 35 struct acpi_device *acpi_parent;
36 struct device *parent = NULL; 36 struct platform_device_info pdevinfo;
37 struct resource_list_entry *rentry; 37 struct resource_list_entry *rentry;
38 struct list_head resource_list; 38 struct list_head resource_list;
39 struct resource *resources; 39 struct resource *resources;
@@ -60,11 +60,13 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
60 60
61 acpi_dev_free_resource_list(&resource_list); 61 acpi_dev_free_resource_list(&resource_list);
62 62
63 memset(&pdevinfo, 0, sizeof(pdevinfo));
63 /* 64 /*
64 * If the ACPI node has a parent and that parent has a physical device 65 * If the ACPI node has a parent and that parent has a physical device
65 * attached to it, that physical device should be the parent of the 66 * attached to it, that physical device should be the parent of the
66 * platform device we are about to create. 67 * platform device we are about to create.
67 */ 68 */
69 pdevinfo.parent = NULL;
68 acpi_parent = adev->parent; 70 acpi_parent = adev->parent;
69 if (acpi_parent) { 71 if (acpi_parent) {
70 struct acpi_device_physical_node *entry; 72 struct acpi_device_physical_node *entry;
@@ -76,12 +78,16 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
76 entry = list_first_entry(list, 78 entry = list_first_entry(list,
77 struct acpi_device_physical_node, 79 struct acpi_device_physical_node,
78 node); 80 node);
79 parent = entry->dev; 81 pdevinfo.parent = entry->dev;
80 } 82 }
81 mutex_unlock(&acpi_parent->physical_node_lock); 83 mutex_unlock(&acpi_parent->physical_node_lock);
82 } 84 }
83 pdev = platform_device_register_resndata(parent, dev_name(&adev->dev), 85 pdevinfo.name = dev_name(&adev->dev);
84 -1, resources, count, NULL, 0); 86 pdevinfo.id = -1;
87 pdevinfo.res = resources;
88 pdevinfo.num_res = count;
89 pdevinfo.acpi_node.handle = adev->handle;
90 pdev = platform_device_register_full(&pdevinfo);
85 if (IS_ERR(pdev)) { 91 if (IS_ERR(pdev)) {
86 dev_err(&adev->dev, "platform device creation failed: %ld\n", 92 dev_err(&adev->dev, "platform device creation failed: %ld\n",
87 PTR_ERR(pdev)); 93 PTR_ERR(pdev));
@@ -94,65 +100,3 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
94 kfree(resources); 100 kfree(resources);
95 return pdev; 101 return pdev;
96} 102}
97
98static acpi_status acpi_platform_match(acpi_handle handle, u32 depth,
99 void *data, void **return_value)
100{
101 struct platform_device *pdev = data;
102 struct acpi_device *adev;
103 acpi_status status;
104
105 status = acpi_bus_get_device(handle, &adev);
106 if (ACPI_FAILURE(status))
107 return status;
108
109 /* Skip ACPI devices that have physical device attached */
110 if (adev->physical_node_count)
111 return AE_OK;
112
113 if (!strcmp(dev_name(&pdev->dev), dev_name(&adev->dev))) {
114 *(acpi_handle *)return_value = handle;
115 return AE_CTRL_TERMINATE;
116 }
117
118 return AE_OK;
119}
120
121static int acpi_platform_find_device(struct device *dev, acpi_handle *handle)
122{
123 struct platform_device *pdev = to_platform_device(dev);
124 char *name, *tmp, *hid;
125
126 /*
127 * The platform device is named using the ACPI device name
128 * _HID:INSTANCE so we strip the INSTANCE out in order to find the
129 * correct device using its _HID.
130 */
131 name = kstrdup(dev_name(dev), GFP_KERNEL);
132 if (!name)
133 return -ENOMEM;
134
135 tmp = name;
136 hid = strsep(&tmp, ":");
137 if (!hid) {
138 kfree(name);
139 return -ENODEV;
140 }
141
142 *handle = NULL;
143 acpi_get_devices(hid, acpi_platform_match, pdev, handle);
144
145 kfree(name);
146 return *handle ? 0 : -ENODEV;
147}
148
149static struct acpi_bus_type acpi_platform_bus = {
150 .bus = &platform_bus_type,
151 .find_device = acpi_platform_find_device,
152};
153
154static int __init acpi_platform_init(void)
155{
156 return register_acpi_bus_type(&acpi_platform_bus);
157}
158arch_initcall(acpi_platform_init);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 7de29ebfce7f..49fd96e23460 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -437,6 +437,7 @@ struct platform_device *platform_device_register_full(
437 goto err_alloc; 437 goto err_alloc;
438 438
439 pdev->dev.parent = pdevinfo->parent; 439 pdev->dev.parent = pdevinfo->parent;
440 ACPI_HANDLE_SET(&pdev->dev, pdevinfo->acpi_node.handle);
440 441
441 if (pdevinfo->dma_mask) { 442 if (pdevinfo->dma_mask) {
442 /* 443 /*
@@ -467,6 +468,7 @@ struct platform_device *platform_device_register_full(
467 ret = platform_device_add(pdev); 468 ret = platform_device_add(pdev);
468 if (ret) { 469 if (ret) {
469err: 470err:
471 ACPI_HANDLE_SET(&pdev->dev, NULL);
470 kfree(pdev->dev.dma_mask); 472 kfree(pdev->dev.dma_mask);
471 473
472err_alloc: 474err_alloc:
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 5711e9525a2a..a9ded9a3c175 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -55,6 +55,7 @@ extern int platform_add_devices(struct platform_device **, int);
55 55
56struct platform_device_info { 56struct platform_device_info {
57 struct device *parent; 57 struct device *parent;
58 struct acpi_dev_node acpi_node;
58 59
59 const char *name; 60 const char *name;
60 int id; 61 int id;