Received: by 10.223.185.116 with SMTP id b49csp2387038wrg; Mon, 5 Mar 2018 01:51:20 -0800 (PST) X-Google-Smtp-Source: AG47ELs7cL/f6hFIchGk/5HVwN7LYS25DdyvArg4eE2imQmTS1br9AY6SGf459R+ryxh6hthV4+V X-Received: by 10.99.120.197 with SMTP id t188mr11798134pgc.358.1520243480355; Mon, 05 Mar 2018 01:51:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520243480; cv=none; d=google.com; s=arc-20160816; b=tdu4fWxlrG0G2rTs0izHm67LR4Bqr13YTR1liRCcEH8Is1OC5z0Dn8y/892sLnLlYA NoxKUyQhktTOlLbDpale/mxZJieorD99YCotCvGyHEquW9e9pEO8HJ084JfJTnIx+6oc sJPNGk12NGOsLxRdCpOq4MkixH0dHWyyfOoIccEPCDOcTAqQNENmJwf8mCCxPqJUE+kt XBGroBRPzD4Bux6CLD6V+koDubXhu1t367F56GDrCglHDTR5lnj3OemQSdd0enQq66lJ oQKA4u+9x9K4guwON3P/8eDGP4fbHDEAFnH0Uz5mndIosYQZpszt2vCqSbPIW0fdJfcQ itiw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:mail-followup-to :message-id:subject:cc:to:from:date:dkim-signature :arc-authentication-results; bh=xKqvw99ovVY7a4nvzAilcjCs3iebIjUPR+jJfTUEa1Q=; b=oM1gQ055MmhGlMuWkULVGkyFsQMMN+/ZGiw50LBSA5o6oOd9L53b0aQGyQCZFfes3C W7rbhKpwZhIqNrDbN8nUnxElEIBEYSIuOI4xgMDsMK2xB5yVLihswIqqoZmvZAQqItcc O6+cS/GEyXLhr6uXf7/5SLVod5HuT2+jouQ+zWBKCuIfPfnF3DoIB3B/JcRpZ4madI7g 3Ah1OTG6d4z4nBKgyQDmHB+3UPsmABIIbDeRvWc1qUO6LtOFy5wmjwZiENEqFqFVtkBE Q2hHHKfv152YImJLwQP6mo6O4+fz+AhsmAbCcF1974eRqhnZxOz4rhmTfDfIk4NlSvLS DDdw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@ffwll.ch header.s=google header.b=ShJu302X; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f3-v6si9065222pld.200.2018.03.05.01.51.05; Mon, 05 Mar 2018 01:51:20 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@ffwll.ch header.s=google header.b=ShJu302X; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933362AbeCEJNq (ORCPT + 99 others); Mon, 5 Mar 2018 04:13:46 -0500 Received: from mail-wm0-f65.google.com ([74.125.82.65]:55766 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932721AbeCEJNk (ORCPT ); Mon, 5 Mar 2018 04:13:40 -0500 Received: by mail-wm0-f65.google.com with SMTP id q83so14323671wme.5 for ; Mon, 05 Mar 2018 01:13:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=sender:date:from:to:cc:subject:message-id:mail-followup-to :references:mime-version:content-disposition:in-reply-to:user-agent; bh=xKqvw99ovVY7a4nvzAilcjCs3iebIjUPR+jJfTUEa1Q=; b=ShJu302Xhp0MDCyllJXOgDvYtqlNP4UhNC/wg9+PDTz1ub2grgn+/Mct/MW4aRj0JN QulSaa0O/fxPt4LjTnYSFMrgepq6dZ3IeISXCANdH51gJWox1EhsMQ0NZJOgJeG4m7g4 dZyAi9Ct1q8V8WHSi+dOUSkNp6d7QpgeND7Q4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:from:to:cc:subject:message-id :mail-followup-to:references:mime-version:content-disposition :in-reply-to:user-agent; bh=xKqvw99ovVY7a4nvzAilcjCs3iebIjUPR+jJfTUEa1Q=; b=l+8LQsAosELQTfOCLHssb6skOe54p4bxFX4SSk8REOVgsRSBsGlzF7ZbFKODqH5C7Q Yr7vF2/7L7vSnKmWDFIELfK+KxZGRyKraZ09FKxdRXMvefojP0Hc5MimXXs25xexM2/Q BwfYsM/FPRaJfbnZ6xowJCvXCTMJUNJS/YOlLT/ecDa6160njdUSajdzITPcauERwo2D BaeJMiv6HKAsWVGjQ1e8nyy4mC4lJ+c/clDEU6OKUDX06AMmfsii5lCeiW7ycOHLqyf6 rhAqf/0SNYwRnj5vnAhPndKMiC6HIOQalpNWTVhoR2HBAgmt0CI2DVcjWhfrc55dABPQ CQGA== X-Gm-Message-State: APf1xPCHP0D2HEYod2QmuTMX4Yr4zqFJhHr5VArHh4nSIV9XzCc9wEN+ DSveOUZ5hdNrCb0m0CsXPEZCxQ6M X-Received: by 10.80.220.200 with SMTP id v8mr17370909edk.49.1520241218967; Mon, 05 Mar 2018 01:13:38 -0800 (PST) Received: from phenom.ffwll.local ([2a02:168:5635:0:39d2:f87e:2033:9f6]) by smtp.gmail.com with ESMTPSA id a43sm449431edd.6.2018.03.05.01.13.37 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 05 Mar 2018 01:13:37 -0800 (PST) Date: Mon, 5 Mar 2018 10:13:35 +0100 From: Daniel Vetter To: Oleksandr Andrushchenko Cc: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, airlied@linux.ie, daniel.vetter@intel.com, seanpaul@chromium.org, gustavo@padovan.org, jgross@suse.com, boris.ostrovsky@oracle.com, konrad.wilk@oracle.com, Oleksandr Andrushchenko Subject: Re: [PATCH 6/9] drm/xen-front: Introduce DRM/KMS virtual display driver Message-ID: <20180305091335.GH22212@phenom.ffwll.local> Mail-Followup-To: Oleksandr Andrushchenko , xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, airlied@linux.ie, daniel.vetter@intel.com, seanpaul@chromium.org, gustavo@padovan.org, jgross@suse.com, boris.ostrovsky@oracle.com, konrad.wilk@oracle.com, Oleksandr Andrushchenko References: <1519200222-20623-1-git-send-email-andr2000@gmail.com> <1519200222-20623-7-git-send-email-andr2000@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1519200222-20623-7-git-send-email-andr2000@gmail.com> X-Operating-System: Linux phenom 4.14.0-3-amd64 User-Agent: Mutt/1.9.3 (2018-01-21) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Feb 21, 2018 at 10:03:39AM +0200, Oleksandr Andrushchenko wrote: > From: Oleksandr Andrushchenko > > Implement essential initialization of the display driver: > - introduce required data structures > - handle DRM/KMS driver registration > - perform basic DRM driver initialization > - register driver on backend connection > - remove driver on backend disconnect > - introduce essential callbacks required by DRM/KMS core > - introduce essential callbacks required for frontend operations > > Signed-off-by: Oleksandr Andrushchenko > --- > drivers/gpu/drm/xen/Makefile | 1 + > drivers/gpu/drm/xen/xen_drm_front.c | 169 ++++++++++++++++++++++++- > drivers/gpu/drm/xen/xen_drm_front.h | 24 ++++ > drivers/gpu/drm/xen/xen_drm_front_drv.c | 211 ++++++++++++++++++++++++++++++++ > drivers/gpu/drm/xen/xen_drm_front_drv.h | 60 +++++++++ > 5 files changed, 462 insertions(+), 3 deletions(-) > create mode 100644 drivers/gpu/drm/xen/xen_drm_front_drv.c > create mode 100644 drivers/gpu/drm/xen/xen_drm_front_drv.h > > diff --git a/drivers/gpu/drm/xen/Makefile b/drivers/gpu/drm/xen/Makefile > index f1823cb596c5..d3068202590f 100644 > --- a/drivers/gpu/drm/xen/Makefile > +++ b/drivers/gpu/drm/xen/Makefile > @@ -1,6 +1,7 @@ > # SPDX-License-Identifier: GPL-2.0 > > drm_xen_front-objs := xen_drm_front.o \ > + xen_drm_front_drv.o \ > xen_drm_front_evtchnl.o \ > xen_drm_front_shbuf.o \ > xen_drm_front_cfg.o > diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c > index 0d94ff272da3..8de88e359d5e 100644 > --- a/drivers/gpu/drm/xen/xen_drm_front.c > +++ b/drivers/gpu/drm/xen/xen_drm_front.c > @@ -18,6 +18,8 @@ > > #include > > +#include > + > #include > #include > #include > @@ -25,15 +27,161 @@ > #include > > #include "xen_drm_front.h" > +#include "xen_drm_front_drv.h" > #include "xen_drm_front_evtchnl.h" > #include "xen_drm_front_shbuf.h" > > +static int be_mode_set(struct xen_drm_front_drm_pipeline *pipeline, uint32_t x, > + uint32_t y, uint32_t width, uint32_t height, uint32_t bpp, > + uint64_t fb_cookie) > + > +{ > + return 0; > +} > + > +static int be_dbuf_create_int(struct xen_drm_front_info *front_info, > + uint64_t dbuf_cookie, uint32_t width, uint32_t height, > + uint32_t bpp, uint64_t size, struct page **pages, > + struct sg_table *sgt) > +{ > + return 0; > +} > + > +static int be_dbuf_create_from_sgt(struct xen_drm_front_info *front_info, > + uint64_t dbuf_cookie, uint32_t width, uint32_t height, > + uint32_t bpp, uint64_t size, struct sg_table *sgt) > +{ > + return be_dbuf_create_int(front_info, dbuf_cookie, width, height, > + bpp, size, NULL, sgt); > +} > + > +static int be_dbuf_create_from_pages(struct xen_drm_front_info *front_info, > + uint64_t dbuf_cookie, uint32_t width, uint32_t height, > + uint32_t bpp, uint64_t size, struct page **pages) > +{ > + return be_dbuf_create_int(front_info, dbuf_cookie, width, height, > + bpp, size, pages, NULL); > +} > + > +static int be_dbuf_destroy(struct xen_drm_front_info *front_info, > + uint64_t dbuf_cookie) > +{ > + return 0; > +} > + > +static int be_fb_attach(struct xen_drm_front_info *front_info, > + uint64_t dbuf_cookie, uint64_t fb_cookie, uint32_t width, > + uint32_t height, uint32_t pixel_format) > +{ > + return 0; > +} > + > +static int be_fb_detach(struct xen_drm_front_info *front_info, > + uint64_t fb_cookie) > +{ > + return 0; > +} > + > +static int be_page_flip(struct xen_drm_front_info *front_info, int conn_idx, > + uint64_t fb_cookie) > +{ > + return 0; > +} > + > +static void xen_drm_drv_unload(struct xen_drm_front_info *front_info) > +{ > + if (front_info->xb_dev->state != XenbusStateReconfiguring) > + return; > + > + DRM_DEBUG("Can try removing driver now\n"); > + xenbus_switch_state(front_info->xb_dev, XenbusStateInitialising); > +} > + > static struct xen_drm_front_ops front_ops = { > - /* placeholder for now */ > + .mode_set = be_mode_set, > + .dbuf_create_from_pages = be_dbuf_create_from_pages, > + .dbuf_create_from_sgt = be_dbuf_create_from_sgt, > + .dbuf_destroy = be_dbuf_destroy, > + .fb_attach = be_fb_attach, > + .fb_detach = be_fb_detach, > + .page_flip = be_page_flip, > + .drm_last_close = xen_drm_drv_unload, > +}; This looks like a midlayer/DRM-abstraction in your driver. Please remove, and instead directly hook your xen-front code into the relevant drm callbacks. In general also pls make sure you don't implement dummy callbacks that do nothing, we've tried really hard to make them all optional in the drm infrastructure. -Daniel > + > +static int xen_drm_drv_probe(struct platform_device *pdev) > +{ > + /* > + * The device is not spawn from a device tree, so arch_setup_dma_ops > + * is not called, thus leaving the device with dummy DMA ops. > + * This makes the device return error on PRIME buffer import, which > + * is not correct: to fix this call of_dma_configure() with a NULL > + * node to set default DMA ops. > + */ > + of_dma_configure(&pdev->dev, NULL); > + return xen_drm_front_drv_probe(pdev, &front_ops); > +} > + > +static int xen_drm_drv_remove(struct platform_device *pdev) > +{ > + return xen_drm_front_drv_remove(pdev); > +} > + > +struct platform_device_info xen_drm_front_platform_info = { > + .name = XENDISPL_DRIVER_NAME, > + .id = 0, > + .num_res = 0, > + .dma_mask = DMA_BIT_MASK(32), > }; > > +static struct platform_driver xen_drm_front_front_info = { > + .probe = xen_drm_drv_probe, > + .remove = xen_drm_drv_remove, > + .driver = { > + .name = XENDISPL_DRIVER_NAME, > + }, > +}; > + > +static void xen_drm_drv_deinit(struct xen_drm_front_info *front_info) > +{ > + if (!front_info->drm_pdrv_registered) > + return; > + > + if (front_info->drm_pdev) > + platform_device_unregister(front_info->drm_pdev); > + > + platform_driver_unregister(&xen_drm_front_front_info); > + front_info->drm_pdrv_registered = false; > + front_info->drm_pdev = NULL; > +} > + > +static int xen_drm_drv_init(struct xen_drm_front_info *front_info) > +{ > + int ret; > + > + ret = platform_driver_register(&xen_drm_front_front_info); > + if (ret < 0) > + return ret; > + > + front_info->drm_pdrv_registered = true; > + /* pass card configuration via platform data */ > + xen_drm_front_platform_info.data = &front_info->cfg; > + xen_drm_front_platform_info.size_data = sizeof(front_info->cfg); > + > + front_info->drm_pdev = platform_device_register_full( > + &xen_drm_front_platform_info); > + if (IS_ERR_OR_NULL(front_info->drm_pdev)) { > + DRM_ERROR("Failed to register " XENDISPL_DRIVER_NAME " PV DRM driver\n"); > + front_info->drm_pdev = NULL; > + xen_drm_drv_deinit(front_info); > + return -ENODEV; > + } > + > + return 0; > +} > + > static void xen_drv_remove_internal(struct xen_drm_front_info *front_info) > { > + xen_drm_drv_deinit(front_info); > xen_drm_front_evtchnl_free_all(front_info); > } > > @@ -59,13 +207,27 @@ static int backend_on_initwait(struct xen_drm_front_info *front_info) > static int backend_on_connected(struct xen_drm_front_info *front_info) > { > xen_drm_front_evtchnl_set_state(front_info, EVTCHNL_STATE_CONNECTED); > - return 0; > + return xen_drm_drv_init(front_info); > } > > static void backend_on_disconnected(struct xen_drm_front_info *front_info) > { > + bool removed = true; > + > + if (front_info->drm_pdev) { > + if (xen_drm_front_drv_is_used(front_info->drm_pdev)) { > + DRM_WARN("DRM driver still in use, deferring removal\n"); > + removed = false; > + } else > + xen_drv_remove_internal(front_info); > + } > + > xen_drm_front_evtchnl_set_state(front_info, EVTCHNL_STATE_DISCONNECTED); > - xenbus_switch_state(front_info->xb_dev, XenbusStateInitialising); > + > + if (removed) > + xenbus_switch_state(front_info->xb_dev, XenbusStateInitialising); > + else > + xenbus_switch_state(front_info->xb_dev, XenbusStateReconfiguring); > } > > static void backend_on_changed(struct xenbus_device *xb_dev, > @@ -148,6 +310,7 @@ static int xen_drv_probe(struct xenbus_device *xb_dev, > > front_info->xb_dev = xb_dev; > spin_lock_init(&front_info->io_lock); > + front_info->drm_pdrv_registered = false; > dev_set_drvdata(&xb_dev->dev, front_info); > return xenbus_switch_state(xb_dev, XenbusStateInitialising); > } > diff --git a/drivers/gpu/drm/xen/xen_drm_front.h b/drivers/gpu/drm/xen/xen_drm_front.h > index 13f22736ae02..9ed5bfb248d0 100644 > --- a/drivers/gpu/drm/xen/xen_drm_front.h > +++ b/drivers/gpu/drm/xen/xen_drm_front.h > @@ -19,6 +19,8 @@ > #ifndef __XEN_DRM_FRONT_H_ > #define __XEN_DRM_FRONT_H_ > > +#include > + > #include "xen_drm_front_cfg.h" > > #ifndef GRANT_INVALID_REF > @@ -30,16 +32,38 @@ > #define GRANT_INVALID_REF 0 > #endif > > +struct xen_drm_front_drm_pipeline; > + > struct xen_drm_front_ops { > + int (*mode_set)(struct xen_drm_front_drm_pipeline *pipeline, > + uint32_t x, uint32_t y, uint32_t width, uint32_t height, > + uint32_t bpp, uint64_t fb_cookie); > + int (*dbuf_create_from_pages)(struct xen_drm_front_info *front_info, > + uint64_t dbuf_cookie, uint32_t width, uint32_t height, > + uint32_t bpp, uint64_t size, struct page **pages); > + int (*dbuf_create_from_sgt)(struct xen_drm_front_info *front_info, > + uint64_t dbuf_cookie, uint32_t width, uint32_t height, > + uint32_t bpp, uint64_t size, struct sg_table *sgt); > + int (*dbuf_destroy)(struct xen_drm_front_info *front_info, > + uint64_t dbuf_cookie); > + int (*fb_attach)(struct xen_drm_front_info *front_info, > + uint64_t dbuf_cookie, uint64_t fb_cookie, > + uint32_t width, uint32_t height, uint32_t pixel_format); > + int (*fb_detach)(struct xen_drm_front_info *front_info, > + uint64_t fb_cookie); > + int (*page_flip)(struct xen_drm_front_info *front_info, > + int conn_idx, uint64_t fb_cookie); > /* CAUTION! this is called with a spin_lock held! */ > void (*on_frame_done)(struct platform_device *pdev, > int conn_idx, uint64_t fb_cookie); > + void (*drm_last_close)(struct xen_drm_front_info *front_info); > }; > > struct xen_drm_front_info { > struct xenbus_device *xb_dev; > /* to protect data between backend IO code and interrupt handler */ > spinlock_t io_lock; > + bool drm_pdrv_registered; > /* virtual DRM platform device */ > struct platform_device *drm_pdev; > > diff --git a/drivers/gpu/drm/xen/xen_drm_front_drv.c b/drivers/gpu/drm/xen/xen_drm_front_drv.c > new file mode 100644 > index 000000000000..b3764d5ed0f6 > --- /dev/null > +++ b/drivers/gpu/drm/xen/xen_drm_front_drv.c > @@ -0,0 +1,211 @@ > +/* > + * Xen para-virtual DRM device > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * Copyright (C) 2016-2018 EPAM Systems Inc. > + * > + * Author: Oleksandr Andrushchenko > + */ > + > +#include > +#include > +#include > + > +#include "xen_drm_front.h" > +#include "xen_drm_front_cfg.h" > +#include "xen_drm_front_drv.h" > + > +static int dumb_create(struct drm_file *filp, > + struct drm_device *dev, struct drm_mode_create_dumb *args) > +{ > + return -EINVAL; > +} > + > +static void free_object(struct drm_gem_object *obj) > +{ > + struct xen_drm_front_drm_info *drm_info = obj->dev->dev_private; > + > + drm_info->front_ops->dbuf_destroy(drm_info->front_info, > + xen_drm_front_dbuf_to_cookie(obj)); > +} > + > +static void on_frame_done(struct platform_device *pdev, > + int conn_idx, uint64_t fb_cookie) > +{ > +} > + > +static void lastclose(struct drm_device *dev) > +{ > + struct xen_drm_front_drm_info *drm_info = dev->dev_private; > + > + drm_info->front_ops->drm_last_close(drm_info->front_info); > +} > + > +static int gem_mmap(struct file *filp, struct vm_area_struct *vma) > +{ > + return -EINVAL; > +} > + > +static struct sg_table *prime_get_sg_table(struct drm_gem_object *obj) > +{ > + return NULL; > +} > + > +static struct drm_gem_object *prime_import_sg_table(struct drm_device *dev, > + struct dma_buf_attachment *attach, struct sg_table *sgt) > +{ > + return NULL; > +} > + > +static void *prime_vmap(struct drm_gem_object *obj) > +{ > + return NULL; > +} > + > +static void prime_vunmap(struct drm_gem_object *obj, void *vaddr) > +{ > +} > + > +static int prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) > +{ > + return -EINVAL; > +} > + > +static const struct file_operations xendrm_fops = { > + .owner = THIS_MODULE, > + .open = drm_open, > + .release = drm_release, > + .unlocked_ioctl = drm_ioctl, > +#ifdef CONFIG_COMPAT > + .compat_ioctl = drm_compat_ioctl, > +#endif > + .poll = drm_poll, > + .read = drm_read, > + .llseek = no_llseek, > + .mmap = gem_mmap, > +}; > + > +static const struct vm_operations_struct xen_drm_vm_ops = { > + .open = drm_gem_vm_open, > + .close = drm_gem_vm_close, > +}; > + > +struct drm_driver xen_drm_driver = { > + .driver_features = DRIVER_GEM | DRIVER_MODESET | > + DRIVER_PRIME | DRIVER_ATOMIC, > + .lastclose = lastclose, > + .gem_free_object_unlocked = free_object, > + .gem_vm_ops = &xen_drm_vm_ops, > + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, > + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, > + .gem_prime_import = drm_gem_prime_import, > + .gem_prime_export = drm_gem_prime_export, > + .gem_prime_get_sg_table = prime_get_sg_table, > + .gem_prime_import_sg_table = prime_import_sg_table, > + .gem_prime_vmap = prime_vmap, > + .gem_prime_vunmap = prime_vunmap, > + .gem_prime_mmap = prime_mmap, > + .dumb_create = dumb_create, > + .fops = &xendrm_fops, > + .name = "xendrm-du", > + .desc = "Xen PV DRM Display Unit", > + .date = "20161109", > + .major = 1, > + .minor = 0, > +}; > + > +int xen_drm_front_drv_probe(struct platform_device *pdev, > + struct xen_drm_front_ops *front_ops) > +{ > + struct xen_drm_front_cfg *cfg = dev_get_platdata(&pdev->dev); > + struct xen_drm_front_drm_info *drm_info; > + struct drm_device *dev; > + int ret; > + > + DRM_INFO("Creating %s\n", xen_drm_driver.desc); > + > + drm_info = devm_kzalloc(&pdev->dev, sizeof(*drm_info), GFP_KERNEL); > + if (!drm_info) > + return -ENOMEM; > + > + drm_info->front_ops = front_ops; > + drm_info->front_ops->on_frame_done = on_frame_done; > + drm_info->front_info = cfg->front_info; > + > + dev = drm_dev_alloc(&xen_drm_driver, &pdev->dev); > + if (!dev) > + return -ENOMEM; > + > + drm_info->drm_dev = dev; > + > + drm_info->cfg = cfg; > + dev->dev_private = drm_info; > + platform_set_drvdata(pdev, drm_info); > + > + ret = drm_vblank_init(dev, cfg->num_connectors); > + if (ret) { > + DRM_ERROR("Failed to initialize vblank, ret %d\n", ret); > + return ret; > + } > + > + dev->irq_enabled = 1; > + > + ret = drm_dev_register(dev, 0); > + if (ret) > + goto fail_register; > + > + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", > + xen_drm_driver.name, xen_drm_driver.major, > + xen_drm_driver.minor, xen_drm_driver.patchlevel, > + xen_drm_driver.date, dev->primary->index); > + > + return 0; > + > +fail_register: > + drm_dev_unregister(dev); > + drm_mode_config_cleanup(dev); > + return ret; > +} > + > +int xen_drm_front_drv_remove(struct platform_device *pdev) > +{ > + struct xen_drm_front_drm_info *drm_info = platform_get_drvdata(pdev); > + struct drm_device *dev = drm_info->drm_dev; > + > + if (dev) { > + drm_dev_unregister(dev); > + drm_atomic_helper_shutdown(dev); > + drm_mode_config_cleanup(dev); > + drm_dev_unref(dev); > + } > + return 0; > +} > + > +bool xen_drm_front_drv_is_used(struct platform_device *pdev) > +{ > + struct xen_drm_front_drm_info *drm_info = platform_get_drvdata(pdev); > + struct drm_device *dev; > + > + if (!drm_info) > + return false; > + > + dev = drm_info->drm_dev; > + if (!dev) > + return false; > + > + /* > + * FIXME: the code below must be protected by drm_global_mutex, > + * but it is not accessible to us. Anyways there is a race condition, > + * but we will re-try. > + */ > + return dev->open_count != 0; > +} > diff --git a/drivers/gpu/drm/xen/xen_drm_front_drv.h b/drivers/gpu/drm/xen/xen_drm_front_drv.h > new file mode 100644 > index 000000000000..aaa476535c13 > --- /dev/null > +++ b/drivers/gpu/drm/xen/xen_drm_front_drv.h > @@ -0,0 +1,60 @@ > +/* > + * Xen para-virtual DRM device > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * Copyright (C) 2016-2018 EPAM Systems Inc. > + * > + * Author: Oleksandr Andrushchenko > + */ > + > +#ifndef __XEN_DRM_FRONT_DRV_H_ > +#define __XEN_DRM_FRONT_DRV_H_ > + > +#include > + > +#include "xen_drm_front.h" > +#include "xen_drm_front_cfg.h" > + > +struct xen_drm_front_drm_pipeline { > + struct xen_drm_front_drm_info *drm_info; > + > + int index; > +}; > + > +struct xen_drm_front_drm_info { > + struct xen_drm_front_info *front_info; > + struct xen_drm_front_ops *front_ops; > + struct drm_device *drm_dev; > + struct xen_drm_front_cfg *cfg; > +}; > + > +static inline uint64_t xen_drm_front_fb_to_cookie( > + struct drm_framebuffer *fb) > +{ > + return (uint64_t)fb; > +} > + > +static inline uint64_t xen_drm_front_dbuf_to_cookie( > + struct drm_gem_object *gem_obj) > +{ > + return (uint64_t)gem_obj; > +} > + > +int xen_drm_front_drv_probe(struct platform_device *pdev, > + struct xen_drm_front_ops *front_ops); > + > +int xen_drm_front_drv_remove(struct platform_device *pdev); > + > +bool xen_drm_front_drv_is_used(struct platform_device *pdev); > + > +#endif /* __XEN_DRM_FRONT_DRV_H_ */ > + > -- > 2.7.4 > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch