2a9b85ca5c0740f8e7079f337925e6454d0adbc0
[safe/jmp/linux-2.6] / arch / arm / mach-msm / smd.c
1 /* arch/arm/mach-msm/smd.c
2  *
3  * Copyright (C) 2007 Google, Inc.
4  * Author: Brian Swetland <swetland@google.com>
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
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  */
16
17 #include <linux/platform_device.h>
18 #include <linux/module.h>
19 #include <linux/fs.h>
20 #include <linux/cdev.h>
21 #include <linux/device.h>
22 #include <linux/wait.h>
23 #include <linux/interrupt.h>
24 #include <linux/irq.h>
25 #include <linux/list.h>
26 #include <linux/slab.h>
27 #include <linux/debugfs.h>
28 #include <linux/delay.h>
29
30 #include <mach/msm_smd.h>
31 #include <mach/system.h>
32
33 #include "smd_private.h"
34 #include "proc_comm.h"
35
36 #if defined(CONFIG_ARCH_QSD8X50)
37 #define CONFIG_QDSP6 1
38 #endif
39
40 void (*msm_hw_reset_hook)(void);
41
42 #define MODULE_NAME "msm_smd"
43
44 enum {
45         MSM_SMD_DEBUG = 1U << 0,
46         MSM_SMSM_DEBUG = 1U << 0,
47 };
48
49 static int msm_smd_debug_mask;
50
51 struct shared_info {
52         int ready;
53         unsigned state;
54 };
55
56 static unsigned dummy_state[SMSM_STATE_COUNT];
57
58 static struct shared_info smd_info = {
59         .state = (unsigned) &dummy_state,
60 };
61
62 module_param_named(debug_mask, msm_smd_debug_mask,
63                    int, S_IRUGO | S_IWUSR | S_IWGRP);
64
65 void *smem_item(unsigned id, unsigned *size);
66 static void smd_diag(void);
67
68 static unsigned last_heap_free = 0xffffffff;
69
70 static inline void notify_other_smsm(void)
71 {
72         msm_a2m_int(5);
73 #ifdef CONFIG_QDSP6
74         msm_a2m_int(8);
75 #endif
76 }
77
78 static inline void notify_modem_smd(void)
79 {
80         msm_a2m_int(0);
81 }
82
83 static inline void notify_dsp_smd(void)
84 {
85         msm_a2m_int(8);
86 }
87
88 static void smd_diag(void)
89 {
90         char *x;
91
92         x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
93         if (x != 0) {
94                 x[SZ_DIAG_ERR_MSG - 1] = 0;
95                 pr_info("smem: DIAG '%s'\n", x);
96         }
97 }
98
99 /* call when SMSM_RESET flag is set in the A9's smsm_state */
100 static void handle_modem_crash(void)
101 {
102         pr_err("ARM9 has CRASHED\n");
103         smd_diag();
104
105         /* hard reboot if possible */
106         if (msm_hw_reset_hook)
107                 msm_hw_reset_hook();
108
109         /* in this case the modem or watchdog should reboot us */
110         for (;;)
111                 ;
112 }
113
114 uint32_t raw_smsm_get_state(enum smsm_state_item item)
115 {
116         return readl(smd_info.state + item * 4);
117 }
118
119 static int check_for_modem_crash(void)
120 {
121         if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET) {
122                 handle_modem_crash();
123                 return -1;
124         }
125         return 0;
126 }
127
128 /* the spinlock is used to synchronize between the
129  * irq handler and code that mutates the channel
130  * list or fiddles with channel state
131  */
132 DEFINE_SPINLOCK(smd_lock);
133 DEFINE_SPINLOCK(smem_lock);
134
135 /* the mutex is used during open() and close()
136  * operations to avoid races while creating or
137  * destroying smd_channel structures
138  */
139 static DEFINE_MUTEX(smd_creation_mutex);
140
141 static int smd_initialized;
142
143 LIST_HEAD(smd_ch_closed_list);
144 LIST_HEAD(smd_ch_list_modem);
145 LIST_HEAD(smd_ch_list_dsp);
146
147 static unsigned char smd_ch_allocated[64];
148 static struct work_struct probe_work;
149
150 static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type);
151
152 static void smd_channel_probe_worker(struct work_struct *work)
153 {
154         struct smd_alloc_elm *shared;
155         unsigned ctype;
156         unsigned type;
157         unsigned n;
158
159         shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
160         if (!shared) {
161                 pr_err("smd: cannot find allocation table\n");
162                 return;
163         }
164         for (n = 0; n < 64; n++) {
165                 if (smd_ch_allocated[n])
166                         continue;
167                 if (!shared[n].ref_count)
168                         continue;
169                 if (!shared[n].name[0])
170                         continue;
171                 ctype = shared[n].ctype;
172                 type = ctype & SMD_TYPE_MASK;
173
174                 /* DAL channels are stream but neither the modem,
175                  * nor the DSP correctly indicate this.  Fixup manually.
176                  */
177                 if (!memcmp(shared[n].name, "DAL", 3))
178                         ctype = (ctype & (~SMD_KIND_MASK)) | SMD_KIND_STREAM;
179
180                 type = shared[n].ctype & SMD_TYPE_MASK;
181                 if ((type == SMD_TYPE_APPS_MODEM) ||
182                     (type == SMD_TYPE_APPS_DSP))
183                         if (!smd_alloc_channel(shared[n].name, shared[n].cid, ctype))
184                                 smd_ch_allocated[n] = 1;
185         }
186 }
187
188 /* how many bytes are available for reading */
189 static int smd_stream_read_avail(struct smd_channel *ch)
190 {
191         return (ch->recv->head - ch->recv->tail) & ch->fifo_mask;
192 }
193
194 /* how many bytes we are free to write */
195 static int smd_stream_write_avail(struct smd_channel *ch)
196 {
197         return ch->fifo_mask -
198                 ((ch->send->head - ch->send->tail) & ch->fifo_mask);
199 }
200
201 static int smd_packet_read_avail(struct smd_channel *ch)
202 {
203         if (ch->current_packet) {
204                 int n = smd_stream_read_avail(ch);
205                 if (n > ch->current_packet)
206                         n = ch->current_packet;
207                 return n;
208         } else {
209                 return 0;
210         }
211 }
212
213 static int smd_packet_write_avail(struct smd_channel *ch)
214 {
215         int n = smd_stream_write_avail(ch);
216         return n > SMD_HEADER_SIZE ? n - SMD_HEADER_SIZE : 0;
217 }
218
219 static int ch_is_open(struct smd_channel *ch)
220 {
221         return (ch->recv->state == SMD_SS_OPENED) &&
222                 (ch->send->state == SMD_SS_OPENED);
223 }
224
225 /* provide a pointer and length to readable data in the fifo */
226 static unsigned ch_read_buffer(struct smd_channel *ch, void **ptr)
227 {
228         unsigned head = ch->recv->head;
229         unsigned tail = ch->recv->tail;
230         *ptr = (void *) (ch->recv_data + tail);
231
232         if (tail <= head)
233                 return head - tail;
234         else
235                 return ch->fifo_size - tail;
236 }
237
238 /* advance the fifo read pointer after data from ch_read_buffer is consumed */
239 static void ch_read_done(struct smd_channel *ch, unsigned count)
240 {
241         BUG_ON(count > smd_stream_read_avail(ch));
242         ch->recv->tail = (ch->recv->tail + count) & ch->fifo_mask;
243         ch->send->fTAIL = 1;
244 }
245
246 /* basic read interface to ch_read_{buffer,done} used
247  * by smd_*_read() and update_packet_state()
248  * will read-and-discard if the _data pointer is null
249  */
250 static int ch_read(struct smd_channel *ch, void *_data, int len)
251 {
252         void *ptr;
253         unsigned n;
254         unsigned char *data = _data;
255         int orig_len = len;
256
257         while (len > 0) {
258                 n = ch_read_buffer(ch, &ptr);
259                 if (n == 0)
260                         break;
261
262                 if (n > len)
263                         n = len;
264                 if (_data)
265                         memcpy(data, ptr, n);
266
267                 data += n;
268                 len -= n;
269                 ch_read_done(ch, n);
270         }
271
272         return orig_len - len;
273 }
274
275 static void update_stream_state(struct smd_channel *ch)
276 {
277         /* streams have no special state requiring updating */
278 }
279
280 static void update_packet_state(struct smd_channel *ch)
281 {
282         unsigned hdr[5];
283         int r;
284
285         /* can't do anything if we're in the middle of a packet */
286         if (ch->current_packet != 0)
287                 return;
288
289         /* don't bother unless we can get the full header */
290         if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE)
291                 return;
292
293         r = ch_read(ch, hdr, SMD_HEADER_SIZE);
294         BUG_ON(r != SMD_HEADER_SIZE);
295
296         ch->current_packet = hdr[0];
297 }
298
299 /* provide a pointer and length to next free space in the fifo */
300 static unsigned ch_write_buffer(struct smd_channel *ch, void **ptr)
301 {
302         unsigned head = ch->send->head;
303         unsigned tail = ch->send->tail;
304         *ptr = (void *) (ch->send_data + head);
305
306         if (head < tail) {
307                 return tail - head - 1;
308         } else {
309                 if (tail == 0)
310                         return ch->fifo_size - head - 1;
311                 else
312                         return ch->fifo_size - head;
313         }
314 }
315
316 /* advace the fifo write pointer after freespace
317  * from ch_write_buffer is filled
318  */
319 static void ch_write_done(struct smd_channel *ch, unsigned count)
320 {
321         BUG_ON(count > smd_stream_write_avail(ch));
322         ch->send->head = (ch->send->head + count) & ch->fifo_mask;
323         ch->send->fHEAD = 1;
324 }
325
326 static void ch_set_state(struct smd_channel *ch, unsigned n)
327 {
328         if (n == SMD_SS_OPENED) {
329                 ch->send->fDSR = 1;
330                 ch->send->fCTS = 1;
331                 ch->send->fCD = 1;
332         } else {
333                 ch->send->fDSR = 0;
334                 ch->send->fCTS = 0;
335                 ch->send->fCD = 0;
336         }
337         ch->send->state = n;
338         ch->send->fSTATE = 1;
339         ch->notify_other_cpu();
340 }
341
342 static void do_smd_probe(void)
343 {
344         struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
345         if (shared->heap_info.free_offset != last_heap_free) {
346                 last_heap_free = shared->heap_info.free_offset;
347                 schedule_work(&probe_work);
348         }
349 }
350
351 static void smd_state_change(struct smd_channel *ch,
352                              unsigned last, unsigned next)
353 {
354         ch->last_state = next;
355
356         pr_info("SMD: ch %d %d -> %d\n", ch->n, last, next);
357
358         switch (next) {
359         case SMD_SS_OPENING:
360                 ch->recv->tail = 0;
361         case SMD_SS_OPENED:
362                 if (ch->send->state != SMD_SS_OPENED)
363                         ch_set_state(ch, SMD_SS_OPENED);
364                 ch->notify(ch->priv, SMD_EVENT_OPEN);
365                 break;
366         case SMD_SS_FLUSHING:
367         case SMD_SS_RESET:
368                 /* we should force them to close? */
369         default:
370                 ch->notify(ch->priv, SMD_EVENT_CLOSE);
371         }
372 }
373
374 static void handle_smd_irq(struct list_head *list, void (*notify)(void))
375 {
376         unsigned long flags;
377         struct smd_channel *ch;
378         int do_notify = 0;
379         unsigned ch_flags;
380         unsigned tmp;
381
382         spin_lock_irqsave(&smd_lock, flags);
383         list_for_each_entry(ch, list, ch_list) {
384                 ch_flags = 0;
385                 if (ch_is_open(ch)) {
386                         if (ch->recv->fHEAD) {
387                                 ch->recv->fHEAD = 0;
388                                 ch_flags |= 1;
389                                 do_notify |= 1;
390                         }
391                         if (ch->recv->fTAIL) {
392                                 ch->recv->fTAIL = 0;
393                                 ch_flags |= 2;
394                                 do_notify |= 1;
395                         }
396                         if (ch->recv->fSTATE) {
397                                 ch->recv->fSTATE = 0;
398                                 ch_flags |= 4;
399                                 do_notify |= 1;
400                         }
401                 }
402                 tmp = ch->recv->state;
403                 if (tmp != ch->last_state)
404                         smd_state_change(ch, ch->last_state, tmp);
405                 if (ch_flags) {
406                         ch->update_state(ch);
407                         ch->notify(ch->priv, SMD_EVENT_DATA);
408                 }
409         }
410         if (do_notify)
411                 notify();
412         spin_unlock_irqrestore(&smd_lock, flags);
413         do_smd_probe();
414 }
415
416 static irqreturn_t smd_modem_irq_handler(int irq, void *data)
417 {
418         handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
419         return IRQ_HANDLED;
420 }
421
422 static irqreturn_t smd_dsp_irq_handler(int irq, void *data)
423 {
424         handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
425         return IRQ_HANDLED;
426 }
427
428 static void smd_fake_irq_handler(unsigned long arg)
429 {
430         handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
431         handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
432 }
433
434 static DECLARE_TASKLET(smd_fake_irq_tasklet, smd_fake_irq_handler, 0);
435
436 static inline int smd_need_int(struct smd_channel *ch)
437 {
438         if (ch_is_open(ch)) {
439                 if (ch->recv->fHEAD || ch->recv->fTAIL || ch->recv->fSTATE)
440                         return 1;
441                 if (ch->recv->state != ch->last_state)
442                         return 1;
443         }
444         return 0;
445 }
446
447 void smd_sleep_exit(void)
448 {
449         unsigned long flags;
450         struct smd_channel *ch;
451         int need_int = 0;
452
453         spin_lock_irqsave(&smd_lock, flags);
454         list_for_each_entry(ch, &smd_ch_list_modem, ch_list) {
455                 if (smd_need_int(ch)) {
456                         need_int = 1;
457                         break;
458                 }
459         }
460         list_for_each_entry(ch, &smd_ch_list_dsp, ch_list) {
461                 if (smd_need_int(ch)) {
462                         need_int = 1;
463                         break;
464                 }
465         }
466         spin_unlock_irqrestore(&smd_lock, flags);
467         do_smd_probe();
468
469         if (need_int) {
470                 if (msm_smd_debug_mask & MSM_SMD_DEBUG)
471                         pr_info("smd_sleep_exit need interrupt\n");
472                 tasklet_schedule(&smd_fake_irq_tasklet);
473         }
474 }
475
476
477 void smd_kick(smd_channel_t *ch)
478 {
479         unsigned long flags;
480         unsigned tmp;
481
482         spin_lock_irqsave(&smd_lock, flags);
483         ch->update_state(ch);
484         tmp = ch->recv->state;
485         if (tmp != ch->last_state) {
486                 ch->last_state = tmp;
487                 if (tmp == SMD_SS_OPENED)
488                         ch->notify(ch->priv, SMD_EVENT_OPEN);
489                 else
490                         ch->notify(ch->priv, SMD_EVENT_CLOSE);
491         }
492         ch->notify(ch->priv, SMD_EVENT_DATA);
493         ch->notify_other_cpu();
494         spin_unlock_irqrestore(&smd_lock, flags);
495 }
496
497 static int smd_is_packet(int chn, unsigned type)
498 {
499         type &= SMD_KIND_MASK;
500         if (type == SMD_KIND_PACKET)
501                 return 1;
502         if (type == SMD_KIND_STREAM)
503                 return 0;
504
505         /* older AMSS reports SMD_KIND_UNKNOWN always */
506         if ((chn > 4) || (chn == 1))
507                 return 1;
508         else
509                 return 0;
510 }
511
512 static int smd_stream_write(smd_channel_t *ch, const void *_data, int len)
513 {
514         void *ptr;
515         const unsigned char *buf = _data;
516         unsigned xfer;
517         int orig_len = len;
518
519         if (len < 0)
520                 return -EINVAL;
521
522         while ((xfer = ch_write_buffer(ch, &ptr)) != 0) {
523                 if (!ch_is_open(ch))
524                         break;
525                 if (xfer > len)
526                         xfer = len;
527                 memcpy(ptr, buf, xfer);
528                 ch_write_done(ch, xfer);
529                 len -= xfer;
530                 buf += xfer;
531                 if (len == 0)
532                         break;
533         }
534
535         ch->notify_other_cpu();
536
537         return orig_len - len;
538 }
539
540 static int smd_packet_write(smd_channel_t *ch, const void *_data, int len)
541 {
542         unsigned hdr[5];
543
544         if (len < 0)
545                 return -EINVAL;
546
547         if (smd_stream_write_avail(ch) < (len + SMD_HEADER_SIZE))
548                 return -ENOMEM;
549
550         hdr[0] = len;
551         hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0;
552
553         smd_stream_write(ch, hdr, sizeof(hdr));
554         smd_stream_write(ch, _data, len);
555
556         return len;
557 }
558
559 static int smd_stream_read(smd_channel_t *ch, void *data, int len)
560 {
561         int r;
562
563         if (len < 0)
564                 return -EINVAL;
565
566         r = ch_read(ch, data, len);
567         if (r > 0)
568                 ch->notify_other_cpu();
569
570         return r;
571 }
572
573 static int smd_packet_read(smd_channel_t *ch, void *data, int len)
574 {
575         unsigned long flags;
576         int r;
577
578         if (len < 0)
579                 return -EINVAL;
580
581         if (len > ch->current_packet)
582                 len = ch->current_packet;
583
584         r = ch_read(ch, data, len);
585         if (r > 0)
586                 ch->notify_other_cpu();
587
588         spin_lock_irqsave(&smd_lock, flags);
589         ch->current_packet -= r;
590         update_packet_state(ch);
591         spin_unlock_irqrestore(&smd_lock, flags);
592
593         return r;
594 }
595
596 static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type)
597 {
598         struct smd_channel *ch;
599
600         ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL);
601         if (ch == 0) {
602                 pr_err("smd_alloc_channel() out of memory\n");
603                 return -1;
604         }
605         ch->n = cid;
606
607         if (_smd_alloc_channel(ch)) {
608                 kfree(ch);
609                 return -1;
610         }
611
612         ch->fifo_mask = ch->fifo_size - 1;
613         ch->type = type;
614
615         if ((type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
616                 ch->notify_other_cpu = notify_modem_smd;
617         else
618                 ch->notify_other_cpu = notify_dsp_smd;
619
620         if (smd_is_packet(cid, type)) {
621                 ch->read = smd_packet_read;
622                 ch->write = smd_packet_write;
623                 ch->read_avail = smd_packet_read_avail;
624                 ch->write_avail = smd_packet_write_avail;
625                 ch->update_state = update_packet_state;
626         } else {
627                 ch->read = smd_stream_read;
628                 ch->write = smd_stream_write;
629                 ch->read_avail = smd_stream_read_avail;
630                 ch->write_avail = smd_stream_write_avail;
631                 ch->update_state = update_stream_state;
632         }
633
634         if ((type & 0xff) == 0)
635                 memcpy(ch->name, "SMD_", 4);
636         else
637                 memcpy(ch->name, "DSP_", 4);
638         memcpy(ch->name + 4, name, 20);
639         ch->name[23] = 0;
640         ch->pdev.name = ch->name;
641         ch->pdev.id = -1;
642
643         pr_info("smd_alloc_channel() cid=%02d size=%05d '%s'\n",
644                 ch->n, ch->fifo_size, ch->name);
645
646         mutex_lock(&smd_creation_mutex);
647         list_add(&ch->ch_list, &smd_ch_closed_list);
648         mutex_unlock(&smd_creation_mutex);
649
650         platform_device_register(&ch->pdev);
651         return 0;
652 }
653
654 static void do_nothing_notify(void *priv, unsigned flags)
655 {
656 }
657
658 struct smd_channel *smd_get_channel(const char *name)
659 {
660         struct smd_channel *ch;
661
662         mutex_lock(&smd_creation_mutex);
663         list_for_each_entry(ch, &smd_ch_closed_list, ch_list) {
664                 if (!strcmp(name, ch->name)) {
665                         list_del(&ch->ch_list);
666                         mutex_unlock(&smd_creation_mutex);
667                         return ch;
668                 }
669         }
670         mutex_unlock(&smd_creation_mutex);
671
672         return NULL;
673 }
674
675 int smd_open(const char *name, smd_channel_t **_ch,
676              void *priv, void (*notify)(void *, unsigned))
677 {
678         struct smd_channel *ch;
679         unsigned long flags;
680
681         if (smd_initialized == 0) {
682                 pr_info("smd_open() before smd_init()\n");
683                 return -ENODEV;
684         }
685
686         ch = smd_get_channel(name);
687         if (!ch)
688                 return -ENODEV;
689
690         if (notify == 0)
691                 notify = do_nothing_notify;
692
693         ch->notify = notify;
694         ch->current_packet = 0;
695         ch->last_state = SMD_SS_CLOSED;
696         ch->priv = priv;
697
698         *_ch = ch;
699
700         spin_lock_irqsave(&smd_lock, flags);
701
702         if ((ch->type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
703                 list_add(&ch->ch_list, &smd_ch_list_modem);
704         else
705                 list_add(&ch->ch_list, &smd_ch_list_dsp);
706
707         /* If the remote side is CLOSING, we need to get it to
708          * move to OPENING (which we'll do by moving from CLOSED to
709          * OPENING) and then get it to move from OPENING to
710          * OPENED (by doing the same state change ourselves).
711          *
712          * Otherwise, it should be OPENING and we can move directly
713          * to OPENED so that it will follow.
714          */
715         if (ch->recv->state == SMD_SS_CLOSING) {
716                 ch->send->head = 0;
717                 ch_set_state(ch, SMD_SS_OPENING);
718         } else {
719                 ch_set_state(ch, SMD_SS_OPENED);
720         }
721         spin_unlock_irqrestore(&smd_lock, flags);
722         smd_kick(ch);
723
724         return 0;
725 }
726
727 int smd_close(smd_channel_t *ch)
728 {
729         unsigned long flags;
730
731         pr_info("smd_close(%p)\n", ch);
732
733         if (ch == 0)
734                 return -1;
735
736         spin_lock_irqsave(&smd_lock, flags);
737         ch->notify = do_nothing_notify;
738         list_del(&ch->ch_list);
739         ch_set_state(ch, SMD_SS_CLOSED);
740         spin_unlock_irqrestore(&smd_lock, flags);
741
742         mutex_lock(&smd_creation_mutex);
743         list_add(&ch->ch_list, &smd_ch_closed_list);
744         mutex_unlock(&smd_creation_mutex);
745
746         return 0;
747 }
748
749 int smd_read(smd_channel_t *ch, void *data, int len)
750 {
751         return ch->read(ch, data, len);
752 }
753
754 int smd_write(smd_channel_t *ch, const void *data, int len)
755 {
756         return ch->write(ch, data, len);
757 }
758
759 int smd_write_atomic(smd_channel_t *ch, const void *data, int len)
760 {
761         unsigned long flags;
762         int res;
763         spin_lock_irqsave(&smd_lock, flags);
764         res = ch->write(ch, data, len);
765         spin_unlock_irqrestore(&smd_lock, flags);
766         return res;
767 }
768
769 int smd_read_avail(smd_channel_t *ch)
770 {
771         return ch->read_avail(ch);
772 }
773
774 int smd_write_avail(smd_channel_t *ch)
775 {
776         return ch->write_avail(ch);
777 }
778
779 int smd_wait_until_readable(smd_channel_t *ch, int bytes)
780 {
781         return -1;
782 }
783
784 int smd_wait_until_writable(smd_channel_t *ch, int bytes)
785 {
786         return -1;
787 }
788
789 int smd_cur_packet_size(smd_channel_t *ch)
790 {
791         return ch->current_packet;
792 }
793
794
795 /* ------------------------------------------------------------------------- */
796
797 void *smem_alloc(unsigned id, unsigned size)
798 {
799         return smem_find(id, size);
800 }
801
802 void *smem_item(unsigned id, unsigned *size)
803 {
804         struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
805         struct smem_heap_entry *toc = shared->heap_toc;
806
807         if (id >= SMEM_NUM_ITEMS)
808                 return 0;
809
810         if (toc[id].allocated) {
811                 *size = toc[id].size;
812                 return (void *) (MSM_SHARED_RAM_BASE + toc[id].offset);
813         } else {
814                 *size = 0;
815         }
816
817         return 0;
818 }
819
820 void *smem_find(unsigned id, unsigned size_in)
821 {
822         unsigned size;
823         void *ptr;
824
825         ptr = smem_item(id, &size);
826         if (!ptr)
827                 return 0;
828
829         size_in = ALIGN(size_in, 8);
830         if (size_in != size) {
831                 pr_err("smem_find(%d, %d): wrong size %d\n",
832                        id, size_in, size);
833                 return 0;
834         }
835
836         return ptr;
837 }
838
839 static irqreturn_t smsm_irq_handler(int irq, void *data)
840 {
841         unsigned long flags;
842         unsigned apps, modm;
843
844         spin_lock_irqsave(&smem_lock, flags);
845
846         apps = raw_smsm_get_state(SMSM_STATE_APPS);
847         modm = raw_smsm_get_state(SMSM_STATE_MODEM);
848
849         if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
850                 pr_info("<SM %08x %08x>\n", apps, modm);
851         if (modm & SMSM_RESET)
852                 handle_modem_crash();
853
854         do_smd_probe();
855
856         spin_unlock_irqrestore(&smem_lock, flags);
857         return IRQ_HANDLED;
858 }
859
860 int smsm_change_state(enum smsm_state_item item,
861                       uint32_t clear_mask, uint32_t set_mask)
862 {
863         unsigned long addr = smd_info.state + item * 4;
864         unsigned long flags;
865         unsigned state;
866
867         if (!smd_info.ready)
868                 return -EIO;
869
870         spin_lock_irqsave(&smem_lock, flags);
871
872         if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET)
873                 handle_modem_crash();
874
875         state = (readl(addr) & ~clear_mask) | set_mask;
876         writel(state, addr);
877
878         if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
879                 pr_info("smsm_change_state %d %x\n", item, state);
880         notify_other_smsm();
881
882         spin_unlock_irqrestore(&smem_lock, flags);
883
884         return 0;
885 }
886
887 uint32_t smsm_get_state(enum smsm_state_item item)
888 {
889         unsigned long flags;
890         uint32_t rv;
891
892         spin_lock_irqsave(&smem_lock, flags);
893
894         rv = readl(smd_info.state + item * 4);
895
896         if (item == SMSM_STATE_MODEM && (rv & SMSM_RESET))
897                 handle_modem_crash();
898
899         spin_unlock_irqrestore(&smem_lock, flags);
900
901         return rv;
902 }
903
904 #ifdef CONFIG_ARCH_MSM_SCORPION
905
906 int smsm_set_sleep_duration(uint32_t delay)
907 {
908         struct msm_dem_slave_data *ptr;
909
910         ptr = smem_find(SMEM_APPS_DEM_SLAVE_DATA, sizeof(*ptr));
911         if (ptr == NULL) {
912                 pr_err("smsm_set_sleep_duration <SM NO APPS_DEM_SLAVE_DATA>\n");
913                 return -EIO;
914         }
915         if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
916                 pr_info("smsm_set_sleep_duration %d -> %d\n",
917                        ptr->sleep_time, delay);
918         ptr->sleep_time = delay;
919         return 0;
920 }
921
922 #else
923
924 int smsm_set_sleep_duration(uint32_t delay)
925 {
926         uint32_t *ptr;
927
928         ptr = smem_find(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
929         if (ptr == NULL) {
930                 pr_err("smsm_set_sleep_duration <SM NO SLEEP_DELAY>\n");
931                 return -EIO;
932         }
933         if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
934                 pr_info("smsm_set_sleep_duration %d -> %d\n",
935                        *ptr, delay);
936         *ptr = delay;
937         return 0;
938 }
939
940 #endif
941
942 int smd_core_init(void)
943 {
944         int r;
945         pr_info("smd_core_init()\n");
946
947         /* wait for essential items to be initialized */
948         for (;;) {
949                 unsigned size;
950                 void *state;
951                 state = smem_item(SMEM_SMSM_SHARED_STATE, &size);
952                 if (size == SMSM_V1_SIZE || size == SMSM_V2_SIZE) {
953                         smd_info.state = (unsigned)state;
954                         break;
955                 }
956         }
957
958         smd_info.ready = 1;
959
960         r = request_irq(INT_A9_M2A_0, smd_modem_irq_handler,
961                         IRQF_TRIGGER_RISING, "smd_dev", 0);
962         if (r < 0)
963                 return r;
964         r = enable_irq_wake(INT_A9_M2A_0);
965         if (r < 0)
966                 pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_0\n");
967
968         r = request_irq(INT_A9_M2A_5, smsm_irq_handler,
969                         IRQF_TRIGGER_RISING, "smsm_dev", 0);
970         if (r < 0) {
971                 free_irq(INT_A9_M2A_0, 0);
972                 return r;
973         }
974         r = enable_irq_wake(INT_A9_M2A_5);
975         if (r < 0)
976                 pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n");
977
978 #if defined(CONFIG_QDSP6)
979         r = request_irq(INT_ADSP_A11, smd_dsp_irq_handler,
980                         IRQF_TRIGGER_RISING, "smd_dsp", 0);
981         if (r < 0) {
982                 free_irq(INT_A9_M2A_0, 0);
983                 free_irq(INT_A9_M2A_5, 0);
984                 return r;
985         }
986 #endif
987
988         /* check for any SMD channels that may already exist */
989         do_smd_probe();
990
991         /* indicate that we're up and running */
992         smsm_change_state(SMSM_STATE_APPS,
993                           ~0, SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT | SMSM_RUN);
994 #ifdef CONFIG_ARCH_MSM_SCORPION
995         smsm_change_state(SMSM_STATE_APPS_DEM, ~0, 0);
996 #endif
997
998         pr_info("smd_core_init() done\n");
999
1000         return 0;
1001 }
1002
1003 static int __init msm_smd_probe(struct platform_device *pdev)
1004 {
1005         pr_info("smd_init()\n");
1006
1007         INIT_WORK(&probe_work, smd_channel_probe_worker);
1008
1009         if (smd_core_init()) {
1010                 pr_err("smd_core_init() failed\n");
1011                 return -1;
1012         }
1013
1014         do_smd_probe();
1015
1016         msm_check_for_modem_crash = check_for_modem_crash;
1017
1018         msm_init_last_radio_log(THIS_MODULE);
1019
1020         smd_initialized = 1;
1021
1022         return 0;
1023 }
1024
1025 static struct platform_driver msm_smd_driver = {
1026         .probe = msm_smd_probe,
1027         .driver = {
1028                 .name = MODULE_NAME,
1029                 .owner = THIS_MODULE,
1030         },
1031 };
1032
1033 static int __init msm_smd_init(void)
1034 {
1035         return platform_driver_register(&msm_smd_driver);
1036 }
1037
1038 module_init(msm_smd_init);
1039
1040 MODULE_DESCRIPTION("MSM Shared Memory Core");
1041 MODULE_AUTHOR("Brian Swetland <swetland@google.com>");
1042 MODULE_LICENSE("GPL");