Add an interface to write to an nvmem cell.
authorkettenis <kettenis@openbsd.org>
Wed, 2 Mar 2022 12:00:46 +0000 (12:00 +0000)
committerkettenis <kettenis@openbsd.org>
Wed, 2 Mar 2022 12:00:46 +0000 (12:00 +0000)
ok patrick@

sys/dev/ofw/ofw_misc.c
sys/dev/ofw/ofw_misc.h

index abb9f49..e0fbdf8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ofw_misc.c,v 1.34 2021/12/18 09:19:25 kettenis Exp $  */
+/*     $OpenBSD: ofw_misc.c,v 1.35 2022/03/02 12:00:46 kettenis Exp $  */
 /*
  * Copyright (c) 2017-2021 Mark Kettenis
  *
@@ -597,9 +597,48 @@ nvmem_read_cell(int node, const char *name, void *data, bus_size_t size)
                return EINVAL;
 
        nd = nc->nc_nd;
+       if (nd->nd_read == NULL)
+               return EACCES;
        return nd->nd_read(nd->nd_cookie, nc->nc_addr, data, size);
 }
 
+int
+nvmem_write_cell(int node, const char *name, const 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;
+       if (nd->nd_write == NULL)
+               return EACCES;
+       return nd->nd_write(nd->nd_cookie, nc->nc_addr, data, size);
+}
+
 /* Port/endpoint interface support */
 
 LIST_HEAD(, endpoint) endpoints =
index e294d30..2dfa800 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ofw_misc.h,v 1.22 2021/12/18 09:19:25 kettenis Exp $  */
+/*     $OpenBSD: ofw_misc.h,v 1.23 2022/03/02 12:00:46 kettenis Exp $  */
 /*
  * Copyright (c) 2017-2021 Mark Kettenis
  *
@@ -125,6 +125,7 @@ struct nvmem_device {
        int     nd_node;
        void    *nd_cookie;
        int     (*nd_read)(void *, bus_addr_t, void *, bus_size_t);
+       int     (*nd_write)(void *, bus_addr_t, const void *, bus_size_t);
 
        LIST_ENTRY(nvmem_device) nd_list;
        uint32_t nd_phandle;
@@ -133,6 +134,7 @@ 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);
+int    nvmem_write_cell(int, const char *name, const void *, bus_size_t);
 
 /* Port/endpoint interface support */