get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 1820095,
    "url": "http://patchwork.ozlabs.org/api/patches/1820095/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-mtd/patch/431de44b006c4c90f54cd3c7378b395369cbea30.1691717480.git.daniel@makrotopia.org/",
    "project": {
        "id": 3,
        "url": "http://patchwork.ozlabs.org/api/projects/3/?format=api",
        "name": "Linux MTD development",
        "link_name": "linux-mtd",
        "list_id": "linux-mtd.lists.infradead.org",
        "list_email": "linux-mtd@lists.infradead.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<431de44b006c4c90f54cd3c7378b395369cbea30.1691717480.git.daniel@makrotopia.org>",
    "list_archive_url": null,
    "date": "2023-08-11T01:38:34",
    "name": "[v4,8/8] mtd: ubi: provide NVMEM layer over UBI volumes",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": false,
    "hash": "b06166e3396a66507d965ba27bac65b1419cc3f9",
    "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/linux-mtd/patch/431de44b006c4c90f54cd3c7378b395369cbea30.1691717480.git.daniel@makrotopia.org/mbox/",
    "series": [
        {
            "id": 368347,
            "url": "http://patchwork.ozlabs.org/api/series/368347/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/linux-mtd/list/?series=368347",
            "date": "2023-08-11T01:36:37",
            "name": "mtd: ubi: allow UBI volumes to provide NVMEM",
            "version": 4,
            "mbox": "http://patchwork.ozlabs.org/series/368347/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/1820095/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/1820095/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "\n <linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n spf=none (no SPF record) smtp.mailfrom=lists.infradead.org\n (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org;\n envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org;\n receiver=<UNKNOWN>)",
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n secure) header.d=lists.infradead.org header.i=@lists.infradead.org\n header.a=rsa-sha256 header.s=bombadil.20210309 header.b=gBU6eb1n;\n\tdkim-atps=neutral"
        ],
        "Received": [
            "from bombadil.infradead.org (bombadil.infradead.org\n [IPv6:2607:7c80:54:3::133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4RMRL15s48z1yf2\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 11 Aug 2023 11:39:37 +1000 (AEST)",
            "from localhost ([::1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux))\n\tid 1qUH77-0095YF-2D;\n\tFri, 11 Aug 2023 01:38:53 +0000",
            "from pidgin.makrotopia.org ([185.142.180.65])\n\tby bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux))\n\tid 1qUH74-0095Wo-2j\n\tfor linux-mtd@lists.infradead.org;\n\tFri, 11 Aug 2023 01:38:52 +0000",
            "from local\n\tby pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256)\n\t (Exim 4.96)\n\t(envelope-from <daniel@makrotopia.org>)\n\tid 1qUH6v-00056Z-2f;\n\tFri, 11 Aug 2023 01:38:42 +0000"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=lists.infradead.org; s=bombadil.20210309; h=Sender:\n\tContent-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:\n\tList-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References:\n\tMessage-ID:Subject:To:From:Date:Reply-To:Cc:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tList-Owner; bh=x41/2nxEo2hRNxGFbgvOn5rJn1JebGuqqC5G/0scRTc=; b=gBU6eb1nE1DpgW\n\tZGztyx7HJ+pzR2Hx3BQsEIw5Rjhl3FMj6Grw2PYZXcTcC5aBjT9Av02v05PmEoITdoemj76uXjiVa\n\tCuKIehbDwP9MeLirdordPbmq9gGheOvFaj6aA5xAeVvW2LYkRS/U2X1LrtJZfzDcItA5B8UT/Am2W\n\trwMX2j9dKt7dVBBabrubGv9Ca0Bhxcob9Z94HhknvUkNtArJnBfWSE4Bi6q0LUCse9NAXPxpUHObC\n\t2COl5PcYqVm6ICaktMdVMSaj9+dDzXZvE6+aI5fnmecsaE4E46j1xH38Km357HWs7hAVjGLtkOFEA\n\tPDMR+8Qy1kJiJ2m/VPLA==;",
        "Date": "Fri, 11 Aug 2023 02:38:34 +0100",
        "From": "Daniel Golle <daniel@makrotopia.org>",
        "To": "Randy Dunlap <rdunlap@infradead.org>,\n\tMiquel Raynal <miquel.raynal@bootlin.com>,\n\tRichard Weinberger <richard@nod.at>,\n\tVignesh Raghavendra <vigneshr@ti.com>,\n\tRob Herring <robh+dt@kernel.org>,\n\tKrzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,\n\tConor Dooley <conor+dt@kernel.org>,\n\tDaniel Golle <daniel@makrotopia.org>, linux-mtd@lists.infradead.org,\n\tdevicetree@vger.kernel.org, linux-kernel@vger.kernel.org",
        "Subject": "[PATCH v4 8/8] mtd: ubi: provide NVMEM layer over UBI volumes",
        "Message-ID": "\n <431de44b006c4c90f54cd3c7378b395369cbea30.1691717480.git.daniel@makrotopia.org>",
        "References": "<cover.1691717480.git.daniel@makrotopia.org>",
        "MIME-Version": "1.0",
        "Content-Disposition": "inline",
        "In-Reply-To": "<cover.1691717480.git.daniel@makrotopia.org>",
        "X-CRM114-Version": "20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ",
        "X-CRM114-CacheID": "sfid-20230810_183850_885489_1B8902A3 ",
        "X-CRM114-Status": "GOOD (  26.40  )",
        "X-Spam-Score": "0.0 (/)",
        "X-Spam-Report": "Spam detection software,\n running on the system \"bombadil.infradead.org\",\n has NOT identified this incoming email as spam.  The original\n message has been attached to this so you can view it or label\n similar future email.  If you have any questions, see\n the administrator of that system for details.\n Content preview:  In an ideal world we would like UBI to be used where ever\n   possible on a NAND chip. And with UBI support in ARM Trusted Firmware and\n   U-Boot it is possible to achieve an (almost-)all-UBI flash layout. H [...]    \n Content analysis details:   (0.0 points, 5.0 required)\n  pts rule name              description\n ---- ----------------------\n --------------------------------------------------\n -0.0 SPF_PASS               SPF: sender matches SPF record\n  0.0 SPF_HELO_NONE          SPF: HELO does not publish an SPF Record",
        "X-BeenThere": "linux-mtd@lists.infradead.org",
        "X-Mailman-Version": "2.1.34",
        "Precedence": "list",
        "List-Id": "Linux MTD discussion mailing list <linux-mtd.lists.infradead.org>",
        "List-Unsubscribe": "<http://lists.infradead.org/mailman/options/linux-mtd>,\n <mailto:linux-mtd-request@lists.infradead.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.infradead.org/pipermail/linux-mtd/>",
        "List-Post": "<mailto:linux-mtd@lists.infradead.org>",
        "List-Help": "<mailto:linux-mtd-request@lists.infradead.org?subject=help>",
        "List-Subscribe": "<http://lists.infradead.org/mailman/listinfo/linux-mtd>,\n <mailto:linux-mtd-request@lists.infradead.org?subject=subscribe>",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Sender": "\"linux-mtd\" <linux-mtd-bounces@lists.infradead.org>",
        "Errors-To": "linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org"
    },
    "content": "In an ideal world we would like UBI to be used where ever possible on a\nNAND chip. And with UBI support in ARM Trusted Firmware and U-Boot it\nis possible to achieve an (almost-)all-UBI flash layout. Hence the need\nfor a way to also use UBI volumes to store board-level constants, such\nas MAC addresses and calibration data of wireless interfaces.\n\nAdd UBI volume NVMEM driver module exposing UBI volumes as NVMEM\nproviders. Allow UBI devices to have a \"volumes\" firmware subnode with\nvolumes which may be compatible with \"nvmem-cells\".\nAccess to UBI volumes via the NVMEM interface at this point is\nread-only, and it is slow, opening and closing the UBI volume for each\naccess due to limitations of the NVMEM provider API.\n\nSigned-off-by: Daniel Golle <daniel@makrotopia.org>\n---\n drivers/mtd/ubi/Kconfig  |  12 +++\n drivers/mtd/ubi/Makefile |   1 +\n drivers/mtd/ubi/nvmem.c  | 189 +++++++++++++++++++++++++++++++++++++++\n 3 files changed, 202 insertions(+)\n create mode 100644 drivers/mtd/ubi/nvmem.c",
    "diff": "diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig\nindex 2ed77b7b3fcb5..45d939bbfa853 100644\n--- a/drivers/mtd/ubi/Kconfig\n+++ b/drivers/mtd/ubi/Kconfig\n@@ -104,4 +104,16 @@ config MTD_UBI_BLOCK\n \n \t   If in doubt, say \"N\".\n \n+config MTD_UBI_NVMEM\n+\ttristate \"UBI virtual NVMEM\"\n+\tdefault n\n+\tdepends on NVMEM\n+\thelp\n+\t   This option enabled an additional driver exposing UBI volumes as NVMEM\n+\t   providers, intended for platforms where UBI is part of the firmware\n+\t   specification and used to store also e.g. MAC addresses or board-\n+\t   specific Wi-Fi calibration data.\n+\n+\t   If in doubt, say \"N\".\n+\n endif # MTD_UBI\ndiff --git a/drivers/mtd/ubi/Makefile b/drivers/mtd/ubi/Makefile\nindex 543673605ca72..4b51aaf00d1a2 100644\n--- a/drivers/mtd/ubi/Makefile\n+++ b/drivers/mtd/ubi/Makefile\n@@ -7,3 +7,4 @@ ubi-$(CONFIG_MTD_UBI_FASTMAP) += fastmap.o\n ubi-$(CONFIG_MTD_UBI_BLOCK) += block.o\n \n obj-$(CONFIG_MTD_UBI_GLUEBI) += gluebi.o\n+obj-$(CONFIG_MTD_UBI_NVMEM) += nvmem.o\ndiff --git a/drivers/mtd/ubi/nvmem.c b/drivers/mtd/ubi/nvmem.c\nnew file mode 100644\nindex 0000000000000..dd7cc6afb8d00\n--- /dev/null\n+++ b/drivers/mtd/ubi/nvmem.c\n@@ -0,0 +1,189 @@\n+// SPDX-License-Identifier: GPL-2.0-or-later\n+/*\n+ * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>\n+ */\n+\n+/* UBI NVMEM provider */\n+#include \"ubi.h\"\n+#include <linux/nvmem-provider.h>\n+\n+/* List of all NVMEM devices */\n+static LIST_HEAD(nvmem_devices);\n+static DEFINE_MUTEX(devices_mutex);\n+\n+struct ubi_nvmem {\n+\tstruct nvmem_device *nvmem;\n+\tint ubi_num;\n+\tint vol_id;\n+\tint usable_leb_size;\n+\tstruct list_head list;\n+};\n+\n+static int ubi_nvmem_reg_read(void *priv, unsigned int from,\n+\t\t\t      void *val, size_t bytes)\n+{\n+\tstruct ubi_nvmem *unv = priv;\n+\tstruct ubi_volume_desc *desc;\n+\tint err = 0, lnum, offs, bytes_left;\n+\tsize_t to_read;\n+\n+\tdesc = ubi_open_volume(unv->ubi_num, unv->vol_id, UBI_READONLY);\n+\tif (IS_ERR(desc))\n+\t\treturn PTR_ERR(desc);\n+\n+\tlnum = div_u64_rem(from, unv->usable_leb_size, &offs);\n+\tbytes_left = bytes;\n+\twhile (bytes_left) {\n+\t\tto_read = unv->usable_leb_size - offs;\n+\n+\t\tif (to_read > bytes_left)\n+\t\t\tto_read = bytes_left;\n+\n+\t\terr = ubi_read(desc, lnum, val, offs, to_read);\n+\t\tif (err)\n+\t\t\tbreak;\n+\n+\t\tlnum += 1;\n+\t\toffs = 0;\n+\t\tbytes_left -= to_read;\n+\t\tval += to_read;\n+\t}\n+\tubi_close_volume(desc);\n+\n+\tif (err)\n+\t\treturn err;\n+\n+\treturn bytes_left == 0 ? 0 : -EIO;\n+}\n+\n+static int ubi_nvmem_add(struct ubi_volume_info *vi)\n+{\n+\tstruct nvmem_config config = {};\n+\tstruct ubi_nvmem *unv;\n+\tint ret;\n+\n+\tif (!device_is_compatible(vi->dev, \"nvmem-cells\"))\n+\t\treturn 0;\n+\n+\tunv = kzalloc(sizeof(struct ubi_nvmem), GFP_KERNEL);\n+\tif (!unv)\n+\t\treturn -ENOMEM;\n+\n+\tconfig.id = NVMEM_DEVID_NONE;\n+\tconfig.dev = vi->dev;\n+\tconfig.name = dev_name(vi->dev);\n+\tconfig.owner = THIS_MODULE;\n+\tconfig.priv = unv;\n+\tconfig.reg_read = ubi_nvmem_reg_read;\n+\tconfig.size = vi->usable_leb_size * vi->size;\n+\tconfig.word_size = 1;\n+\tconfig.stride = 1;\n+\tconfig.read_only = true;\n+\tconfig.root_only = true;\n+\tconfig.ignore_wp = true;\n+\tconfig.of_node = dev_of_node(vi->dev);\n+\n+\tif (!config.of_node)\n+\t\tconfig.no_of_node = true;\n+\n+\tunv->ubi_num = vi->ubi_num;\n+\tunv->vol_id = vi->vol_id;\n+\tunv->usable_leb_size = vi->usable_leb_size;\n+\tunv->nvmem = nvmem_register(&config);\n+\tif (IS_ERR(unv->nvmem)) {\n+\t\t/* Just ignore if there is no NVMEM support in the kernel */\n+\t\tif (PTR_ERR(unv->nvmem) == -EOPNOTSUPP)\n+\t\t\tret = 0;\n+\t\telse\n+\t\t\tret = dev_err_probe(vi->dev, PTR_ERR(unv->nvmem),\n+\t\t\t\t\t    \"Failed to register NVMEM device\\n\");\n+\n+\t\tkfree(unv);\n+\t\treturn ret;\n+\t}\n+\n+\tmutex_lock(&devices_mutex);\n+\tlist_add_tail(&unv->list, &nvmem_devices);\n+\tmutex_unlock(&devices_mutex);\n+\n+\treturn 0;\n+}\n+\n+static void ubi_nvmem_remove(struct ubi_volume_info *vi)\n+{\n+\tstruct ubi_nvmem *unv_c, *unv = NULL;\n+\n+\tmutex_lock(&devices_mutex);\n+\tlist_for_each_entry(unv_c, &nvmem_devices, list)\n+\t\tif (unv_c->ubi_num == vi->ubi_num && unv_c->vol_id == vi->vol_id) {\n+\t\t\tunv = unv_c;\n+\t\t\tbreak;\n+\t\t}\n+\n+\tif (!unv) {\n+\t\tmutex_unlock(&devices_mutex);\n+\t\treturn;\n+\t}\n+\n+\tlist_del(&unv->list);\n+\tmutex_unlock(&devices_mutex);\n+\tnvmem_unregister(unv->nvmem);\n+\tkfree(unv);\n+}\n+\n+/**\n+ * nvmem_notify - UBI notification handler.\n+ * @nb: registered notifier block\n+ * @l: notification type\n+ * @ns_ptr: pointer to the &struct ubi_notification object\n+ */\n+static int nvmem_notify(struct notifier_block *nb, unsigned long l,\n+\t\t\t void *ns_ptr)\n+{\n+\tstruct ubi_notification *nt = ns_ptr;\n+\n+\tswitch (l) {\n+\tcase UBI_VOLUME_RESIZED:\n+\t\tubi_nvmem_remove(&nt->vi);\n+\t\tfallthrough;\n+\tcase UBI_VOLUME_ADDED:\n+\t\tubi_nvmem_add(&nt->vi);\n+\t\tbreak;\n+\tcase UBI_VOLUME_SHUTDOWN:\n+\t\tubi_nvmem_remove(&nt->vi);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n+\t}\n+\treturn NOTIFY_OK;\n+}\n+\n+static struct notifier_block nvmem_notifier = {\n+\t.notifier_call = nvmem_notify,\n+};\n+\n+static int __init ubi_nvmem_init(void)\n+{\n+\treturn ubi_register_volume_notifier(&nvmem_notifier, 0);\n+}\n+\n+static void __exit ubi_nvmem_exit(void)\n+{\n+\tstruct ubi_nvmem *unv, *tmp;\n+\n+\tmutex_lock(&devices_mutex);\n+\tlist_for_each_entry_safe(unv, tmp, &nvmem_devices, list) {\n+\t\tnvmem_unregister(unv->nvmem);\n+\t\tlist_del(&unv->list);\n+\t\tkfree(unv);\n+\t}\n+\tmutex_unlock(&devices_mutex);\n+\n+\tubi_unregister_volume_notifier(&nvmem_notifier);\n+}\n+\n+module_init(ubi_nvmem_init);\n+module_exit(ubi_nvmem_exit);\n+MODULE_DESCRIPTION(\"NVMEM layer over UBI volumes\");\n+MODULE_AUTHOR(\"Daniel Golle\");\n+MODULE_LICENSE(\"GPL\");\n",
    "prefixes": [
        "v4",
        "8/8"
    ]
}