[PATCH v2 3/6] pinctrl: add optional .release_mux() callback

Frank Li posted 6 patches 1 month, 1 week ago
There is a newer version of this series
[PATCH v2 3/6] pinctrl: add optional .release_mux() callback
Posted by Frank Li 1 month, 1 week ago
Add an optional .release_mux() callback to the pinmux_ops.

Some devices require releasing resources that were previously acquired in
.set_mux(). Providing a dedicated .release_mux() callback allows drivers to
properly clean up hardware state or associated resources when a mux
function is no longer active.

The callback is optional and does not affect existing drivers.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/pinctrl/pinmux.c       | 5 +++++
 include/linux/pinctrl/pinmux.h | 5 +++++
 2 files changed, 10 insertions(+)

diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 3a8dd184ba3d670e01a890427e19af59b65eb813..c705bc182266c596c4e6c820f5e3ffcadbbb2838 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -517,6 +517,7 @@ void pinmux_disable_setting(const struct pinctrl_setting *setting)
 {
 	struct pinctrl_dev *pctldev = setting->pctldev;
 	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
+	const struct pinmux_ops *ops = pctldev->desc->pmxops;
 	int ret = 0;
 	const unsigned int *pins = NULL;
 	unsigned int num_pins = 0;
@@ -563,6 +564,10 @@ void pinmux_disable_setting(const struct pinctrl_setting *setting)
 				 pins[i], desc->name, gname);
 		}
 	}
+
+	if (ops->release_mux)
+		ops->release_mux(pctldev, setting->data.mux.func,
+				 setting->data.mux.group);
 }
 
 #ifdef CONFIG_DEBUG_FS
diff --git a/include/linux/pinctrl/pinmux.h b/include/linux/pinctrl/pinmux.h
index 094bbe2fd6fd5ea3c5fdf5b6d6d9a7639700b50b..ad7f8c31655e10ae854f7c325f88d2a533dcb035 100644
--- a/include/linux/pinctrl/pinmux.h
+++ b/include/linux/pinctrl/pinmux.h
@@ -51,6 +51,8 @@ struct pinctrl_gpio_range;
  *	are handled by the pinmux subsystem. The @func_selector selects a
  *	certain function whereas @group_selector selects a certain set of pins
  *	to be used. On simple controllers the latter argument may be ignored
+ * @release_mux: disable  a certain muxing function with a certain pin group,
+ *      which set by @set_mux.
  * @gpio_request_enable: requests and enables GPIO on a certain pin.
  *	Implement this only if you can mux every pin individually as GPIO. The
  *	affected GPIO range is passed along with an offset(pin number) into that
@@ -80,6 +82,9 @@ struct pinmux_ops {
 				  unsigned int selector);
 	int (*set_mux) (struct pinctrl_dev *pctldev, unsigned int func_selector,
 			unsigned int group_selector);
+	void (*release_mux) (struct pinctrl_dev *pctldev,
+			     unsigned int func_selector,
+			     unsigned int group_selector);
 	int (*gpio_request_enable) (struct pinctrl_dev *pctldev,
 				    struct pinctrl_gpio_range *range,
 				    unsigned int offset);

-- 
2.43.0
Re: [PATCH v2 3/6] pinctrl: add optional .release_mux() callback
Posted by Linus Walleij 1 month, 1 week ago
On Thu, Feb 26, 2026 at 12:55 AM Frank Li <Frank.Li@nxp.com> wrote:

> Add an optional .release_mux() callback to the pinmux_ops.
>
> Some devices require releasing resources that were previously acquired in
> .set_mux(). Providing a dedicated .release_mux() callback allows drivers to
> properly clean up hardware state or associated resources when a mux
> function is no longer active.
>
> The callback is optional and does not affect existing drivers.
>
> Signed-off-by: Frank Li <Frank.Li@nxp.com>

Can you explain why you need this custom code for this?

Nominally pin control defines and puts the hardware into a
number of states such as:
"default"
"idle"
"sleep"
"init"

