diff options
-rw-r--r-- | drivers/acpi/acpi_platform.c | 76 | ||||
-rw-r--r-- | drivers/base/platform.c | 2 | ||||
-rw-r--r-- | include/linux/platform_device.h | 1 |
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 | |||
98 | static 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 | |||
121 | static 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 | |||
149 | static struct acpi_bus_type acpi_platform_bus = { | ||
150 | .bus = &platform_bus_type, | ||
151 | .find_device = acpi_platform_find_device, | ||
152 | }; | ||
153 | |||
154 | static int __init acpi_platform_init(void) | ||
155 | { | ||
156 | return register_acpi_bus_type(&acpi_platform_bus); | ||
157 | } | ||
158 | arch_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) { |
469 | err: | 470 | err: |
471 | ACPI_HANDLE_SET(&pdev->dev, NULL); | ||
470 | kfree(pdev->dev.dma_mask); | 472 | kfree(pdev->dev.dma_mask); |
471 | 473 | ||
472 | err_alloc: | 474 | err_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 | ||
56 | struct platform_device_info { | 56 | struct 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; |