diff options
-rw-r--r-- | arch/arm/include/asm/io.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-integrator/pci_v3.c | 23 | ||||
-rw-r--r-- | arch/arm64/Kconfig | 22 | ||||
-rw-r--r-- | arch/arm64/include/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/arm64/include/asm/io.h | 3 | ||||
-rw-r--r-- | arch/arm64/include/asm/pci.h | 37 | ||||
-rw-r--r-- | arch/arm64/include/asm/pgtable.h | 2 | ||||
-rw-r--r-- | arch/arm64/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/arm64/kernel/pci.c | 70 | ||||
-rw-r--r-- | drivers/of/address.c | 154 | ||||
-rw-r--r-- | drivers/of/of_pci.c | 142 | ||||
-rw-r--r-- | drivers/pci/host/pci-tegra.c | 12 | ||||
-rw-r--r-- | drivers/pci/host/pcie-rcar.c | 21 | ||||
-rw-r--r-- | drivers/pci/pci.c | 40 | ||||
-rw-r--r-- | drivers/pci/probe.c | 11 | ||||
-rw-r--r-- | include/asm-generic/io.h | 2 | ||||
-rw-r--r-- | include/asm-generic/pgtable.h | 4 | ||||
-rw-r--r-- | include/linux/of_address.h | 27 | ||||
-rw-r--r-- | include/linux/of_pci.h | 13 | ||||
-rw-r--r-- | include/linux/pci.h | 27 |
20 files changed, 576 insertions, 37 deletions
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 3d23418cbddd..180567408ee8 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h | |||
@@ -178,6 +178,7 @@ static inline void __iomem *__typesafe_io(unsigned long addr) | |||
178 | 178 | ||
179 | /* PCI fixed i/o mapping */ | 179 | /* PCI fixed i/o mapping */ |
180 | #define PCI_IO_VIRT_BASE 0xfee00000 | 180 | #define PCI_IO_VIRT_BASE 0xfee00000 |
181 | #define PCI_IOBASE ((void __iomem *)PCI_IO_VIRT_BASE) | ||
181 | 182 | ||
182 | #if defined(CONFIG_PCI) | 183 | #if defined(CONFIG_PCI) |
183 | void pci_ioremap_set_mem_type(int mem_type); | 184 | void pci_ioremap_set_mem_type(int mem_type); |
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index 05e1f73a1e8d..c186a17c2cff 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c | |||
@@ -660,6 +660,7 @@ static void __init pci_v3_preinit(void) | |||
660 | { | 660 | { |
661 | unsigned long flags; | 661 | unsigned long flags; |
662 | unsigned int temp; | 662 | unsigned int temp; |
663 | phys_addr_t io_address = pci_pio_to_address(io_mem.start); | ||
663 | 664 | ||
664 | pcibios_min_mem = 0x00100000; | 665 | pcibios_min_mem = 0x00100000; |
665 | 666 | ||
@@ -701,7 +702,7 @@ static void __init pci_v3_preinit(void) | |||
701 | /* | 702 | /* |
702 | * Setup window 2 - PCI IO | 703 | * Setup window 2 - PCI IO |
703 | */ | 704 | */ |
704 | v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_mem.start) | | 705 | v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_address) | |
705 | V3_LB_BASE_ENABLE); | 706 | V3_LB_BASE_ENABLE); |
706 | v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0)); | 707 | v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0)); |
707 | 708 | ||
@@ -742,6 +743,7 @@ static void __init pci_v3_preinit(void) | |||
742 | static void __init pci_v3_postinit(void) | 743 | static void __init pci_v3_postinit(void) |
743 | { | 744 | { |
744 | unsigned int pci_cmd; | 745 | unsigned int pci_cmd; |
746 | phys_addr_t io_address = pci_pio_to_address(io_mem.start); | ||
745 | 747 | ||
746 | pci_cmd = PCI_COMMAND_MEMORY | | 748 | pci_cmd = PCI_COMMAND_MEMORY | |
747 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; | 749 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; |
@@ -758,7 +760,7 @@ static void __init pci_v3_postinit(void) | |||
758 | "interrupt: %d\n", ret); | 760 | "interrupt: %d\n", ret); |
759 | #endif | 761 | #endif |
760 | 762 | ||
761 | register_isa_ports(non_mem.start, io_mem.start, 0); | 763 | register_isa_ports(non_mem.start, io_address, 0); |
762 | } | 764 | } |
763 | 765 | ||
764 | /* | 766 | /* |
@@ -867,33 +869,32 @@ static int __init pci_v3_probe(struct platform_device *pdev) | |||
867 | 869 | ||
868 | for_each_of_pci_range(&parser, &range) { | 870 | for_each_of_pci_range(&parser, &range) { |
869 | if (!range.flags) { | 871 | if (!range.flags) { |
870 | of_pci_range_to_resource(&range, np, &conf_mem); | 872 | ret = of_pci_range_to_resource(&range, np, &conf_mem); |
871 | conf_mem.name = "PCIv3 config"; | 873 | conf_mem.name = "PCIv3 config"; |
872 | } | 874 | } |
873 | if (range.flags & IORESOURCE_IO) { | 875 | if (range.flags & IORESOURCE_IO) { |
874 | of_pci_range_to_resource(&range, np, &io_mem); | 876 | ret = of_pci_range_to_resource(&range, np, &io_mem); |
875 | io_mem.name = "PCIv3 I/O"; | 877 | io_mem.name = "PCIv3 I/O"; |
876 | } | 878 | } |
877 | if ((range.flags & IORESOURCE_MEM) && | 879 | if ((range.flags & IORESOURCE_MEM) && |
878 | !(range.flags & IORESOURCE_PREFETCH)) { | 880 | !(range.flags & IORESOURCE_PREFETCH)) { |
879 | non_mem_pci = range.pci_addr; | 881 | non_mem_pci = range.pci_addr; |
880 | non_mem_pci_sz = range.size; | 882 | non_mem_pci_sz = range.size; |
881 | of_pci_range_to_resource(&range, np, &non_mem); | 883 | ret = of_pci_range_to_resource(&range, np, &non_mem); |
882 | non_mem.name = "PCIv3 non-prefetched mem"; | 884 | non_mem.name = "PCIv3 non-prefetched mem"; |
883 | } | 885 | } |
884 | if ((range.flags & IORESOURCE_MEM) && | 886 | if ((range.flags & IORESOURCE_MEM) && |
885 | (range.flags & IORESOURCE_PREFETCH)) { | 887 | (range.flags & IORESOURCE_PREFETCH)) { |
886 | pre_mem_pci = range.pci_addr; | 888 | pre_mem_pci = range.pci_addr; |
887 | pre_mem_pci_sz = range.size; | 889 | pre_mem_pci_sz = range.size; |
888 | of_pci_range_to_resource(&range, np, &pre_mem); | 890 | ret = of_pci_range_to_resource(&range, np, &pre_mem); |
889 | pre_mem.name = "PCIv3 prefetched mem"; | 891 | pre_mem.name = "PCIv3 prefetched mem"; |
890 | } | 892 | } |
891 | } | ||
892 | 893 | ||
893 | if (!conf_mem.start || !io_mem.start || | 894 | if (ret < 0) { |
894 | !non_mem.start || !pre_mem.start) { | 895 | dev_err(&pdev->dev, "missing ranges in device node\n"); |
895 | dev_err(&pdev->dev, "missing ranges in device node\n"); | 896 | return ret; |
896 | return -EINVAL; | 897 | } |
897 | } | 898 | } |
898 | 899 | ||
899 | pci_v3.map_irq = of_irq_parse_and_map_pci; | 900 | pci_v3.map_irq = of_irq_parse_and_map_pci; |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index fd4e81a4e1ce..bc97147d326c 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -81,7 +81,7 @@ config MMU | |||
81 | def_bool y | 81 | def_bool y |
82 | 82 | ||
83 | config NO_IOPORT_MAP | 83 | config NO_IOPORT_MAP |
84 | def_bool y | 84 | def_bool y if !PCI |
85 | 85 | ||
86 | config STACKTRACE_SUPPORT | 86 | config STACKTRACE_SUPPORT |
87 | def_bool y | 87 | def_bool y |
@@ -156,6 +156,26 @@ menu "Bus support" | |||
156 | config ARM_AMBA | 156 | config ARM_AMBA |
157 | bool | 157 | bool |
158 | 158 | ||
159 | config PCI | ||
160 | bool "PCI support" | ||
161 | help | ||
162 | This feature enables support for PCI bus system. If you say Y | ||
163 | here, the kernel will include drivers and infrastructure code | ||
164 | to support PCI bus devices. | ||
165 | |||
166 | config PCI_DOMAINS | ||
167 | def_bool PCI | ||
168 | |||
169 | config PCI_DOMAINS_GENERIC | ||
170 | def_bool PCI | ||
171 | |||
172 | config PCI_SYSCALL | ||
173 | def_bool PCI | ||
174 | |||
175 | source "drivers/pci/Kconfig" | ||
176 | source "drivers/pci/pcie/Kconfig" | ||
177 | source "drivers/pci/hotplug/Kconfig" | ||
178 | |||
159 | endmenu | 179 | endmenu |
160 | 180 | ||
161 | menu "Kernel Features" | 181 | menu "Kernel Features" |
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index 0b3fcf86e6ba..07cb417026b6 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild | |||
@@ -29,6 +29,7 @@ generic-y += mman.h | |||
29 | generic-y += msgbuf.h | 29 | generic-y += msgbuf.h |
30 | generic-y += mutex.h | 30 | generic-y += mutex.h |
31 | generic-y += pci.h | 31 | generic-y += pci.h |
32 | generic-y += pci-bridge.h | ||
32 | generic-y += poll.h | 33 | generic-y += poll.h |
33 | generic-y += preempt.h | 34 | generic-y += preempt.h |
34 | generic-y += resource.h | 35 | generic-y += resource.h |
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index e0ecdcf6632d..f998d90bc389 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h | |||
@@ -121,7 +121,8 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) | |||
121 | /* | 121 | /* |
122 | * I/O port access primitives. | 122 | * I/O port access primitives. |
123 | */ | 123 | */ |
124 | #define IO_SPACE_LIMIT 0xffff | 124 | #define arch_has_dev_port() (1) |
125 | #define IO_SPACE_LIMIT (SZ_32M - 1) | ||
125 | #define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_32M)) | 126 | #define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_32M)) |
126 | 127 | ||
127 | static inline u8 inb(unsigned long addr) | 128 | static inline u8 inb(unsigned long addr) |
diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h new file mode 100644 index 000000000000..872ba939fcb2 --- /dev/null +++ b/arch/arm64/include/asm/pci.h | |||
@@ -0,0 +1,37 @@ | |||
1 | #ifndef __ASM_PCI_H | ||
2 | #define __ASM_PCI_H | ||
3 | #ifdef __KERNEL__ | ||
4 | |||
5 | #include <linux/types.h> | ||
6 | #include <linux/slab.h> | ||
7 | #include <linux/dma-mapping.h> | ||
8 | |||
9 | #include <asm/io.h> | ||
10 | #include <asm-generic/pci-bridge.h> | ||
11 | #include <asm-generic/pci-dma-compat.h> | ||
12 | |||
13 | #define PCIBIOS_MIN_IO 0x1000 | ||
14 | #define PCIBIOS_MIN_MEM 0 | ||
15 | |||
16 | /* | ||
17 | * Set to 1 if the kernel should re-assign all PCI bus numbers | ||
18 | */ | ||
19 | #define pcibios_assign_all_busses() \ | ||
20 | (pci_has_flag(PCI_REASSIGN_ALL_BUS)) | ||
21 | |||
22 | /* | ||
23 | * PCI address space differs from physical memory address space | ||
24 | */ | ||
25 | #define PCI_DMA_BUS_IS_PHYS (0) | ||
26 | |||
27 | extern int isa_dma_bridge_buggy; | ||
28 | |||
29 | #ifdef CONFIG_PCI | ||
30 | static inline int pci_proc_domain(struct pci_bus *bus) | ||
31 | { | ||
32 | return 1; | ||
33 | } | ||
34 | #endif /* CONFIG_PCI */ | ||
35 | |||
36 | #endif /* __KERNEL__ */ | ||
37 | #endif /* __ASM_PCI_H */ | ||
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index ffe1ba0506d1..a968523adf56 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h | |||
@@ -296,6 +296,8 @@ static inline int has_transparent_hugepage(void) | |||
296 | __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN) | 296 | __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN) |
297 | #define pgprot_writecombine(prot) \ | 297 | #define pgprot_writecombine(prot) \ |
298 | __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN) | 298 | __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN) |
299 | #define pgprot_device(prot) \ | ||
300 | __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN) | ||
299 | #define __HAVE_PHYS_MEM_ACCESS_PROT | 301 | #define __HAVE_PHYS_MEM_ACCESS_PROT |
300 | struct file; | 302 | struct file; |
301 | extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | 303 | extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, |
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index df7ef8768fc2..1ed5a06a3863 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile | |||
@@ -29,6 +29,7 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o | |||
29 | arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o | 29 | arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o |
30 | arm64-obj-$(CONFIG_KGDB) += kgdb.o | 30 | arm64-obj-$(CONFIG_KGDB) += kgdb.o |
31 | arm64-obj-$(CONFIG_EFI) += efi.o efi-stub.o efi-entry.o | 31 | arm64-obj-$(CONFIG_EFI) += efi.o efi-stub.o efi-entry.o |
32 | arm64-obj-$(CONFIG_PCI) += pci.o | ||
32 | 33 | ||
33 | obj-y += $(arm64-obj-y) vdso/ | 34 | obj-y += $(arm64-obj-y) vdso/ |
34 | obj-m += $(arm64-obj-m) | 35 | obj-m += $(arm64-obj-m) |
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c new file mode 100644 index 000000000000..ce5836c14ec1 --- /dev/null +++ b/arch/arm64/kernel/pci.c | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * Code borrowed from powerpc/kernel/pci-common.c | ||
3 | * | ||
4 | * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM | ||
5 | * Copyright (C) 2014 ARM Ltd. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/init.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/mm.h> | ||
17 | #include <linux/of_pci.h> | ||
18 | #include <linux/of_platform.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | #include <asm/pci-bridge.h> | ||
22 | |||
23 | /* | ||
24 | * Called after each bus is probed, but before its children are examined | ||
25 | */ | ||
26 | void pcibios_fixup_bus(struct pci_bus *bus) | ||
27 | { | ||
28 | /* nothing to do, expected to be removed in the future */ | ||
29 | } | ||
30 | |||
31 | /* | ||
32 | * We don't have to worry about legacy ISA devices, so nothing to do here | ||
33 | */ | ||
34 | resource_size_t pcibios_align_resource(void *data, const struct resource *res, | ||
35 | resource_size_t size, resource_size_t align) | ||
36 | { | ||
37 | return res->start; | ||
38 | } | ||
39 | |||
40 | /* | ||
41 | * Try to assign the IRQ number from DT when adding a new device | ||
42 | */ | ||
43 | int pcibios_add_device(struct pci_dev *dev) | ||
44 | { | ||
45 | dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); | ||
46 | |||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | |||
51 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | ||
52 | static bool dt_domain_found = false; | ||
53 | |||
54 | void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) | ||
55 | { | ||
56 | int domain = of_get_pci_domain_nr(parent->of_node); | ||
57 | |||
58 | if (domain >= 0) { | ||
59 | dt_domain_found = true; | ||
60 | } else if (dt_domain_found == true) { | ||
61 | dev_err(parent, "Node %s is missing \"linux,pci-domain\" property in DT\n", | ||
62 | parent->of_node->full_name); | ||
63 | return; | ||
64 | } else { | ||
65 | domain = pci_get_new_domain_nr(); | ||
66 | } | ||
67 | |||
68 | bus->domain_nr = domain; | ||
69 | } | ||
70 | #endif | ||
diff --git a/drivers/of/address.c b/drivers/of/address.c index e3718250d66e..afdb78299f61 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c | |||
@@ -5,6 +5,8 @@ | |||
5 | #include <linux/module.h> | 5 | #include <linux/module.h> |
6 | #include <linux/of_address.h> | 6 | #include <linux/of_address.h> |
7 | #include <linux/pci_regs.h> | 7 | #include <linux/pci_regs.h> |
8 | #include <linux/sizes.h> | ||
9 | #include <linux/slab.h> | ||
8 | #include <linux/string.h> | 10 | #include <linux/string.h> |
9 | 11 | ||
10 | /* Max address size we deal with */ | 12 | /* Max address size we deal with */ |
@@ -293,6 +295,51 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser, | |||
293 | } | 295 | } |
294 | EXPORT_SYMBOL_GPL(of_pci_range_parser_one); | 296 | EXPORT_SYMBOL_GPL(of_pci_range_parser_one); |
295 | 297 | ||
298 | /* | ||
299 | * of_pci_range_to_resource - Create a resource from an of_pci_range | ||
300 | * @range: the PCI range that describes the resource | ||
301 | * @np: device node where the range belongs to | ||
302 | * @res: pointer to a valid resource that will be updated to | ||
303 | * reflect the values contained in the range. | ||
304 | * | ||
305 | * Returns EINVAL if the range cannot be converted to resource. | ||
306 | * | ||
307 | * Note that if the range is an IO range, the resource will be converted | ||
308 | * using pci_address_to_pio() which can fail if it is called too early or | ||
309 | * if the range cannot be matched to any host bridge IO space (our case here). | ||
310 | * To guard against that we try to register the IO range first. | ||
311 | * If that fails we know that pci_address_to_pio() will do too. | ||
312 | */ | ||
313 | int of_pci_range_to_resource(struct of_pci_range *range, | ||
314 | struct device_node *np, struct resource *res) | ||
315 | { | ||
316 | int err; | ||
317 | res->flags = range->flags; | ||
318 | res->parent = res->child = res->sibling = NULL; | ||
319 | res->name = np->full_name; | ||
320 | |||
321 | if (res->flags & IORESOURCE_IO) { | ||
322 | unsigned long port; | ||
323 | err = pci_register_io_range(range->cpu_addr, range->size); | ||
324 | if (err) | ||
325 | goto invalid_range; | ||
326 | port = pci_address_to_pio(range->cpu_addr); | ||
327 | if (port == (unsigned long)-1) { | ||
328 | err = -EINVAL; | ||
329 | goto invalid_range; | ||
330 | } | ||
331 | res->start = port; | ||
332 | } else { | ||
333 | res->start = range->cpu_addr; | ||
334 | } | ||
335 | res->end = res->start + range->size - 1; | ||
336 | return 0; | ||
337 | |||
338 | invalid_range: | ||
339 | res->start = (resource_size_t)OF_BAD_ADDR; | ||
340 | res->end = (resource_size_t)OF_BAD_ADDR; | ||
341 | return err; | ||
342 | } | ||
296 | #endif /* CONFIG_PCI */ | 343 | #endif /* CONFIG_PCI */ |
297 | 344 | ||
298 | /* | 345 | /* |
@@ -601,12 +648,119 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, | |||
601 | } | 648 | } |
602 | EXPORT_SYMBOL(of_get_address); | 649 | EXPORT_SYMBOL(of_get_address); |
603 | 650 | ||
651 | #ifdef PCI_IOBASE | ||
652 | struct io_range { | ||
653 | struct list_head list; | ||
654 | phys_addr_t start; | ||
655 | resource_size_t size; | ||
656 | }; | ||
657 | |||
658 | static LIST_HEAD(io_range_list); | ||
659 | static DEFINE_SPINLOCK(io_range_lock); | ||
660 | #endif | ||
661 | |||
662 | /* | ||
663 | * Record the PCI IO range (expressed as CPU physical address + size). | ||
664 | * Return a negative value if an error has occured, zero otherwise | ||
665 | */ | ||
666 | int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size) | ||
667 | { | ||
668 | int err = 0; | ||
669 | |||
670 | #ifdef PCI_IOBASE | ||
671 | struct io_range *range; | ||
672 | resource_size_t allocated_size = 0; | ||
673 | |||
674 | /* check if the range hasn't been previously recorded */ | ||
675 | spin_lock(&io_range_lock); | ||
676 | list_for_each_entry(range, &io_range_list, list) { | ||
677 | if (addr >= range->start && addr + size <= range->start + size) { | ||
678 | /* range already registered, bail out */ | ||
679 | goto end_register; | ||
680 | } | ||
681 | allocated_size += range->size; | ||
682 | } | ||
683 | |||
684 | /* range not registed yet, check for available space */ | ||
685 | if (allocated_size + size - 1 > IO_SPACE_LIMIT) { | ||
686 | /* if it's too big check if 64K space can be reserved */ | ||
687 | if (allocated_size + SZ_64K - 1 > IO_SPACE_LIMIT) { | ||
688 | err = -E2BIG; | ||
689 | goto end_register; | ||
690 | } | ||
691 | |||
692 | size = SZ_64K; | ||
693 | pr_warn("Requested IO range too big, new size set to 64K\n"); | ||
694 | } | ||
695 | |||
696 | /* add the range to the list */ | ||
697 | range = kzalloc(sizeof(*range), GFP_KERNEL); | ||
698 | if (!range) { | ||
699 | err = -ENOMEM; | ||
700 | goto end_register; | ||
701 | } | ||
702 | |||
703 | range->start = addr; | ||
704 | range->size = size; | ||
705 | |||
706 | list_add_tail(&range->list, &io_range_list); | ||
707 | |||
708 | end_register: | ||
709 | spin_unlock(&io_range_lock); | ||
710 | #endif | ||
711 | |||
712 | return err; | ||
713 | } | ||
714 | |||
715 | phys_addr_t pci_pio_to_address(unsigned long pio) | ||
716 | { | ||
717 | phys_addr_t address = (phys_addr_t)OF_BAD_ADDR; | ||
718 | |||
719 | #ifdef PCI_IOBASE | ||
720 | struct io_range *range; | ||
721 | resource_size_t allocated_size = 0; | ||
722 | |||
723 | if (pio > IO_SPACE_LIMIT) | ||
724 | return address; | ||
725 | |||
726 | spin_lock(&io_range_lock); | ||
727 | list_for_each_entry(range, &io_range_list, list) { | ||
728 | if (pio >= allocated_size && pio < allocated_size + range->size) { | ||
729 | address = range->start + pio - allocated_size; | ||
730 | break; | ||
731 | } | ||
732 | allocated_size += range->size; | ||
733 | } | ||
734 | spin_unlock(&io_range_lock); | ||
735 | #endif | ||
736 | |||
737 | return address; | ||
738 | } | ||
739 | |||
604 | unsigned long __weak pci_address_to_pio(phys_addr_t address) | 740 | unsigned long __weak pci_address_to_pio(phys_addr_t address) |
605 | { | 741 | { |
742 | #ifdef PCI_IOBASE | ||
743 | struct io_range *res; | ||
744 | resource_size_t offset = 0; | ||
745 | unsigned long addr = -1; | ||
746 | |||
747 | spin_lock(&io_range_lock); | ||
748 | list_for_each_entry(res, &io_range_list, list) { | ||
749 | if (address >= res->start && address < res->start + res->size) { | ||
750 | addr = res->start - address + offset; | ||
751 | break; | ||
752 | } | ||
753 | offset += res->size; | ||
754 | } | ||
755 | spin_unlock(&io_range_lock); | ||
756 | |||
757 | return addr; | ||
758 | #else | ||
606 | if (address > IO_SPACE_LIMIT) | 759 | if (address > IO_SPACE_LIMIT) |
607 | return (unsigned long)-1; | 760 | return (unsigned long)-1; |
608 | 761 | ||
609 | return (unsigned long) address; | 762 | return (unsigned long) address; |
763 | #endif | ||
610 | } | 764 | } |
611 | 765 | ||
612 | static int __of_address_to_resource(struct device_node *dev, | 766 | static int __of_address_to_resource(struct device_node *dev, |
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c index 848199633798..8882b467be95 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c | |||
@@ -1,7 +1,9 @@ | |||
1 | #include <linux/kernel.h> | 1 | #include <linux/kernel.h> |
2 | #include <linux/export.h> | 2 | #include <linux/export.h> |
3 | #include <linux/of.h> | 3 | #include <linux/of.h> |
4 | #include <linux/of_address.h> | ||
4 | #include <linux/of_pci.h> | 5 | #include <linux/of_pci.h> |
6 | #include <linux/slab.h> | ||
5 | 7 | ||
6 | static inline int __of_pci_pci_compare(struct device_node *node, | 8 | static inline int __of_pci_pci_compare(struct device_node *node, |
7 | unsigned int data) | 9 | unsigned int data) |
@@ -89,6 +91,146 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res) | |||
89 | } | 91 | } |
90 | EXPORT_SYMBOL_GPL(of_pci_parse_bus_range); | 92 | EXPORT_SYMBOL_GPL(of_pci_parse_bus_range); |
91 | 93 | ||
94 | /** | ||
95 | * This function will try to obtain the host bridge domain number by | ||
96 | * finding a property called "linux,pci-domain" of the given device node. | ||
97 | * | ||
98 | * @node: device tree node with the domain information | ||
99 | * | ||
100 | * Returns the associated domain number from DT in the range [0-0xffff], or | ||
101 | * a negative value if the required property is not found. | ||
102 | */ | ||
103 | int of_get_pci_domain_nr(struct device_node *node) | ||
104 | { | ||
105 | const __be32 *value; | ||
106 | int len; | ||
107 | u16 domain; | ||
108 | |||
109 | value = of_get_property(node, "linux,pci-domain", &len); | ||
110 | if (!value || len < sizeof(*value)) | ||
111 | return -EINVAL; | ||
112 | |||
113 | domain = (u16)be32_to_cpup(value); | ||
114 | |||
115 | return domain; | ||
116 | } | ||
117 | EXPORT_SYMBOL_GPL(of_get_pci_domain_nr); | ||
118 | |||
119 | #if defined(CONFIG_OF_ADDRESS) | ||
120 | /** | ||
121 | * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT | ||
122 | * @dev: device node of the host bridge having the range property | ||
123 | * @busno: bus number associated with the bridge root bus | ||
124 | * @bus_max: maximum number of buses for this bridge | ||
125 | * @resources: list where the range of resources will be added after DT parsing | ||
126 | * @io_base: pointer to a variable that will contain on return the physical | ||
127 | * address for the start of the I/O range. Can be NULL if the caller doesn't | ||
128 | * expect IO ranges to be present in the device tree. | ||
129 | * | ||
130 | * It is the caller's job to free the @resources list. | ||
131 | * | ||
132 | * This function will parse the "ranges" property of a PCI host bridge device | ||
133 | * node and setup the resource mapping based on its content. It is expected | ||
134 | * that the property conforms with the Power ePAPR document. | ||
135 | * | ||
136 | * It returns zero if the range parsing has been successful or a standard error | ||
137 | * value if it failed. | ||
138 | */ | ||
139 | int of_pci_get_host_bridge_resources(struct device_node *dev, | ||
140 | unsigned char busno, unsigned char bus_max, | ||
141 | struct list_head *resources, resource_size_t *io_base) | ||
142 | { | ||
143 | struct resource *res; | ||
144 | struct resource *bus_range; | ||
145 | struct of_pci_range range; | ||
146 | struct of_pci_range_parser parser; | ||
147 | char range_type[4]; | ||
148 | int err; | ||
149 | |||
150 | if (io_base) | ||
151 | *io_base = (resource_size_t)OF_BAD_ADDR; | ||
152 | |||
153 | bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL); | ||
154 | if (!bus_range) | ||
155 | return -ENOMEM; | ||
156 | |||
157 | pr_info("PCI host bridge %s ranges:\n", dev->full_name); | ||
158 | |||
159 | err = of_pci_parse_bus_range(dev, bus_range); | ||
160 | if (err) { | ||
161 | bus_range->start = busno; | ||
162 | bus_range->end = bus_max; | ||
163 | bus_range->flags = IORESOURCE_BUS; | ||
164 | pr_info(" No bus range found for %s, using %pR\n", | ||
165 | dev->full_name, bus_range); | ||
166 | } else { | ||
167 | if (bus_range->end > bus_range->start + bus_max) | ||
168 | bus_range->end = bus_range->start + bus_max; | ||
169 | } | ||
170 | pci_add_resource(resources, bus_range); | ||
171 | |||
172 | /* Check for ranges property */ | ||
173 | err = of_pci_range_parser_init(&parser, dev); | ||
174 | if (err) | ||
175 | goto parse_failed; | ||
176 | |||
177 | pr_debug("Parsing ranges property...\n"); | ||
178 | for_each_of_pci_range(&parser, &range) { | ||
179 | /* Read next ranges element */ | ||
180 | if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO) | ||
181 | snprintf(range_type, 4, " IO"); | ||
182 | else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM) | ||
183 | snprintf(range_type, 4, "MEM"); | ||
184 | else | ||
185 | snprintf(range_type, 4, "err"); | ||
186 | pr_info(" %s %#010llx..%#010llx -> %#010llx\n", range_type, | ||
187 | range.cpu_addr, range.cpu_addr + range.size - 1, | ||
188 | range.pci_addr); | ||
189 | |||
190 | /* | ||
191 | * If we failed translation or got a zero-sized region | ||
192 | * then skip this range | ||
193 | */ | ||
194 | if (range.cpu_addr == OF_BAD_ADDR || range.size == 0) | ||
195 | continue; | ||
196 | |||
197 | res = kzalloc(sizeof(struct resource), GFP_KERNEL); | ||
198 | if (!res) { | ||
199 | err = -ENOMEM; | ||
200 | goto parse_failed; | ||
201 | } | ||
202 | |||
203 | err = of_pci_range_to_resource(&range, dev, res); | ||
204 | if (err) | ||
205 | goto conversion_failed; | ||
206 | |||
207 | if (resource_type(res) == IORESOURCE_IO) { | ||
208 | if (!io_base) { | ||
209 | pr_err("I/O range found for %s. Please provide an io_base pointer to save CPU base address\n", | ||
210 | dev->full_name); | ||
211 | err = -EINVAL; | ||
212 | goto conversion_failed; | ||
213 | } | ||
214 | if (*io_base != (resource_size_t)OF_BAD_ADDR) | ||
215 | pr_warn("More than one I/O resource converted for %s. CPU base address for old range lost!\n", | ||
216 | dev->full_name); | ||
217 | *io_base = range.cpu_addr; | ||
218 | } | ||
219 | |||
220 | pci_add_resource_offset(resources, res, res->start - range.pci_addr); | ||
221 | } | ||
222 | |||
223 | return 0; | ||
224 | |||
225 | conversion_failed: | ||
226 | kfree(res); | ||
227 | parse_failed: | ||
228 | pci_free_resource_list(resources); | ||
229 | return err; | ||
230 | } | ||
231 | EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources); | ||
232 | #endif /* CONFIG_OF_ADDRESS */ | ||
233 | |||
92 | #ifdef CONFIG_PCI_MSI | 234 | #ifdef CONFIG_PCI_MSI |
93 | 235 | ||
94 | static LIST_HEAD(of_pci_msi_chip_list); | 236 | static LIST_HEAD(of_pci_msi_chip_list); |
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 79a30476036c..3d43874319be 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
@@ -658,6 +658,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | |||
658 | { | 658 | { |
659 | struct tegra_pcie *pcie = sys_to_pcie(sys); | 659 | struct tegra_pcie *pcie = sys_to_pcie(sys); |
660 | int err; | 660 | int err; |
661 | phys_addr_t io_start; | ||
661 | 662 | ||
662 | err = devm_request_resource(pcie->dev, &pcie->all, &pcie->mem); | 663 | err = devm_request_resource(pcie->dev, &pcie->all, &pcie->mem); |
663 | if (err < 0) | 664 | if (err < 0) |
@@ -667,12 +668,14 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | |||
667 | if (err) | 668 | if (err) |
668 | return err; | 669 | return err; |
669 | 670 | ||
671 | io_start = pci_pio_to_address(pcie->io.start); | ||
672 | |||
670 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); | 673 | pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); |
671 | pci_add_resource_offset(&sys->resources, &pcie->prefetch, | 674 | pci_add_resource_offset(&sys->resources, &pcie->prefetch, |
672 | sys->mem_offset); | 675 | sys->mem_offset); |
673 | pci_add_resource(&sys->resources, &pcie->busn); | 676 | pci_add_resource(&sys->resources, &pcie->busn); |
674 | 677 | ||
675 | pci_ioremap_io(nr * SZ_64K, pcie->io.start); | 678 | pci_ioremap_io(nr * SZ_64K, io_start); |
676 | 679 | ||
677 | return 1; | 680 | return 1; |
678 | } | 681 | } |
@@ -783,6 +786,7 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg) | |||
783 | static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) | 786 | static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) |
784 | { | 787 | { |
785 | u32 fpci_bar, size, axi_address; | 788 | u32 fpci_bar, size, axi_address; |
789 | phys_addr_t io_start = pci_pio_to_address(pcie->io.start); | ||
786 | 790 | ||
787 | /* Bar 0: type 1 extended configuration space */ | 791 | /* Bar 0: type 1 extended configuration space */ |
788 | fpci_bar = 0xfe100000; | 792 | fpci_bar = 0xfe100000; |
@@ -795,7 +799,7 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) | |||
795 | /* Bar 1: downstream IO bar */ | 799 | /* Bar 1: downstream IO bar */ |
796 | fpci_bar = 0xfdfc0000; | 800 | fpci_bar = 0xfdfc0000; |
797 | size = resource_size(&pcie->io); | 801 | size = resource_size(&pcie->io); |
798 | axi_address = pcie->io.start; | 802 | axi_address = io_start; |
799 | afi_writel(pcie, axi_address, AFI_AXI_BAR1_START); | 803 | afi_writel(pcie, axi_address, AFI_AXI_BAR1_START); |
800 | afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ); | 804 | afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ); |
801 | afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1); | 805 | afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1); |
@@ -1680,7 +1684,9 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) | |||
1680 | } | 1684 | } |
1681 | 1685 | ||
1682 | for_each_of_pci_range(&parser, &range) { | 1686 | for_each_of_pci_range(&parser, &range) { |
1683 | of_pci_range_to_resource(&range, np, &res); | 1687 | err = of_pci_range_to_resource(&range, np, &res); |
1688 | if (err < 0) | ||
1689 | return err; | ||
1684 | 1690 | ||
1685 | switch (res.flags & IORESOURCE_TYPE_BITS) { | 1691 | switch (res.flags & IORESOURCE_TYPE_BITS) { |
1686 | case IORESOURCE_IO: | 1692 | case IORESOURCE_IO: |
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 4884ee5e07d4..61158e03ab5f 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c | |||
@@ -323,6 +323,7 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie) | |||
323 | 323 | ||
324 | /* Setup PCIe address space mappings for each resource */ | 324 | /* Setup PCIe address space mappings for each resource */ |
325 | resource_size_t size; | 325 | resource_size_t size; |
326 | resource_size_t res_start; | ||
326 | u32 mask; | 327 | u32 mask; |
327 | 328 | ||
328 | rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win)); | 329 | rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win)); |
@@ -335,8 +336,13 @@ static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie) | |||
335 | mask = (roundup_pow_of_two(size) / SZ_128) - 1; | 336 | mask = (roundup_pow_of_two(size) / SZ_128) - 1; |
336 | rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win)); | 337 | rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win)); |
337 | 338 | ||
338 | rcar_pci_write_reg(pcie, upper_32_bits(res->start), PCIEPARH(win)); | 339 | if (res->flags & IORESOURCE_IO) |
339 | rcar_pci_write_reg(pcie, lower_32_bits(res->start), PCIEPARL(win)); | 340 | res_start = pci_pio_to_address(res->start); |
341 | else | ||
342 | res_start = res->start; | ||
343 | |||
344 | rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPARH(win)); | ||
345 | rcar_pci_write_reg(pcie, lower_32_bits(res_start), PCIEPARL(win)); | ||
340 | 346 | ||
341 | /* First resource is for IO */ | 347 | /* First resource is for IO */ |
342 | mask = PAR_ENABLE; | 348 | mask = PAR_ENABLE; |
@@ -363,9 +369,10 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys) | |||
363 | 369 | ||
364 | rcar_pcie_setup_window(i, pcie); | 370 | rcar_pcie_setup_window(i, pcie); |
365 | 371 | ||
366 | if (res->flags & IORESOURCE_IO) | 372 | if (res->flags & IORESOURCE_IO) { |
367 | pci_ioremap_io(nr * SZ_64K, res->start); | 373 | phys_addr_t io_start = pci_pio_to_address(res->start); |
368 | else | 374 | pci_ioremap_io(nr * SZ_64K, io_start); |
375 | } else | ||
369 | pci_add_resource(&sys->resources, res); | 376 | pci_add_resource(&sys->resources, res); |
370 | } | 377 | } |
371 | pci_add_resource(&sys->resources, &pcie->busn); | 378 | pci_add_resource(&sys->resources, &pcie->busn); |
@@ -935,8 +942,10 @@ static int rcar_pcie_probe(struct platform_device *pdev) | |||
935 | } | 942 | } |
936 | 943 | ||
937 | for_each_of_pci_range(&parser, &range) { | 944 | for_each_of_pci_range(&parser, &range) { |
938 | of_pci_range_to_resource(&range, pdev->dev.of_node, | 945 | err = of_pci_range_to_resource(&range, pdev->dev.of_node, |
939 | &pcie->res[win++]); | 946 | &pcie->res[win++]); |
947 | if (err < 0) | ||
948 | return err; | ||
940 | 949 | ||
941 | if (win > RCAR_PCI_MAX_RESOURCES) | 950 | if (win > RCAR_PCI_MAX_RESOURCES) |
942 | break; | 951 | break; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b7678be7b106..625a4ace10b4 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -2707,6 +2707,37 @@ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name) | |||
2707 | } | 2707 | } |
2708 | EXPORT_SYMBOL(pci_request_regions_exclusive); | 2708 | EXPORT_SYMBOL(pci_request_regions_exclusive); |
2709 | 2709 | ||
2710 | /** | ||
2711 | * pci_remap_iospace - Remap the memory mapped I/O space | ||
2712 | * @res: Resource describing the I/O space | ||
2713 | * @phys_addr: physical address of range to be mapped | ||
2714 | * | ||
2715 | * Remap the memory mapped I/O space described by the @res | ||
2716 | * and the CPU physical address @phys_addr into virtual address space. | ||
2717 | * Only architectures that have memory mapped IO functions defined | ||
2718 | * (and the PCI_IOBASE value defined) should call this function. | ||
2719 | */ | ||
2720 | int __weak pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr) | ||
2721 | { | ||
2722 | #if defined(PCI_IOBASE) && defined(CONFIG_MMU) | ||
2723 | unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start; | ||
2724 | |||
2725 | if (!(res->flags & IORESOURCE_IO)) | ||
2726 | return -EINVAL; | ||
2727 | |||
2728 | if (res->end > IO_SPACE_LIMIT) | ||
2729 | return -EINVAL; | ||
2730 | |||
2731 | return ioremap_page_range(vaddr, vaddr + resource_size(res), phys_addr, | ||
2732 | pgprot_device(PAGE_KERNEL)); | ||
2733 | #else | ||
2734 | /* this architecture does not have memory mapped I/O space, | ||
2735 | so this function should never be called */ | ||
2736 | WARN_ONCE(1, "This architecture does not support memory mapped I/O\n"); | ||
2737 | return -ENODEV; | ||
2738 | #endif | ||
2739 | } | ||
2740 | |||
2710 | static void __pci_set_master(struct pci_dev *dev, bool enable) | 2741 | static void __pci_set_master(struct pci_dev *dev, bool enable) |
2711 | { | 2742 | { |
2712 | u16 old_cmd, cmd; | 2743 | u16 old_cmd, cmd; |
@@ -4409,6 +4440,15 @@ static void pci_no_domains(void) | |||
4409 | #endif | 4440 | #endif |
4410 | } | 4441 | } |
4411 | 4442 | ||
4443 | #ifdef CONFIG_PCI_DOMAINS | ||
4444 | static atomic_t __domain_nr = ATOMIC_INIT(-1); | ||
4445 | |||
4446 | int pci_get_new_domain_nr(void) | ||
4447 | { | ||
4448 | return atomic_inc_return(&__domain_nr); | ||
4449 | } | ||
4450 | #endif | ||
4451 | |||
4412 | /** | 4452 | /** |
4413 | * pci_ext_cfg_avail - can we access extended PCI config space? | 4453 | * pci_ext_cfg_avail - can we access extended PCI config space? |
4414 | * | 4454 | * |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c99c4d65461b..efa48dc0de3b 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -486,7 +486,7 @@ void pci_read_bridge_bases(struct pci_bus *child) | |||
486 | } | 486 | } |
487 | } | 487 | } |
488 | 488 | ||
489 | static struct pci_bus *pci_alloc_bus(void) | 489 | static struct pci_bus *pci_alloc_bus(struct pci_bus *parent) |
490 | { | 490 | { |
491 | struct pci_bus *b; | 491 | struct pci_bus *b; |
492 | 492 | ||
@@ -501,6 +501,10 @@ static struct pci_bus *pci_alloc_bus(void) | |||
501 | INIT_LIST_HEAD(&b->resources); | 501 | INIT_LIST_HEAD(&b->resources); |
502 | b->max_bus_speed = PCI_SPEED_UNKNOWN; | 502 | b->max_bus_speed = PCI_SPEED_UNKNOWN; |
503 | b->cur_bus_speed = PCI_SPEED_UNKNOWN; | 503 | b->cur_bus_speed = PCI_SPEED_UNKNOWN; |
504 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | ||
505 | if (parent) | ||
506 | b->domain_nr = parent->domain_nr; | ||
507 | #endif | ||
504 | return b; | 508 | return b; |
505 | } | 509 | } |
506 | 510 | ||
@@ -672,7 +676,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
672 | /* | 676 | /* |
673 | * Allocate a new bus, and inherit stuff from the parent.. | 677 | * Allocate a new bus, and inherit stuff from the parent.. |
674 | */ | 678 | */ |
675 | child = pci_alloc_bus(); | 679 | child = pci_alloc_bus(parent); |
676 | if (!child) | 680 | if (!child) |
677 | return NULL; | 681 | return NULL; |
678 | 682 | ||
@@ -1913,13 +1917,14 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
1913 | char bus_addr[64]; | 1917 | char bus_addr[64]; |
1914 | char *fmt; | 1918 | char *fmt; |
1915 | 1919 | ||
1916 | b = pci_alloc_bus(); | 1920 | b = pci_alloc_bus(NULL); |
1917 | if (!b) | 1921 | if (!b) |
1918 | return NULL; | 1922 | return NULL; |
1919 | 1923 | ||
1920 | b->sysdata = sysdata; | 1924 | b->sysdata = sysdata; |
1921 | b->ops = ops; | 1925 | b->ops = ops; |
1922 | b->number = b->busn_res.start = bus; | 1926 | b->number = b->busn_res.start = bus; |
1927 | pci_bus_assign_domain_nr(b, parent); | ||
1923 | b2 = pci_find_bus(pci_domain_nr(b), bus); | 1928 | b2 = pci_find_bus(pci_domain_nr(b), bus); |
1924 | if (b2) { | 1929 | if (b2) { |
1925 | /* If we already got to this bus through a different bridge, ignore it */ | 1930 | /* If we already got to this bus through a different bridge, ignore it */ |
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h index 975e1cc75edb..b8fdc57a7335 100644 --- a/include/asm-generic/io.h +++ b/include/asm-generic/io.h | |||
@@ -331,7 +331,7 @@ static inline void iounmap(void __iomem *addr) | |||
331 | #ifndef CONFIG_GENERIC_IOMAP | 331 | #ifndef CONFIG_GENERIC_IOMAP |
332 | static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) | 332 | static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) |
333 | { | 333 | { |
334 | return (void __iomem *) port; | 334 | return PCI_IOBASE + (port & IO_SPACE_LIMIT); |
335 | } | 335 | } |
336 | 336 | ||
337 | static inline void ioport_unmap(void __iomem *p) | 337 | static inline void ioport_unmap(void __iomem *p) |
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 53b2acc38213..977e545a64c3 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h | |||
@@ -249,6 +249,10 @@ static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b) | |||
249 | #define pgprot_writecombine pgprot_noncached | 249 | #define pgprot_writecombine pgprot_noncached |
250 | #endif | 250 | #endif |
251 | 251 | ||
252 | #ifndef pgprot_device | ||
253 | #define pgprot_device pgprot_noncached | ||
254 | #endif | ||
255 | |||
252 | /* | 256 | /* |
253 | * When walking page tables, get the address of the next boundary, | 257 | * When walking page tables, get the address of the next boundary, |
254 | * or the end address of the range if that comes earlier. Although no | 258 | * or the end address of the range if that comes earlier. Although no |
diff --git a/include/linux/of_address.h b/include/linux/of_address.h index fb7b7221e063..8cb14eb393d6 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h | |||
@@ -23,17 +23,6 @@ struct of_pci_range { | |||
23 | #define for_each_of_pci_range(parser, range) \ | 23 | #define for_each_of_pci_range(parser, range) \ |
24 | for (; of_pci_range_parser_one(parser, range);) | 24 | for (; of_pci_range_parser_one(parser, range);) |
25 | 25 | ||
26 | static inline void of_pci_range_to_resource(struct of_pci_range *range, | ||
27 | struct device_node *np, | ||
28 | struct resource *res) | ||
29 | { | ||
30 | res->flags = range->flags; | ||
31 | res->start = range->cpu_addr; | ||
32 | res->end = range->cpu_addr + range->size - 1; | ||
33 | res->parent = res->child = res->sibling = NULL; | ||
34 | res->name = np->full_name; | ||
35 | } | ||
36 | |||
37 | /* Translate a DMA address from device space to CPU space */ | 26 | /* Translate a DMA address from device space to CPU space */ |
38 | extern u64 of_translate_dma_address(struct device_node *dev, | 27 | extern u64 of_translate_dma_address(struct device_node *dev, |
39 | const __be32 *in_addr); | 28 | const __be32 *in_addr); |
@@ -55,7 +44,9 @@ extern void __iomem *of_iomap(struct device_node *device, int index); | |||
55 | extern const __be32 *of_get_address(struct device_node *dev, int index, | 44 | extern const __be32 *of_get_address(struct device_node *dev, int index, |
56 | u64 *size, unsigned int *flags); | 45 | u64 *size, unsigned int *flags); |
57 | 46 | ||
47 | extern int pci_register_io_range(phys_addr_t addr, resource_size_t size); | ||
58 | extern unsigned long pci_address_to_pio(phys_addr_t addr); | 48 | extern unsigned long pci_address_to_pio(phys_addr_t addr); |
49 | extern phys_addr_t pci_pio_to_address(unsigned long pio); | ||
59 | 50 | ||
60 | extern int of_pci_range_parser_init(struct of_pci_range_parser *parser, | 51 | extern int of_pci_range_parser_init(struct of_pci_range_parser *parser, |
61 | struct device_node *node); | 52 | struct device_node *node); |
@@ -80,6 +71,11 @@ static inline const __be32 *of_get_address(struct device_node *dev, int index, | |||
80 | return NULL; | 71 | return NULL; |
81 | } | 72 | } |
82 | 73 | ||
74 | static inline phys_addr_t pci_pio_to_address(unsigned long pio) | ||
75 | { | ||
76 | return 0; | ||
77 | } | ||
78 | |||
83 | static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser, | 79 | static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser, |
84 | struct device_node *node) | 80 | struct device_node *node) |
85 | { | 81 | { |
@@ -138,6 +134,9 @@ extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, | |||
138 | u64 *size, unsigned int *flags); | 134 | u64 *size, unsigned int *flags); |
139 | extern int of_pci_address_to_resource(struct device_node *dev, int bar, | 135 | extern int of_pci_address_to_resource(struct device_node *dev, int bar, |
140 | struct resource *r); | 136 | struct resource *r); |
137 | extern int of_pci_range_to_resource(struct of_pci_range *range, | ||
138 | struct device_node *np, | ||
139 | struct resource *res); | ||
141 | #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */ | 140 | #else /* CONFIG_OF_ADDRESS && CONFIG_PCI */ |
142 | static inline int of_pci_address_to_resource(struct device_node *dev, int bar, | 141 | static inline int of_pci_address_to_resource(struct device_node *dev, int bar, |
143 | struct resource *r) | 142 | struct resource *r) |
@@ -150,6 +149,12 @@ static inline const __be32 *of_get_pci_address(struct device_node *dev, | |||
150 | { | 149 | { |
151 | return NULL; | 150 | return NULL; |
152 | } | 151 | } |
152 | static inline int of_pci_range_to_resource(struct of_pci_range *range, | ||
153 | struct device_node *np, | ||
154 | struct resource *res) | ||
155 | { | ||
156 | return -ENOSYS; | ||
157 | } | ||
153 | #endif /* CONFIG_OF_ADDRESS && CONFIG_PCI */ | 158 | #endif /* CONFIG_OF_ADDRESS && CONFIG_PCI */ |
154 | 159 | ||
155 | #endif /* __OF_ADDRESS_H */ | 160 | #endif /* __OF_ADDRESS_H */ |
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h index dde3a4a0fa5d..1fd207e7a847 100644 --- a/include/linux/of_pci.h +++ b/include/linux/of_pci.h | |||
@@ -15,6 +15,7 @@ struct device_node *of_pci_find_child_device(struct device_node *parent, | |||
15 | int of_pci_get_devfn(struct device_node *np); | 15 | int of_pci_get_devfn(struct device_node *np); |
16 | int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin); | 16 | int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin); |
17 | int of_pci_parse_bus_range(struct device_node *node, struct resource *res); | 17 | int of_pci_parse_bus_range(struct device_node *node, struct resource *res); |
18 | int of_get_pci_domain_nr(struct device_node *node); | ||
18 | #else | 19 | #else |
19 | static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq) | 20 | static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq) |
20 | { | 21 | { |
@@ -43,6 +44,18 @@ of_pci_parse_bus_range(struct device_node *node, struct resource *res) | |||
43 | { | 44 | { |
44 | return -EINVAL; | 45 | return -EINVAL; |
45 | } | 46 | } |
47 | |||
48 | static inline int | ||
49 | of_get_pci_domain_nr(struct device_node *node) | ||
50 | { | ||
51 | return -1; | ||
52 | } | ||
53 | #endif | ||
54 | |||
55 | #if defined(CONFIG_OF_ADDRESS) | ||
56 | int of_pci_get_host_bridge_resources(struct device_node *dev, | ||
57 | unsigned char busno, unsigned char bus_max, | ||
58 | struct list_head *resources, resource_size_t *io_base); | ||
46 | #endif | 59 | #endif |
47 | 60 | ||
48 | #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI) | 61 | #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI) |
diff --git a/include/linux/pci.h b/include/linux/pci.h index ef98f73ea618..9cd27210a889 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -456,6 +456,9 @@ struct pci_bus { | |||
456 | unsigned char primary; /* number of primary bridge */ | 456 | unsigned char primary; /* number of primary bridge */ |
457 | unsigned char max_bus_speed; /* enum pci_bus_speed */ | 457 | unsigned char max_bus_speed; /* enum pci_bus_speed */ |
458 | unsigned char cur_bus_speed; /* enum pci_bus_speed */ | 458 | unsigned char cur_bus_speed; /* enum pci_bus_speed */ |
459 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | ||
460 | int domain_nr; | ||
461 | #endif | ||
459 | 462 | ||
460 | char name[48]; | 463 | char name[48]; |
461 | 464 | ||
@@ -1097,6 +1100,9 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus, | |||
1097 | resource_size_t), | 1100 | resource_size_t), |
1098 | void *alignf_data); | 1101 | void *alignf_data); |
1099 | 1102 | ||
1103 | |||
1104 | int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr); | ||
1105 | |||
1100 | static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar) | 1106 | static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar) |
1101 | { | 1107 | { |
1102 | struct pci_bus_region region; | 1108 | struct pci_bus_region region; |
@@ -1282,12 +1288,32 @@ void pci_cfg_access_unlock(struct pci_dev *dev); | |||
1282 | */ | 1288 | */ |
1283 | #ifdef CONFIG_PCI_DOMAINS | 1289 | #ifdef CONFIG_PCI_DOMAINS |
1284 | extern int pci_domains_supported; | 1290 | extern int pci_domains_supported; |
1291 | int pci_get_new_domain_nr(void); | ||
1285 | #else | 1292 | #else |
1286 | enum { pci_domains_supported = 0 }; | 1293 | enum { pci_domains_supported = 0 }; |
1287 | static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } | 1294 | static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } |
1288 | static inline int pci_proc_domain(struct pci_bus *bus) { return 0; } | 1295 | static inline int pci_proc_domain(struct pci_bus *bus) { return 0; } |
1296 | static inline int pci_get_new_domain_nr(void) { return -ENOSYS; } | ||
1289 | #endif /* CONFIG_PCI_DOMAINS */ | 1297 | #endif /* CONFIG_PCI_DOMAINS */ |
1290 | 1298 | ||
1299 | /* | ||
1300 | * Generic implementation for PCI domain support. If your | ||
1301 | * architecture does not need custom management of PCI | ||
1302 | * domains then this implementation will be used | ||
1303 | */ | ||
1304 | #ifdef CONFIG_PCI_DOMAINS_GENERIC | ||
1305 | static inline int pci_domain_nr(struct pci_bus *bus) | ||
1306 | { | ||
1307 | return bus->domain_nr; | ||
1308 | } | ||
1309 | void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent); | ||
1310 | #else | ||
1311 | static inline void pci_bus_assign_domain_nr(struct pci_bus *bus, | ||
1312 | struct device *parent) | ||
1313 | { | ||
1314 | } | ||
1315 | #endif | ||
1316 | |||
1291 | /* some architectures require additional setup to direct VGA traffic */ | 1317 | /* some architectures require additional setup to direct VGA traffic */ |
1292 | typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode, | 1318 | typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode, |
1293 | unsigned int command_bits, u32 flags); | 1319 | unsigned int command_bits, u32 flags); |
@@ -1396,6 +1422,7 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus, | |||
1396 | 1422 | ||
1397 | static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } | 1423 | static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } |
1398 | static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; } | 1424 | static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) { return NULL; } |
1425 | static inline int pci_get_new_domain_nr(void) { return -ENOSYS; } | ||
1399 | 1426 | ||
1400 | #define dev_is_pci(d) (false) | 1427 | #define dev_is_pci(d) (false) |
1401 | #define dev_is_pf(d) (false) | 1428 | #define dev_is_pf(d) (false) |