// SPDX-License-Identifier: GPL-2.0 OR MIT

/*
 *  Xen para-virtual DRM device
 *
 * Copyright (C) 2016-2018 EPAM Systems Inc.
 *
 * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
 */

#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>

#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_ioctl.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_file.h>
#include <drm/drm_gem.h>

#include <xen/platform_pci.h>
#include <xen/xen.h>
#include <xen/xenbus.h>

#include <xen/xen-front-pgdir-shbuf.h>
#include <xen/interface/io/displif.h>

#include "xen_drm_front.h"
#include "xen_drm_front_cfg.h"
#include "xen_drm_front_evtchnl.h"
#include "xen_drm_front_gem.h"
#include "xen_drm_front_kms.h"

struct xen_drm_front_dbuf {
	struct list_head list;
	u64 dbuf_cookie;
	u64 fb_cookie;

	struct xen_front_pgdir_shbuf shbuf;
};

static void dbuf_add_to_list(struct xen_drm_front_info *front_info,
			     struct xen_drm_front_dbuf *dbuf, u64 dbuf_cookie)
{
	dbuf->dbuf_cookie = dbuf_cookie;
	list_add(&dbuf->list, &front_info->dbuf_list);
}

static struct xen_drm_front_dbuf *dbuf_get(struct list_head *dbuf_list,
					   u64 dbuf_cookie)
{
	struct xen_drm_front_dbuf *buf, *q;

	list_for_each_entry_safe(buf, q, dbuf_list, list)
		if (buf->dbuf_cookie == dbuf_cookie)
			return buf;

	return NULL;
}

static void dbuf_free(struct list_head *dbuf_list, u64 dbuf_cookie)
{
	struct xen_drm_front_dbuf *buf, *q;

	list_for_each_entry_safe(buf, q, dbuf_list, list)
		if (buf->dbuf_cookie == dbuf_cookie) {
			list_del(&buf->list);
			xen_front_pgdir_shbuf_unmap(&buf->shbuf);
			xen_front_pgdir_shbuf_free(&buf->shbuf);
			kfree(buf);
			break;
		}
}

static void dbuf_free_all(struct list_head *dbuf_list)
{
	struct xen_drm_front_dbuf *buf, *q;

	list_for_each_entry_safe(buf, q, dbuf_list, list) {
		list_del(&buf->list);
		xen_front_pgdir_shbuf_unmap(&buf->shbuf);
		xen_front_pgdir_shbuf_free(&buf->shbuf);
		kfree(buf);
	}
}

static struct xendispl_req *
be_prepare_req(struct xen_drm_front_evtchnl *evtchnl, u8 operation)
{
	struct xendispl_req *req;

	req = RING_GET_REQUEST(&evtchnl->u.req.ring,
			       evtchnl->u.req.ring.req_prod_pvt);
	req->operation = operation;
	req->id = evtchnl->evt_next_id++;
	evtchnl->evt_id = req->id;
	return req;
}

static int be_stream_do_io(struct xen_drm_front_evtchnl *evtchnl,
			   struct xendispl_req *req)
{
	reinit_completion(&evtchnl->u.req.completion);
	if (unlikely(evtchnl->state != EVTCHNL_STATE_CONNECTED))
		return -EIO;

	xen_drm_front_evtchnl_flush(evtchnl);
	return 0;
}

static int be_stream_wait_io(struct xen_drm_front_evtchnl *evtchnl)
{
	if (wait_for_completion_timeout(&evtchnl->u.req.completion,
			msecs_to_jiffies(XEN_DRM_FRONT_WAIT_BACK_MS)) <= 0)
		return -ETIMEDOUT;

	return evtchnl->u.req.resp_status;
}

int xen_drm_front_mode_set(struct xen_drm_front_drm_pipeline *pipeline,
			   u32 x, u32 y, u32 width, u32 height,
			   u32 bpp, u64 fb_cookie)
{
	struct xen_drm_front_evtchnl *evtchnl;
	struct xen_drm_front_info *front_info;
	struct xendispl_req *req;
	unsigned long flags;
	int ret;

	front_info = pipeline->drm_info->front_info;
	evtchnl = &front_info->evt_pairs[pipeline->index].req;
	if (unlikely(!evtchnl))
		return -EIO;

	mutex_lock(&evtchnl->u.req.req_io_lock);

	spin_lock_irqsave(&front_info->io_lock, flags);
	req = be_prepare_req(evtchnl, XENDISPL_OP_SET_CONFIG);
	req->op.set_config.x = x;
	req->op.set_config.y = y;
	req->op.set_config.width = width;
	req->op.set_config.height = height;
	req->op.set_config.bpp = bpp;
	req->op.set_config.fb_cookie = fb_cookie;

	ret = be_stream_do_io(evtchnl, req);
	spin_unlock_irqrestore(&front_info->io_lock, flags);

	if (ret == 0)
		ret = be_stream_wait_io(evtchnl);

	mutex_unlock(&evtchnl->u.req.req_io_lock);
	return ret;
}

