linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: Pinconf issues on AMxxx plattforms
       [not found] <aa493d62327f26e4c65d649a812346cdfb26771f.camel@siemens.com>
@ 2023-05-04  5:35 ` Tony Lindgren
  2023-05-04  8:31   ` Linus Walleij
  2023-05-05 12:59   ` Niedermayr, BENEDIKT
  0 siblings, 2 replies; 5+ messages in thread
From: Tony Lindgren @ 2023-05-04  5:35 UTC (permalink / raw)
  To: Niedermayr, BENEDIKT
  Cc: linux-omap@vger.kernel.org, haojian.zhuang@linaro.org,
	Linus Walleij, linux-gpio

Hi,

Adding linux-gpio and Linus W to Cc. Some questions and comments below
towards the end.

* Niedermayr, BENEDIKT <benedikt.niedermayr@siemens.com> [230503 08:38]:
> Hello,
> 
> We encountered some issues when accessing the gpiochardev interface on an
> AM65xx plaform.
>  
> The basic idea was to fully rely on all features the gpiochardev seems to
> offer. 
> I got all relevant information from the Linux Kernel Documentation
> (Documentation/driver-api/pin-control.rst) and saw 
> some presentations from Linus Walleij  regarding the gpiochardev
> capabilities.
> 
> If I understand that correctly the gpiochardev interface should support the
> following features:
> * Requesting gpio pins from userspace
> * Set input/output directions
> * Set BIAS settings (pull-up, pull-down, etc.)
> * Gpio function of that pin automatically gets muxed in if requested 
> 
> Requesting pins worked for me as expected after I added the required DTB
> properties:
> * pinctrl-single: Add each required pin to "pinctrl-single,gpio-range" in
> the pincontroller node 
> * gpio: Add each required pin to gpio-range property in the gpio node
> 
> I also added the required childnodes in the pinctrl node:
> 
> &main_pmx0 {
>   ... 
>    d6_gpio: d6-gpio {
> pinctrl-single,pins = <
> /* (AH16) GPIO0_38 */
> AM65X_IOPAD(0x0098, PIN_INPUT, 7)
> >;
> pinctrl-single,bias-pullup   = <0x20000  0x20000  0x10000  0x30000>;
> pinctrl-single,bias-pulldown = <0x00000  0x0      0x10000  0x30000>;
> };
> ...
> }
> 
> When I tried to set any BIAS settings nothing happened or some error occured
> in the kernel logs (i'm not 100% sure anymore since almost 2 months have
> past). 
> The first thing I had to do was to assign the gpiochip_generic_config
> callback to the gpiochiop for that (gpio-davinci.c). This callback in turn
> will finally call pcs_pinconf_set(), which
> is the pinctrl drivers related callback for setting the pinconf.
> But still no success...
> 
> Then I went deeper into the rabbit whole and encountered that the error had
> to do with pcs_get_function() (pinctrl-single.c).
> I found out that this function requests the current function (or pinmux
> state) from the pinctrl subsystem core. 
> The pinctrl driver needs this information for accessing the correct pinctrl
> childnode bits. 
> 
> So what is the Problem here?
> The pinctrl offers 3 different options for muxing:
> 
> 1.  Using the generic kernel APIs: 
>      Call pinctrl_select_state() function as stated
> in  Documentation/driver-api/pin-control.rst (section "Pin control requests
> from drivers").
>      This function will select a defined state which has been defined in DTB
> with "pinctrl-0", "pinctrl-1", "pinctrl-x"
> 2.  Mux pins with debugfs:
>      Write the desired pingroup and pinfunction into the "pinmux-select"
> file of the related pin controller.
> 3. Mux the GPIO function of a requested GPIO pin by calling the pinctrl
> drivers pcs_request_gpio() function.
> 
> The problem now is that only option 1. will store the current mux
> information in the pinctrl subsystems core. 
> The pinctrl-single driver highly depends on that information, which is not
> available at all wenn muxing with options 2&3.
> 
> I was able to fix that for option 2 but not for option 3. The problem here
> is that the pcs_request_gpio() function just does not provide enough
> parameters with sufficient information for achieving that task.

Care to post what your fix for #2 above looks like?

> I'm not sure if I miss something important here?
> Are you aware of this issue? 

Sounds like something needs to be implemented for pinctrl-single.c.

Regards,

Tony

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Pinconf issues on AMxxx plattforms
  2023-05-04  5:35 ` Pinconf issues on AMxxx plattforms Tony Lindgren
