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. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  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. #include <mach/msm_smd.h>
  30. #include <mach/system.h>
  31. #include "smd_private.h"
  32. #include "proc_comm.h"
  33. #if defined(CONFIG_ARCH_QSD8X50)
  34. #define CONFIG_QDSP6 1
  35. #endif
  36. void (*msm_hw_reset_hook)(void);
  37. #define MODULE_NAME "msm_smd"
  38. enum {
  39. MSM_SMD_DEBUG = 1U << 0,
  40. MSM_SMSM_DEBUG = 1U << 0,
  41. };
  42. static int msm_smd_debug_mask;
  43. struct shared_info {
  44. int ready;
  45. void __iomem *state;
  46. };
  47. static unsigned dummy_state[SMSM_STATE_COUNT];
  48. static struct shared_info smd_info = {
  49. /* FIXME: not a real __iomem pointer */
  50. .state = &dummy_state,
  51. };
  52. module_param_named(debug_mask, msm_smd_debug_mask,
  53. int, S_IRUGO | S_IWUSR | S_IWGRP);
  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_debug("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. /* how many bytes are available for reading */
  121. static int smd_stream_read_avail(struct smd_channel *ch)
  122. {
  123. return (ch->recv->head - ch->recv->tail) & ch->fifo_mask;
  124. }
  125. /* how many bytes we are free to write */
  126. static int smd_stream_write_avail(struct smd_channel *ch)
  127. {
  128. return ch->fifo_mask -
  129. ((ch->send->head - ch->send->tail) & ch->fifo_mask);
  130. }
  131. static int smd_packet_read_avail(struct smd_channel *ch)
  132. {
  133. if (ch->current_packet) {
  134. int n = smd_stream_read_avail(ch);
  135. if (n > ch->current_packet)
  136. n = ch->current_packet;
  137. return n;
  138. } else {
  139. return 0;
  140. }
  141. }
  142. static int smd_packet_write_avail(struct smd_channel *ch)
  143. {
  144. int n = smd_stream_write_avail(ch);
  145. return n > SMD_HEADER_SIZE ? n - SMD_HEADER_SIZE : 0;
  146. }
  147. static int ch_is_open(struct smd_channel *ch)
  148. {
  149. return (ch->recv->state == SMD_SS_OPENED) &&
  150. (ch->send->state == SMD_SS_OPENED);
  151. }
  152. /* provide a pointer and length to readable data in the fifo */
  153. static unsigned ch_read_buffer(struct smd_channel *ch, void **ptr)
  154. {
  155. unsigned head = ch->recv->head;
  156. unsigned tail = ch->recv->tail;
  157. *ptr = (void *) (ch->recv_data + tail);
  158. if (tail <= head)
  159. return head - tail;
  160. else
  161. return ch->fifo_size - tail;
  162. }
  163. /* advance the fifo read pointer after data from ch_read_buffer is consumed */
  164. static void ch_read_done(struct smd_channel *ch, unsigned count)
  165. {
  166. BUG_ON(count > smd_stream_read_avail(ch));
  167. ch->recv->tail = (ch->recv->tail + count) & ch->fifo_mask;
  168. ch->send->fTAIL = 1;
  169. }
  170. /* basic read interface to ch_read_{buffer,done} used
  171. * by smd_*_read() and update_packet_state()
  172. * will read-and-discard if the _data pointer is null
  173. */
  174. static int ch_read(struct smd_channel *ch, void *_data, int len)
  175. {
  176. void *ptr;
  177. unsigned n;
  178. unsigned char *data = _data;
  179. int orig_len = len;
  180. while (len > 0) {
  181. n = ch_read_buffer(ch, &ptr);
  182. if (n == 0)
  183. break;
  184. if (n > len)
  185. n = len;
  186. if (_data)
  187. memcpy(data, ptr, n);
  188. data += n;
  189. len -= n;
  190. ch_read_done(ch, n);
  191. }
  192. return orig_len - len;
  193. }
  194. static void update_stream_state(struct smd_channel *ch)
  195. {
  196. /* streams have no special state requiring updating */
  197. }
  198. static void update_packet_state(struct smd_channel *ch)
  199. {
  200. unsigned hdr[5];
  201. int r;
  202. /* can't do anything if we're in the middle of a packet */
  203. if (ch->current_packet != 0)
  204. return;
  205. /* don't bother unless we can get the full header */
  206. if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE)
  207. return;
  208. r = ch_read(ch, hdr, SMD_HEADER_SIZE);
  209. BUG_ON(r != SMD_HEADER_SIZE);
  210. ch->current_packet = hdr[0];
  211. }
  212. /* provide a pointer and length to next free space in the fifo */
  213. static unsigned ch_write_buffer(struct smd_channel *ch, void **ptr)
  214. {
  215. unsigned head = ch->send->head;
  216. unsigned tail = ch->send->tail;
  217. *ptr = (void *) (ch->send_data + head);
  218. if (head < tail) {
  219. return tail - head - 1;
  220. } else {
  221. if (tail == 0)
  222. return ch->fifo_size - head - 1;
  223. else
  224. return ch->fifo_size - head;
  225. }
  226. }
  227. /* advace the fifo write pointer after freespace
  228. * from ch_write_buffer is filled
  229. */
  230. static void ch_write_done(struct smd_channel *ch, unsigned count)
  231. {
  232. BUG_ON(count > smd_stream_write_avail(ch));
  233. ch->send->head = (ch->send->head + count) & ch->fifo_mask;
  234. ch->send->fHEAD = 1;
  235. }
  236. static void ch_set_state(struct smd_channel *ch, unsigned n)
  237. {
  238. if (n == SMD_SS_OPENED) {
  239. ch->send->fDSR = 1;
  240. ch->send->fCTS = 1;
  241. ch->send->fCD = 1;
  242. } else {
  243. ch->send->fDSR = 0;
  244. ch->send->fCTS = 0;
  245. ch->send->fCD = 0;
  246. }
  247. ch->send->state = n;
  248. ch->send->fSTATE = 1;
  249. ch->notify_other_cpu();
  250. }
  251. static void do_smd_probe(void)
  252. {
  253. struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
  254. if (shared->heap_info.free_offset != last_heap_free) {
  255. last_heap_free = shared->heap_info.free_offset;
  256. schedule_work(&probe_work);
  257. }
  258. }
  259. static void smd_state_change(struct smd_channel *ch,
  260. unsigned last, unsigned next)
  261. {
  262. ch->last_state = next;
  263. pr_debug("ch %d %d -> %d\n", ch->n, last, next);
  264. switch (next) {
  265. case SMD_SS_OPENING:
  266. ch->recv->tail = 0;
  267. case SMD_SS_OPENED:
  268. if (ch->send->state != SMD_SS_OPENED)
  269. ch_set_state(ch, SMD_SS_OPENED);
  270. ch->notify(ch->priv, SMD_EVENT_OPEN);
  271. break;
  272. case SMD_SS_FLUSHING:
  273. case SMD_SS_RESET:
  274. /* we should force them to close? */
  275. default:
  276. ch->notify(ch->priv, SMD_EVENT_CLOSE);
  277. }
  278. }
  279. static void handle_smd_irq(struct list_head *list, void (*notify)(void))
  280. {
  281. unsigned long flags;
  282. struct smd_channel *ch;
  283. int do_notify = 0;
  284. unsigned ch_flags;
  285. unsigned tmp;
  286. spin_lock_irqsave(&smd_lock, flags);
  287. list_for_each_entry(ch, list, ch_list) {
  288. ch_flags = 0;
  289. if (ch_is_open(ch)) {
  290. if (ch->recv->fHEAD) {
  291. ch->recv->fHEAD = 0;
  292. ch_flags |= 1;
  293. do_notify |= 1;
  294. }
  295. if (ch->recv->fTAIL) {
  296. ch->recv->fTAIL = 0;
  297. ch_flags |= 2;
  298. do_notify |= 1;
  299. }
  300. if (ch->recv->fSTATE) {
  301. ch->recv->fSTATE = 0;
  302. ch_flags |= 4;
  303. do_notify |= 1;
  304. }
  305. }
  306. tmp = ch->recv->state;
  307. if (tmp != ch->last_state)
  308. smd_state_change(ch, ch->last_state, tmp);
  309. if (ch_flags) {
  310. ch->update_state(ch);
  311. ch->notify(ch->priv, SMD_EVENT_DATA);
  312. }
  313. }
  314. if (do_notify)
  315. notify();
  316. spin_unlock_irqrestore(&smd_lock, flags);
  317. do_smd_probe();
  318. }
  319. static irqreturn_t smd_modem_irq_handler(int irq, void *data)
  320. {
  321. handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
  322. return IRQ_HANDLED;
  323. }
  324. #if defined(CONFIG_QDSP6)
  325. static irqreturn_t smd_dsp_irq_handler(int irq, void *data)
  326. {
  327. handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
  328. return IRQ_HANDLED;
  329. }
  330. #endif
  331. static void smd_fake_irq_handler(unsigned long arg)
  332. {
  333. handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
  334. handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
  335. }
  336. static DECLARE_TASKLET(smd_fake_irq_tasklet, smd_fake_irq_handler, 0);
  337. static inline int smd_need_int(struct smd_channel *ch)
  338. {
  339. if (ch_is_open(ch)) {
  340. if (ch->recv->fHEAD || ch->recv->fTAIL || ch->recv->fSTATE)
  341. return 1;
  342. if (ch->recv->state != ch->last_state)
  343. return 1;
  344. }
  345. return 0;
  346. }
  347. void smd_sleep_exit(void)
  348. {
  349. unsigned long flags;
  350. struct smd_channel *ch;
  351. int need_int = 0;
  352. spin_lock_irqsave(&smd_lock, flags);
  353. list_for_each_entry(ch, &smd_ch_list_modem, ch_list) {
  354. if (smd_need_int(ch)) {
  355. need_int = 1;
  356. break;
  357. }
  358. }
  359. list_for_each_entry(ch, &smd_ch_list_dsp, ch_list) {
  360. if (smd_need_int(ch)) {
  361. need_int = 1;
  362. break;
  363. }
  364. }
  365. spin_unlock_irqrestore(&smd_lock, flags);
  366. do_smd_probe();
  367. if (need_int) {
  368. if (msm_smd_debug_mask & MSM_SMD_DEBUG)
  369. pr_info("smd_sleep_exit need interrupt\n");
  370. tasklet_schedule(&smd_fake_irq_tasklet);
  371. }
  372. }
  373. void smd_kick(smd_channel_t *ch)
  374. {
  375. unsigned long flags;
  376. unsigned tmp;
  377. spin_lock_irqsave(&smd_lock, flags);
  378. ch->update_state(ch);
  379. tmp = ch->recv->state;
  380. if (tmp != ch->last_state) {
  381. ch->last_state = tmp;
  382. if (tmp == SMD_SS_OPENED)
  383. ch->notify(ch->priv, SMD_EVENT_OPEN);
  384. else
  385. ch->notify(ch->priv, SMD_EVENT_CLOSE);
  386. }
  387. ch->notify(ch->priv, SMD_EVENT_DATA);
  388. ch->notify_other_cpu();
  389. spin_unlock_irqrestore(&smd_lock, flags);
  390. }
  391. static int smd_is_packet(int chn, unsigned type)
  392. {
  393. type &= SMD_KIND_MASK;
  394. if (type == SMD_KIND_PACKET)
  395. return 1;
  396. if (type == SMD_KIND_STREAM)
  397. return 0;
  398. /* older AMSS reports SMD_KIND_UNKNOWN always */
  399. if ((chn > 4) || (chn == 1))
  400. return 1;
  401. else
  402. return 0;
  403. }
  404. static int smd_stream_write(smd_channel_t *ch, const void *_data, int len)
  405. {
  406. void *ptr;
  407. const unsigned char *buf = _data;
  408. unsigned xfer;
  409. int orig_len = len;
  410. if (len < 0)
  411. return -EINVAL;
  412. while ((xfer = ch_write_buffer(ch, &ptr)) != 0) {
  413. if (!ch_is_open(ch))
  414. break;
  415. if (xfer > len)
  416. xfer = len;
  417. memcpy(ptr, buf, xfer);
  418. ch_write_done(ch, xfer);
  419. len -= xfer;
  420. buf += xfer;
  421. if (len == 0)
  422. break;
  423. }
  424. ch->notify_other_cpu();
  425. return orig_len - len;
  426. }
  427. static int smd_packet_write(smd_channel_t *ch, const void *_data, int len)
  428. {
  429. unsigned hdr[5];
  430. if (len < 0)
  431. return -EINVAL;
  432. if (smd_stream_write_avail(ch) < (len + SMD_HEADER_SIZE))
  433. return -ENOMEM;
  434. hdr[0] = len;
  435. hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0;
  436. smd_stream_write(ch, hdr, sizeof(hdr));
  437. smd_stream_write(ch, _data, len);
  438. return len;
  439. }
  440. static int smd_stream_read(smd_channel_t *ch, void *data, int len)
  441. {
  442. int r;
  443. if (len < 0)
  444. return -EINVAL;
  445. r = ch_read(ch, data, len);
  446. if (r > 0)
  447. ch->notify_other_cpu();
  448. return r;
  449. }
  450. static int smd_packet_read(smd_channel_t *ch, void *data, int len)
  451. {
  452. unsigned long flags;
  453. int r;
  454. if (len < 0)
  455. return -EINVAL;
  456. if (len > ch->current_packet)
  457. len = ch->current_packet;
  458. r = ch_read(ch, data, len);
  459. if (r > 0)
  460. ch->notify_other_cpu();
  461. spin_lock_irqsave(&smd_lock, flags);
  462. ch->current_packet -= r;
  463. update_packet_state(ch);
  464. spin_unlock_irqrestore(&smd_lock, flags);
  465. return r;
  466. }
  467. static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type)
  468. {
  469. struct smd_channel *ch;
  470. ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL);
  471. if (ch == 0) {
  472. pr_err("smd_alloc_channel() out of memory\n");
  473. return -1;
  474. }
  475. ch->n = cid;
  476. if (_smd_alloc_channel(ch)) {
  477. kfree(ch);
  478. return -1;
  479. }
  480. ch->fifo_mask = ch->fifo_size - 1;
  481. ch->type = type;
  482. if ((type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
  483. ch->notify_other_cpu = notify_modem_smd;
  484. else
  485. ch->notify_other_cpu = notify_dsp_smd;
  486. if (smd_is_packet(cid, type)) {
  487. ch->read = smd_packet_read;
  488. ch->write = smd_packet_write;
  489. ch->read_avail = smd_packet_read_avail;
  490. ch->write_avail = smd_packet_write_avail;
  491. ch->update_state = update_packet_state;
  492. } else {
  493. ch->read = smd_stream_read;
  494. ch->write = smd_stream_write;
  495. ch->read_avail = smd_stream_read_avail;
  496. ch->write_avail = smd_stream_write_avail;
  497. ch->update_state = update_stream_state;
  498. }
  499. if ((type & 0xff) == 0)
  500. memcpy(ch->name, "SMD_", 4);
  501. else
  502. memcpy(ch->name, "DSP_", 4);
  503. memcpy(ch->name + 4, name, 20);
  504. ch->name[23] = 0;
  505. ch->pdev.name = ch->name;
  506. ch->pdev.id = -1;
  507. pr_debug("smd_alloc_channel() cid=%02d size=%05d '%s'\n",
  508. ch->n, ch->fifo_size, ch->name);
  509. mutex_lock(&smd_creation_mutex);
  510. list_add(&ch->ch_list, &smd_ch_closed_list);
  511. mutex_unlock(&smd_creation_mutex);
  512. platform_device_register(&ch->pdev);
  513. return 0;
  514. }
  515. static void smd_channel_probe_worker(struct work_struct *work)
  516. {
  517. struct smd_alloc_elm *shared;
  518. unsigned ctype;
  519. unsigned type;
  520. unsigned n;
  521. shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
  522. if (!shared) {
  523. pr_err("cannot find allocation table\n");
  524. return;
  525. }
  526. for (n = 0; n < 64; n++) {
  527. if (smd_ch_allocated[n])
  528. continue;
  529. if (!shared[n].ref_count)
  530. continue;
  531. if (!shared[n].name[0])
  532. continue;
  533. ctype = shared[n].ctype;
  534. type = ctype & SMD_TYPE_MASK;
  535. /* DAL channels are stream but neither the modem,
  536. * nor the DSP correctly indicate this. Fixup manually.
  537. */
  538. if (!memcmp(shared[n].name, "DAL", 3))
  539. ctype = (ctype & (~SMD_KIND_MASK)) | SMD_KIND_STREAM;
  540. type = shared[n].ctype & SMD_TYPE_MASK;
  541. if ((type == SMD_TYPE_APPS_MODEM) ||
  542. (type == SMD_TYPE_APPS_DSP))
  543. if (!smd_alloc_channel(shared[n].name, shared[n].cid, ctype))
  544. smd_ch_allocated[n] = 1;
  545. }
  546. }
  547. static void do_nothing_notify(void *priv, unsigned flags)
  548. {
  549. }
  550. struct smd_channel *smd_get_channel(const char *name)
  551. {
  552. struct smd_channel *ch;
  553. mutex_lock(&smd_creation_mutex);
  554. list_for_each_entry(ch, &smd_ch_closed_list, ch_list) {
  555. if (!strcmp(name, ch->name)) {
  556. list_del(&ch->ch_list);
  557. mutex_unlock(&smd_creation_mutex);
  558. return ch;
  559. }
  560. }
  561. mutex_unlock(&smd_creation_mutex);
  562. return NULL;
  563. }
  564. int smd_open(const char *name, smd_channel_t **_ch,
  565. void *priv, void (*notify)(void *, unsigned))
  566. {
  567. struct smd_channel *ch;
  568. unsigned long flags;
  569. if (smd_initialized == 0) {
  570. pr_info("smd_open() before smd_init()\n");
  571. return -ENODEV;
  572. }
  573. ch = smd_get_channel(name);
  574. if (!ch)
  575. return -ENODEV;
  576. if (notify == 0)
  577. notify = do_nothing_notify;
  578. ch->notify = notify;
  579. ch->current_packet = 0;
  580. ch->last_state = SMD_SS_CLOSED;
  581. ch->priv = priv;
  582. *_ch = ch;
  583. spin_lock_irqsave(&smd_lock, flags);
  584. if ((ch->type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
  585. list_add(&ch->ch_list, &smd_ch_list_modem);
  586. else
  587. list_add(&ch->ch_list, &smd_ch_list_dsp);
  588. /* If the remote side is CLOSING, we need to get it to
  589. * move to OPENING (which we'll do by moving from CLOSED to
  590. * OPENING) and then get it to move from OPENING to
  591. * OPENED (by doing the same state change ourselves).
  592. *
  593. * Otherwise, it should be OPENING and we can move directly
  594. * to OPENED so that it will follow.
  595. */
  596. if (ch->recv->state == SMD_SS_CLOSING) {
  597. ch->send->head = 0;
  598. ch_set_state(ch, SMD_SS_OPENING);
  599. } else {
  600. ch_set_state(ch, SMD_SS_OPENED);
  601. }
  602. spin_unlock_irqrestore(&smd_lock, flags);
  603. smd_kick(ch);
  604. return 0;
  605. }
  606. int smd_close(smd_channel_t *ch)
  607. {
  608. unsigned long flags;
  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 __iomem *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 NULL;
  669. if (toc[id].allocated) {
  670. *size = toc[id].size;
  671. return (MSM_SHARED_RAM_BASE + toc[id].offset);
  672. } else {
  673. *size = 0;
  674. }
  675. return NULL;
  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. void __iomem *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. /* wait for essential items to be initialized */
  772. for (;;) {
  773. unsigned size;
  774. void __iomem *state;
  775. state = smem_item(SMEM_SMSM_SHARED_STATE, &size);
  776. if (size == SMSM_V1_SIZE || size == SMSM_V2_SIZE) {
  777. smd_info.state = state;
  778. break;
  779. }
  780. }
  781. smd_info.ready = 1;
  782. r = request_irq(INT_A9_M2A_0, smd_modem_irq_handler,
  783. IRQF_TRIGGER_RISING, "smd_dev", 0);
  784. if (r < 0)
  785. return r;
  786. r = enable_irq_wake(INT_A9_M2A_0);
  787. if (r < 0)
  788. pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_0\n");
  789. r = request_irq(INT_A9_M2A_5, smsm_irq_handler,
  790. IRQF_TRIGGER_RISING, "smsm_dev", 0);
  791. if (r < 0) {
  792. free_irq(INT_A9_M2A_0, 0);
  793. return r;
  794. }
  795. r = enable_irq_wake(INT_A9_M2A_5);
  796. if (r < 0)
  797. pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n");
  798. #if defined(CONFIG_QDSP6)
  799. r = request_irq(INT_ADSP_A11, smd_dsp_irq_handler,
  800. IRQF_TRIGGER_RISING, "smd_dsp", 0);
  801. if (r < 0) {
  802. free_irq(INT_A9_M2A_0, 0);
  803. free_irq(INT_A9_M2A_5, 0);
  804. return r;
  805. }
  806. #endif
  807. /* check for any SMD channels that may already exist */
  808. do_smd_probe();
  809. /* indicate that we're up and running */
  810. smsm_change_state(SMSM_STATE_APPS,
  811. ~0, SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT | SMSM_RUN);
  812. #ifdef CONFIG_ARCH_MSM_SCORPION
  813. smsm_change_state(SMSM_STATE_APPS_DEM, ~0, 0);
  814. #endif
  815. return 0;
  816. }
  817. static int __devinit msm_smd_probe(struct platform_device *pdev)
  818. {
  819. /*
  820. * If we haven't waited for the ARM9 to boot up till now,
  821. * then we need to wait here. Otherwise this should just
  822. * return immediately.
  823. */
  824. proc_comm_boot_wait();
  825. INIT_WORK(&probe_work, smd_channel_probe_worker);
  826. if (smd_core_init()) {
  827. pr_err("smd_core_init() failed\n");
  828. return -1;
  829. }
  830. do_smd_probe();
  831. msm_check_for_modem_crash = check_for_modem_crash;
  832. msm_init_last_radio_log(THIS_MODULE);
  833. smd_initialized = 1;
  834. return 0;
  835. }
  836. static struct platform_driver msm_smd_driver = {
  837. .probe = msm_smd_probe,
  838. .driver = {
  839. .name = MODULE_NAME,
  840. .owner = THIS_MODULE,
  841. },
  842. };
  843. static int __init msm_smd_init(void)
  844. {
  845. return platform_driver_register(&msm_smd_driver);
  846. }
  847. module_init(msm_smd_init);
  848. MODULE_DESCRIPTION("MSM Shared Memory Core");
  849. MODULE_AUTHOR("Brian Swetland <swetland@google.com>");
  850. MODULE_LICENSE("GPL");