Skip to content

Commit 591c1ee

Browse files
author
Santosh Shilimkar
committed
of: configure the platform device dma parameters
Retrieve DMA configuration from DT and setup platform device's DMA parameters. The DMA configuration in DT has to be specified using "dma-ranges" and "dma-coherent" properties if supported. We setup dma_pfn_offset using "dma-ranges" and dma_coherent_ops using "dma-coherent" device tree properties. The set_arch_dma_coherent_ops macro has to be defined by arch if it supports coherent dma_ops. Otherwise, set_arch_dma_coherent_ops() is declared as nop. Cc: Greg Kroah-Hartman <[email protected]> Cc: Russell King <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Olof Johansson <[email protected]> Cc: Grant Likely <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Linus Walleij <[email protected]> Reviewed-by: Rob Herring <[email protected]> Signed-off-by: Grygorii Strashko <[email protected]> Signed-off-by: Santosh Shilimkar <[email protected]>
1 parent 92ea637 commit 591c1ee

File tree

2 files changed

+66
-6
lines changed

2 files changed

+66
-6
lines changed

drivers/of/platform.c

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,64 @@ struct platform_device *of_device_alloc(struct device_node *np,
186186
}
187187
EXPORT_SYMBOL(of_device_alloc);
188188

189+
/**
190+
* of_dma_configure - Setup DMA configuration
191+
* @dev: Device to apply DMA configuration
192+
*
193+
* Try to get devices's DMA configuration from DT and update it
194+
* accordingly.
195+
*
196+
* In case if platform code need to use own special DMA configuration,it
197+
* can use Platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE event
198+
* to fix up DMA configuration.
199+
*/
200+
static void of_dma_configure(struct platform_device *pdev)
201+
{
202+
u64 dma_addr, paddr, size;
203+
int ret;
204+
struct device *dev = &pdev->dev;
205+
206+
#if defined(CONFIG_MICROBLAZE)
207+
pdev->archdata.dma_mask = 0xffffffffUL;
208+
#endif
209+
210+
/*
211+
* Set default dma-mask to 32 bit. Drivers are expected to setup
212+
* the correct supported dma_mask.
213+
*/
214+
dev->coherent_dma_mask = DMA_BIT_MASK(32);
215+
216+
/*
217+
* Set it to coherent_dma_mask by default if the architecture
218+
* code has not set it.
219+
*/
220+
if (!dev->dma_mask)
221+
dev->dma_mask = &dev->coherent_dma_mask;
222+
223+
/*
224+
* if dma-coherent property exist, call arch hook to setup
225+
* dma coherent operations.
226+
*/
227+
if (of_dma_is_coherent(dev->of_node)) {
228+
set_arch_dma_coherent_ops(dev);
229+
dev_dbg(dev, "device is dma coherent\n");
230+
}
231+
232+
/*
233+
* if dma-ranges property doesn't exist - just return else
234+
* setup the dma offset
235+
*/
236+
ret = of_dma_get_range(dev->of_node, &dma_addr, &paddr, &size);
237+
if (ret < 0) {
238+
dev_dbg(dev, "no dma range information to setup\n");
239+
return;
240+
}
241+
242+
/* DMA ranges found. Calculate and set dma_pfn_offset */
243+
dev->dma_pfn_offset = PFN_DOWN(paddr - dma_addr);
244+
dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", dev->dma_pfn_offset);
245+
}
246+
189247
/**
190248
* of_platform_device_create_pdata - Alloc, initialize and register an of_device
191249
* @np: pointer to node to create device for
@@ -211,12 +269,7 @@ static struct platform_device *of_platform_device_create_pdata(
211269
if (!dev)
212270
return NULL;
213271

214-
#if defined(CONFIG_MICROBLAZE)
215-
dev->archdata.dma_mask = 0xffffffffUL;
216-
#endif
217-
dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
218-
if (!dev->dev.dma_mask)
219-
dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
272+
of_dma_configure(dev);
220273
dev->dev.bus = &platform_bus_type;
221274
dev->dev.platform_data = platform_data;
222275

include/linux/dma-mapping.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,13 @@ static inline int dma_coerce_mask_and_coherent(struct device *dev, u64 mask)
123123

124124
extern u64 dma_get_required_mask(struct device *dev);
125125

126+
#ifndef set_arch_dma_coherent_ops
127+
static inline int set_arch_dma_coherent_ops(struct device *dev)
128+
{
129+
return 0;
130+
}
131+
#endif
132+
126133
static inline unsigned int dma_get_max_seg_size(struct device *dev)
127134
{
128135
return dev->dma_parms ? dev->dma_parms->max_segment_size : 65536;

0 commit comments

Comments
 (0)