// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * PTP 1588 clock support - sysfs interface.
 *
 * Copyright (C) 2010 OMICRON electronics GmbH
 * Copyright 2021 NXP
 */
#include <linux/capability.h>
#include <linux/slab.h>

#include "ptp_private.h"

static ssize_t clock_name_show(struct device *dev,
			       struct device_attribute *attr, char *page)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	return sysfs_emit(page, "%s\n", ptp->info->name);
}
static DEVICE_ATTR_RO(clock_name);

static ssize_t max_phase_adjustment_show(struct device *dev,
					 struct device_attribute *attr,
					 char *page)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);

	return snprintf(page, PAGE_SIZE - 1, "%d\n",
			ptp->info->getmaxphase(ptp->info));
}
static DEVICE_ATTR_RO(max_phase_adjustment);

#define PTP_SHOW_INT(name, var)						\
static ssize_t var##_show(struct device *dev,				\
			   struct device_attribute *attr, char *page)	\
{									\
	struct ptp_clock *ptp = dev_get_drvdata(dev);			\
	return snprintf(page, PAGE_SIZE-1, "%d\n", ptp->info->var);	\
}									\
static DEVICE_ATTR(name, 0444, var##_show, NULL);

PTP_SHOW_INT(max_adjustment, max_adj);
PTP_SHOW_INT(n_alarms, n_alarm);
PTP_SHOW_INT(n_external_timestamps, n_ext_ts);
PTP_SHOW_INT(n_periodic_outputs, n_per_out);
PTP_SHOW_INT(n_programmable_pins, n_pins);
PTP_SHOW_INT(pps_available, pps);

static ssize_t extts_enable_store(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf, size_t count)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	struct ptp_clock_info *ops = ptp->info;
	struct ptp_clock_request req = { .type = PTP_CLK_REQ_EXTTS };
	int cnt, enable;
	int err = -EINVAL;

	cnt = sscanf(buf, "%u %d", &req.extts.index, &enable);
	if (cnt != 2)
		goto out;
	if (req.extts.index >= ops->n_ext_ts)
		goto out;

	err = ops->enable(ops, &req, enable ? 1 : 0);
	if (err)
		goto out;

	return count;
out:
	return err;
}
static DEVICE_ATTR(extts_enable, 0220, NULL, extts_enable_store);

static ssize_t extts_fifo_show(struct device *dev,
			       struct device_attribute *attr, char *page)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	struct timestamp_event_queue *queue;
	struct ptp_extts_event event;
	unsigned long flags;
	size_t qcnt;
	int cnt = 0;

	cnt = list_count_nodes(&ptp->tsevqs);
	if (cnt <= 0)
		goto out;

	/* The sysfs fifo will always draw from the fist queue */
	queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue,
				 qlist);

	memset(&event, 0, sizeof(event));
	spin_lock_irqsave(&queue->lock, flags);
	qcnt = queue_cnt(queue);
	if (qcnt) {
		event = queue->buf[queue->head];
		/* Paired with READ_ONCE() in queue_cnt() */
		WRITE_ONCE(queue->head, (queue->head + 1) % PTP_MAX_TIMESTAMPS);
	}
	spin_unlock_irqrestore(&queue->lock, flags);

	if (!qcnt)
		goto out;

	cnt = snprintf(page, PAGE_SIZE, "%u %lld %u\n",
		       event.index, event.t.sec, event.t.nsec);
out:
	return cnt;
}
static DEVICE_ATTR(fifo, 0444, extts_fifo_show, NULL);

static ssize_t period_store(struct device *dev,
			    struct device_attribute *attr,
			    const char *buf, size_t count)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	struct ptp_clock_info *ops = ptp->info;
	struct ptp_clock_request req = { .type = PTP_CLK_REQ_PEROUT };
	int cnt, enable, err = -EINVAL;

	cnt = sscanf(buf, "%u %lld %u %lld %u", &req.perout.index,
		     &req.perout.start.sec, &req.perout.start.nsec,
		     &req.perout.period.sec, &req.perout.period.nsec);
	if (cnt != 5)
		goto out;
	if (req.perout.index >= ops->n_per_out)
		goto out;

	enable = req.perout.period.sec || req.perout.period.nsec;
	err = ops->enable(ops, &req, enable);
	if (err)
		goto out;

	return count;
out:
	return err;
}
static DEVICE_ATTR(period, 0220, NULL, period_store);

static ssize_t pps_enable_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	struct ptp_clock_info *ops = ptp->info;
	struct ptp_clock_request req = { .type = PTP_CLK_REQ_PPS };
	int cnt, enable;
	int err = -EINVAL;

	if (!capable(CAP_SYS_TIME))
		return -EPERM;

	cnt = sscanf(buf, "%d", &enable);
	if (cnt != 1)
		goto out;

	err = ops->enable(ops, &req, enable ? 1 : 0);
	if (err)
		goto out;

	return count;
