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

Merge branches 'acpi-soc', 'acpi-video' and 'acpi-apei'

Merge ACPI SoC drivers changes, ACPI backlight driver changes and APEI
changes for 5.18-rc1:

- Make the ACPI driver for Intel SoCs (LPSS) let the SPI driver know
the exact type of the controller (Andy Shevchenko).

- Force native backlight mode on Clevo NL5xRU and NL5xNU (Werner
Sembach).

- Fix return value of __setup handlers in the APEI code (Randy
Dunlap).

- Add Arm Generic Diagnostic Dump and Reset device driver (Ilkka
Koskinen).

- Limit printable size of BERT table data (Darren Hart).

- Fix up HEST and GHES initialization (Shuai Xue).

* acpi-soc:
ACPI: LPSS: Provide an SSP type to the driver
ACPI: LPSS: Constify properties member in struct lpss_device_desc
ACPI: platform: Constify properties parameter in acpi_create_platform_device()

* acpi-video:
ACPI: video: Force backlight native for Clevo NL5xRU and NL5xNU

* acpi-apei:
ACPI: AGDI: Add driver for Arm Generic Diagnostic Dump and Reset device
ACPI/APEI: Limit printable size of BERT table data
ACPI: APEI: fix return value of __setup handlers
ACPI: APEI: rename ghes_init() with an "acpi_" prefix
ACPI: APEI: explicit init of HEST and GHES in apci_init()

