2 * safe read and write memory routines callable while atomic
4 * Copyright 2005-2008 Analog Devices Inc.
6 * Licensed under the GPL-2 or later.
9 #include <linux/uaccess.h>
12 static int validate_memory_access_address(unsigned long addr
, int size
)
14 if (size
< 0 || addr
== 0)
16 return bfin_mem_access_type(addr
, size
);
19 long probe_kernel_read(void *dst
, void *src
, size_t size
)
21 unsigned long lsrc
= (unsigned long)src
;
24 mem_type
= validate_memory_access_address(lsrc
, size
);
28 if (lsrc
>= SYSMMR_BASE
) {
29 if (size
== 2 && lsrc
% 2 == 0) {
30 u16 mmr
= bfin_read16(src
);
31 memcpy(dst
, &mmr
, sizeof(mmr
));
33 } else if (size
== 4 && lsrc
% 4 == 0) {
34 u32 mmr
= bfin_read32(src
);
35 memcpy(dst
, &mmr
, sizeof(mmr
));
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
))
47 case BFIN_MEM_ACCESS_ITEST
:
48 if (isram_memcpy(dst
, src
, size
))
57 long probe_kernel_write(void *dst
, void *src
, size_t size
)
59 unsigned long ldst
= (unsigned long)dst
;
62 mem_type
= validate_memory_access_address(ldst
, size
);
66 if (ldst
>= SYSMMR_BASE
) {
67 if (size
== 2 && ldst
% 2 == 0) {
69 memcpy(&mmr
, src
, sizeof(mmr
));
70 bfin_write16(dst
, mmr
);
72 } else if (size
== 4 && ldst
% 4 == 0) {
74 memcpy(&mmr
, src
, sizeof(mmr
));
75 bfin_write32(dst
, mmr
);
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
))
87 case BFIN_MEM_ACCESS_ITEST
:
88 if (isram_memcpy(dst
, src
, size
))