1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2021-2022 NVIDIA Corporation
5 * Author: Dipen Patel <dipenp@nvidia.com>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/err.h>
11 #include <linux/slab.h>
13 #include <linux/mutex.h>
14 #include <linux/uaccess.h>
15 #include <linux/hte.h>
16 #include <linux/delay.h>
17 #include <linux/debugfs.h>
18 #include <linux/device.h>
20 /* Global list of the HTE devices */
21 static DEFINE_SPINLOCK(hte_lock
);
22 static LIST_HEAD(hte_devices
);
32 * struct hte_ts_info - Information related to requested timestamp.
34 * @xlated_id: Timestamp ID as understood between HTE subsys and HTE provider,
35 * See xlate callback API.
36 * @flags: Flags holding state information.
37 * @hte_cb_flags: Callback related flags.
38 * @seq: Timestamp sequence counter.
39 * @line_name: HTE allocated line name.
40 * @free_attr_name: If set, free the attr name.
41 * @cb: A nonsleeping callback function provided by clients.
42 * @tcb: A secondary sleeping callback function provided by clients.
43 * @dropped_ts: Dropped timestamps.
44 * @slock: Spin lock to synchronize between disable/enable,
45 * request/release APIs.
46 * @cb_work: callback workqueue, used when tcb is specified.
47 * @req_mlock: Lock during timestamp request/release APIs.
48 * @ts_dbg_root: Root for the debug fs.
49 * @gdev: HTE abstract device that this timestamp information belongs to.
50 * @cl_data: Client specific data.
55 unsigned long hte_cb_flags
;
63 struct work_struct cb_work
;
64 struct mutex req_mlock
;
65 struct dentry
*ts_dbg_root
;
66 struct hte_device
*gdev
;
71 * struct hte_device - HTE abstract device
72 * @nlines: Number of entities this device supports.
73 * @ts_req: Total number of entities requested.
74 * @sdev: Device used at various debug prints.
75 * @dbg_root: Root directory for debug fs.
76 * @list: List node to store hte_device for each provider.
77 * @chip: HTE chip providing this HTE device.
78 * @owner: helps prevent removal of modules when in use.
79 * @ei: Timestamp information.
85 struct dentry
*dbg_root
;
86 struct list_head list
;
87 struct hte_chip
*chip
;
89 struct hte_ts_info ei
[] __counted_by(nlines
);
92 #ifdef CONFIG_DEBUG_FS
94 static struct dentry
*hte_root
;
96 static int __init
hte_subsys_dbgfs_init(void)
98 /* creates /sys/kernel/debug/hte/ */
99 hte_root
= debugfs_create_dir("hte", NULL
);
103 subsys_initcall(hte_subsys_dbgfs_init
);
105 static void hte_chip_dbgfs_init(struct hte_device
*gdev
)
107 const struct hte_chip
*chip
= gdev
->chip
;
108 const char *name
= chip
->name
? chip
->name
: dev_name(chip
->dev
);
110 gdev
->dbg_root
= debugfs_create_dir(name
, hte_root
);
112 debugfs_create_atomic_t("ts_requested", 0444, gdev
->dbg_root
,
114 debugfs_create_u32("total_ts", 0444, gdev
->dbg_root
,
118 static void hte_ts_dbgfs_init(const char *name
, struct hte_ts_info
*ei
)
120 if (!ei
->gdev
->dbg_root
|| !name
)
123 ei
->ts_dbg_root
= debugfs_create_dir(name
, ei
->gdev
->dbg_root
);
125 debugfs_create_atomic_t("dropped_timestamps", 0444, ei
->ts_dbg_root
,
131 static void hte_chip_dbgfs_init(struct hte_device
*gdev
)
135 static void hte_ts_dbgfs_init(const char *name
, struct hte_ts_info
*ei
)
142 * hte_ts_put() - Release and disable timestamp for the given desc.
144 * @desc: timestamp descriptor.
146 * Context: debugfs_remove_recursive() function call may use sleeping locks,
147 * not suitable from atomic context.
148 * Returns: 0 on success or a negative error code on failure.
150 int hte_ts_put(struct hte_ts_desc
*desc
)
154 struct hte_device
*gdev
;
155 struct hte_ts_info
*ei
;
162 if (!ei
|| !ei
->gdev
)
167 mutex_lock(&ei
->req_mlock
);
169 if (unlikely(!test_bit(HTE_TS_REQ
, &ei
->flags
) &&
170 !test_bit(HTE_TS_REGISTERED
, &ei
->flags
))) {
171 dev_info(gdev
->sdev
, "id:%d is not requested\n",
177 if (unlikely(!test_bit(HTE_TS_REQ
, &ei
->flags
) &&
178 test_bit(HTE_TS_REGISTERED
, &ei
->flags
))) {
179 dev_info(gdev
->sdev
, "id:%d is registered but not requested\n",
185 if (test_bit(HTE_TS_REQ
, &ei
->flags
) &&
186 !test_bit(HTE_TS_REGISTERED
, &ei
->flags
)) {
187 clear_bit(HTE_TS_REQ
, &ei
->flags
);
188 desc
->hte_data
= NULL
;
193 ret
= gdev
->chip
->ops
->release(gdev
->chip
, desc
, ei
->xlated_id
);
195 dev_err(gdev
->sdev
, "id: %d free failed\n",
200 kfree(ei
->line_name
);
201 if (ei
->free_attr_name
)
202 kfree_const(desc
->attr
.name
);
204 debugfs_remove_recursive(ei
->ts_dbg_root
);
206 spin_lock_irqsave(&ei
->slock
, flag
);
208 if (test_bit(HTE_TS_QUEUE_WK
, &ei
->flags
)) {
209 spin_unlock_irqrestore(&ei
->slock
, flag
);
210 flush_work(&ei
->cb_work
);
211 spin_lock_irqsave(&ei
->slock
, flag
);
214 atomic_dec(&gdev
->ts_req
);
215 atomic_set(&ei
->dropped_ts
, 0);
219 desc
->hte_data
= NULL
;
221 spin_unlock_irqrestore(&ei
->slock
, flag
);
228 module_put(gdev
->owner
);
230 mutex_unlock(&ei
->req_mlock
);
231 dev_dbg(gdev
->sdev
, "release id: %d\n", desc
->attr
.line_id
);
235 EXPORT_SYMBOL_GPL(hte_ts_put
);
237 static int hte_ts_dis_en_common(struct hte_ts_desc
*desc
, bool en
)
240 struct hte_device
*gdev
;
241 struct hte_ts_info
*ei
;
250 if (!ei
|| !ei
->gdev
)
254 ts_id
= desc
->attr
.line_id
;
256 mutex_lock(&ei
->req_mlock
);
258 if (!test_bit(HTE_TS_REGISTERED
, &ei
->flags
)) {
259 dev_dbg(gdev
->sdev
, "id:%d is not registered", ts_id
);
264 spin_lock_irqsave(&ei
->slock
, flag
);
267 if (!test_bit(HTE_TS_DISABLE
, &ei
->flags
)) {
272 spin_unlock_irqrestore(&ei
->slock
, flag
);
273 ret
= gdev
->chip
->ops
->enable(gdev
->chip
, ei
->xlated_id
);
275 dev_warn(gdev
->sdev
, "id: %d enable failed\n",
280 spin_lock_irqsave(&ei
->slock
, flag
);
281 clear_bit(HTE_TS_DISABLE
, &ei
->flags
);
283 if (test_bit(HTE_TS_DISABLE
, &ei
->flags
)) {
288 spin_unlock_irqrestore(&ei
->slock
, flag
);
289 ret
= gdev
->chip
->ops
->disable(gdev
->chip
, ei
->xlated_id
);
291 dev_warn(gdev
->sdev
, "id: %d disable failed\n",
296 spin_lock_irqsave(&ei
->slock
, flag
);
297 set_bit(HTE_TS_DISABLE
, &ei
->flags
);
301 spin_unlock_irqrestore(&ei
->slock
, flag
);
303 mutex_unlock(&ei
->req_mlock
);
308 * hte_disable_ts() - Disable timestamp on given descriptor.
310 * The API does not release any resources associated with desc.
312 * @desc: ts descriptor, this is the same as returned by the request API.
314 * Context: Holds mutex lock, not suitable from atomic context.
315 * Returns: 0 on success or a negative error code on failure.
317 int hte_disable_ts(struct hte_ts_desc
*desc
)
319 return hte_ts_dis_en_common(desc
, false);
321 EXPORT_SYMBOL_GPL(hte_disable_ts
);
324 * hte_enable_ts() - Enable timestamp on given descriptor.
326 * @desc: ts descriptor, this is the same as returned by the request API.
328 * Context: Holds mutex lock, not suitable from atomic context.
329 * Returns: 0 on success or a negative error code on failure.
331 int hte_enable_ts(struct hte_ts_desc
*desc
)
333 return hte_ts_dis_en_common(desc
, true);
335 EXPORT_SYMBOL_GPL(hte_enable_ts
);
337 static void hte_do_cb_work(struct work_struct
*w
)
340 struct hte_ts_info
*ei
= container_of(w
, struct hte_ts_info
, cb_work
);
342 if (unlikely(!ei
->tcb
))
345 ei
->tcb(ei
->cl_data
);
347 spin_lock_irqsave(&ei
->slock
, flag
);
348 clear_bit(HTE_TS_QUEUE_WK
, &ei
->flags
);
349 spin_unlock_irqrestore(&ei
->slock
, flag
);
352 static int __hte_req_ts(struct hte_ts_desc
*desc
, hte_ts_cb_t cb
,
353 hte_ts_sec_cb_t tcb
, void *data
)
356 struct hte_device
*gdev
;
357 struct hte_ts_info
*ei
= desc
->hte_data
;
361 * There is a chance that multiple consumers requesting same entity,
364 mutex_lock(&ei
->req_mlock
);
366 if (test_bit(HTE_TS_REGISTERED
, &ei
->flags
) ||
367 !test_bit(HTE_TS_REQ
, &ei
->flags
)) {
368 dev_dbg(gdev
->chip
->dev
, "id:%u req failed\n",
377 INIT_WORK(&ei
->cb_work
, hte_do_cb_work
);
379 ret
= gdev
->chip
->ops
->request(gdev
->chip
, desc
, ei
->xlated_id
);
381 dev_err(gdev
->chip
->dev
, "ts request failed\n");
388 atomic_inc(&gdev
->ts_req
);
391 ei
->line_name
= NULL
;
393 ei
->line_name
= kasprintf(GFP_KERNEL
, "ts_%u", desc
->attr
.line_id
);
395 hte_ts_dbgfs_init(desc
->attr
.name
== NULL
?
396 ei
->line_name
: desc
->attr
.name
, ei
);
397 set_bit(HTE_TS_REGISTERED
, &ei
->flags
);
399 dev_dbg(gdev
->chip
->dev
, "id: %u, xlated id:%u",
400 desc
->attr
.line_id
, ei
->xlated_id
);
405 mutex_unlock(&ei
->req_mlock
);
410 static int hte_bind_ts_info_locked(struct hte_ts_info
*ei
,
411 struct hte_ts_desc
*desc
, u32 x_id
)
415 mutex_lock(&ei
->req_mlock
);
417 if (test_bit(HTE_TS_REQ
, &ei
->flags
)) {
418 dev_dbg(ei
->gdev
->chip
->dev
, "id:%u is already requested\n",
424 set_bit(HTE_TS_REQ
, &ei
->flags
);
426 ei
->xlated_id
= x_id
;
429 mutex_unlock(&ei
->req_mlock
);
434 static struct hte_device
*of_node_to_htedevice(struct device_node
*np
)
436 struct hte_device
*gdev
;
438 spin_lock(&hte_lock
);
440 list_for_each_entry(gdev
, &hte_devices
, list
)
441 if (gdev
->chip
&& gdev
->chip
->dev
&&
442 device_match_of_node(gdev
->chip
->dev
, np
)) {
443 spin_unlock(&hte_lock
);
447 spin_unlock(&hte_lock
);
449 return ERR_PTR(-ENODEV
);
452 static struct hte_device
*hte_find_dev_from_linedata(struct hte_ts_desc
*desc
)
454 struct hte_device
*gdev
;
456 spin_lock(&hte_lock
);
458 list_for_each_entry(gdev
, &hte_devices
, list
)
459 if (gdev
->chip
&& gdev
->chip
->match_from_linedata
) {
460 if (!gdev
->chip
->match_from_linedata(gdev
->chip
, desc
))
462 spin_unlock(&hte_lock
);
466 spin_unlock(&hte_lock
);
468 return ERR_PTR(-ENODEV
);
472 * of_hte_req_count - Return the number of entities to timestamp.
474 * The function returns the total count of the requested entities to timestamp
475 * by parsing device tree.
477 * @dev: The HTE consumer.
479 * Returns: Positive number on success, -ENOENT if no entries,
480 * -EINVAL for other errors.
482 int of_hte_req_count(struct device
*dev
)
486 if (!dev
|| !dev
->of_node
)
489 count
= of_count_phandle_with_args(dev
->of_node
, "timestamps",
492 return count
? count
: -ENOENT
;
494 EXPORT_SYMBOL_GPL(of_hte_req_count
);
496 static inline struct hte_device
*hte_get_dev(struct hte_ts_desc
*desc
)
498 return hte_find_dev_from_linedata(desc
);
501 static struct hte_device
*hte_of_get_dev(struct device
*dev
,
502 struct hte_ts_desc
*desc
,
504 struct of_phandle_args
*args
,
508 struct device_node
*np
;
512 return ERR_PTR(-EINVAL
);
516 if (!of_property_present(np
, "timestamp-names")) {
517 /* Let hte core construct it during request time */
518 desc
->attr
.name
= NULL
;
520 ret
= of_property_read_string_index(np
, "timestamp-names",
521 index
, &desc
->attr
.name
);
523 pr_err("can't parse \"timestamp-names\" property\n");
527 if (desc
->attr
.name
) {
528 temp
= skip_spaces(desc
->attr
.name
);
530 desc
->attr
.name
= NULL
;
534 ret
= of_parse_phandle_with_args(np
, "timestamps", "#timestamp-cells",
537 pr_err("%s(): can't parse \"timestamps\" property\n",
542 of_node_put(args
->np
);
544 return of_node_to_htedevice(args
->np
);
548 * hte_ts_get() - The function to initialize and obtain HTE desc.
550 * The function initializes the consumer provided HTE descriptor. If consumer
551 * has device tree node, index is used to parse the line id and other details.
552 * The function needs to be called before using any request APIs.
554 * @dev: HTE consumer/client device, used in case of parsing device tree node.
555 * @desc: Pre-allocated timestamp descriptor.
556 * @index: The index will be used as an index to parse line_id from the
557 * device tree node if node is present.
559 * Context: Holds mutex lock.
560 * Returns: Returns 0 on success or negative error code on failure.
562 int hte_ts_get(struct device
*dev
, struct hte_ts_desc
*desc
, int index
)
564 struct hte_device
*gdev
;
565 struct hte_ts_info
*ei
;
566 const struct fwnode_handle
*fwnode
;
567 struct of_phandle_args args
;
570 bool free_name
= false;
575 fwnode
= dev
? dev_fwnode(dev
) : NULL
;
577 if (is_of_node(fwnode
))
578 gdev
= hte_of_get_dev(dev
, desc
, index
, &args
, &free_name
);
580 gdev
= hte_get_dev(desc
);
583 pr_err("%s() no hte dev found\n", __func__
);
584 return PTR_ERR(gdev
);
587 if (!try_module_get(gdev
->owner
))
591 pr_err("%s(): requested id does not have provider\n",
597 if (is_of_node(fwnode
)) {
598 if (!gdev
->chip
->xlate_of
)
601 ret
= gdev
->chip
->xlate_of(gdev
->chip
, &args
,
604 if (!gdev
->chip
->xlate_plat
)
607 ret
= gdev
->chip
->xlate_plat(gdev
->chip
, desc
,
614 ei
= &gdev
->ei
[xlated_id
];
616 ret
= hte_bind_ts_info_locked(ei
, desc
, xlated_id
);
620 ei
->free_attr_name
= free_name
;
625 module_put(gdev
->owner
);
628 EXPORT_SYMBOL_GPL(hte_ts_get
);
630 static void __devm_hte_release_ts(void *res
)
636 * hte_request_ts_ns() - The API to request and enable hardware timestamp in
639 * The entity is provider specific for example, GPIO lines, signals, buses
640 * etc...The API allocates necessary resources and enables the timestamp.
642 * @desc: Pre-allocated and initialized timestamp descriptor.
643 * @cb: Callback to push the timestamp data to consumer.
644 * @tcb: Optional callback. If its provided, subsystem initializes
645 * workqueue. It is called when cb returns HTE_RUN_SECOND_CB.
646 * @data: Client data, used during cb and tcb callbacks.
648 * Context: Holds mutex lock.
649 * Returns: Returns 0 on success or negative error code on failure.
651 int hte_request_ts_ns(struct hte_ts_desc
*desc
, hte_ts_cb_t cb
,
652 hte_ts_sec_cb_t tcb
, void *data
)
655 struct hte_ts_info
*ei
;
657 if (!desc
|| !desc
->hte_data
|| !cb
)
661 if (!ei
|| !ei
->gdev
)
664 ret
= __hte_req_ts(desc
, cb
, tcb
, data
);
666 dev_err(ei
->gdev
->chip
->dev
,
667 "failed to request id: %d\n", desc
->attr
.line_id
);
673 EXPORT_SYMBOL_GPL(hte_request_ts_ns
);
676 * devm_hte_request_ts_ns() - Resource managed API to request and enable
677 * hardware timestamp in nanoseconds.
679 * The entity is provider specific for example, GPIO lines, signals, buses
680 * etc...The API allocates necessary resources and enables the timestamp. It
681 * deallocates and disables automatically when the consumer exits.
683 * @dev: HTE consumer/client device.
684 * @desc: Pre-allocated and initialized timestamp descriptor.
685 * @cb: Callback to push the timestamp data to consumer.
686 * @tcb: Optional callback. If its provided, subsystem initializes
687 * workqueue. It is called when cb returns HTE_RUN_SECOND_CB.
688 * @data: Client data, used during cb and tcb callbacks.
690 * Context: Holds mutex lock.
691 * Returns: Returns 0 on success or negative error code on failure.
693 int devm_hte_request_ts_ns(struct device
*dev
, struct hte_ts_desc
*desc
,
694 hte_ts_cb_t cb
, hte_ts_sec_cb_t tcb
,
702 err
= hte_request_ts_ns(desc
, cb
, tcb
, data
);
706 err
= devm_add_action_or_reset(dev
, __devm_hte_release_ts
, desc
);
712 EXPORT_SYMBOL_GPL(devm_hte_request_ts_ns
);
715 * hte_init_line_attr() - Initialize line attributes.
717 * Zeroes out line attributes and initializes with provided arguments.
718 * The function needs to be called before calling any consumer facing
721 * @desc: Pre-allocated timestamp descriptor.
723 * @edge_flags: edge flags related to line_id.
724 * @name: name of the line.
725 * @data: line data related to line_id.
728 * Returns: 0 on success or negative error code for the failure.
730 int hte_init_line_attr(struct hte_ts_desc
*desc
, u32 line_id
,
731 unsigned long edge_flags
, const char *name
, void *data
)
736 memset(&desc
->attr
, 0, sizeof(desc
->attr
));
738 desc
->attr
.edge_flags
= edge_flags
;
739 desc
->attr
.line_id
= line_id
;
740 desc
->attr
.line_data
= data
;
742 name
= kstrdup_const(name
, GFP_KERNEL
);
747 desc
->attr
.name
= name
;
751 EXPORT_SYMBOL_GPL(hte_init_line_attr
);
754 * hte_get_clk_src_info() - Get the clock source information for a ts
757 * @desc: ts descriptor, same as returned from request API.
758 * @ci: The API fills this structure with the clock information data.
760 * Context: Any context.
761 * Returns: 0 on success else negative error code on failure.
763 int hte_get_clk_src_info(const struct hte_ts_desc
*desc
,
764 struct hte_clk_info
*ci
)
766 struct hte_chip
*chip
;
767 struct hte_ts_info
*ei
;
769 if (!desc
|| !desc
->hte_data
|| !ci
) {
770 pr_debug("%s:%d\n", __func__
, __LINE__
);
775 if (!ei
->gdev
|| !ei
->gdev
->chip
)
778 chip
= ei
->gdev
->chip
;
779 if (!chip
->ops
->get_clk_src_info
)
782 return chip
->ops
->get_clk_src_info(chip
, ci
);
784 EXPORT_SYMBOL_GPL(hte_get_clk_src_info
);
787 * hte_push_ts_ns() - Push timestamp data in nanoseconds.
789 * It is used by the provider to push timestamp data.
791 * @chip: The HTE chip, used during the registration.
792 * @xlated_id: entity id understood by both subsystem and provider, this is
793 * obtained from xlate callback during request API.
794 * @data: timestamp data.
796 * Returns: 0 on success or a negative error code on failure.
798 int hte_push_ts_ns(const struct hte_chip
*chip
, u32 xlated_id
,
799 struct hte_ts_data
*data
)
803 struct hte_ts_info
*ei
;
806 if (!chip
|| !data
|| !chip
->gdev
)
809 if (xlated_id
>= chip
->nlines
)
812 ei
= &chip
->gdev
->ei
[xlated_id
];
814 spin_lock_irqsave(&ei
->slock
, flag
);
816 /* timestamp sequence counter */
817 data
->seq
= ei
->seq
++;
819 if (!test_bit(HTE_TS_REGISTERED
, &ei
->flags
) ||
820 test_bit(HTE_TS_DISABLE
, &ei
->flags
)) {
821 dev_dbg(chip
->dev
, "Unknown timestamp push\n");
822 atomic_inc(&ei
->dropped_ts
);
827 ret
= ei
->cb(data
, ei
->cl_data
);
828 if (ret
== HTE_RUN_SECOND_CB
&& ei
->tcb
) {
829 queue_work(system_unbound_wq
, &ei
->cb_work
);
830 set_bit(HTE_TS_QUEUE_WK
, &ei
->flags
);
834 spin_unlock_irqrestore(&ei
->slock
, flag
);
838 EXPORT_SYMBOL_GPL(hte_push_ts_ns
);
840 static int hte_register_chip(struct hte_chip
*chip
)
842 struct hte_device
*gdev
;
845 if (!chip
|| !chip
->dev
|| !chip
->dev
->of_node
)
848 if (!chip
->ops
|| !chip
->ops
->request
|| !chip
->ops
->release
) {
849 dev_err(chip
->dev
, "Driver needs to provide ops\n");
853 gdev
= kzalloc(struct_size(gdev
, ei
, chip
->nlines
), GFP_KERNEL
);
859 gdev
->nlines
= chip
->nlines
;
860 gdev
->sdev
= chip
->dev
;
862 for (i
= 0; i
< chip
->nlines
; i
++) {
863 gdev
->ei
[i
].gdev
= gdev
;
864 mutex_init(&gdev
->ei
[i
].req_mlock
);
865 spin_lock_init(&gdev
->ei
[i
].slock
);
868 if (chip
->dev
->driver
)
869 gdev
->owner
= chip
->dev
->driver
->owner
;
871 gdev
->owner
= THIS_MODULE
;
873 of_node_get(chip
->dev
->of_node
);
875 INIT_LIST_HEAD(&gdev
->list
);
877 spin_lock(&hte_lock
);
878 list_add_tail(&gdev
->list
, &hte_devices
);
879 spin_unlock(&hte_lock
);
881 hte_chip_dbgfs_init(gdev
);
883 dev_dbg(chip
->dev
, "Added hte chip\n");
888 static int hte_unregister_chip(struct hte_chip
*chip
)
890 struct hte_device
*gdev
;
897 spin_lock(&hte_lock
);
898 list_del(&gdev
->list
);
899 spin_unlock(&hte_lock
);
903 of_node_put(chip
->dev
->of_node
);
904 debugfs_remove_recursive(gdev
->dbg_root
);
907 dev_dbg(chip
->dev
, "Removed hte chip\n");
912 static void _hte_devm_unregister_chip(void *chip
)
914 hte_unregister_chip(chip
);
918 * devm_hte_register_chip() - Resource managed API to register HTE chip.
920 * It is used by the provider to register itself with the HTE subsystem.
921 * The unregistration is done automatically when the provider exits.
923 * @chip: the HTE chip to add to subsystem.
925 * Returns: 0 on success or a negative error code on failure.
927 int devm_hte_register_chip(struct hte_chip
*chip
)
931 err
= hte_register_chip(chip
);
935 err
= devm_add_action_or_reset(chip
->dev
, _hte_devm_unregister_chip
,
942 EXPORT_SYMBOL_GPL(devm_hte_register_chip
);