<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.thinkwiki.org/w/index.php?action=history&amp;feed=atom&amp;title=Fastboot_Patch_2_6_27</id>
	<title>Fastboot Patch 2 6 27 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.thinkwiki.org/w/index.php?action=history&amp;feed=atom&amp;title=Fastboot_Patch_2_6_27"/>
	<link rel="alternate" type="text/html" href="https://www.thinkwiki.org/w/index.php?title=Fastboot_Patch_2_6_27&amp;action=history"/>
	<updated>2026-05-16T18:54:23Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.31.12</generator>
	<entry>
		<id>https://www.thinkwiki.org/w/index.php?title=Fastboot_Patch_2_6_27&amp;diff=39165&amp;oldid=prev</id>
		<title>Blk: Fastboot patch for vanilla 2.6.27</title>
		<link rel="alternate" type="text/html" href="https://www.thinkwiki.org/w/index.php?title=Fastboot_Patch_2_6_27&amp;diff=39165&amp;oldid=prev"/>
		<updated>2008-10-21T19:30:43Z</updated>

		<summary type="html">&lt;p&gt;Fastboot patch for vanilla 2.6.27&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;'''This is the Fastboot Patch to the 2.6.27 Kernel. There have been expressed constents about this so use at your own risk'''&lt;br /&gt;
it does work fine for me!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c&lt;br /&gt;
index b1c723f..d5d30ca 100644&lt;br /&gt;
--- a/drivers/acpi/battery.c&lt;br /&gt;
+++ b/drivers/acpi/battery.c&lt;br /&gt;
@@ -904,5 +904,5 @@ static void __exit acpi_battery_exit(void)&lt;br /&gt;
 #endif&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
-module_init(acpi_battery_init);&lt;br /&gt;
+module_init_async(acpi_battery_init);&lt;br /&gt;
 module_exit(acpi_battery_exit);&lt;br /&gt;
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c&lt;br /&gt;
index 1dfec41..46b3805 100644&lt;br /&gt;
--- a/drivers/acpi/button.c&lt;br /&gt;
+++ b/drivers/acpi/button.c&lt;br /&gt;
@@ -545,5 +545,5 @@ static void __exit acpi_button_exit(void)&lt;br /&gt;
 	remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
-module_init(acpi_button_init);&lt;br /&gt;
+module_init_async(acpi_button_init);&lt;br /&gt;
 module_exit(acpi_button_exit);&lt;br /&gt;
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c&lt;br /&gt;
index 9127036..c07f9ba 100644&lt;br /&gt;
--- a/drivers/acpi/thermal.c&lt;br /&gt;
+++ b/drivers/acpi/thermal.c&lt;br /&gt;
@@ -1876,5 +1876,5 @@ static void __exit acpi_thermal_exit(void)&lt;br /&gt;
 	return;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
-module_init(acpi_thermal_init);&lt;br /&gt;
+module_init_async(acpi_thermal_init);&lt;br /&gt;
 module_exit(acpi_thermal_exit);&lt;br /&gt;
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig&lt;br /&gt;
index 2281b50..8e72c91 100644&lt;br /&gt;
--- a/drivers/md/Kconfig&lt;br /&gt;
+++ b/drivers/md/Kconfig&lt;br /&gt;
@@ -32,7 +32,7 @@ config BLK_DEV_MD&lt;br /&gt;
 &lt;br /&gt;
 config MD_AUTODETECT&lt;br /&gt;
 	bool &amp;quot;Autodetect RAID arrays during kernel boot&amp;quot;&lt;br /&gt;
-	depends on BLK_DEV_MD=y&lt;br /&gt;
+	depends on BLK_DEV_MD&lt;br /&gt;
 	default y&lt;br /&gt;
 	---help---&lt;br /&gt;
 	  If you say Y here, then the kernel will try to autodetect raid&lt;br /&gt;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c&lt;br /&gt;
index c9884bb..a9301a2 100644&lt;br /&gt;
--- a/drivers/pci/pci.c&lt;br /&gt;
+++ b/drivers/pci/pci.c&lt;br /&gt;
@@ -1909,7 +1909,7 @@ static int __devinit pci_setup(char *str)&lt;br /&gt;
 }&lt;br /&gt;
 early_param(&amp;quot;pci&amp;quot;, pci_setup);&lt;br /&gt;
 &lt;br /&gt;
