2 * Copyright (C) 2014 Gabor Juhos <juhosg@openwrt.org>
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published
6 * by the Free Software Foundation.
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/kernel.h>
13 #include <linux/slab.h>
14 #include <linux/mtd/mtd.h>
15 #include <linux/mtd/partitions.h>
18 #include <asm/unaligned.h>
22 #define LZMA_NR_PARTS 2
23 #define LZMA_PROPERTIES_SIZE 5
26 u8 props
[LZMA_PROPERTIES_SIZE
];
31 static int mtdsplit_parse_lzma(struct mtd_info
*master
,
32 const struct mtd_partition
**pparts
,
33 struct mtd_part_parser_data
*data
)
35 struct lzma_header hdr
;
36 size_t hdr_len
, retlen
;
39 struct mtd_partition
*parts
;
42 hdr_len
= sizeof(hdr
);
43 err
= mtd_read(master
, 0, hdr_len
, &retlen
, (void *) &hdr
);
47 if (retlen
!= hdr_len
)
50 /* verify LZMA properties */
51 if (hdr
.props
[0] >= (9 * 5 * 5))
54 t
= get_unaligned_le32(&hdr
.props
[1]);
55 if (!is_power_of_2(t
))
58 t
= get_unaligned_le32(&hdr
.size_high
);
62 err
= mtd_find_rootfs_from(master
, master
->erasesize
, master
->size
,
63 &rootfs_offset
, NULL
);
67 parts
= kzalloc(LZMA_NR_PARTS
* sizeof(*parts
), GFP_KERNEL
);
71 parts
[0].name
= KERNEL_PART_NAME
;
73 parts
[0].size
= rootfs_offset
;
75 parts
[1].name
= ROOTFS_PART_NAME
;
76 parts
[1].offset
= rootfs_offset
;
77 parts
[1].size
= master
->size
- rootfs_offset
;
83 static const struct of_device_id mtdsplit_lzma_of_match_table
[] = {
84 { .compatible
= "lzma" },
87 MODULE_DEVICE_TABLE(of
, mtdsplit_lzma_of_match_table
);
89 static struct mtd_part_parser mtdsplit_lzma_parser
= {
92 .of_match_table
= mtdsplit_lzma_of_match_table
,
93 .parse_fn
= mtdsplit_parse_lzma
,
94 .type
= MTD_PARSER_TYPE_FIRMWARE
,
97 static int __init
mtdsplit_lzma_init(void)
99 register_mtd_parser(&mtdsplit_lzma_parser
);
104 subsys_initcall(mtdsplit_lzma_init
);