Usually (at least for silicon) what .release_mux() would to
is semantically equivalent to a transition into the "init" or
"sleep" state. And if these are not descriptive enough you can
even define a "released" state.

Is it not possible to reach the set-up of the hardware that you
are desiring by just defining such a relaxed state?

Yours,
Linus Walleij
Re: [PATCH v2 3/6] pinctrl: add optional .release_mux() callback
Posted by Frank Li 1 month, 1 week ago
On Fri, Feb 27, 2026 at 10:07:05AM +0100, Linus Walleij wrote:
> On Thu, Feb 26, 2026 at 12:55 AM Frank Li <Frank.Li@nxp.com> wrote:
>
> > Add an optional .release_mux() callback to the pinmux_ops.
> >
> > Some devices require releasing resources that were previously acquired in
> > .set_mux(). Providing a dedicated .release_mux() callback allows drivers to
> > properly clean up hardware state or associated resources when a mux
> > function is no longer active.
> >
> > The callback is optional and does not affect existing drivers.
> >
> > Signed-off-by: Frank Li <Frank.Li@nxp.com>
>
> Can you explain why you need this custom code for this?
>
> Nominally pin control defines and puts the hardware into a
> number of states such as:
> "default"
> "idle"
> "sleep"
> "init"
>
> Usually (at least for silicon) what .release_mux() would to
> is semantically equivalent to a transition into the "init" or
> "sleep" state. And if these are not descriptive enough you can
> even define a "released" state.
>
> Is it not possible to reach the set-up of the hardware that you
> are desiring by just defining such a relaxed state?

I am not familiar with pinctrl code. I just need a place to call a callback
which do opposite work at .set_mux() function.

I see pair function pinmux_enable_setting() call .set_mux() and
 pinmux_disable_setting() just missing do oppsite work of .set_mux();

I may think too simple. I just do insmod/rmmod test. Any suggestion where
is good place to put it?

Does it call pair pinmux_enable(disable)_setting when switch state?

Frank

>
> Yours,
> Linus Walleij
Re: [PATCH v2 3/6] pinctrl: add optional .release_mux() callback
Posted by Linus Walleij 1 month ago
On Fri, Feb 27, 2026 at 4:32 PM Frank Li <Frank.li@nxp.com> wrote:
> On Fri, Feb 27, 2026 at 10:07:05AM +0100, Linus Walleij wrote:
> > On Thu, Feb 26, 2026 at 12:55 AM Frank Li <Frank.Li@nxp.com> wrote:
> >
> > > Add an optional .release_mux() callback to the pinmux_ops.
> > >
> > > Some devices require releasing resources that were previously acquired in
> > > .set_mux(). Providing a dedicated .release_mux() callback allows drivers to
> > > properly clean up hardware state or associated resources when a mux
> > > function is no longer active.
> > >
> > > The callback is optional and does not affect existing drivers.
> > >
> > > Signed-off-by: Frank Li <Frank.Li@nxp.com>
> >
> > Can you explain why you need this custom code for this?
> >
> > Nominally pin control defines and puts the hardware into a
> > number of states such as:
> > "default"
> > "idle"
> > "sleep"
> > "init"
> >
> > Usually (at least for silicon) what .release_mux() would to
> > is semantically equivalent to a transition into the "init" or
> > "sleep" state. And if these are not descriptive enough you can
> > even define a "released" state.
> >
> > Is it not possible to reach the set-up of the hardware that you
> > are desiring by just defining such a relaxed state?
>
> I am not familiar with pinctrl code. I just need a place to call a callback
> which do opposite work at .set_mux() function.
>
> I see pair function pinmux_enable_setting() call .set_mux() and
>  pinmux_disable_setting() just missing do oppsite work of .set_mux();
>
> I may think too simple. I just do insmod/rmmod test. Any suggestion where
> is good place to put it?
>
> Does it call pair pinmux_enable(disable)_setting when switch state?

The pinmux states are more like a state machine, you transition
between different states.

I think in this case you may want your driver or the device driver
core to transition to the "init" state to release the mux, see
my other reply.

Yours,
Linus Walleij