int xen_drm_front_dbuf_create(struct xen_drm_front_info *front_info,
			      u64 dbuf_cookie, u32 width, u32 height,
			      u32 bpp, u64 size, u32 offset,
			      struct page **pages)
{
	struct xen_drm_front_evtchnl *evtchnl;
	struct xen_drm_front_dbuf *dbuf;
	struct xendispl_req *req;
	struct xen_front_pgdir_shbuf_cfg buf_cfg;
	unsigned long flags;
	int ret;

	evtchnl = &front_info->evt_pairs[GENERIC_OP_EVT_CHNL].req;
	if (unlikely(!evtchnl))
		return -EIO;

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

	dbuf_add_to_list(front_info, dbuf, dbuf_cookie);

	memset(&buf_cfg, 0, sizeof(buf_cfg));
	buf_cfg.xb_dev = front_info->xb_dev;
	buf_cfg.num_pages = DIV_ROUND_UP(size, PAGE_SIZE);
	buf_cfg.pages = pages;
	buf_cfg.pgdir = &dbuf->shbuf;
	buf_cfg.be_alloc = front_info->cfg.be_alloc;

	ret = xen_front_pgdir_shbuf_alloc(&buf_cfg);
	if (ret < 0)
		goto fail_shbuf_alloc;

	mutex_lock(&evtchnl->u.req.req_io_lock);

	spin_lock_irqsave(&front_info->io_lock, flags);
	req = be_prepare_req(evtchnl, XENDISPL_OP_DBUF_CREATE);
	req->op.dbuf_create.gref_directory =
			xen_front_pgdir_shbuf_get_dir_start(&dbuf->shbuf);
	req->op.dbuf_create.buffer_sz = size;
	req->op.dbuf_create.data_ofs = offset;
	req->op.dbuf_create.dbuf_cookie = dbuf_cookie;
	req->op.dbuf_create.width = width;
	req->op.dbuf_create.height = height;
	req->op.dbuf_create.bpp = bpp;
	if (buf_cfg.be_alloc)
		req->op.dbuf_create.flags |= XENDISPL_DBUF_FLG_REQ_ALLOC;

	ret = be_stream_do_io(evtchnl, req);
	spin_unlock_irqrestore(&front_info->io_lock, flags);

	if (ret < 0)
		goto fail;

	ret = be_stream_wait_io(evtchnl);
	if (ret < 0)
		goto fail;

	ret = xen_front_pgdir_shbuf_map(&dbuf->shbuf);
	if (ret < 0)
		goto fail;

	mutex_unlock(&evtchnl->u.req.req_io_lock);
	return 0;

fail:
	mutex_unlock(&evtchnl->u.req.req_io_lock);
fail_shbuf_alloc:
	dbuf_free(&front_info->dbuf_list, dbuf_cookie);
	return ret;
}

static int xen_drm_front_dbuf_destroy(struct xen_drm_front_info *front_info,
				      u64 dbuf_cookie)
{
	struct xen_drm_front_evtchnl *evtchnl;
	struct xendispl_req *req;
	unsigned long flags;
	bool be_alloc;
	int ret;

	evtchnl = &front_info->evt_pairs[GENERIC_OP_EVT_CHNL].req;
	if (unlikely(!evtchnl))
		return -EIO;

	be_alloc = front_info->cfg.be_alloc;

	/*
	 * For the backend allocated buffer release references now, so backend
	 * can free the buffer.
	 */
	if (be_alloc)
		dbuf_free(&front_info->dbuf_list, dbuf_cookie);

	mutex_lock(&evtchnl->u.req.req_io_lock);

	spin_lock_irqsave(&front_info->io_lock, flags);
	req = be_prepare_req(evtchnl, XENDISPL_OP_DBUF_DESTROY);
	req->op.dbuf_destroy.dbuf_cookie = dbuf_cookie;

	ret = be_stream_do_io(evtchnl, req);
	spin_unlock_irqrestore(&front_info->io_lock, flags);

	if (ret == 0)
		ret = be_stream_wait_io(evtchnl);

	/*
	 * Do this regardless of communication status with the backend:
	 * if we cannot remove remote resources remove what we can locally.
	 */
	if (!be_alloc)
		dbuf_free(&front_info->dbuf_list, dbuf_cookie);

	mutex_unlock(&evtchnl->u.req.req_io_lock);
	return ret;
}

int xen_drm_front_fb_attach(struct xen_drm_front_info *front_info,
			    u64 dbuf_cookie, u64 fb_cookie, u32 width,
			    u32 height, u32 pixel_format)
{
	struct xen_drm_front_evtchnl *evtchnl;
	struct xen_drm_front_dbuf *buf;
	struct xendispl_req *req;
	unsigned long flags;
	int ret;

	evtchnl = &front_info->evt_pairs[GENERIC_OP_EVT_CHNL].req;
	if (unlikely(!evtchnl))
		return -EIO;

	buf = dbuf_get(&front_info->dbuf_list, dbuf_cookie);
	if (!buf)
		return -EINVAL;

	buf->fb_cookie = fb_cookie;

	mutex_lock(&evtchnl->u.req.req_io_lock);

	spin_lock_irqsave(&front_info->io_lock, flags);
	req = be_prepare_req(evtchnl, XENDISPL_OP_FB_ATTACH);
	req->op.fb_attach.dbuf_cookie = dbuf_cookie;
	req->op.fb_attach.fb_cookie = fb_cookie;
	req->op.fb_attach.width = width;
	req->op.fb_attach.height = height;
	req->op.fb_attach.pixel_format = pixel_format;

	ret = be_stream_do_io(evtchnl, req);
	spin_unlock_irqrestore(&front_info->io_lock, flags);

	if (ret == 0)
		ret = be_stream_wait_io(evtchnl);

	mutex_unlock(&evtchnl->u.req.req_io_lock);
	return ret;
}

int xen_drm_front_fb_detach(struct xen_drm_front_info *front_info,
			    u64 fb_cookie)
{
	struct xen_drm_front_evtchnl *evtchnl;
	struct xendispl_req *req;
	unsigned long flags;
	int ret;

	evtchnl = &front_info->evt_pairs[GENERIC_OP_EVT_CHNL].req;
	if (unlikely(!evtchnl))
		return -EIO;

	mutex_lock(&evtchnl->u.req.req_io_lock);

	spin_lock_irqsave(&front_info->io_lock, flags);
	req = be_prepare_req(evtchnl, XENDISPL_OP_FB_DETACH);
	req->op.fb_detach.fb_cookie = fb_cookie;

	ret = be_stream_do_io(evtchnl, req);
	spin_unlock_irqrestore(&front_info->io_lock, flags);

	if (ret == 0)
		ret = be_stream_wait_io(evtchnl);

	mutex_unlock(&evtchnl->u.req.req_io_lock);
	return ret;
}

int xen_drm_front_page_flip(struct xen_drm_front_info *front_info,
			    int conn_idx, u64 fb_cookie)
{
	struct xen_drm_front_evtchnl *evtchnl;
	struct xendispl_req *req;
	unsigned long flags;
	int ret;

	if (unlikely(conn_idx >= front_info->num_evt_pairs))
		return -EINVAL;

	evtchnl = &front_info->evt_pairs[conn_idx].req;

	mutex_lock(&evtchnl->u.req.req_io_lock);

	spin_lock_irqsave(&front_info->io_lock, flags);
	req = be_prepare_req(evtchnl, XENDISPL_OP_PG_FLIP);
	req->op.pg_flip.fb_cookie = fb_cookie;

	ret = be_stream_do_io(evtchnl, req);
	spin_unlock_irqrestore(&front_info->io_lock, flags);

	if (ret == 0)
		ret = be_stream_wait_io(evtchnl);

	mutex_unlock(&evtchnl->u.req.req_io_lock);
	return ret;
}

