gpr-lite.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. /* Copyright (c) 2011-2017, 2019-2020 The Linux Foundation. All rights reserved.
  2. * Copyright (c) 2018, Linaro Limited
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/kernel.h>
  14. #include <linux/module.h>
  15. #include <linux/device.h>
  16. #include <linux/spinlock.h>
  17. #include <linux/idr.h>
  18. #include <linux/slab.h>
  19. #include <linux/of_device.h>
  20. #include <ipc/gpr-lite.h>
  21. #include <linux/rpmsg.h>
  22. #include <linux/of.h>
  23. #include <soc/snd_event.h>
  24. #include <dsp/audio_notifier.h>
  25. struct gpr {
  26. struct rpmsg_endpoint *ch;
  27. struct device *dev;
  28. spinlock_t gpr_lock;
  29. bool is_initial_boot;
  30. spinlock_t svcs_lock;
  31. struct idr svcs_idr;
  32. int dest_domain_id;
  33. struct work_struct notifier_reg_work;
  34. };
  35. static struct gpr_q6 q6;
  36. static struct gpr *gpr_priv;
  37. enum gpr_subsys_state gpr_get_q6_state(void)
  38. {
  39. return atomic_read(&q6.q6_state);
  40. }
  41. EXPORT_SYMBOL(gpr_get_q6_state);
  42. enum gpr_subsys_state gpr_get_modem_state(void)
  43. {
  44. return atomic_read(&q6.modem_state);
  45. }
  46. EXPORT_SYMBOL(gpr_get_modem_state);
  47. void gpr_subsys_notif_register(char *client_name, int domain,
  48. struct notifier_block *nb)
  49. {
  50. int ret;
  51. ret = audio_notifier_register(client_name, domain, nb);
  52. if (ret < 0)
  53. dev_err(gpr_priv->dev, "%s: Audio notifier register failed for domain %d ret = %d\n",
  54. __func__, domain, ret);
  55. }
  56. void gpr_subsys_notif_deregister(char *client_name)
  57. {
  58. int ret;
  59. ret = audio_notifier_deregister(client_name);
  60. if (ret < 0)
  61. dev_err(gpr_priv->dev, "%s: Audio notifier de-register failed for client %s\n",
  62. __func__, client_name);
  63. }
  64. /**
  65. * gpr_send_pkt() - Send a gpr message from gpr device
  66. *
  67. * @adev: Pointer to previously registered gpr device.
  68. * @pkt: Pointer to gpr packet to send
  69. *
  70. * Return: Will be an negative and/or packet size on success.
  71. */
  72. int gpr_send_pkt(struct gpr_device *adev, struct gpr_pkt *pkt)
  73. {
  74. struct gpr *gpr;
  75. struct gpr_hdr *hdr;
  76. unsigned long flags;
  77. uint32_t pkt_size;
  78. int ret;
  79. if(!adev)
  80. {
  81. pr_err("%s: enter pointer adev[%pK] \n", __func__, adev);
  82. return -EINVAL;
  83. }
  84. if(!(adev->dev.parent))
  85. {
  86. pr_err("%s: enter pointer adev->dev.parent[%pK] \n",
  87. __func__, adev->dev.parent);
  88. return -EINVAL;
  89. }
  90. gpr = dev_get_drvdata(adev->dev.parent);
  91. spin_lock_irqsave(&adev->lock, flags);
  92. hdr = &pkt->hdr;
  93. pkt_size = GPR_PKT_GET_PACKET_BYTE_SIZE(hdr->header);
  94. dev_dbg(gpr->dev, "SVC_ID %d %s packet size %d\n",
  95. adev->svc_id, __func__, pkt_size);
  96. ret = rpmsg_trysend(gpr->ch, pkt, pkt_size);
  97. spin_unlock_irqrestore(&adev->lock, flags);
  98. return ret ? ret : pkt_size;
  99. }
  100. EXPORT_SYMBOL_GPL(gpr_send_pkt);
  101. /**
  102. * apr_set_modem_state - Update modem load status.
  103. *
  104. * @state: State to update modem load status
  105. *
  106. */
  107. void gpr_set_modem_state(enum gpr_subsys_state state)
  108. {
  109. atomic_set(&q6.modem_state, state);
  110. }
  111. EXPORT_SYMBOL(gpr_set_modem_state);
  112. static void gpr_modem_down(unsigned long opcode)
  113. {
  114. gpr_set_modem_state(GPR_SUBSYS_DOWN);
  115. //dispatch_event(opcode, APR_DEST_MODEM);
  116. }
  117. static void gpr_modem_up(void)
  118. {
  119. //if (apr_cmpxchg_modem_state(APR_SUBSYS_DOWN, APR_SUBSYS_UP) ==
  120. // APR_SUBSYS_DOWN)
  121. // wake_up(&modem_wait);
  122. //is_modem_up = 1;
  123. }
  124. int gpr_set_q6_state(enum gpr_subsys_state state)
  125. {
  126. dev_dbg(gpr_priv->dev,"%s: setting adsp state %d\n", __func__, state);
  127. if (state < GPR_SUBSYS_DOWN || state > GPR_SUBSYS_LOADED)
  128. return -EINVAL;
  129. atomic_set(&q6.q6_state, state);
  130. return 0;
  131. }
  132. EXPORT_SYMBOL(gpr_set_q6_state);
  133. static void gpr_ssr_disable(struct device *dev, void *data)
  134. {
  135. gpr_set_q6_state(GPR_SUBSYS_DOWN);
  136. }
  137. static const struct snd_event_ops gpr_ssr_ops = {
  138. .disable = gpr_ssr_disable,
  139. };
  140. static void gpr_adsp_down(unsigned long opcode)
  141. {
  142. dev_info(gpr_priv->dev,"%s: Q6 is Down\n", __func__);
  143. gpr_set_q6_state(GPR_SUBSYS_DOWN);
  144. snd_event_notify(gpr_priv->dev, SND_EVENT_DOWN);
  145. }
  146. static void gpr_adsp_up(void)
  147. {
  148. dev_info(gpr_priv->dev,"%s: Q6 is Up\n", __func__);
  149. gpr_set_q6_state(GPR_SUBSYS_LOADED);
  150. snd_event_notify(gpr_priv->dev, SND_EVENT_UP);
  151. }
  152. static int gpr_notifier_service_cb(struct notifier_block *this,
  153. unsigned long opcode, void *data)
  154. {
  155. struct audio_notifier_cb_data *cb_data = data;
  156. if (cb_data == NULL) {
  157. dev_err(gpr_priv->dev,"%s: Callback data is NULL!\n", __func__);
  158. goto done;
  159. }
  160. dev_dbg(gpr_priv->dev,"%s: Service opcode 0x%lx, domain %d\n",
  161. __func__, opcode, cb_data->domain);
  162. switch (opcode) {
  163. case AUDIO_NOTIFIER_SERVICE_DOWN:
  164. /*
  165. * Use flag to ignore down notifications during
  166. * initial boot. There is no benefit from error
  167. * recovery notifications during initial boot
  168. * up since everything is expected to be down.
  169. */
  170. spin_lock(&gpr_priv->gpr_lock);
  171. if (gpr_priv->is_initial_boot) {
  172. spin_unlock(&gpr_priv->gpr_lock);
  173. break;
  174. }
  175. spin_unlock(&gpr_priv->gpr_lock);
  176. if (cb_data->domain == AUDIO_NOTIFIER_MODEM_DOMAIN)
  177. gpr_modem_down(opcode);
  178. else
  179. gpr_adsp_down(opcode);
  180. break;
  181. case AUDIO_NOTIFIER_SERVICE_UP:
  182. if (cb_data->domain == AUDIO_NOTIFIER_MODEM_DOMAIN)
  183. gpr_modem_up();
  184. else
  185. gpr_adsp_up();
  186. spin_lock(&gpr_priv->gpr_lock);
  187. gpr_priv->is_initial_boot = false;
  188. spin_unlock(&gpr_priv->gpr_lock);
  189. break;
  190. default:
  191. break;
  192. }
  193. done:
  194. return NOTIFY_OK;
  195. }
  196. static struct notifier_block adsp_service_nb = {
  197. .notifier_call = gpr_notifier_service_cb,
  198. .priority = 0,
  199. };
  200. static struct notifier_block modem_service_nb = {
  201. .notifier_call = gpr_notifier_service_cb,
  202. .priority = 0,
  203. };
  204. static void gpr_dev_release(struct device *dev)
  205. {
  206. struct gpr_device *adev = to_gpr_device(dev);
  207. kfree(adev);
  208. }
  209. static int gpr_callback(struct rpmsg_device *rpdev, void *buf,
  210. int len, void *priv, u32 addr)
  211. {
  212. struct gpr *gpr = dev_get_drvdata(&rpdev->dev);
  213. uint16_t hdr_size, pkt_size, svc_id;
  214. //uint16_t ver;
  215. struct gpr_device *svc = NULL;
  216. struct gpr_driver *adrv = NULL;
  217. struct gpr_hdr *hdr;
  218. unsigned long flags;
  219. //uint32_t opcode_type;
  220. if (len <= GPR_HDR_SIZE) {
  221. dev_err(gpr->dev, "GPR: Improper gpr pkt received:%p %d\n",
  222. buf, len);
  223. return -EINVAL;
  224. }
  225. hdr = buf;
  226. hdr_size = GPR_PKT_GET_HEADER_BYTE_SIZE(hdr->header);
  227. if (hdr_size < GPR_HDR_SIZE) {
  228. dev_err(gpr->dev, "GPR: Wrong hdr size:%d\n", hdr_size);
  229. return -EINVAL;
  230. }
  231. pkt_size = GPR_PKT_GET_PACKET_BYTE_SIZE(hdr->header);
  232. dev_dbg(gpr->dev,"Header %x", hdr->header);
  233. if (pkt_size < GPR_HDR_SIZE || pkt_size != len) {
  234. dev_err(gpr->dev, "GPR: Wrong packet size\n");
  235. return -EINVAL;
  236. }
  237. dev_dbg(gpr->dev, "%s: dst_port %x hdr_size %d pkt_size %d\n",
  238. __func__ , hdr->dst_port, hdr_size, pkt_size);
  239. svc_id = hdr->dst_port;
  240. spin_lock_irqsave(&gpr->svcs_lock, flags);
  241. svc = idr_find(&gpr->svcs_idr, svc_id);
  242. if (svc && svc->dev.driver) {
  243. adrv = to_gpr_driver(svc->dev.driver);
  244. } else {
  245. /*Does not match any SVC ID hence would be routed to audio passthrough*/
  246. svc = idr_find(&gpr->svcs_idr, GPR_SVC_MAX);
  247. if (svc && svc->dev.driver)
  248. adrv = to_gpr_driver(svc->dev.driver);
  249. }
  250. spin_unlock_irqrestore(&gpr->svcs_lock, flags);
  251. if (!adrv) {
  252. dev_err(gpr->dev, "GPR: service is not registered\n");
  253. return -EINVAL;
  254. }
  255. /*
  256. * NOTE: hdr_size is not same as GPR_HDR_SIZE as remote can include
  257. * optional headers in to gpr_hdr which should be ignored
  258. */
  259. adrv->callback(svc, buf);
  260. return 0;
  261. }
  262. static int gpr_device_match(struct device *dev, struct device_driver *drv)
  263. {
  264. struct gpr_device *adev = to_gpr_device(dev);
  265. struct gpr_driver *adrv = to_gpr_driver(drv);
  266. const struct gpr_device_id *id = adrv->id_table;
  267. /* Attempt an OF style match first */
  268. if (of_driver_match_device(dev, drv))
  269. return 1;
  270. if (!id)
  271. return 0;
  272. while (id->domain_id != 0 || id->svc_id != 0) {
  273. if (id->domain_id == adev->domain_id &&
  274. id->svc_id == adev->svc_id)
  275. return 1;
  276. id++;
  277. }
  278. return 0;
  279. }
  280. static int gpr_device_probe(struct device *dev)
  281. {
  282. struct gpr_device *adev = to_gpr_device(dev);
  283. struct gpr_driver *adrv = to_gpr_driver(dev->driver);
  284. return adrv->probe(adev);
  285. }
  286. static int gpr_device_remove(struct device *dev)
  287. {
  288. struct gpr_device *adev = to_gpr_device(dev);
  289. struct gpr_driver *adrv;
  290. struct gpr *gpr = dev_get_drvdata(adev->dev.parent);
  291. if (dev->driver) {
  292. adrv = to_gpr_driver(dev->driver);
  293. if (adrv->remove)
  294. adrv->remove(adev);
  295. spin_lock(&gpr->svcs_lock);
  296. idr_remove(&gpr->svcs_idr, adev->svc_id);
  297. spin_unlock(&gpr->svcs_lock);
  298. }
  299. return 0;
  300. }
  301. static int gpr_uevent(struct device *dev, struct kobj_uevent_env *env)
  302. {
  303. struct gpr_device *adev = to_gpr_device(dev);
  304. int ret;
  305. ret = of_device_uevent_modalias(dev, env);
  306. if (ret != -ENODEV)
  307. return ret;
  308. return add_uevent_var(env, "MODALIAS=gpr:%s", adev->name);
  309. }
  310. struct bus_type gprbus = {
  311. .name = "gprbus",
  312. .match = gpr_device_match,
  313. .probe = gpr_device_probe,
  314. .uevent = gpr_uevent,
  315. .remove = gpr_device_remove,
  316. };
  317. EXPORT_SYMBOL_GPL(gprbus);
  318. static int gpr_add_device(struct device *dev, struct device_node *np,
  319. const struct gpr_device_id *id)
  320. {
  321. struct gpr *gpr = dev_get_drvdata(dev);
  322. struct gpr_device *adev = NULL;
  323. int ret;
  324. adev = kzalloc(sizeof(*adev), GFP_KERNEL);
  325. if (!adev)
  326. return -ENOMEM;
  327. spin_lock_init(&adev->lock);
  328. adev->svc_id = id->svc_id;
  329. adev->domain_id = id->domain_id;
  330. adev->version = id->svc_version;
  331. if (np)
  332. strscpy(adev->name, np->name, GPR_NAME_SIZE);
  333. else
  334. strscpy(adev->name, id->name, GPR_NAME_SIZE);
  335. dev_set_name(&adev->dev, "gprsvc:%s:%x:%x", adev->name,
  336. id->domain_id, id->svc_id);
  337. adev->dev.bus = &gprbus;
  338. adev->dev.parent = dev;
  339. adev->dev.of_node = np;
  340. adev->dev.release = gpr_dev_release;
  341. adev->dev.driver = NULL;
  342. spin_lock(&gpr->svcs_lock);
  343. idr_alloc(&gpr->svcs_idr, adev, id->svc_id,
  344. id->svc_id + 1, GFP_ATOMIC);
  345. spin_unlock(&gpr->svcs_lock);
  346. dev_info(dev, "Adding GPR dev: %s\n", dev_name(&adev->dev));
  347. ret = device_register(&adev->dev);
  348. if (ret) {
  349. dev_err(dev, "device_register failed: %d\n", ret);
  350. put_device(&adev->dev);
  351. }
  352. return ret;
  353. }
  354. static void of_register_gpr_devices(struct device *dev)
  355. {
  356. struct gpr *gpr = dev_get_drvdata(dev);
  357. struct device_node *node;
  358. for_each_child_of_node(dev->of_node, node) {
  359. struct gpr_device_id id = { {0} };
  360. if (of_property_read_u32(node, "reg", &id.svc_id))
  361. continue;
  362. id.domain_id = gpr->dest_domain_id;
  363. if (gpr_add_device(dev, node, &id))
  364. dev_err(dev, "Failed to add gpr %d svc\n", id.svc_id);
  365. }
  366. }
  367. static void gpr_notifier_register(struct work_struct *work)
  368. {
  369. if (GPR_DOMAIN_ADSP == gpr_priv->dest_domain_id) {
  370. gpr_subsys_notif_register("gpr_adsp",
  371. AUDIO_NOTIFIER_ADSP_DOMAIN,
  372. &adsp_service_nb);
  373. } else if (GPR_DOMAIN_MODEM == gpr_priv->dest_domain_id) {
  374. gpr_subsys_notif_register("gpr_modem",
  375. AUDIO_NOTIFIER_MODEM_DOMAIN,
  376. &modem_service_nb);
  377. }
  378. dev_info(gpr_priv->dev, "%s: registered via subsys_notif_register for domain id(%d)",
  379. __func__, gpr_priv->dest_domain_id );
  380. return;
  381. }
  382. static int gpr_probe(struct rpmsg_device *rpdev)
  383. {
  384. struct device *dev = &rpdev->dev;
  385. int ret;
  386. gpr_priv = devm_kzalloc(dev, sizeof(*gpr_priv), GFP_KERNEL);
  387. if (!gpr_priv)
  388. return -ENOMEM;
  389. spin_lock_init(&gpr_priv->gpr_lock);
  390. mutex_init(&q6.lock);
  391. spin_lock(&gpr_priv->gpr_lock);
  392. gpr_priv->is_initial_boot = true;
  393. spin_unlock(&gpr_priv->gpr_lock);
  394. dev_set_drvdata(dev, gpr_priv);
  395. gpr_priv->ch = rpdev->ept;
  396. gpr_priv->dev = dev;
  397. spin_lock_init(&gpr_priv->svcs_lock);
  398. idr_init(&gpr_priv->svcs_idr);
  399. ret = snd_event_client_register(&rpdev->dev, &gpr_ssr_ops, NULL);
  400. if (ret) {
  401. dev_err(dev,"%s: Registration with SND event fwk failed ret = %d\n",
  402. __func__, ret);
  403. ret = 0;
  404. }
  405. ret = of_property_read_u32(dev->of_node, "reg", &gpr_priv->dest_domain_id);
  406. if (ret) {
  407. dev_err(dev, "GPR Domain ID not specified in DT\n");
  408. return ret;
  409. }
  410. of_register_gpr_devices(dev);
  411. INIT_WORK(&gpr_priv->notifier_reg_work, gpr_notifier_register);
  412. if (GPR_DOMAIN_ADSP == gpr_priv->dest_domain_id ||
  413. GPR_DOMAIN_MODEM == gpr_priv->dest_domain_id) {
  414. schedule_work(&gpr_priv->notifier_reg_work);
  415. } else {
  416. dev_err(dev, "%s: invalid dest_domain_id %s\n", __func__,
  417. gpr_priv->dest_domain_id);
  418. return -EINVAL;
  419. }
  420. dev_info(dev, "%s: gpr-lite probe success\n",
  421. __func__);
  422. return 0;
  423. }
  424. static int gpr_remove_device(struct device *dev, void *null)
  425. {
  426. struct gpr_device *adev = to_gpr_device(dev);
  427. device_unregister(&adev->dev);
  428. return 0;
  429. }
  430. static void gpr_remove(struct rpmsg_device *rpdev)
  431. {
  432. struct device *dev = &rpdev->dev;
  433. snd_event_client_deregister(&rpdev->dev);
  434. dev_info(dev, "%s: deregistering via subsys_notif_register for domain_id(%d)",
  435. __func__, gpr_priv->dest_domain_id );
  436. if (GPR_DOMAIN_ADSP == gpr_priv->dest_domain_id)
  437. {
  438. gpr_subsys_notif_deregister("gpr_adsp");
  439. }
  440. else if(GPR_DOMAIN_MODEM == gpr_priv->dest_domain_id)
  441. {
  442. gpr_subsys_notif_deregister("gpr_modem");
  443. }
  444. device_for_each_child(&rpdev->dev, NULL, gpr_remove_device);
  445. }
  446. /*
  447. * __gpr_driver_register() - Client driver registration with gprbus
  448. *
  449. * @drv:Client driver to be associated with client-device.
  450. * @owner: owning module/driver
  451. *
  452. * This API will register the client driver with the gprbus
  453. * It is called from the driver's module-init function.
  454. */
  455. int __gpr_driver_register(struct gpr_driver *drv, struct module *owner)
  456. {
  457. drv->driver.bus = &gprbus;
  458. drv->driver.owner = owner;
  459. return driver_register(&drv->driver);
  460. }
  461. EXPORT_SYMBOL_GPL(__gpr_driver_register);
  462. /*
  463. * gpr_driver_unregister() - Undo effect of gpr_driver_register
  464. *
  465. * @drv: Client driver to be unregistered
  466. */
  467. void gpr_driver_unregister(struct gpr_driver *drv)
  468. {
  469. driver_unregister(&drv->driver);
  470. }
  471. EXPORT_SYMBOL_GPL(gpr_driver_unregister);
  472. static const struct of_device_id gpr_of_match[] = {
  473. { .compatible = "qcom,gpr"},
  474. {}
  475. };
  476. MODULE_DEVICE_TABLE(of, gpr_of_match);
  477. static struct rpmsg_driver gpr_driver = {
  478. .probe = gpr_probe,
  479. .remove = gpr_remove,
  480. .callback = gpr_callback,
  481. .drv = {
  482. .name = "qcom,gpr",
  483. .of_match_table = gpr_of_match,
  484. },
  485. };
  486. static int __init gpr_init(void)
  487. {
  488. int ret;
  489. ret = bus_register(&gprbus);
  490. if (!ret)
  491. ret = register_rpmsg_driver(&gpr_driver);
  492. else
  493. bus_unregister(&gprbus);
  494. return ret;
  495. }
  496. static void __exit gpr_exit(void)
  497. {
  498. bus_unregister(&gprbus);
  499. unregister_rpmsg_driver(&gpr_driver);
  500. }
  501. subsys_initcall(gpr_init);
  502. module_exit(gpr_exit);
  503. MODULE_LICENSE("GPL v2");
  504. MODULE_DESCRIPTION("QTI GPR Bus");