diff options
author | Michal Simek <monstr@monstr.eu> | 2011-04-14 05:48:43 -0400 |
---|---|---|
committer | Michal Simek <monstr@monstr.eu> | 2011-07-25 03:25:13 -0400 |
commit | 2aa8e37596933a43fc3e46e1e385045635674429 (patch) | |
tree | 79cbf1212d42d583a5a5951e28d90e27e94df4e4 /arch/microblaze | |
parent | e721a45fbed13a52093d2cc1962dbb8a754462ea (diff) |
microblaze: Simplify early console binding from DT
Recognize early Linux console from chosen - linux,stdout-path
instead of detecting the first console with appropriate
compatible strings.
This patch solved the problem on system with multiple
consoles.
Signed-off-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'arch/microblaze')
-rw-r--r-- | arch/microblaze/include/asm/prom.h | 8 | ||||
-rw-r--r-- | arch/microblaze/kernel/early_printk.c | 48 | ||||
-rw-r--r-- | arch/microblaze/kernel/prom.c | 96 |
3 files changed, 70 insertions, 82 deletions
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index d0890d36ef61..34c4e8b27805 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h | |||
@@ -26,8 +26,12 @@ | |||
26 | #define HAVE_ARCH_DEVTREE_FIXUPS | 26 | #define HAVE_ARCH_DEVTREE_FIXUPS |
27 | 27 | ||
28 | /* Other Prototypes */ | 28 | /* Other Prototypes */ |
29 | extern int early_uartlite_console(void); | 29 | enum early_consoles { |
30 | extern int early_uart16550_console(void); | 30 | UARTLITE = 1, |
31 | UART16550 = 2, | ||
32 | }; | ||
33 | |||
34 | extern int of_early_console(void *version); | ||
31 | 35 | ||
32 | #ifdef CONFIG_PCI | 36 | #ifdef CONFIG_PCI |
33 | /* | 37 | /* |
diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c index 8f8384e98bf7..e21390da0a4d 100644 --- a/arch/microblaze/kernel/early_printk.c +++ b/arch/microblaze/kernel/early_printk.c | |||
@@ -127,45 +127,41 @@ void early_printk(const char *fmt, ...) | |||
127 | 127 | ||
128 | int __init setup_early_printk(char *opt) | 128 | int __init setup_early_printk(char *opt) |
129 | { | 129 | { |
130 | int version = 0; | ||
131 | |||
130 | if (early_console_initialized) | 132 | if (early_console_initialized) |
131 | return 1; | 133 | return 1; |
132 | 134 | ||
133 | #ifdef CONFIG_SERIAL_UARTLITE_CONSOLE | 135 | base_addr = of_early_console(&version); |
134 | base_addr = early_uartlite_console(); | ||
135 | if (base_addr) { | 136 | if (base_addr) { |
136 | early_console_initialized = 1; | ||
137 | #ifdef CONFIG_MMU | 137 | #ifdef CONFIG_MMU |
138 | early_console_reg_tlb_alloc(base_addr); | 138 | early_console_reg_tlb_alloc(base_addr); |
139 | #endif | 139 | #endif |
140 | early_console = &early_serial_uartlite_console; | 140 | switch (version) { |
141 | early_printk("early_printk_console is enabled at 0x%08x\n", | 141 | #ifdef CONFIG_SERIAL_UARTLITE_CONSOLE |
142 | base_addr); | 142 | case UARTLITE: |
143 | 143 | printk(KERN_INFO "Early console on uartlite " | |
144 | register_console(early_console); | 144 | "at 0x%08x\n", base_addr); |
145 | 145 | early_console = &early_serial_uartlite_console; | |
146 | return 0; | 146 | break; |
147 | } | 147 | #endif |
148 | #endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */ | ||
149 | |||
150 | #ifdef CONFIG_SERIAL_8250_CONSOLE | 148 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
151 | base_addr = early_uart16550_console(); | 149 | case UART16550: |
152 | base_addr &= ~3; /* clear register offset */ | 150 | printk(KERN_INFO "Early console on uart16650 " |
153 | if (base_addr) { | 151 | "at 0x%08x\n", base_addr); |
154 | early_console_initialized = 1; | 152 | early_console = &early_serial_uart16550_console; |
155 | #ifdef CONFIG_MMU | 153 | break; |
156 | early_console_reg_tlb_alloc(base_addr); | ||
157 | #endif | 154 | #endif |
158 | early_console = &early_serial_uart16550_console; | 155 | default: |
159 | 156 | printk(KERN_INFO "Unsupported early console %d\n", | |
160 | early_printk("early_printk_console is enabled at 0x%08x\n", | 157 | version); |
161 | base_addr); | 158 | return 1; |
159 | } | ||
162 | 160 | ||
163 | register_console(early_console); | 161 | register_console(early_console); |
164 | 162 | early_console_initialized = 1; | |
165 | return 0; | 163 | return 0; |
166 | } | 164 | } |
167 | #endif /* CONFIG_SERIAL_8250_CONSOLE */ | ||
168 | |||
169 | return 1; | 165 | return 1; |
170 | } | 166 | } |
171 | 167 | ||
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c index b15cc219b1d9..18d9371d9b26 100644 --- a/arch/microblaze/kernel/prom.c +++ b/arch/microblaze/kernel/prom.c | |||
@@ -53,69 +53,57 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) | |||
53 | } | 53 | } |
54 | 54 | ||
55 | #ifdef CONFIG_EARLY_PRINTK | 55 | #ifdef CONFIG_EARLY_PRINTK |
56 | /* MS this is Microblaze specifig function */ | 56 | char *stdout; |
57 | static int __init early_init_dt_scan_serial(unsigned long node, | ||
58 | const char *uname, int depth, void *data) | ||
59 | { | ||
60 | unsigned long l; | ||
61 | char *p; | ||
62 | const __be32 *addr; | ||
63 | |||
64 | pr_debug("search \"serial\", depth: %d, uname: %s\n", depth, uname); | ||
65 | |||
66 | /* find all serial nodes */ | ||
67 | if (strncmp(uname, "serial", 6) != 0) | ||
68 | return 0; | ||
69 | |||
70 | /* find compatible node with uartlite */ | ||
71 | p = of_get_flat_dt_prop(node, "compatible", &l); | ||
72 | if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) && | ||
73 | (strncmp(p, "xlnx,opb-uartlite", 17) != 0) && | ||
74 | (strncmp(p, "xlnx,axi-uartlite", 17) != 0)) | ||
75 | return 0; | ||
76 | |||
77 | addr = of_get_flat_dt_prop(node, "reg", &l); | ||
78 | return be32_to_cpup(addr); /* return address */ | ||
79 | } | ||
80 | 57 | ||
81 | /* this function is looking for early uartlite console - Microblaze specific */ | 58 | int __init early_init_dt_scan_chosen_serial(unsigned long node, |
82 | int __init early_uartlite_console(void) | ||
83 | { | ||
84 | return of_scan_flat_dt(early_init_dt_scan_serial, NULL); | ||
85 | } | ||
86 | |||
87 | /* MS this is Microblaze specifig function */ | ||
88 | static int __init early_init_dt_scan_serial_full(unsigned long node, | ||
89 | const char *uname, int depth, void *data) | 59 | const char *uname, int depth, void *data) |
90 | { | 60 | { |
91 | unsigned long l; | 61 | unsigned long l; |
92 | char *p; | 62 | char *p; |
93 | unsigned int addr; | ||
94 | |||
95 | pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); | ||
96 | |||
97 | /* find all serial nodes */ | ||
98 | if (strncmp(uname, "serial", 6) != 0) | ||
99 | return 0; | ||
100 | 63 | ||
101 | early_init_dt_check_for_initrd(node); | 64 | pr_debug("%s: depth: %d, uname: %s\n", __func__, depth, uname); |
102 | 65 | ||
103 | /* find compatible node with uartlite */ | 66 | if (depth == 1 && (strcmp(uname, "chosen") == 0 || |
104 | p = of_get_flat_dt_prop(node, "compatible", &l); | 67 | strcmp(uname, "chosen@0") == 0)) { |
105 | 68 | p = of_get_flat_dt_prop(node, "linux,stdout-path", &l); | |
106 | if ((strncmp(p, "xlnx,xps-uart16550", 18) != 0) && | 69 | if (p != NULL && l > 0) |
107 | (strncmp(p, "xlnx,axi-uart16550", 18) != 0)) | 70 | stdout = p; /* store pointer to stdout-path */ |
108 | return 0; | 71 | } |
109 | 72 | ||
110 | addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l); | 73 | if (stdout && strstr(stdout, uname)) { |
111 | addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l); | 74 | p = of_get_flat_dt_prop(node, "compatible", &l); |
112 | return be32_to_cpu(addr); /* return address */ | 75 | pr_debug("Compatible string: %s\n", p); |
76 | |||
77 | if ((strncmp(p, "xlnx,xps-uart16550", 18) == 0) || | ||
78 | (strncmp(p, "xlnx,axi-uart16550", 18) == 0)) { | ||
79 | unsigned int addr; | ||
80 | |||
81 | *(u32 *)data = UART16550; | ||
82 | |||
83 | addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l); | ||
84 | addr += *(u32 *)of_get_flat_dt_prop(node, | ||
85 | "reg-offset", &l); | ||
86 | /* clear register offset */ | ||
87 | return be32_to_cpu(addr) & ~3; | ||
88 | } | ||
89 | if ((strncmp(p, "xlnx,xps-uartlite", 17) == 0) || | ||
90 | (strncmp(p, "xlnx,opb-uartlite", 17) == 0) || | ||
91 | (strncmp(p, "xlnx,axi-uartlite", 17) == 0)) { | ||
92 | unsigned int *addrp; | ||
93 | |||
94 | *(u32 *)data = UARTLITE; | ||
95 | |||
96 | addrp = of_get_flat_dt_prop(node, "reg", &l); | ||
97 | return be32_to_cpup(addrp); /* return address */ | ||
98 | } | ||
99 | } | ||
100 | return 0; | ||
113 | } | 101 | } |
114 | 102 | ||
115 | /* this function is looking for early uartlite console - Microblaze specific */ | 103 | /* this function is looking for early console - Microblaze specific */ |
116 | int __init early_uart16550_console(void) | 104 | int __init of_early_console(void *version) |
117 | { | 105 | { |
118 | return of_scan_flat_dt(early_init_dt_scan_serial_full, NULL); | 106 | return of_scan_flat_dt(early_init_dt_scan_chosen_serial, version); |
119 | } | 107 | } |
120 | #endif | 108 | #endif |
121 | 109 | ||