diff options
| author | Santosh Shilimkar <santosh.shilimkar@ti.com> | 2014-04-24 11:30:04 -0400 |
|---|---|---|
| committer | Santosh Shilimkar <santosh.shilimkar@ti.com> | 2014-05-07 09:21:21 -0400 |
| commit | 591c1ee465ce5372385dbc41e7d3e36cbb477bd8 (patch) | |
| tree | 9a1a70d862e00f8431956479eb15899565f0f6bd | |
| parent | 92ea637edea36e58236e3124f199161da6f5c5de (diff) | |
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 <gregkh@linuxfoundation.org>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <olof@lixom.net>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
| -rw-r--r-- | drivers/of/platform.c | 65 | ||||
| -rw-r--r-- | include/linux/dma-mapping.h | 7 |
2 files changed, 66 insertions, 6 deletions
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 404d1daebefa..91fa9838b56f 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
| @@ -187,6 +187,64 @@ struct platform_device *of_device_alloc(struct device_node *np, | |||
| 187 | EXPORT_SYMBOL(of_device_alloc); | 187 | EXPORT_SYMBOL(of_device_alloc); |
| 188 | 188 | ||
| 189 | /** | 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 | |||
| 247 | /** | ||
| 190 | * of_platform_device_create_pdata - Alloc, initialize and register an of_device | 248 | * of_platform_device_create_pdata - Alloc, initialize and register an of_device |
| 191 | * @np: pointer to node to create device for | 249 | * @np: pointer to node to create device for |
| 192 | * @bus_id: name to assign device | 250 | * @bus_id: name to assign device |
| @@ -211,12 +269,7 @@ static struct platform_device *of_platform_device_create_pdata( | |||
| 211 | if (!dev) | 269 | if (!dev) |
| 212 | return NULL; | 270 | return NULL; |
| 213 | 271 | ||
| 214 | #if defined(CONFIG_MICROBLAZE) | 272 | of_dma_configure(dev); |
| 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; | ||
| 220 | dev->dev.bus = &platform_bus_type; | 273 | dev->dev.bus = &platform_bus_type; |
| 221 | dev->dev.platform_data = platform_data; | 274 | dev->dev.platform_data = platform_data; |
| 222 | 275 | ||
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index fd4aee29ad10..c7d9b1b14ce7 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h | |||
| @@ -123,6 +123,13 @@ static inline int dma_coerce_mask_and_coherent(struct device *dev, u64 mask) | |||
| 123 | 123 | ||
| 124 | extern u64 dma_get_required_mask(struct device *dev); | 124 | extern u64 dma_get_required_mask(struct device *dev); |
| 125 | 125 | ||
| 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 | |||
| 126 | static inline unsigned int dma_get_max_seg_size(struct device *dev) | 133 | static inline unsigned int dma_get_max_seg_size(struct device *dev) |
| 127 | { | 134 | { |
| 128 | return dev->dma_parms ? dev->dma_parms->max_segment_size : 65536; | 135 | return dev->dma_parms ? dev->dma_parms->max_segment_size : 65536; |
