Skip to content

Commit 27cab43

Browse files
AaronDotchenhuacai
authored andcommitted
LoongArch: Add processing ISA Node in DeviceTree
Similar to commit 6d0068a ("MIPS: Loongson64: Process ISA Node in DeviceTree"), we process ISA node in DeviceTree for FDT-based systems. Previously, we are hardcoding reserved ISA I/O Space in, now we are processing it I/O via DeviceTree directly. The ranges property of ISA node is used to determine the size and address of reserved I/O space. Signed-off-by: Binbin Zhou <[email protected]> Signed-off-by: Huacai Chen <[email protected]>
1 parent 88d4d95 commit 27cab43

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

arch/loongarch/kernel/setup.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,81 @@ static void __init resource_init(void)
429429
#endif
430430
}
431431

432+
static int __init add_legacy_isa_io(struct fwnode_handle *fwnode,
433+
resource_size_t hw_start, resource_size_t size)
434+
{
435+
int ret = 0;
436+
unsigned long vaddr;
437+
struct logic_pio_hwaddr *range;
438+
439+
range = kzalloc(sizeof(*range), GFP_ATOMIC);
440+
if (!range)
441+
return -ENOMEM;
442+
443+
range->fwnode = fwnode;
444+
range->size = size = round_up(size, PAGE_SIZE);
445+
range->hw_start = hw_start;
446+
range->flags = LOGIC_PIO_CPU_MMIO;
447+
448+
ret = logic_pio_register_range(range);
449+
if (ret) {
450+
kfree(range);
451+
return ret;
452+
}
453+
454+
/* Legacy ISA must placed at the start of PCI_IOBASE */
455+
if (range->io_start != 0) {
456+
logic_pio_unregister_range(range);
457+
kfree(range);
458+
return -EINVAL;
459+
}
460+
461+
vaddr = (unsigned long)(PCI_IOBASE + range->io_start);
462+
ioremap_page_range(vaddr, vaddr + size, hw_start, pgprot_device(PAGE_KERNEL));
463+
464+
return 0;
465+
}
466+
467+
static __init int arch_reserve_pio_range(void)
468+
{
469+
struct device_node *np;
470+
471+
for_each_node_by_name(np, "isa") {
472+
struct of_range range;
473+
struct of_range_parser parser;
474+
475+
pr_info("ISA Bridge: %pOF\n", np);
476+
477+
if (of_range_parser_init(&parser, np)) {
478+
pr_info("Failed to parse resources.\n");
479+
of_node_put(np);
480+
break;
481+
}
482+
483+
for_each_of_range(&parser, &range) {
484+
switch (range.flags & IORESOURCE_TYPE_BITS) {
485+
case IORESOURCE_IO:
486+
pr_info(" IO 0x%016llx..0x%016llx -> 0x%016llx\n",
487+
range.cpu_addr,
488+
range.cpu_addr + range.size - 1,
489+
range.bus_addr);
490+
if (add_legacy_isa_io(&np->fwnode, range.cpu_addr, range.size))
491+
pr_warn("Failed to reserve legacy IO in Logic PIO\n");
492+
break;
493+
case IORESOURCE_MEM:
494+
pr_info(" MEM 0x%016llx..0x%016llx -> 0x%016llx\n",
495+
range.cpu_addr,
496+
range.cpu_addr + range.size - 1,
497+
range.bus_addr);
498+
break;
499+
}
500+
}
501+
}
502+
503+
return 0;
504+
}
505+
arch_initcall(arch_reserve_pio_range);
506+
432507
static int __init reserve_memblock_reserved_regions(void)
433508
{
434509
u64 i, j;

0 commit comments

Comments
 (0)