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
, const 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 /* XXX: should support IDMA here with SMP */
44 case BFIN_MEM_ACCESS_DMA
:
45 if (dma_memcpy(dst
, src
, size
))
48 case BFIN_MEM_ACCESS_ITEST
:
49 if (isram_memcpy(dst
, src
, size
))
58 long probe_kernel_write(void *dst
, const void *src
, size_t size
)
60 unsigned long ldst
= (unsigned long)dst
;
63 mem_type
= validate_memory_access_address(ldst
, size
);
67 if (ldst
>= SYSMMR_BASE
) {
68 if (size
== 2 && ldst
% 2 == 0) {
70 memcpy(&mmr
, src
, sizeof(mmr
));
71 bfin_write16(dst
, mmr
);
73 } else if (size
== 4 && ldst
% 4 == 0) {
75 memcpy(&mmr
, src
, sizeof(mmr
));
76 bfin_write32(dst
, mmr
);
81 case BFIN_MEM_ACCESS_CORE
:
82 case BFIN_MEM_ACCESS_CORE_ONLY
:
83 return __probe_kernel_write(dst
, src
, size
);
84 /* XXX: should support IDMA here with SMP */
85 case BFIN_MEM_ACCESS_DMA
:
86 if (dma_memcpy(dst
, src
, size
))
89 case BFIN_MEM_ACCESS_ITEST
:
90 if (isram_memcpy(dst
, src
, size
))