From nobody Fri Sep 25 17:42:52 2026 Received: from mail-qk2-f42.google.com (mail-qk2-f42.google.com [74.125.230.234]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E26793AEF51 for ; Thu, 24 Sep 2026 22:24:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.230.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790288692; cv=none; b=ut5TtI0gDq4LuoB3HGtVtJAi1RsAXVmqd+a7/XBcCS2kB4/nlNzHZUeg9MTgsu0dmVIcGtVqbQSN+U5lVUsypFgbiGKsOCM3LRcyeqVxG1tGKvh7TCkvNuZtg8t2CuyhvkH3VkM6NbmJX2d+JQTF35xYDv7ylUPAl3Hel5K7PHA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790288692; c=relaxed/simple; bh=ucLMqZ1UiBxVGeoeiorG+3ar2kSDUn+x16bRZmYSIRQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VjrjWjdo8QQoY1TIlfdqMYJxjHtriC8TSgG+9wHm2Qvp5X4dnIOOFZN8WwiWlttLFAd4r+K6s0raX7LjOwu1a7ldtIjJ6SeIlx/vypqxyt1vkHGWbpOvKRi4UPLgdE2qamsyagDRXiq31/XyeawJ6VStK3tmn0+rPBPwnPQ7ddk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=riscstar.com; spf=pass smtp.mailfrom=riscstar.com; dkim=pass (2048-bit key) header.d=riscstar-com.20251104.gappssmtp.com header.i=@riscstar-com.20251104.gappssmtp.com header.b=bSVxXmnN; arc=none smtp.client-ip=74.125.230.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=riscstar.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=riscstar.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=riscstar-com.20251104.gappssmtp.com header.i=@riscstar-com.20251104.gappssmtp.com header.b="bSVxXmnN" Received: by mail-qk2-f42.google.com with SMTP id af79cd13be357-93be29bb454so41998085a.1 for ; Thu, 24 Sep 2026 15:24:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=riscstar-com.20251104.gappssmtp.com; s=20251104; t=1790288689; x=1790893489; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=X4YnIQUduM9WqwnHXJR5IBSgzIzuiNO0FPLqtzOsUaQ=; b=bSVxXmnNxYxEUypEfFbSDgxaAsb3mpfXI9FsJmpdofVWTJPjrYaChdGFynmk8t1t1I N8+Msknm37AQWsi8TnGnSGOqLK8CFTds8fVPCx3SRdngr2MoPX4asEcjF7xtF5wNu5hl UPMhpoTKKG7sY2lnADUwtSImOq/sW4KdphwzNUqXqINlG7CXxdGdhQW1NBtKEMqTtbCZ RcSUqL7MgfbRnHYov/OvMimrUrtzSSENr7I2UZWLsd+N1hmQNfNgwIo6vAvafiTIW9vU j2TQ1S+Fa7/X+z6wbJQJDo1EZ2UOHiFAJtpHRhCvpULO8dQABotyMH45Bvyq8hy6Hd4t q9AQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790288689; x=1790893489; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=X4YnIQUduM9WqwnHXJR5IBSgzIzuiNO0FPLqtzOsUaQ=; b=LquBjOeH6h2j6eWwuPfPxpc1M7T2QzWTUh0oVyhQElYiFIOL3rEjskEQEkHBdzB/YP Vff2anibKP7eSmh9ImHqYAZUqSNJ0erJe/VUaL/6thOeKGSv7ZCaqil5Oq9ONnsGn2gG Vzh/HtBr7MIa2wwMw/s2Vxh40SdLuzGsY9fWr0sGGGCPyG2Egvxutzvx50kCAHTDmBvs ojfP8Mgkt/nJ1O3vyE32YfR8bsmYZMVPKGn0GRb2Ee6n13f5X2cSltPvmxObJytCLTge q8A4KAeHxHOti8ooCkDh2bjthpWImPoC1TBaq9n884CtVcLsYuwxjKW5LPMXSxgErdti RXdQ== X-Forwarded-Encrypted: i=1; AKwUvBzK8wyQa6hZRMEqzVm9vtf/QiZG0hXRvtqYx34ZJHH62JCcJKKPSXd+lSjz0XXpzw+jtKH7nW4fIGNdCnU=@vger.kernel.org X-Gm-Message-State: AFuF++krzrM8Ah1BP2kJPOWbBguHuswd8qTarCMkh9xnM7uSFQ/wB/3z JrDqgWNEehrBB8s8UUVSRBgfw7bBsjPHfrGLO4yTO6gLwtsQ9QSYwSXHKVePIRxWtaA= X-Gm-Gg: AYBFou1f1AyIuagFgvEI2aWPHWOl2plLnwdxb9RF2Q7h8nXVjc9TQ0ekE1zkHTyd7bn 5r1M8mBCE3dnTfivKLIirH7/tUJhA4PfMdlVv6uXNPyjmG8ziMN+hHA8XMk5uDDBAxTi3qQ6bBq lkrK5Gkk5mYXollXq5YvP82RGGVa3tQeGY0bqh+J8hs+UYeoFVfoX2Y4O7XOtxEtckci7cJREcq 3KDTLXfBWKZAOrdfnCW28+Rj0TP0TIfT0EEtsG0hm/Ol2j/gCkyVd99CTSBzEBJJLYEeIcQIXQN xbThp3qKgHqxzIN09anDvBdlxYgbFpsRQRaxCGMo6qFxRSR3pKQAnpxX/gPtZ4l7S2mznZkkYta Q/dkY3CxcVmctjsVLNH3fETGWmxwwXAeQ+Ag8vv1t4QMvO+6VMZGWLDP3Ajss9s5ytlhxmFlJFO XV46JslaYO2LekoAfCTxXXpSrakgEfJS/uJBhc3fTwGYKSNYMHsBJaatD/wLPUtFgv1NcAmOYeC SU= X-Received: by 2002:a05:620a:3711:b0:93b:e578:5838 with SMTP id af79cd13be357-93c43b86652mr142688685a.12.1790288688837; Thu, 24 Sep 2026 15:24:48 -0700 (PDT) Received: from zippy.localdomain ([73.62.185.64]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-91430eaf5basm3516496d6.44.2026.09.24.15.24.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Sep 2026 15:24:48 -0700 (PDT) From: Alex Elder To: bhelgaas@google.com Cc: lizhi.hou@amd.com, herve.codina@bootlin.com, andrea.porta@suse.com, daniel@riscstar.com, mohdayaa@qti.qualcomm.com, lbiancon@qti.qualcomm.com, mani@kernel.org, robh@kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 1/3] PCI: of: make a flags argument optional Date: Thu, 24 Sep 2026 17:24:41 -0500 Message-ID: <20260924222444.1351466-2-elder@riscstar.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260924222444.1351466-1-elder@riscstar.com> References: <20260924222444.1351466-1-elder@riscstar.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The address of a u32 object is passed to of_pci_get_addr_flags() so it can be filled with the computed flags value. Allow a null pointer to be passed, so that the validity of the resource's flags can be checked without filling in the flags value. Signed-off-by: Alex Elder --- drivers/pci/of_property.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c index 1e5d7dde467b8..a6c0cca986bdc 100644 --- a/drivers/pci/of_property.c +++ b/drivers/pci/of_property.c @@ -82,9 +82,11 @@ static int of_pci_get_addr_flags(const struct resource *= res, u32 *flags) else return -EINVAL; =20 - *flags =3D FIELD_PREP(OF_PCI_ADDR_FIELD_SS, ss); - if (res->flags & IORESOURCE_PREFETCH) - *flags |=3D OF_PCI_ADDR_FIELD_PREFETCH; + if (flags) { + *flags =3D FIELD_PREP(OF_PCI_ADDR_FIELD_SS, ss); + if (res->flags & IORESOURCE_PREFETCH) + *flags |=3D OF_PCI_ADDR_FIELD_PREFETCH; + } =20 return 0; } --=20 2.53.0 From nobody Fri Sep 25 17:42:52 2026 Received: from mail-qv2-f12.google.com (mail-qv2-f12.google.com [74.125.230.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E2DBE403EB9 for ; Thu, 24 Sep 2026 22:24:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.230.140 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790288692; cv=none; b=up+nvQyPG2hvdJUzxOqu7LpopyygpahLZ9eqHFODyAtF8Nd28kjxDvsSpSxZWUgtBdeUudbQcU2yp8YiyHQ8CBpu0l59KLKThlHiv3ZZzUnwoq7JVlm5H5ABA0cxBoqSAHeibS8/GCXWgk78GVGCFJbqlTj3thoUSuKQbzfK/Ok= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790288692; c=relaxed/simple; bh=0CIVmuZgnNf8YV7SFFeCJfSGG6AnPk/hZxzAYsVAg94=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DSLmR778ryrMHaEz7J7Xca6KTQgNPuwy/wOOcI9kVLC+4VR53Yj8zl0E/1LtBWhRUuYllWYOC91F/bMqb1QmOAF7Zo/OhpxWuk1CrEnT9iYEhQw5yKDetEV3Lg8zumJVX5fVk68FnONr3kJcYDwfArIMYIf9iDHbzjUaWhFo/pw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=riscstar.com; spf=pass smtp.mailfrom=riscstar.com; dkim=pass (2048-bit key) header.d=riscstar-com.20251104.gappssmtp.com header.i=@riscstar-com.20251104.gappssmtp.com header.b=aYfqdwNz; arc=none smtp.client-ip=74.125.230.140 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=riscstar.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=riscstar.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=riscstar-com.20251104.gappssmtp.com header.i=@riscstar-com.20251104.gappssmtp.com header.b="aYfqdwNz" Received: by mail-qv2-f12.google.com with SMTP id 6a1803df08f44-90cdfc9b6e3so3530556d6.1 for ; Thu, 24 Sep 2026 15:24:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=riscstar-com.20251104.gappssmtp.com; s=20251104; t=1790288690; x=1790893490; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=6KPtyojyWu8c8G12DM6+VdUpBOs3905ZK16r2yXTzMY=; b=aYfqdwNzmrhK/ZT8hwr78Pg/K66I4hGu9UH21yCQmCiShVzUvFNIB19fICI+/ssccE n+lLcj4YaXunSlTUg8AN+QVO8eVvvPcTary57wQD7jB9PRYsQ+CmfAWlVCa51sA72Ml7 b4V4Exqt9D4T6t4hYqrwwP79h3kpUXg8vMFvl8rNFTU5bnNBIYMwK2lYzIrrPjt2hf4D uyBsYWNVkjVWLRhDKK5E3NroWcH7raq0yWvyovdpowY4dn+vT2iY6ht/yIj5edKDKyqW /haTs2mmkdwhOGpaAPbhHhB+LuIENjyJWHCI6DUkn0ZEIPPYkmf+4XoWLkJ462KQZh6Z 9Dsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790288690; x=1790893490; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=6KPtyojyWu8c8G12DM6+VdUpBOs3905ZK16r2yXTzMY=; b=usLVbKAtIfSPKU139fgG9VGcAEXMJJAGZZCRb6NpDE05/pAw4G35NA7JXOxejx+m82 fYf+DBYM3GcExCRp+jUPX95YOzzJs9MYXcbwxu5yw3xxsRSSozs31En6nZcEz5i9VRUw LFRUzLHkWgwV1A2qynaqFjFg7jJKCRXvlCvflqaNp/Dz/njBqVekwgP1YMEh5pfT0Ean /mHVXUeHTP8gjaK7orT9xn5JsFpFJmbjgdHeflOrUP8i/BrHEs1PBEB7CSXREr4TgI8U M8SWq3rzHSd+YNDeyueyC0zY5cdCsfE5nbgVm+EZAWqAXkzxHokXg3YOL+w1PBpHAhZx gNfw== X-Forwarded-Encrypted: i=1; AKwUvBwL/cWcaYzE+BSLl01w5Xz7/hPmh52LnHWaGGvAMtJXtt6T783DJJWDOKZLOQETBOu85+X95EqQf/elqXk=@vger.kernel.org X-Gm-Message-State: AFuF++mOh8aNL9jdKVnawf6uUpPnTqiWZOwkDIGbYX4pfmuIGICP/aMp GXXKdLZvO+NquNMxunBAJqoIjcU1oi30xijumQ3fnhdLjkSoGlt2IW3T4YPFWH7CJ7U= X-Gm-Gg: AYBFou1IYL2wO52MB499wwsklFcZQao1S72V+iPnL9d1Z/lEYcD9IgoPm5aR7B3kWSW pIZ/MCW00zhCyd5INNeQ5lYbN5tfdfWRBcyIyj+rZ7buQXDsPixy7xUFWjlotLzZ7sceJt15H3X kjivWXMXTYA9vZ012sOivW3mYWdOyOYl94HkZ7iPo88Tlw8wZtQkn3QwjZ4f00tggGmAiQmxacw Y6CK/PEFXnLrkQXesVZzr/G1Oi1eWsmaxtH6+51w04wgw8Own8W9XkzuZ8pVTlQpskQJAY680Ul hzY1FiWW/wK/dM9L4tI221MW9Wj19q1wiixJoh7RrC0e3RM6kq3l0gmioQbRBJjnr6UpNVLmr6M R28WKO1ZhQE5MYaw0tbq5+v6zMfFceAcBM+AV6sFF0mVOAXZIUtOT92+IKD/zw5t64Paxtwokt5 25jTjmdgrcaMWZvPLxpk29Uyz+MsE+WA7S0DlHyATYit85LBHoenO/1Mw2fes9gPIbQuTWAwrHa zu3prlCzmn4YA== X-Received: by 2002:ad4:5ec6:0:b0:912:15a8:bd9f with SMTP id 6a1803df08f44-9142f6a130dmr13977176d6.7.1790288689912; Thu, 24 Sep 2026 15:24:49 -0700 (PDT) Received: from zippy.localdomain ([73.62.185.64]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-91430eaf5basm3516496d6.44.2026.09.24.15.24.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Sep 2026 15:24:49 -0700 (PDT) From: Alex Elder To: bhelgaas@google.com Cc: lizhi.hou@amd.com, herve.codina@bootlin.com, andrea.porta@suse.com, daniel@riscstar.com, mohdayaa@qti.qualcomm.com, lbiancon@qti.qualcomm.com, mani@kernel.org, robh@kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 2/3] PCI: of: introduce of_pci_build_prop_ranges() Date: Thu, 24 Sep 2026 17:24:42 -0500 Message-ID: <20260924222444.1351466-3-elder@riscstar.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260924222444.1351466-1-elder@riscstar.com> References: <20260924222444.1351466-1-elder@riscstar.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Move the bulk of what happens inside of_pci_prop_ranges() into a helper function that builds up the value to be passed to of_changeset_add_prop_u32_array(). This helper will be used in the next commit to build the ranges property for a statically-defined PCI endpoint devicetree node when it has a "pci-ep-bus" sub-node. Signed-off-by: Alex Elder --- drivers/pci/of_property.c | 129 +++++++++++++++++++++++++------------- 1 file changed, 86 insertions(+), 43 deletions(-) diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c index a6c0cca986bdc..9f30b3c09a730 100644 --- a/drivers/pci/of_property.c +++ b/drivers/pci/of_property.c @@ -102,57 +102,100 @@ static int of_pci_prop_bus_range(struct pci_dev *pde= v, ARRAY_SIZE(bus_range)); } =20 +/* + * Build a "ranges" property value that defines the mapping between + * child and parent PCI address space for each of the given PCI + * device's resources. + * + * Returns a dynamically allocated array of u32 devicetree cells, or + * a null pointer if allocation fails. The cell array is built as a + * of_pci_prop_ranges structure consisting of 8 32-bit cells in host + * byte order. It is suitable for use as the value of a PCI device + * node "ranges" property passed to of_changeset_add_prop_u32_array(). + * The total number of cells in the array is returned in *count. + * + * Caller is responsible for ensuring the returned pointer gets freed. + */ +static u32 *of_pci_build_prop_ranges(struct pci_dev *pdev, u32 *count) +{ + bool bridge_device =3D pci_is_bridge(pdev); + struct of_pci_range_entry *entries; + struct of_pci_range_entry *ep; + u32 resource_count =3D 0; + struct resource *res; + u32 first; + u32 num; + u32 i; + + if (bridge_device) { + first =3D PCI_BRIDGE_RESOURCES; + num =3D PCI_BRIDGE_RESOURCE_NUM; + } else { + first =3D PCI_STD_RESOURCES; + num =3D PCI_STD_NUM_BARS; + } + + /* First count how many resources will get a range property */ + res =3D &pdev->resource[first]; + for (i =3D 0; i < num; i++, res++) + if (resource_size(res) && !of_pci_get_addr_flags(res, NULL)) + resource_count++; + + entries =3D kzalloc_objs(*entries, resource_count); + if (!entries) + return NULL; + + ep =3D entries; + res =3D &pdev->resource[first]; + for (i =3D 0; i < num; i++, res++) { + u64 size =3D resource_size(res); + u32 flags; + + if (!size || of_pci_get_addr_flags(res, &flags)) + continue; + + /* Record the size in the range entry */ + ep->size[0] =3D upper_32_bits(size); + ep->size[1] =3D lower_32_bits(size); + + /* Record the parent bus address from the resource */ + of_pci_set_address(pdev, ep->parent_addr, + pci_bus_address(pdev, first + i), + flags, false); + + /* + * For a bridge device, the child address matches the + * parent address (including its flags cell). For an + * endpoint device, the (flags) cell contains the BAR + * number, and the two address cells are zero. + */ + if (bridge_device) + memcpy(ep->child_addr, ep->parent_addr, + sizeof(ep->child_addr)); + else + ep->child_addr[0] =3D i; + + ep++; + } + *count =3D resource_count * sizeof(*ep) / sizeof(u32); + + return (u32 *)entries; +} + static int of_pci_prop_ranges(struct pci_dev *pdev, struct of_changeset *o= cs, struct device_node *np) { struct of_pci_range_entry *rp; - struct resource *res; - int i, j, ret; - u32 flags, num; - u64 val64; + u32 *value; + u32 count; + int ret; =20 - if (pci_is_bridge(pdev)) { - num =3D PCI_BRIDGE_RESOURCE_NUM; - res =3D &pdev->resource[PCI_BRIDGE_RESOURCES]; - } else { - num =3D PCI_STD_NUM_BARS; - res =3D &pdev->resource[PCI_STD_RESOURCES]; - } - - rp =3D kzalloc_objs(*rp, num); - if (!rp) + value =3D of_pci_build_prop_ranges(pdev, &count); + if (!value) return -ENOMEM; =20 - for (i =3D 0, j =3D 0; j < num; j++) { - if (!resource_size(&res[j])) - continue; + ret =3D of_changeset_add_prop_u32_array(ocs, np, "ranges", value, count); =20 - if (of_pci_get_addr_flags(&res[j], &flags)) - continue; - - val64 =3D pci_bus_address(pdev, &res[j] - pdev->resource); - of_pci_set_address(pdev, rp[i].parent_addr, val64, flags, - false); - if (pci_is_bridge(pdev)) { - memcpy(rp[i].child_addr, rp[i].parent_addr, - sizeof(rp[i].child_addr)); - } else { - /* - * For endpoint device, the lower 64-bits of child - * address is always zero. - */ - rp[i].child_addr[0] =3D j; - } - - val64 =3D resource_size(&res[j]); - rp[i].size[0] =3D upper_32_bits(val64); - rp[i].size[1] =3D lower_32_bits(val64); - - i++; - } - - ret =3D of_changeset_add_prop_u32_array(ocs, np, "ranges", (u32 *)rp, - i * sizeof(*rp) / sizeof(u32)); kfree(rp); =20 return ret; --=20 2.53.0 From nobody Fri Sep 25 17:42:52 2026 Received: from mail-qv2-f12.google.com (mail-qv2-f12.google.com [74.125.230.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3A33940B110 for ; Thu, 24 Sep 2026 22:24:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.230.140 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790288693; cv=none; b=Za2/tsrOGk2ESPXHhirTg8NaVjY40nW7IRt11N/LVn8o2NXmgQudC6Y5M8I2eO+PeDxjFN971y/J32kehXTpIqe/JtWmJOLfY1udaLDoE0hrDUm53GaPlIKApIv0UVoeweBoc6+ql0gNCim6eRT7Pssz6zzC2GUyDJCnBTkhLbk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790288693; c=relaxed/simple; bh=tKKgHTVj7sjK3uu9Bd1RURnxjzLdbEIr7XiNphJtbD0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OVkmqRFvE1+6jWoIMnI5Xjm1B58GNDyowgqJnHZR64xDSHlCqXNMNHgwhij9t4Y3hhDv16UTNnfEY1sexWySuUV4cPbKXwCzGYe9u/VTbPAlFFmkl/hyfLceNrQvxo+AeB1NJVvyiY13DlX920+mVgWhdyzJTFT3sLrvFMdiOnE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=riscstar.com; spf=pass smtp.mailfrom=riscstar.com; dkim=pass (2048-bit key) header.d=riscstar-com.20251104.gappssmtp.com header.i=@riscstar-com.20251104.gappssmtp.com header.b=OpLsj+hA; arc=none smtp.client-ip=74.125.230.140 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=riscstar.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=riscstar.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=riscstar-com.20251104.gappssmtp.com header.i=@riscstar-com.20251104.gappssmtp.com header.b="OpLsj+hA" Received: by mail-qv2-f12.google.com with SMTP id 6a1803df08f44-90cdfcb5cb1so3854636d6.1 for ; Thu, 24 Sep 2026 15:24:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=riscstar-com.20251104.gappssmtp.com; s=20251104; t=1790288691; x=1790893491; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=HnmZ0RUOTd+QntYtAvyxm4yxyuFcoMhdt2vyYIZdIuk=; b=OpLsj+hA7CZMVlvXHYMGufv4KOh+WuDxEOG4NRfQ50U4RBLZqhdNDM2QZ4dpwsCLTL A6iXz1FHe6yeCwFBKwt2LWDel6d+xf2FM/q0tXd29toJ1vVyc7754eYkV4fzAb7fL33q a+ziL2P9R3QFu55jbsZc0FEWKiRg105tgcMlcZq+E6VcXcnp4dplWKXYRZlb4J7ZyH0C tiGyrKhPCoM9499m0mEmcterqbaHwAK4lj7ggkZWdQY7MFm34oLFa+Z6WhBdvKvMsRnk nRiop5i7bfCjJuYSpdMWBHgoyZJVVnetA6wFeBocnipjiLdyPRY67T3puzEmJiyvhdd/ qHjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790288691; x=1790893491; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=HnmZ0RUOTd+QntYtAvyxm4yxyuFcoMhdt2vyYIZdIuk=; b=YsLJTDh7sjJHmaUYUSGpBj2KMnPe0lfbTQoOqcdwGkUXBhOKnUQdUnSWRh37524ByX GhUIcrXaaeH//hGui91QzBIw5DuiDwJJmD18SctyrU/K5w0EGXMYwhqfqGj3dKkdJRYd qzr0WpQx5L9FFDDXuYOQgbbfLnaE1QZcp+m9Z6Iko6gaziDZVpyDN2keAELiOhsJvhM1 zC0iNpS9jyCwNGOdSmNX3PRFAtCTOWwYSuGUzl2rHni2Jq6oh8G8wZrwQFwe8pVe5QB0 KwlsX5nTbLntD6Dp8ddJrsuN9Fjhr7E4aCZ/xJYjNd486R49yzG3v3O8rBKXd5UTJ59I 1WRA== X-Forwarded-Encrypted: i=1; AKwUvByCeUd03MxeRxRDkNZxFZ0xEFBuRgsD9irdd6R9dEheel544j1mFu7fAyYURHJYSNiA9hzvvBiF95n1XEU=@vger.kernel.org X-Gm-Message-State: AFuF++k7SFWUxa9q25Za85FkR3vvbUnC4IgWV3g+JQyZ+EeeOH+XBlpf rfRnbC3qqXzj7Z1SSd6J4yVtTw2UHrG8HLA3M9FSbEBVFZnzP+myqnLsiB+IHzTIVdE= X-Gm-Gg: AYBFou1QBE79/BcdTWWR9qKRYxTdZrCxwKcokYv64spvOBfI0lWK8o0a4K7xZFAhZ2M iwiweZU8wP4F8RDpwqWgm0i2uYA341Xz9avZMEwD8j5gyXKZ2epNkDLrB07kG2zooKOjKwGLDl6 IxJU8TLJKqrrWH7+/lWBYHFvSyh5YX9b/oqo+ZEHivz+pEOlMe46qacOmXf+Oa2envdIBCVgggs g65OIrTiVtaGTKn1M3iSD15huRQqzixaUDyEKAJIJrxGWSvSPLDIo5M7gh3am4PnBezJ9QK+Q0D cE9BuZKVKpy+J8Ve0CpyQ3KonSfz/N2Owg9UF2veGGBHE5UCc5fgdoCQ/SNZo6Ts2yEe2IGjZOW 5BwvjTNvJAinUNrKSveNwl1JupSUJ6IlbuhFPFLc9ijOVXAVKBHQYJ6LYCz/usX4tUY2IvBN0bZ 2QXNlGasmyyR8vYCQqIP3hqZl7MGcVd8/YODUOK48ZHuX4uX7eVFHprUF2qNc7eBpYZnFHJ3OqT pM= X-Received: by 2002:a05:6214:c24:b0:90e:9d05:b757 with SMTP id 6a1803df08f44-91431fa978bmr4959886d6.0.1790288691000; Thu, 24 Sep 2026 15:24:51 -0700 (PDT) Received: from zippy.localdomain ([73.62.185.64]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-91430eaf5basm3516496d6.44.2026.09.24.15.24.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Sep 2026 15:24:50 -0700 (PDT) From: Alex Elder To: bhelgaas@google.com Cc: lizhi.hou@amd.com, herve.codina@bootlin.com, andrea.porta@suse.com, daniel@riscstar.com, mohdayaa@qti.qualcomm.com, lbiancon@qti.qualcomm.com, mani@kernel.org, robh@kernel.org, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 3/3] PCI: of: introduce of_pci_update_endpoint_node_ranges() Date: Thu, 24 Sep 2026 17:24:43 -0500 Message-ID: <20260924222444.1351466-4-elder@riscstar.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260924222444.1351466-1-elder@riscstar.com> References: <20260924222444.1351466-1-elder@riscstar.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Commit 407d1a51921e9 ("PCI: Create device tree node for bridge") introduced the PCI_DYNAMIC_OF_NODES Kconfig option, which creates a devicetree node for a PCI bridge as part of pci_bus_add_device(). Its successor commit ae9813db1dc5a ("PCI: Add quirks to generate device tree node for Xilinx Alveo U50") shows how to use a PCI final fixup quirk to also create a devicetree node for a non-bridge PCI device. In both cases, of_pci_make_dev_node() uses an OF changeset to dynamically create a node populated with appropriate properties and apply it to the live devicetree. The dynamic devicetree node for a PCI device will include a "ranges" property, and a new type of 3-cell address is introduced for use within an endpoint. The endpoint's ranges property will contain a range entry for each of the endpoint's BARs. The "child address" portion of each range will use the BAR number in the "flags" (first) cell in the address. This allows addresses within the endpoint to be expressed relative to whatever address gets assigned to each BAR. Unfortunately, if a PCI endpoint device had a devicetree node set up statically, its "ranges" property (if present) will be static, and it cannot contain the addresses assigned to the endpoint's BARs during enumeration. This means that the "BAR number" based addressing scheme doesn't work for PCI endpoints whose devicetree nodes are created statically. To remedy this, modify of_pci_make_dev_node() to dynamically create a "ranges" property even if the device already has a devicetree node--just as is done when the endpoint has none. A few conditions: - A PCI bridge node's ranges property is never updated - If a PCI endpoint node defines a ranges property with a non-empty value (i.e., it's not just "ranges;"), that ranges property is preserved Otherwise a new ranges property is created using assigned addresses, and it replaces (or adds) that property to the PCI endpoint node. As a result, "BAR number" addresses work correctly even when the endpoint's devicetree node is created statically. Signed-off-by: Alex Elder --- v3: - Don't update an existing non-empty ranges property drivers/pci/of.c | 94 +++++++++++++++++++++++++++++++++++---- drivers/pci/of_property.c | 2 +- drivers/pci/pci.h | 1 + 3 files changed, 88 insertions(+), 9 deletions(-) diff --git a/drivers/pci/of.c b/drivers/pci/of.c index 5a040ed836744..7fb5e0351719c 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -742,20 +742,98 @@ void of_pci_remove_node(struct pci_dev *pdev) of_node_put(np); } =20 +/* Returns true if the ranges property was added or updated successfully */ +static bool of_pci_update_endpoint_node_ranges(struct pci_dev *pdev) +{ + struct device_node *np =3D pci_device_to_OF_node(pdev); + struct property *prop; + u32 *value; + u32 size; + + prop =3D kzalloc_obj(*prop); + if (!prop) + return false; + + value =3D of_pci_build_prop_ranges(pdev, &size); + if (!value) { + kfree(prop); + return false; + } + + prop->name =3D "ranges"; + prop->length =3D size * sizeof(u32); + prop->value =3D value; + + /* The property value needs to be in big-endian byte order */ + while (size--) + cpu_to_be32s(value++); + + /* of_update_property() consumes the allocated property */ + of_update_property(np, prop); + + return true; +} + +/* + * Create a devicetree node for a PCI device. If the device is a bridge + * and it already has a devicetree node, there's nothing further to do. + * If it is a bridge without an existing devicetree node, one is created + * dynamically. + * + * This function can also be called (via PCI quirk) for a PCI endpoint + * (function) that implements a PCI endpoint bus. As with a PCI bridge, + * if the endpoint has no existing devicetree node, one is created + * dynamically. The node will include a ranges property that maps + * BAR-relative addresses in the child to the PCI address ranges + * assigned to the PCI endpoint BARs. + * + * If an endpoint already has a devicetree node, and it includes a + * "pci-ep-bus" sub-node, its ranges property must still be dynamically + * populated so that it can take into account the BAR ranges assigned + * during PCI enumeration. + */ void of_pci_make_dev_node(struct pci_dev *pdev) { - struct device_node *ppnode, *np =3D NULL; + struct device_node *np =3D pci_device_to_OF_node(pdev); + struct device *dev =3D &pdev->dev; + struct device_node *ppnode; + struct of_changeset *cset; const char *pci_type; - struct of_changeset *cset; const char *name; int ret; =20 - /* - * If there is already a device tree node linked to this device, - * return immediately. - */ - if (pci_device_to_OF_node(pdev)) + /* See if the PCI device already has a devicetree node */ + if (np) { + struct device_node *child; + unsigned int rlen =3D 0; + + /* Nothing further needed for a bridge */ + if (pci_is_bridge(pdev)) + return; + + /* + * A ranges property is only needed if the endpoint's + * devicetree node includes a "pci-ep-bus" sub-node. + */ + child =3D of_get_child_by_name(np, "pci-ep-bus"); + if (!child) + return; + of_node_put(child); + + /* If the ranges property is non-empty, just keep it.*/ + if (of_get_property(np, "ranges", &rlen) && rlen) + return; + + /* + * Otherwise create a ranges property, defining an entry for + * each BAR, and map BAR offsets to the PCI bus address based + * on the BAR's assigned range. + */ + if (!of_pci_update_endpoint_node_ranges(pdev)) + dev_err(dev, "failed to update ranges property\n"); + return; + } =20 /* Check if there is device tree node for parent device */ if (!pdev->bus->self) @@ -794,7 +872,7 @@ void of_pci_make_dev_node(struct pci_dev *pdev) =20 np->data =3D cset; =20 - ret =3D device_add_of_node(&pdev->dev, np); + ret =3D device_add_of_node(dev, np); if (ret) goto out_revert_cset; =20 diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c index 9f30b3c09a730..8e1548c4aac3c 100644 --- a/drivers/pci/of_property.c +++ b/drivers/pci/of_property.c @@ -116,7 +116,7 @@ static int of_pci_prop_bus_range(struct pci_dev *pdev, * * Caller is responsible for ensuring the returned pointer gets freed. */ -static u32 *of_pci_build_prop_ranges(struct pci_dev *pdev, u32 *count) +u32 *of_pci_build_prop_ranges(struct pci_dev *pdev, u32 *count) { bool bridge_device =3D pci_is_bridge(pdev); struct of_pci_range_entry *entries; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 2e33d3bd4b0ba..1461e52777532 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -1318,6 +1318,7 @@ struct of_changeset; #ifdef CONFIG_PCI_DYNAMIC_OF_NODES void of_pci_make_dev_node(struct pci_dev *pdev); void of_pci_remove_node(struct pci_dev *pdev); +u32 *of_pci_build_prop_ranges(struct pci_dev *pdev, u32 *count); int of_pci_add_properties(struct pci_dev *pdev, struct of_changeset *ocs, struct device_node *np); void of_pci_make_host_bridge_node(struct pci_host_bridge *bridge); --=20 2.53.0