glink_ssr.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #include <linux/err.h>
  13. #include <linux/ipc_logging.h>
  14. #include <linux/list.h>
  15. #include <linux/module.h>
  16. #include <linux/notifier.h>
  17. #include <linux/of.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/sched.h>
  20. #include <linux/slab.h>
  21. #include <linux/suspend.h>
  22. #include <linux/random.h>
  23. #include <soc/qcom/glink.h>
  24. #include <soc/qcom/subsystem_notif.h>
  25. #include "glink_private.h"
  26. #define GLINK_SSR_REPLY_TIMEOUT HZ
  27. #define GLINK_SSR_INTENT_REQ_TIMEOUT_MS 500
  28. #define GLINK_SSR_EVENT_INIT ~0
  29. #define NUM_LOG_PAGES 3
  30. #define GLINK_SSR_PRIORITY 1
  31. #define GLINK_SSR_LOG(x...) do { \
  32. if (glink_ssr_log_ctx) \
  33. ipc_log_string(glink_ssr_log_ctx, x); \
  34. } while (0)
  35. #define GLINK_SSR_ERR(x...) do { \
  36. pr_err(x); \
  37. GLINK_SSR_LOG(x); \
  38. } while (0)
  39. static void *glink_ssr_log_ctx;
  40. /* Global restart counter */
  41. static uint32_t sequence_number;
  42. /* Flag indicating if responses were received for all SSR notifications */
  43. static bool notifications_successful;
  44. /* Completion for setting notifications_successful */
  45. struct completion notifications_successful_complete;
  46. /**
  47. * struct restart_notifier_block - restart notifier wrapper structure
  48. * subsystem: the name of the subsystem as recognized by the SSR framework
  49. * nb: notifier block structure used by the SSR framework
  50. */
  51. struct restart_notifier_block {
  52. const char *subsystem;
  53. struct notifier_block nb;
  54. };
  55. /**
  56. * struct configure_and_open_ch_work - Work structure for used for opening
  57. * glink_ssr channels
  58. * edge: The G-Link edge obtained from the link state callback
  59. * transport: The G-Link transport obtained from the link state callback
  60. * link_state: The link state obtained from the link state callback
  61. * ss_info: Subsystem information structure containing the info for this
  62. * callback
  63. * work: Work structure
  64. */
  65. struct configure_and_open_ch_work {
  66. char edge[GLINK_NAME_SIZE];
  67. char transport[GLINK_NAME_SIZE];
  68. enum glink_link_state link_state;
  69. struct subsys_info *ss_info;
  70. struct work_struct work;
  71. };
  72. /**
  73. * struct rx_done_ch_work - Work structure used for sending rx_done on
  74. * glink_ssr channels
  75. * handle: G-Link channel handle to be used for sending rx_done
  76. * ptr: Intent pointer data provided in notify rx function
  77. * work: Work structure
  78. */
  79. struct rx_done_ch_work {
  80. void *handle;
  81. const void *ptr;
  82. struct work_struct work;
  83. };
  84. /**
  85. * struct close_ch_work - Work structure for used for closing glink_ssr channels
  86. * edge: The G-Link edge name for the channel being closed
  87. * handle: G-Link channel handle to be closed
  88. * work: Work structure
  89. */
  90. struct close_ch_work {
  91. char edge[GLINK_NAME_SIZE];
  92. void *handle;
  93. struct work_struct work;
  94. };
  95. static int glink_ssr_restart_notifier_cb(struct notifier_block *this,
  96. unsigned long code,
  97. void *data);
  98. static void delete_ss_info_notify_list(struct subsys_info *ss_info);
  99. static int configure_and_open_channel(struct subsys_info *ss_info);
  100. static struct workqueue_struct *glink_ssr_wq;
  101. static LIST_HEAD(subsystem_list);
  102. static atomic_t responses_remaining = ATOMIC_INIT(0);
  103. static wait_queue_head_t waitqueue;
  104. /**
  105. * cb_data_release() - Free cb_data and set to NULL
  106. * @kref_ptr: pointer to kref.
  107. *
  108. * This function releses cb_data.
  109. */
  110. static inline void cb_data_release(struct kref *kref_ptr)
  111. {
  112. struct ssr_notify_data *cb_data;
  113. cb_data = container_of(kref_ptr, struct ssr_notify_data, cb_kref);
  114. kfree(cb_data);
  115. }
  116. /**
  117. * check_and_get_cb_data() - Try to get reference to kref of cb_data
  118. * @ss_info: pointer to subsystem info structure.
  119. *
  120. * Return: NULL is cb_data is NULL, pointer to cb_data otherwise
  121. */
  122. static struct ssr_notify_data *check_and_get_cb_data(
  123. struct subsys_info *ss_info)
  124. {
  125. struct ssr_notify_data *cb_data;
  126. unsigned long flags;
  127. spin_lock_irqsave(&ss_info->cb_lock, flags);
  128. if (ss_info->cb_data == NULL) {
  129. GLINK_SSR_LOG("<SSR> %s: cb_data is NULL\n", __func__);
  130. spin_unlock_irqrestore(&ss_info->cb_lock, flags);
  131. return 0;
  132. }
  133. kref_get(&ss_info->cb_data->cb_kref);
  134. cb_data = ss_info->cb_data;
  135. spin_unlock_irqrestore(&ss_info->cb_lock, flags);
  136. return cb_data;
  137. }
  138. static void rx_done_cb_worker(struct work_struct *work)
  139. {
  140. struct rx_done_ch_work *rx_done_work =
  141. container_of(work, struct rx_done_ch_work, work);
  142. glink_rx_done(rx_done_work->handle, rx_done_work->ptr, false);
  143. kfree(rx_done_work);
  144. }
  145. static void link_state_cb_worker(struct work_struct *work)
  146. {
  147. unsigned long flags;
  148. struct configure_and_open_ch_work *ch_open_work =
  149. container_of(work, struct configure_and_open_ch_work, work);
  150. struct subsys_info *ss_info = ch_open_work->ss_info;
  151. GLINK_SSR_LOG("<SSR> %s: LINK STATE[%d] %s:%s\n", __func__,
  152. ch_open_work->link_state, ch_open_work->edge,
  153. ch_open_work->transport);
  154. if (ss_info && ch_open_work->link_state == GLINK_LINK_STATE_UP) {
  155. spin_lock_irqsave(&ss_info->link_up_lock, flags);
  156. if (!ss_info->link_up) {
  157. ss_info->link_up = true;
  158. spin_unlock_irqrestore(&ss_info->link_up_lock, flags);
  159. if (!configure_and_open_channel(ss_info)) {
  160. glink_unregister_link_state_cb(
  161. ss_info->link_state_handle);
  162. ss_info->link_state_handle = NULL;
  163. }
  164. kfree(ch_open_work);
  165. return;
  166. }
  167. spin_unlock_irqrestore(&ss_info->link_up_lock, flags);
  168. } else {
  169. if (ss_info) {
  170. spin_lock_irqsave(&ss_info->link_up_lock, flags);
  171. ss_info->link_up = false;
  172. spin_unlock_irqrestore(&ss_info->link_up_lock, flags);
  173. ss_info->handle = NULL;
  174. } else {
  175. GLINK_SSR_ERR("<SSR> %s: ss_info is NULL\n", __func__);
  176. }
  177. }
  178. kfree(ch_open_work);
  179. }
  180. /**
  181. * glink_lbsrv_link_state_cb() - Callback to receive link state updates
  182. * @cb_info: Information containing link & its state.
  183. * @priv: Private data passed during the link state registration.
  184. *
  185. * This function is called by the G-Link core to notify the glink_ssr module
  186. * regarding the link state updates. This function is registered with the
  187. * G-Link core by the loopback server during glink_register_link_state_cb().
  188. */
  189. static void glink_ssr_link_state_cb(struct glink_link_state_cb_info *cb_info,
  190. void *priv)
  191. {
  192. struct subsys_info *ss_info;
  193. struct configure_and_open_ch_work *open_ch_work;
  194. if (!cb_info) {
  195. GLINK_SSR_ERR("<SSR> %s: Missing cb_data\n", __func__);
  196. return;
  197. }
  198. ss_info = get_info_for_edge(cb_info->edge);
  199. open_ch_work = kmalloc(sizeof(*open_ch_work), GFP_KERNEL);
  200. if (!open_ch_work) {
  201. GLINK_SSR_ERR("<SSR> %s: Could not allocate open_ch_work\n",
  202. __func__);
  203. return;
  204. }
  205. strlcpy(open_ch_work->edge, cb_info->edge, GLINK_NAME_SIZE);
  206. strlcpy(open_ch_work->transport, cb_info->transport, GLINK_NAME_SIZE);
  207. open_ch_work->link_state = cb_info->link_state;
  208. open_ch_work->ss_info = ss_info;
  209. INIT_WORK(&open_ch_work->work, link_state_cb_worker);
  210. queue_work(glink_ssr_wq, &open_ch_work->work);
  211. }
  212. /**
  213. * glink_ssr_notify_rx() - RX Notification callback
  214. * @handle: G-Link channel handle
  215. * @priv: Private callback data
  216. * @pkt_priv: Private packet data
  217. * @ptr: Pointer to the data received
  218. * @size: Size of the data received
  219. *
  220. * This function is a notification callback from the G-Link core that data
  221. * has been received from the remote side. This data is validate to make
  222. * sure it is a cleanup_done message and is processed accordingly if it is.
  223. */
  224. void glink_ssr_notify_rx(void *handle, const void *priv, const void *pkt_priv,
  225. const void *ptr, size_t size)
  226. {
  227. struct do_cleanup_msg *do_cleanup_data =
  228. (struct do_cleanup_msg *)pkt_priv;
  229. struct ssr_notify_data *cb_data = (struct ssr_notify_data *)priv;
  230. struct cleanup_done_msg *resp = (struct cleanup_done_msg *)ptr;
  231. struct rx_done_ch_work *rx_done_work;
  232. rx_done_work = kmalloc(sizeof(*rx_done_work), GFP_ATOMIC);
  233. if (!rx_done_work) {
  234. GLINK_SSR_ERR("<SSR> %s: Could not allocate rx_done_work\n",
  235. __func__);
  236. return;
  237. }
  238. if (unlikely(!do_cleanup_data)) {
  239. GLINK_SSR_ERR("<SSR> %s: Missing do_cleanup data!\n", __func__);
  240. goto no_clean_done;
  241. }
  242. if (unlikely(!cb_data)) {
  243. GLINK_SSR_ERR("<SSR> %s: Missing cb_data!\n", __func__);
  244. goto done;
  245. }
  246. if (unlikely(!resp)) {
  247. GLINK_SSR_ERR("<SSR> %s: Missing response data\n", __func__);
  248. goto done;
  249. }
  250. if (unlikely(resp->version != do_cleanup_data->version)) {
  251. GLINK_SSR_ERR("<SSR> %s: Version mismatch. %s[%d], %s[%d]\n",
  252. __func__, "do_cleanup version",
  253. do_cleanup_data->version, "cleanup_done version",
  254. resp->version);
  255. goto done;
  256. }
  257. if (unlikely(resp->seq_num != do_cleanup_data->seq_num)) {
  258. GLINK_SSR_ERR("<SSR> %s: Invalid seq. number %s[%d], %s[%d]\n",
  259. __func__, "do_cleanup seq num",
  260. do_cleanup_data->seq_num,
  261. "cleanup_done seq_num", resp->seq_num);
  262. goto done;
  263. }
  264. if (unlikely(resp->response != GLINK_SSR_CLEANUP_DONE)) {
  265. GLINK_SSR_ERR("<SSR> %s: Not a cleaup_done message. %s[%d]\n",
  266. __func__, "cleanup_done response", resp->response);
  267. goto done;
  268. }
  269. cb_data->responded = true;
  270. atomic_dec(&responses_remaining);
  271. GLINK_SSR_LOG(
  272. "<SSR> %s: Response from %s resp[%d] version[%d] seq_num[%d] restarted[%s]\n",
  273. __func__, cb_data->edge, resp->response,
  274. resp->version, resp->seq_num,
  275. do_cleanup_data->name);
  276. done:
  277. kfree(do_cleanup_data);
  278. no_clean_done:
  279. rx_done_work->ptr = ptr;
  280. rx_done_work->handle = handle;
  281. INIT_WORK(&rx_done_work->work, rx_done_cb_worker);
  282. queue_work(glink_ssr_wq, &rx_done_work->work);
  283. wake_up(&waitqueue);
  284. return;
  285. }
  286. /**
  287. * glink_ssr_notify_tx_done() - Transmit finished notification callback
  288. * @handle: G-Link channel handle
  289. * @priv: Private callback data
  290. * @pkt_priv: Private packet data
  291. * @ptr: Pointer to the data received
  292. *
  293. * This function is a notification callback from the G-Link core that data
  294. * we sent has finished transmitting.
  295. */
  296. void glink_ssr_notify_tx_done(void *handle, const void *priv,
  297. const void *pkt_priv, const void *ptr)
  298. {
  299. struct ssr_notify_data *cb_data = (struct ssr_notify_data *)priv;
  300. if (unlikely(!cb_data)) {
  301. panic("%s: cb_data is NULL!\n", __func__);
  302. return;
  303. }
  304. GLINK_SSR_LOG("<SSR> %s: Notified %s of restart\n",
  305. __func__, cb_data->edge);
  306. cb_data->tx_done = true;
  307. }
  308. void close_ch_worker(struct work_struct *work)
  309. {
  310. unsigned long flags;
  311. void *link_state_handle;
  312. struct subsys_info *ss_info;
  313. struct close_ch_work *close_work =
  314. container_of(work, struct close_ch_work, work);
  315. glink_close(close_work->handle);
  316. ss_info = get_info_for_edge(close_work->edge);
  317. if (WARN_ON(!ss_info))
  318. return;
  319. spin_lock_irqsave(&ss_info->link_up_lock, flags);
  320. ss_info->link_up = false;
  321. spin_unlock_irqrestore(&ss_info->link_up_lock, flags);
  322. if (WARN_ON(ss_info->link_state_handle != NULL))
  323. return;
  324. link_state_handle = glink_register_link_state_cb(ss_info->link_info,
  325. NULL);
  326. if (IS_ERR_OR_NULL(link_state_handle))
  327. GLINK_SSR_ERR("<SSR> %s: %s, ret[%d]\n", __func__,
  328. "Couldn't register link state cb",
  329. (int)PTR_ERR(link_state_handle));
  330. else
  331. ss_info->link_state_handle = link_state_handle;
  332. if (WARN_ON(!ss_info->cb_data))
  333. return;
  334. spin_lock_irqsave(&ss_info->cb_lock, flags);
  335. kref_put(&ss_info->cb_data->cb_kref, cb_data_release);
  336. ss_info->cb_data = NULL;
  337. spin_unlock_irqrestore(&ss_info->cb_lock, flags);
  338. kfree(close_work);
  339. }
  340. /**
  341. * glink_ssr_notify_state() - Channel state notification callback
  342. * @handle: G-Link channel handle
  343. * @priv: Private callback data
  344. * @event: The state that has been transitioned to
  345. *
  346. * This function is a notification callback from the G-Link core that the
  347. * channel state has changed.
  348. */
  349. void glink_ssr_notify_state(void *handle, const void *priv, unsigned int event)
  350. {
  351. struct ssr_notify_data *cb_data = (struct ssr_notify_data *)priv;
  352. struct close_ch_work *close_work;
  353. if (!cb_data) {
  354. GLINK_SSR_ERR("<SSR> %s: Could not allocate data for cb_data\n",
  355. __func__);
  356. } else {
  357. GLINK_SSR_LOG("<SSR> %s: event[%d]\n",
  358. __func__, event);
  359. cb_data->event = event;
  360. if (event == GLINK_REMOTE_DISCONNECTED) {
  361. close_work =
  362. kmalloc(sizeof(struct close_ch_work),
  363. GFP_KERNEL);
  364. if (!close_work) {
  365. GLINK_SSR_ERR(
  366. "<SSR> %s: Could not allocate %s\n",
  367. __func__, "close work");
  368. return;
  369. }
  370. strlcpy(close_work->edge, cb_data->edge,
  371. sizeof(close_work->edge));
  372. close_work->handle = handle;
  373. INIT_WORK(&close_work->work, close_ch_worker);
  374. queue_work(glink_ssr_wq, &close_work->work);
  375. }
  376. }
  377. }
  378. /**
  379. * glink_ssr_notify_rx_intent_req() - RX intent request notification callback
  380. * @handle: G-Link channel handle
  381. * @priv: Private callback data
  382. * @req_size: The size of the requested intent
  383. *
  384. * This function is a notification callback from the G-Link core of the remote
  385. * side's request for an RX intent to be queued.
  386. *
  387. * Return: Boolean indicating whether or not the request was successfully
  388. * received
  389. */
  390. bool glink_ssr_notify_rx_intent_req(void *handle, const void *priv,
  391. size_t req_size)
  392. {
  393. struct ssr_notify_data *cb_data = (struct ssr_notify_data *)priv;
  394. if (!cb_data) {
  395. GLINK_SSR_ERR("<SSR> %s: Could not allocate data for cb_data\n",
  396. __func__);
  397. return false;
  398. }
  399. GLINK_SSR_LOG("<SSR> %s: rx_intent_req of size %zu\n",
  400. __func__, req_size);
  401. return true;
  402. }
  403. /**
  404. * glink_ssr_restart_notifier_cb() - SSR restart notifier callback function
  405. * @this: Notifier block used by the SSR framework
  406. * @code: The SSR code for which stage of restart is occurring
  407. * @data: Structure containing private data - not used here.
  408. *
  409. * This function is a callback for the SSR framework. From here we initiate
  410. * our handling of SSR.
  411. *
  412. * Return: Status of SSR handling
  413. */
  414. static int glink_ssr_restart_notifier_cb(struct notifier_block *this,
  415. unsigned long code,
  416. void *data)
  417. {
  418. int ret = 0;
  419. struct subsys_info *ss_info = NULL;
  420. struct restart_notifier_block *notifier =
  421. container_of(this, struct restart_notifier_block, nb);
  422. if (code == SUBSYS_AFTER_SHUTDOWN) {
  423. GLINK_SSR_LOG("<SSR> %s: %s: subsystem restart for %s\n",
  424. __func__, "SUBSYS_AFTER_SHUTDOWN",
  425. notifier->subsystem);
  426. ss_info = get_info_for_subsystem(notifier->subsystem);
  427. if (ss_info == NULL) {
  428. GLINK_SSR_ERR("<SSR> %s: ss_info is NULL\n", __func__);
  429. return -EINVAL;
  430. }
  431. glink_ssr(ss_info->edge);
  432. ret = notify_for_subsystem(ss_info);
  433. if (ret) {
  434. GLINK_SSR_ERR("<SSR>: %s: %s, ret[%d]\n", __func__,
  435. "Subsystem notification failed", ret);
  436. return ret;
  437. }
  438. } else if (code == SUBSYS_AFTER_POWERUP) {
  439. GLINK_SSR_LOG("<SSR> %s: %s: subsystem restart for %s\n",
  440. __func__, "SUBSYS_AFTER_POWERUP",
  441. notifier->subsystem);
  442. ss_info = get_info_for_subsystem(notifier->subsystem);
  443. if (ss_info == NULL) {
  444. GLINK_SSR_ERR("<SSR> %s: ss_info is NULL\n", __func__);
  445. return -EINVAL;
  446. }
  447. glink_subsys_up(ss_info->edge);
  448. }
  449. return NOTIFY_DONE;
  450. }
  451. /**
  452. * notify for subsystem() - Notify other subsystems that a subsystem is being
  453. * restarted
  454. * @ss_info: Subsystem info structure for the subsystem being restarted
  455. *
  456. * This function sends notifications to affected subsystems that the subsystem
  457. * in ss_info is being restarted, and waits for the cleanup done response from
  458. * all of those subsystems. It also initiates any local cleanup that is
  459. * necessary.
  460. *
  461. * Return: 0 on success, standard error codes otherwise
  462. */
  463. int notify_for_subsystem(struct subsys_info *ss_info)
  464. {
  465. struct subsys_info *ss_info_channel;
  466. struct subsys_info_leaf *ss_leaf_entry;
  467. struct do_cleanup_msg *do_cleanup_data;
  468. void *handle;
  469. int wait_ret;
  470. int ret;
  471. unsigned long flags;
  472. if (!ss_info) {
  473. GLINK_SSR_ERR("<SSR> %s: ss_info structure invalid\n",
  474. __func__);
  475. return -EINVAL;
  476. }
  477. /*
  478. * No locking is needed here because ss_info->notify_list_len is
  479. * only modified during setup.
  480. */
  481. atomic_set(&responses_remaining, ss_info->notify_list_len);
  482. notifications_successful = true;
  483. list_for_each_entry(ss_leaf_entry, &ss_info->notify_list,
  484. notify_list_node) {
  485. GLINK_SSR_LOG(
  486. "<SSR> %s: Notifying: %s:%s of %s restart, seq_num[%d]\n",
  487. __func__, ss_leaf_entry->edge,
  488. ss_leaf_entry->xprt, ss_info->edge,
  489. sequence_number);
  490. ss_info_channel =
  491. get_info_for_subsystem(ss_leaf_entry->ssr_name);
  492. if (ss_info_channel == NULL) {
  493. GLINK_SSR_ERR(
  494. "<SSR> %s: unable to find subsystem name\n",
  495. __func__);
  496. return -ENODEV;
  497. }
  498. handle = ss_info_channel->handle;
  499. ss_leaf_entry->cb_data = check_and_get_cb_data(
  500. ss_info_channel);
  501. if (!ss_leaf_entry->cb_data) {
  502. GLINK_SSR_LOG("<SSR> %s: CB data is NULL\n", __func__);
  503. atomic_dec(&responses_remaining);
  504. continue;
  505. }
  506. spin_lock_irqsave(&ss_info->link_up_lock, flags);
  507. if (IS_ERR_OR_NULL(ss_info_channel->handle) ||
  508. !ss_info_channel->link_up ||
  509. ss_leaf_entry->cb_data->event
  510. != GLINK_CONNECTED) {
  511. GLINK_SSR_LOG(
  512. "<SSR> %s: %s:%s %s[%d], %s[%p], %s[%d]\n",
  513. __func__, ss_leaf_entry->edge, "Not connected",
  514. "resp. remaining",
  515. atomic_read(&responses_remaining), "handle",
  516. ss_info_channel->handle, "link_up",
  517. ss_info_channel->link_up);
  518. spin_unlock_irqrestore(&ss_info->link_up_lock, flags);
  519. atomic_dec(&responses_remaining);
  520. kref_put(&ss_leaf_entry->cb_data->cb_kref,
  521. cb_data_release);
  522. continue;
  523. }
  524. spin_unlock_irqrestore(&ss_info->link_up_lock, flags);
  525. do_cleanup_data = kmalloc(sizeof(struct do_cleanup_msg),
  526. GFP_KERNEL);
  527. if (!do_cleanup_data) {
  528. GLINK_SSR_ERR(
  529. "%s %s: Could not allocate do_cleanup_msg\n",
  530. "<SSR>", __func__);
  531. kref_put(&ss_leaf_entry->cb_data->cb_kref,
  532. cb_data_release);
  533. return -ENOMEM;
  534. }
  535. do_cleanup_data->version = 0;
  536. do_cleanup_data->command = GLINK_SSR_DO_CLEANUP;
  537. do_cleanup_data->seq_num = sequence_number;
  538. do_cleanup_data->name_len = strlen(ss_info->edge);
  539. strlcpy(do_cleanup_data->name, ss_info->edge,
  540. do_cleanup_data->name_len + 1);
  541. if (strcmp(ss_leaf_entry->ssr_name, "rpm"))
  542. ret = glink_tx(handle, do_cleanup_data,
  543. do_cleanup_data,
  544. sizeof(*do_cleanup_data),
  545. GLINK_TX_REQ_INTENT);
  546. else
  547. ret = glink_tx(handle, do_cleanup_data,
  548. do_cleanup_data,
  549. sizeof(*do_cleanup_data),
  550. GLINK_TX_SINGLE_THREADED);
  551. if (ret) {
  552. GLINK_SSR_ERR("<SSR> %s: tx failed, ret[%d], %s[%d]\n",
  553. __func__, ret, "resp. remaining",
  554. atomic_read(&responses_remaining));
  555. kfree(do_cleanup_data);
  556. if (!strcmp(ss_leaf_entry->ssr_name, "rpm"))
  557. panic("%s: glink_tx() to RPM failed!\n",
  558. __func__);
  559. atomic_dec(&responses_remaining);
  560. kref_put(&ss_leaf_entry->cb_data->cb_kref,
  561. cb_data_release);
  562. continue;
  563. }
  564. ret = glink_queue_rx_intent(handle, do_cleanup_data,
  565. sizeof(struct cleanup_done_msg));
  566. if (ret) {
  567. GLINK_SSR_ERR(
  568. "%s %s: %s, ret[%d], resp. remaining[%d]\n",
  569. "<SSR>", __func__,
  570. "queue_rx_intent failed", ret,
  571. atomic_read(&responses_remaining));
  572. kfree(do_cleanup_data);
  573. if (!strcmp(ss_leaf_entry->ssr_name, "rpm"))
  574. panic("%s: Could not queue intent for RPM!\n",
  575. __func__);
  576. atomic_dec(&responses_remaining);
  577. kref_put(&ss_leaf_entry->cb_data->cb_kref,
  578. cb_data_release);
  579. continue;
  580. }
  581. sequence_number++;
  582. kref_put(&ss_leaf_entry->cb_data->cb_kref, cb_data_release);
  583. }
  584. wait_ret = wait_event_timeout(waitqueue,
  585. atomic_read(&responses_remaining) == 0,
  586. GLINK_SSR_REPLY_TIMEOUT);
  587. list_for_each_entry(ss_leaf_entry, &ss_info->notify_list,
  588. notify_list_node) {
  589. ss_info_channel =
  590. get_info_for_subsystem(ss_leaf_entry->ssr_name);
  591. if (ss_info_channel == NULL) {
  592. GLINK_SSR_ERR(
  593. "<SSR> %s: unable to find subsystem name\n",
  594. __func__);
  595. continue;
  596. }
  597. ss_leaf_entry->cb_data = check_and_get_cb_data(
  598. ss_info_channel);
  599. if (!ss_leaf_entry->cb_data) {
  600. GLINK_SSR_LOG("<SSR> %s: CB data is NULL\n", __func__);
  601. continue;
  602. }
  603. if (!wait_ret && !IS_ERR_OR_NULL(ss_leaf_entry->cb_data)
  604. && !ss_leaf_entry->cb_data->responded) {
  605. GLINK_SSR_ERR("%s %s: Subsystem %s %s\n",
  606. "<SSR>", __func__, ss_leaf_entry->edge,
  607. "failed to respond. Restarting.");
  608. notifications_successful = false;
  609. /* Check for RPM, as it can't be restarted */
  610. if (!strcmp(ss_leaf_entry->ssr_name, "rpm"))
  611. panic("%s: RPM failed to respond!\n", __func__);
  612. }
  613. if (!IS_ERR_OR_NULL(ss_leaf_entry->cb_data))
  614. ss_leaf_entry->cb_data->responded = false;
  615. kref_put(&ss_leaf_entry->cb_data->cb_kref, cb_data_release);
  616. }
  617. complete(&notifications_successful_complete);
  618. return 0;
  619. }
  620. EXPORT_SYMBOL(notify_for_subsystem);
  621. /**
  622. * configure_and_open_channel() - configure and open a G-Link channel for
  623. * the given subsystem
  624. * @ss_info: The subsys_info structure where the channel will be stored
  625. *
  626. * Return: 0 on success, standard error codes otherwise
  627. */
  628. static int configure_and_open_channel(struct subsys_info *ss_info)
  629. {
  630. struct glink_open_config open_cfg;
  631. struct ssr_notify_data *cb_data = NULL;
  632. void *handle = NULL;
  633. unsigned long flags;
  634. if (!ss_info) {
  635. GLINK_SSR_ERR("<SSR> %s: ss_info structure invalid\n",
  636. __func__);
  637. return -EINVAL;
  638. }
  639. cb_data = kmalloc(sizeof(struct ssr_notify_data), GFP_KERNEL);
  640. if (!cb_data) {
  641. GLINK_SSR_ERR("<SSR> %s: Could not allocate cb_data\n",
  642. __func__);
  643. return -ENOMEM;
  644. }
  645. cb_data->responded = false;
  646. cb_data->event = GLINK_SSR_EVENT_INIT;
  647. cb_data->edge = ss_info->edge;
  648. spin_lock_irqsave(&ss_info->cb_lock, flags);
  649. ss_info->cb_data = cb_data;
  650. kref_init(&cb_data->cb_kref);
  651. spin_unlock_irqrestore(&ss_info->cb_lock, flags);
  652. memset(&open_cfg, 0, sizeof(struct glink_open_config));
  653. if (ss_info->xprt) {
  654. open_cfg.transport = ss_info->xprt;
  655. } else {
  656. open_cfg.transport = NULL;
  657. open_cfg.options = GLINK_OPT_INITIAL_XPORT;
  658. }
  659. open_cfg.edge = ss_info->edge;
  660. open_cfg.name = "glink_ssr";
  661. open_cfg.notify_rx = glink_ssr_notify_rx;
  662. open_cfg.notify_tx_done = glink_ssr_notify_tx_done;
  663. open_cfg.notify_state = glink_ssr_notify_state;
  664. open_cfg.notify_rx_intent_req = glink_ssr_notify_rx_intent_req;
  665. open_cfg.priv = ss_info->cb_data;
  666. open_cfg.rx_intent_req_timeout_ms = GLINK_SSR_INTENT_REQ_TIMEOUT_MS;
  667. handle = glink_open(&open_cfg);
  668. if (IS_ERR_OR_NULL(handle)) {
  669. GLINK_SSR_ERR(
  670. "<SSR> %s:%s %s: unable to open channel, ret[%d]\n",
  671. open_cfg.edge, open_cfg.name, __func__,
  672. (int)PTR_ERR(handle));
  673. kfree(cb_data);
  674. cb_data = NULL;
  675. ss_info->cb_data = NULL;
  676. return PTR_ERR(handle);
  677. }
  678. ss_info->handle = handle;
  679. return 0;
  680. }
  681. /**
  682. * get_info_for_subsystem() - Retrieve information about a subsystem from the
  683. * global subsystem_info_list
  684. * @subsystem: The name of the subsystem recognized by the SSR
  685. * framework
  686. *
  687. * Return: subsys_info structure containing info for the requested subsystem;
  688. * NULL if no structure can be found for the requested subsystem
  689. */
  690. struct subsys_info *get_info_for_subsystem(const char *subsystem)
  691. {
  692. struct subsys_info *ss_info_entry;
  693. list_for_each_entry(ss_info_entry, &subsystem_list,
  694. subsystem_list_node) {
  695. if (!strcmp(subsystem, ss_info_entry->ssr_name))
  696. return ss_info_entry;
  697. }
  698. return NULL;
  699. }
  700. EXPORT_SYMBOL(get_info_for_subsystem);
  701. /**
  702. * get_info_for_edge() - Retrieve information about a subsystem from the
  703. * global subsystem_info_list
  704. * @edge: The name of the edge recognized by G-Link
  705. *
  706. * Return: subsys_info structure containing info for the requested subsystem;
  707. * NULL if no structure can be found for the requested subsystem
  708. */
  709. struct subsys_info *get_info_for_edge(const char *edge)
  710. {
  711. struct subsys_info *ss_info_entry;
  712. list_for_each_entry(ss_info_entry, &subsystem_list,
  713. subsystem_list_node) {
  714. if (!strcmp(edge, ss_info_entry->edge))
  715. return ss_info_entry;
  716. }
  717. return NULL;
  718. }
  719. EXPORT_SYMBOL(get_info_for_edge);
  720. /**
  721. * glink_ssr_get_seq_num() - Get the current SSR sequence number
  722. *
  723. * Return: The current SSR sequence number
  724. */
  725. uint32_t glink_ssr_get_seq_num(void)
  726. {
  727. return sequence_number;
  728. }
  729. EXPORT_SYMBOL(glink_ssr_get_seq_num);
  730. /**
  731. * delete_ss_info_notify_list() - Delete the notify list for a subsystem
  732. * @ss_info: The subsystem info structure
  733. */
  734. static void delete_ss_info_notify_list(struct subsys_info *ss_info)
  735. {
  736. struct subsys_info_leaf *leaf, *temp;
  737. list_for_each_entry_safe(leaf, temp, &ss_info->notify_list,
  738. notify_list_node) {
  739. list_del(&leaf->notify_list_node);
  740. kfree(leaf);
  741. }
  742. }
  743. /**
  744. * glink_ssr_wait_cleanup_done() - Get the value of the
  745. * notifications_successful flag.
  746. * @timeout_multiplier: timeout multiplier for waiting on all processors
  747. *
  748. * Return: True if cleanup_done received from all processors, false otherwise
  749. */
  750. bool glink_ssr_wait_cleanup_done(unsigned int ssr_timeout_multiplier)
  751. {
  752. int wait_ret =
  753. wait_for_completion_timeout(&notifications_successful_complete,
  754. ssr_timeout_multiplier * GLINK_SSR_REPLY_TIMEOUT);
  755. reinit_completion(&notifications_successful_complete);
  756. if (!notifications_successful || !wait_ret)
  757. return false;
  758. else
  759. return true;
  760. }
  761. EXPORT_SYMBOL(glink_ssr_wait_cleanup_done);
  762. /**
  763. * glink_ssr_probe() - G-Link SSR platform device probe function
  764. * @pdev: Pointer to the platform device structure
  765. *
  766. * This function parses DT for information on which subsystems should be
  767. * notified when each subsystem undergoes SSR. The global subsystem information
  768. * list is built from this information. In addition, SSR notifier callback
  769. * functions are registered here for the necessary subsystems.
  770. *
  771. * Return: 0 on success, standard error codes otherwise
  772. */
  773. static int glink_ssr_probe(struct platform_device *pdev)
  774. {
  775. struct device_node *node;
  776. struct device_node *phandle_node;
  777. struct restart_notifier_block *nb;
  778. struct subsys_info *ss_info;
  779. struct subsys_info_leaf *ss_info_leaf = NULL;
  780. struct glink_link_info *link_info;
  781. char *key;
  782. const char *edge;
  783. const char *subsys_name;
  784. const char *xprt;
  785. void *handle;
  786. void *link_state_handle;
  787. int phandle_index = 0;
  788. int ret = 0;
  789. if (!pdev) {
  790. GLINK_SSR_ERR("<SSR> %s: pdev is NULL\n", __func__);
  791. ret = -EINVAL;
  792. goto pdev_null_or_ss_info_alloc_failed;
  793. }
  794. node = pdev->dev.of_node;
  795. ss_info = kmalloc(sizeof(*ss_info), GFP_KERNEL);
  796. if (!ss_info) {
  797. GLINK_SSR_ERR("<SSR> %s: %s\n", __func__,
  798. "Could not allocate subsystem info structure\n");
  799. ret = -ENOMEM;
  800. goto pdev_null_or_ss_info_alloc_failed;
  801. }
  802. INIT_LIST_HEAD(&ss_info->notify_list);
  803. link_info = kmalloc(sizeof(struct glink_link_info),
  804. GFP_KERNEL);
  805. if (!link_info) {
  806. GLINK_SSR_ERR("<SSR> %s: %s\n", __func__,
  807. "Could not allocate link info structure\n");
  808. ret = -ENOMEM;
  809. goto link_info_alloc_failed;
  810. }
  811. ss_info->link_info = link_info;
  812. key = "label";
  813. subsys_name = of_get_property(node, key, NULL);
  814. if (!subsys_name) {
  815. GLINK_SSR_ERR("<SSR> %s: missing key %s\n", __func__, key);
  816. ret = -ENODEV;
  817. goto label_or_edge_missing;
  818. }
  819. key = "qcom,edge";
  820. edge = of_get_property(node, key, NULL);
  821. if (!edge) {
  822. GLINK_SSR_ERR("<SSR> %s: missing key %s\n", __func__, key);
  823. ret = -ENODEV;
  824. goto label_or_edge_missing;
  825. }
  826. key = "qcom,xprt";
  827. xprt = of_get_property(node, key, NULL);
  828. if (!xprt)
  829. GLINK_SSR_LOG(
  830. "%s %s: no transport present for subys/edge %s/%s\n",
  831. "<SSR>", __func__, subsys_name, edge);
  832. ss_info->ssr_name = subsys_name;
  833. ss_info->edge = edge;
  834. ss_info->xprt = xprt;
  835. ss_info->notify_list_len = 0;
  836. ss_info->link_info->transport = xprt;
  837. ss_info->link_info->edge = edge;
  838. ss_info->link_info->glink_link_state_notif_cb = glink_ssr_link_state_cb;
  839. ss_info->link_up = false;
  840. ss_info->handle = NULL;
  841. ss_info->link_state_handle = NULL;
  842. ss_info->cb_data = NULL;
  843. spin_lock_init(&ss_info->link_up_lock);
  844. spin_lock_init(&ss_info->cb_lock);
  845. init_waitqueue_head(&waitqueue);
  846. nb = kmalloc(sizeof(struct restart_notifier_block), GFP_KERNEL);
  847. if (!nb) {
  848. GLINK_SSR_ERR("<SSR> %s: Could not allocate notifier block\n",
  849. __func__);
  850. ret = -ENOMEM;
  851. goto label_or_edge_missing;
  852. }
  853. nb->subsystem = subsys_name;
  854. nb->nb.notifier_call = glink_ssr_restart_notifier_cb;
  855. nb->nb.priority = GLINK_SSR_PRIORITY;
  856. handle = subsys_notif_register_notifier(nb->subsystem, &nb->nb);
  857. if (IS_ERR_OR_NULL(handle)) {
  858. GLINK_SSR_ERR("<SSR> %s: Could not register SSR notifier cb\n",
  859. __func__);
  860. ret = -EINVAL;
  861. goto nb_registration_fail;
  862. }
  863. key = "qcom,notify-edges";
  864. while (true) {
  865. phandle_node = of_parse_phandle(node, key, phandle_index++);
  866. if (!phandle_node)
  867. break;
  868. ss_info_leaf = kmalloc(sizeof(struct subsys_info_leaf),
  869. GFP_KERNEL);
  870. if (!ss_info_leaf) {
  871. GLINK_SSR_ERR(
  872. "<SSR> %s: Could not allocate subsys_info_leaf\n",
  873. __func__);
  874. ret = -ENOMEM;
  875. goto notify_edges_no_memory;
  876. }
  877. subsys_name = of_get_property(phandle_node, "label", NULL);
  878. edge = of_get_property(phandle_node, "qcom,edge", NULL);
  879. xprt = of_get_property(phandle_node, "qcom,xprt", NULL);
  880. of_node_put(phandle_node);
  881. if (!subsys_name || !edge) {
  882. GLINK_SSR_ERR(
  883. "%s, %s: Found DT node with invalid data!\n",
  884. "<SSR>", __func__);
  885. ret = -EINVAL;
  886. goto invalid_dt_node;
  887. }
  888. ss_info_leaf->ssr_name = subsys_name;
  889. ss_info_leaf->edge = edge;
  890. ss_info_leaf->xprt = xprt;
  891. list_add_tail(&ss_info_leaf->notify_list_node,
  892. &ss_info->notify_list);
  893. ss_info->notify_list_len++;
  894. }
  895. list_add_tail(&ss_info->subsystem_list_node, &subsystem_list);
  896. link_state_handle = glink_register_link_state_cb(ss_info->link_info,
  897. NULL);
  898. if (IS_ERR_OR_NULL(link_state_handle)) {
  899. GLINK_SSR_ERR("<SSR> %s: Could not register link state cb\n",
  900. __func__);
  901. ret = PTR_ERR(link_state_handle);
  902. goto link_state_register_fail;
  903. }
  904. ss_info->link_state_handle = link_state_handle;
  905. return 0;
  906. link_state_register_fail:
  907. list_del(&ss_info->subsystem_list_node);
  908. invalid_dt_node:
  909. kfree(ss_info_leaf);
  910. notify_edges_no_memory:
  911. subsys_notif_unregister_notifier(handle, &nb->nb);
  912. delete_ss_info_notify_list(ss_info);
  913. nb_registration_fail:
  914. kfree(nb);
  915. label_or_edge_missing:
  916. kfree(link_info);
  917. link_info_alloc_failed:
  918. kfree(ss_info);
  919. pdev_null_or_ss_info_alloc_failed:
  920. return ret;
  921. }
  922. static const struct of_device_id match_table[] = {
  923. { .compatible = "qcom,glink_ssr" },
  924. {},
  925. };
  926. static struct platform_driver glink_ssr_driver = {
  927. .probe = glink_ssr_probe,
  928. .driver = {
  929. .name = "msm_glink_ssr",
  930. .owner = THIS_MODULE,
  931. .of_match_table = match_table,
  932. },
  933. };
  934. static int glink_ssr_init(void)
  935. {
  936. int ret;
  937. glink_ssr_log_ctx =
  938. ipc_log_context_create(NUM_LOG_PAGES, "glink_ssr", 0);
  939. glink_ssr_wq = create_singlethread_workqueue("glink_ssr_wq");
  940. ret = platform_driver_register(&glink_ssr_driver);
  941. if (ret)
  942. GLINK_SSR_ERR("<SSR> %s: %s ret: %d\n", __func__,
  943. "glink_ssr driver registration failed", ret);
  944. notifications_successful = false;
  945. init_completion(&notifications_successful_complete);
  946. return 0;
  947. }
  948. module_init(glink_ssr_init);
  949. MODULE_DESCRIPTION("MSM Generic Link (G-Link) SSR Module");
  950. MODULE_LICENSE("GPL v2");