Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'acpi-5.16-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more ACPI updates from Rafael Wysocki:
"These add support for a new ACPI device configuration object called
_DSC, fix some issues including one recent regression, add two new
items to quirk lists and clean up assorted pieces of code.

Specifics:

- Add support for new ACPI device configuration object called _DSC
("Deepest State for Configuration") to allow certain devices to be
probed without changing their power states, document it and make
two drivers use it (Sakari Ailus, Rajmohan Mani).

- Fix device wakeup power reference counting broken recently by
mistake (Rafael Wysocki).

- Drop unused symbol and macros depending on it from acgcc.h (Rafael
Wysocki).

- Add HP ZHAN 66 Pro to the "no EC wakeup" quirk list (Binbin Zhou).

- Add Xiaomi Mi Pad 2 to the backlight quirk list and drop an unused
piece of data from all of the list entries (Hans de Goede).

- Fix register read accesses handling in the Intel PMIC operation
region driver (Hans de Goede).

- Clean up static variables initialization in the EC driver
(wangzhitong)"

* tag 'acpi-5.16-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
Documentation: ACPI: Fix non-D0 probe _DSC object example
ACPI: Drop ACPI_USE_BUILTIN_STDARG ifdef from acgcc.h
ACPI: PM: Fix device wakeup power reference counting error
ACPI: video: use platform backlight driver on Xiaomi Mi Pad 2
ACPI: video: Drop dmi_system_id.ident settings from video_detect_dmi_table[]
ACPI: PMIC: Fix intel_pmic_regs_handler() read accesses
ACPI: EC: Remove initialization of static variables to false
ACPI: EC: Use ec_no_wakeup on HP ZHAN 66 Pro
at24: Support probing while in non-zero ACPI D state
media: i2c: imx319: Support device probe in non-zero ACPI D state
ACPI: Add a convenience function to tell a device is in D0 state
Documentation: ACPI: Document _DSC object usage for enum power state
i2c: Allow an ACPI driver to manage the device's power state during probe
ACPI: scan: Obtain device's desired enumeration power state

