xref: /openbmc/linux/arch/mips/kernel/prom.c (revision f2ffa5ab)
1f2ffa5abSDezhong Diao /*
2f2ffa5abSDezhong Diao  * MIPS support for CONFIG_OF device tree support
3f2ffa5abSDezhong Diao  *
4f2ffa5abSDezhong Diao  * Copyright (C) 2010 Cisco Systems Inc. <dediao@cisco.com>
5f2ffa5abSDezhong Diao  *
6f2ffa5abSDezhong Diao  * This program is free software; you can redistribute it and/or modify
7f2ffa5abSDezhong Diao  * it under the terms of the GNU General Public License version 2 as
8f2ffa5abSDezhong Diao  * published by the Free Software Foundation.
9f2ffa5abSDezhong Diao  */
10f2ffa5abSDezhong Diao 
11f2ffa5abSDezhong Diao #include <linux/init.h>
12f2ffa5abSDezhong Diao #include <linux/module.h>
13f2ffa5abSDezhong Diao #include <linux/errno.h>
14f2ffa5abSDezhong Diao #include <linux/types.h>
15f2ffa5abSDezhong Diao #include <linux/bootmem.h>
16f2ffa5abSDezhong Diao #include <linux/initrd.h>
17f2ffa5abSDezhong Diao #include <linux/debugfs.h>
18f2ffa5abSDezhong Diao #include <linux/of.h>
19f2ffa5abSDezhong Diao #include <linux/of_fdt.h>
20f2ffa5abSDezhong Diao #include <linux/of_irq.h>
21f2ffa5abSDezhong Diao #include <linux/of_platform.h>
22f2ffa5abSDezhong Diao 
23f2ffa5abSDezhong Diao #include <asm/page.h>
24f2ffa5abSDezhong Diao #include <asm/prom.h>
25f2ffa5abSDezhong Diao 
26f2ffa5abSDezhong Diao int __init early_init_dt_scan_memory_arch(unsigned long node,
27f2ffa5abSDezhong Diao 					  const char *uname, int depth,
28f2ffa5abSDezhong Diao 					  void *data)
29f2ffa5abSDezhong Diao {
30f2ffa5abSDezhong Diao 	return early_init_dt_scan_memory(node, uname, depth, data);
31f2ffa5abSDezhong Diao }
32f2ffa5abSDezhong Diao 
33f2ffa5abSDezhong Diao void __init early_init_dt_add_memory_arch(u64 base, u64 size)
34f2ffa5abSDezhong Diao {
35f2ffa5abSDezhong Diao 	return add_memory_region(base, size, BOOT_MEM_RAM);
36f2ffa5abSDezhong Diao }
37f2ffa5abSDezhong Diao 
38f2ffa5abSDezhong Diao int __init reserve_mem_mach(unsigned long addr, unsigned long size)
39f2ffa5abSDezhong Diao {
40f2ffa5abSDezhong Diao 	return reserve_bootmem(addr, size, BOOTMEM_DEFAULT);
41f2ffa5abSDezhong Diao }
42f2ffa5abSDezhong Diao 
43f2ffa5abSDezhong Diao void __init free_mem_mach(unsigned long addr, unsigned long size)
44f2ffa5abSDezhong Diao {
45f2ffa5abSDezhong Diao 	return free_bootmem(addr, size);
46f2ffa5abSDezhong Diao }
47f2ffa5abSDezhong Diao 
48f2ffa5abSDezhong Diao u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
49f2ffa5abSDezhong Diao {
50f2ffa5abSDezhong Diao 	return virt_to_phys(
51f2ffa5abSDezhong Diao 		__alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS))
52f2ffa5abSDezhong Diao 		);
53f2ffa5abSDezhong Diao }
54f2ffa5abSDezhong Diao 
55f2ffa5abSDezhong Diao #ifdef CONFIG_BLK_DEV_INITRD
56f2ffa5abSDezhong Diao void __init early_init_dt_setup_initrd_arch(unsigned long start,
57f2ffa5abSDezhong Diao 					    unsigned long end)
58f2ffa5abSDezhong Diao {
59f2ffa5abSDezhong Diao 	initrd_start = (unsigned long)__va(start);
60f2ffa5abSDezhong Diao 	initrd_end = (unsigned long)__va(end);
61f2ffa5abSDezhong Diao 	initrd_below_start_ok = 1;
62f2ffa5abSDezhong Diao }
63f2ffa5abSDezhong Diao #endif
64f2ffa5abSDezhong Diao 
65f2ffa5abSDezhong Diao /*
66f2ffa5abSDezhong Diao  * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
67f2ffa5abSDezhong Diao  *
68f2ffa5abSDezhong Diao  * Currently the mapping mechanism is trivial; simple flat hwirq numbers are
69f2ffa5abSDezhong Diao  * mapped 1:1 onto Linux irq numbers.  Cascaded irq controllers are not
70f2ffa5abSDezhong Diao  * supported.
71f2ffa5abSDezhong Diao  */
72f2ffa5abSDezhong Diao unsigned int irq_create_of_mapping(struct device_node *controller,
73f2ffa5abSDezhong Diao 				   const u32 *intspec, unsigned int intsize)
74f2ffa5abSDezhong Diao {
75f2ffa5abSDezhong Diao 	return intspec[0];
76f2ffa5abSDezhong Diao }
77f2ffa5abSDezhong Diao EXPORT_SYMBOL_GPL(irq_create_of_mapping);
78f2ffa5abSDezhong Diao 
79f2ffa5abSDezhong Diao void __init early_init_devtree(void *params)
80f2ffa5abSDezhong Diao {
81f2ffa5abSDezhong Diao 	/* Setup flat device-tree pointer */
82f2ffa5abSDezhong Diao 	initial_boot_params = params;
83f2ffa5abSDezhong Diao 
84f2ffa5abSDezhong Diao 	/* Retrieve various informations from the /chosen node of the
85f2ffa5abSDezhong Diao 	 * device-tree, including the platform type, initrd location and
86f2ffa5abSDezhong Diao 	 * size, and more ...
87f2ffa5abSDezhong Diao 	 */
88f2ffa5abSDezhong Diao 	of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
89f2ffa5abSDezhong Diao 
90f2ffa5abSDezhong Diao 	/* Scan memory nodes */
91f2ffa5abSDezhong Diao 	of_scan_flat_dt(early_init_dt_scan_root, NULL);
92f2ffa5abSDezhong Diao 	of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL);
93f2ffa5abSDezhong Diao }
94f2ffa5abSDezhong Diao 
95f2ffa5abSDezhong Diao void __init device_tree_init(void)
96f2ffa5abSDezhong Diao {
97f2ffa5abSDezhong Diao 	unsigned long base, size;
98f2ffa5abSDezhong Diao 
99f2ffa5abSDezhong Diao 	if (!initial_boot_params)
100f2ffa5abSDezhong Diao 		return;
101f2ffa5abSDezhong Diao 
102f2ffa5abSDezhong Diao 	base = virt_to_phys((void *)initial_boot_params);
103f2ffa5abSDezhong Diao 	size = initial_boot_params->totalsize;
104f2ffa5abSDezhong Diao 
105f2ffa5abSDezhong Diao 	/* Before we do anything, lets reserve the dt blob */
106f2ffa5abSDezhong Diao 	reserve_mem_mach(base, size);
107f2ffa5abSDezhong Diao 
108f2ffa5abSDezhong Diao 	unflatten_device_tree();
109f2ffa5abSDezhong Diao 
110f2ffa5abSDezhong Diao 	/* free the space reserved for the dt blob */
111f2ffa5abSDezhong Diao 	free_mem_mach(base, size);
112f2ffa5abSDezhong Diao }
113