Re: [linux-yocto][v5.15/standard/preempt-rt/nxp-sdk-5.15/nxp-s32g][PATCH] gpio: fix pinctrl_gpio_get_mux_owner

2024-01-26 Thread Bruce Ashfield
In message: Re: 
[linux-yocto][v5.15/standard/preempt-rt/nxp-sdk-5.15/nxp-s32g][PATCH] gpio: fix 
pinctrl_gpio_get_mux_owner
on 26/01/2024 Quanyang Wang wrote:

> Hi Bruce,
> 
> On 1/24/24 14:38, quanyang.wang via lists.yoctoproject.org wrote:
> 
> From: Quanyang Wang 
> 
> The commit 4ce1995313ecb ("gpio: use pinctrl_gpio_get_mux_owner")
> intends to call pinctrl_gpio_get_mux_owner to mark the muxed pin as
> "used" and copy "mux_owner" or "gpio_owner" to "info->consumer". So that
> when calling gpioinfo at userspace, the "mux_owner" is printed as
> "label" in the output of console:
> 
> root@nxp-s32g:~# gpioinfo gpiochip0
> gpiochip0 - 191 lines:
> ...
> line   5:  "PA_05"   unused   input  active-high
> line   6:  "PA_06" "401d8000.spi" input active-high [used]
> line   7:  "PA_07" "401d8000.spi" input active-high [used]
> ...
> 
> But there are 3 problems with the current implementation:
> 1. The parameter "gpio" of the function pinctrl_gpio_get_mux_owner
> should be "gc->base + info->offset" rather than "info->offset".
> 2. The member "strict" of s32cc_pmx_ops can be used to mark the flag
> GPIO_V2_LINE_FLAG_USED, so there is no need to use the funciton
> pinctrl_gpio_get_mux_owner to do that.
> 3. The function pinctrl_gpio_get_mux_owner takes mutex so it must be
> called before taking the spinlock, or else it triggers the following
> calltrace:
> 
> [ 4640.017246] BUG: sleeping function called from invalid context at 
> kernel/locking/rtmutex_api.c:510
> [ 4640.017264] in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 
> 11395, name: gpioinfo
> [ 4640.017271] preempt_count: 0, expected: 0
> [ 4640.017276] RCU nest depth: 1, expected: 0
> [ 4640.017281] INFO: lockdep is turned off.
> [ 4640.017290] CPU: 3 PID: 11395 Comm: gpioinfo Tainted: GW  O
>   5.15.147-rt72-yocto-preempt-rt #1
> [ 4640.017297] Hardware name: Freescale S32G399A (DT)
> [ 4640.017302] Call trace:
> [ 4640.017304]  dump_backtrace+0x0/0x1c0
> [ 4640.017319]  show_stack+0x20/0x30
> [ 4640.017325]  dump_stack_lvl+0xb0/0xf4
> [ 4640.017335]  dump_stack+0x18/0x34
> [ 4640.017342]  __might_resched+0x15c/0x1e0
> [ 4640.017351]  __might_sleep+0x50/0xa0
> [ 4640.017357]  mutex_lock_nested+0x58/0xe0
> [ 4640.017367]  pinctrl_get_device_gpio_range+0x48/0x11c
> [ 4640.017378]  pinctrl_gpio_get_mux_owner+0x48/0x110
> [ 4640.017386]  gpio_desc_to_lineinfo+0x2a8/0x2dc
> [ 4640.017396]  lineinfo_get_v1+0x144/0x260
> [ 4640.017405]  gpio_ioctl_unlocked+0xf4/0x3d0
> [ 4640.017410]  gpio_ioctl+0x4c/0x74
> [ 4640.017415]  __arm64_sys_ioctl+0xb0/0xf4
> [ 4640.017424]  invoke_syscall+0x5c/0x130
> [ 4640.017437]  el0_svc_common.constprop.0+0x68/0x124
> [ 4640.017445]  do_el0_svc+0x4c/0xb0
> [ 4640.017452]  el0_svc+0x54/0x110
> [ 4640.017458]  el0t_64_sync_handler+0xa4/0x12c
> [ 4640.017464]  el0t_64_sync+0x1a0/0x1a4
> 
> Signed-off-by: Quanyang Wang 
> ---
> Hi Bruce,
> Would you please help merge this patch to the branches:
> v5.15/standard/preempt-rt/nxp-sdk-5.15/nxp-s32g
> v5.15/standard/nxp-sdk-5.15/nxp-s32g
> 
> I can't find this patch in v5.15/standard/nxp-sdk-5.15/nxp-s32g, would you
> please help check it?

