--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
--- /dev/null
+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
+
--- /dev/null
+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
+