Input: sprd_eic_keys: remove event log
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / sipc / sipc.c
1 /*
2  * Copyright (C) 2012 Spreadtrum Communications Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/wait.h>
17 #include <linux/spinlock.h>
18 #include <linux/interrupt.h>
19 #include <linux/sched.h>
20 #include <linux/io.h>
21 #include <linux/slab.h>
22 #include <linux/debugfs.h>
23 #include <linux/platform_device.h>
24 #include <linux/of_device.h>
25 #include <linux/of_address.h>
26 #include <linux/of_irq.h>
27 #include <soc/sprd/sci_glb_regs.h>
28
29 #ifdef CONFIG_SPRD_MAILBOX
30 #include <soc/sprd/mailbox.h>
31 #endif
32
33 #include <linux/sipc.h>
34 #include <linux/sipc_priv.h>
35
36 #define SMSG_TXBUF_ADDR         (0)
37 #define SMSG_TXBUF_SIZE         (SZ_1K)
38 #define SMSG_RXBUF_ADDR         (SMSG_TXBUF_SIZE)
39 #define SMSG_RXBUF_SIZE         (SZ_1K)
40
41 #define SMSG_RINGHDR            (SMSG_TXBUF_SIZE + SMSG_RXBUF_SIZE)
42 #define SMSG_TXBUF_RDPTR        (SMSG_RINGHDR + 0)
43 #define SMSG_TXBUF_WRPTR        (SMSG_RINGHDR + 4)
44 #define SMSG_RXBUF_RDPTR        (SMSG_RINGHDR + 8)
45 #define SMSG_RXBUF_WRPTR        (SMSG_RINGHDR + 12)
46
47 /* if it's upon mailbox arch, overwrite the implementation*/
48 #ifdef CONFIG_SPRD_MAILBOX
49
50 #define DEFINE_SIPC_RXIRQ_STATUS_FN(id) \
51 static int sipc_rxirq_status##id(void) \
52 { \
53         return 1;\
54 }
55
56 #define DEFINE_SIPC_RXIRQ_CLEAR_FN(id) \
57 static void sipc_rxirq_clear##id(void) \
58 { \
59         return;\
60 }
61
62 #define DEFINE_SIPC_TXIRQ_TRIGGER_FN(id) \
63 static void sipc_txirq_trigger##id(void) \
64 { \
65         struct sipc_child_node_info *info = &sipc_dev->pdata->info_table[id];\
66         mbox_raw_sent(info->core_id, 0);\
67 }
68
69 #else
70
71 #define DEFINE_SIPC_RXIRQ_STATUS_FN(id) \
72 static int sipc_rxirq_status##id(void) \
73 { \
74         return 1;\
75 }
76
77 #define DEFINE_SIPC_RXIRQ_CLEAR_FN(id) \
78 static void sipc_rxirq_clear##id(void) \
79 { \
80         struct sipc_child_node_info *info = &sipc_dev->pdata->info_table[id];\
81         __raw_writel(info->ap2cp_bit_clr, (volatile void *)info->cp2ap_int_ctrl);\
82 }
83
84 #define DEFINE_SIPC_TXIRQ_TRIGGER_FN(id) \
85 static void sipc_txirq_trigger##id(void) \
86 { \
87         struct sipc_child_node_info *info = &sipc_dev->pdata->info_table[id];\
88         __raw_writel(info->ap2cp_bit_trig, (volatile void *)info->ap2cp_int_ctrl);\
89 }
90
91 #endif
92
93 #define __GET_SIPC_FN_NAME(fn, id) fn##id
94
95 #define __GET_SIPC_FN(fn, id) \
96 ({ \
97         void* ret; \
98         switch(id) { \
99                 case 0: \
100                         ret = __GET_SIPC_FN_NAME(fn, 0);\
101                         break; \
102                 case 1: \
103                         ret = __GET_SIPC_FN_NAME(fn, 1);\
104                         break; \
105                 case 2: \
106                         ret = __GET_SIPC_FN_NAME(fn, 2);\
107                         break; \
108                 default: \
109                         break; \
110         } \
111         ret; \
112 }) \
113
114 #define GET_SIPC_RXIRQ_STATUS_FN(id) __GET_SIPC_FN(sipc_rxirq_status, id)
115 #define GET_SIPC_RXIRQ_CLEAR_FN(id) __GET_SIPC_FN(sipc_rxirq_clear, id)
116 #define GET_SIPC_TXIRQ_TRIGGER_FN(id) __GET_SIPC_FN(sipc_txirq_trigger, id)
117
118 struct sipc_child_node_info {
119         uint8_t dst;
120         char * name;
121
122         uint32_t cp_base;
123         uint32_t cp_size;
124
125         uint32_t ring_base;
126         uint32_t ring_size;
127
128         uint32_t smem_base;
129         uint32_t smem_size;
130
131 #ifdef CONFIG_SPRD_MAILBOX
132         uint32_t core_id;
133 #else
134         uint32_t ap2cp_int_ctrl;
135         uint32_t cp2ap_int_ctrl;
136         uint32_t ap2cp_bit_trig;
137         uint32_t ap2cp_bit_clr;
138
139         uint32_t irq;
140 #endif
141 };
142
143 struct sipc_init_data {
144         int is_alloc;
145         uint32_t chd_nr;
146         uint32_t smem_base;
147         uint32_t smem_size;
148         struct sipc_child_node_info info_table[0];
149 };
150
151 struct sipc_device {
152         int status;
153         uint32_t inst_nr;
154         struct sipc_init_data *pdata;
155         struct smsg_ipc *smsg_inst;
156 };
157
158 struct sipc_device *sipc_dev;
159
160 DEFINE_SIPC_TXIRQ_TRIGGER_FN(0)
161 DEFINE_SIPC_TXIRQ_TRIGGER_FN(1)
162 DEFINE_SIPC_TXIRQ_TRIGGER_FN(2)
163
164 DEFINE_SIPC_RXIRQ_CLEAR_FN(0)
165 DEFINE_SIPC_RXIRQ_CLEAR_FN(1)
166 DEFINE_SIPC_RXIRQ_CLEAR_FN(2)
167
168 DEFINE_SIPC_RXIRQ_STATUS_FN(0)
169 DEFINE_SIPC_RXIRQ_STATUS_FN(1)
170 DEFINE_SIPC_RXIRQ_STATUS_FN(2)
171
172
173 static int sipc_create(struct sipc_device *sipc)
174 {
175         struct sipc_init_data *pdata = sipc->pdata;
176         struct smsg_ipc *inst;
177         struct sipc_child_node_info *info;
178         size_t base;
179         uint32_t num;
180         int ret, i;
181
182         if (!pdata) {
183                 return -ENODEV;
184         }
185
186         num = pdata->chd_nr;
187         inst = sipc->smsg_inst;
188         info = pdata->info_table;
189
190         for (i = 0; i < num; i++) {
191                 base = (size_t)ioremap_nocache((uint32_t)info[i].ring_base, info[i].ring_size);
192                 if(base == NULL){
193                         pr_info("sipc:[%d] ioremap return NULL\n");
194                         return ENOMEM;
195                 }
196                 pr_info("sipc:[%d] after ioremap vbase=0x%lx, pbase=0x%x, size=0x%x\n",
197                         i, base, info[i].ring_base, info[i].ring_size);
198                 inst[i].txbuf_size = SMSG_TXBUF_SIZE / sizeof(struct smsg);
199                 inst[i].txbuf_addr = base + SMSG_TXBUF_ADDR;
200                 inst[i].txbuf_rdptr = base + SMSG_TXBUF_RDPTR;
201                 inst[i].txbuf_wrptr = base + SMSG_TXBUF_WRPTR;
202
203                 inst[i].rxbuf_size = SMSG_RXBUF_SIZE / sizeof(struct smsg);
204                 inst[i].rxbuf_addr = base + SMSG_RXBUF_ADDR;
205                 inst[i].rxbuf_rdptr = base + SMSG_RXBUF_RDPTR;
206                 inst[i].rxbuf_wrptr = base + SMSG_RXBUF_WRPTR;
207
208                 ret = smsg_ipc_create(inst[i].dst, &inst[i]);
209
210                 pr_info("sipc:[%d] created\n", i);
211                 if (ret) {
212                         break;
213                 }
214         }
215         return ret;
216 }
217
218
219 static int sipc_parse_dt(struct sipc_init_data **init, struct device *dev)
220 {
221         struct device_node *np = dev->of_node, *nchd;
222         struct sipc_init_data *pdata;
223         struct sipc_child_node_info *info;
224         struct resource res;
225         uint32_t data, nr, int_ctrl_phy[2];
226         int ret, i;
227
228         nr = of_get_child_count(np);
229         if (nr == 0 || nr >= SIPC_ID_NR) {
230                 return (!nr ? -ENODEV : -EINVAL);
231         }
232         pdata = kzalloc(sizeof(struct sipc_init_data) + nr*sizeof(struct sipc_child_node_info), GFP_KERNEL);
233         if (!pdata) {
234                 pr_err("sipc: failed to alloc mem for pdata\n");
235                 return -ENOMEM;
236         }
237
238         pdata->is_alloc = 1;
239         ret = of_address_to_resource(np, 0, &res);
240         if (ret) {
241                 goto error;
242         }
243         pdata->chd_nr = nr;
244         pdata->smem_base = (uint32_t)res.start;
245         pdata->smem_size = (uint32_t)(res.end - res.start + 1);
246         pr_info("sipc: chd_nr=%d smem_base=0x%x, smem_size=0x%x\n", pdata->chd_nr, pdata->smem_base, pdata->smem_size);
247
248         i = 0;
249         info = pdata->info_table;
250
251         for_each_child_of_node(np, nchd) {
252                 ret = of_property_read_string(nchd, "sprd,name", (const char **)&info[i].name);
253                 if (ret) {
254                         goto error;
255                 }
256                 pr_info("sipc:[%d] name=%s\n", i, info[i].name);
257
258                 ret = of_property_read_u32(nchd, "sprd,dst", &data);
259                 if (ret) {
260                         goto error;
261                 }
262                 info[i].dst = (uint8_t)data;
263                 pr_info("sipc:[%d] dst=%u\n", i, info[i].dst);
264
265 #ifndef CONFIG_SPRD_MAILBOX
266                 /* get ipi base addr */
267                 ret = of_property_read_u32(nchd, "sprd,ap2cp", &int_ctrl_phy[0]);
268                 if (ret) {
269                         goto error;
270                 }
271                 info[i].ap2cp_int_ctrl = SPRD_DEV_P2V(int_ctrl_phy[0]);
272
273                 ret = of_property_read_u32(nchd, "sprd,cp2ap", &int_ctrl_phy[1]);
274                 if (ret) {
275                         goto error;
276                 }
277                 info[i].cp2ap_int_ctrl = SPRD_DEV_P2V(int_ctrl_phy[1]);
278
279                 pr_info("sipc:[%d] ap2cp_int_ctrl=0x%lx, ap2cp_ctrl_phy=0x%x, cp2ap_int_ctrl=0x%lx, cp2ap_ctrl_phy=0x%x\n",
280                         i, info[i].ap2cp_int_ctrl, int_ctrl_phy[0], info[i].cp2ap_int_ctrl, int_ctrl_phy[1]);
281
282                 ret = of_property_read_u32(nchd, "sprd,trig", &info[i].ap2cp_bit_trig);
283                 if (ret) {
284                         goto error;
285                 }
286
287                 ret = of_property_read_u32(nchd, "sprd,clr", &info[i].ap2cp_bit_clr);
288                 if (ret) {
289                         goto error;
290                 }
291                 pr_info("sipc:[%d] ap2cp_bit_trig=0x%x, ap2cp_bit_clr=0x%x\n",
292                         i, info[i].ap2cp_bit_trig, info[i].ap2cp_bit_clr);
293 #endif
294                 /* get cp base addr */
295                 ret = of_address_to_resource(nchd, 0, &res);
296                 if (ret) {
297                         goto error;
298                 }
299                 info[i].cp_base = (uint32_t)res.start;
300                 info[i].cp_size = (uint32_t)(res.end - res.start + 1);
301                 pr_info("sipc:[%d] cp_base=0x%x, cp_size=0x%x\n",
302                         i, info[i].cp_base, info[i].cp_size);
303
304                 /* get smem base addr */
305                 ret = of_address_to_resource(nchd, 1, &res);
306                 if (ret) {
307                         goto error;
308                 }
309                 info[i].smem_base = (uint32_t)res.start;
310                 info[i].smem_size = (uint32_t)(res.end - res.start + 1);
311                 pr_info("sipc:[%d] smem_base=0x%x, smem_size=0x%x\n", i, info[i].smem_base, info[i].smem_size);
312
313                 /* get ring base addr */
314                 ret = of_address_to_resource(nchd, 2, &res);
315                 if (ret) {
316                         goto error;
317                 }
318                 info[i].ring_base = (uint32_t)res.start;
319                 info[i].ring_size = (uint32_t)(res.end - res.start + 1);
320                 pr_info("sipc:[%d] ring_base=0x%x, ring_size=0x%x\n", i, info[i].ring_base, info[i].ring_size);
321
322 #ifdef CONFIG_SPRD_MAILBOX
323                 ret = of_property_read_u32(nchd, "mailbox,core", &info[i].core_id);
324                 if (ret) {
325                         goto error;
326                 }
327                 pr_info("sipc:[%d] core_id=%u\n", i, info[i].core_id);
328 #else
329                 /* get irq */
330                 info[i].irq = irq_of_parse_and_map(nchd, 0);
331                 if (!info[i].irq) {
332                         ret = -EINVAL;
333                         goto error;
334                 }
335                 pr_info("sipc:[%d] irq=%d\n", i, info[i].irq);
336 #endif
337                 i++;
338         }
339         *init = pdata;
340         return 0;
341 error:
342         kfree(pdata);
343         return ret;
344 }
345
346 static void sipc_destroy_pdata(struct sipc_init_data **ppdata)
347 {
348     struct sipc_init_data *pdata = ppdata;
349     if (pdata && pdata->is_alloc) {
350            kfree(pdata);
351        }
352     return;
353 }
354
355 static int sipc_probe(struct platform_device *pdev)
356 {
357         struct sipc_init_data *pdata = pdev->dev.platform_data;
358         struct sipc_device *sipc;
359         struct sipc_child_node_info *info;
360         struct smsg_ipc *smsg;
361         uint32_t num;
362         int ret, i;
363
364         pr_info("sipc:[0] define status=0x%x, clear=0x%x, trigger=0x%x\n",
365                 (uint32_t)sipc_rxirq_status0, (uint32_t)sipc_rxirq_clear0, (uint32_t)sipc_txirq_trigger0);
366
367         pr_info("sipc:[1] define status=0x%x, clear=0x%x, trigger=0x%x\n",
368                 (uint32_t)sipc_rxirq_status1, (uint32_t)sipc_rxirq_clear1, (uint32_t)sipc_txirq_trigger1);
369
370         pr_info("sipc:[2] define status=0x%x, clear=0x%x, trigger=0x%x\n",
371                 (uint32_t)sipc_rxirq_status2, (uint32_t)sipc_rxirq_clear2, (uint32_t)sipc_txirq_trigger2);
372
373         if (!pdata && pdev->dev.of_node) {
374                 ret = sipc_parse_dt(&pdata, &pdev->dev);
375                 if (ret) {
376                         pr_err("sipc: failed to parse dt, ret=%d\n", ret);
377                         return -ENODEV;
378                 }
379         }
380
381         sipc = kzalloc(sizeof(struct sipc_device), GFP_KERNEL);
382         if (!sipc) {
383                 sipc_destroy_pdata(&pdata);
384                 return -ENOMEM;
385         }
386
387         num = pdata->chd_nr;
388         smsg = kzalloc(num * sizeof(struct smsg_ipc), GFP_KERNEL);
389         if (!smsg)
390         {
391                 sipc_destroy_pdata(&pdata);
392                 kfree(sipc);
393                 return -ENOMEM;
394         }
395         pr_info("sipc: num=%d\n", num);
396         info = pdata->info_table;
397         for (i = 0; i < num; i++) {
398                 smsg[i].name = info[i].name;
399                 smsg[i].dst = info[i].dst;
400 #ifdef CONFIG_SPRD_MAILBOX
401                 smsg[i].core_id = info[i].core_id;
402 #else
403                 smsg[i].irq = info[i].irq;
404 #endif
405                 smsg[i].rxirq_status = GET_SIPC_RXIRQ_STATUS_FN(i);
406                 smsg[i].rxirq_clear = GET_SIPC_RXIRQ_CLEAR_FN(i);
407                 smsg[i].txirq_trigger = GET_SIPC_TXIRQ_TRIGGER_FN(i);
408
409                 pr_info("sipc: [%d] fn status=0x%x, clear=0x%x, trigger=0x%x\n",
410                         i, (uint32_t)smsg[i].rxirq_status, (uint32_t)smsg[i].rxirq_clear,
411                         (uint32_t)smsg[i].txirq_trigger);
412 #ifdef CONFIG_SPRD_MAILBOX
413                 pr_info("sipc:[%d] smsg name=%s, dst=%u, core_id=%d\n",
414                         i, smsg[i].name, smsg[i].dst, smsg[i].core_id);
415 #else
416                 pr_info("sipc:[%d] smsg name=%s, dst=%u, irq=%d\n",
417                         i, smsg[i].name, smsg[i].dst, smsg[i].irq);
418 #endif
419         }
420
421         sipc->pdata = pdata;
422         sipc->smsg_inst = smsg;
423         sipc_dev = sipc;
424
425         smsg_suspend_init();
426
427         sipc_create(sipc);
428
429         pr_info("sipc: smem_base=0x%x, smem_size=0x%x\n", pdata->smem_base, pdata->smem_size);
430         smem_init(pdata->smem_base, pdata->smem_size);
431
432         platform_set_drvdata(pdev, sipc);
433         return 0;
434 }
435
436 static int sipc_remove(struct platform_device *pdev)
437 {
438         struct sipc_device *sipc = platform_get_drvdata(pdev);
439
440         sipc_destroy_pdata(&sipc->pdata);
441         kfree(sipc->smsg_inst);
442         kfree(sipc);
443         return 0;
444 }
445
446
447 static const struct of_device_id sipc_match_table[] = {
448         {.compatible = "sprd,sipc", },
449         { },
450 };
451
452 static struct platform_driver sipc_driver = {
453         .driver = {
454                 .owner = THIS_MODULE,
455                 .name = "sipc",
456                 .of_match_table = sipc_match_table,
457         },
458         .probe = sipc_probe,
459         .remove = sipc_remove,
460 };
461
462 static int __init sipc_init(void)
463 {
464         return platform_driver_register(&sipc_driver);
465 }
466
467 static void __exit sipc_exit(void)
468 {
469         platform_driver_unregister(&sipc_driver);
470 }
471
472 arch_initcall(sipc_init);
473 module_exit(sipc_exit);
474
475 MODULE_AUTHOR("Qiu Yi");
476 MODULE_DESCRIPTION("SIPC module driver");
477 MODULE_LICENSE("GPL");