Skip to content

Commit d833150

Browse files
shankerwangmiaoMingcongBai
authored andcommitted
AOSCOS: loongarch: fix missing dependency info in DSDT
On machines with legacy firmware with BPI01000 version, the devices on the LIO bus lackes the dependency on the PCI root controller, causing the memory-mapped address of the legacy IO ports read before the setup of the mapping, resulting in kernel panic. Such DSDT can work on the legacy loongarch linux port because the leading 16K is unconditionally registered, before the enumeration of the devices in the DSDT table. This patch addes such dependency info, to order the initialization of the devices on the LIO bus after the initialization of the PCI root controller, fixing this problem. However, the addition should be done on each possible LIO device, and currently the patch only includes the legacy EC device on some laptops located at the path \_SB.PCI0.LPC.EC. Thus, this patch will be improved to include more devices. The above behavior is only enabled when BPI data and the BPI01000 version is detected. Signed-off-by: Miao Wang <shankerwangmiao@gmail.com> Signed-off-by: Kexy Biscuit <kexybiscuit@aosc.io> Signed-off-by: Mingcong Bai <jeffbai@aosc.io>
1 parent 08d7416 commit d833150

2 files changed

Lines changed: 49 additions & 0 deletions

File tree

arch/loongarch/include/asm/acpi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ extern void acpi_arch_os_table_override (struct acpi_table_header *existing_tabl
4848
extern void acpi_arch_table_init_complete(void);
4949
#define ACPI_HAVE_ARCH_PCI_ROOT_RES_FILTER
5050
extern void acpi_arch_pci_probe_root_dev_filter(struct resource_entry *entry);
51+
#define ACPI_HAVE_ARCH_INIT
52+
extern void acpi_arch_init(void);
5153

5254
#endif /* !CONFIG_ACPI */
5355

arch/loongarch/kernel/legacy_boot.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,53 @@ void acpi_arch_pci_probe_root_dev_filter(struct resource_entry *entry)
617617
}
618618
}
619619

620+
static __initconst const struct {
621+
struct acpi_table_header header;
622+
unsigned char code [];
623+
} __packed dsdt_add_aml_code = {
624+
.header = {
625+
.signature = ACPI_SIG_DSDT
626+
},
627+
.code = {
628+
0x14,0x21,0x5C,0x2F, /* 00000020 " .!\/" */
629+
0x05,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 00000028 "._SB_PCI" */
630+
0x30,0x4C,0x50,0x43,0x5F,0x45,0x43,0x5F, /* 00000030 "0LPC_EC_" */
631+
0x5F,0x5F,0x44,0x45,0x50,0x08,0xA4,0x12, /* 00000038 "__DEP..." */
632+
0x06,0x01,0x50,0x43,0x49,0x30 /* 00000040 "..PCI0" */
633+
},
634+
};
635+
636+
void __init acpi_arch_init (){
637+
if (bpi_version == BPI_VERSION_NONE) {
638+
return;
639+
}
640+
if (bpi_version > BPI_VERSION_V1) {
641+
return;
642+
}
643+
pr_info("BPI: Trying to patch DSDT\n");
644+
645+
acpi_status status;
646+
acpi_handle handle;
647+
648+
status = acpi_get_handle(NULL, "\\_SB.PCI0.LPC.EC", &handle);
649+
if (ACPI_FAILURE(status)) {
650+
if (status != AE_NOT_FOUND) {
651+
pr_info("BPI: Unable to find EC device: %s\n", acpi_format_exception(status));
652+
}
653+
return;
654+
}
655+
if (acpi_has_method(handle, "_DEP")) {
656+
return;
657+
}
658+
659+
status = acpi_install_method((u8 *)&dsdt_add_aml_code);
660+
if (ACPI_FAILURE(status)) {
661+
pr_info("BPI: Unable to patch DSDT(0x%x)\n", status);
662+
return;
663+
}
664+
acpi_handle_info(handle, "BPI: Patched DSDT\n");
665+
}
666+
620667
int loongarch_have_legacy_bpi (void){
621668
return have_bpi;
622669
}

0 commit comments

Comments
 (0)