aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2013-01-18 04:42:26 -0500
committerVineet Gupta <vgupta@synopsys.com>2013-02-15 12:46:13 -0500
commit03a6d28cdddfbd11b338c23e7fe51d0816b9bdef (patch)
tree740383bea378fd680c35ff9b8c074ac36e2781ee /arch/arc/kernel
parent93ad700de2abc111c50bb961c150a9968d5b3982 (diff)
ARC: [Review] Multi-platform image #2: Board callback Infrastructure
The orig platform code orgnaization was singleton design pattern - only one platform (and board thereof) would build at a time. Thus any platform/board specific code (e.g. irq init, early init ...) expected by ARC common code was exported as well defined set of APIs, with only ONE instance building ever. Now with multiple-platform build requirement, that design of code no longer holds - multiple board specific calls need to build at the same time - so ARC common code can't use the API approach, it needs a callback based design where each board registers it's specific set of functions, and at runtime, depending on board detection, the callbacks are used from the registry. This commit adds all the infrastructure, where board specific callbacks are specified as a "maThine description". All the hooks are placed in right spots, no board callbacks registered yet (with MACHINE_STARt/END constructs) so the hooks will not run. Next commit will actually convert the platform to this infrastructure. Signed-off-by: Vineet Gupta <vgupta@synopsys.com> Cc: Arnd Bergmann <arnd@arndb.de> Acked-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arc/kernel')
-rw-r--r--arch/arc/kernel/devtree.c47
-rw-r--r--arch/arc/kernel/irq.c7
-rw-r--r--arch/arc/kernel/setup.c28
-rw-r--r--arch/arc/kernel/smp.c3
-rw-r--r--arch/arc/kernel/time.c4
-rw-r--r--arch/arc/kernel/vmlinux.lds.S6
6 files changed, 84 insertions, 11 deletions
diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c
index c8166dc02c38..a7d98b30358b 100644
--- a/arch/arc/kernel/devtree.c
+++ b/arch/arc/kernel/devtree.c
@@ -16,6 +16,7 @@
16#include <linux/of_fdt.h> 16#include <linux/of_fdt.h>
17#include <asm/prom.h> 17#include <asm/prom.h>
18#include <asm/clk.h> 18#include <asm/clk.h>
19#include <asm/mach_desc.h>
19 20
20/* called from unflatten_device_tree() to bootstrap devicetree itself */ 21/* called from unflatten_device_tree() to bootstrap devicetree itself */
21void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) 22void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
@@ -30,27 +31,57 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
30 * If a dtb was passed to the kernel, then use it to choose the correct 31 * If a dtb was passed to the kernel, then use it to choose the correct
31 * machine_desc and to setup the system. 32 * machine_desc and to setup the system.
32 */ 33 */
33int __init setup_machine_fdt(void *dt) 34struct machine_desc * __init setup_machine_fdt(void *dt)
34{ 35{
35 struct boot_param_header *devtree = dt; 36 struct boot_param_header *devtree = dt;
37 struct machine_desc *mdesc = NULL, *mdesc_best = NULL;
38 unsigned int score, mdesc_score = ~1;
36 unsigned long dt_root; 39 unsigned long dt_root;
37 char *model, *compat; 40 const char *model, *compat;
38 void *clk; 41 void *clk;
39 char manufacturer[16]; 42 char manufacturer[16];
40 unsigned long len; 43 unsigned long len;
41 44
42 /* check device tree validity */ 45 /* check device tree validity */
43 if (be32_to_cpu(devtree->magic) != OF_DT_HEADER) 46 if (be32_to_cpu(devtree->magic) != OF_DT_HEADER)
44 return 1; 47 return NULL;
45 48
46 /* Search the mdescs for the 'best' compatible value match */
47 initial_boot_params = devtree; 49 initial_boot_params = devtree;
48 dt_root = of_get_flat_dt_root(); 50 dt_root = of_get_flat_dt_root();
49 51
52 /*
53 * The kernel could be multi-platform enabled, thus could have many
54 * "baked-in" machine descriptors. Search thru all for the best
55 * "compatible" string match.
56 */
57 for_each_machine_desc(mdesc) {
58 score = of_flat_dt_match(dt_root, mdesc->dt_compat);
59 if (score > 0 && score < mdesc_score) {
60 mdesc_best = mdesc;
61 mdesc_score = score;
62 }
63 }
64 if (!mdesc_best) {
65 const char *prop;
66 long size;
67
68 pr_err("\n unrecognized device tree list:\n[ ");
69
70 prop = of_get_flat_dt_prop(dt_root, "compatible", &size);
71 if (prop) {
72 while (size > 0) {
73 printk("'%s' ", prop);
74 size -= strlen(prop) + 1;
75 prop += strlen(prop) + 1;
76 }
77 }
78 printk("]\n\n");
79
80 machine_halt();
81 }
82
50 /* compat = "<manufacturer>,<model>" */ 83 /* compat = "<manufacturer>,<model>" */
51 compat = of_get_flat_dt_prop(dt_root, "compatible", NULL); 84 compat = mdesc_best->dt_compat[0];
52 if (!compat)
53 compat = "<unknown>";
54 85
55 model = strchr(compat, ','); 86 model = strchr(compat, ',');
56 if (model) 87 if (model)
@@ -73,5 +104,5 @@ int __init setup_machine_fdt(void *dt)
73 if (clk) 104 if (clk)
74 arc_set_core_freq(of_read_ulong(clk, len/4)); 105 arc_set_core_freq(of_read_ulong(clk, len/4));
75 106
76 return 0; 107 return mdesc_best;
77} 108}
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
index df7da2b5a5bd..1198168850e8 100644
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -13,6 +13,7 @@
13#include <linux/irqdomain.h> 13#include <linux/irqdomain.h>
14#include <asm/sections.h> 14#include <asm/sections.h>
15#include <asm/irq.h> 15#include <asm/irq.h>
16#include <asm/mach_desc.h>
16 17
17/* 18/*
18 * Early Hardware specific Interrupt setup 19 * Early Hardware specific Interrupt setup
@@ -125,9 +126,15 @@ void __init init_IRQ(void)
125 init_onchip_IRQ(); 126 init_onchip_IRQ();
126 plat_init_IRQ(); 127 plat_init_IRQ();
127 128
129 /* Any external intc can be setup here */
130 if (machine_desc->init_irq)
131 machine_desc->init_irq();
132
128#ifdef CONFIG_SMP 133#ifdef CONFIG_SMP
129 /* Master CPU can initialize it's side of IPI */ 134 /* Master CPU can initialize it's side of IPI */
130 arc_platform_smp_init_cpu(); 135 arc_platform_smp_init_cpu();
136 if (machine_desc->init_smp)
137 machine_desc->init_smp(smp_processor_id());
131#endif 138#endif
132} 139}
133 140
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index 6cc361c6751a..20273b89e545 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -25,12 +25,14 @@
25#include <asm/prom.h> 25#include <asm/prom.h>
26#include <asm/unwind.h> 26#include <asm/unwind.h>
27#include <asm/clk.h> 27#include <asm/clk.h>
28#include <asm/mach_desc.h>
28 29
29#define FIX_PTR(x) __asm__ __volatile__(";" : "+r"(x)) 30#define FIX_PTR(x) __asm__ __volatile__(";" : "+r"(x))
30 31
31int running_on_hw = 1; /* vs. on ISS */ 32int running_on_hw = 1; /* vs. on ISS */
32 33
33char __initdata command_line[COMMAND_LINE_SIZE]; 34char __initdata command_line[COMMAND_LINE_SIZE];
35struct machine_desc *machine_desc __initdata;
34 36
35struct task_struct *_current_task[NR_CPUS]; /* For stack switching */ 37struct task_struct *_current_task[NR_CPUS]; /* For stack switching */
36 38
@@ -323,8 +325,6 @@ void __init __attribute__((weak)) arc_platform_early_init(void)
323 325
324void __init setup_arch(char **cmdline_p) 326void __init setup_arch(char **cmdline_p)
325{ 327{
326 int rc;
327
328#ifdef CONFIG_CMDLINE_UBOOT 328#ifdef CONFIG_CMDLINE_UBOOT
329 /* Make sure that a whitespace is inserted before */ 329 /* Make sure that a whitespace is inserted before */
330 strlcat(command_line, " ", sizeof(command_line)); 330 strlcat(command_line, " ", sizeof(command_line));
@@ -339,13 +339,17 @@ void __init setup_arch(char **cmdline_p)
339 strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); 339 strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
340 *cmdline_p = command_line; 340 *cmdline_p = command_line;
341 341
342 rc = setup_machine_fdt(__dtb_start); 342 machine_desc = setup_machine_fdt(__dtb_start);
343 if (!machine_desc)
344 panic("Embedded DT invalid\n");
343 345
344 /* To force early parsing of things like mem=xxx */ 346 /* To force early parsing of things like mem=xxx */
345 parse_early_param(); 347 parse_early_param();
346 348
347 /* Platform/board specific: e.g. early console registration */ 349 /* Platform/board specific: e.g. early console registration */
348 arc_platform_early_init(); 350 arc_platform_early_init();
351 if (machine_desc->init_early)
352 machine_desc->init_early();
349 353
350 setup_processor(); 354 setup_processor();
351 355
@@ -372,6 +376,24 @@ void __init setup_arch(char **cmdline_p)
372 arc_unwind_setup(); 376 arc_unwind_setup();
373} 377}
374 378
379static int __init customize_machine(void)
380{
381 /* Add platform devices */
382 if (machine_desc->init_machine)
383 machine_desc->init_machine();
384
385 return 0;
386}
387arch_initcall(customize_machine);
388
389static int __init init_late_machine(void)
390{
391 if (machine_desc->init_late)
392 machine_desc->init_late();
393
394 return 0;
395}
396late_initcall(init_late_machine);
375/* 397/*
376 * Get CPU information for use by the procfs. 398 * Get CPU information for use by the procfs.
377 */ 399 */
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 1f762ad6969b..ea15f073452f 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -32,6 +32,7 @@
32#include <linux/reboot.h> 32#include <linux/reboot.h>
33#include <asm/processor.h> 33#include <asm/processor.h>
34#include <asm/setup.h> 34#include <asm/setup.h>
35#include <asm/mach_desc.h>
35 36
36arch_spinlock_t smp_atomic_ops_lock = __ARCH_SPIN_LOCK_UNLOCKED; 37arch_spinlock_t smp_atomic_ops_lock = __ARCH_SPIN_LOCK_UNLOCKED;
37arch_spinlock_t smp_bitops_lock = __ARCH_SPIN_LOCK_UNLOCKED; 38arch_spinlock_t smp_bitops_lock = __ARCH_SPIN_LOCK_UNLOCKED;
@@ -127,6 +128,8 @@ void __cpuinit start_kernel_secondary(void)
127 pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu); 128 pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
128 129
129 arc_platform_smp_init_cpu(); 130 arc_platform_smp_init_cpu();
131 if (machine_desc->init_smp)
132 machine_desc->init_smp(smp_processor_id());
130 133
131 arc_local_timer_setup(cpu); 134 arc_local_timer_setup(cpu);
132 135
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index 05dba11fdb2d..0ce0e6f76eb0 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -43,6 +43,7 @@
43#include <asm/irq.h> 43#include <asm/irq.h>
44#include <asm/arcregs.h> 44#include <asm/arcregs.h>
45#include <asm/clk.h> 45#include <asm/clk.h>
46#include <asm/mach_desc.h>
46 47
47#define ARC_TIMER_MAX 0xFFFFFFFF 48#define ARC_TIMER_MAX 0xFFFFFFFF
48 49
@@ -258,6 +259,9 @@ void __init time_init(void)
258 259
259 /* sets up the periodic event timer */ 260 /* sets up the periodic event timer */
260 arc_local_timer_setup(smp_processor_id()); 261 arc_local_timer_setup(smp_processor_id());
262
263 if (machine_desc->init_time)
264 machine_desc->init_time();
261} 265}
262 266
263#ifdef CONFIG_ARC_HAS_RTSC 267#ifdef CONFIG_ARC_HAS_RTSC
diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S
index 8d3b0d447498..622d8b665a68 100644
--- a/arch/arc/kernel/vmlinux.lds.S
+++ b/arch/arc/kernel/vmlinux.lds.S
@@ -75,6 +75,12 @@ SECTIONS
75 SECURITY_INITCALL 75 SECURITY_INITCALL
76 } 76 }
77 77
78 .init.arch.info : {
79 __arch_info_begin = .;
80 *(.arch.info.init)
81 __arch_info_end = .;
82 }
83
78 PERCPU_SECTION(L1_CACHE_BYTES) 84 PERCPU_SECTION(L1_CACHE_BYTES)
79 85
80 /* 86 /*