diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/xtensa/Kconfig | 11 | ||||
-rw-r--r-- | arch/xtensa/Makefile | 7 | ||||
-rw-r--r-- | arch/xtensa/boot/Makefile | 11 | ||||
-rw-r--r-- | arch/xtensa/include/asm/bootparam.h | 1 | ||||
-rw-r--r-- | arch/xtensa/include/asm/prom.h | 6 | ||||
-rw-r--r-- | arch/xtensa/kernel/irq.c | 10 | ||||
-rw-r--r-- | arch/xtensa/kernel/setup.c | 143 |
7 files changed, 164 insertions, 25 deletions
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 1816abc5c8d5..8ceb5b2ffbb1 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
@@ -178,6 +178,17 @@ config CMDLINE | |||
178 | time by entering them here. As a minimum, you should specify the | 178 | time by entering them here. As a minimum, you should specify the |
179 | memory size and the root device (e.g., mem=64M root=/dev/nfs). | 179 | memory size and the root device (e.g., mem=64M root=/dev/nfs). |
180 | 180 | ||
181 | config USE_OF | ||
182 | bool "Flattened Device Tree support" | ||
183 | select OF | ||
184 | select OF_EARLY_FLATTREE | ||
185 | help | ||
186 | Include support for flattened device tree machine descriptions. | ||
187 | |||
188 | config BUILTIN_DTB | ||
189 | string "DTB to build into the kernel image" | ||
190 | depends on OF | ||
191 | |||
181 | source "mm/Kconfig" | 192 | source "mm/Kconfig" |
182 | 193 | ||
183 | source "drivers/pcmcia/Kconfig" | 194 | source "drivers/pcmcia/Kconfig" |
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index ab63c9beb930..227f658fc2b9 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile | |||
@@ -79,6 +79,10 @@ core-y += $(buildvar) $(buildplf) | |||
79 | 79 | ||
80 | libs-y += arch/xtensa/lib/ $(LIBGCC) | 80 | libs-y += arch/xtensa/lib/ $(LIBGCC) |
81 | 81 | ||
82 | ifneq ($(CONFIG_BUILTIN_DTB),"") | ||
83 | core-y += arch/xtensa/boot/ | ||
84 | endif | ||
85 | |||
82 | boot := arch/xtensa/boot | 86 | boot := arch/xtensa/boot |
83 | 87 | ||
84 | all: zImage | 88 | all: zImage |
@@ -88,6 +92,9 @@ bzImage : zImage | |||
88 | zImage: vmlinux | 92 | zImage: vmlinux |
89 | $(Q)$(MAKE) $(build)=$(boot) $@ | 93 | $(Q)$(MAKE) $(build)=$(boot) $@ |
90 | 94 | ||
95 | %.dtb: | ||
96 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ | ||
97 | |||
91 | define archhelp | 98 | define archhelp |
92 | @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)' | 99 | @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)' |
93 | endef | 100 | endef |
diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index ff974fc2935b..cb5ff4dbdf88 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile | |||
@@ -25,6 +25,17 @@ bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf | |||
25 | bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf boot-uboot | 25 | bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf boot-uboot |
26 | 26 | ||
27 | 27 | ||
28 | BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB)).dtb.o | ||
29 | ifneq ($(CONFIG_BUILTIN_DTB),"") | ||
30 | obj-y += $(BUILTIN_DTB) | ||
31 | endif | ||
32 | |||
33 | # Rule to build device tree blobs | ||
34 | $(obj)/%.dtb: $(src)/dts/%.dts FORCE | ||
35 | $(call if_changed_dep,dtc) | ||
36 | |||
37 | clean-files := *.dtb.S | ||
38 | |||
28 | zImage Image: $(bootdir-y) | 39 | zImage Image: $(bootdir-y) |
29 | 40 | ||
30 | $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ | 41 | $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ |
diff --git a/arch/xtensa/include/asm/bootparam.h b/arch/xtensa/include/asm/bootparam.h index 9983f2c1b7ee..057077e96c98 100644 --- a/arch/xtensa/include/asm/bootparam.h +++ b/arch/xtensa/include/asm/bootparam.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #define BP_TAG_MEMORY 0x1003 /* memory addr and size (bp_meminfo) */ | 22 | #define BP_TAG_MEMORY 0x1003 /* memory addr and size (bp_meminfo) */ |
23 | #define BP_TAG_SERIAL_BAUSRATE 0x1004 /* baud rate of current console. */ | 23 | #define BP_TAG_SERIAL_BAUSRATE 0x1004 /* baud rate of current console. */ |
24 | #define BP_TAG_SERIAL_PORT 0x1005 /* serial device of current console */ | 24 | #define BP_TAG_SERIAL_PORT 0x1005 /* serial device of current console */ |
25 | #define BP_TAG_FDT 0x1006 /* flat device tree addr */ | ||
25 | 26 | ||
26 | #define BP_TAG_FIRST 0x7B0B /* first tag with a version number */ | 27 | #define BP_TAG_FIRST 0x7B0B /* first tag with a version number */ |
27 | #define BP_TAG_LAST 0x7E0B /* last tag */ | 28 | #define BP_TAG_LAST 0x7E0B /* last tag */ |
diff --git a/arch/xtensa/include/asm/prom.h b/arch/xtensa/include/asm/prom.h new file mode 100644 index 000000000000..f3d7cd2c0de7 --- /dev/null +++ b/arch/xtensa/include/asm/prom.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef _XTENSA_ASM_PROM_H | ||
2 | #define _XTENSA_ASM_PROM_H | ||
3 | |||
4 | #define HAVE_ARCH_DEVTREE_FIXUPS | ||
5 | |||
6 | #endif /* _XTENSA_ASM_PROM_H */ | ||
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index e90d78211195..6f4f9749cff7 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
20 | #include <linux/kernel_stat.h> | 20 | #include <linux/kernel_stat.h> |
21 | #include <linux/irqdomain.h> | 21 | #include <linux/irqdomain.h> |
22 | #include <linux/of.h> | ||
22 | 23 | ||
23 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
24 | #include <asm/platform.h> | 25 | #include <asm/platform.h> |
@@ -199,8 +200,17 @@ void __init init_IRQ(void) | |||
199 | cached_irq_mask = 0; | 200 | cached_irq_mask = 0; |
200 | set_sr(~0, intclear); | 201 | set_sr(~0, intclear); |
201 | 202 | ||
203 | #ifdef CONFIG_OF | ||
204 | /* The interrupt controller device node is mandatory */ | ||
205 | intc = of_find_compatible_node(NULL, NULL, "xtensa,pic"); | ||
206 | BUG_ON(!intc); | ||
207 | |||
208 | root_domain = irq_domain_add_linear(intc, NR_IRQS, | ||
209 | &xtensa_irq_domain_ops, NULL); | ||
210 | #else | ||
202 | root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0, | 211 | root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0, |
203 | &xtensa_irq_domain_ops, NULL); | 212 | &xtensa_irq_domain_ops, NULL); |
213 | #endif | ||
204 | irq_set_default_host(root_domain); | 214 | irq_set_default_host(root_domain); |
205 | 215 | ||
206 | variant_init_irq(); | 216 | variant_init_irq(); |
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 45217617c60d..64d80e4b0bd4 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c | |||
@@ -22,6 +22,11 @@ | |||
22 | #include <linux/bootmem.h> | 22 | #include <linux/bootmem.h> |
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | 24 | ||
25 | #ifdef CONFIG_OF | ||
26 | #include <linux/of_fdt.h> | ||
27 | #include <linux/of_platform.h> | ||
28 | #endif | ||
29 | |||
25 | #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) | 30 | #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) |
26 | # include <linux/console.h> | 31 | # include <linux/console.h> |
27 | #endif | 32 | #endif |
@@ -65,6 +70,11 @@ int initrd_is_mapped = 0; | |||
65 | extern int initrd_below_start_ok; | 70 | extern int initrd_below_start_ok; |
66 | #endif | 71 | #endif |
67 | 72 | ||
73 | #ifdef CONFIG_OF | ||
74 | extern u32 __dtb_start[]; | ||
75 | void *dtb_start = __dtb_start; | ||
76 | #endif | ||
77 | |||
68 | unsigned char aux_device_present; | 78 | unsigned char aux_device_present; |
69 | extern unsigned long loops_per_jiffy; | 79 | extern unsigned long loops_per_jiffy; |
70 | 80 | ||
@@ -84,6 +94,8 @@ extern void init_mmu(void); | |||
84 | static inline void init_mmu(void) { } | 94 | static inline void init_mmu(void) { } |
85 | #endif | 95 | #endif |
86 | 96 | ||
97 | extern int mem_reserve(unsigned long, unsigned long, int); | ||
98 | extern void bootmem_init(void); | ||
87 | extern void zones_init(void); | 99 | extern void zones_init(void); |
88 | 100 | ||
89 | /* | 101 | /* |
@@ -105,28 +117,33 @@ typedef struct tagtable { | |||
105 | 117 | ||
106 | /* parse current tag */ | 118 | /* parse current tag */ |
107 | 119 | ||
108 | static int __init parse_tag_mem(const bp_tag_t *tag) | 120 | static int __init add_sysmem_bank(unsigned long type, unsigned long start, |
121 | unsigned long end) | ||
109 | { | 122 | { |
110 | meminfo_t *mi = (meminfo_t*)(tag->data); | ||
111 | |||
112 | if (mi->type != MEMORY_TYPE_CONVENTIONAL) | ||
113 | return -1; | ||
114 | |||
115 | if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) { | 123 | if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) { |
116 | printk(KERN_WARNING | 124 | printk(KERN_WARNING |
117 | "Ignoring memory bank 0x%08lx size %ldKB\n", | 125 | "Ignoring memory bank 0x%08lx size %ldKB\n", |
118 | (unsigned long)mi->start, | 126 | start, end - start); |
119 | (unsigned long)mi->end - (unsigned long)mi->start); | ||
120 | return -EINVAL; | 127 | return -EINVAL; |
121 | } | 128 | } |
122 | sysmem.bank[sysmem.nr_banks].type = mi->type; | 129 | sysmem.bank[sysmem.nr_banks].type = type; |
123 | sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(mi->start); | 130 | sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(start); |
124 | sysmem.bank[sysmem.nr_banks].end = mi->end & PAGE_MASK; | 131 | sysmem.bank[sysmem.nr_banks].end = end & PAGE_MASK; |
125 | sysmem.nr_banks++; | 132 | sysmem.nr_banks++; |
126 | 133 | ||
127 | return 0; | 134 | return 0; |
128 | } | 135 | } |
129 | 136 | ||
137 | static int __init parse_tag_mem(const bp_tag_t *tag) | ||
138 | { | ||
139 | meminfo_t *mi = (meminfo_t *)(tag->data); | ||
140 | |||
141 | if (mi->type != MEMORY_TYPE_CONVENTIONAL) | ||
142 | return -1; | ||
143 | |||
144 | return add_sysmem_bank(mi->type, mi->start, mi->end); | ||
145 | } | ||
146 | |||
130 | __tagtable(BP_TAG_MEMORY, parse_tag_mem); | 147 | __tagtable(BP_TAG_MEMORY, parse_tag_mem); |
131 | 148 | ||
132 | #ifdef CONFIG_BLK_DEV_INITRD | 149 | #ifdef CONFIG_BLK_DEV_INITRD |
@@ -143,12 +160,31 @@ static int __init parse_tag_initrd(const bp_tag_t* tag) | |||
143 | 160 | ||
144 | __tagtable(BP_TAG_INITRD, parse_tag_initrd); | 161 | __tagtable(BP_TAG_INITRD, parse_tag_initrd); |
145 | 162 | ||
163 | #ifdef CONFIG_OF | ||
164 | |||
165 | static int __init parse_tag_fdt(const bp_tag_t *tag) | ||
166 | { | ||
167 | dtb_start = (void *)(tag->data[0]); | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | __tagtable(BP_TAG_FDT, parse_tag_fdt); | ||
172 | |||
173 | void __init early_init_dt_setup_initrd_arch(unsigned long start, | ||
174 | unsigned long end) | ||
175 | { | ||
176 | initrd_start = (void *)__va(start); | ||
177 | initrd_end = (void *)__va(end); | ||
178 | initrd_below_start_ok = 1; | ||
179 | } | ||
180 | |||
181 | #endif /* CONFIG_OF */ | ||
182 | |||
146 | #endif /* CONFIG_BLK_DEV_INITRD */ | 183 | #endif /* CONFIG_BLK_DEV_INITRD */ |
147 | 184 | ||
148 | static int __init parse_tag_cmdline(const bp_tag_t* tag) | 185 | static int __init parse_tag_cmdline(const bp_tag_t* tag) |
149 | { | 186 | { |
150 | strncpy(command_line, (char*)(tag->data), COMMAND_LINE_SIZE); | 187 | strlcpy(command_line, (char *)(tag->data), COMMAND_LINE_SIZE); |
151 | command_line[COMMAND_LINE_SIZE - 1] = '\0'; | ||
152 | return 0; | 188 | return 0; |
153 | } | 189 | } |
154 | 190 | ||
@@ -186,6 +222,58 @@ static int __init parse_bootparam(const bp_tag_t* tag) | |||
186 | return 0; | 222 | return 0; |
187 | } | 223 | } |
188 | 224 | ||
225 | #ifdef CONFIG_OF | ||
226 | |||
227 | void __init early_init_dt_add_memory_arch(u64 base, u64 size) | ||
228 | { | ||
229 | size &= PAGE_MASK; | ||
230 | add_sysmem_bank(MEMORY_TYPE_CONVENTIONAL, base, base + size); | ||
231 | } | ||
232 | |||
233 | void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) | ||
234 | { | ||
235 | return __alloc_bootmem(size, align, 0); | ||
236 | } | ||
237 | |||
238 | void __init early_init_devtree(void *params) | ||
239 | { | ||
240 | /* Setup flat device-tree pointer */ | ||
241 | initial_boot_params = params; | ||
242 | |||
243 | /* Retrieve various informations from the /chosen node of the | ||
244 | * device-tree, including the platform type, initrd location and | ||
245 | * size, TCE reserve, and more ... | ||
246 | */ | ||
247 | if (!command_line[0]) | ||
248 | of_scan_flat_dt(early_init_dt_scan_chosen, command_line); | ||
249 | |||
250 | /* Scan memory nodes and rebuild MEMBLOCKs */ | ||
251 | of_scan_flat_dt(early_init_dt_scan_root, NULL); | ||
252 | if (sysmem.nr_banks == 0) | ||
253 | of_scan_flat_dt(early_init_dt_scan_memory, NULL); | ||
254 | } | ||
255 | |||
256 | static void __init copy_devtree(void) | ||
257 | { | ||
258 | void *alloc = early_init_dt_alloc_memory_arch( | ||
259 | be32_to_cpu(initial_boot_params->totalsize), 0); | ||
260 | if (alloc) { | ||
261 | memcpy(alloc, initial_boot_params, | ||
262 | be32_to_cpu(initial_boot_params->totalsize)); | ||
263 | initial_boot_params = alloc; | ||
264 | } | ||
265 | } | ||
266 | |||
267 | static int __init xtensa_device_probe(void) | ||
268 | { | ||
269 | of_platform_populate(NULL, NULL, NULL, NULL); | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | device_initcall(xtensa_device_probe); | ||
274 | |||
275 | #endif /* CONFIG_OF */ | ||
276 | |||
189 | /* | 277 | /* |
190 | * Initialize architecture. (Early stage) | 278 | * Initialize architecture. (Early stage) |
191 | */ | 279 | */ |
@@ -194,14 +282,14 @@ void __init init_arch(bp_tag_t *bp_start) | |||
194 | { | 282 | { |
195 | sysmem.nr_banks = 0; | 283 | sysmem.nr_banks = 0; |
196 | 284 | ||
197 | #ifdef CONFIG_CMDLINE_BOOL | ||
198 | strcpy(command_line, default_command_line); | ||
199 | #endif | ||
200 | |||
201 | /* Parse boot parameters */ | 285 | /* Parse boot parameters */ |
202 | 286 | ||
203 | if (bp_start) | 287 | if (bp_start) |
204 | parse_bootparam(bp_start); | 288 | parse_bootparam(bp_start); |
289 | |||
290 | #ifdef CONFIG_OF | ||
291 | early_init_devtree(dtb_start); | ||
292 | #endif | ||
205 | 293 | ||
206 | if (sysmem.nr_banks == 0) { | 294 | if (sysmem.nr_banks == 0) { |
207 | sysmem.nr_banks = 1; | 295 | sysmem.nr_banks = 1; |
@@ -210,6 +298,11 @@ void __init init_arch(bp_tag_t *bp_start) | |||
210 | + PLATFORM_DEFAULT_MEM_SIZE; | 298 | + PLATFORM_DEFAULT_MEM_SIZE; |
211 | } | 299 | } |
212 | 300 | ||
301 | #ifdef CONFIG_CMDLINE_BOOL | ||
302 | if (!command_line[0]) | ||
303 | strlcpy(command_line, default_command_line, COMMAND_LINE_SIZE); | ||
304 | #endif | ||
305 | |||
213 | /* Early hook for platforms */ | 306 | /* Early hook for platforms */ |
214 | 307 | ||
215 | platform_init(bp_start); | 308 | platform_init(bp_start); |
@@ -355,11 +448,7 @@ void __init check_s32c1i(void) | |||
355 | 448 | ||
356 | void __init setup_arch(char **cmdline_p) | 449 | void __init setup_arch(char **cmdline_p) |
357 | { | 450 | { |
358 | extern int mem_reserve(unsigned long, unsigned long, int); | 451 | strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); |
359 | extern void bootmem_init(void); | ||
360 | |||
361 | memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); | ||
362 | boot_command_line[COMMAND_LINE_SIZE-1] = '\0'; | ||
363 | *cmdline_p = command_line; | 452 | *cmdline_p = command_line; |
364 | 453 | ||
365 | check_s32c1i(); | 454 | check_s32c1i(); |
@@ -395,8 +484,12 @@ void __init setup_arch(char **cmdline_p) | |||
395 | 484 | ||
396 | bootmem_init(); | 485 | bootmem_init(); |
397 | 486 | ||
398 | platform_setup(cmdline_p); | 487 | #ifdef CONFIG_OF |
488 | copy_devtree(); | ||
489 | unflatten_device_tree(); | ||
490 | #endif | ||
399 | 491 | ||
492 | platform_setup(cmdline_p); | ||
400 | 493 | ||
401 | paging_init(); | 494 | paging_init(); |
402 | zones_init(); | 495 | zones_init(); |