2022-03-29 12:46:33

by Dipen Patel

[permalink] [raw]
Subject: [PATCH v5 00/11] Intro to Hardware timestamping engine

This patch series introduces new subsystem called hardware timestamping
engine (HTE). It offers functionality such as timestamping through hardware
means in realtime. The HTE subsystem centralizes HTE provider and consumers
where providers can register themselves and the consumers can request
interested entity which could be lines, GPIO, signals or buses. The
HTE subsystem provides timestamp in nano seconds, having said that the provider
need to convert the timestamp if its not in that unit. There was upstream
discussion about the HTE at
https://lore.kernel.org/lkml/[email protected]/

To summarize upstream discussion:
- It was suggested by Linus and Kent to extend GPIOLIB and supporting
GPIO drivers to add HTE functionality and I agreed to experiment with it.
This patch series implements and extends GPIOLIB, GPIOLIB-CDEV and GPIO tegra
driver.
- Discussed possibility to add HTE provider as irqchip instead which
was argued against as HTE devices are not necessarily event emitting
devices. From RFC version 2 however, emulated threaded irq style
implementation.
- Discussed other possibility if HTE device can be added as posix clock
type like PTP clocks. That was argued against since HTE devices
are not necessarily tightly coupled with hardware clock.

Typical HTE provider does following:
- Register itself with HTE subsystem
- Provide request, release, enable, disable timestamp and
get_clk_src_info callbacks to HTE subsystem.
- Provide optional xlate callback to the subsystem which can translate
consumer provided logical ids into actual ids of the entity, where entity here
is the provider dependent and could be GPIO, in chip lines or signals, buses
etc...This converted id is used as communication token between HTE subsystem
and the provider.
- Push timestamps to the subsystem.
- Unregister itself on exit.

Typical HTE consumer does following:
- Request interested entity it wishes to timestamp in realtime to the
subsystem.
- The subsystem does necessary communications with the provider to
complete the request, which includes translating logical id of the entity to
provider dependent physical/actual id and enabling hardware timestamping on
requested id.
- The request includes callbacks, it will be used to push timestamps.
Optionally, the consumer can provided threaded callback, if specified, the HTE
subsystem uses workqueue executing the secondary callback.
- Release entity and its resources.

HTE and GPIOLIB:
- For the HTE provider which can timestamp GPIO lines.
- For the userspace GPIO consumers, the GPIOLIB CDEV framework are extended as
a frontend to the HTE. The kernel space consumers request GPIO lines directly
to HTE subsystem.
- Tegra194 AON GPIO controller has HTE support known as GTE
(Generic Timestamping Engine). The tegra gpio driver is modified to accommodate
HTE functionality.

Changes in V2:
- Removed buffer management and related APIs from the HTE core.
- Removed timestamp retrieve APIs from the HTE core.
- Modified request API with two callbacks, second callback is invoked in thread
context and is optional, while first callback is mandatory and used to push
timestamp data to consumers.
- Replaced hte with hardware-timestamping in DT bindings as hte appeared too
short according to review comments.

Changes in V3:
- Corrected grammatical errors in HTE documentation and its bindings documents.
- Removed multi-plural words in the HTE DT bindings.
- Reflected changes done in DT bindings in the respective source codes.
- Separated previous patch 07 into two patches in this series as 07 and 08.
- Corrections in MAINTAINERS file.

Changes in V4:
- Removed hardware-timestamp-engine device tree property from gpio.txt.
- Added hte_req_ts_by_linedata_ns.
- Removed hte_req_ts_by_hte_name.
- Renamed devm_of_hte_request_ts to devm_of_hte_request_ts_ns.
- Corrected hte ts seqeunce counter handling in hte related code in
gpiolib-cdev code.
- Added line level detection in Tegra GPIO HTE provider.
- Corrected GPIO line level calculation in gpiolib-cdev.

Changes in V5:
- Minor changes in dt-bindings
- Removed kernel thread in the HTE core.

There are patches pending to add HTE provider for another Nvidia Tegra chip
which will be pushed after this patch set.

Dipen Patel (11):
Documentation: Add HTE subsystem guide
drivers: Add hardware timestamp engine (HTE)
hte: Add tegra194 HTE kernel provider
dt-bindings: Add HTE bindings
hte: Add Tegra194 IRQ HTE test driver
gpiolib: Add HTE support
gpio: tegra186: Add HTE in gpio-tegra186 driver
gpiolib: cdev: Add hardware timestamp clock type
tools: gpio: Add new hardware clock type
hte: Add tegra GPIO HTE test driver
MAINTAINERS: Added HTE Subsystem