+273 -41
+26 -7
drivers/acpi/acpi_lpss.c
··· 21 21 #include <linux/pm_domain.h> 22 22 #include <linux/pm_runtime.h> 23 23 #include <linux/pwm.h> 24 + #include <linux/pxa2xx_ssp.h> 24 25 #include <linux/suspend.h> 25 26 #include <linux/delay.h> 26 27 ··· 83 82 const char *clk_con_id; 84 83 unsigned int prv_offset; 85 84 size_t prv_size_override; 86 - struct property_entry *properties; 85 + const struct property_entry *properties; 87 86 void (*setup)(struct lpss_private_data *pdata); 88 87 bool resume_from_noirq; 89 88 }; ··· 220 219 pwm_add_table(bsw_pwm_lookup, ARRAY_SIZE(bsw_pwm_lookup)); 221 220 } 222 221 223 - static const struct lpss_device_desc lpt_dev_desc = { 222 + static const struct property_entry lpt_spi_properties[] = { 223 + PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_LPT_SSP), 224 + { } 225 + }; 226 + 227 + static const struct lpss_device_desc lpt_spi_dev_desc = { 224 228 .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_LTR 225 229 | LPSS_SAVE_CTX, 226 230 .prv_offset = 0x800, 231 + .properties = lpt_spi_properties, 227 232 }; 228 233 229 234 static const struct lpss_device_desc lpt_i2c_dev_desc = { ··· 289 282 .properties = uart_properties, 290 283 }; 291 284 285 + static const struct property_entry byt_spi_properties[] = { 286 + PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_BYT_SSP), 287 + { } 288 + }; 289 + 292 290 static const struct lpss_device_desc byt_spi_dev_desc = { 293 291 .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX, 294 292 .prv_offset = 0x400, 293 + .properties = byt_spi_properties, 295 294 }; 296 295 297 296 static const struct lpss_device_desc byt_sdio_dev_desc = { ··· 318 305 .resume_from_noirq = true, 319 306 }; 320 307 308 + static const struct property_entry bsw_spi_properties[] = { 309 + PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_BSW_SSP), 310 + { } 311 + }; 312 + 321 313 static const struct lpss_device_desc bsw_spi_dev_desc = { 322 314 .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_SAVE_CTX 323 315 | LPSS_NO_D3_DELAY, 324 316 .prv_offset = 0x400, 325 317 .setup = lpss_deassert_reset, 318 + .properties = bsw_spi_properties, 326 319 }; 327 320 328 321 static const struct x86_cpu_id lpss_cpu_ids[] = { ··· 348 329 { "INTL9C60", LPSS_ADDR(lpss_dma_desc) }, 349 330 350 331 /* Lynxpoint LPSS devices */ 351 - { "INT33C0", LPSS_ADDR(lpt_dev_desc) }, 352 - { "INT33C1", LPSS_ADDR(lpt_dev_desc) }, 332 + { "INT33C0", LPSS_ADDR(lpt_spi_dev_desc) }, 333 + { "INT33C1", LPSS_ADDR(lpt_spi_dev_desc) }, 353 334 { "INT33C2", LPSS_ADDR(lpt_i2c_dev_desc) }, 354 335 { "INT33C3", LPSS_ADDR(lpt_i2c_dev_desc) }, 355 336 { "INT33C4", LPSS_ADDR(lpt_uart_dev_desc) }, ··· 375 356 { "808622C1", LPSS_ADDR(bsw_i2c_dev_desc) }, 376 357 377 358 /* Broadwell LPSS devices */ 378 - { "INT3430", LPSS_ADDR(lpt_dev_desc) }, 379 - { "INT3431", LPSS_ADDR(lpt_dev_desc) }, 359 + { "INT3430", LPSS_ADDR(lpt_spi_dev_desc) }, 360 + { "INT3431", LPSS_ADDR(lpt_spi_dev_desc) }, 380 361 { "INT3432", LPSS_ADDR(lpt_i2c_dev_desc) }, 381 362 { "INT3433", LPSS_ADDR(lpt_i2c_dev_desc) }, 382 363 { "INT3434", LPSS_ADDR(lpt_uart_dev_desc) }, ··· 385 366 { "INT3437", }, 386 367 387 368 /* Wildcat Point LPSS devices */ 388 - { "INT3438", LPSS_ADDR(lpt_dev_desc) }, 369 + { "INT3438", LPSS_ADDR(lpt_spi_dev_desc) }, 389 370 390 371 { } 391 372 };
+1 -1
drivers/acpi/acpi_platform.c
··· 95 95 * Name of the platform device will be the same as @adev's. 96 96 */ 97 97 struct platform_device *acpi_create_platform_device(struct acpi_device *adev, 98 - struct property_entry *properties) 98 + const struct property_entry *properties) 99 99 { 100 100 struct platform_device *pdev = NULL; 101 101 struct platform_device_info pdevinfo;
+7 -3
drivers/acpi/apei/bert.c
··· 29 29 30 30 #undef pr_fmt 31 31 #define pr_fmt(fmt) "BERT: " fmt 32 + #define ACPI_BERT_PRINT_MAX_LEN 1024 32 33 33 34 static int bert_disable; 34 35 ··· 59 58 } 60 59 61 60 pr_info_once("Error records from previous boot:\n"); 62 - 63 - cper_estatus_print(KERN_INFO HW_ERR, estatus); 61 + if (region_len < ACPI_BERT_PRINT_MAX_LEN) 62 + cper_estatus_print(KERN_INFO HW_ERR, estatus); 63 + else 64 + pr_info_once("Max print length exceeded, table data is available at:\n" 65 + "/sys/firmware/acpi/tables/data/BERT"); 64 66 65 67 /* 66 68 * Because the boot error source is "one-time polled" type, ··· 81 77 { 82 78 bert_disable = 1; 83 79 84 - return 0; 80 + return 1; 85 81 } 86 82 __setup("bert_disable", setup_bert_disable); 87 83
+1 -1
drivers/acpi/apei/erst.c
··· 891 891 static int __init setup_erst_disable(char *str) 892 892 { 893 893 erst_disable = 1; 894 - return 0; 894 + return 1; 895 895 } 896 896 897 897 __setup("erst_disable", setup_erst_disable);
+8 -11
drivers/acpi/apei/ghes.c
··· 1457 1457 .remove = ghes_remove, 1458 1458 }; 1459 1459 1460 - static int __init ghes_init(void) 1460 + void __init acpi_ghes_init(void) 1461 1461 { 1462 1462 int rc; 1463 1463 1464 + sdei_init(); 1465 + 1464 1466 if (acpi_disabled) 1465 - return -ENODEV; 1467 + return; 1466 1468 1467 1469 switch (hest_disable) { 1468 1470 case HEST_NOT_FOUND: 1469 - return -ENODEV; 1471 + return; 1470 1472 case HEST_DISABLED: 1471 1473 pr_info(GHES_PFX "HEST is not enabled!\n"); 1472 - return -EINVAL; 1474 + return; 1473 1475 default: 1474 1476 break; 1475 1477 } 1476 1478 1477 1479 if (ghes_disable) { 1478 1480 pr_info(GHES_PFX "GHES is not enabled!\n"); 1479 - return -EINVAL; 1481 + return; 1480 1482 } 1481 1483 1482 1484 ghes_nmi_init_cxt(); 1483 1485 1484 1486 rc = platform_driver_register(&ghes_platform_driver); 1485 1487 if (rc) 1486 - goto err; 1488 + return; 1487 1489 1488 1490 rc = apei_osc_setup(); 1489 1491 if (rc == 0 && osc_sb_apei_support_acked) ··· 1496 1494 pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n"); 1497 1495 else 1498 1496 pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n"); 1499 - 1500 - return 0; 1501 - err: 1502 - return rc; 1503 1497 } 1504 - device_initcall(ghes_init);
+1 -1
drivers/acpi/apei/hest.c
··· 224 224 static int __init setup_hest_disable(char *str) 225 225 { 226 226 hest_disable = HEST_DISABLED; 227 - return 0; 227 + return 1; 228 228 } 229 229 230 230 __setup("hest_disable", setup_hest_disable);
+10
drivers/acpi/arm64/Kconfig
··· 8 8 9 9 config ACPI_GTDT 10 10 bool 11 + 12 + config ACPI_AGDI 13 + bool "Arm Generic Diagnostic Dump and Reset Device Interface" 14 + depends on ARM_SDE_INTERFACE 15 + help 16 + Arm Generic Diagnostic Dump and Reset Device Interface (AGDI) is 17 + a standard that enables issuing a non-maskable diagnostic dump and 18 + reset command. 19 + 20 + If set, the kernel parses AGDI table and listens for the command.
+1
drivers/acpi/arm64/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 + obj-$(CONFIG_ACPI_AGDI) += agdi.o 2 3 obj-$(CONFIG_ACPI_IORT) += iort.o 3 4 obj-$(CONFIG_ACPI_GTDT) += gtdt.o 4 5 obj-y += dma.o
+116
drivers/acpi/arm64/agdi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * This file implements handling of 4 + * Arm Generic Diagnostic Dump and Reset Interface table (AGDI) 5 + * 6 + * Copyright (c) 2022, Ampere Computing LLC 7 + */ 8 + 9 + #define pr_fmt(fmt) "ACPI: AGDI: " fmt 10 + 11 + #include <linux/acpi.h> 12 + #include <linux/arm_sdei.h> 13 + #include <linux/io.h> 14 + #include <linux/kernel.h> 15 + #include <linux/platform_device.h> 16 + 17 + struct agdi_data { 18 + int sdei_event; 19 + }; 20 + 21 + static int agdi_sdei_handler(u32 sdei_event, struct pt_regs *regs, void *arg) 22 + { 23 + nmi_panic(regs, "Arm Generic Diagnostic Dump and Reset SDEI event issued"); 24 + return 0; 25 + } 26 + 27 + static int agdi_sdei_probe(struct platform_device *pdev, 28 + struct agdi_data *adata) 29 + { 30 + int err; 31 + 32 + err = sdei_event_register(adata->sdei_event, agdi_sdei_handler, pdev); 33 + if (err) { 34 + dev_err(&pdev->dev, "Failed to register for SDEI event %d", 35 + adata->sdei_event); 36 + return err; 37 + } 38 + 39 + err = sdei_event_enable(adata->sdei_event); 40 + if (err) { 41 + sdei_event_unregister(adata->sdei_event); 42 + dev_err(&pdev->dev, "Failed to enable event %d\n", 43 + adata->sdei_event); 44 + return err; 45 + } 46 + 47 + return 0; 48 + } 49 + 50 + static int agdi_probe(struct platform_device *pdev) 51 + { 52 + struct agdi_data *adata = dev_get_platdata(&pdev->dev); 53 + 54 + if (!adata) 55 + return -EINVAL; 56 + 57 + return agdi_sdei_probe(pdev, adata); 58 + } 59 + 60 + static int agdi_remove(struct platform_device *pdev) 61 + { 62 + struct agdi_data *adata = dev_get_platdata(&pdev->dev); 63 + int err, i; 64 + 65 + err = sdei_event_disable(adata->sdei_event); 66 + if (err) 67 + return err; 68 + 69 + for (i = 0; i < 3; i++) { 70 + err = sdei_event_unregister(adata->sdei_event); 71 + if (err != -EINPROGRESS) 72 + break; 73 + 74 + schedule(); 75 + } 76 + 77 + return err; 78 + } 79 + 80 + static struct platform_driver agdi_driver = { 81 + .driver = { 82 + .name = "agdi", 83 + }, 84 + .probe = agdi_probe, 85 + .remove = agdi_remove, 86 + }; 87 + 88 + void __init acpi_agdi_init(void) 89 + { 90 + struct acpi_table_agdi *agdi_table; 91 + struct agdi_data pdata; 92 + struct platform_device *pdev; 93 + acpi_status status; 94 + 95 + status = acpi_get_table(ACPI_SIG_AGDI, 0, 96 + (struct acpi_table_header **) &agdi_table); 97 + if (ACPI_FAILURE(status)) 98 + return; 99 + 100 + if (agdi_table->flags & ACPI_AGDI_SIGNALING_MODE) { 101 + pr_warn("Interrupt signaling is not supported"); 102 + goto err_put_table; 103 + } 104 + 105 + pdata.sdei_event = agdi_table->sdei_event; 106 + 107 + pdev = platform_device_register_data(NULL, "agdi", 0, &pdata, sizeof(pdata)); 108 + if (IS_ERR(pdev)) 109 + goto err_put_table; 110 + 111 + if (platform_driver_register(&agdi_driver)) 112 + platform_device_unregister(pdev); 113 + 114 + err_put_table: 115 + acpi_put_table((struct acpi_table_header *)agdi_table); 116 + }
+4
drivers/acpi/bus.c
··· 26 26 #include <asm/mpspec.h> 27 27 #include <linux/dmi.h> 28 28 #endif 29 + #include <linux/acpi_agdi.h> 29 30 #include <linux/acpi_iort.h> 30 31 #include <linux/acpi_viot.h> 31 32 #include <linux/pci.h> ··· 1356 1355 1357 1356 pci_mmcfg_late_init(); 1358 1357 acpi_iort_init(); 1358 + acpi_hest_init(); 1359 + acpi_ghes_init(); 1359 1360 acpi_scan_init(); 1360 1361 acpi_ec_init(); 1361 1362 acpi_debugfs_init(); ··· 1366 1363 acpi_debugger_init(); 1367 1364 acpi_setup_sb_notify_handler(); 1368 1365 acpi_viot_init(); 1366 + acpi_agdi_init(); 1369 1367 return 0; 1370 1368 } 1371 1369
-3
drivers/acpi/pci_root.c
··· 22 22 #include <linux/slab.h> 23 23 #include <linux/dmi.h> 24 24 #include <linux/platform_data/x86/apple.h> 25 - #include <acpi/apei.h> /* for acpi_hest_init() */ 26 - 27 25 #include "internal.h" 28 26 29 27 #define ACPI_PCI_ROOT_CLASS "pci_bridge" ··· 941 943 942 944 void __init acpi_pci_root_init(void) 943 945 { 944 - acpi_hest_init(); 945 946 if (acpi_pci_disabled) 946 947 return; 947 948
+75
drivers/acpi/video_detect.c
··· 415 415 DMI_MATCH(DMI_PRODUCT_NAME, "GA503"), 416 416 }, 417 417 }, 418 + /* 419 + * Clevo NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2 have both a 420 + * working native and video interface. However the default detection 421 + * mechanism first registers the video interface before unregistering 422 + * it again and switching to the native interface during boot. This 423 + * results in a dangling SBIOS request for backlight change for some 424 + * reason, causing the backlight to switch to ~2% once per boot on the 425 + * first power cord connect or disconnect event. Setting the native 426 + * interface explicitly circumvents this buggy behaviour, by avoiding 427 + * the unregistering process. 428 + */ 429 + { 430 + .callback = video_detect_force_native, 431 + .ident = "Clevo NL5xRU", 432 + .matches = { 433 + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 434 + DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), 435 + }, 436 + }, 437 + { 438 + .callback = video_detect_force_native, 439 + .ident = "Clevo NL5xRU", 440 + .matches = { 441 + DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"), 442 + DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), 443 + }, 444 + }, 445 + { 446 + .callback = video_detect_force_native, 447 + .ident = "Clevo NL5xRU", 448 + .matches = { 449 + DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), 450 + DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), 451 + }, 452 + }, 453 + { 454 + .callback = video_detect_force_native, 455 + .ident = "Clevo NL5xRU", 456 + .matches = { 457 + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 458 + DMI_MATCH(DMI_BOARD_NAME, "AURA1501"), 459 + }, 460 + }, 461 + { 462 + .callback = video_detect_force_native, 463 + .ident = "Clevo NL5xRU", 464 + .matches = { 465 + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 466 + DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"), 467 + }, 468 + }, 469 + { 470 + .callback = video_detect_force_native, 471 + .ident = "Clevo NL5xNU", 472 + .matches = { 473 + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), 474 + DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), 475 + }, 476 + }, 477 + { 478 + .callback = video_detect_force_native, 479 + .ident = "Clevo NL5xNU", 480 + .matches = { 481 + DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"), 482 + DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), 483 + }, 484 + }, 485 + { 486 + .callback = video_detect_force_native, 487 + .ident = "Clevo NL5xNU", 488 + .matches = { 489 + DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), 490 + DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), 491 + }, 492 + }, 418 493 419 494 /* 420 495 * Desktops which falsely report a backlight and which our heuristics
+1
drivers/firmware/Kconfig
··· 40 40 config ARM_SDE_INTERFACE 41 41 bool "ARM Software Delegated Exception Interface (SDEI)" 42 42 depends on ARM64 43 + depends on ACPI_APEI_GHES 43 44 help 44 45 The Software Delegated Exception Interface (SDEI) is an ARM 45 46 standard for registering callbacks from the platform firmware
+2 -11
drivers/firmware/arm_sdei.c
··· 1059 1059 return true; 1060 1060 } 1061 1061 1062 - static int __init sdei_init(void) 1062 + void __init sdei_init(void) 1063 1063 { 1064 1064 struct platform_device *pdev; 1065 1065 int ret; 1066 1066 1067 1067 ret = platform_driver_register(&sdei_driver); 1068 1068 if (ret || !sdei_present_acpi()) 1069 - return ret; 1069 + return; 1070 1070 1071 1071 pdev = platform_device_register_simple(sdei_driver.driver.name, 1072 1072 0, NULL, 0); ··· 1076 1076 pr_info("Failed to register ACPI:SDEI platform device %d\n", 1077 1077 ret); 1078 1078 } 1079 - 1080 - return ret; 1081 1079 } 1082 - 1083 - /* 1084 - * On an ACPI system SDEI needs to be ready before HEST:GHES tries to register 1085 - * its events. ACPI is initialised from a subsys_initcall(), GHES is initialised 1086 - * by device_initcall(). We want to be called in the middle. 1087 - */ 1088 - subsys_initcall_sync(sdei_init); 1089 1080 1090 1081 int sdei_event_handler(struct pt_regs *regs, 1091 1082 struct sdei_registered_event *arg)
+3 -1
include/acpi/apei.h
··· 27 27 extern int erst_disable; 28 28 #ifdef CONFIG_ACPI_APEI_GHES 29 29 extern bool ghes_disable; 30 + void __init acpi_ghes_init(void); 30 31 #else 31 32 #define ghes_disable 1 33 + static inline void acpi_ghes_init(void) { } 32 34 #endif 33 35 34 36 #ifdef CONFIG_ACPI_APEI 35 37 void __init acpi_hest_init(void); 36 38 #else 37 - static inline void acpi_hest_init(void) { return; } 39 + static inline void acpi_hest_init(void) { } 38 40 #endif 39 41 40 42 int erst_write(const struct cper_record_header *record);
+2 -2
include/linux/acpi.h
··· 692 692 int acpi_device_modalias(struct device *, char *, int); 693 693 694 694 struct platform_device *acpi_create_platform_device(struct acpi_device *, 695 - struct property_entry *); 695 + const struct property_entry *); 696 696 #define ACPI_PTR(_ptr) (_ptr) 697 697 698 698 static inline void acpi_device_set_enumerated(struct acpi_device *adev) ··· 931 931 932 932 static inline struct platform_device * 933 933 acpi_create_platform_device(struct acpi_device *adev, 934 - struct property_entry *properties) 934 + const struct property_entry *properties) 935 935 { 936 936 return NULL; 937 937 }
+13
include/linux/acpi_agdi.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + #ifndef __ACPI_AGDI_H__ 4 + #define __ACPI_AGDI_H__ 5 + 6 + #include <linux/acpi.h> 7 + 8 + #ifdef CONFIG_ACPI_AGDI 9 + void __init acpi_agdi_init(void); 10 + #else 11 + static inline void acpi_agdi_init(void) {} 12 + #endif 13 + #endif /* __ACPI_AGDI_H__ */
+2
include/linux/arm_sdei.h
··· 46 46 /* For use by arch code when CPU hotplug notifiers are not appropriate. */ 47 47 int sdei_mask_local_cpu(void); 48 48 int sdei_unmask_local_cpu(void); 49 + void __init sdei_init(void); 49 50 #else 50 51 static inline int sdei_mask_local_cpu(void) { return 0; } 51 52 static inline int sdei_unmask_local_cpu(void) { return 0; } 53 + static inline void sdei_init(void) { } 52 54 #endif /* CONFIG_ARM_SDE_INTERFACE */ 53 55 54 56