@ 2023-05-04  8:31   ` Linus Walleij
  2023-05-05  8:54     ` Tony Lindgren
  2023-05-05 13:28     ` Niedermayr, BENEDIKT
  2023-05-05 12:59   ` Niedermayr, BENEDIKT
  1 sibling, 2 replies; 5+ messages in thread
From: Linus Walleij @ 2023-05-04  8:31 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Niedermayr, BENEDIKT, linux-omap@vger.kernel.org,
	haojian.zhuang@linaro.org, linux-gpio

On Thu, May 4, 2023 at 7:35 AM Tony Lindgren <tony@atomide.com> wrote:
> * Niedermayr, BENEDIKT <benedikt.niedermayr@siemens.com> [230503 08:38]:

> > We encountered some issues when accessing the gpiochardev interface on an
> > AM65xx plaform.

Thank you for using contemporary APIs!

> > The pinctrl offers 3 different options for muxing:
> >
> > 1.  Using the generic kernel APIs:
> >      Call pinctrl_select_state() function as stated
> > in  Documentation/driver-api/pin-control.rst (section "Pin control requests
> > from drivers").
> >      This function will select a defined state which has been defined in DTB
> > with "pinctrl-0", "pinctrl-1", "pinctrl-x"
> > 2.  Mux pins with debugfs:
> >      Write the desired pingroup and pinfunction into the "pinmux-select"
> > file of the related pin controller.
> > 3. Mux the GPIO function of a requested GPIO pin by calling the pinctrl
> > drivers pcs_request_gpio() function.
> >
> > The problem now is that only option 1. will store the current mux
> > information in the pinctrl subsystems core.
> > The pinctrl-single driver highly depends on that information, which is not
> > available at all wenn muxing with options 2&3.
> >
> > I was able to fix that for option 2 but not for option 3. The problem here
> > is that the pcs_request_gpio() function just does not provide enough
> > parameters with sufficient information for achieving that task.

The fact that 3) doesn't work has to do with how pinctrl-single has
been engineered I think, what the pinctrl_ops .gpio_request_enable/
.gpio_disable_free/.gpio_set_direction provide is a "shortcut"
for drivers that want to take it, in case they can provide the right
information.

The pinctrl-single driver only implements .gpio_request_enable()
but often that is enough.

Then it is the callbacks for generic config that you said you already
added to gpio-davinci.c, so that part should be fine, patches welcome!

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Pinconf issues on AMxxx plattforms
  2023-05-04  8:31   ` Linus Walleij
@ 2023-05-05  8:54     ` Tony Lindgren
  2023-05-05 13:28     ` Niedermayr, BENEDIKT
  1 sibling, 0 replies; 5+ messages in thread
From: Tony Lindgren @ 2023-05-05  8:54 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Niedermayr, BENEDIKT, linux-omap@vger.kernel.org,
	haojian.zhuang@linaro.org, linux-gpio

* Linus Walleij <linus.walleij@linaro.org> [230504 08:31]:
> On Thu, May 4, 2023 at 7:35 AM Tony Lindgren <tony@atomide.com> wrote:
> > * Niedermayr, BENEDIKT <benedikt.niedermayr@siemens.com> [230503 08:38]:
> 
> > > We encountered some issues when accessing the gpiochardev interface on an
> > > AM65xx plaform.
> 
> Thank you for using contemporary APIs!
> 
> > > The pinctrl offers 3 different options for muxing:
> > >
> > > 1.  Using the generic kernel APIs:
> > >      Call pinctrl_select_state() function as stated
> > > in  Documentation/driver-api/pin-control.rst (section "Pin control requests
> > > from drivers").
> > >      This function will select a defined state which has been defined in DTB
> > > with "pinctrl-0", "pinctrl-1", "pinctrl-x"
> > > 2.  Mux pins with debugfs:
> > >      Write the desired pingroup and pinfunction into the "pinmux-select"
> > > file of the related pin controller.
> > > 3. Mux the GPIO function of a requested GPIO pin by calling the pinctrl
> > > drivers pcs_request_gpio() function.
> > >
> > > The problem now is that only option 1. will store the current mux
> > > information in the pinctrl subsystems core.
> > > The pinctrl-single driver highly depends on that information, which is not
> > > available at all wenn muxing with options 2&3.
> > >
> > > I was able to fix that for option 2 but not for option 3. The problem here
> > > is that the pcs_request_gpio() function just does not provide enough
> > > parameters with sufficient information for achieving that task.
> 
> The fact that 3) doesn't work has to do with how pinctrl-single has
> been engineered I think, what the pinctrl_ops .gpio_request_enable/
> .gpio_disable_free/.gpio_set_direction provide is a "shortcut"
> for drivers that want to take it, in case they can provide the right
> information.
> 
> The pinctrl-single driver only implements .gpio_request_enable()
> but often that is enough.
> 
> Then it is the callbacks for generic config that you said you already
> added to gpio-davinci.c, so that part should be fine, patches welcome!

Thanks for explaining. Sounds like pinctrl-single should possibly
implement the missing functions and update pinctrl core with the
changes when a gpio is requested.

Regards,

Tony

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Pinconf issues on AMxxx plattforms
  2023-05-04  5:35 ` Pinconf issues on AMxxx plattforms Tony Lindgren
  2023-05-04  8:31   ` Linus Walleij
@ 2023-05-05 12:59   ` Niedermayr, BENEDIKT
  1 sibling, 0 replies; 5+ messages in thread
