// SPDX-License-Identifier: GPL-2.0-only
/*
 * Host side test driver to test endpoint functionality
 *
 * Copyright (C) 2017 Texas Instruments
 * Author: Kishon Vijay Abraham I <kishon@ti.com>
 */

#include <linux/crc32.h>
#include <linux/cleanup.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>

#include <linux/pci_regs.h>

#include <uapi/linux/pcitest.h>

#define DRV_MODULE_NAME				"pci-endpoint-test"

#define PCI_ENDPOINT_TEST_MAGIC			0x0

#define PCI_ENDPOINT_TEST_COMMAND		0x4
#define COMMAND_RAISE_INTX_IRQ			BIT(0)
#define COMMAND_RAISE_MSI_IRQ			BIT(1)
#define COMMAND_RAISE_MSIX_IRQ			BIT(2)
#define COMMAND_READ				BIT(3)
#define COMMAND_WRITE				BIT(4)
#define COMMAND_COPY				BIT(5)
#define COMMAND_ENABLE_DOORBELL			BIT(6)
#define COMMAND_DISABLE_DOORBELL		BIT(7)
#define COMMAND_BAR_SUBRANGE_SETUP		BIT(8)
#define COMMAND_BAR_SUBRANGE_CLEAR		BIT(9)

#define PCI_ENDPOINT_TEST_STATUS		0x8
#define STATUS_READ_SUCCESS			BIT(0)
#define STATUS_READ_FAIL			BIT(1)
#define STATUS_WRITE_SUCCESS			BIT(2)
#define STATUS_WRITE_FAIL			BIT(3)
#define STATUS_COPY_SUCCESS			BIT(4)
#define STATUS_COPY_FAIL			BIT(5)
#define STATUS_IRQ_RAISED			BIT(6)
#define STATUS_SRC_ADDR_INVALID			BIT(7)
#define STATUS_DST_ADDR_INVALID			BIT(8)
#define STATUS_DOORBELL_SUCCESS			BIT(9)
#define STATUS_DOORBELL_ENABLE_SUCCESS		BIT(10)
#define STATUS_DOORBELL_ENABLE_FAIL		BIT(11)
#define STATUS_DOORBELL_DISABLE_SUCCESS		BIT(12)
#define STATUS_DOORBELL_DISABLE_FAIL		BIT(13)
#define STATUS_BAR_SUBRANGE_SETUP_SUCCESS	BIT(14)
#define STATUS_BAR_SUBRANGE_SETUP_FAIL		BIT(15)
#define STATUS_BAR_SUBRANGE_CLEAR_SUCCESS	BIT(16)
#define STATUS_BAR_SUBRANGE_CLEAR_FAIL		BIT(17)
#define STATUS_NO_RESOURCE			BIT(18)

#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR	0x0c
#define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR	0x10

#define PCI_ENDPOINT_TEST_LOWER_DST_ADDR	0x14
#define PCI_ENDPOINT_TEST_UPPER_DST_ADDR	0x18

#define PCI_ENDPOINT_TEST_SIZE			0x1c
#define PCI_ENDPOINT_TEST_CHECKSUM		0x20

#define PCI_ENDPOINT_TEST_IRQ_TYPE		0x24
#define PCI_ENDPOINT_TEST_IRQ_NUMBER		0x28

#define PCI_ENDPOINT_TEST_FLAGS			0x2c

#define FLAG_USE_DMA				BIT(0)

#define PCI_ENDPOINT_TEST_CAPS			0x30
#define CAP_UNALIGNED_ACCESS			BIT(0)
#define CAP_MSI					BIT(1)
#define CAP_MSIX				BIT(2)
#define CAP_INTX				BIT(3)
#define CAP_SUBRANGE_MAPPING			BIT(4)
#define CAP_DYNAMIC_INBOUND_MAPPING		BIT(5)
#define CAP_BAR0_RESERVED			BIT(6)
#define CAP_BAR1_RESERVED			BIT(7)
#define CAP_BAR2_RESERVED			BIT(8)
#define CAP_BAR3_RESERVED			BIT(9)
#define CAP_BAR4_RESERVED			BIT(10)
#define CAP_BAR5_RESERVED			BIT(11)

#define PCI_ENDPOINT_TEST_DB_BAR		0x34
#define PCI_ENDPOINT_TEST_DB_OFFSET		0x38
#define PCI_ENDPOINT_TEST_DB_DATA		0x3c

#define PCI_DEVICE_ID_TI_AM654			0xb00c
#define PCI_DEVICE_ID_TI_J7200			0xb00f
#define PCI_DEVICE_ID_TI_AM64			0xb010
#define PCI_DEVICE_ID_TI_J721S2		0xb013
#define PCI_DEVICE_ID_LS1088A			0x80c0
#define PCI_DEVICE_ID_IMX8			0x0808

#define is_am654_pci_dev(pdev)		\
		((pdev)->device == PCI_DEVICE_ID_TI_AM654)

#define PCI_DEVICE_ID_RENESAS_R8A774A1		0x0028
#define PCI_DEVICE_ID_RENESAS_R8A774B1		0x002b
#define PCI_DEVICE_ID_RENESAS_R8A774C0		0x002d
#define PCI_DEVICE_ID_RENESAS_R8A774E1		0x0025
#define PCI_DEVICE_ID_RENESAS_R8A779F0		0x0031

#define PCI_DEVICE_ID_ROCKCHIP_RK3588		0x3588

#define PCI_DEVICE_ID_NVIDIA_TEGRA194_EP	0x1ad4
#define PCI_DEVICE_ID_NVIDIA_TEGRA234_EP	0x229b

#define PCI_ENDPOINT_TEST_BAR_SUBRANGE_NSUB	2

static DEFINE_IDA(pci_endpoint_test_ida);

#define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
					    miscdev)

