From patchwork Mon Feb 25 13:20:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 10828559 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 58B171805 for ; Mon, 25 Feb 2019 13:20:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 472452B615 for ; Mon, 25 Feb 2019 13:20:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 452C82B65B; Mon, 25 Feb 2019 13:20:48 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 964762B615 for ; Mon, 25 Feb 2019 13:20:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727136AbfBYNUr (ORCPT ); Mon, 25 Feb 2019 08:20:47 -0500 Received: from mx1.redhat.com ([209.132.183.28]:45564 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726921AbfBYNUq (ORCPT ); Mon, 25 Feb 2019 08:20:46 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 15A123097027; Mon, 25 Feb 2019 13:20:46 +0000 (UTC) Received: from shalem.localdomain.com (ovpn-117-17.ams2.redhat.com [10.36.117.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2915660857; Mon, 25 Feb 2019 13:20:42 +0000 (UTC) From: Hans de Goede To: Maarten Lankhorst , Maxime Ripard , Sean Paul , Daniel Vetter , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi , Greg Kroah-Hartman , Heikki Krogerus Cc: Hans de Goede , David Airlie , intel-gfx , dri-devel@lists.freedesktop.org, linux-usb@vger.kernel.org Subject: [PATCH 1/3] drm: Add support for out-of-band hotplug notification Date: Mon, 25 Feb 2019 14:20:35 +0100 Message-Id: <20190225132037.31458-2-hdegoede@redhat.com> In-Reply-To: <20190225132037.31458-1-hdegoede@redhat.com> References: <20190225132037.31458-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Mon, 25 Feb 2019 13:20:46 +0000 (UTC) Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On some hardware a hotplug event notification may come from outside the display driver / device. One example of this is laptops with hybrid graphics where one or more outputs are connected to the discrete GPU only. In this case if the discrete GPU is fully powered down to save power, a hotplug to one of these outputs will not be noticed through normal means. These laptops have another mechanism to detect the hotplug which will typically raise an event on the ACPI video bus. Another example of this is some USB Type-C setups where the hardware muxes the DisplayPort data and aux-lines but does not pass the altmode HPD status bit to the GPUs DP HPD pin. This commit adds a loose coupling to the drm subsys allowing event-sources to notify drm-drivers of such events without needing a reference to a drm-device or a drm-connector. This loose coupling is implemented through a blocking notifier. drm-drivers interested in oob hotplug events can register themselves to receive notifations and event-sources call drm_kms_call_oob_hotplug_notifier_chain to let any listeners know about events. An earlier attempt has been done to implement this functionality with a tight coupling, where the event-source would somehow figure out the right drm-connector to deliver the event to and then send it directly to that drm-connector. Such a tight coupling approach has several issues with lifetime management of the coupled objects as well as introducing several probe-ordering issues. Therefor the tight coupling approach has been abandoned. Note for now drm_kms_call_oob_hotplug_notifier_chain's event parameter can only have 1 value: DRM_OOB_HOTPLUG_TYPE_C_DP. The ACPI videobus hotplug event case is currently already supported in the nouveau driver by registering a generic acpi event notifier. Signed-off-by: Hans de Goede --- Documentation/gpu/drm-kms-helpers.rst | 1 + drivers/gpu/drm/drm_probe_helper.c | 67 +++++++++++++++++++++++++++ include/drm/drm_probe_helper.h | 12 +++++ 3 files changed, 80 insertions(+) diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index b422eb8edf16..f144d68f8e7a 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -249,6 +249,7 @@ Output Probing Helper Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_probe_helper.c :doc: output probing helper overview + :doc: out-of-band hotplug event helper overview .. kernel-doc:: drivers/gpu/drm/drm_probe_helper.c :export: diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 6fd08e04b323..4f0b421514ef 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -792,3 +793,69 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev) return changed; } EXPORT_SYMBOL(drm_helper_hpd_irq_event); + +/** + * DOC: out-of-band hotplug event helper overview + * + * On some hardware a hotplug event notification may come from outside + * the display driver / device. + * + * One example of this is laptops with hybrid graphics where one or more + * outputs are connected to the discrete GPU only. In this case if the discrete + * GPU is fully powered down to save power, a hotplug to one of these outputs + * will not be noticed through normal means. These laptops have another + * mechanism to detect the hotplug which will typically raise an event on the + * ACPI video bus. + * + * Another example of this is some USB Type-C setups where the hardware + * muxes the DisplayPort data and aux-lines but does not pass the altmode + * HPD status bit to the GPUs DP HPD pin. + * + * The oob hotplug helper functions allow a drm display driver to listen + * for such oob events and allow other subsystems to notify listeners of + * these events. + */ + +static BLOCKING_NOTIFIER_HEAD(drm_kms_oob_hotplug_notifier_head); + +/** + * drm_kms_register_oob_hotplug_notifier - register an oob hotplug notifier + * @nb: notifier_block to register + * + * Drivers can use this helper function to register a notifier for + * out-of-band hotplug events. + */ +int drm_kms_register_oob_hotplug_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register( + &drm_kms_oob_hotplug_notifier_head, nb); +} +EXPORT_SYMBOL(drm_kms_register_oob_hotplug_notifier); + +/** + * drm_kms_unregister_oob_hotplug_notifier - unregister an oob hotplug notifier + * @nb: notifier_block to register + * + * Drivers can use this helper function to unregister a notifier for + * out-of-band hotplug events. + */ +int drm_kms_unregister_oob_hotplug_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister( + &drm_kms_oob_hotplug_notifier_head, nb); +} +EXPORT_SYMBOL(drm_kms_unregister_oob_hotplug_notifier); + +/** + * drm_kms_call_oob_hotplug_notifier_chain - notify about an oob hotplug event + * @event: enum drm_kms_oob_hotplug_event value describing the event + * + * Out-of-band hotplug event sources can call this helper function to notify + * kms-drivers about an oob hotplug event. + */ +int drm_kms_call_oob_hotplug_notifier_chain(unsigned long event) +{ + return blocking_notifier_call_chain( + &drm_kms_oob_hotplug_notifier_head, event, NULL); +} +EXPORT_SYMBOL(drm_kms_call_oob_hotplug_notifier_chain); diff --git a/include/drm/drm_probe_helper.h b/include/drm/drm_probe_helper.h index 8d3ed2834d34..68cfce47d35f 100644 --- a/include/drm/drm_probe_helper.h +++ b/include/drm/drm_probe_helper.h @@ -24,4 +24,16 @@ void drm_kms_helper_poll_disable(struct drm_device *dev); void drm_kms_helper_poll_enable(struct drm_device *dev); bool drm_kms_helper_is_poll_worker(void); +/** + * enum drm_kms_oob_hotplug_event - out-of-band hotplug events + * @DRM_OOB_HOTPLUG_TYPE_C_DP: DisplayPort over Type-C hotplug event + */ +enum drm_kms_oob_hotplug_event { + DRM_OOB_HOTPLUG_TYPE_C_DP = 0, +}; + +int drm_kms_register_oob_hotplug_notifier(struct notifier_block *nb); +int drm_kms_unregister_oob_hotplug_notifier(struct notifier_block *nb); +int drm_kms_call_oob_hotplug_notifier_chain(unsigned long event); + #endif