From patchwork Sat Dec 22 02:52:51 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 6246871 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 346BBBF4A6 for ; Tue, 21 Apr 2015 11:39:16 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 11630203E6 for ; Tue, 21 Apr 2015 11:39:15 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id BDCCE203E3 for ; Tue, 21 Apr 2015 11:39:13 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B79B96E48F; Tue, 21 Apr 2015 04:39:11 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout3.hostsharing.net (mailout3.hostsharing.net [176.9.242.54]) by gabe.freedesktop.org (Postfix) with ESMTP id 0E3236E48F for ; Tue, 21 Apr 2015 04:39:10 -0700 (PDT) Received: from h08.hostsharing.net (h08.hostsharing.net [83.223.95.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mailout3.hostsharing.net (Postfix) with ESMTPS id 11EDA101E6AB3; Tue, 21 Apr 2015 13:31:26 +0200 (CEST) Received: from localhost (5-38-90-81.adsl.cmo.de [81.90.38.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id 6013C603E04D; Tue, 21 Apr 2015 13:31:23 +0200 (CEST) X-Mailbox-Line: From 0d2a7e394cd1fd9a0489d5d4ed8c70250c3f0f93 Mon Sep 17 00:00:00 2001 Message-Id: <0d2a7e394cd1fd9a0489d5d4ed8c70250c3f0f93.1429610300.git.lukas@wunner.de> In-Reply-To: References: From: Lukas Wunner Date: Sat, 22 Dec 2012 12:52:51 +1000 Subject: [PATCH 05/11] vga_switcheroo: Lock/unlock DDC lines To: dri-devel@lists.freedesktop.org Cc: Daniel Vetter , Seth Forshee , Matthew Garrett , Dave Airlie X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00, DATE_IN_PAST_96_XX, RCVD_IN_DNSWL_MED,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Dave Airlie Replace vga_switcheroo_switch_ddc() with vga_switcheroo_lock_ddc() and vga_switcheroo_unlock_ddc(), move mutex from drm_get_edid() to vga_switcheroo.c Motivation for these changes according to Dave Airlie: "I can't figure out why I didn't like this, but I rewrote this way back to lock/unlock the ddc lines, bits are contained in this WIP mess. I think I'd prefer something like that otherwise the interface got really ugly." http://lists.freedesktop.org/archives/dri-devel/2014-June/061629.html Original commit by Dave Airlie contained additional experimental and unused code. Reduced to the bare minimum and amended with this commit message by Lukas Wunner Signed-off-by: Lukas Wunner --- drivers/gpu/drm/drm_edid.c | 16 ++------------ drivers/gpu/vga/vga_switcheroo.c | 46 ++++++++++++++++++++++++++++++++++++++-- include/linux/vga_switcheroo.h | 3 ++- 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index f208bb3..f91593b 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -88,8 +88,6 @@ struct detailed_mode_closure { #define LEVEL_GTF2 2 #define LEVEL_CVT 3 -static DEFINE_MUTEX(drm_edid_mutex); - static struct edid_quirk { char vendor[4]; int product_id; @@ -1328,16 +1326,8 @@ struct edid *drm_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) { struct edid *edid; - struct pci_dev *pdev = connector->dev->pdev; - struct pci_dev *active_pdev = NULL; - - mutex_lock(&drm_edid_mutex); - if (pdev) { - active_pdev = vga_switcheroo_get_active_client(); - if (active_pdev != pdev) - vga_switcheroo_switch_ddc(pdev); - } + vga_switcheroo_lock_ddc(connector->dev->pdev); if (!drm_probe_ddc(adapter)) return NULL; @@ -1346,10 +1336,8 @@ struct edid *drm_get_edid(struct drm_connector *connector, if (edid) drm_get_displayid(connector, edid); - if (active_pdev && active_pdev != pdev) - vga_switcheroo_switch_ddc(active_pdev); + vga_switcheroo_unlock_ddc(connector->dev->pdev); - mutex_unlock(&drm_edid_mutex); return edid; } EXPORT_SYMBOL(drm_get_edid); diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 620c4ac..0223020 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -57,6 +57,9 @@ struct vgasr_priv { struct list_head clients; struct vga_switcheroo_handler *handler; + + struct mutex ddc_lock; + struct pci_dev *old_ddc_owner; }; #define ID_BIT_AUDIO 0x100 @@ -70,6 +73,7 @@ static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv); /* only one switcheroo per system */ static struct vgasr_priv vgasr_priv = { .clients = LIST_HEAD_INIT(vgasr_priv.clients), + .ddc_lock = __MUTEX_INITIALIZER(vgasr_priv.ddc_lock), }; static bool vga_switcheroo_ready(void) @@ -270,8 +274,9 @@ void vga_switcheroo_client_fb_set(struct pci_dev *pdev, } EXPORT_SYMBOL(vga_switcheroo_client_fb_set); -int vga_switcheroo_switch_ddc(struct pci_dev *pdev) +int vga_switcheroo_lock_ddc(struct pci_dev *pdev) { + struct vga_switcheroo_client *client; int ret = 0; int id; @@ -283,6 +288,18 @@ int vga_switcheroo_switch_ddc(struct pci_dev *pdev) } if (vgasr_priv.handler->switch_ddc) { + mutex_lock(&vgasr_priv.ddc_lock); + + client = find_active_client(&vgasr_priv.clients); + if (!client) { + mutex_unlock(&vgasr_priv.ddc_lock); + ret = -ENODEV; + goto out; + } + vgasr_priv.old_ddc_owner = client->pdev; + if (client->pdev == pdev) + goto out; + id = vgasr_priv.handler->get_client_id(pdev); ret = vgasr_priv.handler->switch_ddc(id); } @@ -291,7 +308,32 @@ out: mutex_unlock(&vgasr_mutex); return ret; } -EXPORT_SYMBOL(vga_switcheroo_switch_ddc); +EXPORT_SYMBOL(vga_switcheroo_lock_ddc); + +int vga_switcheroo_unlock_ddc(struct pci_dev *pdev) +{ + int ret = 0; + int id; + mutex_lock(&vgasr_mutex); + + if (!vgasr_priv.handler) { + ret = -ENODEV; + goto out; + } + + if (vgasr_priv.handler->switch_ddc) { + if (vgasr_priv.old_ddc_owner != pdev) { + id = vgasr_priv.handler->get_client_id(vgasr_priv.old_ddc_owner); + ret = vgasr_priv.handler->switch_ddc(id); + } + vgasr_priv.old_ddc_owner = NULL; + mutex_unlock(&vgasr_priv.ddc_lock); + } +out: + mutex_unlock(&vgasr_mutex); + return ret; +} +EXPORT_SYMBOL(vga_switcheroo_unlock_ddc); static int vga_switcheroo_show(struct seq_file *m, void *v) { diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h index c81a686..352bef3 100644 --- a/include/linux/vga_switcheroo.h +++ b/include/linux/vga_switcheroo.h @@ -55,7 +55,8 @@ int vga_switcheroo_register_audio_client(struct pci_dev *pdev, void vga_switcheroo_client_fb_set(struct pci_dev *dev, struct fb_info *info); -int vga_switcheroo_switch_ddc(struct pci_dev *pdev); +int vga_switcheroo_lock_ddc(struct pci_dev *pdev); +int vga_switcheroo_unlock_ddc(struct pci_dev *pdev); int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler); void vga_switcheroo_unregister_handler(void);