enum pci_barno {
	BAR_0,
	BAR_1,
	BAR_2,
	BAR_3,
	BAR_4,
	BAR_5,
	NO_BAR = -1,
};

struct pci_endpoint_test {
	struct pci_dev	*pdev;
	void __iomem	*base;
	void __iomem	*bar[PCI_STD_NUM_BARS];
	struct completion irq_raised;
	int		last_irq;
	int		num_irqs;
	int		irq_type;
	/* mutex to protect the ioctls */
	struct mutex	mutex;
	struct miscdevice miscdev;
	enum pci_barno test_reg_bar;
	size_t alignment;
	u32 ep_caps;
	const char *name;
};

struct pci_endpoint_test_data {
	enum pci_barno test_reg_bar;
	size_t alignment;
};

static inline u32 pci_endpoint_test_readl(struct pci_endpoint_test *test,
					  u32 offset)
{
	return readl(test->base + offset);
}

static inline void pci_endpoint_test_writel(struct pci_endpoint_test *test,
					    u32 offset, u32 value)
{
	writel(value, test->base + offset);
}

static irqreturn_t pci_endpoint_test_irqhandler(int irq, void *dev_id)
{
	struct pci_endpoint_test *test = dev_id;
	u32 reg;

	reg = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
	if (reg & STATUS_IRQ_RAISED) {
		test->last_irq = irq;
		complete(&test->irq_raised);
	}

	return IRQ_HANDLED;
}

static void pci_endpoint_test_free_irq_vectors(struct pci_endpoint_test *test)
{
	struct pci_dev *pdev = test->pdev;

	pci_free_irq_vectors(pdev);
	test->irq_type = PCITEST_IRQ_TYPE_UNDEFINED;
}

static int pci_endpoint_test_alloc_irq_vectors(struct pci_endpoint_test *test,
						int type)
{
	int irq;
	struct pci_dev *pdev = test->pdev;
	struct device *dev = &pdev->dev;

	switch (type) {
	case PCITEST_IRQ_TYPE_INTX:
		irq = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_INTX);
		if (irq < 0) {
			dev_err(dev, "Failed to get Legacy interrupt\n");
			return irq;
		}

		break;
	case PCITEST_IRQ_TYPE_MSI:
		irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI);
		if (irq < 0) {
			dev_err(dev, "Failed to get MSI interrupts\n");
			return irq;
		}

		break;
	case PCITEST_IRQ_TYPE_MSIX:
		irq = pci_alloc_irq_vectors(pdev, 1, 2048, PCI_IRQ_MSIX);
		if (irq < 0) {
			dev_err(dev, "Failed to get MSI-X interrupts\n");
			return irq;
		}

		break;
	default:
		dev_err(dev, "Invalid IRQ type selected\n");
		return -EINVAL;
	}

	test->irq_type = type;
	test->num_irqs = irq;

	return 0;
}

static void pci_endpoint_test_release_irq(struct pci_endpoint_test *test)
{
	int i;
	struct pci_dev *pdev = test->pdev;

	for (i = 0; i < test->num_irqs; i++)
		free_irq(pci_irq_vector(pdev, i), test);

	test->num_irqs = 0;
}

static int pci_endpoint_test_request_irq(struct pci_endpoint_test *test)
{
	int i;
	int ret;
	struct pci_dev *pdev = test->pdev;
	struct device *dev = &pdev->dev;

	for (i = 0; i < test->num_irqs; i++) {
		ret = request_irq(pci_irq_vector(pdev, i),
				  pci_endpoint_test_irqhandler, IRQF_SHARED,
				  test->name, test);
		if (ret)
			goto fail;
	}

	return 0;

fail:
	switch (test->irq_type) {
	case PCITEST_IRQ_TYPE_INTX:
		dev_err(dev, "Failed to request IRQ %d for Legacy\n",
			pci_irq_vector(pdev, i));
		break;
	case PCITEST_IRQ_TYPE_MSI:
		dev_err(dev, "Failed to request IRQ %d for MSI %d\n",
			pci_irq_vector(pdev, i),
			i + 1);
		break;
	case PCITEST_IRQ_TYPE_MSIX:
		dev_err(dev, "Failed to request IRQ %d for MSI-X %d\n",
			pci_irq_vector(pdev, i),
			i + 1);
		break;
	}

	test->num_irqs = i;
	pci_endpoint_test_release_irq(test);

	return ret;
}

static bool bar_is_reserved(struct pci_endpoint_test *test, enum pci_barno bar)
{
	return test->ep_caps & BIT(bar + __fls(CAP_BAR0_RESERVED));
}

static const u32 bar_test_pattern[] = {
	0xA0A0A0A0,
	0xA1A1A1A1,
	0xA2A2A2A2,
	0xA3A3A3A3,
	0xA4A4A4A4,
	0xA5A5A5A5,
};

static int pci_endpoint_test_bar_memcmp(struct pci_endpoint_test *test,
					enum pci_barno barno,
					resource_size_t offset, void *write_buf,
					void *read_buf, int size)
{
	memset(write_buf, bar_test_pattern[barno], size);
	memcpy_toio(test->bar[barno] + offset, write_buf, size);

	memcpy_fromio(read_buf, test->bar[barno] + offset, size);

	return memcmp(write_buf, read_buf, size);
}

static int pci_endpoint_test_bar(struct pci_endpoint_test *test,
				  enum pci_barno barno)
{
	resource_size_t bar_size, offset = 0;
	void *write_buf __free(kfree) = NULL;
	void *read_buf __free(kfree) = NULL;
	struct pci_dev *pdev = test->pdev;
	int buf_size;

	bar_size = pci_resource_len(pdev, barno);
	if (!bar_size)
		return -ENODATA;

	if (!test->bar[barno])
		return -ENOMEM;

	if (barno == test->test_reg_bar)
		bar_size = 0x4;

