aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/ec.c31
-rw-r--r--drivers/acpi/scan.c70
2 files changed, 75 insertions, 26 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 3d304ff7f095..5f9b74b9b71f 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -126,6 +126,7 @@ static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
126static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ 126static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */
127static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ 127static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */
128static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ 128static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
129static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */
129 130
130/* -------------------------------------------------------------------------- 131/* --------------------------------------------------------------------------
131 * Transaction Management 132 * Transaction Management
@@ -236,13 +237,8 @@ static bool advance_transaction(struct acpi_ec *ec)
236 } 237 }
237 return wakeup; 238 return wakeup;
238 } else { 239 } else {
239 /* 240 if (EC_FLAGS_QUERY_HANDSHAKE &&
240 * There is firmware refusing to respond QR_EC when SCI_EVT 241 !(status & ACPI_EC_FLAG_SCI) &&
241 * is not set, for which case, we complete the QR_EC
242 * without issuing it to the firmware.
243 * https://bugzilla.kernel.org/show_bug.cgi?id=86211
244 */
245 if (!(status & ACPI_EC_FLAG_SCI) &&
246 (t->command == ACPI_EC_COMMAND_QUERY)) { 242 (t->command == ACPI_EC_COMMAND_QUERY)) {
247 t->flags |= ACPI_EC_COMMAND_POLL; 243 t->flags |= ACPI_EC_COMMAND_POLL;
248 t->rdata[t->ri++] = 0x00; 244 t->rdata[t->ri++] = 0x00;
@@ -334,13 +330,13 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
334 pr_debug("***** Command(%s) started *****\n", 330 pr_debug("***** Command(%s) started *****\n",
335 acpi_ec_cmd_string(t->command)); 331 acpi_ec_cmd_string(t->command));
336 start_transaction(ec); 332 start_transaction(ec);
337 spin_unlock_irqrestore(&ec->lock, tmp);
338 ret = ec_poll(ec);
339 spin_lock_irqsave(&ec->lock, tmp);
340 if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { 333 if (ec->curr->command == ACPI_EC_COMMAND_QUERY) {
341 clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); 334 clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
342 pr_debug("***** Event stopped *****\n"); 335 pr_debug("***** Event stopped *****\n");
343 } 336 }
337 spin_unlock_irqrestore(&ec->lock, tmp);
338 ret = ec_poll(ec);
339 spin_lock_irqsave(&ec->lock, tmp);
344 pr_debug("***** Command(%s) stopped *****\n", 340 pr_debug("***** Command(%s) stopped *****\n",
345 acpi_ec_cmd_string(t->command)); 341 acpi_ec_cmd_string(t->command));
346 ec->curr = NULL; 342 ec->curr = NULL;
@@ -1012,6 +1008,18 @@ static int ec_enlarge_storm_threshold(const struct dmi_system_id *id)
1012} 1008}
1013 1009
1014/* 1010/*
1011 * Acer EC firmware refuses to respond QR_EC when SCI_EVT is not set, for
1012 * which case, we complete the QR_EC without issuing it to the firmware.
1013 * https://bugzilla.kernel.org/show_bug.cgi?id=86211
1014 */
1015static int ec_flag_query_handshake(const struct dmi_system_id *id)
1016{
1017 pr_debug("Detected the EC firmware requiring QR_EC issued when SCI_EVT set\n");
1018 EC_FLAGS_QUERY_HANDSHAKE = 1;
1019 return 0;
1020}
1021
1022/*
1015 * On some hardware it is necessary to clear events accumulated by the EC during 1023 * On some hardware it is necessary to clear events accumulated by the EC during
1016 * sleep. These ECs stop reporting GPEs until they are manually polled, if too 1024 * sleep. These ECs stop reporting GPEs until they are manually polled, if too
1017 * many events are accumulated. (e.g. Samsung Series 5/9 notebooks) 1025 * many events are accumulated. (e.g. Samsung Series 5/9 notebooks)
@@ -1085,6 +1093,9 @@ static struct dmi_system_id ec_dmi_table[] __initdata = {
1085 { 1093 {
1086 ec_clear_on_resume, "Samsung hardware", { 1094 ec_clear_on_resume, "Samsung hardware", {
1087 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL}, 1095 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL},
1096 {
1097 ec_flag_query_handshake, "Acer hardware", {
1098 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), }, NULL},
1088 {}, 1099 {},
1089}; 1100};
1090 1101
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index d670158a26c5..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);