From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Vetter Date: Mon, 25 Apr 2016 09:15:17 +0000 Subject: Re: [PATCH v2 6/8] drm/fb-cma-helper: Add fb_deferred_io support Message-Id: <20160425091517.GS2510@phenom.ffwll.local> List-Id: References: <1461530942-22485-1-git-send-email-noralf@tronnes.org> <1461530942-22485-7-git-send-email-noralf@tronnes.org> In-Reply-To: <1461530942-22485-7-git-send-email-noralf@tronnes.org> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable To: Noralf =?iso-8859-1?Q?Tr=F8nnes?= Cc: linux-fbdev@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, tomi.valkeinen@ti.com, laurent.pinchart@ideasonboard.com On Sun, Apr 24, 2016 at 10:49:00PM +0200, Noralf Tr=F8nnes wrote: > This adds fbdev deferred io support if CONFIG_FB_DEFERRED_IO is enabled. > The driver has to provide a (struct drm_framebuffer_funcs *)->dirty() > callback to get notification of fbdev framebuffer changes. > If the dirty() hook is set, then fb_deferred_io is set up automatically > by the helper. >=20 > Two functions have been added so that the driver can provide a dirty() > function: > - drm_fbdev_cma_init_with_funcs() > This makes it possible for the driver to provided a custom > (struct drm_fb_helper_funcs *)->fb_probe() function. > - drm_fbdev_cma_create_with_funcs() > This is used by the .fb_probe hook to set a driver provided > (struct drm_framebuffer_funcs *)->dirty() function. >=20 > Signed-off-by: Noralf Tr=F8nnes > --- > drivers/gpu/drm/drm_fb_cma_helper.c | 190 ++++++++++++++++++++++++++++++= +++--- > include/drm/drm_fb_cma_helper.h | 14 +++ > 2 files changed, 192 insertions(+), 12 deletions(-) >=20 > diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb= _cma_helper.c > index bb88e3d..d1e9db0 100644 > --- a/drivers/gpu/drm/drm_fb_cma_helper.c > +++ b/drivers/gpu/drm/drm_fb_cma_helper.c > @@ -25,6 +25,8 @@ > #include > #include > =20 > +#define DEFAULT_FBDEFIO_DELAY_MS 50 > + > struct drm_fb_cma { > struct drm_framebuffer fb; > struct drm_gem_cma_object *obj[4]; > @@ -35,6 +37,61 @@ struct drm_fbdev_cma { > struct drm_fb_cma *fb; > }; > =20 > +/** > + * DOC: framebuffer cma helper functions > + * > + * Provides helper functions for creating a cma (contiguous memory alloc= ator) > + * backed framebuffer. > + * > + * drm_fb_cma_create() is used in the > + * (struct drm_mode_config_funcs *)->fb_create callback function to crea= te the Nit: If you use &drm_mode_config_funcs kerneldoc will insert a hyperlink to the corresponding kerneldoc for the struct. So common style is=20 "drm_fb_cma_create() is used in the &drm_mode_config_funcs ->fb_create() callback function ..." Please roll this it to other places where you reference structs. Eventually kerneldoc people have the dream to enable cross-referencing across the entire kernel tree (so stuff like &delayed_work hopefully works then too). > + * cma backed framebuffer. > + * > + * An fbdev framebuffer backed by cma is also available by calling > + * drm_fbdev_cma_init(). drm_fbdev_cma_fini() tears it down. > + * If CONFIG_FB_DEFERRED_IO is enabled and the callback > + * (struct drm_framebuffer_funcs)->dirty is set, fb_deferred_io > + * will be set up automatically. dirty() is called by > + * drm_fb_helper_deferred_io() in process context (struct delayed_work). > + * > + * Example fbdev deferred io code: > + * > + * static int driver_fbdev_fb_dirty(struct drm_framebuffer *fb, > + * struct drm_file *file_priv, > + * unsigned flags, unsigned color, > + * struct drm_clip_rect *clips, > + * unsigned num_clips) > + * { > + * struct drm_gem_cma_object *cma =3D drm_fb_cma_get_gem_obj(fb,= 0); > + * ... push changes ... > + * return 0; > + * } > + * > + * static struct drm_framebuffer_funcs driver_fbdev_fb_funcs =3D { > + * .destroy =3D drm_fb_cma_destroy, > + * .create_handle =3D drm_fb_cma_create_handle, > + * .dirty =3D driver_fbdev_fb_dirty, > + * }; > + * > + * static int driver_fbdev_create(struct drm_fb_helper *helper, > + * struct drm_fb_helper_surface_size *sizes) > + * { > + * return drm_fbdev_cma_create_with_funcs(helper, sizes, > + * &driver_fbdev_fb_funcs= ); > + * } > + * > + * static const struct drm_fb_helper_funcs driver_fb_helper_funcs = =3D { > + * .fb_probe =3D driver_fbdev_create, > + * }; > + * > + * Initialize: > + * fbdev =3D drm_fbdev_cma_init_with_funcs(dev, 16, > + * dev->mode_config.num_crtc, > + * dev->mode_config.num_connec= tor, > + * &driver_fb_helper_funcs); > + * > + */ > + > static inline struct drm_fbdev_cma *to_fbdev_cma(struct drm_fb_helper *h= elper) > { > return container_of(helper, struct drm_fbdev_cma, fb_helper); > @@ -45,7 +102,7 @@ static inline struct drm_fb_cma *to_fb_cma(struct drm_= framebuffer *fb) > return container_of(fb, struct drm_fb_cma, fb); > } > =20 > -static void drm_fb_cma_destroy(struct drm_framebuffer *fb) > +void drm_fb_cma_destroy(struct drm_framebuffer *fb) > { > struct drm_fb_cma *fb_cma =3D to_fb_cma(fb); > int i; > @@ -58,8 +115,9 @@ static void drm_fb_cma_destroy(struct drm_framebuffer = *fb) > drm_framebuffer_cleanup(fb); > kfree(fb_cma); > } > +EXPORT_SYMBOL(drm_fb_cma_destroy); > =20 > -static int drm_fb_cma_create_handle(struct drm_framebuffer *fb, > +int drm_fb_cma_create_handle(struct drm_framebuffer *fb, > struct drm_file *file_priv, unsigned int *handle) > { > struct drm_fb_cma *fb_cma =3D to_fb_cma(fb); > @@ -67,6 +125,7 @@ static int drm_fb_cma_create_handle(struct drm_framebu= ffer *fb, > return drm_gem_handle_create(file_priv, > &fb_cma->obj[0]->base, handle); > } > +EXPORT_SYMBOL(drm_fb_cma_create_handle); > =20 > static struct drm_framebuffer_funcs drm_fb_cma_funcs =3D { > .destroy =3D drm_fb_cma_destroy, > @@ -76,7 +135,7 @@ static struct drm_framebuffer_funcs drm_fb_cma_funcs = =3D { > static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev, > const struct drm_mode_fb_cmd2 *mode_cmd, > struct drm_gem_cma_object **obj, > - unsigned int num_planes) > + unsigned int num_planes, struct drm_framebuffer_funcs *funcs) > { > struct drm_fb_cma *fb_cma; > int ret; > @@ -91,7 +150,7 @@ static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_= device *dev, > for (i =3D 0; i < num_planes; i++) > fb_cma->obj[i] =3D obj[i]; > =20 > - ret =3D drm_framebuffer_init(dev, &fb_cma->fb, &drm_fb_cma_funcs); > + ret =3D drm_framebuffer_init(dev, &fb_cma->fb, funcs); > if (ret) { > dev_err(dev->dev, "Failed to initialize framebuffer: %d\n", ret); > kfree(fb_cma); > @@ -145,7 +204,7 @@ struct drm_framebuffer *drm_fb_cma_create(struct drm_= device *dev, > objs[i] =3D to_drm_gem_cma_obj(obj); > } > =20 > - fb_cma =3D drm_fb_cma_alloc(dev, mode_cmd, objs, i); > + fb_cma =3D drm_fb_cma_alloc(dev, mode_cmd, objs, i, &drm_fb_cma_funcs); > if (IS_ERR(fb_cma)) { > ret =3D PTR_ERR(fb_cma); > goto err_gem_object_unreference; > @@ -233,8 +292,79 @@ static struct fb_ops drm_fbdev_cma_ops =3D { > .fb_setcmap =3D drm_fb_helper_setcmap, > }; > =20 > -static int drm_fbdev_cma_create(struct drm_fb_helper *helper, > - struct drm_fb_helper_surface_size *sizes) > +#ifdef CONFIG_FB_DEFERRED_IO Same question about config handling. Imo just selecting this is ok, and would remove a few #ifdef from the code. Otherwise lgtm, but needs an ack/r-b from Laurent. -Daniel > +static int drm_fbdev_cma_deferred_io_mmap(struct fb_info *info, > + struct vm_area_struct *vma) > +{ > + fb_deferred_io_mmap(info, vma); > + vma->vm_page_prot =3D pgprot_writecombine(vma->vm_page_prot); > + > + return 0; > +} > + > +static int drm_fbdev_cma_defio_init(struct fb_info *fbi, > + struct drm_gem_cma_object *cma_obj) > +{ > + struct fb_deferred_io *fbdefio; > + struct fb_ops *fbops; > + > + /* > + * Per device structures are needed because: > + * fbops: fb_deferred_io_cleanup() clears fbops.fb_mmap > + * fbdefio: individual delays > + */ > + fbdefio =3D kzalloc(sizeof(*fbdefio), GFP_KERNEL); > + fbops =3D kzalloc(sizeof(*fbops), GFP_KERNEL); > + if (!fbdefio || !fbops) { > + kfree(fbdefio); > + return -ENOMEM; > + } > + > + /* can't be offset from vaddr since dirty() uses cma_obj */ > + fbi->screen_buffer =3D cma_obj->vaddr; > + /* fb_deferred_io_fault() needs a physical address */ > + fbi->fix.smem_start =3D page_to_phys(virt_to_page(fbi->screen_buffer)); > + > + *fbops =3D *fbi->fbops; > + fbi->fbops =3D fbops; > + > + fbdefio->delay =3D msecs_to_jiffies(DEFAULT_FBDEFIO_DELAY_MS); > + fbdefio->deferred_io =3D drm_fb_helper_deferred_io; > + fbi->fbdefio =3D fbdefio; > + fb_deferred_io_init(fbi); > + fbi->fbops->fb_mmap =3D drm_fbdev_cma_deferred_io_mmap; > + > + return 0; > +} > + > +static void drm_fbdev_cma_defio_fini(struct fb_info *fbi) > +{ > + if (!fbi->fbdefio) > + return; > + > + fb_deferred_io_cleanup(fbi); > + kfree(fbi->fbdefio); > + kfree(fbi->fbops); > +} > +#else > +static int drm_fbdev_cma_defio_init(struct fb_info *fbi, > + struct drm_gem_cma_object *cma_obj) > +{ > + return 0; > +} > + > +static void drm_fbdev_cma_defio_fini(struct fb_info *fbi) > +{ > +} > +#endif /* CONFIG_FB_DEFERRED_IO */ > + > +/* > + * For use in a (struct drm_fb_helper_funcs *)->fb_probe callback functi= on that > + * needs custom struct drm_framebuffer_funcs, like dirty() for deferred_= io use. > + */ > +int drm_fbdev_cma_create_with_funcs(struct drm_fb_helper *helper, > + struct drm_fb_helper_surface_size *sizes, > + struct drm_framebuffer_funcs *funcs) > { > struct drm_fbdev_cma *fbdev_cma =3D to_fbdev_cma(helper); > struct drm_mode_fb_cmd2 mode_cmd =3D { 0 }; > @@ -270,7 +400,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper = *helper, > goto err_gem_free_object; > } > =20 > - fbdev_cma->fb =3D drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1); > + fbdev_cma->fb =3D drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1, funcs); > if (IS_ERR(fbdev_cma->fb)) { > dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n"); > ret =3D PTR_ERR(fbdev_cma->fb); > @@ -296,31 +426,48 @@ static int drm_fbdev_cma_create(struct drm_fb_helpe= r *helper, > fbi->screen_size =3D size; > fbi->fix.smem_len =3D size; > =20 > + if (funcs->dirty) { > + ret =3D drm_fbdev_cma_defio_init(fbi, obj); > + if (ret) > + goto err_cma_destroy; > + } > + > return 0; > =20 > +err_cma_destroy: > + drm_framebuffer_unregister_private(&fbdev_cma->fb->fb); > + drm_fb_cma_destroy(&fbdev_cma->fb->fb); > err_fb_info_destroy: > drm_fb_helper_release_fbi(helper); > err_gem_free_object: > dev->driver->gem_free_object(&obj->base); > return ret; > } > +EXPORT_SYMBOL(drm_fbdev_cma_create_with_funcs); > + > +static int drm_fbdev_cma_create(struct drm_fb_helper *helper, > + struct drm_fb_helper_surface_size *sizes) > +{ > + return drm_fbdev_cma_create_with_funcs(helper, sizes, &drm_fb_cma_funcs= ); > +} > =20 > static const struct drm_fb_helper_funcs drm_fb_cma_helper_funcs =3D { > .fb_probe =3D drm_fbdev_cma_create, > }; > =20 > /** > - * drm_fbdev_cma_init() - Allocate and initializes a drm_fbdev_cma struct > + * drm_fbdev_cma_init_with_funcs() - Allocate and initializes a drm_fbde= v_cma struct > * @dev: DRM device > * @preferred_bpp: Preferred bits per pixel for the device > * @num_crtc: Number of CRTCs > * @max_conn_count: Maximum number of connectors > + * @funcs: fb helper functions, in particular fb_probe() > * > * Returns a newly allocated drm_fbdev_cma struct or a ERR_PTR. > */ > -struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev, > +struct drm_fbdev_cma *drm_fbdev_cma_init_with_funcs(struct drm_device *d= ev, > unsigned int preferred_bpp, unsigned int num_crtc, > - unsigned int max_conn_count) > + unsigned int max_conn_count, const struct drm_fb_helper_funcs *funcs) > { > struct drm_fbdev_cma *fbdev_cma; > struct drm_fb_helper *helper; > @@ -334,7 +481,7 @@ struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_d= evice *dev, > =20 > helper =3D &fbdev_cma->fb_helper; > =20 > - drm_fb_helper_prepare(dev, helper, &drm_fb_cma_helper_funcs); > + drm_fb_helper_prepare(dev, helper, funcs); > =20 > ret =3D drm_fb_helper_init(dev, helper, num_crtc, max_conn_count); > if (ret < 0) { > @@ -364,6 +511,24 @@ err_free: > =20 > return ERR_PTR(ret); > } > +EXPORT_SYMBOL_GPL(drm_fbdev_cma_init_with_funcs); > + > +/** > + * drm_fbdev_cma_init() - Allocate and initializes a drm_fbdev_cma struct > + * @dev: DRM device > + * @preferred_bpp: Preferred bits per pixel for the device > + * @num_crtc: Number of CRTCs > + * @max_conn_count: Maximum number of connectors > + * > + * Returns a newly allocated drm_fbdev_cma struct or a ERR_PTR. > + */ > +struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev, > + unsigned int preferred_bpp, unsigned int num_crtc, > + unsigned int max_conn_count) > +{ > + return drm_fbdev_cma_init_with_funcs(dev, preferred_bpp, num_crtc, > + max_conn_count, &drm_fb_cma_helper_funcs); > +} > EXPORT_SYMBOL_GPL(drm_fbdev_cma_init); > =20 > /** > @@ -373,6 +538,7 @@ EXPORT_SYMBOL_GPL(drm_fbdev_cma_init); > void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma) > { > drm_fb_helper_unregister_fbi(&fbdev_cma->fb_helper); > + drm_fbdev_cma_defio_fini(fbdev_cma->fb_helper.fbdev); > drm_fb_helper_release_fbi(&fbdev_cma->fb_helper); > =20 > if (fbdev_cma->fb) { > diff --git a/include/drm/drm_fb_cma_helper.h b/include/drm/drm_fb_cma_hel= per.h > index be62bd3..6554b6f 100644 > --- a/include/drm/drm_fb_cma_helper.h > +++ b/include/drm/drm_fb_cma_helper.h > @@ -4,11 +4,18 @@ > struct drm_fbdev_cma; > struct drm_gem_cma_object; > =20 > +struct drm_fb_helper_surface_size; > +struct drm_framebuffer_funcs; > +struct drm_fb_helper_funcs; > struct drm_framebuffer; > +struct drm_fb_helper; > struct drm_device; > struct drm_file; > struct drm_mode_fb_cmd2; > =20 > +struct drm_fbdev_cma *drm_fbdev_cma_init_with_funcs(struct drm_device *d= ev, > + unsigned int preferred_bpp, unsigned int num_crtc, > + unsigned int max_conn_count, const struct drm_fb_helper_funcs *funcs); > struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev, > unsigned int preferred_bpp, unsigned int num_crtc, > unsigned int max_conn_count); > @@ -16,6 +23,13 @@ void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cm= a); > =20 > void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma); > void drm_fbdev_cma_hotplug_event(struct drm_fbdev_cma *fbdev_cma); > +int drm_fbdev_cma_create_with_funcs(struct drm_fb_helper *helper, > + struct drm_fb_helper_surface_size *sizes, > + struct drm_framebuffer_funcs *funcs); > + > +void drm_fb_cma_destroy(struct drm_framebuffer *fb); > +int drm_fb_cma_create_handle(struct drm_framebuffer *fb, > + struct drm_file *file_priv, unsigned int *handle); > =20 > struct drm_framebuffer *drm_fb_cma_create(struct drm_device *dev, > struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd); > --=20 > 2.2.2 >=20 --=20 Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Vetter Subject: Re: [PATCH v2 6/8] drm/fb-cma-helper: Add fb_deferred_io support Date: Mon, 25 Apr 2016 11:15:17 +0200 Message-ID: <20160425091517.GS2510@phenom.ffwll.local> References: <1461530942-22485-1-git-send-email-noralf@tronnes.org> <1461530942-22485-7-git-send-email-noralf@tronnes.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mail-wm0-x230.google.com (mail-wm0-x230.google.com [IPv6:2a00:1450:400c:c09::230]) by gabe.freedesktop.org (Postfix) with ESMTPS id D0AED6E54D for ; Mon, 25 Apr 2016 09:15:21 +0000 (UTC) Received: by mail-wm0-x230.google.com with SMTP id u206so116499488wme.1 for ; Mon, 25 Apr 2016 02:15:21 -0700 (PDT) Content-Disposition: inline In-Reply-To: <1461530942-22485-7-git-send-email-noralf@tronnes.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Noralf =?iso-8859-1?Q?Tr=F8nnes?= Cc: linux-fbdev@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, tomi.valkeinen@ti.com, laurent.pinchart@ideasonboard.com List-Id: dri-devel@lists.freedesktop.org T24gU3VuLCBBcHIgMjQsIDIwMTYgYXQgMTA6NDk6MDBQTSArMDIwMCwgTm9yYWxmIFRyw7hubmVz IHdyb3RlOgo+IFRoaXMgYWRkcyBmYmRldiBkZWZlcnJlZCBpbyBzdXBwb3J0IGlmIENPTkZJR19G Ql9ERUZFUlJFRF9JTyBpcyBlbmFibGVkLgo+IFRoZSBkcml2ZXIgaGFzIHRvIHByb3ZpZGUgYSAo c3RydWN0IGRybV9mcmFtZWJ1ZmZlcl9mdW5jcyAqKS0+ZGlydHkoKQo+IGNhbGxiYWNrIHRvIGdl dCBub3RpZmljYXRpb24gb2YgZmJkZXYgZnJhbWVidWZmZXIgY2hhbmdlcy4KPiBJZiB0aGUgZGly dHkoKSBob29rIGlzIHNldCwgdGhlbiBmYl9kZWZlcnJlZF9pbyBpcyBzZXQgdXAgYXV0b21hdGlj YWxseQo+IGJ5IHRoZSBoZWxwZXIuCj4gCj4gVHdvIGZ1bmN0aW9ucyBoYXZlIGJlZW4gYWRkZWQg c28gdGhhdCB0aGUgZHJpdmVyIGNhbiBwcm92aWRlIGEgZGlydHkoKQo+IGZ1bmN0aW9uOgo+IC0g ZHJtX2ZiZGV2X2NtYV9pbml0X3dpdGhfZnVuY3MoKQo+ICAgVGhpcyBtYWtlcyBpdCBwb3NzaWJs ZSBmb3IgdGhlIGRyaXZlciB0byBwcm92aWRlZCBhIGN1c3RvbQo+ICAgKHN0cnVjdCBkcm1fZmJf aGVscGVyX2Z1bmNzICopLT5mYl9wcm9iZSgpIGZ1bmN0aW9uLgo+IC0gZHJtX2ZiZGV2X2NtYV9j cmVhdGVfd2l0aF9mdW5jcygpCj4gICBUaGlzIGlzIHVzZWQgYnkgdGhlIC5mYl9wcm9iZSBob29r IHRvIHNldCBhIGRyaXZlciBwcm92aWRlZAo+ICAgKHN0cnVjdCBkcm1fZnJhbWVidWZmZXJfZnVu Y3MgKiktPmRpcnR5KCkgZnVuY3Rpb24uCj4gCj4gU2lnbmVkLW9mZi1ieTogTm9yYWxmIFRyw7hu bmVzIDxub3JhbGZAdHJvbm5lcy5vcmc+Cj4gLS0tCj4gIGRyaXZlcnMvZ3B1L2RybS9kcm1fZmJf Y21hX2hlbHBlci5jIHwgMTkwICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0tLQo+ ICBpbmNsdWRlL2RybS9kcm1fZmJfY21hX2hlbHBlci5oICAgICB8ICAxNCArKysKPiAgMiBmaWxl cyBjaGFuZ2VkLCAxOTIgaW5zZXJ0aW9ucygrKSwgMTIgZGVsZXRpb25zKC0pCj4gCj4gZGlmZiAt LWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9kcm1fZmJfY21hX2hlbHBlci5jIGIvZHJpdmVycy9ncHUv ZHJtL2RybV9mYl9jbWFfaGVscGVyLmMKPiBpbmRleCBiYjg4ZTNkLi5kMWU5ZGIwIDEwMDY0NAo+ IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9kcm1fZmJfY21hX2hlbHBlci5jCj4gKysrIGIvZHJpdmVy cy9ncHUvZHJtL2RybV9mYl9jbWFfaGVscGVyLmMKPiBAQCAtMjUsNiArMjUsOCBAQAo+ICAjaW5j bHVkZSA8ZHJtL2RybV9mYl9jbWFfaGVscGVyLmg+Cj4gICNpbmNsdWRlIDxsaW51eC9tb2R1bGUu aD4KPiAgCj4gKyNkZWZpbmUgREVGQVVMVF9GQkRFRklPX0RFTEFZX01TIDUwCj4gKwo+ICBzdHJ1 Y3QgZHJtX2ZiX2NtYSB7Cj4gIAlzdHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyCQlmYjsKPiAgCXN0cnVj dCBkcm1fZ2VtX2NtYV9vYmplY3QJKm9ials0XTsKPiBAQCAtMzUsNiArMzcsNjEgQEAgc3RydWN0 IGRybV9mYmRldl9jbWEgewo+ICAJc3RydWN0IGRybV9mYl9jbWEJKmZiOwo+ICB9Owo+ICAKPiAr LyoqCj4gKyAqIERPQzogZnJhbWVidWZmZXIgY21hIGhlbHBlciBmdW5jdGlvbnMKPiArICoKPiAr ICogUHJvdmlkZXMgaGVscGVyIGZ1bmN0aW9ucyBmb3IgY3JlYXRpbmcgYSBjbWEgKGNvbnRpZ3Vv dXMgbWVtb3J5IGFsbG9jYXRvcikKPiArICogYmFja2VkIGZyYW1lYnVmZmVyLgo+ICsgKgo+ICsg KiBkcm1fZmJfY21hX2NyZWF0ZSgpIGlzIHVzZWQgaW4gdGhlCj4gKyAqIChzdHJ1Y3QgZHJtX21v ZGVfY29uZmlnX2Z1bmNzICopLT5mYl9jcmVhdGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gY3JlYXRl IHRoZQoKTml0OiBJZiB5b3UgdXNlICZkcm1fbW9kZV9jb25maWdfZnVuY3Mga2VybmVsZG9jIHdp bGwgaW5zZXJ0IGEgaHlwZXJsaW5rCnRvIHRoZSBjb3JyZXNwb25kaW5nIGtlcm5lbGRvYyBmb3Ig dGhlIHN0cnVjdC4gU28gY29tbW9uIHN0eWxlIGlzIAoKImRybV9mYl9jbWFfY3JlYXRlKCkgaXMg dXNlZCBpbiB0aGUgJmRybV9tb2RlX2NvbmZpZ19mdW5jcyAtPmZiX2NyZWF0ZSgpCmNhbGxiYWNr IGZ1bmN0aW9uIC4uLiIKClBsZWFzZSByb2xsIHRoaXMgaXQgdG8gb3RoZXIgcGxhY2VzIHdoZXJl IHlvdSByZWZlcmVuY2Ugc3RydWN0cy4KRXZlbnR1YWxseSBrZXJuZWxkb2MgcGVvcGxlIGhhdmUg dGhlIGRyZWFtIHRvIGVuYWJsZSBjcm9zcy1yZWZlcmVuY2luZwphY3Jvc3MgdGhlIGVudGlyZSBr ZXJuZWwgdHJlZSAoc28gc3R1ZmYgbGlrZSAmZGVsYXllZF93b3JrIGhvcGVmdWxseSB3b3Jrcwp0 aGVuIHRvbykuCgo+ICsgKiBjbWEgYmFja2VkIGZyYW1lYnVmZmVyLgo+ICsgKgo+ICsgKiBBbiBm YmRldiBmcmFtZWJ1ZmZlciBiYWNrZWQgYnkgY21hIGlzIGFsc28gYXZhaWxhYmxlIGJ5IGNhbGxp bmcKPiArICogZHJtX2ZiZGV2X2NtYV9pbml0KCkuIGRybV9mYmRldl9jbWFfZmluaSgpIHRlYXJz IGl0IGRvd24uCj4gKyAqIElmIENPTkZJR19GQl9ERUZFUlJFRF9JTyBpcyBlbmFibGVkIGFuZCB0 aGUgY2FsbGJhY2sKPiArICogKHN0cnVjdCBkcm1fZnJhbWVidWZmZXJfZnVuY3MpLT5kaXJ0eSBp cyBzZXQsIGZiX2RlZmVycmVkX2lvCj4gKyAqIHdpbGwgYmUgc2V0IHVwIGF1dG9tYXRpY2FsbHku IGRpcnR5KCkgaXMgY2FsbGVkIGJ5Cj4gKyAqIGRybV9mYl9oZWxwZXJfZGVmZXJyZWRfaW8oKSBp biBwcm9jZXNzIGNvbnRleHQgKHN0cnVjdCBkZWxheWVkX3dvcmspLgo+ICsgKgo+ICsgKiBFeGFt cGxlIGZiZGV2IGRlZmVycmVkIGlvIGNvZGU6Cj4gKyAqCj4gKyAqICAgICBzdGF0aWMgaW50IGRy aXZlcl9mYmRldl9mYl9kaXJ0eShzdHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyICpmYiwKPiArICogICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBkcm1fZmlsZSAqZmlsZV9w cml2LAo+ICsgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQg ZmxhZ3MsIHVuc2lnbmVkIGNvbG9yLAo+ICsgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgc3RydWN0IGRybV9jbGlwX3JlY3QgKmNsaXBzLAo+ICsgKiAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbnVtX2NsaXBzKQo+ICsgKiAgICAgewo+ ICsgKiAgICAgICAgIHN0cnVjdCBkcm1fZ2VtX2NtYV9vYmplY3QgKmNtYSA9IGRybV9mYl9jbWFf Z2V0X2dlbV9vYmooZmIsIDApOwo+ICsgKiAgICAgICAgIC4uLiBwdXNoIGNoYW5nZXMgLi4uCj4g KyAqICAgICAgICAgcmV0dXJuIDA7Cj4gKyAqICAgICB9Cj4gKyAqCj4gKyAqICAgICBzdGF0aWMg c3RydWN0IGRybV9mcmFtZWJ1ZmZlcl9mdW5jcyBkcml2ZXJfZmJkZXZfZmJfZnVuY3MgPSB7Cj4g KyAqICAgICAgICAgLmRlc3Ryb3kgICAgICAgPSBkcm1fZmJfY21hX2Rlc3Ryb3ksCj4gKyAqICAg ICAgICAgLmNyZWF0ZV9oYW5kbGUgPSBkcm1fZmJfY21hX2NyZWF0ZV9oYW5kbGUsCj4gKyAqICAg ICAgICAgLmRpcnR5ICAgICAgICAgPSBkcml2ZXJfZmJkZXZfZmJfZGlydHksCj4gKyAqICAgICB9 Owo+ICsgKgo+ICsgKiAgICAgc3RhdGljIGludCBkcml2ZXJfZmJkZXZfY3JlYXRlKHN0cnVjdCBk cm1fZmJfaGVscGVyICpoZWxwZXIsCj4gKyAqICAgICAgICAgICAgIHN0cnVjdCBkcm1fZmJfaGVs cGVyX3N1cmZhY2Vfc2l6ZSAqc2l6ZXMpCj4gKyAqICAgICB7Cj4gKyAqICAgICAgICAgcmV0dXJu IGRybV9mYmRldl9jbWFfY3JlYXRlX3dpdGhfZnVuY3MoaGVscGVyLCBzaXplcywKPiArICogICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZHJpdmVyX2ZiZGV2 X2ZiX2Z1bmNzKTsKPiArICogICAgIH0KPiArICoKPiArICogICAgIHN0YXRpYyBjb25zdCBzdHJ1 Y3QgZHJtX2ZiX2hlbHBlcl9mdW5jcyBkcml2ZXJfZmJfaGVscGVyX2Z1bmNzID0gewo+ICsgKiAg ICAgICAgIC5mYl9wcm9iZSA9IGRyaXZlcl9mYmRldl9jcmVhdGUsCj4gKyAqICAgICB9Owo+ICsg Kgo+ICsgKiAgICAgSW5pdGlhbGl6ZToKPiArICogICAgIGZiZGV2ID0gZHJtX2ZiZGV2X2NtYV9p bml0X3dpdGhfZnVuY3MoZGV2LCAxNiwKPiArICogICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgZGV2LT5tb2RlX2NvbmZpZy5udW1fY3J0YywKPiArICogICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2LT5tb2RlX2NvbmZpZy5udW1fY29u bmVjdG9yLAo+ICsgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAm ZHJpdmVyX2ZiX2hlbHBlcl9mdW5jcyk7Cj4gKyAqCj4gKyAqLwo+ICsKPiAgc3RhdGljIGlubGlu ZSBzdHJ1Y3QgZHJtX2ZiZGV2X2NtYSAqdG9fZmJkZXZfY21hKHN0cnVjdCBkcm1fZmJfaGVscGVy ICpoZWxwZXIpCj4gIHsKPiAgCXJldHVybiBjb250YWluZXJfb2YoaGVscGVyLCBzdHJ1Y3QgZHJt X2ZiZGV2X2NtYSwgZmJfaGVscGVyKTsKPiBAQCAtNDUsNyArMTAyLDcgQEAgc3RhdGljIGlubGlu ZSBzdHJ1Y3QgZHJtX2ZiX2NtYSAqdG9fZmJfY21hKHN0cnVjdCBkcm1fZnJhbWVidWZmZXIgKmZi KQo+ICAJcmV0dXJuIGNvbnRhaW5lcl9vZihmYiwgc3RydWN0IGRybV9mYl9jbWEsIGZiKTsKPiAg fQo+ICAKPiAtc3RhdGljIHZvaWQgZHJtX2ZiX2NtYV9kZXN0cm95KHN0cnVjdCBkcm1fZnJhbWVi dWZmZXIgKmZiKQo+ICt2b2lkIGRybV9mYl9jbWFfZGVzdHJveShzdHJ1Y3QgZHJtX2ZyYW1lYnVm ZmVyICpmYikKPiAgewo+ICAJc3RydWN0IGRybV9mYl9jbWEgKmZiX2NtYSA9IHRvX2ZiX2NtYShm Yik7Cj4gIAlpbnQgaTsKPiBAQCAtNTgsOCArMTE1LDkgQEAgc3RhdGljIHZvaWQgZHJtX2ZiX2Nt YV9kZXN0cm95KHN0cnVjdCBkcm1fZnJhbWVidWZmZXIgKmZiKQo+ICAJZHJtX2ZyYW1lYnVmZmVy X2NsZWFudXAoZmIpOwo+ICAJa2ZyZWUoZmJfY21hKTsKPiAgfQo+ICtFWFBPUlRfU1lNQk9MKGRy bV9mYl9jbWFfZGVzdHJveSk7Cj4gIAo+IC1zdGF0aWMgaW50IGRybV9mYl9jbWFfY3JlYXRlX2hh bmRsZShzdHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyICpmYiwKPiAraW50IGRybV9mYl9jbWFfY3JlYXRl X2hhbmRsZShzdHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyICpmYiwKPiAgCXN0cnVjdCBkcm1fZmlsZSAq ZmlsZV9wcml2LCB1bnNpZ25lZCBpbnQgKmhhbmRsZSkKPiAgewo+ICAJc3RydWN0IGRybV9mYl9j bWEgKmZiX2NtYSA9IHRvX2ZiX2NtYShmYik7Cj4gQEAgLTY3LDYgKzEyNSw3IEBAIHN0YXRpYyBp bnQgZHJtX2ZiX2NtYV9jcmVhdGVfaGFuZGxlKHN0cnVjdCBkcm1fZnJhbWVidWZmZXIgKmZiLAo+ ICAJcmV0dXJuIGRybV9nZW1faGFuZGxlX2NyZWF0ZShmaWxlX3ByaXYsCj4gIAkJCSZmYl9jbWEt Pm9ialswXS0+YmFzZSwgaGFuZGxlKTsKPiAgfQo+ICtFWFBPUlRfU1lNQk9MKGRybV9mYl9jbWFf Y3JlYXRlX2hhbmRsZSk7Cj4gIAo+ICBzdGF0aWMgc3RydWN0IGRybV9mcmFtZWJ1ZmZlcl9mdW5j cyBkcm1fZmJfY21hX2Z1bmNzID0gewo+ICAJLmRlc3Ryb3kJPSBkcm1fZmJfY21hX2Rlc3Ryb3ks Cj4gQEAgLTc2LDcgKzEzNSw3IEBAIHN0YXRpYyBzdHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyX2Z1bmNz IGRybV9mYl9jbWFfZnVuY3MgPSB7Cj4gIHN0YXRpYyBzdHJ1Y3QgZHJtX2ZiX2NtYSAqZHJtX2Zi X2NtYV9hbGxvYyhzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAo+ICAJY29uc3Qgc3RydWN0IGRybV9t b2RlX2ZiX2NtZDIgKm1vZGVfY21kLAo+ICAJc3RydWN0IGRybV9nZW1fY21hX29iamVjdCAqKm9i aiwKPiAtCXVuc2lnbmVkIGludCBudW1fcGxhbmVzKQo+ICsJdW5zaWduZWQgaW50IG51bV9wbGFu ZXMsIHN0cnVjdCBkcm1fZnJhbWVidWZmZXJfZnVuY3MgKmZ1bmNzKQo+ICB7Cj4gIAlzdHJ1Y3Qg ZHJtX2ZiX2NtYSAqZmJfY21hOwo+ICAJaW50IHJldDsKPiBAQCAtOTEsNyArMTUwLDcgQEAgc3Rh dGljIHN0cnVjdCBkcm1fZmJfY21hICpkcm1fZmJfY21hX2FsbG9jKHN0cnVjdCBkcm1fZGV2aWNl ICpkZXYsCj4gIAlmb3IgKGkgPSAwOyBpIDwgbnVtX3BsYW5lczsgaSsrKQo+ICAJCWZiX2NtYS0+ b2JqW2ldID0gb2JqW2ldOwo+ICAKPiAtCXJldCA9IGRybV9mcmFtZWJ1ZmZlcl9pbml0KGRldiwg JmZiX2NtYS0+ZmIsICZkcm1fZmJfY21hX2Z1bmNzKTsKPiArCXJldCA9IGRybV9mcmFtZWJ1ZmZl cl9pbml0KGRldiwgJmZiX2NtYS0+ZmIsIGZ1bmNzKTsKPiAgCWlmIChyZXQpIHsKPiAgCQlkZXZf ZXJyKGRldi0+ZGV2LCAiRmFpbGVkIHRvIGluaXRpYWxpemUgZnJhbWVidWZmZXI6ICVkXG4iLCBy ZXQpOwo+ICAJCWtmcmVlKGZiX2NtYSk7Cj4gQEAgLTE0NSw3ICsyMDQsNyBAQCBzdHJ1Y3QgZHJt X2ZyYW1lYnVmZmVyICpkcm1fZmJfY21hX2NyZWF0ZShzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAo+ ICAJCW9ianNbaV0gPSB0b19kcm1fZ2VtX2NtYV9vYmoob2JqKTsKPiAgCX0KPiAgCj4gLQlmYl9j bWEgPSBkcm1fZmJfY21hX2FsbG9jKGRldiwgbW9kZV9jbWQsIG9ianMsIGkpOwo+ICsJZmJfY21h ID0gZHJtX2ZiX2NtYV9hbGxvYyhkZXYsIG1vZGVfY21kLCBvYmpzLCBpLCAmZHJtX2ZiX2NtYV9m dW5jcyk7Cj4gIAlpZiAoSVNfRVJSKGZiX2NtYSkpIHsKPiAgCQlyZXQgPSBQVFJfRVJSKGZiX2Nt YSk7Cj4gIAkJZ290byBlcnJfZ2VtX29iamVjdF91bnJlZmVyZW5jZTsKPiBAQCAtMjMzLDggKzI5 Miw3OSBAQCBzdGF0aWMgc3RydWN0IGZiX29wcyBkcm1fZmJkZXZfY21hX29wcyA9IHsKPiAgCS5m Yl9zZXRjbWFwCT0gZHJtX2ZiX2hlbHBlcl9zZXRjbWFwLAo+ICB9Owo+ICAKPiAtc3RhdGljIGlu dCBkcm1fZmJkZXZfY21hX2NyZWF0ZShzdHJ1Y3QgZHJtX2ZiX2hlbHBlciAqaGVscGVyLAo+IC0J c3RydWN0IGRybV9mYl9oZWxwZXJfc3VyZmFjZV9zaXplICpzaXplcykKPiArI2lmZGVmIENPTkZJ R19GQl9ERUZFUlJFRF9JTwoKU2FtZSBxdWVzdGlvbiBhYm91dCBjb25maWcgaGFuZGxpbmcuIElt byBqdXN0IHNlbGVjdGluZyB0aGlzIGlzIG9rLCBhbmQKd291bGQgcmVtb3ZlIGEgZmV3ICNpZmRl ZiBmcm9tIHRoZSBjb2RlLgoKT3RoZXJ3aXNlIGxndG0sIGJ1dCBuZWVkcyBhbiBhY2svci1iIGZy b20gTGF1cmVudC4KLURhbmllbAoKPiArc3RhdGljIGludCBkcm1fZmJkZXZfY21hX2RlZmVycmVk X2lvX21tYXAoc3RydWN0IGZiX2luZm8gKmluZm8sCj4gKwkJCQkJICBzdHJ1Y3Qgdm1fYXJlYV9z dHJ1Y3QgKnZtYSkKPiArewo+ICsJZmJfZGVmZXJyZWRfaW9fbW1hcChpbmZvLCB2bWEpOwo+ICsJ dm1hLT52bV9wYWdlX3Byb3QgPSBwZ3Byb3Rfd3JpdGVjb21iaW5lKHZtYS0+dm1fcGFnZV9wcm90 KTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGludCBkcm1fZmJkZXZfY21h X2RlZmlvX2luaXQoc3RydWN0IGZiX2luZm8gKmZiaSwKPiArCQkJCSAgICBzdHJ1Y3QgZHJtX2dl bV9jbWFfb2JqZWN0ICpjbWFfb2JqKQo+ICt7Cj4gKwlzdHJ1Y3QgZmJfZGVmZXJyZWRfaW8gKmZi ZGVmaW87Cj4gKwlzdHJ1Y3QgZmJfb3BzICpmYm9wczsKPiArCj4gKwkvKgo+ICsJICogUGVyIGRl dmljZSBzdHJ1Y3R1cmVzIGFyZSBuZWVkZWQgYmVjYXVzZToKPiArCSAqIGZib3BzOiBmYl9kZWZl cnJlZF9pb19jbGVhbnVwKCkgY2xlYXJzIGZib3BzLmZiX21tYXAKPiArCSAqIGZiZGVmaW86IGlu ZGl2aWR1YWwgZGVsYXlzCj4gKwkgKi8KPiArCWZiZGVmaW8gPSBremFsbG9jKHNpemVvZigqZmJk ZWZpbyksIEdGUF9LRVJORUwpOwo+ICsJZmJvcHMgPSBremFsbG9jKHNpemVvZigqZmJvcHMpLCBH RlBfS0VSTkVMKTsKPiArCWlmICghZmJkZWZpbyB8fCAhZmJvcHMpIHsKPiArCQlrZnJlZShmYmRl ZmlvKTsKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCX0KPiArCj4gKwkvKiBjYW4ndCBiZSBvZmZz ZXQgZnJvbSB2YWRkciBzaW5jZSBkaXJ0eSgpIHVzZXMgY21hX29iaiAqLwo+ICsJZmJpLT5zY3Jl ZW5fYnVmZmVyID0gY21hX29iai0+dmFkZHI7Cj4gKwkvKiBmYl9kZWZlcnJlZF9pb19mYXVsdCgp IG5lZWRzIGEgcGh5c2ljYWwgYWRkcmVzcyAqLwo+ICsJZmJpLT5maXguc21lbV9zdGFydCA9IHBh Z2VfdG9fcGh5cyh2aXJ0X3RvX3BhZ2UoZmJpLT5zY3JlZW5fYnVmZmVyKSk7Cj4gKwo+ICsJKmZi b3BzID0gKmZiaS0+ZmJvcHM7Cj4gKwlmYmktPmZib3BzID0gZmJvcHM7Cj4gKwo+ICsJZmJkZWZp by0+ZGVsYXkgPSBtc2Vjc190b19qaWZmaWVzKERFRkFVTFRfRkJERUZJT19ERUxBWV9NUyk7Cj4g KwlmYmRlZmlvLT5kZWZlcnJlZF9pbyA9IGRybV9mYl9oZWxwZXJfZGVmZXJyZWRfaW87Cj4gKwlm YmktPmZiZGVmaW8gPSBmYmRlZmlvOwo+ICsJZmJfZGVmZXJyZWRfaW9faW5pdChmYmkpOwo+ICsJ ZmJpLT5mYm9wcy0+ZmJfbW1hcCA9IGRybV9mYmRldl9jbWFfZGVmZXJyZWRfaW9fbW1hcDsKPiAr Cj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgZHJtX2ZiZGV2X2NtYV9kZWZp b19maW5pKHN0cnVjdCBmYl9pbmZvICpmYmkpCj4gK3sKPiArCWlmICghZmJpLT5mYmRlZmlvKQo+ ICsJCXJldHVybjsKPiArCj4gKwlmYl9kZWZlcnJlZF9pb19jbGVhbnVwKGZiaSk7Cj4gKwlrZnJl ZShmYmktPmZiZGVmaW8pOwo+ICsJa2ZyZWUoZmJpLT5mYm9wcyk7Cj4gK30KPiArI2Vsc2UKPiAr c3RhdGljIGludCBkcm1fZmJkZXZfY21hX2RlZmlvX2luaXQoc3RydWN0IGZiX2luZm8gKmZiaSwK PiArCQkJCSAgICBzdHJ1Y3QgZHJtX2dlbV9jbWFfb2JqZWN0ICpjbWFfb2JqKQo+ICt7Cj4gKwly ZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgZHJtX2ZiZGV2X2NtYV9kZWZpb19maW5p KHN0cnVjdCBmYl9pbmZvICpmYmkpCj4gK3sKPiArfQo+ICsjZW5kaWYgLyogQ09ORklHX0ZCX0RF RkVSUkVEX0lPICovCj4gKwo+ICsvKgo+ICsgKiBGb3IgdXNlIGluIGEgKHN0cnVjdCBkcm1fZmJf aGVscGVyX2Z1bmNzICopLT5mYl9wcm9iZSBjYWxsYmFjayBmdW5jdGlvbiB0aGF0Cj4gKyAqIG5l ZWRzIGN1c3RvbSBzdHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyX2Z1bmNzLCBsaWtlIGRpcnR5KCkgZm9y IGRlZmVycmVkX2lvIHVzZS4KPiArICovCj4gK2ludCBkcm1fZmJkZXZfY21hX2NyZWF0ZV93aXRo X2Z1bmNzKHN0cnVjdCBkcm1fZmJfaGVscGVyICpoZWxwZXIsCj4gKwlzdHJ1Y3QgZHJtX2ZiX2hl bHBlcl9zdXJmYWNlX3NpemUgKnNpemVzLAo+ICsJc3RydWN0IGRybV9mcmFtZWJ1ZmZlcl9mdW5j cyAqZnVuY3MpCj4gIHsKPiAgCXN0cnVjdCBkcm1fZmJkZXZfY21hICpmYmRldl9jbWEgPSB0b19m YmRldl9jbWEoaGVscGVyKTsKPiAgCXN0cnVjdCBkcm1fbW9kZV9mYl9jbWQyIG1vZGVfY21kID0g eyAwIH07Cj4gQEAgLTI3MCw3ICs0MDAsNyBAQCBzdGF0aWMgaW50IGRybV9mYmRldl9jbWFfY3Jl YXRlKHN0cnVjdCBkcm1fZmJfaGVscGVyICpoZWxwZXIsCj4gIAkJZ290byBlcnJfZ2VtX2ZyZWVf b2JqZWN0Owo+ICAJfQo+ICAKPiAtCWZiZGV2X2NtYS0+ZmIgPSBkcm1fZmJfY21hX2FsbG9jKGRl diwgJm1vZGVfY21kLCAmb2JqLCAxKTsKPiArCWZiZGV2X2NtYS0+ZmIgPSBkcm1fZmJfY21hX2Fs bG9jKGRldiwgJm1vZGVfY21kLCAmb2JqLCAxLCBmdW5jcyk7Cj4gIAlpZiAoSVNfRVJSKGZiZGV2 X2NtYS0+ZmIpKSB7Cj4gIAkJZGV2X2VycihkZXYtPmRldiwgIkZhaWxlZCB0byBhbGxvY2F0ZSBE Uk0gZnJhbWVidWZmZXIuXG4iKTsKPiAgCQlyZXQgPSBQVFJfRVJSKGZiZGV2X2NtYS0+ZmIpOwo+ IEBAIC0yOTYsMzEgKzQyNiw0OCBAQCBzdGF0aWMgaW50IGRybV9mYmRldl9jbWFfY3JlYXRlKHN0 cnVjdCBkcm1fZmJfaGVscGVyICpoZWxwZXIsCj4gIAlmYmktPnNjcmVlbl9zaXplID0gc2l6ZTsK PiAgCWZiaS0+Zml4LnNtZW1fbGVuID0gc2l6ZTsKPiAgCj4gKwlpZiAoZnVuY3MtPmRpcnR5KSB7 Cj4gKwkJcmV0ID0gZHJtX2ZiZGV2X2NtYV9kZWZpb19pbml0KGZiaSwgb2JqKTsKPiArCQlpZiAo cmV0KQo+ICsJCQlnb3RvIGVycl9jbWFfZGVzdHJveTsKPiArCX0KPiArCj4gIAlyZXR1cm4gMDsK PiAgCj4gK2Vycl9jbWFfZGVzdHJveToKPiArCWRybV9mcmFtZWJ1ZmZlcl91bnJlZ2lzdGVyX3By aXZhdGUoJmZiZGV2X2NtYS0+ZmItPmZiKTsKPiArCWRybV9mYl9jbWFfZGVzdHJveSgmZmJkZXZf Y21hLT5mYi0+ZmIpOwo+ICBlcnJfZmJfaW5mb19kZXN0cm95Ogo+ICAJZHJtX2ZiX2hlbHBlcl9y ZWxlYXNlX2ZiaShoZWxwZXIpOwo+ICBlcnJfZ2VtX2ZyZWVfb2JqZWN0Ogo+ICAJZGV2LT5kcml2 ZXItPmdlbV9mcmVlX29iamVjdCgmb2JqLT5iYXNlKTsKPiAgCXJldHVybiByZXQ7Cj4gIH0KPiAr RVhQT1JUX1NZTUJPTChkcm1fZmJkZXZfY21hX2NyZWF0ZV93aXRoX2Z1bmNzKTsKPiArCj4gK3N0 YXRpYyBpbnQgZHJtX2ZiZGV2X2NtYV9jcmVhdGUoc3RydWN0IGRybV9mYl9oZWxwZXIgKmhlbHBl ciwKPiArCXN0cnVjdCBkcm1fZmJfaGVscGVyX3N1cmZhY2Vfc2l6ZSAqc2l6ZXMpCj4gK3sKPiAr CXJldHVybiBkcm1fZmJkZXZfY21hX2NyZWF0ZV93aXRoX2Z1bmNzKGhlbHBlciwgc2l6ZXMsICZk cm1fZmJfY21hX2Z1bmNzKTsKPiArfQo+ICAKPiAgc3RhdGljIGNvbnN0IHN0cnVjdCBkcm1fZmJf aGVscGVyX2Z1bmNzIGRybV9mYl9jbWFfaGVscGVyX2Z1bmNzID0gewo+ICAJLmZiX3Byb2JlID0g ZHJtX2ZiZGV2X2NtYV9jcmVhdGUsCj4gIH07Cj4gIAo+ICAvKioKPiAtICogZHJtX2ZiZGV2X2Nt YV9pbml0KCkgLSBBbGxvY2F0ZSBhbmQgaW5pdGlhbGl6ZXMgYSBkcm1fZmJkZXZfY21hIHN0cnVj dAo+ICsgKiBkcm1fZmJkZXZfY21hX2luaXRfd2l0aF9mdW5jcygpIC0gQWxsb2NhdGUgYW5kIGlu aXRpYWxpemVzIGEgZHJtX2ZiZGV2X2NtYSBzdHJ1Y3QKPiAgICogQGRldjogRFJNIGRldmljZQo+ ICAgKiBAcHJlZmVycmVkX2JwcDogUHJlZmVycmVkIGJpdHMgcGVyIHBpeGVsIGZvciB0aGUgZGV2 aWNlCj4gICAqIEBudW1fY3J0YzogTnVtYmVyIG9mIENSVENzCj4gICAqIEBtYXhfY29ubl9jb3Vu dDogTWF4aW11bSBudW1iZXIgb2YgY29ubmVjdG9ycwo+ICsgKiBAZnVuY3M6IGZiIGhlbHBlciBm dW5jdGlvbnMsIGluIHBhcnRpY3VsYXIgZmJfcHJvYmUoKQo+ICAgKgo+ICAgKiBSZXR1cm5zIGEg bmV3bHkgYWxsb2NhdGVkIGRybV9mYmRldl9jbWEgc3RydWN0IG9yIGEgRVJSX1BUUi4KPiAgICov Cj4gLXN0cnVjdCBkcm1fZmJkZXZfY21hICpkcm1fZmJkZXZfY21hX2luaXQoc3RydWN0IGRybV9k ZXZpY2UgKmRldiwKPiArc3RydWN0IGRybV9mYmRldl9jbWEgKmRybV9mYmRldl9jbWFfaW5pdF93 aXRoX2Z1bmNzKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsCj4gIAl1bnNpZ25lZCBpbnQgcHJlZmVy cmVkX2JwcCwgdW5zaWduZWQgaW50IG51bV9jcnRjLAo+IC0JdW5zaWduZWQgaW50IG1heF9jb25u X2NvdW50KQo+ICsJdW5zaWduZWQgaW50IG1heF9jb25uX2NvdW50LCBjb25zdCBzdHJ1Y3QgZHJt X2ZiX2hlbHBlcl9mdW5jcyAqZnVuY3MpCj4gIHsKPiAgCXN0cnVjdCBkcm1fZmJkZXZfY21hICpm YmRldl9jbWE7Cj4gIAlzdHJ1Y3QgZHJtX2ZiX2hlbHBlciAqaGVscGVyOwo+IEBAIC0zMzQsNyAr NDgxLDcgQEAgc3RydWN0IGRybV9mYmRldl9jbWEgKmRybV9mYmRldl9jbWFfaW5pdChzdHJ1Y3Qg ZHJtX2RldmljZSAqZGV2LAo+ICAKPiAgCWhlbHBlciA9ICZmYmRldl9jbWEtPmZiX2hlbHBlcjsK PiAgCj4gLQlkcm1fZmJfaGVscGVyX3ByZXBhcmUoZGV2LCBoZWxwZXIsICZkcm1fZmJfY21hX2hl bHBlcl9mdW5jcyk7Cj4gKwlkcm1fZmJfaGVscGVyX3ByZXBhcmUoZGV2LCBoZWxwZXIsIGZ1bmNz KTsKPiAgCj4gIAlyZXQgPSBkcm1fZmJfaGVscGVyX2luaXQoZGV2LCBoZWxwZXIsIG51bV9jcnRj LCBtYXhfY29ubl9jb3VudCk7Cj4gIAlpZiAocmV0IDwgMCkgewo+IEBAIC0zNjQsNiArNTExLDI0 IEBAIGVycl9mcmVlOgo+ICAKPiAgCXJldHVybiBFUlJfUFRSKHJldCk7Cj4gIH0KPiArRVhQT1JU X1NZTUJPTF9HUEwoZHJtX2ZiZGV2X2NtYV9pbml0X3dpdGhfZnVuY3MpOwo+ICsKPiArLyoqCj4g KyAqIGRybV9mYmRldl9jbWFfaW5pdCgpIC0gQWxsb2NhdGUgYW5kIGluaXRpYWxpemVzIGEgZHJt X2ZiZGV2X2NtYSBzdHJ1Y3QKPiArICogQGRldjogRFJNIGRldmljZQo+ICsgKiBAcHJlZmVycmVk X2JwcDogUHJlZmVycmVkIGJpdHMgcGVyIHBpeGVsIGZvciB0aGUgZGV2aWNlCj4gKyAqIEBudW1f Y3J0YzogTnVtYmVyIG9mIENSVENzCj4gKyAqIEBtYXhfY29ubl9jb3VudDogTWF4aW11bSBudW1i ZXIgb2YgY29ubmVjdG9ycwo+ICsgKgo+ICsgKiBSZXR1cm5zIGEgbmV3bHkgYWxsb2NhdGVkIGRy bV9mYmRldl9jbWEgc3RydWN0IG9yIGEgRVJSX1BUUi4KPiArICovCj4gK3N0cnVjdCBkcm1fZmJk ZXZfY21hICpkcm1fZmJkZXZfY21hX2luaXQoc3RydWN0IGRybV9kZXZpY2UgKmRldiwKPiArCXVu c2lnbmVkIGludCBwcmVmZXJyZWRfYnBwLCB1bnNpZ25lZCBpbnQgbnVtX2NydGMsCj4gKwl1bnNp Z25lZCBpbnQgbWF4X2Nvbm5fY291bnQpCj4gK3sKPiArCXJldHVybiBkcm1fZmJkZXZfY21hX2lu aXRfd2l0aF9mdW5jcyhkZXYsIHByZWZlcnJlZF9icHAsIG51bV9jcnRjLAo+ICsJCQkJbWF4X2Nv bm5fY291bnQsICZkcm1fZmJfY21hX2hlbHBlcl9mdW5jcyk7Cj4gK30KPiAgRVhQT1JUX1NZTUJP TF9HUEwoZHJtX2ZiZGV2X2NtYV9pbml0KTsKPiAgCj4gIC8qKgo+IEBAIC0zNzMsNiArNTM4LDcg QEAgRVhQT1JUX1NZTUJPTF9HUEwoZHJtX2ZiZGV2X2NtYV9pbml0KTsKPiAgdm9pZCBkcm1fZmJk ZXZfY21hX2Zpbmkoc3RydWN0IGRybV9mYmRldl9jbWEgKmZiZGV2X2NtYSkKPiAgewo+ICAJZHJt X2ZiX2hlbHBlcl91bnJlZ2lzdGVyX2ZiaSgmZmJkZXZfY21hLT5mYl9oZWxwZXIpOwo+ICsJZHJt X2ZiZGV2X2NtYV9kZWZpb19maW5pKGZiZGV2X2NtYS0+ZmJfaGVscGVyLmZiZGV2KTsKPiAgCWRy bV9mYl9oZWxwZXJfcmVsZWFzZV9mYmkoJmZiZGV2X2NtYS0+ZmJfaGVscGVyKTsKPiAgCj4gIAlp ZiAoZmJkZXZfY21hLT5mYikgewo+IGRpZmYgLS1naXQgYS9pbmNsdWRlL2RybS9kcm1fZmJfY21h X2hlbHBlci5oIGIvaW5jbHVkZS9kcm0vZHJtX2ZiX2NtYV9oZWxwZXIuaAo+IGluZGV4IGJlNjJi ZDMuLjY1NTRiNmYgMTAwNjQ0Cj4gLS0tIGEvaW5jbHVkZS9kcm0vZHJtX2ZiX2NtYV9oZWxwZXIu aAo+ICsrKyBiL2luY2x1ZGUvZHJtL2RybV9mYl9jbWFfaGVscGVyLmgKPiBAQCAtNCwxMSArNCwx OCBAQAo+ICBzdHJ1Y3QgZHJtX2ZiZGV2X2NtYTsKPiAgc3RydWN0IGRybV9nZW1fY21hX29iamVj dDsKPiAgCj4gK3N0cnVjdCBkcm1fZmJfaGVscGVyX3N1cmZhY2Vfc2l6ZTsKPiArc3RydWN0IGRy bV9mcmFtZWJ1ZmZlcl9mdW5jczsKPiArc3RydWN0IGRybV9mYl9oZWxwZXJfZnVuY3M7Cj4gIHN0 cnVjdCBkcm1fZnJhbWVidWZmZXI7Cj4gK3N0cnVjdCBkcm1fZmJfaGVscGVyOwo+ICBzdHJ1Y3Qg ZHJtX2RldmljZTsKPiAgc3RydWN0IGRybV9maWxlOwo+ICBzdHJ1Y3QgZHJtX21vZGVfZmJfY21k MjsKPiAgCj4gK3N0cnVjdCBkcm1fZmJkZXZfY21hICpkcm1fZmJkZXZfY21hX2luaXRfd2l0aF9m dW5jcyhzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAo+ICsJdW5zaWduZWQgaW50IHByZWZlcnJlZF9i cHAsIHVuc2lnbmVkIGludCBudW1fY3J0YywKPiArCXVuc2lnbmVkIGludCBtYXhfY29ubl9jb3Vu dCwgY29uc3Qgc3RydWN0IGRybV9mYl9oZWxwZXJfZnVuY3MgKmZ1bmNzKTsKPiAgc3RydWN0IGRy bV9mYmRldl9jbWEgKmRybV9mYmRldl9jbWFfaW5pdChzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAo+ ICAJdW5zaWduZWQgaW50IHByZWZlcnJlZF9icHAsIHVuc2lnbmVkIGludCBudW1fY3J0YywKPiAg CXVuc2lnbmVkIGludCBtYXhfY29ubl9jb3VudCk7Cj4gQEAgLTE2LDYgKzIzLDEzIEBAIHZvaWQg ZHJtX2ZiZGV2X2NtYV9maW5pKHN0cnVjdCBkcm1fZmJkZXZfY21hICpmYmRldl9jbWEpOwo+ICAK PiAgdm9pZCBkcm1fZmJkZXZfY21hX3Jlc3RvcmVfbW9kZShzdHJ1Y3QgZHJtX2ZiZGV2X2NtYSAq ZmJkZXZfY21hKTsKPiAgdm9pZCBkcm1fZmJkZXZfY21hX2hvdHBsdWdfZXZlbnQoc3RydWN0IGRy bV9mYmRldl9jbWEgKmZiZGV2X2NtYSk7Cj4gK2ludCBkcm1fZmJkZXZfY21hX2NyZWF0ZV93aXRo X2Z1bmNzKHN0cnVjdCBkcm1fZmJfaGVscGVyICpoZWxwZXIsCj4gKwlzdHJ1Y3QgZHJtX2ZiX2hl bHBlcl9zdXJmYWNlX3NpemUgKnNpemVzLAo+ICsJc3RydWN0IGRybV9mcmFtZWJ1ZmZlcl9mdW5j cyAqZnVuY3MpOwo+ICsKPiArdm9pZCBkcm1fZmJfY21hX2Rlc3Ryb3koc3RydWN0IGRybV9mcmFt ZWJ1ZmZlciAqZmIpOwo+ICtpbnQgZHJtX2ZiX2NtYV9jcmVhdGVfaGFuZGxlKHN0cnVjdCBkcm1f ZnJhbWVidWZmZXIgKmZiLAo+ICsJc3RydWN0IGRybV9maWxlICpmaWxlX3ByaXYsIHVuc2lnbmVk IGludCAqaGFuZGxlKTsKPiAgCj4gIHN0cnVjdCBkcm1fZnJhbWVidWZmZXIgKmRybV9mYl9jbWFf Y3JlYXRlKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsCj4gIAlzdHJ1Y3QgZHJtX2ZpbGUgKmZpbGVf cHJpdiwgY29uc3Qgc3RydWN0IGRybV9tb2RlX2ZiX2NtZDIgKm1vZGVfY21kKTsKPiAtLSAKPiAy LjIuMgo+IAoKLS0gCkRhbmllbCBWZXR0ZXIKU29mdHdhcmUgRW5naW5lZXIsIEludGVsIENvcnBv cmF0aW9uCmh0dHA6Ly9ibG9nLmZmd2xsLmNoCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3Rz LmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xp c3RpbmZvL2RyaS1kZXZlbAo= From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754037AbcDYJPX (ORCPT ); Mon, 25 Apr 2016 05:15:23 -0400 Received: from mail-wm0-f50.google.com ([74.125.82.50]:37990 "EHLO mail-wm0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753483AbcDYJPV (ORCPT ); Mon, 25 Apr 2016 05:15:21 -0400 Date: Mon, 25 Apr 2016 11:15:17 +0200 From: Daniel Vetter To: Noralf =?iso-8859-1?Q?Tr=F8nnes?= Cc: dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org, daniel@ffwll.ch, laurent.pinchart@ideasonboard.com, tomi.valkeinen@ti.com, linux-kernel@vger.kernel.org Subject: Re: [PATCH v2 6/8] drm/fb-cma-helper: Add fb_deferred_io support Message-ID: <20160425091517.GS2510@phenom.ffwll.local> Mail-Followup-To: Noralf =?iso-8859-1?Q?Tr=F8nnes?= , dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org, laurent.pinchart@ideasonboard.com, tomi.valkeinen@ti.com, linux-kernel@vger.kernel.org References: <1461530942-22485-1-git-send-email-noralf@tronnes.org> <1461530942-22485-7-git-send-email-noralf@tronnes.org> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1461530942-22485-7-git-send-email-noralf@tronnes.org> X-Operating-System: Linux phenom 4.4.0-1-amd64 User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sun, Apr 24, 2016 at 10:49:00PM +0200, Noralf Trønnes wrote: > This adds fbdev deferred io support if CONFIG_FB_DEFERRED_IO is enabled. > The driver has to provide a (struct drm_framebuffer_funcs *)->dirty() > callback to get notification of fbdev framebuffer changes. > If the dirty() hook is set, then fb_deferred_io is set up automatically > by the helper. > > Two functions have been added so that the driver can provide a dirty() > function: > - drm_fbdev_cma_init_with_funcs() > This makes it possible for the driver to provided a custom > (struct drm_fb_helper_funcs *)->fb_probe() function. > - drm_fbdev_cma_create_with_funcs() > This is used by the .fb_probe hook to set a driver provided > (struct drm_framebuffer_funcs *)->dirty() function. > > Signed-off-by: Noralf Trønnes > --- > drivers/gpu/drm/drm_fb_cma_helper.c | 190 +++++++++++++++++++++++++++++++++--- > include/drm/drm_fb_cma_helper.h | 14 +++ > 2 files changed, 192 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c > index bb88e3d..d1e9db0 100644 > --- a/drivers/gpu/drm/drm_fb_cma_helper.c > +++ b/drivers/gpu/drm/drm_fb_cma_helper.c > @@ -25,6 +25,8 @@ > #include > #include > > +#define DEFAULT_FBDEFIO_DELAY_MS 50 > + > struct drm_fb_cma { > struct drm_framebuffer fb; > struct drm_gem_cma_object *obj[4]; > @@ -35,6 +37,61 @@ struct drm_fbdev_cma { > struct drm_fb_cma *fb; > }; > > +/** > + * DOC: framebuffer cma helper functions > + * > + * Provides helper functions for creating a cma (contiguous memory allocator) > + * backed framebuffer. > + * > + * drm_fb_cma_create() is used in the > + * (struct drm_mode_config_funcs *)->fb_create callback function to create the Nit: If you use &drm_mode_config_funcs kerneldoc will insert a hyperlink to the corresponding kerneldoc for the struct. So common style is "drm_fb_cma_create() is used in the &drm_mode_config_funcs ->fb_create() callback function ..." Please roll this it to other places where you reference structs. Eventually kerneldoc people have the dream to enable cross-referencing across the entire kernel tree (so stuff like &delayed_work hopefully works then too). > + * cma backed framebuffer. > + * > + * An fbdev framebuffer backed by cma is also available by calling > + * drm_fbdev_cma_init(). drm_fbdev_cma_fini() tears it down. > + * If CONFIG_FB_DEFERRED_IO is enabled and the callback > + * (struct drm_framebuffer_funcs)->dirty is set, fb_deferred_io > + * will be set up automatically. dirty() is called by > + * drm_fb_helper_deferred_io() in process context (struct delayed_work). > + * > + * Example fbdev deferred io code: > + * > + * static int driver_fbdev_fb_dirty(struct drm_framebuffer *fb, > + * struct drm_file *file_priv, > + * unsigned flags, unsigned color, > + * struct drm_clip_rect *clips, > + * unsigned num_clips) > + * { > + * struct drm_gem_cma_object *cma = drm_fb_cma_get_gem_obj(fb, 0); > + * ... push changes ... > + * return 0; > + * } > + * > + * static struct drm_framebuffer_funcs driver_fbdev_fb_funcs = { > + * .destroy = drm_fb_cma_destroy, > + * .create_handle = drm_fb_cma_create_handle, > + * .dirty = driver_fbdev_fb_dirty, > + * }; > + * > + * static int driver_fbdev_create(struct drm_fb_helper *helper, > + * struct drm_fb_helper_surface_size *sizes) > + * { > + * return drm_fbdev_cma_create_with_funcs(helper, sizes, > + * &driver_fbdev_fb_funcs); > + * } > + * > + * static const struct drm_fb_helper_funcs driver_fb_helper_funcs = { > + * .fb_probe = driver_fbdev_create, > + * }; > + * > + * Initialize: > + * fbdev = drm_fbdev_cma_init_with_funcs(dev, 16, > + * dev->mode_config.num_crtc, > + * dev->mode_config.num_connector, > + * &driver_fb_helper_funcs); > + * > + */ > + > static inline struct drm_fbdev_cma *to_fbdev_cma(struct drm_fb_helper *helper) > { > return container_of(helper, struct drm_fbdev_cma, fb_helper); > @@ -45,7 +102,7 @@ static inline struct drm_fb_cma *to_fb_cma(struct drm_framebuffer *fb) > return container_of(fb, struct drm_fb_cma, fb); > } > > -static void drm_fb_cma_destroy(struct drm_framebuffer *fb) > +void drm_fb_cma_destroy(struct drm_framebuffer *fb) > { > struct drm_fb_cma *fb_cma = to_fb_cma(fb); > int i; > @@ -58,8 +115,9 @@ static void drm_fb_cma_destroy(struct drm_framebuffer *fb) > drm_framebuffer_cleanup(fb); > kfree(fb_cma); > } > +EXPORT_SYMBOL(drm_fb_cma_destroy); > > -static int drm_fb_cma_create_handle(struct drm_framebuffer *fb, > +int drm_fb_cma_create_handle(struct drm_framebuffer *fb, > struct drm_file *file_priv, unsigned int *handle) > { > struct drm_fb_cma *fb_cma = to_fb_cma(fb); > @@ -67,6 +125,7 @@ static int drm_fb_cma_create_handle(struct drm_framebuffer *fb, > return drm_gem_handle_create(file_priv, > &fb_cma->obj[0]->base, handle); > } > +EXPORT_SYMBOL(drm_fb_cma_create_handle); > > static struct drm_framebuffer_funcs drm_fb_cma_funcs = { > .destroy = drm_fb_cma_destroy, > @@ -76,7 +135,7 @@ static struct drm_framebuffer_funcs drm_fb_cma_funcs = { > static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev, > const struct drm_mode_fb_cmd2 *mode_cmd, > struct drm_gem_cma_object **obj, > - unsigned int num_planes) > + unsigned int num_planes, struct drm_framebuffer_funcs *funcs) > { > struct drm_fb_cma *fb_cma; > int ret; > @@ -91,7 +150,7 @@ static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev, > for (i = 0; i < num_planes; i++) > fb_cma->obj[i] = obj[i]; > > - ret = drm_framebuffer_init(dev, &fb_cma->fb, &drm_fb_cma_funcs); > + ret = drm_framebuffer_init(dev, &fb_cma->fb, funcs); > if (ret) { > dev_err(dev->dev, "Failed to initialize framebuffer: %d\n", ret); > kfree(fb_cma); > @@ -145,7 +204,7 @@ struct drm_framebuffer *drm_fb_cma_create(struct drm_device *dev, > objs[i] = to_drm_gem_cma_obj(obj); > } > > - fb_cma = drm_fb_cma_alloc(dev, mode_cmd, objs, i); > + fb_cma = drm_fb_cma_alloc(dev, mode_cmd, objs, i, &drm_fb_cma_funcs); > if (IS_ERR(fb_cma)) { > ret = PTR_ERR(fb_cma); > goto err_gem_object_unreference; > @@ -233,8 +292,79 @@ static struct fb_ops drm_fbdev_cma_ops = { > .fb_setcmap = drm_fb_helper_setcmap, > }; > > -static int drm_fbdev_cma_create(struct drm_fb_helper *helper, > - struct drm_fb_helper_surface_size *sizes) > +#ifdef CONFIG_FB_DEFERRED_IO Same question about config handling. Imo just selecting this is ok, and would remove a few #ifdef from the code. Otherwise lgtm, but needs an ack/r-b from Laurent. -Daniel > +static int drm_fbdev_cma_deferred_io_mmap(struct fb_info *info, > + struct vm_area_struct *vma) > +{ > + fb_deferred_io_mmap(info, vma); > + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); > + > + return 0; > +} > + > +static int drm_fbdev_cma_defio_init(struct fb_info *fbi, > + struct drm_gem_cma_object *cma_obj) > +{ > + struct fb_deferred_io *fbdefio; > + struct fb_ops *fbops; > + > + /* > + * Per device structures are needed because: > + * fbops: fb_deferred_io_cleanup() clears fbops.fb_mmap > + * fbdefio: individual delays > + */ > + fbdefio = kzalloc(sizeof(*fbdefio), GFP_KERNEL); > + fbops = kzalloc(sizeof(*fbops), GFP_KERNEL); > + if (!fbdefio || !fbops) { > + kfree(fbdefio); > + return -ENOMEM; > + } > + > + /* can't be offset from vaddr since dirty() uses cma_obj */ > + fbi->screen_buffer = cma_obj->vaddr; > + /* fb_deferred_io_fault() needs a physical address */ > + fbi->fix.smem_start = page_to_phys(virt_to_page(fbi->screen_buffer)); > + > + *fbops = *fbi->fbops; > + fbi->fbops = fbops; > + > + fbdefio->delay = msecs_to_jiffies(DEFAULT_FBDEFIO_DELAY_MS); > + fbdefio->deferred_io = drm_fb_helper_deferred_io; > + fbi->fbdefio = fbdefio; > + fb_deferred_io_init(fbi); > + fbi->fbops->fb_mmap = drm_fbdev_cma_deferred_io_mmap; > + > + return 0; > +} > + > +static void drm_fbdev_cma_defio_fini(struct fb_info *fbi) > +{ > + if (!fbi->fbdefio) > + return; > + > + fb_deferred_io_cleanup(fbi); > + kfree(fbi->fbdefio); > + kfree(fbi->fbops); > +} > +#else > +static int drm_fbdev_cma_defio_init(struct fb_info *fbi, > + struct drm_gem_cma_object *cma_obj) > +{ > + return 0; > +} > + > +static void drm_fbdev_cma_defio_fini(struct fb_info *fbi) > +{ > +} > +#endif /* CONFIG_FB_DEFERRED_IO */ > + > +/* > + * For use in a (struct drm_fb_helper_funcs *)->fb_probe callback function that > + * needs custom struct drm_framebuffer_funcs, like dirty() for deferred_io use. > + */ > +int drm_fbdev_cma_create_with_funcs(struct drm_fb_helper *helper, > + struct drm_fb_helper_surface_size *sizes, > + struct drm_framebuffer_funcs *funcs) > { > struct drm_fbdev_cma *fbdev_cma = to_fbdev_cma(helper); > struct drm_mode_fb_cmd2 mode_cmd = { 0 }; > @@ -270,7 +400,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, > goto err_gem_free_object; > } > > - fbdev_cma->fb = drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1); > + fbdev_cma->fb = drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1, funcs); > if (IS_ERR(fbdev_cma->fb)) { > dev_err(dev->dev, "Failed to allocate DRM framebuffer.\n"); > ret = PTR_ERR(fbdev_cma->fb); > @@ -296,31 +426,48 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, > fbi->screen_size = size; > fbi->fix.smem_len = size; > > + if (funcs->dirty) { > + ret = drm_fbdev_cma_defio_init(fbi, obj); > + if (ret) > + goto err_cma_destroy; > + } > + > return 0; > > +err_cma_destroy: > + drm_framebuffer_unregister_private(&fbdev_cma->fb->fb); > + drm_fb_cma_destroy(&fbdev_cma->fb->fb); > err_fb_info_destroy: > drm_fb_helper_release_fbi(helper); > err_gem_free_object: > dev->driver->gem_free_object(&obj->base); > return ret; > } > +EXPORT_SYMBOL(drm_fbdev_cma_create_with_funcs); > + > +static int drm_fbdev_cma_create(struct drm_fb_helper *helper, > + struct drm_fb_helper_surface_size *sizes) > +{ > + return drm_fbdev_cma_create_with_funcs(helper, sizes, &drm_fb_cma_funcs); > +} > > static const struct drm_fb_helper_funcs drm_fb_cma_helper_funcs = { > .fb_probe = drm_fbdev_cma_create, > }; > > /** > - * drm_fbdev_cma_init() - Allocate and initializes a drm_fbdev_cma struct > + * drm_fbdev_cma_init_with_funcs() - Allocate and initializes a drm_fbdev_cma struct > * @dev: DRM device > * @preferred_bpp: Preferred bits per pixel for the device > * @num_crtc: Number of CRTCs > * @max_conn_count: Maximum number of connectors > + * @funcs: fb helper functions, in particular fb_probe() > * > * Returns a newly allocated drm_fbdev_cma struct or a ERR_PTR. > */ > -struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev, > +struct drm_fbdev_cma *drm_fbdev_cma_init_with_funcs(struct drm_device *dev, > unsigned int preferred_bpp, unsigned int num_crtc, > - unsigned int max_conn_count) > + unsigned int max_conn_count, const struct drm_fb_helper_funcs *funcs) > { > struct drm_fbdev_cma *fbdev_cma; > struct drm_fb_helper *helper; > @@ -334,7 +481,7 @@ struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev, > > helper = &fbdev_cma->fb_helper; > > - drm_fb_helper_prepare(dev, helper, &drm_fb_cma_helper_funcs); > + drm_fb_helper_prepare(dev, helper, funcs); > > ret = drm_fb_helper_init(dev, helper, num_crtc, max_conn_count); > if (ret < 0) { > @@ -364,6 +511,24 @@ err_free: > > return ERR_PTR(ret); > } > +EXPORT_SYMBOL_GPL(drm_fbdev_cma_init_with_funcs); > + > +/** > + * drm_fbdev_cma_init() - Allocate and initializes a drm_fbdev_cma struct > + * @dev: DRM device > + * @preferred_bpp: Preferred bits per pixel for the device > + * @num_crtc: Number of CRTCs > + * @max_conn_count: Maximum number of connectors > + * > + * Returns a newly allocated drm_fbdev_cma struct or a ERR_PTR. > + */ > +struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev, > + unsigned int preferred_bpp, unsigned int num_crtc, > + unsigned int max_conn_count) > +{ > + return drm_fbdev_cma_init_with_funcs(dev, preferred_bpp, num_crtc, > + max_conn_count, &drm_fb_cma_helper_funcs); > +} > EXPORT_SYMBOL_GPL(drm_fbdev_cma_init); > > /** > @@ -373,6 +538,7 @@ EXPORT_SYMBOL_GPL(drm_fbdev_cma_init); > void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma) > { > drm_fb_helper_unregister_fbi(&fbdev_cma->fb_helper); > + drm_fbdev_cma_defio_fini(fbdev_cma->fb_helper.fbdev); > drm_fb_helper_release_fbi(&fbdev_cma->fb_helper); > > if (fbdev_cma->fb) { > diff --git a/include/drm/drm_fb_cma_helper.h b/include/drm/drm_fb_cma_helper.h > index be62bd3..6554b6f 100644 > --- a/include/drm/drm_fb_cma_helper.h > +++ b/include/drm/drm_fb_cma_helper.h > @@ -4,11 +4,18 @@ > struct drm_fbdev_cma; > struct drm_gem_cma_object; > > +struct drm_fb_helper_surface_size; > +struct drm_framebuffer_funcs; > +struct drm_fb_helper_funcs; > struct drm_framebuffer; > +struct drm_fb_helper; > struct drm_device; > struct drm_file; > struct drm_mode_fb_cmd2; > > +struct drm_fbdev_cma *drm_fbdev_cma_init_with_funcs(struct drm_device *dev, > + unsigned int preferred_bpp, unsigned int num_crtc, > + unsigned int max_conn_count, const struct drm_fb_helper_funcs *funcs); > struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev, > unsigned int preferred_bpp, unsigned int num_crtc, > unsigned int max_conn_count); > @@ -16,6 +23,13 @@ void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma); > > void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma); > void drm_fbdev_cma_hotplug_event(struct drm_fbdev_cma *fbdev_cma); > +int drm_fbdev_cma_create_with_funcs(struct drm_fb_helper *helper, > + struct drm_fb_helper_surface_size *sizes, > + struct drm_framebuffer_funcs *funcs); > + > +void drm_fb_cma_destroy(struct drm_framebuffer *fb); > +int drm_fb_cma_create_handle(struct drm_framebuffer *fb, > + struct drm_file *file_priv, unsigned int *handle); > > struct drm_framebuffer *drm_fb_cma_create(struct drm_device *dev, > struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd); > -- > 2.2.2 > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch