diff options
author | 2020-01-23 02:57:10 +0000 | |
---|---|---|
committer | 2020-01-23 02:57:10 +0000 | |
commit | 1bd1536fb12fd18f976cb50868fccb0b0631858c (patch) | |
tree | 9909efa5b188f167611920e72d3e710939d643bc | |
parent | regen after adding pppac (diff) | |
download | wireguard-openbsd-1bd1536fb12fd18f976cb50868fccb0b0631858c.tar.xz wireguard-openbsd-1bd1536fb12fd18f976cb50868fccb0b0631858c.zip |
Add an interface to read an nvmem "cell".
ok patrick@
-rw-r--r-- | sys/dev/ofw/ofw_misc.c | 80 | ||||
-rw-r--r-- | sys/dev/ofw/ofw_misc.h | 3 |
2 files changed, 78 insertions, 5 deletions
diff --git a/sys/dev/ofw/ofw_misc.c b/sys/dev/ofw/ofw_misc.c index 7856088933f..e6672eb4fa9 100644 --- a/sys/dev/ofw/ofw_misc.c +++ b/sys/dev/ofw/ofw_misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ofw_misc.c,v 1.11 2020/01/21 00:21:55 kettenis Exp $ */ +/* $OpenBSD: ofw_misc.c,v 1.12 2020/01/23 02:57:10 kettenis Exp $ */ /* * Copyright (c) 2017 Mark Kettenis * @@ -345,14 +345,51 @@ pwm_set_state(uint32_t *cells, struct pwm_state *ps) LIST_HEAD(, nvmem_device) nvmem_devices = LIST_HEAD_INITIALIZER(nvmem_devices); +struct nvmem_cell { + uint32_t nc_phandle; + struct nvmem_device *nc_nd; + bus_addr_t nc_addr; + bus_size_t nc_size; + + LIST_ENTRY(nvmem_cell) nc_list; +}; + +LIST_HEAD(, nvmem_cell) nvmem_cells = + LIST_HEAD_INITIALIZER(nvmem_cells); + +void +nvmem_register_child(int node, struct nvmem_device *nd) +{ + struct nvmem_cell *nc; + uint32_t phandle; + uint32_t reg[2]; + + phandle = OF_getpropint(node, "phandle", 0); + if (phandle == 0) + return; + + if (OF_getpropintarray(node, "reg", reg, sizeof(reg)) != sizeof(reg)) + return; + + nc = malloc(sizeof(struct nvmem_cell), M_DEVBUF, M_WAITOK); + nc->nc_phandle = phandle; + nc->nc_nd = nd; + nc->nc_addr = reg[0]; + nc->nc_size = reg[1]; + LIST_INSERT_HEAD(&nvmem_cells, nc, nc_list); +} + void nvmem_register(struct nvmem_device *nd) { + int node; + nd->nd_phandle = OF_getpropint(nd->nd_node, "phandle", 0); - if (nd->nd_phandle == 0) - return; + if (nd->nd_phandle) + LIST_INSERT_HEAD(&nvmem_devices, nd, nd_list); - LIST_INSERT_HEAD(&nvmem_devices, nd, nd_list); + for (node = OF_child(nd->nd_node); node; node = OF_peer(node)) + nvmem_register_child(node, nd); } int @@ -367,3 +404,38 @@ nvmem_read(uint32_t phandle, bus_addr_t addr, void *data, bus_size_t size) return ENXIO; } + +int +nvmem_read_cell(int node, const char *name, void *data, bus_size_t size) +{ + struct nvmem_device *nd; + struct nvmem_cell *nc; + uint32_t phandle, *phandles; + int id, len; + + id = OF_getindex(node, name, "nvmem-cell-names"); + if (id < 0) + return ENXIO; + + len = OF_getproplen(node, "nvmem-cells"); + if (len <= 0) + return ENXIO; + + phandles = malloc(len, M_TEMP, M_WAITOK); + OF_getpropintarray(node, "nvmem-cells", phandles, len); + phandle = phandles[id]; + free(phandles, M_TEMP, len); + + LIST_FOREACH(nc, &nvmem_cells, nc_list) { + if (nc->nc_phandle == phandle) + break; + } + if (nc == NULL) + return ENXIO; + + if (size > nc->nc_size) + return EINVAL; + + nd = nc->nc_nd; + return nd->nd_read(nd->nd_cookie, nc->nc_addr, data, size); +} diff --git a/sys/dev/ofw/ofw_misc.h b/sys/dev/ofw/ofw_misc.h index d286ea1fecf..53b3617851d 100644 --- a/sys/dev/ofw/ofw_misc.h +++ b/sys/dev/ofw/ofw_misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ofw_misc.h,v 1.8 2020/01/21 00:21:55 kettenis Exp $ */ +/* $OpenBSD: ofw_misc.h,v 1.9 2020/01/23 02:57:10 kettenis Exp $ */ /* * Copyright (c) 2017 Mark Kettenis * @@ -127,5 +127,6 @@ struct nvmem_device { void nvmem_register(struct nvmem_device *); int nvmem_read(uint32_t, bus_addr_t, void *, bus_size_t); +int nvmem_read_cell(int, const char *name, void *, bus_size_t); #endif /* _DEV_OFW_MISC_H_ */ |