void xen_drm_front_on_frame_done(struct xen_drm_front_info *front_info,
				 int conn_idx, u64 fb_cookie)
{
	struct xen_drm_front_drm_info *drm_info = front_info->drm_info;

	if (unlikely(conn_idx >= front_info->cfg.num_connectors))
		return;

	xen_drm_front_kms_on_frame_done(&drm_info->pipeline[conn_idx],
					fb_cookie);
}

void xen_drm_front_gem_object_free(struct drm_gem_object *obj)
{
	struct xen_drm_front_drm_info *drm_info = obj->dev->dev_private;
	int idx;

	if (drm_dev_enter(obj->dev, &idx)) {
		xen_drm_front_dbuf_destroy(drm_info->front_info,
					   xen_drm_front_dbuf_to_cookie(obj));
		drm_dev_exit(idx);
	} else {
		dbuf_free(&drm_info->front_info->dbuf_list,
			  xen_drm_front_dbuf_to_cookie(obj));
	}

	xen_drm_front_gem_free_object_unlocked(obj);
}

static int xen_drm_drv_dumb_create(struct drm_file *filp,
				   struct drm_device *dev,
				   struct drm_mode_create_dumb *args)
{
	struct xen_drm_front_drm_info *drm_info = dev->dev_private;
	struct drm_gem_object *obj;
	int ret;

	/*
	 * Dumb creation is a two stage process: first we create a fully
	 * constructed GEM object which is communicated to the backend, and
	 * only after that we can create GEM's handle. This is done so,
	 * because of the possible races: once you create a handle it becomes
	 * immediately visible to user-space, so the latter can try accessing
	 * object without pages etc.
	 * For details also see drm_gem_handle_create
	 */
	args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
	args->size = args->pitch * args->height;

	obj = xen_drm_front_gem_create(dev, args->size);
	if (IS_ERR(obj)) {
		ret = PTR_ERR(obj);
		goto fail;
	}

	ret = xen_drm_front_dbuf_create(drm_info->front_info,
					xen_drm_front_dbuf_to_cookie(obj),
					args->width, args->height, args->bpp,
					args->size, 0,
					xen_drm_front_gem_get_pages(obj));
	if (ret)
		goto fail_backend;

	/* This is the tail of GEM object creation */
	ret = drm_gem_handle_create(filp, obj, &args->handle);
	if (ret)
		goto fail_handle;

	/* Drop reference from allocate - handle holds it now */
	drm_gem_object_put(obj);
	return 0;

fail_handle:
	xen_drm_front_dbuf_destroy(drm_info->front_info,
				   xen_drm_front_dbuf_to_cookie(obj));
fail_backend:
	/* drop reference from allocate */
	drm_gem_object_put(obj);
fail:
	DRM_ERROR("Failed to create dumb buffer: %d\n", ret);
	return ret;
}

static void xen_drm_drv_release(struct drm_device *dev)
{
	struct xen_drm_front_drm_info *drm_info = dev->dev_private;
	struct xen_drm_front_info *front_info = drm_info->front_info;

	xen_drm_front_kms_fini(drm_info);

	drm_atomic_helper_shutdown(dev);
	drm_mode_config_cleanup(dev);

	if (front_info->cfg.be_alloc)
		xenbus_switch_state(front_info->xb_dev,
				    XenbusStateInitialising);

	kfree(drm_info);
}

DEFINE_DRM_GEM_FOPS(xen_drm_dev_fops);

static const struct drm_driver xen_drm_driver = {
	.driver_features           = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
	.release                   = xen_drm_drv_release,
	.gem_prime_import_sg_table = xen_drm_front_gem_import_sg_table,
	.dumb_create               = xen_drm_drv_dumb_create,
	.fops                      = &xen_drm_dev_fops,
	.name                      = "xendrm-du",
	.desc                      = "Xen PV DRM Display Unit",
	.major                     = 1,
	.minor                     = 0,

};

