1/* 2 * arch/sh/mm/pg-dma.c 3 * 4 * Fast clear_page()/copy_page() implementation using the SH DMAC 5 * 6 * Copyright (C) 2003 Paul Mundt 7 * 8 * This file is subject to the terms and conditions of the GNU General Public 9 * License. See the file "COPYING" in the main directory of this archive 10 * for more details. 11 */ 12#include <linux/init.h> 13#include <linux/kernel.h> 14#include <linux/module.h> 15#include <asm/semaphore.h> 16#include <asm/mmu_context.h> 17#include <asm/addrspace.h> 18#include <asm/atomic.h> 19#include <asm/page.h> 20#include <asm/dma.h> 21#include <asm/io.h> 22 23/* Channel to use for page ops, must be dual-address mode capable. */ 24static int dma_channel = CONFIG_DMA_PAGE_OPS_CHANNEL; 25 26static void copy_page_dma(void *to, void *from) 27{ 28 /* 29 * This doesn't seem to get triggered until further along in the 30 * boot process, at which point the DMAC is already initialized. 31 * Fix this in the same fashion as clear_page_dma() in the event 32 * that this crashes due to the DMAC not being initialized. 33 */ 34 35 flush_icache_range((unsigned long)from, PAGE_SIZE); 36 dma_write_page(dma_channel, (unsigned long)from, (unsigned long)to); 37 dma_wait_for_completion(dma_channel); 38} 39 40static void clear_page_dma(void *to) 41{ 42 /* 43 * We get invoked quite early on, if the DMAC hasn't been initialized 44 * yet, fall back on the slow manual implementation. 45 */ 46 if (dma_info[dma_channel].chan != dma_channel) { 47 clear_page_slow(to); 48 return; 49 } 50 51 dma_write_page(dma_channel, (unsigned long)empty_zero_page, 52 (unsigned long)to); 53 54 flush_icache_range((unsigned long)to, PAGE_SIZE); 55 56 dma_wait_for_completion(dma_channel); 57} 58 59static int __init pg_dma_init(void) 60{ 61 int ret; 62 63 ret = request_dma(dma_channel, "page ops"); 64 if (ret != 0) 65 return ret; 66 67 copy_page = copy_page_dma; 68 clear_page = clear_page_dma; 69 70 return ret; 71} 72 73static void __exit pg_dma_exit(void) 74{ 75 free_dma(dma_channel); 76} 77 78module_init(pg_dma_init); 79module_exit(pg_dma_exit); 80 81MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); 82MODULE_DESCRIPTION("Optimized page copy/clear routines using a dual-address mode capable DMAC channel"); 83MODULE_LICENSE("GPL"); 84