hte.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2021-2022 NVIDIA Corporation
  4. *
  5. * Author: Dipen Patel <dipenp@nvidia.com>
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/module.h>
  9. #include <linux/err.h>
  10. #include <linux/slab.h>
  11. #include <linux/of.h>
  12. #include <linux/mutex.h>
  13. #include <linux/uaccess.h>
  14. #include <linux/hte.h>
  15. #include <linux/delay.h>
  16. #include <linux/debugfs.h>
  17. #include <linux/device.h>
  18. /* Global list of the HTE devices */
  19. static DEFINE_SPINLOCK(hte_lock);
  20. static LIST_HEAD(hte_devices);
  21. enum {
  22. HTE_TS_REGISTERED,
  23. HTE_TS_REQ,
  24. HTE_TS_DISABLE,
  25. HTE_TS_QUEUE_WK,
  26. };
  27. /**
  28. * struct hte_ts_info - Information related to requested timestamp.
  29. *
  30. * @xlated_id: Timestamp ID as understood between HTE subsys and HTE provider,
  31. * See xlate callback API.
  32. * @flags: Flags holding state information.
  33. * @hte_cb_flags: Callback related flags.
  34. * @seq: Timestamp sequence counter.
  35. * @line_name: HTE allocated line name.
  36. * @free_attr_name: If set, free the attr name.
  37. * @cb: A nonsleeping callback function provided by clients.
  38. * @tcb: A secondary sleeping callback function provided by clients.
  39. * @dropped_ts: Dropped timestamps.
  40. * @slock: Spin lock to synchronize between disable/enable,
  41. * request/release APIs.
  42. * @cb_work: callback workqueue, used when tcb is specified.
  43. * @req_mlock: Lock during timestamp request/release APIs.
  44. * @ts_dbg_root: Root for the debug fs.
  45. * @gdev: HTE abstract device that this timestamp information belongs to.
  46. * @cl_data: Client specific data.
  47. */
  48. struct hte_ts_info {
  49. u32 xlated_id;
  50. unsigned long flags;
  51. unsigned long hte_cb_flags;
  52. u64 seq;
  53. char *line_name;
  54. bool free_attr_name;
  55. hte_ts_cb_t cb;
  56. hte_ts_sec_cb_t tcb;
  57. atomic_t dropped_ts;
  58. spinlock_t slock;
  59. struct work_struct cb_work;
  60. struct mutex req_mlock;
  61. struct dentry *ts_dbg_root;
  62. struct hte_device *gdev;
  63. void *cl_data;
  64. };
  65. /**
  66. * struct hte_device - HTE abstract device
  67. * @nlines: Number of entities this device supports.
  68. * @ts_req: Total number of entities requested.
  69. * @sdev: Device used at various debug prints.
  70. * @dbg_root: Root directory for debug fs.
  71. * @list: List node to store hte_device for each provider.
  72. * @chip: HTE chip providing this HTE device.
  73. * @owner: helps prevent removal of modules when in use.
  74. * @ei: Timestamp information.
  75. */
  76. struct hte_device {
  77. u32 nlines;
  78. atomic_t ts_req;
  79. struct device *sdev;
  80. struct dentry *dbg_root;
  81. struct list_head list;
  82. struct hte_chip *chip;
  83. struct module *owner;
  84. struct hte_ts_info ei[] __counted_by(nlines);
  85. };
  86. #ifdef CONFIG_DEBUG_FS
  87. static struct dentry *hte_root;
  88. static int __init hte_subsys_dbgfs_init(void)
  89. {
  90. /* creates /sys/kernel/debug/hte/ */
  91. hte_root = debugfs_create_dir("hte", NULL);
  92. return 0;
  93. }
  94. subsys_initcall(hte_subsys_dbgfs_init);
  95. static void hte_chip_dbgfs_init(struct hte_device *gdev)
  96. {
  97. const struct hte_chip *chip = gdev->chip;
  98. const char *name = chip->name ? chip->name : dev_name(chip->dev);
  99. gdev->dbg_root = debugfs_create_dir(name, hte_root);
  100. debugfs_create_atomic_t("ts_requested", 0444, gdev->dbg_root,
  101. &gdev->ts_req);
  102. debugfs_create_u32("total_ts", 0444, gdev->dbg_root,
  103. &gdev->nlines);
  104. }
  105. static void hte_ts_dbgfs_init(const char *name, struct hte_ts_info *ei)
  106. {
  107. if (!ei->gdev->dbg_root || !name)
  108. return;
  109. ei->ts_dbg_root = debugfs_create_dir(name, ei->gdev->dbg_root);
  110. debugfs_create_atomic_t("dropped_timestamps", 0444, ei->ts_dbg_root,
  111. &ei->dropped_ts);
  112. }
  113. #else
  114. static void hte_chip_dbgfs_init(struct hte_device *gdev)
  115. {
  116. }
  117. static void hte_ts_dbgfs_init(const char *name, struct hte_ts_info *ei)
  118. {
  119. }
  120. #endif
  121. /**
  122. * hte_ts_put() - Release and disable timestamp for the given desc.
  123. *
  124. * @desc: timestamp descriptor.
  125. *
  126. * Context: debugfs_remove_recursive() function call may use sleeping locks,
  127. * not suitable from atomic context.
  128. * Returns: 0 on success or a negative error code on failure.
  129. */
  130. int hte_ts_put(struct hte_ts_desc *desc)
  131. {
  132. int ret = 0;
  133. unsigned long flag;
  134. struct hte_device *gdev;
  135. struct hte_ts_info *ei;
  136. if (!desc)
  137. return -EINVAL;
  138. ei = desc->hte_data;
  139. if (!ei || !ei->gdev)
  140. return -EINVAL;
  141. gdev = ei->gdev;
  142. mutex_lock(&ei->req_mlock);
  143. if (unlikely(!test_bit(HTE_TS_REQ, &ei->flags) &&
  144. !test_bit(HTE_TS_REGISTERED, &ei->flags))) {
  145. dev_info(gdev->sdev, "id:%d is not requested\n",
  146. desc->attr.line_id);
  147. ret = -EINVAL;
  148. goto unlock;
  149. }
  150. if (unlikely(!test_bit(HTE_TS_REQ, &ei->flags) &&
  151. test_bit(HTE_TS_REGISTERED, &ei->flags))) {
  152. dev_info(gdev->sdev, "id:%d is registered but not requested\n",
  153. desc->attr.line_id);
  154. ret = -EINVAL;
  155. goto unlock;
  156. }
  157. if (test_bit(HTE_TS_REQ, &ei->flags) &&
  158. !test_bit(HTE_TS_REGISTERED, &ei->flags)) {
  159. clear_bit(HTE_TS_REQ, &ei->flags);
  160. desc->hte_data = NULL;
  161. ret = 0;
  162. goto mod_put;
  163. }
  164. ret = gdev->chip->ops->release(gdev->chip, desc, ei->xlated_id);
  165. if (ret) {
  166. dev_err(gdev->sdev, "id: %d free failed\n",
  167. desc->attr.line_id);
  168. goto unlock;
  169. }
  170. kfree(ei->line_name);
  171. if (ei->free_attr_name)
  172. kfree_const(desc->attr.name);
  173. debugfs_remove_recursive(ei->ts_dbg_root);
  174. spin_lock_irqsave(&ei->slock, flag);
  175. if (test_bit(HTE_TS_QUEUE_WK, &ei->flags)) {
  176. spin_unlock_irqrestore(&ei->slock, flag);
  177. flush_work(&ei->cb_work);
  178. spin_lock_irqsave(&ei->slock, flag);
  179. }
  180. atomic_dec(&gdev->ts_req);
  181. atomic_set(&ei->dropped_ts, 0);
  182. ei->seq = 1;
  183. ei->flags = 0;
  184. desc->hte_data = NULL;
  185. spin_unlock_irqrestore(&ei->slock, flag);
  186. ei->cb = NULL;
  187. ei->tcb = NULL;
  188. ei->cl_data = NULL;
  189. mod_put:
  190. module_put(gdev->owner);
  191. unlock:
  192. mutex_unlock(&ei->req_mlock);
  193. dev_dbg(gdev->sdev, "release id: %d\n", desc->attr.line_id);
  194. return ret;
  195. }
  196. EXPORT_SYMBOL_GPL(hte_ts_put);
  197. static int hte_ts_dis_en_common(struct hte_ts_desc *desc, bool en)
  198. {
  199. u32 ts_id;
  200. struct hte_device *gdev;
  201. struct hte_ts_info *ei;
  202. int ret;
  203. unsigned long flag;
  204. if (!desc)
  205. return -EINVAL;
  206. ei = desc->hte_data;
  207. if (!ei || !ei->gdev)
  208. return -EINVAL;
  209. gdev = ei->gdev;
  210. ts_id = desc->attr.line_id;
  211. mutex_lock(&ei->req_mlock);
  212. if (!test_bit(HTE_TS_REGISTERED, &ei->flags)) {
  213. dev_dbg(gdev->sdev, "id:%d is not registered", ts_id);
  214. ret = -EUSERS;
  215. goto out;
  216. }
  217. spin_lock_irqsave(&ei->slock, flag);
  218. if (en) {
  219. if (!test_bit(HTE_TS_DISABLE, &ei->flags)) {
  220. ret = 0;
  221. goto out_unlock;
  222. }
  223. spin_unlock_irqrestore(&ei->slock, flag);
  224. ret = gdev->chip->ops->enable(gdev->chip, ei->xlated_id);
  225. if (ret) {
  226. dev_warn(gdev->sdev, "id: %d enable failed\n",
  227. ts_id);
  228. goto out;
  229. }
  230. spin_lock_irqsave(&ei->slock, flag);
  231. clear_bit(HTE_TS_DISABLE, &ei->flags);
  232. } else {
  233. if (test_bit(HTE_TS_DISABLE, &ei->flags)) {
  234. ret = 0;
  235. goto out_unlock;
  236. }
  237. spin_unlock_irqrestore(&ei->slock, flag);
  238. ret = gdev->chip->ops->disable(gdev->chip, ei->xlated_id);
  239. if (ret) {
  240. dev_warn(gdev->sdev, "id: %d disable failed\n",
  241. ts_id);
  242. goto out;
  243. }
  244. spin_lock_irqsave(&ei->slock, flag);
  245. set_bit(HTE_TS_DISABLE, &ei->flags);
  246. }
  247. out_unlock:
  248. spin_unlock_irqrestore(&ei->slock, flag);
  249. out:
  250. mutex_unlock(&ei->req_mlock);
  251. return ret;
  252. }
  253. /**
  254. * hte_disable_ts() - Disable timestamp on given descriptor.
  255. *
  256. * The API does not release any resources associated with desc.
  257. *
  258. * @desc: ts descriptor, this is the same as returned by the request API.
  259. *
  260. * Context: Holds mutex lock, not suitable from atomic context.
  261. * Returns: 0 on success or a negative error code on failure.
  262. */
  263. int hte_disable_ts(struct hte_ts_desc *desc)
  264. {
  265. return hte_ts_dis_en_common(desc, false);
  266. }
  267. EXPORT_SYMBOL_GPL(hte_disable_ts);
  268. /**
  269. * hte_enable_ts() - Enable timestamp on given descriptor.
  270. *
  271. * @desc: ts descriptor, this is the same as returned by the request API.
  272. *
  273. * Context: Holds mutex lock, not suitable from atomic context.
  274. * Returns: 0 on success or a negative error code on failure.
  275. */
  276. int hte_enable_ts(struct hte_ts_desc *desc)
  277. {
  278. return hte_ts_dis_en_common(desc, true);
  279. }
  280. EXPORT_SYMBOL_GPL(hte_enable_ts);
  281. static void hte_do_cb_work(struct work_struct *w)
  282. {
  283. unsigned long flag;
  284. struct hte_ts_info *ei = container_of(w, struct hte_ts_info, cb_work);
  285. if (unlikely(!ei->tcb))
  286. return;
  287. ei->tcb(ei->cl_data);
  288. spin_lock_irqsave(&ei->slock, flag);
  289. clear_bit(HTE_TS_QUEUE_WK, &ei->flags);
  290. spin_unlock_irqrestore(&ei->slock, flag);
  291. }
  292. static int __hte_req_ts(struct hte_ts_desc *desc, hte_ts_cb_t cb,
  293. hte_ts_sec_cb_t tcb, void *data)
  294. {
  295. int ret;
  296. struct hte_device *gdev;
  297. struct hte_ts_info *ei = desc->hte_data;
  298. gdev = ei->gdev;
  299. /*
  300. * There is a chance that multiple consumers requesting same entity,
  301. * lock here.
  302. */
  303. mutex_lock(&ei->req_mlock);
  304. if (test_bit(HTE_TS_REGISTERED, &ei->flags) ||
  305. !test_bit(HTE_TS_REQ, &ei->flags)) {
  306. dev_dbg(gdev->chip->dev, "id:%u req failed\n",
  307. desc->attr.line_id);
  308. ret = -EUSERS;
  309. goto unlock;
  310. }
  311. ei->cb = cb;
  312. ei->tcb = tcb;
  313. if (tcb)
  314. INIT_WORK(&ei->cb_work, hte_do_cb_work);
  315. ret = gdev->chip->ops->request(gdev->chip, desc, ei->xlated_id);
  316. if (ret < 0) {
  317. dev_err(gdev->chip->dev, "ts request failed\n");
  318. goto unlock;
  319. }
  320. ei->cl_data = data;
  321. ei->seq = 1;
  322. atomic_inc(&gdev->ts_req);
  323. if (desc->attr.name)
  324. ei->line_name = NULL;
  325. else
  326. ei->line_name = kasprintf(GFP_KERNEL, "ts_%u", desc->attr.line_id);
  327. hte_ts_dbgfs_init(desc->attr.name == NULL ?
  328. ei->line_name : desc->attr.name, ei);
  329. set_bit(HTE_TS_REGISTERED, &ei->flags);
  330. dev_dbg(gdev->chip->dev, "id: %u, xlated id:%u",
  331. desc->attr.line_id, ei->xlated_id);
  332. ret = 0;
  333. unlock:
  334. mutex_unlock(&ei->req_mlock);
  335. return ret;
  336. }
  337. static int hte_bind_ts_info_locked(struct hte_ts_info *ei,
  338. struct hte_ts_desc *desc, u32 x_id)
  339. {
  340. int ret = 0;
  341. mutex_lock(&ei->req_mlock);
  342. if (test_bit(HTE_TS_REQ, &ei->flags)) {
  343. dev_dbg(ei->gdev->chip->dev, "id:%u is already requested\n",
  344. desc->attr.line_id);
  345. ret = -EUSERS;
  346. goto out;
  347. }
  348. set_bit(HTE_TS_REQ, &ei->flags);
  349. desc->hte_data = ei;
  350. ei->xlated_id = x_id;
  351. out:
  352. mutex_unlock(&ei->req_mlock);
  353. return ret;
  354. }
  355. static struct hte_device *of_node_to_htedevice(struct device_node *np)
  356. {
  357. struct hte_device *gdev;
  358. spin_lock(&hte_lock);
  359. list_for_each_entry(gdev, &hte_devices, list)
  360. if (gdev->chip && gdev->chip->dev &&
  361. device_match_of_node(gdev->chip->dev, np)) {
  362. spin_unlock(&hte_lock);
  363. return gdev;
  364. }
  365. spin_unlock(&hte_lock);
  366. return ERR_PTR(-ENODEV);
  367. }
  368. static struct hte_device *hte_find_dev_from_linedata(struct hte_ts_desc *desc)
  369. {
  370. struct hte_device *gdev;
  371. spin_lock(&hte_lock);
  372. list_for_each_entry(gdev, &hte_devices, list)
  373. if (gdev->chip && gdev->chip->match_from_linedata) {
  374. if (!gdev->chip->match_from_linedata(gdev->chip, desc))
  375. continue;
  376. spin_unlock(&hte_lock);
  377. return gdev;
  378. }
  379. spin_unlock(&hte_lock);
  380. return ERR_PTR(-ENODEV);
  381. }
  382. /**
  383. * of_hte_req_count - Return the number of entities to timestamp.
  384. *
  385. * The function returns the total count of the requested entities to timestamp
  386. * by parsing device tree.
  387. *
  388. * @dev: The HTE consumer.
  389. *
  390. * Returns: Positive number on success, -ENOENT if no entries,
  391. * -EINVAL for other errors.
  392. */
  393. int of_hte_req_count(struct device *dev)
  394. {
  395. int count;
  396. if (!dev || !dev->of_node)
  397. return -EINVAL;
  398. count = of_count_phandle_with_args(dev->of_node, "timestamps",
  399. "#timestamp-cells");
  400. return count ? count : -ENOENT;
  401. }
  402. EXPORT_SYMBOL_GPL(of_hte_req_count);
  403. static inline struct hte_device *hte_get_dev(struct hte_ts_desc *desc)
  404. {
  405. return hte_find_dev_from_linedata(desc);
  406. }
  407. static struct hte_device *hte_of_get_dev(struct device *dev,
  408. struct hte_ts_desc *desc,
  409. int index,
  410. struct of_phandle_args *args,
  411. bool *free_name)
  412. {
  413. int ret;
  414. struct device_node *np;
  415. char *temp;
  416. if (!dev->of_node)
  417. return ERR_PTR(-EINVAL);
  418. np = dev->of_node;
  419. if (!of_property_present(np, "timestamp-names")) {
  420. /* Let hte core construct it during request time */
  421. desc->attr.name = NULL;
  422. } else {
  423. ret = of_property_read_string_index(np, "timestamp-names",
  424. index, &desc->attr.name);
  425. if (ret) {
  426. pr_err("can't parse \"timestamp-names\" property\n");
  427. return ERR_PTR(ret);
  428. }
  429. *free_name = false;
  430. if (desc->attr.name) {
  431. temp = skip_spaces(desc->attr.name);
  432. if (!*temp)
  433. desc->attr.name = NULL;
  434. }
  435. }
  436. ret = of_parse_phandle_with_args(np, "timestamps", "#timestamp-cells",
  437. index, args);
  438. if (ret) {
  439. pr_err("%s(): can't parse \"timestamps\" property\n",
  440. __func__);
  441. return ERR_PTR(ret);
  442. }
  443. of_node_put(args->np);
  444. return of_node_to_htedevice(args->np);
  445. }
  446. /**
  447. * hte_ts_get() - The function to initialize and obtain HTE desc.
  448. *
  449. * The function initializes the consumer provided HTE descriptor. If consumer
  450. * has device tree node, index is used to parse the line id and other details.
  451. * The function needs to be called before using any request APIs.
  452. *
  453. * @dev: HTE consumer/client device, used in case of parsing device tree node.
  454. * @desc: Pre-allocated timestamp descriptor.
  455. * @index: The index will be used as an index to parse line_id from the
  456. * device tree node if node is present.
  457. *
  458. * Context: Holds mutex lock.
  459. * Returns: Returns 0 on success or negative error code on failure.
  460. */
  461. int hte_ts_get(struct device *dev, struct hte_ts_desc *desc, int index)
  462. {
  463. struct hte_device *gdev;
  464. struct hte_ts_info *ei;
  465. const struct fwnode_handle *fwnode;
  466. struct of_phandle_args args;
  467. u32 xlated_id;
  468. int ret;
  469. bool free_name = false;
  470. if (!desc)
  471. return -EINVAL;
  472. fwnode = dev ? dev_fwnode(dev) : NULL;
  473. if (is_of_node(fwnode))
  474. gdev = hte_of_get_dev(dev, desc, index, &args, &free_name);
  475. else
  476. gdev = hte_get_dev(desc);
  477. if (IS_ERR(gdev)) {
  478. pr_err("%s() no hte dev found\n", __func__);
  479. return PTR_ERR(gdev);
  480. }
  481. if (!try_module_get(gdev->owner))
  482. return -ENODEV;
  483. if (!gdev->chip) {
  484. pr_err("%s(): requested id does not have provider\n",
  485. __func__);
  486. ret = -ENODEV;
  487. goto put;
  488. }
  489. if (is_of_node(fwnode)) {
  490. if (!gdev->chip->xlate_of)
  491. ret = -EINVAL;
  492. else
  493. ret = gdev->chip->xlate_of(gdev->chip, &args,
  494. desc, &xlated_id);
  495. } else {
  496. if (!gdev->chip->xlate_plat)
  497. ret = -EINVAL;
  498. else
  499. ret = gdev->chip->xlate_plat(gdev->chip, desc,
  500. &xlated_id);
  501. }
  502. if (ret < 0)
  503. goto put;
  504. ei = &gdev->ei[xlated_id];
  505. ret = hte_bind_ts_info_locked(ei, desc, xlated_id);
  506. if (ret)
  507. goto put;
  508. ei->free_attr_name = free_name;
  509. return 0;
  510. put:
  511. module_put(gdev->owner);
  512. return ret;
  513. }
  514. EXPORT_SYMBOL_GPL(hte_ts_get);
  515. static void __devm_hte_release_ts(void *res)
  516. {
  517. hte_ts_put(res);
  518. }
  519. /**
  520. * hte_request_ts_ns() - The API to request and enable hardware timestamp in
  521. * nanoseconds.
  522. *
  523. * The entity is provider specific for example, GPIO lines, signals, buses
  524. * etc...The API allocates necessary resources and enables the timestamp.
  525. *
  526. * @desc: Pre-allocated and initialized timestamp descriptor.
  527. * @cb: Callback to push the timestamp data to consumer.
  528. * @tcb: Optional callback. If its provided, subsystem initializes
  529. * workqueue. It is called when cb returns HTE_RUN_SECOND_CB.
  530. * @data: Client data, used during cb and tcb callbacks.
  531. *
  532. * Context: Holds mutex lock.
  533. * Returns: Returns 0 on success or negative error code on failure.
  534. */
  535. int hte_request_ts_ns(struct hte_ts_desc *desc, hte_ts_cb_t cb,
  536. hte_ts_sec_cb_t tcb, void *data)
  537. {
  538. int ret;
  539. struct hte_ts_info *ei;
  540. if (!desc || !desc->hte_data || !cb)
  541. return -EINVAL;
  542. ei = desc->hte_data;
  543. if (!ei || !ei->gdev)
  544. return -EINVAL;
  545. ret = __hte_req_ts(desc, cb, tcb, data);
  546. if (ret < 0) {
  547. dev_err(ei->gdev->chip->dev,
  548. "failed to request id: %d\n", desc->attr.line_id);
  549. return ret;
  550. }
  551. return 0;
  552. }
  553. EXPORT_SYMBOL_GPL(hte_request_ts_ns);
  554. /**
  555. * devm_hte_request_ts_ns() - Resource managed API to request and enable
  556. * hardware timestamp in nanoseconds.
  557. *
  558. * The entity is provider specific for example, GPIO lines, signals, buses
  559. * etc...The API allocates necessary resources and enables the timestamp. It
  560. * deallocates and disables automatically when the consumer exits.
  561. *
  562. * @dev: HTE consumer/client device.
  563. * @desc: Pre-allocated and initialized timestamp descriptor.
  564. * @cb: Callback to push the timestamp data to consumer.
  565. * @tcb: Optional callback. If its provided, subsystem initializes
  566. * workqueue. It is called when cb returns HTE_RUN_SECOND_CB.
  567. * @data: Client data, used during cb and tcb callbacks.
  568. *
  569. * Context: Holds mutex lock.
  570. * Returns: Returns 0 on success or negative error code on failure.
  571. */
  572. int devm_hte_request_ts_ns(struct device *dev, struct hte_ts_desc *desc,
  573. hte_ts_cb_t cb, hte_ts_sec_cb_t tcb,
  574. void *data)
  575. {
  576. int err;
  577. if (!dev)
  578. return -EINVAL;
  579. err = hte_request_ts_ns(desc, cb, tcb, data);
  580. if (err)
  581. return err;
  582. err = devm_add_action_or_reset(dev, __devm_hte_release_ts, desc);
  583. if (err)
  584. return err;
  585. return 0;
  586. }
  587. EXPORT_SYMBOL_GPL(devm_hte_request_ts_ns);
  588. /**
  589. * hte_init_line_attr() - Initialize line attributes.
  590. *
  591. * Zeroes out line attributes and initializes with provided arguments.
  592. * The function needs to be called before calling any consumer facing
  593. * functions.
  594. *
  595. * @desc: Pre-allocated timestamp descriptor.
  596. * @line_id: line id.
  597. * @edge_flags: edge flags related to line_id.
  598. * @name: name of the line.
  599. * @data: line data related to line_id.
  600. *
  601. * Context: Any.
  602. * Returns: 0 on success or negative error code for the failure.
  603. */
  604. int hte_init_line_attr(struct hte_ts_desc *desc, u32 line_id,
  605. unsigned long edge_flags, const char *name, void *data)
  606. {
  607. if (!desc)
  608. return -EINVAL;
  609. memset(&desc->attr, 0, sizeof(desc->attr));
  610. desc->attr.edge_flags = edge_flags;
  611. desc->attr.line_id = line_id;
  612. desc->attr.line_data = data;
  613. if (name) {
  614. name = kstrdup_const(name, GFP_KERNEL);
  615. if (!name)
  616. return -ENOMEM;
  617. }
  618. desc->attr.name = name;
  619. return 0;
  620. }
  621. EXPORT_SYMBOL_GPL(hte_init_line_attr);
  622. /**
  623. * hte_get_clk_src_info() - Get the clock source information for a ts
  624. * descriptor.
  625. *
  626. * @desc: ts descriptor, same as returned from request API.
  627. * @ci: The API fills this structure with the clock information data.
  628. *
  629. * Context: Any context.
  630. * Returns: 0 on success else negative error code on failure.
  631. */
  632. int hte_get_clk_src_info(const struct hte_ts_desc *desc,
  633. struct hte_clk_info *ci)
  634. {
  635. struct hte_chip *chip;
  636. struct hte_ts_info *ei;
  637. if (!desc || !desc->hte_data || !ci) {
  638. pr_debug("%s:%d\n", __func__, __LINE__);
  639. return -EINVAL;
  640. }
  641. ei = desc->hte_data;
  642. if (!ei->gdev || !ei->gdev->chip)
  643. return -EINVAL;
  644. chip = ei->gdev->chip;
  645. if (!chip->ops->get_clk_src_info)
  646. return -EOPNOTSUPP;
  647. return chip->ops->get_clk_src_info(chip, ci);
  648. }
  649. EXPORT_SYMBOL_GPL(hte_get_clk_src_info);
  650. /**
  651. * hte_push_ts_ns() - Push timestamp data in nanoseconds.
  652. *
  653. * It is used by the provider to push timestamp data.
  654. *
  655. * @chip: The HTE chip, used during the registration.
  656. * @xlated_id: entity id understood by both subsystem and provider, this is
  657. * obtained from xlate callback during request API.
  658. * @data: timestamp data.
  659. *
  660. * Returns: 0 on success or a negative error code on failure.
  661. */
  662. int hte_push_ts_ns(const struct hte_chip *chip, u32 xlated_id,
  663. struct hte_ts_data *data)
  664. {
  665. enum hte_return ret;
  666. int st = 0;
  667. struct hte_ts_info *ei;
  668. unsigned long flag;
  669. if (!chip || !data || !chip->gdev)
  670. return -EINVAL;
  671. if (xlated_id >= chip->nlines)
  672. return -EINVAL;
  673. ei = &chip->gdev->ei[xlated_id];
  674. spin_lock_irqsave(&ei->slock, flag);
  675. /* timestamp sequence counter */
  676. data->seq = ei->seq++;
  677. if (!test_bit(HTE_TS_REGISTERED, &ei->flags) ||
  678. test_bit(HTE_TS_DISABLE, &ei->flags)) {
  679. dev_dbg(chip->dev, "Unknown timestamp push\n");
  680. atomic_inc(&ei->dropped_ts);
  681. st = -EINVAL;
  682. goto unlock;
  683. }
  684. ret = ei->cb(data, ei->cl_data);
  685. if (ret == HTE_RUN_SECOND_CB && ei->tcb) {
  686. queue_work(system_unbound_wq, &ei->cb_work);
  687. set_bit(HTE_TS_QUEUE_WK, &ei->flags);
  688. }
  689. unlock:
  690. spin_unlock_irqrestore(&ei->slock, flag);
  691. return st;
  692. }
  693. EXPORT_SYMBOL_GPL(hte_push_ts_ns);
  694. static int hte_register_chip(struct hte_chip *chip)
  695. {
  696. struct hte_device *gdev;
  697. u32 i;
  698. if (!chip || !chip->dev || !chip->dev->of_node)
  699. return -EINVAL;
  700. if (!chip->ops || !chip->ops->request || !chip->ops->release) {
  701. dev_err(chip->dev, "Driver needs to provide ops\n");
  702. return -EINVAL;
  703. }
  704. gdev = kzalloc(struct_size(gdev, ei, chip->nlines), GFP_KERNEL);
  705. if (!gdev)
  706. return -ENOMEM;
  707. gdev->chip = chip;
  708. chip->gdev = gdev;
  709. gdev->nlines = chip->nlines;
  710. gdev->sdev = chip->dev;
  711. for (i = 0; i < chip->nlines; i++) {
  712. gdev->ei[i].gdev = gdev;
  713. mutex_init(&gdev->ei[i].req_mlock);
  714. spin_lock_init(&gdev->ei[i].slock);
  715. }
  716. if (chip->dev->driver)
  717. gdev->owner = chip->dev->driver->owner;
  718. else
  719. gdev->owner = THIS_MODULE;
  720. of_node_get(chip->dev->of_node);
  721. INIT_LIST_HEAD(&gdev->list);
  722. spin_lock(&hte_lock);
  723. list_add_tail(&gdev->list, &hte_devices);
  724. spin_unlock(&hte_lock);
  725. hte_chip_dbgfs_init(gdev);
  726. dev_dbg(chip->dev, "Added hte chip\n");
  727. return 0;
  728. }
  729. static int hte_unregister_chip(struct hte_chip *chip)
  730. {
  731. struct hte_device *gdev;
  732. if (!chip)
  733. return -EINVAL;
  734. gdev = chip->gdev;
  735. spin_lock(&hte_lock);
  736. list_del(&gdev->list);
  737. spin_unlock(&hte_lock);
  738. gdev->chip = NULL;
  739. of_node_put(chip->dev->of_node);
  740. debugfs_remove_recursive(gdev->dbg_root);
  741. kfree(gdev);
  742. dev_dbg(chip->dev, "Removed hte chip\n");
  743. return 0;
  744. }
  745. static void _hte_devm_unregister_chip(void *chip)
  746. {
  747. hte_unregister_chip(chip);
  748. }
  749. /**
  750. * devm_hte_register_chip() - Resource managed API to register HTE chip.
  751. *
  752. * It is used by the provider to register itself with the HTE subsystem.
  753. * The unregistration is done automatically when the provider exits.
  754. *
  755. * @chip: the HTE chip to add to subsystem.
  756. *
  757. * Returns: 0 on success or a negative error code on failure.
  758. */
  759. int devm_hte_register_chip(struct hte_chip *chip)
  760. {
  761. int err;
  762. err = hte_register_chip(chip);
  763. if (err)
  764. return err;
  765. err = devm_add_action_or_reset(chip->dev, _hte_devm_unregister_chip,
  766. chip);
  767. if (err)
  768. return err;
  769. return 0;
  770. }
  771. EXPORT_SYMBOL_GPL(devm_hte_register_chip);