static int xen_drm_drv_init(struct xen_drm_front_info *front_info)
{
	struct device *dev = &front_info->xb_dev->dev;
	struct xen_drm_front_drm_info *drm_info;
	struct drm_device *drm_dev;
	int ret;

	if (drm_firmware_drivers_only())
		return -ENODEV;

	DRM_INFO("Creating %s\n", xen_drm_driver.desc);

	drm_info = kzalloc(sizeof(*drm_info), GFP_KERNEL);
	if (!drm_info) {
		ret = -ENOMEM;
		goto fail;
	}

	drm_info->front_info = front_info;
	front_info->drm_info = drm_info;

	drm_dev = drm_dev_alloc(&xen_drm_driver, dev);
	if (IS_ERR(drm_dev)) {
		ret = PTR_ERR(drm_dev);
		goto fail_dev;
	}

	drm_info->drm_dev = drm_dev;

	drm_dev->dev_private = drm_info;

	ret = xen_drm_front_kms_init(drm_info);
	if (ret) {
		DRM_ERROR("Failed to initialize DRM/KMS, ret %d\n", ret);
		goto fail_modeset;
	}

	ret = drm_dev_register(drm_dev, 0);
	if (ret)
		goto fail_register;

	return 0;

fail_register:
	drm_dev_unregister(drm_dev);
fail_modeset:
	drm_kms_helper_poll_fini(drm_dev);
	drm_mode_config_cleanup(drm_dev);
	drm_dev_put(drm_dev);
fail_dev:
	kfree(drm_info);
	front_info->drm_info = NULL;
fail:
	return ret;
}

static void xen_drm_drv_fini(struct xen_drm_front_info *front_info)
{
	struct xen_drm_front_drm_info *drm_info = front_info->drm_info;
	struct drm_device *dev;

	if (!drm_info)
		return;

	dev = drm_info->drm_dev;
	if (!dev)
		return;

	/* Nothing to do if device is already unplugged */
	if (drm_dev_is_unplugged(dev))
		return;

	drm_kms_helper_poll_fini(dev);
	drm_dev_unplug(dev);
	drm_dev_put(dev);

	front_info->drm_info = NULL;

	xen_drm_front_evtchnl_free_all(front_info);
	dbuf_free_all(&front_info->dbuf_list);

	/*
	 * If we are not using backend allocated buffers, then tell the
	 * backend we are ready to (re)initialize. Otherwise, wait for
	 * drm_driver.release.
	 */
	if (!front_info->cfg.be_alloc)
		xenbus_switch_state(front_info->xb_dev,
				    XenbusStateInitialising);
}

static int displback_initwait(struct xen_drm_front_info *front_info)
{
	struct xen_drm_front_cfg *cfg = &front_info->cfg;
	int ret;

	cfg->front_info = front_info;
	ret = xen_drm_front_cfg_card(front_info, cfg);
	if (ret < 0)
		return ret;

	DRM_INFO("Have %d connector(s)\n", cfg->num_connectors);
	/* Create event channels for all connectors and publish */
	ret = xen_drm_front_evtchnl_create_all(front_info);
	if (ret < 0)
		return ret;

	return xen_drm_front_evtchnl_publish_all(front_info);
}

static int displback_connect(struct xen_drm_front_info *front_info)
{
	xen_drm_front_evtchnl_set_state(front_info, EVTCHNL_STATE_CONNECTED);
	return xen_drm_drv_init(front_info);
}

static void displback_disconnect(struct xen_drm_front_info *front_info)
{
	if (!front_info->drm_info)
		return;

	/* Tell the backend to wait until we release the DRM driver. */
	xenbus_switch_state(front_info->xb_dev, XenbusStateReconfiguring);

	xen_drm_drv_fini(front_info);
}

static void displback_changed(struct xenbus_device *xb_dev,
			      enum xenbus_state backend_state)
{
	struct xen_drm_front_info *front_info = dev_get_drvdata(&xb_dev->dev);
	int ret;

	DRM_DEBUG("Backend state is %s, front is %s\n",
		  xenbus_strstate(backend_state),
		  xenbus_strstate(xb_dev->state));

	switch (backend_state) {
	case XenbusStateReconfiguring:
	case XenbusStateReconfigured:
	case XenbusStateInitialised:
		break;

	case XenbusStateInitialising:
		if (xb_dev->state == XenbusStateReconfiguring)
			break;

		/* recovering after backend unexpected closure */
		displback_disconnect(front_info);
		break;

	case XenbusStateInitWait:
		if (xb_dev->state == XenbusStateReconfiguring)
			break;

		/* recovering after backend unexpected closure */
		displback_disconnect(front_info);
		if (xb_dev->state != XenbusStateInitialising)
			break;

		ret = displback_initwait(front_info);
		if (ret < 0)
			xenbus_dev_fatal(xb_dev, ret, "initializing frontend");
		else
			xenbus_switch_state(xb_dev, XenbusStateInitialised);
		break;

	case XenbusStateConnected:
		if (xb_dev->state != XenbusStateInitialised)
			break;

		ret = displback_connect(front_info);
		if (ret < 0) {
			displback_disconnect(front_info);
			xenbus_dev_fatal(xb_dev, ret, "connecting backend");
		} else {
			xenbus_switch_state(xb_dev, XenbusStateConnected);
		}
		break;

	case XenbusStateClosing:
		/*
		 * in this state backend starts freeing resources,
		 * so let it go into closed state, so we can also
		 * remove ours
		 */
		break;

	case XenbusStateUnknown:
	case XenbusStateClosed:
		if (xb_dev->state == XenbusStateClosed)
			break;

		displback_disconnect(front_info);
		break;
	}
}