-device_initcall(pci_init);&lt;br /&gt;
+device_initcall_sync(pci_init);&lt;br /&gt;
 &lt;br /&gt;
 EXPORT_SYMBOL(pci_reenable_device);&lt;br /&gt;
 EXPORT_SYMBOL(pci_enable_device_io);&lt;br /&gt;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c&lt;br /&gt;
index d343afa..c431abe 100644&lt;br /&gt;
--- a/drivers/usb/host/ehci-hcd.c&lt;br /&gt;
+++ b/drivers/usb/host/ehci-hcd.c&lt;br /&gt;
@@ -1116,7 +1116,7 @@ err_debug:&lt;br /&gt;
 	clear_bit(USB_EHCI_LOADED, &amp;amp;usb_hcds_loaded);&lt;br /&gt;
 	return retval;&lt;br /&gt;
 }&lt;br /&gt;
-module_init(ehci_hcd_init);&lt;br /&gt;
+module_init_async(ehci_hcd_init);&lt;br /&gt;
 &lt;br /&gt;
 static void __exit ehci_hcd_cleanup(void)&lt;br /&gt;
 {&lt;br /&gt;
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c&lt;br /&gt;
index 8647dab..3f47bf6 100644&lt;br /&gt;
--- a/drivers/usb/host/ohci-hcd.c&lt;br /&gt;
+++ b/drivers/usb/host/ohci-hcd.c&lt;br /&gt;
@@ -1185,7 +1185,7 @@ static int __init ohci_hcd_mod_init(void)&lt;br /&gt;
 	clear_bit(USB_OHCI_LOADED, &amp;amp;usb_hcds_loaded);&lt;br /&gt;
 	return retval;&lt;br /&gt;
 }&lt;br /&gt;
