diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-05-22 13:11:07 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-05-23 07:30:52 -0400 |
commit | 6b74f61a471ad0f3a5e919e314d4f60cd3966f5e (patch) | |
tree | 9ab2c2ea8a78c499f1ce755737e5dc5003ca2a07 /drivers/of/platform.c | |
parent | 4b660a7f5c8099d88d1a43d8ae138965112592c7 (diff) | |
parent | 2161c2485d03520060f6094359b22f33913eefa2 (diff) |
Merge tag 'dt-dma-properties-for-arm' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone into devel-stable
DT support for 'dma-ranges'and 'dma-coherent' properties with ARM updates
- The 'dma-ranges' helps to take care of few DMAable system memory
restrictions by use of dma_pfn_offset which is maintained per
device. Arch code then uses it for dma address translations for such
cases. We update the dma_pfn_offset accordingly during DT the device
creation process.
- The 'dma-coherent' property is used to setup arch's coherent dma_ops.
Diffstat (limited to 'drivers/of/platform.c')
-rw-r--r-- | drivers/of/platform.c | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index bd47fbc53dc9..4e91583a3908 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -189,6 +189,64 @@ struct platform_device *of_device_alloc(struct device_node *np, | |||
189 | EXPORT_SYMBOL(of_device_alloc); | 189 | EXPORT_SYMBOL(of_device_alloc); |
190 | 190 | ||
191 | /** | 191 | /** |
192 | * of_dma_configure - Setup DMA configuration | ||
193 | * @dev: Device to apply DMA configuration | ||
194 | * | ||
195 | * Try to get devices's DMA configuration from DT and update it | ||
196 | * accordingly. | ||
197 | * | ||
198 | * In case if platform code need to use own special DMA configuration,it | ||
199 | * can use Platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE event | ||
200 | * to fix up DMA configuration. | ||
201 | */ | ||
202 | static void of_dma_configure(struct platform_device *pdev) | ||
203 | { | ||
204 | u64 dma_addr, paddr, size; | ||
205 | int ret; | ||
206 | struct device *dev = &pdev->dev; | ||
207 | |||
208 | #if defined(CONFIG_MICROBLAZE) | ||
209 | pdev->archdata.dma_mask = 0xffffffffUL; | ||
210 | #endif | ||
211 | |||
212 | /* | ||
213 | * Set default dma-mask to 32 bit. Drivers are expected to setup | ||
214 | * the correct supported dma_mask. | ||
215 | */ | ||
216 | dev->coherent_dma_mask = DMA_BIT_MASK(32); | ||
217 | |||
218 | /* | ||
219 | * Set it to coherent_dma_mask by default if the architecture | ||
220 | * code has not set it. | ||
221 | */ | ||
222 | if (!dev->dma_mask) | ||
223 | dev->dma_mask = &dev->coherent_dma_mask; | ||
224 | |||
225 | /* | ||
226 | * if dma-coherent property exist, call arch hook to setup | ||
227 | * dma coherent operations. | ||
228 | */ | ||
229 | if (of_dma_is_coherent(dev->of_node)) { | ||
230 | set_arch_dma_coherent_ops(dev); | ||
231 | dev_dbg(dev, "device is dma coherent\n"); | ||
232 | } | ||
233 | |||
234 | /* | ||
235 | * if dma-ranges property doesn't exist - just return else | ||
236 | * setup the dma offset | ||
237 | */ | ||
238 | ret = of_dma_get_range(dev->of_node, &dma_addr, &paddr, &size); | ||
239 | if (ret < 0) { | ||
240 | dev_dbg(dev, "no dma range information to setup\n"); | ||
241 | return; | ||
242 | } | ||
243 | |||
244 | /* DMA ranges found. Calculate and set dma_pfn_offset */ | ||
245 | dev->dma_pfn_offset = PFN_DOWN(paddr - dma_addr); | ||
246 | dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", dev->dma_pfn_offset); | ||
247 | } | ||
248 | |||
249 | /** | ||
192 | * of_platform_device_create_pdata - Alloc, initialize and register an of_device | 250 | * of_platform_device_create_pdata - Alloc, initialize and register an of_device |
193 | * @np: pointer to node to create device for | 251 | * @np: pointer to node to create device for |
194 | * @bus_id: name to assign device | 252 | * @bus_id: name to assign device |
@@ -213,12 +271,7 @@ static struct platform_device *of_platform_device_create_pdata( | |||
213 | if (!dev) | 271 | if (!dev) |
214 | return NULL; | 272 | return NULL; |
215 | 273 | ||
216 | #if defined(CONFIG_MICROBLAZE) | 274 | of_dma_configure(dev); |
217 | dev->archdata.dma_mask = 0xffffffffUL; | ||
218 | #endif | ||
219 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | ||
220 | if (!dev->dev.dma_mask) | ||
221 | dev->dev.dma_mask = &dev->dev.coherent_dma_mask; | ||
222 | dev->dev.bus = &platform_bus_type; | 275 | dev->dev.bus = &platform_bus_type; |
223 | dev->dev.platform_data = platform_data; | 276 | dev->dev.platform_data = platform_data; |
224 | 277 | ||