// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * PPS core file
 *
 * Copyright (C) 2005-2009   Rodolfo Giometti <giometti@linux.it>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/idr.h>
#include <linux/mutex.h>
#include <linux/cdev.h>
#include <linux/poll.h>
#include <linux/pps_kernel.h>
#include <linux/slab.h>

#include "kc.h"

/*
 * Local variables
 */

static dev_t pps_devt;
static struct class *pps_class;

static DEFINE_MUTEX(pps_idr_lock);
static DEFINE_IDR(pps_idr);

/*
 * Char device methods
 */

static __poll_t pps_cdev_poll(struct file *file, poll_table *wait)
{
	struct pps_device *pps = file->private_data;

	poll_wait(file, &pps->queue, wait);

	return EPOLLIN | EPOLLRDNORM;
}

static int pps_cdev_fasync(int fd, struct file *file, int on)
{
	struct pps_device *pps = file->private_data;
	return fasync_helper(fd, file, on, &pps->async_queue);
}

static int pps_cdev_pps_fetch(struct pps_device *pps, struct pps_fdata *fdata)
{
	unsigned int ev = pps->last_ev;
	int err = 0;

	/* Manage the timeout */
	if (fdata->timeout.flags & PPS_TIME_INVALID)
		err = wait_event_interruptible(pps->queue,
				ev != pps->last_ev);
	else {
		unsigned long ticks;

		dev_dbg(pps->dev, "timeout %lld.%09d\n",
				(long long) fdata->timeout.sec,
				fdata->timeout.nsec);
		ticks = fdata->timeout.sec * HZ;
		ticks += fdata->timeout.nsec / (NSEC_PER_SEC / HZ);

		if (ticks != 0) {
			err = wait_event_interruptible_timeout(
					pps->queue,
					ev != pps->last_ev,
					ticks);
			if (err == 0)
				return -ETIMEDOUT;
		}
	}

	/* Check for pending signals */
	if (err == -ERESTARTSYS) {
		dev_dbg(pps->dev, "pending signal caught\n");
		return -EINTR;
	}

	return 0;
}

static long pps_cdev_ioctl(struct file *file,
		unsigned int cmd, unsigned long arg)
{
	struct pps_device *pps = file->private_data;
	struct pps_kparams params;
	void __user *uarg = (void __user *) arg;
	int __user *iuarg = (int __user *) arg;
	int err;

	switch (cmd) {
	case PPS_GETPARAMS:
		dev_dbg(pps->dev, "PPS_GETPARAMS\n");

		spin_lock_irq(&pps->lock);

		/* Get the current parameters */
		params = pps->params;

		spin_unlock_irq(&pps->lock);

		err = copy_to_user(uarg, &params, sizeof(struct pps_kparams));
		if (err)
			return -EFAULT;

		break;

	case PPS_SETPARAMS:
		dev_dbg(pps->dev, "PPS_SETPARAMS\n");

		/* Check the capabilities */
		if (!capable(CAP_SYS_TIME))
			return -EPERM;

		err = copy_from_user(&params, uarg, sizeof(struct pps_kparams));
		if (err)
			return -EFAULT;
		if (!(params.mode & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR))) {
			dev_dbg(pps->dev, "capture mode unspecified (%x)\n",
								params.mode);
			return -EINVAL;
		}

		/* Check for supported capabilities */
		if ((params.mode & ~pps->info.mode) != 0) {
			dev_dbg(pps->dev, "unsupported capabilities (%x)\n",
								params.mode);
			return -EINVAL;
		}

		spin_lock_irq(&pps->lock);

		/* Save the new parameters */
		pps->params = params;

		/* Restore the read only parameters */
		if ((params.mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) {
			/* section 3.3 of RFC 2783 interpreted */
			dev_dbg(pps->dev, "time format unspecified (%x)\n",
								params.mode);
			pps->params.mode |= PPS_TSFMT_TSPEC;
		}
		if (pps->info.mode & PPS_CANWAIT)
			pps->params.mode |= PPS_CANWAIT;
		pps->params.api_version = PPS_API_VERS;

		spin_unlock_irq(&pps->lock);

		break;

	case PPS_GETCAP:
		dev_dbg(pps->dev, "PPS_GETCAP\n");

		err = put_user(pps->info.mode, iuarg);
		if (err)
			return -EFAULT;

		break;

	case PPS_FETCH: {
		struct pps_fdata fdata;

		dev_dbg(pps->dev, "PPS_FETCH\n");

		err = copy_from_user(&fdata, uarg, sizeof(struct pps_fdata));
		if (err)
			return -EFAULT;

		err = pps_cdev_pps_fetch(pps, &fdata);
		if (err)
			return err;

		/* Return the fetched timestamp */
		spin_lock_irq(&pps->lock);

		fdata.info.assert_sequence = pps->assert_sequence;
		fdata.info.clear_sequence = pps->clear_sequence;
		fdata.info.assert_tu = pps->assert_tu;
		fdata.info.clear_tu = pps->clear_tu;
		fdata.info.current_mode = pps->current_mode;

		spin_unlock_irq(&pps->lock);

		err = copy_to_user(uarg, &fdata, sizeof(struct pps_fdata));
		if (err)
			return -EFAULT;

		break;
	}
	case PPS_KC_BIND: {
		struct pps_bind_args bind_args;

		dev_dbg(pps->dev, "PPS_KC_BIND\n");

		/* Check the capabilities */
		if (!capable(CAP_SYS_TIME))
			return -EPERM;

		if (copy_from_user(&bind_args, uarg,
					sizeof(struct pps_bind_args)))
			return -EFAULT;

		/* Check for supported capabilities */
		if ((bind_args.edge & ~pps->info.mode) != 0) {
			dev_err(pps->dev, "unsupported capabilities (%x)\n",
					bind_args.edge);
			return -EINVAL;
		}

		/* Validate parameters roughly */
		if (bind_args.tsformat != PPS_TSFMT_TSPEC ||
				(bind_args.edge & ~PPS_CAPTUREBOTH) != 0 ||
				bind_args.consumer != PPS_KC_HARDPPS) {
			dev_err(pps->dev, "invalid kernel consumer bind"
					" parameters (%x)\n", bind_args.edge);
			return -EINVAL;
		}

		err = pps_kc_bind(pps, &bind_args);
		if (err < 0)
			return err;

		break;
	}
	default:
		return -ENOTTY;
	}

	return 0;
}

#ifdef CONFIG_COMPAT
static long pps_cdev_compat_ioctl(struct file *file,
		unsigned int cmd, unsigned long arg)
{
	struct pps_device *pps = file->private_data;
	void __user *uarg = (void __user *) arg;

	cmd = _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(void *));

	if (cmd == PPS_FETCH) {
		struct pps_fdata_compat compat;
		struct pps_fdata fdata;
		int err;

		dev_dbg(pps->dev, "PPS_FETCH\n");

		err = copy_from_user(&compat, uarg, sizeof(struct pps_fdata_compat));
		if (err)
			return -EFAULT;

		memcpy(&fdata.timeout, &compat.timeout,
					sizeof(struct pps_ktime_compat));

		err = pps_cdev_pps_fetch(pps, &fdata);
		if (err)
			return err;

		/* Return the fetched timestamp */
		spin_lock_irq(&pps->lock);

		compat.info.assert_sequence = pps->assert_sequence;
		compat.info.clear_sequence = pps->clear_sequence;
		compat.info.current_mode = pps->current_mode;

		memcpy(&compat.info.assert_tu, &pps->assert_tu,
				sizeof(struct pps_ktime_compat));
		memcpy(&compat.info.clear_tu, &pps->clear_tu,
				sizeof(struct pps_ktime_compat));

		spin_unlock_irq(&pps->lock);

		return copy_to_user(uarg, &compat,
				sizeof(struct pps_fdata_compat)) ? -EFAULT : 0;
	}

	return pps_cdev_ioctl(file, cmd, arg);
}
#else
#define pps_cdev_compat_ioctl	NULL
#endif

static int pps_cdev_open(struct inode *inode, struct file *file)
{
	struct pps_device *pps = container_of(inode->i_cdev,
						struct pps_device, cdev);
	file->private_data = pps;
	kobject_get(&pps->dev->kobj);
	return 0;
}

static int pps_cdev_release(struct inode *inode, struct file *file)
{
	struct pps_device *pps = container_of(inode->i_cdev,
						struct pps_device, cdev);
	kobject_put(&pps->dev->kobj);
	return 0;
}

/*
 * Char device stuff
 */

static const struct file_operations pps_cdev_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.poll		= pps_cdev_poll,
	.fasync		= pps_cdev_fasync,
	.compat_ioctl	= pps_cdev_compat_ioctl,
	.unlocked_ioctl	= pps_cdev_ioctl,
	.open		= pps_cdev_open,
	.release	= pps_cdev_release,
};

