2020-07-20 07:44:57

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH 0/5] MIPS: Loongson64: Process ISA Node in DeviceTree

Hi,

This series convert reservation of Loongson64 Logic PIO into DeviceTree based
method.

It can be used to replace Huacai's
"MIPS: Loongson64: Reserve legacy MMIO space according to bridge type".

Thanks.

Jiaxun Yang (5):
of_address: Add bus type match for pci ranges parser
MIPS: Loongson64: Process ISA Node in DeviceTree
MIPS: Loongson64: Enlarge IO_SPACE_LIMIT
MIPS: Loongson64: DTS: Fix ISA range for RS780E PCH
MIPS: Loongson64: Add ISA node for LS7A PCH

arch/mips/boot/dts/loongson/ls7a-pch.dtsi | 7 ++
arch/mips/boot/dts/loongson/rs780e-pch.dtsi | 2 +-
arch/mips/include/asm/io.h | 3 +-
.../mips/include/asm/mach-loongson64/spaces.h | 3 +-
arch/mips/loongson64/init.c | 85 +++++++++++++------
drivers/of/address.c | 15 +++-
include/linux/of_address.h | 3 +
7 files changed, 85 insertions(+), 33 deletions(-)

--
2.28.0.rc1


2020-07-20 07:45:07

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH 1/5] of_address: Add bus type match for pci ranges parser

So the parser can be used to parse range property of different bus
types, such as ISA bus.

As they're all using PCI-like method of range property, there is no need
start a new parser.

