diff options
-rw-r--r-- | drivers/acpi/acpi_platform.c | 62 |
1 files changed, 22 insertions, 40 deletions
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index a5a23462287d..dbb31d61e310 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c | |||
@@ -120,25 +120,6 @@ static acpi_status acpi_platform_add_resources(struct acpi_resource *res, | |||
120 | return AE_OK; | 120 | return AE_OK; |
121 | } | 121 | } |
122 | 122 | ||
123 | static acpi_status acpi_platform_get_device_uid(struct acpi_device *adev, | ||
124 | int *uid) | ||
125 | { | ||
126 | struct acpi_device_info *info; | ||
127 | acpi_status status; | ||
128 | |||
129 | status = acpi_get_object_info(adev->handle, &info); | ||
130 | if (ACPI_FAILURE(status)) | ||
131 | return status; | ||
132 | |||
133 | status = AE_NOT_EXIST; | ||
134 | if ((info->valid & ACPI_VALID_UID) && | ||
135 | !kstrtoint(info->unique_id.string, 0, uid)) | ||
136 | status = AE_OK; | ||
137 | |||
138 | kfree(info); | ||
139 | return status; | ||
140 | } | ||
141 | |||
142 | /** | 123 | /** |
143 | * acpi_create_platform_device - Create platform device for ACPI device node | 124 | * acpi_create_platform_device - Create platform device for ACPI device node |
144 | * @adev: ACPI device node to create a platform device for. | 125 | * @adev: ACPI device node to create a platform device for. |
@@ -156,19 +137,12 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) | |||
156 | struct device *parent = NULL; | 137 | struct device *parent = NULL; |
157 | struct resource_info ri; | 138 | struct resource_info ri; |
158 | acpi_status status; | 139 | acpi_status status; |
159 | int devid; | ||
160 | 140 | ||
161 | /* If the ACPI node already has a physical device attached, skip it. */ | 141 | /* If the ACPI node already has a physical device attached, skip it. */ |
162 | if (adev->physical_node_count) | 142 | if (adev->physical_node_count) |
163 | return NULL; | 143 | return NULL; |
164 | 144 | ||
165 | /* Use the UID of the device as the new platform device id if found. */ | ||
166 | status = acpi_platform_get_device_uid(adev, &devid); | ||
167 | if (ACPI_FAILURE(status)) | ||
168 | devid = -1; | ||
169 | |||
170 | memset(&ri, 0, sizeof(ri)); | 145 | memset(&ri, 0, sizeof(ri)); |
171 | |||
172 | /* First, count the resources. */ | 146 | /* First, count the resources. */ |
173 | status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS, | 147 | status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS, |
174 | acpi_platform_count_resources, &ri); | 148 | acpi_platform_count_resources, &ri); |
@@ -214,8 +188,8 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) | |||
214 | } | 188 | } |
215 | mutex_unlock(&acpi_parent->physical_node_lock); | 189 | mutex_unlock(&acpi_parent->physical_node_lock); |
216 | } | 190 | } |
217 | pdev = platform_device_register_resndata(parent, acpi_device_hid(adev), | 191 | pdev = platform_device_register_resndata(parent, dev_name(&adev->dev), |
218 | devid, ri.res, ri.n, NULL, 0); | 192 | -1, ri.res, ri.n, NULL, 0); |
219 | if (IS_ERR(pdev)) { | 193 | if (IS_ERR(pdev)) { |
220 | dev_err(&adev->dev, "platform device creation failed: %ld\n", | 194 | dev_err(&adev->dev, "platform device creation failed: %ld\n", |
221 | PTR_ERR(pdev)); | 195 | PTR_ERR(pdev)); |
@@ -245,17 +219,7 @@ static acpi_status acpi_platform_match(acpi_handle handle, u32 depth, | |||
245 | if (adev->physical_node_count) | 219 | if (adev->physical_node_count) |
246 | return AE_OK; | 220 | return AE_OK; |
247 | 221 | ||
248 | if (!strcmp(pdev->name, acpi_device_hid(adev))) { | 222 | if (!strcmp(dev_name(&pdev->dev), dev_name(&adev->dev))) { |
249 | int devid; | ||
250 | |||
251 | /* Check that both name and UID match if it exists */ | ||
252 | status = acpi_platform_get_device_uid(adev, &devid); | ||
253 | if (ACPI_FAILURE(status)) | ||
254 | devid = -1; | ||
255 | |||
256 | if (pdev->id != devid) | ||
257 | return AE_OK; | ||
258 | |||
259 | *(acpi_handle *)return_value = handle; | 223 | *(acpi_handle *)return_value = handle; |
260 | return AE_CTRL_TERMINATE; | 224 | return AE_CTRL_TERMINATE; |
261 | } | 225 | } |
@@ -266,10 +230,28 @@ static acpi_status acpi_platform_match(acpi_handle handle, u32 depth, | |||
266 | static int acpi_platform_find_device(struct device *dev, acpi_handle *handle) | 230 | static int acpi_platform_find_device(struct device *dev, acpi_handle *handle) |
267 | { | 231 | { |
268 | struct platform_device *pdev = to_platform_device(dev); | 232 | struct platform_device *pdev = to_platform_device(dev); |
233 | char *name, *tmp, *hid; | ||
234 | |||
235 | /* | ||
236 | * The platform device is named using the ACPI device name | ||
237 | * _HID:INSTANCE so we strip the INSTANCE out in order to find the | ||
238 | * correct device using its _HID. | ||
239 | */ | ||
240 | name = kstrdup(dev_name(dev), GFP_KERNEL); | ||
241 | if (!name) | ||
242 | return -ENOMEM; | ||
243 | |||
244 | tmp = name; | ||
245 | hid = strsep(&tmp, ":"); | ||
246 | if (!hid) { | ||
247 | kfree(name); | ||
248 | return -ENODEV; | ||
249 | } | ||
269 | 250 | ||
270 | *handle = NULL; | 251 | *handle = NULL; |
271 | acpi_get_devices(pdev->name, acpi_platform_match, pdev, handle); | 252 | acpi_get_devices(hid, acpi_platform_match, pdev, handle); |
272 | 253 | ||
254 | kfree(name); | ||
273 | return *handle ? 0 : -ENODEV; | 255 | return *handle ? 0 : -ENODEV; |
274 | } | 256 | } |
275 | 257 | ||