.../hte/hardware-timestamps-common.yaml | 29 +
.../devicetree/bindings/hte/hte-consumer.yaml | 43 +
.../bindings/hte/nvidia,tegra194-hte.yaml | 82 ++
Documentation/hte/hte.rst | 83 ++
Documentation/hte/index.rst | 22 +
Documentation/hte/tegra194-hte.rst | 52 ++
Documentation/index.rst | 1 +
MAINTAINERS | 8 +
drivers/Kconfig | 2 +
drivers/Makefile | 1 +
drivers/gpio/gpio-tegra186.c | 81 +-
drivers/gpio/gpiolib-cdev.c | 247 +++++-
drivers/gpio/gpiolib.c | 58 ++
drivers/gpio/gpiolib.h | 1 +
drivers/hte/Kconfig | 50 ++
drivers/hte/Makefile | 5 +
drivers/hte/hte-tegra194-gpio-test.c | 273 ++++++
drivers/hte/hte-tegra194-irq-test.c | 179 ++++
drivers/hte/hte-tegra194.c | 690 +++++++++++++++
drivers/hte/hte.c | 828 ++++++++++++++++++
include/linux/gpio/consumer.h | 16 +-
include/linux/gpio/driver.h | 10 +
include/linux/hte.h | 253 ++++++
include/uapi/linux/gpio.h | 3 +
tools/gpio/gpio-event-mon.c | 6 +-
25 files changed, 2986 insertions(+), 37 deletions(-)
create mode 100644 Documentation/devicetree/bindings/hte/hardware-timestamps-common.yaml
create mode 100644 Documentation/devicetree/bindings/hte/hte-consumer.yaml
create mode 100644 Documentation/devicetree/bindings/hte/nvidia,tegra194-hte.yaml
create mode 100644 Documentation/hte/hte.rst
create mode 100644 Documentation/hte/index.rst
create mode 100644 Documentation/hte/tegra194-hte.rst
create mode 100644 drivers/hte/Kconfig
create mode 100644 drivers/hte/Makefile
create mode 100644 drivers/hte/hte-tegra194-gpio-test.c
create mode 100644 drivers/hte/hte-tegra194-irq-test.c
create mode 100644 drivers/hte/hte-tegra194.c
create mode 100644 drivers/hte/hte.c
create mode 100644 include/linux/hte.h


base-commit: f8833a2b23562be2dae91775127c8014c44d8566
--
2.17.1


2022-03-29 13:01:28

by Dipen Patel

[permalink] [raw]
Subject: [PATCH v5 01/11] Documentation: Add HTE subsystem guide

Adding hte document which can help understand various APIs implemented
in HTE framework for the HTE producers and the consumers.

Signed-off-by: Dipen Patel <[email protected]>
---
Changes in v2:
- Removed explanation, instead added kernel-doc references.

Changes in v3:
- Addressed grammatical errors.

Changes in v4:
- Added new API hte_req_ts_by_linedata_ns description.
- Removed hte_req_ts_by_hte_name.

Documentation/hte/hte.rst | 83 +++++++++++++++++++++++++++++++++++++++
1 file changed, 83 insertions(+)
create mode 100644 Documentation/hte/hte.rst

diff --git a/Documentation/hte/hte.rst b/Documentation/hte/hte.rst
new file mode 100644
index 000000000000..7ac3e2fdb952
--- /dev/null
+++ b/Documentation/hte/hte.rst
@@ -0,0 +1,83 @@
+============================================
+The Linux Hardware Timestamping Engine (HTE)
+============================================
+
+:Author: Dipen Patel
+
+Introduction
+------------
+
+Certain devices have built in hardware timestamping engines which can
+monitor sets of system signals, lines, buses etc... in realtime for state
+change; upon detecting the change they can automatically store the timestamp at
+the moment of occurrence. Such functionality may help achieve better accuracy
+in obtaining timestamps than using software counterparts i.e. ktime and
+friends.
+
+This document describes the API that can be used by hardware timestamping
+engine provider and consumer drivers that want to use the hardware timestamping
+engine (HTE) framework. Both consumers and providers must include
+#include <linux/hte.h>.
+
+The HTE framework APIs for the providers
+----------------------------------------
+
+.. kernel-doc:: drivers/hte/hte.c
+ :functions: devm_hte_register_chip hte_push_ts_ns
+
+The HTE framework APIs for the consumers
+----------------------------------------
+
+.. kernel-doc:: drivers/hte/hte.c
+ :functions: devm_of_hte_request_ts_ns hte_req_ts_by_linedata_ns hte_release_ts hte_enable_ts hte_disable_ts hte_get_clk_src_info
+
+The HTE framework public structures
+-----------------------------------
+.. kernel-doc:: include/linux/hte.h
+
+More on the HTE timestamp data
+------------------------------
+The struct hte_ts_data is used to pass timestamp details between the consumers
+and the providers. It expresses timestamp data in nanoseconds in u64 data
+type. For now all the HTE APIs using struct hte_ts_data require tsc to be in
+nanoseconds. An example of the typical hte_ts_data data life cycle, for the
+GPIO line is as follows::
+
+ - Monitors GPIO line change.
+ - Detects the state change on GPIO line.
+ - Converts timestamps in nanoseconds and stores it in tsc.
+ - Stores GPIO raw level in raw_level variable if the provider has that
+ hardware capability.
+ - Pushes this hte_ts_data object to HTE subsystem.
+ - HTE subsystem increments seq counter and invokes consumer provided callback.
+ Based on callback return value, the HTE core invokes secondary callback in
+ the thread context.
+
+HTE subsystem debugfs attributes
+--------------------------------
+HTE subsystem creates debugfs attributes at ``/sys/kernel/debug/hte/``.
+It also creates line/signal-related debugfs attributes at
+``/sys/kernel/debug/hte/<provider>/<label or line id>/``.
+
+`ts_requested`
+ The total number of entities requested from the given provider,
+ where entity is specified by the provider and could represent
+ lines, GPIO, chip signals, buses etc...
+ The attribute will be available at
+ ``/sys/kernel/debug/hte/<provider>/``.
+
+ Read-only value
+
+`total_ts`
+ The total number of entities supported by the provider.
+ The attribute will be available at
+ ``/sys/kernel/debug/hte/<provider>/``.
+
+ Read-only value
+
+`dropped_timestamps`
+ The dropped timestamps for a given line.
+ The attribute will be available at
+ ``/sys/kernel/debug/hte/<provider>/<label or line id>/``.
+
+ Read-only value
--
2.17.1

2022-03-29 14:52:00

by Dipen Patel

[permalink] [raw]
Subject: [PATCH v5 10/11] hte: Add tegra GPIO HTE test driver

Tegra194 AON GPIO controller supports hardware timestamping
through its HTE known as Generic timestamping Engine(GTE).
This kernel space gpio consumer test driver demonstrates HTE
functionality. During probe it registers sysfs
interface /sys/kernel/tegra_hte_gpio_test/gpio_en_dis. The value 1
enables gpio line for the HTE functionality while the value 0
disables that.

The test driver can be compiled as a module and takes optional
parameters gpio_out and gpio_in of type uint that specifies logical
GPIO numbers.

This patch also adds compilation support in Kconfig and Makefile.

Signed-off-by: Dipen Patel <[email protected]>
---
Changes in v3:
- Addressed grammatical errors.

Changes in v4:
- Reflected HTE and GPIOLIB subsytem API changes.

drivers/hte/Kconfig | 9 +
drivers/hte/Makefile | 1 +
drivers/hte/hte-tegra194-gpio-test.c | 273 +++++++++++++++++++++++++++
3 files changed, 283 insertions(+)
create mode 100644 drivers/hte/hte-tegra194-gpio-test.c

diff --git a/drivers/hte/Kconfig b/drivers/hte/Kconfig
index dee8b7a2b980..f20f38ae172b 100644
--- a/drivers/hte/Kconfig
+++ b/drivers/hte/Kconfig
@@ -38,4 +38,13 @@ config HTE_TEGRA194_IRQ_TEST
The NVIDIA Tegra194 GTE IRQ test driver demonstrates HTE subsystem
usage for the LIC IRQ hardware timestamp.

+config HTE_TEGRA194_GPIO_TEST
+ tristate "NVIDIA Tegra194 HTE GPIO Test"
+ depends on HTE_TEGRA194
+ help
+ The NVIDIA Tegra194 GTE GPIO test driver demonstrates how to use the HTE
+ subsystem indirectly through gpiolib API calls for GPIO lines for the
+ hardware-assisted timestamping.
+
endif
+
diff --git a/drivers/hte/Makefile b/drivers/hte/Makefile
index 75b7932c2ffc..1d12f3a36709 100644
--- a/drivers/hte/Makefile
+++ b/drivers/hte/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_HTE) += hte.o
obj-$(CONFIG_HTE_TEGRA194) += hte-tegra194.o
obj-$(CONFIG_HTE_TEGRA194_IRQ_TEST) += hte-tegra194-irq-test.o
+obj-$(CONFIG_HTE_TEGRA194_GPIO_TEST) += hte-tegra194-gpio-test.o

diff --git a/drivers/hte/hte-tegra194-gpio-test.c b/drivers/hte/hte-tegra194-gpio-test.c
new file mode 100644
index 000000000000..dee5a687e21a
--- /dev/null
+++ b/drivers/hte/hte-tegra194-gpio-test.c
@@ -0,0 +1,273 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021-2022 NVIDIA Corporation
+ *
+ * Author: Dipen Patel <[email protected]>
+ */
+
+#include <linux/version.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/timer.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/hte.h>
+
+/*
+ * Tegra194 On chip HTE (hardware timestamping engine) also known as GTE
+ * (generic timestamping engine) can monitor subset of GPIO lines for the event
+ * and timestamp accordingly.
+ *
+ * This sample HTE GPIO test driver demonstrates HTE API usage by enabling
+ * hardware timestamp on gpio_in line which is configured as rising edge.
+ *
+ * Note: gpio_out and gpio_in need to be shorted externally in order for this
+ * test driver to work for the GPIO monitoring. The test driver has been
+ * tested on Jetson AGX Xavier platform by shorting pin 32 and 16 on 40 pin
+ * header. The gpio_out and gpio_in can be passed as parameter during module
+ * loading.
+ *
+ * How to run test driver:
+ * - Load test driver
+ * - echo 1 >/sys/kernel/tegra_hte_gpio_test/gpio_en_dis, sends request to HTE
+ * - echo 0 >/sys/kernel/tegra_hte_gpio_test/gpio_en_dis or unloading sends
+ * release request to HTE.
+ * - Once requested, at regular interval gpio_out pin toggles triggering
+ * HTE for rising edge on gpio_in pin. It will print message as below:
+ * GPIO HW timestamp(1): <timestamp>, edge: rising.
+ */
+
+static unsigned int gpio_in = 322;
+module_param(gpio_in, uint, 0660);
+
+static unsigned int gpio_out = 321;
+module_param(gpio_out, uint, 0660);
+
+static struct tegra_hte_test {
+ bool is_ts_en;
+ int gpio_in_irq;
+ struct gpio_desc *gpio_in;
+ struct gpio_desc *gpio_out;
+ struct hte_ts_desc desc;
+ struct timer_list timer;
+ struct kobject *kobj;
+} hte;
+
+static hte_return_t process_hw_ts(struct hte_ts_data *ts, void *p)
+{
+ char *edge;
+ (void)p;
+
+ if (!ts)
+ return HTE_CB_HANDLED;
+
+ if (ts->raw_level < 0)
+ edge = "Unknown";
+
+ pr_info("GPIO HW timestamp(%llu): %llu, edge: %s\n", ts->seq, ts->tsc,
+ (ts->raw_level >= 0) ? ((ts->raw_level == 0) ?
+ "falling" : "rising") : edge);
+
+ return HTE_CB_HANDLED;
+}
+
+/*
+ * Sysfs attribute to request/release HTE gpio line
+ */
+static ssize_t store_gpio_en_dis(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret = count;
+ unsigned long val = 0;
+ (void)kobj;
+ (void)attr;
+
+ if (kstrtoul(buf, 10, &val) < 0) {
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (val == 1) {
+ if (hte.is_ts_en) {
+ ret = -EEXIST;
+ goto error;
+ }
+
+ hte.desc.attr.line_data = hte.gpio_in;
+ hte.desc.attr.line_id = desc_to_gpio(hte.gpio_in);
+ /*
+ * Driver requests irq which implicitly specifies the edges
+ * for HTE subsystem, no need to setup through HTE
+ */
+ hte.desc.attr.edge_flags = HTE_EDGE_NO_SETUP;
+ hte.desc.attr.name = "gte_gpio";
+
+ ret = hte_req_ts_by_linedata_ns(&hte.desc, process_hw_ts,
+ NULL, NULL);
+ if (ret)
+ goto error;
+
+ hte.is_ts_en = true;
+ } else if (val == 0) {
+ if (!hte.is_ts_en) {
+ ret = -EINVAL;
+ goto error;
+ }
+ ret = hte_release_ts(&hte.desc);
+ if (ret)
+ goto error;
+
+ hte.is_ts_en = false;
+ }
+
+ ret = count;
+
+error:
+ return ret;
+}
+
+struct kobj_attribute gpio_en_dis_attr =
+ __ATTR(gpio_en_dis, 0220, NULL, store_gpio_en_dis);
+
+static struct attribute *attrs[] = {
+ &gpio_en_dis_attr.attr,
+ NULL,
+};
+
+static struct attribute_group tegra_hte_test_attr_group = {
+ .attrs = attrs,
+};
+
+static int tegra_hte_test_sysfs_create(void)
+{
+ int ret;
+
+ /* Creates /sys/kernel/tegra_hte_gpio_test */
+ hte.kobj = kobject_create_and_add("tegra_hte_gpio_test", kernel_kobj);
+ if (!hte.kobj)
+ return -ENOMEM;
+
+ ret = sysfs_create_group(hte.kobj, &tegra_hte_test_attr_group);
+ if (ret)
+ kobject_put(hte.kobj);
+ return ret;
+}
+
+static void gpio_timer_cb(struct timer_list *t)
+{
+ (void)t;
+
+ gpiod_set_value(hte.gpio_out, !gpiod_get_value(hte.gpio_out));
+ mod_timer(&hte.timer, jiffies + msecs_to_jiffies(8000));
+}
+
+static irqreturn_t tegra_hte_test_gpio_isr(int irq, void *data)
+{
+ (void)irq;
+ (void)data;
+
+ return IRQ_HANDLED;
+}
+
+static int __init tegra_hte_gpio_test_init(void)
+{
+ int ret = 0;
+
+ ret = gpio_request(gpio_out, "gte_test_gpio_out");
+ if (ret) {
+ pr_err("failed request gpio out\n");
+ return -EINVAL;
+ }
+
+ ret = gpio_request(gpio_in, "gte_test_gpio_in");
+ if (ret) {
+ pr_err("failed request gpio in\n");
+ ret = -EINVAL;
+ goto free_gpio_out;
+ }
+
+ hte.gpio_out = gpio_to_desc(gpio_out);
+ if (!hte.gpio_out) {
+ pr_err("failed convert gpio out to desc\n");
+ ret = -EINVAL;
+ goto free_gpio_in;
+ }
+
+ hte.gpio_in = gpio_to_desc(gpio_in);
+ if (!hte.gpio_in) {
+ pr_err("failed convert gpio in to desc\n");
+ ret = -EINVAL;
+ goto free_gpio_in;
+ }
+
+ ret = gpiod_direction_output(hte.gpio_out, 0);
+ if (ret) {
+ pr_err("failed to set output\n");
+ ret = -EINVAL;
+ goto free_gpio_in;
+ }
+
+ ret = gpiod_direction_input(hte.gpio_in);
+ if (ret) {
+ pr_err("failed to set input\n");
+ ret = -EINVAL;
+ goto free_gpio_in;
+ }
+
+ ret = gpiod_to_irq(hte.gpio_in);
+ if (ret < 0) {
+ pr_err("failed to map GPIO to IRQ: %d\n", ret);
+ ret = -ENXIO;
+ goto free_gpio_in;
+ }
+
+ hte.gpio_in_irq = ret;
+ ret = request_irq(ret, tegra_hte_test_gpio_isr,
+ IRQF_TRIGGER_RISING,
+ "tegra_hte_gpio_test_isr", &hte);
+ if (ret) {
+ pr_err("failed to acquire IRQ\n");
+ ret = -ENXIO;
+ goto free_irq;
+ }
+
+ ret = tegra_hte_test_sysfs_create();
+ if (ret != 0) {
+ pr_err("sysfs creation failed\n");
+ ret = -ENXIO;
+ goto free_irq;
+ }
+
+ timer_setup(&hte.timer, gpio_timer_cb, 0);
+ mod_timer(&hte.timer, jiffies + msecs_to_jiffies(5000));
+
+ return 0;
+
+free_irq:
+ free_irq(hte.gpio_in_irq, &hte);
+free_gpio_in:
+ gpio_free(gpio_in);
+free_gpio_out:
+ gpio_free(gpio_out);
+
+ return ret;
+}
+
+static void __exit tegra_hte_gpio_test_exit(void)
+{
+ free_irq(hte.gpio_in_irq, &hte);
+ gpio_free(gpio_in);
+ gpio_free(gpio_out);
+ hte_release_ts(&hte.desc);
+ kobject_put(hte.kobj);
+ del_timer(&hte.timer);
+}
+
+module_init(tegra_hte_gpio_test_init);
+module_exit(tegra_hte_gpio_test_exit);
+MODULE_AUTHOR("Dipen Patel <[email protected]>");
+MODULE_LICENSE("GPL v2");
--
2.17.1

2022-03-29 22:26:21

by Dipen Patel

[permalink] [raw]
Subject: [PATCH v5 06/11] gpiolib: Add HTE support

Some GPIO chip can provide hardware timestamp support on its GPIO lines
, in order to support that, additional API needs to be added which
can talk to both GPIO chip and HTE (hardware timestamping engine)
providers if there is any dependencies. This patch introduces optional
hooks to enable and disable hardware timestamping related features
in the GPIO controller chip.

Signed-off-by: Dipen Patel <[email protected]>
Reviewed-by: Linus Walleij <[email protected]>
Reported-by: kernel test robot <[email protected]>
---
Changes in v2:
- removed get timestamp and is timestamp enabled APIs

Changes in v4:
- Removed gpiod_req_hw_timestamp_ns and gpiod_rel_hw_timestamp_ns APIs.
- Added callbacks for the GPIO driver to enable hardware timestamping
functionality if supported which takes gpio desc and flags as arguments.
- Added APIs are called from GPIO provider rather than gpiolib-cdev framework.

drivers/gpio/gpiolib.c | 58 +++++++++++++++++++++++++++++++++++
drivers/gpio/gpiolib.h | 1 +
include/linux/gpio/consumer.h | 16 ++++++++--
include/linux/gpio/driver.h | 10 ++++++
4 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 56d090258d62..d355026892e0 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2422,6 +2422,64 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
}
EXPORT_SYMBOL_GPL(gpiod_direction_output);

