summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2020-01-23 02:57:10 +0000
committerkettenis <kettenis@openbsd.org>2020-01-23 02:57:10 +0000
commit1bd1536fb12fd18f976cb50868fccb0b0631858c (patch)
tree9909efa5b188f167611920e72d3e710939d643bc
parentregen after adding pppac (diff)
downloadwireguard-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.c80
-rw-r--r--sys/dev/ofw/ofw_misc.h3
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_ */