diff options
-rw-r--r-- | arch/powerpc/include/asm/device.h | 11 | ||||
-rw-r--r-- | arch/powerpc/include/asm/dma-mapping.h | 10 | ||||
-rw-r--r-- | arch/powerpc/include/asm/iommu.h | 10 | ||||
-rw-r--r-- | arch/powerpc/kernel/dma-iommu.c | 16 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci-common.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/vio.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/beat_iommu.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/iommu.c | 9 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/iommu.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/iommu.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/iommu.c | 8 | ||||
-rw-r--r-- | arch/powerpc/sysdev/dart_iommu.c | 2 |
12 files changed, 49 insertions, 27 deletions
diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index 9dade15d1ab4..6d94d27ed850 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h | |||
@@ -15,7 +15,16 @@ struct dev_archdata { | |||
15 | 15 | ||
16 | /* DMA operations on that device */ | 16 | /* DMA operations on that device */ |
17 | struct dma_map_ops *dma_ops; | 17 | struct dma_map_ops *dma_ops; |
18 | void *dma_data; | 18 | |
19 | /* | ||
20 | * When an iommu is in use, dma_data is used as a ptr to the base of the | ||
21 | * iommu_table. Otherwise, it is a simple numerical offset. | ||
22 | */ | ||
23 | union { | ||
24 | dma_addr_t dma_offset; | ||
25 | void *iommu_table_base; | ||
26 | } dma_data; | ||
27 | |||
19 | #ifdef CONFIG_SWIOTLB | 28 | #ifdef CONFIG_SWIOTLB |
20 | dma_addr_t max_direct_dma_addr; | 29 | dma_addr_t max_direct_dma_addr; |
21 | #endif | 30 | #endif |
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index 34b919fe8cda..e281daebddca 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h | |||
@@ -97,14 +97,20 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops) | |||
97 | * swiotlb use this function, but it is typically not used by implementations | 97 | * swiotlb use this function, but it is typically not used by implementations |
98 | * with an iommu. | 98 | * with an iommu. |
99 | */ | 99 | */ |
100 | static inline unsigned long get_dma_offset(struct device *dev) | 100 | static inline dma_addr_t get_dma_offset(struct device *dev) |
101 | { | 101 | { |
102 | if (dev) | 102 | if (dev) |
103 | return (unsigned long)dev->archdata.dma_data; | 103 | return dev->archdata.dma_data.dma_offset; |
104 | 104 | ||
105 | return PCI_DRAM_OFFSET; | 105 | return PCI_DRAM_OFFSET; |
106 | } | 106 | } |
107 | 107 | ||
108 | static inline void set_dma_offset(struct device *dev, dma_addr_t off) | ||
109 | { | ||
110 | if (dev) | ||
111 | dev->archdata.dma_data.dma_offset = off; | ||
112 | } | ||
113 | |||
108 | /* this will be removed soon */ | 114 | /* this will be removed soon */ |
109 | #define flush_write_buffers() | 115 | #define flush_write_buffers() |
110 | 116 | ||
diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index 7464c0daddd1..edfc9803ec91 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h | |||
@@ -70,6 +70,16 @@ struct iommu_table { | |||
70 | 70 | ||
71 | struct scatterlist; | 71 | struct scatterlist; |
72 | 72 | ||
73 | static inline void set_iommu_table_base(struct device *dev, void *base) | ||
74 | { | ||
75 | dev->archdata.dma_data.iommu_table_base = base; | ||
76 | } | ||
77 | |||
78 | static inline void *get_iommu_table_base(struct device *dev) | ||
79 | { | ||
80 | return dev->archdata.dma_data.iommu_table_base; | ||
81 | } | ||
82 | |||
73 | /* Frees table for an individual device node */ | 83 | /* Frees table for an individual device node */ |
74 | extern void iommu_free_table(struct iommu_table *tbl, const char *node_name); | 84 | extern void iommu_free_table(struct iommu_table *tbl, const char *node_name); |
75 | 85 | ||
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 87ddb3fb948c..37771a518119 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c | |||
@@ -18,7 +18,7 @@ | |||
18 | static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, | 18 | static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, |
19 | dma_addr_t *dma_handle, gfp_t flag) | 19 | dma_addr_t *dma_handle, gfp_t flag) |
20 | { | 20 | { |
21 | return iommu_alloc_coherent(dev, dev->archdata.dma_data, size, | 21 | return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size, |
22 | dma_handle, device_to_mask(dev), flag, | 22 | dma_handle, device_to_mask(dev), flag, |
23 | dev_to_node(dev)); | 23 | dev_to_node(dev)); |
24 | } | 24 | } |
@@ -26,7 +26,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, | |||
26 | static void dma_iommu_free_coherent(struct device *dev, size_t size, | 26 | static void dma_iommu_free_coherent(struct device *dev, size_t size, |
27 | void *vaddr, dma_addr_t dma_handle) | 27 | void *vaddr, dma_addr_t dma_handle) |
28 | { | 28 | { |
29 | iommu_free_coherent(dev->archdata.dma_data, size, vaddr, dma_handle); | 29 | iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle); |
30 | } | 30 | } |
31 | 31 | ||
32 | /* Creates TCEs for a user provided buffer. The user buffer must be | 32 | /* Creates TCEs for a user provided buffer. The user buffer must be |
@@ -39,8 +39,8 @@ static dma_addr_t dma_iommu_map_page(struct device *dev, struct page *page, | |||
39 | enum dma_data_direction direction, | 39 | enum dma_data_direction direction, |
40 | struct dma_attrs *attrs) | 40 | struct dma_attrs *attrs) |
41 | { | 41 | { |
42 | return iommu_map_page(dev, dev->archdata.dma_data, page, offset, size, | 42 | return iommu_map_page(dev, get_iommu_table_base(dev), page, offset, |
43 | device_to_mask(dev), direction, attrs); | 43 | size, device_to_mask(dev), direction, attrs); |
44 | } | 44 | } |
45 | 45 | ||
46 | 46 | ||
@@ -48,7 +48,7 @@ static void dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle, | |||
48 | size_t size, enum dma_data_direction direction, | 48 | size_t size, enum dma_data_direction direction, |
49 | struct dma_attrs *attrs) | 49 | struct dma_attrs *attrs) |
50 | { | 50 | { |
51 | iommu_unmap_page(dev->archdata.dma_data, dma_handle, size, direction, | 51 | iommu_unmap_page(get_iommu_table_base(dev), dma_handle, size, direction, |
52 | attrs); | 52 | attrs); |
53 | } | 53 | } |
54 | 54 | ||
@@ -57,7 +57,7 @@ static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist, | |||
57 | int nelems, enum dma_data_direction direction, | 57 | int nelems, enum dma_data_direction direction, |
58 | struct dma_attrs *attrs) | 58 | struct dma_attrs *attrs) |
59 | { | 59 | { |
60 | return iommu_map_sg(dev, dev->archdata.dma_data, sglist, nelems, | 60 | return iommu_map_sg(dev, get_iommu_table_base(dev), sglist, nelems, |
61 | device_to_mask(dev), direction, attrs); | 61 | device_to_mask(dev), direction, attrs); |
62 | } | 62 | } |
63 | 63 | ||
@@ -65,14 +65,14 @@ static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist, | |||
65 | int nelems, enum dma_data_direction direction, | 65 | int nelems, enum dma_data_direction direction, |
66 | struct dma_attrs *attrs) | 66 | struct dma_attrs *attrs) |
67 | { | 67 | { |
68 | iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction, | 68 | iommu_unmap_sg(get_iommu_table_base(dev), sglist, nelems, direction, |
69 | attrs); | 69 | attrs); |
70 | } | 70 | } |
71 | 71 | ||
72 | /* We support DMA to/from any memory page via the iommu */ | 72 | /* We support DMA to/from any memory page via the iommu */ |
73 | static int dma_iommu_dma_supported(struct device *dev, u64 mask) | 73 | static int dma_iommu_dma_supported(struct device *dev, u64 mask) |
74 | { | 74 | { |
75 | struct iommu_table *tbl = dev->archdata.dma_data; | 75 | struct iommu_table *tbl = get_iommu_table_base(dev); |
76 | 76 | ||
77 | if (!tbl || tbl->it_offset > mask) { | 77 | if (!tbl || tbl->it_offset > mask) { |
78 | printk(KERN_INFO | 78 | printk(KERN_INFO |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index e9f4840096b3..bb8209e34931 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -1117,7 +1117,7 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) | |||
1117 | 1117 | ||
1118 | /* Hook up default DMA ops */ | 1118 | /* Hook up default DMA ops */ |
1119 | sd->dma_ops = pci_dma_ops; | 1119 | sd->dma_ops = pci_dma_ops; |
1120 | sd->dma_data = (void *)PCI_DRAM_OFFSET; | 1120 | set_dma_offset(&dev->dev, PCI_DRAM_OFFSET); |
1121 | 1121 | ||
1122 | /* Additional platform DMA/iommu setup */ | 1122 | /* Additional platform DMA/iommu setup */ |
1123 | if (ppc_md.pci_dma_dev_setup) | 1123 | if (ppc_md.pci_dma_dev_setup) |
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 1b4f674ad7c4..77f64218abf3 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -1235,7 +1235,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) | |||
1235 | vio_cmo_set_dma_ops(viodev); | 1235 | vio_cmo_set_dma_ops(viodev); |
1236 | else | 1236 | else |
1237 | viodev->dev.archdata.dma_ops = &dma_iommu_ops; | 1237 | viodev->dev.archdata.dma_ops = &dma_iommu_ops; |
1238 | viodev->dev.archdata.dma_data = vio_build_iommu_table(viodev); | 1238 | set_iommu_table_base(&viodev->dev, vio_build_iommu_table(viodev)); |
1239 | set_dev_node(&viodev->dev, of_node_to_nid(of_node)); | 1239 | set_dev_node(&viodev->dev, of_node_to_nid(of_node)); |
1240 | 1240 | ||
1241 | /* init generic 'struct device' fields: */ | 1241 | /* init generic 'struct device' fields: */ |
diff --git a/arch/powerpc/platforms/cell/beat_iommu.c b/arch/powerpc/platforms/cell/beat_iommu.c index 93b0efddd658..39d361c5c6d2 100644 --- a/arch/powerpc/platforms/cell/beat_iommu.c +++ b/arch/powerpc/platforms/cell/beat_iommu.c | |||
@@ -77,7 +77,7 @@ static void __init celleb_init_direct_mapping(void) | |||
77 | static void celleb_dma_dev_setup(struct device *dev) | 77 | static void celleb_dma_dev_setup(struct device *dev) |
78 | { | 78 | { |
79 | dev->archdata.dma_ops = get_pci_dma_ops(); | 79 | dev->archdata.dma_ops = get_pci_dma_ops(); |
80 | dev->archdata.dma_data = (void *)celleb_dma_direct_offset; | 80 | set_dma_offset(dev, celleb_dma_direct_offset); |
81 | } | 81 | } |
82 | 82 | ||
83 | static void celleb_pci_dma_dev_setup(struct pci_dev *pdev) | 83 | static void celleb_pci_dma_dev_setup(struct pci_dev *pdev) |
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 416db17eb18f..ca5bfdfe47f2 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
@@ -657,15 +657,13 @@ static void cell_dma_dev_setup_fixed(struct device *dev); | |||
657 | 657 | ||
658 | static void cell_dma_dev_setup(struct device *dev) | 658 | static void cell_dma_dev_setup(struct device *dev) |
659 | { | 659 | { |
660 | struct dev_archdata *archdata = &dev->archdata; | ||
661 | |||
662 | /* Order is important here, these are not mutually exclusive */ | 660 | /* Order is important here, these are not mutually exclusive */ |
663 | if (get_dma_ops(dev) == &dma_iommu_fixed_ops) | 661 | if (get_dma_ops(dev) == &dma_iommu_fixed_ops) |
664 | cell_dma_dev_setup_fixed(dev); | 662 | cell_dma_dev_setup_fixed(dev); |
665 | else if (get_pci_dma_ops() == &dma_iommu_ops) | 663 | else if (get_pci_dma_ops() == &dma_iommu_ops) |
666 | archdata->dma_data = cell_get_iommu_table(dev); | 664 | set_iommu_table_base(dev, cell_get_iommu_table(dev)); |
667 | else if (get_pci_dma_ops() == &dma_direct_ops) | 665 | else if (get_pci_dma_ops() == &dma_direct_ops) |
668 | archdata->dma_data = (void *)cell_dma_direct_offset; | 666 | set_dma_offset(dev, cell_dma_direct_offset); |
669 | else | 667 | else |
670 | BUG(); | 668 | BUG(); |
671 | } | 669 | } |
@@ -973,11 +971,10 @@ static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask) | |||
973 | 971 | ||
974 | static void cell_dma_dev_setup_fixed(struct device *dev) | 972 | static void cell_dma_dev_setup_fixed(struct device *dev) |
975 | { | 973 | { |
976 | struct dev_archdata *archdata = &dev->archdata; | ||
977 | u64 addr; | 974 | u64 addr; |
978 | 975 | ||
979 | addr = cell_iommu_get_fixed_address(dev) + dma_iommu_fixed_base; | 976 | addr = cell_iommu_get_fixed_address(dev) + dma_iommu_fixed_base; |
980 | archdata->dma_data = (void *)addr; | 977 | set_dma_offset(dev, addr); |
981 | 978 | ||
982 | dev_dbg(dev, "iommu: fixed addr = %llx\n", addr); | 979 | dev_dbg(dev, "iommu: fixed addr = %llx\n", addr); |
983 | } | 980 | } |
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index 6c1e1011959e..9d53cb481a7c 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c | |||
@@ -193,7 +193,7 @@ static void pci_dma_dev_setup_iseries(struct pci_dev *pdev) | |||
193 | pdn->iommu_table = iommu_init_table(tbl, -1); | 193 | pdn->iommu_table = iommu_init_table(tbl, -1); |
194 | else | 194 | else |
195 | kfree(tbl); | 195 | kfree(tbl); |
196 | pdev->dev.archdata.dma_data = pdn->iommu_table; | 196 | set_iommu_table_base(&pdev->dev, pdn->iommu_table); |
197 | } | 197 | } |
198 | #else | 198 | #else |
199 | #define pci_dma_dev_setup_iseries NULL | 199 | #define pci_dma_dev_setup_iseries NULL |
diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c index a0ff03a3d8da..7b1d608ea3c8 100644 --- a/arch/powerpc/platforms/pasemi/iommu.c +++ b/arch/powerpc/platforms/pasemi/iommu.c | |||
@@ -189,7 +189,7 @@ static void pci_dma_dev_setup_pasemi(struct pci_dev *dev) | |||
189 | } | 189 | } |
190 | #endif | 190 | #endif |
191 | 191 | ||
192 | dev->dev.archdata.dma_data = &iommu_table_iobmap; | 192 | set_iommu_table_base(&dev->dev, &iommu_table_iobmap); |
193 | } | 193 | } |
194 | 194 | ||
195 | static void pci_dma_bus_setup_null(struct pci_bus *b) { } | 195 | static void pci_dma_bus_setup_null(struct pci_bus *b) { } |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 661c8e02bcba..1a0000a4b6d6 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -482,7 +482,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev) | |||
482 | phb->node); | 482 | phb->node); |
483 | iommu_table_setparms(phb, dn, tbl); | 483 | iommu_table_setparms(phb, dn, tbl); |
484 | PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node); | 484 | PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node); |
485 | dev->dev.archdata.dma_data = PCI_DN(dn)->iommu_table; | 485 | set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table); |
486 | return; | 486 | return; |
487 | } | 487 | } |
488 | 488 | ||
@@ -494,7 +494,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev) | |||
494 | dn = dn->parent; | 494 | dn = dn->parent; |
495 | 495 | ||
496 | if (dn && PCI_DN(dn)) | 496 | if (dn && PCI_DN(dn)) |
497 | dev->dev.archdata.dma_data = PCI_DN(dn)->iommu_table; | 497 | set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table); |
498 | else | 498 | else |
499 | printk(KERN_WARNING "iommu: Device %s has no iommu table\n", | 499 | printk(KERN_WARNING "iommu: Device %s has no iommu table\n", |
500 | pci_name(dev)); | 500 | pci_name(dev)); |
@@ -538,7 +538,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) | |||
538 | */ | 538 | */ |
539 | if (dma_window == NULL || pdn->parent == NULL) { | 539 | if (dma_window == NULL || pdn->parent == NULL) { |
540 | pr_debug(" no dma window for device, linking to parent\n"); | 540 | pr_debug(" no dma window for device, linking to parent\n"); |
541 | dev->dev.archdata.dma_data = PCI_DN(pdn)->iommu_table; | 541 | set_iommu_table_base(&dev->dev, PCI_DN(pdn)->iommu_table); |
542 | return; | 542 | return; |
543 | } | 543 | } |
544 | 544 | ||
@@ -554,7 +554,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) | |||
554 | pr_debug(" found DMA window, table: %p\n", pci->iommu_table); | 554 | pr_debug(" found DMA window, table: %p\n", pci->iommu_table); |
555 | } | 555 | } |
556 | 556 | ||
557 | dev->dev.archdata.dma_data = pci->iommu_table; | 557 | set_iommu_table_base(&dev->dev, pci->iommu_table); |
558 | } | 558 | } |
559 | #else /* CONFIG_PCI */ | 559 | #else /* CONFIG_PCI */ |
560 | #define pci_dma_bus_setup_pSeries NULL | 560 | #define pci_dma_bus_setup_pSeries NULL |
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 89639ecbf381..ae3c4db86fe8 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c | |||
@@ -297,7 +297,7 @@ static void pci_dma_dev_setup_dart(struct pci_dev *dev) | |||
297 | /* We only have one iommu table on the mac for now, which makes | 297 | /* We only have one iommu table on the mac for now, which makes |
298 | * things simple. Setup all PCI devices to point to this table | 298 | * things simple. Setup all PCI devices to point to this table |
299 | */ | 299 | */ |
300 | dev->dev.archdata.dma_data = &iommu_table_dart; | 300 | set_iommu_table_base(&dev->dev, &iommu_table_dart); |
301 | } | 301 | } |
302 | 302 | ||
303 | static void pci_dma_bus_setup_dart(struct pci_bus *bus) | 303 | static void pci_dma_bus_setup_dart(struct pci_bus *bus) |