Skip to content

Commit 8a0c322

Browse files
committed
AOSCOS: LoongArch: Add ACPI compatibility for ISA I/O space reservation
This patch adds essential compatibility support for ACPI-based systems running on older firmware. Many older computers with old firmware still rely on this mechanism and are unlikely to receive futher firmeware updates. This change ensures proper ISA I/O space reservation across for them. Use DMI to judge if the system needs patching. Signed-off-by: Yinan Qin <[email protected]>
1 parent b0b318f commit 8a0c322

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

arch/loongarch/kernel/legacy_boot.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
#include <linux/efi.h>
2+
#include <linux/dmi.h>
3+
#include <linux/ioport.h>
4+
#include <linux/logic_pio.h>
5+
#include <linux/sizes.h>
26
#include <linux/memblock.h>
37
#include <linux/acpi.h>
48
#include <linux/kmemleak.h>
@@ -88,6 +92,10 @@ static u64 __initdata bpi_flags = 0;
8892

8993
static int have_bpi = 0;
9094

95+
static void __iomem *legacy_isa_base;
96+
static struct resource *legacy_isa_res;
97+
static struct fwnode_handle *legacy_isa_fwnode;
98+
9199
static __initdata struct {
92100
size_t map_count;
93101
struct loongarch_bpi_memmap{
@@ -718,3 +726,68 @@ void __init acpi_arch_init (){
718726
int loongarch_have_legacy_bpi (void){
719727
return have_bpi;
720728
}
729+
730+
/* DMI matching table for hardware requiring legacy ISA support */
731+
static const struct dmi_system_id loongarch_legacy_isa_table[] = {
732+
{
733+
.ident = "Seewo CB.L3A6.MA01",
734+
.matches = {
735+
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CB.L3A6.MA01"),
736+
},
737+
},
738+
{ }
739+
};
740+
741+
static int __init add_legacy_isa_io(struct fwnode_handle *fwnode,
742+
resource_size_t hw_start, resource_size_t size)
743+
{
744+
int ret = 0;
745+
unsigned long vaddr;
746+
struct logic_pio_hwaddr *range;
747+
748+
range = kzalloc(sizeof(*range), GFP_ATOMIC);
749+
if (!range)
750+
return -ENOMEM;
751+
752+
range->fwnode = fwnode;
753+
range->size = size = round_up(size, PAGE_SIZE);
754+
range->hw_start = hw_start;
755+
range->flags = LOGIC_PIO_CPU_MMIO;
756+
757+
ret = logic_pio_register_range(range);
758+
if (ret) {
759+
kfree(range);
760+
return ret;
761+
}
762+
763+
/* Legacy ISA must placed at the start of PCI_IOBASE */
764+
if (range->io_start != 0) {
765+
logic_pio_unregister_range(range);
766+
kfree(range);
767+
return -EINVAL;
768+
}
769+
770+
vaddr = (unsigned long)(PCI_IOBASE + range->io_start);
771+
vmap_page_range(vaddr, vaddr + size, hw_start, pgprot_device(PAGE_KERNEL));
772+
773+
return 0;
774+
}
775+
776+
static __init int loongarch_reserve_pio_range(void)
777+
{
778+
struct fwnode_handle *fwnode;
779+
780+
if (!acpi_disabled && dmi_check_system(loongarch_legacy_isa_table)) {
781+
fwnode = acpi_alloc_fwnode_static();
782+
pr_info("Legacy ISA: Detected Legacy hardware (%s), setting up legacy ISA I/O\n",
783+
dmi_get_system_info(DMI_PRODUCT_NAME));
784+
if (add_legacy_isa_io(fwnode, LOONGSON_LIO_BASE, SZ_64K)) {
785+
pr_warn("Legacy ISA: Failed to setup legacy ISA I/O, some devices may not work!\n");
786+
acpi_free_fwnode_static(fwnode);
787+
}
788+
}
789+
790+
return 0;
791+
}
792+
793+
arch_initcall(loongarch_reserve_pio_range);

0 commit comments

Comments
 (0)