/** * fdt_init_reserved_mem - allocate and init all saved reserved memory regions */ void __init fdt_init_reserved_mem(void) { int i; /* check for overlapping reserved regions */ __rmem_check_for_overlap(); for (i = 0; i < reserved_mem_count; i++) { struct reserved_mem *rmem = &reserved_mem[i]; unsigned long node = rmem->fdt_node; int len; const __be32 *prop; int err = 0; prop = of_get_flat_dt_prop(node, "phandle", &len); if (!prop) prop = of_get_flat_dt_prop(node, "linux,phandle", &len); if (prop) rmem->phandle = of_read_number(prop, len/4); if (rmem->size == 0) err = __reserved_mem_alloc_size(node, rmem->name, &rmem->base, &rmem->size); if (err == 0) __reserved_mem_init_node(rmem); } }
static int __init early_init_dt_scan_epapr(unsigned long node, const char *uname, int depth, void *data) { const u32 *insts; int len; int i; insts = of_get_flat_dt_prop(node, "hcall-instructions", &len); if (!insts) return 0; if (len % 4 || len > (4 * 4)) return -1; for (i = 0; i < (len / 4); i++) { u32 inst = be32_to_cpu(insts[i]); patch_instruction(epapr_hypercall_start + i, inst); #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64) patch_instruction(epapr_ev_idle_start + i, inst); #endif } #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64) if (of_get_flat_dt_prop(node, "has-idle", NULL)) epapr_has_idle = true; #endif epapr_paravirt_enabled = true; return 1; }
static int __init dt_get_boot_common(unsigned long node, const char *uname, int depth, void *data) { struct tag *tags = NULL; char *ptr = NULL, *br_ptr = NULL; if (depth != 1 ||(strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) return 0; tags = (struct tag*)of_get_flat_dt_prop(node, "atag,boot", NULL); if (tags) g_boot_mode = tags->u.boot.bootmode; else pr_warn("'atag,boot' is not found\n"); ptr = (char *)of_get_flat_dt_prop(node, "bootargs", NULL); if (ptr) { if ((br_ptr = strstr(ptr, "boot_reason=")) != 0) g_boot_reason = br_ptr[12] - '0'; /* get boot reason */ else pr_warn("'boot_reason=' is not found\n"); pr_debug("%s\n", ptr); } else pr_warn("'bootargs' is not found\n"); /* break now */ return 1; }
static int __init mmp_fdt_find_fb_info(unsigned long node, const char *uname, int depth, void *data) { __be32 *prop; unsigned long len; if (!of_flat_dt_is_compatible(node, "marvell,mmp-fb")) return 0; prop = of_get_flat_dt_prop(node, "marvell,buffer-num", &len); if (!prop || (len != sizeof(u32))) { pr_err("%s: Can't find buf num property\n", __func__); return 0; } buf_num = be32_to_cpu(prop[0]); prop = of_get_flat_dt_prop(node, "marvell,fb-mem", &len); if (!prop || (len != sizeof(u32))) { pr_err("%s: Can't find fb-mem property\n", __func__); return 0; } fb_addr = be32_to_cpu(prop[0]); return 1; }
static int extmem_scan_memory(unsigned long node, const char *uname, int depth, void *data) { mem_desc_t *mem_desc; char *type = NULL; /* We are scanning "memory" nodes only */ type = of_get_flat_dt_prop(node, "device_type", NULL); if (type == NULL) { /* * The longtrail doesn't have a device_type on the * /memory node, so look for the node called /memory@0. */ if (depth != 1 || strcmp(uname, "memory@0") != 0) return 0; } else if (strcmp(type, "memory") != 0) { return 0; } /* lca reserved memory */ mem_desc = (mem_desc_t *)of_get_flat_dt_prop(node, "lca_reserved_mem", NULL); if (mem_desc && mem_desc->size) { extmem_phys_base = mem_desc->start; extmem_mspace_size = mem_desc->size; extmem_printk("[EXT_MEM] extmem_scan_memory extmem_phys_base: %p, extmem_mspace_size: 0x%zx\n", (void *)extmem_phys_base, extmem_mspace_size); } return node; }
void __init walk_drmem_lmbs_early(unsigned long node, void (*func)(struct drmem_lmb *, const __be32 **)) { const __be32 *prop, *usm; int len; prop = of_get_flat_dt_prop(node, "ibm,lmb-size", &len); if (!prop || len < dt_root_size_cells * sizeof(__be32)) return; drmem_info->lmb_size = dt_mem_next_cell(dt_root_size_cells, &prop); usm = of_get_flat_dt_prop(node, "linux,drconf-usable-memory", &len); prop = of_get_flat_dt_prop(node, "ibm,dynamic-memory", &len); if (prop) { __walk_drmem_v1_lmbs(prop, usm, func); } else { prop = of_get_flat_dt_prop(node, "ibm,dynamic-memory-v2", &len); if (prop) __walk_drmem_v2_lmbs(prop, usm, func); } memblock_dump_all(); }
int __init cma_fdt_scan(unsigned long node, const char *uname, int depth, void *data) { int ret; char *p; unsigned long l; phys_addr_t base, size; unsigned long len; __be32 *prop; if (strncmp(uname, "region@", 7) != 0 || depth != 2 || !of_get_flat_dt_prop(node, "linux,contiguous-region", NULL)) return 0; prop = of_get_flat_dt_prop(node, "reg", &len); if (!prop || (len != 2 * sizeof(unsigned long))) return 0; base = be32_to_cpu(prop[0]); size = be32_to_cpu(prop[1]); pr_info("Found %s, memory base %lx, size %ld MiB\n", uname, (unsigned long)base, (unsigned long)size / SZ_1M); ret = dma_contiguous_reserve_area(size, &base, 0); if(ret == 0) { p = of_get_flat_dt_prop(node, "region_name", &l); if(p != 0 && l > 0) strncpy(cma_areas[cma_area_count - 1].name, p, CMA_REGION_NAME_MAX); } return 0; }
/* * Called very early, MMU is off, device-tree isn't unflattened */ static int __init probe_fw_features(unsigned long node, const char *uname, int depth, void *data) { const char *prop; int len; static int hypertas_found; static int vec5_found; if (depth != 1) return 0; if (!strcmp(uname, "rtas") || !strcmp(uname, "rtas@0")) { prop = of_get_flat_dt_prop(node, "ibm,hypertas-functions", &len); if (prop) { powerpc_firmware_features |= FW_FEATURE_LPAR; fw_hypertas_feature_init(prop, len); } hypertas_found = 1; } if (!strcmp(uname, "chosen")) { prop = of_get_flat_dt_prop(node, "ibm,architecture-vec-5", &len); if (prop) fw_vec5_feature_init(prop, len); vec5_found = 1; } return hypertas_found && vec5_found; }
/** * fdt_scan_reserved_mem() - scan a single FDT node for reserved memory */ static int __init __fdt_scan_reserved_mem(unsigned long node, const char *uname, int depth, void *data) { static int found; const char *status; int err; if (!found && depth == 1 && strcmp(uname, "reserved-memory") == 0) { if (__reserved_mem_check_root(node) != 0) { pr_err("Reserved memory: unsupported node format, ignoring\n"); /* break scan */ return 1; } found = 1; /* scan next node */ return 0; } else if (!found) { /* scan next node */ return 0; } else if (found && depth < 2) { /* scanning of /reserved-memory has been finished */ return 1; } status = of_get_flat_dt_prop(node, "status", NULL); if (status && strcmp(status, "okay") != 0 && strcmp(status, "ok") != 0) return 0; err = __reserved_mem_reserve_reg(node, uname); if (err == -ENOENT && of_get_flat_dt_prop(node, "size", NULL)) fdt_reserved_mem_save_node(node, uname, 0, 0); /* scan next node */ return 0; }
void __init earlyl_init_dt_get_ion_info(unsigned long node) { __be32 *prop; if(owl_fb_size == 0) { prop = of_get_flat_dt_prop(node, "fb_heap_size", NULL); if (prop) { owl_fb_size = be32_to_cpup(prop) * SZ_1M; printk("find owl_fb_size=0x%x\n", owl_fb_size); } } if(owl_kinfo_size == 0) { prop = of_get_flat_dt_prop(node, "kinfo_heap_size", NULL); if (prop) { owl_kinfo_size = be32_to_cpup(prop) * SZ_1M; printk("find owl_kinfo_size=0x%x\n", owl_kinfo_size); } } #ifdef CONFIG_ION if(owl_ion0_size == 0) { prop = of_get_flat_dt_prop(node, "carveout_heap_size", NULL); if (prop) { owl_ion0_size = be32_to_cpup(prop) * SZ_1M; printk("find owl_ion0_size=0x%x\n", owl_ion0_size); } } if(owl_ion1_size == 0) { prop = of_get_flat_dt_prop(node, "dma_heap_size", NULL); if (prop) { owl_ion1_size = be32_to_cpup(prop) * SZ_1M; printk("find owl_ion1_size=0x%x\n", owl_ion1_size); } } #endif }
static int dt_scan_memory(unsigned long node, const char *uname, int depth, void *data) { char *type = of_get_flat_dt_prop(node, "device_type", NULL); __be32 *reg, *endp; unsigned long l; /* We are scanning "memory" nodes only */ if (type == NULL) { /* * The longtrail doesn't have a device_type on the * /memory node, so look for the node called /memory@0. */ if (depth != 1 || strcmp(uname, "memory@0") != 0) return 0; } else if (strcmp(type, "memory") != 0) return 0; reg = of_get_flat_dt_prop(node, "reg", &l); if (reg == NULL) return 0; endp = reg + (l / sizeof(__be32)); *(unsigned long*)data = node; return node; }
/* MS this is Microblaze specifig function */ static int __init early_init_dt_scan_serial_full(unsigned long node, const char *uname, int depth, void *data) { unsigned long l; char *p; unsigned int addr; pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); /* find all serial nodes */ if (strncmp(uname, "serial", 6) != 0) return 0; early_init_dt_check_for_initrd(node); /* find compatible node with uartlite */ p = of_get_flat_dt_prop(node, "compatible", &l); if ((strncmp(p, "xlnx,xps-uart16550", 18) != 0) && (strncmp(p, "xlnx,axi-uart16550", 18) != 0)) return 0; addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l); addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l); return be32_to_cpu(addr); /* return address */ }
int __init s5p_fdt_find_mfc_mem(unsigned long node, const char *uname, int depth, void *data) { __be32 *prop; unsigned long len; struct s5p_mfc_dt_meminfo *mfc_mem = data; if (!data) return 0; if (!of_flat_dt_is_compatible(node, mfc_mem->compatible)) return 0; prop = of_get_flat_dt_prop(node, "samsung,mfc-l", &len); if (!prop || (len != 2 * sizeof(unsigned long))) return 0; mfc_mem->loff = be32_to_cpu(prop[0]); mfc_mem->lsize = be32_to_cpu(prop[1]); prop = of_get_flat_dt_prop(node, "samsung,mfc-r", &len); if (!prop || (len != 2 * sizeof(unsigned long))) return 0; mfc_mem->roff = be32_to_cpu(prop[0]); mfc_mem->rsize = be32_to_cpu(prop[1]); return 1; }
static void __init setup_machine_fdt(phys_addr_t dt_phys) { unsigned long dt_root; if (!dt_phys || !early_init_dt_scan(phys_to_virt(dt_phys))) { early_print("\n" "Error: invalid device tree blob at physical address 0x%p (virtual address 0x%p)\n" "The dtb must be 8-byte aligned and passed in the first 512MB of memory\n" "\nPlease check your bootloader.\n", dt_phys, phys_to_virt(dt_phys)); while (true) cpu_relax(); } dt_root = of_get_flat_dt_root(); /* for hacking machine desc, not upstream */ machine_desc = get_machine_desc_compatible(); if (machine_desc) early_print("find compat machine_desc %s\n", machine_desc->name); machine_name = of_get_flat_dt_prop(dt_root, "model", NULL); if (!machine_name) machine_name = of_get_flat_dt_prop(dt_root, "compatible", NULL); if (!machine_name) machine_name = "<unknown>"; pr_info("Machine: %s\n", machine_name); }
const char * __init of_flat_dt_get_machine_name(void) { const char *name; unsigned long dt_root = of_get_flat_dt_root(); name = of_get_flat_dt_prop(dt_root, "model", NULL); if (!name) name = of_get_flat_dt_prop(dt_root, "compatible", NULL); return name; }
/* return the actual physical DRAM size */ static u64 kernel_mem_sz; static u64 phone_dram_sz; /* original phone DRAM size */ static int dt_scan_memory(unsigned long node, const char *uname, int depth, void *data) { char *type = of_get_flat_dt_prop(node, "device_type", NULL); int i; __be32 *reg, *endp; unsigned long l; dram_info_t *dram_info; /* We are scanning "memory" nodes only */ if (type == NULL) { /* * The longtrail doesn't have a device_type on the * /memory node, so look for the node called /memory@0. */ if (depth != 1 || strcmp(uname, "memory@0") != 0) return 0; } else if (strcmp(type, "memory") != 0) { return 0; } /* * Use kernel_mem_sz if phone_dram_sz is not available (workaround) * Projects use device tree should have orig_dram_info entry in their * device tree. * After the porting is done, kernel_mem_sz will be removed. */ reg = of_get_flat_dt_prop(node, "reg", &l); if (reg == NULL) return 0; endp = reg + (l / sizeof(__be32)); while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { u64 base, size; base = dt_mem_next_cell(dt_root_addr_cells, ®); size = dt_mem_next_cell(dt_root_size_cells, ®); if (size == 0) continue; kernel_mem_sz += size; } /* orig_dram_info */ dram_info = (dram_info_t *)of_get_flat_dt_prop(node, "orig_dram_info", NULL); if (dram_info) { for (i = 0; i < dram_info->rank_num; i++) phone_dram_sz += dram_info->rank_info[i].size; } return node; }
static int __init dt_cpu_ftrs_scan_callback(unsigned long node, const char *uname, int depth, void *data) { const __be32 *prop; int count, i; u32 isa; /* We are scanning "ibm,powerpc-cpu-features" nodes only */ if (!of_flat_dt_is_compatible(node, "ibm,powerpc-cpu-features")) return 0; prop = of_get_flat_dt_prop(node, "isa", NULL); if (!prop) /* We checked before, "can't happen" */ return 0; isa = be32_to_cpup(prop); /* Count and allocate space for cpu features */ of_scan_flat_dt_subnodes(node, count_cpufeatures_subnodes, &nr_dt_cpu_features); dt_cpu_features = __va( memblock_alloc(sizeof(struct dt_cpu_feature)* nr_dt_cpu_features, PAGE_SIZE)); cpufeatures_setup_start(isa); /* Scan nodes into dt_cpu_features and enable those without deps */ count = 0; of_scan_flat_dt_subnodes(node, scan_cpufeatures_subnodes, &count); /* Recursive enable remaining features with dependencies */ for (i = 0; i < nr_dt_cpu_features; i++) { struct dt_cpu_feature *f = &dt_cpu_features[i]; cpufeatures_deps_enable(f); } prop = of_get_flat_dt_prop(node, "display-name", NULL); if (prop && strlen((char *)prop) != 0) { strlcpy(dt_cpu_name, (char *)prop, sizeof(dt_cpu_name)); cur_cpu_spec->cpu_name = dt_cpu_name; } cpufeatures_setup_finished(); memblock_free(__pa(dt_cpu_features), sizeof(struct dt_cpu_feature)*nr_dt_cpu_features); return 0; }
static void __init setup_machine_fdt(phys_addr_t dt_phys) { struct boot_param_header *devtree; unsigned long dt_root; cpuinfo_store_cpu(); /* Check we have a non-NULL DT pointer */ if (!dt_phys) { early_print("\n" "Error: NULL or invalid device tree blob\n" "The dtb must be 8-byte aligned and passed in the first 512MB of memory\n" "\nPlease check your bootloader.\n"); while (true) cpu_relax(); } devtree = phys_to_virt(dt_phys); /* Check device tree validity */ if (be32_to_cpu(devtree->magic) != OF_DT_HEADER) { early_print("\n" "Error: invalid device tree blob at physical address 0x%p (virtual address 0x%p)\n" "Expected 0x%x, found 0x%x\n" "\nPlease check your bootloader.\n", dt_phys, devtree, OF_DT_HEADER, be32_to_cpu(devtree->magic)); while (true) cpu_relax(); } initial_boot_params = devtree; dt_root = of_get_flat_dt_root(); machine_name = of_get_flat_dt_prop(dt_root, "model", NULL); if (!machine_name) machine_name = of_get_flat_dt_prop(dt_root, "compatible", NULL); if (!machine_name) machine_name = "<unknown>"; pr_info("Machine: %s\n", machine_name); /* Retrieve various information from the /chosen node */ of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line); /* Initialize {size,address}-cells info */ of_scan_flat_dt(early_init_dt_scan_root, NULL); /* Setup memory, calling early_init_dt_add_memory_arch */ of_scan_flat_dt(early_init_dt_scan_memory, NULL); }
int __init early_init_dt_scan_pinmux(unsigned long node, const char *uname, int depth, void *data) { const char *prop; unsigned long size, i; uint32_t *p; /*printk(KERN_INFO "%s: node=0x%lx, uname=%s, depth=%d\n", __func__, node, uname, depth);*/ if (depth != 1 || strcmp(uname, "pinmux") != 0) return 0; /* not found, continue... */ prop = of_get_flat_dt_prop(node, "reg", &i); if(!prop) return 1; p = (uint32_t *)prop; i = be32_to_cpu(p[1]); printk(KERN_INFO "reg: 0x%x, 0x%x\n", be32_to_cpu(p[0]), be32_to_cpu(p[1])); /* check the base address passed */ if (be32_to_cpu(p[0]) != PAD_CTRL_BASE_ADDR){ printk(KERN_ERR "Wrong base address!\n"); return 1; } prop = of_get_flat_dt_prop(node, "data", &size); printk("data(0x%x): size=%ld\n", (unsigned int)prop, size); /* Save it */ dt_pinmux_nr = size/4; if (i != dt_pinmux_nr) { printk(KERN_ERR "Mismatch size! %ld & %d\n", i, dt_pinmux_nr); dt_pinmux_nr = 0; } else if (dt_pinmux_nr > PN_MAX) { printk(KERN_ERR "Wrong pad number!\n"); dt_pinmux_nr = 0; } else { p = (uint32_t *)prop; for (i = 0; i < dt_pinmux_nr; i++){ dt_pinmux[i] = be32_to_cpu(p[i]); //printk(KERN_INFO "%d: 0x%x\n", i, dt_pinmux[i]); } } return 1; }
int __init early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data) { const void *basep, *entryp, *sizep; int basesz, entrysz, runtimesz; if (depth != 1 || strcmp(uname, "ibm,opal") != 0) return 0; basep = of_get_flat_dt_prop(node, "opal-base-address", &basesz); entryp = of_get_flat_dt_prop(node, "opal-entry-address", &entrysz); sizep = of_get_flat_dt_prop(node, "opal-runtime-size", &runtimesz); if (!basep || !entryp || !sizep) return 1; opal.base = of_read_number(basep, basesz/4); opal.entry = of_read_number(entryp, entrysz/4); opal.size = of_read_number(sizep, runtimesz/4); pr_debug("OPAL Base = 0x%llx (basep=%p basesz=%d)\n", opal.base, basep, basesz); pr_debug("OPAL Entry = 0x%llx (entryp=%p basesz=%d)\n", opal.entry, entryp, entrysz); pr_debug("OPAL Entry = 0x%llx (sizep=%p runtimesz=%d)\n", opal.size, sizep, runtimesz); powerpc_firmware_features |= FW_FEATURE_OPAL; if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) { powerpc_firmware_features |= FW_FEATURE_OPALv2; powerpc_firmware_features |= FW_FEATURE_OPALv3; printk("OPAL V3 detected !\n"); } else if (of_flat_dt_is_compatible(node, "ibm,opal-v2")) { powerpc_firmware_features |= FW_FEATURE_OPALv2; printk("OPAL V2 detected !\n"); } else { printk("OPAL V1 detected !\n"); } /* Reinit all cores with the right endian */ opal_reinit_cores(); /* Restore some bits */ if (cur_cpu_spec->cpu_restore) cur_cpu_spec->cpu_restore(); return 1; }
static void lk_meta_tag_info_collect(void) { // Device tree method char *tags; int ret; ret = of_scan_flat_dt(early_init_dt_get_chosen, NULL); if(ret==0){ CCCI_UTIL_INF_MSG("device node no chosen node\n"); return; } tags = (char*)of_get_flat_dt_prop(dt_chosen_node, "atag,mdinfo", NULL); if (tags) { tags+=8; // Fix me, Arm64 doesn't have atag defination now md_info_tag_val[0] = tags[0]; md_info_tag_val[1] = tags[1]; md_info_tag_val[2] = tags[2]; md_info_tag_val[3] = tags[3]; CCCI_UTIL_INF_MSG("Get MD info Tags\n"); CCCI_UTIL_INF_MSG("md_inf[0]=%d\n", md_info_tag_val[0]); CCCI_UTIL_INF_MSG("md_inf[1]=%d\n", md_info_tag_val[1]); CCCI_UTIL_INF_MSG("md_inf[2]=%d\n", md_info_tag_val[2]); CCCI_UTIL_INF_MSG("md_inf[3]=%d\n", md_info_tag_val[3]); }else{ CCCI_UTIL_INF_MSG("atag,mdinfo=NULL\n"); } }
static int __init devinfo_parse_dt(unsigned long node, const char *uname, int depth, void *data) { struct devinfo_tag *tags; int i; u32 size = 0; if (depth != 1 || (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) return 0; tags = (struct devinfo_tag *) of_get_flat_dt_prop(node, "atag,devinfo", NULL); if (tags) { size = tags->data_size; if (size == DEVINFO_MAX_SIZE) for (i = 0; i < size; i++) g_devinfo_data[i] = tags->data[i]; else { for (i = 0; i < 50; i++) pr_err("[ERROR][devinfo size mismatch] devinfo size:%d, atag size:%d\n", DEVINFO_MAX_SIZE, size); for (i = 0; i < DEVINFO_MAX_SIZE; i++) g_devinfo_data[i] = (u32)0; } /* print chip id for debugging purpose */ pr_debug("tag_devinfo_data size:%d\n", size); } return 1; }
static int __init pSeries_probe(void) { unsigned long root = of_get_flat_dt_root(); char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(), "device_type", NULL); if (dtype == NULL) return 0; if (strcmp(dtype, "chrp")) return 0; /* Cell blades firmware claims to be chrp while it's not. Until this * is fixed, we need to avoid those here. */ if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0") || of_flat_dt_is_compatible(root, "IBM,CBEA")) return 0; DBG("pSeries detected, looking for LPAR capability...\n"); /* Now try to figure out if we are running on LPAR */ of_scan_flat_dt(pSeries_probe_hypertas, NULL); DBG("Machine is%s LPAR !\n", (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not"); return 1; }
/** * __reserved_mem_check_root() - check if #size-cells, #address-cells provided * in /reserved-memory matches the values supported by the current implementation, * also check if ranges property has been provided */ static int __init __reserved_mem_check_root(unsigned long node) { const __be32 *prop; prop = of_get_flat_dt_prop(node, "#size-cells", NULL); if (!prop || be32_to_cpup(prop) != dt_root_size_cells) return -EINVAL; prop = of_get_flat_dt_prop(node, "#address-cells", NULL); if (!prop || be32_to_cpup(prop) != dt_root_addr_cells) return -EINVAL; prop = of_get_flat_dt_prop(node, "ranges", NULL); if (!prop) return -EINVAL; return 0; }
int __init early_init_dt_scan_recoverable_ranges(unsigned long node, const char *uname, int depth, void *data) { int i, psize, size; const __be32 *prop; if (depth != 1 || strcmp(uname, "ibm,opal") != 0) return 0; prop = of_get_flat_dt_prop(node, "mcheck-recoverable-ranges", &psize); if (!prop) return 1; pr_debug("Found machine check recoverable ranges.\n"); /* * Calculate number of available entries. * * Each recoverable address range entry is (start address, len, * recovery address), 2 cells each for start and recovery address, * 1 cell for len, totalling 5 cells per entry. */ mc_recoverable_range_len = psize / (sizeof(*prop) * 5); /* Sanity check */ if (!mc_recoverable_range_len) return 1; /* Size required to hold all the entries. */ size = mc_recoverable_range_len * sizeof(struct mcheck_recoverable_range); /* * Allocate a buffer to hold the MC recoverable ranges. We would be * accessing them in real mode, hence it needs to be within * RMO region. */ mc_recoverable_range =__va(memblock_alloc_base(size, __alignof__(u64), ppc64_rma_size)); memset(mc_recoverable_range, 0, size); for (i = 0; i < mc_recoverable_range_len; i++) { mc_recoverable_range[i].start_addr = of_read_number(prop + (i * 5) + 0, 2); mc_recoverable_range[i].end_addr = mc_recoverable_range[i].start_addr + of_read_number(prop + (i * 5) + 2, 1); mc_recoverable_range[i].recover_addr = of_read_number(prop + (i * 5) + 3, 2); pr_debug("Machine check recoverable range: %llx..%llx: %llx\n", mc_recoverable_range[i].start_addr, mc_recoverable_range[i].end_addr, mc_recoverable_range[i].recover_addr); } return 1; }
/** * early_init_dt_scan_memory - Look for an parse memory nodes */ int __init early_init_dt_scan_memory(unsigned long node, const char *uname, int depth, void *data) { const char *type = of_get_flat_dt_prop(node, "device_type", NULL); const __be32 *reg, *endp; int l; /* We are scanning "memory" nodes only */ if (type == NULL) { /* * The longtrail doesn't have a device_type on the * /memory node, so look for the node called /memory@0. */ if (!IS_ENABLED(CONFIG_PPC32) || depth != 1 || strcmp(uname, "memory@0") != 0) return 0; } else if (strcmp(type, "memory") != 0) return 0; reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l); if (reg == NULL) reg = of_get_flat_dt_prop(node, "reg", &l); if (reg == NULL) return 0; endp = reg + (l / sizeof(__be32)); pr_debug("memory scan node %s, reg size %d, data: %x %x %x %x,\n", uname, l, reg[0], reg[1], reg[2], reg[3]); while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { u64 base, size; base = dt_mem_next_cell(dt_root_addr_cells, ®); size = dt_mem_next_cell(dt_root_size_cells, ®); if (size == 0) continue; pr_debug(" - %llx , %llx\n", (unsigned long long)base, (unsigned long long)size); early_init_dt_add_memory_arch(base, size); } return 0; }
static int __init early_init_dt_scan_chosen_serial(unsigned long node, const char *uname, int depth, void *data) { unsigned long l; char *p; pr_debug("%s: depth: %d, uname: %s\n", __func__, depth, uname); if (depth == 1 && (strcmp(uname, "chosen") == 0 || strcmp(uname, "chosen@0") == 0)) { p = of_get_flat_dt_prop(node, "linux,stdout-path", &l); if (p != NULL && l > 0) stdout = p; /* store pointer to stdout-path */ } if (stdout && strstr(stdout, uname)) { p = of_get_flat_dt_prop(node, "compatible", &l); pr_debug("Compatible string: %s\n", p); if ((strncmp(p, "xlnx,xps-uart16550", 18) == 0) || (strncmp(p, "xlnx,axi-uart16550", 18) == 0)) { unsigned int addr; *(u32 *)data = UART16550; addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l); addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l); /* clear register offset */ return be32_to_cpu(addr) & ~3; } if ((strncmp(p, "xlnx,xps-uartlite", 17) == 0) || (strncmp(p, "xlnx,opb-uartlite", 17) == 0) || (strncmp(p, "xlnx,axi-uartlite", 17) == 0) || (strncmp(p, "xlnx,mdm", 8) == 0)) { unsigned int *addrp; *(u32 *)data = UARTLITE; addrp = of_get_flat_dt_prop(node, "reg", &l); return be32_to_cpup(addrp); /* return address */ } } return 0; }
int __init early_init_dt_scan_batt(unsigned long node, const char *uname, int depth, void *data) { const char *prop; unsigned long size; uint32_t *p; if (depth != 1 || strcmp(uname, "battery") != 0) return 0; prop = of_get_flat_dt_prop(node, "charge-eoc", &size); if (prop == NULL) printk(KERN_INFO "%s: charge-eoc not found\n", __func__); else battdata.eoc = (uint32_t *)prop; prop = of_get_flat_dt_prop(node, "batt-esr", &size); if (prop == NULL) printk(KERN_INFO "%s: batt-esr not found\n", __func__); else battdata.esr = (uint32_t *)prop; prop = of_get_flat_dt_prop(node, "charge-1c", &size); if (prop == NULL) printk(KERN_INFO "%s: charge-1c not found\n", __func__); else battdata.chrg_1c = (uint32_t *)prop; prop = of_get_flat_dt_prop(node, "capacity", &size); if (prop == NULL) printk(KERN_INFO "%s: battery capacity not found\n", __func__); else battdata.cpcty = (uint32_t *)prop; prop = of_get_flat_dt_prop(node, "vcmap-size", &size); if (prop == NULL) printk(KERN_INFO "%s: battery vcmap-size not found\n", __func__); else { p = (uint32_t *)prop; battdata.voltcap_map_width = p; p++; battdata.voltcap_map_len = p; } prop = of_get_flat_dt_prop(node, "vcmap", &size); if (prop == NULL) printk(KERN_INFO "%s: battery vcmap not found\n", __func__); else { battdata.voltcap_map = (uint32_t *)prop; battdata.voltcap_map_size = size/4; } prop = of_get_flat_dt_prop(node, "model", &size); if (prop == NULL) printk(KERN_INFO "%s: battery model not found\n", __func__); else battdata.model = (char *)prop; battdata.valid = 1; return 1; }
static int __init fdt_find_cpu_features(unsigned long node, const char *uname, int depth, void *data) { if (of_flat_dt_is_compatible(node, "ibm,powerpc-cpu-features") && of_get_flat_dt_prop(node, "isa", NULL)) return 1; return 0; }
static int __init early_init_dt_scan_kona_root(unsigned long node, const char *uname, int depth, void *data) { const char *prop; unsigned long size; /*printk(KERN_INFO "%s: node=0x%lx, uname=%s, depth=%d\n", __func__, node, uname, depth);*/ if (depth != 0 || strcmp(uname, "") != 0) return 0; /* not found, continue... */ prop = (char *)of_get_flat_dt_prop(node, "model", &size); printk(KERN_INFO "model: %s\n", prop); prop = (char *)of_get_flat_dt_prop(node, "compatible", &size); printk(KERN_INFO "compatible: %s\n", prop); return 1; }