aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/devices/block2mtd.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 66f0405f7e53..b16f3cda97ff 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -9,7 +9,15 @@
9 9
10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11 11
12/*
13 * When the first attempt at device initialization fails, we may need to
14 * wait a little bit and retry. This timeout, by default 3 seconds, gives
15 * device time to start up. Required on BCM2708 and a few other chipsets.
16 */
17#define MTD_DEFAULT_TIMEOUT 3
18
12#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/delay.h>
13#include <linux/fs.h> 21#include <linux/fs.h>
14#include <linux/blkdev.h> 22#include <linux/blkdev.h>
15#include <linux/bio.h> 23#include <linux/bio.h>
@@ -209,10 +217,14 @@ static void block2mtd_free_device(struct block2mtd_dev *dev)
209} 217}
210 218
211 219
212static struct block2mtd_dev *add_device(char *devname, int erase_size) 220static struct block2mtd_dev *add_device(char *devname, int erase_size,
221 int timeout)
213{ 222{
223#ifndef MODULE
224 int i;
225#endif
214 const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL; 226 const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
215 struct block_device *bdev; 227 struct block_device *bdev = ERR_PTR(-ENODEV);
216 struct block2mtd_dev *dev; 228 struct block2mtd_dev *dev;
217 char *name; 229 char *name;
218 230
@@ -225,15 +237,28 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
225 237
226 /* Get a handle on the device */ 238 /* Get a handle on the device */
227 bdev = blkdev_get_by_path(devname, mode, dev); 239 bdev = blkdev_get_by_path(devname, mode, dev);
228#ifndef MODULE
229 if (IS_ERR(bdev)) {
230
231 /* We might not have rootfs mounted at this point. Try
232 to resolve the device name by other means. */
233 240
234 dev_t devt = name_to_dev_t(devname); 241#ifndef MODULE
235 if (devt) 242 /*
236 bdev = blkdev_get_by_dev(devt, mode, dev); 243 * We might not have the root device mounted at this point.
244 * Try to resolve the device name by other means.
245 */
246 for (i = 0; IS_ERR(bdev) && i <= timeout; i++) {
247 dev_t devt;
248
249 if (i)
250 /*
251 * Calling wait_for_device_probe in the first loop
252 * was not enough, sleep for a bit in subsequent
253 * go-arounds.
254 */
255 msleep(1000);
256 wait_for_device_probe();
257
258 devt = name_to_dev_t(devname);
259 if (!devt)
260 continue;
261 bdev = blkdev_get_by_dev(devt, mode, dev);
237 } 262 }
238#endif 263#endif
239 264
@@ -280,6 +305,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
280 /* Device didn't get added, so free the entry */ 305 /* Device didn't get added, so free the entry */
281 goto err_destroy_mutex; 306 goto err_destroy_mutex;
282 } 307 }
308
283 list_add(&dev->list, &blkmtd_device_list); 309 list_add(&dev->list, &blkmtd_device_list);
284 pr_info("mtd%d: [%s] erase_size = %dKiB [%d]\n", 310 pr_info("mtd%d: [%s] erase_size = %dKiB [%d]\n",
285 dev->mtd.index, 311 dev->mtd.index,
@@ -348,16 +374,19 @@ static inline void kill_final_newline(char *str)
348 374
349#ifndef MODULE 375#ifndef MODULE
350static int block2mtd_init_called = 0; 376static int block2mtd_init_called = 0;
351static char block2mtd_paramline[80 + 12]; /* 80 for device, 12 for erase size */ 377/* 80 for device, 12 for erase size */
378static char block2mtd_paramline[80 + 12];
352#endif 379#endif
353 380
354static int block2mtd_setup2(const char *val) 381static int block2mtd_setup2(const char *val)
355{ 382{
356 char buf[80 + 12]; /* 80 for device, 12 for erase size */ 383 /* 80 for device, 12 for erase size, 80 for name, 8 for timeout */
384 char buf[80 + 12 + 80 + 8];
357 char *str = buf; 385 char *str = buf;
358 char *token[2]; 386 char *token[2];
359 char *name; 387 char *name;
360 size_t erase_size = PAGE_SIZE; 388 size_t erase_size = PAGE_SIZE;
389 unsigned long timeout = MTD_DEFAULT_TIMEOUT;
361 int i, ret; 390 int i, ret;
362 391
363 if (strnlen(val, sizeof(buf)) >= sizeof(buf)) { 392 if (strnlen(val, sizeof(buf)) >= sizeof(buf)) {
@@ -395,7 +424,7 @@ static int block2mtd_setup2(const char *val)
395 } 424 }
396 } 425 }
397 426
398 add_device(name, erase_size); 427 add_device(name, erase_size, timeout);
399 428
400 return 0; 429 return 0;
401} 430}
@@ -463,8 +492,7 @@ static void block2mtd_exit(void)
463 } 492 }
464} 493}
465 494
466 495late_initcall(block2mtd_init);
467module_init(block2mtd_init);
468module_exit(block2mtd_exit); 496module_exit(block2mtd_exit);
469 497
470MODULE_LICENSE("GPL"); 498MODULE_LICENSE("GPL");