Pull ACPI fixes from Rafael Wysocki: "These are new ACPI IRQ override quirks, low-power S0 idle (S0ix) support adjustments and ACPI backlight handling fixes, mostly for platforms using AMD chips. Specifics: - Add ACPI IRQ override quirks for Asus ExpertBook B2502, Lenovo 14ALC7, and XMG Core 15 (Hans de Goede, Adrian Freund, Erik Schumacher). - Adjust ACPI video detection fallback path to prevent non-operational ACPI backlight devices from being created on systems where the native driver does not detect a suitable panel (Mario Limonciello). - Fix Apple GMUX backlight detection (Hans de Goede). - Add a low-power S0 idle (S0ix) handling quirk for HP Elitebook 865 and stop using AMD-specific low-power S0 idle code path for systems with Rembrandt chips and newer (Mario Limonciello)" * tag 'acpi-6.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI: x86: s2idle: Stop using AMD specific codepath for Rembrandt+ ACPI: x86: s2idle: Force AMD GUID/_REV 2 on HP Elitebook 865 ACPI: video: Fix Apple GMUX backlight detection ACPI: resource: Add Asus ExpertBook B2502 to Asus quirks ACPI: resource: do IRQ override on Lenovo 14ALC7 ACPI: resource: do IRQ override on XMG Core 15 ACPI: video: Don't enable fallback path for creating ACPI backlight by default drm/amd/display: Report to ACPI video if no panels were found ACPI: video: Allow GPU drivers to report no panels
Unified · Split
| @@ -70,11 +70,7 @@ module_param(device_id_scheme, bool, 0444); · 69 unmodified lines | ||
| 70 | 70 | static int only_lcd = -1; |
| 71 | 71 | module_param(only_lcd, int, 0444); |
| 72 | 72 | |
| 73 | −/* | |
| 74 | − * Display probing is known to take up to 5 seconds, so delay the fallback | |
| 75 | − * backlight registration by 5 seconds + 3 seconds for some extra margin. | |
| 76 | − */ | |
| 77 | −static int register_backlight_delay = 8; | |
| 73 | +static int register_backlight_delay; | |
| 78 | 74 | module_param(register_backlight_delay, int, 0444); |
| 79 | 75 | MODULE_PARM_DESC(register_backlight_delay, |
| 80 | 76 | "Delay in seconds before doing fallback (non GPU driver triggered) " |
| @@ -2176,6 +2172,17 @@ static bool should_check_lcd_flag(void) · 2095 unmodified lines | ||
| 2176 | 2172 | return false; |
| 2177 | 2173 | } |
| 2178 | 2174 | |
| 2175 | +/* | |
| 2176 | + * At least one graphics driver has reported that no LCD is connected | |
| 2177 | + * via the native interface. cancel the registration for fallback acpi_video0. | |
| 2178 | + * If another driver still deems this necessary, it can explicitly register it. | |
| 2179 | + */ | |
| 2180 | +void acpi_video_report_nolcd(void) | |
| 2181 | +{ | |
| 2182 | + cancel_delayed_work(&video_bus_register_backlight_work); | |
| 2183 | +} | |
| 2184 | +EXPORT_SYMBOL(acpi_video_report_nolcd); | |
| 2185 | + | |
| 2179 | 2186 | int acpi_video_register(void) |
| 2180 | 2187 | { |
| 2181 | 2188 | int ret = 0; |
| @@ -432,10 +432,24 @@ static const struct dmi_system_id asus_laptop[] = { · 431 unmodified lines | ||
| 432 | 432 | DMI_MATCH(DMI_BOARD_NAME, "S5602ZA"), |
| 433 | 433 | }, |
| 434 | 434 | }, |
| 435 | + { | |
| 436 | + .ident = "Asus ExpertBook B2502", | |
| 437 | + .matches = { | |
| 438 | + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 439 | + DMI_MATCH(DMI_BOARD_NAME, "B2502CBA"), | |
| 440 | + }, | |
| 441 | + }, | |
| 435 | 442 | { } |
| 436 | 443 | }; |
| 437 | 444 | |
| 438 | −static const struct dmi_system_id lenovo_82ra[] = { | |
| 445 | +static const struct dmi_system_id lenovo_laptop[] = { | |
| 446 | + { | |
| 447 | + .ident = "LENOVO IdeaPad Flex 5 14ALC7", | |
| 448 | + .matches = { | |
| 449 | + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | |
| 450 | + DMI_MATCH(DMI_PRODUCT_NAME, "82R9"), | |
| 451 | + }, | |
| 452 | + }, | |
| 439 | 453 | { |
| 440 | 454 | .ident = "LENOVO IdeaPad Flex 5 16ALC7", |
| 441 | 455 | .matches = { |
| @@ -446,6 +460,17 @@ static const struct dmi_system_id lenovo_82ra[] = { · 4 unmodified lines | ||
| 446 | 460 | { } |
| 447 | 461 | }; |
| 448 | 462 | |
| 463 | +static const struct dmi_system_id schenker_gm_rg[] = { | |
| 464 | + { | |
| 465 | + .ident = "XMG CORE 15 (M22)", | |
| 466 | + .matches = { | |
| 467 | + DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"), | |
| 468 | + DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"), | |
| 469 | + }, | |
| 470 | + }, | |
| 471 | + { } | |
| 472 | +}; | |
| 473 | + | |
| 449 | 474 | struct irq_override_cmp { |
| 450 | 475 | const struct dmi_system_id *system; |
| 451 | 476 | unsigned char irq; |
| @@ -458,8 +483,9 @@ struct irq_override_cmp { · 6 unmodified lines | ||
| 458 | 483 | static const struct irq_override_cmp override_table[] = { |
| 459 | 484 | { medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false }, |
| 460 | 485 | { asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false }, |
| 461 | − { lenovo_82ra, 6, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true }, | |
| 462 | − { lenovo_82ra, 10, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true }, | |
| 486 | + { lenovo_laptop, 6, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true }, | |
| 487 | + { lenovo_laptop, 10, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true }, | |
| 488 | + { schenker_gm_rg, 1, ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_LOW, 1, true }, | |
| 463 | 489 | }; |
| 464 | 490 | |
| 465 | 491 | static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity, |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #include <linux/module.h> |
| 35 | 35 | #include <linux/pci.h> |
| 36 | 36 | #include <linux/platform_data/x86/nvidia-wmi-ec-backlight.h> |
| 37 | +#include <linux/pnp.h> | |
| 37 | 38 | #include <linux/types.h> |
| 38 | 39 | #include <linux/workqueue.h> |
| 39 | 40 | #include <acpi/video.h> |
| @@ -105,6 +106,26 @@ static bool nvidia_wmi_ec_supported(void) · 65 unmodified lines | ||
| 105 | 106 | } |
| 106 | 107 | #endif |
| 107 | 108 | |
| 109 | +static bool apple_gmux_backlight_present(void) | |
| 110 | +{ | |
| 111 | + struct acpi_device *adev; | |
| 112 | + struct device *dev; | |
| 113 | + | |
| 114 | + adev = acpi_dev_get_first_match_dev(GMUX_ACPI_HID, NULL, -1); | |
| 115 | + if (!adev) | |
| 116 | + return false; | |
| 117 | + | |
| 118 | + dev = acpi_get_first_physical_node(adev); | |
| 119 | + if (!dev) | |
| 120 | + return false; | |
| 121 | + | |
| 122 | + /* | |
| 123 | + * drivers/platform/x86/apple-gmux.c only supports old style | |
| 124 | + * Apple GMUX with an IO-resource. | |
| 125 | + */ | |
| 126 | + return pnp_get_resource(to_pnp_dev(dev), IORESOURCE_IO, 0) != NULL; | |
| 127 | +} | |
| 128 | + | |
| 108 | 129 | /* Force to use vendor driver when the ACPI device is known to be |
| 109 | 130 | * buggy */ |
| 110 | 131 | static int video_detect_force_vendor(const struct dmi_system_id *d) |
| @@ -767,7 +788,7 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native) · 656 unmodified lines | ||
| 767 | 788 | if (nvidia_wmi_ec_present) |
| 768 | 789 | return acpi_backlight_nvidia_wmi_ec; |
| 769 | 790 | |
| 770 | − if (apple_gmux_present()) | |
| 791 | + if (apple_gmux_backlight_present()) | |
| 771 | 792 | return acpi_backlight_apple_gmux; |
| 772 | 793 | |
| 773 | 794 | /* Use ACPI video if available, except when native should be preferred. */ |
| @@ -28,10 +28,6 @@ static bool sleep_no_lps0 __read_mostly; · 27 unmodified lines | ||
| 28 | 28 | module_param(sleep_no_lps0, bool, 0644); |
| 29 | 29 | MODULE_PARM_DESC(sleep_no_lps0, "Do not use the special LPS0 device interface"); |
| 30 | 30 | |
| 31 | −static bool prefer_microsoft_dsm_guid __read_mostly; | |
| 32 | −module_param(prefer_microsoft_dsm_guid, bool, 0644); | |
| 33 | −MODULE_PARM_DESC(prefer_microsoft_dsm_guid, "Prefer using Microsoft GUID in LPS0 device _DSM evaluation"); | |
| 34 | − | |
| 35 | 31 | static const struct acpi_device_id lps0_device_ids[] = { |
| 36 | 32 | {"PNP0D80", }, |
| 37 | 33 | {"", }, |
| @@ -369,27 +365,15 @@ out: · 331 unmodified lines | ||
| 369 | 365 | } |
| 370 | 366 | |
| 371 | 367 | struct amd_lps0_hid_device_data { |
| 372 | − const unsigned int rev_id; | |
| 373 | 368 | const bool check_off_by_one; |
| 374 | − const bool prefer_amd_guid; | |
| 375 | 369 | }; |
| 376 | 370 | |
| 377 | 371 | static const struct amd_lps0_hid_device_data amd_picasso = { |
| 378 | − .rev_id = 0, | |
| 379 | 372 | .check_off_by_one = true, |
| 380 | − .prefer_amd_guid = false, | |
| 381 | 373 | }; |
| 382 | 374 | |
| 383 | 375 | static const struct amd_lps0_hid_device_data amd_cezanne = { |
| 384 | − .rev_id = 0, | |
| 385 | − .check_off_by_one = false, | |
| 386 | − .prefer_amd_guid = false, | |
| 387 | −}; | |
| 388 | − | |
| 389 | −static const struct amd_lps0_hid_device_data amd_rembrandt = { | |
| 390 | − .rev_id = 2, | |
| 391 | 376 | .check_off_by_one = false, |
| 392 | − .prefer_amd_guid = true, | |
| 393 | 377 | }; |
| 394 | 378 | |
| 395 | 379 | static const struct acpi_device_id amd_hid_ids[] = { |
| @@ -397,69 +381,27 @@ static const struct acpi_device_id amd_hid_ids[] = { · 1 unmodified line | ||
| 397 | 381 | {"AMD0005", (kernel_ulong_t)&amd_picasso, }, |
| 398 | 382 | {"AMDI0005", (kernel_ulong_t)&amd_picasso, }, |
| 399 | 383 | {"AMDI0006", (kernel_ulong_t)&amd_cezanne, }, |
| 400 | − {"AMDI0007", (kernel_ulong_t)&amd_rembrandt, }, | |
| 401 | 384 | {} |
| 402 | 385 | }; |
| 403 | 386 | |
| 404 | −static int lps0_prefer_microsoft(const struct dmi_system_id *id) | |
| 387 | +static int lps0_prefer_amd(const struct dmi_system_id *id) | |
| 405 | 388 | { |
| 406 | − pr_debug("Preferring Microsoft GUID.\n"); | |
| 407 | − prefer_microsoft_dsm_guid = true; | |
| 389 | + pr_debug("Using AMD GUID w/ _REV 2.\n"); | |
| 390 | + rev_id = 2; | |
| 408 | 391 | return 0; |
| 409 | 392 | } |
| 410 | − | |
| 411 | 393 | static const struct dmi_system_id s2idle_dmi_table[] __initconst = { |
| 412 | 394 | { |
| 413 | 395 | /* |
| 414 | − * ASUS TUF Gaming A17 FA707RE | |
| 415 | − * https://bugzilla.kernel.org/show_bug.cgi?id=216101 | |
| 416 | − */ | |
| 417 | − .callback = lps0_prefer_microsoft, | |
| 418 | − .matches = { | |
| 419 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 420 | − DMI_MATCH(DMI_PRODUCT_NAME, "ASUS TUF Gaming A17"), | |
| 421 | − }, | |
| 422 | − }, | |
| 423 | − { | |
| 424 | − /* ASUS ROG Zephyrus G14 (2022) */ | |
| 425 | − .callback = lps0_prefer_microsoft, | |
| 426 | − .matches = { | |
| 427 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 428 | − DMI_MATCH(DMI_PRODUCT_NAME, "ROG Zephyrus G14 GA402"), | |
| 429 | − }, | |
| 430 | − }, | |
| 431 | − { | |
| 432 | − /* | |
| 433 | − * Lenovo Yoga Slim 7 Pro X 14ARH7 | |
| 434 | − * https://bugzilla.kernel.org/show_bug.cgi?id=216473 : 82V2 | |
| 435 | − * https://bugzilla.kernel.org/show_bug.cgi?id=216438 : 82TL | |
| 436 | − */ | |
| 437 | − .callback = lps0_prefer_microsoft, | |
| 438 | − .matches = { | |
| 439 | − DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | |
| 440 | − DMI_MATCH(DMI_PRODUCT_NAME, "82"), | |
| 441 | − }, | |
| 442 | − }, | |
| 443 | − { | |
| 444 | − /* | |
| 445 | − * ASUSTeK COMPUTER INC. ROG Flow X13 GV301RE_GV301RE | |
| 446 | − * https://gitlab.freedesktop.org/drm/amd/-/issues/2148 | |
| 396 | + * AMD Rembrandt based HP EliteBook 835/845/865 G9 | |
| 397 | + * Contains specialized AML in AMD/_REV 2 path to avoid | |
| 398 | + * triggering a bug in Qualcomm WLAN firmware. This may be | |
| 399 | + * removed in the future if that firmware is fixed. | |
| 447 | 400 | */ |
| 448 | − .callback = lps0_prefer_microsoft, | |
| 401 | + .callback = lps0_prefer_amd, | |
| 449 | 402 | .matches = { |
| 450 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 451 | − DMI_MATCH(DMI_PRODUCT_NAME, "ROG Flow X13 GV301"), | |
| 452 | − }, | |
| 453 | − }, | |
| 454 | − { | |
| 455 | − /* | |
| 456 | − * ASUSTeK COMPUTER INC. ROG Flow X16 GV601RW_GV601RW | |
| 457 | − * https://gitlab.freedesktop.org/drm/amd/-/issues/2148 | |
| 458 | − */ | |
| 459 | − .callback = lps0_prefer_microsoft, | |
| 460 | − .matches = { | |
| 461 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 462 | − DMI_MATCH(DMI_PRODUCT_NAME, "ROG Flow X16 GV601"), | |
| 403 | + DMI_MATCH(DMI_BOARD_VENDOR, "HP"), | |
| 404 | + DMI_MATCH(DMI_BOARD_NAME, "8990"), | |
| 463 | 405 | }, |
| 464 | 406 | }, |
| 465 | 407 | {} |
| @@ -484,16 +426,14 @@ static int lps0_device_attach(struct acpi_device *adev, · 18 unmodified lines | ||
| 484 | 426 | if (dev_id->id[0]) |
| 485 | 427 | data = (const struct amd_lps0_hid_device_data *) dev_id->driver_data; |
| 486 | 428 | else |
| 487 | − data = &amd_rembrandt; | |
| 488 | − rev_id = data->rev_id; | |
| 429 | + data = &amd_cezanne; | |
| 489 | 430 | lps0_dsm_func_mask = validate_dsm(adev->handle, |
| 490 | 431 | ACPI_LPS0_DSM_UUID_AMD, rev_id, &lps0_dsm_guid); |
| 491 | 432 | if (lps0_dsm_func_mask > 0x3 && data->check_off_by_one) { |
| 492 | 433 | lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1; |
| 493 | 434 | acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n", |
| 494 | 435 | ACPI_LPS0_DSM_UUID_AMD, lps0_dsm_func_mask); |
| 495 | − } else if (lps0_dsm_func_mask_microsoft > 0 && data->prefer_amd_guid && | |
| 496 | − !prefer_microsoft_dsm_guid) { | |
| 436 | + } else if (lps0_dsm_func_mask_microsoft > 0 && rev_id) { | |
| 497 | 437 | lps0_dsm_func_mask_microsoft = -EINVAL; |
| 498 | 438 | acpi_handle_debug(adev->handle, "_DSM Using AMD method\n"); |
| 499 | 439 | } |
| @@ -501,8 +441,7 @@ static int lps0_device_attach(struct acpi_device *adev, · 1 unmodified line | ||
| 501 | 441 | rev_id = 1; |
| 502 | 442 | lps0_dsm_func_mask = validate_dsm(adev->handle, |
| 503 | 443 | ACPI_LPS0_DSM_UUID, rev_id, &lps0_dsm_guid); |
| 504 | − if (!prefer_microsoft_dsm_guid) | |
| 505 | − lps0_dsm_func_mask_microsoft = -EINVAL; | |
| 444 | + lps0_dsm_func_mask_microsoft = -EINVAL; | |
| 506 | 445 | } |
| 507 | 446 | |
| 508 | 447 | if (lps0_dsm_func_mask < 0 && lps0_dsm_func_mask_microsoft < 0) |
| @@ -4361,6 +4361,10 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) · 4360 unmodified lines | ||
| 4361 | 4361 | amdgpu_set_panel_orientation(&aconnector->base); |
| 4362 | 4362 | } |
| 4363 | 4363 | |
| 4364 | + /* If we didn't find a panel, notify the acpi video detection */ | |
| 4365 | + if (dm->adev->flags & AMD_IS_APU && dm->num_of_edps == 0) | |
| 4366 | + acpi_video_report_nolcd(); | |
| 4367 | + | |
| 4364 | 4368 | /* Software is initialized. Now we can register interrupt handlers. */ |
| 4365 | 4369 | switch (adev->asic_type) { |
| 4366 | 4370 | #if defined(CONFIG_DRM_AMD_DC_SI) |
| @@ -53,6 +53,7 @@ enum acpi_backlight_type { · 52 unmodified lines | ||
| 53 | 53 | }; |
| 54 | 54 | |
| 55 | 55 | #if IS_ENABLED(CONFIG_ACPI_VIDEO) |
| 56 | +extern void acpi_video_report_nolcd(void); | |
| 56 | 57 | extern int acpi_video_register(void); |
| 57 | 58 | extern void acpi_video_unregister(void); |
| 58 | 59 | extern void acpi_video_register_backlight(void); |
| @@ -69,6 +70,7 @@ extern int acpi_video_get_levels(struct acpi_device *device, · 10 unmodified lines | ||
| 69 | 70 | struct acpi_video_device_brightness **dev_br, |
| 70 | 71 | int *pmax_level); |
| 71 | 72 | #else |
| 73 | +static inline void acpi_video_report_nolcd(void) { return; }; | |
| 72 | 74 | static inline int acpi_video_register(void) { return -ENODEV; } |
| 73 | 75 | static inline void acpi_video_unregister(void) { return; } |
| 74 | 76 | static inline void acpi_video_register_backlight(void) { return; } |