struct resource;
struct resource_attribute;
-struct resource_attribute_value {
- /* Indicate the data type among three types (int/double/str)*/
+struct array_value {
int type;
+ int length;
+ void *data;
+};
- union {
- /* Have to use only one among the types */
- int int_value;
-
- int number_int;
- int *int_values;
-
- double double_value;
-
- int number_string;
- char *str_value;;
- } data;
+struct resource_attribute_value {
+ int type;
+ void *data;
};
struct resource_attribute_ops {
int (*set)(const struct resource *res,
const struct resource_attribute *attr,
- const char *buf, int count, void *user_data);
+ const void *data, int count, void *user_data);
int (*get)(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data);
+ void **data, void *user_data);
};
struct resource_attribute {
const struct resource_attribute *get_resource_attr(struct resource *resource, u_int64_t attr_id);
struct resource_attribute_value *
get_resource_attr_value(struct resource *resource, u_int64_t attr_id);
-int get_resource_attr_integer(struct resource *resource, u_int64_t attr_id);
-int get_resource_attr_integer_sync(struct resource *resource, u_int64_t attr_id);
+
+int get_resource_attr_integer(struct resource *resource, u_int64_t attr_id, int *data);
+int get_resource_attr_integer_sync(struct resource *resource, u_int64_t attr_id, int *data);
+int get_resource_attr_double(struct resource *resource, u_int64_t attr_id, double *data);
+int get_resource_attr_double_sync(struct resource *resource, u_int64_t attr_id, double *data);
+int get_resource_attr_string(struct resource *resource, u_int64_t attr_id, char **data);
+int get_resource_attr_string_sync(struct resource *resource, u_int64_t attr_id, char **data);
+int get_resource_attr_array(struct resource *resource, u_int64_t attr_id,
+ struct array_value **data);
+int get_resource_attr_array_sync(struct resource *resource, u_int64_t attr_id,
+ struct array_value **data);
+
void set_resource_attr_interest(struct resource *resource, u_int64_t interest_mask);
void unset_resource_attr_interest(struct resource *resource, u_int64_t interest_mask);
#endif
static int bus_get_cur_freq(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_curr_freq(res->type, res->name);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int bus_get_min_freq(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_min_freq(res->type, res->name);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int bus_get_max_freq(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_max_freq(res->type, res->name);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int bus_get_available_min_freq(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_available_min_freq(res->type, res->name);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int bus_get_available_max_freq(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_available_max_freq(res->type, res->name);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int bus_get_curr_governor(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
+ char buf[BUFF_MAX];
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_curr_governor(res->type, res->name, buf);
if (val < 0)
return -EINVAL;
+ *data = strdup(buf);
+ if (!*data)
+ return -ENOMEM;
+
return 0;
}
static int cpu_get_cur_freq(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_curr_freq(res->type, res->name);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int cpu_get_min_freq(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_min_freq(res->type, res->name);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int cpu_get_max_freq(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_max_freq(res->type, res->name);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int cpu_get_available_min_freq(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_available_min_freq(res->type, res->name);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int cpu_get_available_max_freq(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_available_max_freq(res->type, res->name);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int cpu_get_curr_governor(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
+ char buf[BUFF_MAX];
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_curr_governor(res->type, res->name, buf);
if (val < 0)
return -EINVAL;
+ *data = strdup(buf);
+ if (!*data)
+ return -ENOMEM;
+
return 0;
}
static int cpu_get_online_cpu(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
return 0;
}
static int cpu_get_temperature(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
return 0;
}
static int gpu_get_cur_freq(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_curr_freq(res->type, res->name);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int gpu_get_min_freq(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_min_freq(res->type, res->name);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int gpu_get_max_freq(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_max_freq(res->type, res->name);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int gpu_get_available_min_freq(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_available_min_freq(res->type, res->name);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int gpu_get_available_max_freq(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_available_max_freq(res->type, res->name);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int gpu_get_curr_governor(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
+ char buf[BUFF_MAX];
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = hal_power_dvfs_get_curr_governor(res->type, res->name, buf);
if (val < 0)
return -EINVAL;
+ *data = strdup(buf);
+ if (!*data)
+ return -ENOMEM;
+
return 0;
}
static int gpu_get_temperature(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
return 0;
}
static int memory_get_total_memory(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = memory_read_val_from_proc_node(attr->id);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int memory_get_available_memory(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = memory_read_val_from_proc_node(attr->id);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static int memory_get_free_memory(const struct resource *res,
const struct resource_attribute *attr,
- char *buf, void *user_data)
+ void **data, void *user_data)
{
int val;
- if (!res || !attr || !buf)
+ if (!res || !attr || !data)
return -EINVAL;
val = memory_read_val_from_proc_node(attr->id);
if (val < 0)
return -EINVAL;
- return sprintf(buf, "%d", val);
+ *data = (void *)(intptr_t)val;
+
+ return 0;
}
static const struct resource_attribute memory_attrs[] = {
int attr_index = RESOURCE_ATTR_INDEX(attr_id);
const struct resource_attribute *attr = NULL;
struct resource_attribute_value *attr_value = NULL;
- char buf[BUFF_MAX];
int ret;
if (!resource || attr_index < 0 || attr_index >= resource->num_attrs)
if (!attr->ops.get)
return -EINVAL;
- ret = attr->ops.get(resource, attr, buf, resource->user_data);
+ ret = attr->ops.get(resource, attr, &(attr_value->data), resource->user_data);
if (ret < 0)
return ret;
- /* FIXME: Need to be changed according to data type*/
- ret = sscanf(buf, "%d", &(attr_value->data.int_value));
- if (ret != 1)
- return -EINVAL;
-
return 0;
}
return &resource->attrs_value[attr_index];
}
-int get_resource_attr_integer(struct resource *resource, u_int64_t attr_id)
+static bool check_attr_validate(struct resource *resource, u_int64_t attr_id, int type)
+{
+ const struct resource_attribute *attr = get_resource_attr(resource, attr_id);
+
+ if (!attr || attr->type != type)
+ return false;
+
+ if (!(attr->id & resource->attr_interest))
+ return false;
+
+ return true;
+}
+
+int get_resource_attr_integer(struct resource *resource, u_int64_t attr_id, int *data)
{
- const struct resource_attribute *attr = NULL;
struct resource_attribute_value *attr_value = NULL;
- /* Check whether the data type is integer or not */
- attr = get_resource_attr(resource, attr_id);
- if (!attr || attr->type != DATA_TYPE_INT)
+ if (!check_attr_validate(resource, attr_id, DATA_TYPE_INT))
return -EINVAL;
- if (!(attr->id & resource->attr_interest))
+ attr_value = get_resource_attr_value(resource, attr_id);
+ if (!attr_value)
+ return -EINVAL;
+
+ *data = (int)(intptr_t)attr_value->data;
+
+ return 0;
+}
+
+int get_resource_attr_integer_sync(struct resource *resource, u_int64_t attr_id, int *data)
+{
+ int ret;
+
+ ret = update_resource_attr(resource, attr_id);
+ if (ret < 0)
+ return ret;
+
+ return get_resource_attr_integer(resource, attr_id, data);
+}
+
+int get_resource_attr_double(struct resource *resource, u_int64_t attr_id, double *data)
+{
+ struct resource_attribute_value *attr_value = NULL;
+
+ if (!check_attr_validate(resource, attr_id, DATA_TYPE_DOUBLE))
return -EINVAL;
attr_value = get_resource_attr_value(resource, attr_id);
if (!attr_value)
return -EINVAL;
- return attr_value->data.int_value;
+ *data = (double)(intptr_t)attr_value->data;
+
+ return 0;
+}
+
+int get_resource_attr_double_sync(struct resource *resource, u_int64_t attr_id, double *data)
+{
+ int ret;
+
+ ret = update_resource_attr(resource, attr_id);
+ if (ret < 0)
+ return ret;
+
+ return get_resource_attr_double(resource, attr_id, data);
+}
+
+int get_resource_attr_string(struct resource *resource, u_int64_t attr_id, char **data)
+{
+ struct resource_attribute_value *attr_value = NULL;
+
+ if (!check_attr_validate(resource, attr_id, DATA_TYPE_STRING))
+ return -EINVAL;
+
+ attr_value = get_resource_attr_value(resource, attr_id);
+ if (!attr_value)
+ return -EINVAL;
+
+ *data = (char *)attr_value->data;
+
+ return 0;
+}
+
+int put_resource_attr_string(struct resource *resource, u_int64_t attr_id)
+{
+ struct resource_attribute_value *attr_value = NULL;
+
+ if (!check_attr_validate(resource, attr_id, DATA_TYPE_STRING))
+ return -EINVAL;
+
+ attr_value = get_resource_attr_value(resource, attr_id);
+ if (!attr_value || !attr_value->data)
+ return -EINVAL;
+
+ free(attr_value->data);
+ attr_value->data = NULL;
+
+ return 0;
+}
+
+int get_resource_attr_string_sync(struct resource *resource, u_int64_t attr_id, char **data)
+{
+ int ret;
+
+ ret = update_resource_attr(resource, attr_id);
+ if (ret < 0)
+ return ret;
+
+ return get_resource_attr_string(resource, attr_id, data);
+}
+
+int get_resource_attr_array(struct resource *resource, u_int64_t attr_id, struct array_value **data)
+{
+ struct resource_attribute_value *attr_value = NULL;
+
+ if (!check_attr_validate(resource, attr_id, DATA_TYPE_ARRAY))
+ return -EINVAL;
+
+ attr_value = get_resource_attr_value(resource, attr_id);
+ if (!attr_value)
+ return -EINVAL;
+
+ *data = (struct array_value *)attr_value->data;
+
+ return 0;
+}
+
+int put_resource_attr_array(struct resource *resource, u_int64_t attr_id)
+{
+ struct resource_attribute_value *attr_value = NULL;
+
+ if (!check_attr_validate(resource, attr_id, DATA_TYPE_ARRAY))
+ return -EINVAL;
+
+ attr_value = get_resource_attr_value(resource, attr_id);
+ if (!attr_value || !attr_value->data)
+ return -EINVAL;
+
+ free(attr_value->data);
+ attr_value->data = NULL;
+
+ return 0;
}
-int get_resource_attr_integer_sync(struct resource *resource, u_int64_t attr_id)
+int get_resource_attr_array_sync(struct resource *resource, u_int64_t attr_id,
+ struct array_value **data)
{
int ret;
if (ret < 0)
return ret;
- return get_resource_attr_integer(resource, attr_id);
+ return get_resource_attr_array(resource, attr_id, data);
}
void set_resource_attr_interest(struct resource *resource, u_int64_t interest_mask)