From patchwork Sun Dec 31 13:58:39 2017 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: 10138149 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C71996020A for ; Sun, 31 Dec 2017 13:59:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B722128788 for ; Sun, 31 Dec 2017 13:59:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AC293287E2; Sun, 31 Dec 2017 13:59:37 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=unavailable 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 6B85A28788 for ; Sun, 31 Dec 2017 13:59:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 861B289C55; Sun, 31 Dec 2017 13:59:27 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@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 382A589C46; Sun, 31 Dec 2017 13:59:26 +0000 (UTC) Received: from 211.81-166-168.customer.lyse.net ([81.166.168.211]:48182 helo=localhost.localdomain) by smtp.domeneshop.no with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_CBC_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1eVe96-0003Z0-9U; Sun, 31 Dec 2017 14:59:24 +0100 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= To: dri-devel@lists.freedesktop.org Date: Sun, 31 Dec 2017 14:58:39 +0100 Message-Id: <20171231135843.10760-4-noralf@tronnes.org> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20171231135843.10760-1-noralf@tronnes.org> References: <20171231135843.10760-1-noralf@tronnes.org> MIME-Version: 1.0 Cc: daniel.vetter@ffwll.ch, intel-gfx@lists.freedesktop.org, =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= , laurent.pinchart@ideasonboard.com, dh.herrmann@gmail.com Subject: [Intel-gfx] [RFC 3/7] drm/fb-helper: Don't restore if fbdev is not in use X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Keep track of fbdev users and only restore fbdev in drm_fb_helper_restore_fbdev_mode_unlocked() when in use. This avoids fbdev being restored in drm_driver.last_close when nothing uses it. Additionally fbdev is turned off when the last user is closing. fbcon is a user in this context. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/drm_fb_helper.c | 15 +++++++++++++++ include/drm/drm_fb_helper.h | 14 ++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 2c6adf1d80c2..f9dcc7a5761f 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -522,6 +522,9 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) if (READ_ONCE(fb_helper->deferred_setup)) return 0; + if (!atomic_read(&fb_helper->open_count)) + return 0; + mutex_lock(&fb_helper->lock); ret = restore_fbdev_mode(fb_helper); @@ -781,6 +784,7 @@ void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, INIT_WORK(&helper->resume_work, drm_fb_helper_resume_worker); INIT_WORK(&helper->dirty_work, drm_fb_helper_dirty_work); helper->dirty_clip.x1 = helper->dirty_clip.y1 = ~0; + atomic_set(&helper->open_count, 1); mutex_init(&helper->lock); helper->funcs = funcs; helper->dev = dev; @@ -1212,6 +1216,7 @@ EXPORT_SYMBOL(drm_fb_helper_cfb_imageblit); * @info: fbdev registered by the helper * @user: 1=userspace, 0=fbcon * + * Increase fbdev use count. * If &fb_ops is wrapped in a library, pin the driver module. */ int drm_fb_helper_fb_open(struct fb_info *info, int user) @@ -1224,6 +1229,8 @@ int drm_fb_helper_fb_open(struct fb_info *info, int user) return -ENODEV; } + atomic_inc(&fb_helper->open_count); + return 0; } EXPORT_SYMBOL(drm_fb_helper_fb_open); @@ -1233,6 +1240,7 @@ EXPORT_SYMBOL(drm_fb_helper_fb_open); * @info: fbdev registered by the helper * @user: 1=userspace, 0=fbcon * + * Decrease fbdev use count and turn off if there are no users left. * If &fb_ops is wrapped in a library, unpin the driver module. */ int drm_fb_helper_fb_release(struct fb_info *info, int user) @@ -1240,6 +1248,10 @@ int drm_fb_helper_fb_release(struct fb_info *info, int user) struct drm_fb_helper *fb_helper = info->par; struct drm_device *dev = fb_helper->dev; + if (atomic_dec_and_test(&fb_helper->open_count) && + !drm_dev_is_unplugged(fb_helper->dev)) + drm_fb_helper_blank(FB_BLANK_POWERDOWN, info); + if (info->fbops->owner != dev->driver->fops->owner) module_put(dev->driver->fops->owner); @@ -1936,6 +1948,9 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, if (ret < 0) return ret; + if (fb_helper->fbdev->fbops->fb_open == drm_fb_helper_fb_open) + atomic_set(&fb_helper->open_count, 0); + strcpy(fb_helper->fb->comm, "[fbcon]"); return 0; } diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 6f546ca3a6a1..5d4ccc3f28aa 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -232,6 +232,20 @@ struct drm_fb_helper { * See also: @deferred_setup */ int preferred_bpp; + + /** + * @open_count: + * + * Keeps track of fbdev use to know when to not restore fbdev. + * + * Drivers that use DRM_FB_HELPER_DEFAULT_OPS and don't override + * \.fb_open will get an initial value of 0 and get restore based on + * actual use. Others will get an initial value of 1 which means that + * fbdev will always be restored. Drivers that call + * drm_fb_helper_fb_open() in their \.fb_open, thus needs to set the + * initial value to 0 themselves. + */ + atomic_t open_count; }; /**