diff options
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0028-fastboot-sync-the-async-execution-before-late_initc.patch')
-rw-r--r-- | meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0028-fastboot-sync-the-async-execution-before-late_initc.patch | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0028-fastboot-sync-the-async-execution-before-late_initc.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0028-fastboot-sync-the-async-execution-before-late_initc.patch new file mode 100644 index 0000000000..0700fb3189 --- /dev/null +++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0028-fastboot-sync-the-async-execution-before-late_initc.patch | |||
@@ -0,0 +1,95 @@ | |||
1 | From 660625fb93f2fc0e633da9cb71d13d895b385f64 Mon Sep 17 00:00:00 2001 | ||
2 | From: Arjan van de Ven <arjan@linux.intel.com> | ||
3 | Date: Sun, 20 Jul 2008 09:00:41 -0700 | ||
4 | Subject: [PATCH] fastboot: sync the async execution before late_initcall and move level 6s (sync) first | ||
5 | |||
6 | Rene Herman points out several cases where it's basically needed to have | ||
7 | all level 6/6a/6s calls done before the level 7 (late_initcall) code | ||
8 | runs. This patch adds a sync point in the transition from the 6's to the | ||
9 | 7's. | ||
10 | |||
11 | Second, this patch makes sure that level 6s (sync) happens before the | ||
12 | async code starts, and puts a user in driver/pci in this category that | ||
13 | needs to happen before device init. | ||
14 | |||
15 | Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> | ||
16 | Signed-off-by: Ingo Molnar <mingo@elte.hu> | ||
17 | --- | ||
18 | drivers/pci/pci.c | 2 +- | ||
19 | include/asm-generic/vmlinux.lds.h | 3 ++- | ||
20 | init/main.c | 14 +++++++++++++- | ||
21 | 3 files changed, 16 insertions(+), 3 deletions(-) | ||
22 | |||
23 | diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c | ||
24 | index 44a46c9..d75295d 100644 | ||
25 | --- a/drivers/pci/pci.c | ||
26 | +++ b/drivers/pci/pci.c | ||
27 | @@ -1889,7 +1889,7 @@ static int __devinit pci_setup(char *str) | ||
28 | } | ||
29 | early_param("pci", pci_setup); | ||
30 | |||
31 | -device_initcall(pci_init); | ||
32 | +device_initcall_sync(pci_init); | ||
33 | |||
34 | EXPORT_SYMBOL(pci_reenable_device); | ||
35 | EXPORT_SYMBOL(pci_enable_device_io); | ||
36 | diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h | ||
37 | index 39c1afc..020c641 100644 | ||
38 | --- a/include/asm-generic/vmlinux.lds.h | ||
39 | +++ b/include/asm-generic/vmlinux.lds.h | ||
40 | @@ -372,11 +372,12 @@ | ||
41 | *(.initcall5.init) \ | ||
42 | *(.initcall5s.init) \ | ||
43 | *(.initcallrootfs.init) \ | ||
44 | + *(.initcall6s.init) \ | ||
45 | __async_initcall_start = .; \ | ||
46 | *(.initcall6a.init) \ | ||
47 | __async_initcall_end = .; \ | ||
48 | *(.initcall6.init) \ | ||
49 | - *(.initcall6s.init) \ | ||
50 | + __device_initcall_end = .; \ | ||
51 | *(.initcall7.init) \ | ||
52 | *(.initcall7s.init) | ||
53 | |||
54 | diff --git a/init/main.c b/init/main.c | ||
55 | index 9e2aee8..6be1756 100644 | ||
56 | --- a/init/main.c | ||
57 | +++ b/init/main.c | ||
58 | @@ -739,6 +739,7 @@ static void __init do_one_initcall(initcall_t fn) | ||
59 | |||
60 | extern initcall_t __initcall_start[], __initcall_end[]; | ||
61 | extern initcall_t __async_initcall_start[], __async_initcall_end[]; | ||
62 | +extern initcall_t __device_initcall_end[]; | ||
63 | |||
64 | static void __init do_async_initcalls(struct work_struct *dummy) | ||
65 | { | ||
66 | @@ -762,7 +763,13 @@ static void __init do_initcalls(void) | ||
67 | { | ||
68 | initcall_t *call; | ||
69 | static DECLARE_WORK(async_work, do_async_initcalls); | ||
70 | - int phase = 0; /* 0 = levels 0 - 6, 1 = level 6a, 2 = after level 6a */ | ||
71 | + /* | ||
72 | + * 0 = levels 0 - 6, | ||
73 | + * 1 = level 6a, | ||
74 | + * 2 = after level 6a, | ||
75 | + * 3 = after level 6 | ||
76 | + */ | ||
77 | + int phase = 0; | ||
78 | |||
79 | async_init_wq = create_singlethread_workqueue("kasyncinit"); | ||
80 | |||
81 | @@ -773,6 +780,11 @@ static void __init do_initcalls(void) | ||
82 | } | ||
83 | if (phase == 1 && call >= __async_initcall_end) | ||
84 | phase = 2; | ||
85 | + if (phase == 2 && call >= __device_initcall_end) { | ||
86 | + phase = 3; | ||
87 | + /* make sure all async work is done before level 7 */ | ||
88 | + flush_workqueue(async_init_wq); | ||
89 | + } | ||
90 | if (phase != 1) | ||
91 | do_one_initcall(*call); | ||
92 | } | ||
93 | -- | ||
94 | 1.5.4.3 | ||
95 | |||