Skip to content

Commit e1b7484

Browse files
shankerwangmiaoopsiff
authored andcommitted
loongarch: correct missing offset of PCI root controller in DSDT table
On machines with legacy firmware with BPI version BPI01000, the PCI root controller information in the DSDT table lacks AddressTranslation in its WordIO resource defination, causing the failure of the registration for the LIO address space. This patch corrects this issue when the given offset is zero for the PCI root controller. This patch also fixes the lack of the leading 16K, i.e. ISA_IOSIZE, in the defination of WordIO resource. This is because that address range is registered unconditionally on the legacy loongarch linux port. This patch also fixes the start addresses or end addresses of WordIO resource not aligned to the page size by rouding the addresses up to the nearest page starting. The above behavior is only enabled when BPI data and the BPI01000 version is detected.
1 parent 88818ae commit e1b7484

4 files changed

Lines changed: 29 additions & 1 deletion

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 @@ static inline u32 get_acpi_id_for_cpu(unsigned int cpu)
4848
extern void acpi_arch_os_table_override (struct acpi_table_header *existing_table, struct acpi_table_header **new_table);
4949
#define ACPI_HAVE_ARCH_TABLE_INIT_COMPLETE
5050
extern void acpi_arch_table_init_complete(void);
51+
#define ACPI_HAVE_ARCH_PCI_ROOT_RES_FILTER
52+
extern void acpi_arch_pci_probe_root_dev_filter(struct resource_entry *entry);
5153

5254
#endif /* !CONFIG_ACPI */
5355

arch/loongarch/kernel/legacy_boot.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ struct loongarch_bpi_info __initdata loongarch_bpi_info = {
6060
.bpi = EFI_INVALID_TABLE_ADDR,
6161
};
6262

63-
static enum bpi_vers __initdata bpi_version = BPI_VERSION_NONE;
63+
static enum bpi_vers bpi_version = BPI_VERSION_NONE;
6464
static u64 __initdata bpi_flags = 0;
6565

6666
static int have_bpi = 0;
@@ -596,6 +596,27 @@ void acpi_arch_os_table_override (struct acpi_table_header *existing_table, stru
596596
}
597597
}
598598

599+
void acpi_arch_pci_probe_root_dev_filter(struct resource_entry *entry)
600+
{
601+
if (bpi_version == BPI_VERSION_NONE) {
602+
return;
603+
}
604+
if (bpi_version > BPI_VERSION_V1) {
605+
return;
606+
}
607+
608+
if (entry->res->flags & IORESOURCE_IO) {
609+
if (entry->offset == 0) {
610+
if (entry->res->start == ISA_IOSIZE) {
611+
entry->res->start = 0;
612+
}
613+
entry->offset = LOONGSON_LIO_BASE;
614+
entry->res->start = LOONGSON_LIO_BASE + PFN_ALIGN(entry->res->start);
615+
entry->res->end = LOONGSON_LIO_BASE + PFN_ALIGN(entry->res->end + 1) - 1;
616+
}
617+
}
618+
}
619+
599620
int loongarch_have_legacy_bpi (void){
600621
return have_bpi;
601622
}

drivers/acpi/pci_root.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,7 @@ int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info)
914914
"no IO and memory resources present in _CRS\n");
915915
else {
916916
resource_list_for_each_entry_safe(entry, tmp, list) {
917+
acpi_arch_pci_probe_root_dev_filter(entry);
917918
if (entry->res->flags & IORESOURCE_IO)
918919
acpi_pci_root_remap_iospace(&device->fwnode,
919920
entry);

include/linux/pci-acpi.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ static inline void pci_acpi_remove_edr_notifier(struct pci_dev *pdev) { }
133133
int pci_acpi_set_companion_lookup_hook(struct acpi_device *(*func)(struct pci_dev *));
134134
void pci_acpi_clear_companion_lookup_hook(void);
135135

136+
#ifndef ACPI_HAVE_ARCH_PCI_ROOT_RES_FILTER
137+
static inline void acpi_arch_pci_probe_root_dev_filter(struct resource_entry *entry) { }
138+
#endif
139+
136140
#else /* CONFIG_ACPI */
137141
static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
138142
static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }

0 commit comments

Comments
 (0)