]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Fri, 3 May 2024 16:37:07 +0000 (12:37 -0400)
committerSasha Levin <sashal@kernel.org>
Fri, 3 May 2024 16:37:07 +0000 (12:37 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
20 files changed:
queue-5.4/dmaengine-pl330-issue_pending-waits-until-wfp-state.patch [new file with mode: 0644]
queue-5.4/dmaengine-revert-dmaengine-pl330-issue_pending-waits.patch [new file with mode: 0644]
queue-5.4/nfs-expose-proc-net-sunrpc-nfs-in-net-namespaces.patch [new file with mode: 0644]
queue-5.4/nfs-handle-error-of-rpc_proc_register-in-nfs_net_ini.patch [new file with mode: 0644]
queue-5.4/nfs-make-the-rpc_stat-per-net-namespace.patch [new file with mode: 0644]
queue-5.4/pinctrl-core-delete-incorrect-free-in-pinctrl_enable.patch [new file with mode: 0644]
queue-5.4/pinctrl-devicetree-fix-refcount-leak-in-pinctrl_dt_t.patch [new file with mode: 0644]
queue-5.4/pinctrl-mediatek-backward-compatible-to-previous-med.patch [new file with mode: 0644]
queue-5.4/pinctrl-mediatek-check-gpio-pin-number-and-use-binar.patch [new file with mode: 0644]
queue-5.4/pinctrl-mediatek-paris-fix-pin_config_bias_-readback.patch [new file with mode: 0644]
queue-5.4/pinctrl-mediatek-paris-rework-mtk_pinconf_-get-set-s.patch [new file with mode: 0644]
queue-5.4/pinctrl-mediatek-paris-rework-support-for-pin_config.patch [new file with mode: 0644]
queue-5.4/pinctrl-mediatek-refine-mtk_pinconf_get-and-mtk_pinc.patch [new file with mode: 0644]
queue-5.4/pinctrl-mediatek-refine-mtk_pinconf_get.patch [new file with mode: 0644]
queue-5.4/pinctrl-mediatek-remove-shadow-variable-declaration.patch [new file with mode: 0644]
queue-5.4/pinctrl-mediatek-supporting-driving-setting-without-.patch [new file with mode: 0644]
queue-5.4/power-rt9455-hide-unused-rt9455_boost_voltage_values.patch [new file with mode: 0644]
queue-5.4/series [new file with mode: 0644]
queue-5.4/sunrpc-add-a-struct-rpc_stats-arg-to-rpc_create_args.patch [new file with mode: 0644]
queue-5.4/wifi-nl80211-don-t-free-null-coalescing-rule.patch [new file with mode: 0644]

diff --git a/queue-5.4/dmaengine-pl330-issue_pending-waits-until-wfp-state.patch b/queue-5.4/dmaengine-pl330-issue_pending-waits-until-wfp-state.patch
new file mode 100644 (file)
index 0000000..3eedb79
--- /dev/null
@@ -0,0 +1,46 @@
+From 76ffcf0a9b4ee1e48e9f7ff7e68ace9bc1b457e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Dec 2023 14:50:26 +0900
+Subject: dmaengine: pl330: issue_pending waits until WFP state
+
+From: Bumyong Lee <bumyong.lee@samsung.com>
+
+[ Upstream commit 22a9d9585812440211b0b34a6bc02ade62314be4 ]
+
+According to DMA-330 errata notice[1] 71930, DMAKILL
+cannot clear internal signal, named pipeline_req_active.
+it makes that pl330 would wait forever in WFP state
+although dma already send dma request if pl330 gets
+dma request before entering WFP state.
+
+The errata suggests that polling until entering WFP state
+as workaround and then peripherals allows to issue dma request.
+
+[1]: https://developer.arm.com/documentation/genc008428/latest
+
+Signed-off-by: Bumyong Lee <bumyong.lee@samsung.com>
+Link: https://lore.kernel.org/r/20231219055026.118695-1-bumyong.lee@samsung.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Stable-dep-of: afc89870ea67 ("dmaengine: Revert "dmaengine: pl330: issue_pending waits until WFP state"")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/pl330.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
+index 1d7d4b8d810a5..d12939c25a618 100644
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -1051,6 +1051,9 @@ static bool _trigger(struct pl330_thread *thrd)
+       thrd->req_running = idx;
++      if (desc->rqtype == DMA_MEM_TO_DEV || desc->rqtype == DMA_DEV_TO_MEM)
++              UNTIL(thrd, PL330_STATE_WFP);
++
+       return true;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.4/dmaengine-revert-dmaengine-pl330-issue_pending-waits.patch b/queue-5.4/dmaengine-revert-dmaengine-pl330-issue_pending-waits.patch
new file mode 100644 (file)
index 0000000..f2e3f65
--- /dev/null
@@ -0,0 +1,39 @@
+From dc017414e48cc1eb6b60f51484bbcab461c7fa92 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Mar 2024 12:21:51 +0530
+Subject: dmaengine: Revert "dmaengine: pl330: issue_pending waits until WFP
+ state"
+
+From: Vinod Koul <vkoul@kernel.org>
+
+[ Upstream commit afc89870ea677bd5a44516eb981f7a259b74280c ]
+
+This reverts commit 22a9d9585812 ("dmaengine: pl330: issue_pending waits
+until WFP state") as it seems to cause regression in pl330 driver.
+Note the issue now exists in mainline so a fix to be done.
+
+Cc: stable@vger.kernel.org
+Reported-by: karthikeyan <karthikeyan@linumiz.com>
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/pl330.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
+index d12939c25a618..1d7d4b8d810a5 100644
+--- a/drivers/dma/pl330.c
++++ b/drivers/dma/pl330.c
+@@ -1051,9 +1051,6 @@ static bool _trigger(struct pl330_thread *thrd)
+       thrd->req_running = idx;
+-      if (desc->rqtype == DMA_MEM_TO_DEV || desc->rqtype == DMA_DEV_TO_MEM)
+-              UNTIL(thrd, PL330_STATE_WFP);
+-
+       return true;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.4/nfs-expose-proc-net-sunrpc-nfs-in-net-namespaces.patch b/queue-5.4/nfs-expose-proc-net-sunrpc-nfs-in-net-namespaces.patch
new file mode 100644 (file)
index 0000000..159be9a
--- /dev/null
@@ -0,0 +1,71 @@
+From 3ffad6f5806c058ba9a4d3d4d056720c1c89e3cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Feb 2024 14:57:31 -0500
+Subject: nfs: expose /proc/net/sunrpc/nfs in net namespaces
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit d47151b79e3220e72ae323b8b8e9d6da20dc884e ]
+
+We're using nfs mounts inside of containers in production and noticed
+that the nfs stats are not exposed in /proc.  This is a problem for us
+as we use these stats for monitoring, and have to do this awkward bind
+mount from the main host into the container in order to get to these
+states.
+
+Add the rpc_proc_register call to the pernet operations entry and exit
+points so these stats can be exposed inside of network namespaces.
+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Stable-dep-of: 24457f1be29f ("nfs: Handle error of rpc_proc_register() in nfs_net_init().")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/inode.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+index 3bddf5332b6d6..c154e7f98e6d8 100644
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -2179,11 +2179,13 @@ EXPORT_SYMBOL_GPL(nfs_net_id);
+ static int nfs_net_init(struct net *net)
+ {
+       nfs_clients_init(net);
++      rpc_proc_register(net, &nfs_rpcstat);
+       return nfs_fs_proc_net_init(net);
+ }
+ static void nfs_net_exit(struct net *net)
+ {
++      rpc_proc_unregister(net, "nfs");
+       nfs_fs_proc_net_exit(net);
+       nfs_clients_exit(net);
+ }
+@@ -2242,15 +2244,12 @@ static int __init init_nfs_fs(void)
+       if (err)
+               goto out1;
+-      rpc_proc_register(&init_net, &nfs_rpcstat);
+-
+       err = register_nfs_fs();
+       if (err)
+               goto out0;
+       return 0;
+ out0:
+-      rpc_proc_unregister(&init_net, "nfs");
+       nfs_destroy_directcache();
+ out1:
+       nfs_destroy_writepagecache();
+@@ -2283,7 +2282,6 @@ static void __exit exit_nfs_fs(void)
+       nfs_destroy_nfspagecache();
+       nfs_fscache_unregister();
+       unregister_pernet_subsys(&nfs_net_ops);
+-      rpc_proc_unregister(&init_net, "nfs");
+       unregister_nfs_fs();
+       nfs_fs_proc_exit();
+       nfsiod_stop();
+-- 
+2.43.0
+
diff --git a/queue-5.4/nfs-handle-error-of-rpc_proc_register-in-nfs_net_ini.patch b/queue-5.4/nfs-handle-error-of-rpc_proc_register-in-nfs_net_ini.patch
new file mode 100644 (file)
index 0000000..a929073
--- /dev/null
@@ -0,0 +1,104 @@
+From 684cb63273d62cfcdf3ef4667f9998173a068e0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Apr 2024 15:12:00 -0700
+Subject: nfs: Handle error of rpc_proc_register() in nfs_net_init().
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit 24457f1be29f1e7042e50a7749f5c2dde8c433c8 ]
+
+syzkaller reported a warning [0] triggered while destroying immature
+netns.
+
+rpc_proc_register() was called in init_nfs_fs(), but its error
+has been ignored since at least the initial commit 1da177e4c3f4
+("Linux-2.6.12-rc2").
+
+Recently, commit d47151b79e32 ("nfs: expose /proc/net/sunrpc/nfs
+in net namespaces") converted the procfs to per-netns and made
+the problem more visible.
+
+Even when rpc_proc_register() fails, nfs_net_init() could succeed,
+and thus nfs_net_exit() will be called while destroying the netns.
+
+Then, remove_proc_entry() will be called for non-existing proc
+directory and trigger the warning below.
+
+Let's handle the error of rpc_proc_register() properly in nfs_net_init().
+
+[0]:
+name 'nfs'
+WARNING: CPU: 1 PID: 1710 at fs/proc/generic.c:711 remove_proc_entry+0x1bb/0x2d0 fs/proc/generic.c:711
+Modules linked in:
+CPU: 1 PID: 1710 Comm: syz-executor.2 Not tainted 6.8.0-12822-gcd51db110a7e #12
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
+RIP: 0010:remove_proc_entry+0x1bb/0x2d0 fs/proc/generic.c:711
+Code: 41 5d 41 5e c3 e8 85 09 b5 ff 48 c7 c7 88 58 64 86 e8 09 0e 71 02 e8 74 09 b5 ff 4c 89 e6 48 c7 c7 de 1b 80 84 e8 c5 ad 97 ff <0f> 0b eb b1 e8 5c 09 b5 ff 48 c7 c7 88 58 64 86 e8 e0 0d 71 02 eb
+RSP: 0018:ffffc9000c6d7ce0 EFLAGS: 00010286
+RAX: 0000000000000000 RBX: ffff8880422b8b00 RCX: ffffffff8110503c
+RDX: ffff888030652f00 RSI: ffffffff81105045 RDI: 0000000000000001
+RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000000
+R10: 0000000000000001 R11: ffffffff81bb62cb R12: ffffffff84807ffc
+R13: ffff88804ad6fcc0 R14: ffffffff84807ffc R15: ffffffff85741ff8
+FS:  00007f30cfba8640(0000) GS:ffff88807dd00000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007ff51afe8000 CR3: 000000005a60a005 CR4: 0000000000770ef0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+PKRU: 55555554
+Call Trace:
+ <TASK>
+ rpc_proc_unregister+0x64/0x70 net/sunrpc/stats.c:310
+ nfs_net_exit+0x1c/0x30 fs/nfs/inode.c:2438
+ ops_exit_list+0x62/0xb0 net/core/net_namespace.c:170
+ setup_net+0x46c/0x660 net/core/net_namespace.c:372
+ copy_net_ns+0x244/0x590 net/core/net_namespace.c:505
+ create_new_namespaces+0x2ed/0x770 kernel/nsproxy.c:110
+ unshare_nsproxy_namespaces+0xae/0x160 kernel/nsproxy.c:228
+ ksys_unshare+0x342/0x760 kernel/fork.c:3322
+ __do_sys_unshare kernel/fork.c:3393 [inline]
+ __se_sys_unshare kernel/fork.c:3391 [inline]
+ __x64_sys_unshare+0x1f/0x30 kernel/fork.c:3391
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0x4f/0x110 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x46/0x4e
+RIP: 0033:0x7f30d0febe5d
+Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 73 9f 1b 00 f7 d8 64 89 01 48
+RSP: 002b:00007f30cfba7cc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000110
+RAX: ffffffffffffffda RBX: 00000000004bbf80 RCX: 00007f30d0febe5d
+RDX: 0000000000000000 RSI: 0000000000000000 RDI: 000000006c020600
+RBP: 00000000004bbf80 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000002
+R13: 000000000000000b R14: 00007f30d104c530 R15: 0000000000000000
+ </TASK>
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzkaller <syzkaller@googlegroups.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/inode.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+index 96468ee4406fa..6a7a3b1d926ea 100644
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -2181,7 +2181,12 @@ static int nfs_net_init(struct net *net)
+       struct nfs_net *nn = net_generic(net, nfs_net_id);
+       nfs_clients_init(net);
+-      rpc_proc_register(net, &nn->rpcstats);
++
++      if (!rpc_proc_register(net, &nn->rpcstats)) {
++              nfs_clients_exit(net);
++              return -ENOMEM;
++      }
++
+       return nfs_fs_proc_net_init(net);
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.4/nfs-make-the-rpc_stat-per-net-namespace.patch b/queue-5.4/nfs-make-the-rpc_stat-per-net-namespace.patch
new file mode 100644 (file)
index 0000000..22f7eb9
--- /dev/null
@@ -0,0 +1,113 @@
+From 19fd9b51a1d242421d08d2798f3a321462f44a64 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Feb 2024 14:57:32 -0500
+Subject: nfs: make the rpc_stat per net namespace
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 1548036ef1204df65ca5a16e8b199c858cb80075 ]
+
+Now that we're exposing the rpc stats on a per-network namespace basis,
+move this struct into struct nfs_net and use that to make sure only the
+per-network namespace stats are exposed.
+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Stable-dep-of: 24457f1be29f ("nfs: Handle error of rpc_proc_register() in nfs_net_init().")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/client.c   | 5 ++++-
+ fs/nfs/inode.c    | 4 +++-
+ fs/nfs/internal.h | 2 --
+ fs/nfs/netns.h    | 2 ++
+ 4 files changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/fs/nfs/client.c b/fs/nfs/client.c
+index 35abe63655a9d..323cef064f2a4 100644
+--- a/fs/nfs/client.c
++++ b/fs/nfs/client.c
+@@ -72,7 +72,6 @@ const struct rpc_program nfs_program = {
+       .number                 = NFS_PROGRAM,
+       .nrvers                 = ARRAY_SIZE(nfs_version),
+       .version                = nfs_version,
+-      .stats                  = &nfs_rpcstat,
+       .pipe_dir_name          = NFS_PIPE_DIRNAME,
+ };
+@@ -492,6 +491,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,
+                         const struct nfs_client_initdata *cl_init,
+                         rpc_authflavor_t flavor)
+ {
++      struct nfs_net          *nn = net_generic(clp->cl_net, nfs_net_id);
+       struct rpc_clnt         *clnt = NULL;
+       struct rpc_create_args args = {
+               .net            = clp->cl_net,
+@@ -503,6 +503,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,
+               .servername     = clp->cl_hostname,
+               .nodename       = cl_init->nodename,
+               .program        = &nfs_program,
++              .stats          = &nn->rpcstats,
+               .version        = clp->rpc_ops->version,
+               .authflavor     = flavor,
+               .cred           = cl_init->cred,
+@@ -1077,6 +1078,8 @@ void nfs_clients_init(struct net *net)
+ #endif
+       spin_lock_init(&nn->nfs_client_lock);
+       nn->boot_time = ktime_get_real();
++      memset(&nn->rpcstats, 0, sizeof(nn->rpcstats));
++      nn->rpcstats.program = &nfs_program;
+       nfs_netns_sysfs_setup(nn, net);
+ }
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+index c154e7f98e6d8..96468ee4406fa 100644
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -2178,8 +2178,10 @@ EXPORT_SYMBOL_GPL(nfs_net_id);
+ static int nfs_net_init(struct net *net)
+ {
++      struct nfs_net *nn = net_generic(net, nfs_net_id);
++
+       nfs_clients_init(net);
+-      rpc_proc_register(net, &nfs_rpcstat);
++      rpc_proc_register(net, &nn->rpcstats);
+       return nfs_fs_proc_net_init(net);
+ }
+diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
+index fcd35c98a9377..fb28750da761f 100644
+--- a/fs/nfs/internal.h
++++ b/fs/nfs/internal.h
+@@ -405,8 +405,6 @@ struct dentry * nfs_xdev_mount_common(struct file_system_type *, int,
+ void nfs_kill_super(struct super_block *);
+ void nfs_fill_super(struct super_block *, struct nfs_mount_info *);
+-extern struct rpc_stat nfs_rpcstat;
+-
+ extern int __init register_nfs_fs(void);
+ extern void __exit unregister_nfs_fs(void);
+ extern bool nfs_sb_active(struct super_block *sb);
+diff --git a/fs/nfs/netns.h b/fs/nfs/netns.h
+index c8374f74dce11..a68b21603ea9a 100644
+--- a/fs/nfs/netns.h
++++ b/fs/nfs/netns.h
+@@ -9,6 +9,7 @@
+ #include <linux/nfs4.h>
+ #include <net/net_namespace.h>
+ #include <net/netns/generic.h>
++#include <linux/sunrpc/stats.h>
+ struct bl_dev_msg {
+       int32_t status;
+@@ -34,6 +35,7 @@ struct nfs_net {
+       struct nfs_netns_client *nfs_client;
+       spinlock_t nfs_client_lock;
+       ktime_t boot_time;
++      struct rpc_stat rpcstats;
+ #ifdef CONFIG_PROC_FS
+       struct proc_dir_entry *proc_nfsfs;
+ #endif
+-- 
+2.43.0
+
diff --git a/queue-5.4/pinctrl-core-delete-incorrect-free-in-pinctrl_enable.patch b/queue-5.4/pinctrl-core-delete-incorrect-free-in-pinctrl_enable.patch
new file mode 100644 (file)
index 0000000..02a8f94
--- /dev/null
@@ -0,0 +1,47 @@
+From 9f90700d0571d699e4585007a225337f99b127be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Mar 2024 09:38:39 +0300
+Subject: pinctrl: core: delete incorrect free in pinctrl_enable()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 5038a66dad0199de60e5671603ea6623eb9e5c79 ]
+
+The "pctldev" struct is allocated in devm_pinctrl_register_and_init().
+It's a devm_ managed pointer that is freed by devm_pinctrl_dev_release(),
+so freeing it in pinctrl_enable() will lead to a double free.
+
+The devm_pinctrl_dev_release() function frees the pindescs and destroys
+the mutex as well.
+
+Fixes: 6118714275f0 ("pinctrl: core: Fix pinctrl_register_and_init() with pinctrl_enable()")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Message-ID: <578fbe56-44e9-487c-ae95-29b695650f7c@moroto.mountain>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/core.c | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
+index a1c2dc304fb10..3947b7064bead 100644
+--- a/drivers/pinctrl/core.c
++++ b/drivers/pinctrl/core.c
+@@ -2053,13 +2053,7 @@ int pinctrl_enable(struct pinctrl_dev *pctldev)
+       error = pinctrl_claim_hogs(pctldev);
+       if (error) {
+-              dev_err(pctldev->dev, "could not claim hogs: %i\n",
+-                      error);
+-              pinctrl_free_pindescs(pctldev, pctldev->desc->pins,
+-                                    pctldev->desc->npins);
+-              mutex_destroy(&pctldev->mutex);
+-              kfree(pctldev);
+-
++              dev_err(pctldev->dev, "could not claim hogs: %i\n", error);
+               return error;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.4/pinctrl-devicetree-fix-refcount-leak-in-pinctrl_dt_t.patch b/queue-5.4/pinctrl-devicetree-fix-refcount-leak-in-pinctrl_dt_t.patch
new file mode 100644 (file)
index 0000000..e01930d
--- /dev/null
@@ -0,0 +1,52 @@
+From 637c2303364d0a04cd86442947c6144bd9305f63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Apr 2024 18:53:28 +0800
+Subject: pinctrl: devicetree: fix refcount leak in pinctrl_dt_to_map()
+
+From: Zeng Heng <zengheng4@huawei.com>
+
+[ Upstream commit a0cedbcc8852d6c77b00634b81e41f17f29d9404 ]
+
+If we fail to allocate propname buffer, we need to drop the reference
+count we just took. Because the pinctrl_dt_free_maps() includes the
+droping operation, here we call it directly.
+
+Fixes: 91d5c5060ee2 ("pinctrl: devicetree: fix null pointer dereferencing in pinctrl_dt_to_map")
+Suggested-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Zeng Heng <zengheng4@huawei.com>
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Message-ID: <20240415105328.3651441-1-zengheng4@huawei.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/devicetree.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
+index 362d84c2ead44..200357094e3be 100644
+--- a/drivers/pinctrl/devicetree.c
++++ b/drivers/pinctrl/devicetree.c
+@@ -223,14 +223,16 @@ int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
+       for (state = 0; ; state++) {
+               /* Retrieve the pinctrl-* property */
+               propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
+-              if (!propname)
+-                      return -ENOMEM;
++              if (!propname) {
++                      ret = -ENOMEM;
++                      goto err;
++              }
+               prop = of_find_property(np, propname, &size);
+               kfree(propname);
+               if (!prop) {
+                       if (state == 0) {
+-                              of_node_put(np);
+-                              return -ENODEV;
++                              ret = -ENODEV;
++                              goto err;
+                       }
+                       break;
+               }
+-- 
+2.43.0
+
diff --git a/queue-5.4/pinctrl-mediatek-backward-compatible-to-previous-med.patch b/queue-5.4/pinctrl-mediatek-backward-compatible-to-previous-med.patch
new file mode 100644 (file)
index 0000000..eeb21e4
--- /dev/null
@@ -0,0 +1,442 @@
+From 6f0c1471c8698b2fe4861908877f51d776cdd535 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jan 2020 14:53:13 +0800
+Subject: pinctrl: mediatek: Backward compatible to previous Mediatek's
+ bias-pull usage
+
+From: Light Hsieh <light.hsieh@mediatek.com>
+
+[ Upstream commit cafe19db7751269bf6b4dd2148cbfa9fbe91d651 ]
+
+Refine mtk_pinconf_set()/mtk_pinconf_get() for backward compatibility to
+previous MediaTek's bias-pull usage.
+In PINCTRL_MTK that use pinctrl-mtk-common.c, bias-pull setting for pins
+with 2 pull resistors can be specified as value for bias-pull-up and
+bias-pull-down. For example:
+    bias-pull-up = <MTK_PUPD_SET_R1R0_00>;
+    bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+    bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
+    bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+    bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
+    bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
+    bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+    bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+
+On the other hand, PINCTRL_MTK_PARIS use customized properties
+"mediatek,pull-up-adv" and "mediatek,pull-down-adv" to specify bias-pull
+setting for pins with 2 pull resistors.
+This introduce in-compatibility in device tree and increase porting
+effort to MediaTek's customer that had already used PINCTRL_MTK version.
+Besides, if customers are not aware of this change and still write devicetree
+for PINCTRL_MTK version, they may encounter runtime failure with pinctrl and
+spent time to debug.
+
+This patch adds backward compatible to previous MediaTek's bias-pull usage
+so that Mediatek's customer need not use a new devicetree property name.
+The rationale is that: changing driver implementation had better leave
+interface unchanged.
+
+Signed-off-by: Light Hsieh <light.hsieh@mediatek.com>
+Link: https://lore.kernel.org/r/1579675994-7001-5-git-send-email-light.hsieh@mediatek.com
+Acked-by: Sean Wang <sean.wang@kernel.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt6765.c     |   6 +-
+ drivers/pinctrl/mediatek/pinctrl-mt8183.c     |   6 +-
+ .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  | 221 ++++++++++++++++++
+ .../pinctrl/mediatek/pinctrl-mtk-common-v2.h  |  11 +
+ drivers/pinctrl/mediatek/pinctrl-paris.c      |  49 ++--
+ 5 files changed, 265 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+index 7fae397fe27c1..905dae8c3fd86 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+@@ -1072,10 +1072,8 @@ static const struct mtk_pin_soc mt6765_data = {
+       .gpio_m = 0,
+       .base_names = mt6765_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
+-      .bias_disable_set = mtk_pinconf_bias_disable_set,
+-      .bias_disable_get = mtk_pinconf_bias_disable_get,
+-      .bias_set = mtk_pinconf_bias_set,
+-      .bias_get = mtk_pinconf_bias_get,
++      .bias_set_combo = mtk_pinconf_bias_set_combo,
++      .bias_get_combo = mtk_pinconf_bias_get_combo,
+       .drive_set = mtk_pinconf_drive_set_raw,
+       .drive_get = mtk_pinconf_drive_get_raw,
+       .adv_pull_get = mtk_pinconf_adv_pull_get,
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8183.c b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
+index 4eca81864a965..60318339b6183 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mt8183.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
+@@ -556,10 +556,8 @@ static const struct mtk_pin_soc mt8183_data = {
+       .gpio_m = 0,
+       .base_names = mt8183_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt8183_pinctrl_register_base_names),
+-      .bias_disable_set = mtk_pinconf_bias_disable_set_rev1,
+-      .bias_disable_get = mtk_pinconf_bias_disable_get_rev1,
+-      .bias_set = mtk_pinconf_bias_set_rev1,
+-      .bias_get = mtk_pinconf_bias_get_rev1,
++      .bias_set_combo = mtk_pinconf_bias_set_combo,
++      .bias_get_combo = mtk_pinconf_bias_get_combo,
+       .drive_set = mtk_pinconf_drive_set_rev1,
+       .drive_get = mtk_pinconf_drive_get_rev1,
+       .adv_pull_get = mtk_pinconf_adv_pull_get,
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+index fb87feec7bd3f..634d652aed671 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+@@ -6,6 +6,7 @@
+  *
+  */
++#include <dt-bindings/pinctrl/mt65xx.h>
+ #include <linux/device.h>
+ #include <linux/err.h>
+ #include <linux/gpio/driver.h>
+@@ -521,6 +522,226 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
+       return 0;
+ }
++/* Combo for the following pull register type:
++ * 1. PU + PD
++ * 2. PULLSEL + PULLEN
++ * 3. PUPD + R0 + R1
++ */
++static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 pullup, u32 arg)
++{
++      int err, pu, pd;
++
++      if (arg == MTK_DISABLE) {
++              pu = 0;
++              pd = 0;
++      } else if ((arg == MTK_ENABLE) && pullup) {
++              pu = 1;
++              pd = 0;
++      } else if ((arg == MTK_ENABLE) && !pullup) {
++              pu = 0;
++              pd = 1;
++      } else {
++              err = -EINVAL;
++              goto out;
++      }
++
++      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu);
++      if (err)
++              goto out;
++
++      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd);
++
++out:
++      return err;
++}
++
++static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 pullup, u32 arg)
++{
++      int err, enable;
++
++      if (arg == MTK_DISABLE)
++              enable = 0;
++      else if (arg == MTK_ENABLE)
++              enable = 1;
++      else {
++              err = -EINVAL;
++              goto out;
++      }
++
++      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
++      if (err)
++              goto out;
++
++      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
++
++out:
++      return err;
++}
++
++static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 pullup, u32 arg)
++{
++      int err, r0, r1;
++
++      if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) {
++              pullup = 0;
++              r0 = 0;
++              r1 = 0;
++      } else if (arg == MTK_PUPD_SET_R1R0_01) {
++              r0 = 1;
++              r1 = 0;
++      } else if (arg == MTK_PUPD_SET_R1R0_10) {
++              r0 = 0;
++              r1 = 1;
++      } else if (arg == MTK_PUPD_SET_R1R0_11) {
++              r0 = 1;
++              r1 = 1;
++      } else {
++              err = -EINVAL;
++              goto out;
++      }
++
++      /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
++      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, !pullup);
++      if (err)
++              goto out;
++
++      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, r0);
++      if (err)
++              goto out;
++
++      err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, r1);
++
++out:
++      return err;
++}
++
++static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 *pullup, u32 *enable)
++{
++      int err, pu, pd;
++
++      err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu);
++      if (err)
++              goto out;
++
++      err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd);
++      if (err)
++              goto out;
++
++      if (pu == 0 && pd == 0) {
++              *pullup = 0;
++              *enable = MTK_DISABLE;
++      } else if (pu == 1 && pd == 0) {
++              *pullup = 1;
++              *enable = MTK_ENABLE;
++      } else if (pu == 0 && pd == 1) {
++              *pullup = 0;
++              *enable = MTK_ENABLE;
++      } else
++              err = -EINVAL;
++
++out:
++      return err;
++}
++
++static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 *pullup, u32 *enable)
++{
++      int err;
++
++      err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup);
++      if (err)
++              goto out;
++
++      err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable);
++
++out:
++      return err;
++}
++
++static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 *pullup, u32 *enable)
++{
++      int err, r0, r1;
++
++      err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, pullup);
++      if (err)
++              goto out;
++      /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
++      *pullup = !(*pullup);
++
++      err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &r0);
++      if (err)
++              goto out;
++
++      err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &r1);
++      if (err)
++              goto out;
++
++      if ((r1 == 0) && (r0 == 0))
++              *enable = MTK_PUPD_SET_R1R0_00;
++      else if ((r1 == 0) && (r0 == 1))
++              *enable = MTK_PUPD_SET_R1R0_01;
++      else if ((r1 == 1) && (r0 == 0))
++              *enable = MTK_PUPD_SET_R1R0_10;
++      else if ((r1 == 1) && (r0 == 1))
++              *enable = MTK_PUPD_SET_R1R0_11;
++      else
++              err = -EINVAL;
++
++out:
++      return err;
++}
++
++int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 pullup, u32 arg)
++{
++      int err;
++
++      err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
++      if (!err)
++              goto out;
++
++      err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg);
++      if (!err)
++              goto out;
++
++      err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
++
++out:
++      return err;
++}
++
++int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
++                            const struct mtk_pin_desc *desc,
++                            u32 *pullup, u32 *enable)
++{
++      int err;
++
++      err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
++      if (!err)
++              goto out;
++
++      err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable);
++      if (!err)
++              goto out;
++
++      err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
++
++out:
++      return err;
++}
++
+ /* Revision 0 */
+ int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
+                         const struct mtk_pin_desc *desc, u32 arg)
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+index 75d0e0712c03f..27df087363960 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+@@ -216,6 +216,11 @@ struct mtk_pin_soc {
+       int (*bias_get)(struct mtk_pinctrl *hw,
+                       const struct mtk_pin_desc *desc, bool pullup, int *res);
++      int (*bias_set_combo)(struct mtk_pinctrl *hw,
++                      const struct mtk_pin_desc *desc, u32 pullup, u32 arg);
++      int (*bias_get_combo)(struct mtk_pinctrl *hw,
++                      const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg);
++
+       int (*drive_set)(struct mtk_pinctrl *hw,
+                        const struct mtk_pin_desc *desc, u32 arg);
+       int (*drive_get)(struct mtk_pinctrl *hw,
+@@ -277,6 +282,12 @@ int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
+ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
+                             const struct mtk_pin_desc *desc, bool pullup,
+                             int *res);
++int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
++                              const struct mtk_pin_desc *desc,
++                              u32 pullup, u32 enable);
++int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
++                            const struct mtk_pin_desc *desc,
++                            u32 *pullup, u32 *enable);
+ int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
+                         const struct mtk_pin_desc *desc, u32 arg);
+diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
+index 9bd62c22128f2..18706c46d46ba 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
++++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
+@@ -78,7 +78,7 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+ {
+       struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+       u32 param = pinconf_to_config_param(*config);
+-      int err, reg, ret = 1;
++      int pullup, err, reg, ret = 1;
+       const struct mtk_pin_desc *desc;
+       if (pin >= hw->soc->npins) {
+@@ -89,22 +89,31 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+       switch (param) {
+       case PIN_CONFIG_BIAS_DISABLE:
+-              if (hw->soc->bias_disable_get)
+-                      err = hw->soc->bias_disable_get(hw, desc, &ret);
+-              else
+-                      err = -ENOTSUPP;
+-              break;
+       case PIN_CONFIG_BIAS_PULL_UP:
+-              if (hw->soc->bias_get)
+-                      err = hw->soc->bias_get(hw, desc, 1, &ret);
+-              else
+-                      err = -ENOTSUPP;
+-              break;
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+-              if (hw->soc->bias_get)
+-                      err = hw->soc->bias_get(hw, desc, 0, &ret);
+-              else
++              if (hw->soc->bias_get_combo) {
++                      err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
++                      if (err)
++                              goto out;
++                      if (param == PIN_CONFIG_BIAS_DISABLE) {
++                              if (ret == MTK_PUPD_SET_R1R0_00)
++                                      ret = MTK_DISABLE;
++                      } else if (param == PIN_CONFIG_BIAS_PULL_UP) {
++                              /* When desire to get pull-up value, return
++                               *  error if current setting is pull-down
++                               */
++                              if (!pullup)
++                                      err = -EINVAL;
++                      } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) {
++                              /* When desire to get pull-down value, return
++                               *  error if current setting is pull-up
++                               */
++                              if (pullup)
++                                      err = -EINVAL;
++                      }
++              } else {
+                       err = -ENOTSUPP;
++              }
+               break;
+       case PIN_CONFIG_SLEW_RATE:
+               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
+@@ -195,20 +204,20 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+       switch ((u32)param) {
+       case PIN_CONFIG_BIAS_DISABLE:
+-              if (hw->soc->bias_disable_set)
+-                      err = hw->soc->bias_disable_set(hw, desc);
++              if (hw->soc->bias_set_combo)
++                      err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE);
+               else
+                       err = -ENOTSUPP;
+               break;
+       case PIN_CONFIG_BIAS_PULL_UP:
+-              if (hw->soc->bias_set)
+-                      err = hw->soc->bias_set(hw, desc, 1);
++              if (hw->soc->bias_set_combo)
++                      err = hw->soc->bias_set_combo(hw, desc, 1, arg);
+               else
+                       err = -ENOTSUPP;
+               break;
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+-              if (hw->soc->bias_set)
+-                      err = hw->soc->bias_set(hw, desc, 0);
++              if (hw->soc->bias_set_combo)
++                      err = hw->soc->bias_set_combo(hw, desc, 0, arg);
+               else
+                       err = -ENOTSUPP;
+               break;
+-- 
+2.43.0
+
diff --git a/queue-5.4/pinctrl-mediatek-check-gpio-pin-number-and-use-binar.patch b/queue-5.4/pinctrl-mediatek-check-gpio-pin-number-and-use-binar.patch
new file mode 100644 (file)
index 0000000..181a754
--- /dev/null
@@ -0,0 +1,182 @@
+From 822820bc9097eb3d1cc2ded1b176f8cfcb81af29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jan 2020 14:53:09 +0800
+Subject: pinctrl: mediatek: Check gpio pin number and use binary search in
+ mtk_hw_pin_field_lookup()
+
+From: Light Hsieh <light.hsieh@mediatek.com>
+
+[ Upstream commit 3de7deefce693bb9783bca4cb42a81653ebec4e9 ]
+
+1. Check if gpio pin number is in valid range to prevent from get invalid
+   pointer 'desc' in the following code:
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+
+2. Improve  mtk_hw_pin_field_lookup()
+2.1 Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
+     search.
+2.2 Correct message after the following check fail:
+    if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
+               rc = &hw->soc->reg_cal[field];
+    The original message is:
+       "Not support field %d for pin %d (%s)\n"
+    However, the check is on soc chip level, not on pin level yet.
+    So the message is corrected as:
+       "Not support field %d for this soc\n"
+
+Signed-off-by: Light Hsieh <light.hsieh@mediatek.com>
+Link: https://lore.kernel.org/r/1579675994-7001-1-git-send-email-light.hsieh@mediatek.com
+Acked-by: Sean Wang <sean.wang@kernel.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  | 27 ++++++++++++++-----
+ drivers/pinctrl/mediatek/pinctrl-paris.c      | 25 +++++++++++++++++
+ 2 files changed, 46 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+index c3e6f3c1b4743..2795d0fd0f5bd 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+@@ -68,32 +68,44 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
+ {
+       const struct mtk_pin_field_calc *c, *e;
+       const struct mtk_pin_reg_calc *rc;
++      int start = 0, end, check;
++      bool found = false;
+       u32 bits;
+       if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
+               rc = &hw->soc->reg_cal[field];
+       } else {
+               dev_dbg(hw->dev,
+-                      "Not support field %d for pin %d (%s)\n",
+-                      field, desc->number, desc->name);
++                      "Not support field %d for this soc\n", field);
+               return -ENOTSUPP;
+       }
++      end = rc->nranges - 1;
+       c = rc->range;
+       e = c + rc->nranges;
+-      while (c < e) {
+-              if (desc->number >= c->s_pin && desc->number <= c->e_pin)
++      while (start <= end) {
++              check = (start + end) >> 1;
++              if (desc->number >= rc->range[check].s_pin
++               && desc->number <= rc->range[check].e_pin) {
++                      found = true;
++                      break;
++              } else if (start == end)
+                       break;
+-              c++;
++              else if (desc->number < rc->range[check].s_pin)
++                      end = check - 1;
++              else
++                      start = check + 1;
+       }
+-      if (c >= e) {
++      if (!found) {
+               dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
+                       field, desc->number, desc->name);
+               return -ENOTSUPP;
+       }
++      c = rc->range + check;
++
+       if (c->i_base > hw->nbase - 1) {
+               dev_err(hw->dev,
+                       "Invalid base for field %d for pin = %d (%s)\n",
+@@ -182,6 +194,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
+       if (err)
+               return err;
++      if (value < 0 || value > pf.mask)
++              return -EINVAL;
++
+       if (!pf.next)
+               mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
+                       (value & pf.mask) << pf.bitpos);
+diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
+index 31449514a8c0c..93fa44504bdd7 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
++++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
+@@ -81,6 +81,8 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+       int val, val2, err, reg, ret = 1;
+       const struct mtk_pin_desc *desc;
++      if (pin >= hw->soc->npins)
++              return -EINVAL;
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+       switch (param) {
+@@ -205,6 +207,10 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+       int err = 0;
+       u32 reg;
++      if (pin >= hw->soc->npins) {
++              err = -EINVAL;
++              goto err;
++      }
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+       switch ((u32)param) {
+@@ -690,6 +696,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
+       const struct mtk_pin_desc *desc;
+       int value, err;
++      if (gpio > hw->soc->npins)
++              return -EINVAL;
++
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+       err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
+@@ -705,6 +714,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
+       const struct mtk_pin_desc *desc;
+       int value, err;
++      if (gpio > hw->soc->npins)
++              return -EINVAL;
++
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+       err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
+@@ -719,6 +731,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
+       struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+       const struct mtk_pin_desc *desc;
++      if (gpio > hw->soc->npins)
++              return;
++
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+       mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
+@@ -726,12 +741,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
+ static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
+ {
++      struct mtk_pinctrl *hw = gpiochip_get_data(chip);
++
++      if (gpio > hw->soc->npins)
++              return -EINVAL;
++
+       return pinctrl_gpio_direction_input(chip->base + gpio);
+ }
+ static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
+                                    int value)
+ {
++      struct mtk_pinctrl *hw = gpiochip_get_data(chip);
++
++      if (gpio > hw->soc->npins)
++              return -EINVAL;
++
+       mtk_gpio_set(chip, gpio, value);
+       return pinctrl_gpio_direction_output(chip->base + gpio);
+-- 
+2.43.0
+
diff --git a/queue-5.4/pinctrl-mediatek-paris-fix-pin_config_bias_-readback.patch b/queue-5.4/pinctrl-mediatek-paris-fix-pin_config_bias_-readback.patch
new file mode 100644 (file)
index 0000000..7e1d7e5
--- /dev/null
@@ -0,0 +1,61 @@
+From 36586b7db2b322956f65ad40dcd56b3a2d58ab73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Mar 2022 18:09:47 +0800
+Subject: pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_* readback
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit 3e8c6bc608480010f360c4a59578d7841726137d ]
+
+When reading back pin bias settings, if the pin is not in the
+corresponding bias state, the function should return -EINVAL.
+
+Fix this in the mediatek-paris pinctrl library so that the read back
+state is not littered with bogus a "input bias disabled" combined with
+"pull up" or "pull down" states.
+
+Fixes: 805250982bb5 ("pinctrl: mediatek: add pinctrl-paris that implements the vendor dt-bindings")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20220308100956.2750295-3-wenst@chromium.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-paris.c | 16 ++++++----------
+ 1 file changed, 6 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
+index b613dda50151b..cb4979cefdd09 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
++++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
+@@ -95,20 +95,16 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+                       err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
+                       if (err)
+                               goto out;
++                      if (ret == MTK_PUPD_SET_R1R0_00)
++                              ret = MTK_DISABLE;
+                       if (param == PIN_CONFIG_BIAS_DISABLE) {
+-                              if (ret == MTK_PUPD_SET_R1R0_00)
+-                                      ret = MTK_DISABLE;
++                              if (ret != MTK_DISABLE)
++                                      err = -EINVAL;
+                       } else if (param == PIN_CONFIG_BIAS_PULL_UP) {
+-                              /* When desire to get pull-up value, return
+-                               *  error if current setting is pull-down
+-                               */
+-                              if (!pullup)
++                              if (!pullup || ret == MTK_DISABLE)
+                                       err = -EINVAL;
+                       } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) {
+-                              /* When desire to get pull-down value, return
+-                               *  error if current setting is pull-up
+-                               */
+-                              if (pullup)
++                              if (pullup || ret == MTK_DISABLE)
+                                       err = -EINVAL;
+                       }
+               } else {
+-- 
+2.43.0
+
diff --git a/queue-5.4/pinctrl-mediatek-paris-rework-mtk_pinconf_-get-set-s.patch b/queue-5.4/pinctrl-mediatek-paris-rework-mtk_pinconf_-get-set-s.patch
new file mode 100644 (file)
index 0000000..4c1dfcb
--- /dev/null
@@ -0,0 +1,301 @@
+From 36dd759c1cc914d3a38fe17930058d7df24d6f4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Mar 2022 18:09:52 +0800
+Subject: pinctrl: mediatek: paris: Rework mtk_pinconf_{get,set} switch/case
+ logic
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit 9b780fa1ff14663c2e0f07ad098b96b8337f27a4 ]
+
+The current code deals with optional features by testing for the
+function pointers and returning -ENOTSUPP if it is not valid. This is
+done for multiple pin config settings and results in the code that
+handles the supporting cases to get indented by one level. This is
+aggrevated by the fact that some features require another level of
+conditionals.
+
+Instead of assigning the same error code in all unsupported optional
+feature cases, simply have that error code as the default, and break
+out of the switch/case block whenever a feature is unsupported, or an
+error is returned. This reduces indentation by one level for the useful
+code.
+
+Also replace the goto statements with break statements. The result is
+the same, as the gotos simply exit the switch/case block, which can
+also be achieved with a break statement. With the latter the intent
+is clear and easier to understand.
+
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://lore.kernel.org/r/20220308100956.2750295-8-wenst@chromium.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-paris.c | 144 ++++++++++-------------
+ 1 file changed, 61 insertions(+), 83 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
+index cb4979cefdd09..f568df4f0f643 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
++++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
+@@ -78,37 +78,34 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+ {
+       struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+       u32 param = pinconf_to_config_param(*config);
+-      int pullup, err, reg, ret = 1;
++      int pullup, reg, err = -ENOTSUPP, ret = 1;
+       const struct mtk_pin_desc *desc;
+-      if (pin >= hw->soc->npins) {
+-              err = -EINVAL;
+-              goto out;
+-      }
++      if (pin >= hw->soc->npins)
++              return -EINVAL;
++
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+       switch (param) {
+       case PIN_CONFIG_BIAS_DISABLE:
+       case PIN_CONFIG_BIAS_PULL_UP:
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+-              if (hw->soc->bias_get_combo) {
+-                      err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
+-                      if (err)
+-                              goto out;
+-                      if (ret == MTK_PUPD_SET_R1R0_00)
+-                              ret = MTK_DISABLE;
+-                      if (param == PIN_CONFIG_BIAS_DISABLE) {
+-                              if (ret != MTK_DISABLE)
+-                                      err = -EINVAL;
+-                      } else if (param == PIN_CONFIG_BIAS_PULL_UP) {
+-                              if (!pullup || ret == MTK_DISABLE)
+-                                      err = -EINVAL;
+-                      } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) {
+-                              if (pullup || ret == MTK_DISABLE)
+-                                      err = -EINVAL;
+-                      }
+-              } else {
+-                      err = -ENOTSUPP;
++              if (!hw->soc->bias_get_combo)
++                      break;
++              err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
++              if (err)
++                      break;
++              if (ret == MTK_PUPD_SET_R1R0_00)
++                      ret = MTK_DISABLE;
++              if (param == PIN_CONFIG_BIAS_DISABLE) {
++                      if (ret != MTK_DISABLE)
++                              err = -EINVAL;
++              } else if (param == PIN_CONFIG_BIAS_PULL_UP) {
++                      if (!pullup || ret == MTK_DISABLE)
++                              err = -EINVAL;
++              } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) {
++                      if (pullup || ret == MTK_DISABLE)
++                              err = -EINVAL;
+               }
+               break;
+       case PIN_CONFIG_SLEW_RATE:
+@@ -118,7 +115,7 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+       case PIN_CONFIG_OUTPUT_ENABLE:
+               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
+               if (err)
+-                      goto out;
++                      break;
+               /*     CONFIG     Current direction return value
+                * -------------  ----------------- ----------------------
+                * OUTPUT_ENABLE       output       1 (= HW value)
+@@ -133,23 +130,21 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+       case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
+               if (err)
+-                      goto out;
++                      break;
+               /* return error when in output mode
+                * because schmitt trigger only work in input mode
+                */
+               if (ret) {
+                       err = -EINVAL;
+-                      goto out;
++                      break;
+               }
+               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret);
+-
+               break;
+       case PIN_CONFIG_DRIVE_STRENGTH:
+-              if (hw->soc->drive_get)
+-                      err = hw->soc->drive_get(hw, desc, &ret);
+-              else
+-                      err = -ENOTSUPP;
++              if (!hw->soc->drive_get)
++                      break;
++              err = hw->soc->drive_get(hw, desc, &ret);
+               break;
+       case MTK_PIN_CONFIG_TDSEL:
+       case MTK_PIN_CONFIG_RDSEL:
+@@ -159,23 +154,18 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+               break;
+       case MTK_PIN_CONFIG_PU_ADV:
+       case MTK_PIN_CONFIG_PD_ADV:
+-              if (hw->soc->adv_pull_get) {
+-                      pullup = param == MTK_PIN_CONFIG_PU_ADV;
+-                      err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
+-              } else
+-                      err = -ENOTSUPP;
++              if (!hw->soc->adv_pull_get)
++                      break;
++              pullup = param == MTK_PIN_CONFIG_PU_ADV;
++              err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
+               break;
+       case MTK_PIN_CONFIG_DRV_ADV:
+-              if (hw->soc->adv_drive_get)
+-                      err = hw->soc->adv_drive_get(hw, desc, &ret);
+-              else
+-                      err = -ENOTSUPP;
++              if (!hw->soc->adv_drive_get)
++                      break;
++              err = hw->soc->adv_drive_get(hw, desc, &ret);
+               break;
+-      default:
+-              err = -ENOTSUPP;
+       }
+-out:
+       if (!err)
+               *config = pinconf_to_config_packed(param, ret);
+@@ -187,33 +177,29 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+ {
+       struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+       const struct mtk_pin_desc *desc;
+-      int err = 0;
++      int err = -ENOTSUPP;
+       u32 reg;
+-      if (pin >= hw->soc->npins) {
+-              err = -EINVAL;
+-              goto err;
+-      }
++      if (pin >= hw->soc->npins)
++              return -EINVAL;
++
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+       switch ((u32)param) {
+       case PIN_CONFIG_BIAS_DISABLE:
+-              if (hw->soc->bias_set_combo)
+-                      err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE);
+-              else
+-                      err = -ENOTSUPP;
++              if (!hw->soc->bias_set_combo)
++                      break;
++              err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE);
+               break;
+       case PIN_CONFIG_BIAS_PULL_UP:
+-              if (hw->soc->bias_set_combo)
+-                      err = hw->soc->bias_set_combo(hw, desc, 1, arg);
+-              else
+-                      err = -ENOTSUPP;
++              if (!hw->soc->bias_set_combo)
++                      break;
++              err = hw->soc->bias_set_combo(hw, desc, 1, arg);
+               break;
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+-              if (hw->soc->bias_set_combo)
+-                      err = hw->soc->bias_set_combo(hw, desc, 0, arg);
+-              else
+-                      err = -ENOTSUPP;
++              if (!hw->soc->bias_set_combo)
++                      break;
++              err = hw->soc->bias_set_combo(hw, desc, 0, arg);
+               break;
+       case PIN_CONFIG_OUTPUT_ENABLE:
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
+@@ -222,7 +208,7 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+                *  does not have SMT control
+                */
+               if (err != -ENOTSUPP)
+-                      goto err;
++                      break;
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+                                      MTK_OUTPUT);
+@@ -231,7 +217,7 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+               /* regard all non-zero value as enable */
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg);
+               if (err)
+-                      goto err;
++                      break;
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+                                      MTK_INPUT);
+@@ -244,7 +230,7 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+                                      MTK_OUTPUT);
+               if (err)
+-                      goto err;
++                      break;
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO,
+                                      arg);
+@@ -256,15 +242,14 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+                */
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !arg);
+               if (err)
+-                      goto err;
++                      break;
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!arg);
+               break;
+       case PIN_CONFIG_DRIVE_STRENGTH:
+-              if (hw->soc->drive_set)
+-                      err = hw->soc->drive_set(hw, desc, arg);
+-              else
+-                      err = -ENOTSUPP;
++              if (!hw->soc->drive_set)
++                      break;
++              err = hw->soc->drive_set(hw, desc, arg);
+               break;
+       case MTK_PIN_CONFIG_TDSEL:
+       case MTK_PIN_CONFIG_RDSEL:
+@@ -274,26 +259,19 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+               break;
+       case MTK_PIN_CONFIG_PU_ADV:
+       case MTK_PIN_CONFIG_PD_ADV:
+-              if (hw->soc->adv_pull_set) {
+-                      bool pullup;
+-
+-                      pullup = param == MTK_PIN_CONFIG_PU_ADV;
+-                      err = hw->soc->adv_pull_set(hw, desc, pullup,
+-                                                  arg);
+-              } else
+-                      err = -ENOTSUPP;
++              if (!hw->soc->adv_pull_set)
++                      break;
++              err = hw->soc->adv_pull_set(hw, desc,
++                                          (param == MTK_PIN_CONFIG_PU_ADV),
++                                          arg);
+               break;
+       case MTK_PIN_CONFIG_DRV_ADV:
+-              if (hw->soc->adv_drive_set)
+-                      err = hw->soc->adv_drive_set(hw, desc, arg);
+-              else
+-                      err = -ENOTSUPP;
++              if (!hw->soc->adv_drive_set)
++                      break;
++              err = hw->soc->adv_drive_set(hw, desc, arg);
+               break;
+-      default:
+-              err = -ENOTSUPP;
+       }
+-err:
+       return err;
+ }
+-- 
+2.43.0
+
diff --git a/queue-5.4/pinctrl-mediatek-paris-rework-support-for-pin_config.patch b/queue-5.4/pinctrl-mediatek-paris-rework-support-for-pin_config.patch
new file mode 100644 (file)
index 0000000..30d1758
--- /dev/null
@@ -0,0 +1,107 @@
+From 77229d1ecc9b133c4e9844e2d028d85180587974 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Mar 2024 17:13:34 +0800
+Subject: pinctrl: mediatek: paris: Rework support for
+ PIN_CONFIG_{INPUT,OUTPUT}_ENABLE
+
+From: Chen-Yu Tsai <wenst@chromium.org>
+
+[ Upstream commit c5d3b64c568a344e998830e0e94a7c04e372f89b ]
+
+There is a misinterpretation of some of the PIN_CONFIG_* options in this
+driver library. PIN_CONFIG_OUTPUT_ENABLE should refer to a buffer or
+switch in the output direction of the electrical path. The MediaTek
+hardware does not have such a thing. The driver incorrectly maps this
+option to the GPIO function's direction.
+
+Likewise, PIN_CONFIG_INPUT_ENABLE should refer to a buffer or switch in
+the input direction. The hardware does have such a mechanism, and is
+mapped to the IES bit. The driver however sets the direction in addition
+to the IES bit, which is incorrect. On readback, the IES bit isn't even
+considered.
+
+Ironically, the driver does not support readback for PIN_CONFIG_OUTPUT,
+while its readback of PIN_CONFIG_{INPUT,OUTPUT}_ENABLE is what it should
+be doing for PIN_CONFIG_OUTPUT.
+
+Rework support for these three options, so that PIN_CONFIG_OUTPUT_ENABLE
+is completely removed, PIN_CONFIG_INPUT_ENABLE is only linked to the IES
+bit, and PIN_CONFIG_OUTPUT is linked to the GPIO function's direction
+and output level.
+
+Fixes: 805250982bb5 ("pinctrl: mediatek: add pinctrl-paris that implements the vendor dt-bindings")
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Message-ID: <20240327091336.3434141-3-wenst@chromium.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-paris.c | 38 +++++++-----------------
+ 1 file changed, 11 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
+index f568df4f0f643..31a4d464211cc 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
++++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
+@@ -112,20 +112,21 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
+               break;
+       case PIN_CONFIG_INPUT_ENABLE:
+-      case PIN_CONFIG_OUTPUT_ENABLE:
++              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_IES, &ret);
++              if (!ret)
++                      err = -EINVAL;
++              break;
++      case PIN_CONFIG_OUTPUT:
+               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
+               if (err)
+                       break;
+-              /*     CONFIG     Current direction return value
+-               * -------------  ----------------- ----------------------
+-               * OUTPUT_ENABLE       output       1 (= HW value)
+-               *                     input        0 (= HW value)
+-               * INPUT_ENABLE        output       0 (= reverse HW value)
+-               *                     input        1 (= reverse HW value)
+-               */
+-              if (param == PIN_CONFIG_INPUT_ENABLE)
+-                      ret = !ret;
++              if (!ret) {
++                      err = -EINVAL;
++                      break;
++              }
++
++              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DO, &ret);
+               break;
+       case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
+@@ -201,26 +202,9 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+                       break;
+               err = hw->soc->bias_set_combo(hw, desc, 0, arg);
+               break;
+-      case PIN_CONFIG_OUTPUT_ENABLE:
+-              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
+-                                     MTK_DISABLE);
+-              /* Keep set direction to consider the case that a GPIO pin
+-               *  does not have SMT control
+-               */
+-              if (err != -ENOTSUPP)
+-                      break;
+-
+-              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+-                                     MTK_OUTPUT);
+-              break;
+       case PIN_CONFIG_INPUT_ENABLE:
+               /* regard all non-zero value as enable */
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg);
+-              if (err)
+-                      break;
+-
+-              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+-                                     MTK_INPUT);
+               break;
+       case PIN_CONFIG_SLEW_RATE:
+               /* regard all non-zero value as enable */
+-- 
+2.43.0
+
diff --git a/queue-5.4/pinctrl-mediatek-refine-mtk_pinconf_get-and-mtk_pinc.patch b/queue-5.4/pinctrl-mediatek-refine-mtk_pinconf_get-and-mtk_pinc.patch
new file mode 100644 (file)
index 0000000..3ab42a2
--- /dev/null
@@ -0,0 +1,354 @@
+From f72dddfd8d82d330712c052857afde1ec483b663 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jan 2020 14:53:11 +0800
+Subject: pinctrl: mediatek: Refine mtk_pinconf_get() and mtk_pinconf_set()
+
+From: Light Hsieh <light.hsieh@mediatek.com>
+
+[ Upstream commit 3599cc525486be6681640ff3083376c001264c61 ]
+
+1.Refine mtk_pinconf_get():
+  Use only one occurrence of return at end of this function.
+
+2.Refine mtk_pinconf_set():
+2.1 Use only one occurrence of return at end of this function.
+2.2 Modify case of PIN_CONFIG_INPUT_ENABLE -
+2.2.1
+    Regard all non-zero setting value as enable, instead of always enable.
+2.2.2
+    Remove check of ies_present flag and always invoke mtk_hw_set_value()
+    since mtk_hw_pin_field_lookup() invoked inside mtk_hw_set_value() has
+    the same effect of checking if ies control is supported.
+    [The rationale is that: available of a control is always checked
+     in mtk_hw_pin_field_lookup() and no need to add ies_present flag
+     specially for ies control.]
+2.3 Simply code logic for case of PIN_CONFIG_INPUT_SCHMITT.
+2.4 Add case for PIN_CONFIG_INPUT_SCHMITT_ENABLE and process it with the
+    same code for case of PIN_CONFIG_INPUT_SCHMITT.
+
+Signed-off-by: Light Hsieh <light.hsieh@mediatek.com>
+Link: https://lore.kernel.org/r/1579675994-7001-3-git-send-email-light.hsieh@mediatek.com
+Acked-by: Sean Wang <sean.wang@kernel.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt6765.c |   1 -
+ drivers/pinctrl/mediatek/pinctrl-mt8183.c |   1 -
+ drivers/pinctrl/mediatek/pinctrl-paris.c  | 171 ++++++++--------------
+ 3 files changed, 65 insertions(+), 108 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+index 12122646bbc28..7fae397fe27c1 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+@@ -1070,7 +1070,6 @@ static const struct mtk_pin_soc mt6765_data = {
+       .ngrps = ARRAY_SIZE(mtk_pins_mt6765),
+       .eint_hw = &mt6765_eint_hw,
+       .gpio_m = 0,
+-      .ies_present = true,
+       .base_names = mt6765_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
+       .bias_disable_set = mtk_pinconf_bias_disable_set,
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8183.c b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
+index 9a74d5025be64..4eca81864a965 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mt8183.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt8183.c
+@@ -554,7 +554,6 @@ static const struct mtk_pin_soc mt8183_data = {
+       .ngrps = ARRAY_SIZE(mtk_pins_mt8183),
+       .eint_hw = &mt8183_eint_hw,
+       .gpio_m = 0,
+-      .ies_present = true,
+       .base_names = mt8183_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt8183_pinctrl_register_base_names),
+       .bias_disable_set = mtk_pinconf_bias_disable_set_rev1,
+diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
+index 93fa44504bdd7..5ee49da18b3de 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
++++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
+@@ -81,37 +81,30 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+       int val, val2, err, reg, ret = 1;
+       const struct mtk_pin_desc *desc;
+-      if (pin >= hw->soc->npins)
+-              return -EINVAL;
++      if (pin >= hw->soc->npins) {
++              err = -EINVAL;
++              goto out;
++      }
+       desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
+       switch (param) {
+       case PIN_CONFIG_BIAS_DISABLE:
+-              if (hw->soc->bias_disable_get) {
++              if (hw->soc->bias_disable_get)
+                       err = hw->soc->bias_disable_get(hw, desc, &ret);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              else
++                      err = -ENOTSUPP;
+               break;
+       case PIN_CONFIG_BIAS_PULL_UP:
+-              if (hw->soc->bias_get) {
++              if (hw->soc->bias_get)
+                       err = hw->soc->bias_get(hw, desc, 1, &ret);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              else
++                      err = -ENOTSUPP;
+               break;
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+-              if (hw->soc->bias_get) {
++              if (hw->soc->bias_get)
+                       err = hw->soc->bias_get(hw, desc, 0, &ret);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              else
++                      err = -ENOTSUPP;
+               break;
+       case PIN_CONFIG_SLEW_RATE:
+               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);
+@@ -126,12 +119,16 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+       case PIN_CONFIG_OUTPUT_ENABLE:
+               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
+               if (err)
+-                      return err;
+-
+-              /* HW takes input mode as zero; output mode as non-zero */
+-              if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||
+-                  (!val && param == PIN_CONFIG_OUTPUT_ENABLE))
+-                      return -EINVAL;
++                      goto out;
++              /*     CONFIG     Current direction return value
++               * -------------  ----------------- ----------------------
++               * OUTPUT_ENABLE       output       1 (= HW value)
++               *                     input        0 (= HW value)
++               * INPUT_ENABLE        output       0 (= reverse HW value)
++               *                     input        1 (= reverse HW value)
++               */
++              if (param == PIN_CONFIG_INPUT_ENABLE)
++                      val = !val;
+               break;
+       case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+@@ -148,13 +145,10 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+               break;
+       case PIN_CONFIG_DRIVE_STRENGTH:
+-              if (hw->soc->drive_get) {
++              if (hw->soc->drive_get)
+                       err = hw->soc->drive_get(hw, desc, &ret);
+-                      if (err)
+-                              return err;
+-              } else {
++              else
+                       err = -ENOTSUPP;
+-              }
+               break;
+       case MTK_PIN_CONFIG_TDSEL:
+       case MTK_PIN_CONFIG_RDSEL:
+@@ -175,28 +169,24 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+                       pullup = param == MTK_PIN_CONFIG_PU_ADV;
+                       err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              } else
++                      err = -ENOTSUPP;
+               break;
+       case MTK_PIN_CONFIG_DRV_ADV:
+-              if (hw->soc->adv_drive_get) {
++              if (hw->soc->adv_drive_get)
+                       err = hw->soc->adv_drive_get(hw, desc, &ret);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              else
++                      err = -ENOTSUPP;
+               break;
+       default:
+-              return -ENOTSUPP;
++              err = -ENOTSUPP;
+       }
+-      *config = pinconf_to_config_packed(param, ret);
++out:
++      if (!err)
++              *config = pinconf_to_config_packed(param, ret);
+-      return 0;
++      return err;
+ }
+ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+@@ -215,60 +205,47 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+       switch ((u32)param) {
+       case PIN_CONFIG_BIAS_DISABLE:
+-              if (hw->soc->bias_disable_set) {
++              if (hw->soc->bias_disable_set)
+                       err = hw->soc->bias_disable_set(hw, desc);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              else
++                      err = -ENOTSUPP;
+               break;
+       case PIN_CONFIG_BIAS_PULL_UP:
+-              if (hw->soc->bias_set) {
++              if (hw->soc->bias_set)
+                       err = hw->soc->bias_set(hw, desc, 1);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              else
++                      err = -ENOTSUPP;
+               break;
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+-              if (hw->soc->bias_set) {
++              if (hw->soc->bias_set)
+                       err = hw->soc->bias_set(hw, desc, 0);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              else
++                      err = -ENOTSUPP;
+               break;
+       case PIN_CONFIG_OUTPUT_ENABLE:
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
+                                      MTK_DISABLE);
+-              if (err)
++              /* Keep set direction to consider the case that a GPIO pin
++               *  does not have SMT control
++               */
++              if (err != -ENOTSUPP)
+                       goto err;
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+                                      MTK_OUTPUT);
+-              if (err)
+-                      goto err;
+               break;
+       case PIN_CONFIG_INPUT_ENABLE:
+-              if (hw->soc->ies_present) {
+-                      mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES,
+-                                       MTK_ENABLE);
+-              }
++              /* regard all non-zero value as enable */
++              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg);
++              if (err)
++                      goto err;
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+                                      MTK_INPUT);
+-              if (err)
+-                      goto err;
+               break;
+       case PIN_CONFIG_SLEW_RATE:
+-              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR,
+-                                     arg);
+-              if (err)
+-                      goto err;
+-
++              /* regard all non-zero value as enable */
++              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, !!arg);
+               break;
+       case PIN_CONFIG_OUTPUT:
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+@@ -278,41 +255,29 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO,
+                                      arg);
+-              if (err)
+-                      goto err;
+               break;
++      case PIN_CONFIG_INPUT_SCHMITT:
+       case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+               /* arg = 1: Input mode & SMT enable ;
+                * arg = 0: Output mode & SMT disable
+                */
+-              arg = arg ? 2 : 1;
+-              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+-                                     arg & 1);
++              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !arg);
+               if (err)
+                       goto err;
+-              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
+-                                     !!(arg & 2));
+-              if (err)
+-                      goto err;
++              err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!arg);
+               break;
+       case PIN_CONFIG_DRIVE_STRENGTH:
+-              if (hw->soc->drive_set) {
++              if (hw->soc->drive_set)
+                       err = hw->soc->drive_set(hw, desc, arg);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              else
++                      err = -ENOTSUPP;
+               break;
+       case MTK_PIN_CONFIG_TDSEL:
+       case MTK_PIN_CONFIG_RDSEL:
+               reg = (param == MTK_PIN_CONFIG_TDSEL) ?
+                      PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
+-
+               err = mtk_hw_set_value(hw, desc, reg, arg);
+-              if (err)
+-                      goto err;
+               break;
+       case MTK_PIN_CONFIG_PU_ADV:
+       case MTK_PIN_CONFIG_PD_ADV:
+@@ -322,20 +287,14 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
+                       pullup = param == MTK_PIN_CONFIG_PU_ADV;
+                       err = hw->soc->adv_pull_set(hw, desc, pullup,
+                                                   arg);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              } else
++                      err = -ENOTSUPP;
+               break;
+       case MTK_PIN_CONFIG_DRV_ADV:
+-              if (hw->soc->adv_drive_set) {
++              if (hw->soc->adv_drive_set)
+                       err = hw->soc->adv_drive_set(hw, desc, arg);
+-                      if (err)
+-                              return err;
+-              } else {
+-                      return -ENOTSUPP;
+-              }
++              else
++                      err = -ENOTSUPP;
+               break;
+       default:
+               err = -ENOTSUPP;
+-- 
+2.43.0
+
diff --git a/queue-5.4/pinctrl-mediatek-refine-mtk_pinconf_get.patch b/queue-5.4/pinctrl-mediatek-refine-mtk_pinconf_get.patch
new file mode 100644 (file)
index 0000000..78b3281
--- /dev/null
@@ -0,0 +1,108 @@
+From 6593850b2a3d2f7608466c8f5a707f9f7b6a382a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jan 2020 14:53:12 +0800
+Subject: pinctrl: mediatek: Refine mtk_pinconf_get()
+
+From: Light Hsieh <light.hsieh@mediatek.com>
+
+[ Upstream commit 1bea6afbc84206cd939ae227cf81d6c824af6fd7 ]
+
+Correct cases for PIN_CONFIG_SLEW_RATE, PIN_CONFIG_INPUT_SCHMITT_ENABLE,
+and PIN_CONFIG_OUTPUT_ENABLE -
+Use variable ret to receive value in mtk_hw_get_value() (instead of
+variable val) since pinconf_to_config_packed() at end of this function
+use variable ret to pack config value.
+
+Signed-off-by: Light Hsieh <light.hsieh@mediatek.com>
+Link: https://lore.kernel.org/r/1579675994-7001-4-git-send-email-light.hsieh@mediatek.com
+Acked-by: Sean Wang <sean.wang@kernel.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-paris.c | 40 +++++++++---------------
+ 1 file changed, 15 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
+index 5ee49da18b3de..9bd62c22128f2 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
++++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
+@@ -78,7 +78,7 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+ {
+       struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+       u32 param = pinconf_to_config_param(*config);
+-      int val, val2, err, reg, ret = 1;
++      int err, reg, ret = 1;
+       const struct mtk_pin_desc *desc;
+       if (pin >= hw->soc->npins) {
+@@ -107,17 +107,11 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+                       err = -ENOTSUPP;
+               break;
+       case PIN_CONFIG_SLEW_RATE:
+-              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);
+-              if (err)
+-                      return err;
+-
+-              if (!val)
+-                      return -EINVAL;
+-
++              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
+               break;
+       case PIN_CONFIG_INPUT_ENABLE:
+       case PIN_CONFIG_OUTPUT_ENABLE:
+-              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
++              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
+               if (err)
+                       goto out;
+               /*     CONFIG     Current direction return value
+@@ -128,20 +122,22 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+                *                     input        1 (= reverse HW value)
+                */
+               if (param == PIN_CONFIG_INPUT_ENABLE)
+-                      val = !val;
++                      ret = !ret;
+               break;
+       case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+-              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
++              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
+               if (err)
+-                      return err;
+-
+-              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &val2);
+-              if (err)
+-                      return err;
++                      goto out;
++              /* return error when in output mode
++               * because schmitt trigger only work in input mode
++               */
++              if (ret) {
++                      err = -EINVAL;
++                      goto out;
++              }
+-              if (val || !val2)
+-                      return -EINVAL;
++              err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret);
+               break;
+       case PIN_CONFIG_DRIVE_STRENGTH:
+@@ -154,13 +150,7 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+       case MTK_PIN_CONFIG_RDSEL:
+               reg = (param == MTK_PIN_CONFIG_TDSEL) ?
+                      PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
+-
+-              err = mtk_hw_get_value(hw, desc, reg, &val);
+-              if (err)
+-                      return err;
+-
+-              ret = val;
+-
++              err = mtk_hw_get_value(hw, desc, reg, &ret);
+               break;
+       case MTK_PIN_CONFIG_PU_ADV:
+       case MTK_PIN_CONFIG_PD_ADV:
+-- 
+2.43.0
+
diff --git a/queue-5.4/pinctrl-mediatek-remove-shadow-variable-declaration.patch b/queue-5.4/pinctrl-mediatek-remove-shadow-variable-declaration.patch
new file mode 100644 (file)
index 0000000..c6ecb2e
--- /dev/null
@@ -0,0 +1,37 @@
+From b18ecdce0189e59f3d4c1492339485f7ba48b4ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Apr 2020 18:33:52 +0800
+Subject: pinctrl: mediatek: remove shadow variable declaration
+
+From: Light Hsieh <light.hsieh@mediatek.com>
+
+[ Upstream commit d1f7af4b4a11bcd85a18b383cb6fae1915916a83 ]
+
+Remove shadow declaration of variable 'pullup' in mtk_pinconf_get()
+
+Signed-off-by: Light Hsieh <light.hsieh@mediatek.com>
+Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
+Link: https://lore.kernel.org/r/1586255632-27528-1-git-send-email-light.hsieh@mediatek.com
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-paris.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
+index 18706c46d46ba..b613dda50151b 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
++++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
+@@ -164,8 +164,6 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
+       case MTK_PIN_CONFIG_PU_ADV:
+       case MTK_PIN_CONFIG_PD_ADV:
+               if (hw->soc->adv_pull_get) {
+-                      bool pullup;
+-
+                       pullup = param == MTK_PIN_CONFIG_PU_ADV;
+                       err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
+               } else
+-- 
+2.43.0
+
diff --git a/queue-5.4/pinctrl-mediatek-supporting-driving-setting-without-.patch b/queue-5.4/pinctrl-mediatek-supporting-driving-setting-without-.patch
new file mode 100644 (file)
index 0000000..d13be58
--- /dev/null
@@ -0,0 +1,97 @@
+From 449c685acd69dbff63f70943cbcb54b1694d9fc6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jan 2020 14:53:10 +0800
+Subject: pinctrl: mediatek: Supporting driving setting without mapping current
+ to register value
+
+From: Light Hsieh <light.hsieh@mediatek.com>
+
+[ Upstream commit 5f755e1f1efe5ca3b475b14169e6e85bf1411bb5 ]
+
+MediaTek's smartphone project actual usage does need to know current value
+(in mA) in procedure of finding the best driving setting.
+The steps in the procedure is like as follow:
+
+1. set driving setting field in setting register as 0, measure waveform,
+   perform test, and etc.
+2. set driving setting field in setting register as 1, measure waveform,
+   perform test, and etc.
+...
+n. set driving setting field in setting register as n-1, measure
+   waveform, perform test, and etc.
+Check the results of steps 1~n and adopt the setting that get best result.
+
+This procedure does need to know the mapping between current to register
+value.
+Therefore, setting driving without mapping current is more practical for
+MediaTek's smartphone usage.
+
+Signed-off-by: Light Hsieh <light.hsieh@mediatek.com>
+Link: https://lore.kernel.org/r/1579675994-7001-2-git-send-email-light.hsieh@mediatek.com
+Acked-by: Sean Wang <sean.wang@kernel.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Stable-dep-of: c5d3b64c568a ("pinctrl: mediatek: paris: Rework support for PIN_CONFIG_{INPUT,OUTPUT}_ENABLE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pinctrl/mediatek/pinctrl-mt6765.c        |  4 ++--
+ drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 12 ++++++++++++
+ drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h |  5 +++++
+ 3 files changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+index 32451e8693be7..12122646bbc28 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+@@ -1077,8 +1077,8 @@ static const struct mtk_pin_soc mt6765_data = {
+       .bias_disable_get = mtk_pinconf_bias_disable_get,
+       .bias_set = mtk_pinconf_bias_set,
+       .bias_get = mtk_pinconf_bias_get,
+-      .drive_set = mtk_pinconf_drive_set_rev1,
+-      .drive_get = mtk_pinconf_drive_get_rev1,
++      .drive_set = mtk_pinconf_drive_set_raw,
++      .drive_get = mtk_pinconf_drive_get_raw,
+       .adv_pull_get = mtk_pinconf_adv_pull_get,
+       .adv_pull_set = mtk_pinconf_adv_pull_set,
+ };
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+index 2795d0fd0f5bd..fb87feec7bd3f 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+@@ -612,6 +612,18 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
+       return 0;
+ }
++int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
++                             const struct mtk_pin_desc *desc, u32 arg)
++{
++      return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
++}
++
++int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
++                             const struct mtk_pin_desc *desc, int *val)
++{
++      return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
++}
++
+ int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
+                            const struct mtk_pin_desc *desc, bool pullup,
+                            u32 arg)
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+index 1b7da42aa1d53..75d0e0712c03f 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+@@ -288,6 +288,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
+ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
+                              const struct mtk_pin_desc *desc, int *val);
++int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw,
++                             const struct mtk_pin_desc *desc, u32 arg);
++int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw,
++                             const struct mtk_pin_desc *desc, int *val);
++
+ int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
+                            const struct mtk_pin_desc *desc, bool pullup,
+                            u32 arg);
+-- 
+2.43.0
+
diff --git a/queue-5.4/power-rt9455-hide-unused-rt9455_boost_voltage_values.patch b/queue-5.4/power-rt9455-hide-unused-rt9455_boost_voltage_values.patch
new file mode 100644 (file)
index 0000000..1fe552a
--- /dev/null
@@ -0,0 +1,48 @@
+From 60ad49c7cfa3457f18d7483f11f7212df5fc74bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Apr 2024 10:06:27 +0200
+Subject: power: rt9455: hide unused rt9455_boost_voltage_values
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 452d8950db3e839aba1bb13bc5378f4bac11fa04 ]
+
+The rt9455_boost_voltage_values[] array is only used when USB PHY
+support is enabled, causing a W=1 warning otherwise:
+
+drivers/power/supply/rt9455_charger.c:200:18: error: 'rt9455_boost_voltage_values' defined but not used [-Werror=unused-const-variable=]
+
+Enclose the definition in the same #ifdef as the references to it.
+
+Fixes: e86d69dd786e ("power_supply: Add support for Richtek RT9455 battery charger")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20240403080702.3509288-10-arnd@kernel.org
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/rt9455_charger.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/power/supply/rt9455_charger.c b/drivers/power/supply/rt9455_charger.c
+index 29161ae902456..5864b31426b8f 100644
+--- a/drivers/power/supply/rt9455_charger.c
++++ b/drivers/power/supply/rt9455_charger.c
+@@ -193,6 +193,7 @@ static const int rt9455_voreg_values[] = {
+       4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000
+ };
++#if IS_ENABLED(CONFIG_USB_PHY)
+ /*
+  * When the charger is in boost mode, REG02[7:2] represent boost output
+  * voltage.
+@@ -208,6 +209,7 @@ static const int rt9455_boost_voltage_values[] = {
+       5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000,
+       5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000,
+ };
++#endif
+ /* REG07[3:0] (VMREG) in uV */
+ static const int rt9455_vmreg_values[] = {
+-- 
+2.43.0
+
diff --git a/queue-5.4/series b/queue-5.4/series
new file mode 100644 (file)
index 0000000..061beb9
--- /dev/null
@@ -0,0 +1,19 @@
+dmaengine-pl330-issue_pending-waits-until-wfp-state.patch
+dmaengine-revert-dmaengine-pl330-issue_pending-waits.patch
+wifi-nl80211-don-t-free-null-coalescing-rule.patch
+pinctrl-core-delete-incorrect-free-in-pinctrl_enable.patch
+pinctrl-mediatek-check-gpio-pin-number-and-use-binar.patch
+pinctrl-mediatek-supporting-driving-setting-without-.patch
+pinctrl-mediatek-refine-mtk_pinconf_get-and-mtk_pinc.patch
+pinctrl-mediatek-refine-mtk_pinconf_get.patch
+pinctrl-mediatek-backward-compatible-to-previous-med.patch
+pinctrl-mediatek-remove-shadow-variable-declaration.patch
+pinctrl-mediatek-paris-fix-pin_config_bias_-readback.patch
+pinctrl-mediatek-paris-rework-mtk_pinconf_-get-set-s.patch
+pinctrl-mediatek-paris-rework-support-for-pin_config.patch
+sunrpc-add-a-struct-rpc_stats-arg-to-rpc_create_args.patch
+nfs-expose-proc-net-sunrpc-nfs-in-net-namespaces.patch
+nfs-make-the-rpc_stat-per-net-namespace.patch
+nfs-handle-error-of-rpc_proc_register-in-nfs_net_ini.patch
+power-rt9455-hide-unused-rt9455_boost_voltage_values.patch
+pinctrl-devicetree-fix-refcount-leak-in-pinctrl_dt_t.patch
diff --git a/queue-5.4/sunrpc-add-a-struct-rpc_stats-arg-to-rpc_create_args.patch b/queue-5.4/sunrpc-add-a-struct-rpc_stats-arg-to-rpc_create_args.patch
new file mode 100644 (file)
index 0000000..d296153
--- /dev/null
@@ -0,0 +1,74 @@
+From d42a67f30a0131e6ef315a474b01d5bba18aa115 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Feb 2024 14:57:30 -0500
+Subject: sunrpc: add a struct rpc_stats arg to rpc_create_args
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 2057a48d0dd00c6a2a94ded7df2bf1d3f2a4a0da ]
+
+We want to be able to have our rpc stats handled in a per network
+namespace manner, so add an option to rpc_create_args to specify a
+different rpc_stats struct instead of using the one on the rpc_program.
+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Stable-dep-of: 24457f1be29f ("nfs: Handle error of rpc_proc_register() in nfs_net_init().")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/sunrpc/clnt.h | 1 +
+ net/sunrpc/clnt.c           | 5 ++++-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
+index 336802acc629b..18d4cf2d637b6 100644
+--- a/include/linux/sunrpc/clnt.h
++++ b/include/linux/sunrpc/clnt.h
+@@ -121,6 +121,7 @@ struct rpc_create_args {
+       const char              *servername;
+       const char              *nodename;
+       const struct rpc_program *program;
++      struct rpc_stat         *stats;
+       u32                     prognumber;     /* overrides program->number */
+       u32                     version;
+       rpc_authflavor_t        authflavor;
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index 9071dc6928ac2..c6fe108845e8b 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -400,7 +400,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args,
+       clnt->cl_maxproc  = version->nrprocs;
+       clnt->cl_prog     = args->prognumber ? : program->number;
+       clnt->cl_vers     = version->number;
+-      clnt->cl_stats    = program->stats;
++      clnt->cl_stats    = args->stats ? : program->stats;
+       clnt->cl_metrics  = rpc_alloc_iostats(clnt);
+       rpc_init_pipe_dir_head(&clnt->cl_pipedir_objects);
+       err = -ENOMEM;
+@@ -666,6 +666,7 @@ struct rpc_clnt *rpc_clone_client(struct rpc_clnt *clnt)
+               .version        = clnt->cl_vers,
+               .authflavor     = clnt->cl_auth->au_flavor,
+               .cred           = clnt->cl_cred,
++              .stats          = clnt->cl_stats,
+       };
+       return __rpc_clone_client(&args, clnt);
+ }
+@@ -688,6 +689,7 @@ rpc_clone_client_set_auth(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
+               .version        = clnt->cl_vers,
+               .authflavor     = flavor,
+               .cred           = clnt->cl_cred,
++              .stats          = clnt->cl_stats,
+       };
+       return __rpc_clone_client(&args, clnt);
+ }
+@@ -961,6 +963,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
+               .version        = vers,
+               .authflavor     = old->cl_auth->au_flavor,
+               .cred           = old->cl_cred,
++              .stats          = old->cl_stats,
+       };
+       struct rpc_clnt *clnt;
+       int err;
+-- 
+2.43.0
+
diff --git a/queue-5.4/wifi-nl80211-don-t-free-null-coalescing-rule.patch b/queue-5.4/wifi-nl80211-don-t-free-null-coalescing-rule.patch
new file mode 100644 (file)
index 0000000..c196d52
--- /dev/null
@@ -0,0 +1,37 @@
+From 32acd3ba3154b83a29938c51c74794cd43807ef0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Apr 2024 10:52:23 +0200
+Subject: wifi: nl80211: don't free NULL coalescing rule
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 801ea33ae82d6a9d954074fbcf8ea9d18f1543a7 ]
+
+If the parsing fails, we can dereference a NULL pointer here.
+
+Cc: stable@vger.kernel.org
+Fixes: be29b99a9b51 ("cfg80211/nl80211: Add packet coalesce support")
+Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://msgid.link/20240418105220.b328f80406e7.Id75d961050deb05b3e4e354e024866f350c68103@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index c698fc458f5f9..0d15dd68565cb 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -12023,6 +12023,8 @@ static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
+ error:
+       for (i = 0; i < new_coalesce.n_rules; i++) {
+               tmp_rule = &new_coalesce.rules[i];
++              if (!tmp_rule)
++                      continue;
+               for (j = 0; j < tmp_rule->n_patterns; j++)
+                       kfree(tmp_rule->patterns[j].mask);
+               kfree(tmp_rule->patterns);
+-- 
+2.43.0
+