• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/blackfin/mm/
1/*
2 * safe read and write memory routines callable while atomic
3 *
4 * Copyright 2005-2008 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/uaccess.h>
10#include <asm/dma.h>
11
12static int validate_memory_access_address(unsigned long addr, int size)
13{
14	if (size < 0 || addr == 0)
15		return -EFAULT;
16	return bfin_mem_access_type(addr, size);
17}
18
19long probe_kernel_read(void *dst, void *src, size_t size)
20{
21	unsigned long lsrc = (unsigned long)src;
22	int mem_type;
23
24	mem_type = validate_memory_access_address(lsrc, size);
25	if (mem_type < 0)
26		return mem_type;
27
28	if (lsrc >= SYSMMR_BASE) {
29		if (size == 2 && lsrc % 2 == 0) {
30			u16 mmr = bfin_read16(src);
31			memcpy(dst, &mmr, sizeof(mmr));
32			return 0;
33		} else if (size == 4 && lsrc % 4 == 0) {
34			u32 mmr = bfin_read32(src);
35			memcpy(dst, &mmr, sizeof(mmr));
36			return 0;
37		}
38	} else {
39		switch (mem_type) {
40		case BFIN_MEM_ACCESS_CORE:
41		case BFIN_MEM_ACCESS_CORE_ONLY:
42			return __probe_kernel_read(dst, src, size);
43		case BFIN_MEM_ACCESS_DMA:
44			if (dma_memcpy(dst, src, size))
45				return 0;
46			break;
47		case BFIN_MEM_ACCESS_ITEST:
48			if (isram_memcpy(dst, src, size))
49				return 0;
50			break;
51		}
52	}
53
54	return -EFAULT;
55}
56
57long probe_kernel_write(void *dst, void *src, size_t size)
58{
59	unsigned long ldst = (unsigned long)dst;
60	int mem_type;
61
62	mem_type = validate_memory_access_address(ldst, size);
63	if (mem_type < 0)
64		return mem_type;
65
66	if (ldst >= SYSMMR_BASE) {
67		if (size == 2 && ldst % 2 == 0) {
68			u16 mmr;
69			memcpy(&mmr, src, sizeof(mmr));
70			bfin_write16(dst, mmr);
71			return 0;
72		} else if (size == 4 && ldst % 4 == 0) {
73			u32 mmr;
74			memcpy(&mmr, src, sizeof(mmr));
75			bfin_write32(dst, mmr);
76			return 0;
77		}
78	} else {
79		switch (mem_type) {
80		case BFIN_MEM_ACCESS_CORE:
81		case BFIN_MEM_ACCESS_CORE_ONLY:
82			return __probe_kernel_write(dst, src, size);
83		case BFIN_MEM_ACCESS_DMA:
84			if (dma_memcpy(dst, src, size))
85				return 0;
86			break;
87		case BFIN_MEM_ACCESS_ITEST:
88			if (isram_memcpy(dst, src, size))
89				return 0;
90			break;
91		}
92	}
93
94	return -EFAULT;
95}
96