From: Niedermayr, BENEDIKT @ 2023-05-05 12:59 UTC (permalink / raw)
  To: tony@atomide.com
  Cc: haojian.zhuang@linaro.org, linux-gpio@vger.kernel.org,
	linux-omap@vger.kernel.org, linus.walleij@linaro.org

On Thu, 2023-05-04 at 08:35 +0300, Tony Lindgren wrote:
> Hi,
> 
> Adding linux-gpio and Linus W to Cc. Some questions and comments below
> towards the end.
> 
> * Niedermayr, BENEDIKT <benedikt.niedermayr@siemens.com> [230503 08:38]:
> > Hello,
> > 
> > We encountered some issues when accessing the gpiochardev interface on an
> > AM65xx plaform.
> >  
> > The basic idea was to fully rely on all features the gpiochardev seems to
> > offer. 
> > I got all relevant information from the Linux Kernel Documentation
> > (Documentation/driver-api/pin-control.rst) and saw 
> > some presentations from Linus Walleij  regarding the gpiochardev
> > capabilities.
> > 
> > If I understand that correctly the gpiochardev interface should support the
> > following features:
> > * Requesting gpio pins from userspace
> > * Set input/output directions
> > * Set BIAS settings (pull-up, pull-down, etc.)
> > * Gpio function of that pin automatically gets muxed in if requested 
> > 
> > Requesting pins worked for me as expected after I added the required DTB
> > properties:
> > * pinctrl-single: Add each required pin to "pinctrl-single,gpio-range" in
> > the pincontroller node 
> > * gpio: Add each required pin to gpio-range property in the gpio node
> > 
> > I also added the required childnodes in the pinctrl node:
> > 
> > &main_pmx0 {
> >   ... 
> >    d6_gpio: d6-gpio {
> > pinctrl-single,pins = <
> > /* (AH16) GPIO0_38 */
> > AM65X_IOPAD(0x0098, PIN_INPUT, 7)
> > > ;
> > pinctrl-single,bias-pullup   = <0x20000  0x20000  0x10000  0x30000>;
> > pinctrl-single,bias-pulldown = <0x00000  0x0      0x10000  0x30000>;
> > };
> > ...
> > }
> > 
> > When I tried to set any BIAS settings nothing happened or some error occured
> > in the kernel logs (i'm not 100% sure anymore since almost 2 months have
> > past). 
> > The first thing I had to do was to assign the gpiochip_generic_config
> > callback to the gpiochiop for that (gpio-davinci.c). This callback in turn
> > will finally call pcs_pinconf_set(), which
> > is the pinctrl drivers related callback for setting the pinconf.
> > But still no success...
> > 
> > Then I went deeper into the rabbit whole and encountered that the error had
> > to do with pcs_get_function() (pinctrl-single.c).
> > I found out that this function requests the current function (or pinmux
> > state) from the pinctrl subsystem core. 
> > The pinctrl driver needs this information for accessing the correct pinctrl
> > childnode bits. 
> > 
> > So what is the Problem here?
> > The pinctrl offers 3 different options for muxing:
> > 
> > 1.  Using the generic kernel APIs: 
> >      Call pinctrl_select_state() function as stated
> > in  Documentation/driver-api/pin-control.rst (section "Pin control requests
> > from drivers").
> >      This function will select a defined state which has been defined in DTB
> > with "pinctrl-0", "pinctrl-1", "pinctrl-x"
> > 2.  Mux pins with debugfs:
> >      Write the desired pingroup and pinfunction into the "pinmux-select"
> > file of the related pin controller.
> > 3. Mux the GPIO function of a requested GPIO pin by calling the pinctrl
> > drivers pcs_request_gpio() function.
> > 
> > The problem now is that only option 1. will store the current mux
> > information in the pinctrl subsystems core. 
> > The pinctrl-single driver highly depends on that information, which is not
> > available at all wenn muxing with options 2&3.
> > 
> > I was able to fix that for option 2 but not for option 3. The problem here
> > is that the pcs_request_gpio() function just does not provide enough
> > parameters with sufficient information for achieving that task.
> 
> Care to post what your fix for #2 above looks like?

Thanks for the reply.

Sure, I can post it. But that is just an example and not a final proposal.

It seems pretty complex but accessing "pdesc->mux_setting" directly was not possible, since
it is defined as const pointer. 

So I created an internal shadow copy private data struct and stored the mux_settings there.
In pcs_set_mux() I can then update the mux_setting and query it in pcs_get_function().

Im sure that there are much better solutions but for now it's just a first shot.


diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index cd314a5305a2..fa47fbf1534c 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -38,6 +38,16 @@
 #define DRIVER_NAME			"pinctrl-single"
 #define PCS_OFF_DISABLED		~0U
 
+/**
+ * struct pcs_setting_mux - hold current mux settings per pin
+ * @func: 	selected pin function
+ * @group:	selected pin group
+ */
+struct pcs_setting_mux {
+	unsigned func;
+	unsigned group;
+};
+
 /**
  * struct pcs_func_vals - mux function register offset and value pair
  * @reg:	register virtual address
@@ -340,12 +350,11 @@ static int pcs_get_function(struct pinctrl_dev *pctldev, unsigned pin,
 {
 	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
 	struct pin_desc *pdesc = pin_desc_get(pctldev, pin);
-	const struct pinctrl_setting_mux *setting;
+	struct pcs_setting_mux *setting = pdesc->drv_data;
 	struct function_desc *function;
 	unsigned fselector;
 
 	/* If pin is not described in DTS & enabled, mux_setting is NULL. */
-	setting = pdesc->mux_setting;
 	if (!setting)
 		return -ENOTSUPP;
 	fselector = setting->func;
@@ -365,7 +374,9 @@ static int pcs_set_mux(struct pinctrl_dev *pctldev, unsigned fselector,
 	struct pcs_device *pcs;
 	struct function_desc *function;
 	struct pcs_function *func;
-	int i;
+	int i, ret;
+	const unsigned *pins = NULL;
+	unsigned num_pins = 0;
 
 	pcs = pinctrl_dev_get_drvdata(pctldev);
 	/* If function mask is null, needn't enable it. */
@@ -376,8 +387,32 @@ static int pcs_set_mux(struct pinctrl_dev *pctldev, unsigned fselector,
 	if (!func)
 		return -EINVAL;
 
-	dev_dbg(pcs->dev, "enabling %s function%i\n",
-		func->name, fselector);
+	/*
+	 * Last mux setting must be stored here as well.
+	 * Referring to proper pinconf requires the current pin function
+	 * to be known
+	 */
+	ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &num_pins);
+	if (ret && PCS_HAS_PINCONF) {
+		dev_err(pcs->dev, "Cannot store mux settings\n");
+		return ret;
+	}
+
+	for (i = 0; i < num_pins; i++) {
+		struct pcs_setting_mux *setting;
+		struct pin_desc *desc;
+
+		desc = pin_desc_get(pctldev, pins[i]);
+		if (!desc) {
+			dev_err(pcs->dev, "Unable to request pindesc for PIN%d\n",
+				pins[i]);
+			continue;
+		}
+
+		setting = desc->drv_data;
+		setting->func = fselector;
+		setting->group = group;
+	}
 
 	for (i = 0; i < func->nvals; i++) {
 		struct pcs_func_vals *vals;
@@ -682,6 +717,7 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned int offset)
 {
 	struct pcs_soc_data *pcs_soc = &pcs->socdata;
 	struct pinctrl_pin_desc *pin;
+	struct pcs_setting_mux *setting;
 	int i;
 
 	i = pcs->pins.cur;
@@ -703,7 +739,14 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned int offset)
 		}
 	}
 