+/**
+ * gpiod_enable_hw_timestamp_ns - Enable hardware timestamp in nanoseconds.
+ *
+ * @desc: GPIO to enable.
+ * @flags: Flags related to GPIO edge.
+ *
+ * Return 0 in case of success, else negative error code.
+ */
+int gpiod_enable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags)
+{
+ int ret = 0;
+ struct gpio_chip *gc;
+
+ VALIDATE_DESC(desc);
+
+ gc = desc->gdev->chip;
+ if (!gc->en_hw_timestamp) {
+ gpiod_warn(desc, "%s: hw ts not supported\n", __func__);
+ return -ENOTSUPP;
+ }
+
+ ret = gc->en_hw_timestamp(gc, gpio_chip_hwgpio(desc), flags);
+ if (ret)
+ gpiod_warn(desc, "%s: hw ts request failed\n", __func__);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gpiod_enable_hw_timestamp_ns);
+
+/**
+ * gpiod_disable_hw_timestamp_ns - Disable hardware timestamp.
+ *
+ * @desc: GPIO to disable.
+ * @flags: Flags related to GPIO edge, same value as used during enable call.
+ *
+ * Return 0 in case of success, else negative error code.
+ */
+int gpiod_disable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags)
+{
+ int ret = 0;
+ struct gpio_chip *gc;
+
+ VALIDATE_DESC(desc);
+
+ gc = desc->gdev->chip;
+ if (!gc->dis_hw_timestamp) {
+ gpiod_warn(desc, "%s: hw ts not supported\n", __func__);
+ return -ENOTSUPP;
+ }
+
+ ret = gc->dis_hw_timestamp(gc, gpio_chip_hwgpio(desc), flags);
+ if (ret)
+ gpiod_warn(desc, "%s: hw ts release failed\n", __func__);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(gpiod_disable_hw_timestamp_ns);
+
/**
* gpiod_set_config - sets @config for a GPIO
* @desc: descriptor of the GPIO for which to set the configuration
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 06f3faa9fbef..29a7d39062b3 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -158,6 +158,7 @@ struct gpio_desc {
#define FLAG_EDGE_RISING 16 /* GPIO CDEV detects rising edge events */
#define FLAG_EDGE_FALLING 17 /* GPIO CDEV detects falling edge events */
#define FLAG_EVENT_CLOCK_REALTIME 18 /* GPIO CDEV reports REALTIME timestamps in events */
+#define FLAG_EVENT_CLOCK_HTE 19 /* GPIO CDEV reports hardware timestamps in events */

/* Connection label */
const char *label;
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index c3aa8b330e1c..7eaec081ae6c 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -109,6 +109,8 @@ int gpiod_get_direction(struct gpio_desc *desc);
int gpiod_direction_input(struct gpio_desc *desc);
int gpiod_direction_output(struct gpio_desc *desc, int value);
int gpiod_direction_output_raw(struct gpio_desc *desc, int value);
+int gpiod_enable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags);
+int gpiod_disable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags);

