Commit ca41cc96 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-v3.7' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping

Pull CMA and DMA-mapping updates from Marek Szyprowski:
 "This time the pull request is rather small, because the further
  redesign patches were not ready on time.

  This pull request consists of the patches which extend ARM DMA-mapping
  subsystem with support for CPU coherent (ACP) DMA busses.  The first
  client of the new version is HighBank SATA driver.  The second part of
  the pull request includes various cleanup for both CMA common code and
  ARM DMA-mapping subsystem."

Fix up trivial add-add conflict due to the "dma-coherent" DT property
being added next to the "calxeda,port-phys" property for the Calxeda
AHCI controller.

* 'for-v3.7' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping:
  ARM: dma-mapping: Remove unsed var at arm_coherent_iommu_unmap_page
  ARM: highbank: add coherent DMA setup
  ARM: kill off arch_is_coherent
  ARM: add coherent iommu dma ops
  ARM: add coherent dma ops
  ARM: dma-mapping: Refrain noisy console message
  ARM: dma-mapping: Small logical clean up
  drivers: dma-contiguous: refactor dma_alloc_from_contiguous()
parents 3151367f 461b6f0d
...@@ -12,6 +12,7 @@ Optional properties: ...@@ -12,6 +12,7 @@ Optional properties:
- calxeda,port-phys: phandle-combophy and lane assignment, which maps each - calxeda,port-phys: phandle-combophy and lane assignment, which maps each
SATA port to a combophy and a lane within that SATA port to a combophy and a lane within that
combophy combophy
- dma-coherent : Present if dma operations are coherent
Example: Example:
sata@ffe08000 { sata@ffe08000 {
......
...@@ -9,6 +9,9 @@ Required properties: ...@@ -9,6 +9,9 @@ Required properties:
region. region.
- interrupts: interrupt number to the cpu. - interrupts: interrupt number to the cpu.
Optional properties:
- dma-coherent : Present if dma operations are coherent
Example: Example:
pdma0: pdma@12680000 { pdma0: pdma@12680000 {
......
...@@ -6,6 +6,9 @@ Required properties: ...@@ -6,6 +6,9 @@ Required properties:
- interrupts : Should contain 3 xgmac interrupts. The 1st is main interrupt. - interrupts : Should contain 3 xgmac interrupts. The 1st is main interrupt.
The 2nd is pwr mgt interrupt. The 3rd is low power state interrupt. The 2nd is pwr mgt interrupt. The 3rd is low power state interrupt.
Optional properties:
- dma-coherent : Present if dma operations are coherent
Example: Example:
ethernet@fff50000 { ethernet@fff50000 {
......
...@@ -124,6 +124,7 @@ sata@ffe08000 { ...@@ -124,6 +124,7 @@ sata@ffe08000 {
calxeda,port-phys = <&combophy5 0 &combophy0 0 calxeda,port-phys = <&combophy5 0 &combophy0 0
&combophy0 1 &combophy0 2 &combophy0 1 &combophy0 2
&combophy0 3>; &combophy0 3>;
dma-coherent;
}; };
sdhci@ffe0e000 { sdhci@ffe0e000 {
......
...@@ -44,10 +44,9 @@ ...@@ -44,10 +44,9 @@
#define rmb() dsb() #define rmb() dsb()
#define wmb() mb() #define wmb() mb()
#else #else
#include <asm/memory.h> #define mb() barrier()
#define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) #define rmb() barrier()
#define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) #define wmb() barrier()
#define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
#endif #endif
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#define DMA_ERROR_CODE (~0) #define DMA_ERROR_CODE (~0)
extern struct dma_map_ops arm_dma_ops; extern struct dma_map_ops arm_dma_ops;
extern struct dma_map_ops arm_coherent_dma_ops;
static inline struct dma_map_ops *get_dma_ops(struct device *dev) static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{ {
......
...@@ -275,14 +275,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x) ...@@ -275,14 +275,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) #define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)
/*
* Optional coherency support. Currently used only by selected
* Intel XSC3-based systems.
*/
#ifndef arch_is_coherent
#define arch_is_coherent() 0
#endif
#endif #endif
#include <asm-generic/memory_model.h> #include <asm-generic/memory_model.h>
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clkdev.h> #include <linux/clkdev.h>
#include <linux/dma-mapping.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
...@@ -23,6 +24,7 @@ ...@@ -23,6 +24,7 @@
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/amba/bus.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
...@@ -149,11 +151,61 @@ static void highbank_power_off(void) ...@@ -149,11 +151,61 @@ static void highbank_power_off(void)
cpu_do_idle(); cpu_do_idle();
} }
static int highbank_platform_notifier(struct notifier_block *nb,
unsigned long event, void *__dev)
{
struct resource *res;
int reg = -1;
struct device *dev = __dev;
if (event != BUS_NOTIFY_ADD_DEVICE)
return NOTIFY_DONE;
if (of_device_is_compatible(dev->of_node, "calxeda,hb-ahci"))
reg = 0xc;
else if (of_device_is_compatible(dev->of_node, "calxeda,hb-sdhci"))
reg = 0x18;
else if (of_device_is_compatible(dev->of_node, "arm,pl330"))
reg = 0x20;
else if (of_device_is_compatible(dev->of_node, "calxeda,hb-xgmac")) {
res = platform_get_resource(to_platform_device(dev),
IORESOURCE_MEM, 0);
if (res) {
if (res->start == 0xfff50000)
reg = 0;
else if (res->start == 0xfff51000)
reg = 4;
}
}
if (reg < 0)
return NOTIFY_DONE;
if (of_property_read_bool(dev->of_node, "dma-coherent")) {
writel(0xff31, sregs_base + reg);
set_dma_ops(dev, &arm_coherent_dma_ops);
} else
writel(0, sregs_base + reg);
return NOTIFY_OK;
}
static struct notifier_block highbank_amba_nb = {
.notifier_call = highbank_platform_notifier,
};
static struct notifier_block highbank_platform_nb = {
.notifier_call = highbank_platform_notifier,
};
static void __init highbank_init(void) static void __init highbank_init(void)
{ {
pm_power_off = highbank_power_off; pm_power_off = highbank_power_off;
highbank_pm_init(); highbank_pm_init();
bus_register_notifier(&platform_bus_type, &highbank_platform_nb);
bus_register_notifier(&amba_bustype, &highbank_amba_nb);
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
} }
......
This diff is collapsed.
...@@ -422,17 +422,6 @@ static void __init build_mem_type_table(void) ...@@ -422,17 +422,6 @@ static void __init build_mem_type_table(void)
cp = &cache_policies[cachepolicy]; cp = &cache_policies[cachepolicy];
vecs_pgprot = kern_pgprot = user_pgprot = cp->pte; vecs_pgprot = kern_pgprot = user_pgprot = cp->pte;
/*
* Enable CPU-specific coherency if supported.
* (Only available on XSC3 at the moment.)
*/
if (arch_is_coherent() && cpu_is_xsc3()) {
mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED;
mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
}
/* /*
* ARMv6 and above have extended page tables. * ARMv6 and above have extended page tables.
*/ */
......
...@@ -315,6 +315,7 @@ struct page *dma_alloc_from_contiguous(struct device *dev, int count, ...@@ -315,6 +315,7 @@ struct page *dma_alloc_from_contiguous(struct device *dev, int count,
{ {
unsigned long mask, pfn, pageno, start = 0; unsigned long mask, pfn, pageno, start = 0;
struct cma *cma = dev_get_cma_area(dev); struct cma *cma = dev_get_cma_area(dev);
struct page *page = NULL;
int ret; int ret;
if (!cma || !cma->count) if (!cma || !cma->count)
...@@ -336,18 +337,17 @@ struct page *dma_alloc_from_contiguous(struct device *dev, int count, ...@@ -336,18 +337,17 @@ struct page *dma_alloc_from_contiguous(struct device *dev, int count,
for (;;) { for (;;) {
pageno = bitmap_find_next_zero_area(cma->bitmap, cma->count, pageno = bitmap_find_next_zero_area(cma->bitmap, cma->count,
start, count, mask); start, count, mask);
if (pageno >= cma->count) { if (pageno >= cma->count)
ret = -ENOMEM; break;
goto error;
}
pfn = cma->base_pfn + pageno; pfn = cma->base_pfn + pageno;
ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA); ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
if (ret == 0) { if (ret == 0) {
bitmap_set(cma->bitmap, pageno, count); bitmap_set(cma->bitmap, pageno, count);
page = pfn_to_page(pfn);
break; break;
} else if (ret != -EBUSY) { } else if (ret != -EBUSY) {
goto error; break;
} }
pr_debug("%s(): memory range at %p is busy, retrying\n", pr_debug("%s(): memory range at %p is busy, retrying\n",
__func__, pfn_to_page(pfn)); __func__, pfn_to_page(pfn));
...@@ -356,12 +356,8 @@ struct page *dma_alloc_from_contiguous(struct device *dev, int count, ...@@ -356,12 +356,8 @@ struct page *dma_alloc_from_contiguous(struct device *dev, int count,
} }
mutex_unlock(&cma_mutex); mutex_unlock(&cma_mutex);
pr_debug("%s(): returned %p\n", __func__, page);
pr_debug("%s(): returned %p\n", __func__, pfn_to_page(pfn)); return page;
return pfn_to_page(pfn);
error:
mutex_unlock(&cma_mutex);
return NULL;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment