// SPDX-License-Identifier: GPL-2.0
/*
 * Intel Platform Monitory Technology Telemetry 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/mm.h>
#include <linux/pci.h>

#include "intel_pmt_class.h"

#define PMT_XA_START		0
#define PMT_XA_MAX		INT_MAX
#define PMT_XA_LIMIT		XA_LIMIT(PMT_XA_START, PMT_XA_MAX)

/*
 * sysfs
 */
static ssize_t
intel_pmt_read(struct file *filp, struct kobject *kobj,
	       struct bin_attribute *attr, char *buf, loff_t off,
	       size_t count)
{
	struct intel_pmt_entry *entry = container_of(attr,
						     struct intel_pmt_entry,
						     pmt_bin_attr);

	if (off < 0)
		return -EINVAL;

	if (off >= entry->size)
		return 0;

	if (count > entry->size - off)
		count = entry->size - off;

	memcpy_fromio(buf, entry->base + off, count);

	return count;
}

static int
intel_pmt_mmap(struct file *filp, struct kobject *kobj,
		struct bin_attribute *attr, struct vm_area_struct *vma)
{
	struct intel_pmt_entry *entry = container_of(attr,
						     struct intel_pmt_entry,
						     pmt_bin_attr);
	unsigned long vsize = vma->vm_end - vma->vm_start;
	struct device *dev = kobj_to_dev(kobj);
	unsigned long phys = entry->base_addr;
	unsigned long pfn = PFN_DOWN(phys);
	unsigned long psize;

	if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE))
		return -EROFS;

	psize = (PFN_UP(entry->base_addr + entry->size) - pfn) * PAGE_SIZE;
	if (vsize > psize) {
		dev_err(dev, "Requested mmap size is too large\n");
		return -EINVAL;
	}

	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
	if (io_remap_pfn_range(vma, vma->vm_start, pfn,
		vsize, vma->vm_page_prot))
		return -EAGAIN;

	return 0;
}

static ssize_t
guid_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct intel_pmt_entry *entry = dev_get_drvdata(dev);

	return sprintf(buf, "0x%x\n", entry->guid);
}
static DEVICE_ATTR_RO(guid);

static ssize_t size_show(struct device *dev, struct device_attribute *attr,
			 char *buf)
{
	struct intel_pmt_entry *entry = dev_get_drvdata(dev);

	return sprintf(buf, "%zu\n", entry->size);
}
static DEVICE_ATTR_RO(size);

static ssize_t
offset_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct intel_pmt_entry *entry = dev_get_drvdata(dev);

	return sprintf(buf, "%lu\n", offset_in_page(entry->base_addr));
}
static DEVICE_ATTR_RO(offset);

static struct attribute *intel_pmt_attrs[] = {
	&dev_attr_guid.attr,
	&dev_attr_size.attr,
	&dev_attr_offset.attr,
	NULL
};
ATTRIBUTE_GROUPS(intel_pmt);

static struct class intel_pmt_class = {
	.name = "intel_pmt",
	.owner = THIS_MODULE,
	.dev_groups = intel_pmt_groups,
};

static int intel_pmt_populate_entry(struct intel_pmt_entry *entry,
				    struct intel_pmt_header *header,
				    struct device *dev,
				    struct resource *disc_res)
{
	struct pci_dev *pci_dev = to_pci_dev(dev->parent);
	u8 bir;

	/*
	 * The base offset should always be 8 byte aligned.
	 *
	 * For non-local access types the lower 3 bits of base offset
	 * contains the index of the base address register where the
	 * telemetry can be found.
	 */
	bir = GET_BIR(header->base_offset);

	/* Local access and BARID only for now */
	switch (header->access_type) {
	case ACCESS_LOCAL:
		if (bir) {
			dev_err(dev,
				"Unsupported BAR index %d for access type %d\n",
				bir, header->access_type);
			return -EINVAL;
		}
		/*
		 * For access_type LOCAL, the base address is as follows:
		 * base address = end of discovery region + base offset
		 */
		entry->base_addr = disc_res->end + 1 + header->base_offset;
		break;
	case ACCESS_BARID:
		/*
		 * If another BAR was specified then the base offset
		 * represents the offset within that BAR. SO retrieve the
		 * address from the parent PCI device and add offset.
		 */
		entry->base_addr = pci_resource_start(pci_dev, bir) +
				   GET_ADDRESS(header->base_offset);
		break;
	default:
		dev_err(dev, "Unsupported access type %d\n",
			header->access_type);
		return -EINVAL;
	}

	entry->guid = header->guid;
	entry->size = header->size;

	return 0;
}

static int intel_pmt_dev_register(struct intel_pmt_entry *entry,
				  struct intel_pmt_namespace *ns,
				  struct device *parent)
{
	struct resource res;
	struct device *dev;
	int ret;

	ret = xa_alloc(ns->xa, &entry->devid, entry, PMT_XA_LIMIT, GFP_KERNEL);
	if (ret)
		return ret;

	dev = device_create(&intel_pmt_class, parent, MKDEV(0, 0), entry,
			    "%s%d", ns->name, entry->devid);

	if (IS_ERR(dev)) {
		dev_err(parent, "Could not create %s%d device node\n",
			ns->name, entry->devid);
		ret = PTR_ERR(dev);
		goto fail_dev_create;
	}

	entry->kobj = &dev->kobj;

	if (ns->attr_grp) {
		ret = sysfs_create_group(entry->kobj, ns->attr_grp);
		if (ret)
			goto fail_sysfs;
	}

	/* if size is 0 assume no data buffer, so no file needed */
	if (!entry->size)
		return 0;

	res.start = entry->base_addr;
	res.end = res.start + entry->size - 1;
	res.flags = IORESOURCE_MEM;

	entry->base = devm_ioremap_resource(dev, &res);
	if (IS_ERR(entry->base)) {
		ret = PTR_ERR(entry->base);
		goto fail_ioremap;
	}

	sysfs_bin_attr_init(&entry->pmt_bin_attr);
	entry->pmt_bin_attr.attr.name = ns->name;
	entry->pmt_bin_attr.attr.mode = 0440;
	entry->pmt_bin_attr.mmap = intel_pmt_mmap;
	entry->pmt_bin_attr.read = intel_pmt_read;
	entry->pmt_bin_attr.size = entry->size;

	ret = sysfs_create_bin_file(&dev->kobj, &entry->pmt_bin_attr);
	if (!ret)
		return 0;

fail_ioremap:
	if (ns->attr_grp)
		sysfs_remove_group(entry->kobj, ns->attr_grp);
fail_sysfs:
	device_unregister(dev);
fail_dev_create:
	xa_erase(ns->xa, entry->devid);

	return ret;
}

int intel_pmt_dev_create(struct intel_pmt_entry *entry,
			 struct intel_pmt_namespace *ns,
			 struct platform_device *pdev, int idx)
{
	struct intel_pmt_header header;
	struct resource	*disc_res;
	int ret = -ENODEV;

	disc_res = platform_get_resource(pdev, IORESOURCE_MEM, idx);
	if (!disc_res)
		return ret;

	entry->disc_table = devm_platform_ioremap_resource(pdev, idx);
	if (IS_ERR(entry->disc_table))
		return PTR_ERR(entry->disc_table);

	ret = ns->pmt_header_decode(entry, &header, &pdev->dev);
	if (ret)
		return ret;

	ret = intel_pmt_populate_entry(entry, &header, &pdev->dev, disc_res);
	if (ret)
		return ret;

	return intel_pmt_dev_register(entry, ns, &pdev->dev);

}
EXPORT_SYMBOL_GPL(intel_pmt_dev_create);

void intel_pmt_dev_destroy(struct intel_pmt_entry *entry,
			   struct intel_pmt_namespace *ns)
{
	struct device *dev = kobj_to_dev(entry->kobj);

	if (entry->size)
		sysfs_remove_bin_file(entry->kobj, &entry->pmt_bin_attr);

	if (ns->attr_grp)
		sysfs_remove_group(entry->kobj, ns->attr_grp);

	device_unregister(dev);
	xa_erase(ns->xa, entry->devid);
}
EXPORT_SYMBOL_GPL(intel_pmt_dev_destroy);

static int __init pmt_class_init(void)
{
	return class_register(&intel_pmt_class);
}

static void __exit pmt_class_exit(void)
{
	class_unregister(&intel_pmt_class);
}

module_init(pmt_class_init);
module_exit(pmt_class_exit);

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