From patchwork Wed Nov 21 16:56:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Noralf_Tr=C3=B8nnes?= X-Patchwork-Id: 10692843 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C9E5A14BD for ; Wed, 21 Nov 2018 16:57:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B89962C3C5 for ; Wed, 21 Nov 2018 16:57:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AA3FD2C3F0; Wed, 21 Nov 2018 16:57:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E5FC82C3C5 for ; Wed, 21 Nov 2018 16:57:07 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id ECACE6E0F1; Wed, 21 Nov 2018 16:57:05 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from smtp.domeneshop.no (smtp.domeneshop.no [IPv6:2a01:5b40:0:3005::1]) by gabe.freedesktop.org (Postfix) with ESMTPS id 797F46E0F1 for ; Wed, 21 Nov 2018 16:57:04 +0000 (UTC) Received: from 211.81-166-168.customer.lyse.net ([81.166.168.211]:40006 helo=localhost.localdomain) by smtp.domeneshop.no with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.84_2) (envelope-from ) id 1gPVoE-0002V7-GL; Wed, 21 Nov 2018 17:57:02 +0100 From: =?utf-8?q?Noralf_Tr=C3=B8nnes?= To: dri-devel@lists.freedesktop.org Subject: [PATCH] drm/fb-helper/generic: Only restore when in use Date: Wed, 21 Nov 2018 17:56:42 +0100 Message-Id: <20181121165642.33563-1-noralf@tronnes.org> X-Mailer: git-send-email 2.15.1 MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP On drm_driver->last_close the generic fbdev emulation will restore fbdev regardless of it being used or not. This is a problem for e-ink displays which don't want to be overwritten with zeroes when DRM userspace closes. Amend this by adding an open counter to track fbdev use to know when to restore. Make use of it in the generic fbdev emulation. It wasn't possible to add this funtionality to say all the drivers that use the DRM_FB_HELPER_DEFAULT_OPS macro, because some of its users set .fb_open and .fb_release. If some driver wants this functionality it can export drm_fbdev_fb_open() and drm_fbdev_fb_release() and use them. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/drm_fb_helper.c | 25 +++++++++++++++++++++++-- include/drm/drm_fb_helper.h | 14 ++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 9a69ad7e9f3b..24ffaee11f5a 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -530,7 +530,7 @@ static int restore_fbdev_mode(struct drm_fb_helper *fb_helper) int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) { bool do_delayed; - int ret; + int ret = 0; if (!drm_fbdev_emulation || !fb_helper) return -ENODEV; @@ -539,7 +539,8 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) return 0; mutex_lock(&fb_helper->lock); - ret = restore_fbdev_mode(fb_helper); + if (fb_helper->fb_open_count) + ret = restore_fbdev_mode(fb_helper); do_delayed = fb_helper->delayed_hotplug; if (do_delayed) @@ -888,6 +889,8 @@ int drm_fb_helper_init(struct drm_device *dev, i++; } + fb_helper->fb_open_count = 1; + dev->fb_helper = fb_helper; return 0; @@ -2942,16 +2945,32 @@ EXPORT_SYMBOL(drm_fb_helper_output_poll_changed); static int drm_fbdev_fb_open(struct fb_info *info, int user) { struct drm_fb_helper *fb_helper = info->par; + unsigned int fb_open_count; if (!try_module_get(fb_helper->dev->driver->fops->owner)) return -ENODEV; + mutex_lock(&fb_helper->lock); + fb_open_count = fb_helper->fb_open_count++; + mutex_unlock(&fb_helper->lock); + + if (!fb_open_count) + drm_fb_helper_blank(FB_BLANK_UNBLANK, info); + return 0; } static int drm_fbdev_fb_release(struct fb_info *info, int user) { struct drm_fb_helper *fb_helper = info->par; + unsigned int fb_open_count; + + mutex_lock(&fb_helper->lock); + fb_open_count = --fb_helper->fb_open_count; + mutex_unlock(&fb_helper->lock); + + if (!fb_open_count) + drm_fb_helper_blank(FB_BLANK_POWERDOWN, info); module_put(fb_helper->dev->driver->fops->owner); @@ -3050,6 +3069,8 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper, sizes->surface_width, sizes->surface_height, sizes->surface_bpp); + fb_helper->fb_open_count = 0; + format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); buffer = drm_client_framebuffer_create(client, sizes->surface_width, sizes->surface_height, format); diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index bb9acea61369..846ca8509427 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -247,6 +247,20 @@ struct drm_fb_helper { * See also: @deferred_setup */ int preferred_bpp; + + /** + * @fb_open_count: + * + * Used to track userspace/fbcon opens to know when to restore fbdev in + * drm_fb_helper_restore_fbdev_mode_unlocked(). The value is set to 1 by + * default which means it will always restore. Drivers that want to + * track this can set this to zero in their + * &drm_fb_helper_funcs.fb_probe function. Additionally the value must + * be increased in &fb_ops.fb_open and decreased in &fb_ops.fb_release. + * + * The value is protected by @lock. + */ + unsigned int fb_open_count; }; static inline struct drm_fb_helper *