aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-06 11:12:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-06 11:12:08 -0400
commitf84d9fa86820b3074a8c143444a6932c0c0fd019 (patch)
tree5a255baa763c8d895ab3dc5feee03c288e0f0810
parent82fa407da081d05323171577d86f62d77df17465 (diff)
parent98e98eb6a8a179a444a30d903714fab356726155 (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.h1
-rw-r--r--arch/sparc/kernel/kprobes.c2
-rw-r--r--arch/sparc/kernel/pci_sun4v.c52
-rw-r--r--arch/sparc/kernel/traps_64.c2
-rw-r--r--arch/sparc/kernel/unaligned_64.c2
-rw-r--r--arch/sparc/mm/fault_64.c2
-rw-r--r--arch/sparc/mm/init_64.c2
-rw-r--r--arch/sparc/prom/ranges.c52
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
33static unsigned long vpci_major = 1; 33static unsigned long vpci_major;
34static unsigned long vpci_minor = 1; 34static unsigned long vpci_minor;
35
36struct vpci_version {
37 unsigned long major;
38 unsigned long minor;
39};
40
41/* Ordered from largest major to lowest */
42static 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];
16static int num_obio_ranges; 16static int num_obio_ranges;
17 17
18/* Adjust register values based upon the ranges parameters. */ 18/* Adjust register values based upon the ranges parameters. */
19static void 19static void prom_adjust_regs(struct linux_prom_registers *regp, int nregs,
20prom_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
37static void 36static void prom_adjust_ranges(struct linux_prom_ranges *ranges1, int nranges1,
38prom_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. */
60void 57void prom_apply_obio_ranges(struct linux_prom_registers *regs, int nregs)
61prom_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}
66EXPORT_SYMBOL(prom_apply_obio_ranges); 62EXPORT_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
91void prom_apply_generic_ranges(phandle node, phandle parent, 87void 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);