smd.c 22 KB

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