-module_init(ohci_hcd_mod_init);&lt;br /&gt;
+module_init_async(ohci_hcd_mod_init);&lt;br /&gt;
 &lt;br /&gt;
 static void __exit ohci_hcd_mod_exit(void)&lt;br /&gt;
 {&lt;br /&gt;
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c&lt;br /&gt;
index cf5e4cf..a646297 100644&lt;br /&gt;
--- a/drivers/usb/host/uhci-hcd.c&lt;br /&gt;
+++ b/drivers/usb/host/uhci-hcd.c&lt;br /&gt;
@@ -1001,7 +1001,7 @@ static void __exit uhci_hcd_cleanup(void)&lt;br /&gt;
 	clear_bit(USB_UHCI_LOADED, &amp;amp;usb_hcds_loaded);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
-module_init(uhci_hcd_init);&lt;br /&gt;
+module_init_async(uhci_hcd_init);&lt;br /&gt;
 module_exit(uhci_hcd_cleanup);&lt;br /&gt;
 &lt;br /&gt;
 MODULE_AUTHOR(DRIVER_AUTHOR);&lt;br /&gt;
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h&lt;br /&gt;
index 74c5faf..3111159 100644&lt;br /&gt;
--- a/include/asm-generic/vmlinux.lds.h&lt;br /&gt;
+++ b/include/asm-generic/vmlinux.lds.h&lt;br /&gt;
@@ -384,8 +384,12 @@&lt;br /&gt;
   	*(.initcall5.init)						\&lt;br /&gt;
   	*(.initcall5s.init)						\&lt;br /&gt;
 	*(.initcallrootfs.init)						\&lt;br /&gt;
+	*(.initcall6s.init)						\&lt;br /&gt;
+	VMLINUX_SYMBOL(__async_initcall_start) = .;			\&lt;br /&gt;
+	*(.initcall6a.init)						\&lt;br /&gt;
+	VMLINUX_SYMBOL(__async_initcall_end) = .;			\&lt;br /&gt;
   	*(.initcall6.init)						\&lt;br /&gt;
-  	*(.initcall6s.init)						\&lt;br /&gt;
+	VMLINUX_SYMBOL(__device_initcall_end) = .;			\&lt;br /&gt;
   	*(.initcall7.init)						\&lt;br /&gt;
   	*(.initcall7s.init)&lt;br /&gt;
 &lt;br /&gt;
diff --git a/include/linux/init.h b/include/linux/init.h&lt;br /&gt;
index ad63824..af9b3ab 100644&lt;br /&gt;
--- a/include/linux/init.h&lt;br /&gt;
+++ b/include/linux/init.h&lt;br /&gt;
@@ -143,6 +143,8 @@ extern int do_one_initcall(initcall_t fn);&lt;br /&gt;
 extern char __initdata boot_command_line[];&lt;br /&gt;
 extern char *saved_command_line;&lt;br /&gt;
 extern unsigned int reset_devices;&lt;br /&gt;
+extern int do_one_initcall(initcall_t fn);&lt;br /&gt;
+&lt;br /&gt;
 &lt;br /&gt;
 /* used by init/main.c */&lt;br /&gt;
 void setup_arch(char **);&lt;br /&gt;
@@ -197,11 +199,13 @@ extern void (*late_time_init)(void);&lt;br /&gt;
 #define fs_initcall_sync(fn)		__define_initcall(&amp;quot;5s&amp;quot;,fn,5s)&lt;br /&gt;
 #define rootfs_initcall(fn)		__define_initcall(&amp;quot;rootfs&amp;quot;,fn,rootfs)&lt;br /&gt;
 #define device_initcall(fn)		__define_initcall(&amp;quot;6&amp;quot;,fn,6)&lt;br /&gt;
+#define device_initcall_async(fn)	__define_initcall(&amp;quot;6a&amp;quot;, fn, 6a)&lt;br /&gt;
 #define device_initcall_sync(fn)	__define_initcall(&amp;quot;6s&amp;quot;,fn,6s)&lt;br /&gt;
 #define late_initcall(fn)		__define_initcall(&amp;quot;7&amp;quot;,fn,7)&lt;br /&gt;
 #define late_initcall_sync(fn)		__define_initcall(&amp;quot;7s&amp;quot;,fn,7s)&lt;br /&gt;
 &lt;br /&gt;
 #define __initcall(fn) device_initcall(fn)&lt;br /&gt;
+#define __initcall_async(fn) device_initcall_async(fn)&lt;br /&gt;
 &lt;br /&gt;
 #define __exitcall(fn) \&lt;br /&gt;
 	static exitcall_t __exitcall_##fn __exit_call = fn&lt;br /&gt;
@@ -254,6 +258,7 @@ void __init parse_early_param(void);&lt;br /&gt;
  * be one per module.&lt;br /&gt;
  */&lt;br /&gt;
 #define module_init(x)	__initcall(x);&lt;br /&gt;
+#define module_init_async(x)	__initcall_async(x);&lt;br /&gt;
 &lt;br /&gt;
 /**&lt;br /&gt;
  * module_exit() - driver exit entry point&lt;br /&gt;
@@ -276,10 +281,13 @@ void __init parse_early_param(void);&lt;br /&gt;
 #define subsys_initcall(fn)		module_init(fn)&lt;br /&gt;
 #define fs_initcall(fn)			module_init(fn)&lt;br /&gt;
 #define device_initcall(fn)		module_init(fn)&lt;br /&gt;
+#define device_initcall_async(fn)	module_init(fn)&lt;br /&gt;
 #define late_initcall(fn)		module_init(fn)&lt;br /&gt;
 &lt;br /&gt;
 #define security_initcall(fn)		module_init(fn)&lt;br /&gt;
 &lt;br /&gt;
+#define module_init_async(fn)		module_init(fn)&lt;br /&gt;
+&lt;br /&gt;
 /* Each module must use one module_init(). */&lt;br /&gt;
 #define module_init(initfn)					\&lt;br /&gt;
 	static inline initcall_t __inittest(void)		\&lt;br /&gt;
diff --git a/init/Kconfig b/init/Kconfig&lt;br /&gt;
index 5ceff32..bb8d30f 100644&lt;br /&gt;
--- a/init/Kconfig&lt;br /&gt;
+++ b/init/Kconfig&lt;br /&gt;
@@ -524,6 +524,17 @@ config CC_OPTIMIZE_FOR_SIZE&lt;br /&gt;
 &lt;br /&gt;
 	  If unsure, say Y.&lt;br /&gt;
 &lt;br /&gt;
+config FASTBOOT&lt;br /&gt;
+	bool &amp;quot;Fast boot support&amp;quot;&lt;br /&gt;
+	help&lt;br /&gt;
+	  The fastboot option will cause the kernel to try to optimize&lt;br /&gt;
+	  for faster boot. &lt;br /&gt;
+&lt;br /&gt;
+	  This includes doing some of the device initialization asynchronously&lt;br /&gt;
+	  as well as opportunistically trying to mount the root fs early.&lt;br /&gt;
+&lt;br /&gt;
+	  If unsure, say N.&lt;br /&gt;
+&lt;br /&gt;
 config SYSCTL&lt;br /&gt;
 	bool&lt;br /&gt;
 &lt;br /&gt;
diff --git a/init/do_mounts.c b/init/do_mounts.c&lt;br /&gt;
index d055b19..b7b613c 100644&lt;br /&gt;
--- a/init/do_mounts.c&lt;br /&gt;
+++ b/init/do_mounts.c&lt;br /&gt;
@@ -369,9 +369,11 @@ void __init prepare_namespace(void)&lt;br /&gt;
 		ssleep(root_delay);&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
+#ifndef CONFIG_FASTBOOT&lt;br /&gt;
 	/* wait for the known devices to complete their probing */&lt;br /&gt;
 	while (driver_probe_done() != 0)&lt;br /&gt;
 		msleep(100);&lt;br /&gt;
+#endif&lt;br /&gt;
 &lt;br /&gt;
 	md_run_setup();&lt;br /&gt;
 &lt;br /&gt;
diff --git a/init/initramfs.c b/init/initramfs.c&lt;br /&gt;
index 4f5ba75..3d98d25 100644&lt;br /&gt;
--- a/init/initramfs.c&lt;br /&gt;
+++ b/init/initramfs.c&lt;br /&gt;
@@ -5,6 +5,7 @@&lt;br /&gt;
 #include &amp;lt;linux/fcntl.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;linux/delay.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;linux/string.h&amp;gt;&lt;br /&gt;
+#include &amp;lt;linux/dirent.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;linux/syscalls.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;linux/utime.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
@@ -166,8 +167,6 @@ static __initdata char *victim;&lt;br /&gt;
 static __initdata unsigned count;&lt;br /&gt;
 static __initdata loff_t this_header, next_header;&lt;br /&gt;
 &lt;br /&gt;
-static __initdata int dry_run;&lt;br /&gt;
-&lt;br /&gt;
 static inline void __init eat(unsigned n)&lt;br /&gt;
 {&lt;br /&gt;
 	victim += n;&lt;br /&gt;
@@ -229,10 +228,6 @@ static int __init do_header(void)&lt;br /&gt;
 	parse_header(collected);&lt;br /&gt;
 	next_header = this_header + N_ALIGN(name_len) + body_len;&lt;br /&gt;
 	next_header = (next_header + 3) &amp;amp; ~3;&lt;br /&gt;
-	if (dry_run) {&lt;br /&gt;
-		read_into(name_buf, N_ALIGN(name_len), GotName);&lt;br /&gt;
-		return 0;&lt;br /&gt;
-	}&lt;br /&gt;
 	state = SkipIt;&lt;br /&gt;
 	if (name_len &amp;lt;= 0 || name_len &amp;gt; PATH_MAX)&lt;br /&gt;
 		return 0;&lt;br /&gt;
@@ -303,8 +298,6 @@ static int __init do_name(void)&lt;br /&gt;
 		free_hash();&lt;br /&gt;
 		return 0;&lt;br /&gt;
 	}&lt;br /&gt;
-	if (dry_run)&lt;br /&gt;
-		return 0;&lt;br /&gt;
 	clean_path(collected, mode);&lt;br /&gt;
 	if (S_ISREG(mode)) {&lt;br /&gt;
 		int ml = maybe_link();&lt;br /&gt;
@@ -475,10 +468,9 @@ static void __init flush_window(void)&lt;br /&gt;
 	outcnt = 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
-static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)&lt;br /&gt;
+static char * __init unpack_to_rootfs(char *buf, unsigned len)&lt;br /&gt;
 {&lt;br /&gt;
 	int written;&lt;br /&gt;
-	dry_run = check_only;&lt;br /&gt;
 	header_buf = kmalloc(110, GFP_KERNEL);&lt;br /&gt;
 	symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);&lt;br /&gt;
 	name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);&lt;br /&gt;