	/*
	 * Allocate a buffer of max size 1MB, and reuse that buffer while
	 * iterating over the whole BAR size (which might be much larger).
	 */
	buf_size = min(SZ_1M, bar_size);

	write_buf = kmalloc(buf_size, GFP_KERNEL);
	if (!write_buf)
		return -ENOMEM;

	read_buf = kmalloc(buf_size, GFP_KERNEL);
	if (!read_buf)
		return -ENOMEM;

	while (offset < bar_size) {
		if (pci_endpoint_test_bar_memcmp(test, barno, offset, write_buf,
						 read_buf, buf_size))
			return -EIO;
		offset += buf_size;
	}

	return 0;
}

static u32 bar_test_pattern_with_offset(enum pci_barno barno, int offset)
{
	u32 val;

	/* Keep the BAR pattern in the top byte. */
	val = bar_test_pattern[barno] & 0xff000000;
	/* Store the (partial) offset in the remaining bytes. */
	val |= offset & 0x00ffffff;

	return val;
}

static void pci_endpoint_test_bars_write_bar(struct pci_endpoint_test *test,
					     enum pci_barno barno)
{
	struct pci_dev *pdev = test->pdev;
	int j, size;

	size = pci_resource_len(pdev, barno);

	if (barno == test->test_reg_bar)
		size = 0x4;

	for (j = 0; j < size; j += 4)
		writel_relaxed(bar_test_pattern_with_offset(barno, j),
			       test->bar[barno] + j);
}

static int pci_endpoint_test_bars_read_bar(struct pci_endpoint_test *test,
					    enum pci_barno barno)
{
	struct pci_dev *pdev = test->pdev;
	struct device *dev = &pdev->dev;
	int j, size;
	u32 val;

	size = pci_resource_len(pdev, barno);

	if (barno == test->test_reg_bar)
		size = 0x4;

	for (j = 0; j < size; j += 4) {
		u32 expected = bar_test_pattern_with_offset(barno, j);

		val = readl_relaxed(test->bar[barno] + j);
		if (val != expected) {
			dev_err(dev,
				"BAR%d incorrect data at offset: %#x, got: %#x expected: %#x\n",
				barno, j, val, expected);
			return -EIO;
		}
	}

	return 0;
}

static int pci_endpoint_test_bars(struct pci_endpoint_test *test)
{
	enum pci_barno bar;
	int ret;

	/* Write all BARs in order (without reading). */
	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
		if (test->bar[bar] && !bar_is_reserved(test, bar))
			pci_endpoint_test_bars_write_bar(test, bar);

	/*
	 * Read all BARs in order (without writing).
	 * If there is an address translation issue on the EP, writing one BAR
	 * might have overwritten another BAR. Ensure that this is not the case.
	 * (Reading back the BAR directly after writing can not detect this.)
	 */
	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
		if (test->bar[bar] && !bar_is_reserved(test, bar)) {
			ret = pci_endpoint_test_bars_read_bar(test, bar);
			if (ret)
				return ret;
		}
	}

	return 0;
}

static u8 pci_endpoint_test_subrange_sig_byte(enum pci_barno barno,
					      unsigned int subno)
{
	return 0x50 + (barno * 8) + subno;
}

static u8 pci_endpoint_test_subrange_test_byte(enum pci_barno barno,
					       unsigned int subno)
{
	return 0xa0 + (barno * 8) + subno;
}

static int pci_endpoint_test_bar_subrange_cmd(struct pci_endpoint_test *test,
					      enum pci_barno barno, u32 command,
					      u32 ok_bit, u32 fail_bit)
{
	struct pci_dev *pdev = test->pdev;
	struct device *dev = &pdev->dev;
	int irq_type = test->irq_type;
	u32 status;

	if (irq_type < PCITEST_IRQ_TYPE_INTX ||
	    irq_type > PCITEST_IRQ_TYPE_MSIX) {
		dev_err(dev, "Invalid IRQ type\n");
		return -EINVAL;
	}

	reinit_completion(&test->irq_raised);

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_STATUS, 0);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
	/* Reuse SIZE as a command parameter: bar number. */
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, barno);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND, command);

	if (!wait_for_completion_timeout(&test->irq_raised,
					 msecs_to_jiffies(1000)))
		return -ETIMEDOUT;

	status = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
	if (status & fail_bit)
		return (status & STATUS_NO_RESOURCE) ? -ENOSPC : -EIO;

	if (!(status & ok_bit))
		return -EIO;

	return 0;
}

static int pci_endpoint_test_bar_subrange_setup(struct pci_endpoint_test *test,
						enum pci_barno barno)
{
	return pci_endpoint_test_bar_subrange_cmd(test, barno,
			COMMAND_BAR_SUBRANGE_SETUP,
			STATUS_BAR_SUBRANGE_SETUP_SUCCESS,
			STATUS_BAR_SUBRANGE_SETUP_FAIL);
}

static int pci_endpoint_test_bar_subrange_clear(struct pci_endpoint_test *test,
						enum pci_barno barno)
{
	return pci_endpoint_test_bar_subrange_cmd(test, barno,
			COMMAND_BAR_SUBRANGE_CLEAR,
			STATUS_BAR_SUBRANGE_CLEAR_SUCCESS,
			STATUS_BAR_SUBRANGE_CLEAR_FAIL);
}

static int pci_endpoint_test_bar_subrange(struct pci_endpoint_test *test,
					  enum pci_barno barno)
{
	u32 nsub = PCI_ENDPOINT_TEST_BAR_SUBRANGE_NSUB;
	struct device *dev = &test->pdev->dev;
	size_t sub_size, buf_size;
	resource_size_t bar_size;
	void __iomem *bar_addr;
	void *read_buf = NULL;
	int ret, clear_ret;
	size_t off, chunk;
	u32 i, exp, val;
	u8 pattern;

	if (!(test->ep_caps & CAP_SUBRANGE_MAPPING))
		return -EOPNOTSUPP;