I'm not sure what happened, but indeed, I missed that
branch.

It should be fixed now

Bruce

> 
> Thanks,
> 
> Quanyang
> 
> Thanks,
> Quanyang
> ---
>  drivers/gpio/gpiolib-cdev.c| 10 +++---
>  drivers/pinctrl/freescale/pinctrl-s32cc-core.c |  1 +
>  2 files changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
> index e3b0d1fbd728a..80e8c32d65e12 100644
> --- a/drivers/gpio/gpiolib-cdev.c
> +++ b/drivers/gpio/gpiolib-cdev.c
> @@ -2021,7 +2021,6 @@ static void gpio_desc_to_lineinfo(struct gpio_desc 
> *desc,
> unsigned long flags;
> u32 debounce_period_us;
> unsigned int num_attrs = 0;
> -   int ret;
> 
> memset(info, 0, sizeof(*info));
> info->offset = gpio_chip_hwgpio(desc);
> @@ -2036,6 +2035,9 @@ static void gpio_desc_to_lineinfo(struct gpio_desc 
> *desc,
> ok_for_pinctrl =
> pinctrl_gpio_can_use_line(gc->base + 

Re: [linux-yocto][v5.15/standard/preempt-rt/nxp-sdk-5.15/nxp-s32g][PATCH] gpio: fix pinctrl_gpio_get_mux_owner

2024-01-25 Thread quanyang.wang via lists.yoctoproject.org

Hi Bruce,

On 1/24/24 14:38, quanyang.wang via lists.yoctoproject.org wrote:

From: Quanyang Wang

The commit 4ce1995313ecb ("gpio: use pinctrl_gpio_get_mux_owner")
intends to call pinctrl_gpio_get_mux_owner to mark the muxed pin as
"used" and copy "mux_owner" or "gpio_owner" to "info->consumer". So that
when calling gpioinfo at userspace, the "mux_owner" is printed as
"label" in the output of console:

 root@nxp-s32g:~# gpioinfo gpiochip0
 gpiochip0 - 191 lines:
...
 line   5:  "PA_05"   unused   input  active-high
 line   6:  "PA_06" "401d8000.spi" input active-high [used]
 line   7:  "PA_07" "401d8000.spi" input active-high [used]
...

But there are 3 problems with the current implementation:
1. The parameter "gpio" of the function pinctrl_gpio_get_mux_owner
should be "gc->base + info->offset" rather than "info->offset".
2. The member "strict" of s32cc_pmx_ops can be used to mark the flag
GPIO_V2_LINE_FLAG_USED, so there is no need to use the funciton
pinctrl_gpio_get_mux_owner to do that.
3. The function pinctrl_gpio_get_mux_owner takes mutex so it must be
called before taking the spinlock, or else it triggers the following
calltrace:

[ 4640.017246] BUG: sleeping function called from invalid context at 
kernel/locking/rtmutex_api.c:510
[ 4640.017264] in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 11395, 
name: gpioinfo
[ 4640.017271] preempt_count: 0, expected: 0
[ 4640.017276] RCU nest depth: 1, expected: 0
[ 4640.017281] INFO: lockdep is turned off.
[ 4640.017290] CPU: 3 PID: 11395 Comm: gpioinfo Tainted: GW  O  
5.15.147-rt72-yocto-preempt-rt #1
[ 4640.017297] Hardware name: Freescale S32G399A (DT)
[ 4640.017302] Call trace:
[ 4640.017304]  dump_backtrace+0x0/0x1c0
[ 4640.017319]  show_stack+0x20/0x30
[ 4640.017325]  dump_stack_lvl+0xb0/0xf4
[ 4640.017335]  dump_stack+0x18/0x34
[ 4640.017342]  __might_resched+0x15c/0x1e0
[ 4640.017351]  __might_sleep+0x50/0xa0
[ 4640.017357]  mutex_lock_nested+0x58/0xe0
[ 4640.017367]  pinctrl_get_device_gpio_range+0x48/0x11c
[ 4640.017378]  pinctrl_gpio_get_mux_owner+0x48/0x110
[ 4640.017386]  gpio_desc_to_lineinfo+0x2a8/0x2dc
[ 4640.017396]  lineinfo_get_v1+0x144/0x260
[ 4640.017405]  gpio_ioctl_unlocked+0xf4/0x3d0
[ 4640.017410]  gpio_ioctl+0x4c/0x74
[ 4640.017415]  __arm64_sys_ioctl+0xb0/0xf4
[ 4640.017424]  invoke_syscall+0x5c/0x130
[ 4640.017437]  el0_svc_common.constprop.0+0x68/0x124
[ 4640.017445]  do_el0_svc+0x4c/0xb0
[ 4640.017452]  el0_svc+0x54/0x110
[ 4640.017458]  el0t_64_sync_handler+0xa4/0x12c
[ 4640.017464]  el0t_64_sync+0x1a0/0x1a4

Signed-off-by: Quanyang Wang
---
Hi Bruce,
Would you please help merge this patch to the branches:
v5.15/standard/preempt-rt/nxp-sdk-5.15/nxp-s32g
v5.15/standard/nxp-sdk-5.15/nxp-s32g


I can't find this patch in v5.15/standard/nxp-sdk-5.15/nxp-s32g, would 
you please help check it?


Thanks,

Quanyang


Thanks,
Quanyang
---
  drivers/gpio/gpiolib-cdev.c| 10 +++---
  drivers/pinctrl/freescale/pinctrl-s32cc-core.c |  1 +
  2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index e3b0d1fbd728a..80e8c32d65e12 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -2021,7 +2021,6 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
unsigned long flags;
u32 debounce_period_us;
unsigned int num_attrs = 0;
-   int ret;
  
  	memset(info, 0, sizeof(*info));

info->offset = gpio_chip_hwgpio(desc);
@@ -2036,6 +2035,9 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
ok_for_pinctrl =
pinctrl_gpio_can_use_line(gc->base + info->offset);
  
+	pinctrl_gpio_get_mux_owner(gc->base + info->offset, info->consumer,

+sizeof(info->consumer));
+
spin_lock_irqsave(_lock, flags);
  
  	if (desc->name)

@@ -2049,12 +2051,6 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
  
  	if (desc->label)

strscpy(info->consumer, desc->label, sizeof(info->consumer));
-   else {
-   ret = pinctrl_gpio_get_mux_owner(info->offset, info->consumer,
-sizeof(info->consumer));
-   if (!ret)
-   info->flags |= GPIO_V2_LINE_FLAG_USED;
-   }
  
  	if (test_bit(FLAG_REQUESTED, >flags) ||

test_bit(FLAG_IS_HOGGED, >flags) ||
diff --git a/drivers/pinctrl/freescale/pinctrl-s32cc-core.c 
b/drivers/pinctrl/freescale/pinctrl-s32cc-core.c
index e1d0cc817b65a..a711242dc626b 100644
--- a/drivers/pinctrl/freescale/pinctrl-s32cc-core.c
+++ b/drivers/pinctrl/freescale/pinctrl-s32cc-core.c
@@ -553,6 +553,7 @@ static const struct pinmux_ops s32cc_pmx_ops = {
.gpio_request_enable = s32cc_pmx_gpio_request_enable,
.gpio_disable_free = s32cc_pmx_gpio_disable_free,

Re: [linux-yocto][v5.15/standard/preempt-rt/nxp-sdk-5.15/nxp-s32g][PATCH] gpio: fix pinctrl_gpio_get_mux_owner

2024-01-24 Thread Bruce Ashfield
merged.

Bruce

In message: 
[linux-yocto][v5.15/standard/preempt-rt/nxp-sdk-5.15/nxp-s32g][PATCH] gpio: fix 
pinctrl_gpio_get_mux_owner
on 24/01/2024 quanyang.w...@windriver.com wrote:

> From: Quanyang Wang 
> 
> The commit 4ce1995313ecb ("gpio: use pinctrl_gpio_get_mux_owner")
> intends to call pinctrl_gpio_get_mux_owner to mark the muxed pin as
> "used" and copy "mux_owner" or "gpio_owner" to "info->consumer". So that
> when calling gpioinfo at userspace, the "mux_owner" is printed as
> "label" in the output of console:
> 
> root@nxp-s32g:~# gpioinfo gpiochip0
> gpiochip0 - 191 lines:
>   ...
> line   5:  "PA_05"   unused   input  active-high
> line   6:  "PA_06" "401d8000.spi" input active-high [used]
> line   7:  "PA_07" "401d8000.spi" input active-high [used]
>   ...
> 
> But there are 3 problems with the current implementation:
> 1. The parameter "gpio" of the function pinctrl_gpio_get_mux_owner
> should be "gc->base + info->offset" rather than "info->offset".
> 2. The member "strict" of s32cc_pmx_ops can be used to mark the flag
> GPIO_V2_LINE_FLAG_USED, so there is no need to use the funciton
> pinctrl_gpio_get_mux_owner to do that.
> 3. The function pinctrl_gpio_get_mux_owner takes mutex so it must be
> called before taking the spinlock, or else it triggers the following
> calltrace:
> 
> [ 4640.017246] BUG: sleeping function called from invalid context at 
> kernel/locking/rtmutex_api.c:510
> [ 4640.017264] in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 11395, 
> name: gpioinfo
> [ 4640.017271] preempt_count: 0, expected: 0
> [ 4640.017276] RCU nest depth: 1, expected: 0
> [ 4640.017281] INFO: lockdep is turned off.
> [ 4640.017290] CPU: 3 PID: 11395 Comm: gpioinfo Tainted: GW  O  
> 5.15.147-rt72-yocto-preempt-rt #1
> [ 4640.017297] Hardware name: Freescale S32G399A (DT)
> [ 4640.017302] Call trace:
> [ 4640.017304]  dump_backtrace+0x0/0x1c0
> [ 4640.017319]  show_stack+0x20/0x30
> [ 4640.017325]  dump_stack_lvl+0xb0/0xf4
> [ 4640.017335]  dump_stack+0x18/0x34
> [ 4640.017342]  __might_resched+0x15c/0x1e0
> [ 4640.017351]  __might_sleep+0x50/0xa0
> [ 4640.017357]  mutex_lock_nested+0x58/0xe0
> [ 4640.017367]  pinctrl_get_device_gpio_range+0x48/0x11c
> [ 4640.017378]  pinctrl_gpio_get_mux_owner+0x48/0x110
> [ 4640.017386]  gpio_desc_to_lineinfo+0x2a8/0x2dc
> [ 4640.017396]  lineinfo_get_v1+0x144/0x260
> [ 4640.017405]  gpio_ioctl_unlocked+0xf4/0x3d0
> [ 4640.017410]  gpio_ioctl+0x4c/0x74
> [ 4640.017415]  __arm64_sys_ioctl+0xb0/0xf4
> [ 4640.017424]  invoke_syscall+0x5c/0x130
> [ 4640.017437]  el0_svc_common.constprop.0+0x68/0x124
> [ 4640.017445]  do_el0_svc+0x4c/0xb0
> [ 4640.017452]  el0_svc+0x54/0x110
> [ 4640.017458]  el0t_64_sync_handler+0xa4/0x12c
> [ 4640.017464]  el0t_64_sync+0x1a0/0x1a4
> 
> Signed-off-by: Quanyang Wang 
> ---
> Hi Bruce,
> Would you please help merge this patch to the branches:
>   v5.15/standard/preempt-rt/nxp-sdk-5.15/nxp-s32g
>   v5.15/standard/nxp-sdk-5.15/nxp-s32g
> Thanks,
> Quanyang
> ---
>  drivers/gpio/gpiolib-cdev.c| 10 +++---
>  drivers/pinctrl/freescale/pinctrl-s32cc-core.c |  1 +
>  2 files changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
> index e3b0d1fbd728a..80e8c32d65e12 100644
> --- a/drivers/gpio/gpiolib-cdev.c
> +++ b/drivers/gpio/gpiolib-cdev.c
> @@ -2021,7 +2021,6 @@ static void gpio_desc_to_lineinfo(struct gpio_desc 
> *desc,
>   unsigned long flags;
>   u32 debounce_period_us;
>   unsigned int num_attrs = 0;
> - int ret;
>  
>   memset(info, 0, sizeof(*info));
>   info->offset = gpio_chip_hwgpio(desc);
> @@ -2036,6 +2035,9 @@ static void gpio_desc_to_lineinfo(struct gpio_desc 
> *desc,
>   ok_for_pinctrl =
>   pinctrl_gpio_can_use_line(gc->base + info->offset);
>  
> + pinctrl_gpio_get_mux_owner(gc->base + info->offset, info->consumer,
> +  sizeof(info->consumer));
> +
>   spin_lock_irqsave(_lock, flags);
>  
>   if (desc->name)
> @@ -2049,12 +2051,6 @@ static void gpio_desc_to_lineinfo(struct gpio_desc 
> *desc,
>  
>   if (desc->label)
>   strscpy(info->consumer, desc->label, sizeof(info->consumer));
> - else {
> - ret = pinctrl_gpio_get_mux_owner(info->offset, info->consumer,
> -  siz

[linux-yocto][v5.15/standard/preempt-rt/nxp-sdk-5.15/nxp-s32g][PATCH] gpio: fix pinctrl_gpio_get_mux_owner

2024-01-23 Thread quanyang.wang via lists.yoctoproject.org
From: Quanyang Wang 

The commit 4ce1995313ecb ("gpio: use pinctrl_gpio_get_mux_owner")
intends to call pinctrl_gpio_get_mux_owner to mark the muxed pin as
"used" and copy "mux_owner" or "gpio_owner" to "info->consumer". So that
when calling gpioinfo at userspace, the "mux_owner" is printed as
"label" in the output of console:

root@nxp-s32g:~# gpioinfo gpiochip0
gpiochip0 - 191 lines:
...
line   5:  "PA_05"   unused   input  active-high
line   6:  "PA_06" "401d8000.spi" input active-high [used]
line   7:  "PA_07" "401d8000.spi" input active-high [used]
...

But there are 3 problems with the current implementation:
1. The parameter "gpio" of the function pinctrl_gpio_get_mux_owner
should be "gc->base + info->offset" rather than "info->offset".
2. The member "strict" of s32cc_pmx_ops can be used to mark the flag
GPIO_V2_LINE_FLAG_USED, so there is no need to use the funciton
pinctrl_gpio_get_mux_owner to do that.
3. The function pinctrl_gpio_get_mux_owner takes mutex so it must be
called before taking the spinlock, or else it triggers the following
calltrace:

[ 4640.017246] BUG: sleeping function called from invalid context at 
kernel/locking/rtmutex_api.c:510
[ 4640.017264] in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 11395, 
name: gpioinfo
[ 4640.017271] preempt_count: 0, expected: 0
[ 4640.017276] RCU nest depth: 1, expected: 0
[ 4640.017281] INFO: lockdep is turned off.
[ 4640.017290] CPU: 3 PID: 11395 Comm: gpioinfo Tainted: GW  O  
5.15.147-rt72-yocto-preempt-rt #1
[ 4640.017297] Hardware name: Freescale S32G399A (DT)
[ 4640.017302] Call trace:
[ 4640.017304]  dump_backtrace+0x0/0x1c0
[ 4640.017319]  show_stack+0x20/0x30
[ 4640.017325]  dump_stack_lvl+0xb0/0xf4
[ 4640.017335]  dump_stack+0x18/0x34
[ 4640.017342]  __might_resched+0x15c/0x1e0
[ 4640.017351]  __might_sleep+0x50/0xa0
[ 4640.017357]  mutex_lock_nested+0x58/0xe0
[ 4640.017367]  pinctrl_get_device_gpio_range+0x48/0x11c
[ 4640.017378]  pinctrl_gpio_get_mux_owner+0x48/0x110
[ 4640.017386]  gpio_desc_to_lineinfo+0x2a8/0x2dc
[ 4640.017396]  lineinfo_get_v1+0x144/0x260
[ 4640.017405]  gpio_ioctl_unlocked+0xf4/0x3d0
[ 4640.017410]  gpio_ioctl+0x4c/0x74
[ 4640.017415]  __arm64_sys_ioctl+0xb0/0xf4
[ 4640.017424]  invoke_syscall+0x5c/0x130
[ 4640.017437]  el0_svc_common.constprop.0+0x68/0x124
[ 4640.017445]  do_el0_svc+0x4c/0xb0
[ 4640.017452]  el0_svc+0x54/0x110
[ 4640.017458]  el0t_64_sync_handler+0xa4/0x12c
[ 4640.017464]  el0t_64_sync+0x1a0/0x1a4

Signed-off-by: Quanyang Wang 
---
Hi Bruce,
Would you please help merge this patch to the branches:
v5.15/standard/preempt-rt/nxp-sdk-5.15/nxp-s32g
v5.15/standard/nxp-sdk-5.15/nxp-s32g
Thanks,
Quanyang
---
 drivers/gpio/gpiolib-cdev.c| 10 +++---
 drivers/pinctrl/freescale/pinctrl-s32cc-core.c |  1 +
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index e3b0d1fbd728a..80e8c32d65e12 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -2021,7 +2021,6 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
unsigned long flags;
u32 debounce_period_us;
unsigned int num_attrs = 0;
-   int ret;
 
memset(info, 0, sizeof(*info));
info->offset = gpio_chip_hwgpio(desc);
@@ -2036,6 +2035,9 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
ok_for_pinctrl =
pinctrl_gpio_can_use_line(gc->base + info->offset);
 
+   pinctrl_gpio_get_mux_owner(gc->base + info->offset, info->consumer,
+sizeof(info->consumer));
+
spin_lock_irqsave(_lock, flags);
 
if (desc->name)
@@ -2049,12 +2051,6 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
 
if (desc->label)
strscpy(info->consumer, desc->label, sizeof(info->consumer));
-   else {
-   ret = pinctrl_gpio_get_mux_owner(info->offset, info->consumer,
-sizeof(info->consumer));
-   if (!ret)
-   info->flags |= GPIO_V2_LINE_FLAG_USED;
-   }
 
if (test_bit(FLAG_REQUESTED, >flags) ||
test_bit(FLAG_IS_HOGGED, >flags) ||
diff --git a/drivers/pinctrl/freescale/pinctrl-s32cc-core.c 
b/drivers/pinctrl/freescale/pinctrl-s32cc-core.c
index e1d0cc817b65a..a711242dc626b 100644
--- a/drivers/pinctrl/freescale/pinctrl-s32cc-core.c
+++ b/drivers/pinctrl/freescale/pinctrl-s32cc-core.c
@@ -553,6 +553,7 @@ static const struct pinmux_ops s32cc_pmx_ops = {
.gpio_request_enable = s32cc_pmx_gpio_request_enable,
.gpio_disable_free = s32cc_pmx_gpio_disable_free,
.gpio_set_direction = s32cc_pmx_gpio_set_direction,
+   .strict = true,
 };
 
 static int s32cc_pinconf_get(struct pinctrl_dev *pctldev,
-- 
2.36.1


-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all