@@ -573,10 +565,59 @@ skip:&lt;br /&gt;
 	initrd_end = 0;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
+#ifdef CONFIG_BLK_DEV_RAM&lt;br /&gt;
+#define BUF_SIZE 1024&lt;br /&gt;
+static void __init clean_rootfs(void)&lt;br /&gt;
+{&lt;br /&gt;
+	int fd;&lt;br /&gt;
+	void *buf;&lt;br /&gt;
+	struct linux_dirent64 *dirp;&lt;br /&gt;
+	int count;&lt;br /&gt;
+&lt;br /&gt;
+	fd = sys_open(&amp;quot;/&amp;quot;, O_RDONLY, 0);&lt;br /&gt;
+	WARN_ON(fd &amp;lt; 0);&lt;br /&gt;
+	if (fd &amp;lt; 0)&lt;br /&gt;
+		return;&lt;br /&gt;
+	buf = kzalloc(BUF_SIZE, GFP_KERNEL);&lt;br /&gt;
+	WARN_ON(!buf);&lt;br /&gt;
+	if (!buf) {&lt;br /&gt;
+		sys_close(fd);&lt;br /&gt;
+		return;&lt;br /&gt;
+	}&lt;br /&gt;
+&lt;br /&gt;
+	dirp = buf;&lt;br /&gt;
+	count = sys_getdents64(fd, dirp, BUF_SIZE);&lt;br /&gt;
+	while (count &amp;gt; 0) {&lt;br /&gt;
+		while (count &amp;gt; 0) {&lt;br /&gt;
+			struct stat st;&lt;br /&gt;
+			int ret;&lt;br /&gt;
+&lt;br /&gt;
+			ret = sys_newlstat(dirp-&amp;gt;d_name, &amp;amp;st);&lt;br /&gt;
+			WARN_ON_ONCE(ret);&lt;br /&gt;
+			if (!ret) {&lt;br /&gt;
+				if (S_ISDIR(st.st_mode))&lt;br /&gt;
+					sys_rmdir(dirp-&amp;gt;d_name);&lt;br /&gt;
+				else&lt;br /&gt;
+					sys_unlink(dirp-&amp;gt;d_name);&lt;br /&gt;
+			}&lt;br /&gt;
+&lt;br /&gt;
+			count -= dirp-&amp;gt;d_reclen;&lt;br /&gt;
+			dirp = (void *)dirp + dirp-&amp;gt;d_reclen;&lt;br /&gt;
+		}&lt;br /&gt;
+		dirp = buf;&lt;br /&gt;
+		memset(buf, 0, BUF_SIZE);&lt;br /&gt;
+		count = sys_getdents64(fd, dirp, BUF_SIZE);&lt;br /&gt;
+	}&lt;br /&gt;
+&lt;br /&gt;
+	sys_close(fd);&lt;br /&gt;
+	kfree(buf);&lt;br /&gt;
+}&lt;br /&gt;
+#endif&lt;br /&gt;
+&lt;br /&gt;
 static int __init populate_rootfs(void)&lt;br /&gt;
 {&lt;br /&gt;
 	char *err = unpack_to_rootfs(__initramfs_start,&lt;br /&gt;
-			 __initramfs_end - __initramfs_start, 0);&lt;br /&gt;
+			 __initramfs_end - __initramfs_start);&lt;br /&gt;
 	if (err)&lt;br /&gt;
 		panic(err);&lt;br /&gt;
 	if (initrd_start) {&lt;br /&gt;
@@ -584,13 +625,15 @@ static int __init populate_rootfs(void)&lt;br /&gt;
 		int fd;&lt;br /&gt;
 		printk(KERN_INFO &amp;quot;checking if image is initramfs...&amp;quot;);&lt;br /&gt;
 		err = unpack_to_rootfs((char *)initrd_start,&lt;br /&gt;
-			initrd_end - initrd_start, 1);&lt;br /&gt;
+			initrd_end - initrd_start);&lt;br /&gt;
 		if (!err) {&lt;br /&gt;
 			printk(&amp;quot; it is\n&amp;quot;);&lt;br /&gt;
-			unpack_to_rootfs((char *)initrd_start,&lt;br /&gt;
-				initrd_end - initrd_start, 0);&lt;br /&gt;
 			free_initrd();&lt;br /&gt;
 			return 0;&lt;br /&gt;
+		} else {&lt;br /&gt;
+			clean_rootfs();&lt;br /&gt;
+			unpack_to_rootfs(__initramfs_start,&lt;br /&gt;
+				 __initramfs_end - __initramfs_start);&lt;br /&gt;
 		}&lt;br /&gt;
 		printk(&amp;quot;it isn't (%s); looks like an initrd\n&amp;quot;, err);&lt;br /&gt;
 		fd = sys_open(&amp;quot;/initrd.image&amp;quot;, O_WRONLY|O_CREAT, 0700);&lt;br /&gt;
@@ -603,7 +646,7 @@ static int __init populate_rootfs(void)&lt;br /&gt;
 #else&lt;br /&gt;
 		printk(KERN_INFO &amp;quot;Unpacking initramfs...&amp;quot;);&lt;br /&gt;
 		err = unpack_to_rootfs((char *)initrd_start,&lt;br /&gt;
-			initrd_end - initrd_start, 0);&lt;br /&gt;
+			initrd_end - initrd_start);&lt;br /&gt;
 		if (err)&lt;br /&gt;
 			panic(err);&lt;br /&gt;
 		printk(&amp;quot; done\n&amp;quot;);&lt;br /&gt;
