// SPDX-License-Identifier: GPL-2.0
/*
 * Intel Platform Monitoring Technology Crashlog driver
 *
 * Copyright (c) 2020, Intel Corporation.
 * All Rights Reserved.
 *
 * Author: "Alexander Duyck" <alexander.h.duyck@linux.intel.com>
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/overflow.h>

#include "intel_pmt_class.h"

#define DRV_NAME		"pmt_crashlog"

/* Crashlog discovery header types */
#define CRASH_TYPE_OOBMSM	1

/* Control Flags */
#define CRASHLOG_FLAG_DISABLE		BIT(27)

/*
 * Bits 28 and 29 control the state of bit 31.
 *
 * Bit 28 will clear bit 31, if set, allowing a new crashlog to be captured.
 * Bit 29 will immediately trigger a crashlog to be generated, setting bit 31.
 * Bit 30 is read-only and reserved as 0.
 * Bit 31 is the read-only status with a 1 indicating log is complete.
 */
#define CRASHLOG_FLAG_TRIGGER_CLEAR	BIT(28)
#define CRASHLOG_FLAG_TRIGGER_EXECUTE	BIT(29)
#define CRASHLOG_FLAG_TRIGGER_COMPLETE	BIT(31)
#define CRASHLOG_FLAG_TRIGGER_MASK	GENMASK(31, 28)

/* Crashlog Discovery Header */
#define CONTROL_OFFSET		0x0
#define GUID_OFFSET		0x4
#define BASE_OFFSET		0x8
#define SIZE_OFFSET		0xC
#define GET_ACCESS(v)		((v) & GENMASK(3, 0))
#define GET_TYPE(v)		(((v) & GENMASK(7, 4)) >> 4)
#define GET_VERSION(v)		(((v) & GENMASK(19, 16)) >> 16)
/* size is in bytes */
#define GET_SIZE(v)		((v) * sizeof(u32))

struct crashlog_entry {
	/* entry must be first member of struct */
	struct intel_pmt_entry		entry;
	struct mutex			control_mutex;
};

struct pmt_crashlog_priv {
	int			num_entries;
	struct crashlog_entry	entry[];
};

/*
 * I/O
 */
static bool pmt_crashlog_complete(struct intel_pmt_entry *entry)
{
	u32 control = readl(entry->disc_table + CONTROL_OFFSET);

	/* return current value of the crashlog complete flag */
	return !!(control & CRASHLOG_FLAG_TRIGGER_COMPLETE);
}

static bool pmt_crashlog_disabled(struct intel_pmt_entry *entry)
{
	u32 control = readl(entry->disc_table + CONTROL_OFFSET);

	/* return current value of the crashlog disabled flag */
	return !!(control & CRASHLOG_FLAG_DISABLE);
}

static bool pmt_crashlog_supported(struct intel_pmt_entry *entry)
{
	u32 discovery_header = readl(entry->disc_table + CONTROL_OFFSET);
	u32 crash_type, version;

	crash_type = GET_TYPE(discovery_header);
	version = GET_VERSION(discovery_header);

	/*
	 * Currently we only recognize OOBMSM version 0 devices.
	 * We can ignore all other crashlog devices in the system.
	 */
	return crash_type == CRASH_TYPE_OOBMSM && version == 0;
}

static void pmt_crashlog_set_disable(struct intel_pmt_entry *entry,
				     bool disable)
{
	u32 control = readl(entry->disc_table + CONTROL_OFFSET);

	/* clear trigger bits so we are only modifying disable flag */
	control &= ~CRASHLOG_FLAG_TRIGGER_MASK;

	if (disable)
		control |= CRASHLOG_FLAG_DISABLE;
	else
		control &= ~CRASHLOG_FLAG_DISABLE;

	writel(control, entry->disc_table + CONTROL_OFFSET);
}

static void pmt_crashlog_set_clear(struct intel_pmt_entry *entry)
{
	u32 control = readl(entry->disc_table + CONTROL_OFFSET);

	control &= ~CRASHLOG_FLAG_TRIGGER_MASK;
	control |= CRASHLOG_FLAG_TRIGGER_CLEAR;

	writel(control, entry->disc_table + CONTROL_OFFSET);
}

static void pmt_crashlog_set_execute(struct intel_pmt_entry *entry)
{
	u32 control = readl(entry->disc_table + CONTROL_OFFSET);

	control &= ~CRASHLOG_FLAG_TRIGGER_MASK;
	control |= CRASHLOG_FLAG_TRIGGER_EXECUTE;

	writel(control, entry->disc_table + CONTROL_OFFSET);
}

/*
 * sysfs
 */
static ssize_t
enable_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct intel_pmt_entry *entry = dev_get_drvdata(dev);
	int enabled = !pmt_crashlog_disabled(entry);

	return sprintf(buf, "%d\n", enabled);
}

static ssize_t
enable_store(struct device *dev, struct device_attribute *attr,
	    const char *buf, size_t count)
{
	struct crashlog_entry *entry;
	bool enabled;
	int result;

	entry = dev_get_drvdata(dev);

	result = kstrtobool(buf, &enabled);
	if (result)
		return result;

	mutex_lock(&entry->control_mutex);
	pmt_crashlog_set_disable(&entry->entry, !enabled);
	mutex_unlock(&entry->control_mutex);

	return count;
}
static DEVICE_ATTR_RW(enable);

static ssize_t
trigger_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct intel_pmt_entry *entry;
	int trigger;

	entry = dev_get_drvdata(dev);
	trigger = pmt_crashlog_complete(entry);

	return sprintf(buf, "%d\n", trigger);
}

static ssize_t
trigger_store(struct device *dev, struct device_attribute *attr,
	    const char *buf, size_t count)
{
	struct crashlog_entry *entry;
	bool trigger;
	int result;

	entry = dev_get_drvdata(dev);

	result = kstrtobool(buf, &trigger);
	if (result)
		return result;

	mutex_lock(&entry->control_mutex);

	if (!trigger) {
		pmt_crashlog_set_clear(&entry->entry);
	} else if (pmt_crashlog_complete(&entry->entry)) {
		/* we cannot trigger a new crash if one is still pending */
		result = -EEXIST;
		goto err;
	} else if (pmt_crashlog_disabled(&entry->entry)) {
		/* if device is currently disabled, return busy */
		result = -EBUSY;
		goto err;
	} else {
		pmt_crashlog_set_execute(&entry->entry);
	}

	result = count;
err:
	mutex_unlock(&entry->control_mutex);
	return result;
}
static DEVICE_ATTR_RW(trigger);

static struct attribute *pmt_crashlog_attrs[] = {
	&dev_attr_enable.attr,
	&dev_attr_trigger.attr,
	NULL
};

static struct attribute_group pmt_crashlog_group = {
	.attrs	= pmt_crashlog_attrs,
};

static int pmt_crashlog_header_decode(struct intel_pmt_entry *entry,
				      struct intel_pmt_header *header,
				      struct device *dev)
{
	void __iomem *disc_table = entry->disc_table;
	struct crashlog_entry *crashlog;

	if (!pmt_crashlog_supported(entry))
		return 1;

	/* initialize control mutex */
	crashlog = container_of(entry, struct crashlog_entry, entry);
	mutex_init(&crashlog->control_mutex);

	header->access_type = GET_ACCESS(readl(disc_table));
	header->guid = readl(disc_table + GUID_OFFSET);
	header->base_offset = readl(disc_table + BASE_OFFSET);

	/* Size is measured in DWORDS, but accessor returns bytes */
	header->size = GET_SIZE(readl(disc_table + SIZE_OFFSET));

	return 0;
}

static DEFINE_XARRAY_ALLOC(crashlog_array);
static struct intel_pmt_namespace pmt_crashlog_ns = {
	.name = "crashlog",
	.xa = &crashlog_array,
	.attr_grp = &pmt_crashlog_group,
	.pmt_header_decode = pmt_crashlog_header_decode,
};

/*
 * initialization
 */
static int pmt_crashlog_remove(struct platform_device *pdev)
{
	struct pmt_crashlog_priv *priv = platform_get_drvdata(pdev);
	int i;

	for (i = 0; i < priv->num_entries; i++)
		intel_pmt_dev_destroy(&priv->entry[i].entry, &pmt_crashlog_ns);

	return 0;
}

static int pmt_crashlog_probe(struct platform_device *pdev)
{
	struct pmt_crashlog_priv *priv;
	size_t size;
	int i, ret;

	size = struct_size(priv, entry, pdev->num_resources);
	priv = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	platform_set_drvdata(pdev, priv);

	for (i = 0; i < pdev->num_resources; i++) {
		struct intel_pmt_entry *entry = &priv->entry[i].entry;

		ret = intel_pmt_dev_create(entry, &pmt_crashlog_ns, pdev, i);
		if (ret < 0)
			goto abort_probe;
		if (ret)
			continue;

		priv->num_entries++;
	}

	return 0;
abort_probe:
	pmt_crashlog_remove(pdev);
	return ret;
}

static struct platform_driver pmt_crashlog_driver = {
	.driver = {
		.name   = DRV_NAME,
	},
	.remove = pmt_crashlog_remove,
	.probe  = pmt_crashlog_probe,
};

static int __init pmt_crashlog_init(void)
{
	return platform_driver_register(&pmt_crashlog_driver);
}

static void __exit pmt_crashlog_exit(void)
{
	platform_driver_unregister(&pmt_crashlog_driver);
	xa_destroy(&crashlog_array);
}

module_init(pmt_crashlog_init);
module_exit(pmt_crashlog_exit);

MODULE_AUTHOR("Alexander Duyck <alexander.h.duyck@linux.intel.com>");
MODULE_DESCRIPTION("Intel PMT Crashlog driver");
MODULE_ALIAS("platform:" DRV_NAME);
MODULE_LICENSE("GPL v2");
