smd.c 23 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096
  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_v2(struct smd_channel *ch)
  509. {
  510. struct smd_shared_v2 *shared2;
  511. void *buffer;
  512. unsigned buffer_sz;
  513. shared2 = smem_alloc(SMEM_SMD_BASE_ID + ch->n, sizeof(*shared2));
  514. buffer = smem_item(SMEM_SMD_FIFO_BASE_ID + ch->n, &buffer_sz);
  515. if (!buffer)
  516. return -1;
  517. /* buffer must be a power-of-two size */
  518. if (buffer_sz & (buffer_sz - 1))
  519. return -1;
  520. buffer_sz /= 2;
  521. ch->send = &shared2->ch0;
  522. ch->recv = &shared2->ch1;
  523. ch->send_data = buffer;
  524. ch->recv_data = buffer + buffer_sz;
  525. ch->fifo_size = buffer_sz;
  526. return 0;
  527. }
  528. static int smd_alloc_v1(struct smd_channel *ch)
  529. {
  530. struct smd_shared_v1 *shared1;
  531. shared1 = smem_alloc(ID_SMD_CHANNELS + ch->n, sizeof(*shared1));
  532. if (!shared1) {
  533. pr_err("smd_alloc_channel() cid %d does not exist\n", ch->n);
  534. return -1;
  535. }
  536. ch->send = &shared1->ch0;
  537. ch->recv = &shared1->ch1;
  538. ch->send_data = shared1->data0;
  539. ch->recv_data = shared1->data1;
  540. ch->fifo_size = SMD_BUF_SIZE;
  541. return 0;
  542. }
  543. static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type)
  544. {
  545. struct smd_channel *ch;
  546. ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL);
  547. if (ch == 0) {
  548. pr_err("smd_alloc_channel() out of memory\n");
  549. return -1;
  550. }
  551. ch->n = cid;
  552. if (smd_alloc_v2(ch) && smd_alloc_v1(ch)) {
  553. kfree(ch);
  554. return -1;
  555. }
  556. ch->fifo_mask = ch->fifo_size - 1;
  557. ch->type = type;
  558. if ((type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
  559. ch->notify_other_cpu = notify_modem_smd;
  560. else
  561. ch->notify_other_cpu = notify_dsp_smd;
  562. if (smd_is_packet(cid, type)) {
  563. ch->read = smd_packet_read;
  564. ch->write = smd_packet_write;
  565. ch->read_avail = smd_packet_read_avail;
  566. ch->write_avail = smd_packet_write_avail;
  567. ch->update_state = update_packet_state;
  568. } else {
  569. ch->read = smd_stream_read;
  570. ch->write = smd_stream_write;
  571. ch->read_avail = smd_stream_read_avail;
  572. ch->write_avail = smd_stream_write_avail;
  573. ch->update_state = update_stream_state;
  574. }
  575. if ((type & 0xff) == 0)
  576. memcpy(ch->name, "SMD_", 4);
  577. else
  578. memcpy(ch->name, "DSP_", 4);
  579. memcpy(ch->name + 4, name, 20);
  580. ch->name[23] = 0;
  581. ch->pdev.name = ch->name;
  582. ch->pdev.id = -1;
  583. pr_info("smd_alloc_channel() cid=%02d size=%05d '%s'\n",
  584. ch->n, ch->fifo_size, ch->name);
  585. mutex_lock(&smd_creation_mutex);
  586. list_add(&ch->ch_list, &smd_ch_closed_list);
  587. mutex_unlock(&smd_creation_mutex);
  588. platform_device_register(&ch->pdev);
  589. return 0;
  590. }
  591. static void do_nothing_notify(void *priv, unsigned flags)
  592. {
  593. }
  594. struct smd_channel *smd_get_channel(const char *name)
  595. {
  596. struct smd_channel *ch;
  597. mutex_lock(&smd_creation_mutex);
  598. list_for_each_entry(ch, &smd_ch_closed_list, ch_list) {
  599. if (!strcmp(name, ch->name)) {
  600. list_del(&ch->ch_list);
  601. mutex_unlock(&smd_creation_mutex);
  602. return ch;
  603. }
  604. }
  605. mutex_unlock(&smd_creation_mutex);
  606. return NULL;
  607. }
  608. int smd_open(const char *name, smd_channel_t **_ch,
  609. void *priv, void (*notify)(void *, unsigned))
  610. {
  611. struct smd_channel *ch;
  612. unsigned long flags;
  613. if (smd_initialized == 0) {
  614. pr_info("smd_open() before smd_init()\n");
  615. return -ENODEV;
  616. }
  617. ch = smd_get_channel(name);
  618. if (!ch)
  619. return -ENODEV;
  620. if (notify == 0)
  621. notify = do_nothing_notify;
  622. ch->notify = notify;
  623. ch->current_packet = 0;
  624. ch->last_state = SMD_SS_CLOSED;
  625. ch->priv = priv;
  626. *_ch = ch;
  627. spin_lock_irqsave(&smd_lock, flags);
  628. if ((ch->type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
  629. list_add(&ch->ch_list, &smd_ch_list_modem);
  630. else
  631. list_add(&ch->ch_list, &smd_ch_list_dsp);
  632. /* If the remote side is CLOSING, we need to get it to
  633. * move to OPENING (which we'll do by moving from CLOSED to
  634. * OPENING) and then get it to move from OPENING to
  635. * OPENED (by doing the same state change ourselves).
  636. *
  637. * Otherwise, it should be OPENING and we can move directly
  638. * to OPENED so that it will follow.
  639. */
  640. if (ch->recv->state == SMD_SS_CLOSING) {
  641. ch->send->head = 0;
  642. ch_set_state(ch, SMD_SS_OPENING);
  643. } else {
  644. ch_set_state(ch, SMD_SS_OPENED);
  645. }
  646. spin_unlock_irqrestore(&smd_lock, flags);
  647. smd_kick(ch);
  648. return 0;
  649. }
  650. int smd_close(smd_channel_t *ch)
  651. {
  652. unsigned long flags;
  653. pr_info("smd_close(%p)\n", ch);
  654. if (ch == 0)
  655. return -1;
  656. spin_lock_irqsave(&smd_lock, flags);
  657. ch->notify = do_nothing_notify;
  658. list_del(&ch->ch_list);
  659. ch_set_state(ch, SMD_SS_CLOSED);
  660. spin_unlock_irqrestore(&smd_lock, flags);
  661. mutex_lock(&smd_creation_mutex);
  662. list_add(&ch->ch_list, &smd_ch_closed_list);
  663. mutex_unlock(&smd_creation_mutex);
  664. return 0;
  665. }
  666. int smd_read(smd_channel_t *ch, void *data, int len)
  667. {
  668. return ch->read(ch, data, len);
  669. }
  670. int smd_write(smd_channel_t *ch, const void *data, int len)
  671. {
  672. return ch->write(ch, data, len);
  673. }
  674. int smd_write_atomic(smd_channel_t *ch, const void *data, int len)
  675. {
  676. unsigned long flags;
  677. int res;
  678. spin_lock_irqsave(&smd_lock, flags);
  679. res = ch->write(ch, data, len);
  680. spin_unlock_irqrestore(&smd_lock, flags);
  681. return res;
  682. }
  683. int smd_read_avail(smd_channel_t *ch)
  684. {
  685. return ch->read_avail(ch);
  686. }
  687. int smd_write_avail(smd_channel_t *ch)
  688. {
  689. return ch->write_avail(ch);
  690. }
  691. int smd_wait_until_readable(smd_channel_t *ch, int bytes)
  692. {
  693. return -1;
  694. }
  695. int smd_wait_until_writable(smd_channel_t *ch, int bytes)
  696. {
  697. return -1;
  698. }
  699. int smd_cur_packet_size(smd_channel_t *ch)
  700. {
  701. return ch->current_packet;
  702. }
  703. /* ------------------------------------------------------------------------- */
  704. void *smem_alloc(unsigned id, unsigned size)
  705. {
  706. return smem_find(id, size);
  707. }
  708. void *smem_item(unsigned id, unsigned *size)
  709. {
  710. struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
  711. struct smem_heap_entry *toc = shared->heap_toc;
  712. if (id >= SMEM_NUM_ITEMS)
  713. return 0;
  714. if (toc[id].allocated) {
  715. *size = toc[id].size;
  716. return (void *) (MSM_SHARED_RAM_BASE + toc[id].offset);
  717. } else {
  718. *size = 0;
  719. }
  720. return 0;
  721. }
  722. void *smem_find(unsigned id, unsigned size_in)
  723. {
  724. unsigned size;
  725. void *ptr;
  726. ptr = smem_item(id, &size);
  727. if (!ptr)
  728. return 0;
  729. size_in = ALIGN(size_in, 8);
  730. if (size_in != size) {
  731. pr_err("smem_find(%d, %d): wrong size %d\n",
  732. id, size_in, size);
  733. return 0;
  734. }
  735. return ptr;
  736. }
  737. static irqreturn_t smsm_irq_handler(int irq, void *data)
  738. {
  739. unsigned long flags;
  740. unsigned apps, modm;
  741. spin_lock_irqsave(&smem_lock, flags);
  742. apps = raw_smsm_get_state(SMSM_STATE_APPS);
  743. modm = raw_smsm_get_state(SMSM_STATE_MODEM);
  744. if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
  745. pr_info("<SM %08x %08x>\n", apps, modm);
  746. if (modm & SMSM_RESET)
  747. handle_modem_crash();
  748. do_smd_probe();
  749. spin_unlock_irqrestore(&smem_lock, flags);
  750. return IRQ_HANDLED;
  751. }
  752. int smsm_change_state(enum smsm_state_item item,
  753. uint32_t clear_mask, uint32_t set_mask)
  754. {
  755. unsigned long flags;
  756. unsigned state;
  757. unsigned addr = smd_info.state + item * 4;
  758. if (!smd_info.ready)
  759. return -EIO;
  760. spin_lock_irqsave(&smem_lock, flags);
  761. if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET)
  762. handle_modem_crash();
  763. state = (readl(addr) & ~clear_mask) | set_mask;
  764. writel(state, addr);
  765. if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
  766. pr_info("smsm_change_state %d %x\n", item, state);
  767. notify_other_smsm();
  768. spin_unlock_irqrestore(&smem_lock, flags);
  769. return 0;
  770. }
  771. uint32_t smsm_get_state(enum smsm_state_item item)
  772. {
  773. unsigned long flags;
  774. uint32_t rv;
  775. spin_lock_irqsave(&smem_lock, flags);
  776. rv = readl(smd_info.state + item * 4);
  777. if (item == SMSM_STATE_MODEM && (rv & SMSM_RESET))
  778. handle_modem_crash();
  779. spin_unlock_irqrestore(&smem_lock, flags);
  780. return rv;
  781. }
  782. #ifdef CONFIG_ARCH_MSM_SCORPION
  783. int smsm_set_sleep_duration(uint32_t delay)
  784. {
  785. struct msm_dem_slave_data *ptr;
  786. ptr = smem_find(SMEM_APPS_DEM_SLAVE_DATA, sizeof(*ptr));
  787. if (ptr == NULL) {
  788. pr_err("smsm_set_sleep_duration <SM NO APPS_DEM_SLAVE_DATA>\n");
  789. return -EIO;
  790. }
  791. if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
  792. pr_info("smsm_set_sleep_duration %d -> %d\n",
  793. ptr->sleep_time, delay);
  794. ptr->sleep_time = delay;
  795. return 0;
  796. }
  797. #else
  798. int smsm_set_sleep_duration(uint32_t delay)
  799. {
  800. uint32_t *ptr;
  801. ptr = smem_find(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
  802. if (ptr == NULL) {
  803. pr_err("smsm_set_sleep_duration <SM NO SLEEP_DELAY>\n");
  804. return -EIO;
  805. }
  806. if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
  807. pr_info("smsm_set_sleep_duration %d -> %d\n",
  808. *ptr, delay);
  809. *ptr = delay;
  810. return 0;
  811. }
  812. #endif
  813. int smd_core_init(void)
  814. {
  815. int r;
  816. pr_info("smd_core_init()\n");
  817. /* wait for essential items to be initialized */
  818. for (;;) {
  819. unsigned size;
  820. void *state;
  821. state = smem_item(SMEM_SMSM_SHARED_STATE, &size);
  822. if (size == SMSM_V1_SIZE || size == SMSM_V2_SIZE) {
  823. smd_info.state = (unsigned)state;
  824. break;
  825. }
  826. }
  827. smd_info.ready = 1;
  828. r = request_irq(INT_A9_M2A_0, smd_modem_irq_handler,
  829. IRQF_TRIGGER_RISING, "smd_dev", 0);
  830. if (r < 0)
  831. return r;
  832. r = enable_irq_wake(INT_A9_M2A_0);
  833. if (r < 0)
  834. pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_0\n");
  835. r = request_irq(INT_A9_M2A_5, smsm_irq_handler,
  836. IRQF_TRIGGER_RISING, "smsm_dev", 0);
  837. if (r < 0) {
  838. free_irq(INT_A9_M2A_0, 0);
  839. return r;
  840. }
  841. r = enable_irq_wake(INT_A9_M2A_5);
  842. if (r < 0)
  843. pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n");
  844. #if defined(CONFIG_QDSP6)
  845. r = request_irq(INT_ADSP_A11, smd_dsp_irq_handler,
  846. IRQF_TRIGGER_RISING, "smd_dsp", 0);
  847. if (r < 0) {
  848. free_irq(INT_A9_M2A_0, 0);
  849. free_irq(INT_A9_M2A_5, 0);
  850. return r;
  851. }
  852. #endif
  853. /* check for any SMD channels that may already exist */
  854. do_smd_probe();
  855. /* indicate that we're up and running */
  856. smsm_change_state(SMSM_STATE_APPS,
  857. ~0, SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT | SMSM_RUN);
  858. #ifdef CONFIG_ARCH_MSM_SCORPION
  859. smsm_change_state(SMSM_STATE_APPS_DEM, ~0, 0);
  860. #endif
  861. pr_info("smd_core_init() done\n");
  862. return 0;
  863. }
  864. static int __init msm_smd_probe(struct platform_device *pdev)
  865. {
  866. pr_info("smd_init()\n");
  867. INIT_WORK(&probe_work, smd_channel_probe_worker);
  868. if (smd_core_init()) {
  869. pr_err("smd_core_init() failed\n");
  870. return -1;
  871. }
  872. do_smd_probe();
  873. msm_check_for_modem_crash = check_for_modem_crash;
  874. msm_init_last_radio_log(THIS_MODULE);
  875. smd_initialized = 1;
  876. return 0;
  877. }
  878. static struct platform_driver msm_smd_driver = {
  879. .probe = msm_smd_probe,
  880. .driver = {
  881. .name = MODULE_NAME,
  882. .owner = THIS_MODULE,
  883. },
  884. };
  885. static int __init msm_smd_init(void)
  886. {
  887. return platform_driver_register(&msm_smd_driver);
  888. }
  889. module_init(msm_smd_init);
  890. MODULE_DESCRIPTION("MSM Shared Memory Core");
  891. MODULE_AUTHOR("Brian Swetland <swetland@google.com>");
  892. MODULE_LICENSE("GPL");