9
0
Fork 0

Merge branch 'for-next/state'

This commit is contained in:
Sascha Hauer 2015-06-09 09:26:44 +02:00
commit e349701487
8 changed files with 393 additions and 117 deletions

View File

@ -1,4 +1,6 @@
barebox,state
.. _barebox,state:
barebox state
=============
Overview

1
arch/arm/crypto/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/sha256-core.S

View File

@ -159,6 +159,25 @@ int of_register_fixup(int (*fixup)(struct device_node *, void *), void *context)
return 0;
}
/*
* Remove a previously registered fixup. Only the first (if any) is removed.
* Returns 0 if a match was found (and removed), -ENOENT otherwise.
*/
int of_unregister_fixup(int (*fixup)(struct device_node *, void *),
void *context)
{
struct of_fixup *of_fixup;
list_for_each_entry(of_fixup, &of_fixup_list, list) {
if (of_fixup->fixup == fixup && of_fixup->context == context) {
list_del(&of_fixup->list);
return 0;
}
}
return -ENOENT;
}
/*
* Apply registered fixups for the given fdt. The fdt must have
* enough free space to apply the fixups.

View File

@ -54,12 +54,14 @@ struct state_backend {
int (*load)(struct state_backend *backend, struct state *state);
int (*save)(struct state_backend *backend, struct state *state);
const char *name;
const char *of_path;
const char *path;
};
enum state_variable_type {
STATE_TYPE_INVALID = 0,
STATE_TYPE_ENUM,
STATE_TYPE_U8,
STATE_TYPE_U32,
STATE_TYPE_MAC,
};
@ -74,12 +76,20 @@ struct state_variable {
void *raw;
};
enum state_convert {
STATE_CONVERT_FROM_NODE,
STATE_CONVERT_FROM_NODE_CREATE,
STATE_CONVERT_TO_NODE,
STATE_CONVERT_FIXUP,
};
/* A variable type (uint32, enum32) */
struct variable_type {
enum state_variable_type type;
const char *type_name;
struct list_head list;
int (*export)(struct state_variable *, struct device_node *);
int (*export)(struct state_variable *, struct device_node *,
enum state_convert);
int (*import)(struct state_variable *, const struct device_node *);
struct state_variable *(*create)(struct state *state,
const char *name, struct device_node *);
@ -126,15 +136,15 @@ static inline struct state_uint32 *to_state_uint32(struct state_variable *s)
}
static int state_uint32_export(struct state_variable *var,
struct device_node *node)
struct device_node *node, enum state_convert conv)
{
struct state_uint32 *su32 = to_state_uint32(var);
int ret;
if (su32->value_default) {
if (su32->value_default || conv == STATE_CONVERT_FIXUP) {
ret = of_property_write_u32(node, "default",
su32->value_default);
if (ret)
if (ret || conv == STATE_CONVERT_FIXUP)
return ret;
}
@ -153,7 +163,7 @@ static int state_uint32_import(struct state_variable *sv,
return 0;
}
static struct state_variable *state_uint32_create(struct state *state,
static struct state_variable *state_uint8_create(struct state *state,
const char *name, struct device_node *node)
{
struct state_uint32 *su32;
@ -168,6 +178,32 @@ static struct state_variable *state_uint32_create(struct state *state,
return ERR_CAST(param);
}
su32->param = param;
su32->var.size = sizeof(uint8_t);
#ifdef __LITTLE_ENDIAN
su32->var.raw = &su32->value;
#else
su32->var.raw = &su32->value + 3;
#endif
return &su32->var;
}
static struct state_variable *state_uint32_create(struct state *state,
const char *name, struct device_node *node)
{
struct state_uint32 *su32;
struct param_d *param;
su32 = xzalloc(sizeof(*su32));
param = dev_add_param_int(&state->dev, name, state_set_dirty,
NULL, &su32->value, "%u", state);
if (IS_ERR(param)) {
free(su32);
return ERR_CAST(param);
}
su32->param = param;
su32->var.size = sizeof(uint32_t);
su32->var.raw = &su32->value;
@ -193,16 +229,16 @@ static inline struct state_enum32 *to_state_enum32(struct state_variable *s)
}
static int state_enum32_export(struct state_variable *var,
struct device_node *node)
struct device_node *node, enum state_convert conv)
{
struct state_enum32 *enum32 = to_state_enum32(var);
int ret, i, len;
char *prop, *str;
if (enum32->value_default) {
if (enum32->value_default || conv == STATE_CONVERT_FIXUP) {
ret = of_property_write_u32(node, "default",
enum32->value_default);
if (ret)
if (ret || conv == STATE_CONVERT_FIXUP)
return ret;
}
@ -309,14 +345,14 @@ static inline struct state_mac *to_state_mac(struct state_variable *s)
}
static int state_mac_export(struct state_variable *var,
struct device_node *node)
struct device_node *node, enum state_convert conv)
{
struct state_mac *mac = to_state_mac(var);
int ret;
ret = of_property_write_u8_array(node, "default", mac->value_default,
ARRAY_SIZE(mac->value_default));
if (ret)
if (ret || conv == STATE_CONVERT_FIXUP)
return ret;
return of_property_write_u8_array(node, "value", mac->value,
@ -363,6 +399,12 @@ out:
static struct variable_type types[] = {
{
.type = STATE_TYPE_U8,
.type_name = "uint8",
.export = state_uint32_export,
.import = state_uint32_import,
.create = state_uint8_create,
}, {
.type = STATE_TYPE_U32,
.type_name = "uint32",
.export = state_uint32_export,
@ -426,13 +468,6 @@ static struct state *state_new(const char *name)
return state;
}
static void state_release(struct state *state)
{
list_del(&state->list);
unregister_device(&state->dev);
free(state);
}
static struct state_variable *state_find_var(struct state *state,
const char *name)
{
@ -446,12 +481,6 @@ static struct state_variable *state_find_var(struct state *state,
return ERR_PTR(-ENOENT);
}
enum state_convert {
STATE_CONVERT_FROM_NODE,
STATE_CONVERT_FROM_NODE_CREATE,
STATE_CONVERT_TO_NODE,
};
static int state_convert_node_variable(struct state *state,
struct device_node *node, struct device_node *parent,
const char *parent_name, enum state_convert conv)
@ -476,7 +505,8 @@ static int state_convert_node_variable(struct state *state,
parent_name, parent_name[0] ? "." : "", short_name);
free(short_name);
if (conv == STATE_CONVERT_TO_NODE)
if ((conv == STATE_CONVERT_TO_NODE) ||
(conv == STATE_CONVERT_FIXUP))
new_node = of_new_node(parent, node->name);
for_each_child_of_node(node, child) {
@ -489,6 +519,15 @@ static int state_convert_node_variable(struct state *state,
/* parents are allowed to have no type */
ret = of_property_read_string(node, "type", &type_name);
if (!list_empty(&node->children) && ret == -EINVAL) {
if (conv == STATE_CONVERT_FIXUP) {
ret = of_property_write_u32(new_node, "#address-cells", 1);
if (ret)
goto out_free;
ret = of_property_write_u32(new_node, "#size-cells", 1);
if (ret)
goto out_free;
}
ret = 0;
goto out_free;
} else if (ret) {
@ -512,13 +551,16 @@ static int state_convert_node_variable(struct state *state,
ret = of_property_read_u32_array(node, "reg", start_size,
ARRAY_SIZE(start_size));
if (ret)
if (ret) {
dev_err(&state->dev,
"%s: reg property not found\n", name);
goto out_free;
}
if (start_size[1] != sv->size) {
dev_err(&state->dev,
"size mismatch: type=%s(size=%u) size=%u\n",
type_name, sv->size, start_size[1]);
"%s: size mismatch: type=%s(size=%u) size=%u\n",
name, type_name, sv->size, start_size[1]);
ret = -EOVERFLOW;
goto out_free;
}
@ -539,7 +581,8 @@ static int state_convert_node_variable(struct state *state,
}
free(name);
if (conv == STATE_CONVERT_TO_NODE) {
if ((conv == STATE_CONVERT_TO_NODE) ||
(conv == STATE_CONVERT_FIXUP)) {
ret = of_set_property(new_node, "type",
vtype->type_name,
strlen(vtype->type_name) + 1, 1);
@ -556,8 +599,9 @@ static int state_convert_node_variable(struct state *state,
}
}
if (conv == STATE_CONVERT_TO_NODE)
ret = vtype->export(sv, new_node);
if ((conv == STATE_CONVERT_TO_NODE) ||
(conv == STATE_CONVERT_FIXUP))
ret = vtype->export(sv, new_node, conv);
else
ret = vtype->import(sv, node);
@ -571,20 +615,21 @@ out:
return ret;
}
static struct device_node *state_to_node(struct state *state)
static struct device_node *state_to_node(struct state *state, struct device_node *parent,
enum state_convert conv)
{
struct device_node *child;
struct device_node *root;
int ret;
root = of_new_node(NULL, NULL);
root = of_new_node(parent, state->root->name);
ret = of_property_write_u32(root, "magic", state->magic);
if (ret)
goto out;
for_each_child_of_node(state->root, child) {
ret = state_convert_node_variable(state, child, root, "",
STATE_CONVERT_TO_NODE);
conv);
if (ret)
goto out;
}
@ -657,6 +702,101 @@ static int state_from_node(struct state *state, struct device_node *node,
return ret;
}
static int of_state_fixup(struct device_node *root, void *ctx)
{
struct state *state = ctx;
const char *compatible = "barebox,state";
struct device_node *new_node, *node, *parent, *backend_node;
struct property *p;
int ret;
phandle phandle;
node = of_find_node_by_path_from(root, state->root->full_name);
if (node) {
/* replace existing node - it will be deleted later */
parent = node->parent;
} else {
char *of_path, *c;
/* look for parent, remove last '/' from path */
of_path = xstrdup(state->root->full_name);
c = strrchr(of_path, '/');
if (!c)
return -ENODEV;
*c = '0';
parent = of_find_node_by_path(of_path);
if (!parent)
parent = root;
free(of_path);
}
/* serialize variable definitions */
new_node = state_to_node(state, parent, STATE_CONVERT_FIXUP);
if (IS_ERR(new_node))
return PTR_ERR(new_node);
/* compatible */
p = of_new_property(new_node, "compatible", compatible,
strlen(compatible) + 1);
if (!p) {
ret = -ENOMEM;
goto out;
}
/* backend-type */
if (!state->backend) {
ret = -ENODEV;
goto out;
}
p = of_new_property(new_node, "backend-type", state->backend->name,
strlen(state->backend->name) + 1);
if (!p) {
ret = -ENOMEM;
goto out;
}
/* backend phandle */
backend_node = of_find_node_by_path_from(root, state->backend->of_path);
if (!backend_node) {
ret = -ENODEV;
goto out;
}
phandle = of_node_create_phandle(backend_node);
ret = of_property_write_u32(new_node, "backend", phandle);
if (ret)
goto out;
/* address-cells + size-cells */
ret = of_property_write_u32(new_node, "#address-cells", 1);
if (ret)
goto out;
ret = of_property_write_u32(new_node, "#size-cells", 1);
if (ret)
goto out;
/* delete existing node */
if (node)
of_delete_node(node);
return 0;
out:
of_delete_node(new_node);
return ret;
}
void state_release(struct state *state)
{
of_unregister_fixup(of_state_fixup, state);
list_del(&state->list);
unregister_device(&state->dev);
free(state);
}
/*
* state_new_from_node - create a new state instance from a device_node
*
@ -678,27 +818,11 @@ struct state *state_new_from_node(const char *name, struct device_node *node)
return ERR_PTR(ret);
}
return state;
}
/*
* state_new_from_fdt - create a new state instance from a fdt binary blob
*
* @name The name of the new state instance
* @fdt The fdt binary blob describing the new state instance
*/
struct state *state_new_from_fdt(const char *name, void *fdt)
{
struct state *state;
struct device_node *root;
root = of_unflatten_dtb(fdt);
if (!root)
return ERR_PTR(-EINVAL);
state = state_new_from_node(name, root);
of_delete_node(root);
ret = of_register_fixup(of_state_fixup, state);
if (ret) {
state_release(state);
return ERR_PTR(ret);
}
return state;
}
@ -757,10 +881,13 @@ int state_load(struct state *state)
return -ENOSYS;
ret = state->backend->load(state->backend, state);
if (ret)
if (ret) {
dev_warn(&state->dev, "load failed\n");
state->dirty = 1;
else
} else {
dev_info(&state->dev, "load successful\n");
state->dirty = 0;
}
return ret;
}
@ -809,7 +936,7 @@ static int mtd_get_meminfo(const char *path, struct mtd_info_user *meminfo)
{
int fd, ret;
fd = open(path, O_RDWR);
fd = open(path, O_RDONLY);
if (fd < 0)
return fd;
@ -863,7 +990,7 @@ static int state_backend_dtb_save(struct state_backend *backend,
struct device_node *root;
struct fdt_header *fdt;
root = state_to_node(state);
root = state_to_node(state, NULL, STATE_CONVERT_TO_NODE);
if (IS_ERR(root))
return PTR_ERR(root);
@ -906,7 +1033,7 @@ out:
* @state The state instance to work on
* @path The path where the state will be stored to
*/
int state_backend_dtb_file(struct state *state, const char *path)
int state_backend_dtb_file(struct state *state, const char *of_path, const char *path)
{
struct state_backend_dtb *backend_dtb;
struct state_backend *backend;
@ -921,13 +1048,14 @@ int state_backend_dtb_file(struct state *state, const char *path)
backend->load = state_backend_dtb_load;
backend->save = state_backend_dtb_save;
backend->of_path = xstrdup(of_path);
backend->path = xstrdup(path);
backend->name = "dtb";
state->backend = backend;
ret = mtd_get_meminfo(backend->path, &meminfo);
if (!ret && !(meminfo.mtd->flags & MTD_NO_ERASE))
if (!ret && !(meminfo.flags & MTD_NO_ERASE))
backend_dtb->need_erase = true;
return 0;
@ -938,9 +1066,9 @@ int state_backend_dtb_file(struct state *state, const char *path)
*/
struct state_backend_raw {
struct state_backend backend;
unsigned long size_data; /* The raw data size (without magic and crc) */
unsigned long size_full;
unsigned long step; /* The step in bytes between two copies */
unsigned long size_data; /* The raw data size (without header) */
unsigned long size_full; /* The size header + raw data */
unsigned long stride; /* The stride size in bytes of the copies */
off_t offset; /* offset in the storage file */
size_t size; /* size of the storage area */
int num_copy_read; /* The first successfully read copy */
@ -961,16 +1089,23 @@ static int backend_raw_load_one(struct state_backend_raw *backend_raw,
uint32_t crc;
struct state_variable *sv;
struct backend_raw_header header = {};
unsigned long max_len;
int ret;
void *buf;
max_len = backend_raw->stride;
ret = lseek(fd, offset, SEEK_SET);
if (ret < 0)
return ret;
ret = read_full(fd, &header, sizeof(header));
if (ret < 0)
max_len -= sizeof(header);
if (ret < 0) {
dev_err(&state->dev,
"cannot read header from backend device");
return ret;
}
crc = crc32(0, &header, sizeof(header) - sizeof(uint32_t));
if (crc != header.header_crc) {
@ -987,6 +1122,13 @@ static int backend_raw_load_one(struct state_backend_raw *backend_raw,
return -EINVAL;
}
if (header.data_len > max_len) {
dev_err(&state->dev,
"invalid data_len %u in header, max is %lu\n",
header.data_len, max_len);
return -EINVAL;
}
buf = xzalloc(header.data_len);
ret = read_full(fd, buf, header.data_len);
@ -1024,11 +1166,13 @@ static int state_backend_raw_load(struct state_backend *backend,
int ret = 0, fd, i;
fd = open(backend->path, O_RDONLY);
if (fd < 0)
if (fd < 0) {
dev_err(&state->dev, "cannot open %s\n", backend->path);
return fd;
}
for (i = 0; i < RAW_BACKEND_COPIES; i++) {
off_t offset = backend_raw->offset + i * backend_raw->step;
off_t offset = backend_raw->offset + i * backend_raw->stride;
ret = backend_raw_load_one(backend_raw, state, fd, offset);
if (!ret) {
@ -1044,11 +1188,11 @@ static int state_backend_raw_load(struct state_backend *backend,
return ret;
}
static int backend_raw_write_one(struct state_backend_raw *backend_raw,
static int backend_raw_save_one(struct state_backend_raw *backend_raw,
struct state *state, int fd, int num, void *buf, size_t size)
{
int ret;
off_t offset = backend_raw->offset + num * backend_raw->step;
off_t offset = backend_raw->offset + num * backend_raw->stride;
dev_dbg(&state->dev, "%s: 0x%08lx 0x%08zx\n",
__func__, offset, size);
@ -1058,7 +1202,7 @@ static int backend_raw_write_one(struct state_backend_raw *backend_raw,
return ret;
if (backend_raw->need_erase) {
ret = erase(fd, backend_raw->size_full, offset);
ret = erase(fd, backend_raw->stride, offset);
if (ret)
return ret;
}
@ -1075,14 +1219,12 @@ static int state_backend_raw_save(struct state_backend *backend,
{
struct state_backend_raw *backend_raw = container_of(backend,
struct state_backend_raw, backend);
int ret = 0, size, fd;
int ret = 0, fd, i;
void *buf, *data;
struct backend_raw_header *header;
struct state_variable *sv;
size = backend_raw->size_data + sizeof(struct backend_raw_header);
buf = xzalloc(size);
buf = xzalloc(backend_raw->size_full);
header = buf;
data = buf + sizeof(*header);
@ -1100,13 +1242,20 @@ static int state_backend_raw_save(struct state_backend *backend,
if (fd < 0)
goto out_free;
ret = backend_raw_write_one(backend_raw, state, fd,
!backend_raw->num_copy_read, buf, size);
if (ret)
goto out_close;
/* save other slots first */
for (i = 0; i < RAW_BACKEND_COPIES; i++) {
if (i == backend_raw->num_copy_read)
continue;
ret = backend_raw_write_one(backend_raw, state, fd,
backend_raw->num_copy_read, buf, size);
ret = backend_raw_save_one(backend_raw, state, fd,
i, buf, backend_raw->size_full);
if (ret)
goto out_close;
}
ret = backend_raw_save_one(backend_raw, state, fd,
backend_raw->num_copy_read, buf, backend_raw->size_full);
if (ret)
goto out_close;
@ -1119,6 +1268,60 @@ out_free:
return ret;
}
#ifdef __BAREBOX__
#define STAT_GIVES_SIZE(s) (S_ISREG(s.st_mode) || S_ISCHR(s.st_mode))
#define BLKGET_GIVES_SIZE(s) 0
#ifndef BLKGETSIZE64
#define BLKGETSIZE64 -1
#endif
#else
#define STAT_GIVES_SIZE(s) (S_ISREG(s.st_mode))
#define BLKGET_GIVES_SIZE(s) (S_ISBLK(s.st_mode))
#endif
static int state_backend_raw_file_get_size(const char *path, size_t *out_size)
{
struct mtd_info_user meminfo;
struct stat s;
int ret;
ret = stat(path, &s);
if (ret)
return -errno;
/*
* under Linux, stat() gives the size only on regular files
* under barebox, it works on char dev, too
*/
if (STAT_GIVES_SIZE(s)) {
*out_size = s.st_size;
return 0;
}
/* this works under Linux on block devs */
if (BLKGET_GIVES_SIZE(s)) {
int fd;
fd = open(path, O_RDONLY);
if (fd < 0)
return -errno;
ret = ioctl(fd, BLKGETSIZE64, out_size);
close(fd);
if (!ret)
return 0;
}
/* try mtd next */
ret = mtd_get_meminfo(path, &meminfo);
if (!ret) {
*out_size = meminfo.size;
return 0;
}
return ret;
}
/*
* state_backend_raw_file - create a raw file backend store for a state instance
*
@ -1136,32 +1339,34 @@ out_free:
* device @size may be 0. The two copies are spread to different
* eraseblocks if approriate for this device.
*/
int state_backend_raw_file(struct state *state, const char *path, off_t offset,
size_t size)
int state_backend_raw_file(struct state *state, const char *of_path,
const char *path, off_t offset, size_t size)
{
struct state_backend_raw *backend_raw;
struct state_backend *backend;
struct state_variable *sv;
int ret;
struct stat s;
struct mtd_info_user meminfo;
size_t path_size = 0;
int ret;
if (state->backend)
return -EBUSY;
ret = stat(path, &s);
if (!ret && S_ISCHR(s.st_mode)) {
if (size == 0)
size = s.st_size;
else if (offset + size > s.st_size)
return -EINVAL;
}
ret = state_backend_raw_file_get_size(path, &path_size);
if (ret)
return ret;
if (size == 0)
size = path_size;
else if (offset + size > path_size)
return -EINVAL;
backend_raw = xzalloc(sizeof(*backend_raw));
backend = &backend_raw->backend;
backend->load = state_backend_raw_load;
backend->save = state_backend_raw_save;
backend->of_path = xstrdup(of_path);
backend->path = xstrdup(path);
backend->name = "raw";
@ -1175,18 +1380,21 @@ int state_backend_raw_file(struct state *state, const char *path, off_t offset,
state->backend = backend;
ret = mtd_get_meminfo(backend->path, &meminfo);
if (!ret && !(meminfo.mtd->flags & MTD_NO_ERASE)) {
if (!ret && !(meminfo.flags & MTD_NO_ERASE)) {
backend_raw->need_erase = true;
backend_raw->step = ALIGN(backend_raw->size_full,
meminfo.erasesize);
backend_raw->size_full = ALIGN(backend_raw->size_full,
meminfo.writesize);
backend_raw->stride = ALIGN(backend_raw->size_full,
meminfo.erasesize);
dev_dbg(&state->dev, "is a mtd, adjust stepsize to %ld\n",
backend_raw->step);
backend_raw->stride);
} else {
backend_raw->step = backend_raw->size_full;
backend_raw->stride = backend_raw->size_full;
}
if (backend_raw->size / backend_raw->step < RAW_BACKEND_COPIES) {
dev_err(&state->dev, "not enough space for two copies\n");
if (backend_raw->size / backend_raw->stride < RAW_BACKEND_COPIES) {
dev_err(&state->dev, "not enough space for two copies (%lu each)\n",
backend_raw->stride);
ret = -ENOSPC;
goto err;
}

View File

@ -24,10 +24,12 @@
static int state_probe(struct device_d *dev)
{
struct device_node *np = dev->device_node;
struct device_node *partition_node;
struct state *state;
const char *alias;
const char *backend_type = NULL;
int ret;
int len, ret;
const char *of_path;
char *path;
if (!np)
@ -41,28 +43,70 @@ static int state_probe(struct device_d *dev)
if (IS_ERR(state))
return PTR_ERR(state);
ret = of_find_path(np, "backend", &path, 0);
if (ret)
return ret;
of_path = of_get_property(np, "backend", &len);
if (!of_path) {
ret = -ENODEV;
goto out_release;
}
dev_info(dev, "outpath: %s\n", path);
/* guess if of_path is a path, not a phandle */
if (of_path[0] == '/' && len > 1) {
ret = of_find_path(np, "backend", &path, 0);
if (ret)
goto out_release;
} else {
struct device_d *dev;
struct cdev *cdev;
partition_node = of_parse_phandle(np, "backend", 0);
if (!partition_node) {
ret = -ENODEV;
goto out_release;
}
dev = of_find_device_by_node(partition_node);
if (!list_is_singular(&dev->cdevs)) {
ret = -ENODEV;
goto out_release;
}
cdev = list_first_entry(&dev->cdevs, struct cdev, devices_list);
if (!cdev) {
ret = -ENODEV;
goto out_release;
}
path = asprintf("/dev/%s", cdev->name);
of_path = partition_node->full_name;
}
ret = of_property_read_string(np, "backend-type", &backend_type);
if (ret)
return ret;
else if (!strcmp(backend_type, "raw"))
ret = state_backend_raw_file(state, path, 0, 0);
else if (!strcmp(backend_type, "dtb"))
ret = state_backend_dtb_file(state, path);
else
if (ret) {
goto out_free;
} else if (!strcmp(backend_type, "raw")) {
ret = state_backend_raw_file(state, of_path, path, 0, 0);
} else if (!strcmp(backend_type, "dtb")) {
ret = state_backend_dtb_file(state, of_path, path);
} else {
dev_warn(dev, "invalid backend type: %s\n", backend_type);
ret = -ENODEV;
goto out_free;
}
if (ret)
return ret;
goto out_free;
dev_info(dev, "backend: %s, path: %s, of_path: %s\n", backend_type, path, of_path);
free(path);
state_load(state);
return 0;
out_free:
free(path);
out_release:
state_release(state);
return ret;
}
static __maybe_unused struct of_device_id state_ids[] = {

View File

@ -21,7 +21,7 @@
#ifdef CONFIG_HABV4
int habv4_get_status(void);
#else
static inline int habv4_get_status()
static inline int habv4_get_status(void)
{
return -EPERM;
}

View File

@ -243,6 +243,7 @@ struct device_d *of_find_device_by_node_path(const char *path);
#define OF_FIND_PATH_FLAGS_BB 1 /* return .bb device if available */
int of_find_path(struct device_node *node, const char *propname, char **outpath, unsigned flags);
int of_register_fixup(int (*fixup)(struct device_node *, void *), void *context);
int of_unregister_fixup(int (*fixup)(struct device_node *, void *), void *context);
struct device_node *of_find_node_by_alias(struct device_node *root,
const char *alias);
struct device_node *of_find_node_by_path_or_alias(struct device_node *root,

View File

@ -5,12 +5,13 @@
struct state;
int state_backend_dtb_file(struct state *state, const char *path);
int state_backend_raw_file(struct state *state, const char *path,
off_t offset, size_t size);
int state_backend_dtb_file(struct state *state, const char *of_path,
const char *path);
int state_backend_raw_file(struct state *state, const char *of_path,
const char *path, off_t offset, size_t size);
struct state *state_new_from_fdt(const char *name, void *fdt);
struct state *state_new_from_node(const char *name, struct device_node *node);
void state_release(struct state *state);
struct state *state_by_name(const char *name);
struct state *state_by_node(const struct device_node *node);