get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.0/patches/2219838/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2219838,
    "url": "http://patchwork.ozlabs.org/api/1.0/patches/2219838/?format=api",
    "project": {
        "id": 28,
        "url": "http://patchwork.ozlabs.org/api/1.0/projects/28/?format=api",
        "name": "Linux PCI development",
        "link_name": "linux-pci",
        "list_id": "linux-pci.vger.kernel.org",
        "list_email": "linux-pci@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null
    },
    "msgid": "<20260404182854.2183651-3-cjd@cjdns.fr>",
    "date": "2026-04-04T18:28:54",
    "name": "[v4,2/2] PCI: mediatek: Add support for EcoNet EN7528 SoC",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "a4be265eb984bf11e7e07c35096630f2cfdcd4a8",
    "submitter": {
        "id": 66262,
        "url": "http://patchwork.ozlabs.org/api/1.0/people/66262/?format=api",
        "name": "Caleb James DeLisle",
        "email": "cjd@cjdns.fr"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-pci/patch/20260404182854.2183651-3-cjd@cjdns.fr/mbox/",
    "series": [
        {
            "id": 498745,
            "url": "http://patchwork.ozlabs.org/api/1.0/series/498745/?format=api",
            "date": "2026-04-04T18:28:54",
            "name": "PCI: mediatek: Add support for EcoNet SoCs",
            "version": 4,
            "mbox": "http://patchwork.ozlabs.org/series/498745/mbox/"
        }
    ],
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2219838/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "\n <linux-pci+bounces-51899-incoming=patchwork.ozlabs.org@vger.kernel.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "linux-pci@vger.kernel.org"
        ],
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=cjdns.fr header.i=@cjdns.fr header.a=rsa-sha256\n header.s=dkim header.b=Rn6Gb5QX;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=172.105.105.114; helo=tor.lore.kernel.org;\n envelope-from=linux-pci+bounces-51899-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)",
            "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr\n header.b=\"Rn6Gb5QX\"",
            "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=5.135.140.105",
            "smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=cjdns.fr",
            "smtp.subspace.kernel.org;\n spf=none smtp.mailfrom=cjdns.fr"
        ],
        "Received": [
            "from tor.lore.kernel.org (tor.lore.kernel.org [172.105.105.114])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fp47W6cQFz1yCs\n\tfor <incoming@patchwork.ozlabs.org>; Sun, 05 Apr 2026 04:36:55 +1000 (AEST)",
            "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id 249B2300D6A8\n\tfor <incoming@patchwork.ozlabs.org>; Sat,  4 Apr 2026 18:36:50 +0000 (UTC)",
            "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 919A033DED9;\n\tSat,  4 Apr 2026 18:36:47 +0000 (UTC)",
            "from mail.cjdns.fr (mail.cjdns.fr [5.135.140.105])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 94AB72EA171;\n\tSat,  4 Apr 2026 18:36:45 +0000 (UTC)",
            "from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon)\n with ESMTPSA id B559418DE45;\n\tSat,  4 Apr 2026 20:29:06 +0200 (CEST)"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1775327807; cv=none;\n b=LGwE6qW5IeF7C4xetP49BsR/dqd6gDmNLnn6Ug5z4xKXFIyBeJKaBmahnk1nzhzfOCmy91yonefS4xZy5S9rOQ3deUgXXjq/KEt+r5MSu+oLF2QQU+44kLRG41l5BEeMdTtw0dTGrX7lTJ0Fq/nLvXi7iEGXFOl5j9T7rMsALP8=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1775327807; c=relaxed/simple;\n\tbh=O3z31uVT+Dfd8j0b4hkRpmwYzvLPn03LuNW3yKqjl40=;\n\th=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:\n\t MIME-Version;\n b=onD1a2Ny6C4eicvPlBe8br6BMyB5DZImMyAZVWPSqg+Um4cj7aG1nBINxc0sRy0Xe2JucwqQP0qr0OLxSLf11ICvpfyWGHZU1jFS4l3sh4wO+LJ9JgCoypgKbuBx/2W/4/8pyQfVqXk/ZUH2R6rit6moqmECNqZhPrkQkj6jhOo=",
        "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=cjdns.fr;\n spf=none smtp.mailfrom=cjdns.fr;\n dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr\n header.b=Rn6Gb5QX; arc=none smtp.client-ip=5.135.140.105",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=cjdns.fr; s=dkim;\n\tt=1775327350; h=from:subject:date:message-id:to:cc:mime-version:\n\t content-transfer-encoding:in-reply-to:references;\n\tbh=GdKZudBiZWRmnj2Q8xLAe5Ktsw/srDvDPRU3HuRREMc=;\n\tb=Rn6Gb5QXZSL5zhyytefJst9A+Qdw6SWvJs967M8kEw+/W/uBKhTtX5UFzfWrzsiVI2Cmr5\n\tq2WzVV8YyKZOZnAFnIWRS7krVGWY7bVY5/dFEWlIsVSY5cI2y0T7uJFlqqDKwKOsM0yXXC\n\tinkkhr6TECuK3HTDrmQlX+phlU0seQwBtDrY/b7T3FkeGvVGIbWNBxwAYDrmxJ1MmYvLlg\n\tw6rswPBuSY3bWcVfAarnsNPKTDRLH9nG0Ws4BMiFPqXj62yLULL/YiOjyy/T2wnbCywJ6f\n\t2cNshIo1YlZ4+0ijHEyEJ8J31CQ8H/VGOiO1rsRRHy79hOmORl/MaLsicsrXRg==",
        "From": "Caleb James DeLisle <cjd@cjdns.fr>",
        "To": "linux-pci@vger.kernel.org",
        "Cc": "linux-mips@vger.kernel.org,\n\tnaseefkm@gmail.com,\n\tryder.lee@mediatek.com,\n\thelgaas@kernel.org,\n\tlpieralisi@kernel.org,\n\tkwilczynski@kernel.org,\n\tmani@kernel.org,\n\trobh@kernel.org,\n\tkrzk+dt@kernel.org,\n\tconor+dt@kernel.org,\n\tmatthias.bgg@gmail.com,\n\tangelogioacchino.delregno@collabora.com,\n\tansuelsmth@gmail.com,\n\tlinux-mediatek@lists.infradead.org,\n\tdevicetree@vger.kernel.org,\n\tlinux-kernel@vger.kernel.org,\n\tCaleb James DeLisle <cjd@cjdns.fr>",
        "Subject": "[PATCH v4 2/2] PCI: mediatek: Add support for EcoNet EN7528 SoC",
        "Date": "Sat,  4 Apr 2026 18:28:54 +0000",
        "Message-Id": "<20260404182854.2183651-3-cjd@cjdns.fr>",
        "In-Reply-To": "<20260404182854.2183651-1-cjd@cjdns.fr>",
        "References": "<20260404182854.2183651-1-cjd@cjdns.fr>",
        "Precedence": "bulk",
        "X-Mailing-List": "linux-pci@vger.kernel.org",
        "List-Id": "<linux-pci.vger.kernel.org>",
        "List-Subscribe": "<mailto:linux-pci+subscribe@vger.kernel.org>",
        "List-Unsubscribe": "<mailto:linux-pci+unsubscribe@vger.kernel.org>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-Last-TLS-Session-Version": "TLSv1.3"
    },
    "content": "Add support for the PCIe present on the EcoNet EN7528 (and EN751221) SoCs.\n\nThese SoCs have a mix of Gen1 and Gen2 capable ports, but the Gen2 ports\nrequire re-training after startup.\n\nCo-developed-by: Ahmed Naseef <naseefkm@gmail.com>\nSigned-off-by: Ahmed Naseef <naseefkm@gmail.com>\nSigned-off-by: Caleb James DeLisle <cjd@cjdns.fr>\n---\n drivers/pci/controller/Kconfig         |   2 +-\n drivers/pci/controller/pcie-mediatek.c | 133 +++++++++++++++++++++++++\n 2 files changed, 134 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig\nindex 686349e09cd3..5808d5e407fd 100644\n--- a/drivers/pci/controller/Kconfig\n+++ b/drivers/pci/controller/Kconfig\n@@ -209,7 +209,7 @@ config PCI_MVEBU\n \n config PCIE_MEDIATEK\n \ttristate \"MediaTek PCIe controller\"\n-\tdepends on ARCH_AIROHA || ARCH_MEDIATEK || COMPILE_TEST\n+\tdepends on ARCH_AIROHA || ARCH_MEDIATEK || ECONET || COMPILE_TEST\n \tdepends on OF\n \tdepends on PCI_MSI\n \tselect IRQ_MSI_LIB\ndiff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c\nindex 75722524fe74..915a35825ce1 100644\n--- a/drivers/pci/controller/pcie-mediatek.c\n+++ b/drivers/pci/controller/pcie-mediatek.c\n@@ -7,6 +7,7 @@\n  *\t   Honghui Zhang <honghui.zhang@mediatek.com>\n  */\n \n+#include <asm-generic/errno-base.h>\n #include <linux/clk.h>\n #include <linux/delay.h>\n #include <linux/iopoll.h>\n@@ -14,6 +15,7 @@\n #include <linux/irqchip/chained_irq.h>\n #include <linux/irqchip/irq-msi-lib.h>\n #include <linux/irqdomain.h>\n+#include <linux/kconfig.h>\n #include <linux/kernel.h>\n #include <linux/mfd/syscon.h>\n #include <linux/msi.h>\n@@ -77,6 +79,7 @@\n \n #define PCIE_CONF_VEND_ID\t0x100\n #define PCIE_CONF_DEVICE_ID\t0x102\n+#define PCIE_CONF_REV_CLASS\t0x104\n #define PCIE_CONF_CLASS_ID\t0x106\n \n #define PCIE_INT_MASK\t\t0x420\n@@ -89,6 +92,11 @@\n #define MSI_MASK\t\tBIT(23)\n #define MTK_MSI_IRQS_NUM\t32\n \n+#define EN7528_HOST_MODE\t0x00804201\n+#define EN7528_LINKUP_REG\t0x50\n+#define EN7528_RC0_LINKUP\tBIT(1)\n+#define EN7528_RC1_LINKUP\tBIT(2)\n+\n #define PCIE_AHB_TRANS_BASE0_L\t0x438\n #define PCIE_AHB_TRANS_BASE0_H\t0x43c\n #define AHB2PCIE_SIZE(x)\t((x) & GENMASK(4, 0))\n@@ -148,12 +156,15 @@ struct mtk_pcie_port;\n  * @MTK_PCIE_FIX_DEVICE_ID: host's device ID needed to be fixed\n  * @MTK_PCIE_NO_MSI: Bridge has no MSI support, and relies on an external block\n  * @MTK_PCIE_SKIP_RSTB: Skip calling RSTB bits on PCIe probe\n+ * @MTK_PCIE_RETRAIN: Re-train link to bridge after startup because some\n+ *                    Gen2-capable devices start as Gen1.\n  */\n enum mtk_pcie_quirks {\n \tMTK_PCIE_FIX_CLASS_ID = BIT(0),\n \tMTK_PCIE_FIX_DEVICE_ID = BIT(1),\n \tMTK_PCIE_NO_MSI = BIT(2),\n \tMTK_PCIE_SKIP_RSTB = BIT(3),\n+\tMTK_PCIE_RETRAIN = BIT(4),\n };\n \n /**\n@@ -753,6 +764,80 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)\n \treturn 0;\n }\n \n+static int mtk_pcie_startup_port_en7528(struct mtk_pcie_port *port)\n+{\n+\tstruct mtk_pcie *pcie = port->pcie;\n+\tstruct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);\n+\tstruct resource *mem = NULL;\n+\tstruct resource_entry *entry;\n+\tu32 val, link_mask;\n+\tint err;\n+\n+\tentry = resource_list_first_type(&host->windows, IORESOURCE_MEM);\n+\tif (entry)\n+\t\tmem = entry->res;\n+\tif (!mem)\n+\t\treturn -EINVAL;\n+\n+\tif (!pcie->cfg) {\n+\t\tdev_err(pcie->dev, \"EN7528: pciecfg syscon not available\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Assert all reset signals */\n+\twritel(0, port->base + PCIE_RST_CTRL);\n+\n+\t/*\n+\t * Enable PCIe link down reset, if link status changed from link up to\n+\t * link down, this will reset MAC control registers and configuration\n+\t * space.\n+\t */\n+\twritel(PCIE_LINKDOWN_RST_EN, port->base + PCIE_RST_CTRL);\n+\n+\tmsleep(PCIE_T_PVPERL_MS);\n+\n+\t/* De-assert PHY, PE, PIPE, MAC and configuration reset */\n+\tval = readl(port->base + PCIE_RST_CTRL);\n+\tval |= PCIE_PHY_RSTB | PCIE_PERSTB | PCIE_PIPE_SRSTB |\n+\t       PCIE_MAC_SRSTB | PCIE_CRSTB;\n+\twritel(val, port->base + PCIE_RST_CTRL);\n+\n+\twritel(PCIE_CLASS_CODE | PCIE_REVISION_ID,\n+\t       port->base + PCIE_CONF_REV_CLASS);\n+\twritel(EN7528_HOST_MODE, port->base);\n+\n+\tlink_mask = (port->slot == 0) ? EN7528_RC0_LINKUP : EN7528_RC1_LINKUP;\n+\n+\t/* 100ms timeout value should be enough for Gen1/2 training */\n+\terr = regmap_read_poll_timeout(pcie->cfg, EN7528_LINKUP_REG, val,\n+\t\t\t\t       !!(val & link_mask), 20,\n+\t\t\t\t       PCI_PM_D3COLD_WAIT * USEC_PER_MSEC);\n+\tif (err) {\n+\t\tdev_err(pcie->dev, \"EN7528: port%d link timeout\\n\", port->slot);\n+\t\treturn -ETIMEDOUT;\n+\t}\n+\n+\t/* Activate INTx interrupts */\n+\tval = readl(port->base + PCIE_INT_MASK);\n+\tval &= ~INTX_MASK;\n+\twritel(val, port->base + PCIE_INT_MASK);\n+\n+\tif (IS_ENABLED(CONFIG_PCI_MSI))\n+\t\tmtk_pcie_enable_msi(port);\n+\n+\t/* Set AHB to PCIe translation windows */\n+\tval = lower_32_bits(mem->start) |\n+\t      AHB2PCIE_SIZE(fls(resource_size(mem)));\n+\twritel(val, port->base + PCIE_AHB_TRANS_BASE0_L);\n+\n+\tval = upper_32_bits(mem->start);\n+\twritel(val, port->base + PCIE_AHB_TRANS_BASE0_H);\n+\n+\twritel(WIN_ENABLE, port->base + PCIE_AXI_WINDOW0);\n+\n+\treturn 0;\n+}\n+\n static void __iomem *mtk_pcie_map_bus(struct pci_bus *bus,\n \t\t\t\t      unsigned int devfn, int where)\n {\n@@ -1149,6 +1234,46 @@ static int mtk_pcie_probe(struct platform_device *pdev)\n \tif (err)\n \t\tgoto put_resources;\n \n+\t/* EN7528 PCIe initially comes up as Gen1 even if Gen2 is supported.\n+\t * The cannonical way to achieve Gen2 is to re-train the link\n+\t * immediately after setup. However, to save a lot of duplicated code\n+\t * we use pcie_retrain_link() which is usable once we have the pci_dev\n+\t * struct for the bridge, i.e. after pci_host_probe(). */\n+\tif (pcie->soc->quirks & MTK_PCIE_RETRAIN) {\n+\t\tint slot = of_get_pci_domain_nr(dev->of_node);\n+\t\tstruct pci_dev *rc = NULL;\n+\t\tint ret = -ENOENT;\n+\n+\t\tif (slot >= 0)\n+\t\t\trc = pci_get_slot(host->bus, PCI_DEVFN(slot, 0));\n+\n+\t\tif (rc) {\n+\t\t\tret = -EOPNOTSUPP;\n+\n+\t\t\t/* pcie_retrain_link() is not an exported symbol but\n+\t\t\t * this driver supports being built as a loadable\n+\t\t\t * module. Someone using this on an EN7528 should make\n+\t\t\t * it builtin, or accept Gen1 PCI. */\n+#if IS_BUILTIN(CONFIG_PCIE_MEDIATEK)\n+\t\t\tret = pcie_retrain_link(rc, true);\n+#endif\n+\t\t}\n+\n+\t\tif (ret) {\n+\t\t\tdev_info(dev, \"port%d failed to retrain %pe\\n\", slot,\n+\t\t\t\t ERR_PTR(ret));\n+\t\t} else {\n+\t\t\tu16 lnksta;\n+\t\t\tu32 speed;\n+\n+\t\t\tpcie_capability_read_word(rc, PCI_EXP_LNKSTA, &lnksta);\n+\t\t\tspeed = lnksta & PCI_EXP_LNKSTA_CLS;\n+\n+\t\t\tdev_info(dev, \"port%d link retrained, speed %s\\n\", slot,\n+\t\t\t\t pci_speed_string(pcie_link_speed[speed]));\n+\t\t}\n+\t}\n+\n \treturn 0;\n \n put_resources:\n@@ -1264,8 +1389,16 @@ static const struct mtk_pcie_soc mtk_pcie_soc_mt7629 = {\n \t.quirks = MTK_PCIE_FIX_CLASS_ID | MTK_PCIE_FIX_DEVICE_ID,\n };\n \n+static const struct mtk_pcie_soc mtk_pcie_soc_en7528 = {\n+\t.ops = &mtk_pcie_ops_v2,\n+\t.startup = mtk_pcie_startup_port_en7528,\n+\t.setup_irq = mtk_pcie_setup_irq,\n+\t.quirks = MTK_PCIE_RETRAIN,\n+};\n+\n static const struct of_device_id mtk_pcie_ids[] = {\n \t{ .compatible = \"airoha,an7583-pcie\", .data = &mtk_pcie_soc_an7583 },\n+\t{ .compatible = \"econet,en7528-pcie\", .data = &mtk_pcie_soc_en7528 },\n \t{ .compatible = \"mediatek,mt2701-pcie\", .data = &mtk_pcie_soc_v1 },\n \t{ .compatible = \"mediatek,mt7623-pcie\", .data = &mtk_pcie_soc_v1 },\n \t{ .compatible = \"mediatek,mt2712-pcie\", .data = &mtk_pcie_soc_mt2712 },\n",
    "prefixes": [
        "v4",
        "2/2"
    ]
}