out:
	return err;
}
static DEVICE_ATTR(pps_enable, 0220, NULL, pps_enable_store);

static int unregister_vclock(struct device *dev, void *data)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	struct ptp_clock_info *info = ptp->info;
	struct ptp_vclock *vclock;
	u32 *num = data;

	vclock = info_to_vclock(info);
	dev_info(dev->parent, "delete virtual clock ptp%d\n",
		 vclock->clock->index);

	ptp_vclock_unregister(vclock);
	(*num)--;

	/* For break. Not error. */
	if (*num == 0)
		return -EINVAL;

	return 0;
}

static ssize_t n_vclocks_show(struct device *dev,
			      struct device_attribute *attr, char *page)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	ssize_t size;

	if (mutex_lock_interruptible(&ptp->n_vclocks_mux))
		return -ERESTARTSYS;

	size = snprintf(page, PAGE_SIZE - 1, "%u\n", ptp->n_vclocks);

	mutex_unlock(&ptp->n_vclocks_mux);

	return size;
}

static ssize_t n_vclocks_store(struct device *dev,
			       struct device_attribute *attr,
			       const char *buf, size_t count)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	struct ptp_vclock *vclock;
	int err = -EINVAL;
	u32 num, i;

	if (kstrtou32(buf, 0, &num))
		return err;

	if (mutex_lock_interruptible(&ptp->n_vclocks_mux))
		return -ERESTARTSYS;

	if (num > ptp->max_vclocks) {
		dev_err(dev, "max value is %d\n", ptp->max_vclocks);
		goto out;
	}

	/* Need to create more vclocks */
	if (num > ptp->n_vclocks) {
		for (i = 0; i < num - ptp->n_vclocks; i++) {
			vclock = ptp_vclock_register(ptp);
			if (!vclock)
				goto out;

			*(ptp->vclock_index + ptp->n_vclocks + i) =
				vclock->clock->index;

			dev_info(dev, "new virtual clock ptp%d\n",
				 vclock->clock->index);
		}
	}

	/* Need to delete vclocks */
	if (num < ptp->n_vclocks) {
		i = ptp->n_vclocks - num;
		device_for_each_child_reverse(dev, &i,
					      unregister_vclock);

		for (i = 1; i <= ptp->n_vclocks - num; i++)
			*(ptp->vclock_index + ptp->n_vclocks - i) = -1;
	}

	/* Need to inform about changed physical clock behavior */
	if (!ptp->has_cycles) {
		if (num == 0)
			dev_info(dev, "only physical clock in use now\n");
		else
			dev_info(dev, "guarantee physical clock free running\n");
	}

	ptp->n_vclocks = num;
	mutex_unlock(&ptp->n_vclocks_mux);

	return count;
out:
	mutex_unlock(&ptp->n_vclocks_mux);
	return err;
}
static DEVICE_ATTR_RW(n_vclocks);

static ssize_t max_vclocks_show(struct device *dev,
				struct device_attribute *attr, char *page)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	ssize_t size;

	size = snprintf(page, PAGE_SIZE - 1, "%u\n", ptp->max_vclocks);

	return size;
}

static ssize_t max_vclocks_store(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf, size_t count)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	unsigned int *vclock_index;
	int err = -EINVAL;
	size_t size;
	u32 max;

	if (kstrtou32(buf, 0, &max) || max == 0)
		return -EINVAL;

	if (max == ptp->max_vclocks)
		return count;

	if (mutex_lock_interruptible(&ptp->n_vclocks_mux))
		return -ERESTARTSYS;

	if (max < ptp->n_vclocks)
		goto out;

	size = sizeof(int) * max;
	vclock_index = kzalloc(size, GFP_KERNEL);
	if (!vclock_index) {
		err = -ENOMEM;
		goto out;
	}

	size = sizeof(int) * ptp->n_vclocks;
	memcpy(vclock_index, ptp->vclock_index, size);

	kfree(ptp->vclock_index);
	ptp->vclock_index = vclock_index;
	ptp->max_vclocks = max;

	mutex_unlock(&ptp->n_vclocks_mux);

	return count;
out:
	mutex_unlock(&ptp->n_vclocks_mux);
	return err;
}
static DEVICE_ATTR_RW(max_vclocks);

static struct attribute *ptp_attrs[] = {
	&dev_attr_clock_name.attr,

	&dev_attr_max_adjustment.attr,
	&dev_attr_max_phase_adjustment.attr,
	&dev_attr_n_alarms.attr,
	&dev_attr_n_external_timestamps.attr,
	&dev_attr_n_periodic_outputs.attr,
	&dev_attr_n_programmable_pins.attr,
	&dev_attr_pps_available.attr,

