mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-27 05:32:27 +00:00
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>
This commit is contained in:
parent
ed74862103
commit
1f5c69aa51
@ -2,6 +2,9 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/of_iommu.h>
|
||||||
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mod_devicetable.h>
|
#include <linux/mod_devicetable.h>
|
||||||
@ -66,6 +69,62 @@ int of_device_add(struct platform_device *ofdev)
|
|||||||
return device_add(&ofdev->dev);
|
return device_add(&ofdev->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* of_dma_configure - Setup DMA configuration
|
||||||
|
* @dev: Device to apply DMA configuration
|
||||||
|
* @np: Pointer to OF node having DMA configuration
|
||||||
|
*
|
||||||
|
* Try to get devices's DMA configuration from DT and update it
|
||||||
|
* accordingly.
|
||||||
|
*
|
||||||
|
* If platform code needs to use its own special DMA configuration, it
|
||||||
|
* can use a platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE events
|
||||||
|
* to fix up DMA configuration.
|
||||||
|
*/
|
||||||
|
void of_dma_configure(struct device *dev, struct device_node *np)
|
||||||
|
{
|
||||||
|
u64 dma_addr, paddr, size;
|
||||||
|
int ret;
|
||||||
|
bool coherent;
|
||||||
|
unsigned long offset;
|
||||||
|
struct iommu_ops *iommu;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set default dma-mask to 32 bit. Drivers are expected to setup
|
||||||
|
* the correct supported dma_mask.
|
||||||
|
*/
|
||||||
|
dev->coherent_dma_mask = DMA_BIT_MASK(32);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set it to coherent_dma_mask by default if the architecture
|
||||||
|
* code has not set it.
|
||||||
|
*/
|
||||||
|
if (!dev->dma_mask)
|
||||||
|
dev->dma_mask = &dev->coherent_dma_mask;
|
||||||
|
|
||||||
|
ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
|
||||||
|
if (ret < 0) {
|
||||||
|
dma_addr = offset = 0;
|
||||||
|
size = dev->coherent_dma_mask;
|
||||||
|
} else {
|
||||||
|
offset = PFN_DOWN(paddr - dma_addr);
|
||||||
|
dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->dma_pfn_offset = offset;
|
||||||
|
|
||||||
|
coherent = of_dma_is_coherent(np);
|
||||||
|
dev_dbg(dev, "device is%sdma coherent\n",
|
||||||
|
coherent ? " " : " not ");
|
||||||
|
|
||||||
|
iommu = of_iommu_configure(dev, np);
|
||||||
|
dev_dbg(dev, "device is%sbehind an iommu\n",
|
||||||
|
iommu ? " " : " not ");
|
||||||
|
|
||||||
|
arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(of_dma_configure);
|
||||||
|
|
||||||
int of_device_register(struct platform_device *pdev)
|
int of_device_register(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
device_initialize(&pdev->dev);
|
device_initialize(&pdev->dev);
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/of_iommu.h>
|
|
||||||
#include <linux/of_irq.h>
|
#include <linux/of_irq.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
@ -150,59 +149,6 @@ struct platform_device *of_device_alloc(struct device_node *np,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(of_device_alloc);
|
EXPORT_SYMBOL(of_device_alloc);
|
||||||
|
|
||||||
/**
|
|
||||||
* of_dma_configure - Setup DMA configuration
|
|
||||||
* @dev: Device to apply DMA configuration
|
|
||||||
*
|
|
||||||
* Try to get devices's DMA configuration from DT and update it
|
|
||||||
* accordingly.
|
|
||||||
*
|
|
||||||
* In case if platform code need to use own special DMA configuration,it
|
|
||||||
* can use Platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE event
|
|
||||||
* to fix up DMA configuration.
|
|
||||||
*/
|
|
||||||
static void of_dma_configure(struct device *dev)
|
|
||||||
{
|
|
||||||
u64 dma_addr, paddr, size;
|
|
||||||
int ret;
|
|
||||||
bool coherent;
|
|
||||||
unsigned long offset;
|
|
||||||
struct iommu_ops *iommu;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set default dma-mask to 32 bit. Drivers are expected to setup
|
|
||||||
* the correct supported dma_mask.
|
|
||||||
*/
|
|
||||||
dev->coherent_dma_mask = DMA_BIT_MASK(32);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set it to coherent_dma_mask by default if the architecture
|
|
||||||
* code has not set it.
|
|
||||||
*/
|
|
||||||
if (!dev->dma_mask)
|
|
||||||
dev->dma_mask = &dev->coherent_dma_mask;
|
|
||||||
|
|
||||||
ret = of_dma_get_range(dev->of_node, &dma_addr, &paddr, &size);
|
|
||||||
if (ret < 0) {
|
|
||||||
dma_addr = offset = 0;
|
|
||||||
size = dev->coherent_dma_mask;
|
|
||||||
} else {
|
|
||||||
offset = PFN_DOWN(paddr - dma_addr);
|
|
||||||
dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
|
|
||||||
}
|
|
||||||
dev->dma_pfn_offset = offset;
|
|
||||||
|
|
||||||
coherent = of_dma_is_coherent(dev->of_node);
|
|
||||||
dev_dbg(dev, "device is%sdma coherent\n",
|
|
||||||
coherent ? " " : " not ");
|
|
||||||
|
|
||||||
iommu = of_iommu_configure(dev, dev->of_node);
|
|
||||||
dev_dbg(dev, "device is%sbehind an iommu\n",
|
|
||||||
iommu ? " " : " not ");
|
|
||||||
|
|
||||||
arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void of_dma_deconfigure(struct device *dev)
|
static void of_dma_deconfigure(struct device *dev)
|
||||||
{
|
{
|
||||||
arch_teardown_dma_ops(dev);
|
arch_teardown_dma_ops(dev);
|
||||||
@ -236,7 +182,7 @@ static struct platform_device *of_platform_device_create_pdata(
|
|||||||
|
|
||||||
dev->dev.bus = &platform_bus_type;
|
dev->dev.bus = &platform_bus_type;
|
||||||
dev->dev.platform_data = platform_data;
|
dev->dev.platform_data = platform_data;
|
||||||
of_dma_configure(&dev->dev);
|
of_dma_configure(&dev->dev, dev->dev.of_node);
|
||||||
|
|
||||||
if (of_device_add(dev) != 0) {
|
if (of_device_add(dev) != 0) {
|
||||||
of_dma_deconfigure(&dev->dev);
|
of_dma_deconfigure(&dev->dev);
|
||||||
@ -299,7 +245,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
|
|||||||
dev_set_name(&dev->dev, "%s", bus_id);
|
dev_set_name(&dev->dev, "%s", bus_id);
|
||||||
else
|
else
|
||||||
of_device_make_bus_id(&dev->dev);
|
of_device_make_bus_id(&dev->dev);
|
||||||
of_dma_configure(&dev->dev);
|
of_dma_configure(&dev->dev, dev->dev.of_node);
|
||||||
|
|
||||||
/* Allow the HW Peripheral ID to be overridden */
|
/* Allow the HW Peripheral ID to be overridden */
|
||||||
prop = of_get_property(node, "arm,primecell-periphid", NULL);
|
prop = of_get_property(node, "arm,primecell-periphid", NULL);
|
||||||
|
@ -53,6 +53,7 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
|
|||||||
return of_node_get(cpu_dev->of_node);
|
return of_node_get(cpu_dev->of_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void of_dma_configure(struct device *dev, struct device_node *np);
|
||||||
#else /* CONFIG_OF */
|
#else /* CONFIG_OF */
|
||||||
|
|
||||||
static inline int of_driver_match_device(struct device *dev,
|
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)
|
|||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
static inline void of_dma_configure(struct device *dev, struct device_node *np)
|
||||||
|
{}
|
||||||
#endif /* CONFIG_OF */
|
#endif /* CONFIG_OF */
|
||||||
|
|
||||||
#endif /* _LINUX_OF_DEVICE_H */
|
#endif /* _LINUX_OF_DEVICE_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user