+
+	setting = devm_kzalloc(pcs->dev, sizeof(*setting), GFP_KERNEL);
+	if (!setting)
+		return -ENOMEM;
+
+
 	pin = &pcs->pins.pa[i];
+	pin->drv_data = setting;
 	pin->number = i;
 	pcs->pins.cur++;

> pin_desc
> > I'm not sure if I miss something important here?
> > Are you aware of this issue? 
> 
> Sounds like something needs to be implemented for pinctrl-single.c.

Ok then I'm not completely wrong. 
I will try to sent out a more complete patchseries for discussions during next two weeks.
  

> 
> Regards,
> 
> Tony

Cheers,
Benedikt

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: Pinconf issues on AMxxx plattforms
  2023-05-04  8:31   ` Linus Walleij
  2023-05-05  8:54     ` Tony Lindgren
@ 2023-05-05 13:28     ` Niedermayr, BENEDIKT
  1 sibling, 0 replies; 5+ messages in thread
From: Niedermayr, BENEDIKT @ 2023-05-05 13:28 UTC (permalink / raw)
  To: tony@atomide.com, linus.walleij@linaro.org
  Cc: haojian.zhuang@linaro.org, linux-gpio@vger.kernel.org,
	linux-omap@vger.kernel.org

On Thu, 2023-05-04 at 10:31 +0200, Linus Walleij wrote:
> On Thu, May 4, 2023 at 7:35 AM Tony Lindgren <tony@atomide.com> wrote:
> > * Niedermayr, BENEDIKT <benedikt.niedermayr@siemens.com> [230503 08:38]:
> > > We encountered some issues when accessing the gpiochardev interface on an
> > > AM65xx plaform.
> 
> Thank you for using contemporary APIs!

And thank you for providing such!
> 
> > > The pinctrl offers 3 different options for muxing:
> > > 
> > > 1.  Using the generic kernel APIs:
> > >      Call pinctrl_select_state() function as stated
> > > in  Documentation/driver-api/pin-control.rst (section "Pin control requests
> > > from drivers").
> > >      This function will select a defined state which has been defined in DTB
> > > with "pinctrl-0", "pinctrl-1", "pinctrl-x"
> > > 2.  Mux pins with debugfs:
> > >      Write the desired pingroup and pinfunction into the "pinmux-select"
> > > file of the related pin controller.
> > > 3. Mux the GPIO function of a requested GPIO pin by calling the pinctrl
> > > drivers pcs_request_gpio() function.
> > > 
> > > The problem now is that only option 1. will store the current mux
> > > information in the pinctrl subsystems core.
> > > The pinctrl-single driver highly depends on that information, which is not
> > > available at all wenn muxing with options 2&3.
> > > 
> > > I was able to fix that for option 2 but not for option 3. The problem here
> > > is that the pcs_request_gpio() function just does not provide enough
> > > parameters with sufficient information for achieving that task.
> 
> The fact that 3) doesn't work has to do with how pinctrl-single has
> been engineered I think, what the pinctrl_ops .gpio_request_enable/
> .gpio_disable_free/.gpio_set_direction provide is a "shortcut"
> for drivers that want to take it, in case they can provide the right
> information.

Ok so I'm not completely wrong here. Now I feel more confident for further
investigation. 


> 
> The pinctrl-single driver only implements .gpio_request_enable()
> but often that is enough.
> 
> Then it is the callbacks for generic config that you said you already
> added to gpio-davinci.c, so that part should be fine, patches welcome!

I'll send out some patches the next two weeks...

> 
> Yours,
> Linus Walleij


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-05-05 13:28 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <aa493d62327f26e4c65d649a812346cdfb26771f.camel@siemens.com>
2023-05-04  5:35 ` Pinconf issues on AMxxx plattforms Tony Lindgren
2023-05-04  8:31   ` Linus Walleij
2023-05-05  8:54     ` Tony Lindgren
2023-05-05 13:28     ` Niedermayr, BENEDIKT
2023-05-05 12:59   ` Niedermayr, BENEDIKT

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).