diff options
-rw-r--r-- | arch/powerpc/kernel/vio.c | 7 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/iommu.c | 30 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/mf.c | 23 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/viopath.c | 6 | ||||
-rw-r--r-- | drivers/cdrom/viocd.c | 5 | ||||
-rw-r--r-- | drivers/char/viotape.c | 7 | ||||
-rw-r--r-- | include/asm-powerpc/iseries/hv_call_event.h | 10 | ||||
-rw-r--r-- | include/asm-powerpc/iseries/vio.h | 4 |
8 files changed, 57 insertions, 35 deletions
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index fd631d4d1602..eaf7f6992a2f 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -49,11 +49,8 @@ static struct vio_dev vio_bus_device = { /* fake "parent" device */ | |||
49 | }; | 49 | }; |
50 | 50 | ||
51 | #ifdef CONFIG_PPC_ISERIES | 51 | #ifdef CONFIG_PPC_ISERIES |
52 | struct device *iSeries_vio_dev = &vio_bus_device.dev; | ||
53 | EXPORT_SYMBOL(iSeries_vio_dev); | ||
54 | |||
55 | static struct iommu_table veth_iommu_table; | 52 | static struct iommu_table veth_iommu_table; |
56 | static struct iommu_table vio_iommu_table; | 53 | struct iommu_table vio_iommu_table; |
57 | 54 | ||
58 | static void __init iommu_vio_init(void) | 55 | static void __init iommu_vio_init(void) |
59 | { | 56 | { |
@@ -66,8 +63,6 @@ static void __init iommu_vio_init(void) | |||
66 | printk("Virtual Bus VETH TCE table failed.\n"); | 63 | printk("Virtual Bus VETH TCE table failed.\n"); |
67 | if (!iommu_init_table(&vio_iommu_table, -1)) | 64 | if (!iommu_init_table(&vio_iommu_table, -1)) |
68 | printk("Virtual Bus VIO TCE table failed.\n"); | 65 | printk("Virtual Bus VIO TCE table failed.\n"); |
69 | vio_bus_device.dev.archdata.dma_ops = &dma_iommu_ops; | ||
70 | vio_bus_device.dev.archdata.dma_data = &vio_iommu_table; | ||
71 | } | 66 | } |
72 | #else | 67 | #else |
73 | static void __init iommu_vio_init(void) | 68 | static void __init iommu_vio_init(void) |
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index 3b6a9666c2c0..3281f10bbd16 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/dma-mapping.h> | 28 | #include <linux/dma-mapping.h> |
29 | #include <linux/list.h> | 29 | #include <linux/list.h> |
30 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
31 | #include <linux/module.h> | ||
31 | 32 | ||
32 | #include <asm/iommu.h> | 33 | #include <asm/iommu.h> |
33 | #include <asm/tce.h> | 34 | #include <asm/tce.h> |
@@ -36,6 +37,7 @@ | |||
36 | #include <asm/prom.h> | 37 | #include <asm/prom.h> |
37 | #include <asm/pci-bridge.h> | 38 | #include <asm/pci-bridge.h> |
38 | #include <asm/iseries/hv_call_xm.h> | 39 | #include <asm/iseries/hv_call_xm.h> |
40 | #include <asm/iseries/hv_call_event.h> | ||
39 | #include <asm/iseries/iommu.h> | 41 | #include <asm/iseries/iommu.h> |
40 | 42 | ||
41 | static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, | 43 | static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, |
@@ -189,6 +191,34 @@ void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn) | |||
189 | } | 191 | } |
190 | #endif | 192 | #endif |
191 | 193 | ||
194 | extern struct iommu_table vio_iommu_table; | ||
195 | |||
196 | void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag) | ||
197 | { | ||
198 | return iommu_alloc_coherent(&vio_iommu_table, size, dma_handle, | ||
199 | DMA_32BIT_MASK, flag, -1); | ||
200 | } | ||
201 | EXPORT_SYMBOL_GPL(iseries_hv_alloc); | ||
202 | |||
203 | void iseries_hv_free(size_t size, void *vaddr, dma_addr_t dma_handle) | ||
204 | { | ||
205 | iommu_free_coherent(&vio_iommu_table, size, vaddr, dma_handle); | ||
206 | } | ||
207 | EXPORT_SYMBOL_GPL(iseries_hv_free); | ||
208 | |||
209 | dma_addr_t iseries_hv_map(void *vaddr, size_t size, | ||
210 | enum dma_data_direction direction) | ||
211 | { | ||
212 | return iommu_map_single(&vio_iommu_table, vaddr, size, | ||
213 | DMA_32BIT_MASK, direction); | ||
214 | } | ||
215 | |||
216 | void iseries_hv_unmap(dma_addr_t dma_handle, size_t size, | ||
217 | enum dma_data_direction direction) | ||
218 | { | ||
219 | iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction); | ||
220 | } | ||
221 | |||
192 | void iommu_init_early_iSeries(void) | 222 | void iommu_init_early_iSeries(void) |
193 | { | 223 | { |
194 | ppc_md.tce_build = tce_build_iSeries; | 224 | ppc_md.tce_build = tce_build_iSeries; |
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index b1187d95e3b2..c0f2433bc16e 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c | |||
@@ -39,9 +39,9 @@ | |||
39 | #include <asm/paca.h> | 39 | #include <asm/paca.h> |
40 | #include <asm/abs_addr.h> | 40 | #include <asm/abs_addr.h> |
41 | #include <asm/firmware.h> | 41 | #include <asm/firmware.h> |
42 | #include <asm/iseries/vio.h> | ||
43 | #include <asm/iseries/mf.h> | 42 | #include <asm/iseries/mf.h> |
44 | #include <asm/iseries/hv_lp_config.h> | 43 | #include <asm/iseries/hv_lp_config.h> |
44 | #include <asm/iseries/hv_lp_event.h> | ||
45 | #include <asm/iseries/it_lp_queue.h> | 45 | #include <asm/iseries/it_lp_queue.h> |
46 | 46 | ||
47 | #include "setup.h" | 47 | #include "setup.h" |
@@ -870,8 +870,7 @@ static int proc_mf_dump_cmdline(char *page, char **start, off_t off, | |||
870 | if ((off + count) > 256) | 870 | if ((off + count) > 256) |
871 | count = 256 - off; | 871 | count = 256 - off; |
872 | 872 | ||
873 | dma_addr = dma_map_single(iSeries_vio_dev, page, off + count, | 873 | dma_addr = iseries_hv_map(page, off + count, DMA_FROM_DEVICE); |
874 | DMA_FROM_DEVICE); | ||
875 | if (dma_mapping_error(dma_addr)) | 874 | if (dma_mapping_error(dma_addr)) |
876 | return -ENOMEM; | 875 | return -ENOMEM; |
877 | memset(page, 0, off + count); | 876 | memset(page, 0, off + count); |
@@ -883,8 +882,7 @@ static int proc_mf_dump_cmdline(char *page, char **start, off_t off, | |||
883 | vsp_cmd.sub_data.kern.length = off + count; | 882 | vsp_cmd.sub_data.kern.length = off + count; |
884 | mb(); | 883 | mb(); |
885 | rc = signal_vsp_instruction(&vsp_cmd); | 884 | rc = signal_vsp_instruction(&vsp_cmd); |
886 | dma_unmap_single(iSeries_vio_dev, dma_addr, off + count, | 885 | iseries_hv_unmap(dma_addr, off + count, DMA_FROM_DEVICE); |
887 | DMA_FROM_DEVICE); | ||
888 | if (rc) | 886 | if (rc) |
889 | return rc; | 887 | return rc; |
890 | if (vsp_cmd.result_code != 0) | 888 | if (vsp_cmd.result_code != 0) |
@@ -919,8 +917,7 @@ static int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side) | |||
919 | int len = *size; | 917 | int len = *size; |
920 | dma_addr_t dma_addr; | 918 | dma_addr_t dma_addr; |
921 | 919 | ||
922 | dma_addr = dma_map_single(iSeries_vio_dev, buffer, len, | 920 | dma_addr = iseries_hv_map(buffer, len, DMA_FROM_DEVICE); |
923 | DMA_FROM_DEVICE); | ||
924 | memset(buffer, 0, len); | 921 | memset(buffer, 0, len); |
925 | memset(&vsp_cmd, 0, sizeof(vsp_cmd)); | 922 | memset(&vsp_cmd, 0, sizeof(vsp_cmd)); |
926 | vsp_cmd.cmd = 32; | 923 | vsp_cmd.cmd = 32; |
@@ -938,7 +935,7 @@ static int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side) | |||
938 | rc = -ENOMEM; | 935 | rc = -ENOMEM; |
939 | } | 936 | } |
940 | 937 | ||
941 | dma_unmap_single(iSeries_vio_dev, dma_addr, len, DMA_FROM_DEVICE); | 938 | iseries_hv_unmap(dma_addr, len, DMA_FROM_DEVICE); |
942 | 939 | ||
943 | return rc; | 940 | return rc; |
944 | } | 941 | } |
@@ -1149,8 +1146,7 @@ static int proc_mf_change_cmdline(struct file *file, const char __user *buffer, | |||
1149 | goto out; | 1146 | goto out; |
1150 | 1147 | ||
1151 | dma_addr = 0; | 1148 | dma_addr = 0; |
1152 | page = dma_alloc_coherent(iSeries_vio_dev, count, &dma_addr, | 1149 | page = iseries_hv_alloc(count, &dma_addr, GFP_ATOMIC); |
1153 | GFP_ATOMIC); | ||
1154 | ret = -ENOMEM; | 1150 | ret = -ENOMEM; |
1155 | if (page == NULL) | 1151 | if (page == NULL) |
1156 | goto out; | 1152 | goto out; |
@@ -1170,7 +1166,7 @@ static int proc_mf_change_cmdline(struct file *file, const char __user *buffer, | |||
1170 | ret = count; | 1166 | ret = count; |
1171 | 1167 | ||
1172 | out_free: | 1168 | out_free: |
1173 | dma_free_coherent(iSeries_vio_dev, count, page, dma_addr); | 1169 | iseries_hv_free(count, page, dma_addr); |
1174 | out: | 1170 | out: |
1175 | return ret; | 1171 | return ret; |
1176 | } | 1172 | } |
@@ -1190,8 +1186,7 @@ static ssize_t proc_mf_change_vmlinux(struct file *file, | |||
1190 | goto out; | 1186 | goto out; |
1191 | 1187 | ||
1192 | dma_addr = 0; | 1188 | dma_addr = 0; |
1193 | page = dma_alloc_coherent(iSeries_vio_dev, count, &dma_addr, | 1189 | page = iseries_hv_alloc(count, &dma_addr, GFP_ATOMIC); |
1194 | GFP_ATOMIC); | ||
1195 | rc = -ENOMEM; | 1190 | rc = -ENOMEM; |
1196 | if (page == NULL) { | 1191 | if (page == NULL) { |
1197 | printk(KERN_ERR "mf.c: couldn't allocate memory to set vmlinux chunk\n"); | 1192 | printk(KERN_ERR "mf.c: couldn't allocate memory to set vmlinux chunk\n"); |
@@ -1219,7 +1214,7 @@ static ssize_t proc_mf_change_vmlinux(struct file *file, | |||
1219 | *ppos += count; | 1214 | *ppos += count; |
1220 | rc = count; | 1215 | rc = count; |
1221 | out_free: | 1216 | out_free: |
1222 | dma_free_coherent(iSeries_vio_dev, count, page, dma_addr); | 1217 | iseries_hv_free(count, page, dma_addr); |
1223 | out: | 1218 | out: |
1224 | return rc; | 1219 | return rc; |
1225 | } | 1220 | } |
diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c index 45f2fe39c87e..df23331eb25c 100644 --- a/arch/powerpc/platforms/iseries/viopath.c +++ b/arch/powerpc/platforms/iseries/viopath.c | |||
@@ -124,8 +124,7 @@ static int proc_viopath_show(struct seq_file *m, void *v) | |||
124 | if (!buf) | 124 | if (!buf) |
125 | return 0; | 125 | return 0; |
126 | 126 | ||
127 | handle = dma_map_single(iSeries_vio_dev, buf, HW_PAGE_SIZE, | 127 | handle = iseries_hv_map(buf, HW_PAGE_SIZE, DMA_FROM_DEVICE); |
128 | DMA_FROM_DEVICE); | ||
129 | 128 | ||
130 | hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, | 129 | hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, |
131 | HvLpEvent_Type_VirtualIo, | 130 | HvLpEvent_Type_VirtualIo, |
@@ -146,8 +145,7 @@ static int proc_viopath_show(struct seq_file *m, void *v) | |||
146 | buf[HW_PAGE_SIZE-1] = '\0'; | 145 | buf[HW_PAGE_SIZE-1] = '\0'; |
147 | seq_printf(m, "%s", buf); | 146 | seq_printf(m, "%s", buf); |
148 | 147 | ||
149 | dma_unmap_single(iSeries_vio_dev, handle, HW_PAGE_SIZE, | 148 | iseries_hv_unmap(handle, HW_PAGE_SIZE, DMA_FROM_DEVICE); |
150 | DMA_FROM_DEVICE); | ||
151 | kfree(buf); | 149 | kfree(buf); |
152 | 150 | ||
153 | seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap); | 151 | seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap); |
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index b88fdebe77f6..c081e5400ce0 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
@@ -220,7 +220,7 @@ static void __init get_viocd_info(void) | |||
220 | struct cdrom_info *viocd_unitinfo; | 220 | struct cdrom_info *viocd_unitinfo; |
221 | dma_addr_t unitinfo_dmaaddr; | 221 | dma_addr_t unitinfo_dmaaddr; |
222 | 222 | ||
223 | viocd_unitinfo = dma_alloc_coherent(iSeries_vio_dev, | 223 | viocd_unitinfo = iseries_hv_alloc( |
224 | sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, | 224 | sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, |
225 | &unitinfo_dmaaddr, GFP_ATOMIC); | 225 | &unitinfo_dmaaddr, GFP_ATOMIC); |
226 | if (viocd_unitinfo == NULL) { | 226 | if (viocd_unitinfo == NULL) { |
@@ -262,8 +262,7 @@ static void __init get_viocd_info(void) | |||
262 | } | 262 | } |
263 | 263 | ||
264 | error_ret: | 264 | error_ret: |
265 | dma_free_coherent(iSeries_vio_dev, | 265 | iseries_hv_free(sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, |
266 | sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, | ||
267 | viocd_unitinfo, unitinfo_dmaaddr); | 266 | viocd_unitinfo, unitinfo_dmaaddr); |
268 | } | 267 | } |
269 | 268 | ||
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index e12275df6ea2..064c09195215 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c | |||
@@ -392,8 +392,8 @@ static int get_viotape_info(void) | |||
392 | if (op == NULL) | 392 | if (op == NULL) |
393 | return -ENOMEM; | 393 | return -ENOMEM; |
394 | 394 | ||
395 | viotape_unitinfo = dma_alloc_coherent(iSeries_vio_dev, len, | 395 | viotape_unitinfo = iseries_hv_alloc(len, &viotape_unitinfo_token, |
396 | &viotape_unitinfo_token, GFP_ATOMIC); | 396 | GFP_ATOMIC); |
397 | if (viotape_unitinfo == NULL) { | 397 | if (viotape_unitinfo == NULL) { |
398 | free_op_struct(op); | 398 | free_op_struct(op); |
399 | return -ENOMEM; | 399 | return -ENOMEM; |
@@ -1103,8 +1103,7 @@ static void __exit viotap_exit(void) | |||
1103 | class_destroy(tape_class); | 1103 | class_destroy(tape_class); |
1104 | unregister_chrdev(VIOTAPE_MAJOR, "viotape"); | 1104 | unregister_chrdev(VIOTAPE_MAJOR, "viotape"); |
1105 | if (viotape_unitinfo) | 1105 | if (viotape_unitinfo) |
1106 | dma_free_coherent(iSeries_vio_dev, | 1106 | iseries_hv_free(sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE, |
1107 | sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE, | ||
1108 | viotape_unitinfo, viotape_unitinfo_token); | 1107 | viotape_unitinfo, viotape_unitinfo_token); |
1109 | viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2); | 1108 | viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2); |
1110 | vio_clearHandler(viomajorsubtype_tape); | 1109 | vio_clearHandler(viomajorsubtype_tape); |
diff --git a/include/asm-powerpc/iseries/hv_call_event.h b/include/asm-powerpc/iseries/hv_call_event.h index 4cec4762076d..cc029d388e11 100644 --- a/include/asm-powerpc/iseries/hv_call_event.h +++ b/include/asm-powerpc/iseries/hv_call_event.h | |||
@@ -21,6 +21,9 @@ | |||
21 | #ifndef _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H | 21 | #ifndef _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H |
22 | #define _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H | 22 | #define _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H |
23 | 23 | ||
24 | #include <linux/types.h> | ||
25 | #include <linux/dma-mapping.h> | ||
26 | |||
24 | #include <asm/iseries/hv_call_sc.h> | 27 | #include <asm/iseries/hv_call_sc.h> |
25 | #include <asm/iseries/hv_types.h> | 28 | #include <asm/iseries/hv_types.h> |
26 | #include <asm/abs_addr.h> | 29 | #include <asm/abs_addr.h> |
@@ -113,6 +116,13 @@ static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp, | |||
113 | eventData3, eventData4, eventData5); | 116 | eventData3, eventData4, eventData5); |
114 | } | 117 | } |
115 | 118 | ||
119 | extern void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag); | ||
120 | extern void iseries_hv_free(size_t size, void *vaddr, dma_addr_t dma_handle); | ||
121 | extern dma_addr_t iseries_hv_map(void *vaddr, size_t size, | ||
122 | enum dma_data_direction direction); | ||
123 | extern void iseries_hv_unmap(dma_addr_t dma_handle, size_t size, | ||
124 | enum dma_data_direction direction); | ||
125 | |||
116 | static inline HvLpEvent_Rc HvCallEvent_ackLpEvent(struct HvLpEvent *event) | 126 | static inline HvLpEvent_Rc HvCallEvent_ackLpEvent(struct HvLpEvent *event) |
117 | { | 127 | { |
118 | return HvCall1(HvCallEventAckLpEvent, virt_to_abs(event)); | 128 | return HvCall1(HvCallEventAckLpEvent, virt_to_abs(event)); |
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h index 7a95d296abd1..5a5cd0f0c095 100644 --- a/include/asm-powerpc/iseries/vio.h +++ b/include/asm-powerpc/iseries/vio.h | |||
@@ -150,8 +150,4 @@ enum viochar_rc { | |||
150 | viochar_rc_ebusy = 1 | 150 | viochar_rc_ebusy = 1 |
151 | }; | 151 | }; |
152 | 152 | ||
153 | struct device; | ||
154 | |||
155 | extern struct device *iSeries_vio_dev; | ||
156 | |||
157 | #endif /* _ASM_POWERPC_ISERIES_VIO_H */ | 153 | #endif /* _ASM_POWERPC_ISERIES_VIO_H */ |