aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c59
1 files changed, 30 insertions, 29 deletions
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 0307901e4132..f253361552ae 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -52,7 +52,7 @@
52 52
53 53
54static void tce_invalidate_pSeries_sw(struct iommu_table *tbl, 54static void tce_invalidate_pSeries_sw(struct iommu_table *tbl,
55 u64 *startp, u64 *endp) 55 __be64 *startp, __be64 *endp)
56{ 56{
57 u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index; 57 u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index;
58 unsigned long start, end, inc; 58 unsigned long start, end, inc;
@@ -86,7 +86,7 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index,
86 struct dma_attrs *attrs) 86 struct dma_attrs *attrs)
87{ 87{
88 u64 proto_tce; 88 u64 proto_tce;
89 u64 *tcep, *tces; 89 __be64 *tcep, *tces;
90 u64 rpn; 90 u64 rpn;
91 91
92 proto_tce = TCE_PCI_READ; // Read allowed 92 proto_tce = TCE_PCI_READ; // Read allowed
@@ -94,12 +94,12 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index,
94 if (direction != DMA_TO_DEVICE) 94 if (direction != DMA_TO_DEVICE)
95 proto_tce |= TCE_PCI_WRITE; 95 proto_tce |= TCE_PCI_WRITE;
96 96
97 tces = tcep = ((u64 *)tbl->it_base) + index; 97 tces = tcep = ((__be64 *)tbl->it_base) + index;
98 98
99 while (npages--) { 99 while (npages--) {
100 /* can't move this out since we might cross MEMBLOCK boundary */ 100 /* can't move this out since we might cross MEMBLOCK boundary */
101 rpn = __pa(uaddr) >> TCE_SHIFT; 101 rpn = __pa(uaddr) >> TCE_SHIFT;
102 *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; 102 *tcep = cpu_to_be64(proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT);
103 103
104 uaddr += TCE_PAGE_SIZE; 104 uaddr += TCE_PAGE_SIZE;
105 tcep++; 105 tcep++;
@@ -113,9 +113,9 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index,
113 113
114static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) 114static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
115{ 115{
116 u64 *tcep, *tces; 116 __be64 *tcep, *tces;
117 117
118 tces = tcep = ((u64 *)tbl->it_base) + index; 118 tces = tcep = ((__be64 *)tbl->it_base) + index;
119 119
120 while (npages--) 120 while (npages--)
121 *(tcep++) = 0; 121 *(tcep++) = 0;
@@ -126,11 +126,11 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
126 126
127static unsigned long tce_get_pseries(struct iommu_table *tbl, long index) 127static unsigned long tce_get_pseries(struct iommu_table *tbl, long index)
128{ 128{
129 u64 *tcep; 129 __be64 *tcep;
130 130
131 tcep = ((u64 *)tbl->it_base) + index; 131 tcep = ((__be64 *)tbl->it_base) + index;
132 132
133 return *tcep; 133 return be64_to_cpu(*tcep);
134} 134}
135 135
136static void tce_free_pSeriesLP(struct iommu_table*, long, long); 136static void tce_free_pSeriesLP(struct iommu_table*, long, long);
@@ -177,7 +177,7 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
177 return ret; 177 return ret;
178} 178}
179 179
180static DEFINE_PER_CPU(u64 *, tce_page); 180static DEFINE_PER_CPU(__be64 *, tce_page);
181 181
182static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, 182static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
183 long npages, unsigned long uaddr, 183 long npages, unsigned long uaddr,
@@ -186,7 +186,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
186{ 186{
187 u64 rc = 0; 187 u64 rc = 0;
188 u64 proto_tce; 188 u64 proto_tce;
189 u64 *tcep; 189 __be64 *tcep;
190 u64 rpn; 190 u64 rpn;
191 long l, limit; 191 long l, limit;
192 long tcenum_start = tcenum, npages_start = npages; 192 long tcenum_start = tcenum, npages_start = npages;
@@ -206,7 +206,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
206 * from iommu_alloc{,_sg}() 206 * from iommu_alloc{,_sg}()
207 */ 207 */
208 if (!tcep) { 208 if (!tcep) {
209 tcep = (u64 *)__get_free_page(GFP_ATOMIC); 209 tcep = (__be64 *)__get_free_page(GFP_ATOMIC);
210 /* If allocation fails, fall back to the loop implementation */ 210 /* If allocation fails, fall back to the loop implementation */
211 if (!tcep) { 211 if (!tcep) {
212 local_irq_restore(flags); 212 local_irq_restore(flags);
@@ -230,7 +230,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
230 limit = min_t(long, npages, 4096/TCE_ENTRY_SIZE); 230 limit = min_t(long, npages, 4096/TCE_ENTRY_SIZE);
231 231
232 for (l = 0; l < limit; l++) { 232 for (l = 0; l < limit; l++) {
233 tcep[l] = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; 233 tcep[l] = cpu_to_be64(proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT);
234 rpn++; 234 rpn++;
235 } 235 }
236 236
@@ -329,16 +329,16 @@ struct direct_window {
329 329
330/* Dynamic DMA Window support */ 330/* Dynamic DMA Window support */
331struct ddw_query_response { 331struct ddw_query_response {
332 u32 windows_available; 332 __be32 windows_available;
333 u32 largest_available_block; 333 __be32 largest_available_block;
334 u32 page_size; 334 __be32 page_size;
335 u32 migration_capable; 335 __be32 migration_capable;
336}; 336};
337 337
338struct ddw_create_response { 338struct ddw_create_response {
339 u32 liobn; 339 __be32 liobn;
340 u32 addr_hi; 340 __be32 addr_hi;
341 u32 addr_lo; 341 __be32 addr_lo;
342}; 342};
343 343
344static LIST_HEAD(direct_window_list); 344static LIST_HEAD(direct_window_list);
@@ -392,7 +392,8 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
392 unsigned long num_pfn, const void *arg) 392 unsigned long num_pfn, const void *arg)
393{ 393{
394 const struct dynamic_dma_window_prop *maprange = arg; 394 const struct dynamic_dma_window_prop *maprange = arg;
395 u64 *tcep, tce_size, num_tce, dma_offset, next, proto_tce, liobn; 395 u64 tce_size, num_tce, dma_offset, next, proto_tce, liobn;
396 __be64 *tcep;
396 u32 tce_shift; 397 u32 tce_shift;
397 u64 rc = 0; 398 u64 rc = 0;
398 long l, limit; 399 long l, limit;
@@ -401,7 +402,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
401 tcep = __get_cpu_var(tce_page); 402 tcep = __get_cpu_var(tce_page);
402 403
403 if (!tcep) { 404 if (!tcep) {
404 tcep = (u64 *)__get_free_page(GFP_ATOMIC); 405 tcep = (__be64 *)__get_free_page(GFP_ATOMIC);
405 if (!tcep) { 406 if (!tcep) {
406 local_irq_enable(); 407 local_irq_enable();
407 return -ENOMEM; 408 return -ENOMEM;
@@ -435,7 +436,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
435 dma_offset = next + be64_to_cpu(maprange->dma_base); 436 dma_offset = next + be64_to_cpu(maprange->dma_base);
436 437
437 for (l = 0; l < limit; l++) { 438 for (l = 0; l < limit; l++) {
438 tcep[l] = proto_tce | next; 439 tcep[l] = cpu_to_be64(proto_tce | next);
439 next += tce_size; 440 next += tce_size;
440 } 441 }
441 442
@@ -780,7 +781,7 @@ static u64 find_existing_ddw(struct device_node *pdn)
780 list_for_each_entry(window, &direct_window_list, list) { 781 list_for_each_entry(window, &direct_window_list, list) {
781 if (window->device == pdn) { 782 if (window->device == pdn) {
782 direct64 = window->prop; 783 direct64 = window->prop;
783 dma_addr = direct64->dma_base; 784 dma_addr = be64_to_cpu(direct64->dma_base);
784 break; 785 break;
785 } 786 }
786 } 787 }
@@ -1045,11 +1046,11 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
1045 dev_dbg(&dev->dev, "no free dynamic windows"); 1046 dev_dbg(&dev->dev, "no free dynamic windows");
1046 goto out_restore_window; 1047 goto out_restore_window;
1047 } 1048 }
1048 if (query.page_size & 4) { 1049 if (be32_to_cpu(query.page_size) & 4) {
1049 page_shift = 24; /* 16MB */ 1050 page_shift = 24; /* 16MB */
1050 } else if (query.page_size & 2) { 1051 } else if (be32_to_cpu(query.page_size) & 2) {
1051 page_shift = 16; /* 64kB */ 1052 page_shift = 16; /* 64kB */
1052 } else if (query.page_size & 1) { 1053 } else if (be32_to_cpu(query.page_size) & 1) {
1053 page_shift = 12; /* 4kB */ 1054 page_shift = 12; /* 4kB */
1054 } else { 1055 } else {
1055 dev_dbg(&dev->dev, "no supported direct page size in mask %x", 1056 dev_dbg(&dev->dev, "no supported direct page size in mask %x",
@@ -1059,7 +1060,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
1059 /* verify the window * number of ptes will map the partition */ 1060 /* verify the window * number of ptes will map the partition */
1060 /* check largest block * page size > max memory hotplug addr */ 1061 /* check largest block * page size > max memory hotplug addr */
1061 max_addr = memory_hotplug_max(); 1062 max_addr = memory_hotplug_max();
1062 if (query.largest_available_block < (max_addr >> page_shift)) { 1063 if (be32_to_cpu(query.largest_available_block) < (max_addr >> page_shift)) {
1063 dev_dbg(&dev->dev, "can't map partiton max 0x%llx with %u " 1064 dev_dbg(&dev->dev, "can't map partiton max 0x%llx with %u "
1064 "%llu-sized pages\n", max_addr, query.largest_available_block, 1065 "%llu-sized pages\n", max_addr, query.largest_available_block,
1065 1ULL << page_shift); 1066 1ULL << page_shift);
@@ -1085,7 +1086,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
1085 if (ret != 0) 1086 if (ret != 0)
1086 goto out_free_prop; 1087 goto out_free_prop;
1087 1088
1088 ddwprop->liobn = cpu_to_be32(create.liobn); 1089 ddwprop->liobn = create.liobn;
1089 ddwprop->dma_base = cpu_to_be64(of_read_number(&create.addr_hi, 2)); 1090 ddwprop->dma_base = cpu_to_be64(of_read_number(&create.addr_hi, 2));
1090 ddwprop->tce_shift = cpu_to_be32(page_shift); 1091 ddwprop->tce_shift = cpu_to_be32(page_shift);
1091 ddwprop->window_shift = cpu_to_be32(len); 1092 ddwprop->window_shift = cpu_to_be32(len);