[PATCH] gpio: tegra186: Support multi-socket devices

Prathamesh Shete posted 1 patch 1 month, 2 weeks ago
drivers/gpio/gpio-tegra186.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
[PATCH] gpio: tegra186: Support multi-socket devices
Posted by Prathamesh Shete 1 month, 2 weeks ago
On Tegra platforms, multiple SoC instances may be present with each
defining the same GPIO name. For such devices, this results in
duplicate GPIO names.

When the device has a valid NUMA node, prepend the NUMA node ID
to the GPIO name prefix. The node ID identifies each socket,
ensuring GPIO line names remain distinct across multiple sockets.

Signed-off-by: Prathamesh Shete <pshete@nvidia.com>
---
 drivers/gpio/gpio-tegra186.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c
index 9c874f07be75..daf5aaffa28a 100644
--- a/drivers/gpio/gpio-tegra186.c
+++ b/drivers/gpio/gpio-tegra186.c
@@ -857,7 +857,8 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
 	struct device_node *np;
 	struct resource *res;
 	char **names;
-	int err;
+	char *instance = "";
+	int node, err;
 
 	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
 	if (!gpio)
@@ -937,17 +938,21 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
 	if (!names)
 		return -ENOMEM;
 
+	node = dev_to_node(&pdev->dev);
+	if (node >= 0) {
+		instance = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "%d-", node);
+		if (!instance)
+			return -ENOMEM;
+	}
+
 	for (i = 0, offset = 0; i < gpio->soc->num_ports; i++) {
 		const struct tegra_gpio_port *port = &gpio->soc->ports[i];
 		char *name;
 
 		for (j = 0; j < port->pins; j++) {
-			if (gpio->soc->prefix)
-				name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "%s-P%s.%02x",
-						      gpio->soc->prefix, port->name, j);
-			else
-				name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "P%s.%02x",
-						      port->name, j);
+			name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "%s%sP%s.%02x",
+					      instance ?: "", gpio->soc->prefix ?: "",
+					      port->name, j);
 			if (!name)
 				return -ENOMEM;
 
@@ -1373,6 +1378,9 @@ static const struct tegra_gpio_soc tegra256_main_soc = {
 	.has_vm_support = true,
 };
 
+/* Macro to define GPIO name prefix with separator */
+#define TEGRA_GPIO_PREFIX(_x)	_x "-"
+
 #define TEGRA410_COMPUTE_GPIO_PORT(_name, _bank, _port, _pins)	\
 	TEGRA_GPIO_PORT(TEGRA410_COMPUTE, _name, _bank, _port, _pins)
 
@@ -1388,7 +1396,7 @@ static const struct tegra_gpio_soc tegra410_compute_soc = {
 	.num_ports = ARRAY_SIZE(tegra410_compute_ports),
 	.ports = tegra410_compute_ports,
 	.name = "tegra410-gpio-compute",
-	.prefix = "COMPUTE",
+	.prefix = TEGRA_GPIO_PREFIX("COMPUTE"),
 	.num_irqs_per_bank = 8,
 	.instance = 0,
 };
@@ -1418,7 +1426,7 @@ static const struct tegra_gpio_soc tegra410_system_soc = {
 	.num_ports = ARRAY_SIZE(tegra410_system_ports),
 	.ports = tegra410_system_ports,
 	.name = "tegra410-gpio-system",
-	.prefix = "SYSTEM",
+	.prefix = TEGRA_GPIO_PREFIX("SYSTEM"),
 	.num_irqs_per_bank = 8,
 	.instance = 0,
 };
-- 
2.43.0
Re: [PATCH] gpio: tegra186: Support multi-socket devices
Posted by Bartosz Golaszewski 1 month, 2 weeks ago
On Mon, 16 Feb 2026 05:58:42 +0100, Prathamesh Shete <pshete@nvidia.com> said:
> On Tegra platforms, multiple SoC instances may be present with each
> defining the same GPIO name. For such devices, this results in
> duplicate GPIO names.
>
> When the device has a valid NUMA node, prepend the NUMA node ID
> to the GPIO name prefix. The node ID identifies each socket,
> ensuring GPIO line names remain distinct across multiple sockets.
>
> Signed-off-by: Prathamesh Shete <pshete@nvidia.com>
> ---
>  drivers/gpio/gpio-tegra186.c | 26 +++++++++++++++++---------
>  1 file changed, 17 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c
> index 9c874f07be75..daf5aaffa28a 100644
> --- a/drivers/gpio/gpio-tegra186.c
> +++ b/drivers/gpio/gpio-tegra186.c
> @@ -857,7 +857,8 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
>  	struct device_node *np;
>  	struct resource *res;
>  	char **names;
> -	int err;
> +	char *instance = "";
> +	int node, err;
>
>  	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
>  	if (!gpio)
> @@ -937,17 +938,21 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
>  	if (!names)
>  		return -ENOMEM;
>
> +	node = dev_to_node(&pdev->dev);
> +	if (node >= 0) {
> +		instance = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "%d-", node);

I've never noticed it before (and it's not introduced by this patch) but I
really dislike the child device registering devres nodes with its parent...

> +		if (!instance)
> +			return -ENOMEM;
> +	}
> +
>  	for (i = 0, offset = 0; i < gpio->soc->num_ports; i++) {
>  		const struct tegra_gpio_port *port = &gpio->soc->ports[i];
>  		char *name;
>
>  		for (j = 0; j < port->pins; j++) {
> -			if (gpio->soc->prefix)
> -				name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "%s-P%s.%02x",
> -						      gpio->soc->prefix, port->name, j);
> -			else
> -				name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "P%s.%02x",
> -						      port->name, j);
> +			name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "%s%sP%s.%02x",
> +					      instance ?: "", gpio->soc->prefix ?: "",

instance can't be NULL here, can it? Either print it unconditionally or
initialize it to NULL.

> +					      port->name, j);
>  			if (!name)
>  				return -ENOMEM;
>
> @@ -1373,6 +1378,9 @@ static const struct tegra_gpio_soc tegra256_main_soc = {
>  	.has_vm_support = true,
>  };
>
> +/* Macro to define GPIO name prefix with separator */
> +#define TEGRA_GPIO_PREFIX(_x)	_x "-"
> +

This doesn't look like it belongs to this patch, why are you doing it?

Bart

>  #define TEGRA410_COMPUTE_GPIO_PORT(_name, _bank, _port, _pins)	\
>  	TEGRA_GPIO_PORT(TEGRA410_COMPUTE, _name, _bank, _port, _pins)
>
> @@ -1388,7 +1396,7 @@ static const struct tegra_gpio_soc tegra410_compute_soc = {
>  	.num_ports = ARRAY_SIZE(tegra410_compute_ports),
>  	.ports = tegra410_compute_ports,
>  	.name = "tegra410-gpio-compute",
> -	.prefix = "COMPUTE",
> +	.prefix = TEGRA_GPIO_PREFIX("COMPUTE"),
>  	.num_irqs_per_bank = 8,
>  	.instance = 0,
>  };
> @@ -1418,7 +1426,7 @@ static const struct tegra_gpio_soc tegra410_system_soc = {
>  	.num_ports = ARRAY_SIZE(tegra410_system_ports),
>  	.ports = tegra410_system_ports,
>  	.name = "tegra410-gpio-system",
> -	.prefix = "SYSTEM",
> +	.prefix = TEGRA_GPIO_PREFIX("SYSTEM"),
>  	.num_irqs_per_bank = 8,
>  	.instance = 0,
>  };
> --
> 2.43.0
>
>
Re: [PATCH] gpio: tegra186: Support multi-socket devices
Posted by Jon Hunter 1 month, 2 weeks ago
On 16/02/2026 11:29, Bartosz Golaszewski wrote:
> On Mon, 16 Feb 2026 05:58:42 +0100, Prathamesh Shete <pshete@nvidia.com> said:
>> On Tegra platforms, multiple SoC instances may be present with each
>> defining the same GPIO name. For such devices, this results in
>> duplicate GPIO names.
>>
>> When the device has a valid NUMA node, prepend the NUMA node ID
>> to the GPIO name prefix. The node ID identifies each socket,
>> ensuring GPIO line names remain distinct across multiple sockets.
>>
>> Signed-off-by: Prathamesh Shete <pshete@nvidia.com>
>> ---
>>   drivers/gpio/gpio-tegra186.c | 26 +++++++++++++++++---------
>>   1 file changed, 17 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c
>> index 9c874f07be75..daf5aaffa28a 100644
>> --- a/drivers/gpio/gpio-tegra186.c
>> +++ b/drivers/gpio/gpio-tegra186.c
>> @@ -857,7 +857,8 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
>>   	struct device_node *np;
>>   	struct resource *res;
>>   	char **names;
>> -	int err;
>> +	char *instance = "";
>> +	int node, err;
>>
>>   	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
>>   	if (!gpio)
>> @@ -937,17 +938,21 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
>>   	if (!names)
>>   		return -ENOMEM;
>>
>> +	node = dev_to_node(&pdev->dev);
>> +	if (node >= 0) {
>> +		instance = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "%d-", node);
> 
> I've never noticed it before (and it's not introduced by this patch) but I
> really dislike the child device registering devres nodes with its parent...
> 
>> +		if (!instance)
>> +			return -ENOMEM;
>> +	}
>> +
>>   	for (i = 0, offset = 0; i < gpio->soc->num_ports; i++) {
>>   		const struct tegra_gpio_port *port = &gpio->soc->ports[i];
>>   		char *name;
>>
>>   		for (j = 0; j < port->pins; j++) {
>> -			if (gpio->soc->prefix)
>> -				name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "%s-P%s.%02x",
>> -						      gpio->soc->prefix, port->name, j);
>> -			else
>> -				name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "P%s.%02x",
>> -						      port->name, j);
>> +			name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "%s%sP%s.%02x",
>> +					      instance ?: "", gpio->soc->prefix ?: "",
> 
> instance can't be NULL here, can it? Either print it unconditionally or
> initialize it to NULL.

The other alternative here is that we just use 'instance' without the 
ternary operator because we initialise to "" ...

  name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "%s%sP%s.%02x",
                        instance, gpio->soc->prefix ?: "",
                        port->name, j);

Jon

-- 
nvpublic
Re: [PATCH] gpio: tegra186: Support multi-socket devices
Posted by Jon Hunter 1 month, 2 weeks ago
On 16/02/2026 11:29, Bartosz Golaszewski wrote:
> On Mon, 16 Feb 2026 05:58:42 +0100, Prathamesh Shete <pshete@nvidia.com> said:
>> On Tegra platforms, multiple SoC instances may be present with each
>> defining the same GPIO name. For such devices, this results in
>> duplicate GPIO names.
>>
>> When the device has a valid NUMA node, prepend the NUMA node ID
>> to the GPIO name prefix. The node ID identifies each socket,
>> ensuring GPIO line names remain distinct across multiple sockets.
>>
>> Signed-off-by: Prathamesh Shete <pshete@nvidia.com>
>> ---
>>   drivers/gpio/gpio-tegra186.c | 26 +++++++++++++++++---------
>>   1 file changed, 17 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c
>> index 9c874f07be75..daf5aaffa28a 100644
>> --- a/drivers/gpio/gpio-tegra186.c
>> +++ b/drivers/gpio/gpio-tegra186.c
>> @@ -857,7 +857,8 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
>>   	struct device_node *np;
>>   	struct resource *res;
>>   	char **names;
>> -	int err;
>> +	char *instance = "";
>> +	int node, err;
>>
>>   	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
>>   	if (!gpio)
>> @@ -937,17 +938,21 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
>>   	if (!names)
>>   		return -ENOMEM;
>>
>> +	node = dev_to_node(&pdev->dev);
>> +	if (node >= 0) {
>> +		instance = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "%d-", node);
> 
> I've never noticed it before (and it's not introduced by this patch) but I
> really dislike the child device registering devres nodes with its parent...

While it looks a bit odd, the parent is initialised as ...

  gpio->gpio.parent = &pdev->dev

