aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/device.h3
-rw-r--r--arch/powerpc/include/asm/dma-mapping.h8
-rw-r--r--arch/powerpc/include/asm/swiotlb.h5
-rw-r--r--arch/powerpc/kernel/dma-swiotlb.c36
-rw-r--r--arch/powerpc/platforms/85xx/mpc8536_ds.c1
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ds.c1
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c1
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c1
8 files changed, 28 insertions, 28 deletions
diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h
index 7d2277cef09..0086f8d46f1 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -16,6 +16,9 @@ struct dev_archdata {
16 /* DMA operations on that device */ 16 /* DMA operations on that device */
17 struct dma_mapping_ops *dma_ops; 17 struct dma_mapping_ops *dma_ops;
18 void *dma_data; 18 void *dma_data;
19#ifdef CONFIG_SWIOTLB
20 dma_addr_t max_direct_dma_addr;
21#endif
19}; 22};
20 23
21static inline void dev_archdata_set_node(struct dev_archdata *ad, 24static inline void dev_archdata_set_node(struct dev_archdata *ad,
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index 0c34371ec49..1765c379138 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -87,8 +87,6 @@ struct dma_mapping_ops {
87 dma_addr_t dma_address, size_t size, 87 dma_addr_t dma_address, size_t size,
88 enum dma_data_direction direction, 88 enum dma_data_direction direction,
89 struct dma_attrs *attrs); 89 struct dma_attrs *attrs);
90 int (*addr_needs_map)(struct device *dev, dma_addr_t addr,
91 size_t size);
92#ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS 90#ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS
93 void (*sync_single_range_for_cpu)(struct device *hwdev, 91 void (*sync_single_range_for_cpu)(struct device *hwdev,
94 dma_addr_t dma_handle, unsigned long offset, 92 dma_addr_t dma_handle, unsigned long offset,
@@ -426,10 +424,12 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
426 424
427static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) 425static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
428{ 426{
429 struct dma_mapping_ops *ops = get_dma_ops(dev); 427#ifdef CONFIG_SWIOTLB
428 struct dev_archdata *sd = &dev->archdata;
430 429
431 if (ops->addr_needs_map && ops->addr_needs_map(dev, addr, size)) 430 if (sd->max_direct_dma_addr && addr + size > sd->max_direct_dma_addr)
432 return 0; 431 return 0;
432#endif
433 433
434 if (!dev->dma_mask) 434 if (!dev->dma_mask)
435 return 0; 435 return 0;
diff --git a/arch/powerpc/include/asm/swiotlb.h b/arch/powerpc/include/asm/swiotlb.h
index 30891d6e2bc..31e0e43c880 100644
--- a/arch/powerpc/include/asm/swiotlb.h
+++ b/arch/powerpc/include/asm/swiotlb.h
@@ -16,12 +16,11 @@
16extern struct dma_mapping_ops swiotlb_dma_ops; 16extern struct dma_mapping_ops swiotlb_dma_ops;
17extern struct dma_mapping_ops swiotlb_pci_dma_ops; 17extern struct dma_mapping_ops swiotlb_pci_dma_ops;
18 18
19int swiotlb_arch_address_needs_mapping(struct device *, dma_addr_t,
20 size_t size);
21
22static inline void dma_mark_clean(void *addr, size_t size) {} 19static inline void dma_mark_clean(void *addr, size_t size) {}
23 20
24extern unsigned int ppc_swiotlb_enable; 21extern unsigned int ppc_swiotlb_enable;
25int __init swiotlb_setup_bus_notifier(void); 22int __init swiotlb_setup_bus_notifier(void);
26 23
24extern void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev);
25
27#endif /* __ASM_SWIOTLB_H */ 26#endif /* __ASM_SWIOTLB_H */
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c
index e8a57de85bc..c9f6a302e87 100644
--- a/arch/powerpc/kernel/dma-swiotlb.c
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -25,26 +25,6 @@ int swiotlb __read_mostly;
25unsigned int ppc_swiotlb_enable; 25unsigned int ppc_swiotlb_enable;
26 26
27/* 27/*
28 * Determine if an address is reachable by a pci device, or if we must bounce.
29 */
30static int
31swiotlb_pci_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size)
32{
33 dma_addr_t max;
34 struct pci_controller *hose;
35 struct pci_dev *pdev = to_pci_dev(hwdev);
36
37 hose = pci_bus_to_host(pdev->bus);
38 max = hose->dma_window_base_cur + hose->dma_window_size;
39
40 /* check that we're within mapped pci window space */
41 if ((addr + size > max) | (addr < hose->dma_window_base_cur))
42 return 1;
43
44 return 0;
45}
46
47/*
48 * At the moment, all platforms that use this code only require 28 * At the moment, all platforms that use this code only require
49 * swiotlb to be used if we're operating on HIGHMEM. Since 29 * swiotlb to be used if we're operating on HIGHMEM. Since
50 * we don't ever call anything other than map_sg, unmap_sg, 30 * we don't ever call anything other than map_sg, unmap_sg,
@@ -73,22 +53,36 @@ struct dma_mapping_ops swiotlb_pci_dma_ops = {
73 .dma_supported = swiotlb_dma_supported, 53 .dma_supported = swiotlb_dma_supported,
74 .map_page = swiotlb_map_page, 54 .map_page = swiotlb_map_page,
75 .unmap_page = swiotlb_unmap_page, 55 .unmap_page = swiotlb_unmap_page,
76 .addr_needs_map = swiotlb_pci_addr_needs_map,
77 .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu, 56 .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
78 .sync_single_range_for_device = swiotlb_sync_single_range_for_device, 57 .sync_single_range_for_device = swiotlb_sync_single_range_for_device,
79 .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, 58 .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
80 .sync_sg_for_device = swiotlb_sync_sg_for_device 59 .sync_sg_for_device = swiotlb_sync_sg_for_device
81}; 60};
82 61
62void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev)
63{
64 struct pci_controller *hose;
65 struct dev_archdata *sd;
66
67 hose = pci_bus_to_host(pdev->bus);
68 sd = &pdev->dev.archdata;
69 sd->max_direct_dma_addr =
70 hose->dma_window_base_cur + hose->dma_window_size;
71}
72
83static int ppc_swiotlb_bus_notify(struct notifier_block *nb, 73static int ppc_swiotlb_bus_notify(struct notifier_block *nb,
84 unsigned long action, void *data) 74 unsigned long action, void *data)
85{ 75{
86 struct device *dev = data; 76 struct device *dev = data;
77 struct dev_archdata *sd;
87 78
88 /* We are only intereted in device addition */ 79 /* We are only intereted in device addition */
89 if (action != BUS_NOTIFY_ADD_DEVICE) 80 if (action != BUS_NOTIFY_ADD_DEVICE)
90 return 0; 81 return 0;
91 82
83 sd = &dev->archdata;
84 sd->max_direct_dma_addr = 0;
85
92 /* May need to bounce if the device can't address all of DRAM */ 86 /* May need to bounce if the device can't address all of DRAM */
93 if (dma_get_mask(dev) < lmb_end_of_DRAM()) 87 if (dma_get_mask(dev) < lmb_end_of_DRAM())
94 set_dma_ops(dev, &swiotlb_dma_ops); 88 set_dma_ops(dev, &swiotlb_dma_ops);
diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c
index 055ff417bae..bf052c05610 100644
--- a/arch/powerpc/platforms/85xx/mpc8536_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c
@@ -97,6 +97,7 @@ static void __init mpc8536_ds_setup_arch(void)
97 if (lmb_end_of_DRAM() > max) { 97 if (lmb_end_of_DRAM() > max) {
98 ppc_swiotlb_enable = 1; 98 ppc_swiotlb_enable = 1;
99 set_pci_dma_ops(&swiotlb_pci_dma_ops); 99 set_pci_dma_ops(&swiotlb_pci_dma_ops);
100 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
100 } 101 }
101#endif 102#endif
102 103
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 849c0ac0025..c6f92ccd963 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -193,6 +193,7 @@ static void __init mpc85xx_ds_setup_arch(void)
193 if (lmb_end_of_DRAM() > max) { 193 if (lmb_end_of_DRAM() > max) {
194 ppc_swiotlb_enable = 1; 194 ppc_swiotlb_enable = 1;
195 set_pci_dma_ops(&swiotlb_pci_dma_ops); 195 set_pci_dma_ops(&swiotlb_pci_dma_ops);
196 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
196 } 197 }
197#endif 198#endif
198 199
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 20a61d0af33..25998b661f2 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -256,6 +256,7 @@ static void __init mpc85xx_mds_setup_arch(void)
256 if (lmb_end_of_DRAM() > max) { 256 if (lmb_end_of_DRAM() > max) {
257 ppc_swiotlb_enable = 1; 257 ppc_swiotlb_enable = 1;
258 set_pci_dma_ops(&swiotlb_pci_dma_ops); 258 set_pci_dma_ops(&swiotlb_pci_dma_ops);
259 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
259 } 260 }
260#endif 261#endif
261} 262}
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 66327024a6a..80323015687 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -106,6 +106,7 @@ mpc86xx_hpcn_setup_arch(void)
106 if (lmb_end_of_DRAM() > max) { 106 if (lmb_end_of_DRAM() > max) {
107 ppc_swiotlb_enable = 1; 107 ppc_swiotlb_enable = 1;
108 set_pci_dma_ops(&swiotlb_pci_dma_ops); 108 set_pci_dma_ops(&swiotlb_pci_dma_ops);
109 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
109 } 110 }
110#endif 111#endif
111} 112}