get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2196998,
    "url": "http://patchwork.ozlabs.org/api/patches/2196998/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/b2ad68da753c0e0a87db8c6f928e1176a50efbe1.1771275704.git.daniel@makrotopia.org/",
    "project": {
        "id": 18,
        "url": "http://patchwork.ozlabs.org/api/projects/18/?format=api",
        "name": "U-Boot",
        "link_name": "uboot",
        "list_id": "u-boot.lists.denx.de",
        "list_email": "u-boot@lists.denx.de",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<b2ad68da753c0e0a87db8c6f928e1176a50efbe1.1771275704.git.daniel@makrotopia.org>",
    "list_archive_url": null,
    "date": "2026-02-16T21:21:49",
    "name": "[RFC,04/20] boot: image-loader: add MTD backend",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "510aed4c2f76b59664f2f54225fc6eadf3b9c821",
    "submitter": {
        "id": 64091,
        "url": "http://patchwork.ozlabs.org/api/people/64091/?format=api",
        "name": "Daniel Golle",
        "email": "daniel@makrotopia.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/b2ad68da753c0e0a87db8c6f928e1176a50efbe1.1771275704.git.daniel@makrotopia.org/mbox/",
    "series": [
        {
            "id": 492351,
            "url": "http://patchwork.ozlabs.org/api/series/492351/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=492351",
            "date": "2026-02-16T21:21:14",
            "name": "boot: add OpenWrt boot method and on-demand FIT loading",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/492351/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2196998/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2196998/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<u-boot-bounces@lists.denx.de>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=85.214.62.61; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)",
            "phobos.denx.de;\n dmarc=none (p=none dis=none) header.from=makrotopia.org",
            "phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de",
            "phobos.denx.de; dmarc=none (p=none dis=none)\n header.from=makrotopia.org",
            "phobos.denx.de;\n spf=pass smtp.mailfrom=daniel@makrotopia.org"
        ],
        "Received": [
            "from phobos.denx.de (phobos.denx.de [85.214.62.61])\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 4fFG3g3Mlzz1xwD\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 17 Feb 2026 08:23:43 +1100 (AEDT)",
            "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id E2E4E83D5D;\n\tMon, 16 Feb 2026 22:23:02 +0100 (CET)",
            "by phobos.denx.de (Postfix, from userid 109)\n id 3030883AA9; Mon, 16 Feb 2026 22:22:13 +0100 (CET)",
            "from pidgin.makrotopia.org (pidgin.makrotopia.org\n [IPv6:2a07:2ec0:3002::65])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id 64A1983CB5\n for <u-boot@lists.denx.de>; Mon, 16 Feb 2026 22:22:10 +0100 (CET)",
            "from local\n by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256)\n (Exim 4.99) (envelope-from <daniel@makrotopia.org>)\n id 1vs62T-000000002eB-2MMy; Mon, 16 Feb 2026 21:21:53 +0000"
        ],
        "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de",
        "X-Spam-Level": "",
        "X-Spam-Status": "No, score=-1.9 required=5.0 tests=BAYES_00,\n RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham\n autolearn_force=no version=3.4.2",
        "Date": "Mon, 16 Feb 2026 21:21:49 +0000",
        "From": "Daniel Golle <daniel@makrotopia.org>",
        "To": "Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>,\n Quentin Schulz <quentin.schulz@cherry.de>,\n Daniel Golle <daniel@makrotopia.org>,\n Kory Maincent <kory.maincent@bootlin.com>,\n Mattijs Korpershoek <mkorpershoek@kernel.org>,\n Martin Schwan <m.schwan@phytec.de>, Anshul Dalal <anshuld@ti.com>,\n Ilias Apalodimas <ilias.apalodimas@linaro.org>,\n Sughosh Ganu <sughosh.ganu@arm.com>, Aristo Chen <jj251510319013@gmail.com>,\n\t=?utf-8?b?54mbIOW/l+Wujw==?= <Zone.Niuzh@hotmail.com>,\n Marek Vasut <marek.vasut+renesas@mailbox.org>,\n Heinrich Schuchardt <xypron.glpk@gmx.de>,\n Wolfgang Wallner <wolfgang.wallner@at.abb.com>,\n Frank Wunderlich <frank-w@public-files.de>,\n David Lechner <dlechner@baylibre.com>,\n Osama Abdelkader <osama.abdelkader@gmail.com>,\n Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>,\n Michael Trimarchi <michael@amarulasolutions.com>,\n Miquel Raynal <miquel.raynal@bootlin.com>,\n Andrew Goodbody <andrew.goodbody@linaro.org>,\n Yegor Yefremov <yegorslists@googlemail.com>,\n Mike Looijmans <mike.looijmans@topic.nl>,\n Weijie Gao <weijie.gao@mediatek.com>,\n Alexander Stein <alexander.stein@ew.tq-group.com>,\n Neil Armstrong <neil.armstrong@linaro.org>,\n Mayuresh Chitale <mchitale@ventanamicro.com>,\n Paul HENRYS <paul.henrys_ext@softathome.com>, u-boot@lists.denx.de",
        "Cc": "John Crispin <john@phrozen.org>, Paul Spooren <mail@aparcar.org>",
        "Subject": "[RFC PATCH 04/20] boot: image-loader: add MTD backend",
        "Message-ID": "\n <b2ad68da753c0e0a87db8c6f928e1176a50efbe1.1771275704.git.daniel@makrotopia.org>",
        "References": "<cover.1771275704.git.daniel@makrotopia.org>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=utf-8",
        "Content-Disposition": "inline",
        "Content-Transfer-Encoding": "8bit",
        "In-Reply-To": "<cover.1771275704.git.daniel@makrotopia.org>",
        "X-Mailman-Approved-At": "Mon, 16 Feb 2026 22:22:55 +0100",
        "X-BeenThere": "u-boot@lists.denx.de",
        "X-Mailman-Version": "2.1.39",
        "Precedence": "list",
        "List-Id": "U-Boot discussion <u-boot.lists.denx.de>",
        "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>",
        "List-Archive": "<https://lists.denx.de/pipermail/u-boot/>",
        "List-Post": "<mailto:u-boot@lists.denx.de>",
        "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>",
        "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>",
        "Errors-To": "u-boot-bounces@lists.denx.de",
        "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>",
        "X-Virus-Scanned": "clamav-milter 0.103.8 at phobos.denx.de",
        "X-Virus-Status": "Clean"
    },
    "content": "Add an MTD storage backend for the image_loader framework.\n\nimage_loader_init_mtd() takes the name of an MTD partition, resolves\nit via get_mtd_device_nm(), and installs a .read() callback that\ntranslates byte-offset reads into mtd_read() calls.\n\nOn NAND devices, the read callback implements bad-block skipping:\nwhen a read straddles a bad block, the block is silently skipped and\nreading continues at the next good block. This matches the convention\nused by the mtd command and OpenWrt's mtd utilities.\n\nFor NOR devices, reads are passed straight through to mtd_read()\nwithout bad-block logic.\n\nThe .cleanup callback releases the MTD device reference (via\nput_mtd_device()) and frees the private context, ensuring safe\nteardown between consecutive boot attempts.\n\nGated by CONFIG_IMAGE_LOADER_MTD (depends on DM_MTD && IMAGE_LOADER).\n\nSigned-off-by: Daniel Golle <daniel@makrotopia.org>\n---\n boot/Kconfig            |   8 ++++\n boot/Makefile           |   1 +\n boot/image-loader-mtd.c | 103 ++++++++++++++++++++++++++++++++++++++++\n include/image-loader.h  |  14 ++++++\n 4 files changed, 126 insertions(+)\n create mode 100644 boot/image-loader-mtd.c",
    "diff": "diff --git a/boot/Kconfig b/boot/Kconfig\nindex e94b52288a3..23848a0f57e 100644\n--- a/boot/Kconfig\n+++ b/boot/Kconfig\n@@ -1195,6 +1195,14 @@ config IMAGE_LOADER_BLK\n \t  USB, etc.) using the image_loader framework. Partitions can\n \t  be identified by number or name.\n \n+config IMAGE_LOADER_MTD\n+\tbool \"MTD backend for image loader\"\n+\tdepends on IMAGE_LOADER && DM_MTD\n+\thelp\n+\t  Allows loading images from MTD partitions (SPI-NOR, SPI-NAND,\n+\t  parallel NAND, etc.) using the image_loader framework.\n+\t  NAND bad blocks are skipped transparently.\n+\n config DISTRO_DEFAULTS\n \tbool \"(deprecated) Script-based booting of Linux distributions\"\n \tselect CMDLINE\ndiff --git a/boot/Makefile b/boot/Makefile\nindex ac006bbaa82..1dde16db694 100644\n--- a/boot/Makefile\n+++ b/boot/Makefile\n@@ -75,6 +75,7 @@ obj-$(CONFIG_$(PHASE_)BOOTMETH_ANDROID) += bootmeth_android.o\n \n obj-$(CONFIG_IMAGE_LOADER) += image-loader.o\n obj-$(CONFIG_IMAGE_LOADER_BLK) += image-loader-blk.o\n+obj-$(CONFIG_IMAGE_LOADER_MTD) += image-loader-mtd.o\n \n obj-$(CONFIG_$(PHASE_)BOOTMETH_VBE_ABREC) += vbe_abrec.o vbe_common.o\n obj-$(CONFIG_$(PHASE_)BOOTMETH_VBE_ABREC_FW) += vbe_abrec_fw.o\ndiff --git a/boot/image-loader-mtd.c b/boot/image-loader-mtd.c\nnew file mode 100644\nindex 00000000000..0aa1163e2db\n--- /dev/null\n+++ b/boot/image-loader-mtd.c\n@@ -0,0 +1,103 @@\n+// SPDX-License-Identifier: GPL-2.0+\n+/*\n+ * MTD backend for image_loader\n+ *\n+ * Copyright (C) 2026 Daniel Golle <daniel@makrotopia.org>\n+ */\n+\n+#include <image-loader.h>\n+#include <malloc.h>\n+#include <mtd.h>\n+#include <log.h>\n+#include <linux/err.h>\n+\n+struct image_loader_mtd_priv {\n+\tstruct mtd_info *mtd;\n+};\n+\n+static int image_loader_mtd_read(struct image_loader *ldr, ulong src,\n+\t\t\t\t ulong size, void *dst)\n+{\n+\tstruct image_loader_mtd_priv *priv = ldr->priv;\n+\tstruct mtd_info *mtd = priv->mtd;\n+\tloff_t phys = src;\n+\tsize_t retlen;\n+\tint ret;\n+\n+\tif (mtd_can_have_bb(mtd)) {\n+\t\t/*\n+\t\t * NAND — walk from the beginning of the device, skipping\n+\t\t * bad blocks, to translate the logical byte offset @src\n+\t\t * into a physical byte offset. The actual read with\n+\t\t * further bad-block skipping is handled by\n+\t\t * mtd_read_skip_bad().\n+\t\t */\n+\t\tloff_t off = 0;\n+\t\tulong logical = 0;\n+\n+\t\twhile (logical < src) {\n+\t\t\tloff_t block_start = off & ~(loff_t)(mtd->erasesize - 1);\n+\t\t\tulong block_remain, chunk;\n+\n+\t\t\tif (off >= mtd->size) {\n+\t\t\t\tlog_err(\"image_loader_mtd: offset past end of device\\n\");\n+\t\t\t\treturn -EINVAL;\n+\t\t\t}\n+\n+\t\t\tif (mtd_block_isbad(mtd, block_start)) {\n+\t\t\t\toff = block_start + mtd->erasesize;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tblock_remain = mtd->erasesize - (ulong)(off - block_start);\n+\t\t\tchunk = min(block_remain, (ulong)(src - logical));\n+\t\t\toff += chunk;\n+\t\t\tlogical += chunk;\n+\t\t}\n+\n+\t\tphys = off;\n+\t}\n+\n+\tret = mtd_read_skip_bad(mtd, phys, size, &retlen, dst);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn (retlen == size) ? 0 : -EIO;\n+}\n+\n+static void image_loader_mtd_cleanup(struct image_loader *ldr)\n+{\n+\tstruct image_loader_mtd_priv *priv = ldr->priv;\n+\n+\tput_mtd_device(priv->mtd);\n+\tfree(priv);\n+}\n+\n+int image_loader_init_mtd(struct image_loader *ldr, const char *name)\n+{\n+\tstruct image_loader_mtd_priv *priv;\n+\tstruct mtd_info *mtd;\n+\n+\tmtd_probe_devices();\n+\n+\tmtd = get_mtd_device_nm(name);\n+\tif (IS_ERR_OR_NULL(mtd)) {\n+\t\tlog_err(\"image_loader_mtd: MTD device \\\"%s\\\" not found\\n\",\n+\t\t\tname);\n+\t\treturn -ENODEV;\n+\t}\n+\n+\tpriv = malloc(sizeof(*priv));\n+\tif (!priv) {\n+\t\tput_mtd_device(mtd);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tpriv->mtd = mtd;\n+\n+\tldr->read = image_loader_mtd_read;\n+\tldr->cleanup = image_loader_mtd_cleanup;\n+\tldr->priv = priv;\n+\n+\treturn 0;\n+}\ndiff --git a/include/image-loader.h b/include/image-loader.h\nindex 1a9048ba482..7ccf901d37d 100644\n--- a/include/image-loader.h\n+++ b/include/image-loader.h\n@@ -158,4 +158,18 @@ void *image_loader_map_to(struct image_loader *ldr, ulong img_offset,\n int image_loader_init_blk(struct image_loader *ldr, const char *ifname,\n \t\t\t  const char *dev_part_str);\n \n+/**\n+ * image_loader_init_mtd() - Initialise loader for an MTD partition\n+ *\n+ * Resolves the MTD device by @name via get_mtd_device_nm(), then\n+ * installs a .read() callback that translates byte-offset reads into\n+ * mtd_read() calls. On NAND devices, bad blocks are transparently\n+ * skipped.\n+ *\n+ * @ldr:\tThe image loader to initialise\n+ * @name:\tMTD device/partition name\n+ * Return: 0 on success, negative errno on failure\n+ */\n+int image_loader_init_mtd(struct image_loader *ldr, const char *name);\n+\n #endif /* __IMAGE_LOADER_H */\n",
    "prefixes": [
        "RFC",
        "04/20"
    ]
}