From: Greg KH <greg@kroah.com>
To: Rodolfo Giometti <giometti@enneenne.com>
Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
Andrew Morton <akpm@linux-foundation.org>,
corbet@lwn.net, Hall Christopher S <christopher.s.hall@intel.com>,
Mohan Subramanian <subramanian.mohan@intel.com>,
tglx@linutronix.de, andriy.shevchenko@linux.intel.com,
Dong Eddie <eddie.dong@intel.com>,
N Pandith <pandith.n@intel.com>,
T R Thejesh Reddy <thejesh.reddy.t.r@intel.com>,
Zage David <david.zage@intel.com>,
Chinnadurai Srinivasan <srinivasan.chinnadurai@intel.com>
Subject: Re: [RFC 1/3] drivers pps: add PPS generators support
Date: Tue, 8 Oct 2024 17:42:46 +0200 [thread overview]
Message-ID: <2024100855-unsecured-mammogram-001a@gregkh> (raw)
In-Reply-To: <20241008135033.3171915-2-giometti@enneenne.com>
On Tue, Oct 08, 2024 at 03:50:31PM +0200, Rodolfo Giometti wrote:
> Sometimes one needs to be able not only to catch PPS signals but to
> produce them also. For example, running a distributed simulation,
> which requires computers' clock to be synchronized very tightly.
>
> This patch adds PPS generators class in order to have a well-defined
> interface for these devices.
>
> Signed-off-by: Rodolfo Giometti <giometti@enneenne.com>
Some minor comments on the design:
> ---
> drivers/pps/Makefile | 3 +-
> drivers/pps/generators/Kconfig | 19 +-
> drivers/pps/generators/Makefile | 4 +
> drivers/pps/generators/pps_gen-dummy.c | 83 ++++++++
> drivers/pps/generators/pps_gen.c | 283 +++++++++++++++++++++++++
> drivers/pps/generators/sysfs.c | 89 ++++++++
> include/linux/pps_gen_kernel.h | 57 +++++
> include/uapi/linux/pps_gen.h | 35 +++
> 8 files changed, 571 insertions(+), 2 deletions(-)
> create mode 100644 drivers/pps/generators/pps_gen-dummy.c
> create mode 100644 drivers/pps/generators/pps_gen.c
> create mode 100644 drivers/pps/generators/sysfs.c
> create mode 100644 include/linux/pps_gen_kernel.h
> create mode 100644 include/uapi/linux/pps_gen.h
>
> diff --git a/drivers/pps/Makefile b/drivers/pps/Makefile
> index ceaf65cc1f1d..0aea394d4e4d 100644
> --- a/drivers/pps/Makefile
> +++ b/drivers/pps/Makefile
> @@ -6,6 +6,7 @@
> pps_core-y := pps.o kapi.o sysfs.o
> pps_core-$(CONFIG_NTP_PPS) += kc.o
> obj-$(CONFIG_PPS) := pps_core.o
> -obj-y += clients/ generators/
> +obj-y += clients/
> +obj-$(CONFIG_PPS_GENERATOR) += generators/
>
> ccflags-$(CONFIG_PPS_DEBUG) := -DDEBUG
> diff --git a/drivers/pps/generators/Kconfig b/drivers/pps/generators/Kconfig
> index d615e640fcad..e3dfe31609ba 100644
> --- a/drivers/pps/generators/Kconfig
> +++ b/drivers/pps/generators/Kconfig
> @@ -3,7 +3,22 @@
> # PPS generators configuration
> #
>
> -comment "PPS generators support"
> +menuconfig PPS_GENERATOR
> + tristate "PPS generators support"
> + help
> + PPS generators are special hardware which are able to produce PPS
> + (Pulse Per Second) signals.
> +
> +if PPS_GENERATOR
> +
> +config PPS_GENERATOR_DUMMY
> + tristate "Dummy PPS generator (Testing generator, use for debug)"
> + help
> + If you say yes here you get support for a PPS debugging generator
> + (which actual generates no PPS signal at all).
> +
> + This driver can also be built as a module. If so, the module
> + will be called pps_gen-dummy.
Put the dummy driver in a separate patch please, it doesn't belong with
the core changes.
>
> config PPS_GENERATOR_PARPORT
> tristate "Parallel port PPS signal generator"
> @@ -12,3 +27,5 @@ config PPS_GENERATOR_PARPORT
> If you say yes here you get support for a PPS signal generator which
> utilizes STROBE pin of a parallel port to send PPS signals. It uses
> parport abstraction layer and hrtimers to precisely control the signal.
> +
> +endif # PPS_GENERATOR
> diff --git a/drivers/pps/generators/Makefile b/drivers/pps/generators/Makefile
> index 2589fd0f2481..dc1aa5a4688b 100644
> --- a/drivers/pps/generators/Makefile
> +++ b/drivers/pps/generators/Makefile
> @@ -3,6 +3,10 @@
> # Makefile for PPS generators.
> #
>
> +pps_gen_core-y := pps_gen.o sysfs.o
> +obj-$(CONFIG_PPS_GENERATOR) := pps_gen_core.o
> +
> +obj-$(CONFIG_PPS_GENERATOR_DUMMY) += pps_gen-dummy.o
> obj-$(CONFIG_PPS_GENERATOR_PARPORT) += pps_gen_parport.o
>
> ccflags-$(CONFIG_PPS_DEBUG) := -DDEBUG
> diff --git a/drivers/pps/generators/pps_gen-dummy.c b/drivers/pps/generators/pps_gen-dummy.c
> new file mode 100644
> index 000000000000..2d257f3f9bf9
> --- /dev/null
> +++ b/drivers/pps/generators/pps_gen-dummy.c
> @@ -0,0 +1,83 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * PPS dummy generator
> + *
> + * Copyright (C) 2024 Rodolfo Giometti <giometti@enneenne.com>
Why so many spaces after "2024"?
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
Why is this needed, drivers should only ever use dev_*() calls, never
pr_*() calls.
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/time.h>
> +#include <linux/pps_gen_kernel.h>
> +
> +/*
> + * Global variables
> + */
> +
> +static struct pps_gen_device *pps_gen;
That's by definition, static, not global :)
Also, why is it needed at all?
> +
> +/*
> + * PPS Generator methods
> + */
> +
> +static int pps_gen_dummy_get_time(struct pps_gen_device *pps_gen,
> + struct timespec64 *time)
> +{
> + struct system_time_snapshot snap;
> +
> + ktime_get_snapshot(&snap);
> + *time = ktime_to_timespec64(snap.real);
> +
> + return 0;
> +}
> +
> +static int pps_gen_dummy_enable(struct pps_gen_device *pps_gen, bool enable)
> +{
> + /* always enabled */
> + return 0;
> +}
> +
> +/*
> + * The PPS info struct
> + */
> +
> +static struct pps_gen_source_info pps_gen_dummy_info = {
> + .name = "dummy",
> + .use_system_clock = true,
> + .get_time = pps_gen_dummy_get_time,
> + .enable = pps_gen_dummy_enable,
> +};
> +
> +/*
> + * Module staff
> + */
> +
> +static void __exit pps_gen_dummy_exit(void)
> +{
> + dev_info(pps_gen->dev, "dummy PPS generator unregistered\n");
When drivers are working properly, they are quiet.
> +
> + pps_gen_unregister_source(pps_gen);
> +}
> +
> +static int __init pps_gen_dummy_init(void)
> +{
> + pps_gen = pps_gen_register_source(&pps_gen_dummy_info);
> + if (IS_ERR(pps_gen)) {
> + pr_err("cannot register PPS generator\n");
> + return PTR_ERR(pps_gen);
> + }
> +
> + dev_info(pps_gen->dev, "dummy PPS generator registered\n");
Again, quiet...
> +
> + return 0;
> +}
> +
> +module_init(pps_gen_dummy_init);
> +module_exit(pps_gen_dummy_exit);
> +
> +MODULE_AUTHOR("Rodolfo Giometti <giometti@enneenne.com>");
> +MODULE_DESCRIPTION("LinuxPPS dummy generator");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/pps/generators/pps_gen.c b/drivers/pps/generators/pps_gen.c
> new file mode 100644
> index 000000000000..40b05087b4b4
> --- /dev/null
> +++ b/drivers/pps/generators/pps_gen.c
> @@ -0,0 +1,283 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * PPS generators core file
> + *
> + * Copyright (C) 2024 Rodolfo Giometti <giometti@enneenne.com>
Again spaces.
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
Again, not needed.
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/sched.h>
> +#include <linux/time.h>
> +#include <linux/timex.h>
> +#include <linux/uaccess.h>
> +#include <linux/idr.h>
> +#include <linux/mutex.h>
> +#include <linux/cdev.h>
Why a cdev?
> +#include <linux/fs.h>
> +#include <linux/pps_gen_kernel.h>
> +#include <linux/slab.h>
> +
> +/*
> + * Local variables
> + */
> +
> +static int pps_gen_major;
> +static struct class *pps_gen_class;
> +
> +static DEFINE_MUTEX(pps_gen_idr_lock);
> +static DEFINE_IDR(pps_gen_idr);
> +
> +/*
> + * Char device methods
> + */
> +
> +static long pps_gen_cdev_ioctl(struct file *file,
> + unsigned int cmd, unsigned long arg)
> +{
> + struct pps_gen_device *pps_gen = file->private_data;
> + unsigned int __user *uiuarg = (unsigned int __user *) arg;
> + unsigned int status;
> + int ret;
> +
> + switch (cmd) {
> + case PPS_GEN_SETENABLE:
> + dev_dbg(pps_gen->dev, "PPS_GEN_SETENABLE\n");
> +
> + ret = get_user(status, uiuarg);
> + if (ret)
> + return -EFAULT;
> +
> + ret = pps_gen->info.enable(pps_gen, status);
> + if (ret)
> + return ret;
> + pps_gen->enabled = status;
> +
> + break;
> +
> + default:
> + return -ENOTTY;
> + }
> +
> + return 0;
> +}
Why is there an ioctl call? That's a totally different user/kernel api
than sysfs, why do you have 2?
> +
> +#ifdef CONFIG_COMPAT
> +static long pps_gen_cdev_compat_ioctl(struct file *file,
> + unsigned int cmd, unsigned long arg)
> +{
> + cmd = _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(void *));
> + return pps_gen_cdev_ioctl(file, cmd, arg);
> +}
> +#else
> +#define pps_gen_cdev_compat_ioctl NULL
> +#endif
> +
> +static struct pps_gen_device *pps_gen_idr_get(unsigned long id)
> +{
> + struct pps_gen_device *pps_gen;
> +
> + mutex_lock(&pps_gen_idr_lock);
> + pps_gen = idr_find(&pps_gen_idr, id);
> + if (pps_gen)
> + kobject_get(&pps_gen->dev->kobj);
> +
> + mutex_unlock(&pps_gen_idr_lock);
Doesn't an idr have a lock in it? I can never remember...
> + return pps_gen;
> +}
> +
> +static int pps_gen_cdev_open(struct inode *inode, struct file *file)
> +{
> + struct pps_gen_device *pps_gen = pps_gen_idr_get(iminor(inode));
> +
> + if (!pps_gen)
> + return -ENODEV;
> +
> + file->private_data = pps_gen;
> + return 0;
> +}
> +
> +static int pps_gen_cdev_release(struct inode *inode, struct file *file)
> +{
> + struct pps_gen_device *pps_gen = file->private_data;
> +
> + WARN_ON(pps_gen->id != iminor(inode));
If this can never happen, don't add this line. If it can happen, then
handle it properly. Either way, don't reboot a box because it happened.
> + kobject_put(&pps_gen->dev->kobj);
Messing with a kobject reference directly from a device feels wrong and
should never be done. Please use the proper apis.
> + return 0;
> +}
> +
> +/*
> + * Char device stuff
> + */
> +
> +static const struct file_operations pps_gen_cdev_fops = {
> + .owner = THIS_MODULE,
> + .compat_ioctl = pps_gen_cdev_compat_ioctl,
Why compat for a new ioctl? Why not write it properly to not need it?
> + .unlocked_ioctl = pps_gen_cdev_ioctl,
> + .open = pps_gen_cdev_open,
> + .release = pps_gen_cdev_release,
> +};
> +
> +static void pps_gen_device_destruct(struct device *dev)
> +{
> + struct pps_gen_device *pps_gen = dev_get_drvdata(dev);
> +
> + pr_debug("deallocating pps-gen%d\n", pps_gen->id);
ftrace is your friend.
> + kfree(dev);
> + kfree(pps_gen);
> +}
> +
> +static int pps_gen_register_cdev(struct pps_gen_device *pps_gen)
> +{
> + int err;
> + dev_t devt;
> +
> + mutex_lock(&pps_gen_idr_lock);
> +
> + err = idr_alloc(&pps_gen_idr, pps_gen, 0, PPS_GEN_MAX_SOURCES,
> + GFP_KERNEL);
> + if (err < 0) {
> + if (err == -ENOSPC) {
> + pr_err("%s: too many PPS sources in the system\n",
> + pps_gen->info.name);
> + err = -EBUSY;
> + }
> + goto out_unlock;
> + }
> + pps_gen->id = err;
> +
> + devt = MKDEV(pps_gen_major, pps_gen->id);
> + pps_gen->dev = device_create(pps_gen_class, pps_gen->info.parent, devt,
> + pps_gen, "pps-gen%d", pps_gen->id);
> + if (IS_ERR(pps_gen->dev)) {
> + err = PTR_ERR(pps_gen->dev);
> + goto free_idr;
> + }
> +
> + /* Override the release function with our own */
> + pps_gen->dev->release = pps_gen_device_destruct;
> +
> + pr_debug("generator %s got cdev (%d:%d)\n",
> + pps_gen->info.name, pps_gen_major, pps_gen->id);
Why not dev_dbg()?
> +
> + kobject_get(&pps_gen->dev->kobj);
> + mutex_unlock(&pps_gen_idr_lock);
> + return 0;
> +
> +free_idr:
> + idr_remove(&pps_gen_idr, pps_gen->id);
> +out_unlock:
> + mutex_unlock(&pps_gen_idr_lock);
> + return err;
> +}
> +
> +static void pps_gen_unregister_cdev(struct pps_gen_device *pps_gen)
> +{
> + pr_debug("unregistering pps-gen%d\n", pps_gen->id);
> + device_destroy(pps_gen_class, pps_gen->dev->devt);
> +
> + /* Now we can release the ID for re-use */
> + mutex_lock(&pps_gen_idr_lock);
> + idr_remove(&pps_gen_idr, pps_gen->id);
> + kobject_put(&pps_gen->dev->kobj);
> + mutex_unlock(&pps_gen_idr_lock);
> +}
> +
> +/*
> + * Exported functions
> + */
> +
> +/* pps_gen_register_source - add a PPS generator in the system
> + * @info: the PPS generator info struct
> + *
> + * The function returns, in case of success, the PPS generaor device. Otherwise
> + * ERR_PTR(errno).
> + */
> +
> +struct pps_gen_device *pps_gen_register_source(struct pps_gen_source_info *info)
> +{
> + struct pps_gen_device *pps_gen;
> + int err;
> +
> + pps_gen = kzalloc(sizeof(struct pps_gen_device), GFP_KERNEL);
> + if (pps_gen == NULL) {
> + err = -ENOMEM;
> + goto pps_gen_register_source_exit;
> + }
> + pps_gen->info = *info;
> + pps_gen->enabled = false;
Whitespace is all messed up here, did you run checkpatch?
> +
> + /* Create the char device */
> + err = pps_gen_register_cdev(pps_gen);
> + if (err < 0) {
> + pr_err("%s: unable to create char device\n",
> + info->name);
> + goto kfree_pps_gen;
> + }
> +
> + dev_info(pps_gen->dev, "new PPS generator %s\n", info->name);
Again, quiet...
> +
> + return pps_gen;
> +
> +kfree_pps_gen:
> + kfree(pps_gen);
> +
> +pps_gen_register_source_exit:
> + pr_err("%s: unable to register generaor\n", info->name);
dev_err()?
> +
> + return ERR_PTR(err);
> +}
> +EXPORT_SYMBOL(pps_gen_register_source);
I have to ask, why not EXPORT_SYMBOL_GPL()?
> +
> +/* pps_gen_unregister_source - remove a PPS generator from the system
> + * @pps_gen: the PPS generator
> + */
> +
> +void pps_gen_unregister_source(struct pps_gen_device *pps_gen)
> +{
> + pps_gen_unregister_cdev(pps_gen);
> +}
> +EXPORT_SYMBOL(pps_gen_unregister_source);
> +
> +/*
> + * Module stuff
> + */
> +
> +static void __exit pps_gen_exit(void)
> +{
> + class_destroy(pps_gen_class);
> + __unregister_chrdev(pps_gen_major, 0, PPS_GEN_MAX_SOURCES, "pps-gen");
Why the __ version? Are you sure?
> +}
> +
> +static int __init pps_gen_init(void)
> +{
> + pps_gen_class = class_create("pps-gen");
> + if (IS_ERR(pps_gen_class)) {
> + pr_err("failed to allocate class\n");
> + return PTR_ERR(pps_gen_class);
> + }
> + pps_gen_class->dev_groups = pps_gen_groups;
> +
> + pps_gen_major = __register_chrdev(0, 0, PPS_GEN_MAX_SOURCES, "pps-gen",
> + &pps_gen_cdev_fops);
Again, why __?
> + if (pps_gen_major < 0) {
> + pr_err("failed to allocate char device region\n");
> + goto remove_class;
> + }
> +
> + return 0;
> +
> +remove_class:
> + class_destroy(pps_gen_class);
> + return pps_gen_major;
> +}
> +
> +subsys_initcall(pps_gen_init);
> +module_exit(pps_gen_exit);
> +
> +MODULE_AUTHOR("Rodolfo Giometti <giometti@enneenne.com>");
> +MODULE_DESCRIPTION("LinuxPPS generators support");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/pps/generators/sysfs.c b/drivers/pps/generators/sysfs.c
> new file mode 100644
> index 000000000000..247030d138e1
> --- /dev/null
> +++ b/drivers/pps/generators/sysfs.c
> @@ -0,0 +1,89 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * PPS generators sysfs support
> + *
> + * Copyright (C) 2024 Rodolfo Giometti <giometti@enneenne.com>
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
again...
> +
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/string.h>
> +#include <linux/pps_gen_kernel.h>
> +
> +/*
> + * Attribute functions
> + */
> +
> +static ssize_t system_show(struct device *dev, struct device_attribute *attr,
> + char *buf)
> +{
> + struct pps_gen_device *pps_gen = dev_get_drvdata(dev);
Again whitespace...
> +
> + return sysfs_emit(buf, "%d\n", pps_gen->info.use_system_clock);
> +}
> +static DEVICE_ATTR_RO(system);
> +
> +static ssize_t time_show(struct device *dev, struct device_attribute *attr,
> + char *buf)
> +{
> + struct pps_gen_device *pps_gen = dev_get_drvdata(dev);
> + struct timespec64 time;
> + int ret;
> +
> + ret = pps_gen->info.get_time(pps_gen, &time);
> + if (ret)
> + return ret;
> +
> + return sysfs_emit(buf, "%llu %09lu\n", time.tv_sec, time.tv_nsec);
> +}
> +static DEVICE_ATTR_RO(time);
> +
> +static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct pps_gen_device *pps_gen = dev_get_drvdata(dev);
> + bool status;
> + unsigned int enable;
> + int ret;
> +
> + ret = sscanf(buf, "%u", &enable);
> + if (ret != 1)
> + return -EINVAL;
> + status = !!enable;
> +
> + ret = pps_gen->info.enable(pps_gen, status);
> + if (ret)
> + return ret;
> + pps_gen->enabled = status;
> +
> + return count;
> +}
> +static DEVICE_ATTR_WO(enable);
> +
> +static ssize_t name_show(struct device *dev, struct device_attribute *attr,
> + char *buf)
> +{
> + struct pps_gen_device *pps_gen = dev_get_drvdata(dev);
> +
> + return sysfs_emit(buf, "%s\n", pps_gen->info.name);
Why have a separate name? That shouldn't matter at all. If it does
matter, than link to the device that created it properly, don't make up
yet another name for your device.
> +}
> +static DEVICE_ATTR_RO(name);
> +
> +static struct attribute *pps_gen_attrs[] = {
> + &dev_attr_enable.attr,
> + &dev_attr_name.attr,
> + &dev_attr_time.attr,
> + &dev_attr_system.attr,
> + NULL,
> +};
> +
> +static const struct attribute_group pps_gen_group = {
> + .attrs = pps_gen_attrs,
> +};
> +
> +const struct attribute_group *pps_gen_groups[] = {
> + &pps_gen_group,
> + NULL,
> +};
> diff --git a/include/linux/pps_gen_kernel.h b/include/linux/pps_gen_kernel.h
> new file mode 100644
> index 000000000000..5513415b53ec
> --- /dev/null
> +++ b/include/linux/pps_gen_kernel.h
> @@ -0,0 +1,57 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * PPS generator API kernel header
> + *
> + * Copyright (C) 2024 Rodolfo Giometti <giometti@enneenne.com>
> + */
> +
> +#ifndef LINUX_PPS_GEN_KERNEL_H
> +#define LINUX_PPS_GEN_KERNEL_H
> +
> +#include <linux/pps_gen.h>
> +#include <linux/cdev.h>
> +#include <linux/device.h>
> +
> +/*
> + * Global defines
> + */
> +
> +struct pps_gen_device;
> +
> +/* The specific PPS source info */
> +struct pps_gen_source_info {
> + char name[PPS_GEN_MAX_NAME_LEN]; /* symbolic name */
> + bool use_system_clock;
> +
> + int (*get_time)(struct pps_gen_device *pps_gen,
> + struct timespec64 *time);
> + int (*enable)(struct pps_gen_device *pps_gen, bool enable);
> +
> + struct module *owner;
> + struct device *parent; /* for device_create */
> +};
> +
> +/* The main struct */
> +struct pps_gen_device {
> + struct pps_gen_source_info info; /* PSS generator info */
> + bool enabled; /* PSS generator status */
> +
> + unsigned int id; /* PPS generator unique ID */
> + struct device *dev;
Why not be a real device? What is this a pointer to?
> +};
This structure can be private, right?
> +
> +/*
> + * Global variables
> + */
> +
> +extern const struct attribute_group *pps_gen_groups[];
Why is this global?
> +
> +/*
> + * Exported functions
> + */
> +
> +extern struct pps_gen_device *pps_gen_register_source(
> + struct pps_gen_source_info *info);
> +extern void pps_gen_unregister_source(struct pps_gen_device *pps_gen);
> +
> +#endif /* LINUX_PPS_GEN_KERNEL_H */
> diff --git a/include/uapi/linux/pps_gen.h b/include/uapi/linux/pps_gen.h
> new file mode 100644
> index 000000000000..7b6f50fcab8c
> --- /dev/null
> +++ b/include/uapi/linux/pps_gen.h
> @@ -0,0 +1,35 @@
> +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
I have to ask, why "GPL-2.0+"?
> +/*
> + * PPS generator API header
> + *
> + * Copyright (C) 2024 Rodolfo Giometti <giometti@enneenne.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
License boilerplate should be removed.
> + */
> +
> +
> +#ifndef _PPS_GEN_H_
> +#define _PPS_GEN_H_
> +
> +#include <linux/types.h>
> +
> +#define PPS_GEN_MAX_SOURCES 16 /* should be enough... */
What is this for? Who is using it in userspace?
> +#define PPS_GEN_MAX_NAME_LEN 32
Why is this exported to userspace?
> +
> +#include <linux/ioctl.h>
> +
> +#define PPS_GEN_SETENABLE _IOW('g', 0xa1, unsigned int *)
Documentation for this new ioctl?
thanks,
greg k-h
next prev parent reply other threads:[~2024-10-08 15:42 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-08 13:50 [RFC 0/3] Add PPS generators Rodolfo Giometti
2024-10-08 13:50 ` [RFC 1/3] drivers pps: add PPS generators support Rodolfo Giometti
2024-10-08 15:42 ` Greg KH [this message]
2024-10-09 8:48 ` Rodolfo Giometti
2024-10-09 9:19 ` Greg KH
2024-10-10 7:25 ` Rodolfo Giometti
2024-10-10 7:15 ` Greg KH
2024-10-10 7:32 ` Rodolfo Giometti
2024-10-10 7:54 ` Greg KH
2024-10-10 9:53 ` Rodolfo Giometti
2024-10-10 10:04 ` Greg KH
2024-10-10 10:18 ` Rodolfo Giometti
2024-10-09 2:49 ` Hall, Christopher S
2024-10-09 8:48 ` Rodolfo Giometti
2024-10-08 13:50 ` [RFC 2/3] Documentation pps.rst: add PPS generators documentation Rodolfo Giometti
2024-10-08 15:43 ` Greg KH
2024-10-09 8:48 ` Rodolfo Giometti
2024-10-09 9:14 ` Greg KH
2024-10-10 7:26 ` Rodolfo Giometti
2024-10-08 13:50 ` [RFC 3/3] Documentation ABI: add PPS generators documentaion Rodolfo Giometti
2024-10-08 15:43 ` Greg KH
2024-10-09 8:48 ` Rodolfo Giometti
2024-10-09 9:15 ` Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2024100855-unsecured-mammogram-001a@gregkh \
--to=greg@kroah.com \
--cc=akpm@linux-foundation.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=christopher.s.hall@intel.com \
--cc=corbet@lwn.net \
--cc=david.zage@intel.com \
--cc=eddie.dong@intel.com \
--cc=giometti@enneenne.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pandith.n@intel.com \
--cc=srinivasan.chinnadurai@intel.com \
--cc=subramanian.mohan@intel.com \
--cc=tglx@linutronix.de \
--cc=thejesh.reddy.t.r@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.