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