aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-05-13 16:57:05 -0400
committerDavid S. Miller <davem@davemloft.net>2012-05-13 16:57:05 -0400
commitd894d964ff7ddf5a81a5b150fee46caf99619f26 (patch)
treecb34a4346407f98e2d2d0ec272b3aeb6f7b84ab5
parent679bea5e438df70b5d4348fd2da4501aaeacebe0 (diff)
sparc32: Convert mmu_* interfaces from btfixup to method ops.
This set of changes displays one major danger of btfixup, interface signatures are not always type checked fully. As seen here the iounit variant of the map_dma_area routine had an incorrect type for one of it's arguments. It turns out to be harmless in this case, but just imagine trying to debug something involving this kind of problem. No thanks. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc/include/asm/dma.h39
-rw-r--r--arch/sparc/kernel/ioport.c8
-rw-r--r--arch/sparc/kernel/sparc_ksyms_32.c4
-rw-r--r--arch/sparc/mm/io-unit.c23
-rw-r--r--arch/sparc/mm/iommu.c49
5 files changed, 79 insertions, 44 deletions
diff --git a/arch/sparc/include/asm/dma.h b/arch/sparc/include/asm/dma.h
index 1ef6f0b0a39f..3d434ef5eae3 100644
--- a/arch/sparc/include/asm/dma.h
+++ b/arch/sparc/include/asm/dma.h
@@ -92,21 +92,31 @@ extern int isa_dma_bridge_buggy;
92#ifdef CONFIG_SPARC32 92#ifdef CONFIG_SPARC32
93 93
94/* Routines for data transfer buffers. */ 94/* Routines for data transfer buffers. */
95struct page;
96struct device; 95struct device;
97struct scatterlist; 96struct scatterlist;
98 97
99/* These are implementations for sbus_map_sg/sbus_unmap_sg... collapse later */ 98struct sparc32_dma_ops {
100BTFIXUPDEF_CALL(__u32, mmu_get_scsi_one, struct device *, char *, unsigned long) 99 __u32 (*get_scsi_one)(struct device *, char *, unsigned long);
101BTFIXUPDEF_CALL(void, mmu_get_scsi_sgl, struct device *, struct scatterlist *, int) 100 void (*get_scsi_sgl)(struct device *, struct scatterlist *, int);
102BTFIXUPDEF_CALL(void, mmu_release_scsi_one, struct device *, __u32, unsigned long) 101 void (*release_scsi_one)(struct device *, __u32, unsigned long);
103BTFIXUPDEF_CALL(void, mmu_release_scsi_sgl, struct device *, struct scatterlist *, int) 102 void (*release_scsi_sgl)(struct device *, struct scatterlist *,int);
103#ifdef CONFIG_SBUS
104 int (*map_dma_area)(struct device *, dma_addr_t *, unsigned long, unsigned long, int);
105 void (*unmap_dma_area)(struct device *, unsigned long, int);
106#endif
107};
108extern const struct sparc32_dma_ops *sparc32_dma_ops;
104 109
105#define mmu_get_scsi_one(dev,vaddr,len) BTFIXUP_CALL(mmu_get_scsi_one)(dev,vaddr,len) 110#define mmu_get_scsi_one(dev,vaddr,len) \
106#define mmu_get_scsi_sgl(dev,sg,sz) BTFIXUP_CALL(mmu_get_scsi_sgl)(dev,sg,sz) 111 sparc32_dma_ops->get_scsi_one(dev, vaddr, len)
107#define mmu_release_scsi_one(dev,vaddr,len) BTFIXUP_CALL(mmu_release_scsi_one)(dev,vaddr,len) 112#define mmu_get_scsi_sgl(dev,sg,sz) \
108#define mmu_release_scsi_sgl(dev,sg,sz) BTFIXUP_CALL(mmu_release_scsi_sgl)(dev,sg,sz) 113 sparc32_dma_ops->get_scsi_sgl(dev, sg, sz)
114#define mmu_release_scsi_one(dev,vaddr,len) \
115 sparc32_dma_ops->release_scsi_one(dev, vaddr,len)
116#define mmu_release_scsi_sgl(dev,sg,sz) \
117 sparc32_dma_ops->release_scsi_sgl(dev, sg, sz)
109 118
119#ifdef CONFIG_SBUS
110/* 120/*
111 * mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep. 121 * mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep.
112 * 122 *
@@ -122,11 +132,12 @@ BTFIXUPDEF_CALL(void, mmu_release_scsi_sgl, struct device *, struct scatterlist
122 * know if we are mapping RAM or I/O, so it has to be an additional argument 132 * know if we are mapping RAM or I/O, so it has to be an additional argument
123 * to a separate mapping function for CPU visible mappings. 133 * to a separate mapping function for CPU visible mappings.
124 */ 134 */
125BTFIXUPDEF_CALL(int, mmu_map_dma_area, struct device *, dma_addr_t *, unsigned long, unsigned long, int len) 135#define sbus_map_dma_area(dev,pba,va,a,len) \
126BTFIXUPDEF_CALL(void, mmu_unmap_dma_area, struct device *, unsigned long busa, int len) 136 sparc32_dma_ops->map_dma_area(dev, pba, va, a, len)
137#define sbus_unmap_dma_area(dev,ba,len) \
138 sparc32_dma_ops->unmap_dma_area(dev, ba, len)
139#endif /* CONFIG_SBUS */
127 140
128#define mmu_map_dma_area(dev,pba,va,a,len) BTFIXUP_CALL(mmu_map_dma_area)(dev,pba,va,a,len)
129#define mmu_unmap_dma_area(dev,ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(dev,ba,len)
130#endif 141#endif
131 142
132#endif /* !(_ASM_SPARC_DMA_H) */ 143#endif /* !(_ASM_SPARC_DMA_H) */
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 1720fc294f5e..a2846f5e32d8 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -50,6 +50,8 @@
50#include <asm/io-unit.h> 50#include <asm/io-unit.h>
51#include <asm/leon.h> 51#include <asm/leon.h>
52 52
53const struct sparc32_dma_ops *sparc32_dma_ops;
54
53/* This function must make sure that caches and memory are coherent after DMA 55/* This function must make sure that caches and memory are coherent after DMA
54 * On LEON systems without cache snooping it flushes the entire D-CACHE. 56 * On LEON systems without cache snooping it flushes the entire D-CACHE.
55 */ 57 */
@@ -292,13 +294,13 @@ static void *sbus_alloc_coherent(struct device *dev, size_t len,
292 goto err_nova; 294 goto err_nova;
293 } 295 }
294 296
295 // XXX The mmu_map_dma_area does this for us below, see comments. 297 // XXX The sbus_map_dma_area does this for us below, see comments.
296 // srmmu_mapiorange(0, virt_to_phys(va), res->start, len_total); 298 // srmmu_mapiorange(0, virt_to_phys(va), res->start, len_total);
297 /* 299 /*
298 * XXX That's where sdev would be used. Currently we load 300 * XXX That's where sdev would be used. Currently we load
299 * all iommu tables with the same translations. 301 * all iommu tables with the same translations.
300 */ 302 */
301 if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0) 303 if (sbus_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0)
302 goto err_noiommu; 304 goto err_noiommu;
303 305
304 res->name = op->dev.of_node->name; 306 res->name = op->dev.of_node->name;
@@ -343,7 +345,7 @@ static void sbus_free_coherent(struct device *dev, size_t n, void *p,
343 kfree(res); 345 kfree(res);
344 346
345 pgv = virt_to_page(p); 347 pgv = virt_to_page(p);
346 mmu_unmap_dma_area(dev, ba, n); 348 sbus_unmap_dma_area(dev, ba, n);
347 349
348 __free_pages(pgv, get_order(n)); 350 __free_pages(pgv, get_order(n));
349} 351}
diff --git a/arch/sparc/kernel/sparc_ksyms_32.c b/arch/sparc/kernel/sparc_ksyms_32.c
index 5cc35baddedf..4ad7377e2d0f 100644
--- a/arch/sparc/kernel/sparc_ksyms_32.c
+++ b/arch/sparc/kernel/sparc_ksyms_32.c
@@ -32,10 +32,6 @@ EXPORT_SYMBOL(empty_zero_page);
32#ifdef CONFIG_SMP 32#ifdef CONFIG_SMP
33EXPORT_SYMBOL(BTFIXUP_CALL(__hard_smp_processor_id)); 33EXPORT_SYMBOL(BTFIXUP_CALL(__hard_smp_processor_id));
34#endif 34#endif
35EXPORT_SYMBOL(BTFIXUP_CALL(mmu_get_scsi_sgl));
36EXPORT_SYMBOL(BTFIXUP_CALL(mmu_get_scsi_one));
37EXPORT_SYMBOL(BTFIXUP_CALL(mmu_release_scsi_sgl));
38EXPORT_SYMBOL(BTFIXUP_CALL(mmu_release_scsi_one));
39 35
40/* Exporting a symbol from /init/main.c */ 36/* Exporting a symbol from /init/main.c */
41EXPORT_SYMBOL(saved_command_line); 37EXPORT_SYMBOL(saved_command_line);
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index d175c0ae5e4d..eb99862e9654 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -197,7 +197,7 @@ static void iounit_release_scsi_sgl(struct device *dev, struct scatterlist *sg,
197} 197}
198 198
199#ifdef CONFIG_SBUS 199#ifdef CONFIG_SBUS
200static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, __u32 addr, int len) 200static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, unsigned long addr, int len)
201{ 201{
202 struct iounit_struct *iounit = dev->archdata.iommu; 202 struct iounit_struct *iounit = dev->archdata.iommu;
203 unsigned long page, end; 203 unsigned long page, end;
@@ -242,15 +242,18 @@ static void iounit_unmap_dma_area(struct device *dev, unsigned long addr, int le
242} 242}
243#endif 243#endif
244 244
245void __init ld_mmu_iounit(void) 245static const struct sparc32_dma_ops iounit_dma_ops = {
246{ 246 .get_scsi_one = iounit_get_scsi_one,
247 BTFIXUPSET_CALL(mmu_get_scsi_one, iounit_get_scsi_one, BTFIXUPCALL_NORM); 247 .get_scsi_sgl = iounit_get_scsi_sgl,
248 BTFIXUPSET_CALL(mmu_get_scsi_sgl, iounit_get_scsi_sgl, BTFIXUPCALL_NORM); 248 .release_scsi_one = iounit_release_scsi_one,
249 BTFIXUPSET_CALL(mmu_release_scsi_one, iounit_release_scsi_one, BTFIXUPCALL_NORM); 249 .release_scsi_sgl = iounit_release_scsi_sgl,
250 BTFIXUPSET_CALL(mmu_release_scsi_sgl, iounit_release_scsi_sgl, BTFIXUPCALL_NORM);
251
252#ifdef CONFIG_SBUS 250#ifdef CONFIG_SBUS
253 BTFIXUPSET_CALL(mmu_map_dma_area, iounit_map_dma_area, BTFIXUPCALL_NORM); 251 .map_dma_area = iounit_map_dma_area,
254 BTFIXUPSET_CALL(mmu_unmap_dma_area, iounit_unmap_dma_area, BTFIXUPCALL_NORM); 252 .unmap_dma_area = iounit_unmap_dma_area,
255#endif 253#endif
254};
255
256void __init ld_mmu_iounit(void)
257{
258 sparc32_dma_ops = &iounit_dma_ops;
256} 259}
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 349ba83f1789..c64f81e370aa 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -426,29 +426,52 @@ static void iommu_unmap_dma_area(struct device *dev, unsigned long busa, int len
426} 426}
427#endif 427#endif
428 428
429static const struct sparc32_dma_ops iommu_dma_noflush_ops = {
430 .get_scsi_one = iommu_get_scsi_one_noflush,
431 .get_scsi_sgl = iommu_get_scsi_sgl_noflush,
432 .release_scsi_one = iommu_release_scsi_one,
433 .release_scsi_sgl = iommu_release_scsi_sgl,
434#ifdef CONFIG_SBUS
435 .map_dma_area = iommu_map_dma_area,
436 .unmap_dma_area = iommu_unmap_dma_area,
437#endif
438};
439
440static const struct sparc32_dma_ops iommu_dma_gflush_ops = {
441 .get_scsi_one = iommu_get_scsi_one_gflush,
442 .get_scsi_sgl = iommu_get_scsi_sgl_gflush,
443 .release_scsi_one = iommu_release_scsi_one,
444 .release_scsi_sgl = iommu_release_scsi_sgl,
445#ifdef CONFIG_SBUS
446 .map_dma_area = iommu_map_dma_area,
447 .unmap_dma_area = iommu_unmap_dma_area,
448#endif
449};
450
451static const struct sparc32_dma_ops iommu_dma_pflush_ops = {
452 .get_scsi_one = iommu_get_scsi_one_pflush,
453 .get_scsi_sgl = iommu_get_scsi_sgl_pflush,
454 .release_scsi_one = iommu_release_scsi_one,
455 .release_scsi_sgl = iommu_release_scsi_sgl,
456#ifdef CONFIG_SBUS
457 .map_dma_area = iommu_map_dma_area,
458 .unmap_dma_area = iommu_unmap_dma_area,
459#endif
460};
461
429void __init ld_mmu_iommu(void) 462void __init ld_mmu_iommu(void)
430{ 463{
431 viking_flush = (BTFIXUPVAL_CALL(flush_page_for_dma) == (unsigned long)viking_flush_page); 464 viking_flush = (BTFIXUPVAL_CALL(flush_page_for_dma) == (unsigned long)viking_flush_page);
432 465
433 if (!BTFIXUPVAL_CALL(flush_page_for_dma)) { 466 if (!BTFIXUPVAL_CALL(flush_page_for_dma)) {
434 /* IO coherent chip */ 467 /* IO coherent chip */
435 BTFIXUPSET_CALL(mmu_get_scsi_one, iommu_get_scsi_one_noflush, BTFIXUPCALL_RETO0); 468 sparc32_dma_ops = &iommu_dma_noflush_ops;
436 BTFIXUPSET_CALL(mmu_get_scsi_sgl, iommu_get_scsi_sgl_noflush, BTFIXUPCALL_NORM);
437 } else if (flush_page_for_dma_global) { 469 } else if (flush_page_for_dma_global) {
438 /* flush_page_for_dma flushes everything, no matter of what page is it */ 470 /* flush_page_for_dma flushes everything, no matter of what page is it */
439 BTFIXUPSET_CALL(mmu_get_scsi_one, iommu_get_scsi_one_gflush, BTFIXUPCALL_NORM); 471 sparc32_dma_ops = &iommu_dma_gflush_ops;
440 BTFIXUPSET_CALL(mmu_get_scsi_sgl, iommu_get_scsi_sgl_gflush, BTFIXUPCALL_NORM);
441 } else { 472 } else {
442 BTFIXUPSET_CALL(mmu_get_scsi_one, iommu_get_scsi_one_pflush, BTFIXUPCALL_NORM); 473 sparc32_dma_ops = &iommu_dma_pflush_ops;
443 BTFIXUPSET_CALL(mmu_get_scsi_sgl, iommu_get_scsi_sgl_pflush, BTFIXUPCALL_NORM);
444 } 474 }
445 BTFIXUPSET_CALL(mmu_release_scsi_one, iommu_release_scsi_one, BTFIXUPCALL_NORM);
446 BTFIXUPSET_CALL(mmu_release_scsi_sgl, iommu_release_scsi_sgl, BTFIXUPCALL_NORM);
447
448#ifdef CONFIG_SBUS
449 BTFIXUPSET_CALL(mmu_map_dma_area, iommu_map_dma_area, BTFIXUPCALL_NORM);
450 BTFIXUPSET_CALL(mmu_unmap_dma_area, iommu_unmap_dma_area, BTFIXUPCALL_NORM);
451#endif
452 475
453 if (viking_mxcc_present || srmmu_modtype == HyperSparc) { 476 if (viking_mxcc_present || srmmu_modtype == HyperSparc) {
454 dvma_prot = __pgprot(SRMMU_CACHE | SRMMU_ET_PTE | SRMMU_PRIV); 477 dvma_prot = __pgprot(SRMMU_CACHE | SRMMU_ET_PTE | SRMMU_PRIV);