diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-06 11:12:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-06 11:12:08 -0400 |
commit | f84d9fa86820b3074a8c143444a6932c0c0fd019 (patch) | |
tree | 5a255baa763c8d895ab3dc5feee03c288e0f0810 | |
parent | 82fa407da081d05323171577d86f62d77df17465 (diff) | |
parent | 98e98eb6a8a179a444a30d903714fab356726155 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Pull sparc updates from David Miller:
"Besides some cleanups the major thing here is supporting relaxed
ordering PCIe transactions on newer sparc64 machines, from Chris
Hyser"
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
sparc: fixing ident and beautifying code
sparc64: Enable setting "relaxed ordering" in IOMMU mappings
sparc64: Enable PCI IOMMU version 2 API
sparc: migrate exception table users off module.h and onto extable.h
-rw-r--r-- | arch/sparc/include/asm/hypervisor.h | 1 | ||||
-rw-r--r-- | arch/sparc/kernel/kprobes.c | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/pci_sun4v.c | 52 | ||||
-rw-r--r-- | arch/sparc/kernel/traps_64.c | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/unaligned_64.c | 2 | ||||
-rw-r--r-- | arch/sparc/mm/fault_64.c | 2 | ||||
-rw-r--r-- | arch/sparc/mm/init_64.c | 2 | ||||
-rw-r--r-- | arch/sparc/prom/ranges.c | 52 |
8 files changed, 71 insertions, 44 deletions
diff --git a/arch/sparc/include/asm/hypervisor.h b/arch/sparc/include/asm/hypervisor.h index f5b6537306f0..666d5ba230d2 100644 --- a/arch/sparc/include/asm/hypervisor.h +++ b/arch/sparc/include/asm/hypervisor.h | |||
@@ -1744,6 +1744,7 @@ unsigned long sun4v_vintr_set_target(unsigned long dev_handle, | |||
1744 | 1744 | ||
1745 | #define HV_PCI_MAP_ATTR_READ 0x01 | 1745 | #define HV_PCI_MAP_ATTR_READ 0x01 |
1746 | #define HV_PCI_MAP_ATTR_WRITE 0x02 | 1746 | #define HV_PCI_MAP_ATTR_WRITE 0x02 |
1747 | #define HV_PCI_MAP_ATTR_RELAXED_ORDER 0x04 | ||
1747 | 1748 | ||
1748 | #define HV_PCI_DEVICE_BUILD(b,d,f) \ | 1749 | #define HV_PCI_DEVICE_BUILD(b,d,f) \ |
1749 | ((((b) & 0xff) << 16) | \ | 1750 | ((((b) & 0xff) << 16) | \ |
diff --git a/arch/sparc/kernel/kprobes.c b/arch/sparc/kernel/kprobes.c index cd83be527586..b0377db12d83 100644 --- a/arch/sparc/kernel/kprobes.c +++ b/arch/sparc/kernel/kprobes.c | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
7 | #include <linux/kprobes.h> | 7 | #include <linux/kprobes.h> |
8 | #include <linux/module.h> | 8 | #include <linux/extable.h> |
9 | #include <linux/kdebug.h> | 9 | #include <linux/kdebug.h> |
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
11 | #include <linux/context_tracking.h> | 11 | #include <linux/context_tracking.h> |
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 61c6f935accc..db57d8acdc01 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c | |||
@@ -30,8 +30,19 @@ | |||
30 | #define DRIVER_NAME "pci_sun4v" | 30 | #define DRIVER_NAME "pci_sun4v" |
31 | #define PFX DRIVER_NAME ": " | 31 | #define PFX DRIVER_NAME ": " |
32 | 32 | ||
33 | static unsigned long vpci_major = 1; | 33 | static unsigned long vpci_major; |
34 | static unsigned long vpci_minor = 1; | 34 | static unsigned long vpci_minor; |
35 | |||
36 | struct vpci_version { | ||
37 | unsigned long major; | ||
38 | unsigned long minor; | ||
39 | }; | ||
40 | |||
41 | /* Ordered from largest major to lowest */ | ||
42 | static struct vpci_version vpci_versions[] = { | ||
43 | { .major = 2, .minor = 0 }, | ||
44 | { .major = 1, .minor = 1 }, | ||
45 | }; | ||
35 | 46 | ||
36 | #define PGLIST_NENTS (PAGE_SIZE / sizeof(u64)) | 47 | #define PGLIST_NENTS (PAGE_SIZE / sizeof(u64)) |
37 | 48 | ||
@@ -67,6 +78,10 @@ static long iommu_batch_flush(struct iommu_batch *p) | |||
67 | u64 *pglist = p->pglist; | 78 | u64 *pglist = p->pglist; |
68 | unsigned long npages = p->npages; | 79 | unsigned long npages = p->npages; |
69 | 80 | ||
81 | /* VPCI maj=1, min=[0,1] only supports read and write */ | ||
82 | if (vpci_major < 2) | ||
83 | prot &= (HV_PCI_MAP_ATTR_READ | HV_PCI_MAP_ATTR_WRITE); | ||
84 | |||
70 | while (npages != 0) { | 85 | while (npages != 0) { |
71 | long num; | 86 | long num; |
72 | 87 | ||
@@ -133,6 +148,7 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size, | |||
133 | unsigned long attrs) | 148 | unsigned long attrs) |
134 | { | 149 | { |
135 | unsigned long flags, order, first_page, npages, n; | 150 | unsigned long flags, order, first_page, npages, n; |
151 | unsigned long prot = 0; | ||
136 | struct iommu *iommu; | 152 | struct iommu *iommu; |
137 | struct page *page; | 153 | struct page *page; |
138 | void *ret; | 154 | void *ret; |
@@ -146,6 +162,9 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size, | |||
146 | 162 | ||
147 | npages = size >> IO_PAGE_SHIFT; | 163 | npages = size >> IO_PAGE_SHIFT; |
148 | 164 | ||
165 | if (attrs & DMA_ATTR_WEAK_ORDERING) | ||
166 | prot = HV_PCI_MAP_ATTR_RELAXED_ORDER; | ||
167 | |||
149 | nid = dev->archdata.numa_node; | 168 | nid = dev->archdata.numa_node; |
150 | page = alloc_pages_node(nid, gfp, order); | 169 | page = alloc_pages_node(nid, gfp, order); |
151 | if (unlikely(!page)) | 170 | if (unlikely(!page)) |
@@ -169,7 +188,7 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size, | |||
169 | local_irq_save(flags); | 188 | local_irq_save(flags); |
170 | 189 | ||
171 | iommu_batch_start(dev, | 190 | iommu_batch_start(dev, |
172 | (HV_PCI_MAP_ATTR_READ | | 191 | (HV_PCI_MAP_ATTR_READ | prot | |
173 | HV_PCI_MAP_ATTR_WRITE), | 192 | HV_PCI_MAP_ATTR_WRITE), |
174 | entry); | 193 | entry); |
175 | 194 | ||
@@ -266,6 +285,9 @@ static dma_addr_t dma_4v_map_page(struct device *dev, struct page *page, | |||
266 | if (direction != DMA_TO_DEVICE) | 285 | if (direction != DMA_TO_DEVICE) |
267 | prot |= HV_PCI_MAP_ATTR_WRITE; | 286 | prot |= HV_PCI_MAP_ATTR_WRITE; |
268 | 287 | ||
288 | if (attrs & DMA_ATTR_WEAK_ORDERING) | ||
289 | prot |= HV_PCI_MAP_ATTR_RELAXED_ORDER; | ||
290 | |||
269 | local_irq_save(flags); | 291 | local_irq_save(flags); |
270 | 292 | ||
271 | iommu_batch_start(dev, prot, entry); | 293 | iommu_batch_start(dev, prot, entry); |
@@ -344,6 +366,9 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, | |||
344 | if (direction != DMA_TO_DEVICE) | 366 | if (direction != DMA_TO_DEVICE) |
345 | prot |= HV_PCI_MAP_ATTR_WRITE; | 367 | prot |= HV_PCI_MAP_ATTR_WRITE; |
346 | 368 | ||
369 | if (attrs & DMA_ATTR_WEAK_ORDERING) | ||
370 | prot |= HV_PCI_MAP_ATTR_RELAXED_ORDER; | ||
371 | |||
347 | outs = s = segstart = &sglist[0]; | 372 | outs = s = segstart = &sglist[0]; |
348 | outcount = 1; | 373 | outcount = 1; |
349 | incount = nelems; | 374 | incount = nelems; |
@@ -907,22 +932,27 @@ static int pci_sun4v_probe(struct platform_device *op) | |||
907 | struct device_node *dp; | 932 | struct device_node *dp; |
908 | struct iommu *iommu; | 933 | struct iommu *iommu; |
909 | u32 devhandle; | 934 | u32 devhandle; |
910 | int i, err; | 935 | int i, err = -ENODEV; |
911 | 936 | ||
912 | dp = op->dev.of_node; | 937 | dp = op->dev.of_node; |
913 | 938 | ||
914 | if (!hvapi_negotiated++) { | 939 | if (!hvapi_negotiated++) { |
915 | err = sun4v_hvapi_register(HV_GRP_PCI, | 940 | for (i = 0; i < ARRAY_SIZE(vpci_versions); i++) { |
916 | vpci_major, | 941 | vpci_major = vpci_versions[i].major; |
917 | &vpci_minor); | 942 | vpci_minor = vpci_versions[i].minor; |
943 | |||
944 | err = sun4v_hvapi_register(HV_GRP_PCI, vpci_major, | ||
945 | &vpci_minor); | ||
946 | if (!err) | ||
947 | break; | ||
948 | } | ||
918 | 949 | ||
919 | if (err) { | 950 | if (err) { |
920 | printk(KERN_ERR PFX "Could not register hvapi, " | 951 | pr_err(PFX "Could not register hvapi, err=%d\n", err); |
921 | "err=%d\n", err); | ||
922 | return err; | 952 | return err; |
923 | } | 953 | } |
924 | printk(KERN_INFO PFX "Registered hvapi major[%lu] minor[%lu]\n", | 954 | pr_info(PFX "Registered hvapi major[%lu] minor[%lu]\n", |
925 | vpci_major, vpci_minor); | 955 | vpci_major, vpci_minor); |
926 | 956 | ||
927 | dma_ops = &sun4v_dma_ops; | 957 | dma_ops = &sun4v_dma_ops; |
928 | } | 958 | } |
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index d21cd625c0de..4094a51b1970 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * I like traps on v9, :)))) | 8 | * I like traps on v9, :)))) |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/module.h> | 11 | #include <linux/extable.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index 9aacb9159262..52c00d90d4b4 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/mm.h> | 13 | #include <linux/mm.h> |
14 | #include <linux/module.h> | 14 | #include <linux/extable.h> |
15 | #include <asm/asi.h> | 15 | #include <asm/asi.h> |
16 | #include <asm/ptrace.h> | 16 | #include <asm/ptrace.h> |
17 | #include <asm/pstate.h> | 17 | #include <asm/pstate.h> |
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c index 3f291d8c57f7..643c149a3151 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/mman.h> | 14 | #include <linux/mman.h> |
15 | #include <linux/signal.h> | 15 | #include <linux/signal.h> |
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/module.h> | 17 | #include <linux/extable.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/perf_event.h> | 19 | #include <linux/perf_event.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 7ac6b62fb7c1..439784b7b7ac 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * Copyright (C) 1997-1999 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | 5 | * Copyright (C) 1997-1999 Jakub Jelinek (jj@sunsite.mff.cuni.cz) |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/module.h> | 8 | #include <linux/extable.h> |
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
11 | #include <linux/string.h> | 11 | #include <linux/string.h> |
diff --git a/arch/sparc/prom/ranges.c b/arch/sparc/prom/ranges.c index ad143c13bdc0..6d8dc2aa94ce 100644 --- a/arch/sparc/prom/ranges.c +++ b/arch/sparc/prom/ranges.c | |||
@@ -16,9 +16,8 @@ static struct linux_prom_ranges promlib_obio_ranges[PROMREG_MAX]; | |||
16 | static int num_obio_ranges; | 16 | static int num_obio_ranges; |
17 | 17 | ||
18 | /* Adjust register values based upon the ranges parameters. */ | 18 | /* Adjust register values based upon the ranges parameters. */ |
19 | static void | 19 | static void prom_adjust_regs(struct linux_prom_registers *regp, int nregs, |
20 | prom_adjust_regs(struct linux_prom_registers *regp, int nregs, | 20 | struct linux_prom_ranges *rangep, int nranges) |
21 | struct linux_prom_ranges *rangep, int nranges) | ||
22 | { | 21 | { |
23 | int regc, rngc; | 22 | int regc, rngc; |
24 | 23 | ||
@@ -34,33 +33,30 @@ prom_adjust_regs(struct linux_prom_registers *regp, int nregs, | |||
34 | } | 33 | } |
35 | } | 34 | } |
36 | 35 | ||
37 | static void | 36 | static void prom_adjust_ranges(struct linux_prom_ranges *ranges1, int nranges1, |
38 | prom_adjust_ranges(struct linux_prom_ranges *ranges1, int nranges1, | 37 | struct linux_prom_ranges *ranges2, int nranges2) |
39 | struct linux_prom_ranges *ranges2, int nranges2) | ||
40 | { | 38 | { |
41 | int rng1c, rng2c; | 39 | int rng1c, rng2c; |
42 | 40 | ||
43 | for(rng1c=0; rng1c < nranges1; rng1c++) { | 41 | for (rng1c = 0; rng1c < nranges1; rng1c++) { |
44 | for(rng2c=0; rng2c < nranges2; rng2c++) | 42 | for (rng2c = 0; rng2c < nranges2; rng2c++) |
45 | if(ranges1[rng1c].ot_parent_space == ranges2[rng2c].ot_child_space && | 43 | if (ranges1[rng1c].ot_parent_space == ranges2[rng2c].ot_child_space && |
46 | ranges1[rng1c].ot_parent_base >= ranges2[rng2c].ot_child_base && | 44 | ranges1[rng1c].ot_parent_base >= ranges2[rng2c].ot_child_base && |
47 | ranges2[rng2c].ot_child_base + ranges2[rng2c].or_size - ranges1[rng1c].ot_parent_base > 0U) | 45 | ranges2[rng2c].ot_child_base + ranges2[rng2c].or_size - ranges1[rng1c].ot_parent_base > 0U) |
48 | break; | 46 | break; |
49 | if(rng2c == nranges2) /* oops */ | 47 | if (rng2c == nranges2) /* oops */ |
50 | prom_printf("adjust_ranges: Could not find matching bus type...\n"); | 48 | prom_printf("adjust_ranges: Could not find matching bus type...\n"); |
51 | else if (ranges1[rng1c].ot_parent_base + ranges1[rng1c].or_size > ranges2[rng2c].ot_child_base + ranges2[rng2c].or_size) | 49 | else if (ranges1[rng1c].ot_parent_base + ranges1[rng1c].or_size > ranges2[rng2c].ot_child_base + ranges2[rng2c].or_size) |
52 | ranges1[rng1c].or_size = | 50 | ranges1[rng1c].or_size = ranges2[rng2c].ot_child_base + ranges2[rng2c].or_size - ranges1[rng1c].ot_parent_base; |
53 | ranges2[rng2c].ot_child_base + ranges2[rng2c].or_size - ranges1[rng1c].ot_parent_base; | ||
54 | ranges1[rng1c].ot_parent_space = ranges2[rng2c].ot_parent_space; | 51 | ranges1[rng1c].ot_parent_space = ranges2[rng2c].ot_parent_space; |
55 | ranges1[rng1c].ot_parent_base += ranges2[rng2c].ot_parent_base; | 52 | ranges1[rng1c].ot_parent_base += ranges2[rng2c].ot_parent_base; |
56 | } | 53 | } |
57 | } | 54 | } |
58 | 55 | ||
59 | /* Apply probed obio ranges to registers passed, if no ranges return. */ | 56 | /* Apply probed obio ranges to registers passed, if no ranges return. */ |
60 | void | 57 | void prom_apply_obio_ranges(struct linux_prom_registers *regs, int nregs) |
61 | prom_apply_obio_ranges(struct linux_prom_registers *regs, int nregs) | ||
62 | { | 58 | { |
63 | if(num_obio_ranges) | 59 | if (num_obio_ranges) |
64 | prom_adjust_regs(regs, nregs, promlib_obio_ranges, num_obio_ranges); | 60 | prom_adjust_regs(regs, nregs, promlib_obio_ranges, num_obio_ranges); |
65 | } | 61 | } |
66 | EXPORT_SYMBOL(prom_apply_obio_ranges); | 62 | EXPORT_SYMBOL(prom_apply_obio_ranges); |
@@ -76,40 +72,40 @@ void __init prom_ranges_init(void) | |||
76 | node = prom_getchild(prom_root_node); | 72 | node = prom_getchild(prom_root_node); |
77 | obio_node = prom_searchsiblings(node, "obio"); | 73 | obio_node = prom_searchsiblings(node, "obio"); |
78 | 74 | ||
79 | if(obio_node) { | 75 | if (obio_node) { |
80 | success = prom_getproperty(obio_node, "ranges", | 76 | success = prom_getproperty(obio_node, "ranges", |
81 | (char *) promlib_obio_ranges, | 77 | (char *) promlib_obio_ranges, |
82 | sizeof(promlib_obio_ranges)); | 78 | sizeof(promlib_obio_ranges)); |
83 | if(success != -1) | 79 | if (success != -1) |
84 | num_obio_ranges = (success/sizeof(struct linux_prom_ranges)); | 80 | num_obio_ranges = (success / sizeof(struct linux_prom_ranges)); |
85 | } | 81 | } |
86 | 82 | ||
87 | if(num_obio_ranges) | 83 | if (num_obio_ranges) |
88 | prom_printf("PROMLIB: obio_ranges %d\n", num_obio_ranges); | 84 | prom_printf("PROMLIB: obio_ranges %d\n", num_obio_ranges); |
89 | } | 85 | } |
90 | 86 | ||
91 | void prom_apply_generic_ranges(phandle node, phandle parent, | 87 | void prom_apply_generic_ranges(phandle node, phandle parent, |
92 | struct linux_prom_registers *regs, int nregs) | 88 | struct linux_prom_registers *regs, int nregs) |
93 | { | 89 | { |
94 | int success; | 90 | int success; |
95 | int num_ranges; | 91 | int num_ranges; |
96 | struct linux_prom_ranges ranges[PROMREG_MAX]; | 92 | struct linux_prom_ranges ranges[PROMREG_MAX]; |
97 | 93 | ||
98 | success = prom_getproperty(node, "ranges", | 94 | success = prom_getproperty(node, "ranges", |
99 | (char *) ranges, | 95 | (char *) ranges, |
100 | sizeof (ranges)); | 96 | sizeof(ranges)); |
101 | if (success != -1) { | 97 | if (success != -1) { |
102 | num_ranges = (success/sizeof(struct linux_prom_ranges)); | 98 | num_ranges = (success / sizeof(struct linux_prom_ranges)); |
103 | if (parent) { | 99 | if (parent) { |
104 | struct linux_prom_ranges parent_ranges[PROMREG_MAX]; | 100 | struct linux_prom_ranges parent_ranges[PROMREG_MAX]; |
105 | int num_parent_ranges; | 101 | int num_parent_ranges; |
106 | 102 | ||
107 | success = prom_getproperty(parent, "ranges", | 103 | success = prom_getproperty(parent, "ranges", |
108 | (char *) parent_ranges, | 104 | (char *) parent_ranges, |
109 | sizeof (parent_ranges)); | 105 | sizeof(parent_ranges)); |
110 | if (success != -1) { | 106 | if (success != -1) { |
111 | num_parent_ranges = (success/sizeof(struct linux_prom_ranges)); | 107 | num_parent_ranges = (success / sizeof(struct linux_prom_ranges)); |
112 | prom_adjust_ranges (ranges, num_ranges, parent_ranges, num_parent_ranges); | 108 | prom_adjust_ranges(ranges, num_ranges, parent_ranges, num_parent_ranges); |
113 | } | 109 | } |
114 | } | 110 | } |
115 | prom_adjust_regs(regs, nregs, ranges, num_ranges); | 111 | prom_adjust_regs(regs, nregs, ranges, num_ranges); |