From fa0f13076453854f23487205be1df92b3eec34a6 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Wed, 7 May 2025 03:58:17 +0100 Subject: [PATCH] generic: 6.12: update block NVMEM driver Update block NVMEM driver based on backported OF partition support. Note the different MMC card DT binding compared to the previous downstream solution: Instead of having a 'partitions' subnode inside a 'block' node, the 'partitions' node now resides directly under the node representing the card. In order to make references to the 'boot0' or 'boot1' hw partitions you will have to define 'partitions-boot0' or 'partitions-boot1', and move the NVMEM layout into a partition (you may, of course, use 'fixed-partitions' for that, and cover the whole device, if needed). See also https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/mmc/mmc-card.yaml?h=v6.13 Signed-off-by: Daniel Golle --- ...lock-allow-setting-partition-of_node.patch | 123 +++++ ...k-add-basic-bindings-for-block-devic.patch | 120 ----- ...-of-assign-Device-Tree-node-to-parti.patch | 25 + ...451-block-partitions-populate-fwnode.patch | 135 ----- ...artitions-efi-apply-Linux-code-style.patch | 498 ++++++++++++++++++ ...ck-add-new-genhd-flag-GENHD_FL_NVMEM.patch | 56 -- ...llow-assigning-partition-Device-Tree.patch | 75 +++ ...block-add-support-for-notifications.patch} | 80 ++- ...ck-add-new-genhd-flag-GENHD_FL_NVMEM.patch | 29 + ...-mmc-mmc-card-add-block-device-nodes.patch | 74 --- .../456-mmc-core-set-card-fwnode_handle.patch | 23 - ...vmem-implement-block-NVMEM-provider.patch} | 54 +- ...=> 457-mmc-block-set-GENHD_FL_NVMEM.patch} | 6 +- ...mmc-block-set-fwnode-of-disk-devices.patch | 27 - 14 files changed, 810 insertions(+), 515 deletions(-) create mode 100644 target/linux/generic/pending-6.12/450-block-allow-setting-partition-of_node.patch delete mode 100644 target/linux/generic/pending-6.12/450-dt-bindings-block-add-basic-bindings-for-block-devic.patch create mode 100644 target/linux/generic/pending-6.12/451-block-partitions-of-assign-Device-Tree-node-to-parti.patch delete mode 100644 target/linux/generic/pending-6.12/451-block-partitions-populate-fwnode.patch create mode 100644 target/linux/generic/pending-6.12/452-partitions-efi-apply-Linux-code-style.patch delete mode 100644 target/linux/generic/pending-6.12/453-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch create mode 100644 target/linux/generic/pending-6.12/453-partitions-efi-allow-assigning-partition-Device-Tree.patch rename target/linux/generic/pending-6.12/{452-block-add-support-for-notifications.patch => 454-block-add-support-for-notifications.patch} (60%) create mode 100644 target/linux/generic/pending-6.12/455-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch delete mode 100644 target/linux/generic/pending-6.12/455-dt-bindings-mmc-mmc-card-add-block-device-nodes.patch delete mode 100644 target/linux/generic/pending-6.12/456-mmc-core-set-card-fwnode_handle.patch rename target/linux/generic/pending-6.12/{454-nvmem-implement-block-NVMEM-provider.patch => 456-nvmem-implement-block-NVMEM-provider.patch} (86%) rename target/linux/generic/pending-6.12/{458-mmc-block-set-GENHD_FL_NVMEM.patch => 457-mmc-block-set-GENHD_FL_NVMEM.patch} (79%) delete mode 100644 target/linux/generic/pending-6.12/457-mmc-block-set-fwnode-of-disk-devices.patch diff --git a/target/linux/generic/pending-6.12/450-block-allow-setting-partition-of_node.patch b/target/linux/generic/pending-6.12/450-block-allow-setting-partition-of_node.patch new file mode 100644 index 00000000000..a3c8abc1d9d --- /dev/null +++ b/target/linux/generic/pending-6.12/450-block-allow-setting-partition-of_node.patch @@ -0,0 +1,123 @@ +From decc6959a423c8617e87244fd269129fc4e7d0e6 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Mon, 7 Oct 2024 23:36:14 +0100 +Subject: [PATCH 1/8] block: allow setting partition of_node + +Allow partition parsers to set the Device Tree node for a partition by +introducing of_put_partition() and extending struct parsed_partitions +accordingly. + +As the partition information is preallocated independently of the actual +number of partitions the additional pointer takes about 2 kiB of allocated +memory which is worth avoiding in case CONFIG_OF is not set. This is +achieved by only adding the corresponding field to the struct in case +CONFIG_OF is set using #ifdef'ery. + +Signed-off-by: Daniel Golle +--- + block/partitions/check.h | 16 +++++++++++++++- + block/partitions/core.c | 14 +++++++++++--- + 2 files changed, 26 insertions(+), 4 deletions(-) + +--- a/block/partitions/check.h ++++ b/block/partitions/check.h +@@ -1,6 +1,7 @@ + /* SPDX-License-Identifier: GPL-2.0 */ + #include + #include ++#include + #include "../blk.h" + + /* +@@ -16,6 +17,9 @@ struct parsed_partitions { + int flags; + bool has_info; + struct partition_meta_info info; ++#ifdef CONFIG_OF ++ struct device_node *np; ++#endif + } *parts; + int next; + int limit; +@@ -34,18 +38,28 @@ static inline void put_dev_sector(Sector + } + + static inline void +-put_partition(struct parsed_partitions *p, int n, sector_t from, sector_t size) ++of_put_partition(struct parsed_partitions *p, int n, sector_t from, sector_t size, ++ struct device_node *np) + { + if (n < p->limit) { + char tmp[1 + BDEVNAME_SIZE + 10 + 1]; + + p->parts[n].from = from; + p->parts[n].size = size; ++#ifdef CONFIG_OF ++ p->parts[n].np = np; ++#endif + snprintf(tmp, sizeof(tmp), " %s%d", p->name, n); + strlcat(p->pp_buf, tmp, PAGE_SIZE); + } + } + ++static inline void ++put_partition(struct parsed_partitions *p, int n, sector_t from, sector_t size) ++{ ++ of_put_partition(p, n, from, size, NULL); ++} ++ + /* detection routines go here in alphabetical order: */ + int adfspart_check_ADFS(struct parsed_partitions *state); + int adfspart_check_CUMANA(struct parsed_partitions *state); +--- a/block/partitions/core.c ++++ b/block/partitions/core.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include "check.h" + +@@ -290,7 +291,8 @@ static const DEVICE_ATTR(whole_disk, 044 + */ + static struct block_device *add_partition(struct gendisk *disk, int partno, + sector_t start, sector_t len, int flags, +- struct partition_meta_info *info) ++ struct partition_meta_info *info, ++ struct device_node *np) + { + dev_t devt = MKDEV(0, 0); + struct device *ddev = disk_to_dev(disk); +@@ -339,6 +341,7 @@ static struct block_device *add_partitio + pdev->class = &block_class; + pdev->type = &part_type; + pdev->parent = ddev; ++ device_set_node(pdev, of_fwnode_handle(np)); + + /* in consecutive minor range? */ + if (bdev_partno(bdev) < disk->minors) { +@@ -445,7 +448,7 @@ int bdev_add_partition(struct gendisk *d + } + + part = add_partition(disk, partno, start, length, +- ADDPART_FLAG_NONE, NULL); ++ ADDPART_FLAG_NONE, NULL, NULL); + ret = PTR_ERR_OR_ZERO(part); + out: + mutex_unlock(&disk->open_mutex); +@@ -559,8 +562,13 @@ static bool blk_add_partition(struct gen + size = get_capacity(disk) - from; + } + ++#ifdef CONFIG_OF + part = add_partition(disk, p, from, size, state->parts[p].flags, +- &state->parts[p].info); ++ &state->parts[p].info, state->parts[p].np); ++#else ++ part = add_partition(disk, p, from, size, state->parts[p].flags, ++ &state->parts[p].info, NULL); ++#endif + if (IS_ERR(part)) { + if (PTR_ERR(part) != -ENXIO) { + printk(KERN_ERR " %s: p%d could not be added: %pe\n", diff --git a/target/linux/generic/pending-6.12/450-dt-bindings-block-add-basic-bindings-for-block-devic.patch b/target/linux/generic/pending-6.12/450-dt-bindings-block-add-basic-bindings-for-block-devic.patch deleted file mode 100644 index 9089ce6440e..00000000000 --- a/target/linux/generic/pending-6.12/450-dt-bindings-block-add-basic-bindings-for-block-devic.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 3245921a87154bdfbe7a55d743ea62dd559a8fb0 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 30 May 2024 03:13:09 +0100 -Subject: [PATCH 1/9] dt-bindings: block: add basic bindings for block devices - -Add bindings for block devices which are used to allow referencing -nvmem bits on them. - -Signed-off-by: Daniel Golle ---- - .../bindings/block/block-device.yaml | 22 ++++++++ - .../devicetree/bindings/block/partition.yaml | 51 +++++++++++++++++++ - .../devicetree/bindings/block/partitions.yaml | 20 ++++++++ - 3 files changed, 93 insertions(+) - create mode 100644 Documentation/devicetree/bindings/block/block-device.yaml - create mode 100644 Documentation/devicetree/bindings/block/partition.yaml - create mode 100644 Documentation/devicetree/bindings/block/partitions.yaml - ---- /dev/null -+++ b/Documentation/devicetree/bindings/block/block-device.yaml -@@ -0,0 +1,22 @@ -+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/block/block-device.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: block storage device -+ -+description: | -+ This binding is generic and describes a block-oriented storage device. -+ -+maintainers: -+ - Daniel Golle -+ -+properties: -+ partitions: -+ $ref: /schemas/block/partitions.yaml -+ -+ nvmem-layout: -+ $ref: /schemas/nvmem/layouts/nvmem-layout.yaml# -+ -+unevaluatedProperties: false ---- /dev/null -+++ b/Documentation/devicetree/bindings/block/partition.yaml -@@ -0,0 +1,51 @@ -+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/block/partition.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Partition on a block device -+ -+description: | -+ This binding describes a partition on a block device. -+ Partitions may be matched by a combination of partition number, name, -+ and UUID. -+ -+maintainers: -+ - Daniel Golle -+ -+properties: -+ $nodename: -+ pattern: '^block-partition-.+$' -+ -+ partnum: -+ $ref: /schemas/types.yaml#/definitions/uint32 -+ description: -+ Matches partition by number if present. -+ -+ partname: -+ $ref: /schemas/types.yaml#/definitions/string -+ description: -+ Matches partition by PARTNAME if present. -+ -+ partuuid: -+ $ref: /schemas/types.yaml#/definitions/string -+ description: -+ Matches partition by PARTUUID if present. -+ -+ nvmem-layout: -+ $ref: /schemas/nvmem/layouts/nvmem-layout.yaml# -+ description: -+ This container may reference an NVMEM layout parser. -+ -+anyOf: -+ - required: -+ - partnum -+ -+ - required: -+ - partname -+ -+ - required: -+ - partuuid -+ -+unevaluatedProperties: false ---- /dev/null -+++ b/Documentation/devicetree/bindings/block/partitions.yaml -@@ -0,0 +1,20 @@ -+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/block/partitions.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Partitions on block devices -+ -+description: | -+ This binding is generic and describes the content of the partitions container -+ node. -+ -+maintainers: -+ - Daniel Golle -+ -+patternProperties: -+ "^block-partition-.+$": -+ $ref: partition.yaml -+ -+unevaluatedProperties: false diff --git a/target/linux/generic/pending-6.12/451-block-partitions-of-assign-Device-Tree-node-to-parti.patch b/target/linux/generic/pending-6.12/451-block-partitions-of-assign-Device-Tree-node-to-parti.patch new file mode 100644 index 00000000000..f9e41d03c85 --- /dev/null +++ b/target/linux/generic/pending-6.12/451-block-partitions-of-assign-Device-Tree-node-to-parti.patch @@ -0,0 +1,25 @@ +From 5d265996597a6b0d654bbeda1bc3bae197061de7 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Mon, 7 Oct 2024 23:43:32 +0100 +Subject: [PATCH 2/8] block: partitions: of: assign Device Tree node to + partition + +Assign partition of_node so other drivers are able to identify a +partition by its Device Tree node. + +Signed-off-by: Daniel Golle +--- + block/partitions/of.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/block/partitions/of.c ++++ b/block/partitions/of.c +@@ -48,7 +48,7 @@ static void add_of_partition(struct pars + u64 offset = of_read_number(reg, a_cells) / SECTOR_SIZE; + u64 size = of_read_number(reg + a_cells, s_cells) / SECTOR_SIZE; + +- put_partition(state, slot, offset, size); ++ of_put_partition(state, slot, offset, size, np); + + if (of_property_read_bool(np, "read-only")) + state->parts[slot].flags |= ADDPART_FLAG_READONLY; diff --git a/target/linux/generic/pending-6.12/451-block-partitions-populate-fwnode.patch b/target/linux/generic/pending-6.12/451-block-partitions-populate-fwnode.patch deleted file mode 100644 index 98c5de08445..00000000000 --- a/target/linux/generic/pending-6.12/451-block-partitions-populate-fwnode.patch +++ /dev/null @@ -1,135 +0,0 @@ -From patchwork Tue Jul 30 19:25:59 2024 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Daniel Golle -X-Patchwork-Id: 13747816 -Date: Tue, 30 Jul 2024 20:25:59 +0100 -From: Daniel Golle -To: Rob Herring , Krzysztof Kozlowski , - Conor Dooley , Jens Axboe , - Daniel Golle , Christian Brauner , - Al Viro , Li Lingfeng , - Ming Lei , Christian Heusel , - =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= , - Felix Fietkau , John Crispin , - Chad Monroe , Yangyu Chen , - Tianling Shen , Chuanhong Guo , - Chen Minqiang , devicetree@vger.kernel.org, - linux-kernel@vger.kernel.org, linux-block@vger.kernel.org -Subject: [PATCH v5 2/4] block: partitions: populate fwnode -Message-ID: - <3051ac090ad3b3e2f5adb6b67c923261ead729a5.1722365899.git.daniel@makrotopia.org> -References: -Precedence: bulk -X-Mailing-List: linux-block@vger.kernel.org -List-Id: -List-Subscribe: -List-Unsubscribe: -MIME-Version: 1.0 -Content-Disposition: inline -In-Reply-To: - -Assign matching firmware nodes to block partitions in order to allow -them to be referenced e.g. as NVMEM providers. - -Signed-off-by: Daniel Golle ---- - block/partitions/core.c | 72 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 72 insertions(+) - ---- a/block/partitions/core.c -+++ b/block/partitions/core.c -@@ -10,6 +10,8 @@ - #include - #include - #include -+#include -+ - #include "check.h" - - static int (*const check_part[])(struct parsed_partitions *) = { -@@ -284,6 +286,74 @@ static ssize_t whole_disk_show(struct de - } - static const DEVICE_ATTR(whole_disk, 0444, whole_disk_show, NULL); - -+static bool part_meta_match(const char *attr, const char *member, size_t length) -+{ -+ /* check if length of attr exceeds specified maximum length */ -+ if (strnlen(attr, length) == length) -+ return false; -+ -+ /* return true if strings match */ -+ return !strncmp(attr, member, length); -+} -+ -+static struct fwnode_handle *find_partition_fwnode(struct block_device *bdev) -+{ -+ struct fwnode_handle *fw_parts, *fw_part; -+ struct device *ddev = disk_to_dev(bdev->bd_disk); -+ const char *partname, *uuid; -+ u32 partno; -+ bool got_uuid, got_partname, got_partno; -+ -+ fw_parts = device_get_named_child_node(ddev, "partitions"); -+ if (!fw_parts) -+ return NULL; -+ -+ fwnode_for_each_child_node(fw_parts, fw_part) { -+ got_uuid = false; -+ got_partname = false; -+ got_partno = false; -+ /* -+ * In case 'uuid' is defined in the partitions firmware node -+ * require partition meta info being present and the specified -+ * uuid to match. -+ */ -+ got_uuid = !fwnode_property_read_string(fw_part, "uuid", &uuid); -+ if (got_uuid && (!bdev->bd_meta_info || -+ !part_meta_match(uuid, bdev->bd_meta_info->uuid, -+ PARTITION_META_INFO_UUIDLTH))) -+ continue; -+ -+ /* -+ * In case 'partname' is defined in the partitions firmware node -+ * require partition meta info being present and the specified -+ * volname to match. -+ */ -+ got_partname = !fwnode_property_read_string(fw_part, "partname", -+ &partname); -+ if (got_partname && (!bdev->bd_meta_info || -+ !part_meta_match(partname, -+ bdev->bd_meta_info->volname, -+ PARTITION_META_INFO_VOLNAMELTH))) -+ continue; -+ -+ /* -+ * In case 'partno' is defined in the partitions firmware node -+ * the specified partno needs to match. -+ */ -+ got_partno = !fwnode_property_read_u32(fw_part, "partno", &partno); -+ if (got_partno && bdev_partno(bdev) != partno) -+ continue; -+ -+ /* Skip if no matching criteria is present in firmware node */ -+ if (!got_uuid && !got_partname && !got_partno) -+ continue; -+ -+ return fw_part; -+ } -+ -+ return NULL; -+} -+ - /* - * Must be called either with open_mutex held, before a disk can be opened or - * after all disk users are gone. -@@ -358,6 +428,8 @@ static struct block_device *add_partitio - goto out_put; - } - -+ device_set_node(pdev, find_partition_fwnode(bdev)); -+ - /* delay uevent until 'holders' subdir is created */ - dev_set_uevent_suppress(pdev, 1); - err = device_add(pdev); diff --git a/target/linux/generic/pending-6.12/452-partitions-efi-apply-Linux-code-style.patch b/target/linux/generic/pending-6.12/452-partitions-efi-apply-Linux-code-style.patch new file mode 100644 index 00000000000..6e996ca3f70 --- /dev/null +++ b/target/linux/generic/pending-6.12/452-partitions-efi-apply-Linux-code-style.patch @@ -0,0 +1,498 @@ +From d4e82837c8b86ff2c21fa923271908988bc72faa Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Mon, 7 Oct 2024 23:22:53 +0100 +Subject: [PATCH 3/8] partitions/efi: apply Linux code style + +Fix (mostly white space related) coding style issues in +block/partitions/efi.c by use of clang-format. + +Signed-off-by: Daniel Golle +--- + block/partitions/efi.c | 235 +++++++++++++++++++++-------------------- + 1 file changed, 121 insertions(+), 114 deletions(-) + +--- a/block/partitions/efi.c ++++ b/block/partitions/efi.c +@@ -95,15 +95,13 @@ + * the partition tables happens after init too. + */ + static int force_gpt; +-static int __init +-force_gpt_fn(char *str) ++static int __init force_gpt_fn(char *str) + { + force_gpt = 1; + return 1; + } + __setup("gpt", force_gpt_fn); + +- + /** + * efi_crc32() - EFI version of crc32 function + * @buf: buffer to calculate crc32 of +@@ -116,8 +114,7 @@ __setup("gpt", force_gpt_fn); + * Note, the EFI Specification, v1.02, has a reference to + * Dr. Dobbs Journal, May 1994 (actually it's in May 1992). + */ +-static inline u32 +-efi_crc32(const void *buf, unsigned long len) ++static inline u32 efi_crc32(const void *buf, unsigned long len) + { + return (crc32(~0L, buf, len) ^ ~0L); + } +@@ -134,7 +131,8 @@ efi_crc32(const void *buf, unsigned long + static u64 last_lba(struct gendisk *disk) + { + return div_u64(bdev_nr_bytes(disk->part0), +- queue_logical_block_size(disk->queue)) - 1ULL; ++ queue_logical_block_size(disk->queue)) - ++ 1ULL; + } + + static inline int pmbr_part_valid(gpt_mbr_record *part) +@@ -195,7 +193,7 @@ static int is_pmbr_valid(legacy_mbr *mbr + check_hybrid: + for (i = 0; i < 4; i++) + if ((mbr->partition_record[i].os_type != +- EFI_PMBR_OSTYPE_EFI_GPT) && ++ EFI_PMBR_OSTYPE_EFI_GPT) && + (mbr->partition_record[i].os_type != 0x00)) + ret = GPT_MBR_HYBRID; + +@@ -213,10 +211,11 @@ check_hybrid: + */ + if (ret == GPT_MBR_PROTECTIVE) { + sz = le32_to_cpu(mbr->partition_record[part].size_in_lba); +- if (sz != (uint32_t) total_sectors - 1 && sz != 0xFFFFFFFF) +- pr_debug("GPT: mbr size in lba (%u) different than whole disk (%u).\n", +- sz, min_t(uint32_t, +- total_sectors - 1, 0xFFFFFFFF)); ++ if (sz != (uint32_t)total_sectors - 1 && sz != 0xFFFFFFFF) ++ pr_debug( ++ "GPT: mbr size in lba (%u) different than whole disk (%u).\n", ++ sz, ++ min_t(uint32_t, total_sectors - 1, 0xFFFFFFFF)); + } + done: + return ret; +@@ -232,15 +231,14 @@ done: + * Description: Reads @count bytes from @state->disk into @buffer. + * Returns number of bytes read on success, 0 on error. + */ +-static size_t read_lba(struct parsed_partitions *state, +- u64 lba, u8 *buffer, size_t count) ++static size_t read_lba(struct parsed_partitions *state, u64 lba, u8 *buffer, ++ size_t count) + { + size_t totalreadcount = 0; +- sector_t n = lba * +- (queue_logical_block_size(state->disk->queue) / 512); ++ sector_t n = lba * (queue_logical_block_size(state->disk->queue) / 512); + + if (!buffer || lba > last_lba(state->disk)) +- return 0; ++ return 0; + + while (count) { + int copied = 512; +@@ -253,7 +251,7 @@ static size_t read_lba(struct parsed_par + memcpy(buffer, data, copied); + put_dev_sector(sect); + buffer += copied; +- totalreadcount +=copied; ++ totalreadcount += copied; + count -= copied; + } + return totalreadcount; +@@ -278,17 +276,17 @@ static gpt_entry *alloc_read_gpt_entries + return NULL; + + count = (size_t)le32_to_cpu(gpt->num_partition_entries) * +- le32_to_cpu(gpt->sizeof_partition_entry); ++ le32_to_cpu(gpt->sizeof_partition_entry); + if (!count) + return NULL; + pte = kmalloc(count, GFP_KERNEL); + if (!pte) + return NULL; + +- if (read_lba(state, le64_to_cpu(gpt->partition_entry_lba), +- (u8 *) pte, count) < count) { ++ if (read_lba(state, le64_to_cpu(gpt->partition_entry_lba), (u8 *)pte, ++ count) < count) { + kfree(pte); +- pte=NULL; ++ pte = NULL; + return NULL; + } + return pte; +@@ -313,9 +311,9 @@ static gpt_header *alloc_read_gpt_header + if (!gpt) + return NULL; + +- if (read_lba(state, lba, (u8 *) gpt, ssz) < ssz) { ++ if (read_lba(state, lba, (u8 *)gpt, ssz) < ssz) { + kfree(gpt); +- gpt=NULL; ++ gpt = NULL; + return NULL; + } + +@@ -354,8 +352,9 @@ static int is_gpt_valid(struct parsed_pa + + /* Check the GUID Partition Table header size is too big */ + if (le32_to_cpu((*gpt)->header_size) > +- queue_logical_block_size(state->disk->queue)) { +- pr_debug("GUID Partition Table Header size is too large: %u > %u\n", ++ queue_logical_block_size(state->disk->queue)) { ++ pr_debug( ++ "GUID Partition Table Header size is too large: %u > %u\n", + le32_to_cpu((*gpt)->header_size), + queue_logical_block_size(state->disk->queue)); + goto fail; +@@ -363,16 +362,17 @@ static int is_gpt_valid(struct parsed_pa + + /* Check the GUID Partition Table header size is too small */ + if (le32_to_cpu((*gpt)->header_size) < sizeof(gpt_header)) { +- pr_debug("GUID Partition Table Header size is too small: %u < %zu\n", +- le32_to_cpu((*gpt)->header_size), +- sizeof(gpt_header)); ++ pr_debug( ++ "GUID Partition Table Header size is too small: %u < %zu\n", ++ le32_to_cpu((*gpt)->header_size), sizeof(gpt_header)); + goto fail; + } + + /* Check the GUID Partition Table CRC */ + origcrc = le32_to_cpu((*gpt)->header_crc32); + (*gpt)->header_crc32 = 0; +- crc = efi_crc32((const unsigned char *) (*gpt), le32_to_cpu((*gpt)->header_size)); ++ crc = efi_crc32((const unsigned char *)(*gpt), ++ le32_to_cpu((*gpt)->header_size)); + + if (crc != origcrc) { + pr_debug("GUID Partition Table Header CRC is wrong: %x != %x\n", +@@ -396,20 +396,25 @@ static int is_gpt_valid(struct parsed_pa + lastlba = last_lba(state->disk); + if (le64_to_cpu((*gpt)->first_usable_lba) > lastlba) { + pr_debug("GPT: first_usable_lba incorrect: %lld > %lld\n", +- (unsigned long long)le64_to_cpu((*gpt)->first_usable_lba), ++ (unsigned long long)le64_to_cpu( ++ (*gpt)->first_usable_lba), + (unsigned long long)lastlba); + goto fail; + } + if (le64_to_cpu((*gpt)->last_usable_lba) > lastlba) { + pr_debug("GPT: last_usable_lba incorrect: %lld > %lld\n", +- (unsigned long long)le64_to_cpu((*gpt)->last_usable_lba), ++ (unsigned long long)le64_to_cpu( ++ (*gpt)->last_usable_lba), + (unsigned long long)lastlba); + goto fail; + } +- if (le64_to_cpu((*gpt)->last_usable_lba) < le64_to_cpu((*gpt)->first_usable_lba)) { ++ if (le64_to_cpu((*gpt)->last_usable_lba) < ++ le64_to_cpu((*gpt)->first_usable_lba)) { + pr_debug("GPT: last_usable_lba incorrect: %lld > %lld\n", +- (unsigned long long)le64_to_cpu((*gpt)->last_usable_lba), +- (unsigned long long)le64_to_cpu((*gpt)->first_usable_lba)); ++ (unsigned long long)le64_to_cpu( ++ (*gpt)->last_usable_lba), ++ (unsigned long long)le64_to_cpu( ++ (*gpt)->first_usable_lba)); + goto fail; + } + /* Check that sizeof_partition_entry has the correct value */ +@@ -420,10 +425,11 @@ static int is_gpt_valid(struct parsed_pa + + /* Sanity check partition table size */ + pt_size = (u64)le32_to_cpu((*gpt)->num_partition_entries) * +- le32_to_cpu((*gpt)->sizeof_partition_entry); ++ le32_to_cpu((*gpt)->sizeof_partition_entry); + if (pt_size > KMALLOC_MAX_SIZE) { +- pr_debug("GUID Partition Table is too large: %llu > %lu bytes\n", +- (unsigned long long)pt_size, KMALLOC_MAX_SIZE); ++ pr_debug( ++ "GUID Partition Table is too large: %llu > %lu bytes\n", ++ (unsigned long long)pt_size, KMALLOC_MAX_SIZE); + goto fail; + } + +@@ -431,7 +437,7 @@ static int is_gpt_valid(struct parsed_pa + goto fail; + + /* Check the GUID Partition Entry Array CRC */ +- crc = efi_crc32((const unsigned char *) (*ptes), pt_size); ++ crc = efi_crc32((const unsigned char *)(*ptes), pt_size); + + if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) { + pr_debug("GUID Partition Entry Array CRC check failed.\n"); +@@ -441,10 +447,10 @@ static int is_gpt_valid(struct parsed_pa + /* We're done, all's well */ + return 1; + +- fail_ptes: ++fail_ptes: + kfree(*ptes); + *ptes = NULL; +- fail: ++fail: + kfree(*gpt); + *gpt = NULL; + return 0; +@@ -457,12 +463,11 @@ static int is_gpt_valid(struct parsed_pa + * + * Description: returns 1 if valid, 0 on error. + */ +-static inline int +-is_pte_valid(const gpt_entry *pte, const u64 lastlba) ++static inline int is_pte_valid(const gpt_entry *pte, const u64 lastlba) + { + if ((!efi_guidcmp(pte->partition_type_guid, NULL_GUID)) || +- le64_to_cpu(pte->starting_lba) > lastlba || +- le64_to_cpu(pte->ending_lba) > lastlba) ++ le64_to_cpu(pte->starting_lba) > lastlba || ++ le64_to_cpu(pte->ending_lba) > lastlba) + return 0; + return 1; + } +@@ -477,8 +482,7 @@ is_pte_valid(const gpt_entry *pte, const + * and prints warnings on discrepancies. + * + */ +-static void +-compare_gpts(gpt_header *pgpt, gpt_header *agpt, u64 lastlba) ++static void compare_gpts(gpt_header *pgpt, gpt_header *agpt, u64 lastlba) + { + int error_found = 0; + if (!pgpt || !agpt) +@@ -486,31 +490,32 @@ compare_gpts(gpt_header *pgpt, gpt_heade + if (le64_to_cpu(pgpt->my_lba) != le64_to_cpu(agpt->alternate_lba)) { + pr_warn("GPT:Primary header LBA != Alt. header alternate_lba\n"); + pr_warn("GPT:%lld != %lld\n", +- (unsigned long long)le64_to_cpu(pgpt->my_lba), +- (unsigned long long)le64_to_cpu(agpt->alternate_lba)); ++ (unsigned long long)le64_to_cpu(pgpt->my_lba), ++ (unsigned long long)le64_to_cpu(agpt->alternate_lba)); + error_found++; + } + if (le64_to_cpu(pgpt->alternate_lba) != le64_to_cpu(agpt->my_lba)) { + pr_warn("GPT:Primary header alternate_lba != Alt. header my_lba\n"); + pr_warn("GPT:%lld != %lld\n", +- (unsigned long long)le64_to_cpu(pgpt->alternate_lba), +- (unsigned long long)le64_to_cpu(agpt->my_lba)); ++ (unsigned long long)le64_to_cpu(pgpt->alternate_lba), ++ (unsigned long long)le64_to_cpu(agpt->my_lba)); + error_found++; + } + if (le64_to_cpu(pgpt->first_usable_lba) != +- le64_to_cpu(agpt->first_usable_lba)) { ++ le64_to_cpu(agpt->first_usable_lba)) { + pr_warn("GPT:first_usable_lbas don't match.\n"); + pr_warn("GPT:%lld != %lld\n", +- (unsigned long long)le64_to_cpu(pgpt->first_usable_lba), +- (unsigned long long)le64_to_cpu(agpt->first_usable_lba)); ++ (unsigned long long)le64_to_cpu(pgpt->first_usable_lba), ++ (unsigned long long)le64_to_cpu( ++ agpt->first_usable_lba)); + error_found++; + } + if (le64_to_cpu(pgpt->last_usable_lba) != +- le64_to_cpu(agpt->last_usable_lba)) { ++ le64_to_cpu(agpt->last_usable_lba)) { + pr_warn("GPT:last_usable_lbas don't match.\n"); + pr_warn("GPT:%lld != %lld\n", +- (unsigned long long)le64_to_cpu(pgpt->last_usable_lba), +- (unsigned long long)le64_to_cpu(agpt->last_usable_lba)); ++ (unsigned long long)le64_to_cpu(pgpt->last_usable_lba), ++ (unsigned long long)le64_to_cpu(agpt->last_usable_lba)); + error_found++; + } + if (efi_guidcmp(pgpt->disk_guid, agpt->disk_guid)) { +@@ -518,27 +523,27 @@ compare_gpts(gpt_header *pgpt, gpt_heade + error_found++; + } + if (le32_to_cpu(pgpt->num_partition_entries) != +- le32_to_cpu(agpt->num_partition_entries)) { ++ le32_to_cpu(agpt->num_partition_entries)) { + pr_warn("GPT:num_partition_entries don't match: " +- "0x%x != 0x%x\n", +- le32_to_cpu(pgpt->num_partition_entries), +- le32_to_cpu(agpt->num_partition_entries)); ++ "0x%x != 0x%x\n", ++ le32_to_cpu(pgpt->num_partition_entries), ++ le32_to_cpu(agpt->num_partition_entries)); + error_found++; + } + if (le32_to_cpu(pgpt->sizeof_partition_entry) != +- le32_to_cpu(agpt->sizeof_partition_entry)) { ++ le32_to_cpu(agpt->sizeof_partition_entry)) { + pr_warn("GPT:sizeof_partition_entry values don't match: " +- "0x%x != 0x%x\n", +- le32_to_cpu(pgpt->sizeof_partition_entry), +- le32_to_cpu(agpt->sizeof_partition_entry)); ++ "0x%x != 0x%x\n", ++ le32_to_cpu(pgpt->sizeof_partition_entry), ++ le32_to_cpu(agpt->sizeof_partition_entry)); + error_found++; + } + if (le32_to_cpu(pgpt->partition_entry_array_crc32) != +- le32_to_cpu(agpt->partition_entry_array_crc32)) { ++ le32_to_cpu(agpt->partition_entry_array_crc32)) { + pr_warn("GPT:partition_entry_array_crc32 values don't match: " +- "0x%x != 0x%x\n", +- le32_to_cpu(pgpt->partition_entry_array_crc32), +- le32_to_cpu(agpt->partition_entry_array_crc32)); ++ "0x%x != 0x%x\n", ++ le32_to_cpu(pgpt->partition_entry_array_crc32), ++ le32_to_cpu(agpt->partition_entry_array_crc32)); + error_found++; + } + if (le64_to_cpu(pgpt->alternate_lba) != lastlba) { +@@ -594,7 +599,7 @@ static int find_valid_gpt(struct parsed_ + return 0; + + lastlba = last_lba(state->disk); +- if (!force_gpt) { ++ if (!force_gpt) { + /* This will be added to the EFI Spec. per Intel after v1.02. */ + legacymbr = kzalloc(sizeof(*legacymbr), GFP_KERNEL); + if (!legacymbr) +@@ -608,18 +613,17 @@ static int find_valid_gpt(struct parsed_ + goto fail; + + pr_debug("Device has a %s MBR\n", +- good_pmbr == GPT_MBR_PROTECTIVE ? +- "protective" : "hybrid"); ++ good_pmbr == GPT_MBR_PROTECTIVE ? "protective" : ++ "hybrid"); + } + +- good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA, +- &pgpt, &pptes); +- if (good_pgpt) +- good_agpt = is_gpt_valid(state, +- le64_to_cpu(pgpt->alternate_lba), +- &agpt, &aptes); +- if (!good_agpt && force_gpt) +- good_agpt = is_gpt_valid(state, lastlba, &agpt, &aptes); ++ good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA, &pgpt, ++ &pptes); ++ if (good_pgpt) ++ good_agpt = is_gpt_valid( ++ state, le64_to_cpu(pgpt->alternate_lba), &agpt, &aptes); ++ if (!good_agpt && force_gpt) ++ good_agpt = is_gpt_valid(state, lastlba, &agpt, &aptes); + + if (!good_agpt && force_gpt && fops->alternative_gpt_sector) { + sector_t agpt_sector; +@@ -627,43 +631,42 @@ static int find_valid_gpt(struct parsed_ + + err = fops->alternative_gpt_sector(disk, &agpt_sector); + if (!err) +- good_agpt = is_gpt_valid(state, agpt_sector, +- &agpt, &aptes); ++ good_agpt = ++ is_gpt_valid(state, agpt_sector, &agpt, &aptes); + } + +- /* The obviously unsuccessful case */ +- if (!good_pgpt && !good_agpt) +- goto fail; +- +- compare_gpts(pgpt, agpt, lastlba); +- +- /* The good cases */ +- if (good_pgpt) { +- *gpt = pgpt; +- *ptes = pptes; +- kfree(agpt); +- kfree(aptes); ++ /* The obviously unsuccessful case */ ++ if (!good_pgpt && !good_agpt) ++ goto fail; ++ ++ compare_gpts(pgpt, agpt, lastlba); ++ ++ /* The good cases */ ++ if (good_pgpt) { ++ *gpt = pgpt; ++ *ptes = pptes; ++ kfree(agpt); ++ kfree(aptes); + if (!good_agpt) +- pr_warn("Alternate GPT is invalid, using primary GPT.\n"); +- return 1; +- } +- else if (good_agpt) { +- *gpt = agpt; +- *ptes = aptes; +- kfree(pgpt); +- kfree(pptes); ++ pr_warn("Alternate GPT is invalid, using primary GPT.\n"); ++ return 1; ++ } else if (good_agpt) { ++ *gpt = agpt; ++ *ptes = aptes; ++ kfree(pgpt); ++ kfree(pptes); + pr_warn("Primary GPT is invalid, using alternate GPT.\n"); +- return 1; +- } ++ return 1; ++ } + +- fail: +- kfree(pgpt); +- kfree(agpt); +- kfree(pptes); +- kfree(aptes); +- *gpt = NULL; +- *ptes = NULL; +- return 0; ++fail: ++ kfree(pgpt); ++ kfree(agpt); ++ kfree(pptes); ++ kfree(aptes); ++ *gpt = NULL; ++ *ptes = NULL; ++ return 0; + } + + /** +@@ -725,7 +728,9 @@ int efi_partition(struct parsed_partitio + + pr_debug("GUID Partition Table is valid! Yea!\n"); + +- for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) { ++ for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && ++ i < state->limit - 1; ++ i++) { + struct partition_meta_info *info; + unsigned label_max; + u64 start = le64_to_cpu(ptes[i].starting_lba); +@@ -735,10 +740,11 @@ int efi_partition(struct parsed_partitio + if (!is_pte_valid(&ptes[i], last_lba(state->disk))) + continue; + +- put_partition(state, i+1, start * ssz, size * ssz); ++ put_partition(state, i + 1, start * ssz, size * ssz); + + /* If this is a RAID volume, tell md */ +- if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_RAID_GUID)) ++ if (!efi_guidcmp(ptes[i].partition_type_guid, ++ PARTITION_LINUX_RAID_GUID)) + state->parts[i + 1].flags = ADDPART_FLAG_RAID; + + info = &state->parts[i + 1].info; +@@ -747,7 +753,8 @@ int efi_partition(struct parsed_partitio + /* Naively convert UTF16-LE to 7 bits. */ + label_max = min(ARRAY_SIZE(info->volname) - 1, + ARRAY_SIZE(ptes[i].partition_name)); +- utf16_le_to_7bit(ptes[i].partition_name, label_max, info->volname); ++ utf16_le_to_7bit(ptes[i].partition_name, label_max, ++ info->volname); + state->parts[i + 1].has_info = true; + } + kfree(ptes); diff --git a/target/linux/generic/pending-6.12/453-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch b/target/linux/generic/pending-6.12/453-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch deleted file mode 100644 index 36dc9e6a515..00000000000 --- a/target/linux/generic/pending-6.12/453-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch +++ /dev/null @@ -1,56 +0,0 @@ -From patchwork Tue Jul 30 19:27:07 2024 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Daniel Golle -X-Patchwork-Id: 13747818 -Date: Tue, 30 Jul 2024 20:27:07 +0100 -From: Daniel Golle -To: Rob Herring , Krzysztof Kozlowski , - Conor Dooley , Jens Axboe , - Daniel Golle , Christian Brauner , - Al Viro , Li Lingfeng , - Ming Lei , Christian Heusel , - =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= , - Felix Fietkau , John Crispin , - Chad Monroe , Yangyu Chen , - Tianling Shen , Chuanhong Guo , - Chen Minqiang , devicetree@vger.kernel.org, - linux-kernel@vger.kernel.org, linux-block@vger.kernel.org -Subject: [PATCH v5 4/4] block: add new genhd flag GENHD_FL_NVMEM -Message-ID: - <311ea569c23ce14e2896cd3b069dc494c58c49c2.1722365899.git.daniel@makrotopia.org> -References: -Precedence: bulk -X-Mailing-List: linux-block@vger.kernel.org -List-Id: -List-Subscribe: -List-Unsubscribe: -MIME-Version: 1.0 -Content-Disposition: inline -In-Reply-To: - -Add new flag to destinguish block devices which may act as an NVMEM -provider. - -Signed-off-by: Daniel Golle ---- - include/linux/blkdev.h | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/include/linux/blkdev.h -+++ b/include/linux/blkdev.h -@@ -82,11 +82,13 @@ struct partition_meta_info { - * ``GENHD_FL_NO_PART``: partition support is disabled. The kernel will not - * scan for partitions from add_disk, and users can't add partitions manually. - * -+ * ``GENHD_FL_NVMEM``: the block device should be considered as NVMEM provider. - */ - enum { - GENHD_FL_REMOVABLE = 1 << 0, - GENHD_FL_HIDDEN = 1 << 1, - GENHD_FL_NO_PART = 1 << 2, -+ GENHD_FL_NVMEM = 1 << 3, - }; - - enum { diff --git a/target/linux/generic/pending-6.12/453-partitions-efi-allow-assigning-partition-Device-Tree.patch b/target/linux/generic/pending-6.12/453-partitions-efi-allow-assigning-partition-Device-Tree.patch new file mode 100644 index 00000000000..cc2c20338af --- /dev/null +++ b/target/linux/generic/pending-6.12/453-partitions-efi-allow-assigning-partition-Device-Tree.patch @@ -0,0 +1,75 @@ +From f28e36c19b927671d93ccd2b5de3d518fccf721e Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 8 Oct 2024 00:25:12 +0100 +Subject: [PATCH 4/8] partitions/efi: allow assigning partition Device Tree + node + +Signed-off-by: Daniel Golle +--- + block/partitions/efi.c | 34 +++++++++++++++++++++++++++++++++- + 1 file changed, 33 insertions(+), 1 deletion(-) + +--- a/block/partitions/efi.c ++++ b/block/partitions/efi.c +@@ -86,6 +86,7 @@ + #include + #include + #include ++#include + #include + #include "check.h" + #include "efi.h" +@@ -694,6 +695,34 @@ static void utf16_le_to_7bit(const __le1 + } + } + ++static struct device_node *find_partition_of_node(struct device_node *partitions_np, ++ gpt_entry *ptes) ++{ ++ char volname[64], partuuid[UUID_STRING_LEN + 1]; ++ const char *uuid, *name; ++ ++ if (!partitions_np || ++ !of_device_is_compatible(partitions_np, "gpt-partitions")) ++ return NULL; ++ ++ efi_guid_to_str(&ptes->unique_partition_guid, partuuid); ++ utf16_le_to_7bit(ptes->partition_name, ARRAY_SIZE(volname) - 1, volname); ++ ++ for_each_available_child_of_node_scoped(partitions_np, np) { ++ if (!of_property_read_string(np, "uuid", &uuid) && ++ strncmp(uuid, partuuid, ARRAY_SIZE(partuuid))) ++ continue; ++ ++ if (!of_property_read_string(np, "partname", &name) && ++ strncmp(name, volname, ARRAY_SIZE(volname))) ++ continue; ++ ++ return np; ++ } ++ ++ return NULL; ++} ++ + /** + * efi_partition - scan for GPT partitions + * @state: disk parsed partitions +@@ -719,6 +748,8 @@ int efi_partition(struct parsed_partitio + gpt_entry *ptes = NULL; + u32 i; + unsigned ssz = queue_logical_block_size(state->disk->queue) / 512; ++ struct device *ddev = disk_to_dev(state->disk); ++ struct device_node *partitions_np = of_node_get(ddev->of_node); + + if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) { + kfree(gpt); +@@ -740,7 +771,8 @@ int efi_partition(struct parsed_partitio + if (!is_pte_valid(&ptes[i], last_lba(state->disk))) + continue; + +- put_partition(state, i + 1, start * ssz, size * ssz); ++ of_put_partition(state, i + 1, start * ssz, size * ssz, ++ find_partition_of_node(partitions_np, &ptes[i])); + + /* If this is a RAID volume, tell md */ + if (!efi_guidcmp(ptes[i].partition_type_guid, diff --git a/target/linux/generic/pending-6.12/452-block-add-support-for-notifications.patch b/target/linux/generic/pending-6.12/454-block-add-support-for-notifications.patch similarity index 60% rename from target/linux/generic/pending-6.12/452-block-add-support-for-notifications.patch rename to target/linux/generic/pending-6.12/454-block-add-support-for-notifications.patch index aed497c0be3..300cbf7c7c5 100644 --- a/target/linux/generic/pending-6.12/452-block-add-support-for-notifications.patch +++ b/target/linux/generic/pending-6.12/454-block-add-support-for-notifications.patch @@ -1,45 +1,18 @@ -From patchwork Tue Jul 30 19:26:42 2024 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Daniel Golle -X-Patchwork-Id: 13747817 -Date: Tue, 30 Jul 2024 20:26:42 +0100 +From 858df9db80c1568db255659baca7602504f823af Mon Sep 17 00:00:00 2001 From: Daniel Golle -To: Rob Herring , Krzysztof Kozlowski , - Conor Dooley , Jens Axboe , - Daniel Golle , Christian Brauner , - Al Viro , Li Lingfeng , - Ming Lei , Christian Heusel , - =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= , - Felix Fietkau , John Crispin , - Chad Monroe , Yangyu Chen , - Tianling Shen , Chuanhong Guo , - Chen Minqiang , devicetree@vger.kernel.org, - linux-kernel@vger.kernel.org, linux-block@vger.kernel.org -Subject: [PATCH v5 3/4] block: add support for notifications -Message-ID: - -References: -Precedence: bulk -X-Mailing-List: linux-block@vger.kernel.org -List-Id: -List-Subscribe: -List-Unsubscribe: -MIME-Version: 1.0 -Content-Disposition: inline -In-Reply-To: +Date: Wed, 15 May 2024 08:19:51 +0100 +Subject: [PATCH 5/8] block: add support for notifications Add notifier block to notify other subsystems about the addition or removal of block devices. Signed-off-by: Daniel Golle --- - block/Kconfig | 6 +++ - block/Makefile | 1 + - block/blk-notify.c | 87 ++++++++++++++++++++++++++++++++++++++++++ - include/linux/blkdev.h | 11 ++++++ - 4 files changed, 105 insertions(+) + block/Kconfig | 6 +++ + block/Makefile | 1 + + block/blk-notify.c | 107 +++++++++++++++++++++++++++++++++++++++++ + include/linux/blkdev.h | 8 +++ + 4 files changed, 122 insertions(+) create mode 100644 block/blk-notify.c --- a/block/Kconfig @@ -66,7 +39,7 @@ Signed-off-by: Daniel Golle +obj-$(CONFIG_BLOCK_NOTIFIERS) += blk-notify.o --- /dev/null +++ b/block/blk-notify.c -@@ -0,0 +1,87 @@ +@@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Notifiers for addition and removal of block devices @@ -77,6 +50,7 @@ Signed-off-by: Daniel Golle +#include +#include +#include ++#include + +#include "blk.h" + @@ -89,6 +63,11 @@ Signed-off-by: Daniel Golle +static DEFINE_MUTEX(blk_notifier_lock); +static LIST_HEAD(blk_devices); + ++struct blk_notify_event { ++ struct delayed_work work; ++ struct device *dev; ++}; ++ +void blk_register_notify(struct notifier_block *nb) +{ + struct blk_device_list *existing_blkdev; @@ -111,19 +90,33 @@ Signed-off-by: Daniel Golle +} +EXPORT_SYMBOL_GPL(blk_unregister_notify); + ++static void blk_notify_work(struct work_struct *work) ++{ ++ struct blk_notify_event *ev = ++ container_of(work, struct blk_notify_event, work.work); ++ ++ raw_notifier_call_chain(&blk_notifier_list, BLK_DEVICE_ADD, ev->dev); ++ kfree(ev); ++} ++ +static int blk_call_notifier_add(struct device *dev) +{ + struct blk_device_list *new_blkdev; ++ struct blk_notify_event *ev; + -+ new_blkdev = kmalloc(sizeof(*new_blkdev), GFP_KERNEL); ++ new_blkdev = kmalloc(sizeof (*new_blkdev), GFP_KERNEL); + if (!new_blkdev) + return -ENOMEM; + ++ ev = kmalloc(sizeof(*ev), GFP_KERNEL); ++ INIT_DEFERRABLE_WORK(&ev->work, blk_notify_work); ++ ev->dev = dev; + new_blkdev->dev = dev; + mutex_lock(&blk_notifier_lock); + list_add_tail(&new_blkdev->list, &blk_devices); -+ raw_notifier_call_chain(&blk_notifier_list, BLK_DEVICE_ADD, dev); ++ schedule_delayed_work(&ev->work, msecs_to_jiffies(500)); + mutex_unlock(&blk_notifier_lock); ++ + return 0; +} + @@ -156,19 +149,16 @@ Signed-off-by: Daniel Golle +device_initcall(blk_notifications_init); --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h -@@ -1696,4 +1696,15 @@ static inline bool bdev_can_atomic_write +@@ -1696,4 +1696,12 @@ static inline bool bdev_can_atomic_write #define DEFINE_IO_COMP_BATCH(name) struct io_comp_batch name = { } + ++#ifdef CONFIG_BLOCK_NOTIFIERS +#define BLK_DEVICE_ADD 1 +#define BLK_DEVICE_REMOVE 2 -+#if defined(CONFIG_BLOCK_NOTIFIERS) -+void blk_register_notify(struct notifier_block *nb); -+void blk_unregister_notify(struct notifier_block *nb); -+#else -+static inline void blk_register_notify(struct notifier_block *nb) { }; -+static inline void blk_unregister_notify(struct notifier_block *nb) { }; ++extern void blk_register_notify(struct notifier_block *nb); ++extern void blk_unregister_notify(struct notifier_block *nb); +#endif + #endif /* _LINUX_BLKDEV_H */ diff --git a/target/linux/generic/pending-6.12/455-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch b/target/linux/generic/pending-6.12/455-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch new file mode 100644 index 00000000000..4f9a26fd161 --- /dev/null +++ b/target/linux/generic/pending-6.12/455-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch @@ -0,0 +1,29 @@ +From 2b28bf485b283991eea9f00c5831c1c39c73991f Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Thu, 21 Mar 2024 19:33:49 +0000 +Subject: [PATCH 6/8] block: add new genhd flag GENHD_FL_NVMEM + +Add new flag to destinguish block devices which may act as an NVMEM +provider. + +Signed-off-by: Daniel Golle +--- + include/linux/blkdev.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -82,11 +82,13 @@ struct partition_meta_info { + * ``GENHD_FL_NO_PART``: partition support is disabled. The kernel will not + * scan for partitions from add_disk, and users can't add partitions manually. + * ++ * ``GENHD_FL_NVMEM``: the block device should be considered as NVMEM provider. + */ + enum { + GENHD_FL_REMOVABLE = 1 << 0, + GENHD_FL_HIDDEN = 1 << 1, + GENHD_FL_NO_PART = 1 << 2, ++ GENHD_FL_NVMEM = 1 << 3, + }; + + enum { diff --git a/target/linux/generic/pending-6.12/455-dt-bindings-mmc-mmc-card-add-block-device-nodes.patch b/target/linux/generic/pending-6.12/455-dt-bindings-mmc-mmc-card-add-block-device-nodes.patch deleted file mode 100644 index 74e6c821ba6..00000000000 --- a/target/linux/generic/pending-6.12/455-dt-bindings-mmc-mmc-card-add-block-device-nodes.patch +++ /dev/null @@ -1,74 +0,0 @@ -From f7ec19b34d1b7e934a58ceb102369bbd30b2631d Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 30 May 2024 03:15:11 +0100 -Subject: [PATCH 6/9] dt-bindings: mmc: mmc-card: add block device nodes - -Add nodes representing the block devices exposed by an MMC device -including an example involving nvmem-cells. - -Signed-off-by: Daniel Golle ---- - .../devicetree/bindings/mmc/mmc-card.yaml | 45 +++++++++++++++++++ - 1 file changed, 45 insertions(+) - ---- a/Documentation/devicetree/bindings/mmc/mmc-card.yaml -+++ b/Documentation/devicetree/bindings/mmc/mmc-card.yaml -@@ -26,6 +26,18 @@ properties: - Use this to indicate that the mmc-card has a broken hpi - implementation, and that hpi should not be used. - -+ block: -+ $ref: /schemas/block/block-device.yaml# -+ description: -+ Represents the block storage provided by an SD card or the -+ main hardware partition of an eMMC. -+ -+patternProperties: -+ '^boot[0-9]+': -+ $ref: /schemas/block/block-device.yaml# -+ description: -+ Represents a boot hardware partition on an eMMC. -+ - required: - - compatible - - reg -@@ -42,6 +54,39 @@ examples: - compatible = "mmc-card"; - reg = <0>; - broken-hpi; -+ -+ block { -+ partitions { -+ cal_data: block-partition-rf { -+ partnum = <3>; -+ partname = "rf"; -+ -+ nvmem-layout { -+ compatible = "fixed-layout"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ eeprom@0 { -+ reg = <0x0 0x1000>; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ boot1 { -+ nvmem-layout { -+ compatible = "fixed-layout"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ macaddr: macaddr@a { -+ compatible = "mac-base"; -+ reg = <0xa 0x6>; -+ #nvmem-cell-cells = <1>; -+ }; -+ }; -+ }; - }; - }; - diff --git a/target/linux/generic/pending-6.12/456-mmc-core-set-card-fwnode_handle.patch b/target/linux/generic/pending-6.12/456-mmc-core-set-card-fwnode_handle.patch deleted file mode 100644 index 85438df61b6..00000000000 --- a/target/linux/generic/pending-6.12/456-mmc-core-set-card-fwnode_handle.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 043c4f88476cc0f29c9bf82a8a516f58d848e1cd Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 30 May 2024 03:15:25 +0100 -Subject: [PATCH 7/9] mmc: core: set card fwnode_handle - -Set fwnode in case it isn't set yet and of_node is present. - -Signed-off-by: Daniel Golle ---- - drivers/mmc/core/bus.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/mmc/core/bus.c -+++ b/drivers/mmc/core/bus.c -@@ -368,6 +368,8 @@ int mmc_add_card(struct mmc_card *card) - - mmc_add_card_debugfs(card); - card->dev.of_node = mmc_of_find_child_device(card->host, 0); -+ if (card->dev.of_node && !card->dev.fwnode) -+ card->dev.fwnode = &card->dev.of_node->fwnode; - - device_enable_async_suspend(&card->dev); - diff --git a/target/linux/generic/pending-6.12/454-nvmem-implement-block-NVMEM-provider.patch b/target/linux/generic/pending-6.12/456-nvmem-implement-block-NVMEM-provider.patch similarity index 86% rename from target/linux/generic/pending-6.12/454-nvmem-implement-block-NVMEM-provider.patch rename to target/linux/generic/pending-6.12/456-nvmem-implement-block-NVMEM-provider.patch index 3c08f6dd84b..563b9f1259d 100644 --- a/target/linux/generic/pending-6.12/454-nvmem-implement-block-NVMEM-provider.patch +++ b/target/linux/generic/pending-6.12/456-nvmem-implement-block-NVMEM-provider.patch @@ -1,7 +1,7 @@ -From 9703951cdfe868b130e64d6122420396c2807be8 Mon Sep 17 00:00:00 2001 +From 26ae98bf77fdbd60536fe5c2175e528469b9ac9a Mon Sep 17 00:00:00 2001 From: Daniel Golle -Date: Thu, 30 May 2024 03:15:02 +0100 -Subject: [PATCH 5/9] nvmem: implement block NVMEM provider +Date: Wed, 15 May 2024 18:18:37 +0300 +Subject: [PATCH 7/8] nvmem: implement block NVMEM provider On embedded devices using an eMMC it is common that one or more partitions on the eMMC are used to store MAC addresses and Wi-Fi calibration EEPROM @@ -12,8 +12,8 @@ Signed-off-by: Daniel Golle --- drivers/nvmem/Kconfig | 11 +++ drivers/nvmem/Makefile | 2 + - drivers/nvmem/block.c | 197 +++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 210 insertions(+) + drivers/nvmem/block.c | 198 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 211 insertions(+) create mode 100644 drivers/nvmem/block.c --- a/drivers/nvmem/Kconfig @@ -49,7 +49,7 @@ Signed-off-by: Daniel Golle obj-$(CONFIG_NVMEM_IMX_IIM) += nvmem-imx-iim.o --- /dev/null +++ b/drivers/nvmem/block.c -@@ -0,0 +1,208 @@ +@@ -0,0 +1,198 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * block device NVMEM provider @@ -71,43 +71,33 @@ Signed-off-by: Daniel Golle +static DEFINE_MUTEX(devices_mutex); + +struct blk_nvmem { -+ struct nvmem_device *nvmem; -+ struct block_device *bdev; -+ struct list_head list; ++ struct nvmem_device *nvmem; ++ struct device *dev; ++ struct list_head list; +}; + +static int blk_nvmem_reg_read(void *priv, unsigned int from, + void *val, size_t bytes) +{ ++ blk_mode_t mode = BLK_OPEN_READ | BLK_OPEN_RESTRICT_WRITES; + unsigned long offs = from & ~PAGE_MASK, to_read; + pgoff_t f_index = from >> PAGE_SHIFT; -+ struct address_space *mapping; + struct blk_nvmem *bnv = priv; + size_t bytes_left = bytes; ++ struct file *bdev_file; + struct folio *folio; + void *p; -+ int ret; ++ int ret = 0; + -+ if (!bnv->bdev) ++ bdev_file = bdev_file_open_by_dev(bnv->dev->devt, mode, priv, NULL); ++ if (!bdev_file) + return -ENODEV; + -+ if (!bnv->bdev->bd_disk) -+ return -EINVAL; -+ -+ if (!bnv->bdev->bd_disk->fops) -+ return -EIO; -+ -+ if (!bnv->bdev->bd_disk->fops->open) -+ return -EIO; -+ -+ ret = bnv->bdev->bd_disk->fops->open(bnv->bdev->bd_disk, BLK_OPEN_READ); -+ if (ret) -+ return ret; -+ -+ mapping = bnv->bdev->bd_inode->i_mapping; ++ if (IS_ERR(bdev_file)) ++ return PTR_ERR(bdev_file); + + while (bytes_left) { -+ folio = read_mapping_folio(mapping, f_index++, NULL); ++ folio = read_mapping_folio(bdev_file->f_mapping, f_index++, NULL); + if (IS_ERR(folio)) { + ret = PTR_ERR(folio); + goto err_release_bdev; @@ -122,15 +112,15 @@ Signed-off-by: Daniel Golle + } + +err_release_bdev: -+ bnv->bdev->bd_disk->fops->release(bnv->bdev->bd_disk); ++ fput(bdev_file); + + return ret; +} + +static int blk_nvmem_register(struct device *dev) +{ -+ struct device_node *np = dev_of_node(dev); + struct block_device *bdev = dev_to_bdev(dev); ++ struct device_node *np = dev_of_node(dev); + struct nvmem_config config = {}; + struct blk_nvmem *bnv; + @@ -178,7 +168,7 @@ Signed-off-by: Daniel Golle + config.ignore_wp = true; + config.of_node = to_of_node(dev->fwnode); + -+ bnv->bdev = bdev; ++ bnv->dev = &bdev->bd_device; + bnv->nvmem = nvmem_register(&config); + if (IS_ERR(bnv->nvmem)) { + dev_err_probe(&bdev->bd_device, PTR_ERR(bnv->nvmem), @@ -197,12 +187,11 @@ Signed-off-by: Daniel Golle + +static void blk_nvmem_unregister(struct device *dev) +{ -+ struct block_device *bdev = dev_to_bdev(dev); + struct blk_nvmem *bnv_c, *bnv = NULL; + + mutex_lock(&devices_mutex); + list_for_each_entry(bnv_c, &nvmem_devices, list) { -+ if (bnv_c->bdev == bdev) { ++ if (bnv_c->dev == dev) { + bnv = bnv_c; + break; + } @@ -226,6 +215,7 @@ Signed-off-by: Daniel Golle + switch (code) { + case BLK_DEVICE_ADD: + return blk_nvmem_register(dev); ++ break; + case BLK_DEVICE_REMOVE: + blk_nvmem_unregister(dev); + break; diff --git a/target/linux/generic/pending-6.12/458-mmc-block-set-GENHD_FL_NVMEM.patch b/target/linux/generic/pending-6.12/457-mmc-block-set-GENHD_FL_NVMEM.patch similarity index 79% rename from target/linux/generic/pending-6.12/458-mmc-block-set-GENHD_FL_NVMEM.patch rename to target/linux/generic/pending-6.12/457-mmc-block-set-GENHD_FL_NVMEM.patch index 7ef0d019880..955fa6676e9 100644 --- a/target/linux/generic/pending-6.12/458-mmc-block-set-GENHD_FL_NVMEM.patch +++ b/target/linux/generic/pending-6.12/457-mmc-block-set-GENHD_FL_NVMEM.patch @@ -1,7 +1,7 @@ -From 7903b50441000365a6fe5badb39735889f562252 Mon Sep 17 00:00:00 2001 +From caac69565748349a3e532130a891e18dd5c36c5e Mon Sep 17 00:00:00 2001 From: Daniel Golle -Date: Thu, 30 May 2024 03:15:46 +0100 -Subject: [PATCH 9/9] mmc: block: set GENHD_FL_NVMEM +Date: Thu, 20 Jul 2023 17:36:44 +0100 +Subject: [PATCH 8/8] mmc: block: set GENHD_FL_NVMEM Set flag to consider MMC block devices as NVMEM providers. diff --git a/target/linux/generic/pending-6.12/457-mmc-block-set-fwnode-of-disk-devices.patch b/target/linux/generic/pending-6.12/457-mmc-block-set-fwnode-of-disk-devices.patch deleted file mode 100644 index e37d15b1243..00000000000 --- a/target/linux/generic/pending-6.12/457-mmc-block-set-fwnode-of-disk-devices.patch +++ /dev/null @@ -1,27 +0,0 @@ -From ef3e38fec26901b71975d7e810a2df6b8bd54a8e Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 30 May 2024 03:15:36 +0100 -Subject: [PATCH 8/9] mmc: block: set fwnode of disk devices - -Set fwnode of disk devices to 'block', 'boot0' and 'boot1' subnodes of -the mmc-card. This is done in preparation for having the eMMC act as -NVMEM provider. - -Signed-off-by: Daniel Golle ---- - drivers/mmc/core/block.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/drivers/mmc/core/block.c -+++ b/drivers/mmc/core/block.c -@@ -2678,6 +2678,10 @@ static struct mmc_blk_data *mmc_blk_allo - if (area_type == MMC_BLK_DATA_AREA_MAIN) - dev_set_drvdata(&card->dev, md); - disk_fwnode = mmc_blk_get_partitions_node(parent, subname); -+ if (!disk_fwnode) -+ disk_fwnode = device_get_named_child_node(subname ? md->parent->parent : -+ md->parent, -+ subname ? subname : "block"); - ret = add_disk_fwnode(md->parent, md->disk, mmc_disk_attr_groups, - disk_fwnode); - if (ret)