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