2 * Copyright (C) 2012 Spreadtrum Communications Inc.
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.
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.
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/sched.h>
17 #include <linux/kthread.h>
18 #include <linux/wait.h>
19 #include <linux/interrupt.h>
20 #include <linux/delay.h>
21 #include <linux/slab.h>
23 #include <linux/debugfs.h>
24 #include <linux/seq_file.h>
25 #ifdef CONFIG_SPRD_MAILBOX
26 #include <soc/sprd/mailbox.h>
29 #include <linux/sipc.h>
30 #include <linux/sipc_priv.h>
31 #include <linux/wakelock.h>
32 #include <linux/syscore_ops.h>
34 static struct smsg_ipc *smsg_ipcs[SIPC_ID_NR];
36 static ushort debug_enable = 0;
38 static struct wake_lock sipc_wake_lock;
40 module_param_named(debug_enable, debug_enable, ushort, 0644);
42 irqreturn_t smsg_irq_handler(int irq, void *dev_id)
44 struct smsg_ipc *ipc = (struct smsg_ipc *)dev_id;
46 struct smsg_channel *ch;
50 if (ipc->rxirq_status()) {
54 while (readl(ipc->rxbuf_wrptr) != readl(ipc->rxbuf_rdptr)) {
55 rxpos = (readl(ipc->rxbuf_rdptr) & (ipc->rxbuf_size - 1)) *
56 sizeof (struct smsg) + ipc->rxbuf_addr;
57 msg = (struct smsg *)rxpos;
59 pr_debug("irq get smsg: wrptr=%u, rdptr=%u, rxpos=0x%lx\n",
60 readl(ipc->rxbuf_wrptr), readl(ipc->rxbuf_rdptr), rxpos);
61 pr_debug("irq read smsg: channel=%d, type=%d, flag=0x%04x, value=0x%08x\n",
62 msg->channel, msg->type, msg->flag, msg->value);
63 if(msg->type == SMSG_TYPE_DIE) {
67 /* update smsg rdptr */
68 writel(readl(ipc->rxbuf_rdptr) + 1, ipc->rxbuf_rdptr);
73 if (msg->channel >= SMSG_CH_NR || msg->type >= SMSG_TYPE_NR) {
75 printk(KERN_ERR "invalid smsg: channel=%d, type=%d, flag=0x%04x, value=0x%08x\n",
76 msg->channel, msg->type, msg->flag, msg->value);
78 /* update smsg rdptr */
79 writel(readl(ipc->rxbuf_rdptr) + 1, ipc->rxbuf_rdptr);
84 ch = ipc->channels[msg->channel];
86 if (ipc->states[msg->channel] == CHAN_STATE_UNUSED &&
87 msg->type == SMSG_TYPE_OPEN &&
88 msg->flag == SMSG_OPEN_MAGIC) {
90 ipc->states[msg->channel] = CHAN_STATE_WAITING;
92 /* drop this bad msg since channel is not opened */
93 printk(KERN_ERR "smsg channel %d not opened! "
94 "drop smsg: type=%d, flag=0x%04x, value=0x%08x\n",
95 msg->channel, msg->type, msg->flag, msg->value);
97 /* update smsg rdptr */
98 writel(readl(ipc->rxbuf_rdptr) + 1, ipc->rxbuf_rdptr);
103 atomic_inc(&(ipc->busy[msg->channel]));
105 if ((int)(readl(ch->wrptr) - readl(ch->rdptr)) >= SMSG_CACHE_NR) {
106 /* msg cache is full, drop this msg */
107 printk(KERN_ERR "smsg channel %d recv cache is full! "
108 "drop smsg: type=%d, flag=0x%04x, value=0x%08x\n",
109 msg->channel, msg->type, msg->flag, msg->value);
111 /* write smsg to cache */
112 wr = readl(ch->wrptr) & (SMSG_CACHE_NR - 1);
113 memcpy(&(ch->caches[wr]), msg, sizeof(struct smsg));
114 writel(readl(ch->wrptr) + 1, ch->wrptr);
117 /* update smsg rdptr */
118 writel(readl(ipc->rxbuf_rdptr) + 1, ipc->rxbuf_rdptr);
120 wake_up_interruptible_all(&(ch->rxwait));
122 atomic_dec(&(ipc->busy[msg->channel]));
125 wake_lock_timeout(&sipc_wake_lock, HZ / 2);
130 int smsg_ipc_create(uint8_t dst, struct smsg_ipc *ipc)
134 if (!ipc->irq_handler) {
135 ipc->irq_handler = smsg_irq_handler;
138 spin_lock_init(&(ipc->txpinlock));
140 smsg_ipcs[dst] = ipc;
142 #ifdef CONFIG_SPRD_MAILBOX
143 /* explicitly call irq handler in case of missing irq on boot */
144 ipc->irq_handler(ipc->core_id, ipc);
146 rval = mbox_register_irq_handle(ipc->core_id, ipc->irq_handler, ipc);
148 printk(KERN_ERR "Failed to register irq handler in mailbox: %s\n",
153 /* explicitly call irq handler in case of missing irq on boot */
154 ipc->irq_handler(ipc->irq, ipc);
156 /* register IPI irq */
157 rval = request_irq(ipc->irq, ipc->irq_handler,
158 IRQF_NO_SUSPEND, ipc->name, ipc);
160 printk(KERN_ERR "Failed to request irq %s: %d\n",
161 ipc->name, ipc->irq);
168 int smsg_ipc_destroy(uint8_t dst)
170 struct smsg_ipc *ipc = smsg_ipcs[dst];
172 kthread_stop(ipc->thread);
173 free_irq(ipc->irq, ipc);
174 smsg_ipcs[dst] = NULL;
179 /* ****************************************************************** */
181 int smsg_ch_open(uint8_t dst, uint8_t channel, int timeout)
183 struct smsg_ipc *ipc = smsg_ipcs[dst];
184 struct smsg_channel *ch;
185 struct smsg mopen, mrecv;
192 ch = kzalloc(sizeof(struct smsg_channel), GFP_KERNEL);
197 atomic_set(&(ipc->busy[channel]), 1);
198 init_waitqueue_head(&(ch->rxwait));
199 mutex_init(&(ch->rxlock));
200 ipc->channels[channel] = ch;
202 smsg_set(&mopen, channel, SMSG_TYPE_OPEN, SMSG_OPEN_MAGIC, 0);
203 rval = smsg_send(dst, &mopen, timeout);
205 printk(KERN_ERR "smsg_ch_open smsg send error, errno %d!\n", rval);
206 ipc->states[channel] = CHAN_STATE_UNUSED;
207 ipc->channels[channel] = NULL;
208 atomic_dec(&(ipc->busy[channel]));
209 /* guarantee that channel resource isn't used in irq handler */
210 while(atomic_read(&(ipc->busy[channel]))) {
218 /* open msg might be got before */
219 if (ipc->states[channel] == CHAN_STATE_WAITING) {
223 smsg_set(&mrecv, channel, 0, 0, 0);
224 rval = smsg_recv(dst, &mrecv, timeout);
226 printk(KERN_ERR "smsg_ch_open smsg receive error, errno %d!\n", rval);
227 ipc->states[channel] = CHAN_STATE_UNUSED;
228 ipc->channels[channel] = NULL;
229 atomic_dec(&(ipc->busy[channel]));
230 /* guarantee that channel resource isn't used in irq handler */
231 while(atomic_read(&(ipc->busy[channel]))) {
239 if (mrecv.type != SMSG_TYPE_OPEN || mrecv.flag != SMSG_OPEN_MAGIC) {
240 printk(KERN_ERR "Got bad open msg on channel %d-%d\n", dst, channel);
241 ipc->states[channel] = CHAN_STATE_UNUSED;
242 ipc->channels[channel] = NULL;
243 atomic_dec(&(ipc->busy[channel]));
244 /* guarantee that channel resource isn't used in irq handler */
245 while(atomic_read(&(ipc->busy[channel]))) {
254 ipc->states[channel] = CHAN_STATE_OPENED;
255 atomic_dec(&(ipc->busy[channel]));
260 int smsg_ch_close(uint8_t dst, uint8_t channel, int timeout)
262 struct smsg_ipc *ipc = smsg_ipcs[dst];
263 struct smsg_channel *ch = ipc->channels[channel];
270 smsg_set(&mclose, channel, SMSG_TYPE_CLOSE, SMSG_CLOSE_MAGIC, 0);
271 smsg_send(dst, &mclose, timeout);
273 ipc->states[channel] = CHAN_STATE_FREE;
274 wake_up_interruptible_all(&(ch->rxwait));
276 /* wait for the channel beeing unused */
277 while(atomic_read(&(ipc->busy[channel]))) {
281 /* maybe channel has been free for smsg_ch_open failed */
282 if (ipc->channels[channel]){
283 ipc->channels[channel] = NULL;
284 /* guarantee that channel resource isn't used in irq handler */
285 while(atomic_read(&(ipc->busy[channel]))) {
291 /* finally, update the channel state*/
292 ipc->states[channel] = CHAN_STATE_UNUSED;
297 int smsg_send(uint8_t dst, struct smsg *msg, int timeout)
299 struct smsg_ipc *ipc = smsg_ipcs[dst];
308 if (!ipc->channels[msg->channel]) {
309 printk(KERN_ERR "channel %d not inited!\n", msg->channel);
313 if (ipc->states[msg->channel] != CHAN_STATE_OPENED &&
314 msg->type != SMSG_TYPE_OPEN &&
315 msg->type != SMSG_TYPE_CLOSE) {
316 printk(KERN_ERR "channel %d not opened!\n", msg->channel);
320 pr_debug("smsg_send: dst=%d, channel=%d, timeout=%d\n",
321 dst, msg->channel, timeout);
322 pr_debug("send smsg: channel=%d, type=%d, flag=0x%04x, value=0x%08x\n",
323 msg->channel, msg->type, msg->flag, msg->value);
325 spin_lock_irqsave(&(ipc->txpinlock), flags);
326 if ((int)(readl(ipc->txbuf_wrptr) -
327 readl(ipc->txbuf_rdptr)) >= ipc->txbuf_size) {
328 printk(KERN_WARNING "smsg txbuf is full!\n");
333 /* calc txpos and write smsg */
334 txpos = (readl(ipc->txbuf_wrptr) & (ipc->txbuf_size - 1)) *
335 sizeof(struct smsg) + ipc->txbuf_addr;
336 memcpy((void *)txpos, msg, sizeof(struct smsg));
338 pr_debug("write smsg: wrptr=%u, rdptr=%u, txpos=0x%lx\n",
339 readl(ipc->txbuf_wrptr),
340 readl(ipc->txbuf_rdptr), txpos);
343 writel(readl(ipc->txbuf_wrptr) + 1, ipc->txbuf_wrptr);
344 ipc->txirq_trigger();
347 spin_unlock_irqrestore(&(ipc->txpinlock), flags);
352 int smsg_recv(uint8_t dst, struct smsg *msg, int timeout)
354 struct smsg_ipc *ipc = smsg_ipcs[dst];
355 struct smsg_channel *ch;
363 atomic_inc(&(ipc->busy[msg->channel]));
365 ch = ipc->channels[msg->channel];
368 printk(KERN_ERR "channel %d not opened!\n", msg->channel);
369 atomic_dec(&(ipc->busy[msg->channel]));
373 pr_debug("smsg_recv: dst=%d, channel=%d, timeout=%d\n",
374 dst, msg->channel, timeout);
378 if (!mutex_trylock(&(ch->rxlock))) {
379 printk(KERN_INFO "recv smsg busy!\n");
380 atomic_dec(&(ipc->busy[msg->channel]));
386 if (readl(ch->wrptr) == readl(ch->rdptr)) {
387 printk(KERN_WARNING "smsg rx cache is empty!\n");
392 } else if (timeout < 0) {
393 mutex_lock(&(ch->rxlock));
395 rval = wait_event_interruptible(ch->rxwait,
396 (readl(ch->wrptr) != readl(ch->rdptr)) ||
397 (ipc->states[msg->channel] == CHAN_STATE_FREE));
399 printk(KERN_WARNING "smsg_recv wait interrupted!\n");
404 if (ipc->states[msg->channel] == CHAN_STATE_FREE) {
405 printk(KERN_WARNING "smsg_recv smsg channel is free!\n");
411 mutex_lock(&(ch->rxlock));
413 rval = wait_event_interruptible_timeout(ch->rxwait,
414 (readl(ch->wrptr) != readl(ch->rdptr)) ||
415 (ipc->states[msg->channel] == CHAN_STATE_FREE), timeout);
417 printk(KERN_WARNING "smsg_recv wait interrupted!\n");
420 } else if (rval == 0) {
421 printk(KERN_WARNING "smsg_recv wait timeout!\n");
427 if (ipc->states[msg->channel] == CHAN_STATE_FREE) {
428 printk(KERN_ERR "smsg_recv smsg channel is free!\n");
435 /* read smsg from cache */
436 rd = readl(ch->rdptr) & (SMSG_CACHE_NR - 1);
437 memcpy(msg, &(ch->caches[rd]), sizeof(struct smsg));
438 writel(readl(ch->rdptr) + 1, ch->rdptr);
440 pr_debug("read smsg: wrptr=%d, rdptr=%d, rd=%d\n",
441 readl(ch->wrptr), readl(ch->rdptr), rd);
442 pr_debug("recv smsg: channel=%d, type=%d, flag=0x%04x, value=0x%08x\n",
443 msg->channel, msg->type, msg->flag, msg->value);
446 mutex_unlock(&(ch->rxlock));
447 atomic_dec(&(ipc->busy[msg->channel]));
452 #if defined(CONFIG_DEBUG_FS)
453 static int smsg_debug_show(struct seq_file *m, void *private)
455 struct smsg_ipc *smsg_sipc = NULL;
458 for (i = 0; i < SIPC_ID_NR; i++) {
459 smsg_sipc = smsg_ipcs[i];
463 seq_printf(m, "sipc: %s: \n", smsg_sipc->name);
464 seq_printf(m, "dst: 0x%0x, irq: 0x%0x\n",
465 smsg_sipc->dst, smsg_sipc->irq);
466 seq_printf(m, "txbufAddr: 0x%0x, txbufsize: 0x%0x, txbufrdptr: [0x%0x]=%lu, txbufwrptr: [0x%0x]=%lu\n",
467 smsg_sipc->txbuf_addr, smsg_sipc->txbuf_size, smsg_sipc->txbuf_rdptr, readl(smsg_sipc->txbuf_rdptr), smsg_sipc->txbuf_wrptr, readl(smsg_sipc->txbuf_wrptr));
468 seq_printf(m, "rxbufAddr: 0x%0x, rxbufsize: 0x%0x, rxbufrdptr: [0x%0x]=%lu, rxbufwrptr: [0x%0x]=%lu\n",
469 smsg_sipc->rxbuf_addr, smsg_sipc->rxbuf_size, smsg_sipc->rxbuf_rdptr, readl(smsg_sipc->rxbuf_rdptr), smsg_sipc->rxbuf_wrptr, readl(smsg_sipc->rxbuf_wrptr));
471 for (j=0; j<SMSG_CH_NR; j++) {
472 seq_printf(m, "channel[%d] states: %d\n", j, smsg_sipc->states[j]);
478 static int smsg_debug_open(struct inode *inode, struct file *file)
480 return single_open(file, smsg_debug_show, inode->i_private);
483 static const struct file_operations smsg_debug_fops = {
484 .open = smsg_debug_open,
487 .release = single_release,
490 int smsg_init_debugfs(void *root )
494 debugfs_create_file("smsg", S_IRUGO, (struct dentry *)root, NULL, &smsg_debug_fops);
498 #endif /* CONFIG_DEBUG_FS */
500 static int sipc_syscore_suspend(void)
502 int ret = has_wake_lock(WAKE_LOCK_SUSPEND) ? -EAGAIN : 0;
506 static struct syscore_ops sipc_syscore_ops = {
507 .suspend = sipc_syscore_suspend,
510 int smsg_suspend_init(void)
512 wake_lock_init(&sipc_wake_lock, WAKE_LOCK_SUSPEND, "sipc-smsg");
513 register_syscore_ops(&sipc_syscore_ops);
519 EXPORT_SYMBOL(smsg_ch_open);
520 EXPORT_SYMBOL(smsg_ch_close);
521 EXPORT_SYMBOL(smsg_send);
522 EXPORT_SYMBOL(smsg_recv);
524 MODULE_AUTHOR("Chen Gaopeng");
525 MODULE_DESCRIPTION("SIPC/SMSG driver");
526 MODULE_LICENSE("GPL");