+302 -130
+1
Documentation/firmware-guide/acpi/index.rst
··· 26 26 acpi-lid 27 27 lpit 28 28 video_extension 29 + non-d0-probe 29 30 extcon-intel-int3496 30 31 intel-pmc-mux
+78
Documentation/firmware-guide/acpi/non-d0-probe.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + ======================================== 4 + Probing devices in other D states than 0 5 + ======================================== 6 + 7 + Introduction 8 + ============ 9 + 10 + In some cases it may be preferred to leave certain devices powered off for the 11 + entire system bootup if powering on these devices has adverse side effects, 12 + beyond just powering on the said device. 13 + 14 + How it works 15 + ============ 16 + 17 + The _DSC (Device State for Configuration) object that evaluates to an integer 18 + may be used to tell Linux the highest allowed D state for a device during 19 + probe. The support for _DSC requires support from the kernel bus type if the 20 + bus driver normally sets the device in D0 state for probe. 21 + 22 + The downside of using _DSC is that as the device is not powered on, even if 23 + there's a problem with the device, the driver likely probes just fine but the 24 + first user will find out the device doesn't work, instead of a failure at probe 25 + time. This feature should thus be used sparingly. 26 + 27 + I²C 28 + --- 29 + 30 + If an I²C driver indicates its support for this by setting the 31 + I2C_DRV_ACPI_WAIVE_D0_PROBE flag in struct i2c_driver.flags field and the 32 + _DSC object evaluates to integer higher than the D state of the device, 33 + the device will not be powered on (put in D0 state) for probe. 34 + 35 + D states 36 + -------- 37 + 38 + The D states and thus also the allowed values for _DSC are listed below. Refer 39 + to [1] for more information on device power states. 40 + 41 + .. code-block:: text 42 + 43 + Number State Description 44 + 0 D0 Device fully powered on 45 + 1 D1 46 + 2 D2 47 + 3 D3hot 48 + 4 D3cold Off 49 + 50 + References 51 + ========== 52 + 53 + [1] https://uefi.org/specifications/ACPI/6.4/02_Definition_of_Terms/Definition_of_Terms.html#device-power-state-definitions 54 + 55 + Example 56 + ======= 57 + 58 + An ASL example describing an ACPI device using _DSC object to tell Operating 59 + System the device should remain powered off during probe looks like this. Some 60 + objects not relevant from the example point of view have been omitted. 61 + 62 + .. code-block:: text 63 + 64 + Device (CAM0) 65 + { 66 + Name (_HID, "SONY319A") 67 + Name (_UID, Zero) 68 + Name (_CRS, ResourceTemplate () 69 + { 70 + I2cSerialBus(0x0020, ControllerInitiated, 0x00061A80, 71 + AddressingMode7Bit, "\\_SB.PCI0.I2C0", 72 + 0x00, ResourceConsumer) 73 + }) 74 + Method (_DSC, 0, NotSerialized) 75 + { 76 + Return (0x4) 77 + } 78 + }
+26
drivers/acpi/device_pm.c
··· 1400 1400 } 1401 1401 EXPORT_SYMBOL_GPL(acpi_storage_d3); 1402 1402 1403 + /** 1404 + * acpi_dev_state_d0 - Tell if the device is in D0 power state 1405 + * @dev: Physical device the ACPI power state of which to check 1406 + * 1407 + * On a system without ACPI, return true. On a system with ACPI, return true if 1408 + * the current ACPI power state of the device is D0, or false otherwise. 1409 + * 1410 + * Note that the power state of a device is not well-defined after it has been 1411 + * passed to acpi_device_set_power() and before that function returns, so it is 1412 + * not valid to ask for the ACPI power state of the device in that time frame. 1413 + * 1414 + * This function is intended to be used in a driver's probe or remove 1415 + * function. See Documentation/firmware-guide/acpi/low-power-probe.rst for 1416 + * more information. 1417 + */ 1418 + bool acpi_dev_state_d0(struct device *dev) 1419 + { 1420 + struct acpi_device *adev = ACPI_COMPANION(dev); 1421 + 1422 + if (!adev) 1423 + return true; 1424 + 1425 + return adev->power.state == ACPI_STATE_D0; 1426 + } 1427 + EXPORT_SYMBOL_GPL(acpi_dev_state_d0); 1428 + 1403 1429 #endif /* CONFIG_PM */
+9 -2
drivers/acpi/ec.c
··· 133 133 module_param(ec_storm_threshold, uint, 0644); 134 134 MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm"); 135 135 136 - static bool ec_freeze_events __read_mostly = false; 136 + static bool ec_freeze_events __read_mostly; 137 137 module_param(ec_freeze_events, bool, 0644); 138 138 MODULE_PARM_DESC(ec_freeze_events, "Disabling event handling during suspend/resume"); 139 139 ··· 177 177 EXPORT_SYMBOL(first_ec); 178 178 179 179 static struct acpi_ec *boot_ec; 180 - static bool boot_ec_is_ecdt = false; 180 + static bool boot_ec_is_ecdt; 181 181 static struct workqueue_struct *ec_wq; 182 182 static struct workqueue_struct *ec_query_wq; 183 183 ··· 2150 2150 .matches = { 2151 2151 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 2152 2152 DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Yoga 3rd"), 2153 + }, 2154 + }, 2155 + { 2156 + .ident = "HP ZHAN 66 Pro", 2157 + .matches = { 2158 + DMI_MATCH(DMI_SYS_VENDOR, "HP"), 2159 + DMI_MATCH(DMI_PRODUCT_FAMILY, "103C_5336AN HP ZHAN 66 Pro"), 2153 2160 }, 2154 2161 }, 2155 2162 { },
+28 -23
drivers/acpi/pmic/intel_pmic.c
··· 211 211 void *handler_context, void *region_context) 212 212 { 213 213 struct intel_pmic_opregion *opregion = region_context; 214 - int result = 0; 214 + int result = -EINVAL; 215 215 216 - switch (address) { 217 - case 0: 218 - return AE_OK; 219 - case 1: 220 - opregion->ctx.addr |= (*value64 & 0xff) << 8; 221 - return AE_OK; 222 - case 2: 223 - opregion->ctx.addr |= *value64 & 0xff; 224 - return AE_OK; 225 - case 3: 226 - opregion->ctx.val = *value64 & 0xff; 227 - return AE_OK; 228 - case 4: 229 - if (*value64) { 230 - result = regmap_write(opregion->regmap, opregion->ctx.addr, 231 - opregion->ctx.val); 232 - } else { 233 - result = regmap_read(opregion->regmap, opregion->ctx.addr, 234 - &opregion->ctx.val); 235 - if (result == 0) 236 - *value64 = opregion->ctx.val; 216 + if (function == ACPI_WRITE) { 217 + switch (address) { 218 + case 0: 219 + return AE_OK; 220 + case 1: 221 + opregion->ctx.addr |= (*value64 & 0xff) << 8; 222 + return AE_OK; 223 + case 2: 224 + opregion->ctx.addr |= *value64 & 0xff; 225 + return AE_OK; 226 + case 3: 227 + opregion->ctx.val = *value64 & 0xff; 228 + return AE_OK; 229 + case 4: 230 + if (*value64) { 231 + result = regmap_write(opregion->regmap, opregion->ctx.addr, 232 + opregion->ctx.val); 233 + } else { 234 + result = regmap_read(opregion->regmap, opregion->ctx.addr, 235 + &opregion->ctx.val); 236 + } 237 + opregion->ctx.addr = 0; 237 238 } 238 - memset(&opregion->ctx, 0x00, sizeof(opregion->ctx)); 239 + } 240 + 241 + if (function == ACPI_READ && address == 3) { 242 + *value64 = opregion->ctx.val; 243 + return AE_OK; 239 244 } 240 245 241 246 if (result < 0) {
+4 -6
drivers/acpi/power.c
··· 757 757 758 758 mutex_lock(&acpi_device_lock); 759 759 760 - if (dev->wakeup.prepare_count > 1) { 761 - dev->wakeup.prepare_count--; 762 - goto out; 763 - } 764 - 765 760 /* Do nothing if wakeup power has not been enabled for this device. */ 766 - if (!dev->wakeup.prepare_count) 761 + if (dev->wakeup.prepare_count <= 0) 762 + goto out; 763 + 764 + if (--dev->wakeup.prepare_count > 0) 767 765 goto out; 768 766 769 767 err = acpi_device_sleep_wake(dev, 0, 0, 0);
+4
drivers/acpi/scan.c
··· 1017 1017 1018 1018 static void acpi_bus_get_power_flags(struct acpi_device *device) 1019 1019 { 1020 + unsigned long long dsc = ACPI_STATE_D0; 1020 1021 u32 i; 1021 1022 1022 1023 /* Presence of _PS0|_PR0 indicates 'power manageable' */ ··· 1038 1037 1039 1038 if (acpi_has_method(device->handle, "_DSW")) 1040 1039 device->power.flags.dsw_present = 1; 1040 + 1041 + acpi_evaluate_integer(device->handle, "_DSC", NULL, &dsc); 1042 + device->power.state_for_enumeration = dsc; 1041 1043 1042 1044 /* 1043 1045 * Enumerate supported power management states
+43 -35
drivers/acpi/video_detect.c
··· 115 115 */ 116 116 { 117 117 .callback = video_detect_force_vendor, 118 - .ident = "X360", 118 + /* X360 */ 119 119 .matches = { 120 120 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), 121 121 DMI_MATCH(DMI_PRODUCT_NAME, "X360"), ··· 124 124 }, 125 125 { 126 126 .callback = video_detect_force_vendor, 127 - .ident = "Asus UL30VT", 127 + /* Asus UL30VT */ 128 128 .matches = { 129 129 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 130 130 DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"), ··· 132 132 }, 133 133 { 134 134 .callback = video_detect_force_vendor, 135 - .ident = "Asus UL30A", 135 + /* Asus UL30A */ 136 136 .matches = { 137 137 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 138 138 DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), ··· 140 140 }, 141 141 { 142 142 .callback = video_detect_force_vendor, 143 - .ident = "GIGABYTE GB-BXBT-2807", 143 + /* GIGABYTE GB-BXBT-2807 */ 144 144 .matches = { 145 145 DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), 146 146 DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"), ··· 148 148 }, 149 149 { 150 150 .callback = video_detect_force_vendor, 151 - .ident = "Sony VPCEH3U1E", 151 + /* Sony VPCEH3U1E */ 152 152 .matches = { 153 153 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 154 154 DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"), 155 + }, 156 + }, 157 + { 158 + .callback = video_detect_force_vendor, 159 + /* Xiaomi Mi Pad 2 */ 160 + .matches = { 161 + DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"), 162 + DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"), 155 163 }, 156 164 }, 157 165 ··· 172 164 */ 173 165 { 174 166 .callback = video_detect_force_video, 175 - .ident = "ThinkPad T420", 167 + /* ThinkPad T420 */ 176 168 .matches = { 177 169 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 178 170 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T420"), ··· 180 172 }, 181 173 { 182 174 .callback = video_detect_force_video, 183 - .ident = "ThinkPad T520", 175 + /* ThinkPad T520 */ 184 176 .matches = { 185 177 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 186 178 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T520"), ··· 188 180 }, 189 181 { 190 182 .callback = video_detect_force_video, 191 - .ident = "ThinkPad X201s", 183 + /* ThinkPad X201s */ 192 184 .matches = { 193 185 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 194 186 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201s"), ··· 196 188 }, 197 189 { 198 190 .callback = video_detect_force_video, 199 - .ident = "ThinkPad X201T", 191 + /* ThinkPad X201T */ 200 192 .matches = { 201 193 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 202 194 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201T"), ··· 207 199 { 208 200 /* https://bugs.freedesktop.org/show_bug.cgi?id=81515 */ 209 201 .callback = video_detect_force_video, 210 - .ident = "HP ENVY 15 Notebook", 202 + /* HP ENVY 15 Notebook */ 211 203 .matches = { 212 204 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 213 205 DMI_MATCH(DMI_PRODUCT_NAME, "HP ENVY 15 Notebook PC"), ··· 215 207 }, 216 208 { 217 209 .callback = video_detect_force_video, 218 - .ident = "SAMSUNG 870Z5E/880Z5E/680Z5E", 210 + /* SAMSUNG 870Z5E/880Z5E/680Z5E */ 219 211 .matches = { 220 212 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), 221 213 DMI_MATCH(DMI_PRODUCT_NAME, "870Z5E/880Z5E/680Z5E"), ··· 223 215 }, 224 216 { 225 217 .callback = video_detect_force_video, 226 - .ident = "SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V", 218 + /* SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V */ 227 219 .matches = { 228 220 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), 229 221 DMI_MATCH(DMI_PRODUCT_NAME, ··· 233 225 { 234 226 /* https://bugzilla.redhat.com/show_bug.cgi?id=1186097 */ 235 227 .callback = video_detect_force_video, 236 - .ident = "SAMSUNG 3570R/370R/470R/450R/510R/4450RV", 228 + /* SAMSUNG 3570R/370R/470R/450R/510R/4450RV */ 237 229 .matches = { 238 230 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), 239 231 DMI_MATCH(DMI_PRODUCT_NAME, ··· 243 235 { 244 236 /* https://bugzilla.redhat.com/show_bug.cgi?id=1557060 */ 245 237 .callback = video_detect_force_video, 246 - .ident = "SAMSUNG 670Z5E", 238 + /* SAMSUNG 670Z5E */ 247 239 .matches = { 248 240 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), 249 241 DMI_MATCH(DMI_PRODUCT_NAME, "670Z5E"), ··· 252 244 { 253 245 /* https://bugzilla.redhat.com/show_bug.cgi?id=1094948 */ 254 246 .callback = video_detect_force_video, 255 - .ident = "SAMSUNG 730U3E/740U3E", 247 + /* SAMSUNG 730U3E/740U3E */ 256 248 .matches = { 257 249 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), 258 250 DMI_MATCH(DMI_PRODUCT_NAME, "730U3E/740U3E"), ··· 261 253 { 262 254 /* https://bugs.freedesktop.org/show_bug.cgi?id=87286 */ 263 255 .callback = video_detect_force_video, 264 - .ident = "SAMSUNG 900X3C/900X3D/900X3E/900X4C/900X4D", 256 + /* SAMSUNG 900X3C/900X3D/900X3E/900X4C/900X4D */ 265 257 .matches = { 266 258 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), 267 259 DMI_MATCH(DMI_PRODUCT_NAME, ··· 271 263 { 272 264 /* https://bugzilla.redhat.com/show_bug.cgi?id=1272633 */ 273 265 .callback = video_detect_force_video, 274 - .ident = "Dell XPS14 L421X", 266 + /* Dell XPS14 L421X */ 275 267 .matches = { 276 268 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 277 269 DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"), ··· 280 272 { 281 273 /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */ 282 274 .callback = video_detect_force_video, 283 - .ident = "Dell XPS15 L521X", 275 + /* Dell XPS15 L521X */ 284 276 .matches = { 285 277 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 286 278 DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"), ··· 289 281 { 290 282 /* https://bugzilla.kernel.org/show_bug.cgi?id=108971 */ 291 283 .callback = video_detect_force_video, 292 - .ident = "SAMSUNG 530U4E/540U4E", 284 + /* SAMSUNG 530U4E/540U4E */ 293 285 .matches = { 294 286 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), 295 287 DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"), ··· 298 290 /* https://bugs.launchpad.net/bugs/1894667 */ 299 291 { 300 292 .callback = video_detect_force_video, 301 - .ident = "HP 635 Notebook", 293 + /* HP 635 Notebook */ 302 294 .matches = { 303 295 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 304 296 DMI_MATCH(DMI_PRODUCT_NAME, "HP 635 Notebook PC"), ··· 309 301 { 310 302 /* https://bugzilla.redhat.com/show_bug.cgi?id=1201530 */ 311 303 .callback = video_detect_force_native, 312 - .ident = "Lenovo Ideapad S405", 304 + /* Lenovo Ideapad S405 */ 313 305 .matches = { 314 306 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 315 307 DMI_MATCH(DMI_BOARD_NAME, "Lenovo IdeaPad S405"), ··· 318 310 { 319 311 /* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */ 320 312 .callback = video_detect_force_native, 321 - .ident = "Lenovo Ideapad Z570", 313 + /* Lenovo Ideapad Z570 */ 322 314 .matches = { 323 315 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 324 316 DMI_MATCH(DMI_PRODUCT_NAME, "102434U"), ··· 326 318 }, 327 319 { 328 320 .callback = video_detect_force_native, 329 - .ident = "Lenovo E41-25", 321 + /* Lenovo E41-25 */ 330 322 .matches = { 331 323 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 332 324 DMI_MATCH(DMI_PRODUCT_NAME, "81FS"), ··· 334 326 }, 335 327 { 336 328 .callback = video_detect_force_native, 337 - .ident = "Lenovo E41-45", 329 + /* Lenovo E41-45 */ 338 330 .matches = { 339 331 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 340 332 DMI_MATCH(DMI_PRODUCT_NAME, "82BK"), ··· 343 335 { 344 336 /* https://bugzilla.redhat.com/show_bug.cgi?id=1217249 */ 345 337 .callback = video_detect_force_native, 346 - .ident = "Apple MacBook Pro 12,1", 338 + /* Apple MacBook Pro 12,1 */ 347 339 .matches = { 348 340 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), 349 341 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"), ··· 351 343 }, 352 344 { 353 345 .callback = video_detect_force_native, 354 - .ident = "Dell Vostro V131", 346 + /* Dell Vostro V131 */ 355 347 .matches = { 356 348 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 357 349 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"), ··· 360 352 { 361 353 /* https://bugzilla.redhat.com/show_bug.cgi?id=1123661 */ 362 354 .callback = video_detect_force_native, 363 - .ident = "Dell XPS 17 L702X", 355 + /* Dell XPS 17 L702X */ 364 356 .matches = { 365 357 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 366 358 DMI_MATCH(DMI_PRODUCT_NAME, "Dell System XPS L702X"), ··· 368 360 }, 369 361 { 370 362 .callback = video_detect_force_native, 371 - .ident = "Dell Precision 7510", 363 + /* Dell Precision 7510 */ 372 364 .matches = { 373 365 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 374 366 DMI_MATCH(DMI_PRODUCT_NAME, "Precision 7510"), ··· 376 368 }, 377 369 { 378 370 .callback = video_detect_force_native, 379 - .ident = "Acer Aspire 5738z", 371 + /* Acer Aspire 5738z */ 380 372 .matches = { 381 373 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 382 374 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"), ··· 386 378 { 387 379 /* https://bugzilla.kernel.org/show_bug.cgi?id=207835 */ 388 380 .callback = video_detect_force_native, 389 - .ident = "Acer TravelMate 5735Z", 381 + /* Acer TravelMate 5735Z */ 390 382 .matches = { 391 383 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 392 384 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5735Z"), ··· 395 387 }, 396 388 { 397 389 .callback = video_detect_force_native, 398 - .ident = "ASUSTeK COMPUTER INC. GA401", 390 + /* ASUSTeK COMPUTER INC. GA401 */ 399 391 .matches = { 400 392 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 401 393 DMI_MATCH(DMI_PRODUCT_NAME, "GA401"), ··· 403 395 }, 404 396 { 405 397 .callback = video_detect_force_native, 406 - .ident = "ASUSTeK COMPUTER INC. GA502", 398 + /* ASUSTeK COMPUTER INC. GA502 */ 407 399 .matches = { 408 400 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 409 401 DMI_MATCH(DMI_PRODUCT_NAME, "GA502"), ··· 411 403 }, 412 404 { 413 405 .callback = video_detect_force_native, 414 - .ident = "ASUSTeK COMPUTER INC. GA503", 406 + /* ASUSTeK COMPUTER INC. GA503 */ 415 407 .matches = { 416 408 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 417 409 DMI_MATCH(DMI_PRODUCT_NAME, "GA503"), ··· 424 416 */ 425 417 { 426 418 .callback = video_detect_force_none, 427 - .ident = "Dell OptiPlex 9020M", 419 + /* Dell OptiPlex 9020M */ 428 420 .matches = { 429 421 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 430 422 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"), ··· 432 424 }, 433 425 { 434 426 .callback = video_detect_force_none, 435 - .ident = "MSI MS-7721", 427 + /* MSI MS-7721 */ 436 428 .matches = { 437 429 DMI_MATCH(DMI_SYS_VENDOR, "MSI"), 438 430 DMI_MATCH(DMI_PRODUCT_NAME, "MS-7721"),
+10
drivers/i2c/i2c-core-acpi.c
··· 522 522 } 523 523 EXPORT_SYMBOL_GPL(i2c_acpi_new_device); 524 524 525 + bool i2c_acpi_waive_d0_probe(struct device *dev) 526 + { 527 + struct i2c_driver *driver = to_i2c_driver(dev->driver); 528 + struct acpi_device *adev = ACPI_COMPANION(dev); 529 + 530 + return driver->flags & I2C_DRV_ACPI_WAIVE_D0_PROBE && 531 + adev && adev->power.state_for_enumeration >= adev->power.state; 532 + } 533 + EXPORT_SYMBOL_GPL(i2c_acpi_waive_d0_probe); 534 + 525 535 #ifdef CONFIG_ACPI_I2C_OPREGION 526 536 static int acpi_gsb_i2c_read_bytes(struct i2c_client *client, 527 537 u8 cmd, u8 *data, u8 data_len)
+4 -3
drivers/i2c/i2c-core-base.c
··· 551 551 if (status < 0) 552 552 goto err_clear_wakeup_irq; 553 553 554 - status = dev_pm_domain_attach(&client->dev, true); 554 + status = dev_pm_domain_attach(&client->dev, 555 + !i2c_acpi_waive_d0_probe(dev)); 555 556 if (status) 556 557 goto err_clear_wakeup_irq; 557 558 ··· 591 590 err_release_driver_resources: 592 591 devres_release_group(&client->dev, client->devres_group_id); 593 592 err_detach_pm_domain: 594 - dev_pm_domain_detach(&client->dev, true); 593 + dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev)); 595 594 err_clear_wakeup_irq: 596 595 dev_pm_clear_wake_irq(&client->dev); 597 596 device_init_wakeup(&client->dev, false); ··· 622 621 623 622 devres_release_group(&client->dev, client->devres_group_id); 624 623 625 - dev_pm_domain_detach(&client->dev, true); 624 + dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev)); 626 625 if (!pm_runtime_status_suspended(&client->dev) && adap->bus_regulator) 627 626 regulator_disable(adap->bus_regulator); 628 627
+44 -30
drivers/media/i2c/imx319.c
··· 140 140 141 141 /* Streaming on/off */ 142 142 bool streaming; 143 + /* True if the device has been identified */ 144 + bool identified; 143 145 }; 144 146 145 147 static const struct imx319_reg imx319_global_regs[] = { ··· 2086 2084 return 0; 2087 2085 } 2088 2086 2087 + /* Verify chip ID */ 2088 + static int imx319_identify_module(struct imx319 *imx319) 2089 + { 2090 + struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd); 2091 + int ret; 2092 + u32 val; 2093 + 2094 + if (imx319->identified) 2095 + return 0; 2096 + 2097 + ret = imx319_read_reg(imx319, IMX319_REG_CHIP_ID, 2, &val); 2098 + if (ret) 2099 + return ret; 2100 + 2101 + if (val != IMX319_CHIP_ID) { 2102 + dev_err(&client->dev, "chip id mismatch: %x!=%x", 2103 + IMX319_CHIP_ID, val); 2104 + return -EIO; 2105 + } 2106 + 2107 + imx319->identified = true; 2108 + 2109 + return 0; 2110 + } 2111 + 2089 2112 /* Start streaming */ 2090 2113 static int imx319_start_streaming(struct imx319 *imx319) 2091 2114 { 2092 2115 struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd); 2093 2116 const struct imx319_reg_list *reg_list; 2094 2117 int ret; 2118 + 2119 + ret = imx319_identify_module(imx319); 2120 + if (ret) 2121 + return ret; 2095 2122 2096 2123 /* Global Setting */ 2097 2124 reg_list = &imx319_global_setting; ··· 2235 2204 imx319_stop_streaming(imx319); 2236 2205 imx319->streaming = 0; 2237 2206 return ret; 2238 - } 2239 - 2240 - /* Verify chip ID */ 2241 - static int imx319_identify_module(struct imx319 *imx319) 2242 - { 2243 - struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd); 2244 - int ret; 2245 - u32 val; 2246 - 2247 - ret = imx319_read_reg(imx319, IMX319_REG_CHIP_ID, 2, &val); 2248 - if (ret) 2249 - return ret; 2250 - 2251 - if (val != IMX319_CHIP_ID) { 2252 - dev_err(&client->dev, "chip id mismatch: %x!=%x", 2253 - IMX319_CHIP_ID, val); 2254 - return -EIO; 2255 - } 2256 - 2257 - return 0; 2258 2207 } 2259 2208 2260 2209 static const struct v4l2_subdev_core_ops imx319_subdev_core_ops = { ··· 2431 2420 static int imx319_probe(struct i2c_client *client) 2432 2421 { 2433 2422 struct imx319 *imx319; 2423 + bool full_power; 2434 2424 int ret; 2435 2425 u32 i; 2436 2426 ··· 2444 2432 /* Initialize subdev */ 2445 2433 v4l2_i2c_subdev_init(&imx319->sd, client, &imx319_subdev_ops); 2446 2434 2447 - /* Check module identity */ 2448 - ret = imx319_identify_module(imx319); 2449 - if (ret) { 2450 - dev_err(&client->dev, "failed to find sensor: %d", ret); 2451 - goto error_probe; 2435 + full_power = acpi_dev_state_d0(&client->dev); 2436 + if (full_power) { 2437 + /* Check module identity */ 2438 + ret = imx319_identify_module(imx319); 2439 + if (ret) { 2440 + dev_err(&client->dev, "failed to find sensor: %d", ret); 2441 + goto error_probe; 2442 + } 2452 2443 } 2453 2444 2454 2445 imx319->hwcfg = imx319_get_hwcfg(&client->dev); ··· 2503 2488 if (ret < 0) 2504 2489 goto error_media_entity; 2505 2490 2506 - /* 2507 - * Device is already turned on by i2c-core with ACPI domain PM. 2508 - * Enable runtime PM and turn off the device. 2509 - */ 2510 - pm_runtime_set_active(&client->dev); 2491 + /* Set the device's state to active if it's in D0 state. */ 2492 + if (full_power) 2493 + pm_runtime_set_active(&client->dev); 2511 2494 pm_runtime_enable(&client->dev); 2512 2495 pm_runtime_idle(&client->dev); 2513 2496 ··· 2558 2545 }, 2559 2546 .probe_new = imx319_probe, 2560 2547 .remove = imx319_remove, 2548 + .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, 2561 2549 }; 2562 2550 module_i2c_driver(imx319_i2c_driver); 2563 2551
+27 -18
drivers/misc/eeprom/at24.c
··· 595 595 bool i2c_fn_i2c, i2c_fn_block; 596 596 unsigned int i, num_addresses; 597 597 struct at24_data *at24; 598 + bool full_power; 598 599 struct regmap *regmap; 599 600 bool writable; 600 601 u8 test_byte; ··· 748 747 749 748 i2c_set_clientdata(client, at24); 750 749 751 - err = regulator_enable(at24->vcc_reg); 752 - if (err) { 753 - dev_err(dev, "Failed to enable vcc regulator\n"); 754 - return err; 755 - } 750 + full_power = acpi_dev_state_d0(&client->dev); 751 + if (full_power) { 752 + err = regulator_enable(at24->vcc_reg); 753 + if (err) { 754 + dev_err(dev, "Failed to enable vcc regulator\n"); 755 + return err; 756 + } 756 757 757 - /* enable runtime pm */ 758 - pm_runtime_set_active(dev); 758 + pm_runtime_set_active(dev); 759 + } 759 760 pm_runtime_enable(dev); 760 761 761 762 at24->nvmem = devm_nvmem_register(dev, &nvmem_config); ··· 769 766 } 770 767 771 768 /* 772 - * Perform a one-byte test read to verify that the 773 - * chip is functional. 769 + * Perform a one-byte test read to verify that the chip is functional, 770 + * unless powering on the device is to be avoided during probe (i.e. 771 + * it's powered off right now). 774 772 */ 775 - err = at24_read(at24, 0, &test_byte, 1); 776 - if (err) { 777 - pm_runtime_disable(dev); 778 - if (!pm_runtime_status_suspended(dev)) 779 - regulator_disable(at24->vcc_reg); 780 - return -ENODEV; 773 + if (full_power) { 774 + err = at24_read(at24, 0, &test_byte, 1); 775 + if (err) { 776 + pm_runtime_disable(dev); 777 + if (!pm_runtime_status_suspended(dev)) 778 + regulator_disable(at24->vcc_reg); 779 + return -ENODEV; 780 + } 781 781 } 782 782 783 783 pm_runtime_idle(dev); ··· 800 794 struct at24_data *at24 = i2c_get_clientdata(client); 801 795 802 796 pm_runtime_disable(&client->dev); 803 - if (!pm_runtime_status_suspended(&client->dev)) 804 - regulator_disable(at24->vcc_reg); 805 - pm_runtime_set_suspended(&client->dev); 797 + if (acpi_dev_state_d0(&client->dev)) { 798 + if (!pm_runtime_status_suspended(&client->dev)) 799 + regulator_disable(at24->vcc_reg); 800 + pm_runtime_set_suspended(&client->dev); 801 + } 806 802 807 803 return 0; 808 804 } ··· 841 833 .probe_new = at24_probe, 842 834 .remove = at24_remove, 843 835 .id_table = at24_ids, 836 + .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, 844 837 }; 845 838 846 839 static int __init at24_init(void)
+1
include/acpi/acpi_bus.h
··· 278 278 int state; /* Current state */ 279 279 struct acpi_device_power_flags flags; 280 280 struct acpi_device_power_state states[ACPI_D_STATE_COUNT]; /* Power states (D0-D3Cold) */ 281 + u8 state_for_enumeration; /* Deepest power state for enumeration */ 281 282 }; 282 283 283 284 struct acpi_dep_data {
-13
include/acpi/platform/acgcc.h
··· 10 10 #ifndef __ACGCC_H__ 11 11 #define __ACGCC_H__ 12 12 13 - /* 14 - * Use compiler specific <stdarg.h> is a good practice for even when 15 - * -nostdinc is specified (i.e., ACPI_USE_STANDARD_HEADERS undefined. 16 - */ 17 13 #ifndef va_arg 18 - #ifdef ACPI_USE_BUILTIN_STDARG 19 - typedef __builtin_va_list va_list; 20 - #define va_start(v, l) __builtin_va_start(v, l) 21 - #define va_end(v) __builtin_va_end(v) 22 - #define va_arg(v, l) __builtin_va_arg(v, l) 23 - #define va_copy(d, s) __builtin_va_copy(d, s) 24 - #else 25 14 #ifdef __KERNEL__ 26 15 #include <linux/stdarg.h> 27 16 #else 28 - /* Used to build acpi tools */ 29 17 #include <stdarg.h> 30 18 #endif /* __KERNEL__ */ 31 - #endif /* ACPI_USE_BUILTIN_STDARG */ 32 19 #endif /* ! va_arg */ 33 20 34 21 #define ACPI_INLINE __inline__
+5
include/linux/acpi.h
··· 1014 1014 int acpi_subsys_runtime_resume(struct device *dev); 1015 1015 int acpi_dev_pm_attach(struct device *dev, bool power_on); 1016 1016 bool acpi_storage_d3(struct device *dev); 1017 + bool acpi_dev_state_d0(struct device *dev); 1017 1018 #else 1018 1019 static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; } 1019 1020 static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; } ··· 1025 1024 static inline bool acpi_storage_d3(struct device *dev) 1026 1025 { 1027 1026 return false; 1027 + } 1028 + static inline bool acpi_dev_state_d0(struct device *dev) 1029 + { 1030 + return true; 1028 1031 } 1029 1032 #endif 1030 1033
+18
include/linux/i2c.h
··· 11 11 #define _LINUX_I2C_H 12 12 13 13 #include <linux/acpi.h> /* for acpi_handle */ 14 + #include <linux/bits.h> 14 15 #include <linux/mod_devicetable.h> 15 16 #include <linux/device.h> /* for struct device */ 16 17 #include <linux/sched.h> /* for completion */ ··· 224 223 }; 225 224 226 225 /** 226 + * enum i2c_driver_flags - Flags for an I2C device driver 227 + * 228 + * @I2C_DRV_ACPI_WAIVE_D0_PROBE: Don't put the device in D0 state for probe 229 + */ 230 + enum i2c_driver_flags { 231 + I2C_DRV_ACPI_WAIVE_D0_PROBE = BIT(0), 232 + }; 233 + 234 + /** 227 235 * struct i2c_driver - represent an I2C device driver 228 236 * @class: What kind of i2c device we instantiate (for detect) 229 237 * @probe: Callback for device binding - soon to be deprecated ··· 246 236 * @detect: Callback for device detection 247 237 * @address_list: The I2C addresses to probe (for detect) 248 238 * @clients: List of detected clients we created (for i2c-core use only) 239 + * @flags: A bitmask of flags defined in &enum i2c_driver_flags 249 240 * 250 241 * The driver.owner field should be set to the module owner of this driver. 251 242 * The driver.name field should be set to the name of this driver. ··· 305 294 int (*detect)(struct i2c_client *client, struct i2c_board_info *info); 306 295 const unsigned short *address_list; 307 296 struct list_head clients; 297 + 298 + u32 flags; 308 299 }; 309 300 #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) 310 301 ··· 1028 1015 struct i2c_client *i2c_acpi_new_device(struct device *dev, int index, 1029 1016 struct i2c_board_info *info); 1030 1017 struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle); 1018 + bool i2c_acpi_waive_d0_probe(struct device *dev); 1031 1019 #else 1032 1020 static inline bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares, 1033 1021 struct acpi_resource_i2c_serialbus **i2c) ··· 1051 1037 static inline struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle) 1052 1038 { 1053 1039 return NULL; 1040 + } 1041 + static inline bool i2c_acpi_waive_d0_probe(struct device *dev) 1042 + { 1043 + return false; 1054 1044 } 1055 1045 #endif /* CONFIG_ACPI */ 1056 1046