|
@@ -945,13 +945,13 @@ case), we define a mapping like this:
|
|
|
The result of grabbing this mapping from the device with something like
|
|
|
this (see next paragraph):
|
|
|
|
|
|
- p = pinctrl_get(dev);
|
|
|
+ p = devm_pinctrl_get(dev);
|
|
|
s = pinctrl_lookup_state(p, "8bit");
|
|
|
ret = pinctrl_select_state(p, s);
|
|
|
|
|
|
or more simply:
|
|
|
|
|
|
- p = pinctrl_get_select(dev, "8bit");
|
|
|
+ p = devm_pinctrl_get_select(dev, "8bit");
|
|
|
|
|
|
Will be that you activate all the three bottom records in the mapping at
|
|
|
once. Since they share the same name, pin controller device, function and
|
|
@@ -985,7 +985,7 @@ foo_probe()
|
|
|
/* Allocate a state holder named "foo" etc */
|
|
|
struct foo_state *foo = ...;
|
|
|
|
|
|
- foo->p = pinctrl_get(&device);
|
|
|
+ foo->p = devm_pinctrl_get(&device);
|
|
|
if (IS_ERR(foo->p)) {
|
|
|
/* FIXME: clean up "foo" here */
|
|
|
return PTR_ERR(foo->p);
|
|
@@ -993,24 +993,17 @@ foo_probe()
|
|
|
|
|
|
foo->s = pinctrl_lookup_state(foo->p, PINCTRL_STATE_DEFAULT);
|
|
|
if (IS_ERR(foo->s)) {
|
|
|
- pinctrl_put(foo->p);
|
|
|
/* FIXME: clean up "foo" here */
|
|
|
return PTR_ERR(s);
|
|
|
}
|
|
|
|
|
|
ret = pinctrl_select_state(foo->s);
|
|
|
if (ret < 0) {
|
|
|
- pinctrl_put(foo->p);
|
|
|
/* FIXME: clean up "foo" here */
|
|
|
return ret;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-foo_remove()
|
|
|
-{
|
|
|
- pinctrl_put(state->p);
|
|
|
-}
|
|
|
-
|
|
|
This get/lookup/select/put sequence can just as well be handled by bus drivers
|
|
|
if you don't want each and every driver to handle it and you know the
|
|
|
arrangement on your bus.
|
|
@@ -1022,6 +1015,11 @@ The semantics of the pinctrl APIs are:
|
|
|
kernel memory to hold the pinmux state. All mapping table parsing or similar
|
|
|
slow operations take place within this API.
|
|
|
|
|
|
+- devm_pinctrl_get() is a variant of pinctrl_get() that causes pinctrl_put()
|
|
|
+ to be called automatically on the retrieved pointer when the associated
|
|
|
+ device is removed. It is recommended to use this function over plain
|
|
|
+ pinctrl_get().
|
|
|
+
|
|
|
- pinctrl_lookup_state() is called in process context to obtain a handle to a
|
|
|
specific state for a the client device. This operation may be slow too.
|
|
|
|
|
@@ -1034,14 +1032,25 @@ The semantics of the pinctrl APIs are:
|
|
|
|
|
|
- pinctrl_put() frees all information associated with a pinctrl handle.
|
|
|
|
|
|
+- devm_pinctrl_put() is a variant of pinctrl_put() that may be used to
|
|
|
+ explicitly destroy a pinctrl object returned by devm_pinctrl_get().
|
|
|
+ However, use of this function will be rare, due to the automatic cleanup
|
|
|
+ that will occur even without calling it.
|
|
|
+
|
|
|
+ pinctrl_get() must be paired with a plain pinctrl_put().
|
|
|
+ pinctrl_get() may not be paired with devm_pinctrl_put().
|
|
|
+ devm_pinctrl_get() can optionally be paired with devm_pinctrl_put().
|
|
|
+ devm_pinctrl_get() may not be paired with plain pinctrl_put().
|
|
|
+
|
|
|
Usually the pin control core handled the get/put pair and call out to the
|
|
|
device drivers bookkeeping operations, like checking available functions and
|
|
|
the associated pins, whereas the enable/disable pass on to the pin controller
|
|
|
driver which takes care of activating and/or deactivating the mux setting by
|
|
|
quickly poking some registers.
|
|
|
|
|
|
-The pins are allocated for your device when you issue the pinctrl_get() call,
|
|
|
-after this you should be able to see this in the debugfs listing of all pins.
|
|
|
+The pins are allocated for your device when you issue the devm_pinctrl_get()
|
|
|
+call, after this you should be able to see this in the debugfs listing of all
|
|
|
+pins.
|
|
|
|
|
|
NOTE: the pinctrl system will return -EPROBE_DEFER if it cannot find the
|
|
|
requested pinctrl handles, for example if the pinctrl driver has not yet
|
|
@@ -1092,13 +1101,13 @@ it, disables and releases it, and muxes it in on the pins defined by group B:
|
|
|
|
|
|
#include <linux/pinctrl/consumer.h>
|
|
|
|
|
|
-foo_switch()
|
|
|
-{
|
|
|
- struct pinctrl *p;
|
|
|
- struct pinctrl_state *s1, *s2;
|
|
|
+struct pinctrl *p;
|
|
|
+struct pinctrl_state *s1, *s2;
|
|
|
|
|
|
+foo_probe()
|
|
|
+{
|
|
|
/* Setup */
|
|
|
- p = pinctrl_get(&device);
|
|
|
+ p = devm_pinctrl_get(&device);
|
|
|
if (IS_ERR(p))
|
|
|
...
|
|
|
|
|
@@ -1109,7 +1118,10 @@ foo_switch()
|
|
|
s2 = pinctrl_lookup_state(foo->p, "pos-B");
|
|
|
if (IS_ERR(s2))
|
|
|
...
|
|
|
+}
|
|
|
|
|
|
+foo_switch()
|
|
|
+{
|
|
|
/* Enable on position A */
|
|
|
ret = pinctrl_select_state(s1);
|
|
|
if (ret < 0)
|
|
@@ -1123,8 +1135,6 @@ foo_switch()
|
|
|
...
|
|
|
|
|
|
...
|
|
|
-
|
|
|
- pinctrl_put(p);
|
|
|
}
|
|
|
|
|
|
The above has to be done from process context.
|