int of_read_drc_info_cell(struct property **prop, const __be32 **curval, struct of_drc_info *data) { const char *p; const __be32 *p2; if (!data) return -EINVAL; /* Get drc-type:encode-string */ p = data->drc_type = (char*) (*curval); p = of_prop_next_string(*prop, p); if (!p) return -EINVAL; /* Get drc-name-prefix:encode-string */ data->drc_name_prefix = (char *)p; p = of_prop_next_string(*prop, p); if (!p) return -EINVAL; /* Get drc-index-start:encode-int */ p2 = (const __be32 *)p; p2 = of_prop_next_u32(*prop, p2, &data->drc_index_start); if (!p2) return -EINVAL; /* Get drc-name-suffix-start:encode-int */ p2 = of_prop_next_u32(*prop, p2, &data->drc_name_suffix_start); if (!p2) return -EINVAL; /* Get number-sequential-elements:encode-int */ p2 = of_prop_next_u32(*prop, p2, &data->num_sequential_elems); if (!p2) return -EINVAL; /* Get sequential-increment:encode-int */ p2 = of_prop_next_u32(*prop, p2, &data->sequential_inc); if (!p2) return -EINVAL; /* Get drc-power-domain:encode-int */ p2 = of_prop_next_u32(*prop, p2, &data->drc_power_domain); if (!p2) return -EINVAL; /* Should now know end of current entry */ (*curval) = (void *)p2; data->last_drc_index = data->drc_index_start + ((data->num_sequential_elems - 1) * data->sequential_inc); return 0; }
static void v4l2_of_parse_csi_bus(const struct device_node *node, struct v4l2_of_endpoint *endpoint) { struct v4l2_of_bus_mipi_csi2 *bus = &endpoint->bus.mipi_csi2; u32 data_lanes[ARRAY_SIZE(bus->data_lanes)]; struct property *prop; bool have_clk_lane = false; unsigned int flags = 0; u32 v; prop = of_find_property(node, "data-lanes", NULL); if (prop) { const __be32 *lane = NULL; int i; for (i = 0; i < ARRAY_SIZE(data_lanes); i++) { lane = of_prop_next_u32(prop, lane, &data_lanes[i]); if (!lane) break; } bus->num_data_lanes = i; while (i--) bus->data_lanes[i] = data_lanes[i]; } if (!of_property_read_u32(node, "clock-lanes", &v)) { bus->clock_lane = v; have_clk_lane = true; } if (of_get_property(node, "clock-noncontinuous", &v)) flags |= V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK; else if (have_clk_lane || bus->num_data_lanes > 0) flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; bus->flags = flags; endpoint->bus_type = V4L2_MBUS_CSI2; }
static u32 cpu_to_drc_index(int cpu) { struct device_node *dn = NULL; int thread_index; int rc = 1; u32 ret = 0; dn = of_find_node_by_path("/cpus"); if (dn == NULL) goto err; /* Convert logical cpu number to core number */ thread_index = cpu_core_index_of_thread(cpu); if (firmware_has_feature(FW_FEATURE_DRC_INFO)) { struct property *info = NULL; struct of_drc_info drc; int j; u32 num_set_entries; const __be32 *value; info = of_find_property(dn, "ibm,drc-info", NULL); if (info == NULL) goto err_of_node_put; value = of_prop_next_u32(info, NULL, &num_set_entries); if (!value) goto err_of_node_put; for (j = 0; j < num_set_entries; j++) { of_read_drc_info_cell(&info, &value, &drc); if (strncmp(drc.drc_type, "CPU", 3)) goto err; if (thread_index < drc.last_drc_index) break; } ret = drc.drc_index_start + (thread_index * drc.sequential_inc); } else { const __be32 *indexes; indexes = of_get_property(dn, "ibm,drc-indexes", NULL); if (indexes == NULL) goto err_of_node_put; /* * The first element indexes[0] is the number of drc_indexes * returned in the list. Hence thread_index+1 will get the * drc_index corresponding to core number thread_index. */ ret = indexes[thread_index + 1]; } rc = 0; err_of_node_put: of_node_put(dn); err: if (rc) printk(KERN_WARNING "cpu_to_drc_index(%d) failed", cpu); return ret; }
static int drc_index_to_cpu(u32 drc_index) { struct device_node *dn = NULL; const int *indexes; int thread_index = 0, cpu = 0; int rc = 1; dn = of_find_node_by_path("/cpus"); if (dn == NULL) goto err; if (firmware_has_feature(FW_FEATURE_DRC_INFO)) { struct property *info = NULL; struct of_drc_info drc; int j; u32 num_set_entries; const __be32 *value; info = of_find_property(dn, "ibm,drc-info", NULL); if (info == NULL) goto err_of_node_put; value = of_prop_next_u32(info, NULL, &num_set_entries); if (!value) goto err_of_node_put; for (j = 0; j < num_set_entries; j++) { of_read_drc_info_cell(&info, &value, &drc); if (strncmp(drc.drc_type, "CPU", 3)) goto err; if (drc_index > drc.last_drc_index) { cpu += drc.num_sequential_elems; continue; } cpu += ((drc_index - drc.drc_index_start) / drc.sequential_inc); thread_index = cpu_first_thread_of_core(cpu); rc = 0; break; } } else { unsigned long int i; indexes = of_get_property(dn, "ibm,drc-indexes", NULL); if (indexes == NULL) goto err_of_node_put; /* * First element in the array is the number of drc_indexes * returned. Search through the list to find the matching * drc_index and get the core number */ for (i = 0; i < indexes[0]; i++) { if (indexes[i + 1] == drc_index) break; } /* Convert core number to logical cpu number */ thread_index = cpu_first_thread_of_core(i); rc = 0; } err_of_node_put: of_node_put(dn); err: if (rc) printk(KERN_WARNING "drc_index_to_cpu(%d) failed", drc_index); return thread_index; }
static int max77693_led_parse_dt(struct max77693_led_device *led, struct max77693_led_config_data *cfg, struct device_node **sub_nodes) { struct device *dev = &led->pdev->dev; struct max77693_sub_led *sub_leds = led->sub_leds; struct device_node *node = dev->of_node, *child_node; struct property *prop; u32 led_sources[2]; int i, ret, fled_id; of_property_read_u32(node, "maxim,boost-mode", &cfg->boost_mode); of_property_read_u32(node, "maxim,boost-mvout", &cfg->boost_vout); of_property_read_u32(node, "maxim,mvsys-min", &cfg->low_vsys); for_each_available_child_of_node(node, child_node) { prop = of_find_property(child_node, "led-sources", NULL); if (prop) { const __be32 *srcs = NULL; for (i = 0; i < ARRAY_SIZE(led_sources); ++i) { srcs = of_prop_next_u32(prop, srcs, &led_sources[i]); if (!srcs) break; } } else { dev_err(dev, "led-sources DT property missing\n"); of_node_put(child_node); return -EINVAL; } if (i == 2) { fled_id = FLED1; led->fled_mask = FLED1_IOUT | FLED2_IOUT; } else if (led_sources[0] == FLED1) { fled_id = FLED1; led->fled_mask |= FLED1_IOUT; } else if (led_sources[0] == FLED2) { fled_id = FLED2; led->fled_mask |= FLED2_IOUT; } else { dev_err(dev, "Wrong led-sources DT property value.\n"); of_node_put(child_node); return -EINVAL; } if (sub_nodes[fled_id]) { dev_err(dev, "Conflicting \"led-sources\" DT properties\n"); of_node_put(child_node); return -EINVAL; } sub_nodes[fled_id] = child_node; sub_leds[fled_id].fled_id = fled_id; cfg->label[fled_id] = of_get_property(child_node, "label", NULL) ? : child_node->name; ret = of_property_read_u32(child_node, "led-max-microamp", &cfg->iout_torch_max[fled_id]); if (ret < 0) { cfg->iout_torch_max[fled_id] = TORCH_IOUT_MIN; dev_warn(dev, "led-max-microamp DT property missing\n"); } ret = of_property_read_u32(child_node, "flash-max-microamp", &cfg->iout_flash_max[fled_id]); if (ret < 0) { cfg->iout_flash_max[fled_id] = FLASH_IOUT_MIN; dev_warn(dev, "flash-max-microamp DT property missing\n"); } ret = of_property_read_u32(child_node, "flash-max-timeout-us", &cfg->flash_timeout_max[fled_id]); if (ret < 0) { cfg->flash_timeout_max[fled_id] = FLASH_TIMEOUT_MIN; dev_warn(dev, "flash-max-timeout-us DT property missing\n"); } if (++cfg->num_leds == 2 || (max77693_fled_used(led, FLED1) && max77693_fled_used(led, FLED2))) { of_node_put(child_node); break; } }