/* Value get/set from non-sleeping context */
int gpiod_get_value(const struct gpio_desc *desc);
@@ -350,8 +352,18 @@ static inline int gpiod_direction_output_raw(struct gpio_desc *desc, int value)
WARN_ON(desc);
return -ENOSYS;
}
-
-
+static inline int gpiod_enable_hw_timestamp_ns(struct gpio_desc *desc,
+ unsigned long flags)
+{
+ WARN_ON(desc);
+ return -ENOSYS;
+}
+static inline int gpiod_disable_hw_timestamp_ns(struct gpio_desc *desc,
+ unsigned long flags)
+{
+ WARN_ON(desc);
+ return -ENOSYS;
+}
static inline int gpiod_get_value(const struct gpio_desc *desc)
{
/* GPIO can never have been requested */
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index b0728c8ad90c..f28d1e9b61f0 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -320,6 +320,10 @@ struct gpio_irq_chip {
* @add_pin_ranges: optional routine to initialize pin ranges, to be used when
* requires special mapping of the pins that provides GPIO functionality.
* It is called after adding GPIO chip and before adding IRQ chip.
+ * @en_hw_timestamp: Dependent on GPIO chip, an optional routine to
+ * enable hardware timestamp.
+ * @dis_hw_timestamp: Dependent on GPIO chip, an optional routine to
+ * disable hardware timestamp.
* @base: identifies the first GPIO number handled by this chip;
* or, if negative during registration, requests dynamic ID allocation.
* DEPRECATION: providing anything non-negative and nailing the base
@@ -416,6 +420,12 @@ struct gpio_chip {

int (*add_pin_ranges)(struct gpio_chip *gc);

+ int (*en_hw_timestamp)(struct gpio_chip *gc,
+ u32 offset,
+ unsigned long flags);
+ int (*dis_hw_timestamp)(struct gpio_chip *gc,
+ u32 offset,
+ unsigned long flags);
int base;
u16 ngpio;
u16 offset;
--
2.17.1

2022-03-30 07:52:29

by Dipen Patel

[permalink] [raw]
Subject: Re: [PATCH v5 01/11] Documentation: Add HTE subsystem guide

Hi,

On 3/29/22 8:27 AM, Jonathan Corbet wrote:
> Bagas Sanjaya <[email protected]> writes:
>
>> On 29/03/22 12.45, Dipen Patel wrote:
>>> +============================================
>>> +The Linux Hardware Timestamping Engine (HTE)
>>> +============================================
>>> +
>>> +:Author: Dipen Patel
>>> +
>> Please learn how to convey semantics with rst format, see further comments
>> below.
> That is the Sphinx "field list" syntax; it's pretty heavily used
> throughout the kernel documentation and doesn't seem to merit that sort
> of response...?
>
> [...]
>
>>> +The struct hte_ts_data is used to pass timestamp details between the consumers
>>> +and the providers. It expresses timestamp data in nanoseconds in u64 data
>>> +type. For now all the HTE APIs using struct hte_ts_data require tsc to be in
>>> +nanoseconds. An example of the typical hte_ts_data data life cycle, for the
>>> +GPIO line is as follows::
>>> +
>> When we talk about name terms found in actual code (like keywords or variable
>> names), it is customary to enclose them inside inline code (for example,
>> ``struct what`` or ``u64 what``).
> It's also customary to minimize markup. In the case of "struct
> whatever" the markup is actively harmful since it interferes with the
> automatic recognition and cross-referencing of the type.
I agree, I will keep only necessary reference in this section.
>
> jon

2022-03-30 12:07:08

by Bagas Sanjaya

[permalink] [raw]
Subject: Re: [PATCH v5 01/11] Documentation: Add HTE subsystem guide

On 29/03/22 12.45, Dipen Patel wrote:
> +============================================
> +The Linux Hardware Timestamping Engine (HTE)
> +============================================
> +
> +:Author: Dipen Patel
> +

Please learn how to convey semantics with rst format, see further comments
below.

> +This document describes the API that can be used by hardware timestamping
> +engine provider and consumer drivers that want to use the hardware timestamping
> +engine (HTE) framework. Both consumers and providers must include
> +#include <linux/hte.h>.
> +

Maybe it's better to write as `... providers must ``#include <linux/hte.h>```.

> +The HTE framework APIs for the providers
> +----------------------------------------
> +
> +.. kernel-doc:: drivers/hte/hte.c
> + :functions: devm_hte_register_chip hte_push_ts_ns
> +
> +The HTE framework APIs for the consumers
> +----------------------------------------
> +
> +.. kernel-doc:: drivers/hte/hte.c
> + :functions: devm_of_hte_request_ts_ns hte_req_ts_by_linedata_ns hte_release_ts hte_enable_ts hte_disable_ts hte_get_clk_src_info
> +
> +The HTE framework public structures
> +-----------------------------------
> +.. kernel-doc:: include/linux/hte.h
> +
> +More on the HTE timestamp data
> +------------------------------
> +The struct hte_ts_data is used to pass timestamp details between the consumers
> +and the providers. It expresses timestamp data in nanoseconds in u64 data
> +type. For now all the HTE APIs using struct hte_ts_data require tsc to be in
> +nanoseconds. An example of the typical hte_ts_data data life cycle, for the
> +GPIO line is as follows::
> +

When we talk about name terms found in actual code (like keywords or variable
names), it is customary to enclose them inside inline code (for example,
``struct what`` or ``u64 what``).

> + - Monitors GPIO line change.
> + - Detects the state change on GPIO line.
> + - Converts timestamps in nanoseconds and stores it in tsc.
> + - Stores GPIO raw level in raw_level variable if the provider has that
> + hardware capability.
> + - Pushes this hte_ts_data object to HTE subsystem.
> + - HTE subsystem increments seq counter and invokes consumer provided callback.
> + Based on callback return value, the HTE core invokes secondary callback in
> + the thread context.
> +
> +HTE subsystem debugfs attributes
> +--------------------------------
> +HTE subsystem creates debugfs attributes at ``/sys/kernel/debug/hte/``.
> +It also creates line/signal-related debugfs attributes at
> +``/sys/kernel/debug/hte/<provider>/<label or line id>/``.
> +
> +`ts_requested`
> + The total number of entities requested from the given provider,
> + where entity is specified by the provider and could represent
> + lines, GPIO, chip signals, buses etc...
> + The attribute will be available at
> + ``/sys/kernel/debug/hte/<provider>/``.
> +
> + Read-only value
> +
> +`total_ts`
> + The total number of entities supported by the provider.
> + The attribute will be available at
> + ``/sys/kernel/debug/hte/<provider>/``.
> +
> + Read-only value
> +
> +`dropped_timestamps`
> + The dropped timestamps for a given line.
> + The attribute will be available at
> + ``/sys/kernel/debug/hte/<provider>/<label or line id>/``.
> +
> + Read-only value

Since all these debugfs variables are read-only, we can say "Note that all
these values are read-only".

--
An old man doll... just what I always wanted! - Clara

2022-03-30 14:11:37

by Jonathan Corbet

[permalink] [raw]
Subject: Re: [PATCH v5 01/11] Documentation: Add HTE subsystem guide

Bagas Sanjaya <[email protected]> writes:

> On 29/03/22 12.45, Dipen Patel wrote:
>> +============================================
>> +The Linux Hardware Timestamping Engine (HTE)
>> +============================================
>> +
>> +:Author: Dipen Patel
>> +
>
> Please learn how to convey semantics with rst format, see further comments
> below.

That is the Sphinx "field list" syntax; it's pretty heavily used
throughout the kernel documentation and doesn't seem to merit that sort
of response...?

[...]

>> +The struct hte_ts_data is used to pass timestamp details between the consumers
>> +and the providers. It expresses timestamp data in nanoseconds in u64 data
>> +type. For now all the HTE APIs using struct hte_ts_data require tsc to be in
>> +nanoseconds. An example of the typical hte_ts_data data life cycle, for the
>> +GPIO line is as follows::
>> +
>
> When we talk about name terms found in actual code (like keywords or variable
> names), it is customary to enclose them inside inline code (for example,
> ``struct what`` or ``u64 what``).

It's also customary to minimize markup. In the case of "struct
whatever" the markup is actively harmful since it interferes with the
automatic recognition and cross-referencing of the type.

jon

2022-03-31 03:45:12

by Dipen Patel

[permalink] [raw]
Subject: Re: [PATCH v5 01/11] Documentation: Add HTE subsystem guide

Hi Sanjaya,

I will address your comments in next patch version.  Thanks for the comment.

Best,

Dipen Patel

On 3/29/22 6:16 AM, Bagas Sanjaya wrote:
> On 29/03/22 12.45, Dipen Patel wrote:
>> +============================================
>> +The Linux Hardware Timestamping Engine (HTE)
>> +============================================
>> +
>> +:Author: Dipen Patel
>> +
>
> Please learn how to convey semantics with rst format, see further comments
> below.
>
>> +This document describes the API that can be used by hardware timestamping
>> +engine provider and consumer drivers that want to use the hardware timestamping
>> +engine (HTE) framework. Both consumers and providers must include
>> +#include <linux/hte.h>.
>> +
>
> Maybe it's better to write as `... providers must ``#include <linux/hte.h>```.
>
>> +The HTE framework APIs for the providers
>> +----------------------------------------
>> +
>> +.. kernel-doc:: drivers/hte/hte.c
>> +   :functions: devm_hte_register_chip hte_push_ts_ns
>> +
>> +The HTE framework APIs for the consumers
>> +----------------------------------------
>> +
>> +.. kernel-doc:: drivers/hte/hte.c
>> +   :functions: devm_of_hte_request_ts_ns hte_req_ts_by_linedata_ns hte_release_ts hte_enable_ts hte_disable_ts hte_get_clk_src_info
>> +
>> +The HTE framework public structures
>> +-----------------------------------
>> +.. kernel-doc:: include/linux/hte.h
>> +
>> +More on the HTE timestamp data
>> +------------------------------
>> +The struct hte_ts_data is used to pass timestamp details between the consumers
>> +and the providers. It expresses timestamp data in nanoseconds in u64 data
>> +type. For now all the HTE APIs using struct hte_ts_data require tsc to be in
>> +nanoseconds. An example of the typical hte_ts_data data life cycle, for the
>> +GPIO line is as follows::
>> +
>
> When we talk about name terms found in actual code (like keywords or variable
> names), it is customary to enclose them inside inline code (for example,
> ``struct what`` or ``u64 what``).
>
>> + - Monitors GPIO line change.
>> + - Detects the state change on GPIO line.
>> + - Converts timestamps in nanoseconds and stores it in tsc.
>> + - Stores GPIO raw level in raw_level variable if the provider has that
>> + hardware capability.
>> + - Pushes this hte_ts_data object to HTE subsystem.
>> + - HTE subsystem increments seq counter and invokes consumer provided callback.
>> + Based on callback return value, the HTE core invokes secondary callback in
>> + the thread context.
>> +
>> +HTE subsystem debugfs attributes
>> +--------------------------------
>> +HTE subsystem creates debugfs attributes at ``/sys/kernel/debug/hte/``.
>> +It also creates line/signal-related debugfs attributes at
>> +``/sys/kernel/debug/hte/<provider>/<label or line id>/``.
>> +
>> +`ts_requested`
>> +        The total number of entities requested from the given provider,
>> +        where entity is specified by the provider and could represent
>> +        lines, GPIO, chip signals, buses etc...
>> +                The attribute will be available at
>> +        ``/sys/kernel/debug/hte/<provider>/``.
>> +
>> +        Read-only value
>> +
>> +`total_ts`
>> +        The total number of entities supported by the provider.
>> +                The attribute will be available at
>> +        ``/sys/kernel/debug/hte/<provider>/``.
>> +
>> +        Read-only value
>> +
>> +`dropped_timestamps`
>> +        The dropped timestamps for a given line.
>> +                The attribute will be available at
>> +        ``/sys/kernel/debug/hte/<provider>/<label or line id>/``.
>> +
>> +        Read-only value
>
> Since all these debugfs variables are read-only, we can say "Note that all
> these values are read-only".
>

2022-04-21 02:43:18

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH v5 00/11] Intro to Hardware timestamping engine

On Wed, Apr 20, 2022 at 12:46:43AM +0200, Linus Walleij wrote:
> On Tue, Mar 29, 2022 at 7:45 AM Dipen Patel <[email protected]> wrote:
>
> > This patch series introduces new subsystem called hardware timestamping
> > engine (HTE). It offers functionality such as timestamping through hardware
> > means in realtime. The HTE subsystem centralizes HTE provider and consumers
> > where providers can register themselves and the consumers can request
> > interested entity which could be lines, GPIO, signals or buses. The
> > HTE subsystem provides timestamp in nano seconds, having said that the provider
> > need to convert the timestamp if its not in that unit. There was upstream
> > discussion about the HTE at
> > https://lore.kernel.org/lkml/[email protected]/
>
> I like this.
>
> Can you put it in a public git and make it eligible for Stephen Rothwell to
> pull into linux-next and ask him to do so, as we intend to merge this for
> v5.19?

Do you intend to maintain this as part of the pinctrl or GPIO trees with
Dipen as a sub-maintainer? Or would you prefer for this to be a separate
tree?

Thierry


Attachments:
(No filename) (1.14 kB)
signature.asc (849.00 B)
Download all attachments

2022-04-21 14:51:20

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH v5 00/11] Intro to Hardware timestamping engine

On Wed, Apr 20, 2022 at 3:47 PM Thierry Reding <[email protected]> wrote:
> On Wed, Apr 20, 2022 at 12:46:43AM +0200, Linus Walleij wrote:
> > On Tue, Mar 29, 2022 at 7:45 AM Dipen Patel <[email protected]> wrote:
> >
> > > This patch series introduces new subsystem called hardware timestamping
> > > engine (HTE). It offers functionality such as timestamping through hardware
> > > means in realtime. The HTE subsystem centralizes HTE provider and consumers
> > > where providers can register themselves and the consumers can request
> > > interested entity which could be lines, GPIO, signals or buses. The
> > > HTE subsystem provides timestamp in nano seconds, having said that the provider
> > > need to convert the timestamp if its not in that unit. There was upstream
> > > discussion about the HTE at
> > > https://lore.kernel.org/lkml/[email protected]/
> >
> > I like this.
> >
> > Can you put it in a public git and make it eligible for Stephen Rothwell to
> > pull into linux-next and ask him to do so, as we intend to merge this for
> > v5.19?
>
> Do you intend to maintain this as part of the pinctrl or GPIO trees with
> Dipen as a sub-maintainer? Or would you prefer for this to be a separate
> tree?

It has nothing to do with pin control but a bit to do with GPIO and IIO.
I think it needs to be its own tree just like regulators or clocks.

Yours,
Linus Walleij

2022-04-22 19:28:44

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH v5 00/11] Intro to Hardware timestamping engine

On Tue, Mar 29, 2022 at 7:45 AM Dipen Patel <[email protected]> wrote:

> This patch series introduces new subsystem called hardware timestamping
> engine (HTE). It offers functionality such as timestamping through hardware
> means in realtime. The HTE subsystem centralizes HTE provider and consumers
> where providers can register themselves and the consumers can request
> interested entity which could be lines, GPIO, signals or buses. The
> HTE subsystem provides timestamp in nano seconds, having said that the provider
> need to convert the timestamp if its not in that unit. There was upstream
> discussion about the HTE at
> https://lore.kernel.org/lkml/[email protected]/

I like this.

Can you put it in a public git and make it eligible for Stephen Rothwell to
pull into linux-next and ask him to do so, as we intend to merge this for
v5.19?

Yours,
Linus Walleij

2022-04-22 23:47:17

by Dipen Patel

[permalink] [raw]
Subject: Re: [PATCH v5 00/11] Intro to Hardware timestamping engine

Hi Linus,

Thanks for the feedback. I have just sent v6 version reflecting review comments in dt binding.

I have also added some init APIs in hte core and moved few codes around. It does not change

much from the consumer point of view.

On 4/19/22 3:46 PM, Linus Walleij wrote:
> On Tue, Mar 29, 2022 at 7:45 AM Dipen Patel <[email protected]> wrote:
>
>> This patch series introduces new subsystem called hardware timestamping
>> engine (HTE). It offers functionality such as timestamping through hardware
>> means in realtime. The HTE subsystem centralizes HTE provider and consumers
>> where providers can register themselves and the consumers can request
>> interested entity which could be lines, GPIO, signals or buses. The
>> HTE subsystem provides timestamp in nano seconds, having said that the provider
>> need to convert the timestamp if its not in that unit. There was upstream
>> discussion about the HTE at
>> https://lore.kernel.org/lkml/[email protected]/
> I like this.
>
> Can you put it in a public git and make it eligible for Stephen Rothwell to
> pull into linux-next and ask him to do so, as we intend to merge this for
> v5.19?
>
> Yours,
> Linus Walleij