// SPDX-License-Identifier: GPL-2.0
/*
 * virtio_pmem.c: Virtio pmem Driver
 *
 * Discovers persistent memory range information
 * from host and registers the virtual pmem device
 * with libnvdimm core.
 */
#include "virtio_pmem.h"
#include "nd.h"

static struct virtio_device_id id_table[] = {
	{ VIRTIO_ID_PMEM, VIRTIO_DEV_ANY_ID },
	{ 0 },
};

 /* Initialize virt queue */
static int init_vq(struct virtio_pmem *vpmem)
{
	/* single vq */
	vpmem->req_vq = virtio_find_single_vq(vpmem->vdev,
					virtio_pmem_host_ack, "flush_queue");
	if (IS_ERR(vpmem->req_vq))
		return PTR_ERR(vpmem->req_vq);

	spin_lock_init(&vpmem->pmem_lock);
	INIT_LIST_HEAD(&vpmem->req_list);

	return 0;
};

static int virtio_pmem_validate(struct virtio_device *vdev)
{
	struct virtio_shm_region shm_reg;

	if (virtio_has_feature(vdev, VIRTIO_PMEM_F_SHMEM_REGION) &&
		!virtio_get_shm_region(vdev, &shm_reg, (u8)VIRTIO_PMEM_SHMEM_REGION_ID)
	) {
		dev_notice(&vdev->dev, "failed to get shared memory region %d\n",
				VIRTIO_PMEM_SHMEM_REGION_ID);
		__virtio_clear_bit(vdev, VIRTIO_PMEM_F_SHMEM_REGION);
	}
	return 0;
}

static int virtio_pmem_probe(struct virtio_device *vdev)
{
	struct nd_region_desc ndr_desc = {};
	struct nd_region *nd_region;
	struct virtio_pmem *vpmem;
	struct resource res;
	struct virtio_shm_region shm_reg;
	int err = 0;

	if (!vdev->config->get) {
		dev_err(&vdev->dev, "%s failure: config access disabled\n",
			__func__);
		return -EINVAL;
	}

	vpmem = devm_kzalloc(&vdev->dev, sizeof(*vpmem), GFP_KERNEL);
	if (!vpmem) {
		err = -ENOMEM;
		goto out_err;
	}

	vpmem->vdev = vdev;
	vdev->priv = vpmem;
	err = init_vq(vpmem);
	if (err) {
		dev_err(&vdev->dev, "failed to initialize virtio pmem vq's\n");
		goto out_err;
	}

	if (virtio_has_feature(vdev, VIRTIO_PMEM_F_SHMEM_REGION)) {
		virtio_get_shm_region(vdev, &shm_reg, (u8)VIRTIO_PMEM_SHMEM_REGION_ID);
		vpmem->start = shm_reg.addr;
		vpmem->size = shm_reg.len;
	} else {
		virtio_cread_le(vpmem->vdev, struct virtio_pmem_config,
				start, &vpmem->start);
		virtio_cread_le(vpmem->vdev, struct virtio_pmem_config,
				size, &vpmem->size);
	}

	res.start = vpmem->start;
	res.end   = vpmem->start + vpmem->size - 1;
	vpmem->nd_desc.provider_name = "virtio-pmem";
	vpmem->nd_desc.module = THIS_MODULE;

	vpmem->nvdimm_bus = nvdimm_bus_register(&vdev->dev,
						&vpmem->nd_desc);
	if (!vpmem->nvdimm_bus) {
		dev_err(&vdev->dev, "failed to register device with nvdimm_bus\n");
		err = -ENXIO;
		goto out_vq;
	}

	dev_set_drvdata(&vdev->dev, vpmem->nvdimm_bus);

	ndr_desc.res = &res;

	ndr_desc.numa_node = memory_add_physaddr_to_nid(res.start);
	ndr_desc.target_node = phys_to_target_node(res.start);
	if (ndr_desc.target_node == NUMA_NO_NODE) {
		ndr_desc.target_node = ndr_desc.numa_node;
		dev_dbg(&vdev->dev, "changing target node from %d to %d",
			NUMA_NO_NODE, ndr_desc.target_node);
	}

	ndr_desc.flush = async_pmem_flush;
	ndr_desc.provider_data = vdev;
	set_bit(ND_REGION_PAGEMAP, &ndr_desc.flags);
	set_bit(ND_REGION_ASYNC, &ndr_desc.flags);
	/*
	 * The NVDIMM region could be available before the
	 * virtio_device_ready() that is called by
	 * virtio_dev_probe(), so we set device ready here.
	 */
	virtio_device_ready(vdev);
	nd_region = nvdimm_pmem_region_create(vpmem->nvdimm_bus, &ndr_desc);
	if (!nd_region) {
		dev_err(&vdev->dev, "failed to create nvdimm region\n");
		err = -ENXIO;
		goto out_nd;
	}
	return 0;
out_nd:
	virtio_reset_device(vdev);
	nvdimm_bus_unregister(vpmem->nvdimm_bus);
out_vq:
	vdev->config->del_vqs(vdev);
out_err:
	return err;
}

static void virtio_pmem_remove(struct virtio_device *vdev)
{
	struct nvdimm_bus *nvdimm_bus = dev_get_drvdata(&vdev->dev);

	nvdimm_bus_unregister(nvdimm_bus);
	vdev->config->del_vqs(vdev);
	virtio_reset_device(vdev);
}

static unsigned int features[] = {
	VIRTIO_PMEM_F_SHMEM_REGION,
};

static struct virtio_driver virtio_pmem_driver = {
	.feature_table		= features,
	.feature_table_size	= ARRAY_SIZE(features),
	.driver.name		= KBUILD_MODNAME,
	.driver.owner		= THIS_MODULE,
	.id_table		= id_table,
	.validate		= virtio_pmem_validate,
	.probe			= virtio_pmem_probe,
	.remove			= virtio_pmem_remove,
};

module_virtio_driver(virtio_pmem_driver);
MODULE_DEVICE_TABLE(virtio, id_table);
MODULE_DESCRIPTION("Virtio pmem driver");
MODULE_LICENSE("GPL");
