diff options
author | Richard Zhu <r65037@freescale.com> | 2014-04-15 02:23:42 -0400 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2014-04-16 09:58:21 -0400 |
commit | d9bc7e358e1494e29da5acc4c33c1144cdbd31f2 (patch) | |
tree | 1d665ea6cc1f5d992c769078fff5422be2227ba8 | |
parent | 81b4f7898ff6f212d016f0ad8877a15160c7f0e1 (diff) |
ENGR00308060-2 mcc: implementation mcc on imx6sx
- inherited mcc ver 001.002 from vibryd mqx release.
- use mu general int4 as the cpu2cpu int (num is 122 at a9 side).
- add linux wait_event/wake_up mechanism on the buffer management
of share memory
- replace wait_event_interruptible### by wait_event###, so the sleep
task wouldn't be waken up by reboot or CTRL+C signals.
- use the offset address to do the MQX_TO_VIRT and VIRT_TO_MQX
exchanges.
- regmap_bits_updat can't write 1 to clear the bit-set asr, use
regmap_read/write
- fix mu irq clear hang issue
only do the regmap once in the isr register func, and
replace the multi-regmap operations in the kinds of mx6sx mcc related
apis by one global imx_mu_reg.
Signed-off-by: Richard Zhu <r65037@freescale.com>
-rw-r--r-- | arch/arm/mach-imx/Kconfig | 5 | ||||
-rw-r--r-- | arch/arm/mach-imx/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-imx/mcc_imx6sx.c | 148 | ||||
-rw-r--r-- | arch/arm/mach-imx/mcc_linux.c | 281 | ||||
-rw-r--r-- | include/linux/mcc_imx6sx.h | 43 | ||||
-rw-r--r-- | include/linux/mcc_linux.h | 53 |
6 files changed, 531 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 7875adb8c7f4..65d5476679c6 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig | |||
@@ -81,6 +81,10 @@ config HAVE_IMX_MMDC | |||
81 | config HAVE_IMX_SRC | 81 | config HAVE_IMX_SRC |
82 | def_bool y if SMP | 82 | def_bool y if SMP |
83 | 83 | ||
84 | config HAVE_IMX_MCC | ||
85 | select IMX_SEMA4 | ||
86 | bool | ||
87 | |||
84 | config IMX_HAVE_IOMUX_V1 | 88 | config IMX_HAVE_IOMUX_V1 |
85 | bool | 89 | bool |
86 | 90 | ||
@@ -860,6 +864,7 @@ config SOC_IMX6SX | |||
860 | select HAVE_IMX_SRC | 864 | select HAVE_IMX_SRC |
861 | select MIGHT_HAVE_PCI | 865 | select MIGHT_HAVE_PCI |
862 | select PCI_DOMAINS if PCI | 866 | select PCI_DOMAINS if PCI |
867 | select HAVE_IMX_MCC | ||
863 | select PINCTRL | 868 | select PINCTRL |
864 | select PINCTRL_IMX6SX | 869 | select PINCTRL_IMX6SX |
865 | select PL310_ERRATA_588369 if CACHE_PL310 | 870 | select PL310_ERRATA_588369 if CACHE_PL310 |
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index d56ea8b34182..ed67b70a7a24 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile | |||
@@ -96,6 +96,7 @@ obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o | |||
96 | obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o | 96 | obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o |
97 | obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o | 97 | obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o |
98 | obj-$(CONFIG_HAVE_IMX_SRC) += src.o | 98 | obj-$(CONFIG_HAVE_IMX_SRC) += src.o |
99 | obj-$(CONFIG_HAVE_IMX_MCC) += mcc_api.o mcc_common.o mcc_linux.o mcc_imx6sx.o | ||
99 | AFLAGS_headsmp.o :=-Wa,-march=armv7-a | 100 | AFLAGS_headsmp.o :=-Wa,-march=armv7-a |
100 | obj-$(CONFIG_SMP) += headsmp.o platsmp.o | 101 | obj-$(CONFIG_SMP) += headsmp.o platsmp.o |
101 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 102 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
diff --git a/arch/arm/mach-imx/mcc_imx6sx.c b/arch/arm/mach-imx/mcc_imx6sx.c new file mode 100644 index 000000000000..4e22ffc6f6f4 --- /dev/null +++ b/arch/arm/mach-imx/mcc_imx6sx.c | |||
@@ -0,0 +1,148 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Freescale Semiconductor, Inc. | ||
3 | * Freescale IMX Linux-specific MCC implementation. | ||
4 | * iMX6sx-specific MCC library functions. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #include <linux/delay.h> | ||
20 | #include <linux/err.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/regmap.h> | ||
23 | #include <linux/mcc_imx6sx.h> | ||
24 | #include <linux/mcc_linux.h> | ||
25 | |||
26 | /*! | ||
27 | * \brief This function returns the core number | ||
28 | * | ||
29 | * \return int | ||
30 | */ | ||
31 | unsigned int _psp_core_num(void) | ||
32 | { | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * This field contains CPU-to-CPU interrupt vector numbers | ||
38 | * for all device cores. | ||
39 | */ | ||
40 | static const unsigned int mcc_cpu_to_cpu_vectors[] = {INT_CPU_TO_CPU_MU_A2M, | ||
41 | INT_CPU_TO_CPU_MU_M2A}; | ||
42 | |||
43 | /*! | ||
44 | * \brief This function gets the CPU-to-CPU vector num for the particular core. | ||
45 | * | ||
46 | * Platform-specific inter-CPU vector numbers for each core are defined in the | ||
47 | * mcc_cpu_to_cpu_vectors[] field. | ||
48 | * | ||
49 | * \param[in] core Core number. | ||
50 | * | ||
51 | * \return vector number for the particular core | ||
52 | * \return MCC_VECTOR_NUMBER_INVALID (vector number for the particular core | ||
53 | * number not found) | ||
54 | */ | ||
55 | unsigned int mcc_get_cpu_to_cpu_vector(unsigned int core) | ||
56 | { | ||
57 | u32 val; | ||
58 | |||
59 | val = sizeof(mcc_cpu_to_cpu_vectors)/sizeof(mcc_cpu_to_cpu_vectors[0]); | ||
60 | if (core < val) | ||
61 | return mcc_cpu_to_cpu_vectors[core]; | ||
62 | |||
63 | return MCC_VECTOR_NUMBER_INVALID; | ||
64 | } | ||
65 | |||
66 | /*! | ||
67 | * \brief This function clears the CPU-to-CPU int flag for the particular core. | ||
68 | * | ||
69 | * Implementation is platform-specific. | ||
70 | * | ||
71 | * \param[in] core Core number. | ||
72 | */ | ||
73 | void mcc_clear_cpu_to_cpu_interrupt(unsigned int core) | ||
74 | { | ||
75 | u32 val; | ||
76 | |||
77 | regmap_read(imx_mu_reg, MU_ASR, &val); | ||
78 | /* write 1 to BIT31 to clear the bit31(GIP3) of MU_ASR */ | ||
79 | val = val | (1 << 31); | ||
80 | regmap_write(imx_mu_reg, MU_ASR, val); | ||
81 | } | ||
82 | |||
83 | /*! | ||
84 | * \brief This function triggers the CPU-to-CPU interrupt. | ||
85 | * | ||
86 | * Platform-specific software triggering the inter-CPU interrupts. | ||
87 | */ | ||
88 | void mcc_triger_cpu_to_cpu_interrupt(void) | ||
89 | { | ||
90 | int i = 0; | ||
91 | u32 val; | ||
92 | |||
93 | regmap_read(imx_mu_reg, MU_ACR, &val); | ||
94 | |||
95 | if ((val & BIT(19)) != 0) { | ||
96 | do { | ||
97 | regmap_read(imx_mu_reg, MU_ACR, &val); | ||
98 | msleep(1); | ||
99 | } while (((val & BIT(19)) > 0) && (i++ < 100)); | ||
100 | } | ||
101 | |||
102 | if ((val & BIT(19)) == 0) | ||
103 | /* Enable the bit19(GIR3) of MU_ACR */ | ||
104 | regmap_update_bits(imx_mu_reg, MU_ACR, BIT(19), BIT(19)); | ||
105 | else | ||
106 | pr_info("mcc int still be triggered after %d ms polling!\n", i); | ||
107 | } | ||
108 | |||
109 | /*! | ||
110 | * \brief This function disable the CPU-to-CPU interrupt. | ||
111 | * | ||
112 | * Platform-specific software disable the inter-CPU interrupts. | ||
113 | */ | ||
114 | int imx_mcc_bsp_int_disable(unsigned int vector_number) | ||
115 | { | ||
116 | u32 val; | ||
117 | |||
118 | if (vector_number == INT_CPU_TO_CPU_MU_A2M) { | ||
119 | /* Disable the bit31(GIE3) of MU_ACR */ | ||
120 | regmap_update_bits(imx_mu_reg, MU_ACR, BIT(31), 0); | ||
121 | /* flush */ | ||
122 | regmap_read(imx_mu_reg, MU_ACR, &val); | ||
123 | } else | ||
124 | pr_err("ERR:wrong vector number in mcc.\n"); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | /*! | ||
130 | * \brief This function enable the CPU-to-CPU interrupt. | ||
131 | * | ||
132 | * Platform-specific software enable the inter-CPU interrupts. | ||
133 | */ | ||
134 | int imx_mcc_bsp_int_enable(unsigned int vector_number) | ||
135 | { | ||
136 | u32 val; | ||
137 | |||
138 | if (vector_number == INT_CPU_TO_CPU_MU_A2M) { | ||
139 | /* Enable the bit31(GIE3) of MU_ACR */ | ||
140 | regmap_update_bits(imx_mu_reg, MU_ACR, BIT(31), BIT(31)); | ||
141 | /* flush */ | ||
142 | regmap_read(imx_mu_reg, MU_ACR, &val); | ||
143 | return 0; | ||
144 | } else { | ||
145 | pr_err("ERR:wrong vector number in mcc.\n"); | ||
146 | return -EINVAL; | ||
147 | } | ||
148 | } | ||
diff --git a/arch/arm/mach-imx/mcc_linux.c b/arch/arm/mach-imx/mcc_linux.c new file mode 100644 index 000000000000..551cc12ed4a5 --- /dev/null +++ b/arch/arm/mach-imx/mcc_linux.c | |||
@@ -0,0 +1,281 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Freescale Semiconductor, Inc. | ||
3 | * Freescale IMX Linux-specific MCC implementation. | ||
4 | * Linux-specific MCC library functions | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #include <linux/delay.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/mfd/syscon.h> | ||
22 | #include <linux/regmap.h> | ||
23 | #include <linux/sched.h> | ||
24 | #include <linux/wait.h> | ||
25 | #include <linux/imx_sema4.h> | ||
26 | #include "mcc_config.h" | ||
27 | #include <linux/mcc_common.h> | ||
28 | #include <linux/mcc_api.h> | ||
29 | #include <linux/mcc_imx6sx.h> | ||
30 | #include <linux/mcc_linux.h> | ||
31 | |||
32 | /* Global variables */ | ||
33 | struct regmap *imx_mu_reg; | ||
34 | unsigned long mcc_shm_offset; | ||
35 | static struct imx_sema4_mutex *shm_ptr; | ||
36 | static unsigned int cpu_to_cpu_isr_vector = MCC_VECTOR_NUMBER_INVALID; | ||
37 | |||
38 | unsigned int imx_mcc_buffer_freed = 0, imx_mcc_buffer_queued = 0; | ||
39 | DECLARE_WAIT_QUEUE_HEAD(buffer_freed_wait_queue); /* Used for blocking send */ | ||
40 | DECLARE_WAIT_QUEUE_HEAD(buffer_queued_wait_queue); /* Used for blocking recv */ | ||
41 | |||
42 | /*! | ||
43 | * \brief This function is the CPU-to-CPU interrupt handler. | ||
44 | * | ||
45 | * Each core can interrupt the other. There are two logical signals: | ||
46 | * \n - Receive data available for (Node,Port) - signaled when a buffer | ||
47 | * is queued to a Receive Data Queue. | ||
48 | * \n - Buffer available - signaled when a buffer is queued to the Free | ||
49 | * Buffer Queue. | ||
50 | * \n It is possible that several signals can occur while one interrupt | ||
51 | * is being processed. | ||
52 | * Therefore, a Receive Signal Queue of received signals is also required | ||
53 | * - one for each core. | ||
54 | * The interrupting core queues to the tail and the interrupted core pulls | ||
55 | * from the head. | ||
56 | * For a circular file, no semaphore is required since only the sender | ||
57 | * modifies the tail and only the receiver modifies the head. | ||
58 | * | ||
59 | * \param[in] param Pointer to data being passed to the ISR. | ||
60 | */ | ||
61 | static irqreturn_t mcc_cpu_to_cpu_isr(int irq, void *param) | ||
62 | { | ||
63 | MCC_SIGNAL serviced_signal; | ||
64 | |||
65 | /* | ||
66 | * Try to lock the core mutex. If successfully locked, perform | ||
67 | * mcc_dequeue_signal(), release the gate and finally clear the | ||
68 | * interrupt flag. If trylock fails (HW semaphore already locked | ||
69 | * by another core), do not clear the interrupt flag – this | ||
70 | * way the CPU-to-CPU isr is re-issued again until the HW semaphore | ||
71 | * is locked. Higher priority ISRs will be serviced while issued at | ||
72 | * the time we are waiting for the unlocked gate. To prevent trylog | ||
73 | * failure due to core mutex currently locked by our own core(a task), | ||
74 | * the cpu-to-cpu isr is temporarily disabled when mcc_get_semaphore() | ||
75 | * is called and re-enabled again when mcc_release_semaphore() | ||
76 | * is issued. | ||
77 | */ | ||
78 | if (SEMA4_A9_LOCK == imx_sema4_mutex_trylock(shm_ptr)) { | ||
79 | while (MCC_SUCCESS == mcc_dequeue_signal(MCC_CORE_NUMBER, | ||
80 | &serviced_signal)) { | ||
81 | if ((serviced_signal.type == BUFFER_QUEUED) && | ||
82 | (serviced_signal.destination.core == MCC_CORE_NUMBER)) { | ||
83 | /* | ||
84 | * Unblock receiver, in case of asynchronous | ||
85 | * communication | ||
86 | */ | ||
87 | imx_mcc_buffer_queued = 1; | ||
88 | wake_up(&buffer_queued_wait_queue); | ||
89 | } else if (serviced_signal.type == BUFFER_FREED) { | ||
90 | /* Unblock sender, in case of asynchronous | ||
91 | * communication | ||
92 | */ | ||
93 | imx_mcc_buffer_freed = 1; | ||
94 | wake_up(&buffer_freed_wait_queue); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | /* Clear the interrupt flag */ | ||
99 | mcc_clear_cpu_to_cpu_interrupt(MCC_CORE_NUMBER); | ||
100 | |||
101 | /* Unlocks the core mutex */ | ||
102 | imx_sema4_mutex_unlock(shm_ptr); | ||
103 | } | ||
104 | |||
105 | return IRQ_HANDLED; | ||
106 | } | ||
107 | |||
108 | /*! | ||
109 | * \brief This function initializes the hw semaphore (SEMA4). | ||
110 | * | ||
111 | * Calls core-mutex driver to create a core mutex. | ||
112 | * | ||
113 | * \param[in] sem_num SEMA4 gate number. | ||
114 | */ | ||
115 | int mcc_init_semaphore(unsigned int sem_num) | ||
116 | { | ||
117 | /* Create a core mutex */ | ||
118 | shm_ptr = imx_sema4_mutex_create(0, sem_num); | ||
119 | |||
120 | if (NULL == shm_ptr) | ||
121 | return MCC_ERR_SEMAPHORE; | ||
122 | else | ||
123 | return MCC_SUCCESS; | ||
124 | } | ||
125 | |||
126 | /*! | ||
127 | * \brief This function de-initializes the hw semaphore (SEMA4). | ||
128 | * | ||
129 | * Calls core-mutex driver to destroy a core mutex. | ||
130 | * | ||
131 | * \param[in] sem_num SEMA4 gate number. | ||
132 | */ | ||
133 | int mcc_deinit_semaphore(unsigned int sem_num) | ||
134 | { | ||
135 | /* Destroy the core mutex */ | ||
136 | if (0 == imx_sema4_mutex_destroy(shm_ptr)) | ||
137 | return MCC_SUCCESS; | ||
138 | else | ||
139 | return MCC_ERR_SEMAPHORE; | ||
140 | } | ||
141 | |||
142 | /*! | ||
143 | * \brief This function locks the specified core mutex. | ||
144 | * | ||
145 | * Calls core-mutex driver to lock the core mutex. | ||
146 | * | ||
147 | */ | ||
148 | int mcc_get_semaphore(void) | ||
149 | { | ||
150 | if (imx_mcc_bsp_int_disable(cpu_to_cpu_isr_vector)) { | ||
151 | pr_err("ERR:failed to disable mcc int.\n"); | ||
152 | return MCC_ERR_SEMAPHORE; | ||
153 | } | ||
154 | |||
155 | if (0 == imx_sema4_mutex_lock(shm_ptr)) { | ||
156 | return MCC_SUCCESS; | ||
157 | } else { | ||
158 | if (imx_mcc_bsp_int_enable(cpu_to_cpu_isr_vector)) { | ||
159 | pr_err("ERR:failed to enable mcc int.\n"); | ||
160 | return MCC_ERR_INT; | ||
161 | } | ||
162 | return MCC_ERR_SEMAPHORE; | ||
163 | } | ||
164 | } | ||
165 | |||
166 | /*! | ||
167 | * \brief This function unlocks the specified core mutex. | ||
168 | * | ||
169 | * Calls core-mutex driver to unlock the core mutex. | ||
170 | * | ||
171 | */ | ||
172 | int mcc_release_semaphore(void) | ||
173 | { | ||
174 | if (0 == imx_sema4_mutex_unlock(shm_ptr)) { | ||
175 | /* | ||
176 | * Enable the cpu-to-cpu isr just in case imx_semae_mutex_unlock | ||
177 | * function has not woke up another task waiting for the core | ||
178 | * mutex. | ||
179 | */ | ||
180 | if (shm_ptr->gate_val != (MCC_CORE_NUMBER + 1)) | ||
181 | imx_mcc_bsp_int_enable(cpu_to_cpu_isr_vector); | ||
182 | return MCC_SUCCESS; | ||
183 | } | ||
184 | |||
185 | return MCC_ERR_SEMAPHORE; | ||
186 | } | ||
187 | |||
188 | /*! | ||
189 | * \brief This function registers the CPU-to-CPU interrupt. | ||
190 | * | ||
191 | * Calls interrupt component functions to install and enable the | ||
192 | * CPU-to-CPU interrupt. | ||
193 | * | ||
194 | */ | ||
195 | int mcc_register_cpu_to_cpu_isr(void) | ||
196 | { | ||
197 | int ret; | ||
198 | unsigned int vector_number; | ||
199 | |||
200 | vector_number = mcc_get_cpu_to_cpu_vector(MCC_CORE_NUMBER); | ||
201 | |||
202 | if (vector_number != MCC_VECTOR_NUMBER_INVALID) { | ||
203 | imx_mu_reg = | ||
204 | syscon_regmap_lookup_by_compatible("fsl,imx6sx-mu"); | ||
205 | if (IS_ERR(imx_mu_reg)) | ||
206 | pr_err("ERR:unable to find imx mu registers\n"); | ||
207 | |||
208 | ret = request_irq(vector_number, mcc_cpu_to_cpu_isr, | ||
209 | 0, "imx-linux-mcc", NULL); | ||
210 | if (ret) { | ||
211 | pr_err("%s: register interrupt %d failed, rc %d\n", | ||
212 | __func__, vector_number, ret); | ||
213 | return MCC_ERR_INT; | ||
214 | } | ||
215 | /* Make sure the INT is cleared */ | ||
216 | mcc_clear_cpu_to_cpu_interrupt(MCC_CORE_NUMBER); | ||
217 | |||
218 | /* Enable INT */ | ||
219 | ret = imx_mcc_bsp_int_enable(vector_number); | ||
220 | if (ret < 0) { | ||
221 | pr_err("ERR:failed to enable mcc int.\n"); | ||
222 | return MCC_ERR_INT; | ||
223 | } | ||
224 | |||
225 | cpu_to_cpu_isr_vector = vector_number; | ||
226 | return MCC_SUCCESS; | ||
227 | } else { | ||
228 | return MCC_ERR_INT; | ||
229 | } | ||
230 | } | ||
231 | |||
232 | /*! | ||
233 | * \brief This function triggers an interrupt to other core(s). | ||
234 | * | ||
235 | */ | ||
236 | int mcc_generate_cpu_to_cpu_interrupt(void) | ||
237 | { | ||
238 | /* | ||
239 | * Assert directed CPU interrupts for all processors except | ||
240 | * the requesting core | ||
241 | */ | ||
242 | mcc_triger_cpu_to_cpu_interrupt(); | ||
243 | |||
244 | return MCC_SUCCESS; | ||
245 | } | ||
246 | |||
247 | /*! | ||
248 | * \brief This function copies data. | ||
249 | * | ||
250 | * Copies the number of single-addressable units from the source address | ||
251 | * to destination address. | ||
252 | * | ||
253 | * \param[in] src Source address. | ||
254 | * \param[in] dest Destination address. | ||
255 | * \param[in] size Number of single-addressable units to copy. | ||
256 | */ | ||
257 | void mcc_memcpy(void *src, void *dest, unsigned int size) | ||
258 | { | ||
259 | memcpy(dest, src, size); | ||
260 | } | ||
261 | |||
262 | void _mem_zero(void *ptr, unsigned int size) | ||
263 | { | ||
264 | memset(ptr, 0, size); | ||
265 | } | ||
266 | |||
267 | void *virt_to_mqx(void *x) | ||
268 | { | ||
269 | if (null == x) | ||
270 | return NULL; | ||
271 | else | ||
272 | return (void *)((unsigned long) (x) - mcc_shm_offset); | ||
273 | } | ||
274 | |||
275 | void *mqx_to_virt(void *x) | ||
276 | { | ||
277 | if (null == x) | ||
278 | return NULL; | ||
279 | else | ||
280 | return (void *)((unsigned long) (x) + mcc_shm_offset); | ||
281 | } | ||
diff --git a/include/linux/mcc_imx6sx.h b/include/linux/mcc_imx6sx.h new file mode 100644 index 000000000000..86a6de7da31d --- /dev/null +++ b/include/linux/mcc_imx6sx.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Freescale Semiconductor, Inc. | ||
3 | * Freescale IMX Linux-specific MCC implementation. | ||
4 | * Prototypes for iMX6sx-specific MCC library functions. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | /* | ||
20 | * Define the phiscal memory address on A9 and shared M4, | ||
21 | * This definition should be aligned on both A9 and M4 | ||
22 | */ | ||
23 | #define MCC_VECTOR_NUMBER_INVALID (0) | ||
24 | |||
25 | enum { | ||
26 | /* FIXME */ | ||
27 | INT_CPU_TO_CPU_MU_A2M = 122, | ||
28 | INT_CPU_TO_CPU_MU_M2A = 90, | ||
29 | |||
30 | MU_ASR = 0x20, | ||
31 | MU_ACR = 0x24, | ||
32 | }; | ||
33 | |||
34 | extern struct regmap *imx_mu_reg; | ||
35 | |||
36 | /* Return core num. A9 0, M4 1 */ | ||
37 | unsigned int _psp_core_num(void); | ||
38 | |||
39 | unsigned int mcc_get_cpu_to_cpu_vector(unsigned int); | ||
40 | void mcc_clear_cpu_to_cpu_interrupt(unsigned int); | ||
41 | void mcc_triger_cpu_to_cpu_interrupt(void); | ||
42 | int imx_mcc_bsp_int_disable(unsigned int vector_number); | ||
43 | int imx_mcc_bsp_int_enable(unsigned int vector_number); | ||
diff --git a/include/linux/mcc_linux.h b/include/linux/mcc_linux.h new file mode 100644 index 000000000000..f8591de63e74 --- /dev/null +++ b/include/linux/mcc_linux.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Freescale Semiconductor, Inc. | ||
3 | * Freescale IMX Linux-specific MCC implementation. | ||
4 | * Prototypes for Linunx-specific MCC library functions | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifndef __MCC_LINUX__ | ||
20 | #define __MCC_LINUX__ | ||
21 | |||
22 | /* Define the kinds of cache macros */ | ||
23 | #define MCC_DCACHE_ENABLE(n) | ||
24 | #define MCC_DCACHE_DISABLE() | ||
25 | #define MCC_DCACHE_FLUSH() | ||
26 | #define MCC_DCACHE_FLUSH_LINE(p) | ||
27 | #define MCC_DCACHE_FLUSH_MLINES(p, m) | ||
28 | #define MCC_DCACHE_INVALIDATE() | ||
29 | #define MCC_DCACHE_INVALIDATE_LINE(p) | ||
30 | #define MCC_DCACHE_INVALIDATE_MLINES(p, m) | ||
31 | |||
32 | #define _mem_size unsigned int | ||
33 | |||
34 | void * virt_to_mqx(void *); | ||
35 | void * mqx_to_virt(void *); | ||
36 | #define VIRT_TO_MQX(x) virt_to_mqx(x) | ||
37 | #define MQX_TO_VIRT(x) mqx_to_virt(x) | ||
38 | |||
39 | /* Semaphore-related functions */ | ||
40 | int mcc_init_semaphore(unsigned int); | ||
41 | int mcc_deinit_semaphore(unsigned int); | ||
42 | int mcc_get_semaphore(void); | ||
43 | int mcc_release_semaphore(void); | ||
44 | |||
45 | /* CPU-to-CPU interrupt-related functions */ | ||
46 | int mcc_register_cpu_to_cpu_isr(void); | ||
47 | int mcc_generate_cpu_to_cpu_interrupt(void); | ||
48 | |||
49 | /* Memory management-related functions */ | ||
50 | void mcc_memcpy(void *, void *, unsigned int); | ||
51 | void _mem_zero(void *, unsigned int); | ||
52 | |||
53 | #endif /* __MCC_LINUX__ */ | ||