Signed-off-by: Jiaxun Yang <[email protected]>
---
drivers/of/address.c | 15 +++++++++++----
include/linux/of_address.h | 3 +++
2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/of/address.c b/drivers/of/address.c
index 8eea3f6e29a4..250c91767648 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -702,6 +702,10 @@ static int parser_init(struct of_pci_range_parser *parser,
parser->ns = of_bus_n_size_cells(node);
parser->dma = !strcmp(name, "dma-ranges");

+ parser->bus = of_match_bus(node);
+ if (!parser->bus)
+ return -ENOENT;
+
parser->range = of_get_property(node, name, &rlen);
if (parser->range == NULL)
return -ENOENT;
@@ -732,6 +736,7 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
int na = parser->na;
int ns = parser->ns;
int np = parser->pna + na + ns;
+ int bus_na = 0;

if (!range)
return NULL;
@@ -739,8 +744,10 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
if (!parser->range || parser->range + np > parser->end)
return NULL;

- if (parser->na == 3)
- range->flags = of_bus_pci_get_flags(parser->range);
+ parser->bus->count_cells(parser->node, &bus_na, NULL);
+
+ if (parser->na == bus_na)
+ range->flags = parser->bus->get_flags(parser->range);
else
range->flags = 0;

@@ -761,8 +768,8 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
u32 flags = 0;
u64 pci_addr, cpu_addr, size;

- if (parser->na == 3)
- flags = of_bus_pci_get_flags(parser->range);
+ if (parser->na == bus_na)
+ flags = parser->bus->get_flags(parser->range);
pci_addr = of_read_number(parser->range, na);
if (parser->dma)
cpu_addr = of_translate_dma_address(parser->node,
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index 763022ed3456..3929b4637033 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -6,8 +6,11 @@
#include <linux/of.h>
#include <linux/io.h>

+struct of_bus;
+
struct of_pci_range_parser {
struct device_node *node;
+ struct of_bus *bus;
const __be32 *range;
const __be32 *end;
int na;
--
2.28.0.rc1

2020-07-20 07:45:40

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH 2/5] MIPS: Loongson64: Process ISA Node in DeviceTree

Previously, we're hardcoding resserved ISA I/O Space in code, now
we're processing reverved I/O via DeviceTree directly. Using the ranges
property to determine the size and address of reserved I/O space.

Signed-off-by: Jiaxun Yang <[email protected]>
---
arch/mips/loongson64/init.c | 85 ++++++++++++++++++++++++++-----------
1 file changed, 60 insertions(+), 25 deletions(-)

diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c
index 59ddadace83f..028d7b324ec2 100644
--- a/arch/mips/loongson64/init.c
+++ b/arch/mips/loongson64/init.c
@@ -7,6 +7,8 @@
#include <linux/irqchip.h>
#include <linux/logic_pio.h>
#include <linux/memblock.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
#include <asm/bootinfo.h>
#include <asm/traps.h>
#include <asm/smp-ops.h>
@@ -63,41 +65,74 @@ void __init prom_free_prom_memory(void)
{
}

-static __init void reserve_pio_range(void)
+static int __init add_legacy_isa_io(struct fwnode_handle *fwnode, phys_addr_t addr,
+ resource_size_t size)
{
+ int ret = 0;
struct logic_pio_hwaddr *range;
+ unsigned long vaddr;

range = kzalloc(sizeof(*range), GFP_ATOMIC);
if (!range)
- return;
+ return -ENOMEM;

- range->fwnode = &of_root->fwnode;
- range->size = MMIO_LOWER_RESERVED;
- range->hw_start = LOONGSON_PCIIO_BASE;
+ range->fwnode = fwnode;
+ range->size = size;
+ range->hw_start = addr;
range->flags = LOGIC_PIO_CPU_MMIO;

- if (logic_pio_register_range(range)) {
- pr_err("Failed to reserve PIO range for legacy ISA\n");
- goto free_range;
+ ret = logic_pio_register_range(range);
+ if (ret) {
+ kfree(range);
+ return ret;
+ }
+
+ /* Legacy ISA must placed at the start of PCI_IOBASE */
+ if (range->io_start != 0) {
+ logic_pio_unregister_range(range);
+ kfree(range);
+ return -EINVAL;
}

- if (WARN(range->io_start != 0,
- "Reserved PIO range does not start from 0\n"))
- goto unregister;
-
- /*
- * i8259 would access I/O space, so mapping must be done here.
- * Please remove it when all drivers can be managed by logic_pio.
- */
- ioremap_page_range(PCI_IOBASE, PCI_IOBASE + MMIO_LOWER_RESERVED,
- LOONGSON_PCIIO_BASE,
- pgprot_device(PAGE_KERNEL));
-
- return;
-unregister:
- logic_pio_unregister_range(range);
-free_range:
- kfree(range);
+ vaddr = PCI_IOBASE + range->io_start;
+
+ ioremap_page_range(vaddr, vaddr + size, addr, pgprot_device(PAGE_KERNEL));
+
+ return 0;
+}
+
+static __init void reserve_pio_range(void)
+{
+ struct device_node *np;
+
+ for_each_node_by_name(np, "isa") {
+ struct of_pci_range range;
+ struct of_pci_range_parser parser;
+
+ pr_info("ISA Bridge: %pOF\n", np);
+
+ if (of_pci_range_parser_init(&parser, np)) {
+ pr_info("Failed to parse resources.\n");
+ break;
+ }
+
+ for_each_of_pci_range(&parser, &range) {
+ switch (range.flags & IORESOURCE_TYPE_BITS) {
+ case IORESOURCE_IO:
+ pr_info(" IO 0x%016llx..0x%016llx\n",
+ range.cpu_addr,
+ range.cpu_addr + range.size - 1);
+ if (add_legacy_isa_io(&np->fwnode, range.cpu_addr, range.size))
+ pr_warn("Failed to reserve legacy IO in Logic PIO\n");
+ break;
+ case IORESOURCE_MEM:
+ pr_info(" MEM 0x%016llx..0x%016llx\n",
+ range.cpu_addr,
+ range.cpu_addr + range.size - 1);
+ break;
+ }
+ }
+ }
}

void __init arch_init_irq(void)
--
2.28.0.rc1

2020-07-20 07:46:05

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH 3/5] MIPS: Loongson64: Enlarge IO_SPACE_LIMIT

It can be very big on LS7A PCH systems.

Signed-off-by: Jiaxun Yang <[email protected]>
---
arch/mips/include/asm/io.h | 3 ++-
arch/mips/include/asm/mach-loongson64/spaces.h | 3 +--
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 346fffd9e972..0072489325fa 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -50,8 +50,9 @@
# define __relaxed_ioswabq ioswabq

/* ioswab[bwlq], __mem_ioswab[bwlq] are defined in mangle-port.h */
-
+#ifndef IO_SPACE_LIMIT
#define IO_SPACE_LIMIT 0xffff
+#endif

/*
* On MIPS I/O ports are memory mapped, so we access them using normal
diff --git a/arch/mips/include/asm/mach-loongson64/spaces.h b/arch/mips/include/asm/mach-loongson64/spaces.h
index 3de0ac9d8829..b99b43854929 100644
--- a/arch/mips/include/asm/mach-loongson64/spaces.h
+++ b/arch/mips/include/asm/mach-loongson64/spaces.h
@@ -11,8 +11,7 @@
#define PCI_IOSIZE SZ_16M
#define MAP_BASE (PCI_IOBASE + PCI_IOSIZE)

-/* Reserved at the start of PCI_IOBASE for legacy drivers */
-#define MMIO_LOWER_RESERVED 0x10000
+#define IO_SPACE_LIMIT 0x00ffffff

#include <asm/mach-generic/spaces.h>
#endif
--
2.28.0.rc1

2020-07-20 07:48:37

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH 4/5] MIPS: Loongson64: DTS: Fix ISA range for RS780E PCH

Ranges should express the actual physical address on bus.

Signed-off-by: Jiaxun Yang <[email protected]>
---
arch/mips/boot/dts/loongson/rs780e-pch.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/boot/dts/loongson/rs780e-pch.dtsi b/arch/mips/boot/dts/loongson/rs780e-pch.dtsi
index d4c803d74036..99174b52dfb8 100644
--- a/arch/mips/boot/dts/loongson/rs780e-pch.dtsi
+++ b/arch/mips/boot/dts/loongson/rs780e-pch.dtsi
@@ -25,7 +25,7 @@ isa {
compatible = "isa";
#address-cells = <2>;
#size-cells = <1>;
- ranges = <1 0 0 0 0x4000>;
+ ranges = <1 0 0 0x18000000 0x4000>;

rtc0: rtc@70 {
compatible = "motorola,mc146818";
--
2.28.0.rc1

2020-07-20 07:48:57

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH 5/5] MIPS: Loongson64: Add ISA node for LS7A PCH

Although currently we're not enabling any ISA device in devicetree,
but this node is required to express the ranges of address reserved
for ISA.

Signed-off-by: Jiaxun Yang <[email protected]>
---
arch/mips/boot/dts/loongson/ls7a-pch.dtsi | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi
index 1c286bb8c703..724929ea3f5f 100644
--- a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi
+++ b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi
@@ -19,6 +19,13 @@ pic: interrupt-controller@10000000 {
#interrupt-cells = <2>;
};

+ isa {
+ compatible = "isa";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <1 0 0 0x18000000 0x20000>;
+ };
+
pci@1a000000 {
compatible = "loongson,ls7a-pci";
device_type = "pci";
--
2.28.0.rc1

2020-07-20 10:05:04

by Huacai Chen

[permalink] [raw]
Subject: Re: [PATCH 2/5] MIPS: Loongson64: Process ISA Node in DeviceTree

Hi, Jiaxun,

On Mon, Jul 20, 2020 at 3:44 PM Jiaxun Yang <[email protected]> wrote:
>
> Previously, we're hardcoding resserved ISA I/O Space in code, now
> we're processing reverved I/O via DeviceTree directly. Using the ranges
> property to determine the size and address of reserved I/O space.
Maybe it is better to reserve a default legacy io range if there is no
"isa" node in the .dts file?

Huacai
>
> Signed-off-by: Jiaxun Yang <[email protected]>
> ---
> arch/mips/loongson64/init.c | 85 ++++++++++++++++++++++++++-----------
> 1 file changed, 60 insertions(+), 25 deletions(-)
>
> diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c
> index 59ddadace83f..028d7b324ec2 100644
> --- a/arch/mips/loongson64/init.c
> +++ b/arch/mips/loongson64/init.c
> @@ -7,6 +7,8 @@
> #include <linux/irqchip.h>
> #include <linux/logic_pio.h>
> #include <linux/memblock.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> #include <asm/bootinfo.h>
> #include <asm/traps.h>
> #include <asm/smp-ops.h>
> @@ -63,41 +65,74 @@ void __init prom_free_prom_memory(void)
> {
> }
>
> -static __init void reserve_pio_range(void)
> +static int __init add_legacy_isa_io(struct fwnode_handle *fwnode, phys_addr_t addr,
> + resource_size_t size)
> {
> + int ret = 0;
> struct logic_pio_hwaddr *range;
> + unsigned long vaddr;
>
> range = kzalloc(sizeof(*range), GFP_ATOMIC);
> if (!range)
> - return;
> + return -ENOMEM;
>
> - range->fwnode = &of_root->fwnode;
> - range->size = MMIO_LOWER_RESERVED;
> - range->hw_start = LOONGSON_PCIIO_BASE;
> + range->fwnode = fwnode;
> + range->size = size;
> + range->hw_start = addr;
> range->flags = LOGIC_PIO_CPU_MMIO;
>
> - if (logic_pio_register_range(range)) {
> - pr_err("Failed to reserve PIO range for legacy ISA\n");
> - goto free_range;
> + ret = logic_pio_register_range(range);
> + if (ret) {
> + kfree(range);
> + return ret;
> + }
> +
> + /* Legacy ISA must placed at the start of PCI_IOBASE */
> + if (range->io_start != 0) {
> + logic_pio_unregister_range(range);
> + kfree(range);
> + return -EINVAL;
> }
>
> - if (WARN(range->io_start != 0,
> - "Reserved PIO range does not start from 0\n"))
> - goto unregister;
> -
> - /*
> - * i8259 would access I/O space, so mapping must be done here.
> - * Please remove it when all drivers can be managed by logic_pio.
> - */
> - ioremap_page_range(PCI_IOBASE, PCI_IOBASE + MMIO_LOWER_RESERVED,
> - LOONGSON_PCIIO_BASE,
> - pgprot_device(PAGE_KERNEL));
> -
> - return;
> -unregister:
> - logic_pio_unregister_range(range);
> -free_range:
> - kfree(range);
> + vaddr = PCI_IOBASE + range->io_start;
> +
> + ioremap_page_range(vaddr, vaddr + size, addr, pgprot_device(PAGE_KERNEL));
> +
> + return 0;
> +}
> +
> +static __init void reserve_pio_range(void)
> +{
> + struct device_node *np;
> +
> + for_each_node_by_name(np, "isa") {
> + struct of_pci_range range;
> + struct of_pci_range_parser parser;
> +
> + pr_info("ISA Bridge: %pOF\n", np);
> +
> + if (of_pci_range_parser_init(&parser, np)) {
> + pr_info("Failed to parse resources.\n");
> + break;
> + }
> +
> + for_each_of_pci_range(&parser, &range) {
> + switch (range.flags & IORESOURCE_TYPE_BITS) {
> + case IORESOURCE_IO:
> + pr_info(" IO 0x%016llx..0x%016llx\n",
> + range.cpu_addr,
> + range.cpu_addr + range.size - 1);
> + if (add_legacy_isa_io(&np->fwnode, range.cpu_addr, range.size))
> + pr_warn("Failed to reserve legacy IO in Logic PIO\n");
> + break;
> + case IORESOURCE_MEM:
> + pr_info(" MEM 0x%016llx..0x%016llx\n",
> + range.cpu_addr,
> + range.cpu_addr + range.size - 1);
> + break;
> + }
> + }
> + }
> }
>
> void __init arch_init_irq(void)
> --
> 2.28.0.rc1
>

2020-07-20 10:06:38

by Huacai Chen

[permalink] [raw]
Subject: Re: [PATCH 3/5] MIPS: Loongson64: Enlarge IO_SPACE_LIMIT

Hi, Jiaxun,

On Mon, Jul 20, 2020 at 3:45 PM Jiaxun Yang <[email protected]> wrote:
>
> It can be very big on LS7A PCH systems.
>
> Signed-off-by: Jiaxun Yang <[email protected]>
> ---
> arch/mips/include/asm/io.h | 3 ++-
> arch/mips/include/asm/mach-loongson64/spaces.h | 3 +--
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
> index 346fffd9e972..0072489325fa 100644
> --- a/arch/mips/include/asm/io.h
> +++ b/arch/mips/include/asm/io.h
> @@ -50,8 +50,9 @@
> # define __relaxed_ioswabq ioswabq
>
> /* ioswab[bwlq], __mem_ioswab[bwlq] are defined in mangle-port.h */
> -
> +#ifndef IO_SPACE_LIMIT
> #define IO_SPACE_LIMIT 0xffff
> +#endif
>
> /*
> * On MIPS I/O ports are memory mapped, so we access them using normal
> diff --git a/arch/mips/include/asm/mach-loongson64/spaces.h b/arch/mips/include/asm/mach-loongson64/spaces.h
> index 3de0ac9d8829..b99b43854929 100644
> --- a/arch/mips/include/asm/mach-loongson64/spaces.h
> +++ b/arch/mips/include/asm/mach-loongson64/spaces.h
> @@ -11,8 +11,7 @@
> #define PCI_IOSIZE SZ_16M
> #define MAP_BASE (PCI_IOBASE + PCI_IOSIZE)
>
> -/* Reserved at the start of PCI_IOBASE for legacy drivers */
> -#define MMIO_LOWER_RESERVED 0x10000
> +#define IO_SPACE_LIMIT 0x00ffffff
Maybe using 0xffffff is better?

Huacai
>
> #include <asm/mach-generic/spaces.h>
> #endif
> --
> 2.28.0.rc1
>

2020-07-20 10:07:48

by Huacai Chen

[permalink] [raw]
Subject: Re: [PATCH 5/5] MIPS: Loongson64: Add ISA node for LS7A PCH

Hi, Jiaxun,

On Mon, Jul 20, 2020 at 3:48 PM Jiaxun Yang <[email protected]> wrote:
>
> Although currently we're not enabling any ISA device in devicetree,
> but this node is required to express the ranges of address reserved
> for ISA.
>
> Signed-off-by: Jiaxun Yang <[email protected]>
> ---
> arch/mips/boot/dts/loongson/ls7a-pch.dtsi | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi
> index 1c286bb8c703..724929ea3f5f 100644
> --- a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi
> +++ b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi
> @@ -19,6 +19,13 @@ pic: interrupt-controller@10000000 {
> #interrupt-cells = <2>;
> };
>
> + isa {
> + compatible = "isa";
> + #address-cells = <2>;
> + #size-cells = <1>;
> + ranges = <1 0 0 0x18000000 0x20000>;
> + };
> +
Maybe it is better to define isa after pci, which keeps the
consistency as rs780e.

Huacai
> pci@1a000000 {
> compatible = "loongson,ls7a-pci";
> device_type = "pci";
> --
> 2.28.0.rc1
>

2020-07-20 10:22:24

by Jiaxun Yang

[permalink] [raw]
Subject: Re: [PATCH 2/5] MIPS: Loongson64: Process ISA Node in DeviceTree



在 2020/7/20 下午6:01, Huacai Chen 写道:
> Hi, Jiaxun,
>
> On Mon, Jul 20, 2020 at 3:44 PM Jiaxun Yang <[email protected]> wrote:
>> Previously, we're hardcoding resserved ISA I/O Space in code, now
>> we're processing reverved I/O via DeviceTree directly. Using the ranges
>> property to determine the size and address of reserved I/O space.
> Maybe it is better to reserve a default legacy io range if there is no
> "isa" node in the .dts file?

As currently all dts is built-in in Kernel, I don't think it's necessary.

Also the only ISA driver remaining that can't be probed by dts is i8042.
We can convert it to DeviceTree based, and then we'll always be safe.

Thanks.

- Jiaxun

>
> Huacai
>> Signed-off-by: Jiaxun Yang <[email protected]>
>> ---
>> arch/mips/loongson64/init.c | 85 ++++++++++++++++++++++++++-----------
>> 1 file changed, 60 insertions(+), 25 deletions(-)
>>
>> diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c
>> index 59ddadace83f..028d7b324ec2 100644
>> --- a/arch/mips/loongson64/init.c
>> +++ b/arch/mips/loongson64/init.c
>> @@ -7,6 +7,8 @@
>> #include <linux/irqchip.h>
>> #include <linux/logic_pio.h>
>> #include <linux/memblock.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> #include <asm/bootinfo.h>
>> #include <asm/traps.h>
>> #include <asm/smp-ops.h>
>> @@ -63,41 +65,74 @@ void __init prom_free_prom_memory(void)
>> {
>> }
>>
>> -static __init void reserve_pio_range(void)
>> +static int __init add_legacy_isa_io(struct fwnode_handle *fwnode, phys_addr_t addr,
>> + resource_size_t size)
>> {
>> + int ret = 0;
>> struct logic_pio_hwaddr *range;
>> + unsigned long vaddr;
>>
>> range = kzalloc(sizeof(*range), GFP_ATOMIC);
>> if (!range)
>> - return;
>> + return -ENOMEM;
>>
>> - range->fwnode = &of_root->fwnode;
>> - range->size = MMIO_LOWER_RESERVED;
>> - range->hw_start = LOONGSON_PCIIO_BASE;
>> + range->fwnode = fwnode;
>> + range->size = size;
>> + range->hw_start = addr;
>> range->flags = LOGIC_PIO_CPU_MMIO;
>>
>> - if (logic_pio_register_range(range)) {
>> - pr_err("Failed to reserve PIO range for legacy ISA\n");
>> - goto free_range;
>> + ret = logic_pio_register_range(range);
>> + if (ret) {
>> + kfree(range);
>> + return ret;
>> + }
>> +
>> + /* Legacy ISA must placed at the start of PCI_IOBASE */
>> + if (range->io_start != 0) {
>> + logic_pio_unregister_range(range);
>> + kfree(range);
>> + return -EINVAL;
>> }
>>
>> - if (WARN(range->io_start != 0,
>> - "Reserved PIO range does not start from 0\n"))
>> - goto unregister;
>> -
>> - /*
>> - * i8259 would access I/O space, so mapping must be done here.
>> - * Please remove it when all drivers can be managed by logic_pio.
>> - */
>> - ioremap_page_range(PCI_IOBASE, PCI_IOBASE + MMIO_LOWER_RESERVED,
>> - LOONGSON_PCIIO_BASE,
>> - pgprot_device(PAGE_KERNEL));
>> -
>> - return;
>> -unregister:
>> - logic_pio_unregister_range(range);
>> -free_range:
>> - kfree(range);
>> + vaddr = PCI_IOBASE + range->io_start;
>> +
>> + ioremap_page_range(vaddr, vaddr + size, addr, pgprot_device(PAGE_KERNEL));
>> +
>> + return 0;
>> +}
>> +
>> +static __init void reserve_pio_range(void)
>> +{
>> + struct device_node *np;
>> +
>> + for_each_node_by_name(np, "isa") {
>> + struct of_pci_range range;
>> + struct of_pci_range_parser parser;
>> +
>> + pr_info("ISA Bridge: %pOF\n", np);
>> +
>> + if (of_pci_range_parser_init(&parser, np)) {
>> + pr_info("Failed to parse resources.\n");
>> + break;
>> + }
>> +
>> + for_each_of_pci_range(&parser, &range) {
>> + switch (range.flags & IORESOURCE_TYPE_BITS) {
>> + case IORESOURCE_IO:
>> + pr_info(" IO 0x%016llx..0x%016llx\n",
>> + range.cpu_addr,
>> + range.cpu_addr + range.size - 1);
>> + if (add_legacy_isa_io(&np->fwnode, range.cpu_addr, range.size))
>> + pr_warn("Failed to reserve legacy IO in Logic PIO\n");
>> + break;
>> + case IORESOURCE_MEM:
>> + pr_info(" MEM 0x%016llx..0x%016llx\n",
>> + range.cpu_addr,
>> + range.cpu_addr + range.size - 1);
>> + break;
>> + }
>> + }
>> + }
>> }
>>
>> void __init arch_init_irq(void)
>> --
>> 2.28.0.rc1
>>

2020-07-20 10:47:48

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 3/5] MIPS: Loongson64: Enlarge IO_SPACE_LIMIT

On Mon, Jul 20, 2020 at 9:44 AM Jiaxun Yang <[email protected]> wrote:
>
> It can be very big on LS7A PCH systems.
>
> Signed-off-by: Jiaxun Yang <[email protected]>
> ---
> * On MIPS I/O ports are memory mapped, so we access them using normal
> diff --git a/arch/mips/include/asm/mach-loongson64/spaces.h b/arch/mips/include/asm/mach-loongson64/spaces.h
> index 3de0ac9d8829..b99b43854929 100644
> --- a/arch/mips/include/asm/mach-loongson64/spaces.h
> +++ b/arch/mips/include/asm/mach-loongson64/spaces.h
> @@ -11,8 +11,7 @@
> #define PCI_IOSIZE SZ_16M
> #define MAP_BASE (PCI_IOBASE + PCI_IOSIZE)
>
> -/* Reserved at the start of PCI_IOBASE for legacy drivers */
> -#define MMIO_LOWER_RESERVED 0x10000
> +#define IO_SPACE_LIMIT 0x00ffffff

Does this mean that firmware may already have assigned "high" I/O space
numbers for devices? I'm not sure how well device drivers can generally
deal with port numbers that don't fit into a 16-bit integer.

Is it possible to run a 32-bit kernel on these machines? If yes, than
taking up 16MB of virtual addresses may also become a problem.

In practice, one should rarely need more than a few kb worth of
port numbers, unless you expect to see hundreds of legacy PCI
devices.

Arnd

2020-07-20 11:45:33

by Huacai Chen

[permalink] [raw]
Subject: Re: [PATCH 2/5] MIPS: Loongson64: Process ISA Node in DeviceTree

Hi, Jiaxun,

On Mon, Jul 20, 2020 at 6:20 PM Jiaxun Yang <[email protected]> wrote:
>
>
>
> 在 2020/7/20 下午6:01, Huacai Chen 写道:
> > Hi, Jiaxun,
> >
> > On Mon, Jul 20, 2020 at 3:44 PM Jiaxun Yang <[email protected]> wrote:
> >> Previously, we're hardcoding resserved ISA I/O Space in code, now
> >> we're processing reverved I/O via DeviceTree directly. Using the ranges
> >> property to determine the size and address of reserved I/O space.
> > Maybe it is better to reserve a default legacy io range if there is no
> > "isa" node in the .dts file?
>
> As currently all dts is built-in in Kernel, I don't think it's necessary.
>
> Also the only ISA driver remaining that can't be probed by dts is i8042.
> We can convert it to DeviceTree based, and then we'll always be safe.
>
If you don't reserve a default legacy io range, then I should define
an "isa" node for KVM guests even if the VM doesn't have i8042 and
i8259. Because some pci devices still have legacy i/o ports, such as
qxl. I have tested your patches and found that KVM guests with qxl
cannot work without an "isa" node.

Huacai
> Thanks.
>
> - Jiaxun
>
> >
> > Huacai
> >> Signed-off-by: Jiaxun Yang <[email protected]>
> >> ---
> >> arch/mips/loongson64/init.c | 85 ++++++++++++++++++++++++++-----------
> >> 1 file changed, 60 insertions(+), 25 deletions(-)
> >>
> >> diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c
> >> index 59ddadace83f..028d7b324ec2 100644
> >> --- a/arch/mips/loongson64/init.c
> >> +++ b/arch/mips/loongson64/init.c
> >> @@ -7,6 +7,8 @@
> >> #include <linux/irqchip.h>
> >> #include <linux/logic_pio.h>
> >> #include <linux/memblock.h>
> >> +#include <linux/of.h>
> >> +#include <linux/of_address.h>
> >> #include <asm/bootinfo.h>
> >> #include <asm/traps.h>
> >> #include <asm/smp-ops.h>
> >> @@ -63,41 +65,74 @@ void __init prom_free_prom_memory(void)
> >> {
> >> }
> >>
> >> -static __init void reserve_pio_range(void)
> >> +static int __init add_legacy_isa_io(struct fwnode_handle *fwnode, phys_addr_t addr,
> >> + resource_size_t size)
> >> {
> >> + int ret = 0;
> >> struct logic_pio_hwaddr *range;
> >> + unsigned long vaddr;
> >>
> >> range = kzalloc(sizeof(*range), GFP_ATOMIC);
> >> if (!range)
> >> - return;
> >> + return -ENOMEM;
> >>
> >> - range->fwnode = &of_root->fwnode;
> >> - range->size = MMIO_LOWER_RESERVED;
> >> - range->hw_start = LOONGSON_PCIIO_BASE;
> >> + range->fwnode = fwnode;
> >> + range->size = size;
> >> + range->hw_start = addr;
> >> range->flags = LOGIC_PIO_CPU_MMIO;
> >>
> >> - if (logic_pio_register_range(range)) {
> >> - pr_err("Failed to reserve PIO range for legacy ISA\n");
> >> - goto free_range;
> >> + ret = logic_pio_register_range(range);
> >> + if (ret) {
> >> + kfree(range);
> >> + return ret;
> >> + }
> >> +
> >> + /* Legacy ISA must placed at the start of PCI_IOBASE */
> >> + if (range->io_start != 0) {
> >> + logic_pio_unregister_range(range);
> >> + kfree(range);
> >> + return -EINVAL;
> >> }
> >>
> >> - if (WARN(range->io_start != 0,
> >> - "Reserved PIO range does not start from 0\n"))
> >> - goto unregister;
> >> -
> >> - /*
> >> - * i8259 would access I/O space, so mapping must be done here.
> >> - * Please remove it when all drivers can be managed by logic_pio.
> >> - */
> >> - ioremap_page_range(PCI_IOBASE, PCI_IOBASE + MMIO_LOWER_RESERVED,
> >> - LOONGSON_PCIIO_BASE,
> >> - pgprot_device(PAGE_KERNEL));
> >> -
> >> - return;
> >> -unregister:
> >> - logic_pio_unregister_range(range);
> >> -free_range:
> >> - kfree(range);
> >> + vaddr = PCI_IOBASE + range->io_start;
> >> +
> >> + ioremap_page_range(vaddr, vaddr + size, addr, pgprot_device(PAGE_KERNEL));
> >> +
> >> + return 0;
> >> +}
> >> +
> >> +static __init void reserve_pio_range(void)
> >> +{
> >> + struct device_node *np;
> >> +
> >> + for_each_node_by_name(np, "isa") {
> >> + struct of_pci_range range;
> >> + struct of_pci_range_parser parser;
> >> +
> >> + pr_info("ISA Bridge: %pOF\n", np);
> >> +
> >> + if (of_pci_range_parser_init(&parser, np)) {
> >> + pr_info("Failed to parse resources.\n");
> >> + break;
> >> + }
> >> +
> >> + for_each_of_pci_range(&parser, &range) {
> >> + switch (range.flags & IORESOURCE_TYPE_BITS) {
> >> + case IORESOURCE_IO:
> >> + pr_info(" IO 0x%016llx..0x%016llx\n",
> >> + range.cpu_addr,
> >> + range.cpu_addr + range.size - 1);
> >> + if (add_legacy_isa_io(&np->fwnode, range.cpu_addr, range.size))
> >> + pr_warn("Failed to reserve legacy IO in Logic PIO\n");
> >> + break;
> >> + case IORESOURCE_MEM:
> >> + pr_info(" MEM 0x%016llx..0x%016llx\n",
> >> + range.cpu_addr,
> >> + range.cpu_addr + range.size - 1);
> >> + break;
> >> + }
> >> + }
> >> + }
> >> }
> >>
> >> void __init arch_init_irq(void)
> >> --
> >> 2.28.0.rc1
> >>

2020-07-20 12:02:36

by Jiaxun Yang

[permalink] [raw]
Subject: Re: [PATCH 2/5] MIPS: Loongson64: Process ISA Node in DeviceTree



在 2020/7/20 下午7:44, Huacai Chen 写道:
> Hi, Jiaxun,
>
> On Mon, Jul 20, 2020 at 6:20 PM Jiaxun Yang <[email protected]> wrote:
>>
>>
>> 在 2020/7/20 下午6:01, Huacai Chen 写道:
>>> Hi, Jiaxun,
>>>
>>> On Mon, Jul 20, 2020 at 3:44 PM Jiaxun Yang <[email protected]> wrote:
>>>> Previously, we're hardcoding resserved ISA I/O Space in code, now
>>>> we're processing reverved I/O via DeviceTree directly. Using the ranges
>>>> property to determine the size and address of reserved I/O space.
>>> Maybe it is better to reserve a default legacy io range if there is no
>>> "isa" node in the .dts file?
>> As currently all dts is built-in in Kernel, I don't think it's necessary.
>>
>> Also the only ISA driver remaining that can't be probed by dts is i8042.
>> We can convert it to DeviceTree based, and then we'll always be safe.
>>
> If you don't reserve a default legacy io range, then I should define
> an "isa" node for KVM guests even if the VM doesn't have i8042 and
> i8259. Because some pci devices still have legacy i/o ports, such as
> qxl. I have tested your patches and found that KVM guests with qxl
> cannot work without an "isa" node.

Oops, I forgot stdvga. piix4_smbus may face the same situation too.

But I'd still think adding a isa node for QEMU virt target can be better.
My universal target is to kill boot_param and reach full-DT boot, thus I
don't
want to introduce such regression.


Thanks
- Jiaxun

>
> Huacai
>> Thanks.
>>
>> - Jiaxun
>>
>>> Huacai
>>>> Signed-off-by: Jiaxun Yang <[email protected]>
>>>> ---
>>>> arch/mips/loongson64/init.c | 85 ++++++++++++++++++++++++++-----------
>>>> 1 file changed, 60 insertions(+), 25 deletions(-)
>>>>
>>>> diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c
>>>> index 59ddadace83f..028d7b324ec2 100644
>>>> --- a/arch/mips/loongson64/init.c
>>>> +++ b/arch/mips/loongson64/init.c
>>>> @@ -7,6 +7,8 @@
>>>> #include <linux/irqchip.h>
>>>> #include <linux/logic_pio.h>
>>>> #include <linux/memblock.h>
>>>> +#include <linux/of.h>
>>>> +#include <linux/of_address.h>
>>>> #include <asm/bootinfo.h>
>>>> #include <asm/traps.h>
>>>> #include <asm/smp-ops.h>
>>>> @@ -63,41 +65,74 @@ void __init prom_free_prom_memory(void)
>>>> {
>>>> }
>>>>
>>>> -static __init void reserve_pio_range(void)
>>>> +static int __init add_legacy_isa_io(struct fwnode_handle *fwnode, phys_addr_t addr,
>>>> + resource_size_t size)
>>>> {
>>>> + int ret = 0;
>>>> struct logic_pio_hwaddr *range;
>>>> + unsigned long vaddr;
>>>>
>>>> range = kzalloc(sizeof(*range), GFP_ATOMIC);
>>>> if (!range)
>>>> - return;
>>>> + return -ENOMEM;
>>>>
>>>> - range->fwnode = &of_root->fwnode;
>>>> - range->size = MMIO_LOWER_RESERVED;
>>>> - range->hw_start = LOONGSON_PCIIO_BASE;
>>>> + range->fwnode = fwnode;
>>>> + range->size = size;
>>>> + range->hw_start = addr;
>>>> range->flags = LOGIC_PIO_CPU_MMIO;
>>>>
>>>> - if (logic_pio_register_range(range)) {
>>>> - pr_err("Failed to reserve PIO range for legacy ISA\n");
>>>> - goto free_range;
>>>> + ret = logic_pio_register_range(range);
>>>> + if (ret) {
>>>> + kfree(range);
>>>> + return ret;
>>>> + }
>>>> +
>>>> + /* Legacy ISA must placed at the start of PCI_IOBASE */
>>>> + if (range->io_start != 0) {
>>>> + logic_pio_unregister_range(range);
>>>> + kfree(range);
>>>> + return -EINVAL;
>>>> }
>>>>
>>>> - if (WARN(range->io_start != 0,
>>>> - "Reserved PIO range does not start from 0\n"))
>>>> - goto unregister;
>>>> -
>>>> - /*
>>>> - * i8259 would access I/O space, so mapping must be done here.
>>>> - * Please remove it when all drivers can be managed by logic_pio.
>>>> - */
>>>> - ioremap_page_range(PCI_IOBASE, PCI_IOBASE + MMIO_LOWER_RESERVED,
>>>> - LOONGSON_PCIIO_BASE,
>>>> - pgprot_device(PAGE_KERNEL));
>>>> -
>>>> - return;
>>>> -unregister:
>>>> - logic_pio_unregister_range(range);
>>>> -free_range:
>>>> - kfree(range);
>>>> + vaddr = PCI_IOBASE + range->io_start;
>>>> +
>>>> + ioremap_page_range(vaddr, vaddr + size, addr, pgprot_device(PAGE_KERNEL));
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static __init void reserve_pio_range(void)
>>>> +{
>>>> + struct device_node *np;
>>>> +
>>>> + for_each_node_by_name(np, "isa") {
>>>> + struct of_pci_range range;
>>>> + struct of_pci_range_parser parser;
>>>> +
>>>> + pr_info("ISA Bridge: %pOF\n", np);
>>>> +
>>>> + if (of_pci_range_parser_init(&parser, np)) {
>>>> + pr_info("Failed to parse resources.\n");
>>>> + break;
>>>> + }
>>>> +
>>>> + for_each_of_pci_range(&parser, &range) {
>>>> + switch (range.flags & IORESOURCE_TYPE_BITS) {
>>>> + case IORESOURCE_IO:
>>>> + pr_info(" IO 0x%016llx..0x%016llx\n",
>>>> + range.cpu_addr,
>>>> + range.cpu_addr + range.size - 1);
>>>> + if (add_legacy_isa_io(&np->fwnode, range.cpu_addr, range.size))
>>>> + pr_warn("Failed to reserve legacy IO in Logic PIO\n");
>>>> + break;
>>>> + case IORESOURCE_MEM:
>>>> + pr_info(" MEM 0x%016llx..0x%016llx\n",
>>>> + range.cpu_addr,
>>>> + range.cpu_addr + range.size - 1);
>>>> + break;
>>>> + }
>>>> + }
>>>> + }
>>>> }
>>>>
>>>> void __init arch_init_irq(void)
>>>> --
>>>> 2.28.0.rc1
>>>>

2020-07-20 12:08:01

by Jiaxun Yang

[permalink] [raw]
Subject: Re: [PATCH 3/5] MIPS: Loongson64: Enlarge IO_SPACE_LIMIT



在 2020/7/20 下午6:45, Arnd Bergmann 写道:
> On Mon, Jul 20, 2020 at 9:44 AM Jiaxun Yang <[email protected]> wrote:
>> It can be very big on LS7A PCH systems.
>>
>> Signed-off-by: Jiaxun Yang <[email protected]>
>> ---
>> * On MIPS I/O ports are memory mapped, so we access them using normal
>> diff --git a/arch/mips/include/asm/mach-loongson64/spaces.h b/arch/mips/include/asm/mach-loongson64/spaces.h
>> index 3de0ac9d8829..b99b43854929 100644
>> --- a/arch/mips/include/asm/mach-loongson64/spaces.h
>> +++ b/arch/mips/include/asm/mach-loongson64/spaces.h
>> @@ -11,8 +11,7 @@
>> #define PCI_IOSIZE SZ_16M
>> #define MAP_BASE (PCI_IOBASE + PCI_IOSIZE)
>>
>> -/* Reserved at the start of PCI_IOBASE for legacy drivers */
>> -#define MMIO_LOWER_RESERVED 0x10000
>> +#define IO_SPACE_LIMIT 0x00ffffff
> Does this mean that firmware may already have assigned "high" I/O space
> numbers for devices? I'm not sure how well device drivers can generally
> deal with port numbers that don't fit into a 16-bit integer.
Limited test shows most drivers can deal with that. But We'll aware the
problem,
thanks for the remind.
>
> Is it possible to run a 32-bit kernel on these machines? If yes, than
> taking up 16MB of virtual addresses may also become a problem.

We've killed the ability of running 32-bit kernel on MACH_LOONGSON64.

> In practice, one should rarely need more than a few kb worth of
> port numbers, unless you expect to see hundreds of legacy PCI
> devices.
I must blame stupid hardware design here. The LPC Controller (for ISA
device) can eat
up to 0x20000 IO BAR, and we can't resize it. Thus we have to enlarge
the I/O Space.

Thanks!

- Jiaxun
>
> Arnd

2020-07-20 12:23:44

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 3/5] MIPS: Loongson64: Enlarge IO_SPACE_LIMIT

On Mon, Jul 20, 2020 at 2:07 PM Jiaxun Yang <[email protected]> wrote:
> 在 2020/7/20 下午6:45, Arnd Bergmann 写道:
> > On Mon, Jul 20, 2020 at 9:44 AM Jiaxun Yang <[email protected]> wrote:
> >> It can be very big on LS7A PCH systems.
> > In practice, one should rarely need more than a few kb worth of
> > port numbers, unless you expect to see hundreds of legacy PCI
> > devices.
> I must blame stupid hardware design here. The LPC Controller (for ISA
> device) can eat
> up to 0x20000 IO BAR, and we can't resize it. Thus we have to enlarge
> the I/O Space.

Ok, I see.

Arnd

2020-07-21 00:24:44

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH 1/5] of_address: Add bus type match for pci ranges parser

On Mon, Jul 20, 2020 at 1:49 AM Jiaxun Yang <[email protected]> wrote:
>
> So the parser can be used to parse range property of different bus
> types, such as ISA bus.

Regular MMIO buses are actually already supported, but not ISA.

>
> As they're all using PCI-like method of range property, there is no need
> start a new parser.
>
> Signed-off-by: Jiaxun Yang <[email protected]>
> ---
> drivers/of/address.c | 15 +++++++++++----
> include/linux/of_address.h | 3 +++
> 2 files changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index 8eea3f6e29a4..250c91767648 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -702,6 +702,10 @@ static int parser_init(struct of_pci_range_parser *parser,
> parser->ns = of_bus_n_size_cells(node);
> parser->dma = !strcmp(name, "dma-ranges");
>
> + parser->bus = of_match_bus(node);
> + if (!parser->bus)
> + return -ENOENT;

You'll hit BUG() before you get here, so you can assume success.

> +
> parser->range = of_get_property(node, name, &rlen);
> if (parser->range == NULL)
> return -ENOENT;
> @@ -732,6 +736,7 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
> int na = parser->na;
> int ns = parser->ns;
> int np = parser->pna + na + ns;
> + int bus_na = 0;
>
> if (!range)
> return NULL;
> @@ -739,8 +744,10 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
> if (!parser->range || parser->range + np > parser->end)
> return NULL;
>
> - if (parser->na == 3)
> - range->flags = of_bus_pci_get_flags(parser->range);
> + parser->bus->count_cells(parser->node, &bus_na, NULL);
> +
> + if (parser->na == bus_na)
> + range->flags = parser->bus->get_flags(parser->range);

I think you can just unconditionally call this and drop the else. For
plain MMIO bus, we'd just return IORESOURCE_MEM, but I think the flags
are ignored in that case.

> else
> range->flags = 0;
>
> @@ -761,8 +768,8 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
> u32 flags = 0;
> u64 pci_addr, cpu_addr, size;
>
> - if (parser->na == 3)
> - flags = of_bus_pci_get_flags(parser->range);
> + if (parser->na == bus_na)

This too can be unconditional.

> + flags = parser->bus->get_flags(parser->range);
> pci_addr = of_read_number(parser->range, na);

Perhaps rename pci_addr to child_addr and cpu_addr to parent_addr.

> if (parser->dma)
> cpu_addr = of_translate_dma_address(parser->node,
> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> index 763022ed3456..3929b4637033 100644
> --- a/include/linux/of_address.h
> +++ b/include/linux/of_address.h
> @@ -6,8 +6,11 @@
> #include <linux/of.h>
> #include <linux/io.h>
>
> +struct of_bus;
> +
> struct of_pci_range_parser {
> struct device_node *node;
> + struct of_bus *bus;
> const __be32 *range;
> const __be32 *end;
> int na;
> --
> 2.28.0.rc1
>

2020-07-21 00:28:21

by Rob Herring

[permalink] [raw]
Subject: Re: [PATCH 2/5] MIPS: Loongson64: Process ISA Node in DeviceTree

On Mon, Jul 20, 2020 at 1:54 AM Jiaxun Yang <[email protected]> wrote:
>
> Previously, we're hardcoding resserved ISA I/O Space in code, now
> we're processing reverved I/O via DeviceTree directly. Using the ranges
> property to determine the size and address of reserved I/O space.
>
> Signed-off-by: Jiaxun Yang <[email protected]>
> ---
> arch/mips/loongson64/init.c | 85 ++++++++++++++++++++++++++-----------
> 1 file changed, 60 insertions(+), 25 deletions(-)
>
> diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c
> index 59ddadace83f..028d7b324ec2 100644
> --- a/arch/mips/loongson64/init.c
> +++ b/arch/mips/loongson64/init.c
> @@ -7,6 +7,8 @@
> #include <linux/irqchip.h>
> #include <linux/logic_pio.h>
> #include <linux/memblock.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> #include <asm/bootinfo.h>
> #include <asm/traps.h>
> #include <asm/smp-ops.h>
> @@ -63,41 +65,74 @@ void __init prom_free_prom_memory(void)
> {
> }
>
> -static __init void reserve_pio_range(void)
> +static int __init add_legacy_isa_io(struct fwnode_handle *fwnode, phys_addr_t addr,
> + resource_size_t size)
> {
> + int ret = 0;
> struct logic_pio_hwaddr *range;
> + unsigned long vaddr;
>
> range = kzalloc(sizeof(*range), GFP_ATOMIC);
> if (!range)
> - return;
> + return -ENOMEM;
>
> - range->fwnode = &of_root->fwnode;
> - range->size = MMIO_LOWER_RESERVED;
> - range->hw_start = LOONGSON_PCIIO_BASE;
> + range->fwnode = fwnode;
> + range->size = size;
> + range->hw_start = addr;
> range->flags = LOGIC_PIO_CPU_MMIO;
>
> - if (logic_pio_register_range(range)) {
> - pr_err("Failed to reserve PIO range for legacy ISA\n");
> - goto free_range;
> + ret = logic_pio_register_range(range);
> + if (ret) {
> + kfree(range);
> + return ret;
> + }
> +
> + /* Legacy ISA must placed at the start of PCI_IOBASE */
> + if (range->io_start != 0) {
> + logic_pio_unregister_range(range);
> + kfree(range);
> + return -EINVAL;
> }
>
> - if (WARN(range->io_start != 0,
> - "Reserved PIO range does not start from 0\n"))
> - goto unregister;
> -
> - /*
> - * i8259 would access I/O space, so mapping must be done here.
> - * Please remove it when all drivers can be managed by logic_pio.
> - */
> - ioremap_page_range(PCI_IOBASE, PCI_IOBASE + MMIO_LOWER_RESERVED,
> - LOONGSON_PCIIO_BASE,
> - pgprot_device(PAGE_KERNEL));
> -
> - return;
> -unregister:
> - logic_pio_unregister_range(range);
> -free_range:
> - kfree(range);
> + vaddr = PCI_IOBASE + range->io_start;
> +
> + ioremap_page_range(vaddr, vaddr + size, addr, pgprot_device(PAGE_KERNEL));
> +
> + return 0;
> +}
> +
> +static __init void reserve_pio_range(void)
> +{
> + struct device_node *np;
> +
> + for_each_node_by_name(np, "isa") {
> + struct of_pci_range range;
> + struct of_pci_range_parser parser;

Use of_range, of_range_parser instead of PCI variant.

> +
> + pr_info("ISA Bridge: %pOF\n", np);
> +
> + if (of_pci_range_parser_init(&parser, np)) {
> + pr_info("Failed to parse resources.\n");
> + break;
> + }
> +
> + for_each_of_pci_range(&parser, &range) {

for_each_of_range()

We need to add a define for of_range_parser_init too.

> + switch (range.flags & IORESOURCE_TYPE_BITS) {
> + case IORESOURCE_IO:
> + pr_info(" IO 0x%016llx..0x%016llx\n",
> + range.cpu_addr,
> + range.cpu_addr + range.size - 1);
> + if (add_legacy_isa_io(&np->fwnode, range.cpu_addr, range.size))
> + pr_warn("Failed to reserve legacy IO in Logic PIO\n");
> + break;
> + case IORESOURCE_MEM:
> + pr_info(" MEM 0x%016llx..0x%016llx\n",
> + range.cpu_addr,
> + range.cpu_addr + range.size - 1);
> + break;
> + }
> + }
> + }
> }
>
> void __init arch_init_irq(void)
> --
> 2.28.0.rc1
>