aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorBrian Swetland <swetland@google.com>2009-07-01 21:30:47 -0400
committerDaniel Walker <dwalker@codeaurora.org>2010-05-12 12:15:11 -0400
commit37521a3181123dc4a9584cc4b8572c08ea0a8274 (patch)
tree1e5571657f48baa7e2a8b5763fc33da583be878c /arch/arm
parent03e00cd350c6636b5f2a9854609fea93a5c7b677 (diff)
[ARM] msm: smd: add support for DSP SMD channels
- QSD8250 has a DSP that speaks SMD, in addition to the modem - handle a separate list of modem vs dsp channels - install dsp smd irq handler as necessary Signed-off-by: Brian Swetland <swetland@google.com> Signed-off-by: Daniel Walker <dwalker@codeaurora.org>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-msm/smd.c114
-rw-r--r--arch/arm/mach-msm/smd_debug.c9
-rw-r--r--arch/arm/mach-msm/smd_private.h3
3 files changed, 76 insertions, 50 deletions
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index 1aaee4d70863..a88a8fc05f86 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -35,6 +35,10 @@
35#include "smd_private.h" 35#include "smd_private.h"
36#include "proc_comm.h" 36#include "proc_comm.h"
37 37
38#if defined(CONFIG_ARCH_QSD8X50)
39#define CONFIG_QDSP6 1
40#endif
41
38void (*msm_hw_reset_hook)(void); 42void (*msm_hw_reset_hook)(void);
39 43
40#define MODULE_NAME "msm_smd" 44#define MODULE_NAME "msm_smd"
@@ -70,6 +74,9 @@ static unsigned last_heap_free = 0xffffffff;
70static inline void notify_other_smsm(void) 74static inline void notify_other_smsm(void)
71{ 75{
72 writel(1, MSM_A2M_INT(5)); 76 writel(1, MSM_A2M_INT(5));
77#ifdef CONFIG_QDSP6
78 writel(1, MSM_A2M_INT(8));
79#endif
73} 80}
74 81
75static inline void notify_modem_smd(void) 82static inline void notify_modem_smd(void)
@@ -140,7 +147,8 @@ static DEFINE_MUTEX(smd_creation_mutex);
140static int smd_initialized; 147static int smd_initialized;
141 148
142LIST_HEAD(smd_ch_closed_list); 149LIST_HEAD(smd_ch_closed_list);
143LIST_HEAD(smd_ch_list); /* todo: per-target lists */ 150LIST_HEAD(smd_ch_list_modem);
151LIST_HEAD(smd_ch_list_dsp);
144 152
145static unsigned char smd_ch_allocated[64]; 153static unsigned char smd_ch_allocated[64];
146static struct work_struct probe_work; 154static struct work_struct probe_work;
@@ -150,6 +158,7 @@ static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type);
150static void smd_channel_probe_worker(struct work_struct *work) 158static void smd_channel_probe_worker(struct work_struct *work)
151{ 159{
152 struct smd_alloc_elm *shared; 160 struct smd_alloc_elm *shared;
161 unsigned ctype;
153 unsigned type; 162 unsigned type;
154 unsigned n; 163 unsigned n;
155 164
@@ -165,12 +174,19 @@ static void smd_channel_probe_worker(struct work_struct *work)
165 continue; 174 continue;
166 if (!shared[n].name[0]) 175 if (!shared[n].name[0])
167 continue; 176 continue;
177 ctype = shared[n].ctype;
178 type = ctype & SMD_TYPE_MASK;
179
180 /* DAL channels are stream but neither the modem,
181 * nor the DSP correctly indicate this. Fixup manually.
182 */
183 if (!memcmp(shared[n].name, "DAL", 3))
184 ctype = (ctype & (~SMD_KIND_MASK)) | SMD_KIND_STREAM;
185
168 type = shared[n].ctype & SMD_TYPE_MASK; 186 type = shared[n].ctype & SMD_TYPE_MASK;
169 if ((type == SMD_TYPE_APPS_MODEM) || 187 if ((type == SMD_TYPE_APPS_MODEM) ||
170 (type == SMD_TYPE_APPS_DSP)) 188 (type == SMD_TYPE_APPS_DSP))
171 smd_alloc_channel(shared[n].name, 189 smd_alloc_channel(shared[n].name, shared[n].cid, ctype);
172 shared[n].cid,
173 shared[n].ctype);
174 smd_ch_allocated[n] = 1; 190 smd_ch_allocated[n] = 1;
175 } 191 }
176} 192}
@@ -403,67 +419,59 @@ static void handle_smd_irq(struct list_head *list, void (*notify)(void))
403 do_smd_probe(); 419 do_smd_probe();
404} 420}
405 421
406static irqreturn_t smd_irq_handler(int irq, void *data) 422static irqreturn_t smd_modem_irq_handler(int irq, void *data)
423{
424 handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
425 return IRQ_HANDLED;
426}
427
428static irqreturn_t smd_dsp_irq_handler(int irq, void *data)
407{ 429{
408 handle_smd_irq(&smd_ch_list, notify_modem_smd); 430 handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
409 return IRQ_HANDLED; 431 return IRQ_HANDLED;
410} 432}
411 433
412static void smd_fake_irq_handler(unsigned long arg) 434static void smd_fake_irq_handler(unsigned long arg)
413{ 435{
414 smd_irq_handler(0, NULL); 436 handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
437 handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
415} 438}
416 439
417static DECLARE_TASKLET(smd_fake_irq_tasklet, smd_fake_irq_handler, 0); 440static DECLARE_TASKLET(smd_fake_irq_tasklet, smd_fake_irq_handler, 0);
418 441
442static inline int smd_need_int(struct smd_channel *ch)
443{
444 if (ch_is_open(ch)) {
445 if (ch->recv->fHEAD || ch->recv->fTAIL || ch->recv->fSTATE)
446 return 1;
447 if (ch->recv->state != ch->last_state)
448 return 1;
449 }
450 return 0;
451}
452
419void smd_sleep_exit(void) 453void smd_sleep_exit(void)
420{ 454{
421 unsigned long flags; 455 unsigned long flags;
422 struct smd_channel *ch; 456 struct smd_channel *ch;
423 unsigned tmp;
424 int need_int = 0; 457 int need_int = 0;
425 458
426 spin_lock_irqsave(&smd_lock, flags); 459 spin_lock_irqsave(&smd_lock, flags);
427 list_for_each_entry(ch, &smd_ch_list, ch_list) { 460 list_for_each_entry(ch, &smd_ch_list_modem, ch_list) {
428 if (ch_is_open(ch)) { 461 if (smd_need_int(ch)) {
429 if (ch->recv->fHEAD) { 462 need_int = 1;
430 if (msm_smd_debug_mask & MSM_SMD_DEBUG) 463 break;
431 pr_info("smd_sleep_exit ch %d fHEAD " 464 }
432 "%x %x %x\n", 465 }
433 ch->n, ch->recv->fHEAD, 466 list_for_each_entry(ch, &smd_ch_list_dsp, ch_list) {
434 ch->recv->head, ch->recv->tail); 467 if (smd_need_int(ch)) {
435 need_int = 1; 468 need_int = 1;
436 break; 469 break;
437 }
438 if (ch->recv->fTAIL) {
439 if (msm_smd_debug_mask & MSM_SMD_DEBUG)
440 pr_info("smd_sleep_exit ch %d fTAIL "
441 "%x %x %x\n",
442 ch->n, ch->recv->fTAIL,
443 ch->send->head, ch->send->tail);
444 need_int = 1;
445 break;
446 }
447 if (ch->recv->fSTATE) {
448 if (msm_smd_debug_mask & MSM_SMD_DEBUG)
449 pr_info("smd_sleep_exit ch %d fSTATE %x"
450 "\n", ch->n, ch->recv->fSTATE);
451 need_int = 1;
452 break;
453 }
454 tmp = ch->recv->state;
455 if (tmp != ch->last_state) {
456 if (msm_smd_debug_mask & MSM_SMD_DEBUG)
457 pr_info("smd_sleep_exit ch %d "
458 "state %x != %x\n",
459 ch->n, tmp, ch->last_state);
460 need_int = 1;
461 break;
462 }
463 } 470 }
464 } 471 }
465 spin_unlock_irqrestore(&smd_lock, flags); 472 spin_unlock_irqrestore(&smd_lock, flags);
466 do_smd_probe(); 473 do_smd_probe();
474
467 if (need_int) { 475 if (need_int) {
468 if (msm_smd_debug_mask & MSM_SMD_DEBUG) 476 if (msm_smd_debug_mask & MSM_SMD_DEBUG)
469 pr_info("smd_sleep_exit need interrupt\n"); 477 pr_info("smd_sleep_exit need interrupt\n");
@@ -737,7 +745,11 @@ int smd_open(const char *name, smd_channel_t **_ch,
737 *_ch = ch; 745 *_ch = ch;
738 746
739 spin_lock_irqsave(&smd_lock, flags); 747 spin_lock_irqsave(&smd_lock, flags);
740 list_add(&ch->ch_list, &smd_ch_list); 748
749 if ((ch->type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
750 list_add(&ch->ch_list, &smd_ch_list_modem);
751 else
752 list_add(&ch->ch_list, &smd_ch_list_dsp);
741 753
742 /* If the remote side is CLOSING, we need to get it to 754 /* If the remote side is CLOSING, we need to get it to
743 * move to OPENING (which we'll do by moving from CLOSED to 755 * move to OPENING (which we'll do by moving from CLOSED to
@@ -982,7 +994,7 @@ int smd_core_init(void)
982 994
983 smd_info.ready = 1; 995 smd_info.ready = 1;
984 996
985 r = request_irq(INT_A9_M2A_0, smd_irq_handler, 997 r = request_irq(INT_A9_M2A_0, smd_modem_irq_handler,
986 IRQF_TRIGGER_RISING, "smd_dev", 0); 998 IRQF_TRIGGER_RISING, "smd_dev", 0);
987 if (r < 0) 999 if (r < 0)
988 return r; 1000 return r;
@@ -1000,6 +1012,16 @@ int smd_core_init(void)
1000 if (r < 0) 1012 if (r < 0)
1001 pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n"); 1013 pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n");
1002 1014
1015#if defined(CONFIG_QDSP6)
1016 r = request_irq(INT_ADSP_A11, smd_dsp_irq_handler,
1017 IRQF_TRIGGER_RISING, "smd_dsp", 0);
1018 if (r < 0) {
1019 free_irq(INT_A9_M2A_0, 0);
1020 free_irq(INT_A9_M2A_5, 0);
1021 return r;
1022 }
1023#endif
1024
1003 /* check for any SMD channels that may already exist */ 1025 /* check for any SMD channels that may already exist */
1004 do_smd_probe(); 1026 do_smd_probe();
1005 1027
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c
index 3bb40a7fa283..0cc3ef8a94d3 100644
--- a/arch/arm/mach-msm/smd_debug.c
+++ b/arch/arm/mach-msm/smd_debug.c
@@ -55,7 +55,7 @@ static int dump_ch(char *buf, int max, struct smd_channel *ch)
55 buf, max, 55 buf, max,
56 "ch%02d:" 56 "ch%02d:"
57 " %8s(%05d/%05d) %c%c%c%c%c%c%c <->" 57 " %8s(%05d/%05d) %c%c%c%c%c%c%c <->"
58 " %8s(%05d/%05d) %c%c%c%c%c%c%c\n", ch->n, 58 " %8s(%05d/%05d) %c%c%c%c%c%c%c '%s'\n", ch->n,
59 chstate(s->state), s->tail, s->head, 59 chstate(s->state), s->tail, s->head,
60 s->fDSR ? 'D' : 'd', 60 s->fDSR ? 'D' : 'd',
61 s->fCTS ? 'C' : 'c', 61 s->fCTS ? 'C' : 'c',
@@ -71,7 +71,8 @@ static int dump_ch(char *buf, int max, struct smd_channel *ch)
71 r->fRI ? 'I' : 'i', 71 r->fRI ? 'I' : 'i',
72 r->fHEAD ? 'W' : 'w', 72 r->fHEAD ? 'W' : 'w',
73 r->fTAIL ? 'R' : 'r', 73 r->fTAIL ? 'R' : 'r',
74 r->fSTATE ? 'S' : 's' 74 r->fSTATE ? 'S' : 's',
75 ch->name
75 ); 76 );
76} 77}
77 78
@@ -135,7 +136,9 @@ static int debug_read_ch(char *buf, int max)
135 int i = 0; 136 int i = 0;
136 137
137 spin_lock_irqsave(&smd_lock, flags); 138 spin_lock_irqsave(&smd_lock, flags);
138 list_for_each_entry(ch, &smd_ch_list, ch_list) 139 list_for_each_entry(ch, &smd_ch_list_dsp, ch_list)
140 i += dump_ch(buf + i, max - i, ch);
141 list_for_each_entry(ch, &smd_ch_list_modem, ch_list)
139 i += dump_ch(buf + i, max - i, ch); 142 i += dump_ch(buf + i, max - i, ch);
140 list_for_each_entry(ch, &smd_ch_closed_list, ch_list) 143 list_for_each_entry(ch, &smd_ch_closed_list, ch_list)
141 i += dump_ch(buf + i, max - i, ch); 144 i += dump_ch(buf + i, max - i, ch);
diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h
index 13d7c9d31a9a..5a8831cc41ee 100644
--- a/arch/arm/mach-msm/smd_private.h
+++ b/arch/arm/mach-msm/smd_private.h
@@ -324,7 +324,8 @@ struct smd_channel {
324#define SMD_KIND_PACKET 0x200 324#define SMD_KIND_PACKET 0x200
325 325
326extern struct list_head smd_ch_closed_list; 326extern struct list_head smd_ch_closed_list;
327extern struct list_head smd_ch_list; 327extern struct list_head smd_ch_list_modem;
328extern struct list_head smd_ch_list_dsp;
328 329
329extern spinlock_t smd_lock; 330extern spinlock_t smd_lock;
330extern spinlock_t smem_lock; 331extern spinlock_t smem_lock;