Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/fdt Fix the pinctrl api to match the spec. A pinctrl...
details: https://anonhg.NetBSD.org/src/rev/6a65d12e24ac
branches: trunk
changeset: 354872:6a65d12e24ac
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sun Jul 02 15:27:58 2017 +0000
description:
Fix the pinctrl api to match the spec. A pinctrl config can have more
than one xref, and an xref may have specifier data associated with it.
diffstat:
sys/dev/fdt/fdt_pinctrl.c | 110 +++++++++++++++++++++++++++++----------------
sys/dev/fdt/fdt_subr.c | 12 ++++-
sys/dev/fdt/fdtvar.h | 8 ++-
3 files changed, 86 insertions(+), 44 deletions(-)
diffs (246 lines):
diff -r 3307b9345efa -r 6a65d12e24ac sys/dev/fdt/fdt_pinctrl.c
--- a/sys/dev/fdt/fdt_pinctrl.c Sun Jul 02 15:09:53 2017 +0000
+++ b/sys/dev/fdt/fdt_pinctrl.c Sun Jul 02 15:27:58 2017 +0000
@@ -1,6 +1,7 @@
-/* $NetBSD: fdt_pinctrl.c,v 1.3 2016/10/11 13:04:57 maxv Exp $ */
+/* $NetBSD: fdt_pinctrl.c,v 1.4 2017/07/02 15:27:58 jmcneill Exp $ */
/*-
+ * Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
* Copyright (c) 2015 Martin Fouts
* All rights reserved.
*
@@ -27,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdt_pinctrl.c,v 1.3 2016/10/11 13:04:57 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdt_pinctrl.c,v 1.4 2017/07/02 15:27:58 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -37,8 +38,8 @@
#include <dev/fdt/fdtvar.h>
struct fdtbus_pinctrl_controller {
+ device_t pc_dev;
int pc_phandle;
- void *pc_cookie;
const struct fdtbus_pinctrl_controller_func *pc_funcs;
struct fdtbus_pinctrl_controller *pc_next;
@@ -47,13 +48,13 @@
static struct fdtbus_pinctrl_controller *fdtbus_pc = NULL;
int
-fdtbus_register_pinctrl_config(void *cookie, int phandle,
+fdtbus_register_pinctrl_config(device_t dev, int phandle,
const struct fdtbus_pinctrl_controller_func *funcs)
{
struct fdtbus_pinctrl_controller *pc;
pc = kmem_alloc(sizeof(*pc), KM_SLEEP);
- pc->pc_cookie = cookie;
+ pc->pc_dev = dev;
pc->pc_phandle = phandle;
pc->pc_funcs = funcs;
@@ -78,57 +79,88 @@
int
fdtbus_pinctrl_set_config_index(int phandle, u_int index)
{
- char buf[80];
- int len, handle;
struct fdtbus_pinctrl_controller *pc;
+ const u_int *pinctrl_data;
+ char buf[16];
+ u_int xref, pinctrl_cells;
+ int len, error;
- snprintf(buf, 80, "pinctrl-%d", index);
+ snprintf(buf, sizeof(buf), "pinctrl-%u", index);
+
+ pinctrl_data = fdtbus_get_prop(phandle, buf, &len);
+ if (pinctrl_data == NULL)
+ return ENOENT;
- len = OF_getprop(phandle, buf, (char *)&handle,
- sizeof(handle));
- if (len != sizeof(int)) {
- printf("%s: couldn't get %s.\n", __func__, buf);
- return -1;
- }
+ while (len > 0) {
+ xref = fdtbus_get_phandle_from_native(be32toh(pinctrl_data[0]));
+ pc = fdtbus_pinctrl_lookup(xref);
+ if (pc == NULL)
+ return ENXIO;
- handle = fdtbus_get_phandle_from_native(be32toh(handle));
+ if (of_getprop_uint32(OF_parent(xref), "#pinctrl-cells", &pinctrl_cells) != 0)
+ pinctrl_cells = 1;
- pc = fdtbus_pinctrl_lookup(handle);
- if (!pc) {
- printf("%s: Couldn't get handle %d for %s\n", __func__, handle,
- buf);
- return -1;
+ error = pc->pc_funcs->set_config(pc->pc_dev, pinctrl_data, pinctrl_cells * 4);
+ if (error != 0)
+ return error;
+
+ pinctrl_data += pinctrl_cells;
+ len -= (pinctrl_cells * 4);
}
- return pc->pc_funcs->set_config(pc->pc_cookie);
+ return 0;
}
int
fdtbus_pinctrl_set_config(int phandle, const char *cfgname)
{
- int index = 0;
- int len;
- char *result;
- char *next;
+ const char *pinctrl_names, *name;
+ int len, index;
- len = OF_getproplen(phandle, "pinctrl-names");
- if (len <= 0)
+ if ((len = OF_getproplen(phandle, "pinctrl-names")) < 0)
return -1;
- result = kmem_zalloc(len, KM_SLEEP);
- OF_getprop(phandle, "pinctrl-names", result, len);
- next = result;
- while (next - result < len) {
- if (!strcmp(next, cfgname)) {
- kmem_free(result, len);
+ pinctrl_names = fdtbus_get_string(phandle, "pinctrl-names");
+
+ for (name = pinctrl_names, index = 0; len > 0;
+ name += strlen(name) + 1, index++) {
+ if (strcmp(name, cfgname) == 0)
return fdtbus_pinctrl_set_config_index(phandle, index);
- }
- index++;
- while (*next)
- next++;
- next++;
}
- kmem_free(result, len);
+ /* Not found */
return -1;
}
+
+static void
+fdtbus_pinctrl_configure_node(int phandle)
+{
+ char buf[256];
+ int child, error;
+
+ for (child = OF_child(phandle); child; child = OF_peer(child)) {
+ if (!fdtbus_status_okay(child))
+ continue;
+
+ /* Configure child nodes */
+ fdtbus_pinctrl_configure_node(child);
+
+ /*
+ * Set configuration 0 for this node. This may fail if the
+ * pinctrl provider is missing; that's OK, we will re-configure
+ * when that provider attaches.
+ */
+ fdtbus_get_path(child, buf, sizeof(buf));
+ error = fdtbus_pinctrl_set_config_index(child, 0);
+ if (error == 0)
+ aprint_debug("pinctrl: set config pinctrl-0 for %s\n", buf);
+ else if (error != ENOENT)
+ aprint_debug("pinctrl: failed to set config pinctrl-0 for %s: %d\n", buf, error);
+ }
+}
+
+void
+fdtbus_pinctrl_configure(void)
+{
+ fdtbus_pinctrl_configure_node(OF_finddevice("/"));
+}
diff -r 3307b9345efa -r 6a65d12e24ac sys/dev/fdt/fdt_subr.c
--- a/sys/dev/fdt/fdt_subr.c Sun Jul 02 15:09:53 2017 +0000
+++ b/sys/dev/fdt/fdt_subr.c Sun Jul 02 15:27:58 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fdt_subr.c,v 1.14 2017/06/30 09:11:22 jmcneill Exp $ */
+/* $NetBSD: fdt_subr.c,v 1.15 2017/07/02 15:27:58 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdt_subr.c,v 1.14 2017/06/30 09:11:22 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdt_subr.c,v 1.15 2017/07/02 15:27:58 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -407,6 +407,14 @@
return strncmp(prop, "ok", 2) == 0;
}
+const void *
+fdtbus_get_prop(int phandle, const char *prop, int *plen)
+{
+ const int off = fdtbus_phandle2offset(phandle);
+
+ return fdt_getprop(fdtbus_get_data(), off, prop, plen);
+}
+
const char *
fdtbus_get_string(int phandle, const char *prop)
{
diff -r 3307b9345efa -r 6a65d12e24ac sys/dev/fdt/fdtvar.h
--- a/sys/dev/fdt/fdtvar.h Sun Jul 02 15:09:53 2017 +0000
+++ b/sys/dev/fdt/fdtvar.h Sun Jul 02 15:27:58 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: fdtvar.h,v 1.22 2017/06/30 09:11:22 jmcneill Exp $ */
+/* $NetBSD: fdtvar.h,v 1.23 2017/07/02 15:27:58 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -85,7 +85,7 @@
};
struct fdtbus_pinctrl_controller_func {
- int (*set_config)(void *);
+ int (*set_config)(device_t, const void *, size_t);
};
struct fdtbus_regulator_controller;
@@ -211,7 +211,7 @@
const struct fdtbus_i2c_controller_func *);
int fdtbus_register_gpio_controller(device_t, int,
const struct fdtbus_gpio_controller_func *);
-int fdtbus_register_pinctrl_config(void *, int,
+int fdtbus_register_pinctrl_config(device_t, int,
const struct fdtbus_pinctrl_controller_func *);
int fdtbus_register_regulator_controller(device_t, int,
const struct fdtbus_regulator_controller_func *);
@@ -241,6 +241,7 @@
void fdtbus_gpio_write(struct fdtbus_gpio_pin *, int);
int fdtbus_gpio_read_raw(struct fdtbus_gpio_pin *);
void fdtbus_gpio_write_raw(struct fdtbus_gpio_pin *, int);
+void fdtbus_pinctrl_configure(void);
int fdtbus_pinctrl_set_config_index(int, u_int);
int fdtbus_pinctrl_set_config(int, const char *);
struct fdtbus_regulator *fdtbus_regulator_acquire(int, const char *);
@@ -294,6 +295,7 @@
bool fdtbus_status_okay(int);
+const void * fdtbus_get_prop(int, const char *, int *);
const char * fdtbus_get_string(int, const char *);
int fdtbus_print(void *, const char *);
Home |
Main Index |
Thread Index |
Old Index