ARM: rockchip: rk3228: add grf definition
[firefly-linux-kernel-4.4.55.git] / include / asm-generic / fncpy.h
1 /*
2  * include/asm-generic/fncpy.h - helper macros for function body copying
3  *
4  * Copyright (C) 2011 Linaro Limited
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19
20 /*
21  * These macros are intended for use when there is a need to copy a low-level
22  * function body into special memory.
23  *
24  * For example, when reconfiguring the SDRAM controller, the code doing the
25  * reconfiguration may need to run from SRAM.
26  *
27  * NOTE: that the copied function body must be entirely self-contained and
28  * position-independent in order for this to work properly.
29  *
30  * Typical usage example:
31  *
32  * extern int f(args);
33  * extern uint32_t size_of_f;
34  * int (*copied_f)(args);
35  * void *sram_buffer;
36  *
37  * copied_f = fncpy(sram_buffer, &f, size_of_f);
38  *
39  * ... later, call the function: ...
40  *
41  * copied_f(args);
42  *
43  * The size of the function to be copied can't be determined from C:
44  * this must be determined by other means, such as adding assmbler directives
45  * in the file where f is defined.
46  */
47
48 #ifndef __ASM_GENERIC_FNCPY_H
49 #define __ASM_GENERIC_FNCPY_H
50
51 #include <linux/types.h>
52 #include <linux/string.h>
53
54 #include <asm/bug.h>
55 #include <asm/cacheflush.h>
56
57 /*
58  * Minimum alignment requirement for the source and destination addresses
59  * for function copying.
60  */
61 #ifndef ARCH_FNCPY_ALIGN
62 #define ARCH_FNCPY_ALIGN        0
63 #endif
64
65 #define ARCH_FNCPY_MASK         ((1 << (ARCH_FNCPY_ALIGN)) - 1)
66
67 #ifndef fnptr_to_addr
68 #define fnptr_to_addr(funcp) ({                                         \
69         (uintptr_t) (funcp);                                            \
70 })
71 #endif
72
73 #ifndef fnptr_translate
74 #define fnptr_translate(orig_funcp, new_addr) ({                        \
75         (typeof(orig_funcp)) (new_addr);                                \
76 })
77 #endif
78
79 /* Ensure alignment of source and destination addresses */
80 #ifndef fn_dest_invalid
81 #define fn_dest_invalid(funcp, dest_buf) ({                             \
82         uintptr_t __funcp_address;                                      \
83                                                                         \
84         __funcp_address = fnptr_to_addr(funcp);                         \
85                                                                         \
86         ((uintptr_t)(dest_buf) & ARCH_FNCPY_MASK) ||                    \
87                 (__funcp_address & ARCH_FNCPY_MASK);                    \
88 })
89 #endif
90
91 #ifndef fncpy
92 #define fncpy(dest_buf, funcp, size) ({                                 \
93         BUG_ON(fn_dest_invalid(funcp, dest_buf));                       \
94                                                                         \
95         memcpy(dest_buf, (void const *)(funcp), size);                  \
96         flush_icache_range((unsigned long)(dest_buf),                   \
97                 (unsigned long)(dest_buf) + (size));                    \
98                                                                         \
99         fnptr_translate(funcp, dest_buf);                               \
100 })
101 #endif
102
103 #endif /* !__ASM_GENERIC_FNCPY_H */
104