/* Initializes the block_list with info from a netlist */ void read_netlist(IN const char* net_file, IN int num_types, IN const struct s_type_descriptor block_types[], IN block_type_ptr IO_type, IN int io_ipin, IN int io_opin, OUT subblock_data_t* subblock_data_ptr, OUT int* num_blocks, OUT block_t* block_list[], OUT int* num_nets, OUT net_t* net_list[]) { int i, j, k, l, m; enum { COUNT, LOAD, MAP, STOP } pass; int line, prev_line; enum special_blk overide; char** block_tokens; char** pin_tokens; char** tokens; subblock_t** slist = NULL; int* scount = NULL; block_type_ptr type = NULL; FILE* infile = my_fopen(net_file, "r"); int bcount = 0; block_t* blist = NULL; int ncount = 0; net_t* nlist = NULL; memset(subblock_data_ptr, 0, sizeof(subblock_data_t)); /* Multi-pass load * COUNT *->count blocks *->count nets * * LOAD *->alloc num_subblocks_per_block list *->allocate s_block list at start *->allocate s_net list at start *->count subblocks per block *->sets block names *->sets block types *->allocs block net lists *->sets net names * * MAP *->fills in s_block:nets list *->fills in subblocks */ for (pass = 0; pass < STOP; ++pass) { rewind(infile); line = 0; i = 0; j = 0; overide = NORMAL; /* Alloc the lists */ if (LOAD == pass) { blist = (block_t*)my_malloc(sizeof(block_t) * bcount); memset(blist, 0, (sizeof(block_t) * bcount)); nlist = (net_t*)my_malloc(sizeof(net_t) * ncount); memset(nlist, 0, (sizeof(net_t) * ncount)); slist = (subblock_t**) my_malloc(sizeof(subblock_t*) * bcount); memset(slist, 0, (sizeof(subblock_t*) * bcount)); scount = (int*)my_malloc(sizeof(int) * bcount); memset(scount, 0, (sizeof(int) * bcount)); } /* Read file line by line */ block_tokens = ReadLineTokens(infile, &line); prev_line = line; while (block_tokens) { /* .global directives have special meaning */ if (0 == strcmp(block_tokens[0], ".global")) { if (MAP == pass) { for (l = 0; l < ncount; ++l) { if (0 == strcmp(nlist[l].name, block_tokens[1])) { nlist[l].is_global = TRUE; break; } } if (l == ncount) { printf(ERRTAG "'%s':%d - '.global' specified an invalid net\n", net_file, prev_line); exit(1); } } /* Don't do any more processing on this */ FreeTokens(&block_tokens); block_tokens = ReadLineTokens(infile, &line); prev_line = line; continue; } pin_tokens = ReadLineTokens(infile, &line); if (CountTokens(block_tokens) != 2) { printf(ERRTAG "'%s':%d - block type line should " "be in form '.type_name block_name'\n", net_file, prev_line); exit(1); } if (NULL == pin_tokens) { printf(ERRTAG "'%s':%d - blocks must be follow by a 'pinlist:' line\n", net_file, line); exit(1); } if (0 != strcmp("pinlist:", pin_tokens[0])) { printf(ERRTAG "'%s':%d - 'pinlist:' line must follow " "block type line\n", net_file, line); exit(1); } type = get_type_by_name(block_tokens[0], num_types, block_types, IO_type, net_file, prev_line, &overide); /* Check if we are overiding the pinlist format for this block */ if (overide) { if (CountTokens(pin_tokens) != 2) { /* 'pinlist:' and name */ printf(ERRTAG "'%s':%d - pinlist for .input and .output should " "only have one item.\n", net_file, line); exit(1); } /* Make a new faked token list with 'pinlist:' and then pin mappings and a null */ tokens = (char**)my_malloc(sizeof(char*) * (type->num_type_pins + 2)); l = strlen(pinlist_str) + 1; k = strlen(pin_tokens[1]) + 1; tokens[0] = (char*)my_malloc(sizeof(char) * (k + l)); memcpy(tokens[0], pinlist_str, l * sizeof(char)); memcpy(tokens[0] + l, pin_tokens[1], k * sizeof(char)); /* Set all other pins to open */ for (k = 0; k < type->num_type_pins; ++k) { tokens[1 + k] = "open"; /* free wont be called on this so is safe */ } tokens[1 + k] = NULL; /* End of token list marker */ /* Set the one pin with the value given */ for (k = 0; k < type->num_type_pins; ++k) { switch (overide) { case INPAD: tokens[1 + io_opin] = (tokens[0] + l); break; case OUTPAD: tokens[1 + io_ipin] = (tokens[0] + l); break; } } FreeTokens(&pin_tokens); pin_tokens = tokens; tokens = NULL; } if (CountTokens(pin_tokens) != (type->num_type_pins + 1)) { printf(ERRTAG "'%s':%d - 'pinlist:' line has %d pins instead of " "expect %d pins.\n", net_file, line, CountTokens(pin_tokens) - 1, type->num_type_pins); exit(1); } /* Load block name and type and alloc net list */ if (LOAD == pass) { blist[i].name = my_strdup(block_tokens[1]); blist[i].block_type = type; blist[i].nets = (int*)my_malloc(sizeof(int) * type->num_type_pins); for (k = 0; k < type->num_type_pins; ++k) { blist[i].nets[k] = OPEN; } } /* Examine pin list to determine nets */ for (k = 0; k < type->num_type_pins; ++k) { if (0 != strcmp("open", pin_tokens[1 + k])) { if (DRIVER == type->class_inf[type->pin_class[k]].type) { if (LOAD == pass) { nlist[j].name = my_strdup(pin_tokens[1 + k]); } if (MAP == pass) { blist[i].nets[k] = j; /* If we are net source we don't need to search */ } ++j; /* This was an active netlist */ } else { if (MAP == pass) { /* Map sinks by doing a linear search to find the net */ blist[i].nets[k] = OPEN; for (l = 0; l < ncount; ++l) { if (0 == strcmp(nlist[l].name, pin_tokens[1 + k])) { blist[i].nets[k] = l; break; } } if (OPEN == blist[i].nets[k]) { printf(ERRTAG "'%s':%d - Net '%s' not found\n", net_file, line, pin_tokens [1 + k]); exit(1); } } } } } /* Allocating subblocks */ if (MAP == pass) { /* All blocks internally have subblocks but I/O subblocks are allocated and loaded elsewhere */ if (scount[i] > 0) { slist[i] = (subblock_t*) my_malloc(sizeof(subblock_t) * scount[i]); for (k = 0; k < scount[i]; ++k) { slist[i][k].name = NULL; slist[i][k].clock = OPEN; slist[i][k].inputs = (int*)my_malloc(sizeof(int) * type->max_subblock_inputs); for (l = 0; l < type->max_subblock_inputs; ++l) { slist[i][k].inputs[l] = OPEN; } slist[i][k].outputs = (int*)my_malloc(sizeof(int) * type->max_subblock_outputs); for (l = 0; l < type->max_subblock_outputs; ++l) { slist[i][k].outputs[l] = OPEN; } } } } /* Ignore subblock data */ tokens = ReadLineTokens(infile, &line); prev_line = line; m = 0; while (tokens && (0 == strcmp(tokens[0], "subblock:"))) { if (CountTokens(tokens) != (type->max_subblock_inputs + type->max_subblock_outputs + 1 + /* clocks */ 2)) { /* 'subblock:', name */ printf("subblock wrong pin count, netlist has %d, architecture as %d on line %d \n" , CountTokens(tokens) - 2, (type->max_subblock_inputs + type->max_subblock_outputs + 1), line); exit(1); } /* Count subblocks given */ if (LOAD == pass) { scount[i]++; } /* Load subblock name */ if (MAP == pass) { assert(i < bcount); assert(m < scount[i]); slist[i][m].name = my_strdup(tokens[1]); for (k = 0; k < type->max_subblock_inputs; ++k) { /* Check prefix and load pin num */ l = 2 + k; if (0 == strncmp("ble_", tokens[l], 4)) { /* Skip the 'ble_' part */ slist[i][m].inputs[k] = type->num_type_pins + my_atoi(tokens[l] + 4); } else if (0 != strcmp("open", tokens[l])) { slist[i][m].inputs[k] = my_atoi(tokens[l]); } } for (k = 0; k < type->max_subblock_outputs; ++k) { l = 2 + type->max_subblock_inputs + k; if (0 != strcmp("open", tokens[l])) { slist[i][m].outputs[k] = my_atoi(tokens[l]); } } l = 2 + type->max_subblock_inputs + type->max_subblock_outputs; if (0 != strcmp("open", tokens[l])) { slist[i][m].clock = my_atoi(tokens[l]); } } ++m; /* Next subblock */ FreeTokens(&tokens); tokens = ReadLineTokens(infile, &line); prev_line = line; } if (pass > COUNT) { /* Check num of subblocks read */ if (scount[i] > type->max_subblocks) { printf("too many subblocks on block [%d] %s\n", i, blist[i].name); exit(1); } } ++i; /* End of this block */ FreeTokens(&block_tokens); FreeTokens(&pin_tokens); block_tokens = tokens; } /* Save counts */ if (COUNT == pass) { bcount = i; ncount = j; } } fclose(infile); /* Builds mappings from each netlist to the blocks contained */ sync_nets_to_blocks(bcount, blist, ncount, nlist); /* Send values back to caller */ *num_blocks = bcount; *block_list = blist; *num_nets = ncount; *net_list = nlist; subblock_data_ptr->subblock_inf = slist; subblock_data_ptr->num_subblocks_per_block = scount; }
static int hi6220_set_platform_data(struct platform_device *pdev) { unsigned int base; unsigned int size; unsigned int id; const char *heap_name; const char *type_name; enum ion_heap_type type; int ret; struct device_node *np; struct ion_platform_heap *p_data; const struct device_node *dt_node = pdev->dev.of_node; int index = 0; for_each_child_of_node(dt_node, np) num_heaps++; heaps_data = devm_kzalloc(&pdev->dev, sizeof(struct ion_platform_heap *) * num_heaps, GFP_KERNEL); if (!heaps_data) return -ENOMEM; for_each_child_of_node(dt_node, np) { ret = of_property_read_string(np, "heap-name", &heap_name); if (ret < 0) { pr_err("check the name of node %s\n", np->name); continue; } ret = of_property_read_u32(np, "heap-id", &id); if (ret < 0) { pr_err("check the id %s\n", np->name); continue; } ret = of_property_read_u32(np, "heap-base", &base); if (ret < 0) { pr_err("check the base of node %s\n", np->name); continue; } ret = of_property_read_u32(np, "heap-size", &size); if (ret < 0) { pr_err("check the size of node %s\n", np->name); continue; } ret = of_property_read_string(np, "heap-type", &type_name); if (ret < 0) { pr_err("check the type of node %s\n", np->name); continue; } ret = get_type_by_name(type_name, &type); if (ret < 0) { pr_err("type name error %s!\n", type_name); continue; } pr_info("heap index %d : name %s base 0x%x size 0x%x id %d type %d\n", index, heap_name, base, size, id, type); p_data = devm_kzalloc(&pdev->dev, sizeof(struct ion_platform_heap), GFP_KERNEL); if (!p_data) return -ENOMEM; p_data->name = heap_name; p_data->base = base; p_data->size = size; p_data->id = id; p_data->type = type; heaps_data[index] = p_data; index++; }