glink_bgcom_xprt.c 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754
  1. /* Copyright (c) 2017-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/delay.h>
  13. #include <linux/err.h>
  14. #include <linux/gfp.h>
  15. #include <linux/kernel.h>
  16. #include <linux/kthread.h>
  17. #include <linux/list.h>
  18. #include <linux/module.h>
  19. #include <linux/mutex.h>
  20. #include <linux/of.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/printk.h>
  23. #include <linux/sched.h>
  24. #include <linux/seq_file.h>
  25. #include <linux/slab.h>
  26. #include <linux/spinlock.h>
  27. #include <linux/srcu.h>
  28. #include <linux/wait.h>
  29. #include <linux/component.h>
  30. #include <soc/qcom/tracer_pkt.h>
  31. #include "glink_core_if.h"
  32. #include "glink_private.h"
  33. #include "glink_xprt_if.h"
  34. #include "bgcom.h"
  35. #define XPRT_NAME "bgcom"
  36. #define FIFO_ALIGNMENT 16
  37. #define TRACER_PKT_FEATURE BIT(2)
  38. #define ACTIVE_TX BIT(0)
  39. #define ACTIVE_RX BIT(1)
  40. #define ID_MASK 0xFFFFFF
  41. #define BGCOM_RESET 0x00000000
  42. #define BGCOM_APPLICATION_RUNNING 0x00000001
  43. #define BGCOM_TO_SLAVE_FIFO_READY 0x00000002
  44. #define BGCOM_TO_MASTER_FIFO_READY 0x00000004
  45. #define BGCOM_AHB_READY 0x00000008
  46. #define WORD_SIZE 4
  47. #define TX_BLOCKED_CMD_RESERVE 16
  48. #define FIFO_FULL_RESERVE (TX_BLOCKED_CMD_RESERVE/WORD_SIZE)
  49. #define BGCOM_LINKUP (BGCOM_APPLICATION_RUNNING \
  50. | BGCOM_TO_SLAVE_FIFO_READY \
  51. | BGCOM_TO_MASTER_FIFO_READY \
  52. | BGCOM_AHB_READY)
  53. /**
  54. * enum command_types - definition of the types of commands sent/received
  55. * @VERSION_CMD: Version and feature set supported
  56. * @VERSION_ACK_CMD: Response for @VERSION_CMD
  57. * @OPEN_CMD: Open a channel
  58. * @CLOSE_CMD: Close a channel
  59. * @OPEN_ACK_CMD: Response to @OPEN_CMD
  60. * @CLOSE_ACK_CMD: Response for @CLOSE_CMD
  61. * @RX_INTENT_CMD: RX intent for a channel is queued
  62. * @RX_DONE_CMD: Use of RX intent for a channel is complete
  63. * @RX_DONE_W_REUSE_CMD: Same as @RX_DONE but also reuse the used intent
  64. * @RX_INTENT_REQ_CMD: Request to have RX intent queued
  65. * @RX_INTENT_REQ_ACK_CMD: Response for @RX_INTENT_REQ_CMD
  66. * @TX_DATA_CMD: Start of a data transfer
  67. * @TX_DATA_CONT_CMD: Continuation or end of a data transfer
  68. * @READ_NOTIF_CMD: Request for a notification when this cmd is read
  69. * @SIGNALS_CMD: Sideband signals
  70. * @TRACER_PKT_CMD: Start of a Tracer Packet Command
  71. * @TRACER_PKT_CONT_CMD: Continuation or end of a Tracer Packet Command
  72. */
  73. enum command_types {
  74. VERSION_CMD,
  75. VERSION_ACK_CMD,
  76. OPEN_CMD,
  77. CLOSE_CMD,
  78. OPEN_ACK_CMD,
  79. CLOSE_ACK_CMD,
  80. RX_INTENT_CMD,
  81. RX_DONE_CMD,
  82. RX_DONE_W_REUSE_CMD,
  83. RX_INTENT_REQ_CMD,
  84. RX_INTENT_REQ_ACK_CMD,
  85. TX_DATA_CMD,
  86. TX_DATA_CONT_CMD,
  87. READ_NOTIF_CMD,
  88. SIGNALS_CMD,
  89. TRACER_PKT_CMD,
  90. TRACER_PKT_CONT_CMD,
  91. };
  92. struct bgcom_fifo_size {
  93. uint32_t to_master:16;
  94. uint32_t to_slave:16;
  95. };
  96. struct bgcom_fifo_fill {
  97. uint32_t rx_avail:16;
  98. uint32_t tx_avail:16;
  99. };
  100. /**
  101. * struct edge_info - local information for managing a single complete edge
  102. * @list: List item to traverse in edge_info list
  103. * @xprt_if: The transport interface registered with the
  104. * glink core associated with this edge.
  105. * @xprt_cfg: The transport configuration for the glink core
  106. * assocaited with this edge.
  107. * @subsys_name: Name of the remote subsystem in the edge.
  108. * @bgcom_dev: Pointer to the connectingSPI Device.
  109. * @fifo_size: Size of the FIFO at the remote end.
  110. * @fifo_fill: Current available fifo size.
  111. * @tx_avail_lock: Lock to serialize access to tx_avail.
  112. * @kwork: Work to be executed when receiving data.
  113. * @kworker: Handle to the entity processing @kwork.
  114. * @task: Handle to the task context that runs @kworker.
  115. * @use_ref: Active users of this transport grab a
  116. * reference. Used for SSR synchronization.
  117. * @in_ssr: Signals if this transport is in ssr.
  118. * @water_mark_reached Signals if tx_avail need to read from fifo.
  119. * @write_lock: Lock to serialize write/tx operation.
  120. * @tx_blocked_queue: Queue of entities waiting for the remote side to
  121. * signal the resumption of TX.
  122. * @tx_resume_needed: A tx resume signal needs to be sent to the glink
  123. * core.
  124. * @tx_blocked_signal_sent: Flag to indicate the flush signal has already
  125. * been sent, and a response is pending from the
  126. * remote side. Protected by @write_lock.
  127. * @num_pw_states: Size of @ramp_time_us.
  128. * @ramp_time_us: Array of ramp times in microseconds where array
  129. * index position represents a power state.
  130. * @bgcom_status Maintains bgcom status based on events.
  131. * @wakeup_work : Work item for waking up tx_thread
  132. * @activity_flag: Flag indicating active TX and RX.
  133. * @activity_lock: Lock to synchronize access to activity flag.
  134. * @bgcom_config: Config to be given to bgcom driver.
  135. * @bgcom_handle: Handle to use bgcom driver apis.
  136. */
  137. struct edge_info {
  138. struct list_head list;
  139. struct glink_transport_if xprt_if;
  140. struct glink_core_transport_cfg xprt_cfg;
  141. char subsys_name[GLINK_NAME_SIZE];
  142. struct bgcom_device *bgcom_dev;
  143. struct bgcom_fifo_size fifo_size;
  144. struct bgcom_fifo_fill fifo_fill;
  145. struct mutex tx_avail_lock;
  146. struct kthread_worker kworker;
  147. struct task_struct *task;
  148. struct srcu_struct use_ref;
  149. bool in_ssr;
  150. bool water_mark_reached;
  151. struct mutex write_lock;
  152. wait_queue_head_t tx_blocked_queue;
  153. bool tx_resume_needed;
  154. bool tx_blocked_signal_sent;
  155. uint32_t num_pw_states;
  156. unsigned long *ramp_time_us;
  157. uint32_t bgcom_status;
  158. struct work_struct wakeup_work;
  159. uint32_t activity_flag;
  160. spinlock_t activity_lock;
  161. struct bgcom_open_config_type bgcom_config;
  162. void *bgcom_handle;
  163. };
  164. struct rx_pkt {
  165. void *rx_buf;
  166. uint32_t rx_len;
  167. struct edge_info *einfo;
  168. struct kthread_work kwork;
  169. };
  170. static uint32_t negotiate_features_v1(struct glink_transport_if *if_ptr,
  171. const struct glink_core_version *version,
  172. uint32_t features);
  173. static DEFINE_SPINLOCK(edge_infos_lock);
  174. static LIST_HEAD(edge_infos);
  175. static struct glink_core_version versions[] = {
  176. {1, TRACER_PKT_FEATURE, negotiate_features_v1},
  177. };
  178. /**
  179. * negotiate_features_v1() - determine what features of a version can be used
  180. * @if_ptr: The transport for which features are negotiated for.
  181. * @version: The version negotiated.
  182. * @features: The set of requested features.
  183. *
  184. * Return: What set of the requested features can be supported.
  185. */
  186. static uint32_t negotiate_features_v1(struct glink_transport_if *if_ptr,
  187. const struct glink_core_version *version,
  188. uint32_t features)
  189. {
  190. return features & version->features;
  191. }
  192. /**
  193. * glink_bgcom_get_tx_avail() - Available Write Space in the remote side
  194. * @einfo: Edge information corresponding to the remote side.
  195. *
  196. * Return: 0 on error, available write space on success.
  197. */
  198. static int glink_bgcom_get_tx_avail(struct edge_info *einfo)
  199. {
  200. uint32_t tx_avail;
  201. mutex_lock(&einfo->tx_avail_lock);
  202. tx_avail = einfo->fifo_fill.tx_avail;
  203. if (tx_avail < FIFO_FULL_RESERVE)
  204. tx_avail = 0;
  205. else
  206. tx_avail -= FIFO_FULL_RESERVE;
  207. mutex_unlock(&einfo->tx_avail_lock);
  208. return tx_avail;
  209. }
  210. /**
  211. * glink_bgcom_update_tx_avail() - update available Write Space in fifo
  212. * @einfo: Edge information corresponding to the remote side.
  213. * @size: size to update.
  214. *
  215. * Return: 0 on error, available write space on success.
  216. */
  217. static void glink_bgcom_update_tx_avail(struct edge_info *einfo, uint32_t size)
  218. {
  219. mutex_lock(&einfo->tx_avail_lock);
  220. einfo->fifo_fill.tx_avail -= size;
  221. if (einfo->fifo_fill.tx_avail < einfo->fifo_size.to_slave/2)
  222. einfo->water_mark_reached = true;
  223. mutex_unlock(&einfo->tx_avail_lock);
  224. }
  225. /**
  226. * glink_bgcom_xprt_tx_cmd_safe() - Transmit G-Link commands
  227. * @einfo: Edge information corresponding to the remote subsystem.
  228. * @src: Source buffer containing the G-Link command.
  229. * @size: Size of the command to transmit.
  230. *
  231. * This function is used to transmit the G-Link commands. This function
  232. * must be called with einfo->write_lock locked.
  233. *
  234. * Return: 0 on success, standard Linux error codes on error.
  235. */
  236. static int glink_bgcom_xprt_tx_cmd_safe(struct edge_info *einfo, void *src,
  237. uint32_t size)
  238. {
  239. uint32_t tx_avail = glink_bgcom_get_tx_avail(einfo);
  240. int ret;
  241. uint32_t size_in_words = size/WORD_SIZE;
  242. if (size_in_words > tx_avail) {
  243. GLINK_ERR("%s: No Space in Fifo\n", __func__);
  244. return -ENOSPC;
  245. }
  246. ret = bgcom_fifo_write(einfo->bgcom_handle, size_in_words, src);
  247. if (ret < 0) {
  248. GLINK_ERR("%s: Error %d writing data\n", __func__, ret);
  249. return ret;
  250. }
  251. glink_bgcom_update_tx_avail(einfo, size_in_words);
  252. return ret;
  253. }
  254. /**
  255. * send_tx_blocked_signal() - Send flow control request message
  256. * @einfo: Edge information corresponding to the remote subsystem.
  257. *
  258. * This function is used to send a message to the remote subsystem indicating
  259. * that the local subsystem is waiting for the write space. The remote
  260. * subsystem on receiving this message will send a resume tx message.
  261. */
  262. static void send_tx_blocked_signal(struct edge_info *einfo)
  263. {
  264. struct read_notif_request {
  265. uint16_t cmd;
  266. uint16_t reserved;
  267. uint32_t reserved2;
  268. uint64_t reserved3;
  269. };
  270. struct read_notif_request read_notif_req = {0};
  271. int size_in_word = sizeof(read_notif_req)/WORD_SIZE;
  272. void *src = &read_notif_req;
  273. int ret;
  274. read_notif_req.cmd = READ_NOTIF_CMD;
  275. if (!einfo->tx_blocked_signal_sent) {
  276. einfo->tx_blocked_signal_sent = true;
  277. ret = bgcom_fifo_write(einfo->bgcom_handle, size_in_word, src);
  278. if (ret < 0) {
  279. GLINK_ERR("%s: Err %d send blocked\n", __func__, ret);
  280. return;
  281. }
  282. glink_bgcom_update_tx_avail(einfo, size_in_word);
  283. }
  284. }
  285. /**
  286. * glink_bgcom_xprt_tx_cmd() - Transmit G-Link commands
  287. * @einfo: Edge information corresponding to the remote subsystem.
  288. * @src: Source buffer containing the G-Link command.
  289. * @size: Size of the command to transmit.
  290. *
  291. * This function is used to transmit the G-Link commands. This function
  292. * might sleep if the space is not available to transmit the command.
  293. *
  294. * Return: 0 on success, standard Linux error codes on error.
  295. */
  296. static int glink_bgcom_xprt_tx_cmd(struct edge_info *einfo, void *src,
  297. uint32_t size)
  298. {
  299. int ret;
  300. DEFINE_WAIT(wait);
  301. mutex_lock(&einfo->write_lock);
  302. while (glink_bgcom_get_tx_avail(einfo) < (size/WORD_SIZE)) {
  303. send_tx_blocked_signal(einfo);
  304. prepare_to_wait(&einfo->tx_blocked_queue, &wait,
  305. TASK_UNINTERRUPTIBLE);
  306. if (glink_bgcom_get_tx_avail(einfo) < (size/WORD_SIZE)
  307. && !einfo->in_ssr) {
  308. mutex_unlock(&einfo->write_lock);
  309. schedule();
  310. mutex_lock(&einfo->write_lock);
  311. }
  312. finish_wait(&einfo->tx_blocked_queue, &wait);
  313. if (einfo->in_ssr) {
  314. mutex_unlock(&einfo->write_lock);
  315. return -EFAULT;
  316. }
  317. }
  318. ret = glink_bgcom_xprt_tx_cmd_safe(einfo, src, size);
  319. mutex_unlock(&einfo->write_lock);
  320. return ret;
  321. }
  322. /**
  323. * process_rx_data() - process received data from an edge
  324. * @einfo: The edge the data is received on.
  325. * @cmd_id: ID to specify the type of data.
  326. * @rcid: The remote channel id associated with the data.
  327. * @intend_id: The intent the data should be put in.
  328. * @src: Address of the source buffer from which the data
  329. * is read.
  330. * @frag_size: Size of the data fragment to read.
  331. * @size_remaining: Size of data left to be read in this packet.
  332. */
  333. static void process_rx_data(struct edge_info *einfo, uint16_t cmd_id,
  334. uint32_t rcid, uint32_t intent_id, void *src,
  335. uint32_t frag_size, uint32_t size_remaining)
  336. {
  337. struct glink_core_rx_intent *intent;
  338. int rc = 0;
  339. intent = einfo->xprt_if.glink_core_if_ptr->rx_get_pkt_ctx(
  340. &einfo->xprt_if, rcid, intent_id);
  341. if (intent == NULL) {
  342. GLINK_ERR("%s: no intent for ch %d liid %d\n", __func__, rcid,
  343. intent_id);
  344. return;
  345. } else if (intent->data == NULL) {
  346. GLINK_ERR("%s: intent for ch %d liid %d has no data buff\n",
  347. __func__, rcid, intent_id);
  348. return;
  349. } else if (intent->intent_size - intent->write_offset < frag_size ||
  350. intent->write_offset + size_remaining > intent->intent_size) {
  351. GLINK_ERR("%s: rx data size:%d and remaining:%d %s %d %s:%d\n",
  352. __func__, frag_size, size_remaining,
  353. "will overflow ch", rcid, "intent", intent_id);
  354. return;
  355. }
  356. rc = bgcom_ahb_read(einfo->bgcom_handle, (uint32_t)(size_t)src,
  357. ALIGN(frag_size, WORD_SIZE)/WORD_SIZE,
  358. intent->data + intent->write_offset);
  359. if (rc < 0) {
  360. GLINK_ERR("%s: Error %d receiving data %d:%d:%d:%d\n",
  361. __func__, rc, rcid, intent_id, frag_size,
  362. size_remaining);
  363. size_remaining += frag_size;
  364. } else {
  365. intent->write_offset += frag_size;
  366. intent->pkt_size += frag_size;
  367. if (unlikely((cmd_id == TRACER_PKT_CMD ||
  368. cmd_id == TRACER_PKT_CONT_CMD) && !size_remaining)) {
  369. tracer_pkt_log_event(intent->data, GLINK_XPRT_RX);
  370. intent->tracer_pkt = true;
  371. }
  372. }
  373. einfo->xprt_if.glink_core_if_ptr->rx_put_pkt_ctx(&einfo->xprt_if,
  374. rcid, intent, size_remaining ? false : true);
  375. }
  376. /**
  377. * process_rx_cmd() - Process incoming G-Link commands
  378. * @einfo: Edge information corresponding to the remote subsystem.
  379. * @rx_data: Buffer which contains the G-Link commands to be processed.
  380. * @rx_size: Size of the buffer containing the series of G-Link commands.
  381. *
  382. * This function is used to parse and process a series of G-Link commands
  383. * received in a buffer.
  384. */
  385. static void process_rx_cmd(struct edge_info *einfo,
  386. void *rx_data, int rx_size)
  387. {
  388. struct command {
  389. uint16_t id;
  390. uint16_t param1;
  391. uint32_t param2;
  392. uint32_t param3;
  393. uint32_t param4;
  394. };
  395. struct intent_desc {
  396. uint32_t size;
  397. uint32_t id;
  398. uint64_t addr;
  399. };
  400. struct rx_desc {
  401. uint32_t size;
  402. uint32_t size_left;
  403. uint64_t addr;
  404. };
  405. struct command *cmd;
  406. struct intent_desc *intents;
  407. struct rx_desc *rx_descp;
  408. int offset = 0;
  409. int rcu_id;
  410. uint16_t rcid;
  411. uint16_t name_len;
  412. uint16_t prio;
  413. char *name;
  414. bool granted;
  415. int i;
  416. rcu_id = srcu_read_lock(&einfo->use_ref);
  417. if (einfo->in_ssr) {
  418. srcu_read_unlock(&einfo->use_ref, rcu_id);
  419. return;
  420. }
  421. while (offset < rx_size) {
  422. cmd = (struct command *)(rx_data + offset);
  423. offset += sizeof(*cmd);
  424. switch (cmd->id) {
  425. case VERSION_CMD:
  426. einfo->xprt_if.glink_core_if_ptr->rx_cmd_version(
  427. &einfo->xprt_if, cmd->param1, cmd->param2);
  428. break;
  429. case VERSION_ACK_CMD:
  430. einfo->xprt_if.glink_core_if_ptr->rx_cmd_version_ack(
  431. &einfo->xprt_if, cmd->param1, cmd->param2);
  432. break;
  433. case OPEN_CMD:
  434. rcid = cmd->param1;
  435. name_len = (uint16_t)(cmd->param2 & 0xFFFF);
  436. prio = (uint16_t)((cmd->param2 & 0xFFFF0000) >> 16);
  437. name = (char *)(rx_data + offset);
  438. offset += ALIGN(name_len, FIFO_ALIGNMENT);
  439. einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_remote_open(
  440. &einfo->xprt_if, rcid, name, prio);
  441. break;
  442. case CLOSE_CMD:
  443. einfo->xprt_if.glink_core_if_ptr->
  444. rx_cmd_ch_remote_close(
  445. &einfo->xprt_if, cmd->param1);
  446. break;
  447. case OPEN_ACK_CMD:
  448. prio = (uint16_t)(cmd->param2 & 0xFFFF);
  449. einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_open_ack(
  450. &einfo->xprt_if, cmd->param1, prio);
  451. break;
  452. case CLOSE_ACK_CMD:
  453. einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_close_ack(
  454. &einfo->xprt_if, cmd->param1);
  455. break;
  456. case RX_INTENT_CMD:
  457. for (i = 0; i < cmd->param2; i++) {
  458. intents = (struct intent_desc *)
  459. (rx_data + offset);
  460. offset += sizeof(*intents);
  461. einfo->xprt_if.glink_core_if_ptr->
  462. rx_cmd_remote_rx_intent_put_cookie(
  463. &einfo->xprt_if, cmd->param1,
  464. intents->id, intents->size,
  465. (void *)(uintptr_t)(intents->addr));
  466. }
  467. break;
  468. case RX_DONE_CMD:
  469. einfo->xprt_if.glink_core_if_ptr->rx_cmd_tx_done(
  470. &einfo->xprt_if, cmd->param1, cmd->param2,
  471. false);
  472. break;
  473. case RX_INTENT_REQ_CMD:
  474. einfo->xprt_if.glink_core_if_ptr->
  475. rx_cmd_remote_rx_intent_req(
  476. &einfo->xprt_if, cmd->param1,
  477. cmd->param2);
  478. break;
  479. case RX_INTENT_REQ_ACK_CMD:
  480. granted = cmd->param2 == 1 ? true : false;
  481. einfo->xprt_if.glink_core_if_ptr->
  482. rx_cmd_rx_intent_req_ack(&einfo->xprt_if,
  483. cmd->param1, granted);
  484. break;
  485. case TX_DATA_CMD:
  486. case TX_DATA_CONT_CMD:
  487. case TRACER_PKT_CMD:
  488. case TRACER_PKT_CONT_CMD:
  489. rx_descp = (struct rx_desc *)(rx_data + offset);
  490. offset += sizeof(*rx_descp);
  491. process_rx_data(einfo, cmd->id, cmd->param1,
  492. cmd->param2,
  493. (void *)(uintptr_t)(rx_descp->addr),
  494. rx_descp->size, rx_descp->size_left);
  495. break;
  496. case READ_NOTIF_CMD:
  497. break;
  498. case SIGNALS_CMD:
  499. einfo->xprt_if.glink_core_if_ptr->rx_cmd_remote_sigs(
  500. &einfo->xprt_if, cmd->param1, cmd->param2);
  501. break;
  502. case RX_DONE_W_REUSE_CMD:
  503. einfo->xprt_if.glink_core_if_ptr->rx_cmd_tx_done(
  504. &einfo->xprt_if, cmd->param1,
  505. cmd->param2, true);
  506. break;
  507. default:
  508. GLINK_ERR("Unrecognized command: %d\n", cmd->id);
  509. break;
  510. }
  511. }
  512. srcu_read_unlock(&einfo->use_ref, rcu_id);
  513. }
  514. /**
  515. * tx_wakeup_worker() - worker function to wakeup tx blocked thread
  516. * @work: kwork associated with the edge to process commands on.
  517. */
  518. static void tx_wakeup_worker(struct edge_info *einfo)
  519. {
  520. int rcu_id;
  521. struct bgcom_fifo_fill fifo_fill;
  522. mutex_lock(&einfo->tx_avail_lock);
  523. bgcom_reg_read(einfo->bgcom_handle, BGCOM_REG_FIFO_FILL, 1,
  524. &fifo_fill);
  525. einfo->fifo_fill.tx_avail = fifo_fill.tx_avail;
  526. if (einfo->fifo_fill.tx_avail > einfo->fifo_size.to_slave/2)
  527. einfo->water_mark_reached = false;
  528. mutex_unlock(&einfo->tx_avail_lock);
  529. rcu_id = srcu_read_lock(&einfo->use_ref);
  530. if (einfo->in_ssr) {
  531. srcu_read_unlock(&einfo->use_ref, rcu_id);
  532. return;
  533. }
  534. if (einfo->tx_resume_needed &&
  535. glink_bgcom_get_tx_avail(einfo)) {
  536. einfo->tx_resume_needed = false;
  537. einfo->xprt_if.glink_core_if_ptr->tx_resume(
  538. &einfo->xprt_if);
  539. }
  540. mutex_lock(&einfo->write_lock);
  541. if (einfo->tx_blocked_signal_sent) {
  542. wake_up_all(&einfo->tx_blocked_queue);
  543. einfo->tx_blocked_signal_sent = false;
  544. }
  545. mutex_unlock(&einfo->write_lock);
  546. srcu_read_unlock(&einfo->use_ref, rcu_id);
  547. }
  548. /**
  549. * __rx_worker() - Receive commands on a specific edge
  550. * @einfo: Edge to process commands on.
  551. *
  552. * This function checks the size of data to be received, allocates the
  553. * buffer for that data and reads the data from the remote subsytem
  554. * into that buffer. This function then calls the process_rx_cmd() to
  555. * parse the received G-Link command sequence. This function will also
  556. * poll for the data for a predefined duration for performance reasons.
  557. */
  558. static void __rx_worker(struct rx_pkt *rx_pkt_info)
  559. {
  560. int rcu_id;
  561. struct edge_info *einfo = rx_pkt_info->einfo;
  562. rcu_id = srcu_read_lock(&einfo->use_ref);
  563. if (einfo->in_ssr) {
  564. srcu_read_unlock(&einfo->use_ref, rcu_id);
  565. return;
  566. }
  567. process_rx_cmd(einfo, rx_pkt_info->rx_buf,
  568. rx_pkt_info->rx_len*WORD_SIZE);
  569. kfree(rx_pkt_info->rx_buf);
  570. kfree(rx_pkt_info);
  571. srcu_read_unlock(&einfo->use_ref, rcu_id);
  572. }
  573. /**
  574. * rx_worker() - Worker function to process received commands
  575. * @work: kwork associated with the edge to process commands on.
  576. */
  577. static void rx_worker(struct kthread_work *work)
  578. {
  579. struct rx_pkt *rx_pkt_info;
  580. rx_pkt_info = container_of(work, struct rx_pkt, kwork);
  581. __rx_worker(rx_pkt_info);
  582. };
  583. /**
  584. * tx_cmd_version() - Convert a version cmd to wire format and transmit
  585. * @if_ptr: The transport to transmit on.
  586. * @version: The version number to encode.
  587. * @features: The features information to encode.
  588. */
  589. static void tx_cmd_version(struct glink_transport_if *if_ptr, uint32_t version,
  590. uint32_t features)
  591. {
  592. struct command {
  593. uint16_t id;
  594. uint16_t version;
  595. uint32_t features;
  596. uint32_t fifo_size;
  597. uint32_t reserved;
  598. };
  599. struct command cmd;
  600. struct edge_info *einfo;
  601. int rcu_id;
  602. memset(&cmd, 0, sizeof(cmd));
  603. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  604. rcu_id = srcu_read_lock(&einfo->use_ref);
  605. if (einfo->in_ssr) {
  606. srcu_read_unlock(&einfo->use_ref, rcu_id);
  607. return;
  608. }
  609. cmd.id = VERSION_CMD;
  610. cmd.version = version;
  611. cmd.features = features;
  612. glink_bgcom_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
  613. srcu_read_unlock(&einfo->use_ref, rcu_id);
  614. }
  615. /**
  616. * tx_cmd_version_ack() - Convert a version ack cmd to wire format and transmit
  617. * @if_ptr: The transport to transmit on.
  618. * @version: The version number to encode.
  619. * @features: The features information to encode.
  620. */
  621. static void tx_cmd_version_ack(struct glink_transport_if *if_ptr,
  622. uint32_t version,
  623. uint32_t features)
  624. {
  625. struct command {
  626. uint16_t id;
  627. uint16_t version;
  628. uint32_t features;
  629. uint32_t fifo_size;
  630. uint32_t reserved;
  631. };
  632. struct command cmd;
  633. struct edge_info *einfo;
  634. int rcu_id;
  635. memset(&cmd, 0, sizeof(cmd));
  636. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  637. rcu_id = srcu_read_lock(&einfo->use_ref);
  638. if (einfo->in_ssr) {
  639. srcu_read_unlock(&einfo->use_ref, rcu_id);
  640. return;
  641. }
  642. cmd.id = VERSION_ACK_CMD;
  643. cmd.version = version;
  644. cmd.features = features;
  645. glink_bgcom_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
  646. srcu_read_unlock(&einfo->use_ref, rcu_id);
  647. }
  648. /**
  649. * set_version() - Activate a negotiated version and feature set
  650. * @if_ptr: The transport to configure.
  651. * @version: The version to use.
  652. * @features: The features to use.
  653. *
  654. * Return: The supported capabilities of the transport.
  655. */
  656. static uint32_t set_version(struct glink_transport_if *if_ptr, uint32_t version,
  657. uint32_t features)
  658. {
  659. struct edge_info *einfo;
  660. uint32_t ret;
  661. int rcu_id;
  662. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  663. rcu_id = srcu_read_lock(&einfo->use_ref);
  664. if (einfo->in_ssr) {
  665. srcu_read_unlock(&einfo->use_ref, rcu_id);
  666. return 0;
  667. }
  668. ret = GCAP_SIGNALS;
  669. if (features & TRACER_PKT_FEATURE)
  670. ret |= GCAP_TRACER_PKT;
  671. srcu_read_unlock(&einfo->use_ref, rcu_id);
  672. return ret;
  673. }
  674. /**
  675. * tx_cmd_ch_open() - Convert a channel open cmd to wire format and transmit
  676. * @if_ptr: The transport to transmit on.
  677. * @lcid: The local channel id to encode.
  678. * @name: The channel name to encode.
  679. * @req_xprt: The transport the core would like to migrate this channel to.
  680. *
  681. * Return: 0 on success or standard Linux error code.
  682. */
  683. static int tx_cmd_ch_open(struct glink_transport_if *if_ptr, uint32_t lcid,
  684. const char *name, uint16_t req_xprt)
  685. {
  686. struct command {
  687. uint16_t id;
  688. uint16_t lcid;
  689. uint16_t length;
  690. uint16_t req_xprt;
  691. uint64_t reserved;
  692. };
  693. struct command cmd;
  694. struct edge_info *einfo;
  695. uint32_t buf_size;
  696. void *buf;
  697. int rcu_id;
  698. memset(&cmd, 0, sizeof(cmd));
  699. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  700. rcu_id = srcu_read_lock(&einfo->use_ref);
  701. if (einfo->in_ssr) {
  702. srcu_read_unlock(&einfo->use_ref, rcu_id);
  703. return -EFAULT;
  704. }
  705. cmd.id = OPEN_CMD;
  706. cmd.lcid = lcid;
  707. cmd.length = (uint16_t)(strlen(name) + 1);
  708. cmd.req_xprt = req_xprt;
  709. buf_size = ALIGN(sizeof(cmd) + cmd.length, FIFO_ALIGNMENT);
  710. buf = kzalloc(buf_size, GFP_KERNEL);
  711. if (!buf) {
  712. srcu_read_unlock(&einfo->use_ref, rcu_id);
  713. return -ENOMEM;
  714. }
  715. memcpy(buf, &cmd, sizeof(cmd));
  716. memcpy(buf + sizeof(cmd), name, cmd.length);
  717. glink_bgcom_xprt_tx_cmd(einfo, buf, buf_size);
  718. kfree(buf);
  719. srcu_read_unlock(&einfo->use_ref, rcu_id);
  720. return 0;
  721. }
  722. /**
  723. * tx_cmd_ch_close() - Convert a channel close cmd to wire format and transmit
  724. * @if_ptr: The transport to transmit on.
  725. * @lcid: The local channel id to encode.
  726. *
  727. * Return: 0 on success or standard Linux error code.
  728. */
  729. static int tx_cmd_ch_close(struct glink_transport_if *if_ptr, uint32_t lcid)
  730. {
  731. struct command {
  732. uint16_t id;
  733. uint16_t lcid;
  734. uint32_t reserved1;
  735. uint64_t reserved2;
  736. };
  737. struct command cmd;
  738. struct edge_info *einfo;
  739. int rcu_id;
  740. memset(&cmd, 0, sizeof(cmd));
  741. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  742. rcu_id = srcu_read_lock(&einfo->use_ref);
  743. if (einfo->in_ssr) {
  744. srcu_read_unlock(&einfo->use_ref, rcu_id);
  745. return -EFAULT;
  746. }
  747. cmd.id = CLOSE_CMD;
  748. cmd.lcid = lcid;
  749. glink_bgcom_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
  750. srcu_read_unlock(&einfo->use_ref, rcu_id);
  751. return 0;
  752. }
  753. /**
  754. * tx_cmd_ch_remote_open_ack() - Convert a channel open ack cmd to wire format
  755. * and transmit
  756. * @if_ptr: The transport to transmit on.
  757. * @rcid: The remote channel id to encode.
  758. * @xprt_resp: The response to a transport migration request.
  759. */
  760. static void tx_cmd_ch_remote_open_ack(struct glink_transport_if *if_ptr,
  761. uint32_t rcid, uint16_t xprt_resp)
  762. {
  763. struct command {
  764. uint16_t id;
  765. uint16_t rcid;
  766. uint16_t reserved1;
  767. uint16_t xprt_resp;
  768. uint64_t reserved2;
  769. };
  770. struct command cmd;
  771. struct edge_info *einfo;
  772. int rcu_id;
  773. memset(&cmd, 0, sizeof(cmd));
  774. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  775. rcu_id = srcu_read_lock(&einfo->use_ref);
  776. if (einfo->in_ssr) {
  777. srcu_read_unlock(&einfo->use_ref, rcu_id);
  778. return;
  779. }
  780. cmd.id = OPEN_ACK_CMD;
  781. cmd.rcid = rcid;
  782. cmd.xprt_resp = xprt_resp;
  783. glink_bgcom_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
  784. srcu_read_unlock(&einfo->use_ref, rcu_id);
  785. }
  786. /**
  787. * tx_cmd_ch_remote_close_ack() - Convert a channel close ack cmd to wire format
  788. * and transmit
  789. * @if_ptr: The transport to transmit on.
  790. * @rcid: The remote channel id to encode.
  791. */
  792. static void tx_cmd_ch_remote_close_ack(struct glink_transport_if *if_ptr,
  793. uint32_t rcid)
  794. {
  795. struct command {
  796. uint16_t id;
  797. uint16_t rcid;
  798. uint32_t reserved1;
  799. uint64_t reserved2;
  800. };
  801. struct command cmd;
  802. struct edge_info *einfo;
  803. int rcu_id;
  804. memset(&cmd, 0, sizeof(cmd));
  805. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  806. rcu_id = srcu_read_lock(&einfo->use_ref);
  807. if (einfo->in_ssr) {
  808. srcu_read_unlock(&einfo->use_ref, rcu_id);
  809. return;
  810. }
  811. cmd.id = CLOSE_ACK_CMD;
  812. cmd.rcid = rcid;
  813. glink_bgcom_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
  814. srcu_read_unlock(&einfo->use_ref, rcu_id);
  815. }
  816. /**
  817. * ssr() - Process a subsystem restart notification of a transport
  818. * @if_ptr: The transport to restart
  819. *
  820. * Return: 0 on success or standard Linux error code.
  821. */
  822. static int ssr(struct glink_transport_if *if_ptr)
  823. {
  824. struct edge_info *einfo;
  825. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  826. einfo->in_ssr = true;
  827. wake_up_all(&einfo->tx_blocked_queue);
  828. synchronize_srcu(&einfo->use_ref);
  829. einfo->tx_resume_needed = false;
  830. einfo->tx_blocked_signal_sent = false;
  831. einfo->xprt_if.glink_core_if_ptr->link_down(&einfo->xprt_if);
  832. return 0;
  833. }
  834. /**
  835. * allocate_rx_intent() - Allocate/reserve space for RX Intent
  836. * @if_ptr: The transport the intent is associated with.
  837. * @size: size of intent.
  838. * @intent: Pointer to the intent structure.
  839. *
  840. * Assign "data" with the buffer created, since the transport creates
  841. * a linear buffer and "iovec" with the "intent" itself, so that
  842. * the data can be passed to a client that receives only vector buffer.
  843. * Note that returning NULL for the pointer is valid (it means that space has
  844. * been reserved, but the actual pointer will be provided later).
  845. *
  846. * Return: 0 on success or standard Linux error code.
  847. */
  848. static int allocate_rx_intent(struct glink_transport_if *if_ptr, size_t size,
  849. struct glink_core_rx_intent *intent)
  850. {
  851. void *t;
  852. t = kzalloc(ALIGN(size, WORD_SIZE), GFP_KERNEL);
  853. if (!t)
  854. return -ENOMEM;
  855. intent->data = t;
  856. intent->iovec = (void *)intent;
  857. intent->vprovider = rx_linear_vbuf_provider;
  858. intent->pprovider = NULL;
  859. return 0;
  860. }
  861. /**
  862. * deallocate_rx_intent() - Deallocate space created for RX Intent
  863. * @if_ptr: The transport the intent is associated with.
  864. * @intent: Pointer to the intent structure.
  865. *
  866. * Return: 0 on success or standard Linux error code.
  867. */
  868. static int deallocate_rx_intent(struct glink_transport_if *if_ptr,
  869. struct glink_core_rx_intent *intent)
  870. {
  871. if (!intent || !intent->data)
  872. return -EINVAL;
  873. kfree(intent->data);
  874. intent->data = NULL;
  875. intent->iovec = NULL;
  876. intent->vprovider = NULL;
  877. return 0;
  878. }
  879. /**
  880. * tx_cmd_local_rx_intent() - Convert an rx intent cmd to wire format and
  881. * transmit
  882. * @if_ptr: The transport to transmit on.
  883. * @lcid: The local channel id to encode.
  884. * @size: The intent size to encode.
  885. * @liid: The local intent id to encode.
  886. *
  887. * Return: 0 on success or standard Linux error code.
  888. */
  889. static int tx_cmd_local_rx_intent(struct glink_transport_if *if_ptr,
  890. uint32_t lcid, size_t size, uint32_t liid)
  891. {
  892. struct command {
  893. uint16_t id;
  894. uint16_t lcid;
  895. uint32_t count;
  896. uint64_t reserved;
  897. uint32_t size;
  898. uint32_t liid;
  899. uint64_t addr;
  900. };
  901. struct command cmd;
  902. struct edge_info *einfo;
  903. int rcu_id;
  904. if (size > UINT_MAX) {
  905. GLINK_ERR("%s: size %zu is too large to encode\n",
  906. __func__, size);
  907. return -EMSGSIZE;
  908. }
  909. memset(&cmd, 0, sizeof(cmd));
  910. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  911. rcu_id = srcu_read_lock(&einfo->use_ref);
  912. if (einfo->in_ssr) {
  913. srcu_read_unlock(&einfo->use_ref, rcu_id);
  914. return -EFAULT;
  915. }
  916. cmd.id = RX_INTENT_CMD;
  917. cmd.lcid = lcid;
  918. cmd.count = 1;
  919. cmd.size = size;
  920. cmd.liid = liid;
  921. glink_bgcom_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
  922. srcu_read_unlock(&einfo->use_ref, rcu_id);
  923. return 0;
  924. }
  925. /**
  926. * tx_cmd_local_rx_done() - Convert an rx done cmd to wire format and transmit
  927. * @if_ptr: The transport to transmit on.
  928. * @lcid: The local channel id to encode.
  929. * @liid: The local intent id to encode.
  930. * @reuse: Reuse the consumed intent.
  931. */
  932. static void tx_cmd_local_rx_done(struct glink_transport_if *if_ptr,
  933. uint32_t lcid, uint32_t liid, bool reuse)
  934. {
  935. struct command {
  936. uint16_t id;
  937. uint16_t lcid;
  938. uint32_t liid;
  939. uint64_t reserved;
  940. };
  941. struct command cmd;
  942. struct edge_info *einfo;
  943. int rcu_id;
  944. memset(&cmd, 0, sizeof(cmd));
  945. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  946. rcu_id = srcu_read_lock(&einfo->use_ref);
  947. if (einfo->in_ssr) {
  948. srcu_read_unlock(&einfo->use_ref, rcu_id);
  949. return;
  950. }
  951. cmd.id = reuse ? RX_DONE_W_REUSE_CMD : RX_DONE_CMD;
  952. cmd.lcid = lcid;
  953. cmd.liid = liid;
  954. glink_bgcom_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
  955. srcu_read_unlock(&einfo->use_ref, rcu_id);
  956. }
  957. /**
  958. * tx_cmd_rx_intent_req() - Convert an rx intent request cmd to wire format and
  959. * transmit
  960. * @if_ptr: The transport to transmit on.
  961. * @lcid: The local channel id to encode.
  962. * @size: The requested intent size to encode.
  963. *
  964. * Return: 0 on success or standard Linux error code.
  965. */
  966. static int tx_cmd_rx_intent_req(struct glink_transport_if *if_ptr,
  967. uint32_t lcid, size_t size)
  968. {
  969. struct command {
  970. uint16_t id;
  971. uint16_t lcid;
  972. uint32_t size;
  973. uint64_t reserved;
  974. };
  975. struct command cmd;
  976. struct edge_info *einfo;
  977. int rcu_id;
  978. if (size > UINT_MAX) {
  979. GLINK_ERR("%s: size %zu is too large to encode\n",
  980. __func__, size);
  981. return -EMSGSIZE;
  982. }
  983. memset(&cmd, 0, sizeof(cmd));
  984. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  985. rcu_id = srcu_read_lock(&einfo->use_ref);
  986. if (einfo->in_ssr) {
  987. srcu_read_unlock(&einfo->use_ref, rcu_id);
  988. return -EFAULT;
  989. }
  990. cmd.id = RX_INTENT_REQ_CMD,
  991. cmd.lcid = lcid;
  992. cmd.size = ALIGN(size, WORD_SIZE);
  993. glink_bgcom_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
  994. srcu_read_unlock(&einfo->use_ref, rcu_id);
  995. return 0;
  996. }
  997. /**
  998. * tx_cmd_rx_intent_req_ack() - Convert an rx intent request ack cmd to wire
  999. * format and transmit
  1000. * @if_ptr: The transport to transmit on.
  1001. * @lcid: The local channel id to encode.
  1002. * @granted: The request response to encode.
  1003. *
  1004. * Return: 0 on success or standard Linux error code.
  1005. */
  1006. static int tx_cmd_remote_rx_intent_req_ack(struct glink_transport_if *if_ptr,
  1007. uint32_t lcid, bool granted)
  1008. {
  1009. struct command {
  1010. uint16_t id;
  1011. uint16_t lcid;
  1012. uint32_t response;
  1013. uint64_t reserved;
  1014. };
  1015. struct command cmd;
  1016. struct edge_info *einfo;
  1017. int rcu_id;
  1018. memset(&cmd, 0, sizeof(cmd));
  1019. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  1020. rcu_id = srcu_read_lock(&einfo->use_ref);
  1021. if (einfo->in_ssr) {
  1022. srcu_read_unlock(&einfo->use_ref, rcu_id);
  1023. return -EFAULT;
  1024. }
  1025. cmd.id = RX_INTENT_REQ_ACK_CMD,
  1026. cmd.lcid = lcid;
  1027. if (granted)
  1028. cmd.response = 1;
  1029. else
  1030. cmd.response = 0;
  1031. glink_bgcom_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
  1032. srcu_read_unlock(&einfo->use_ref, rcu_id);
  1033. return 0;
  1034. }
  1035. /**
  1036. * tx_cmd_set_sigs() - Convert a signals ack cmd to wire format and transmit
  1037. * @if_ptr: The transport to transmit on.
  1038. * @lcid: The local channel id to encode.
  1039. * @sigs: The signals to encode.
  1040. *
  1041. * Return: 0 on success or standard Linux error code.
  1042. */
  1043. static int tx_cmd_set_sigs(struct glink_transport_if *if_ptr, uint32_t lcid,
  1044. uint32_t sigs)
  1045. {
  1046. struct command {
  1047. uint16_t id;
  1048. uint16_t lcid;
  1049. uint32_t sigs;
  1050. uint64_t reserved;
  1051. };
  1052. struct command cmd;
  1053. struct edge_info *einfo;
  1054. int rcu_id;
  1055. memset(&cmd, 0, sizeof(cmd));
  1056. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  1057. rcu_id = srcu_read_lock(&einfo->use_ref);
  1058. if (einfo->in_ssr) {
  1059. srcu_read_unlock(&einfo->use_ref, rcu_id);
  1060. return -EFAULT;
  1061. }
  1062. cmd.id = SIGNALS_CMD,
  1063. cmd.lcid = lcid;
  1064. cmd.sigs = sigs;
  1065. glink_bgcom_xprt_tx_cmd(einfo, &cmd, sizeof(cmd));
  1066. srcu_read_unlock(&einfo->use_ref, rcu_id);
  1067. return 0;
  1068. }
  1069. /**
  1070. * tx_data() - convert a data/tracer_pkt to wire format and transmit
  1071. * @if_ptr: The transport to transmit on.
  1072. * @cmd_id: The command ID to transmit.
  1073. * @lcid: The local channel id to encode.
  1074. * @pctx: The data to encode.
  1075. *
  1076. * Return: Number of bytes written or standard Linux error code.
  1077. */
  1078. static int tx_data(struct glink_transport_if *if_ptr, uint16_t cmd_id,
  1079. uint32_t lcid, struct glink_core_tx_pkt *pctx)
  1080. {
  1081. struct command {
  1082. uint16_t id;
  1083. uint16_t lcid;
  1084. uint32_t riid;
  1085. uint64_t reserved;
  1086. uint32_t size;
  1087. uint32_t size_left;
  1088. uint64_t addr;
  1089. };
  1090. struct command cmd;
  1091. struct edge_info *einfo;
  1092. void *data_start, *dst = NULL;
  1093. size_t tx_size = 0;
  1094. int rcu_id;
  1095. if (pctx->size < pctx->size_remaining) {
  1096. GLINK_ERR("%s: size remaining exceeds size. Resetting.\n",
  1097. __func__);
  1098. pctx->size_remaining = pctx->size;
  1099. }
  1100. if (!pctx->size_remaining)
  1101. return 0;
  1102. memset(&cmd, 0, sizeof(cmd));
  1103. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  1104. rcu_id = srcu_read_lock(&einfo->use_ref);
  1105. if (einfo->in_ssr) {
  1106. srcu_read_unlock(&einfo->use_ref, rcu_id);
  1107. return -EFAULT;
  1108. }
  1109. if (cmd_id == TX_DATA_CMD) {
  1110. if (pctx->size_remaining == pctx->size)
  1111. cmd.id = TX_DATA_CMD;
  1112. else
  1113. cmd.id = TX_DATA_CONT_CMD;
  1114. } else {
  1115. if (pctx->size_remaining == pctx->size)
  1116. cmd.id = TRACER_PKT_CMD;
  1117. else
  1118. cmd.id = TRACER_PKT_CONT_CMD;
  1119. }
  1120. cmd.lcid = lcid;
  1121. cmd.riid = pctx->riid;
  1122. data_start = get_tx_vaddr(pctx, pctx->size - pctx->size_remaining,
  1123. &tx_size);
  1124. if (unlikely(!data_start)) {
  1125. GLINK_ERR("%s: invalid data_start\n", __func__);
  1126. srcu_read_unlock(&einfo->use_ref, rcu_id);
  1127. return -EINVAL;
  1128. }
  1129. if (likely(pctx->cookie))
  1130. dst = pctx->cookie + (pctx->size - pctx->size_remaining);
  1131. mutex_lock(&einfo->write_lock);
  1132. /* Need enough space to write the command */
  1133. if (glink_bgcom_get_tx_avail(einfo) <= sizeof(cmd)/WORD_SIZE) {
  1134. einfo->tx_resume_needed = true;
  1135. send_tx_blocked_signal(einfo);
  1136. mutex_unlock(&einfo->write_lock);
  1137. srcu_read_unlock(&einfo->use_ref, rcu_id);
  1138. GLINK_ERR("%s: No Space in Fifo\n", __func__);
  1139. return -EAGAIN;
  1140. }
  1141. cmd.addr = 0;
  1142. cmd.size = tx_size;
  1143. pctx->size_remaining -= tx_size;
  1144. cmd.size_left = pctx->size_remaining;
  1145. if (cmd.id == TRACER_PKT_CMD)
  1146. tracer_pkt_log_event((void *)(pctx->data), GLINK_XPRT_TX);
  1147. bgcom_resume(einfo->bgcom_handle);
  1148. bgcom_ahb_write(einfo->bgcom_handle, (uint32_t)(size_t)dst,
  1149. ALIGN(tx_size, WORD_SIZE)/WORD_SIZE,
  1150. data_start);
  1151. glink_bgcom_xprt_tx_cmd_safe(einfo, &cmd, sizeof(cmd));
  1152. GLINK_DBG("%s %s: lcid[%u] riid[%u] cmd %d, size[%d], size_left[%d]\n",
  1153. "<BGCOM>", __func__, cmd.lcid, cmd.riid, cmd.id, cmd.size,
  1154. cmd.size_left);
  1155. mutex_unlock(&einfo->write_lock);
  1156. srcu_read_unlock(&einfo->use_ref, rcu_id);
  1157. return cmd.size;
  1158. }
  1159. /**
  1160. * tx() - convert a data transmit cmd to wire format and transmit
  1161. * @if_ptr: The transport to transmit on.
  1162. * @lcid: The local channel id to encode.
  1163. * @pctx: The data to encode.
  1164. *
  1165. * Return: Number of bytes written or standard Linux error code.
  1166. */
  1167. static int tx(struct glink_transport_if *if_ptr, uint32_t lcid,
  1168. struct glink_core_tx_pkt *pctx)
  1169. {
  1170. return tx_data(if_ptr, TX_DATA_CMD, lcid, pctx);
  1171. }
  1172. /**
  1173. * tx_cmd_tracer_pkt() - convert a tracer packet cmd to wire format and transmit
  1174. * @if_ptr: The transport to transmit on.
  1175. * @lcid: The local channel id to encode.
  1176. * @pctx: The data to encode.
  1177. *
  1178. * Return: Number of bytes written or standard Linux error code.
  1179. */
  1180. static int tx_cmd_tracer_pkt(struct glink_transport_if *if_ptr, uint32_t lcid,
  1181. struct glink_core_tx_pkt *pctx)
  1182. {
  1183. return tx_data(if_ptr, TRACER_PKT_CMD, lcid, pctx);
  1184. }
  1185. /**
  1186. * int wait_link_down() - Check status of read/write indices
  1187. * @if_ptr: The transport to check
  1188. *
  1189. * Return: 1 if indices are all zero, 0 otherwise
  1190. */
  1191. static int wait_link_down(struct glink_transport_if *if_ptr)
  1192. {
  1193. return 0;
  1194. }
  1195. /**
  1196. * get_power_vote_ramp_time() - Get the ramp time required for the power
  1197. * votes to be applied
  1198. * @if_ptr: The transport interface on which power voting is requested.
  1199. * @state: The power state for which ramp time is required.
  1200. *
  1201. * Return: The ramp time specific to the power state, standard error otherwise.
  1202. */
  1203. static unsigned long get_power_vote_ramp_time(
  1204. struct glink_transport_if *if_ptr, uint32_t state)
  1205. {
  1206. return 0;
  1207. }
  1208. /**
  1209. * power_vote() - Update the power votes to meet qos requirement
  1210. * @if_ptr: The transport interface on which power voting is requested.
  1211. * @state: The power state for which the voting should be done.
  1212. *
  1213. * Return: 0 on Success, standard error otherwise.
  1214. */
  1215. static int power_vote(struct glink_transport_if *if_ptr, uint32_t state)
  1216. {
  1217. unsigned long flags;
  1218. struct edge_info *einfo;
  1219. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  1220. spin_lock_irqsave(&einfo->activity_lock, flags);
  1221. einfo->activity_flag |= ACTIVE_TX;
  1222. spin_unlock_irqrestore(&einfo->activity_lock, flags);
  1223. return 0;
  1224. }
  1225. /**
  1226. * power_unvote() - Remove the all the power votes
  1227. * @if_ptr: The transport interface on which power voting is requested.
  1228. *
  1229. * Return: 0 on Success, standard error otherwise.
  1230. */
  1231. static int power_unvote(struct glink_transport_if *if_ptr)
  1232. {
  1233. unsigned long flags;
  1234. struct edge_info *einfo;
  1235. einfo = container_of(if_ptr, struct edge_info, xprt_if);
  1236. spin_lock_irqsave(&einfo->activity_lock, flags);
  1237. einfo->activity_flag &= ~ACTIVE_TX;
  1238. spin_unlock_irqrestore(&einfo->activity_lock, flags);
  1239. return 0;
  1240. }
  1241. static void glink_bgcom_linkup(struct edge_info *einfo)
  1242. {
  1243. if (einfo->bgcom_status != BGCOM_LINKUP)
  1244. return;
  1245. einfo->in_ssr = false;
  1246. synchronize_srcu(&einfo->use_ref);
  1247. bgcom_reg_read(einfo->bgcom_handle, BGCOM_REG_FIFO_SIZE, 1,
  1248. &einfo->fifo_size);
  1249. mutex_lock(&einfo->tx_avail_lock);
  1250. einfo->fifo_fill.tx_avail = einfo->fifo_size.to_master;
  1251. mutex_unlock(&einfo->tx_avail_lock);
  1252. einfo->xprt_if.glink_core_if_ptr->link_up(&einfo->xprt_if);
  1253. }
  1254. static void glink_bgcom_event_handler(void *handle,
  1255. void *priv_data, enum bgcom_event_type event,
  1256. union bgcom_event_data_type *data)
  1257. {
  1258. struct edge_info *einfo = (struct edge_info *)priv_data;
  1259. struct rx_pkt *rx_pkt_info;
  1260. switch (event) {
  1261. case BGCOM_EVENT_APPLICATION_RUNNING:
  1262. if (data->application_running &&
  1263. einfo->bgcom_status != BGCOM_LINKUP) {
  1264. einfo->bgcom_status |= BGCOM_APPLICATION_RUNNING;
  1265. glink_bgcom_linkup(einfo);
  1266. }
  1267. break;
  1268. case BGCOM_EVENT_TO_SLAVE_FIFO_READY:
  1269. if (data->to_slave_fifo_ready &&
  1270. einfo->bgcom_status != BGCOM_LINKUP) {
  1271. einfo->bgcom_status |= BGCOM_TO_SLAVE_FIFO_READY;
  1272. glink_bgcom_linkup(einfo);
  1273. }
  1274. break;
  1275. case BGCOM_EVENT_TO_MASTER_FIFO_READY:
  1276. if (data->to_master_fifo_ready &&
  1277. einfo->bgcom_status != BGCOM_LINKUP) {
  1278. einfo->bgcom_status |= BGCOM_TO_MASTER_FIFO_READY;
  1279. glink_bgcom_linkup(einfo);
  1280. }
  1281. break;
  1282. case BGCOM_EVENT_AHB_READY:
  1283. if (data->ahb_ready &&
  1284. einfo->bgcom_status != BGCOM_LINKUP) {
  1285. einfo->bgcom_status |= BGCOM_AHB_READY;
  1286. glink_bgcom_linkup(einfo);
  1287. }
  1288. break;
  1289. case BGCOM_EVENT_TO_MASTER_FIFO_USED:
  1290. rx_pkt_info = kzalloc(sizeof(struct rx_pkt), GFP_KERNEL);
  1291. rx_pkt_info->rx_buf = data->fifo_data.data;
  1292. rx_pkt_info->rx_len = data->fifo_data.to_master_fifo_used;
  1293. rx_pkt_info->einfo = einfo;
  1294. kthread_init_work(&rx_pkt_info->kwork, rx_worker);
  1295. kthread_queue_work(&einfo->kworker, &rx_pkt_info->kwork);
  1296. break;
  1297. case BGCOM_EVENT_TO_SLAVE_FIFO_FREE:
  1298. if (einfo->water_mark_reached)
  1299. tx_wakeup_worker(einfo);
  1300. break;
  1301. case BGCOM_EVENT_RESET_OCCURRED:
  1302. einfo->bgcom_status = BGCOM_RESET;
  1303. ssr(&einfo->xprt_if);
  1304. break;
  1305. case BGCOM_EVENT_ERROR_WRITE_FIFO_OVERRUN:
  1306. case BGCOM_EVENT_ERROR_WRITE_FIFO_BUS_ERR:
  1307. case BGCOM_EVENT_ERROR_WRITE_FIFO_ACCESS:
  1308. case BGCOM_EVENT_ERROR_READ_FIFO_UNDERRUN:
  1309. case BGCOM_EVENT_ERROR_READ_FIFO_BUS_ERR:
  1310. case BGCOM_EVENT_ERROR_READ_FIFO_ACCESS:
  1311. case BGCOM_EVENT_ERROR_TRUNCATED_READ:
  1312. case BGCOM_EVENT_ERROR_TRUNCATED_WRITE:
  1313. case BGCOM_EVENT_ERROR_AHB_ILLEGAL_ADDRESS:
  1314. case BGCOM_EVENT_ERROR_AHB_BUS_ERR:
  1315. GLINK_ERR("%s: ERROR %d", __func__, event);
  1316. break;
  1317. default:
  1318. GLINK_ERR("%s: unhandled event %d", __func__, event);
  1319. break;
  1320. }
  1321. }
  1322. /**
  1323. * init_xprt_if() - Initialize the xprt_if for an edge
  1324. * @einfo: The edge to initialize.
  1325. */
  1326. static void init_xprt_if(struct edge_info *einfo)
  1327. {
  1328. einfo->xprt_if.tx_cmd_version = tx_cmd_version;
  1329. einfo->xprt_if.tx_cmd_version_ack = tx_cmd_version_ack;
  1330. einfo->xprt_if.set_version = set_version;
  1331. einfo->xprt_if.tx_cmd_ch_open = tx_cmd_ch_open;
  1332. einfo->xprt_if.tx_cmd_ch_close = tx_cmd_ch_close;
  1333. einfo->xprt_if.tx_cmd_ch_remote_open_ack = tx_cmd_ch_remote_open_ack;
  1334. einfo->xprt_if.tx_cmd_ch_remote_close_ack = tx_cmd_ch_remote_close_ack;
  1335. einfo->xprt_if.ssr = ssr;
  1336. einfo->xprt_if.allocate_rx_intent = allocate_rx_intent;
  1337. einfo->xprt_if.deallocate_rx_intent = deallocate_rx_intent;
  1338. einfo->xprt_if.tx_cmd_local_rx_intent = tx_cmd_local_rx_intent;
  1339. einfo->xprt_if.tx_cmd_local_rx_done = tx_cmd_local_rx_done;
  1340. einfo->xprt_if.tx = tx;
  1341. einfo->xprt_if.tx_cmd_rx_intent_req = tx_cmd_rx_intent_req;
  1342. einfo->xprt_if.tx_cmd_remote_rx_intent_req_ack =
  1343. tx_cmd_remote_rx_intent_req_ack;
  1344. einfo->xprt_if.tx_cmd_set_sigs = tx_cmd_set_sigs;
  1345. einfo->xprt_if.wait_link_down = wait_link_down;
  1346. einfo->xprt_if.tx_cmd_tracer_pkt = tx_cmd_tracer_pkt;
  1347. einfo->xprt_if.get_power_vote_ramp_time = get_power_vote_ramp_time;
  1348. einfo->xprt_if.power_vote = power_vote;
  1349. einfo->xprt_if.power_unvote = power_unvote;
  1350. }
  1351. /**
  1352. * init_xprt_cfg() - Initialize the xprt_cfg for an edge
  1353. * @einfo: The edge to initialize.
  1354. * @name: The name of the remote side this edge communicates to.
  1355. */
  1356. static void init_xprt_cfg(struct edge_info *einfo, const char *name)
  1357. {
  1358. einfo->xprt_cfg.name = XPRT_NAME;
  1359. einfo->xprt_cfg.edge = name;
  1360. einfo->xprt_cfg.versions = versions;
  1361. einfo->xprt_cfg.versions_entries = ARRAY_SIZE(versions);
  1362. einfo->xprt_cfg.max_cid = SZ_64K;
  1363. einfo->xprt_cfg.max_iid = SZ_2G;
  1364. }
  1365. /**
  1366. * parse_qos_dt_params() - Parse the power states from DT
  1367. * @dev: Reference to the platform device for a specific edge.
  1368. * @einfo: Edge information for the edge probe function is called.
  1369. *
  1370. * Return: 0 on success, standard error code otherwise.
  1371. */
  1372. static int parse_qos_dt_params(struct device_node *node,
  1373. struct edge_info *einfo)
  1374. {
  1375. int rc;
  1376. int i;
  1377. char *key;
  1378. uint32_t *arr32;
  1379. uint32_t num_states;
  1380. key = "qcom,ramp-time";
  1381. if (!of_find_property(node, key, &num_states))
  1382. return -ENODEV;
  1383. num_states /= sizeof(uint32_t);
  1384. einfo->num_pw_states = num_states;
  1385. arr32 = kmalloc_array(num_states, sizeof(uint32_t), GFP_KERNEL);
  1386. if (!arr32)
  1387. return -ENOMEM;
  1388. einfo->ramp_time_us = kmalloc_array(num_states, sizeof(unsigned long),
  1389. GFP_KERNEL);
  1390. if (!einfo->ramp_time_us) {
  1391. rc = -ENOMEM;
  1392. goto mem_alloc_fail;
  1393. }
  1394. rc = of_property_read_u32_array(node, key, arr32, num_states);
  1395. if (rc) {
  1396. rc = -ENODEV;
  1397. goto invalid_key;
  1398. }
  1399. for (i = 0; i < num_states; i++)
  1400. einfo->ramp_time_us[i] = arr32[i];
  1401. kfree(arr32);
  1402. return 0;
  1403. invalid_key:
  1404. kfree(einfo->ramp_time_us);
  1405. mem_alloc_fail:
  1406. kfree(arr32);
  1407. return rc;
  1408. }
  1409. static int glink_bgcom_probe(struct platform_device *pdev)
  1410. {
  1411. struct device_node *node;
  1412. struct device_node *phandle_node;
  1413. struct edge_info *einfo;
  1414. int rc;
  1415. char *key;
  1416. const char *subsys_name;
  1417. unsigned long flags;
  1418. node = pdev->dev.of_node;
  1419. einfo = devm_kzalloc(&pdev->dev, sizeof(*einfo), GFP_KERNEL);
  1420. if (!einfo) {
  1421. rc = -ENOMEM;
  1422. goto edge_info_alloc_fail;
  1423. }
  1424. key = "label";
  1425. subsys_name = of_get_property(node, key, NULL);
  1426. if (!subsys_name) {
  1427. GLINK_ERR("%s: missing key %s\n", __func__, key);
  1428. rc = -ENODEV;
  1429. goto missing_key;
  1430. }
  1431. strlcpy(einfo->subsys_name, subsys_name, sizeof(einfo->subsys_name));
  1432. init_xprt_cfg(einfo, subsys_name);
  1433. init_xprt_if(einfo);
  1434. kthread_init_worker(&einfo->kworker);
  1435. init_srcu_struct(&einfo->use_ref);
  1436. mutex_init(&einfo->write_lock);
  1437. init_waitqueue_head(&einfo->tx_blocked_queue);
  1438. spin_lock_init(&einfo->activity_lock);
  1439. mutex_init(&einfo->tx_avail_lock);
  1440. spin_lock_irqsave(&edge_infos_lock, flags);
  1441. list_add_tail(&einfo->list, &edge_infos);
  1442. spin_unlock_irqrestore(&edge_infos_lock, flags);
  1443. einfo->task = kthread_run(kthread_worker_fn, &einfo->kworker,
  1444. "bgcom_%s", subsys_name);
  1445. if (IS_ERR(einfo->task)) {
  1446. rc = PTR_ERR(einfo->task);
  1447. GLINK_ERR("%s: kthread run failed %d\n", __func__, rc);
  1448. goto kthread_fail;
  1449. }
  1450. key = "qcom,qos-config";
  1451. phandle_node = of_parse_phandle(node, key, 0);
  1452. if (phandle_node && !(of_get_glink_core_qos_cfg(phandle_node,
  1453. &einfo->xprt_cfg)))
  1454. parse_qos_dt_params(node, einfo);
  1455. rc = glink_core_register_transport(&einfo->xprt_if, &einfo->xprt_cfg);
  1456. if (rc == -EPROBE_DEFER)
  1457. goto reg_xprt_fail;
  1458. if (rc) {
  1459. GLINK_ERR("%s: glink core register transport failed: %d\n",
  1460. __func__, rc);
  1461. goto reg_xprt_fail;
  1462. }
  1463. einfo->bgcom_config.priv = (void *)einfo;
  1464. einfo->bgcom_config.bgcom_notification_cb = glink_bgcom_event_handler;
  1465. einfo->bgcom_handle = NULL;
  1466. dev_set_drvdata(&pdev->dev, einfo);
  1467. if (!strcmp(einfo->xprt_cfg.edge, "bg")) {
  1468. einfo->bgcom_handle = bgcom_open(&einfo->bgcom_config);
  1469. if (!einfo->bgcom_handle) {
  1470. GLINK_ERR("%s: bgcom open failed\n", __func__);
  1471. rc = -ENODEV;
  1472. goto bgcom_open_fail;
  1473. }
  1474. }
  1475. return 0;
  1476. bgcom_open_fail:
  1477. dev_set_drvdata(&pdev->dev, NULL);
  1478. glink_core_unregister_transport(&einfo->xprt_if);
  1479. reg_xprt_fail:
  1480. kthread_flush_worker(&einfo->kworker);
  1481. kthread_stop(einfo->task);
  1482. einfo->task = NULL;
  1483. kthread_fail:
  1484. spin_lock_irqsave(&edge_infos_lock, flags);
  1485. list_del(&einfo->list);
  1486. spin_unlock_irqrestore(&edge_infos_lock, flags);
  1487. missing_key:
  1488. kfree(einfo);
  1489. edge_info_alloc_fail:
  1490. return rc;
  1491. }
  1492. static int glink_bgcom_remove(struct platform_device *pdev)
  1493. {
  1494. struct edge_info *einfo;
  1495. unsigned long flags;
  1496. einfo = (struct edge_info *)dev_get_drvdata(&pdev->dev);
  1497. bgcom_close(&einfo->bgcom_handle);
  1498. glink_core_unregister_transport(&einfo->xprt_if);
  1499. kthread_flush_worker(&einfo->kworker);
  1500. kthread_stop(einfo->task);
  1501. einfo->task = NULL;
  1502. spin_lock_irqsave(&edge_infos_lock, flags);
  1503. list_del(&einfo->list);
  1504. spin_unlock_irqrestore(&edge_infos_lock, flags);
  1505. return 0;
  1506. }
  1507. static int glink_bgcom_resume(struct platform_device *pdev)
  1508. {
  1509. return 0;
  1510. }
  1511. static int glink_bgcom_suspend(struct platform_device *pdev,
  1512. pm_message_t state)
  1513. {
  1514. unsigned long flags;
  1515. struct edge_info *einfo;
  1516. bool suspend;
  1517. int rc = -EBUSY;
  1518. einfo = (struct edge_info *)dev_get_drvdata(&pdev->dev);
  1519. if (strcmp(einfo->xprt_cfg.edge, "bg"))
  1520. return 0;
  1521. spin_lock_irqsave(&einfo->activity_lock, flags);
  1522. suspend = !(einfo->activity_flag);
  1523. spin_unlock_irqrestore(&einfo->activity_lock, flags);
  1524. if (suspend)
  1525. rc = bgcom_suspend(einfo->bgcom_handle);
  1526. if (rc < 0)
  1527. GLINK_ERR("%s: Could not suspend activity_flag %d, rc %d\n",
  1528. __func__, einfo->activity_flag, rc);
  1529. return rc;
  1530. }
  1531. static const struct of_device_id bgcom_match_table[] = {
  1532. { .compatible = "qcom,glink-bgcom-xprt" },
  1533. {},
  1534. };
  1535. static struct platform_driver glink_bgcom_driver = {
  1536. .probe = glink_bgcom_probe,
  1537. .remove = glink_bgcom_remove,
  1538. .resume = glink_bgcom_resume,
  1539. .suspend = glink_bgcom_suspend,
  1540. .driver = {
  1541. .name = "msm_glink_bgcom_xprt",
  1542. .owner = THIS_MODULE,
  1543. .of_match_table = bgcom_match_table,
  1544. },
  1545. };
  1546. static int __init glink_bgcom_xprt_init(void)
  1547. {
  1548. int rc;
  1549. rc = platform_driver_register(&glink_bgcom_driver);
  1550. if (rc)
  1551. GLINK_ERR("%s: glink_bgcom register failed %d\n", __func__, rc);
  1552. return rc;
  1553. }
  1554. module_init(glink_bgcom_xprt_init);
  1555. static void __exit glink_bgcom_xprt_exit(void)
  1556. {
  1557. platform_driver_unregister(&glink_bgcom_driver);
  1558. }
  1559. module_exit(glink_bgcom_xprt_exit);
  1560. MODULE_DESCRIPTION("MSM G-Link bgcom Transport");
  1561. MODULE_LICENSE("GPL v2");