Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp322201ybl; Thu, 9 Jan 2020 22:42:14 -0800 (PST) X-Google-Smtp-Source: APXvYqyiBxCLgaDg2vPcsK0p0otseEjB7rpCSd7Qd7N5UUJck5JOLw2INcwxr8xDB8/rsNNv3jjl X-Received: by 2002:a05:6830:2141:: with SMTP id r1mr1381789otd.39.1578638534838; Thu, 09 Jan 2020 22:42:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1578638534; cv=none; d=google.com; s=arc-20160816; b=dLJfMep7qFs+XoT45r9ZHuumtiYqR+DgdzXXR1vkAdltrNFtD8O+owALQG2+FTrrGh HmrDiapF8L2YZgyIq3pxtUSSJ8XQaVaav1NGQLNf7EQTBcncIMHutl7q3UxOiEKcsgiq x15KFauv36168KDLmQM1hg0fyICVhP3C703Un2xVJ7poNM6lGjOXMNAeVKamF7yMQeTK 4Bb49+wEcR2pgo0AoN/Dd4qgBbRlgxP8nOLDNyNL7Zq/rv6tWEO9Re1N3iRywerMARO8 L1JN+8irOi1aFVrx7GX7f25uP8BBc7ujEu2A08guGox+6m7BlIO5h/M2o2KBv52p5+A4 FBmw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=x/RZ4u0JUpuGVwwhSIZqye0oIIcumhyPw3EAY8ouXyM=; b=Z2k6gwhM6++nNy3ChQxUiC9vbIVFUJaUxXwu8dSWqG2l4WeXX38AuDb4IUWGdDT6Tu 4B5T2GQK7yJGopZ4hq2rt9KrXWnIVfvi8Zlpxop0I+1MN5oA7VVwACGx/VYRxOXWaG6C cXyKbuC2foy+IJZw3+/X9JLFumImMNkkHTeY5+1FogaQbikU7awy2C0zRQuukQ2FhFMR EzXpPnC+I/I2fOrAdGLEssWgh6PYTedcRFS2C8we9s7qrnt8C0eVP4yHsuQUofQGWLV8 PHxmS19IV2KKvA81II+BBoMK4ii6IcKhG8B8hA9CwLr89K40evYArPnlCyR+riFxxPz8 3CKw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GxZgFbxD; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h139si516334oib.85.2020.01.09.22.42.03; Thu, 09 Jan 2020 22:42:14 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GxZgFbxD; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731555AbgAJGlH (ORCPT + 99 others); Fri, 10 Jan 2020 01:41:07 -0500 Received: from mail-wr1-f66.google.com ([209.85.221.66]:40275 "EHLO mail-wr1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731530AbgAJGlH (ORCPT ); Fri, 10 Jan 2020 01:41:07 -0500 Received: by mail-wr1-f66.google.com with SMTP id c14so663573wrn.7 for ; Thu, 09 Jan 2020 22:41:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=x/RZ4u0JUpuGVwwhSIZqye0oIIcumhyPw3EAY8ouXyM=; b=GxZgFbxDOTwF4adCXyVdmjulIseFJKagZ1Y48ouQhAPdK6sb4/Dco+KIaYEcXpnqSC InD5wvPYobtLG8O4DZSW2Uo3RJSVw1+7vH+jr8AqOQxNSkdHHUAPX7RdPX3+i6ZuQGxl VuIgTzHeIrnYwn3HmzXrTUIqyN9SzPYlTWr2bNqSV2xK1QUiOxUwU53df5AXWrQv9inN IjolUD49XRU+mZ07jmPLXFZ9q7JP//LrSNKJItAjVEc28ZUGlawCVWIjR8PHZqj4ZmYw uKj4srBNEbULWNrWGSNOnr88NiGVhQ2pmzCigYjeBzakOvoKZSkormLVo0MWzwt9E4zI YNUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=x/RZ4u0JUpuGVwwhSIZqye0oIIcumhyPw3EAY8ouXyM=; b=QnC3zxPkQr9xUxP2xBR04gRDZU1p8EW8YUj+Tu6KVuxZBxY7LWgbuyeTvfOkEmyHW0 YXEEBXVpnUl+CBDl6++H5jvLbOJHj4JwN1Guia0LxUlv5btjn9ahPKn2KIYb5X59Liia dVXSzkthBq68IiFhzDYFKoohsT63jtVtmU6gLP0FnBTMTdvICHhgFNyQIFV1PTdiA3c3 aN9gYSJch8f0kF3QdG9253obOW9pju5c3CAlYyYLAWnAIjVESDUeqkXklzBWT3w3G4mB Ou3SA8qctYeGXbUGaIc1I/5myjWUNzic+uZ5tgVls+u4pomeNbT7W8ei/vrtfCVO6kvx KgBw== X-Gm-Message-State: APjAAAWiyCHULTMfO2MthBsC/BQZ8fsojik4eTNKPssb4spoaYMko58U YRf8F57EztEEL4dCkbyONJRvrYHvO3xNTI3sP46SiA== X-Received: by 2002:a5d:46c1:: with SMTP id g1mr1571884wrs.200.1578638464682; Thu, 09 Jan 2020 22:41:04 -0800 (PST) MIME-Version: 1.0 References: <20200110030112.188845-1-saravanak@google.com> In-Reply-To: <20200110030112.188845-1-saravanak@google.com> From: Ard Biesheuvel Date: Fri, 10 Jan 2020 07:40:53 +0100 Message-ID: Subject: Re: [PATCH v3] efi: arm: defer probe of PCIe backed efifb on DT systems To: Saravana Kannan Cc: Ard Biesheuvel , linux-arm-kernel , Will Deacon , Bjorn Helgaas , Greg Kroah-Hartman , Android Kernel Team , linux-efi , Linux Kernel Mailing List Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, 10 Jan 2020 at 04:01, Saravana Kannan wrote: > > From: Ard Biesheuvel > > The new of_devlink support breaks PCIe probing on ARM platforms booting > via UEFI if the firmware exposes a EFI framebuffer that is backed by a > PCI device. The reason is that the probing order gets reversed, > resulting in a resource conflict on the framebuffer memory window when > the PCIe probes last, causing it to give up entirely. > > Given that we rely on PCI quirks to deal with EFI framebuffers that get > moved around in memory, we cannot simply drop the memory reservation, so > instead, let's use the device link infrastructure to register this > dependency, and force the probing to occur in the expected order. > > Cc: Greg Kroah-Hartman > Signed-off-by: Ard Biesheuvel > Co-developed-by: Saravana Kannan > Signed-off-by: Saravana Kannan > Reviewed-by: Ard Biesheuvel > --- > > v1 -> v2: > - Rewrote the device linking part to not depend on initcall ordering > v2 -> v3: > - Added const and check for CONFIG_PCI > Thanks. I've queued this version in efi/next for v5.6 > drivers/firmware/efi/arm-init.c | 107 ++++++++++++++++++++++++++++++-- > 1 file changed, 103 insertions(+), 4 deletions(-) > > diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c > index 904fa09e6a6b..d99f5b0c8a09 100644 > --- a/drivers/firmware/efi/arm-init.c > +++ b/drivers/firmware/efi/arm-init.c > @@ -10,10 +10,12 @@ > #define pr_fmt(fmt) "efi: " fmt > > #include > +#include > #include > #include > #include > #include > +#include > #include > #include > #include > @@ -276,15 +278,112 @@ void __init efi_init(void) > efi_memmap_unmap(); > } > > +static bool efifb_overlaps_pci_range(const struct of_pci_range *range) > +{ > + u64 fb_base = screen_info.lfb_base; > + > + if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) > + fb_base |= (u64)(unsigned long)screen_info.ext_lfb_base << 32; > + > + return fb_base >= range->cpu_addr && > + fb_base < (range->cpu_addr + range->size); > +} > + > +static struct device_node *find_pci_overlap_node(void) > +{ > + struct device_node *np; > + > + for_each_node_by_type(np, "pci") { > + struct of_pci_range_parser parser; > + struct of_pci_range range; > + int err; > + > + err = of_pci_range_parser_init(&parser, np); > + if (err) { > + pr_warn("of_pci_range_parser_init() failed: %d\n", err); > + continue; > + } > + > + for_each_of_pci_range(&parser, &range) > + if (efifb_overlaps_pci_range(&range)) > + return np; > + } > + return NULL; > +} > + > +/* > + * If the efifb framebuffer is backed by a PCI graphics controller, we have > + * to ensure that this relation is expressed using a device link when > + * running in DT mode, or the probe order may be reversed, resulting in a > + * resource reservation conflict on the memory window that the efifb > + * framebuffer steals from the PCIe host bridge. > + */ > +static int efifb_add_links(const struct fwnode_handle *fwnode, > + struct device *dev) > +{ > + struct device_node *sup_np; > + struct device *sup_dev; > + > + sup_np = find_pci_overlap_node(); > + > + /* > + * If there's no PCI graphics controller backing the efifb, we are > + * done here. > + */ > + if (!sup_np) > + return 0; > + > + sup_dev = get_dev_from_fwnode(&sup_np->fwnode); > + of_node_put(sup_np); > + > + /* > + * Return -ENODEV if the PCI graphics controller device hasn't been > + * registered yet. This ensures that efifb isn't allowed to probe > + * and this function is retried again when new devices are > + * registered. > + */ > + if (!sup_dev) > + return -ENODEV; > + > + /* > + * If this fails, retrying this function at a later point won't > + * change anything. So, don't return an error after this. > + */ > + if (!device_link_add(dev, sup_dev, 0)) > + dev_warn(dev, "device_link_add() failed\n"); > + > + put_device(sup_dev); > + > + return 0; > +} > + > +static const struct fwnode_operations efifb_fwnode_ops = { > + .add_links = efifb_add_links, > +}; > + > +static struct fwnode_handle efifb_fwnode = { > + .ops = &efifb_fwnode_ops, > +}; > + > static int __init register_gop_device(void) > { > - void *pd; > + struct platform_device *pd; > + int err; > > if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) > return 0; > > - pd = platform_device_register_data(NULL, "efi-framebuffer", 0, > - &screen_info, sizeof(screen_info)); > - return PTR_ERR_OR_ZERO(pd); > + pd = platform_device_alloc("efi-framebuffer", 0); > + if (!pd) > + return -ENOMEM; > + > + if (IS_ENABLED(CONFIG_PCI)) > + pd->dev.fwnode = &efifb_fwnode; > + > + err = platform_device_add_data(pd, &screen_info, sizeof(screen_info)); > + if (err) > + return err; > + > + return platform_device_add(pd); > } > subsys_initcall(register_gop_device); > -- > 2.25.0.rc1.283.g88dfdc4193-goog >