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); 103e31fee7cSThomas Chou size = be32_to_cpu(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