Lines Matching +full:parent +full:- +full:child
1 // SPDX-License-Identifier: GPL-2.0-only
12 * parent node is a virtual description of the aggregation of the
42 return -ENOSYS; in get_time_window_us()
47 return -ENOSYS; in set_time_window_us()
54 *max_power_uw = dtpm->power_max - dtpm->power_min; in get_max_power_range_uw()
61 struct dtpm *child; in __get_power_uw() local
65 if (dtpm->ops) { in __get_power_uw()
66 *power_uw = dtpm->ops->get_power_uw(dtpm); in __get_power_uw()
72 list_for_each_entry(child, &dtpm->children, sibling) { in __get_power_uw()
73 ret = __get_power_uw(child, &power); in __get_power_uw()
89 struct dtpm *child; in __dtpm_rebalance_weight() local
91 list_for_each_entry(child, &dtpm->children, sibling) { in __dtpm_rebalance_weight()
94 child->weight, child->zone.name); in __dtpm_rebalance_weight()
96 child->weight = DIV64_U64_ROUND_CLOSEST( in __dtpm_rebalance_weight()
97 child->power_max * 1024, dtpm->power_max); in __dtpm_rebalance_weight()
99 __dtpm_rebalance_weight(child); in __dtpm_rebalance_weight()
105 struct dtpm *parent = dtpm->parent; in __dtpm_sub_power() local
107 while (parent) { in __dtpm_sub_power()
108 parent->power_min -= dtpm->power_min; in __dtpm_sub_power()
109 parent->power_max -= dtpm->power_max; in __dtpm_sub_power()
110 parent->power_limit -= dtpm->power_limit; in __dtpm_sub_power()
111 parent = parent->parent; in __dtpm_sub_power()
117 struct dtpm *parent = dtpm->parent; in __dtpm_add_power() local
119 while (parent) { in __dtpm_add_power()
120 parent->power_min += dtpm->power_min; in __dtpm_add_power()
121 parent->power_max += dtpm->power_max; in __dtpm_add_power()
122 parent->power_limit += dtpm->power_limit; in __dtpm_add_power()
123 parent = parent->parent; in __dtpm_add_power()
128 * dtpm_update_power - Update the power on the dtpm
134 * Return: zero on success, -EINVAL if the values are inconsistent
142 ret = dtpm->ops->update_power_uw(dtpm); in dtpm_update_power()
145 dtpm->zone.name, ret); in dtpm_update_power()
147 if (!test_bit(DTPM_POWER_LIMIT_FLAG, &dtpm->flags)) in dtpm_update_power()
148 dtpm->power_limit = dtpm->power_max; in dtpm_update_power()
159 * dtpm_release_zone - Cleanup when the node is released
167 * Return: 0 on success, -EBUSY if there are children
172 struct dtpm *parent = dtpm->parent; in dtpm_release_zone() local
174 if (!list_empty(&dtpm->children)) in dtpm_release_zone()
175 return -EBUSY; in dtpm_release_zone()
177 if (parent) in dtpm_release_zone()
178 list_del(&dtpm->sibling); in dtpm_release_zone()
182 if (dtpm->ops) in dtpm_release_zone()
183 dtpm->ops->release(dtpm); in dtpm_release_zone()
193 *power_limit = to_dtpm(pcz)->power_limit; in get_power_limit_uw()
206 struct dtpm *child; in __set_power_limit_uw() local
214 if (power_limit == dtpm->power_max) { in __set_power_limit_uw()
215 clear_bit(DTPM_POWER_LIMIT_FLAG, &dtpm->flags); in __set_power_limit_uw()
217 set_bit(DTPM_POWER_LIMIT_FLAG, &dtpm->flags); in __set_power_limit_uw()
221 dtpm->zone.name, power_limit); in __set_power_limit_uw()
226 if (dtpm->ops) { in __set_power_limit_uw()
227 dtpm->power_limit = dtpm->ops->set_power_uw(dtpm, power_limit); in __set_power_limit_uw()
229 dtpm->power_limit = 0; in __set_power_limit_uw()
231 list_for_each_entry(child, &dtpm->children, sibling) { in __set_power_limit_uw()
237 * initial value, we force the child's min or in __set_power_limit_uw()
241 if (power_limit == dtpm->power_max) { in __set_power_limit_uw()
242 power = child->power_max; in __set_power_limit_uw()
243 } else if (power_limit == dtpm->power_min) { in __set_power_limit_uw()
244 power = child->power_min; in __set_power_limit_uw()
247 power_limit * child->weight, 1024); in __set_power_limit_uw()
251 child->zone.name, power); in __set_power_limit_uw()
253 ret = __set_power_limit_uw(child, cid, power); in __set_power_limit_uw()
255 ret = get_power_limit_uw(&child->zone, cid, &power); in __set_power_limit_uw()
260 dtpm->power_limit += power; in __set_power_limit_uw()
277 power_limit = clamp_val(power_limit, dtpm->power_min, dtpm->power_max); in set_power_limit_uw()
282 dtpm->zone.name, dtpm->power_limit, dtpm->power_max); in set_power_limit_uw()
294 *max_power = to_dtpm(pcz)->power_max; in get_max_power_uw()
315 * dtpm_init - Allocate and initialize a dtpm struct
322 INIT_LIST_HEAD(&dtpm->children); in dtpm_init()
323 INIT_LIST_HEAD(&dtpm->sibling); in dtpm_init()
324 dtpm->weight = 1024; in dtpm_init()
325 dtpm->ops = ops; in dtpm_init()
330 * dtpm_unregister - Unregister a dtpm node from the hierarchy tree
338 powercap_unregister_zone(pct, &dtpm->zone); in dtpm_unregister()
340 pr_debug("Unregistered dtpm node '%s'\n", dtpm->zone.name); in dtpm_unregister()
344 * dtpm_register - Register a dtpm node in the hierarchy tree
347 * @parent: a pointer to a dtpm structure corresponding to the parent node
349 * Create a dtpm node in the tree. If no parent is specified, the node
358 * -EAGAIN: the function is called before the framework is initialized.
359 * -EBUSY: the root node is already inserted
360 * -EINVAL: * there is no root node yet and @parent is specified
362 * * parent have ops which are reserved for leaves
365 int dtpm_register(const char *name, struct dtpm *dtpm, struct dtpm *parent) in dtpm_register() argument
370 return -EAGAIN; in dtpm_register()
372 if (root && !parent) in dtpm_register()
373 return -EBUSY; in dtpm_register()
375 if (!root && parent) in dtpm_register()
376 return -EINVAL; in dtpm_register()
378 if (parent && parent->ops) in dtpm_register()
379 return -EINVAL; in dtpm_register()
382 return -EINVAL; in dtpm_register()
384 if (dtpm->ops && !(dtpm->ops->set_power_uw && in dtpm_register()
385 dtpm->ops->get_power_uw && in dtpm_register()
386 dtpm->ops->update_power_uw && in dtpm_register()
387 dtpm->ops->release)) in dtpm_register()
388 return -EINVAL; in dtpm_register()
390 pcz = powercap_register_zone(&dtpm->zone, pct, name, in dtpm_register()
391 parent ? &parent->zone : NULL, in dtpm_register()
397 if (parent) { in dtpm_register()
398 list_add_tail(&dtpm->sibling, &parent->children); in dtpm_register()
399 dtpm->parent = parent; in dtpm_register()
404 if (dtpm->ops && !dtpm->ops->update_power_uw(dtpm)) { in dtpm_register()
406 dtpm->power_limit = dtpm->power_max; in dtpm_register()
409 pr_debug("Registered dtpm node '%s' / %llu-%llu uW, \n", in dtpm_register()
410 dtpm->zone.name, dtpm->power_min, dtpm->power_max); in dtpm_register()
416 struct dtpm *parent) in dtpm_setup_virtual() argument
423 return ERR_PTR(-ENOMEM); in dtpm_setup_virtual()
426 ret = dtpm_register(hierarchy->name, dtpm, parent); in dtpm_setup_virtual()
429 hierarchy->name, ret); in dtpm_setup_virtual()
438 struct dtpm *parent) in dtpm_setup_dt() argument
443 np = of_find_node_by_path(hierarchy->name); in dtpm_setup_dt()
445 pr_err("Failed to find '%s'\n", hierarchy->name); in dtpm_setup_dt()
446 return ERR_PTR(-ENXIO); in dtpm_setup_dt()
451 if (!dtpm_subsys[i]->setup) in dtpm_setup_dt()
454 ret = dtpm_subsys[i]->setup(parent, np); in dtpm_setup_dt()
456 pr_err("Failed to setup '%s': %d\n", dtpm_subsys[i]->name, ret); in dtpm_setup_dt()
466 * is no child for us as we are a leaf of the tree in dtpm_setup_dt()
479 const struct dtpm_node *it, struct dtpm *parent) in dtpm_for_each_child() argument
486 if (hierarchy[i].parent != it) in dtpm_for_each_child()
489 dtpm = dtpm_node_callback[hierarchy[i].type](&hierarchy[i], parent); in dtpm_for_each_child()
524 * dtpm_create_hierarchy - Create the dtpm hierarchy
535 * [1] { .name = "package", .type = DTPM_NODE_VIRTUAL, .parent = &hierarchy[0] },
536 * [2] { .name = "/cpus/cpu0", .type = DTPM_NODE_DT, .parent = &hierarchy[1] },
537 * [3] { .name = "/cpus/cpu1", .type = DTPM_NODE_DT, .parent = &hierarchy[1] },
538 * [4] { .name = "/cpus/cpu2", .type = DTPM_NODE_DT, .parent = &hierarchy[1] },
539 * [5] { .name = "/cpus/cpu3", .type = DTPM_NODE_DT, .parent = &hierarchy[1] },
559 ret = -EBUSY; in dtpm_create_hierarchy()
570 ret = -ENODEV; in dtpm_create_hierarchy()
582 hierarchy = match->data; in dtpm_create_hierarchy()
584 ret = -EFAULT; in dtpm_create_hierarchy()
594 if (!dtpm_subsys[i]->init) in dtpm_create_hierarchy()
597 ret = dtpm_subsys[i]->init(); in dtpm_create_hierarchy()
600 dtpm_subsys[i]->name, ret); in dtpm_create_hierarchy()
620 struct dtpm *child, *aux; in __dtpm_destroy_hierarchy() local
622 list_for_each_entry_safe(child, aux, &dtpm->children, sibling) in __dtpm_destroy_hierarchy()
623 __dtpm_destroy_hierarchy(child); in __dtpm_destroy_hierarchy()
646 if (!dtpm_subsys[i]->exit) in dtpm_destroy_hierarchy()
649 dtpm_subsys[i]->exit(); in dtpm_destroy_hierarchy()