diff --git a/init/main.c b/init/main.c&lt;br /&gt;
index 27f6bf6..68f38ee 100644&lt;br /&gt;
--- a/init/main.c&lt;br /&gt;
+++ b/init/main.c&lt;br /&gt;
@@ -745,16 +745,68 @@ int do_one_initcall(initcall_t fn)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];&lt;br /&gt;
+extern initcall_t __async_initcall_start[], __async_initcall_end[];&lt;br /&gt;
+extern initcall_t __device_initcall_end[];&lt;br /&gt;
 &lt;br /&gt;
-static void __init do_initcalls(void)&lt;br /&gt;
+static void __init do_async_initcalls(struct work_struct *dummy)&lt;br /&gt;
 {&lt;br /&gt;
 	initcall_t *call;&lt;br /&gt;
 &lt;br /&gt;
-	for (call = __early_initcall_end; call &amp;lt; __initcall_end; call++)&lt;br /&gt;
+	/*&lt;br /&gt;
+	 * For compatibility with normal init calls... take the BKL&lt;br /&gt;
+	 * not pretty, not desirable, but compatibility first&lt;br /&gt;
+	 */&lt;br /&gt;
+	lock_kernel();&lt;br /&gt;
+	for (call = __async_initcall_start; call &amp;lt; __async_initcall_end; call++)&lt;br /&gt;
 		do_one_initcall(*call);&lt;br /&gt;
+	unlock_kernel();&lt;br /&gt;
+}&lt;br /&gt;
+&lt;br /&gt;
+static struct workqueue_struct *async_init_wq;&lt;br /&gt;
 &lt;br /&gt;
