Skip to content

Commit 60d943c

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 <a.elysia@proton.me>
1 parent b0b318f commit 60d943c

1 file changed

Lines changed: 69 additions & 0 deletions

File tree

arch/loongarch/kernel/legacy_boot.c

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

0 commit comments

Comments
 (0)