aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/vio.c7
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c30
-rw-r--r--arch/powerpc/platforms/iseries/mf.c23
-rw-r--r--arch/powerpc/platforms/iseries/viopath.c6
-rw-r--r--drivers/cdrom/viocd.c5
-rw-r--r--drivers/char/viotape.c7
-rw-r--r--include/asm-powerpc/iseries/hv_call_event.h10
-rw-r--r--include/asm-powerpc/iseries/vio.h4
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
52struct device *iSeries_vio_dev = &vio_bus_device.dev;
53EXPORT_SYMBOL(iSeries_vio_dev);
54
55static struct iommu_table veth_iommu_table; 52static struct iommu_table veth_iommu_table;
56static struct iommu_table vio_iommu_table; 53struct iommu_table vio_iommu_table;
57 54
58static void __init iommu_vio_init(void) 55static 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
73static void __init iommu_vio_init(void) 68static 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
41static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, 43static 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
194extern struct iommu_table vio_iommu_table;
195
196void *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}
201EXPORT_SYMBOL_GPL(iseries_hv_alloc);
202
203void 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}
207EXPORT_SYMBOL_GPL(iseries_hv_free);
208
209dma_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
216void 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
192void iommu_init_early_iSeries(void) 222void 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
1172out_free: 1168out_free:
1173 dma_free_coherent(iSeries_vio_dev, count, page, dma_addr); 1169 iseries_hv_free(count, page, dma_addr);
1174out: 1170out:
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;
1221out_free: 1216out_free:
1222 dma_free_coherent(iSeries_vio_dev, count, page, dma_addr); 1217 iseries_hv_free(count, page, dma_addr);
1223out: 1218out:
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
264error_ret: 264error_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
119extern void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag);
120extern void iseries_hv_free(size_t size, void *vaddr, dma_addr_t dma_handle);
121extern dma_addr_t iseries_hv_map(void *vaddr, size_t size,
122 enum dma_data_direction direction);
123extern void iseries_hv_unmap(dma_addr_t dma_handle, size_t size,
124 enum dma_data_direction direction);
125
116static inline HvLpEvent_Rc HvCallEvent_ackLpEvent(struct HvLpEvent *event) 126static 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
153struct device;
154
155extern struct device *iSeries_vio_dev;
156
157#endif /* _ASM_POWERPC_ISERIES_VIO_H */ 153#endif /* _ASM_POWERPC_ISERIES_VIO_H */