From patchwork Mon Apr 20 10:08:12 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 7000811 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 7903D9F52D for ; Wed, 12 Aug 2015 11:40:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 673C3206C5 for ; Wed, 12 Aug 2015 11:40:08 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 154E5206EE for ; Wed, 12 Aug 2015 11:40:03 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1C5AC6EB3D; Wed, 12 Aug 2015 04:39:57 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mailout2.hostsharing.net (mailout2.hostsharing.net [83.223.90.233]) by gabe.freedesktop.org (Postfix) with ESMTPS id CF5AE6EB36 for ; Wed, 12 Aug 2015 04:39:53 -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 mailout2.hostsharing.net (Postfix) with ESMTPS id F11B91008CB2E; Wed, 12 Aug 2015 13:31:00 +0200 (CEST) Received: from localhost (6-38-90-81.adsl.cmo.de [81.90.38.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id 8262360423EA; Wed, 12 Aug 2015 13:30:58 +0200 (CEST) X-Mailbox-Line: From e14b2b0ba7d6248edbdb74935f5743a705a62bb6 Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: <832f1cfceab9d9403b541b51733b87110fd8e019.1439288957.git.lukas@wunner.de> References: <29bed586baf62f6be77b7ab0ba1b8f5cb3be3aad.1439288957.git.lukas@wunner.de> <164b43588e80baaddb7a4d1081785c4d03a89c4b.1439288957.git.lukas@wunner.de> <27944adb13aa1ab246ee4a1ebb833e397324d073.1439288957.git.lukas@wunner.de> <2ac3eca0759cedd1009221cbef908605f8d29e1e.1439288957.git.lukas@wunner.de> <832f1cfceab9d9403b541b51733b87110fd8e019.1439288957.git.lukas@wunner.de> From: Lukas Wunner Date: Mon, 20 Apr 2015 12:08:12 +0200 Subject: [PATCH v2 11/22] vga_switcheroo: Generate hotplug event on handler and proxy registration To: dri-devel@lists.freedesktop.org Cc: Andreas Heider , Paul Hordiienko , William Brown , Bruno Bierbaumer , 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,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 On laptops which require the handler to switch DDC lines, already registered clients must reprobe their connectors if the handler registers late. This is the case on pre-retina MacBook Pros, which use a gmux controller as handler. Based (loosely) on a patch by Matthew Garrett who used an additional driver callback rather than generating a hotplug event: http://lists.freedesktop.org/archives/dri-devel/2014-June/060941.html Matthew Garrett invoked the driver callback in vga_switcheroo_enable(). On pre-retina MacBook Pros, this delayed reprobing until a second gpu registers, which may never happen if its driver is not installed or blacklisted. The MacBook Pro 2011 in particular suffers from widespread gpu soldering issues due to overheating, eventually rendering it unusable with OS X. Folks are solving this by moving to Linux and disabling the discrete gpu entirely. In those cases we can't wait for a second gpu to register, we do need to reprobe as soon as the handler registers: https://ifixit.org/blog/6882/why-i-drilled-holes-in-my-macbook-pro-and-put-it-in-the-oven/#comment-26745 Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115 Tested-by: Paul Hordiienko [MBP 6,2 2010 intel ILK + nvidia GT216 pre-retina] Tested-by: William Brown [MBP 8,2 2011 intel SNB + amd turks pre-retina] Tested-by: Lukas Wunner [MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina] Tested-by: Bruno Bierbaumer [MBP 11,3 2013 intel HSW + nvidia GK107 retina -- work in progress] Signed-off-by: Lukas Wunner --- drivers/gpu/vga/vga_switcheroo.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 8027c9f..94b0b6f 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -18,6 +18,8 @@ - can_switch - check if the device is in a position to switch now */ +#include + #include #include #include @@ -35,6 +37,7 @@ struct vga_switcheroo_client { struct pci_dev *pdev; struct fb_info *fb_info; + struct work_struct reprobe_work; int pwr_state; const struct vga_switcheroo_client_ops *ops; int id; @@ -106,6 +109,30 @@ static void vga_switcheroo_enable(void) vgasr_priv.active = true; } +static void vga_switcheroo_reprobe_client(struct work_struct *work) +{ + struct vga_switcheroo_client *client = + container_of(work, struct vga_switcheroo_client, reprobe_work); + void (*generate_hotplug_event)(struct drm_device *); + + generate_hotplug_event = symbol_get(drm_kms_helper_hotplug_event); + if (!generate_hotplug_event) + return; + + generate_hotplug_event(pci_get_drvdata(client->pdev)); +} + +static void vga_switcheroo_reprobe_inactive_clients(void) +{ + struct vga_switcheroo_client *client; + + list_for_each_entry(client, &vgasr_priv.clients, list) + if (!client->active && client_is_vga(client)) { + cancel_work_sync(&client->reprobe_work); + schedule_work(&client->reprobe_work); + } +} + int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) { mutex_lock(&vgasr_mutex); @@ -115,11 +142,17 @@ int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) } vgasr_priv.handler = handler; + if (vga_switcheroo_ready()) { printk(KERN_INFO "vga_switcheroo: enabled\n"); vga_switcheroo_enable(); } mutex_unlock(&vgasr_mutex); + + /* clients which registered before the handler must reprobe */ + if (vgasr_priv.handler->switch_ddc) + vga_switcheroo_reprobe_inactive_clients(); + return 0; } EXPORT_SYMBOL(vga_switcheroo_register_handler); @@ -153,6 +186,7 @@ static int register_client(struct pci_dev *pdev, client->id = id; client->active = active; client->driver_power_control = driver_power_control; + INIT_WORK(&client->reprobe_work, vga_switcheroo_reprobe_client); mutex_lock(&vgasr_mutex); list_add_tail(&client->list, &vgasr_priv.clients);