static void pps_device_destruct(struct device *dev)
{
	struct pps_device *pps = dev_get_drvdata(dev);

	cdev_del(&pps->cdev);

	/* Now we can release the ID for re-use */
	pr_debug("deallocating pps%d\n", pps->id);
	mutex_lock(&pps_idr_lock);
	idr_remove(&pps_idr, pps->id);
	mutex_unlock(&pps_idr_lock);

	kfree(dev);
	kfree(pps);
}

int pps_register_cdev(struct pps_device *pps)
{
	int err;
	dev_t devt;

	mutex_lock(&pps_idr_lock);
	/*
	 * Get new ID for the new PPS source.  After idr_alloc() calling
	 * the new source will be freely available into the kernel.
	 */
	err = idr_alloc(&pps_idr, pps, 0, PPS_MAX_SOURCES, GFP_KERNEL);
	if (err < 0) {
		if (err == -ENOSPC) {
			pr_err("%s: too many PPS sources in the system\n",
			       pps->info.name);
			err = -EBUSY;
		}
		goto out_unlock;
	}
	pps->id = err;
	mutex_unlock(&pps_idr_lock);

	devt = MKDEV(MAJOR(pps_devt), pps->id);

	cdev_init(&pps->cdev, &pps_cdev_fops);
	pps->cdev.owner = pps->info.owner;

	err = cdev_add(&pps->cdev, devt, 1);
	if (err) {
		pr_err("%s: failed to add char device %d:%d\n",
				pps->info.name, MAJOR(pps_devt), pps->id);
		goto free_idr;
	}
	pps->dev = device_create(pps_class, pps->info.dev, devt, pps,
							"pps%d", pps->id);
	if (IS_ERR(pps->dev)) {
		err = PTR_ERR(pps->dev);
		goto del_cdev;
	}

	/* Override the release function with our own */
	pps->dev->release = pps_device_destruct;

	pr_debug("source %s got cdev (%d:%d)\n", pps->info.name,
			MAJOR(pps_devt), pps->id);

	return 0;

del_cdev:
	cdev_del(&pps->cdev);

free_idr:
	mutex_lock(&pps_idr_lock);
	idr_remove(&pps_idr, pps->id);
out_unlock:
	mutex_unlock(&pps_idr_lock);
	return err;
}

void pps_unregister_cdev(struct pps_device *pps)
{
	pr_debug("unregistering pps%d\n", pps->id);
	pps->lookup_cookie = NULL;
	device_destroy(pps_class, pps->dev->devt);
}

/*
 * Look up a pps device by magic cookie.
 * The cookie is usually a pointer to some enclosing device, but this
 * code doesn't care; you should never be dereferencing it.
 *
 * This is a bit of a kludge that is currently used only by the PPS
 * serial line discipline.  It may need to be tweaked when a second user
 * is found.
 *
 * There is no function interface for setting the lookup_cookie field.
 * It's initialized to NULL when the pps device is created, and if a
 * client wants to use it, just fill it in afterward.
 *
 * The cookie is automatically set to NULL in pps_unregister_source()
 * so that it will not be used again, even if the pps device cannot
 * be removed from the idr due to pending references holding the minor
 * number in use.
 */
struct pps_device *pps_lookup_dev(void const *cookie)
{
	struct pps_device *pps;
	unsigned id;

	rcu_read_lock();
	idr_for_each_entry(&pps_idr, pps, id)
		if (cookie == pps->lookup_cookie)
			break;
	rcu_read_unlock();
	return pps;
}
EXPORT_SYMBOL(pps_lookup_dev);

/*
 * Module stuff
 */

static void __exit pps_exit(void)
{
	class_destroy(pps_class);
	unregister_chrdev_region(pps_devt, PPS_MAX_SOURCES);
}

static int __init pps_init(void)
{
	int err;

	pps_class = class_create(THIS_MODULE, "pps");
	if (IS_ERR(pps_class)) {
		pr_err("failed to allocate class\n");
		return PTR_ERR(pps_class);
	}
	pps_class->dev_groups = pps_groups;

	err = alloc_chrdev_region(&pps_devt, 0, PPS_MAX_SOURCES, "pps");
	if (err < 0) {
		pr_err("failed to allocate char device region\n");
		goto remove_class;
	}

	pr_info("LinuxPPS API ver. %d registered\n", PPS_API_VERS);
	pr_info("Software ver. %s - Copyright 2005-2007 Rodolfo Giometti "
		"<giometti@linux.it>\n", PPS_VERSION);

	return 0;

remove_class:
	class_destroy(pps_class);

	return err;
}

subsys_initcall(pps_init);
module_exit(pps_exit);

MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
MODULE_DESCRIPTION("LinuxPPS support (RFC 2783) - ver. " PPS_VERSION);
MODULE_LICENSE("GPL");
