Commit 76dfdc2c6ed8cd9dde0d18091c2cf41b1e378be4

Authored by Rafael J. Wysocki

Merge branches 'acpi-scan' and 'acpi-ec'

* acpi-scan:
  ACPI: Use ACPI companion to match only the first physical device

* acpi-ec:
  ACPI / EC: Fix regression due to conflicting firmware behavior between Samsung and Acer.
  Revert "ACPI / EC: Add support to disallow QR_EC to be issued before completing previous QR_EC"

Showing 2 changed files Side-by-side Diff

... ... @@ -126,6 +126,7 @@
126 126 static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */
127 127 static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */
128 128 static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
  129 +static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */
129 130  
130 131 /* --------------------------------------------------------------------------
131 132 * Transaction Management
... ... @@ -236,13 +237,8 @@
236 237 }
237 238 return wakeup;
238 239 } else {
239   - /*
240   - * There is firmware refusing to respond QR_EC when SCI_EVT
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) &&
  240 + if (EC_FLAGS_QUERY_HANDSHAKE &&
  241 + !(status & ACPI_EC_FLAG_SCI) &&
246 242 (t->command == ACPI_EC_COMMAND_QUERY)) {
247 243 t->flags |= ACPI_EC_COMMAND_POLL;
248 244 t->rdata[t->ri++] = 0x00;
249 245  
... ... @@ -334,13 +330,13 @@
334 330 pr_debug("***** Command(%s) started *****\n",
335 331 acpi_ec_cmd_string(t->command));
336 332 start_transaction(ec);
337   - spin_unlock_irqrestore(&ec->lock, tmp);
338   - ret = ec_poll(ec);
339   - spin_lock_irqsave(&ec->lock, tmp);
340 333 if (ec->curr->command == ACPI_EC_COMMAND_QUERY) {
341 334 clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
342 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 340 pr_debug("***** Command(%s) stopped *****\n",
345 341 acpi_ec_cmd_string(t->command));
346 342 ec->curr = NULL;
... ... @@ -1012,6 +1008,18 @@
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 + */
  1015 +static 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 1023 * On some hardware it is necessary to clear events accumulated by the EC during
1016 1024 * sleep. These ECs stop reporting GPEs until they are manually polled, if too
1017 1025 * many events are accumulated. (e.g. Samsung Series 5/9 notebooks)
... ... @@ -1085,6 +1093,9 @@
1085 1093 {
1086 1094 ec_clear_on_resume, "Samsung hardware", {
1087 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  
... ... @@ -142,6 +142,53 @@
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 + */
  164 +static 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 192 * Creates uevent modalias field for ACPI enumerated devices.
146 193 * Because the other buses does not support ACPI HIDs & CIDs.
147 194 * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get:
148 195  
149 196  
150 197  
... ... @@ -149,20 +196,14 @@
149 196 */
150 197 int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
151 198 {
152   - struct acpi_device *acpi_dev;
153 199 int len;
154 200  
155   - acpi_dev = ACPI_COMPANION(dev);
156   - if (!acpi_dev)
  201 + if (!acpi_companion_match(dev))
157 202 return -ENODEV;
158 203  
159   - /* Fall back to bus specific way of modalias exporting */
160   - if (list_empty(&acpi_dev->pnp.ids))
161   - return -ENODEV;
162   -
163 204 if (add_uevent_var(env, "MODALIAS="))
164 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 207 sizeof(env->buf) - env->buflen);
167 208 if (len <= 0)
168 209 return len;
169 210  
170 211  
... ... @@ -179,18 +220,12 @@
179 220 */
180 221 int acpi_device_modalias(struct device *dev, char *buf, int size)
181 222 {
182   - struct acpi_device *acpi_dev;
183 223 int len;
184 224  
185   - acpi_dev = ACPI_COMPANION(dev);
186   - if (!acpi_dev)
  225 + if (!acpi_companion_match(dev))
187 226 return -ENODEV;
188 227  
189   - /* Fall back to bus specific way of modalias exporting */
190   - if (list_empty(&acpi_dev->pnp.ids))
191   - return -ENODEV;
192   -
193   - len = create_modalias(acpi_dev, buf, size -1);
  228 + len = create_modalias(ACPI_COMPANION(dev), buf, size -1);
194 229 if (len <= 0)
195 230 return len;
196 231 buf[len++] = '\n';
... ... @@ -851,6 +886,9 @@
851 886 acpi_handle handle = ACPI_HANDLE(dev);
852 887  
853 888 if (!ids || !handle || acpi_bus_get_device(handle, &adev))
  889 + return NULL;
  890 +
  891 + if (!acpi_companion_match(dev))
854 892 return NULL;
855 893  
856 894 return __acpi_match_device(adev, ids);