Input: sprd_eic_keys: remove event log
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / sipc / sctrl.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/cdev.h>
17 #include <linux/poll.h>
18 #include <linux/platform_device.h>
19 #include <linux/slab.h>
20 #ifdef CONFIG_OF
21 #include <linux/of_device.h>
22 #endif
23 #include "soc/sprd/mailbox.h"
24 #include <linux/sched.h>
25 #include <linux/kthread.h>
26 #include <linux/delay.h>
27 #include <linux/sizes.h>
28 #include <soc/sprd/sci_glb_regs.h>
29 #include <linux/sipc.h>
30 #include <linux/spipe.h>
31 #include <linux/sipc_priv.h>
32 #include "sctrl.h"
33
34 #define SMSG_TXBUF_ADDR         (0)
35 #define SMSG_TXBUF_SIZE         (SZ_1K)
36 #define SMSG_RXBUF_ADDR         (SMSG_TXBUF_SIZE)
37 #define SMSG_RXBUF_SIZE         (SZ_1K)
38 /*
39 #define SMSG_RINGHDR            (SMSG_TXBUF_SIZE + SMSG_RXBUF_SIZE)
40 #define SMSG_TXBUF_RDPTR        (SMSG_RINGHDR + 0)
41 #define SMSG_TXBUF_WRPTR        (SMSG_RINGHDR + 4)
42 #define SMSG_RXBUF_RDPTR        (SMSG_RINGHDR + 8)
43 #define SMSG_RXBUF_WRPTR        (SMSG_RINGHDR + 12)
44 */
45
46 static struct class     *sctrl_class;
47 static struct sctrl_mgr strcl_mgr_val;
48 //#define SCTRL_LOOPBACK_DEBUG
49 #ifdef SCTRL_LOOPBACK_DEBUG
50 struct timer_list sctrl_ti;
51 static void sctrl_tx(void)
52 {
53     struct smsg mrevt;
54     smsg_set(&mrevt, 1, 0, 0, 0);
55     smsg_send(SIPC_ID_PMIC, &mrevt, -1);
56 }
57 void sctrl_timer_func(unsigned long arg)
58 {
59     struct timer_list *timer=(struct timer_list *)arg;
60     unsigned long  j = jiffies;
61     mod_timer(timer,j+8*HZ);
62     pr_err(" sctrl_timer_func expired at jif=%lx\n", j);
63     sctrl_tx();
64 }
65 #endif
66 static int sctrl_thread(void *data)
67 {
68     struct sctrl_mgr *strcl_mgr_ptr= data;
69     struct smsg mrecv;
70     int rval;
71     struct sched_param param = {.sched_priority = 90};
72
73     /*set the thread as a real time thread, and its priority is 90*/
74     sched_setscheduler(current, SCHED_RR, &param);
75
76     /* since the channel open may hang, we call it in the sctrl thread */
77     rval = smsg_ch_open(strcl_mgr_ptr->dst, strcl_mgr_ptr->channel, -1);
78     if (rval != 0) {
79         pr_err("Failed to open channel %d, rval=%d\n", strcl_mgr_ptr->channel,rval);
80         /* assign NULL to thread poniter as failed to open channel */
81         strcl_mgr_ptr->thread = NULL;
82         return rval;
83     }
84
85 #ifdef SCTRL_LOOPBACK_DEBUG
86     /*initiated a timer to send smsg to arm7*/
87     init_timer(&sctrl_ti);
88     sctrl_ti.data=(unsigned long)&sctrl_ti;
89     sctrl_ti.function=sctrl_timer_func;
90     sctrl_ti.expires = jiffies + HZ;
91     add_timer(&sctrl_ti);
92 #endif
93
94     while (!kthread_should_stop()) {
95         /* monitor sctrl rdptr/wrptr update smsg */
96         smsg_set(&mrecv, strcl_mgr_ptr->channel, 0, 0, 0);
97         rval = smsg_recv(strcl_mgr_ptr->dst, &mrecv, -1);
98
99         if (rval == -EIO) {
100             /* channel state is free */
101             msleep(5);
102             continue;
103         }
104         printk(KERN_ERR "sctrl thread recv msg: dst=%d, channel=%d, "
105                         "type=%d, flag=0x%04x, value=0x%08x\n",
106                             strcl_mgr_ptr->dst, strcl_mgr_ptr->channel,
107                             mrecv.type, mrecv.flag, mrecv.value);
108         switch (mrecv.type) {
109         case  SMSG_TYPE_DFS_RSP:
110             if(mrecv.value == 0)
111             {
112                 strcl_mgr_ptr->state = SCTL_STATE_REV_CMPT;
113             }
114             else
115             {
116                 strcl_mgr_ptr->state = SCTL_STATE_READY;
117             }
118             wake_up_interruptible_all(&strcl_mgr_ptr->rx_pending);
119             break;
120         default :
121             break;
122         }
123 #if 0
124         case SMSG_TYPE_CLOSE:
125         /* handle channel recovery */
126         smsg_close_ack(strcl_mgr_ptr->dst, strcl_mgr_ptr->channel);
127         strcl_mgr_ptr->state = SCTL_STATE_IDLE;
128             break;
129
130         case SMSG_TYPE_CMD:
131         /* respond cmd done for sctrl init */
132         smsg_set(&mcmd, strcl_mgr_ptr->channel, SMSG_TYPE_DONE,SMSG_DONE_SBUF_INIT, 0);
133         smsg_send(strcl_mgr_ptr->dst, &mcmd, -1);
134         strcl_mgr_ptr->state = SCTL_STATE_READY;
135             break;
136 #endif
137     }
138     return 0;
139 }
140 void sctrl_send_async(uint32_t type, uint32_t target_id, uint32_t value)
141 {
142         struct smsg mevt;
143         smsg_set(&mevt,  1, type, target_id ,value);
144         smsg_send(SIPC_ID_PMIC, &mevt, -1);
145 }
146 int sctrl_send_sync(uint32_t type, uint32_t target_id, uint32_t value)
147 {
148         struct smsg mrecv;
149         int rval = 0;
150         int timeout =msecs_to_jiffies(50000);
151         smsg_set(&mrecv,  1, type, target_id ,value);
152         smsg_send(SIPC_ID_PMIC, &mrecv, -1);
153         if(type ==SMSG_TYPE_DFS)
154         {
155             rval = wait_event_interruptible_timeout(strcl_mgr_val.rx_pending,\
156                 strcl_mgr_val.state != SCTL_STATE_IDLE, timeout);
157             if (rval < 0) {
158                 pr_warning(" sctrl_send_sync wait interrupted!\n");
159             } else if (rval == 0) {
160                 pr_err(" sctrl_send_sync wait timeout!\n");
161                 rval = -ETIME;
162             }
163             if (strcl_mgr_val.state == SCTL_STATE_REV_CMPT)
164             {
165                 strcl_mgr_val.state =  SCTL_STATE_IDLE;
166                 pr_info(" sctrl_send_sync DFS Response!\n");
167                 return 0;
168             }
169             else
170             {
171                 goto FAIL;
172             }
173         }
174         else {
175                 goto FAIL;
176         }
177 FAIL:
178         strcl_mgr_val.state =  SCTL_STATE_IDLE;
179         return -EINVAL;
180 }
181 int sctrl_create(uint8_t dst, uint8_t channel, uint32_t bufnum)
182 {
183     int result;
184     strcl_mgr_val.state = SCTL_STATE_IDLE;
185     strcl_mgr_val.dst = dst;
186     strcl_mgr_val.channel = channel;
187     init_waitqueue_head(&strcl_mgr_val.tx_pending);
188     init_waitqueue_head(&strcl_mgr_val.rx_pending);
189     strcl_mgr_val.thread = kthread_create(sctrl_thread, &strcl_mgr_val, "sctrl-%d-%d", dst, channel);
190     if (IS_ERR(strcl_mgr_val.thread)) {
191         printk(KERN_ERR "Failed to create kthread: sctrl-%d-%d\n", dst, channel);
192             result = PTR_ERR(strcl_mgr_val.thread);
193             return result;
194     }
195     pr_err(" sctrl create strcl_mgr_val.thread %p\n", strcl_mgr_val.thread);
196     wake_up_process(strcl_mgr_val.thread);
197     return 0;
198 }
199 static int sctrl_open(struct inode *inode, struct file *filp)
200 {
201         int minor = iminor(filp->f_path.dentry->d_inode);
202         struct sctrl_device *sctrl;
203         struct sctrl_buf *sbuf;
204
205         sctrl = container_of(inode->i_cdev, struct sctrl_device, cdev);
206         sbuf = kmalloc(sizeof(struct sctrl_buf), GFP_KERNEL);
207         if (!sbuf) {
208             pr_err(" sctrl open malloc sbuf fail\n");
209             return -ENOMEM;
210         }
211         filp->private_data = sbuf;
212
213         sbuf->dst = sctrl->init->dst;
214         sbuf->channel = sctrl->init->channel;
215         sbuf->bufid = minor - sctrl->minor;
216         pr_info("sctrl open sucess\n");
217         return 0;
218 }
219
220 static int sctrl_release(struct inode *inode, struct file *filp)
221 {
222         struct sctrl_buf *sbuf = filp->private_data;
223
224         if (sbuf) {
225                 kfree(sbuf);
226         }
227
228         return 0;
229 }
230
231 static ssize_t sctrl_read(struct file *filp,
232                 char __user *buf, size_t count, loff_t *ppos)
233 {
234         struct sctrl_buf *sbuf = filp->private_data;
235         struct smsg mevt = {0};
236         int timeout = -1;
237
238         if (filp->f_flags & O_NONBLOCK) {
239                 timeout = 0;
240         }
241         if(smsg_recv(sbuf->dst,&mevt,timeout) == 0)
242         {
243             if(copy_to_user((void __user *)buf, (void *)&mevt, sizeof(struct smsg)))
244                     return -1;
245             else
246                     return 0;
247         }
248         else{
249             return -1;
250         }
251 }
252
253 static ssize_t sctrl_write(struct file *filp,
254                 const char __user *buf, size_t count, loff_t *ppos)
255 {
256         struct sctrl_buf *sbuf = filp->private_data;
257         struct smsg mevt = {0};
258         int timeout = -1;
259
260         if (filp->f_flags & O_NONBLOCK) {
261                 timeout = 0;
262         }
263         pr_info("sctrl open sucess\n");
264
265         sctrl_send_sync(SMSG_TYPE_DFS, SIPC_ID_PMIC,0xfe);
266         return count;
267 }
268
269 static unsigned int sctrl_poll(struct file *filp, poll_table *wait)
270 {
271     struct sctrl_buf *sbuf = filp->private_data;
272     unsigned int mask = 0;
273     if (!sbuf) {
274         return -ENODEV;
275     }
276     return mask;
277 }
278
279 static long sctrl_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
280 {
281         return 0;
282 }
283 uint32_t pmic_rxirq_status(void)
284 {
285     return 1;
286 }
287 void pmic_rxirq_clear(void)
288 {
289 }
290 void pmic_txirq_trigger(void)
291 {
292     mbox_raw_sent(ARM7, 0);
293 }
294
295 static struct smsg_ipc smsg_ipc_pmic = {
296         .name = "sipc-pmic",
297         .dst = SIPC_ID_PMIC,
298         .core_id = ARM7,
299         .rxirq_status = pmic_rxirq_status,
300         .rxirq_clear = pmic_rxirq_clear,
301         .txirq_trigger = pmic_txirq_trigger,
302 };
303
304 static int __init sipc_pmic_init(ssize_t base)
305 {
306
307         smsg_ipc_pmic.txbuf_size = SMSG_TXBUF_SIZE / sizeof(struct smsg);
308         smsg_ipc_pmic.txbuf_addr = base + SMSG_TXBUF_ADDR;
309         smsg_ipc_pmic.txbuf_rdptr =base+0x1c00+ 0;
310         smsg_ipc_pmic.txbuf_wrptr = base+0x1c00+ 8;
311
312         smsg_ipc_pmic.rxbuf_size = SMSG_RXBUF_SIZE / sizeof(struct smsg);
313         smsg_ipc_pmic.rxbuf_addr = base + SMSG_RXBUF_ADDR;
314         smsg_ipc_pmic.rxbuf_rdptr =  base+0x1c00+ 16;
315         smsg_ipc_pmic.rxbuf_wrptr =  base+0x1c00+ 24;
316
317         return smsg_ipc_create(SIPC_ID_PMIC, &smsg_ipc_pmic);
318 }
319 static const struct file_operations sctrl_fops = {
320         .open           = sctrl_open,
321         .release        = sctrl_release,
322         .read           = sctrl_read,
323         .write          = sctrl_write,
324         .poll           = sctrl_poll,
325         .unlocked_ioctl = sctrl_ioctl,
326         .owner          = THIS_MODULE,
327         .llseek         = default_llseek,
328 };
329
330 static int sctrl_parse_dt(struct spipe_init_data **init, struct device *dev)
331 {
332 #ifdef CONFIG_OF
333         struct device_node *np = dev->of_node;
334         struct spipe_init_data *pdata = NULL;
335         ssize_t ring_base = 0;
336         ssize_t vm_base= 0;
337         uint32_t rxbuf_size = 0;
338         uint32_t txbuf_size = 0;
339         int ret;
340         uint32_t data;
341
342         pdata = kzalloc(sizeof(struct spipe_init_data), GFP_KERNEL);
343         if (!pdata) {
344                 printk(KERN_ERR "Failed to allocate pdata memory\n");
345                 return -ENOMEM;
346         }
347
348         ret = of_property_read_string(np, "sprd,name", (const char**)&pdata->name);
349         if (ret) {
350                 printk(KERN_ERR "Failed to read sprd name\n");
351                 goto error;
352         }
353
354         ret = of_property_read_u32(np, "sprd,dst", (uint32_t *)&data);
355         if (ret) {
356                 printk(KERN_ERR "Failed to read sprd dst\n");
357                 goto error;
358         }
359         pdata->dst = (uint8_t)data;
360
361         ret = of_property_read_u32(np, "sprd,channel", (uint32_t *)&data);
362         if (ret) {
363                 printk(KERN_ERR "Failed to read sprd channel\n");
364                 goto error;
365         }
366         pdata->channel = (uint8_t)data;
367         ret = of_property_read_u32(np, "sprd,ringnr", (uint32_t *)&data);
368         if (ret) {
369             printk(KERN_ERR "Failed to read sprd ringnr, ret=%d\n", ret);
370             goto error;
371         }
372         pdata->ringnr=data;
373         ret = of_property_read_u32(np, "sprd,ringbase", (uint32_t *)&vm_base);
374         if(ret) {
375                 goto error;
376         }
377         ring_base = (unsigned long)ioremap_nocache(vm_base,SZ_8K);
378         if(!ring_base){
379                 printk(KERN_ERR "Unable to map ring base\n");
380                 goto error;
381         }
382
383         ret = of_property_read_u32(np, "sprd,size-rxbuf", &rxbuf_size);
384         if (ret) {
385                 goto error;
386         }
387
388         ret = of_property_read_u32(np, "sprd,size-txbuf", &txbuf_size);
389         if (ret) {
390                 goto error;
391         }
392         pr_info("sipc_pmic_init with base=0x%lx\n", ring_base);
393         sipc_pmic_init(ring_base);
394         *init = pdata;
395         return ret;
396 error:
397         kfree(pdata);
398         *init = NULL;
399         return ret;
400 #else
401         return -ENODEV;
402 #endif
403 }
404
405 static inline void sctrl_destroy_pdata(struct spipe_init_data **init)
406 {
407 #ifdef CONFIG_OF
408         struct spipe_init_data *pdata = *init;
409
410         if (pdata) {
411                 kfree(pdata);
412         }
413
414         *init = NULL;
415 #else
416         return;
417 #endif
418 }
419
420 static int sctrl_probe(struct platform_device *pdev)
421 {
422         struct spipe_init_data *init = pdev->dev.platform_data;
423         struct sctrl_device *sctrl;
424         dev_t devid;
425         int i, rval;
426
427         if (pdev->dev.of_node && !init) {
428                 rval = sctrl_parse_dt(&init, &pdev->dev);
429                 if (rval) {
430                         printk(KERN_ERR "Failed to parse sctrl device tree, ret=%d\n", rval);
431                         return rval;
432                 }
433         }
434         pr_info("sctrl: after parse device tree, name=%s, dst=%u, channel=%u, ringnr=%u, rxbuf_size=%u, txbuf_size=%u\n",
435                 init->name, init->dst, init->channel, init->ringnr, init->rxbuf_size, init->txbuf_size);
436
437
438         rval =  sctrl_create(init->dst, init->channel, init->ringnr);
439         if (rval != 0) {
440                 printk(KERN_ERR "Failed to create sctrl device: %d\n", rval);
441                 sctrl_destroy_pdata(&init);
442                 return rval;
443         }
444
445         sctrl = kzalloc(sizeof(struct sctrl_device), GFP_KERNEL);
446         if (sctrl == NULL) {
447                 sctrl_destroy_pdata(&init);
448                 printk(KERN_ERR "Failed to allocate sctrl_device\n");
449                 return -ENOMEM;
450         }
451         rval = alloc_chrdev_region(&devid, 0, init->ringnr, init->name);
452         if (rval != 0) {
453                 kfree(sctrl);
454                 sctrl_destroy_pdata(&init);
455                 printk(KERN_ERR "Failed to alloc sctrl chrdev\n");
456                 return rval;
457         }
458
459         cdev_init(&(sctrl->cdev), &sctrl_fops);
460         rval = cdev_add(&(sctrl->cdev), devid, init->ringnr);
461         if (rval != 0) {
462                 kfree(sctrl);
463                 unregister_chrdev_region(devid, init->ringnr);
464                 sctrl_destroy_pdata(&init);
465                 printk(KERN_ERR "Failed to add sctrl cdev\n");
466                 return rval;
467         }
468
469         sctrl->major = MAJOR(devid);
470         sctrl->minor = MINOR(devid);
471         if (init->ringnr > 1) {
472                 for (i = 0; i < init->ringnr; i++) {
473                         device_create(sctrl_class, NULL,
474                                 MKDEV(sctrl->major, sctrl->minor + i),
475                                 NULL, "%s%d", init->name, i);
476                 }
477         } else {
478                 device_create(sctrl_class, NULL,
479                         MKDEV(sctrl->major, sctrl->minor),
480                         NULL, "%s", init->name);
481         }
482
483         sctrl->init = init;
484         platform_set_drvdata(pdev, sctrl);
485         return 0;
486 }
487
488 static int  sctrl_remove(struct platform_device *pdev)
489 {
490         struct sctrl_device *sctrl = platform_get_drvdata(pdev);
491         int i;
492
493         for (i = 0; i < sctrl->init->ringnr; i++) {
494                 device_destroy(sctrl_class,
495                                 MKDEV(sctrl->major, sctrl->minor + i));
496         }
497         cdev_del(&(sctrl->cdev));
498         unregister_chrdev_region(
499                 MKDEV(sctrl->major, sctrl->minor), sctrl->init->ringnr);
500
501         sctrl_destroy_pdata(&sctrl->init);
502
503         kfree(sctrl);
504
505         platform_set_drvdata(pdev, NULL);
506
507         return 0;
508 }
509
510 static const struct of_device_id sctrl_match_table[] = {
511         {.compatible = "sprd,sctrl", },
512         { },
513 };
514
515 static struct platform_driver sctrl_driver = {
516         .driver = {
517                 .owner = THIS_MODULE,
518                 .name = "sctrl",
519                 .of_match_table = sctrl_match_table,
520         },
521         .probe = sctrl_probe,
522         .remove = sctrl_remove,
523 };
524
525 static int __init sctrl_init(void)
526 {
527         sctrl_class = class_create(THIS_MODULE, "sctrl");
528         if (IS_ERR(sctrl_class))
529                 return PTR_ERR(sctrl_class);
530
531         return platform_driver_register(&sctrl_driver);
532 }
533
534 static void __exit sctrl_exit(void)
535 {
536         class_destroy(sctrl_class);
537         platform_driver_unregister(&sctrl_driver);
538 }
539
540 module_init(sctrl_init);
541 module_exit(sctrl_exit);
542
543 MODULE_AUTHOR("Andrew Yang");
544 MODULE_DESCRIPTION("SIPC/SCTRL driver");
545 MODULE_LICENSE("GPL");