From de1230ab3be91cea8e4a51211b0d1ce24cc85d81 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Sat, 15 Sep 2018 00:01:17 +0200 Subject: target/linux/mediatek: add all other patches --- .../mediatek/patches/0441-block2mtd_probe.patch | 266 +++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 target/linux/mediatek/patches/0441-block2mtd_probe.patch (limited to 'target/linux/mediatek/patches/0441-block2mtd_probe.patch') diff --git a/target/linux/mediatek/patches/0441-block2mtd_probe.patch b/target/linux/mediatek/patches/0441-block2mtd_probe.patch new file mode 100644 index 0000000..5fdbcbc --- /dev/null +++ b/target/linux/mediatek/patches/0441-block2mtd_probe.patch @@ -0,0 +1,266 @@ +Index: linux-3.10.20/drivers/mtd/devices/block2mtd.c +=================================================================== +--- linux-3.10.20.orig/drivers/mtd/devices/block2mtd.c ++++ linux-3.10.20/drivers/mtd/devices/block2mtd.c +@@ -7,6 +7,7 @@ + * Licence: GPL + */ + #include ++#include + #include + #include + #include +@@ -32,10 +33,18 @@ struct block2mtd_dev { + }; + + ++/* the mtd parsers we want to use */ ++static const char * const block2mtd_probe_types[] = { "cmdlinepart", NULL }; ++ ++/* we can map a single or a list of partitions */ ++enum { ++ B2M_SINGLE = 0, ++ B2M_PARSER, ++}; ++ + /* Static info about the MTD, used in cleanup_module */ + static LIST_HEAD(blkmtd_device_list); + +- + static struct page *page_read(struct address_space *mapping, int index) + { + return read_mapping_page(mapping, index, NULL); +@@ -211,14 +220,16 @@ static void block2mtd_free_device(struct + + + /* FIXME: ensure that mtd->size % erase_size == 0 */ +-static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname) ++static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname, int timeout, int offset, int length, int mtdparts) + { + const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL; +- struct block_device *bdev; ++ struct block_device *bdev = ERR_PTR(-ENODEV); + struct block2mtd_dev *dev; + struct mtd_partition *part; + char *name; +- ++#ifndef MODULE ++ int i; ++#endif + if (!devname) + return NULL; + +@@ -228,15 +239,20 @@ static struct block2mtd_dev *add_device( + + /* Get a handle on the device */ + bdev = blkdev_get_by_path(devname, mode, dev); ++ + #ifndef MODULE +- if (IS_ERR(bdev)) { ++ for (i = 0; IS_ERR(bdev) && i <= timeout; i++) { ++ dev_t devt; + +- /* We might not have rootfs mounted at this point. Try +- to resolve the device name by other means. */ ++ if (i) ++ msleep(1000); ++ wait_for_device_probe(); ++ ++ devt = name_to_dev_t(devname); ++ if (!devt) ++ continue; + +- dev_t devt = name_to_dev_t(devname); +- if (devt) +- bdev = blkdev_get_by_dev(devt, mode, dev); ++ bdev = blkdev_get_by_dev(devt, mode, dev); + } + #endif + +@@ -251,6 +267,16 @@ static struct block2mtd_dev *add_device( + goto devinit_err; + } + ++ if (length && (long)length % erase_size) { ++ pr_err("length must be a divisor of device size\n"); ++ goto devinit_err; ++ } ++ ++ if (offset && (long)offset % erase_size) { ++ pr_err("offset must be a divisor of device size\n"); ++ goto devinit_err; ++ } ++ + mutex_init(&dev->write_mutex); + + /* Setup the MTD structure */ +@@ -277,6 +303,7 @@ static struct block2mtd_dev *add_device( + dev->mtd.priv = dev; + dev->mtd.owner = THIS_MODULE; + ++#if 0 + part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL); + part->name = name; + part->offset = 0; +@@ -285,6 +312,31 @@ static struct block2mtd_dev *add_device( + /* Device didn't get added, so free the entry */ + goto devinit_err; + } ++#else ++ if (mtdparts == B2M_PARSER) { ++ struct mtd_part_parser_data ppdata = { 0 }; ++ if (mtd_device_parse_register(&dev->mtd, block2mtd_probe_types, &ppdata, NULL, 0)) { ++ /* Device didn't get added, so free the entry */ ++ goto devinit_err; ++ } ++ } else { ++ part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL); ++ part->name = name; ++ if (offset) { ++ part->offset = 0; ++ if (length && offset + length <= dev->mtd.size) ++ part->size = length; ++ else ++ part->size = dev->mtd.size - part->offset; ++ } else { ++ part->size = dev->mtd.size; ++ } ++ if (mtd_device_register(&dev->mtd, part, 1)) { ++ /* Device didn't get added, so free the entry */ ++ goto devinit_err; ++ } ++ } ++#endif + list_add(&dev->list, &blkmtd_device_list); + INFO("mtd%d: [%s] erase_size = %dKiB [%d]", dev->mtd.index, + mtdname, dev->mtd.erasesize >> 10, dev->mtd.erasesize); +@@ -354,17 +406,20 @@ static inline void kill_final_newline(ch + + #ifndef MODULE + static int block2mtd_init_called = 0; +-static char block2mtd_paramline[80 + 12]; /* 80 for device, 12 for erase size */ ++static char block2mtd_paramline[80 + 12 + 80 + 8]; /* 80 for device, 12 for erase size */ ++static char block2mtdparts_paramline[80 + 12 + 80 + 8]; /* 80 for device, 12 for erase size */ ++ + #endif + + +-static int block2mtd_setup2(const char *val) ++static int block2mtd_setup2(const char *val, int mtdparts) + { +- char buf[80 + 12 + 80]; /* 80 for device, 12 for erase size, 80 for name */ ++ char buf[80 + 12 + 80 + 8 + 12 + 12]; /* 80 for device, 12 for erase size, 80 for name, 8 for timeout, 12 for offset, 12 for size */ + char *str = buf; +- char *token[3]; ++ char *token[6]; + char *name; + size_t erase_size = PAGE_SIZE; ++ unsigned long timeout = 0, offset = 0, length = 0; + int i, ret; + + if (strnlen(val, sizeof(buf)) >= sizeof(buf)) +@@ -373,7 +428,7 @@ static int block2mtd_setup2(const char * + strcpy(str, val); + kill_final_newline(str); + +- for (i = 0; i < 3; i++) ++ for (i = 0; i < 6; i++) + token[i] = strsep(&str, ","); + + if (str) +@@ -395,7 +450,16 @@ static int block2mtd_setup2(const char * + if (token[2] && (strlen(token[2]) + 1 > 80)) + parse_err("mtd device name too long"); + +- add_device(name, erase_size, token[2]); ++ if (token[3] && kstrtoul(token[3], 0, &timeout)) ++ parse_err("invalid timeout"); ++ ++ if (token[4] && kstrtoul(token[4], 0, &offset)) ++ pr_err("invalid offset\n"); ++ ++ if (token[5] && kstrtoul(token[5], 0, &length)) ++ pr_err("invalid length\n"); ++ ++ add_device(name, erase_size, token[2], timeout, offset, length, mtdparts); + + return 0; + } +@@ -404,7 +468,7 @@ static int block2mtd_setup2(const char * + static int block2mtd_setup(const char *val, struct kernel_param *kp) + { + #ifdef MODULE +- return block2mtd_setup2(val); ++ return block2mtd_setup2(val, B2M_SINGLE); + #else + /* If more parameters are later passed in via + /sys/module/block2mtd/parameters/block2mtd +@@ -412,7 +476,7 @@ static int block2mtd_setup(const char *v + we can parse the argument now. */ + + if (block2mtd_init_called) +- return block2mtd_setup2(val); ++ return block2mtd_setup2(val, B2M_SINGLE); + + /* During early boot stage, we only save the parameters + here. We must parse them later: if the param passed +@@ -428,8 +492,38 @@ static int block2mtd_setup(const char *v + } + + ++static int block2mtdparts_setup(const char *val, struct kernel_param *kp) ++{ ++#ifdef MODULE ++ return block2mtd_setup2(val, B2M_PARSER); ++#else ++ /* If more parameters are later passed in via ++ /sys/module/block2mtd/parameters/block2mtd ++ and block2mtd_init() has already been called, ++ we can parse the argument now. */ ++ ++ if (block2mtd_init_called) ++ return block2mtd_setup2(val, B2M_PARSER); ++ ++ /* During early boot stage, we only save the parameters ++ here. We must parse them later: if the param passed ++ from kernel boot command line, block2mtd_setup() is ++ called so early that it is not possible to resolve ++ the device (even kmalloc() fails). Deter that work to ++ block2mtd_setup2(). */ ++ ++ strlcpy(block2mtdparts_paramline, val, sizeof(block2mtdparts_paramline)); ++ ++ return 0; ++#endif ++} ++ ++ + module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); +-MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=[,[,]]\""); ++MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=[,[,[,]]]\""); ++ ++module_param_call(block2mtdparts, block2mtdparts_setup, NULL, NULL, 0200); ++MODULE_PARM_DESC(block2mtdparts, "Device to use. \"block2mtdparts=[,[,[,]]]\""); + + static int __init block2mtd_init(void) + { +@@ -437,7 +531,9 @@ static int __init block2mtd_init(void) + + #ifndef MODULE + if (strlen(block2mtd_paramline)) +- ret = block2mtd_setup2(block2mtd_paramline); ++ ret = block2mtd_setup2(block2mtd_paramline, B2M_SINGLE); ++ if (strlen(block2mtdparts_paramline)) ++ ret = block2mtd_setup2(block2mtdparts_paramline, B2M_PARSER); + block2mtd_init_called = 1; + #endif + +@@ -462,7 +558,7 @@ static void block2mtd_exit(void) + } + + +-module_init(block2mtd_init); ++late_initcall(block2mtd_init); + module_exit(block2mtd_exit); + + MODULE_LICENSE("GPL"); -- cgit v1.1