> 
>> +		if (!instance)
>> +			return -ENOMEM;
>> +	}
>> +
>>   	for (i = 0, offset = 0; i < gpio->soc->num_ports; i++) {
>>   		const struct tegra_gpio_port *port = &gpio->soc->ports[i];
>>   		char *name;
>>
>>   		for (j = 0; j < port->pins; j++) {
>> -			if (gpio->soc->prefix)
>> -				gpio->gpio.parent, GFP_KERNEL, "%s-P%s.%02x",
>> -						      gpio->soc->prefix, port->name, j);
>> -			else
>> -				name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "P%s.%02x",
>> -						      port->name, j);
>> +			name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "%s%sP%s.%02x",
>> +					      instance ?: "", gpio->soc->prefix ?: "",
> 
> instance can't be NULL here, can it? Either print it unconditionally or
> initialize it to NULL.

Probably best to drop 'instance' altogether and just ...

  if (node >= 0)
        name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL,
                              "%d-%sP%s.%02x", node,
                              gpio->soc->prefix ?: "",
                              port->name, j);
  else
        name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL,
                              "%sP%s.%02x",
                              gpio->soc->prefix ?: "",
                              port->name, j);

> 
>> +					      port->name, j);
>>   			if (!name)
>>   				return -ENOMEM;
>>
>> @@ -1373,6 +1378,9 @@ static const struct tegra_gpio_soc tegra256_main_soc = {
>>   	.has_vm_support = true,
>>   };
>>
>> +/* Macro to define GPIO name prefix with separator */
>> +#define TEGRA_GPIO_PREFIX(_x)	_x "-"
>> +
> 
> This doesn't look like it belongs to this patch, why are you doing it

Yes we should split this into two patches; one to simplify the prefix 
handling and one to handle the socket.

Jon

-- 
nvpublic
Re: [PATCH] gpio: tegra186: Support multi-socket devices
Posted by Bartosz Golaszewski 1 month, 2 weeks ago
On Mon, Feb 16, 2026 at 6:22 PM Jon Hunter <jonathanh@nvidia.com> wrote:
>
>
> On 16/02/2026 11:29, Bartosz Golaszewski wrote:
> > On Mon, 16 Feb 2026 05:58:42 +0100, Prathamesh Shete <pshete@nvidia.com> said:
> >> On Tegra platforms, multiple SoC instances may be present with each
> >> defining the same GPIO name. For such devices, this results in
> >> duplicate GPIO names.
> >>
> >> When the device has a valid NUMA node, prepend the NUMA node ID
> >> to the GPIO name prefix. The node ID identifies each socket,
> >> ensuring GPIO line names remain distinct across multiple sockets.
> >>
> >> Signed-off-by: Prathamesh Shete <pshete@nvidia.com>
> >> ---
> >>   drivers/gpio/gpio-tegra186.c | 26 +++++++++++++++++---------
> >>   1 file changed, 17 insertions(+), 9 deletions(-)
> >>
> >> diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c
> >> index 9c874f07be75..daf5aaffa28a 100644
> >> --- a/drivers/gpio/gpio-tegra186.c
> >> +++ b/drivers/gpio/gpio-tegra186.c
> >> @@ -857,7 +857,8 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
> >>      struct device_node *np;
> >>      struct resource *res;
> >>      char **names;
> >> -    int err;
> >> +    char *instance = "";
> >> +    int node, err;
> >>
> >>      gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
> >>      if (!gpio)
> >> @@ -937,17 +938,21 @@ static int tegra186_gpio_probe(struct platform_device *pdev)
> >>      if (!names)
> >>              return -ENOMEM;
> >>
> >> +    node = dev_to_node(&pdev->dev);
> >> +    if (node >= 0) {
> >> +            instance = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, "%d-", node);
> >
> > I've never noticed it before (and it's not introduced by this patch) but I
> > really dislike the child device registering devres nodes with its parent...
>
> While it looks a bit odd, the parent is initialised as ...
>
>   gpio->gpio.parent = &pdev->dev
>

Right. Nevermind my comment then.

Bart