aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/acpi_platform.c62
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
123static 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,
266static int acpi_platform_find_device(struct device *dev, acpi_handle *handle) 230static 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