parisc: merge pcx_dma_ops and pcxl_dma_ops
The only difference is that pcxl supports dma coherent allocations, while pcx only supports non-consistent allocations and otherwise fails. But dma_alloc* is not in the fast path, and merging these two allows an easy migration path to the generic dma-noncoherent implementation, so do it. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Helge Deller <deller@gmx.de>
This commit is contained in:
committed by
Helge Deller
parent
94710cac0e
commit
a34a9b9682
@@ -22,8 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_PA11
|
#ifdef CONFIG_PA11
|
||||||
extern const struct dma_map_ops pcxl_dma_ops;
|
extern const struct dma_map_ops pa11_dma_ops;
|
||||||
extern const struct dma_map_ops pcx_dma_ops;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern const struct dma_map_ops *hppa_dma_ops;
|
extern const struct dma_map_ops *hppa_dma_ops;
|
||||||
|
|||||||
@@ -395,7 +395,7 @@ pcxl_dma_init(void)
|
|||||||
|
|
||||||
__initcall(pcxl_dma_init);
|
__initcall(pcxl_dma_init);
|
||||||
|
|
||||||
static void *pa11_dma_alloc(struct device *dev, size_t size,
|
static void *pcxl_dma_alloc(struct device *dev, size_t size,
|
||||||
dma_addr_t *dma_handle, gfp_t flag, unsigned long attrs)
|
dma_addr_t *dma_handle, gfp_t flag, unsigned long attrs)
|
||||||
{
|
{
|
||||||
unsigned long vaddr;
|
unsigned long vaddr;
|
||||||
@@ -422,16 +422,44 @@ static void *pa11_dma_alloc(struct device *dev, size_t size,
|
|||||||
return (void *)vaddr;
|
return (void *)vaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *pcx_dma_alloc(struct device *dev, size_t size,
|
||||||
|
dma_addr_t *dma_handle, gfp_t flag, unsigned long attrs)
|
||||||
|
{
|
||||||
|
void *addr;
|
||||||
|
|
||||||
|
if ((attrs & DMA_ATTR_NON_CONSISTENT) == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
addr = (void *)__get_free_pages(flag, get_order(size));
|
||||||
|
if (addr)
|
||||||
|
*dma_handle = (dma_addr_t)virt_to_phys(addr);
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *pa11_dma_alloc(struct device *dev, size_t size,
|
||||||
|
dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (boot_cpu_data.cpu_type == pcxl2 || boot_cpu_data.cpu_type == pcxl)
|
||||||
|
return pcxl_dma_alloc(dev, size, dma_handle, gfp, attrs);
|
||||||
|
else
|
||||||
|
return pcx_dma_alloc(dev, size, dma_handle, gfp, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
static void pa11_dma_free(struct device *dev, size_t size, void *vaddr,
|
static void pa11_dma_free(struct device *dev, size_t size, void *vaddr,
|
||||||
dma_addr_t dma_handle, unsigned long attrs)
|
dma_addr_t dma_handle, unsigned long attrs)
|
||||||
{
|
{
|
||||||
int order;
|
int order = get_order(size);
|
||||||
|
|
||||||
order = get_order(size);
|
if (boot_cpu_data.cpu_type == pcxl2 || boot_cpu_data.cpu_type == pcxl) {
|
||||||
size = 1 << (order + PAGE_SHIFT);
|
size = 1 << (order + PAGE_SHIFT);
|
||||||
unmap_uncached_pages((unsigned long)vaddr, size);
|
unmap_uncached_pages((unsigned long)vaddr, size);
|
||||||
pcxl_free_range((unsigned long)vaddr, size);
|
pcxl_free_range((unsigned long)vaddr, size);
|
||||||
free_pages((unsigned long)__va(dma_handle), order);
|
|
||||||
|
vaddr = __va(dma_handle);
|
||||||
|
}
|
||||||
|
free_pages((unsigned long)vaddr, get_order(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
static dma_addr_t pa11_dma_map_page(struct device *dev, struct page *page,
|
static dma_addr_t pa11_dma_map_page(struct device *dev, struct page *page,
|
||||||
@@ -560,7 +588,7 @@ static void pa11_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
|||||||
flush_kernel_dcache_range((unsigned long)vaddr, size);
|
flush_kernel_dcache_range((unsigned long)vaddr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct dma_map_ops pcxl_dma_ops = {
|
const struct dma_map_ops pa11_dma_ops = {
|
||||||
.alloc = pa11_dma_alloc,
|
.alloc = pa11_dma_alloc,
|
||||||
.free = pa11_dma_free,
|
.free = pa11_dma_free,
|
||||||
.map_page = pa11_dma_map_page,
|
.map_page = pa11_dma_map_page,
|
||||||
@@ -573,39 +601,3 @@ const struct dma_map_ops pcxl_dma_ops = {
|
|||||||
.sync_sg_for_device = pa11_dma_sync_sg_for_device,
|
.sync_sg_for_device = pa11_dma_sync_sg_for_device,
|
||||||
.cache_sync = pa11_dma_cache_sync,
|
.cache_sync = pa11_dma_cache_sync,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void *pcx_dma_alloc(struct device *dev, size_t size,
|
|
||||||
dma_addr_t *dma_handle, gfp_t flag, unsigned long attrs)
|
|
||||||
{
|
|
||||||
void *addr;
|
|
||||||
|
|
||||||
if ((attrs & DMA_ATTR_NON_CONSISTENT) == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
addr = (void *)__get_free_pages(flag, get_order(size));
|
|
||||||
if (addr)
|
|
||||||
*dma_handle = (dma_addr_t)virt_to_phys(addr);
|
|
||||||
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pcx_dma_free(struct device *dev, size_t size, void *vaddr,
|
|
||||||
dma_addr_t iova, unsigned long attrs)
|
|
||||||
{
|
|
||||||
free_pages((unsigned long)vaddr, get_order(size));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct dma_map_ops pcx_dma_ops = {
|
|
||||||
.alloc = pcx_dma_alloc,
|
|
||||||
.free = pcx_dma_free,
|
|
||||||
.map_page = pa11_dma_map_page,
|
|
||||||
.unmap_page = pa11_dma_unmap_page,
|
|
||||||
.map_sg = pa11_dma_map_sg,
|
|
||||||
.unmap_sg = pa11_dma_unmap_sg,
|
|
||||||
.sync_single_for_cpu = pa11_dma_sync_single_for_cpu,
|
|
||||||
.sync_single_for_device = pa11_dma_sync_single_for_device,
|
|
||||||
.sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
|
|
||||||
.sync_sg_for_device = pa11_dma_sync_sg_for_device,
|
|
||||||
.cache_sync = pa11_dma_cache_sync,
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -97,14 +97,12 @@ void __init dma_ops_init(void)
|
|||||||
panic( "PA-RISC Linux currently only supports machines that conform to\n"
|
panic( "PA-RISC Linux currently only supports machines that conform to\n"
|
||||||
"the PA-RISC 1.1 or 2.0 architecture specification.\n");
|
"the PA-RISC 1.1 or 2.0 architecture specification.\n");
|
||||||
|
|
||||||
case pcxs:
|
|
||||||
case pcxt:
|
|
||||||
hppa_dma_ops = &pcx_dma_ops;
|
|
||||||
break;
|
|
||||||
case pcxl2:
|
case pcxl2:
|
||||||
pa7300lc_init();
|
pa7300lc_init();
|
||||||
case pcxl: /* falls through */
|
case pcxl: /* falls through */
|
||||||
hppa_dma_ops = &pcxl_dma_ops;
|
case pcxs:
|
||||||
|
case pcxt:
|
||||||
|
hppa_dma_ops = &pa11_dma_ops;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
#include <linux/gfp.h>
|
#include <linux/gfp.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/pci.h> /* for hppa_dma_ops and pcxl_dma_ops */
|
|
||||||
#include <linux/initrd.h>
|
#include <linux/initrd.h>
|
||||||
#include <linux/swap.h>
|
#include <linux/swap.h>
|
||||||
#include <linux/unistd.h>
|
#include <linux/unistd.h>
|
||||||
@@ -616,17 +615,13 @@ void __init mem_init(void)
|
|||||||
free_all_bootmem();
|
free_all_bootmem();
|
||||||
|
|
||||||
#ifdef CONFIG_PA11
|
#ifdef CONFIG_PA11
|
||||||
if (hppa_dma_ops == &pcxl_dma_ops) {
|
if (boot_cpu_data.cpu_type == pcxl2 || boot_cpu_data.cpu_type == pcxl) {
|
||||||
pcxl_dma_start = (unsigned long)SET_MAP_OFFSET(MAP_START);
|
pcxl_dma_start = (unsigned long)SET_MAP_OFFSET(MAP_START);
|
||||||
parisc_vmalloc_start = SET_MAP_OFFSET(pcxl_dma_start
|
parisc_vmalloc_start = SET_MAP_OFFSET(pcxl_dma_start
|
||||||
+ PCXL_DMA_MAP_SIZE);
|
+ PCXL_DMA_MAP_SIZE);
|
||||||
} else {
|
} else
|
||||||
pcxl_dma_start = 0;
|
|
||||||
parisc_vmalloc_start = SET_MAP_OFFSET(MAP_START);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
parisc_vmalloc_start = SET_MAP_OFFSET(MAP_START);
|
|
||||||
#endif
|
#endif
|
||||||
|
parisc_vmalloc_start = SET_MAP_OFFSET(MAP_START);
|
||||||
|
|
||||||
mem_init_print_info(NULL);
|
mem_init_print_info(NULL);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user