-	/* Make sure there is no pending stuff from the initcall sequence */&lt;br /&gt;
+&lt;br /&gt;
+&lt;br /&gt;
+static void __init do_initcalls(void)&lt;br /&gt;
+{&lt;br /&gt;
+	initcall_t *call;&lt;br /&gt;
+	static DECLARE_WORK(async_work, do_async_initcalls);&lt;br /&gt;
+	/*&lt;br /&gt;
+	 * 0 = levels 0 - 6,&lt;br /&gt;
+	 * 1 = level 6a,&lt;br /&gt;
+	 * 2 = after level 6a,&lt;br /&gt;
+	 * 3 = after level 6&lt;br /&gt;
+	 */&lt;br /&gt;
+	int phase = 0;&lt;br /&gt;
+&lt;br /&gt;
+	async_init_wq = create_singlethread_workqueue(&amp;quot;kasyncinit&amp;quot;);&lt;br /&gt;
+&lt;br /&gt;
+	for (call = __early_initcall_end; call &amp;lt; __initcall_end; call++) {&lt;br /&gt;
+		if (phase == 0 &amp;amp;&amp;amp; call &amp;gt;= __async_initcall_start) {&lt;br /&gt;
+			phase = 1;&lt;br /&gt;
+#ifdef CONFIG_FASTBOOT&lt;br /&gt;
+			queue_work(async_init_wq, &amp;amp;async_work);&lt;br /&gt;
+#else&lt;br /&gt;
+			do_async_initcalls(NULL);&lt;br /&gt;
+#endif&lt;br /&gt;
+		}&lt;br /&gt;
+		if (phase == 1 &amp;amp;&amp;amp; call &amp;gt;= __async_initcall_end)&lt;br /&gt;
+			phase = 2;&lt;br /&gt;
+		if (phase == 2 &amp;amp;&amp;amp; call &amp;gt;= __device_initcall_end) {&lt;br /&gt;
+			phase = 3;&lt;br /&gt;
+			/* make sure all async work is done before level 7 */&lt;br /&gt;
+			flush_workqueue(async_init_wq);&lt;br /&gt;
+		}&lt;br /&gt;
+		if (phase != 1)&lt;br /&gt;
+			do_one_initcall(*call);&lt;br /&gt;
+	}&lt;br /&gt;
+&lt;br /&gt;
+	/*&lt;br /&gt;
+	 * Make sure there is no pending stuff from the initcall sequence,&lt;br /&gt;
+	 * including the async initcalls&lt;br /&gt;
+	 */&lt;br /&gt;
 	flush_scheduled_work();&lt;br /&gt;
+	flush_workqueue(async_init_wq);&lt;br /&gt;
+	destroy_workqueue(async_init_wq);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /*&lt;br /&gt;
@@ -794,6 +846,7 @@ static void run_init_process(char *init_filename)&lt;br /&gt;
  */&lt;br /&gt;
 static int noinline init_post(void)&lt;br /&gt;
 {&lt;br /&gt;
+	int retry_count = 1;&lt;br /&gt;
 	free_initmem();&lt;br /&gt;
 	unlock_kernel();&lt;br /&gt;
 	mark_rodata_ro();&lt;br /&gt;
@@ -814,6 +867,7 @@ static int noinline init_post(void)&lt;br /&gt;
 				ramdisk_execute_command);&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
+retry:&lt;br /&gt;
 	/*&lt;br /&gt;
 	 * We try each of these until one succeeds.&lt;br /&gt;
 	 *&lt;br /&gt;
@@ -826,6 +880,23 @@ static int noinline init_post(void)&lt;br /&gt;
 					&amp;quot;defaults...\n&amp;quot;, execute_command);&lt;br /&gt;
 	}&lt;br /&gt;
 	run_init_process(&amp;quot;/sbin/init&amp;quot;);&lt;br /&gt;
+&lt;br /&gt;
+	if (retry_count &amp;gt; 0) {&lt;br /&gt;
+		retry_count--;&lt;br /&gt;
+		/* &lt;br /&gt;
+		 * We haven't found init yet... potentially because the device&lt;br /&gt;
+		 * is still being probed. We need to&lt;br /&gt;
+		 * - flush keventd and friends&lt;br /&gt;
+		 * - wait for the known devices to complete their probing&lt;br /&gt;
+		 * - try to mount the root fs again&lt;br /&gt;
+		 */&lt;br /&gt;
+		flush_scheduled_work();&lt;br /&gt;
+		while (driver_probe_done() != 0)&lt;br /&gt;
+			msleep(100);&lt;br /&gt;
+		prepare_namespace();&lt;br /&gt;
+		goto retry;&lt;br /&gt;
+	}&lt;br /&gt;
+	&lt;br /&gt;
 	run_init_process(&amp;quot;/etc/init&amp;quot;);&lt;br /&gt;
 	run_init_process(&amp;quot;/bin/init&amp;quot;);&lt;br /&gt;
 	run_init_process(&amp;quot;/bin/sh&amp;quot;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Blk</name></author>
		
	</entry>
</feed>