diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-powerpc/device.h | 19 | ||||
-rw-r--r-- | include/asm-powerpc/dma-mapping.h | 180 | ||||
-rw-r--r-- | include/asm-powerpc/ibmebus.h | 1 | ||||
-rw-r--r-- | include/asm-powerpc/iommu.h | 20 | ||||
-rw-r--r-- | include/asm-powerpc/iseries/iommu.h | 4 | ||||
-rw-r--r-- | include/asm-powerpc/machdep.h | 4 | ||||
-rw-r--r-- | include/asm-powerpc/of_device.h | 2 | ||||
-rw-r--r-- | include/asm-powerpc/pci.h | 8 | ||||
-rw-r--r-- | include/asm-powerpc/vio.h | 1 |
9 files changed, 180 insertions, 59 deletions
diff --git a/include/asm-powerpc/device.h b/include/asm-powerpc/device.h index d8f9872b0e2d..228ab2a315b9 100644 --- a/include/asm-powerpc/device.h +++ b/include/asm-powerpc/device.h | |||
@@ -3,5 +3,22 @@ | |||
3 | * | 3 | * |
4 | * This file is released under the GPLv2 | 4 | * This file is released under the GPLv2 |
5 | */ | 5 | */ |
6 | #include <asm-generic/device.h> | 6 | #ifndef _ASM_POWERPC_DEVICE_H |
7 | #define _ASM_POWERPC_DEVICE_H | ||
7 | 8 | ||
9 | struct dma_mapping_ops; | ||
10 | struct device_node; | ||
11 | |||
12 | struct dev_archdata { | ||
13 | /* Optional pointer to an OF device node */ | ||
14 | struct device_node *of_node; | ||
15 | |||
16 | /* DMA operations on that device */ | ||
17 | struct dma_mapping_ops *dma_ops; | ||
18 | void *dma_data; | ||
19 | |||
20 | /* NUMA node if applicable */ | ||
21 | int numa_node; | ||
22 | }; | ||
23 | |||
24 | #endif /* _ASM_POWERPC_DEVICE_H */ | ||
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h index 2ab9baf78bb4..8367810c994c 100644 --- a/include/asm-powerpc/dma-mapping.h +++ b/include/asm-powerpc/dma-mapping.h | |||
@@ -44,26 +44,148 @@ extern void __dma_sync_page(struct page *page, unsigned long offset, | |||
44 | #endif /* ! CONFIG_NOT_COHERENT_CACHE */ | 44 | #endif /* ! CONFIG_NOT_COHERENT_CACHE */ |
45 | 45 | ||
46 | #ifdef CONFIG_PPC64 | 46 | #ifdef CONFIG_PPC64 |
47 | /* | ||
48 | * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO | ||
49 | */ | ||
50 | struct dma_mapping_ops { | ||
51 | void * (*alloc_coherent)(struct device *dev, size_t size, | ||
52 | dma_addr_t *dma_handle, gfp_t flag); | ||
53 | void (*free_coherent)(struct device *dev, size_t size, | ||
54 | void *vaddr, dma_addr_t dma_handle); | ||
55 | dma_addr_t (*map_single)(struct device *dev, void *ptr, | ||
56 | size_t size, enum dma_data_direction direction); | ||
57 | void (*unmap_single)(struct device *dev, dma_addr_t dma_addr, | ||
58 | size_t size, enum dma_data_direction direction); | ||
59 | int (*map_sg)(struct device *dev, struct scatterlist *sg, | ||
60 | int nents, enum dma_data_direction direction); | ||
61 | void (*unmap_sg)(struct device *dev, struct scatterlist *sg, | ||
62 | int nents, enum dma_data_direction direction); | ||
63 | int (*dma_supported)(struct device *dev, u64 mask); | ||
64 | int (*dac_dma_supported)(struct device *dev, u64 mask); | ||
65 | int (*set_dma_mask)(struct device *dev, u64 dma_mask); | ||
66 | }; | ||
67 | |||
68 | static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) | ||
69 | { | ||
70 | /* We don't handle the NULL dev case for ISA for now. We could | ||
71 | * do it via an out of line call but it is not needed for now. The | ||
72 | * only ISA DMA device we support is the floppy and we have a hack | ||
73 | * in the floppy driver directly to get a device for us. | ||
74 | */ | ||
75 | if (unlikely(dev == NULL || dev->archdata.dma_ops == NULL)) | ||
76 | return NULL; | ||
77 | return dev->archdata.dma_ops; | ||
78 | } | ||
79 | |||
80 | static inline int dma_supported(struct device *dev, u64 mask) | ||
81 | { | ||
82 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
83 | |||
84 | if (unlikely(dma_ops == NULL)) | ||
85 | return 0; | ||
86 | if (dma_ops->dma_supported == NULL) | ||
87 | return 1; | ||
88 | return dma_ops->dma_supported(dev, mask); | ||
89 | } | ||
90 | |||
91 | static inline int dma_set_mask(struct device *dev, u64 dma_mask) | ||
92 | { | ||
93 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
94 | |||
95 | if (unlikely(dma_ops == NULL)) | ||
96 | return -EIO; | ||
97 | if (dma_ops->set_dma_mask != NULL) | ||
98 | return dma_ops->set_dma_mask(dev, dma_mask); | ||
99 | if (!dev->dma_mask || !dma_supported(dev, *dev->dma_mask)) | ||
100 | return -EIO; | ||
101 | *dev->dma_mask = dma_mask; | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, | ||
106 | dma_addr_t *dma_handle, gfp_t flag) | ||
107 | { | ||
108 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
109 | |||
110 | BUG_ON(!dma_ops); | ||
111 | return dma_ops->alloc_coherent(dev, size, dma_handle, flag); | ||
112 | } | ||
113 | |||
114 | static inline void dma_free_coherent(struct device *dev, size_t size, | ||
115 | void *cpu_addr, dma_addr_t dma_handle) | ||
116 | { | ||
117 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
118 | |||
119 | BUG_ON(!dma_ops); | ||
120 | dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); | ||
121 | } | ||
122 | |||
123 | static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, | ||
124 | size_t size, | ||
125 | enum dma_data_direction direction) | ||
126 | { | ||
127 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
128 | |||
129 | BUG_ON(!dma_ops); | ||
130 | return dma_ops->map_single(dev, cpu_addr, size, direction); | ||
131 | } | ||
132 | |||
133 | static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, | ||
134 | size_t size, | ||
135 | enum dma_data_direction direction) | ||
136 | { | ||
137 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
138 | |||
139 | BUG_ON(!dma_ops); | ||
140 | dma_ops->unmap_single(dev, dma_addr, size, direction); | ||
141 | } | ||
142 | |||
143 | static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, | ||
144 | unsigned long offset, size_t size, | ||
145 | enum dma_data_direction direction) | ||
146 | { | ||
147 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
148 | |||
149 | BUG_ON(!dma_ops); | ||
150 | return dma_ops->map_single(dev, page_address(page) + offset, size, | ||
151 | direction); | ||
152 | } | ||
153 | |||
154 | static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address, | ||
155 | size_t size, | ||
156 | enum dma_data_direction direction) | ||
157 | { | ||
158 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
159 | |||
160 | BUG_ON(!dma_ops); | ||
161 | dma_ops->unmap_single(dev, dma_address, size, direction); | ||
162 | } | ||
163 | |||
164 | static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, | ||
165 | int nents, enum dma_data_direction direction) | ||
166 | { | ||
167 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
168 | |||
169 | BUG_ON(!dma_ops); | ||
170 | return dma_ops->map_sg(dev, sg, nents, direction); | ||
171 | } | ||
172 | |||
173 | static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, | ||
174 | int nhwentries, | ||
175 | enum dma_data_direction direction) | ||
176 | { | ||
177 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | ||
178 | |||
179 | BUG_ON(!dma_ops); | ||
180 | dma_ops->unmap_sg(dev, sg, nhwentries, direction); | ||
181 | } | ||
47 | 182 | ||
48 | extern int dma_supported(struct device *dev, u64 mask); | 183 | |
49 | extern int dma_set_mask(struct device *dev, u64 dma_mask); | 184 | /* |
50 | extern void *dma_alloc_coherent(struct device *dev, size_t size, | 185 | * Available generic sets of operations |
51 | dma_addr_t *dma_handle, gfp_t flag); | 186 | */ |
52 | extern void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, | 187 | extern struct dma_mapping_ops dma_iommu_ops; |
53 | dma_addr_t dma_handle); | 188 | extern struct dma_mapping_ops dma_direct_ops; |
54 | extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, | ||
55 | size_t size, enum dma_data_direction direction); | ||
56 | extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, | ||
57 | size_t size, enum dma_data_direction direction); | ||
58 | extern dma_addr_t dma_map_page(struct device *dev, struct page *page, | ||
59 | unsigned long offset, size_t size, | ||
60 | enum dma_data_direction direction); | ||
61 | extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address, | ||
62 | size_t size, enum dma_data_direction direction); | ||
63 | extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | ||
64 | enum dma_data_direction direction); | ||
65 | extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg, | ||
66 | int nhwentries, enum dma_data_direction direction); | ||
67 | 189 | ||
68 | #else /* CONFIG_PPC64 */ | 190 | #else /* CONFIG_PPC64 */ |
69 | 191 | ||
@@ -261,25 +383,5 @@ static inline void dma_cache_sync(void *vaddr, size_t size, | |||
261 | __dma_sync(vaddr, size, (int)direction); | 383 | __dma_sync(vaddr, size, (int)direction); |
262 | } | 384 | } |
263 | 385 | ||
264 | /* | ||
265 | * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO | ||
266 | */ | ||
267 | struct dma_mapping_ops { | ||
268 | void * (*alloc_coherent)(struct device *dev, size_t size, | ||
269 | dma_addr_t *dma_handle, gfp_t flag); | ||
270 | void (*free_coherent)(struct device *dev, size_t size, | ||
271 | void *vaddr, dma_addr_t dma_handle); | ||
272 | dma_addr_t (*map_single)(struct device *dev, void *ptr, | ||
273 | size_t size, enum dma_data_direction direction); | ||
274 | void (*unmap_single)(struct device *dev, dma_addr_t dma_addr, | ||
275 | size_t size, enum dma_data_direction direction); | ||
276 | int (*map_sg)(struct device *dev, struct scatterlist *sg, | ||
277 | int nents, enum dma_data_direction direction); | ||
278 | void (*unmap_sg)(struct device *dev, struct scatterlist *sg, | ||
279 | int nents, enum dma_data_direction direction); | ||
280 | int (*dma_supported)(struct device *dev, u64 mask); | ||
281 | int (*dac_dma_supported)(struct device *dev, u64 mask); | ||
282 | }; | ||
283 | |||
284 | #endif /* __KERNEL__ */ | 386 | #endif /* __KERNEL__ */ |
285 | #endif /* _ASM_DMA_MAPPING_H */ | 387 | #endif /* _ASM_DMA_MAPPING_H */ |
diff --git a/include/asm-powerpc/ibmebus.h b/include/asm-powerpc/ibmebus.h index 3493429b70f5..66112114b8c5 100644 --- a/include/asm-powerpc/ibmebus.h +++ b/include/asm-powerpc/ibmebus.h | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <linux/mod_devicetable.h> | 44 | #include <linux/mod_devicetable.h> |
45 | #include <asm/of_device.h> | 45 | #include <asm/of_device.h> |
46 | 46 | ||
47 | extern struct dma_mapping_ops ibmebus_dma_ops; | ||
48 | extern struct bus_type ibmebus_bus_type; | 47 | extern struct bus_type ibmebus_bus_type; |
49 | 48 | ||
50 | struct ibmebus_dev { | 49 | struct ibmebus_dev { |
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h index 19e6f7e0a607..19403183dbbc 100644 --- a/include/asm-powerpc/iommu.h +++ b/include/asm-powerpc/iommu.h | |||
@@ -79,22 +79,22 @@ extern void iommu_free_table(struct device_node *dn); | |||
79 | extern struct iommu_table *iommu_init_table(struct iommu_table * tbl, | 79 | extern struct iommu_table *iommu_init_table(struct iommu_table * tbl, |
80 | int nid); | 80 | int nid); |
81 | 81 | ||
82 | extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | 82 | extern int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, |
83 | struct scatterlist *sglist, int nelems, unsigned long mask, | 83 | int nelems, unsigned long mask, |
84 | enum dma_data_direction direction); | 84 | enum dma_data_direction direction); |
85 | extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, | 85 | extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, |
86 | int nelems, enum dma_data_direction direction); | 86 | int nelems, enum dma_data_direction direction); |
87 | 87 | ||
88 | extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, | 88 | extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, |
89 | dma_addr_t *dma_handle, unsigned long mask, | 89 | dma_addr_t *dma_handle, unsigned long mask, |
90 | gfp_t flag, int node); | 90 | gfp_t flag, int node); |
91 | extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, | 91 | extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, |
92 | void *vaddr, dma_addr_t dma_handle); | 92 | void *vaddr, dma_addr_t dma_handle); |
93 | extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, | 93 | extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, |
94 | size_t size, unsigned long mask, | 94 | size_t size, unsigned long mask, |
95 | enum dma_data_direction direction); | 95 | enum dma_data_direction direction); |
96 | extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, | 96 | extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, |
97 | size_t size, enum dma_data_direction direction); | 97 | size_t size, enum dma_data_direction direction); |
98 | 98 | ||
99 | extern void iommu_init_early_pSeries(void); | 99 | extern void iommu_init_early_pSeries(void); |
100 | extern void iommu_init_early_iSeries(void); | 100 | extern void iommu_init_early_iSeries(void); |
diff --git a/include/asm-powerpc/iseries/iommu.h b/include/asm-powerpc/iseries/iommu.h index 0edbfe10cb37..6e323a13ac30 100644 --- a/include/asm-powerpc/iseries/iommu.h +++ b/include/asm-powerpc/iseries/iommu.h | |||
@@ -21,11 +21,13 @@ | |||
21 | * Boston, MA 02111-1307 USA | 21 | * Boston, MA 02111-1307 USA |
22 | */ | 22 | */ |
23 | 23 | ||
24 | struct pci_dev; | ||
24 | struct device_node; | 25 | struct device_node; |
25 | struct iommu_table; | 26 | struct iommu_table; |
26 | 27 | ||
27 | /* Creates table for an individual device node */ | 28 | /* Creates table for an individual device node */ |
28 | extern void iommu_devnode_init_iSeries(struct device_node *dn); | 29 | extern void iommu_devnode_init_iSeries(struct pci_dev *pdev, |
30 | struct device_node *dn); | ||
29 | 31 | ||
30 | /* Get table parameters from HV */ | 32 | /* Get table parameters from HV */ |
31 | extern void iommu_table_getparms_iSeries(unsigned long busno, | 33 | extern void iommu_table_getparms_iSeries(unsigned long busno, |
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h index 162205f62641..ccc29744656e 100644 --- a/include/asm-powerpc/machdep.h +++ b/include/asm-powerpc/machdep.h | |||
@@ -84,8 +84,8 @@ struct machdep_calls { | |||
84 | unsigned long (*tce_get)(struct iommu_table *tbl, | 84 | unsigned long (*tce_get)(struct iommu_table *tbl, |
85 | long index); | 85 | long index); |
86 | void (*tce_flush)(struct iommu_table *tbl); | 86 | void (*tce_flush)(struct iommu_table *tbl); |
87 | void (*iommu_dev_setup)(struct pci_dev *dev); | 87 | void (*pci_dma_dev_setup)(struct pci_dev *dev); |
88 | void (*iommu_bus_setup)(struct pci_bus *bus); | 88 | void (*pci_dma_bus_setup)(struct pci_bus *bus); |
89 | #endif /* CONFIG_PPC64 */ | 89 | #endif /* CONFIG_PPC64 */ |
90 | 90 | ||
91 | int (*probe)(void); | 91 | int (*probe)(void); |
diff --git a/include/asm-powerpc/of_device.h b/include/asm-powerpc/of_device.h index 1ef7e9edd1a7..a889b2005bf5 100644 --- a/include/asm-powerpc/of_device.h +++ b/include/asm-powerpc/of_device.h | |||
@@ -14,7 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | struct of_device | 15 | struct of_device |
16 | { | 16 | { |
17 | struct device_node *node; /* OF device node */ | 17 | struct device_node *node; /* to be obsoleted */ |
18 | u64 dma_mask; /* DMA mask */ | 18 | u64 dma_mask; /* DMA mask */ |
19 | struct device dev; /* Generic device interface */ | 19 | struct device dev; /* Generic device interface */ |
20 | }; | 20 | }; |
diff --git a/include/asm-powerpc/pci.h b/include/asm-powerpc/pci.h index c77286051496..16f13319c769 100644 --- a/include/asm-powerpc/pci.h +++ b/include/asm-powerpc/pci.h | |||
@@ -70,15 +70,15 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) | |||
70 | */ | 70 | */ |
71 | #define PCI_DISABLE_MWI | 71 | #define PCI_DISABLE_MWI |
72 | 72 | ||
73 | extern struct dma_mapping_ops pci_dma_ops; | 73 | extern struct dma_mapping_ops *pci_dma_ops; |
74 | 74 | ||
75 | /* For DAC DMA, we currently don't support it by default, but | 75 | /* For DAC DMA, we currently don't support it by default, but |
76 | * we let 64-bit platforms override this. | 76 | * we let 64-bit platforms override this. |
77 | */ | 77 | */ |
78 | static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask) | 78 | static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask) |
79 | { | 79 | { |
80 | if (pci_dma_ops.dac_dma_supported) | 80 | if (pci_dma_ops && pci_dma_ops->dac_dma_supported) |
81 | return pci_dma_ops.dac_dma_supported(&hwdev->dev, mask); | 81 | return pci_dma_ops->dac_dma_supported(&hwdev->dev, mask); |
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
84 | 84 | ||
@@ -210,6 +210,8 @@ extern int remap_bus_range(struct pci_bus *bus); | |||
210 | extern void pcibios_fixup_device_resources(struct pci_dev *dev, | 210 | extern void pcibios_fixup_device_resources(struct pci_dev *dev, |
211 | struct pci_bus *bus); | 211 | struct pci_bus *bus); |
212 | 212 | ||
213 | extern void pcibios_setup_new_device(struct pci_dev *dev); | ||
214 | |||
213 | extern void pcibios_claim_one_bus(struct pci_bus *b); | 215 | extern void pcibios_claim_one_bus(struct pci_bus *b); |
214 | 216 | ||
215 | extern struct pci_controller *init_phb_dynamic(struct device_node *dn); | 217 | extern struct pci_controller *init_phb_dynamic(struct device_node *dn); |
diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h index 4b51d42e1419..0117b544ecbc 100644 --- a/include/asm-powerpc/vio.h +++ b/include/asm-powerpc/vio.h | |||
@@ -45,7 +45,6 @@ struct iommu_table; | |||
45 | * The vio_dev structure is used to describe virtual I/O devices. | 45 | * The vio_dev structure is used to describe virtual I/O devices. |
46 | */ | 46 | */ |
47 | struct vio_dev { | 47 | struct vio_dev { |
48 | struct iommu_table *iommu_table; /* vio_map_* uses this */ | ||
49 | const char *name; | 48 | const char *name; |
50 | const char *type; | 49 | const char *type; |
51 | uint32_t unit_address; | 50 | uint32_t unit_address; |