static int xen_drv_probe(struct xenbus_device *xb_dev,
			 const struct xenbus_device_id *id)
{
	struct xen_drm_front_info *front_info;
	struct device *dev = &xb_dev->dev;
	int ret;

	ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64));
	if (ret < 0) {
		DRM_ERROR("Cannot setup DMA mask, ret %d", ret);
		return ret;
	}

	front_info = devm_kzalloc(&xb_dev->dev,
				  sizeof(*front_info), GFP_KERNEL);
	if (!front_info)
		return -ENOMEM;

	front_info->xb_dev = xb_dev;
	spin_lock_init(&front_info->io_lock);
	INIT_LIST_HEAD(&front_info->dbuf_list);
	dev_set_drvdata(&xb_dev->dev, front_info);

	return xenbus_switch_state(xb_dev, XenbusStateInitialising);
}

static void xen_drv_remove(struct xenbus_device *dev)
{
	struct xen_drm_front_info *front_info = dev_get_drvdata(&dev->dev);
	int to = 100;

	xenbus_switch_state(dev, XenbusStateClosing);

	/*
	 * On driver removal it is disconnected from XenBus,
	 * so no backend state change events come via .otherend_changed
	 * callback. This prevents us from exiting gracefully, e.g.
	 * signaling the backend to free event channels, waiting for its
	 * state to change to XenbusStateClosed and cleaning at our end.
	 * Normally when front driver removed backend will finally go into
	 * XenbusStateInitWait state.
	 *
	 * Workaround: read backend's state manually and wait with time-out.
	 */
	while ((xenbus_read_unsigned(front_info->xb_dev->otherend, "state",
				     XenbusStateUnknown) != XenbusStateInitWait) &&
				     --to)
		msleep(10);

	if (!to) {
		unsigned int state;

		state = xenbus_read_unsigned(front_info->xb_dev->otherend,
					     "state", XenbusStateUnknown);
		DRM_ERROR("Backend state is %s while removing driver\n",
			  xenbus_strstate(state));
	}

	xen_drm_drv_fini(front_info);
	xenbus_frontend_closed(dev);
}

static const struct xenbus_device_id xen_driver_ids[] = {
	{ XENDISPL_DRIVER_NAME },
	{ "" }
};

static struct xenbus_driver xen_driver = {
	.ids = xen_driver_ids,
	.probe = xen_drv_probe,
	.remove = xen_drv_remove,
	.otherend_changed = displback_changed,
	.not_essential = true,
};

static int __init xen_drv_init(void)
{
	/* At the moment we only support case with XEN_PAGE_SIZE == PAGE_SIZE */
	if (XEN_PAGE_SIZE != PAGE_SIZE) {
		DRM_ERROR(XENDISPL_DRIVER_NAME ": different kernel and Xen page sizes are not supported: XEN_PAGE_SIZE (%lu) != PAGE_SIZE (%lu)\n",
			  XEN_PAGE_SIZE, PAGE_SIZE);
		return -ENODEV;
	}

	if (!xen_domain())
		return -ENODEV;

	if (!xen_has_pv_devices())
		return -ENODEV;

	DRM_INFO("Registering XEN PV " XENDISPL_DRIVER_NAME "\n");
	return xenbus_register_frontend(&xen_driver);
}

static void __exit xen_drv_fini(void)
{
	DRM_INFO("Unregistering XEN PV " XENDISPL_DRIVER_NAME "\n");
	xenbus_unregister_driver(&xen_driver);
}

module_init(xen_drv_init);
module_exit(xen_drv_fini);

MODULE_DESCRIPTION("Xen para-virtualized display device frontend");
MODULE_LICENSE("GPL");
MODULE_ALIAS("xen:" XENDISPL_DRIVER_NAME);
