smd.c 22 KB

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