aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c73
1 files changed, 56 insertions, 17 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index ae44d8654c82..0476e90b2091 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -142,6 +142,53 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
142} 142}
143 143
144/* 144/*
145 * acpi_companion_match() - Can we match via ACPI companion device
146 * @dev: Device in question
147 *
148 * Check if the given device has an ACPI companion and if that companion has
149 * a valid list of PNP IDs, and if the device is the first (primary) physical
150 * device associated with it.
151 *
152 * If multiple physical devices are attached to a single ACPI companion, we need
153 * to be careful. The usage scenario for this kind of relationship is that all
154 * of the physical devices in question use resources provided by the ACPI
155 * companion. A typical case is an MFD device where all the sub-devices share
156 * the parent's ACPI companion. In such cases we can only allow the primary
157 * (first) physical device to be matched with the help of the companion's PNP
158 * IDs.
159 *
160 * Additional physical devices sharing the ACPI companion can still use
161 * resources available from it but they will be matched normally using functions
162 * provided by their bus types (and analogously for their modalias).
163 */
164static bool acpi_companion_match(const struct device *dev)
165{
166 struct acpi_device *adev;
167 bool ret;
168
169 adev = ACPI_COMPANION(dev);
170 if (!adev)
171 return false;
172
173 if (list_empty(&adev->pnp.ids))
174 return false;
175
176 mutex_lock(&adev->physical_node_lock);
177 if (list_empty(&adev->physical_node_list)) {
178 ret = false;
179 } else {
180 const struct acpi_device_physical_node *node;
181
182 node = list_first_entry(&adev->physical_node_list,
183 struct acpi_device_physical_node, node);
184 ret = node->dev == dev;
185 }
186 mutex_unlock(&adev->physical_node_lock);
187
188 return ret;
189}
190
191/*
145 * Creates uevent modalias field for ACPI enumerated devices. 192 * Creates uevent modalias field for ACPI enumerated devices.
146 * Because the other buses does not support ACPI HIDs & CIDs. 193 * Because the other buses does not support ACPI HIDs & CIDs.
147 * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get: 194 * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get:
@@ -149,20 +196,14 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
149 */ 196 */
150int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) 197int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
151{ 198{
152 struct acpi_device *acpi_dev;
153 int len; 199 int len;
154 200
155 acpi_dev = ACPI_COMPANION(dev); 201 if (!acpi_companion_match(dev))
156 if (!acpi_dev)
157 return -ENODEV;
158
159 /* Fall back to bus specific way of modalias exporting */
160 if (list_empty(&acpi_dev->pnp.ids))
161 return -ENODEV; 202 return -ENODEV;
162 203
163 if (add_uevent_var(env, "MODALIAS=")) 204 if (add_uevent_var(env, "MODALIAS="))
164 return -ENOMEM; 205 return -ENOMEM;
165 len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], 206 len = create_modalias(ACPI_COMPANION(dev), &env->buf[env->buflen - 1],
166 sizeof(env->buf) - env->buflen); 207 sizeof(env->buf) - env->buflen);
167 if (len <= 0) 208 if (len <= 0)
168 return len; 209 return len;
@@ -179,18 +220,12 @@ EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias);
179 */ 220 */
180int acpi_device_modalias(struct device *dev, char *buf, int size) 221int acpi_device_modalias(struct device *dev, char *buf, int size)
181{ 222{
182 struct acpi_device *acpi_dev;
183 int len; 223 int len;
184 224
185 acpi_dev = ACPI_COMPANION(dev); 225 if (!acpi_companion_match(dev))
186 if (!acpi_dev)
187 return -ENODEV; 226 return -ENODEV;
188 227
189 /* Fall back to bus specific way of modalias exporting */ 228 len = create_modalias(ACPI_COMPANION(dev), buf, size -1);
190 if (list_empty(&acpi_dev->pnp.ids))
191 return -ENODEV;
192
193 len = create_modalias(acpi_dev, buf, size -1);
194 if (len <= 0) 229 if (len <= 0)
195 return len; 230 return len;
196 buf[len++] = '\n'; 231 buf[len++] = '\n';
@@ -853,6 +888,9 @@ const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
853 if (!ids || !handle || acpi_bus_get_device(handle, &adev)) 888 if (!ids || !handle || acpi_bus_get_device(handle, &adev))
854 return NULL; 889 return NULL;
855 890
891 if (!acpi_companion_match(dev))
892 return NULL;
893
856 return __acpi_match_device(adev, ids); 894 return __acpi_match_device(adev, ids);
857} 895}
858EXPORT_SYMBOL_GPL(acpi_match_device); 896EXPORT_SYMBOL_GPL(acpi_match_device);
@@ -1470,7 +1508,7 @@ static void acpi_wakeup_gpe_init(struct acpi_device *device)
1470 if (ACPI_FAILURE(status)) 1508 if (ACPI_FAILURE(status))
1471 return; 1509 return;
1472 1510
1473 wakeup->flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HANDLE); 1511 wakeup->flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HAS_HANDLER);
1474} 1512}
1475 1513
1476static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) 1514static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
@@ -2315,6 +2353,7 @@ int __init acpi_scan_init(void)
2315 acpi_container_init(); 2353 acpi_container_init();
2316 acpi_memory_hotplug_init(); 2354 acpi_memory_hotplug_init();
2317 acpi_pnp_init(); 2355 acpi_pnp_init();
2356 acpi_int340x_thermal_init();
2318 2357
2319 mutex_lock(&acpi_scan_lock); 2358 mutex_lock(&acpi_scan_lock);
2320 /* 2359 /*