From patchwork Fri Sep 7 15:22:06 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Seth Forshee X-Patchwork-Id: 1429921 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 9ADAE40220 for ; Mon, 10 Sep 2012 06:20:50 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7166B9ED5A for ; Sun, 9 Sep 2012 23:20:50 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from youngberry.canonical.com (youngberry.canonical.com [91.189.89.112]) by gabe.freedesktop.org (Postfix) with ESMTP id 905179E7D7 for ; Fri, 7 Sep 2012 08:22:24 -0700 (PDT) Received: from 64-126-113-183.dyn.everestkc.net ([64.126.113.183] helo=canonical.com) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1TA0Nz-00065T-GE; Fri, 07 Sep 2012 15:22:23 +0000 From: Seth Forshee To: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/7] vga_switcheroo: Add notifier call chain for switcheroo events Date: Fri, 7 Sep 2012 10:22:06 -0500 Message-Id: <1347031330-19657-4-git-send-email-seth.forshee@canonical.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1347031330-19657-1-git-send-email-seth.forshee@canonical.com> References: <1347031330-19657-1-git-send-email-seth.forshee@canonical.com> X-Mailman-Approved-At: Sun, 09 Sep 2012 23:17:45 -0700 Cc: Daniel Vetter , Seth Forshee , Andreas Heider , Matthew Garrett X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org DRM needs to be notified of client and handler registration in order to defer initialization of the secondary GPU until the EDID can be read from the LVDS panel. To support this add a notifier call chain to vga_switcheroo for subscribing to switcheroo events. Events are generated for registration and unregistration of handlers and clients. Signed-off-by: Seth Forshee --- drivers/gpu/vga/vga_switcheroo.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/vga_switcheroo.h | 14 ++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index e53f67d..d5cd274 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -70,6 +71,28 @@ static struct vgasr_priv vgasr_priv = { .clients = LIST_HEAD_INIT(vgasr_priv.clients), }; +static BLOCKING_NOTIFIER_HEAD(vga_switcheroo_notifier_list); + +int vga_switcheroo_register_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&vga_switcheroo_notifier_list, + nb); +} +EXPORT_SYMBOL(vga_switcheroo_register_notifier); + +int vga_switcheroo_unregister_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&vga_switcheroo_notifier_list, + nb); +} +EXPORT_SYMBOL(vga_switcheroo_unregister_notifier); + +static int vga_switcheroo_notifier_call_chain(enum vga_switcheroo_event event) +{ + return blocking_notifier_call_chain(&vga_switcheroo_notifier_list, + event, NULL); +} + static bool vga_switcheroo_ready(void) { /* we're ready if we get two clients + handler */ @@ -113,10 +136,18 @@ int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) vga_switcheroo_enable(); } mutex_unlock(&vgasr_mutex); + + vga_switcheroo_notifier_call_chain(VGA_SWITCHEROO_HANDLER_REGISTERED); return 0; } EXPORT_SYMBOL(vga_switcheroo_register_handler); +bool vga_switcheroo_handler_registered(void) +{ + return !!vgasr_priv.handler; +} +EXPORT_SYMBOL(vga_switcheroo_handler_registered); + void vga_switcheroo_unregister_handler(void) { mutex_lock(&vgasr_mutex); @@ -127,6 +158,7 @@ void vga_switcheroo_unregister_handler(void) vgasr_priv.active = false; } mutex_unlock(&vgasr_mutex); + vga_switcheroo_notifier_call_chain(VGA_SWITCHEROO_HANDLER_UNREGISTERED); } EXPORT_SYMBOL(vga_switcheroo_unregister_handler); @@ -156,6 +188,7 @@ static int register_client(struct pci_dev *pdev, vga_switcheroo_enable(); } mutex_unlock(&vgasr_mutex); + vga_switcheroo_notifier_call_chain(VGA_SWITCHEROO_CLIENT_REGISTERED); return 0; } @@ -250,6 +283,7 @@ void vga_switcheroo_unregister_client(struct pci_dev *pdev) vgasr_priv.active = false; } mutex_unlock(&vgasr_mutex); + vga_switcheroo_notifier_call_chain(VGA_SWITCHEROO_CLIENT_UNREGISTERED); } EXPORT_SYMBOL(vga_switcheroo_unregister_client); diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h index e361858..c3d7c6f 100644 --- a/include/linux/vga_switcheroo.h +++ b/include/linux/vga_switcheroo.h @@ -11,6 +11,7 @@ #define _LINUX_VGA_SWITCHEROO_H_ #include +#include struct pci_dev; @@ -28,6 +29,13 @@ enum vga_switcheroo_client_id { VGA_SWITCHEROO_MAX_CLIENTS, }; +enum vga_switcheroo_event { + VGA_SWITCHEROO_CLIENT_REGISTERED, + VGA_SWITCHEROO_CLIENT_UNREGISTERED, + VGA_SWITCHEROO_HANDLER_REGISTERED, + VGA_SWITCHEROO_HANDLER_UNREGISTERED, +}; + struct vga_switcheroo_handler { int (*switch_ddc)(enum vga_switcheroo_client_id id); int (*switchto)(enum vga_switcheroo_client_id id); @@ -44,6 +52,9 @@ struct vga_switcheroo_client_ops { }; #if defined(CONFIG_VGA_SWITCHEROO) +int vga_switcheroo_register_notifier(struct notifier_block *nb); +int vga_switcheroo_unregister_notifier(struct notifier_block *nb); +bool vga_switcheroo_handler_registered(void); void vga_switcheroo_unregister_client(struct pci_dev *dev); int vga_switcheroo_register_client(struct pci_dev *dev, const struct vga_switcheroo_client_ops *ops); @@ -66,6 +77,9 @@ int vga_switcheroo_get_client_state(struct pci_dev *dev); #else +static inline int vga_switcheroo_register_notifier(struct notifier_block *nb) { return 0; } +static inline int vga_switcheroo_unregister_notifier(struct notifier_block *nb) { return 0; } +static inline bool vga_switcheroo_handler_registered(void) { return false; } static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {} static inline int vga_switcheroo_register_client(struct pci_dev *dev, const struct vga_switcheroo_client_ops *ops) { return 0; }