	/*
	 * The test register BAR is not safe to reprogram and write/read
	 * over its full size. BAR_TEST already special-cases it to a tiny
	 * range. For subrange mapping tests, let's simply skip it.
	 */
	if (barno == test->test_reg_bar)
		return -EBUSY;

	bar_size = pci_resource_len(test->pdev, barno);
	if (!bar_size)
		return -ENODATA;

	bar_addr = test->bar[barno];
	if (!bar_addr)
		return -ENOMEM;

	ret = pci_endpoint_test_bar_subrange_setup(test, barno);
	if (ret)
		return ret;

	if (bar_size % nsub || bar_size / nsub > SIZE_MAX) {
		ret = -EINVAL;
		goto out_clear;
	}

	sub_size = bar_size / nsub;
	if (sub_size < sizeof(u32)) {
		ret = -EINVAL;
		goto out_clear;
	}

	/* Limit the temporary buffer size */
	buf_size = min_t(size_t, sub_size, SZ_1M);

	read_buf = kmalloc(buf_size, GFP_KERNEL);
	if (!read_buf) {
		ret = -ENOMEM;
		goto out_clear;
	}

	/*
	 * Step 1: verify EP-provided signature per subrange. This detects
	 * whether the EP actually applied the submap order.
	 */
	for (i = 0; i < nsub; i++) {
		exp = (u32)pci_endpoint_test_subrange_sig_byte(barno, i) *
			0x01010101U;
		val = ioread32(bar_addr + (i * sub_size));
		if (val != exp) {
			dev_err(dev,
				"BAR%d subrange%u signature mismatch @%#zx: exp %#08x got %#08x\n",
				barno, i, (size_t)i * sub_size, exp, val);
			ret = -EIO;
			goto out_clear;
		}
		val = ioread32(bar_addr + (i * sub_size) + sub_size - sizeof(u32));
		if (val != exp) {
			dev_err(dev,
				"BAR%d subrange%u signature mismatch @%#zx: exp %#08x got %#08x\n",
				barno, i,
				((size_t)i * sub_size) + sub_size - sizeof(u32),
				exp, val);
			ret = -EIO;
			goto out_clear;
		}
	}

	/* Step 2: write unique pattern per subrange (write all first). */
	for (i = 0; i < nsub; i++) {
		pattern = pci_endpoint_test_subrange_test_byte(barno, i);
		memset_io(bar_addr + (i * sub_size), pattern, sub_size);
	}

	/* Step 3: read back and verify (read all after all writes). */
	for (i = 0; i < nsub; i++) {
		pattern = pci_endpoint_test_subrange_test_byte(barno, i);
		for (off = 0; off < sub_size; off += chunk) {
			void *bad;

			chunk = min_t(size_t, buf_size, sub_size - off);
			memcpy_fromio(read_buf, bar_addr + (i * sub_size) + off,
				      chunk);
			bad = memchr_inv(read_buf, pattern, chunk);
			if (bad) {
				size_t bad_off = (u8 *)bad - (u8 *)read_buf;

				dev_err(dev,
					"BAR%d subrange%u data mismatch @%#zx (pattern %#02x)\n",
					barno, i, (size_t)i * sub_size + off + bad_off,
					pattern);
				ret = -EIO;
				goto out_clear;
			}
		}
	}

out_clear:
	kfree(read_buf);
	clear_ret = pci_endpoint_test_bar_subrange_clear(test, barno);
	return ret ?: clear_ret;
}

static int pci_endpoint_test_intx_irq(struct pci_endpoint_test *test)
{
	u32 val;

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
				 PCITEST_IRQ_TYPE_INTX);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 0);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
				 COMMAND_RAISE_INTX_IRQ);
	val = wait_for_completion_timeout(&test->irq_raised,
					  msecs_to_jiffies(1000));
	if (!val)
		return -ETIMEDOUT;

	return 0;
}

static int pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
				       u16 msi_num, bool msix)
{
	struct pci_dev *pdev = test->pdev;
	u32 val;
	int irq;

	irq = pci_irq_vector(pdev, msi_num - 1);
	if (irq < 0)
		return irq;

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE,
				 msix ? PCITEST_IRQ_TYPE_MSIX :
				 PCITEST_IRQ_TYPE_MSI);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, msi_num);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
				 msix ? COMMAND_RAISE_MSIX_IRQ :
				 COMMAND_RAISE_MSI_IRQ);
	val = wait_for_completion_timeout(&test->irq_raised,
					  msecs_to_jiffies(1000));
	if (!val)
		return -ETIMEDOUT;

	if (irq != test->last_irq)
		return -EIO;

	return 0;
}

static int pci_endpoint_test_validate_xfer_params(struct device *dev,
		struct pci_endpoint_test_xfer_param *param, size_t alignment)
{
	if (!param->size) {
		dev_dbg(dev, "Data size is zero\n");
		return -EINVAL;
	}

	if (param->size > SIZE_MAX - alignment) {
		dev_dbg(dev, "Maximum transfer data size exceeded\n");
		return -EINVAL;
	}

	return 0;
}

static int pci_endpoint_test_copy(struct pci_endpoint_test *test,
				   unsigned long arg)
{
	struct pci_endpoint_test_xfer_param param;
	void *src_addr;
	void *dst_addr;
	u32 flags = 0;
	bool use_dma;
	size_t size;
	dma_addr_t src_phys_addr;
	dma_addr_t dst_phys_addr;
	struct pci_dev *pdev = test->pdev;
	struct device *dev = &pdev->dev;
	void *orig_src_addr;
	dma_addr_t orig_src_phys_addr;
	void *orig_dst_addr;
	dma_addr_t orig_dst_phys_addr;
	size_t offset;
	size_t alignment = test->alignment;
	int irq_type = test->irq_type;
	u32 src_crc32;
	u32 dst_crc32;
	int ret;

	ret = copy_from_user(&param, (void __user *)arg, sizeof(param));
	if (ret) {
		dev_err(dev, "Failed to get transfer param\n");
		return -EFAULT;
	}

	ret = pci_endpoint_test_validate_xfer_params(dev, &param, alignment);
	if (ret)
		return ret;

	size = param.size;

	use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
	if (use_dma)
		flags |= FLAG_USE_DMA;

	if (irq_type < PCITEST_IRQ_TYPE_INTX ||
	    irq_type > PCITEST_IRQ_TYPE_MSIX) {
		dev_err(dev, "Invalid IRQ type option\n");
		return -EINVAL;
	}

	orig_src_addr = kzalloc(size + alignment, GFP_KERNEL);
	if (!orig_src_addr) {
		dev_err(dev, "Failed to allocate source buffer\n");
		return -ENOMEM;
	}

	get_random_bytes(orig_src_addr, size + alignment);
	orig_src_phys_addr = dma_map_single(dev, orig_src_addr,
					    size + alignment, DMA_TO_DEVICE);
	ret = dma_mapping_error(dev, orig_src_phys_addr);
	if (ret) {
		dev_err(dev, "failed to map source buffer address\n");
		goto err_src_phys_addr;
	}

	if (alignment && !IS_ALIGNED(orig_src_phys_addr, alignment)) {
		src_phys_addr = PTR_ALIGN(orig_src_phys_addr, alignment);
		offset = src_phys_addr - orig_src_phys_addr;
		src_addr = orig_src_addr + offset;
	} else {
		src_phys_addr = orig_src_phys_addr;
		src_addr = orig_src_addr;
	}

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_SRC_ADDR,
				 lower_32_bits(src_phys_addr));

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_SRC_ADDR,
				 upper_32_bits(src_phys_addr));

	src_crc32 = crc32_le(~0, src_addr, size);

	orig_dst_addr = kzalloc(size + alignment, GFP_KERNEL);
	if (!orig_dst_addr) {
		dev_err(dev, "Failed to allocate destination address\n");
		ret = -ENOMEM;
		goto err_dst_addr;
	}

	orig_dst_phys_addr = dma_map_single(dev, orig_dst_addr,
					    size + alignment, DMA_FROM_DEVICE);
	ret = dma_mapping_error(dev, orig_dst_phys_addr);
	if (ret) {
		dev_err(dev, "failed to map destination buffer address\n");
		goto err_dst_phys_addr;
	}

	if (alignment && !IS_ALIGNED(orig_dst_phys_addr, alignment)) {
		dst_phys_addr = PTR_ALIGN(orig_dst_phys_addr, alignment);
		offset = dst_phys_addr - orig_dst_phys_addr;
		dst_addr = orig_dst_addr + offset;
	} else {
		dst_phys_addr = orig_dst_phys_addr;
		dst_addr = orig_dst_addr;
	}

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR,
				 lower_32_bits(dst_phys_addr));
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_DST_ADDR,
				 upper_32_bits(dst_phys_addr));

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE,
				 size);

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
				 COMMAND_COPY);

	wait_for_completion(&test->irq_raised);

	dma_unmap_single(dev, orig_dst_phys_addr, size + alignment,
			 DMA_FROM_DEVICE);

	dst_crc32 = crc32_le(~0, dst_addr, size);
	if (dst_crc32 != src_crc32)
		ret = -EIO;

err_dst_phys_addr:
	kfree(orig_dst_addr);

err_dst_addr:
	dma_unmap_single(dev, orig_src_phys_addr, size + alignment,
			 DMA_TO_DEVICE);

err_src_phys_addr:
	kfree(orig_src_addr);
	return ret;
}

static int pci_endpoint_test_write(struct pci_endpoint_test *test,
				    unsigned long arg)
{
	struct pci_endpoint_test_xfer_param param;
	u32 flags = 0;
	bool use_dma;
	u32 reg;
	void *addr;
	dma_addr_t phys_addr;
	struct pci_dev *pdev = test->pdev;
	struct device *dev = &pdev->dev;
	void *orig_addr;
	dma_addr_t orig_phys_addr;
	size_t offset;
	size_t alignment = test->alignment;
	int irq_type = test->irq_type;
	size_t size;
	u32 crc32;
	int ret;

	ret = copy_from_user(&param, (void __user *)arg, sizeof(param));
	if (ret) {
		dev_err(dev, "Failed to get transfer param\n");
		return -EFAULT;
	}

	ret = pci_endpoint_test_validate_xfer_params(dev, &param, alignment);
	if (ret)
		return ret;

	size = param.size;

	use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
	if (use_dma)
		flags |= FLAG_USE_DMA;

	if (irq_type < PCITEST_IRQ_TYPE_INTX ||
	    irq_type > PCITEST_IRQ_TYPE_MSIX) {
		dev_err(dev, "Invalid IRQ type option\n");
		return -EINVAL;
	}

	orig_addr = kzalloc(size + alignment, GFP_KERNEL);
	if (!orig_addr) {
		dev_err(dev, "Failed to allocate address\n");
		return -ENOMEM;
	}

	get_random_bytes(orig_addr, size + alignment);

	orig_phys_addr = dma_map_single(dev, orig_addr, size + alignment,
					DMA_TO_DEVICE);
	ret = dma_mapping_error(dev, orig_phys_addr);
	if (ret) {
		dev_err(dev, "failed to map source buffer address\n");
		goto err_phys_addr;
	}

	if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) {
		phys_addr =  PTR_ALIGN(orig_phys_addr, alignment);
		offset = phys_addr - orig_phys_addr;
		addr = orig_addr + offset;
	} else {
		phys_addr = orig_phys_addr;
		addr = orig_addr;
	}

	crc32 = crc32_le(~0, addr, size);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_CHECKSUM,
				 crc32);

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_SRC_ADDR,
				 lower_32_bits(phys_addr));
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_SRC_ADDR,
				 upper_32_bits(phys_addr));

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
				 COMMAND_READ);

	wait_for_completion(&test->irq_raised);

	reg = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
	if (!(reg & STATUS_READ_SUCCESS))
		ret = -EIO;

	dma_unmap_single(dev, orig_phys_addr, size + alignment,
			 DMA_TO_DEVICE);

err_phys_addr:
	kfree(orig_addr);
	return ret;
}

static int pci_endpoint_test_read(struct pci_endpoint_test *test,
				   unsigned long arg)
{
	struct pci_endpoint_test_xfer_param param;
	u32 flags = 0;
	bool use_dma;
	size_t size;
	void *addr;
	dma_addr_t phys_addr;
	struct pci_dev *pdev = test->pdev;
	struct device *dev = &pdev->dev;
	void *orig_addr;
	dma_addr_t orig_phys_addr;
	size_t offset;
	size_t alignment = test->alignment;
	int irq_type = test->irq_type;
	u32 crc32;
	int ret;

	ret = copy_from_user(&param, (void __user *)arg, sizeof(param));
	if (ret) {
		dev_err(dev, "Failed to get transfer param\n");
		return -EFAULT;
	}

	ret = pci_endpoint_test_validate_xfer_params(dev, &param, alignment);
	if (ret)
		return ret;

	size = param.size;

	use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
	if (use_dma)
		flags |= FLAG_USE_DMA;

	if (irq_type < PCITEST_IRQ_TYPE_INTX ||
	    irq_type > PCITEST_IRQ_TYPE_MSIX) {
		dev_err(dev, "Invalid IRQ type option\n");
		return -EINVAL;
	}

	orig_addr = kzalloc(size + alignment, GFP_KERNEL);
	if (!orig_addr) {
		dev_err(dev, "Failed to allocate destination address\n");
		return -ENOMEM;
	}

	orig_phys_addr = dma_map_single(dev, orig_addr, size + alignment,
					DMA_FROM_DEVICE);
	ret = dma_mapping_error(dev, orig_phys_addr);
	if (ret) {
		dev_err(dev, "failed to map source buffer address\n");
		goto err_phys_addr;
	}

	if (alignment && !IS_ALIGNED(orig_phys_addr, alignment)) {
		phys_addr = PTR_ALIGN(orig_phys_addr, alignment);
		offset = phys_addr - orig_phys_addr;
		addr = orig_addr + offset;
	} else {
		phys_addr = orig_phys_addr;
		addr = orig_addr;
	}

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR,
				 lower_32_bits(phys_addr));
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_DST_ADDR,
				 upper_32_bits(phys_addr));

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_FLAGS, flags);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
				 COMMAND_WRITE);

	wait_for_completion(&test->irq_raised);

	dma_unmap_single(dev, orig_phys_addr, size + alignment,
			 DMA_FROM_DEVICE);

	crc32 = crc32_le(~0, addr, size);
	if (crc32 != pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CHECKSUM))
		ret = -EIO;

err_phys_addr:
	kfree(orig_addr);
	return ret;
}

static int pci_endpoint_test_clear_irq(struct pci_endpoint_test *test)
{
	pci_endpoint_test_release_irq(test);
	pci_endpoint_test_free_irq_vectors(test);

	return 0;
}

static int pci_endpoint_test_set_irq(struct pci_endpoint_test *test,
				      int req_irq_type)
{
	struct pci_dev *pdev = test->pdev;
	struct device *dev = &pdev->dev;
	int ret;

	if (req_irq_type < PCITEST_IRQ_TYPE_INTX ||
	    req_irq_type > PCITEST_IRQ_TYPE_AUTO) {
		dev_err(dev, "Invalid IRQ type option\n");
		return -EINVAL;
	}

	if (req_irq_type == PCITEST_IRQ_TYPE_AUTO) {
		if (test->ep_caps & CAP_MSI)
			req_irq_type = PCITEST_IRQ_TYPE_MSI;
		else if (test->ep_caps & CAP_MSIX)
			req_irq_type = PCITEST_IRQ_TYPE_MSIX;
		else if (test->ep_caps & CAP_INTX)
			req_irq_type = PCITEST_IRQ_TYPE_INTX;
		else
			/* fallback to MSI if no caps defined */
			req_irq_type = PCITEST_IRQ_TYPE_MSI;
	}

	if (test->irq_type == req_irq_type)
		return 0;

	pci_endpoint_test_release_irq(test);
	pci_endpoint_test_free_irq_vectors(test);

	ret = pci_endpoint_test_alloc_irq_vectors(test, req_irq_type);
	if (ret)
		return ret;

	ret = pci_endpoint_test_request_irq(test);
	if (ret) {
		pci_endpoint_test_free_irq_vectors(test);
		return ret;
	}

	return 0;
}

static int pci_endpoint_test_doorbell(struct pci_endpoint_test *test)
{
	struct pci_dev *pdev = test->pdev;
	struct device *dev = &pdev->dev;
	int irq_type = test->irq_type;
	int ret = 0;
	enum pci_barno bar;
	u32 data, status;
	u32 addr;
	int left;

	if (!(test->ep_caps & CAP_DYNAMIC_INBOUND_MAPPING))
		return -EOPNOTSUPP;

	if (irq_type < PCITEST_IRQ_TYPE_INTX ||
	    irq_type > PCITEST_IRQ_TYPE_MSIX) {
		dev_err(dev, "Invalid IRQ type\n");
		return -EINVAL;
	}

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
				 COMMAND_ENABLE_DOORBELL);

	left = wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));

	status = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
	if (!left || !(status & STATUS_DOORBELL_ENABLE_SUCCESS)) {
		dev_err(dev, "Failed to enable doorbell\n");
		return -EINVAL;
	}

	data = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_DATA);
	addr = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_OFFSET);

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_TYPE, irq_type);
	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_IRQ_NUMBER, 1);

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_STATUS, 0);

	bar = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_DB_BAR);
	if (bar < BAR_0 || bar >= PCI_STD_NUM_BARS) {
		dev_err(dev, "BAR %d reported by endpoint out of range [0, %u]\n",
			bar, PCI_STD_NUM_BARS - 1);
		return -ERANGE;
	}

	writel(data, test->bar[bar] + addr);

	left = wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));

	status = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);

	if (!left || !(status & STATUS_DOORBELL_SUCCESS)) {
		dev_err(dev, "Failed to trigger doorbell in endpoint\n");
		/* Store error code, but continue to disable doorbell. */
		ret = -EINVAL;
	}

	pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
				 COMMAND_DISABLE_DOORBELL);

	wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));

	status |= pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);

	if (!(status & STATUS_DOORBELL_DISABLE_SUCCESS)) {
		dev_err(dev, "Failed to disable doorbell\n");
		return -EINVAL;
	}

	return ret;
}

static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
				    unsigned long arg)
{
	int ret = -EINVAL;
	enum pci_barno bar;
	struct pci_endpoint_test *test = to_endpoint_test(file->private_data);
	struct pci_dev *pdev = test->pdev;

	mutex_lock(&test->mutex);

	reinit_completion(&test->irq_raised);
	test->last_irq = -ENODATA;

	switch (cmd) {
	case PCITEST_BAR:
	case PCITEST_BAR_SUBRANGE:
		bar = arg;
		if (bar <= NO_BAR || bar > BAR_5)
			goto ret;
		if (is_am654_pci_dev(pdev) && bar == BAR_0)
			goto ret;

		if (bar_is_reserved(test, bar)) {
			ret = -ENOBUFS;
			goto ret;
		}

		if (cmd == PCITEST_BAR)
			ret = pci_endpoint_test_bar(test, bar);
		else
			ret = pci_endpoint_test_bar_subrange(test, bar);
		break;
	case PCITEST_BARS:
		ret = pci_endpoint_test_bars(test);
		break;
	case PCITEST_INTX_IRQ:
		ret = pci_endpoint_test_intx_irq(test);
		break;
	case PCITEST_MSI:
	case PCITEST_MSIX:
		ret = pci_endpoint_test_msi_irq(test, arg, cmd == PCITEST_MSIX);
		break;
	case PCITEST_WRITE:
		ret = pci_endpoint_test_write(test, arg);
		break;
	case PCITEST_READ:
		ret = pci_endpoint_test_read(test, arg);
		break;
	case PCITEST_COPY:
		ret = pci_endpoint_test_copy(test, arg);
		break;
	case PCITEST_SET_IRQTYPE:
		ret = pci_endpoint_test_set_irq(test, arg);
		break;
	case PCITEST_GET_IRQTYPE:
		ret = test->irq_type;
		break;
	case PCITEST_CLEAR_IRQ:
		ret = pci_endpoint_test_clear_irq(test);
		break;
	case PCITEST_DOORBELL:
		ret = pci_endpoint_test_doorbell(test);
		break;
	}

ret:
	mutex_unlock(&test->mutex);
	return ret;
}

static const struct file_operations pci_endpoint_test_fops = {
	.owner = THIS_MODULE,
	.unlocked_ioctl = pci_endpoint_test_ioctl,
};

static void pci_endpoint_test_get_capabilities(struct pci_endpoint_test *test)
{
	struct pci_dev *pdev = test->pdev;
	struct device *dev = &pdev->dev;

	test->ep_caps = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CAPS);
	dev_dbg(dev, "PCI_ENDPOINT_TEST_CAPS: %#x\n", test->ep_caps);

	/* CAP_UNALIGNED_ACCESS is set if the EP can do unaligned access */
	if (test->ep_caps & CAP_UNALIGNED_ACCESS)
		test->alignment = 0;
}

static int pci_endpoint_test_probe(struct pci_dev *pdev,
				   const struct pci_device_id *ent)
{
	int ret;
	int id;
	char name[29];
	enum pci_barno bar;
	void __iomem *base;
	struct device *dev = &pdev->dev;
	struct pci_endpoint_test *test;
	struct pci_endpoint_test_data *data;
	enum pci_barno test_reg_bar = BAR_0;
	struct miscdevice *misc_device;

	if (pci_is_bridge(pdev))
		return -ENODEV;

	test = devm_kzalloc(dev, sizeof(*test), GFP_KERNEL);
	if (!test)
		return -ENOMEM;

	test->pdev = pdev;
	test->irq_type = PCITEST_IRQ_TYPE_UNDEFINED;

	data = (struct pci_endpoint_test_data *)ent->driver_data;
	if (data) {
		test_reg_bar = data->test_reg_bar;
		test->test_reg_bar = test_reg_bar;
		test->alignment = data->alignment;
	}

	init_completion(&test->irq_raised);
	mutex_init(&test->mutex);

	dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(48));

	ret = pci_enable_device(pdev);
	if (ret) {
		dev_err(dev, "Cannot enable PCI device\n");
		return ret;
	}

	ret = pci_request_regions(pdev, DRV_MODULE_NAME);
	if (ret) {
		dev_err(dev, "Cannot obtain PCI resources\n");
		goto err_disable_pdev;
	}

	pci_set_master(pdev);

	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
		if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
			base = pci_ioremap_bar(pdev, bar);
			if (!base) {
				dev_err(dev, "Failed to read BAR%d\n", bar);
				WARN_ON(bar == test_reg_bar);
			}
			test->bar[bar] = base;
		}
	}

	test->base = test->bar[test_reg_bar];
	if (!test->base) {
		ret = -ENOMEM;
		dev_err(dev, "Cannot perform PCI test without BAR%d\n",
			test_reg_bar);
		goto err_iounmap;
	}

	pci_set_drvdata(pdev, test);

	id = ida_alloc(&pci_endpoint_test_ida, GFP_KERNEL);
	if (id < 0) {
		ret = id;
		dev_err(dev, "Unable to get id\n");
		goto err_iounmap;
	}

	snprintf(name, sizeof(name), DRV_MODULE_NAME ".%d", id);
	test->name = kstrdup(name, GFP_KERNEL);
	if (!test->name) {
		ret = -ENOMEM;
		goto err_ida_remove;
	}

	pci_endpoint_test_get_capabilities(test);

	misc_device = &test->miscdev;
	misc_device->minor = MISC_DYNAMIC_MINOR;
	misc_device->name = kstrdup(name, GFP_KERNEL);
	if (!misc_device->name) {
		ret = -ENOMEM;
		goto err_kfree_test_name;
	}
	misc_device->parent = &pdev->dev;
	misc_device->fops = &pci_endpoint_test_fops;

	pci_save_state(pdev);

	ret = misc_register(misc_device);
	if (ret) {
		dev_err(dev, "Failed to register device\n");
		goto err_kfree_name;
	}

	return 0;

err_kfree_name:
	kfree(misc_device->name);

err_kfree_test_name:
	kfree(test->name);

err_ida_remove:
	ida_free(&pci_endpoint_test_ida, id);

err_iounmap:
	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
		if (test->bar[bar])
			pci_iounmap(pdev, test->bar[bar]);
	}

	pci_release_regions(pdev);

err_disable_pdev:
	pci_disable_device(pdev);

	return ret;
}

static void pci_endpoint_test_remove(struct pci_dev *pdev)
{
	int id;
	enum pci_barno bar;
	struct pci_endpoint_test *test = pci_get_drvdata(pdev);
	struct miscdevice *misc_device = &test->miscdev;

	if (sscanf(misc_device->name, DRV_MODULE_NAME ".%d", &id) != 1)
		return;
	if (id < 0)
		return;

	pci_endpoint_test_release_irq(test);
	pci_endpoint_test_free_irq_vectors(test);

	misc_deregister(&test->miscdev);
	kfree(misc_device->name);
	kfree(test->name);
	ida_free(&pci_endpoint_test_ida, id);
	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
		if (test->bar[bar])
			pci_iounmap(pdev, test->bar[bar]);
	}

	pci_release_regions(pdev);
	pci_disable_device(pdev);
}

static const struct pci_endpoint_test_data default_data = {
	.test_reg_bar = BAR_0,
	.alignment = SZ_4K,
};

static const struct pci_endpoint_test_data am654_data = {
	.test_reg_bar = BAR_2,
	.alignment = SZ_64K,
};

static const struct pci_endpoint_test_data j721e_data = {
	.alignment = 256,
};

static const struct pci_endpoint_test_data rk3588_data = {
	.alignment = SZ_64K,
};

/*
 * If the controller's Vendor/Device ID are programmable, you may be able to
 * use one of the existing entries for testing instead of adding a new one.
 */
static const struct pci_device_id pci_endpoint_test_tbl[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x),
	  .driver_data = (kernel_ulong_t)&default_data,
	},
	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x),
	  .driver_data = (kernel_ulong_t)&default_data,
	},
	{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x81c0),
	  .driver_data = (kernel_ulong_t)&default_data,
	},
	{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_IMX8) },
	{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_LS1088A),
	  .driver_data = (kernel_ulong_t)&default_data,
	},
	{ PCI_DEVICE_DATA(SYNOPSYS, EDDA, NULL) },
	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654),
	  .driver_data = (kernel_ulong_t)&am654_data,
	},
	{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774A1) },
	{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774B1) },
	{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774C0) },
	{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A774E1) },
	{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS, PCI_DEVICE_ID_RENESAS_R8A779F0),
	  .driver_data = (kernel_ulong_t)&default_data,
	},
	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J721E),
	  .driver_data = (kernel_ulong_t)&j721e_data,
	},
	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J7200),
	  .driver_data = (kernel_ulong_t)&j721e_data,
	},
	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM64),
	  .driver_data = (kernel_ulong_t)&j721e_data,
	},
	{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J721S2),
	  .driver_data = (kernel_ulong_t)&j721e_data,
	},
	{ PCI_DEVICE(PCI_VENDOR_ID_ROCKCHIP, PCI_DEVICE_ID_ROCKCHIP_RK3588),
	  .driver_data = (kernel_ulong_t)&rk3588_data,
	},
	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TEGRA194_EP) },
	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TEGRA234_EP) },
	{ }
};
MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);

static pci_ers_result_t pci_endpoint_test_error_detected(struct pci_dev *pdev,
					      pci_channel_state_t state)
{
	if (state == pci_channel_io_perm_failure)
		return PCI_ERS_RESULT_DISCONNECT;

	return PCI_ERS_RESULT_NEED_RESET;
}

static pci_ers_result_t pci_endpoint_test_slot_reset(struct pci_dev *pdev)
{
	pci_restore_state(pdev);
	return PCI_ERS_RESULT_RECOVERED;
}

static const struct pci_error_handlers pci_endpoint_test_err_handler = {
	.error_detected = pci_endpoint_test_error_detected,
	.slot_reset = pci_endpoint_test_slot_reset,
};

static struct pci_driver pci_endpoint_test_driver = {
	.name		= DRV_MODULE_NAME,
	.id_table	= pci_endpoint_test_tbl,
	.probe		= pci_endpoint_test_probe,
	.remove		= pci_endpoint_test_remove,
	.sriov_configure = pci_sriov_configure_simple,
	.err_handler    = &pci_endpoint_test_err_handler,
};
module_pci_driver(pci_endpoint_test_driver);

MODULE_DESCRIPTION("PCI ENDPOINT TEST HOST DRIVER");
MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
MODULE_LICENSE("GPL v2");
