From b00e5334ab1bb2e41187fb964a1a2304871fb4ff Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Tue, 31 May 2016 11:13:27 +0200 Subject: vga_switcheroo: Add helper for deferred probing So far we've got one condition when DRM drivers need to defer probing on a dual GPU system and it's coded separately into each of the relevant drivers. As suggested by Daniel Vetter, deduplicate that code in the drivers and move it to a new vga_switcheroo helper. This yields better encapsulation of concepts and lets us add further checks in a central place. (The existing check pertains to pre-retina MacBook Pros and an additional check is expected to be needed for retinas.) One might be tempted to check deferred probing conditions in vga_switcheroo_register_client(), but this is usually called fairly late during driver load. The GPU is fully brought up and ready for switching at that point. On boot the ->probe hook is potentially called dozens of times until it finally succeeds, and each time we'd repeat bringup and teardown of the GPU, lengthening boot time considerably and cluttering logfiles. A separate helper is therefore needed which can be called right at the beginning of the ->probe hook. Note that amdgpu currently does not call this helper as the AMD GPUs built into MacBook Pros are only supported by radeon so far. v2: This helper could eventually be used by audio clients as well, so rephrase kerneldoc to refer to "client" instead of "GPU" and move the single existing check in an if block specific to PCI_CLASS_DISPLAY_VGA devices. Move documentation on that check from kerneldoc to a comment. (Daniel Vetter) v3: Mandate in kerneldoc that registration of client shall only happen after calling this helper. (Daniel Vetter) v4: Rebase on 412c8f7de011 ("drm/radeon: Return -EPROBE_DEFER when amdkfd not loaded") v5: Some Optimus GPUs use PCI_CLASS_DISPLAY_3D, make sure those are matched as well. (Emil Velikov) v6: The if-condition referring to PCI_BASE_CLASS_DISPLAY may be considered a functional change. Move to a separate commit to keep this a pure refactoring change. (Emil Velikov, Jani Nikula) Cc: Daniel Vetter Cc: Ben Skeggs Cc: Alex Deucher Signed-off-by: Lukas Wunner Signed-off-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/575885fd440c2b13c3f19ddf44360cfbbff35f50.1464685538.git.lukas@wunner.de --- drivers/gpu/vga/vga_switcheroo.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/vga') diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index cbd7c986d926..d349bf91dd11 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -30,6 +30,7 @@ #define pr_fmt(fmt) "vga_switcheroo: " fmt +#include #include #include #include @@ -308,7 +309,8 @@ static int register_client(struct pci_dev *pdev, * * Register vga client (GPU). Enable vga_switcheroo if another GPU and a * handler have already registered. The power state of the client is assumed - * to be ON. + * to be ON. Beforehand, vga_switcheroo_client_probe_defer() shall be called + * to ensure that all prerequisites are met. * * Return: 0 on success, -ENOMEM on memory allocation error. */ @@ -375,6 +377,31 @@ find_active_client(struct list_head *head) return NULL; } +/** + * vga_switcheroo_client_probe_defer() - whether to defer probing a given client + * @pdev: client pci device + * + * Determine whether any prerequisites are not fulfilled to probe a given + * client. Drivers shall invoke this early on in their ->probe callback + * and return %-EPROBE_DEFER if it evaluates to %true. Thou shalt not + * register the client ere thou hast called this. + * + * Return: %true if probing should be deferred, otherwise %false. + */ +bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev) +{ + /* + * apple-gmux is needed on pre-retina MacBook Pro + * to probe the panel if pdev is the inactive GPU. + */ + if (apple_gmux_present() && pdev != vga_default_device() && + !vgasr_priv.handler_flags) + return true; + + return false; +} +EXPORT_SYMBOL(vga_switcheroo_client_probe_defer); + /** * vga_switcheroo_get_client_state() - obtain power state of a given client * @pdev: client pci device -- cgit v1.2.3