	&dev_attr_extts_enable.attr,
	&dev_attr_fifo.attr,
	&dev_attr_period.attr,
	&dev_attr_pps_enable.attr,
	&dev_attr_n_vclocks.attr,
	&dev_attr_max_vclocks.attr,
	NULL
};

static umode_t ptp_is_attribute_visible(struct kobject *kobj,
					struct attribute *attr, int n)
{
	struct device *dev = kobj_to_dev(kobj);
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	struct ptp_clock_info *info = ptp->info;
	umode_t mode = attr->mode;

	if (attr == &dev_attr_extts_enable.attr ||
	    attr == &dev_attr_fifo.attr) {
		if (!info->n_ext_ts)
			mode = 0;
	} else if (attr == &dev_attr_period.attr) {
		if (!info->n_per_out)
			mode = 0;
	} else if (attr == &dev_attr_pps_enable.attr) {
		if (!info->pps)
			mode = 0;
	} else if (attr == &dev_attr_n_vclocks.attr ||
		   attr == &dev_attr_max_vclocks.attr) {
		if (ptp->is_virtual_clock)
			mode = 0;
	} else if (attr == &dev_attr_max_phase_adjustment.attr) {
		if (!info->adjphase || !info->getmaxphase)
			mode = 0;
	}

	return mode;
}

static const struct attribute_group ptp_group = {
	.is_visible	= ptp_is_attribute_visible,
	.attrs		= ptp_attrs,
};

const struct attribute_group *ptp_groups[] = {
	&ptp_group,
	NULL
};

static int ptp_pin_name2index(struct ptp_clock *ptp, const char *name)
{
	int i;
	for (i = 0; i < ptp->info->n_pins; i++) {
		if (!strcmp(ptp->info->pin_config[i].name, name))
			return i;
	}
	return -1;
}

static ssize_t ptp_pin_show(struct device *dev, struct device_attribute *attr,
			    char *page)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	unsigned int func, chan;
	int index;

	index = ptp_pin_name2index(ptp, attr->attr.name);
	if (index < 0)
		return -EINVAL;

	if (mutex_lock_interruptible(&ptp->pincfg_mux))
		return -ERESTARTSYS;

	func = ptp->info->pin_config[index].func;
	chan = ptp->info->pin_config[index].chan;

	mutex_unlock(&ptp->pincfg_mux);

	return sysfs_emit(page, "%u %u\n", func, chan);
}

static ssize_t ptp_pin_store(struct device *dev, struct device_attribute *attr,
			     const char *buf, size_t count)
{
	struct ptp_clock *ptp = dev_get_drvdata(dev);
	unsigned int func, chan;
	int cnt, err, index;

	cnt = sscanf(buf, "%u %u", &func, &chan);
	if (cnt != 2)
		return -EINVAL;

	index = ptp_pin_name2index(ptp, attr->attr.name);
	if (index < 0)
		return -EINVAL;

	if (mutex_lock_interruptible(&ptp->pincfg_mux))
		return -ERESTARTSYS;
	err = ptp_set_pinfunc(ptp, index, func, chan);
	mutex_unlock(&ptp->pincfg_mux);
	if (err)
		return err;

	return count;
}

int ptp_populate_pin_groups(struct ptp_clock *ptp)
{
	struct ptp_clock_info *info = ptp->info;
	int err = -ENOMEM, i, n_pins = info->n_pins;

	if (!n_pins)
		return 0;

	ptp->pin_dev_attr = kcalloc(n_pins, sizeof(*ptp->pin_dev_attr),
				    GFP_KERNEL);
	if (!ptp->pin_dev_attr)
		goto no_dev_attr;

	ptp->pin_attr = kcalloc(1 + n_pins, sizeof(*ptp->pin_attr), GFP_KERNEL);
	if (!ptp->pin_attr)
		goto no_pin_attr;

	for (i = 0; i < n_pins; i++) {
		struct device_attribute *da = &ptp->pin_dev_attr[i];
		sysfs_attr_init(&da->attr);
		da->attr.name = info->pin_config[i].name;
		da->attr.mode = 0644;
		da->show = ptp_pin_show;
		da->store = ptp_pin_store;
		ptp->pin_attr[i] = &da->attr;
	}

	ptp->pin_attr_group.name = "pins";
	ptp->pin_attr_group.attrs = ptp->pin_attr;

	ptp->pin_attr_groups[0] = &ptp->pin_attr_group;

	return 0;

no_pin_attr:
	kfree(ptp->pin_dev_attr);
no_dev_attr:
	return err;
}

void ptp_cleanup_pin_groups(struct ptp_clock *ptp)
{
	kfree(ptp->pin_attr);
	kfree(ptp->pin_dev_attr);
}
