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 */ |
