diff options
author | Murali Karicheri <m-karicheri2@ti.com> | 2015-03-03 12:52:09 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2015-03-03 15:42:56 -0500 |
commit | 1f5c69aa51f9c7c8d2a5c2e4dc339f6c7d5c15cd (patch) | |
tree | 152d30ba274eddb828c0f5ea8d886ab82f96819a | |
parent | ed748621031c2a205749997421e59fb4dfb1e909 (diff) |
of: Move of_dma_configure() to device.c to help re-use
Move of_dma_configure() to device.c so it can be re-used for PCI devices to
obtain DMA configuration from DT. Also add a second argument so that for
PCI, the DT node of root bus host bridge can be used to obtain the DMA
configuration for the slave PCI device.
Tested-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com> (AMD Seattle)
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Will Deacon <will.deacon@arm.com>
Acked-by: Rob Herring <robh+dt@kernel.org>
CC: Joerg Roedel <joro@8bytes.org>
CC: Grant Likely <grant.likely@linaro.org>
CC: Russell King <linux@arm.linux.org.uk>
CC: Arnd Bergmann <arnd@arndb.de>
-rw-r--r-- | drivers/of/device.c | 59 | ||||
-rw-r--r-- | drivers/of/platform.c | 58 | ||||
-rw-r--r-- | include/linux/of_device.h | 3 |
3 files changed, 64 insertions, 56 deletions
diff --git a/drivers/of/device.c b/drivers/of/device.c index 46d6c75c1404..31a7875b34a4 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c | |||
@@ -2,6 +2,9 @@ | |||
2 | #include <linux/kernel.h> | 2 | #include <linux/kernel.h> |
3 | #include <linux/of.h> | 3 | #include <linux/of.h> |
4 | #include <linux/of_device.h> | 4 | #include <linux/of_device.h> |
5 | #include <linux/of_address.h> | ||
6 | #include <linux/of_iommu.h> | ||
7 | #include <linux/dma-mapping.h> | ||
5 | #include <linux/init.h> | 8 | #include <linux/init.h> |
6 | #include <linux/module.h> | 9 | #include <linux/module.h> |
7 | #include <linux/mod_devicetable.h> | 10 | #include <linux/mod_devicetable.h> |
@@ -66,6 +69,62 @@ int of_device_add(struct platform_device *ofdev) | |||
66 | return device_add(&ofdev->dev); | 69 | return device_add(&ofdev->dev); |
67 | } | 70 | } |
68 | 71 | ||
72 | /** | ||
73 | * of_dma_configure - Setup DMA configuration | ||
74 | * @dev: Device to apply DMA configuration | ||
75 | * @np: Pointer to OF node having DMA configuration | ||
76 | * | ||
77 | * Try to get devices's DMA configuration from DT and update it | ||
78 | * accordingly. | ||
79 | * | ||
80 | * If platform code needs to use its own special DMA configuration, it | ||
81 | * can use a platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE events | ||
82 | * to fix up DMA configuration. | ||
83 | */ | ||
84 | void of_dma_configure(struct device *dev, struct device_node *np) | ||
85 | { | ||
86 | u64 dma_addr, paddr, size; | ||
87 | int ret; | ||
88 | bool coherent; | ||
89 | unsigned long offset; | ||
90 | struct iommu_ops *iommu; | ||
91 | |||
92 | /* | ||
93 | * Set default dma-mask to 32 bit. Drivers are expected to setup | ||
94 | * the correct supported dma_mask. | ||
95 | */ | ||
96 | dev->coherent_dma_mask = DMA_BIT_MASK(32); | ||
97 | |||
98 | /* | ||
99 | * Set it to coherent_dma_mask by default if the architecture | ||
100 | * code has not set it. | ||
101 | */ | ||
102 | if (!dev->dma_mask) | ||
103 | dev->dma_mask = &dev->coherent_dma_mask; | ||
104 | |||
105 | ret = of_dma_get_range(np, &dma_addr, &paddr, &size); | ||
106 | if (ret < 0) { | ||
107 | dma_addr = offset = 0; | ||
108 | size = dev->coherent_dma_mask; | ||
109 | } else { | ||
110 | offset = PFN_DOWN(paddr - dma_addr); | ||
111 | dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset); | ||
112 | } | ||
113 | |||
114 | dev->dma_pfn_offset = offset; | ||
115 | |||
116 | coherent = of_dma_is_coherent(np); | ||
117 | dev_dbg(dev, "device is%sdma coherent\n", | ||
118 | coherent ? " " : " not "); | ||
119 | |||
120 | iommu = of_iommu_configure(dev, np); | ||
121 | dev_dbg(dev, "device is%sbehind an iommu\n", | ||
122 | iommu ? " " : " not "); | ||
123 | |||
124 | arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent); | ||
125 | } | ||
126 | EXPORT_SYMBOL_GPL(of_dma_configure); | ||
127 | |||
69 | int of_device_register(struct platform_device *pdev) | 128 | int of_device_register(struct platform_device *pdev) |
70 | { | 129 | { |
71 | device_initialize(&pdev->dev); | 130 | device_initialize(&pdev->dev); |
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 667c6f13f12b..a01f57c9e34e 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/of_address.h> | 20 | #include <linux/of_address.h> |
21 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
22 | #include <linux/of_iommu.h> | ||
23 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
24 | #include <linux/of_platform.h> | 23 | #include <linux/of_platform.h> |
25 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
@@ -150,59 +149,6 @@ struct platform_device *of_device_alloc(struct device_node *np, | |||
150 | } | 149 | } |
151 | EXPORT_SYMBOL(of_device_alloc); | 150 | EXPORT_SYMBOL(of_device_alloc); |
152 | 151 | ||
153 | /** | ||
154 | * of_dma_configure - Setup DMA configuration | ||
155 | * @dev: Device to apply DMA configuration | ||
156 | * | ||
157 | * Try to get devices's DMA configuration from DT and update it | ||
158 | * accordingly. | ||
159 | * | ||
160 | * In case if platform code need to use own special DMA configuration,it | ||
161 | * can use Platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE event | ||
162 | * to fix up DMA configuration. | ||
163 | */ | ||
164 | static void of_dma_configure(struct device *dev) | ||
165 | { | ||
166 | u64 dma_addr, paddr, size; | ||
167 | int ret; | ||
168 | bool coherent; | ||
169 | unsigned long offset; | ||
170 | struct iommu_ops *iommu; | ||
171 | |||
172 | /* | ||
173 | * Set default dma-mask to 32 bit. Drivers are expected to setup | ||
174 | * the correct supported dma_mask. | ||
175 | */ | ||
176 | dev->coherent_dma_mask = DMA_BIT_MASK(32); | ||
177 | |||
178 | /* | ||
179 | * Set it to coherent_dma_mask by default if the architecture | ||
180 | * code has not set it. | ||
181 | */ | ||
182 | if (!dev->dma_mask) | ||
183 | dev->dma_mask = &dev->coherent_dma_mask; | ||
184 | |||
185 | ret = of_dma_get_range(dev->of_node, &dma_addr, &paddr, &size); | ||
186 | if (ret < 0) { | ||
187 | dma_addr = offset = 0; | ||
188 | size = dev->coherent_dma_mask; | ||
189 | } else { | ||
190 | offset = PFN_DOWN(paddr - dma_addr); | ||
191 | dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset); | ||
192 | } | ||
193 | dev->dma_pfn_offset = offset; | ||
194 | |||
195 | coherent = of_dma_is_coherent(dev->of_node); | ||
196 | dev_dbg(dev, "device is%sdma coherent\n", | ||
197 | coherent ? " " : " not "); | ||
198 | |||
199 | iommu = of_iommu_configure(dev, dev->of_node); | ||
200 | dev_dbg(dev, "device is%sbehind an iommu\n", | ||
201 | iommu ? " " : " not "); | ||
202 | |||
203 | arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent); | ||
204 | } | ||
205 | |||
206 | static void of_dma_deconfigure(struct device *dev) | 152 | static void of_dma_deconfigure(struct device *dev) |
207 | { | 153 | { |
208 | arch_teardown_dma_ops(dev); | 154 | arch_teardown_dma_ops(dev); |
@@ -236,7 +182,7 @@ static struct platform_device *of_platform_device_create_pdata( | |||
236 | 182 | ||
237 | dev->dev.bus = &platform_bus_type; | 183 | dev->dev.bus = &platform_bus_type; |
238 | dev->dev.platform_data = platform_data; | 184 | dev->dev.platform_data = platform_data; |
239 | of_dma_configure(&dev->dev); | 185 | of_dma_configure(&dev->dev, dev->dev.of_node); |
240 | 186 | ||
241 | if (of_device_add(dev) != 0) { | 187 | if (of_device_add(dev) != 0) { |
242 | of_dma_deconfigure(&dev->dev); | 188 | of_dma_deconfigure(&dev->dev); |
@@ -299,7 +245,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node, | |||
299 | dev_set_name(&dev->dev, "%s", bus_id); | 245 | dev_set_name(&dev->dev, "%s", bus_id); |
300 | else | 246 | else |
301 | of_device_make_bus_id(&dev->dev); | 247 | of_device_make_bus_id(&dev->dev); |
302 | of_dma_configure(&dev->dev); | 248 | of_dma_configure(&dev->dev, dev->dev.of_node); |
303 | 249 | ||
304 | /* Allow the HW Peripheral ID to be overridden */ | 250 | /* Allow the HW Peripheral ID to be overridden */ |
305 | prop = of_get_property(node, "arm,primecell-periphid", NULL); | 251 | prop = of_get_property(node, "arm,primecell-periphid", NULL); |
diff --git a/include/linux/of_device.h b/include/linux/of_device.h index ef370210ffb2..22801b10cef5 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h | |||
@@ -53,6 +53,7 @@ static inline struct device_node *of_cpu_device_node_get(int cpu) | |||
53 | return of_node_get(cpu_dev->of_node); | 53 | return of_node_get(cpu_dev->of_node); |
54 | } | 54 | } |
55 | 55 | ||
56 | void of_dma_configure(struct device *dev, struct device_node *np); | ||
56 | #else /* CONFIG_OF */ | 57 | #else /* CONFIG_OF */ |
57 | 58 | ||
58 | static inline int of_driver_match_device(struct device *dev, | 59 | static inline int of_driver_match_device(struct device *dev, |
@@ -90,6 +91,8 @@ static inline struct device_node *of_cpu_device_node_get(int cpu) | |||
90 | { | 91 | { |
91 | return NULL; | 92 | return NULL; |
92 | } | 93 | } |
94 | static inline void of_dma_configure(struct device *dev, struct device_node *np) | ||
95 | {} | ||
93 | #endif /* CONFIG_OF */ | 96 | #endif /* CONFIG_OF */ |
94 | 97 | ||
95 | #endif /* _LINUX_OF_DEVICE_H */ | 98 | #endif /* _LINUX_OF_DEVICE_H */ |