// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
 *
 * Copyright(c) 2017 Intel Corporation. All rights reserved.
 *
 * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
 *         Yan Wang <yan.wan@linux.intel.com>
 *
 * Generic debug routines used to export DSP MMIO and memories to userspace
 * for firmware debugging.
 */

#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <uapi/sound/sof-ipc.h>
#include "sof-priv.h"
#include "ops.h"

static int sof_dfsentry_open(struct inode *inode, struct file *file)
{
	file->private_data = inode->i_private;

	return 0;
}

static ssize_t sof_dfsentry_read(struct file *file, char __user *buffer,
				 size_t count, loff_t *ppos)
{
	struct snd_sof_dfsentry_io *dfse = file->private_data;
	struct snd_sof_dev *sdev = dfse->sdev;
	int size, err;
	u32 *buf;
	loff_t pos = *ppos;
	size_t ret;

	size = dfse->size;

	/* validate position & count */
	if (pos < 0)
		return -EINVAL;
	if (pos >= size || !count)
		return 0;
	if (count > size - pos)
		count = size - pos;

	/* intermediate buffer size must be u32 multiple */
	size = (count + 3) & ~3;
	buf = kzalloc(size, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	/* copy from DSP MMIO */
	err = pm_runtime_get_sync(sdev->dev);
	if (err < 0) {
		dev_err(sdev->dev, "error: debugFS failed to resume %d\n",
			err);
		return err;
	}

	memcpy_fromio(buf,  dfse->buf + pos, size);
	pm_runtime_put(sdev->dev);

	/* copy to userspace */
	ret = copy_to_user(buffer, buf, count);
	kfree(buf);

	/* update count & position if copy succeeded */
	if (ret == count)
		return -EFAULT;
	count -= ret;
	*ppos = pos + count;

	return count;
}

static const struct file_operations sof_dfs_fops = {
	.open = sof_dfsentry_open,
	.read = sof_dfsentry_read,
	.llseek = default_llseek,
};

int snd_sof_debugfs_create_item(struct snd_sof_dev *sdev,
				void __iomem *base, size_t size,
				const char *name)
{
	struct snd_sof_dfsentry_io *dfse;

	if (!sdev)
		return -EINVAL;

	dfse = kzalloc(sizeof(*dfse), GFP_KERNEL);
	if (!dfse)
		return -ENOMEM;

	dfse->buf = base;
	dfse->size = size;
	dfse->sdev = sdev;

	dfse->dfsentry = debugfs_create_file(name, 0444, sdev->debugfs_root,
					     dfse, &sof_dfs_fops);
	if (!dfse->dfsentry) {
		dev_err(sdev->dev, "cannot create debugfs entry.\n");
		kfree(dfse);
		return -ENODEV;
	}

	return 0;
}
EXPORT_SYMBOL(snd_sof_debugfs_create_item);

int snd_sof_dbg_init(struct snd_sof_dev *sdev)
{
	const struct snd_sof_dsp_ops *ops = sdev->ops;
	const struct snd_sof_debugfs_map *map;
	int err = 0, i;

	/* use "sof" as top level debugFS dir */
	sdev->debugfs_root = debugfs_create_dir("sof", NULL);
	if (IS_ERR_OR_NULL(sdev->debugfs_root)) {
		dev_err(sdev->dev, "error: failed to create debugfs directory\n");
		return -EINVAL;
	}

	/* create debugFS files for platform specific MMIO/DSP memories */
	for (i = 0; i < ops->debug_map_count; i++) {
		map = &ops->debug_map[i];

		err = snd_sof_debugfs_create_item(sdev, sdev->bar[map->bar] +
						  map->offset, map->size,
						  map->name);
		if (err < 0)
			dev_err(sdev->dev, "cannot create debugfs for %s\n",
				map->name);
	}

	return err;
}
EXPORT_SYMBOL(snd_sof_dbg_init);

void snd_sof_free_debug(struct snd_sof_dev *sdev)
{
	debugfs_remove_recursive(sdev->debugfs_root);
}
EXPORT_SYMBOL(snd_sof_free_debug);
