summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authormarty <marty@NetBSD.org>2016-01-01 22:35:44 +0000
committermarty <marty@NetBSD.org>2016-01-01 22:35:44 +0000
commitf83aba99f073fb17e57d482e9a002fff32bd5ef1 (patch)
tree8bae45006a1c910a204f94ded4c3a0140fc9e9b0 /sys/dev
parent3054d56d7a99fe17140ae265b3bd0aeeab392a0b (diff)
FDT pinctl - review from Jared
These changes reflect a redesign based on a preliminary review by Jared. Instead of the acquire/release/set/get approach of the original, this uses a much simpler, and cleaner register/set approach.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/fdt/fdt_pinctrl.c95
-rw-r--r--sys/dev/fdt/fdtvar.h15
2 files changed, 63 insertions, 47 deletions
diff --git a/sys/dev/fdt/fdt_pinctrl.c b/sys/dev/fdt/fdt_pinctrl.c
index 0d265cca560..4e43439bb33 100644
--- a/sys/dev/fdt/fdt_pinctrl.c
+++ b/sys/dev/fdt/fdt_pinctrl.c
@@ -1,7 +1,7 @@
-/* $NetBSD: fdt_pinctrl.c,v 1.1 2015/12/30 04:23:39 marty Exp $ */
+/* $NetBSD: fdt_pinctrl.c,v 1.2 2016/01/01 22:35:44 marty Exp $ */
/*-
- * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
+ * Copyright (c) 2015 Martin Fouts
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdt_pinctrl.c,v 1.1 2015/12/30 04:23:39 marty Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdt_pinctrl.c,v 1.2 2016/01/01 22:35:44 marty Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -37,8 +37,8 @@ __KERNEL_RCSID(0, "$NetBSD: fdt_pinctrl.c,v 1.1 2015/12/30 04:23:39 marty Exp $"
#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 +47,13 @@ struct fdtbus_pinctrl_controller {
static struct fdtbus_pinctrl_controller *fdtbus_pc = NULL;
int
-fdtbus_register_pinctrl_controller(device_t dev, int phandle,
+fdtbus_register_pinctrl_config(void *cookie, int phandle,
const struct fdtbus_pinctrl_controller_func *funcs)
{
struct fdtbus_pinctrl_controller *pc;
pc = kmem_alloc(sizeof(*pc), KM_SLEEP);
- pc->pc_dev = dev;
+ pc->pc_cookie = cookie;
pc->pc_phandle = phandle;
pc->pc_funcs = funcs;
@@ -63,49 +63,70 @@ fdtbus_register_pinctrl_controller(device_t dev, int phandle,
return 0;
}
-struct fdtbus_pinctrl_pin *
-fdtbus_pinctrl_acquire(int phandle, const char *prop)
+static struct fdtbus_pinctrl_controller *
+fdtbus_pinctrl_lookup(int phandle)
{
struct fdtbus_pinctrl_controller *pc;
- struct fdtbus_pinctrl_pin *gp;
-
- gp = kmem_alloc(sizeof(*gp), KM_SLEEP);
- for (pc = fdtbus_pc; pc; pc = pc->pc_next) {
- gp->pp_pc = pc;
- gp->pp_priv = pc->pc_funcs->acquire(pc->pc_dev, prop);
- if (gp->pp_priv != NULL)
- break;
- }
- if (gp->pp_priv == NULL) {
- kmem_free(gp, sizeof(*gp));
- return NULL;
- }
+ for (pc = fdtbus_pc; pc; pc = pc->pc_next)
+ if (pc->pc_phandle == phandle)
+ return pc;
- return gp;
+ return NULL;
}
-void
-fdtbus_pinctrl_release(struct fdtbus_pinctrl_pin *gp)
+int
+fdtbus_pinctrl_set_config_index(int phandle, u_int index)
{
- struct fdtbus_pinctrl_controller *pc = gp->pp_pc;
+ char buf[80];
+ int len, handle;
+ struct fdtbus_pinctrl_controller *pc;
- pc->pc_funcs->release(pc->pc_dev, gp->pp_priv);
- kmem_free(gp, sizeof(*gp));
-}
+ snprintf(buf, 80, "pinctrl-%d", index);
-void
-fdtbus_pinctrl_get_cfg(struct fdtbus_pinctrl_pin *gp, void *cookie)
-{
- struct fdtbus_pinctrl_controller *pc = gp->pp_pc;
+ len = OF_getprop(phandle, buf, (char *)&handle,
+ sizeof(handle));
+ if (len != sizeof(int)) {
+ printf("%s: couldn't get %s.\n", __func__, buf);
+ return -1;
+ }
- pc->pc_funcs->get(gp, cookie);
+ handle = fdtbus_get_phandle_from_native(be32toh(handle));
+
+ pc = fdtbus_pinctrl_lookup(handle);
+ if (!pc) {
+ printf("%s: Couldn't get handle %d for %s\n", __func__, handle,
+ buf);
+ return -1;
+ }
+
+ return pc->pc_funcs->set_config(pc->pc_cookie);
}
-void
-fdtbus_pinctrl_set_cfg(struct fdtbus_pinctrl_pin *gp, void *cookie)
+int
+fdtbus_pinctrl_set_config(int phandle, const char *cfgname)
{
- struct fdtbus_pinctrl_controller *pc = gp->pp_pc;
+ int index = 0;
+ int len;
+ char *result;
+ char *next;
+
+ len = OF_getproplen(phandle, "pinctrl-names");
+ if (len <= 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)) {
+ return fdtbus_pinctrl_set_config_index(phandle, index);
+ }
+ index++;
+ while (*next)
+ next++;
+ next++;
+ }
- pc->pc_funcs->set(gp, cookie);
+ return -1;
}
diff --git a/sys/dev/fdt/fdtvar.h b/sys/dev/fdt/fdtvar.h
index 237693a4e79..b2f68159927 100644
--- a/sys/dev/fdt/fdtvar.h
+++ b/sys/dev/fdt/fdtvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: fdtvar.h,v 1.5 2015/12/30 04:23:39 marty Exp $ */
+/* $NetBSD: fdtvar.h,v 1.6 2016/01/01 22:35:44 marty Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@@ -84,10 +84,7 @@ struct fdtbus_pinctrl_pin {
};
struct fdtbus_pinctrl_controller_func {
- void * (*acquire)(device_t, const char *);
- void (*release)(device_t, void *);
- void (*get)(struct fdtbus_pinctrl_pin *, void *);
- void (*set)(struct fdtbus_pinctrl_pin *, void *);
+ int (*set_config)(void *);
};
struct fdtbus_regulator_controller;
@@ -126,7 +123,7 @@ int fdtbus_register_i2c_controller(device_t, int,
const struct fdtbus_i2c_controller_func *);
int fdtbus_register_gpio_controller(device_t, int,
const struct fdtbus_gpio_controller_func *);
-int fdtbus_register_pinctrl_controller(device_t, int,
+int fdtbus_register_pinctrl_config(void *, int,
const struct fdtbus_pinctrl_controller_func *);
int fdtbus_register_regulator_controller(device_t, int,
const struct fdtbus_regulator_controller_func *);
@@ -149,10 +146,8 @@ int fdtbus_gpio_read(struct fdtbus_gpio_pin *);
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);
-struct fdtbus_pinctrl_pin *fdtbus_pinctrl_acquire(int, const char *);
-void fdtbus_pinctrl_release(struct fdtbus_pinctrl_pin *);
-void fdtbus_pinctrl_set_cfg(struct fdtbus_pinctrl_pin *, void *);
-void fdtbus_pinctrl_get_cfg(struct fdtbus_pinctrl_pin *, 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 *);
void fdtbus_regulator_release(struct fdtbus_regulator *);
int fdtbus_regulator_enable(struct fdtbus_regulator *);