Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 8/8] Documentation: networking: document phy_link_topology
From: Maxime Chevallier @ 2024-04-09 10:58 UTC (permalink / raw)
  To: davem
  Cc: Maxime Chevallier, netdev, linux-kernel, thomas.petazzoni,
	Andrew Lunn, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
	Russell King, linux-arm-kernel, Christophe Leroy, Herve Codina,
	Florian Fainelli, Heiner Kallweit, Vladimir Oltean,
	Köry Maincent, Jesse Brandeburg, Jonathan Corbet,
	Marek Behún, Piergiorgio Beruto, Oleksij Rempel,
	Nicolò Veronese, Simon Horman, mwojtas
In-Reply-To: <20240409105847.465298-1-maxime.chevallier@bootlin.com>

The newly introduced phy_link_topology tracks all ethernet PHYs that are
attached to a netdevice. Document the base principle, internal and
external APIs. As the phy_link_topology is expected to be extended, this
documentation will hold any further improvements and additions made
relative to topology handling.

Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
 Documentation/networking/ethtool-netlink.rst  |   3 +
 Documentation/networking/index.rst            |   1 +
 .../networking/phy-link-topology.rst          | 120 ++++++++++++++++++
 3 files changed, 124 insertions(+)
 create mode 100644 Documentation/networking/phy-link-topology.rst

diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst
index b89a3d562018..1ae3bfd805ce 100644
--- a/Documentation/networking/ethtool-netlink.rst
+++ b/Documentation/networking/ethtool-netlink.rst
@@ -2027,10 +2027,13 @@ Retrieve information about a given Ethernet PHY sitting on the link. The DO
 operation returns all available information about dev->phydev. User can also
 specify a PHY_INDEX, in which case the DO request returns information about that
 specific PHY.
+
 As there can be more than one PHY, the DUMP operation can be used to list the PHYs
 present on a given interface, by passing an interface index or name in
 the dump request.
 
+For more information, refer to :ref:`Documentation/networking/phy-link-topology.rst`
+
 Request contents:
 
   ====================================  ======  ==========================
diff --git a/Documentation/networking/index.rst b/Documentation/networking/index.rst
index 473d72c36d61..c29bc5179d8a 100644
--- a/Documentation/networking/index.rst
+++ b/Documentation/networking/index.rst
@@ -89,6 +89,7 @@ Contents:
    operstates
    packet_mmap
    phonet
+   phy-link-topology
    pktgen
    plip
    ppp_generic
diff --git a/Documentation/networking/phy-link-topology.rst b/Documentation/networking/phy-link-topology.rst
new file mode 100644
index 000000000000..1f021419ae8c
--- /dev/null
+++ b/Documentation/networking/phy-link-topology.rst
@@ -0,0 +1,120 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================
+PHY link topology
+=================
+
+Overview
+========
+
+The PHY link topology representation in the networking stack aims at representing
+the hardware layout for any given Ethernet link.
+
+An Ethernet interface from userspace's point of view is nothing but a
+:c:type:`struct net_device <net_device>`, which exposes configuration options
+through the legacy ioctls and the ethtool netlink commands. The base assumption
+when designing these configuration APIs were that the link looks something like ::
+
+  +-----------------------+        +----------+      +--------------+
+  | Ethernet Controller / |        | Ethernet |      | Connector /  |
+  |       MAC             | ------ |   PHY    | ---- |    Port      | ---... to LP
+  +-----------------------+        +----------+      +--------------+
+  struct net_device               struct phy_device
+
+Commands that needs to configure the PHY will go through the net_device.phydev
+field to reach the PHY and perform the relevant configuration.
+
+This assumption falls apart in more complex topologies that can arise when,
+for example, using SFP transceivers (although that's not the only specific case).
+
+Here, we have 2 basic scenarios. Either the MAC is able to output a serialized
+interface, that can directly be fed to an SFP cage, such as SGMII, 1000BaseX,
+10GBaseR, etc.
+
+The link topology then looks like this (when an SFP module is inserted) ::
+
+  +-----+  SGMII  +------------+
+  | MAC | ------- | SFP Module |
+  +-----+         +------------+
+
+Knowing that some modules embed a PHY, the actual link is more like ::
+
+  +-----+  SGMII   +--------------+
+  | MAC | -------- | PHY (on SFP) |
+  +-----+          +--------------+
+
+In this case, the SFP PHY is handled by phylib, and registered by phylink through
+its SFP upstream ops.
+
+Now some Ethernet controllers aren't able to output a serialized interface, so
+we can't directly connect them to an SFP cage. However, some PHYs can be used
+as media-converters, to translate the non-serialized MAC MII interface to a
+serialized MII interface fed to the SFP ::
+
+  +-----+  RGMII  +-----------------------+  SGMII  +--------------+
+  | MAC | ------- | PHY (media converter) | ------- | PHY (on SFP) |
+  +-----+         +-----------------------+         +--------------+
+
+This is where the model of having a single net_device.phydev pointer shows its
+limitations, as we now have 2 PHYs on the link.
+
+The phy_link topology framework aims at providing a way to keep track of every
+PHY on the link, for use by both kernel drivers and subsystems, but also to
+report the topology to userspace, allowing to target individual PHYs in configuration
+commands.
+
+API
+===
+
+The :c:type:`struct phy_link_topology <phy_link_topology>` is a per-netdevice
+resource, that gets initialized at netdevice creation. Once it's initialized,
+it is then possible to register PHYs to the topology through :
+
+:c:func:`phy_link_topo_add_phy`
+
+Besides registering the PHY to the topology, this call will also assign a unique
+index to the PHY, which can then be reported to userspace to refer to this PHY
+(akin to the ifindex). This index is a u32, ranging from 1 to U32_MAX. The value
+0 is reserved to indicate the PHY doesn't belong to any topology yet.
+
+The PHY can then be removed from the topology through
+
+:c:func:`phy_link_topo_del_phy`
+
+These function are already hooked into the phylib subsystem, so all PHYs that
+are linked to a net_device through :c:func:`phy_attach_direct` will automatically
+join the netdev's topology.
+
+PHYs that are on a SFP module will also be automatically registered IF the SFP
+upstream is phylink (so, no media-converter).
+
+PHY drivers that can be used as SFP upstream need to call :c:func:`phy_sfp_attach_phy`
+and :c:func:`phy_sfp_detach_phy`, which can be used as a
+.attach_phy / .detach_phy implementation for the
+:c:type:`struct sfp_upstream_ops <sfp_upstream_ops>`.
+
+UAPI
+====
+
+There exist a set of netlink commands to query the link topology from userspace,
+see ``Documentation/networking/ethtool-netlink.rst``.
+
+The whole point of having a topology representation is to assign the phyindex
+field in :c:type:`struct phy_device <phy_device>`. This index is reported to
+userspace using the ``ETHTOOL_MSG_PHY_GET`` ethtnl command. Performing a DUMP operation
+will result in all PHYs from all net_device being listed. The DUMP command
+accepts either a ``ETHTOOL_A_HEADER_DEV_INDEX`` or ``ETHTOOL_A_HEADER_DEV_NAME``
+to be passed in the request to filter the DUMP to a single net_device.
+
+The retrieved index can then be passed as a request parameter using the
+``ETHTOOL_A_HEADER_PHY_INDEX`` field in the following ethnl commands :
+
+* ``ETHTOOL_MSG_STRSET_GET`` to get the stats string set from a given PHY
+* ``ETHTOOL_MSG_CABLE_TEST_ACT`` and ``ETHTOOL_MSG_CABLE_TEST_ACT``, to perform
+  cable testing on a given PHY on the link (most likely the outermost PHY)
+* ``ETHTOOL_MSG_PSE_SET`` and ``ETHTOOL_MSG_PSE_GET`` for PHY-controlled PoE and PSE settings
+* ``ETHTOOL_MSG_PLCA_GET_CFG``, ``ETHTOOL_MSG_PLCA_SET_CFG`` and ``ETHTOOL_MSG_PLCA_GET_STATUS``
+  to set the PLCA (Physical Layer Collision Avoidance) parameters
+
+Note that the PHY index can be passed to other requests, which will silently
+ignore it if present and irrelevant.
-- 
2.44.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH] pinctrl: apple-gpio: Fix null pointer dereference in apple_gpio_pinctrl_probe()
From: Ma Ke @ 2024-04-09 11:02 UTC (permalink / raw)
  To: marcan, sven, alyssa, linus.walleij
  Cc: asahi, linux-arm-kernel, linux-gpio, linux-kernel, Ma Ke

devm_kasprintf() returns a pointer to dynamically allocated memory which
can be NULL upon failure. We add a check to ensure that failure does not
occur.

Signed-off-by: Ma Ke <make_ruc2021@163.com>
---
 drivers/pinctrl/pinctrl-apple-gpio.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-apple-gpio.c b/drivers/pinctrl/pinctrl-apple-gpio.c
index 3751c7de37aa..af2f90d1950f 100644
--- a/drivers/pinctrl/pinctrl-apple-gpio.c
+++ b/drivers/pinctrl/pinctrl-apple-gpio.c
@@ -474,6 +474,8 @@ static int apple_gpio_pinctrl_probe(struct platform_device *pdev)
 	for (i = 0; i < npins; i++) {
 		pins[i].number = i;
 		pins[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "PIN%u", i);
+		if (!pins[i].name)
+			return -ENOMEM;
 		pins[i].drv_data = pctl;
 		pin_names[i] = pins[i].name;
 		pin_nums[i] = i;
-- 
2.37.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [syzbot] [mm?] BUG: unable to handle kernel paging request in copy_from_kernel_nofault (2)
From: Puranjay Mohan @ 2024-04-09 11:07 UTC (permalink / raw)
  To: syzbot, akpm, alexei.starovoitov, andrii.nakryiko, bpf,
	linux-arm-kernel, linux-kernel, linux-mm, linux, mark.rutland,
	syzkaller-bugs
In-Reply-To: <00000000000065955e0615a759ab@google.com>

syzbot <syzbot+186522670e6722692d86@syzkaller.appspotmail.com> writes:

> Hello,
>
> syzbot has tested the proposed patch but the reproducer is still triggering an issue:
> INFO: task hung in _vm_unmap_aliases
>
> INFO: task kworker/0:1:8 blocked for more than 430 seconds.
>       Not tainted 6.9.0-rc2-syzkaller #0
> "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> task:kworker/0:1     state:D stack:0     pid:8     tgid:8     ppid:2      flags:0x00000000
> Workqueue: events bpf_prog_free_deferred
> Call trace: 
> [<8189be20>] (__schedule) from [<8189ca5c>] (__schedule_loop kernel/sched/core.c:6823 [inline])
> [<8189be20>] (__schedule) from [<8189ca5c>] (schedule+0x2c/0xfc kernel/sched/core.c:6838)
>  r10:82c16005 r9:00000000 r8:82714be8 r7:00000002 r6:df839d94 r5:82e2d400
>  r4:82e2d400
> [<8189ca30>] (schedule) from [<8189d06c>] (schedule_preempt_disabled+0x18/0x24 kernel/sched/core.c:6895)
>  r5:82e2d400 r4:82714be4
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock_common kernel/locking/mutex.c:684 [inline])
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock.constprop.0+0x2e8/0xae0 kernel/locking/mutex.c:752)
> [<8189f664>] (__mutex_lock.constprop.0) from [<818a0218>] (__mutex_lock_slowpath+0x14/0x18 kernel/locking/mutex.c:1040)
>  r10:82c16005 r9:df839e20 r8:00000000 r7:ffffffff r6:00000000 r5:84eb4f80
>  r4:00000000
> [<818a0204>] (__mutex_lock_slowpath) from [<818a0258>] (mutex_lock+0x3c/0x40 kernel/locking/mutex.c:286)
> [<818a021c>] (mutex_lock) from [<8049c734>] (_vm_unmap_aliases+0x60/0x2e8 mm/vmalloc.c:2788)
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vm_reset_perms mm/vmalloc.c:3235 [inline])
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vfree+0x170/0x1e4 mm/vmalloc.c:3314)
>  r10:82c16005 r9:00000001 r8:00000000 r7:ffffffff r6:00000000 r5:84eb4f80
>  r4:00000000
> [<804a0448>] (vfree) from [<802edb3c>] (module_memfree+0x30/0x50 kernel/module/main.c:1189)
>  r9:82e2d400 r8:00000080 r7:00000000 r6:82c16000 r5:00001000 r4:7f02d000
> [<802edb0c>] (module_memfree) from [<803916e0>] (bpf_jit_free_exec+0x10/0x14 kernel/bpf/core.c:1058)
>  r5:00001000 r4:dfb13000
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_binary_free kernel/bpf/core.c:1104 [inline])
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_free+0x68/0xe4 kernel/bpf/core.c:1228)
> [<80391838>] (bpf_jit_free) from [<80392988>] (bpf_prog_free_deferred+0x14c/0x164 kernel/bpf/core.c:2783)
>  r5:84eebf54 r4:84eebc00
> [<8039283c>] (bpf_prog_free_deferred) from [<8026678c>] (process_one_work+0x1b8/0x508 kernel/workqueue.c:3254)
>  r7:dddd00c0 r6:82c16000 r5:84eebf54 r4:82c0bf00
> [<802665d4>] (process_one_work) from [<802674b0>] (process_scheduled_works kernel/workqueue.c:3335 [inline])
> [<802665d4>] (process_one_work) from [<802674b0>] (worker_thread+0x1ec/0x418 kernel/workqueue.c:3416)
>  r10:82e2d400 r9:82c0bf2c r8:61c88647 r7:dddd00e0 r6:82604d40 r5:dddd00c0
>  r4:82c0bf00
> [<802672c4>] (worker_thread) from [<802701c4>] (kthread+0x104/0x134 kernel/kthread.c:388)
>  r10:00000000 r9:df835e90 r8:82cad880 r7:82c0bf00 r6:802672c4 r5:82e2d400
>  r4:82cad140
> [<802700c0>] (kthread) from [<80200104>] (ret_from_fork+0x14/0x30 arch/arm/kernel/entry-common.S:134)
> Exception stack(0xdf839fb0 to 0xdf839ff8)
> 9fa0:                                     00000000 00000000 00000000 00000000
> 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
>  r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:802700c0 r4:82cad140
> INFO: task kworker/1:6:3904 blocked for more than 430 seconds.
>       Not tainted 6.9.0-rc2-syzkaller #0
> "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> task:kworker/1:6     state:D stack:0     pid:3904  tgid:3904  ppid:2      flags:0x00000000
> Workqueue: events bpf_prog_free_deferred
> Call trace: 
> [<8189be20>] (__schedule) from [<8189ca5c>] (__schedule_loop kernel/sched/core.c:6823 [inline])
> [<8189be20>] (__schedule) from [<8189ca5c>] (schedule+0x2c/0xfc kernel/sched/core.c:6838)
>  r10:82c16205 r9:00000000 r8:82714be8 r7:00000002 r6:e0741d94 r5:83efd400
>  r4:83efd400
> [<8189ca30>] (schedule) from [<8189d06c>] (schedule_preempt_disabled+0x18/0x24 kernel/sched/core.c:6895)
>  r5:83efd400 r4:82714be4
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock_common kernel/locking/mutex.c:684 [inline])
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock.constprop.0+0x2e8/0xae0 kernel/locking/mutex.c:752)
> [<8189f664>] (__mutex_lock.constprop.0) from [<818a0218>] (__mutex_lock_slowpath+0x14/0x18 kernel/locking/mutex.c:1040)
>  r10:82c16205 r9:e0741e20 r8:00000000 r7:ffffffff r6:00000000 r5:84eb4300
>  r4:00000000
> [<818a0204>] (__mutex_lock_slowpath) from [<818a0258>] (mutex_lock+0x3c/0x40 kernel/locking/mutex.c:286)
> [<818a021c>] (mutex_lock) from [<8049c734>] (_vm_unmap_aliases+0x60/0x2e8 mm/vmalloc.c:2788)
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vm_reset_perms mm/vmalloc.c:3235 [inline])
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vfree+0x170/0x1e4 mm/vmalloc.c:3314)
>  r10:82c16205 r9:00000001 r8:00000000 r7:ffffffff r6:00000000 r5:84eb4300
>  r4:00000000
> [<804a0448>] (vfree) from [<802edb3c>] (module_memfree+0x30/0x50 kernel/module/main.c:1189)
>  r9:83efd400 r8:00000180 r7:00000000 r6:82c16200 r5:00001000 r4:7f00b000
> [<802edb0c>] (module_memfree) from [<803916e0>] (bpf_jit_free_exec+0x10/0x14 kernel/bpf/core.c:1058)
>  r5:00001000 r4:df98f000
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_binary_free kernel/bpf/core.c:1104 [inline])
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_free+0x68/0xe4 kernel/bpf/core.c:1228)
> [<80391838>] (bpf_jit_free) from [<80392988>] (bpf_prog_free_deferred+0x14c/0x164 kernel/bpf/core.c:2783)
>  r5:84ee9754 r4:84ee9400
> [<8039283c>] (bpf_prog_free_deferred) from [<8026678c>] (process_one_work+0x1b8/0x508 kernel/workqueue.c:3254)
>  r7:ddde40c0 r6:82c16200 r5:84ee9754 r4:84603500
> [<802665d4>] (process_one_work) from [<802674b0>] (process_scheduled_works kernel/workqueue.c:3335 [inline])
> [<802665d4>] (process_one_work) from [<802674b0>] (worker_thread+0x1ec/0x418 kernel/workqueue.c:3416)
>  r10:83efd400 r9:8460352c r8:61c88647 r7:ddde40e0 r6:82604d40 r5:ddde40c0
>  r4:84603500
> [<802672c4>] (worker_thread) from [<802701c4>] (kthread+0x104/0x134 kernel/kthread.c:388)
>  r10:00000000 r9:df879e90 r8:84e34440 r7:84603500 r6:802672c4 r5:83efd400
>  r4:84cc58c0
> [<802700c0>] (kthread) from [<80200104>] (ret_from_fork+0x14/0x30 arch/arm/kernel/entry-common.S:134)
> Exception stack(0xe0741fb0 to 0xe0741ff8)
> 1fa0:                                     00000000 00000000 00000000 00000000
> 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000
>  r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:802700c0 r4:84cc58c0
> INFO: task kworker/0:55:4238 blocked for more than 430 seconds.
>       Not tainted 6.9.0-rc2-syzkaller #0
> "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> task:kworker/0:55    state:D stack:0     pid:4238  tgid:4238  ppid:2      flags:0x00000000
> Workqueue: events bpf_prog_free_deferred
> Call trace: 
> [<8189be20>] (__schedule) from [<8189ca5c>] (__schedule_loop kernel/sched/core.c:6823 [inline])
> [<8189be20>] (__schedule) from [<8189ca5c>] (schedule+0x2c/0xfc kernel/sched/core.c:6838)
>  r10:82c16005 r9:00000000 r8:82714be8 r7:00000002 r6:dfb09d94 r5:84e8c800
>  r4:84e8c800
> [<8189ca30>] (schedule) from [<8189d06c>] (schedule_preempt_disabled+0x18/0x24 kernel/sched/core.c:6895)
>  r5:84e8c800 r4:82714be4
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock_common kernel/locking/mutex.c:684 [inline])
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock.constprop.0+0x2e8/0xae0 kernel/locking/mutex.c:752)
> [<8189f664>] (__mutex_lock.constprop.0) from [<818a0218>] (__mutex_lock_slowpath+0x14/0x18 kernel/locking/mutex.c:1040)
>  r10:82c16005 r9:dfb09e20 r8:00000000 r7:ffffffff r6:00000000 r5:84eb8640
>  r4:00000000
> [<818a0204>] (__mutex_lock_slowpath) from [<818a0258>] (mutex_lock+0x3c/0x40 kernel/locking/mutex.c:286)
> [<818a021c>] (mutex_lock) from [<8049c734>] (_vm_unmap_aliases+0x60/0x2e8 mm/vmalloc.c:2788)
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vm_reset_perms mm/vmalloc.c:3235 [inline])
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vfree+0x170/0x1e4 mm/vmalloc.c:3314)
>  r10:82c16005 r9:00000001 r8:00000000 r7:ffffffff r6:00000000 r5:84eb8640
>  r4:00000000
> [<804a0448>] (vfree) from [<802edb3c>] (module_memfree+0x30/0x50 kernel/module/main.c:1189)
>  r9:84e8c800 r8:00000080 r7:00000000 r6:82c16000 r5:00001000 r4:7f057000
> [<802edb0c>] (module_memfree) from [<803916e0>] (bpf_jit_free_exec+0x10/0x14 kernel/bpf/core.c:1058)
>  r5:00001000 r4:dffb3000
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_binary_free kernel/bpf/core.c:1104 [inline])
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_free+0x68/0xe4 kernel/bpf/core.c:1228)
> [<80391838>] (bpf_jit_free) from [<80392988>] (bpf_prog_free_deferred+0x14c/0x164 kernel/bpf/core.c:2783)
>  r5:84e08b54 r4:84e08800
> [<8039283c>] (bpf_prog_free_deferred) from [<8026678c>] (process_one_work+0x1b8/0x508 kernel/workqueue.c:3254)
>  r7:dddd00c0 r6:82c16000 r5:84e08b54 r4:84e60000
> [<802665d4>] (process_one_work) from [<802674b0>] (process_scheduled_works kernel/workqueue.c:3335 [inline])
> [<802665d4>] (process_one_work) from [<802674b0>] (worker_thread+0x1ec/0x418 kernel/workqueue.c:3416)
>  r10:84e8c800 r9:84e6002c r8:61c88647 r7:dddd00e0 r6:82604d40 r5:dddd00c0
>  r4:84e60000
> [<802672c4>] (worker_thread) from [<802701c4>] (kthread+0x104/0x134 kernel/kthread.c:388)
>  r10:00000000 r9:df9bde90 r8:84616fc0 r7:84e60000 r6:802672c4 r5:84e8c800
>  r4:84e5b940
> [<802700c0>] (kthread) from [<80200104>] (ret_from_fork+0x14/0x30 arch/arm/kernel/entry-common.S:134)
> Exception stack(0xdfb09fb0 to 0xdfb09ff8)
> 9fa0:                                     00000000 00000000 00000000 00000000
> 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
>  r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:802700c0 r4:84e5b940
> INFO: task kworker/0:57:4264 blocked for more than 430 seconds.
>       Not tainted 6.9.0-rc2-syzkaller #0
> "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> task:kworker/0:57    state:D stack:0     pid:4264  tgid:4264  ppid:2      flags:0x00000000
> Workqueue: events bpf_prog_free_deferred
> Call trace: 
> [<8189be20>] (__schedule) from [<8189ca5c>] (__schedule_loop kernel/sched/core.c:6823 [inline])
> [<8189be20>] (__schedule) from [<8189ca5c>] (schedule+0x2c/0xfc kernel/sched/core.c:6838)
>  r10:82c16005 r9:00000000 r8:82714be8 r7:00000002 r6:dfd11d94 r5:844e5400
>  r4:844e5400
> [<8189ca30>] (schedule) from [<8189d06c>] (schedule_preempt_disabled+0x18/0x24 kernel/sched/core.c:6895)
>  r5:844e5400 r4:82714be4
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock_common kernel/locking/mutex.c:684 [inline])
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock.constprop.0+0x2e8/0xae0 kernel/locking/mutex.c:752)
> [<8189f664>] (__mutex_lock.constprop.0) from [<818a0218>] (__mutex_lock_slowpath+0x14/0x18 kernel/locking/mutex.c:1040)
>  r10:82c16005 r9:dfd11e20 r8:00000000 r7:ffffffff r6:00000000 r5:84eb4d80
>  r4:00000000
> [<818a0204>] (__mutex_lock_slowpath) from [<818a0258>] (mutex_lock+0x3c/0x40 kernel/locking/mutex.c:286)
> [<818a021c>] (mutex_lock) from [<8049c734>] (_vm_unmap_aliases+0x60/0x2e8 mm/vmalloc.c:2788)
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vm_reset_perms mm/vmalloc.c:3235 [inline])
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vfree+0x170/0x1e4 mm/vmalloc.c:3314)
>  r10:82c16005 r9:00000001 r8:00000000 r7:ffffffff r6:00000000 r5:84eb4d80
>  r4:00000000
> [<804a0448>] (vfree) from [<802edb3c>] (module_memfree+0x30/0x50 kernel/module/main.c:1189)
>  r9:844e5400 r8:00000080 r7:00000000 r6:82c16000 r5:00001000 r4:7f02f000
> [<802edb0c>] (module_memfree) from [<803916e0>] (bpf_jit_free_exec+0x10/0x14 kernel/bpf/core.c:1058)
>  r5:00001000 r4:dfb49000
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_binary_free kernel/bpf/core.c:1104 [inline])
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_free+0x68/0xe4 kernel/bpf/core.c:1228)
> [<80391838>] (bpf_jit_free) from [<80392988>] (bpf_prog_free_deferred+0x14c/0x164 kernel/bpf/core.c:2783)
>  r5:84eeaf54 r4:84eeac00
> [<8039283c>] (bpf_prog_free_deferred) from [<8026678c>] (process_one_work+0x1b8/0x508 kernel/workqueue.c:3254)
>  r7:dddd00c0 r6:82c16000 r5:84eeaf54 r4:84e60100
> [<802665d4>] (process_one_work) from [<802674b0>] (process_scheduled_works kernel/workqueue.c:3335 [inline])
> [<802665d4>] (process_one_work) from [<802674b0>] (worker_thread+0x1ec/0x418 kernel/workqueue.c:3416)
>  r10:844e5400 r9:84e6012c r8:61c88647 r7:dddd00e0 r6:82604d40 r5:dddd00c0
>  r4:84e60100
> [<802672c4>] (worker_thread) from [<802701c4>] (kthread+0x104/0x134 kernel/kthread.c:388)
>  r10:00000000 r9:dfb09e90 r8:84ea8b80 r7:84e60100 r6:802672c4 r5:844e5400
>  r4:84ea8b00
> [<802700c0>] (kthread) from [<80200104>] (ret_from_fork+0x14/0x30 arch/arm/kernel/entry-common.S:134)
> Exception stack(0xdfd11fb0 to 0xdfd11ff8)
> 1fa0:                                     00000000 00000000 00000000 00000000
> 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000
>  r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:802700c0 r4:84ea8b00
> INFO: task kworker/1:59:4286 blocked for more than 430 seconds.
>       Not tainted 6.9.0-rc2-syzkaller #0
> "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> task:kworker/1:59    state:D stack:0     pid:4286  tgid:4286  ppid:2      flags:0x00000000
> Workqueue: events bpf_prog_free_deferred
> Call trace: 
> [<8189be20>] (__schedule) from [<8189ca5c>] (__schedule_loop kernel/sched/core.c:6823 [inline])
> [<8189be20>] (__schedule) from [<8189ca5c>] (schedule+0x2c/0xfc kernel/sched/core.c:6838)
>  r10:82c16205 r9:00000000 r8:82714be8 r7:00000002 r6:dfe89d94 r5:84e96000
>  r4:84e96000
> [<8189ca30>] (schedule) from [<8189d06c>] (schedule_preempt_disabled+0x18/0x24 kernel/sched/core.c:6895)
>  r5:84e96000 r4:82714be4
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock_common kernel/locking/mutex.c:684 [inline])
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock.constprop.0+0x2e8/0xae0 kernel/locking/mutex.c:752)
> [<8189f664>] (__mutex_lock.constprop.0) from [<818a0218>] (__mutex_lock_slowpath+0x14/0x18 kernel/locking/mutex.c:1040)
>  r10:82c16205 r9:dfe89e20 r8:00000000 r7:ffffffff r6:00000000 r5:84eb8040
>  r4:00000000
> [<818a0204>] (__mutex_lock_slowpath) from [<818a0258>] (mutex_lock+0x3c/0x40 kernel/locking/mutex.c:286)
> [<818a021c>] (mutex_lock) from [<8049c734>] (_vm_unmap_aliases+0x60/0x2e8 mm/vmalloc.c:2788)
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vm_reset_perms mm/vmalloc.c:3235 [inline])
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vfree+0x170/0x1e4 mm/vmalloc.c:3314)
>  r10:82c16205 r9:00000001 r8:00000000 r7:ffffffff r6:00000000 r5:84eb8040
>  r4:00000000
> [<804a0448>] (vfree) from [<802edb3c>] (module_memfree+0x30/0x50 kernel/module/main.c:1189)
>  r9:84e96000 r8:00000180 r7:00000000 r6:82c16200 r5:00001000 r4:7f055000
> [<802edb0c>] (module_memfree) from [<803916e0>] (bpf_jit_free_exec+0x10/0x14 kernel/bpf/core.c:1058)
>  r5:00001000 r4:dff77000
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_binary_free kernel/bpf/core.c:1104 [inline])
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_free+0x68/0xe4 kernel/bpf/core.c:1228)
> [<80391838>] (bpf_jit_free) from [<80392988>] (bpf_prog_free_deferred+0x14c/0x164 kernel/bpf/core.c:2783)
>  r5:82ceb354 r4:82ceb000
> [<8039283c>] (bpf_prog_free_deferred) from [<8026678c>] (process_one_work+0x1b8/0x508 kernel/workqueue.c:3254)
>  r7:ddde40c0 r6:82c16200 r5:82ceb354 r4:84e69480
> [<802665d4>] (process_one_work) from [<802674b0>] (process_scheduled_works kernel/workqueue.c:3335 [inline])
> [<802665d4>] (process_one_work) from [<802674b0>] (worker_thread+0x1ec/0x418 kernel/workqueue.c:3416)
>  r10:84e96000 r9:84e694ac r8:61c88647 r7:ddde40e0 r6:82604d40 r5:ddde40c0
>  r4:84e69480
> [<802672c4>] (worker_thread) from [<802701c4>] (kthread+0x104/0x134 kernel/kthread.c:388)
>  r10:00000000 r9:dfdcde90 r8:84ea8840 r7:84e69480 r6:802672c4 r5:84e96000
>  r4:84ea8e40
> [<802700c0>] (kthread) from [<80200104>] (ret_from_fork+0x14/0x30 arch/arm/kernel/entry-common.S:134)
> Exception stack(0xdfe89fb0 to 0xdfe89ff8)
> 9fa0:                                     00000000 00000000 00000000 00000000
> 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
>  r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:802700c0 r4:84ea8e40
> INFO: task kworker/1:63:4298 blocked for more than 430 seconds.
>       Not tainted 6.9.0-rc2-syzkaller #0
> "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> task:kworker/1:63    state:D stack:0     pid:4298  tgid:4298  ppid:2      flags:0x00000000
> Workqueue: events bpf_prog_free_deferred
> Call trace: 
> [<8189be20>] (__schedule) from [<8189ca5c>] (__schedule_loop kernel/sched/core.c:6823 [inline])
> [<8189be20>] (__schedule) from [<8189ca5c>] (schedule+0x2c/0xfc kernel/sched/core.c:6838)
>  r10:82c16205 r9:00000000 r8:82714be8 r7:00000002 r6:dfee5d94 r5:84e91800
>  r4:84e91800
> [<8189ca30>] (schedule) from [<8189d06c>] (schedule_preempt_disabled+0x18/0x24 kernel/sched/core.c:6895)
>  r5:84e91800 r4:82714be4
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock_common kernel/locking/mutex.c:684 [inline])
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock.constprop.0+0x2e8/0xae0 kernel/locking/mutex.c:752)
> [<8189f664>] (__mutex_lock.constprop.0) from [<818a0218>] (__mutex_lock_slowpath+0x14/0x18 kernel/locking/mutex.c:1040)
>  r10:82c16205 r9:dfee5e20 r8:00000000 r7:ffffffff r6:00000000 r5:84eba380
>  r4:00000000
> [<818a0204>] (__mutex_lock_slowpath) from [<818a0258>] (mutex_lock+0x3c/0x40 kernel/locking/mutex.c:286)
> [<818a021c>] (mutex_lock) from [<8049c734>] (_vm_unmap_aliases+0x60/0x2e8 mm/vmalloc.c:2788)
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vm_reset_perms mm/vmalloc.c:3235 [inline])
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vfree+0x170/0x1e4 mm/vmalloc.c:3314)
>  r10:82c16205 r9:00000001 r8:00000000 r7:ffffffff r6:00000000 r5:84eba380
>  r4:00000000
> [<804a0448>] (vfree) from [<802edb3c>] (module_memfree+0x30/0x50 kernel/module/main.c:1189)
>  r9:84e91800 r8:00000180 r7:00000000 r6:82c16200 r5:00001000 r4:7f00d000
> [<802edb0c>] (module_memfree) from [<803916e0>] (bpf_jit_free_exec+0x10/0x14 kernel/bpf/core.c:1058)
>  r5:00001000 r4:df9d3000
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_binary_free kernel/bpf/core.c:1104 [inline])
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_free+0x68/0xe4 kernel/bpf/core.c:1228)
> [<80391838>] (bpf_jit_free) from [<80392988>] (bpf_prog_free_deferred+0x14c/0x164 kernel/bpf/core.c:2783)
>  r5:84e18b54 r4:84e18800
> [<8039283c>] (bpf_prog_free_deferred) from [<8026678c>] (process_one_work+0x1b8/0x508 kernel/workqueue.c:3254)
>  r7:ddde40c0 r6:82c16200 r5:84e18b54 r4:84e69680
> [<802665d4>] (process_one_work) from [<802674b0>] (process_scheduled_works kernel/workqueue.c:3335 [inline])
> [<802665d4>] (process_one_work) from [<802674b0>] (worker_thread+0x1ec/0x418 kernel/workqueue.c:3416)
>  r10:84e91800 r9:84e696ac r8:61c88647 r7:ddde40e0 r6:82604d40 r5:ddde40c0
>  r4:84e69680
> [<802672c4>] (worker_thread) from [<802701c4>] (kthread+0x104/0x134 kernel/kthread.c:388)
>  r10:00000000 r9:dfe89e90 r8:84e53340 r7:84e69680 r6:802672c4 r5:84e91800
>  r4:84e532c0
> [<802700c0>] (kthread) from [<80200104>] (ret_from_fork+0x14/0x30 arch/arm/kernel/entry-common.S:134)
> Exception stack(0xdfee5fb0 to 0xdfee5ff8)
> 5fa0:                                     00000000 00000000 00000000 00000000
> 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000
>  r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:802700c0 r4:84e532c0
> INFO: task kworker/1:64:4299 blocked for more than 430 seconds.
>       Not tainted 6.9.0-rc2-syzkaller #0
> "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> task:kworker/1:64    state:D stack:0     pid:4299  tgid:4299  ppid:2      flags:0x00000000
> Workqueue: events bpf_prog_free_deferred
> Call trace: 
> [<8189be20>] (__schedule) from [<8189ca5c>] (__schedule_loop kernel/sched/core.c:6823 [inline])
> [<8189be20>] (__schedule) from [<8189ca5c>] (schedule+0x2c/0xfc kernel/sched/core.c:6838)
>  r10:82c16205 r9:00000000 r8:82714be8 r7:00000002 r6:dff41d94 r5:84e74800
>  r4:84e74800
> [<8189ca30>] (schedule) from [<8189d06c>] (schedule_preempt_disabled+0x18/0x24 kernel/sched/core.c:6895)
>  r5:84e74800 r4:82714be4
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock_common kernel/locking/mutex.c:684 [inline])
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock.constprop.0+0x2e8/0xae0 kernel/locking/mutex.c:752)
> [<8189f664>] (__mutex_lock.constprop.0) from [<818a0218>] (__mutex_lock_slowpath+0x14/0x18 kernel/locking/mutex.c:1040)
>  r10:82c16205 r9:dff41e20 r8:00000000 r7:ffffffff r6:00000000 r5:84e53640
>  r4:00000000
> [<818a0204>] (__mutex_lock_slowpath) from [<818a0258>] (mutex_lock+0x3c/0x40 kernel/locking/mutex.c:286)
> [<818a021c>] (mutex_lock) from [<8049c734>] (_vm_unmap_aliases+0x60/0x2e8 mm/vmalloc.c:2788)
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vm_reset_perms mm/vmalloc.c:3235 [inline])
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vfree+0x170/0x1e4 mm/vmalloc.c:3314)
>  r10:82c16205 r9:00000001 r8:00000000 r7:ffffffff r6:00000000 r5:84e53640
>  r4:00000000
> [<804a0448>] (vfree) from [<802edb3c>] (module_memfree+0x30/0x50 kernel/module/main.c:1189)
>  r9:84e74800 r8:00000180 r7:00000000 r6:82c16200 r5:00001000 r4:7f033000
> [<802edb0c>] (module_memfree) from [<803916e0>] (bpf_jit_free_exec+0x10/0x14 kernel/bpf/core.c:1058)
>  r5:00001000 r4:dfbd7000
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_binary_free kernel/bpf/core.c:1104 [inline])
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_free+0x68/0xe4 kernel/bpf/core.c:1228)
> [<80391838>] (bpf_jit_free) from [<80392988>] (bpf_prog_free_deferred+0x14c/0x164 kernel/bpf/core.c:2783)
>  r5:84ee8f54 r4:84ee8c00
> [<8039283c>] (bpf_prog_free_deferred) from [<8026678c>] (process_one_work+0x1b8/0x508 kernel/workqueue.c:3254)
>  r7:ddde40c0 r6:82c16200 r5:84ee8f54 r4:84e69780
> [<802665d4>] (process_one_work) from [<802674b0>] (process_scheduled_works kernel/workqueue.c:3335 [inline])
> [<802665d4>] (process_one_work) from [<802674b0>] (worker_thread+0x1ec/0x418 kernel/workqueue.c:3416)
>  r10:84e74800 r9:84e697ac r8:61c88647 r7:ddde40e0 r6:82604d40 r5:ddde40c0
>  r4:84e69780
> [<802672c4>] (worker_thread) from [<802701c4>] (kthread+0x104/0x134 kernel/kthread.c:388)
>  r10:00000000 r9:dfe89e90 r8:84eb4000 r7:84e69780 r6:802672c4 r5:84e74800
>  r4:84e53900
> [<802700c0>] (kthread) from [<80200104>] (ret_from_fork+0x14/0x30 arch/arm/kernel/entry-common.S:134)
> Exception stack(0xdff41fb0 to 0xdff41ff8)
> 1fa0:                                     00000000 00000000 00000000 00000000
> 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000
>  r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:802700c0 r4:84e53900
> INFO: task kworker/0:58:4308 blocked for more than 430 seconds.
>       Not tainted 6.9.0-rc2-syzkaller #0
> "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> task:kworker/0:58    state:D stack:0     pid:4308  tgid:4308  ppid:2      flags:0x00000000
> Workqueue: events bpf_prog_free_deferred
> Call trace: 
> [<8189be20>] (__schedule) from [<8189ca5c>] (__schedule_loop kernel/sched/core.c:6823 [inline])
> [<8189be20>] (__schedule) from [<8189ca5c>] (schedule+0x2c/0xfc kernel/sched/core.c:6838)
>  r10:82c16005 r9:00000000 r8:82714be8 r7:00000002 r6:dff71d94 r5:84e76c00
>  r4:84e76c00
> [<8189ca30>] (schedule) from [<8189d06c>] (schedule_preempt_disabled+0x18/0x24 kernel/sched/core.c:6895)
>  r5:84e76c00 r4:82714be4
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock_common kernel/locking/mutex.c:684 [inline])
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock.constprop.0+0x2e8/0xae0 kernel/locking/mutex.c:752)
> [<8189f664>] (__mutex_lock.constprop.0) from [<818a0218>] (__mutex_lock_slowpath+0x14/0x18 kernel/locking/mutex.c:1040)
>  r10:82c16005 r9:dff71e20 r8:00000000 r7:ffffffff r6:00000000 r5:84eb8d00
>  r4:00000000
> [<818a0204>] (__mutex_lock_slowpath) from [<818a0258>] (mutex_lock+0x3c/0x40 kernel/locking/mutex.c:286)
> [<818a021c>] (mutex_lock) from [<8049c734>] (_vm_unmap_aliases+0x60/0x2e8 mm/vmalloc.c:2788)
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vm_reset_perms mm/vmalloc.c:3235 [inline])
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vfree+0x170/0x1e4 mm/vmalloc.c:3314)
>  r10:82c16005 r9:00000001 r8:00000000 r7:ffffffff r6:00000000 r5:84eb8d00
>  r4:00000000
> [<804a0448>] (vfree) from [<802edb3c>] (module_memfree+0x30/0x50 kernel/module/main.c:1189)
>  r9:84e76c00 r8:00000080 r7:00000000 r6:82c16000 r5:00001000 r4:7f031000
> [<802edb0c>] (module_memfree) from [<803916e0>] (bpf_jit_free_exec+0x10/0x14 kernel/bpf/core.c:1058)
>  r5:00001000 r4:dfb8f000
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_binary_free kernel/bpf/core.c:1104 [inline])
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_free+0x68/0xe4 kernel/bpf/core.c:1228)
> [<80391838>] (bpf_jit_free) from [<80392988>] (bpf_prog_free_deferred+0x14c/0x164 kernel/bpf/core.c:2783)
>  r5:84c30b54 r4:84c30800
> [<8039283c>] (bpf_prog_free_deferred) from [<8026678c>] (process_one_work+0x1b8/0x508 kernel/workqueue.c:3254)
>  r7:dddd00c0 r6:82c16000 r5:84c30b54 r4:84e60180
> [<802665d4>] (process_one_work) from [<802674b0>] (process_scheduled_works kernel/workqueue.c:3335 [inline])
> [<802665d4>] (process_one_work) from [<802674b0>] (worker_thread+0x1ec/0x418 kernel/workqueue.c:3416)
>  r10:84e76c00 r9:84e601ac r8:61c88647 r7:dddd00e0 r6:82604d40 r5:dddd00c0
>  r4:84e60180
> [<802672c4>] (worker_thread) from [<802701c4>] (kthread+0x104/0x134 kernel/kthread.c:388)
>  r10:00000000 r9:dfd11e90 r8:84eb4a40 r7:84e60180 r6:802672c4 r5:84e76c00
>  r4:84eb4e00
> [<802700c0>] (kthread) from [<80200104>] (ret_from_fork+0x14/0x30 arch/arm/kernel/entry-common.S:134)
> Exception stack(0xdff71fb0 to 0xdff71ff8)
> 1fa0:                                     00000000 00000000 00000000 00000000
> 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000
>  r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:802700c0 r4:84eb4e00
> INFO: task kworker/0:59:4311 blocked for more than 430 seconds.
>       Not tainted 6.9.0-rc2-syzkaller #0
> "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> task:kworker/0:59    state:D stack:0     pid:4311  tgid:4311  ppid:2      flags:0x00000000
> Workqueue: events bpf_prog_free_deferred
> Call trace: 
> [<8189be20>] (__schedule) from [<8189ca5c>] (__schedule_loop kernel/sched/core.c:6823 [inline])
> [<8189be20>] (__schedule) from [<8189ca5c>] (schedule+0x2c/0xfc kernel/sched/core.c:6838)
>  r10:82c16005 r9:00000000 r8:82714be8 r7:00000002 r6:dfb8dd94 r5:84e75400
>  r4:84e75400
> [<8189ca30>] (schedule) from [<8189d06c>] (schedule_preempt_disabled+0x18/0x24 kernel/sched/core.c:6895)
>  r5:84e75400 r4:82714be4
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock_common kernel/locking/mutex.c:684 [inline])
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock.constprop.0+0x2e8/0xae0 kernel/locking/mutex.c:752)
> [<8189f664>] (__mutex_lock.constprop.0) from [<818a0218>] (__mutex_lock_slowpath+0x14/0x18 kernel/locking/mutex.c:1040)
>  r10:82c16005 r9:dfb8de20 r8:00000000 r7:ffffffff r6:00000000 r5:84e5b5c0
>  r4:00000000
> [<818a0204>] (__mutex_lock_slowpath) from [<818a0258>] (mutex_lock+0x3c/0x40 kernel/locking/mutex.c:286)
> [<818a021c>] (mutex_lock) from [<8049c734>] (_vm_unmap_aliases+0x60/0x2e8 mm/vmalloc.c:2788)
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vm_reset_perms mm/vmalloc.c:3235 [inline])
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vfree+0x170/0x1e4 mm/vmalloc.c:3314)
>  r10:82c16005 r9:00000001 r8:00000000 r7:ffffffff r6:00000000 r5:84e5b5c0
>  r4:00000000
> [<804a0448>] (vfree) from [<802edb3c>] (module_memfree+0x30/0x50 kernel/module/main.c:1189)
>  r9:84e75400 r8:00000080 r7:00000000 r6:82c16000 r5:00001000 r4:7f03b000
> [<802edb0c>] (module_memfree) from [<803916e0>] (bpf_jit_free_exec+0x10/0x14 kernel/bpf/core.c:1058)
>  r5:00001000 r4:dfcc9000
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_binary_free kernel/bpf/core.c:1104 [inline])
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_free+0x68/0xe4 kernel/bpf/core.c:1228)
> [<80391838>] (bpf_jit_free) from [<80392988>] (bpf_prog_free_deferred+0x14c/0x164 kernel/bpf/core.c:2783)
>  r5:84e19b54 r4:84e19800
> [<8039283c>] (bpf_prog_free_deferred) from [<8026678c>] (process_one_work+0x1b8/0x508 kernel/workqueue.c:3254)
>  r7:dddd00c0 r6:82c16000 r5:84e19b54 r4:84e60280
> [<802665d4>] (process_one_work) from [<802674b0>] (process_scheduled_works kernel/workqueue.c:3335 [inline])
> [<802665d4>] (process_one_work) from [<802674b0>] (worker_thread+0x1ec/0x418 kernel/workqueue.c:3416)
>  r10:84e75400 r9:84e602ac r8:61c88647 r7:dddd00e0 r6:82604d40 r5:dddd00c0
>  r4:84e60280
> [<802672c4>] (worker_thread) from [<802701c4>] (kthread+0x104/0x134 kernel/kthread.c:388)
>  r10:00000000 r9:dff71e90 r8:84eb8c00 r7:84e60280 r6:802672c4 r5:84e75400
>  r4:84eb4380
> [<802700c0>] (kthread) from [<80200104>] (ret_from_fork+0x14/0x30 arch/arm/kernel/entry-common.S:134)
> Exception stack(0xdfb8dfb0 to 0xdfb8dff8)
> dfa0:                                     00000000 00000000 00000000 00000000
> dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> dfe0: 00000000 00000000 00000000 00000000 00000013 00000000
>  r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:802700c0 r4:84eb4380
> INFO: task kworker/0:60:4312 blocked for more than 430 seconds.
>       Not tainted 6.9.0-rc2-syzkaller #0
> "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> task:kworker/0:60    state:D stack:0     pid:4312  tgid:4312  ppid:2      flags:0x00000000
> Workqueue: events bpf_prog_free_deferred
> Call trace: 
> [<8189be20>] (__schedule) from [<8189ca5c>] (__schedule_loop kernel/sched/core.c:6823 [inline])
> [<8189be20>] (__schedule) from [<8189ca5c>] (schedule+0x2c/0xfc kernel/sched/core.c:6838)
>  r10:82c16005 r9:00000000 r8:82714be8 r7:00000002 r6:dffb1d94 r5:84e90c00
>  r4:84e90c00
> [<8189ca30>] (schedule) from [<8189d06c>] (schedule_preempt_disabled+0x18/0x24 kernel/sched/core.c:6895)
>  r5:84e90c00 r4:82714be4
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock_common kernel/locking/mutex.c:684 [inline])
> [<8189d054>] (schedule_preempt_disabled) from [<8189f94c>] (__mutex_lock.constprop.0+0x2e8/0xae0 kernel/locking/mutex.c:752)
> [<8189f664>] (__mutex_lock.constprop.0) from [<818a0218>] (__mutex_lock_slowpath+0x14/0x18 kernel/locking/mutex.c:1040)
>  r10:82c16005 r9:dffb1e20 r8:00000000 r7:ffffffff r6:00000000 r5:84e5b640
>  r4:00000000
> [<818a0204>] (__mutex_lock_slowpath) from [<818a0258>] (mutex_lock+0x3c/0x40 kernel/locking/mutex.c:286)
> [<818a021c>] (mutex_lock) from [<8049c734>] (_vm_unmap_aliases+0x60/0x2e8 mm/vmalloc.c:2788)
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vm_reset_perms mm/vmalloc.c:3235 [inline])
> [<8049c6d4>] (_vm_unmap_aliases) from [<804a05b8>] (vfree+0x170/0x1e4 mm/vmalloc.c:3314)
>  r10:82c16005 r9:00000001 r8:00000000 r7:ffffffff r6:00000000 r5:84e5b640
>  r4:00000000
> [<804a0448>] (vfree) from [<802edb3c>] (module_memfree+0x30/0x50 kernel/module/main.c:1189)
>  r9:84e90c00 r8:00000080 r7:00000000 r6:82c16000 r5:00001000 r4:7f03f000
> [<802edb0c>] (module_memfree) from [<803916e0>] (bpf_jit_free_exec+0x10/0x14 kernel/bpf/core.c:1058)
>  r5:00001000 r4:dfd63000
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_binary_free kernel/bpf/core.c:1104 [inline])
> [<803916d0>] (bpf_jit_free_exec) from [<803918a0>] (bpf_jit_free+0x68/0xe4 kernel/bpf/core.c:1228)
> [<80391838>] (bpf_jit_free) from [<80392988>] (bpf_prog_free_deferred+0x14c/0x164 kernel/bpf/core.c:2783)
>  r5:84ef0754 r4:84ef0400
> [<8039283c>] (bpf_prog_free_deferred) from [<8026678c>] (process_one_work+0x1b8/0x508 kernel/workqueue.c:3254)
>  r7:dddd00c0 r6:82c16000 r5:84ef0754 r4:84e60300
> [<802665d4>] (process_one_work) from [<802674b0>] (process_scheduled_works kernel/workqueue.c:3335 [inline])
> [<802665d4>] (process_one_work) from [<802674b0>] (worker_thread+0x1ec/0x418 kernel/workqueue.c:3416)
>  r10:84e90c00 r9:84e6032c r8:61c88647 r7:dddd00e0 r6:82604d40 r5:dddd00c0
>  r4:84e60300
> [<802672c4>] (worker_thread) from [<802701c4>] (kthread+0x104/0x134 kernel/kthread.c:388)
>  r10:00000000 r9:dfb8de90 r8:84eb8f40 r7:84e60300 r6:802672c4 r5:84e90c00
>  r4:84eb4300
> [<802700c0>] (kthread) from [<80200104>] (ret_from_fork+0x14/0x30 arch/arm/kernel/entry-common.S:134)
> Exception stack(0xdffb1fb0 to 0xdffb1ff8)
> 1fa0:                                     00000000 00000000 00000000 00000000
> 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000
>  r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:802700c0 r4:84eb4300
> Future hung task reports are suppressed, see sysctl kernel.hung_task_warnings
> NMI backtrace for cpu 0
> CPU: 0 PID: 31 Comm: khungtaskd Not tainted 6.9.0-rc2-syzkaller #0
> Hardware name: ARM-Versatile Express
> Call trace: 
> [<8187a69c>] (dump_backtrace) from [<8187a798>] (show_stack+0x18/0x1c arch/arm/kernel/traps.c:256)
>  r7:00000000 r6:00000013 r5:60000093 r4:81fc48fc
> [<8187a780>] (show_stack) from [<81897f54>] (__dump_stack lib/dump_stack.c:88 [inline])
> [<8187a780>] (show_stack) from [<81897f54>] (dump_stack_lvl+0x70/0x7c lib/dump_stack.c:114)
> [<81897ee4>] (dump_stack_lvl) from [<81897f78>] (dump_stack+0x18/0x1c lib/dump_stack.c:123)
>  r5:00000000 r4:00000001
> [<81897f60>] (dump_stack) from [<81867a74>] (nmi_cpu_backtrace+0x160/0x17c lib/nmi_backtrace.c:113)
> [<81867914>] (nmi_cpu_backtrace) from [<81867bc0>] (nmi_trigger_cpumask_backtrace+0x130/0x1d8 lib/nmi_backtrace.c:62)
>  r7:00000000 r6:8260c590 r5:8261a88c r4:ffffffff
> [<81867a90>] (nmi_trigger_cpumask_backtrace) from [<802105b4>] (arch_trigger_cpumask_backtrace+0x18/0x1c arch/arm/kernel/smp.c:851)
>  r9:8260c6f4 r8:000076c2 r7:8289dfe0 r6:00007d59 r5:8514be04 r4:850f5d24
> [<8021059c>] (arch_trigger_cpumask_backtrace) from [<8034ec78>] (trigger_all_cpu_backtrace include/linux/nmi.h:160 [inline])
> [<8021059c>] (arch_trigger_cpumask_backtrace) from [<8034ec78>] (check_hung_uninterruptible_tasks kernel/hung_task.c:223 [inline])
> [<8021059c>] (arch_trigger_cpumask_backtrace) from [<8034ec78>] (watchdog+0x480/0x594 kernel/hung_task.c:380)
> [<8034e7f8>] (watchdog) from [<802701c4>] (kthread+0x104/0x134 kernel/kthread.c:388)
>  r10:00000000 r9:df819e58 r8:82e98340 r7:00000000 r6:8034e7f8 r5:82ee8c00
>  r4:82f41200
> [<802700c0>] (kthread) from [<80200104>] (ret_from_fork+0x14/0x30 arch/arm/kernel/entry-common.S:134)
> Exception stack(0xdf8ddfb0 to 0xdf8ddff8)
> dfa0:                                     00000000 00000000 00000000 00000000
> dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> dfe0: 00000000 00000000 00000000 00000000 00000013 00000000
>  r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:802700c0 r4:82f41200
> Sending NMI from CPU 0 to CPUs 1:
> NMI backtrace for cpu 1
> CPU: 1 PID: 6890 Comm: syz-executor.0 Not tainted 6.9.0-rc2-syzkaller #0
> Hardware name: ARM-Versatile Express
> PC is at kmap_local_sched_in kernel/sched/core.c:5189 [inline]
> PC is at finish_task_switch+0x8c/0x298 kernel/sched/core.c:5291
> LR is at __raw_spin_unlock include/linux/spinlock_api_smp.h:143 [inline]
> LR is at _raw_spin_unlock+0x2c/0x50 kernel/locking/spinlock.c:186
> pc : [<8027cd4c>]    lr : [<818a4f88>]    psr: 20000113
> sp : eb539ab8  ip : eb539aa8  fp : eb539afc
> r10: 00000402  r9 : 8514bc00  r8 : 82e33000
> r7 : a3e9c050  r6 : 8189c228  r5 : ddde4440  r4 : 00000000
> r3 : 8514bc00  r2 : 00000001  r1 : 81fc48fc  r0 : 00000001
> Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
> Control: 30c5387d  Table: 851ca6c0  DAC: 00000000
> Call trace: 
> [<8027ccc0>] (finish_task_switch) from [<8189c228>] (context_switch kernel/sched/core.c:5412 [inline])
> [<8027ccc0>] (finish_task_switch) from [<8189c228>] (__schedule+0x408/0xc10 kernel/sched/core.c:6746)
>  r10:00000000 r9:84df6400 r8:a69b624b r7:a3e9c050 r6:8514bc00 r5:ddde4440
>  r4:82e33000
> [<8189be20>] (__schedule) from [<8189d0b8>] (preempt_schedule_irq+0x40/0xa8 kernel/sched/core.c:7068)
>  r10:eb539db0 r9:8514bc00 r8:80200b9c r7:eb539bbc r6:ffffffff r5:8514bc00
>  r4:00000000
> [<8189d078>] (preempt_schedule_irq) from [<80200bb4>] (svc_preempt+0x8/0x18)
> Exception stack(0xeb539b88 to 0xeb539bd0)
> 9b80:                   000f1b1e 003ff40e 0000071f 00000000 00000000 8514bc00
> 9ba0: 00000598 0000071f 000f1b1e 00000000 eb539db0 eb539bf4 eb539bf8 eb539bd8
> 9bc0: 80479eb8 8027f380 60000113 ffffffff
>  r5:60000113 r4:8027f380
> [<8027f354>] (migrate_disable) from [<80479eb8>] (__kmap_local_pfn_prot+0x20/0x1ac mm/highmem.c:548)
>  r7:0000071f r6:00c00000 r5:dedf605c r4:00000000
> [<80479e98>] (__kmap_local_pfn_prot) from [<8047a0b4>] (__kmap_local_page_prot mm/highmem.c:581 [inline])
> [<80479e98>] (__kmap_local_pfn_prot) from [<8047a0b4>] (__kmap_local_page_prot+0x70/0x74 mm/highmem.c:564)
>  r8:00000001 r7:828584e8 r6:00000001 r5:dedf605c r4:00000000
> [<8047a044>] (__kmap_local_page_prot) from [<804a23ec>] (kmap_local_page include/linux/highmem-internal.h:73 [inline])
> [<8047a044>] (__kmap_local_page_prot) from [<804a23ec>] (clear_highpage_kasan_tagged include/linux/highmem.h:246 [inline])
> [<8047a044>] (__kmap_local_page_prot) from [<804a23ec>] (kernel_init_pages+0x3c/0x60 mm/page_alloc.c:1080)
> [<804a23b0>] (kernel_init_pages) from [<804a52d4>] (post_alloc_hook+0x88/0xc0 mm/page_alloc.c:1532)
>  r9:00000000 r8:827e21bc r7:00000001 r6:00000001 r5:dedf6038 r4:00000000
> [<804a524c>] (post_alloc_hook) from [<804a7968>] (prep_new_page mm/page_alloc.c:1541 [inline])
> [<804a524c>] (post_alloc_hook) from [<804a7968>] (get_page_from_freelist+0x28c/0x13d8 mm/page_alloc.c:3317)
>  r7:8514bc00 r6:827e1f00 r5:00000000 r4:00540dc2
> [<804a76dc>] (get_page_from_freelist) from [<804a8fe4>] (__alloc_pages+0xe0/0x1168 mm/page_alloc.c:4575)
>  r10:00000000 r9:84df6400 r8:20000000 r7:8514bc00 r6:00440dc2 r5:00540dc2
>  r4:00000000
> [<804a8f04>] (__alloc_pages) from [<8047b688>] (__alloc_pages_node include/linux/gfp.h:238 [inline])
> [<804a8f04>] (__alloc_pages) from [<8047b688>] (alloc_pages_node include/linux/gfp.h:261 [inline])
> [<804a8f04>] (__alloc_pages) from [<8047b688>] (alloc_pages include/linux/gfp.h:274 [inline])
> [<804a8f04>] (__alloc_pages) from [<8047b688>] (pagetable_alloc include/linux/mm.h:2862 [inline])
> [<804a8f04>] (__alloc_pages) from [<8047b688>] (__pte_alloc_one include/asm-generic/pgalloc.h:68 [inline])
> [<804a8f04>] (__alloc_pages) from [<8047b688>] (pte_alloc_one+0x24/0xf8 arch/arm/include/asm/pgalloc.h:99)
>  r10:00000040 r9:84df6400 r8:20000000 r7:84db6000 r6:20000000 r5:85268800
>  r4:84df6400
> [<8047b664>] (pte_alloc_one) from [<8047cc70>] (__pte_alloc+0x2c/0x108 mm/memory.c:440)
>  r5:85268800 r4:84df6400
> [<8047cc44>] (__pte_alloc) from [<80481b10>] (do_anonymous_page mm/memory.c:4402 [inline])
> [<8047cc44>] (__pte_alloc) from [<80481b10>] (do_pte_missing mm/memory.c:3878 [inline])
> [<8047cc44>] (__pte_alloc) from [<80481b10>] (handle_pte_fault mm/memory.c:5300 [inline])
> [<8047cc44>] (__pte_alloc) from [<80481b10>] (__handle_mm_fault mm/memory.c:5441 [inline])
> [<8047cc44>] (__pte_alloc) from [<80481b10>] (handle_mm_fault+0xfac/0x12b8 mm/memory.c:5606)
>  r5:8514bc00 r4:00000255
> [<80480b64>] (handle_mm_fault) from [<80215d94>] (do_page_fault+0x148/0x3a8 arch/arm/mm/fault.c:333)
>  r10:00000002 r9:84df6400 r8:20000000 r7:00000a06 r6:00000255 r5:20000000
>  r4:eb539fb0
> [<80215c4c>] (do_page_fault) from [<80216174>] (do_translation_fault+0xfc/0x12c arch/arm/mm/fault.c:444)
>  r10:7ee33670 r9:7ee33670 r8:80216078 r7:eb539fb0 r6:20000000 r5:00000a06
>  r4:8261d0d0
> [<80216078>] (do_translation_fault) from [<802161dc>] (do_DataAbort+0x38/0xa8 arch/arm/mm/fault.c:565)
>  r9:7ee33670 r8:80216078 r7:eb539fb0 r6:20000000 r5:00000a06 r4:8261d0d0
> [<802161a4>] (do_DataAbort) from [<80200e3c>] (__dabt_usr+0x5c/0x60 arch/arm/kernel/entry-armv.S:427)
> Exception stack(0xeb539fb0 to 0xeb539ff8)
> 9fa0:                                     00000000 00000000 00000001 20000000
> 9fc0: 00000004 00000000 00000000 00000000 fffffffe 7ee33670 7ee33670 7ee33630
> 9fe0: 01068590 7ee333a8 0001d150 0001d4ac 40000010 ffffffff
>  r8:824a9044 r7:8514bc00 r6:ffffffff r5:40000010 r4:0001d4ac
>
>
> Tested on:
>
> commit:         2929be95 arm32, bpf: Fix sign-extension mov instruction
> git tree:       https://github.com/puranjaymohan/linux.git arm32_movsx_fix
> console output: https://syzkaller.appspot.com/x/log.txt?x=11362cf3180000
> kernel config:  https://syzkaller.appspot.com/x/.config?x=10acd270ef193b93
> dashboard link: https://syzkaller.appspot.com/bug?extid=186522670e6722692d86
> compiler:       arm-linux-gnueabi-gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40
> userspace arch: arm
>
> Note: no patches were applied.

I gave it the bpf.git tree maybe that is the reason for the above??
Should have given the upstream tree with the exact commit where it was
reproduced earlier.

Let's try again, I pushed the correct tree now:

#syz test: https://github.com/puranjaymohan/linux.git arm32_movsx_fix

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 00/13] drm/display: Convert helpers Kconfig symbols to depends on
From: Jani Nikula @ 2024-04-09 11:12 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Maxime Ripard, Maarten Lankhorst, Thomas Zimmermann, David Airlie,
	Daniel Vetter, dri-devel, Lucas De Marchi, kernel test robot,
	linux-renesas-soc, linux-arm-kernel, linux-kbuild
In-Reply-To: <CAMuHMdVMhXFm-kZ50Un1ZFmEcjJ7SnpyEyw65-wucBGpVRUFww@mail.gmail.com>

On Tue, 09 Apr 2024, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> Hi Jani,
>
> On Tue, Apr 9, 2024 at 12:04 PM Jani Nikula <jani.nikula@linux.intel.com> wrote:
>> On Tue, 09 Apr 2024, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>> > The user should not need to know which helpers are needed for the driver
>> > he is interested in.  When a symbol selects another symbol, it should
>> > just make sure the dependencies of the target symbol are met.
>>
>> It's really not "just make sure". This leads to perpetual illegal
>> configurations, and duct tape fixes. Select should not be used for
>> visible symbols or symbols with dependencies [1].
>
> In other words: none of these helpers should be visible...

...and should have no dependencies? :p

>
>> What we'd need for usability is not more abuse of select, but rather 1)
>> warnings for selecting symbols with dependencies, and 2) a way to enable
>
> Kconfig already warns if dependencies of selected symbols are not met.

But it does lead to cases where a builtin tries to use a symbol from a
module, failing at link time, not config time. Then I regularly see
patches trying to fix this with IS_REACHABLE(), making it a silent
runtime failure instead, when it should've been a config issue.

>> a kconfig option with all its dependencies, recursively. This is what we
>> lack.
>
> You cannot force-enable all dependencies of the target symbol, as some
> of these dependencies may be impossible to meet on the system you are
> configuring a kernel for.

Surely kconfig should be able to figure out if they're possible or not.

> The current proper way is to add these dependencies to the source
> symbol, which is what we have been doing everywhere else.  Another
> solution may be to teach Kconfig to ignore any symbols that select a
> symbol with unmet dependencies.

...

It seems like your main argument in favour of using select is that it's
more convenient for people who configure the kernel. Because the user
should be able to just enable a driver, and that would select everything
that's needed. But where do we draw the line? Then what qualifies for
"depends on"?

Look at config DRM_I915 and where select abuse has lead us. Like, why
don't we just select DRM, PCI and X86 as well instead of depend. :p

A lot of things we have to select because it appears to generally be the
case that if some places select and some places depends on a symbol,
it'll lead to circular dependencies.

Sure there may be a usability issue with using depends on. But the
proper fix isn't hacking in kconfig files, it's to fix the usability in
kconfig the tool UI. But nobody steps up, because at least I find the
kconfig source to be inpenetrable. I've tried many times, and given up.

I mean, if you want to enable a driver D, it could, at a minimum, show
you a tree of (possibly alternative) things you also need to enable. But
if the dependencies aren't there, you won't even see the config for
D. That's not something that should be "fixed" by abusing select in
kconfig files.


BR,
Jani.


-- 
Jani Nikula, Intel

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2 1/7] arm64: mm: cleanup __do_page_fault()
From: Catalin Marinas @ 2024-04-09 11:14 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: akpm, Russell King, Will Deacon, Michael Ellerman,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Alexander Gordeev, Gerald Schaefer, Dave Hansen,
	Andy Lutomirski, Peter Zijlstra, x86, linux-arm-kernel,
	linuxppc-dev, linux-riscv, linux-s390, surenb, linux-mm
In-Reply-To: <20240403083805.1818160-2-wangkefeng.wang@huawei.com>

On Wed, Apr 03, 2024 at 04:37:59PM +0800, Kefeng Wang wrote:
> The __do_page_fault() only calls handle_mm_fault() after vm_flags
> checked, and it is only called by do_page_fault(), let's squash
> it into do_page_fault() to cleanup code.
> 
> Reviewed-by: Suren Baghdasaryan <surenb@google.com>
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>

As I reviewed v1 and the changes are minimal:

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2 2/7] arm64: mm: accelerate pagefault when VM_FAULT_BADACCESS
From: Catalin Marinas @ 2024-04-09 11:15 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: akpm, Russell King, Will Deacon, Michael Ellerman,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Alexander Gordeev, Gerald Schaefer, Dave Hansen,
	Andy Lutomirski, Peter Zijlstra, x86, linux-arm-kernel,
	linuxppc-dev, linux-riscv, linux-s390, surenb, linux-mm
In-Reply-To: <20240403083805.1818160-3-wangkefeng.wang@huawei.com>

On Wed, Apr 03, 2024 at 04:38:00PM +0800, Kefeng Wang wrote:
> The vm_flags of vma already checked under per-VMA lock, if it is a
> bad access, directly set fault to VM_FAULT_BADACCESS and handle error,
> no need to retry with mmap_lock again, the latency time reduces 34% in
> 'lat_sig -P 1 prot lat_sig' from lmbench testcase.
> 
> Since the page faut is handled under per-VMA lock, count it as a vma lock
> event with VMA_LOCK_SUCCESS.
> 
> Reviewed-by: Suren Baghdasaryan <surenb@google.com>
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v2 04/18] ASoC: dt-bindings: mt6357: Add audio codec document
From: Alexandre Mergnat @ 2024-04-09 10:13 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Lee Jones, Flora Fu, Jaroslav Kysela, Takashi Iwai, Sumit Semwal,
	Christian König, Catalin Marinas, Will Deacon, Rob Herring
  Cc: linux-sound, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-media, dri-devel, linaro-mm-sig,
	Alexandre Mergnat
In-Reply-To: <20240226-audio-i350-v2-0-3043d483de0d@baylibre.com>

Add MT8365 audio codec bindings to set required
and optional voltage properties between the codec and the board.
The properties are:
- phandle of the requiered power supply.
- Setup of microphone bias voltage.
- Setup of the speaker pin pull-down.

Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
---
 .../devicetree/bindings/sound/mt6357.yaml          | 54 ++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/mt6357.yaml b/Documentation/devicetree/bindings/sound/mt6357.yaml
new file mode 100644
index 000000000000..f532a9e7dff5
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt6357.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/mt6357.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT6357 Codec
+
+maintainers:
+  - Alexandre Mergnat <amergnat@baylibre.com>
+
+description: |
+  This is the required and optional voltage properties for this subdevice.
+  The communication between MT6357 and SoC is through Mediatek PMIC wrapper.
+  For more detail, please visit Mediatek PMIC wrapper documentation.
+  Must be a child node of PMIC wrapper.
+
+properties:
+  vaud28-supply:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: 2.8 volt supply for the audio codec
+
+  mediatek,hp-pull-down:
+    description:
+      Earphone driver positive output stage short to
+      the audio reference ground.
+    type: boolean
+
+  mediatek,micbias0-microvolt:
+    description: Selects MIC Bias 0 output voltage.
+    enum: [1700000, 1800000, 1900000, 2000000,
+           2100000, 2500000, 2600000, 2700000]
+    default: 1700000
+
+  mediatek,micbias1-microvolt:
+    description: Selects MIC Bias 1 output voltage.
+    enum: [1700000, 1800000, 1900000, 2000000,
+           2100000, 2500000, 2600000, 2700000]
+    default: 1700000
+
+required:
+  - vaud28-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    codec {
+        vaud28-supply = <&mt6357_vaud28_reg>;
+        mediatek,micbias0-microvolt = <1900000>;
+        mediatek,micbias1-microvolt = <1700000>;
+    };
+
+...

-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v2 16/18] arm64: dts: mediatek: add mt6357 audio codec support
From: Alexandre Mergnat @ 2024-04-09 10:13 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Lee Jones, Flora Fu, Jaroslav Kysela, Takashi Iwai, Sumit Semwal,
	Christian König, Catalin Marinas, Will Deacon, Rob Herring
  Cc: linux-sound, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-media, dri-devel, linaro-mm-sig,
	Alexandre Mergnat
In-Reply-To: <20240226-audio-i350-v2-0-3043d483de0d@baylibre.com>

Add audio codec support of MT6357 PMIC.
Update the file header.

Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
---
 arch/arm64/boot/dts/mediatek/mt6357.dtsi | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt6357.dtsi b/arch/arm64/boot/dts/mediatek/mt6357.dtsi
index 3330a03c2f74..ade410851524 100644
--- a/arch/arm64/boot/dts/mediatek/mt6357.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6357.dtsi
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Copyright (c) 2020 MediaTek Inc.
- * Copyright (c) 2023 BayLibre Inc.
+ * Copyright (c) 2024 BayLibre Inc.
  */
 
 #include <dt-bindings/input/input.h>
@@ -10,6 +10,9 @@ &pwrap {
 	mt6357_pmic: pmic {
 		compatible = "mediatek,mt6357";
 
+		mt6357_codec: codec {
+		};
+
 		regulators {
 			mt6357_vproc_reg: buck-vproc {
 				regulator-name = "vproc";

-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v2 03/18] dt-bindings: mfd: mediatek: Add codec property for MT6357 PMIC
From: Alexandre Mergnat @ 2024-04-09 10:13 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Lee Jones, Flora Fu, Jaroslav Kysela, Takashi Iwai, Sumit Semwal,
	Christian König, Catalin Marinas, Will Deacon, Rob Herring
  Cc: linux-sound, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-media, dri-devel, linaro-mm-sig,
	Alexandre Mergnat
In-Reply-To: <20240226-audio-i350-v2-0-3043d483de0d@baylibre.com>

Add the audio codec sub-device. This sub-device is used to set required
and optional voltage properties between the codec and the board.

Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
---
 Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml b/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml
index 37423c2e0fdf..7c6a4a587b5f 100644
--- a/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml
+++ b/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml
@@ -37,6 +37,11 @@ properties:
   "#interrupt-cells":
     const: 2
 
+  codec:
+    type: object
+    $ref: /schemas/sound/mt6357.yaml
+    unevaluatedProperties: false
+
   regulators:
     type: object
     $ref: /schemas/regulator/mediatek,mt6357-regulator.yaml

-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v2 10/18] ASoC: mediatek: mt8365: Add PCM DAI support
From: Alexandre Mergnat @ 2024-04-09 10:13 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Lee Jones, Flora Fu, Jaroslav Kysela, Takashi Iwai, Sumit Semwal,
	Christian König, Catalin Marinas, Will Deacon, Rob Herring
  Cc: linux-sound, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-media, dri-devel, linaro-mm-sig,
	Alexandre Mergnat
In-Reply-To: <20240226-audio-i350-v2-0-3043d483de0d@baylibre.com>

Add Pulse Code Modulation Device Audio Interface support for MT8365 SoC.

Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
---
 sound/soc/mediatek/mt8365/mt8365-dai-pcm.c | 293 +++++++++++++++++++++++++++++
 1 file changed, 293 insertions(+)

diff --git a/sound/soc/mediatek/mt8365/mt8365-dai-pcm.c b/sound/soc/mediatek/mt8365/mt8365-dai-pcm.c
new file mode 100644
index 000000000000..a5de47c69620
--- /dev/null
+++ b/sound/soc/mediatek/mt8365/mt8365-dai-pcm.c
@@ -0,0 +1,293 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek 8365 ALSA SoC Audio DAI PCM Control
+ *
+ * Copyright (c) 2024 MediaTek Inc.
+ * Authors: Jia Zeng <jia.zeng@mediatek.com>
+ *          Alexandre Mergnat <amergnat@baylibre.com>
+ */
+
+#include <linux/bitops.h>
+#include <linux/regmap.h>
+#include <sound/pcm_params.h>
+#include "mt8365-afe-clk.h"
+#include "mt8365-afe-common.h"
+
+struct mt8365_pcm_intf_data {
+	bool slave_mode;
+	bool lrck_inv;
+	bool bck_inv;
+	unsigned int format;
+};
+
+/* DAI Drivers */
+
+static void mt8365_dai_enable_pcm1(struct mtk_base_afe *afe)
+{
+	regmap_update_bits(afe->regmap, PCM_INTF_CON1,
+			   PCM_INTF_CON1_EN, PCM_INTF_CON1_EN);
+}
+
+static void mt8365_dai_disable_pcm1(struct mtk_base_afe *afe)
+{
+	regmap_update_bits(afe->regmap, PCM_INTF_CON1,
+			   PCM_INTF_CON1_EN, 0x0);
+}
+
+static int mt8365_dai_configure_pcm1(struct snd_pcm_substream *substream,
+				     struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8365_afe_private *afe_priv = afe->platform_priv;
+	struct mt8365_pcm_intf_data *pcm_priv = afe_priv->dai_priv[MT8365_AFE_IO_PCM1];
+	bool slave_mode = pcm_priv->slave_mode;
+	bool lrck_inv = pcm_priv->lrck_inv;
+	bool bck_inv = pcm_priv->bck_inv;
+	unsigned int fmt = pcm_priv->format;
+	unsigned int bit_width = dai->sample_bits;
+	unsigned int val = 0;
+
+	if (!slave_mode) {
+		val |= PCM_INTF_CON1_MASTER_MODE |
+		       PCM_INTF_CON1_BYPASS_ASRC;
+
+		if (lrck_inv)
+			val |= PCM_INTF_CON1_SYNC_OUT_INV;
+		if (bck_inv)
+			val |= PCM_INTF_CON1_BCLK_OUT_INV;
+	} else {
+		val |= PCM_INTF_CON1_SLAVE_MODE;
+
+		if (lrck_inv)
+			val |= PCM_INTF_CON1_SYNC_IN_INV;
+		if (bck_inv)
+			val |= PCM_INTF_CON1_BCLK_IN_INV;
+
+		// TODO: add asrc setting
+	}
+
+	val |= FIELD_PREP(PCM_INTF_CON1_FORMAT_MASK, fmt);
+
+	if (fmt == MT8365_PCM_FORMAT_PCMA ||
+	    fmt == MT8365_PCM_FORMAT_PCMB)
+		val |= PCM_INTF_CON1_SYNC_LEN(1);
+	else
+		val |= PCM_INTF_CON1_SYNC_LEN(bit_width);
+
+	switch (substream->runtime->rate) {
+	case 48000:
+		val |= PCM_INTF_CON1_FS_48K;
+		break;
+	case 32000:
+		val |= PCM_INTF_CON1_FS_32K;
+		break;
+	case 16000:
+		val |= PCM_INTF_CON1_FS_16K;
+		break;
+	case 8000:
+		val |= PCM_INTF_CON1_FS_8K;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (bit_width > 16)
+		val |= PCM_INTF_CON1_24BIT | PCM_INTF_CON1_64BCK;
+	else
+		val |= PCM_INTF_CON1_16BIT | PCM_INTF_CON1_32BCK;
+
+	val |= PCM_INTF_CON1_EXT_MODEM;
+
+	regmap_update_bits(afe->regmap, PCM_INTF_CON1,
+			   PCM_INTF_CON1_CONFIG_MASK, val);
+
+	return 0;
+}
+
+static int mt8365_dai_pcm1_startup(struct snd_pcm_substream *substream,
+				   struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+
+	if (snd_soc_dai_active(dai))
+		return 0;
+
+	mt8365_afe_enable_main_clk(afe);
+
+	return 0;
+}
+
+static void mt8365_dai_pcm1_shutdown(struct snd_pcm_substream *substream,
+				     struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+
+	if (snd_soc_dai_active(dai))
+		return;
+
+	mt8365_dai_disable_pcm1(afe);
+	mt8365_afe_disable_main_clk(afe);
+}
+
+static int mt8365_dai_pcm1_prepare(struct snd_pcm_substream *substream,
+				   struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	int ret;
+
+	if ((snd_soc_dai_stream_active_playback(dai) +
+	    snd_soc_dai_stream_active_capture(dai)) > 1) {
+		dev_info(afe->dev, "%s '%s' active(%u-%u) already\n",
+			 __func__, snd_pcm_stream_str(substream),
+			 snd_soc_dai_stream_active_playback(dai),
+			 snd_soc_dai_stream_active_capture(dai));
+		return 0;
+	}
+
+	ret = mt8365_dai_configure_pcm1(substream, dai);
+	if (ret)
+		return ret;
+
+	mt8365_dai_enable_pcm1(afe);
+
+	return 0;
+}
+
+static int mt8365_dai_pcm1_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8365_afe_private *afe_priv = afe->platform_priv;
+	struct mt8365_pcm_intf_data *pcm_priv = afe_priv->dai_priv[MT8365_AFE_IO_PCM1];
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		pcm_priv->format = MT8365_PCM_FORMAT_I2S;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+		pcm_priv->bck_inv = false;
+		pcm_priv->lrck_inv = false;
+		break;
+	case SND_SOC_DAIFMT_NB_IF:
+		pcm_priv->bck_inv = false;
+		pcm_priv->lrck_inv = true;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		pcm_priv->bck_inv = true;
+		pcm_priv->lrck_inv = false;
+		break;
+	case SND_SOC_DAIFMT_IB_IF:
+		pcm_priv->bck_inv = true;
+		pcm_priv->lrck_inv = true;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+		pcm_priv->slave_mode = true;
+		break;
+	case SND_SOC_DAIFMT_CBS_CFS:
+		pcm_priv->slave_mode = false;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops mt8365_dai_pcm1_ops = {
+	.startup	= mt8365_dai_pcm1_startup,
+	.shutdown	= mt8365_dai_pcm1_shutdown,
+	.prepare	= mt8365_dai_pcm1_prepare,
+	.set_fmt	= mt8365_dai_pcm1_set_fmt,
+};
+
+static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = {
+	{
+		.name = "PCM1",
+		.id = MT8365_AFE_IO_PCM1,
+		.playback = {
+			.stream_name = "PCM1 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_8000 |
+				 SNDRV_PCM_RATE_16000 |
+				 SNDRV_PCM_RATE_32000 |
+				 SNDRV_PCM_RATE_48000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE |
+				   SNDRV_PCM_FMTBIT_S32_LE,
+		},
+		.capture = {
+			.stream_name = "PCM1 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_8000 |
+				 SNDRV_PCM_RATE_16000 |
+				 SNDRV_PCM_RATE_32000 |
+				 SNDRV_PCM_RATE_48000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE |
+				   SNDRV_PCM_FMTBIT_S32_LE,
+		},
+		.ops = &mt8365_dai_pcm1_ops,
+		.symmetric_rate = 1,
+		.symmetric_sample_bits = 1,
+	}
+};
+
+/* DAI widget */
+
+static const struct snd_soc_dapm_widget mtk_dai_pcm_widgets[] = {
+	SND_SOC_DAPM_OUTPUT("PCM1 Out"),
+	SND_SOC_DAPM_INPUT("PCM1 In"),
+};
+
+/* DAI route */
+
+static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = {
+	{"PCM1 Playback", NULL, "O07"},
+	{"PCM1 Playback", NULL, "O08"},
+	{"PCM1 Out", NULL, "PCM1 Playback"},
+
+	{"I09", NULL, "PCM1 Capture"},
+	{"I22", NULL, "PCM1 Capture"},
+	{"PCM1 Capture", NULL, "PCM1 In"},
+};
+
+static int init_pcmif_priv_data(struct mtk_base_afe *afe)
+{
+	struct mt8365_afe_private *afe_priv = afe->platform_priv;
+	struct mt8365_pcm_intf_data *pcmif_priv;
+
+	pcmif_priv = devm_kzalloc(afe->dev, sizeof(struct mt8365_pcm_intf_data),
+				  GFP_KERNEL);
+	if (!pcmif_priv)
+		return -ENOMEM;
+
+	afe_priv->dai_priv[MT8365_AFE_IO_PCM1] = pcmif_priv;
+	return 0;
+}
+
+int mt8365_dai_pcm_register(struct mtk_base_afe *afe)
+{
+	struct mtk_base_afe_dai *dai;
+
+	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+	if (!dai)
+		return -ENOMEM;
+
+	list_add(&dai->list, &afe->sub_dais);
+	dai->dai_drivers = mtk_dai_pcm_driver;
+	dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_pcm_driver);
+	dai->dapm_widgets = mtk_dai_pcm_widgets;
+	dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_pcm_widgets);
+	dai->dapm_routes = mtk_dai_pcm_routes;
+	dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_pcm_routes);
+	return init_pcmif_priv_data(afe);
+}

-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v2 17/18] arm64: dts: mediatek: add afe support for mt8365 SoC
From: Alexandre Mergnat @ 2024-04-09 10:13 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Lee Jones, Flora Fu, Jaroslav Kysela, Takashi Iwai, Sumit Semwal,
	Christian König, Catalin Marinas, Will Deacon, Rob Herring
  Cc: linux-sound, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-media, dri-devel, linaro-mm-sig,
	Alexandre Mergnat
In-Reply-To: <20240226-audio-i350-v2-0-3043d483de0d@baylibre.com>

Add audio front end support of MT8365 SoC.
Update the file header.

Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
---
 arch/arm64/boot/dts/mediatek/mt8365.dtsi | 46 +++++++++++++++++++++++++++++---
 1 file changed, 43 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8365.dtsi b/arch/arm64/boot/dts/mediatek/mt8365.dtsi
index 24581f7410aa..0bb6f6388bb8 100644
--- a/arch/arm64/boot/dts/mediatek/mt8365.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8365.dtsi
@@ -1,10 +1,12 @@
 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * (C) 2018 MediaTek Inc.
- * Copyright (C) 2022 BayLibre SAS
- * Fabien Parent <fparent@baylibre.com>
- * Bernhard Rosenkränzer <bero@baylibre.com>
+ * Copyright (C) 2024 BayLibre SAS
+ * Authors: Fabien Parent <fparent@baylibre.com>
+ *	    Bernhard Rosenkränzer <bero@baylibre.com>
+ *	    Alexandre Mergnat <amergnat@baylibre.com>
  */
+
 #include <dt-bindings/clock/mediatek,mt8365-clk.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
@@ -813,6 +815,44 @@ apu: syscon@19020000 {
 			reg = <0 0x19020000 0 0x1000>;
 			#clock-cells = <1>;
 		};
+
+		afe: audio-controller@11220000 {
+			compatible = "mediatek,mt8365-afe-pcm";
+			reg = <0 0x11220000 0 0x1000>;
+			#sound-dai-cells = <0>;
+			clocks = <&clk26m>,
+				 <&topckgen CLK_TOP_AUDIO_SEL>,
+				 <&topckgen CLK_TOP_AUD_I2S0_M>,
+				 <&topckgen CLK_TOP_AUD_I2S1_M>,
+				 <&topckgen CLK_TOP_AUD_I2S2_M>,
+				 <&topckgen CLK_TOP_AUD_I2S3_M>,
+				 <&topckgen CLK_TOP_AUD_ENGEN1_SEL>,
+				 <&topckgen CLK_TOP_AUD_ENGEN2_SEL>,
+				 <&topckgen CLK_TOP_AUD_1_SEL>,
+				 <&topckgen CLK_TOP_AUD_2_SEL>,
+				 <&topckgen CLK_TOP_APLL_I2S0_SEL>,
+				 <&topckgen CLK_TOP_APLL_I2S1_SEL>,
+				 <&topckgen CLK_TOP_APLL_I2S2_SEL>,
+				 <&topckgen CLK_TOP_APLL_I2S3_SEL>;
+			clock-names = "top_clk26m_clk",
+				      "top_audio_sel",
+				      "audio_i2s0_m",
+				      "audio_i2s1_m",
+				      "audio_i2s2_m",
+				      "audio_i2s3_m",
+				      "engen1",
+				      "engen2",
+				      "aud1",
+				      "aud2",
+				      "i2s0_m_sel",
+				      "i2s1_m_sel",
+				      "i2s2_m_sel",
+				      "i2s3_m_sel";
+			interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_LOW>;
+			power-domains = <&spm MT8365_POWER_DOMAIN_AUDIO>;
+			mediatek,topckgen = <&topckgen>;
+			status = "disabled";
+		};
 	};
 
 	timer {

-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v2 13/18] ASoC: codecs: add MT6357 support
From: amergnat @ 2024-04-09 10:13 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Lee Jones, Flora Fu, Jaroslav Kysela, Takashi Iwai, Sumit Semwal,
	Christian König, Catalin Marinas, Will Deacon, Rob Herring
  Cc: linux-sound, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-media, dri-devel, linaro-mm-sig,
	Alexandre Mergnat, Nicolas Belin
In-Reply-To: <20240226-audio-i350-v2-0-3043d483de0d@baylibre.com>

From: Nicolas Belin <nbelin@baylibre.com>

Add the support of MT6357 PMIC audio codec.

Signed-off-by: Nicolas Belin <nbelin@baylibre.com>
Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
---
 sound/soc/codecs/Kconfig  |    7 +
 sound/soc/codecs/Makefile |    2 +
 sound/soc/codecs/mt6357.c | 1898 +++++++++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/mt6357.h |  662 ++++++++++++++++
 4 files changed, 2569 insertions(+)

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 1752814fffdd..7742445f7b7b 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -154,6 +154,7 @@ config SND_SOC_ALL_CODECS
 	imply SND_SOC_MC13783
 	imply SND_SOC_ML26124
 	imply SND_SOC_MT6351
+	imply SND_SOC_MT6357
 	imply SND_SOC_MT6358
 	imply SND_SOC_MT6359
 	imply SND_SOC_MT6660
@@ -2421,6 +2422,12 @@ config SND_SOC_ML26124
 config SND_SOC_MT6351
 	tristate "MediaTek MT6351 Codec"
 
+config SND_SOC_MT6357
+	tristate "MediaTek MT6357 Codec"
+	help
+	  Enable support for the platform which uses MT6357 as
+	  external codec device.
+
 config SND_SOC_MT6358
 	tristate "MediaTek MT6358 Codec"
 	help
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 9ba24fb870b1..d43a6065706c 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -172,6 +172,7 @@ snd-soc-ml26124-objs := ml26124.o
 snd-soc-msm8916-analog-objs := msm8916-wcd-analog.o
 snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o
 snd-soc-mt6351-objs := mt6351.o
+snd-soc-mt6357-objs := mt6357.o
 snd-soc-mt6358-objs := mt6358.o
 snd-soc-mt6359-objs := mt6359.o
 snd-soc-mt6359-accdet-objs := mt6359-accdet.o
@@ -563,6 +564,7 @@ obj-$(CONFIG_SND_SOC_ML26124)	+= snd-soc-ml26124.o
 obj-$(CONFIG_SND_SOC_MSM8916_WCD_ANALOG) +=snd-soc-msm8916-analog.o
 obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o
 obj-$(CONFIG_SND_SOC_MT6351)	+= snd-soc-mt6351.o
+obj-$(CONFIG_SND_SOC_MT6357)	+= snd-soc-mt6357.o
 obj-$(CONFIG_SND_SOC_MT6358)	+= snd-soc-mt6358.o
 obj-$(CONFIG_SND_SOC_MT6359)	+= snd-soc-mt6359.o
 obj-$(CONFIG_SND_SOC_MT6359_ACCDET) += mt6359-accdet.o
diff --git a/sound/soc/codecs/mt6357.c b/sound/soc/codecs/mt6357.c
new file mode 100644
index 000000000000..b3c3d9d73aa3
--- /dev/null
+++ b/sound/soc/codecs/mt6357.c
@@ -0,0 +1,1898 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MT6357 ALSA SoC audio codec driver
+ *
+ * Copyright (c) 2024 Baylibre
+ * Author: Nicolas Belin <nbelin@baylibre.com>
+ */
+
+#include <linux/dma-mapping.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+#include <linux/mfd/mt6397/core.h>
+#include <linux/regulator/consumer.h>
+
+#include "mt6357.h"
+
+static void set_playback_gpio(struct mt6357_priv *priv, bool enable)
+{
+	regmap_write(priv->regmap, MT6357_GPIO_MODE2_CLR, MT6357_GPIO_MODE2_CLEAR_ALL);
+	if (enable) {
+		/* set gpio mosi mode */
+		regmap_write(priv->regmap, MT6357_GPIO_MODE2_SET,
+			     MT6357_GPIO8_MODE_SET_AUD_CLK_MOSI |
+			     MT6357_GPIO9_MODE_SET_AUD_DAT_MOSI0 |
+			     MT6357_GPIO10_MODE_SET_AUD_DAT_MOSI1 |
+			     MT6357_GPIO11_MODE_SET_AUD_SYNC_MOSI);
+	} else {
+		/* pad_aud_*_mosi are GPIO mode after clear and set them to dir input
+		 * reason:
+		 * pad_aud_dat_mosi*, because the pin is used as boot strap
+		 */
+		regmap_update_bits(priv->regmap, MT6357_GPIO_DIR0,
+				   MT6357_GPIO8_DIR_MASK |
+				   MT6357_GPIO9_DIR_MASK |
+				   MT6357_GPIO10_DIR_MASK |
+				   MT6357_GPIO11_DIR_MASK,
+				   MT6357_GPIO8_DIR_INPUT |
+				   MT6357_GPIO9_DIR_INPUT |
+				   MT6357_GPIO10_DIR_INPUT |
+				   MT6357_GPIO11_DIR_INPUT);
+	}
+}
+
+static void set_capture_gpio(struct mt6357_priv *priv, bool enable)
+{
+	regmap_write(priv->regmap, MT6357_GPIO_MODE3_CLR, MT6357_GPIO_MODE3_CLEAR_ALL);
+	if (enable) {
+		/* set gpio miso mode */
+		regmap_write(priv->regmap, MT6357_GPIO_MODE3_SET,
+			     MT6357_GPIO12_MODE_SET_AUD_CLK_MISO |
+			     MT6357_GPIO13_MODE_SET_AUD_DAT_MISO0 |
+			     MT6357_GPIO14_MODE_SET_AUD_DAT_MISO1 |
+			     MT6357_GPIO15_MODE_SET_AUD_SYNC_MISO);
+	} else {
+		/* pad_aud_*_mosi are GPIO mode after clear and set them to dir input
+		 * reason:
+		 * pad_aud_clk_miso, because when playback only the miso_clk
+		 * will also have 26m, so will have power leak
+		 * pad_aud_dat_miso*, because the pin is used as boot strap
+		 */
+		regmap_update_bits(priv->regmap, MT6357_GPIO_DIR0,
+				   MT6357_GPIO12_DIR_MASK |
+				   MT6357_GPIO13_DIR_MASK |
+				   MT6357_GPIO14_DIR_MASK |
+				   MT6357_GPIO15_DIR_MASK,
+				   MT6357_GPIO12_DIR_INPUT |
+				   MT6357_GPIO13_DIR_INPUT |
+				   MT6357_GPIO14_DIR_INPUT |
+				   MT6357_GPIO15_DIR_INPUT);
+	}
+}
+
+static void hp_main_output_ramp(struct mt6357_priv *priv, bool up)
+{
+	int i, stage;
+
+	/* Enable/Reduce HPL/R main output stage step by step */
+	for (i = 0; i <= MT6357_HPLOUT_STG_CTRL_VAUDP15_MAX; i++) {
+		stage = up ? i : MT6357_HPLOUT_STG_CTRL_VAUDP15_MAX - i;
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPLOUT_STG_CTRL_VAUDP15_MASK,
+				   stage << MT6357_HPLOUT_STG_CTRL_VAUDP15_SFT);
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPROUT_STG_CTRL_VAUDP15_MASK,
+				   stage << MT6357_HPROUT_STG_CTRL_VAUDP15_SFT);
+		usleep_range(600, 700);
+	}
+}
+
+static void hp_aux_feedback_loop_gain_ramp(struct mt6357_priv *priv, bool up)
+{
+	int i, stage;
+
+	/* Reduce HP aux feedback loop gain step by step */
+	for (i = 0; i <= MT6357_HP_AUX_LOOP_GAIN_MAX; i++) {
+		stage = up ? i : MT6357_HP_AUX_LOOP_GAIN_MAX - i;
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
+				   MT6357_HP_AUX_LOOP_GAIN_MASK,
+				   stage << MT6357_HP_AUX_LOOP_GAIN_SFT);
+		usleep_range(600, 700);
+	}
+}
+
+static void hp_pull_down(struct mt6357_priv *priv, bool enable)
+{
+	if (enable)
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON2,
+				   MT6357_HPP_SHORT_2VCM_VAUDP15_MASK,
+				   MT6357_HPP_SHORT_2VCM_VAUDP15_ENABLE);
+	else
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON2,
+				   MT6357_HPP_SHORT_2VCM_VAUDP15_MASK,
+				   MT6357_HPP_SHORT_2VCM_VAUDP15_DISABLE);
+}
+
+static bool is_valid_hp_pga_idx(int reg_idx)
+{
+	return (reg_idx >= DL_GAIN_8DB && reg_idx <= DL_GAIN_N_12DB) || reg_idx == DL_GAIN_N_40DB;
+}
+
+static void volume_ramp(struct mt6357_priv *priv, int lfrom, int lto,
+			int rfrom, int rto, unsigned int reg_addr)
+{
+	int lcount, rcount, sleep = 0;
+
+	if (!is_valid_hp_pga_idx(lfrom) || !is_valid_hp_pga_idx(lto))
+		pr_debug("%s(), invalid left volume index, from %d, to %d\n",
+			 __func__, lfrom, lto);
+
+	if (!is_valid_hp_pga_idx(rfrom) || !is_valid_hp_pga_idx(rto))
+		pr_debug("%s(), invalid right volume index, from %d, to %d\n",
+			 __func__, rfrom, rto);
+
+	if (lto > lfrom)
+		lcount = 1;
+	else
+		lcount = -1;
+
+	if (rto > rfrom)
+		rcount = 1;
+	else
+		rcount = -1;
+
+	while ((lto != lfrom) || (rto != rfrom)) {
+		if (lto != lfrom) {
+			lfrom += lcount;
+			if (is_valid_hp_pga_idx(lfrom)) {
+				regmap_update_bits(priv->regmap, reg_addr,
+						   MT6357_DL_GAIN_REG_LEFT_MASK,
+						   lfrom << MT6357_DL_GAIN_REG_LEFT_SHIFT);
+				sleep = 1;
+			}
+		}
+		if (rto != rfrom) {
+			rfrom += rcount;
+			if (is_valid_hp_pga_idx(rfrom)) {
+				regmap_update_bits(priv->regmap, reg_addr,
+						   MT6357_DL_GAIN_REG_RIGHT_MASK,
+						   rfrom << MT6357_DL_GAIN_REG_RIGHT_SHIFT);
+				sleep = 1;
+			}
+		}
+		if (sleep)
+			usleep_range(200, 300);
+	}
+}
+
+static void lo_volume_ramp(struct mt6357_priv *priv, int lfrom, int lto, int rfrom, int rto)
+{
+	volume_ramp(priv, lfrom, lto, rfrom, rto, MT6357_ZCD_CON1);
+}
+
+static void hp_volume_ramp(struct mt6357_priv *priv, int lfrom, int lto, int rfrom, int rto)
+{
+	volume_ramp(priv, lfrom, lto, rfrom, rto, MT6357_ZCD_CON2);
+}
+
+static void hs_volume_ramp(struct mt6357_priv *priv, int from, int to)
+{
+	volume_ramp(priv, from, to, 0, 0, MT6357_ZCD_CON3);
+}
+
+/* Volume and channel swap controls */
+static const DECLARE_TLV_DB_SCALE(playback_tlv, -1000, 100, 0);
+static const DECLARE_TLV_DB_SCALE(capture_tlv, 0, 600, 0);
+static const DECLARE_TLV_DB_SCALE(hp_degain_tlv, -1200, 1200, 0);
+
+static const struct snd_kcontrol_new mt6357_controls[] = {
+	/* dl pga gain */
+	SOC_DOUBLE_TLV("Headphone Volume",
+		       MT6357_ZCD_CON2, MT6357_AUD_HPL_GAIN_SFT,
+		       MT6357_AUD_HPR_GAIN_SFT, MT6357_AUD_HP_GAIN_MAX,
+		       1, playback_tlv),
+	SOC_SINGLE_TLV("Headphone Vin Volume",
+		       MT6357_AUDDEC_ANA_CON7, MT6357_HP_IVBUF_DEGAIN_SFT,
+		       MT6357_HP_IVBUF_DEGAIN_MAX, 1, hp_degain_tlv),
+	SOC_DOUBLE_TLV("Lineout Volume",
+		       MT6357_ZCD_CON1, MT6357_AUD_LOL_GAIN_SFT,
+		       MT6357_AUD_LOR_GAIN_SFT, MT6357_AUD_LO_GAIN_MAX,
+		       1, playback_tlv),
+	SOC_SINGLE_TLV("Handset Volume",
+		       MT6357_ZCD_CON3, MT6357_AUD_HS_GAIN_SFT,
+		       MT6357_AUD_HS_GAIN_MAX, 1, playback_tlv),
+	/* ul pga gain */
+	SOC_DOUBLE_R_TLV("Mic Volume",
+			 MT6357_AUDENC_ANA_CON0, MT6357_AUDENC_ANA_CON1,
+			 MT6357_AUDPREAMPLGAIN_SFT, MT6357_AUDPREAMPLGAIN_MAX,
+			 0, capture_tlv),
+};
+
+/* Uplink controls */
+
+enum {
+	MIC_TYPE_MUX_IDLE,
+	MIC_TYPE_MUX_ACC,
+	MIC_TYPE_MUX_DMIC,
+	MIC_TYPE_MUX_DCC,
+	MIC_TYPE_MUX_DCC_ECM_DIFF,
+	MIC_TYPE_MUX_DCC_ECM_SINGLE,
+	MIC_TYPE_MUX_LPBK,
+	MIC_TYPE_MUX_SGEN,
+};
+
+#define IS_DCC_BASE(type) ((type) == MIC_TYPE_MUX_DCC || \
+			(type) == MIC_TYPE_MUX_DCC_ECM_DIFF || \
+			(type) == MIC_TYPE_MUX_DCC_ECM_SINGLE)
+
+static const char * const mic_type_mux_map[] = {
+	"Idle",
+	"ACC",
+	"DMIC",
+	"DCC",
+	"DCC_ECM_DIFF",
+	"DCC_ECM_SINGLE",
+	"Loopback",
+	"Sine Generator",
+};
+
+static SOC_ENUM_SINGLE_DECL(mic_type_mux_map_enum, SND_SOC_NOPM,
+			    0, mic_type_mux_map);
+
+static const struct snd_kcontrol_new mic_type_mux_control =
+	SOC_DAPM_ENUM("Mic Type Select", mic_type_mux_map_enum);
+
+static const char * const pga_mux_map[] = {
+	"None", "AIN0", "AIN1", "AIN2"
+};
+
+static SOC_ENUM_SINGLE_DECL(pga_left_mux_map_enum,
+			    MT6357_AUDENC_ANA_CON0,
+			    MT6357_AUDPREAMPLINPUTSEL_SFT,
+			    pga_mux_map);
+
+static const struct snd_kcontrol_new pga_left_mux_control =
+	SOC_DAPM_ENUM("PGA L Select", pga_left_mux_map_enum);
+
+static SOC_ENUM_SINGLE_DECL(pga_right_mux_map_enum,
+			    MT6357_AUDENC_ANA_CON1,
+			    MT6357_AUDPREAMPRINPUTSEL_SFT,
+			    pga_mux_map);
+
+static const struct snd_kcontrol_new pga_right_mux_control =
+	SOC_DAPM_ENUM("PGA R Select", pga_right_mux_map_enum);
+
+/* Downlink controls */
+static const char * const hslo_mux_map[] = {
+	"Open", "DACR", "Playback", "Test mode"
+};
+
+static SOC_ENUM_SINGLE_DECL(lo_mux_map_enum,
+			    MT6357_AUDDEC_ANA_CON4,
+			    MT6357_AUD_LOL_MUX_INPUT_VAUDP15_SFT,
+			    hslo_mux_map);
+
+static const struct snd_kcontrol_new lo_mux_control =
+	SOC_DAPM_ENUM("Line out source", lo_mux_map_enum);
+
+static SOC_ENUM_SINGLE_DECL(hs_mux_map_enum,
+			    MT6357_AUDDEC_ANA_CON3,
+			    MT6357_AUD_HS_MUX_INPUT_VAUDP15_SFT,
+			    hslo_mux_map);
+
+static const struct snd_kcontrol_new hs_mux_control =
+	SOC_DAPM_ENUM("Handset source", hs_mux_map_enum);
+
+static const char * const hplr_mux_map[] = {
+	"Open", "Line Out", "DAC", "Handset"
+};
+
+static SOC_ENUM_SINGLE_DECL(hpr_mux_map_enum,
+			    MT6357_AUDDEC_ANA_CON0,
+			    MT6357_AUD_HPR_MUX_INPUT_VAUDP15_SFT,
+			    hplr_mux_map);
+
+static const struct snd_kcontrol_new hpr_mux_control =
+	SOC_DAPM_ENUM("Headphone Right source", hpr_mux_map_enum);
+
+static SOC_ENUM_SINGLE_DECL(hpl_mux_map_enum,
+			    MT6357_AUDDEC_ANA_CON0,
+			    MT6357_AUD_HPL_MUX_INPUT_VAUDP15_SFT,
+			    hplr_mux_map);
+
+static const struct snd_kcontrol_new hpl_mux_control =
+	SOC_DAPM_ENUM("Headphone Left source", hpl_mux_map_enum);
+
+static const char * const dac_mux_map[] = {
+	"Normal Path", "Sine Generator"
+};
+
+static SOC_ENUM_SINGLE_DECL(dac_mux_map_enum,
+			    MT6357_AFE_TOP_CON0,
+			    MT6357_DL_SINE_ON_SFT,
+			    dac_mux_map);
+
+static const struct snd_kcontrol_new dac_mux_control =
+	SOC_DAPM_ENUM("DAC Select", dac_mux_map_enum);
+
+static int mt6357_set_dmic(struct mt6357_priv *priv, bool enable)
+{
+	if (enable) {
+		/* DMIC enable */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON7,
+				   MT6357_AUDDIGMICBIAS_MASK | MT6357_AUDDIGMICEN_MASK,
+				   MT6357_AUDDIGMICBIAS_DEFAULT_VALUE | MT6357_AUDDIGMICEN_ENABLE);
+		/* enable aud_pad TX fifos */
+		regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_ENABLE);
+		/* UL dmic setting: dual mode */
+		regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_H,
+				   MT6357_C_TWO_DIGITAL_MIC_CTL_MASK,
+				   MT6357_C_TWO_DIGITAL_MIC_ENABLE);
+		/* UL turn on SDM 3 level mode */
+		regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
+				   MT6357_UL_SDM_3_LEVEL_CTL_MASK,
+				   MT6357_UL_SDM_3_LEVEL_SELECT);
+		/* UL turn on */
+		regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
+				   MT6357_UL_SRC_ON_TMP_CTL_MASK,
+				   MT6357_UL_SRC_ENABLE);
+		/* Wait to avoid any pop noises */
+		msleep(100);
+	} else {
+		/* UL turn off */
+		regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
+				   MT6357_UL_SRC_ON_TMP_CTL_MASK,
+				   MT6357_UL_SRC_DISABLE);
+		/* UL turn on SDM 3 level mode */
+		regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
+				   MT6357_UL_SDM_3_LEVEL_CTL_MASK,
+				   MT6357_UL_SDM_3_LEVEL_DESELECT);
+		/* disable aud_pad TX fifos */
+		regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_DISABLE);
+		/* UL dmic setting: dual mode */
+		regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_H,
+				   MT6357_C_TWO_DIGITAL_MIC_CTL_MASK,
+				   MT6357_C_TWO_DIGITAL_MIC_DISABLE);
+		/* DMIC disable */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON7,
+				   MT6357_AUDDIGMICBIAS_MASK | MT6357_AUDDIGMICEN_MASK,
+				   MT6357_AUDDIGMICBIAS_OFF | MT6357_AUDDIGMICEN_DISABLE);
+	}
+	return 0;
+}
+
+static int mt6357_set_amic(struct mt6357_priv *priv, bool enable, unsigned int mic_type)
+{
+	if (enable) {
+		if (IS_DCC_BASE(mic_type)) {
+			regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0,
+					   MT6357_DCCLK_DIV_MASK, MT6357_DCCLK_DIV_RUN_VALUE);
+			regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0,
+					   MT6357_DCCLK_PDN_MASK, MT6357_DCCLK_OUTPUT);
+			regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0,
+					   MT6357_DCCLK_GEN_ON_MASK, MT6357_DCCLK_GEN_ON);
+			regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG1,
+					   MT6357_DCCLK_RESYNC_BYPASS_MASK,
+					   MT6357_DCCLK_RESYNC_BYPASS);
+
+			/* mic bias 0: set the correct DC couple*/
+			switch (mic_type) {
+			case MIC_TYPE_MUX_DCC_ECM_DIFF:
+				regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON8,
+						   MT6357_AUD_MICBIAS0_DC_MASK,
+						   MT6357_AUD_MICBIAS0_DC_ENABLE_ALL);
+				break;
+			case MIC_TYPE_MUX_DCC_ECM_SINGLE:
+				regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON8,
+						   MT6357_AUD_MICBIAS0_DC_MASK,
+						   MT6357_AUD_MICBIAS0_DC_ENABLE_P1);
+				break;
+			default:
+				regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON8,
+						   MT6357_AUD_MICBIAS0_DC_MASK,
+						   MT6357_AUD_MICBIAS0_DC_DISABLE_ALL);
+				break;
+			}
+
+			/* mic bias 1: set the correct DC couple */
+			if (mic_type == MIC_TYPE_MUX_DCC_ECM_SINGLE)
+				regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON9,
+						   MT6357_AUD_MICBIAS1_DCSW1P_EN_MASK,
+						   MT6357_AUD_MICBIAS1_DCSW1P_ENABLE);
+
+			/* Audio L/R preamplifier DCC precharge */
+			regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+					   MT6357_AUDPREAMPLDCPRECHARGE_MASK,
+					   MT6357_AUDPREAMPLDCPRECHARGE_ENABLE);
+			regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
+					   MT6357_AUDPREAMPRDCPRECHARGE_MASK,
+					   MT6357_AUDPREAMPRDCPRECHARGE_ENABLE);
+			/* L preamplifier DCCEN */
+			regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+					   MT6357_AUDPREAMPLDCCEN_MASK,
+					   MT6357_AUDPREAMPLDCCEN_DC);
+			/* R preamplifier DCCEN */
+			regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
+					   MT6357_AUDPREAMPRDCCEN_MASK,
+					   MT6357_AUDPREAMPRDCCEN_DC);
+		} else {
+			/* Audio L preamplifier DCC precharge disable */
+			regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+					   MT6357_AUDPREAMPLDCPRECHARGE_MASK,
+					   MT6357_AUDPREAMPLDCPRECHARGE_DISABLE);
+			/* L preamplifier ACC */
+			regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+					   MT6357_AUDPREAMPLDCCEN_MASK,
+					   MT6357_AUDPREAMPLDCCEN_AC);
+			/* Audio R preamplifier DCC precharge disable */
+			regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
+					   MT6357_AUDPREAMPRDCPRECHARGE_MASK,
+					   MT6357_AUDPREAMPRDCPRECHARGE_DISABLE);
+			/* R preamplifier ACC */
+			regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
+					   MT6357_AUDPREAMPRDCCEN_MASK,
+					   MT6357_AUDPREAMPRDCCEN_AC);
+		}
+	} else {
+		/* disable any Mic Bias 0 DC couple */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON8,
+				   MT6357_AUD_MICBIAS0_DC_MASK,
+				   MT6357_AUD_MICBIAS0_DC_DISABLE_ALL);
+		/* disable any Mic Bias 1 DC couple */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON9,
+				   MT6357_AUD_MICBIAS1_DCSW1P_EN_MASK,
+				   MT6357_AUD_MICBIAS1_DCSW1P_DISABLE);
+		if (IS_DCC_BASE(mic_type)) {
+			regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0,
+					   MT6357_DCCLK_GEN_ON_MASK, MT6357_DCCLK_GEN_OFF);
+			regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0,
+					   MT6357_DCCLK_PDN_MASK, MT6357_DCCLK_PDN);
+			regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0,
+					   MT6357_DCCLK_DIV_MASK, MT6357_DCCLK_DIV_STOP_VALUE);
+		}
+	}
+
+	return 0;
+}
+
+static int mt6357_set_loopback(struct mt6357_priv *priv, bool enable)
+{
+	if (enable) {
+		/* enable aud_pad TX fifos */
+		regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_ENABLE);
+		/* enable aud_pad lpk TX fifos */
+		regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
+				   MT6357_AUD_PAD_TX_FIFO_LPBK_MASK,
+				   MT6357_AUD_PAD_TX_FIFO_LPBK_ENABLE);
+		/* Set UL Part: enable new lpbk 2 */
+		regmap_update_bits(priv->regmap, MT6357_AFE_ADDA_MTKAIF_CFG0,
+				   MT6357_ADDA_MTKAIF_LPBK_CTL_MASK,
+				   MT6357_ADDA_MTKAIF_LPBK_ENABLE);
+		/* UL turn on */
+		regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
+				   MT6357_UL_SRC_ON_TMP_CTL_MASK,
+				   MT6357_UL_SRC_ENABLE);
+	} else {
+		/* UL turn off */
+		regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
+				   MT6357_UL_SRC_ON_TMP_CTL_MASK,
+				   MT6357_UL_SRC_DISABLE);
+		/* disable new lpbk 2 */
+		regmap_update_bits(priv->regmap, MT6357_AFE_ADDA_MTKAIF_CFG0,
+				   MT6357_ADDA_MTKAIF_LPBK_CTL_MASK,
+				   MT6357_ADDA_MTKAIF_LPBK_DISABLE);
+		/* disable aud_pad lpbk TX fifos */
+		regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
+				   MT6357_AUD_PAD_TX_FIFO_LPBK_MASK,
+				   MT6357_AUD_PAD_TX_FIFO_LPBK_DISABLE);
+		/* disable aud_pad TX fifos */
+		regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_DISABLE);
+	}
+
+	return 0;
+}
+
+static int mt6357_set_ul_sine_gen(struct mt6357_priv *priv, bool enable)
+{
+	if (enable) {
+		/* enable aud_pad TX fifos */
+		regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_ENABLE);
+		/* UL turn on */
+		regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
+				   MT6357_UL_SRC_ON_TMP_CTL_MASK,
+				   MT6357_UL_SRC_ENABLE);
+	} else {
+		/* UL turn off */
+		regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
+				   MT6357_UL_SRC_ON_TMP_CTL_MASK,
+				   MT6357_UL_SRC_DISABLE);
+		/* disable aud_pad TX fifos */
+		regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_DISABLE);
+	}
+
+	return 0;
+}
+
+static int mt_aif_out_event(struct snd_soc_dapm_widget *w,
+			    struct snd_kcontrol *kcontrol,
+			    int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		set_capture_gpio(priv, true);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		set_capture_gpio(priv, false);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mt_adc_supply_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol,
+			       int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		/* Enable audio ADC CLKGEN  */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON11,
+				   MT6357_RSTB_ENCODER_VA28_MASK, MT6357_RSTB_ENCODER_VA28_ENABLE);
+		/* Enable  LCLDO_ENC 2P8V */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12,
+				   MT6357_LCLDO_ENC_EN_VA28_MASK, MT6357_LCLDO_ENC_EN_VA28_ENABLE);
+		/* LCLDO_ENC remote sense */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12,
+				   MT6357_VA28REFGEN_EN_VA28_MASK |
+				   MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_MASK,
+				   MT6357_VA28REFGEN_EN_VA28_ENABLE |
+				   MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_ENABLE);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/* LCLDO_ENC remote sense off */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12,
+				   MT6357_VA28REFGEN_EN_VA28_MASK |
+				   MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_MASK,
+				   MT6357_VA28REFGEN_EN_VA28_DISABLE |
+				   MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_DISABLE);
+		/* disable LCLDO_ENC 2P8V */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12,
+				   MT6357_LCLDO_ENC_EN_VA28_MASK,
+				   MT6357_LCLDO_ENC_EN_VA28_DISABLE);
+		/* disable audio ADC CLKGEN  */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON11,
+				   MT6357_RSTB_ENCODER_VA28_MASK,
+				   MT6357_RSTB_ENCODER_VA28_DISABLE);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mt_mic_type_event(struct snd_soc_dapm_widget *w,
+			     struct snd_kcontrol *kcontrol,
+			     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
+	unsigned int mic_type = dapm_kcontrol_get_value(w->kcontrols[0]);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		switch (mic_type) {
+		case MIC_TYPE_MUX_DMIC:
+			mt6357_set_dmic(priv, true);
+			break;
+		case MIC_TYPE_MUX_LPBK:
+			mt6357_set_loopback(priv, true);
+			break;
+		case MIC_TYPE_MUX_SGEN:
+			mt6357_set_ul_sine_gen(priv, true);
+			break;
+		default:
+			mt6357_set_amic(priv, true, mic_type);
+			break;
+		}
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		switch (mic_type) {
+		case MIC_TYPE_MUX_DMIC:
+			mt6357_set_dmic(priv, false);
+			break;
+		case MIC_TYPE_MUX_LPBK:
+			mt6357_set_loopback(priv, false);
+			break;
+		case MIC_TYPE_MUX_SGEN:
+			mt6357_set_ul_sine_gen(priv, false);
+			break;
+		default:
+			mt6357_set_amic(priv, false, mic_type);
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mt_pga_left_event(struct snd_soc_dapm_widget *w,
+			     struct snd_kcontrol *kcontrol,
+			     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		/* L preamplifier enable */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+				   MT6357_AUDPREAMPLON_MASK,
+				   MT6357_AUDPREAMPLON_ENABLE);
+		/* L ADC input sel : L PGA. Enable audio L ADC */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+				   MT6357_AUDADCLINPUTSEL_MASK,
+				   MT6357_AUDADCLINPUTSEL_PREAMPLIFIER);
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+				   MT6357_AUDADCLPWRUP_MASK,
+				   MT6357_AUDADCLPWRUP);
+		/* Audio L preamplifier DCC precharge off */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+				   MT6357_AUDPREAMPLDCPRECHARGE_MASK,
+				   MT6357_AUDPREAMPLDCPRECHARGE_DISABLE);
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		/* Audio L ADC input sel : off, disable audio L ADC */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+				   MT6357_AUDADCLPWRUP_MASK,
+				   MT6357_AUDADCLPWRDOWN);
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+				   MT6357_AUDADCLINPUTSEL_MASK,
+				   MT6357_AUDADCLINPUTSEL_IDLE);
+		/* L preamplifier ACC */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+				   MT6357_AUDPREAMPLDCCEN_MASK,
+				   MT6357_AUDPREAMPLDCCEN_AC);
+		/* L preamplifier disable */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+				   MT6357_AUDPREAMPLON_MASK,
+				   MT6357_AUDPREAMPLON_DISABLE);
+		/* disable Audio L preamplifier DCC precharge */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+				   MT6357_AUDPREAMPLDCPRECHARGE_MASK,
+				   MT6357_AUDPREAMPLDCPRECHARGE_DISABLE);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mt_pga_right_event(struct snd_soc_dapm_widget *w,
+			      struct snd_kcontrol *kcontrol,
+			      int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		/* R preamplifier enable */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
+				   MT6357_AUDPREAMPRON_MASK, MT6357_AUDPREAMPRON_ENABLE);
+		/* R ADC input sel : R PGA. Enable audio R ADC */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
+				   MT6357_AUDADCRINPUTSEL_MASK,
+				   MT6357_AUDADCRINPUTSEL_PREAMPLIFIER);
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
+				   MT6357_AUDADCRPWRUP_MASK, MT6357_AUDADCRPWRUP);
+		/* Audio R preamplifier DCC precharge off */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
+				   MT6357_AUDPREAMPRDCPRECHARGE_MASK,
+				   MT6357_AUDPREAMPRDCPRECHARGE_DISABLE);
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		/* Audio R ADC input sel : off, disable audio R ADC */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
+				   MT6357_AUDADCRPWRUP_MASK, MT6357_AUDADCRPWRDOWN);
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+				   MT6357_AUDADCRINPUTSEL_MASK, MT6357_AUDADCRINPUTSEL_IDLE);
+		/* R preamplifier ACC */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
+				   MT6357_AUDPREAMPRDCCEN_MASK, MT6357_AUDPREAMPRDCCEN_AC);
+		/* R preamplifier disable */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
+				   MT6357_AUDPREAMPRON_MASK, MT6357_AUDPREAMPRON_DISABLE);
+		/* disable Audio R preamplifier DCC precharge */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
+				   MT6357_AUDPREAMPRDCPRECHARGE_MASK,
+				   MT6357_AUDPREAMPRDCPRECHARGE_DISABLE);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int adc_enable_event(struct snd_soc_dapm_widget *w,
+			    struct snd_kcontrol *kcontrol,
+			    int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
+	int lgain, rgain;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		regmap_read(priv->regmap, MT6357_AUDENC_ANA_CON0, &lgain);
+		regmap_read(priv->regmap, MT6357_AUDENC_ANA_CON1, &rgain);
+		/* L PGA 0 dB gain */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+				   MT6357_AUDPREAMPLGAIN_MASK,
+				   UL_GAIN_0DB << MT6357_AUDPREAMPLGAIN_SFT);
+		/* R PGA 0 dB gain */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
+				   MT6357_AUDPREAMPRGAIN_MASK,
+				   UL_GAIN_0DB << MT6357_AUDPREAMPRGAIN_SFT);
+		/* enable aud_pad TX fifos */
+		regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_ENABLE);
+		/* UL turn on */
+		regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
+				   MT6357_UL_SRC_ON_TMP_CTL_MASK, MT6357_UL_SRC_ENABLE);
+		/* Wait to avoid any pop noises */
+		msleep(100);
+		/* set the mic gains to the stored values */
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
+				   MT6357_AUDPREAMPLGAIN_MASK, lgain);
+		regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
+				   MT6357_AUDPREAMPRGAIN_MASK, rgain);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		/* UL turn off */
+		regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
+				   MT6357_UL_SRC_ON_TMP_CTL_MASK, MT6357_UL_SRC_DISABLE);
+		/* disable aud_pad TX fifos */
+		regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
+				   MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_DISABLE);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static void configure_downlinks(struct mt6357_priv *priv, bool enable)
+{
+	if (enable) {
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ELR_0,
+				   MT6357_AUD_HP_TRIM_EN_VAUDP15_MASK,
+				   MT6357_AUD_HP_TRIM_EN_VAUDP15_ENABLE);
+		/* Disable headphone short-circuit protection */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
+				   MT6357_AUD_HPR_SC_VAUDP15_MASK | MT6357_AUD_HPL_SC_VAUDP15_MASK,
+				   MT6357_AUD_HPR_SC_VAUDP15_DISABLE |
+				   MT6357_AUD_HPL_SC_VAUDP15_DISABLE);
+		/* Disable handset short-circuit protection */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
+				   MT6357_AUD_HS_SC_VAUDP15_MASK,
+				   MT6357_AUD_HS_SC_VAUDP15_DISABLE);
+		/* Disable lineout short-circuit protection */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
+				   MT6357_AUD_LOL_SC_VAUDP15_MASK,
+				   MT6357_AUD_LOL_SC_VAUDP15_DISABLE);
+		/* Reduce ESD resistance of AU_REFN */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON2,
+				   MT6357_AUD_REFN_DERES_VAUDP15_MASK,
+				   MT6357_AUD_REFN_DERES_VAUDP15_ENABLE);
+		/* Turn on DA_600K_NCP_VA18 */
+		regmap_write(priv->regmap, MT6357_AUDNCP_CLKDIV_CON1, MT6357_DIVCKS_ON);
+		/* Set NCP clock as 604kHz // 26MHz/43 = 604KHz */
+		regmap_write(priv->regmap, MT6357_AUDNCP_CLKDIV_CON2, 0x002c);
+		/* Toggle DIVCKS_CHG */
+		regmap_write(priv->regmap, MT6357_AUDNCP_CLKDIV_CON0, MT6357_DIVCKS_CHG);
+		/* Set NCP soft start mode as default mode: 150us */
+		regmap_write(priv->regmap, MT6357_AUDNCP_CLKDIV_CON4,
+			     MT6357_DIVCKS_PWD_NCP_ST_150US);
+		/* Enable NCP */
+		regmap_write(priv->regmap, MT6357_AUDNCP_CLKDIV_CON3,
+			     MT6357_DIVCKS_PWD_NCP_ENABLE);
+		usleep_range(250, 270);
+		/* Enable cap-less LDOs (1.5V) */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12,
+				   MT6357_VA33REFGEN_EN_VA18_MASK |
+				   MT6357_LCLDO_REMOTE_SENSE_VA18_MASK |
+				   MT6357_LCLDO_EN_VA18_MASK |
+				   MT6357_HCLDO_REMOTE_SENSE_VA18_MASK |
+				   MT6357_HCLDO_EN_VA18_MASK,
+				   MT6357_VA33REFGEN_EN_VA18_ENABLE |
+				   MT6357_LCLDO_REMOTE_SENSE_VA18_ENABLE |
+				   MT6357_LCLDO_EN_VA18_ENABLE |
+				   MT6357_HCLDO_REMOTE_SENSE_VA18_ENABLE |
+				   MT6357_HCLDO_EN_VA18_ENABLE);
+		/* Enable NV regulator (-1.2V) */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON13,
+				   MT6357_NVREG_EN_VAUDP15_MASK, MT6357_NVREG_EN_VAUDP15_ENABLE);
+		usleep_range(100, 120);
+		/* Enable IBIST */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON10,
+				   MT6357_AUD_IBIAS_PWRDN_VAUDP15_MASK,
+				   MT6357_AUD_IBIAS_PWRDN_VAUDP15_ENABLE);
+		/* Enable AUD_CLK */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON11,
+				   MT6357_RSTB_DECODER_VA28_MASK,
+				   MT6357_RSTB_DECODER_VA28_ENABLE);
+		/* Enable low-noise mode of DAC */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
+				   MT6357_DAC_LOW_NOISE_MODE_MASK,
+				   MT6357_DAC_LOW_NOISE_MODE_ENABLE);
+		usleep_range(100, 120);
+	} else {
+		/* Disable low-noise mode of DAC */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
+				   MT6357_DAC_LOW_NOISE_MODE_MASK,
+				   MT6357_DAC_LOW_NOISE_MODE_DISABLE);
+		/* Disable AUD_CLK */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON11,
+				   MT6357_RSTB_DECODER_VA28_MASK,
+				   MT6357_RSTB_DECODER_VA28_DISABLE);
+		/* Enable linout short-circuit protection */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
+				   MT6357_AUD_LOL_SC_VAUDP15_MASK,
+				   MT6357_AUD_LOL_SC_VAUDP15_ENABLE);
+		/* Enable handset short-circuit protection */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
+				   MT6357_AUD_HS_SC_VAUDP15_MASK,
+				   MT6357_AUD_HS_SC_VAUDP15_ENABLE);
+		/* Enable headphone short-circuit protection */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
+				   MT6357_AUD_HPR_SC_VAUDP15_MASK |
+				   MT6357_AUD_HPL_SC_VAUDP15_MASK,
+				   MT6357_AUD_HPR_SC_VAUDP15_ENABLE |
+				   MT6357_AUD_HPL_SC_VAUDP15_ENABLE);
+		/* Disable IBIST */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON10,
+				   MT6357_AUD_IBIAS_PWRDN_VAUDP15_MASK,
+				   MT6357_AUD_IBIAS_PWRDN_VAUDP15_DISABLE);
+		/* Disable NV regulator (-1.2V) */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON13,
+				   MT6357_NVREG_EN_VAUDP15_MASK,
+				   MT6357_NVREG_EN_VAUDP15_DISABLE);
+		/* Disable cap-less LDOs (1.5V) */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12,
+				   MT6357_VA33REFGEN_EN_VA18_MASK |
+				   MT6357_LCLDO_REMOTE_SENSE_VA18_MASK |
+				   MT6357_LCLDO_EN_VA18_MASK |
+				   MT6357_HCLDO_REMOTE_SENSE_VA18_MASK |
+				   MT6357_HCLDO_EN_VA18_MASK,
+				   MT6357_VA33REFGEN_EN_VA18_DISABLE |
+				   MT6357_LCLDO_REMOTE_SENSE_VA18_DISABLE |
+				   MT6357_LCLDO_EN_VA18_DISABLE |
+				   MT6357_HCLDO_REMOTE_SENSE_VA18_DISABLE |
+				   MT6357_HCLDO_EN_VA18_DISABLE);
+		/* Disable NCP */
+		regmap_update_bits(priv->regmap, MT6357_AUDNCP_CLKDIV_CON3,
+				   MT6357_DIVCKS_PWD_NCP_MASK, MT6357_DIVCKS_PWD_NCP_DISABLE);
+	}
+}
+
+static int mt_audio_in_event(struct snd_soc_dapm_widget *w,
+			     struct snd_kcontrol *kcontrol,
+			     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		set_playback_gpio(priv, true);
+
+		/* Pull-down HPL/R to AVSS28_AUD */
+		if (priv->pull_down_needed)
+			hp_pull_down(priv, true);
+
+		/* Disable HP main CMFB Switch */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
+				   MT6357_HPRL_MAIN_CMFB_LOOP_MASK,
+				   MT6357_HPRL_MAIN_CMFB_LOOP_DISABLE);
+		/* Audio system digital clock power down release */
+		regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON2,
+			     MT6357_CCI_AUDIO_FIFO_DISABLE |
+			     MT6357_CCI_ACD_MODE_NORMAL_PATH |
+			     MT6357_CCI_AFIFO_CLK_PWDB_ON |
+			     MT6357_CCI_ACD_FUNC_RSTB_RESET);
+		/* sdm audio fifo clock power on */
+		regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON0,
+			     MT6357_CCI_AUD_ANACK_INVERT |
+			     (4 << MT6357_CCI_AUDIO_FIFO_WPTR_SFT) |
+			     MT6357_CCI_SCRAMBLER_CG_ENABLE |
+			     MT6357_CCI_RAND_ENABLE |
+			     MT6357_CCI_SPLT_SCRMB_CLK_ON |
+			     MT6357_CCI_SPLT_SCRMB_ON |
+			     MT6357_CCI_ZERO_PADDING_DISABLE |
+			     MT6357_CCI_SCRAMBLER_ENABLE);
+		/* scrambler clock on enable */
+		regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON2,
+			     MT6357_CCI_AUDIO_FIFO_DISABLE |
+			     MT6357_CCI_ACD_MODE_TEST_PATH |
+			     MT6357_CCI_AFIFO_CLK_PWDB_ON |
+			     MT6357_CCI_ACD_FUNC_RSTB_RELEASE);
+		/* sdm power on */
+		regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON2,
+			     MT6357_CCI_AUDIO_FIFO_ENABLE |
+			     MT6357_CCI_ACD_MODE_TEST_PATH |
+			     MT6357_CCI_AFIFO_CLK_PWDB_ON |
+			     MT6357_CCI_ACD_FUNC_RSTB_RELEASE);
+
+		configure_downlinks(priv, true);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		configure_downlinks(priv, false);
+		/* DL scrambler disabling sequence */
+		regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON2,
+			     MT6357_CCI_AUDIO_FIFO_DISABLE |
+			     MT6357_CCI_ACD_MODE_TEST_PATH |
+			     MT6357_CCI_AFIFO_CLK_PWDB_DOWN |
+			     MT6357_CCI_ACD_FUNC_RSTB_RESET);
+		regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON0,
+			     MT6357_CCI_AUD_ANACK_INVERT |
+			     (4 << MT6357_CCI_AUDIO_FIFO_WPTR_SFT) |
+			     MT6357_CCI_SCRAMBLER_CG_ENABLE |
+			     MT6357_CCI_RAND_ENABLE |
+			     MT6357_CCI_SPLT_SCRMB_CLK_ON |
+			     MT6357_CCI_SPLT_SCRMB_ON |
+			     MT6357_CCI_ZERO_PADDING_DISABLE |
+			     MT6357_CCI_SCRAMBLER_DISABLE);
+
+		set_playback_gpio(priv, false);
+
+		/* disable Pull-down HPL/R to AVSS28_AUD */
+		if (priv->pull_down_needed)
+			hp_pull_down(priv, false);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mt_delay_250_event(struct snd_soc_dapm_widget *w,
+			      struct snd_kcontrol *kcontrol,
+			      int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		usleep_range(250, 270);
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		usleep_range(250, 270);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int lo_mux_event(struct snd_soc_dapm_widget *w,
+			struct snd_kcontrol *kcontrol,
+			int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
+	int lgain, rgain;
+
+	/* Get current gain value */
+	regmap_read(priv->regmap, MT6357_ZCD_CON1, &lgain);
+	rgain = (lgain & MT6357_AUD_LOR_GAIN_MASK) >> MT6357_AUD_LOR_GAIN_SFT;
+	lgain = lgain & MT6357_AUD_LOL_GAIN_MASK;
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		/* Set -40dB before enable HS to avoid POP noise */
+		regmap_update_bits(priv->regmap, MT6357_ZCD_CON1,
+				   MT6357_AUD_LOL_GAIN_MASK |
+				   MT6357_AUD_LOR_GAIN_MASK,
+				   MT6357_DL_GAIN_N_40DB_REG);
+		/* Set LO STB enhance circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
+				   MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_MASK,
+				   MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_ENABLE);
+		/* Enable LO driver bias circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
+				   MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_MASK,
+				   MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_ENABLE);
+		/* Enable LO driver core circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
+				   MT6357_AUD_LOL_PWRUP_VAUDP15_MASK,
+				   MT6357_AUD_LOL_PWRUP_VAUDP15_ENABLE);
+		/* Set LOL gain to normal gain step by step */
+		lo_volume_ramp(priv, DL_GAIN_N_40DB, lgain,
+			       DL_GAIN_N_40DB, rgain);
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		/* decrease LOL gain to minimum gain step by step */
+
+		lo_volume_ramp(priv, lgain, DL_GAIN_N_40DB,
+			       rgain, DL_GAIN_N_40DB);
+		/* Disable LO driver core circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
+				   MT6357_AUD_LOL_PWRUP_VAUDP15_MASK,
+				   MT6357_AUD_LOL_PWRUP_VAUDP15_DISABLE);
+		/* Disable LO driver bias circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
+				   MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_MASK,
+				   MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_DISABLE);
+		/* Clear LO STB enhance circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
+				   MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_MASK,
+				   MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_DISABLE);
+		/* Save the gain value into the register*/
+		regmap_update_bits(priv->regmap, MT6357_ZCD_CON1,
+				   MT6357_AUD_LOL_GAIN_MASK |
+				   MT6357_AUD_LOR_GAIN_MASK,
+				   lgain << MT6357_AUD_LOL_GAIN_SFT |
+				   rgain << MT6357_AUD_LOR_GAIN_SFT);
+
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int hs_mux_event(struct snd_soc_dapm_widget *w,
+			struct snd_kcontrol *kcontrol,
+			int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
+	int gain; /* HS register has only one gain slot */
+
+	/* Get current gain value */
+	regmap_read(priv->regmap, MT6357_ZCD_CON3, &gain);
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		/* Set -40dB before enable HS to avoid POP noise */
+		regmap_update_bits(priv->regmap, MT6357_ZCD_CON3,
+				   MT6357_AUD_HS_GAIN_MASK,
+				   DL_GAIN_N_40DB);
+
+		/* Set HS STB enhance circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
+				   MT6357_AUD_HSOUT_STB_ENH_VAUDP15_MASK,
+				   MT6357_AUD_HSOUT_STB_ENH_VAUDP15_ENABLE);
+		/* Enable HS driver bias circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
+				   MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_MASK,
+				   MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_ENABLE);
+		/* Enable HS driver core circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
+				   MT6357_AUD_HS_PWRUP_VAUDP15_MASK,
+				   MT6357_AUD_HS_PWRUP_VAUDP15_ENABLE);
+		/* Set HS gain to normal gain step by step */
+		hs_volume_ramp(priv, DL_GAIN_N_40DB, gain);
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		/* decrease HS gain to minimum gain step by step */
+		hs_volume_ramp(priv,  gain, DL_GAIN_N_40DB);
+		/* Disable HS driver core circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
+				   MT6357_AUD_HS_PWRUP_VAUDP15_MASK,
+				   MT6357_AUD_HS_PWRUP_VAUDP15_DISABLE);
+		/* Disable HS driver bias circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
+				   MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_MASK,
+				   MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_ENABLE);
+		/* Clear HS STB enhance circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
+				   MT6357_AUD_HSOUT_STB_ENH_VAUDP15_MASK,
+				   MT6357_AUD_HSOUT_STB_ENH_VAUDP15_DISABLE);
+		/* Save the gain value into the register*/
+		regmap_update_bits(priv->regmap, MT6357_ZCD_CON3,
+				   MT6357_AUD_HS_GAIN_MASK, gain);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int hp_main_mux_event(struct snd_soc_dapm_widget *w,
+			     struct snd_kcontrol *kcontrol,
+			     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
+	int lgain, rgain;
+
+	/* Get current gain value */
+	regmap_read(priv->regmap, MT6357_ZCD_CON2, &lgain);
+	rgain = (lgain & MT6357_AUD_HPR_GAIN_MASK) >> MT6357_AUD_HPR_GAIN_SFT;
+	lgain = lgain & MT6357_AUD_HPL_GAIN_MASK;
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		priv->hp_channel_number++;
+		if (priv->hp_channel_number > 1)
+			break;
+		/* Set -40dB before enable HS to avoid POP noise */
+		regmap_update_bits(priv->regmap, MT6357_ZCD_CON2,
+				   MT6357_AUD_HPL_GAIN_MASK |
+				   MT6357_AUD_HPR_GAIN_MASK,
+				   MT6357_DL_GAIN_N_40DB_REG);
+		/* Set HPP/N STB enhance circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON2,
+				   MT6357_HPROUT_STB_ENH_VAUDP15_MASK |
+				   MT6357_HPLOUT_STB_ENH_VAUDP15_MASK,
+				   MT6357_HPROUT_STB_ENH_VAUDP15_N470_P250 |
+				   MT6357_HPLOUT_STB_ENH_VAUDP15_N470_P250);
+		/* Enable HP aux output stage */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPROUT_AUX_PWRUP_VAUDP15_MASK |
+				   MT6357_HPLOUT_AUX_PWRUP_VAUDP15_MASK,
+				   MT6357_HPROUT_AUX_PWRUP_VAUDP15_ENABLE |
+				   MT6357_HPLOUT_AUX_PWRUP_VAUDP15_ENABLE);
+		/* Enable HP aux feedback loop */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPR_AUX_FBRSW_VAUDP15_MASK |
+				   MT6357_HPL_AUX_FBRSW_VAUDP15_MASK,
+				   MT6357_HPR_AUX_FBRSW_VAUDP15_ENABLE |
+				   MT6357_HPL_AUX_FBRSW_VAUDP15_ENABLE);
+		/* Enable HP aux CMFB loop */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
+				   MT6357_HP_CMFB_RST_MASK |
+				   MT6357_HPL_AUX_CMFB_LOOP_MASK |
+				   MT6357_HPR_AUX_CMFB_LOOP_MASK,
+				   MT6357_HP_CMFB_RST_NORMAL |
+				   MT6357_HPL_AUX_CMFB_LOOP_ENABLE |
+				   MT6357_HPR_AUX_CMFB_LOOP_ENABLE);
+		/* Enable HP driver bias circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
+				   MT6357_AUD_HPR_BIAS_VAUDP15_MASK |
+				   MT6357_AUD_HPL_BIAS_VAUDP15_MASK,
+				   MT6357_AUD_HPR_BIAS_VAUDP15_ENABLE |
+				   MT6357_AUD_HPL_BIAS_VAUDP15_ENABLE);
+		/* Enable HP driver core circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
+				   MT6357_AUD_HPR_PWRUP_VAUDP15_MASK |
+				   MT6357_AUD_HPL_PWRUP_VAUDP15_MASK,
+				   MT6357_AUD_HPR_PWRUP_VAUDP15_ENABLE |
+				   MT6357_AUD_HPL_PWRUP_VAUDP15_ENABLE);
+		/* Short HP main output to HP aux output stage */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPR_SHORT2HPR_AUX_VAUDP15_MASK |
+				   MT6357_HPL_SHORT2HPR_AUX_VAUDP15_MASK,
+				   MT6357_HPR_SHORT2HPR_AUX_VAUDP15_ENABLE |
+				   MT6357_HPL_SHORT2HPR_AUX_VAUDP15_ENABLE);
+		/* Enable HP main CMFB loop */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
+				   MT6357_HPRL_MAIN_CMFB_LOOP_MASK,
+				   MT6357_HPRL_MAIN_CMFB_LOOP_ENABLE);
+		/* Disable HP aux CMFB loop */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
+				   MT6357_HPR_AUX_CMFB_LOOP_MASK |
+				   MT6357_HPL_AUX_CMFB_LOOP_MASK,
+				   MT6357_HPR_AUX_CMFB_LOOP_DISABLE |
+				   MT6357_HPL_AUX_CMFB_LOOP_DISABLE);
+		/* Enable HP main output stage */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPROUT_PWRUP_VAUDP15_MASK |
+				   MT6357_HPLOUT_PWRUP_VAUDP15_MASK,
+				   MT6357_HPROUT_PWRUP_VAUDP15_ENABLE |
+				   MT6357_HPLOUT_PWRUP_VAUDP15_ENABLE);
+		/* Enable HPR/L main output stage step by step */
+		hp_main_output_ramp(priv, true);
+		usleep_range(1000, 1200);
+		/* Reduce HP aux feedback loop gain */
+		hp_aux_feedback_loop_gain_ramp(priv, true);
+		/* Disable HP aux feedback loop */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPR_AUX_FBRSW_VAUDP15_MASK |
+				   MT6357_HPL_AUX_FBRSW_VAUDP15_MASK,
+				   MT6357_HPR_AUX_FBRSW_VAUDP15_DISABLE |
+				   MT6357_HPL_AUX_FBRSW_VAUDP15_DISABLE);
+		/* apply volume setting */
+		hp_volume_ramp(priv, DL_GAIN_N_40DB, lgain,
+			       DL_GAIN_N_40DB, rgain);
+		/* Disable HP aux output stage */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPROUT_AUX_PWRUP_VAUDP15_MASK |
+				   MT6357_HPLOUT_AUX_PWRUP_VAUDP15_MASK,
+				   MT6357_HPROUT_AUX_PWRUP_VAUDP15_DISABLE |
+				   MT6357_HPLOUT_AUX_PWRUP_VAUDP15_DISABLE);
+		/* Unshort HP main output to HP aux output stage */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPR_SHORT2HPR_AUX_VAUDP15_MASK |
+				   MT6357_HPL_SHORT2HPR_AUX_VAUDP15_MASK,
+				   MT6357_HPR_SHORT2HPR_AUX_VAUDP15_DISABLE |
+				   MT6357_HPL_SHORT2HPR_AUX_VAUDP15_DISABLE);
+		usleep_range(100, 120);
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		priv->hp_channel_number--;
+		if (priv->hp_channel_number > 0)
+			break;
+		/* Short HP main output to HP aux output stage */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPR_SHORT2HPR_AUX_VAUDP15_MASK |
+				   MT6357_HPL_SHORT2HPR_AUX_VAUDP15_MASK,
+				   MT6357_HPR_SHORT2HPR_AUX_VAUDP15_ENABLE |
+				   MT6357_HPL_SHORT2HPR_AUX_VAUDP15_ENABLE);
+		/* Enable HP aux output stage */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPROUT_AUX_PWRUP_VAUDP15_MASK |
+				   MT6357_HPLOUT_AUX_PWRUP_VAUDP15_MASK,
+				   MT6357_HPROUT_AUX_PWRUP_VAUDP15_ENABLE |
+				   MT6357_HPLOUT_AUX_PWRUP_VAUDP15_ENABLE);
+		/* decrease HPL/R gain to normal gain step by step */
+		hp_volume_ramp(priv, lgain, DL_GAIN_N_40DB,
+			       rgain, DL_GAIN_N_40DB);
+		/* Enable HP aux feedback loop */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPR_AUX_FBRSW_VAUDP15_MASK |
+				   MT6357_HPL_AUX_FBRSW_VAUDP15_MASK,
+				   MT6357_HPR_AUX_FBRSW_VAUDP15_ENABLE |
+				   MT6357_HPL_AUX_FBRSW_VAUDP15_ENABLE);
+		/* Reduce HP aux feedback loop gain */
+		hp_aux_feedback_loop_gain_ramp(priv, false);
+		/* decrease HPR/L main output stage step by step */
+		hp_main_output_ramp(priv, false);
+		/* Disable HP main output stage */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPROUT_PWRUP_VAUDP15_MASK |
+				   MT6357_HPLOUT_PWRUP_VAUDP15_MASK,
+				   MT6357_HPROUT_PWRUP_VAUDP15_DISABLE |
+				   MT6357_HPLOUT_PWRUP_VAUDP15_DISABLE);
+		/* Enable HP aux CMFB loop */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
+				   MT6357_HP_CMFB_RST_MASK |
+				   MT6357_HPL_AUX_CMFB_LOOP_MASK |
+				   MT6357_HPR_AUX_CMFB_LOOP_MASK,
+				   MT6357_HP_CMFB_RST_RESET |
+				   MT6357_HPL_AUX_CMFB_LOOP_ENABLE |
+				   MT6357_HPR_AUX_CMFB_LOOP_ENABLE);
+		/* Disable HP main CMFB loop */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
+				   MT6357_HPRL_MAIN_CMFB_LOOP_MASK,
+				   MT6357_HPRL_MAIN_CMFB_LOOP_DISABLE);
+		/* Unshort HP main output to HP aux output stage */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPR_SHORT2HPR_AUX_VAUDP15_MASK |
+				   MT6357_HPL_SHORT2HPR_AUX_VAUDP15_MASK,
+				   MT6357_HPR_SHORT2HPR_AUX_VAUDP15_DISABLE |
+				   MT6357_HPL_SHORT2HPR_AUX_VAUDP15_DISABLE);
+		/* Disable HP driver core circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
+				   MT6357_AUD_HPR_PWRUP_VAUDP15_MASK |
+				   MT6357_AUD_HPL_PWRUP_VAUDP15_MASK,
+				   MT6357_AUD_HPR_PWRUP_VAUDP15_DISABLE |
+				   MT6357_AUD_HPL_PWRUP_VAUDP15_DISABLE);
+		/* Disable HP driver bias circuits */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
+				   MT6357_AUD_HPR_BIAS_VAUDP15_MASK |
+				   MT6357_AUD_HPL_BIAS_VAUDP15_MASK,
+				   MT6357_AUD_HPR_BIAS_VAUDP15_DISABLE |
+				   MT6357_AUD_HPL_BIAS_VAUDP15_DISABLE);
+		/* Disable HP aux CMFB loop,
+		 * Enable HP main CMFB for HP off state
+		 */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
+				   MT6357_HPRL_MAIN_CMFB_LOOP_MASK |
+				   MT6357_HPR_AUX_CMFB_LOOP_MASK |
+				   MT6357_HPL_AUX_CMFB_LOOP_MASK,
+				   MT6357_HPRL_MAIN_CMFB_LOOP_ENABLE |
+				   MT6357_HPR_AUX_CMFB_LOOP_DISABLE |
+				   MT6357_HPL_AUX_CMFB_LOOP_DISABLE);
+		/* Disable HP aux feedback loop */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPR_AUX_FBRSW_VAUDP15_MASK |
+				   MT6357_HPL_AUX_FBRSW_VAUDP15_MASK,
+				   MT6357_HPR_AUX_FBRSW_VAUDP15_DISABLE |
+				   MT6357_HPL_AUX_FBRSW_VAUDP15_DISABLE);
+		/* Disable HP aux output stage */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
+				   MT6357_HPROUT_AUX_PWRUP_VAUDP15_MASK |
+				   MT6357_HPLOUT_AUX_PWRUP_VAUDP15_MASK,
+				   MT6357_HPROUT_AUX_PWRUP_VAUDP15_DISABLE |
+				   MT6357_HPLOUT_AUX_PWRUP_VAUDP15_DISABLE);
+		/* Save the gain value into the register*/
+		regmap_update_bits(priv->regmap, MT6357_ZCD_CON2,
+				   MT6357_AUD_HPL_GAIN_MASK |
+				   MT6357_AUD_HPR_GAIN_MASK,
+				   lgain << MT6357_AUD_HPL_GAIN_SFT |
+				   rgain << MT6357_AUD_HPR_GAIN_SFT);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int right_dac_event(struct snd_soc_dapm_widget *w,
+			   struct snd_kcontrol *kcontrol,
+			   int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		/* Enable Audio DAC and control audio bias gen */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
+				   MT6357_AUD_DACR_PWRUP_VA28_MASK |
+				   MT6357_AUD_DACR_PWRUP_VAUDP15_MASK,
+				   MT6357_AUD_DACR_PWRUP_VA28_ENABLE |
+				   MT6357_AUD_DACR_PWRUP_VAUDP15_ENABLE);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		/* disable Pull-down HPL/R to AVSS28_AUD */
+		if (priv->pull_down_needed)
+			hp_pull_down(priv, false);
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		/* Pull-down HPL/R to AVSS28_AUD */
+		if (priv->pull_down_needed)
+			hp_pull_down(priv, true);
+		/* Disable Audio DAC and control audio bias gen  */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
+				   MT6357_AUD_DACR_PWRUP_VA28_MASK |
+				   MT6357_AUD_DACR_PWRUP_VAUDP15_MASK,
+				   MT6357_AUD_DACR_PWRUP_VA28_DISABLE |
+				   MT6357_AUD_DACR_PWRUP_VAUDP15_DISABLE);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int left_dac_event(struct snd_soc_dapm_widget *w,
+			  struct snd_kcontrol *kcontrol,
+			  int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		/* Enable Audio DAC and control audio bias gen  */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
+				   MT6357_AUD_DACL_PWRUP_VA28_MASK |
+				   MT6357_AUD_DACL_PWRUP_VAUDP15_MASK,
+				   MT6357_AUD_DACL_PWRUP_VA28_ENABLE |
+				   MT6357_AUD_DACL_PWRUP_VAUDP15_ENABLE);
+		break;
+	case SND_SOC_DAPM_POST_PMU:
+		/* disable Pull-down HPL/R to AVSS28_AUD */
+		if (priv->pull_down_needed)
+			hp_pull_down(priv, false);
+		break;
+	case SND_SOC_DAPM_PRE_PMD:
+		/* Pull-down HPL/R to AVSS28_AUD */
+		if (priv->pull_down_needed)
+			hp_pull_down(priv, true);
+		/* Disable Audio DAC and control audio bias gen  */
+		regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
+				   MT6357_AUD_DACL_PWRUP_VA28_MASK |
+				   MT6357_AUD_DACL_PWRUP_VAUDP15_MASK,
+				   MT6357_AUD_DACL_PWRUP_VA28_DISABLE |
+				   MT6357_AUD_DACL_PWRUP_VAUDP15_DISABLE);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+/* Supply widgets subsequence */
+enum {
+	/* common */
+	SUPPLY_SEQ_CLK_BUF,
+	SUPPLY_SEQ_AUD_GLB,
+	SUPPLY_SEQ_CLKSQ,
+	SUPPLY_SEQ_VOW_AUD_LPW,
+	SUPPLY_SEQ_AUD_VOW,
+	SUPPLY_SEQ_VOW_CLK,
+	SUPPLY_SEQ_VOW_LDO,
+	SUPPLY_SEQ_TOP_CK,
+	SUPPLY_SEQ_TOP_CK_LAST,
+	SUPPLY_SEQ_AUD_TOP,
+	SUPPLY_SEQ_AUD_TOP_LAST,
+	SUPPLY_SEQ_AFE,
+	/* capture */
+	SUPPLY_SEQ_ADC_SUPPLY,
+};
+
+/* DAPM Widgets */
+static const struct snd_soc_dapm_widget mt6357_dapm_widgets[] = {
+	/* Analog Clocks */
+	SND_SOC_DAPM_SUPPLY_S("CLK_BUF", SUPPLY_SEQ_CLK_BUF,
+			      MT6357_DCXO_CW14,
+			      MT6357_XO_AUDIO_EN_M_SFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("AUDGLB", SUPPLY_SEQ_AUD_GLB,
+			      MT6357_AUDDEC_ANA_CON11,
+			      MT6357_AUDGLB_PWRDN_VA28_SFT, 1, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("CLKSQ Audio", SUPPLY_SEQ_CLKSQ,
+			      MT6357_AUDENC_ANA_CON6,
+			      MT6357_CLKSQ_EN_SFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("AUDNCP_CK", SUPPLY_SEQ_TOP_CK,
+			      MT6357_AUD_TOP_CKPDN_CON0,
+			      MT6357_AUDNCP_CK_PDN_SFT, 1, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("ZCD13M_CK", SUPPLY_SEQ_TOP_CK,
+			      MT6357_AUD_TOP_CKPDN_CON0,
+			      MT6357_ZCD13M_CK_PDN_SFT, 1, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("AUD_CK", SUPPLY_SEQ_TOP_CK_LAST,
+			      MT6357_AUD_TOP_CKPDN_CON0,
+			      MT6357_AUD_CK_PDN_SFT, 1,
+			      mt_delay_250_event,
+			      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+	SND_SOC_DAPM_SUPPLY_S("AUDIF_CK", SUPPLY_SEQ_TOP_CK,
+			      MT6357_AUD_TOP_CKPDN_CON0,
+			      MT6357_AUDIF_CK_PDN_SFT, 1, NULL, 0),
+
+	/* Digital Clocks */
+	SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_AFE_CTL", SUPPLY_SEQ_AUD_TOP_LAST,
+			      MT6357_AUDIO_TOP_CON0,
+			      MT6357_PDN_AFE_CTL_SFT, 1,
+			      mt_delay_250_event,
+			      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+	SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_DAC_CTL", SUPPLY_SEQ_AUD_TOP,
+			      MT6357_AUDIO_TOP_CON0,
+			      MT6357_PDN_DAC_CTL_SFT, 1, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_ADC_CTL", SUPPLY_SEQ_AUD_TOP,
+			      MT6357_AUDIO_TOP_CON0,
+			      MT6357_PDN_ADC_CTL_SFT, 1, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_I2S_DL", SUPPLY_SEQ_AUD_TOP,
+			      MT6357_AUDIO_TOP_CON0,
+			      MT6357_PDN_I2S_DL_CTL_SFT, 1, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PWR_CLK", SUPPLY_SEQ_AUD_TOP,
+			      MT6357_AUDIO_TOP_CON0,
+			      MT6357_PWR_CLK_DIS_CTL_SFT, 1, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PDN_AFE_TESTMODEL", SUPPLY_SEQ_AUD_TOP,
+			      MT6357_AUDIO_TOP_CON0,
+			      MT6357_PDN_AFE_TESTMODEL_CTL_SFT, 1, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PDN_RESERVED", SUPPLY_SEQ_AUD_TOP,
+			      MT6357_AUDIO_TOP_CON0,
+			      MT6357_PDN_RESERVED_SFT, 1, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_LPBK", SUPPLY_SEQ_AUD_TOP,
+			      MT6357_AUDIO_TOP_CON0,
+			      MT6357_PDN_LPBK_CTL_SFT, 1, NULL, 0),
+
+	/* General */
+	SND_SOC_DAPM_SUPPLY_S("AFE_ON", SUPPLY_SEQ_AFE,
+			      MT6357_AFE_UL_DL_CON0,
+			      MT6357_AFE_ON_SFT, 0, NULL, 0),
+
+	/* Uplinks */
+	SND_SOC_DAPM_AIF_OUT_E("AIF1TX", "MT6357 Capture", 0,
+			       SND_SOC_NOPM, 0, 0,
+			       mt_aif_out_event,
+			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ADC Supply", SUPPLY_SEQ_ADC_SUPPLY,
+			      SND_SOC_NOPM, 0, 0,
+			      mt_adc_supply_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_ADC_E("ADC", NULL, SND_SOC_NOPM, 0, 0, adc_enable_event,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_MUX_E("PGA L Mux", SND_SOC_NOPM, 0, 0,
+			   &pga_left_mux_control,
+			   mt_pga_left_event,
+			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+	SND_SOC_DAPM_MUX_E("PGA R Mux", SND_SOC_NOPM, 0, 0,
+			   &pga_right_mux_control,
+			   mt_pga_right_event,
+			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+	SND_SOC_DAPM_PGA("PGA L", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("PGA R", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_MUX_E("Mic Type Mux", SND_SOC_NOPM, 0, 0,
+			   &mic_type_mux_control,
+			   mt_mic_type_event,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY("MICBIAS0", MT6357_AUDENC_ANA_CON8,
+			    MT6357_AUD_MICBIAS0_PWD_SFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("MICBIAS1", MT6357_AUDENC_ANA_CON9,
+			    MT6357_AUD_MICBIAS1_PWD_SFT, 0, NULL, 0),
+
+	/* UL inputs */
+	SND_SOC_DAPM_INPUT("AIN0"),
+	SND_SOC_DAPM_INPUT("AIN1"),
+	SND_SOC_DAPM_INPUT("AIN2"),
+	SND_SOC_DAPM_INPUT("LPBK"),
+	SND_SOC_DAPM_INPUT("SGEN UL"),
+
+	/* Downlinks */
+	SND_SOC_DAPM_AIF_IN_E("AIF_RX", "MT6357 Playback", 0,
+			      SND_SOC_NOPM, 0, 0,
+			      mt_audio_in_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_INPUT("SGEN DL"),
+	SND_SOC_DAPM_MUX("DAC Mux", SND_SOC_NOPM, 0, 0, &dac_mux_control),
+
+	SND_SOC_DAPM_DAC_E("DACR", NULL, SND_SOC_NOPM, 0, 0, right_dac_event,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+	SND_SOC_DAPM_DAC_E("DACL", NULL, SND_SOC_NOPM, 0, 0, left_dac_event,
+			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+	SND_SOC_DAPM_SUPPLY("DL Digital Supply", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("DL Analog Supply", SND_SOC_NOPM, 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("DL SRC", MT6357_AFE_DL_SRC2_CON0_L,
+			    MT6357_DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0, NULL, 0),
+
+	SND_SOC_DAPM_MUX_E("Line Out Source", SND_SOC_NOPM, 0, 0, &lo_mux_control,
+			   lo_mux_event,
+			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+	SND_SOC_DAPM_MUX_E("Handset Source", SND_SOC_NOPM, 0, 0, &hs_mux_control,
+			   hs_mux_event,
+			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+	SND_SOC_DAPM_MUX_E("Headphone Right Source", SND_SOC_NOPM, 0, 0, &hpr_mux_control,
+			   hp_main_mux_event,
+			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+	SND_SOC_DAPM_MUX_E("Headphone Left Source", SND_SOC_NOPM, 0, 0, &hpl_mux_control,
+			   hp_main_mux_event,
+			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+	/* DL outputs */
+	SND_SOC_DAPM_OUTPUT("Headphones"),
+	SND_SOC_DAPM_OUTPUT("Hansdet"),
+	SND_SOC_DAPM_OUTPUT("Line out"),
+
+	/* Sine generator */
+	SND_SOC_DAPM_SUPPLY("SGEN UL Enable",
+			    MT6357_AFE_TOP_CON0, MT6357_UL_SINE_ON_SFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("SGEN Enable",
+			    MT6357_AFE_SGEN_CFG0,
+			    MT6357_SGEN_DAC_EN_CTL_SFT, 0, mt_audio_in_event,
+			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY("SGEN MUTE",
+			    MT6357_AFE_SGEN_CFG0,
+			    MT6357_SGEN_MUTE_SW_CTL_SFT, 1, NULL, 0)
+};
+
+static const struct snd_soc_dapm_route mt6357_dapm_routes[] = {
+	/* Capture */
+	{"AIF1TX", NULL, "Mic Type Mux"},
+	{"AIF1TX", NULL, "CLK_BUF"},
+	{"AIF1TX", NULL, "AUDGLB"},
+	{"AIF1TX", NULL, "CLKSQ Audio"},
+	{"AIF1TX", NULL, "AUD_CK"},
+	{"AIF1TX", NULL, "AUDIF_CK"},
+
+	{"AIF1TX", NULL, "AUDIO_TOP_AFE_CTL"},
+	{"AIF1TX", NULL, "AUDIO_TOP_ADC_CTL"},
+	{"AIF1TX", NULL, "AUDIO_TOP_PWR_CLK"},
+	{"AIF1TX", NULL, "AUDIO_TOP_PDN_RESERVED"},
+	{"AIF1TX", NULL, "AUDIO_TOP_I2S_DL"},
+	{"AIF1TX", NULL, "AFE_ON"},
+
+	{"Mic Type Mux", "ACC", "ADC"},
+	{"Mic Type Mux", "DCC", "ADC"},
+	{"Mic Type Mux", "DCC_ECM_DIFF", "ADC"},
+	{"Mic Type Mux", "DCC_ECM_SINGLE", "ADC"},
+	{"Mic Type Mux", "DMIC", "AIN0"},
+	{"Mic Type Mux", "DMIC", "AIN2"},
+	{"Mic Type Mux", "Loopback", "LPBK"},
+	{"Mic Type Mux", "Sine Generator", "SGEN UL"},
+
+	{"SGEN UL", NULL, "AUDIO_TOP_PDN_AFE_TESTMODEL"},
+	{"SGEN UL", NULL, "SGEN UL Enable"},
+	{"SGEN UL", NULL, "SGEN MUTE"},
+	{"SGEN UL", NULL, "SGEN Enable"},
+
+	{"ADC", NULL, "PGA L Mux"},
+	{"ADC", NULL, "PGA R Mux"},
+	{"ADC", NULL, "ADC Supply"},
+
+	{"PGA L Mux", "AIN0", "AIN0"},
+	{"PGA L Mux", "AIN1", "AIN1"},
+	{"PGA L Mux", "AIN2", "AIN2"},
+
+	{"PGA R Mux", "AIN0", "AIN0"},
+	{"PGA R Mux", "AIN1", "AIN1"},
+	{"PGA R Mux", "AIN2", "AIN2"},
+
+	{"AIN0", NULL, "MICBIAS0"},
+	{"AIN1", NULL, "MICBIAS1"},
+	{"AIN2", NULL, "MICBIAS0"},
+	{"LPBK", NULL, "AUDIO_TOP_LPBK"},
+
+	/* Playback */
+	{"DAC Mux", "Normal Path", "AIF_RX"},
+	{"DAC Mux", "Sine Generator", "SGEN DL"},
+
+	{"AIF_RX", NULL, "DL SRC"},
+
+	{"SGEN DL", NULL, "DL SRC"},
+	{"SGEN DL", NULL, "SGEN MUTE"},
+	{"SGEN DL", NULL, "SGEN Enable"},
+	{"SGEN DL", NULL, "DL Digital Supply"},
+	{"SGEN DL", NULL, "AUDIO_TOP_PDN_AFE_TESTMODEL"},
+
+	{"DACL", NULL, "DAC Mux"},
+	{"DACR", NULL, "DAC Mux"},
+
+	{"DL Analog Supply", NULL, "CLK_BUF"},
+	{"DL Analog Supply", NULL, "AUDGLB"},
+	{"DL Analog Supply", NULL, "CLKSQ Audio"},
+	{"DL Analog Supply", NULL, "AUDNCP_CK"},
+	{"DL Analog Supply", NULL, "ZCD13M_CK"},
+	{"DL Analog Supply", NULL, "AUD_CK"},
+	{"DL Analog Supply", NULL, "AUDIF_CK"},
+
+	{"DL Digital Supply", NULL, "AUDIO_TOP_AFE_CTL"},
+	{"DL Digital Supply", NULL, "AUDIO_TOP_DAC_CTL"},
+	{"DL Digital Supply", NULL, "AUDIO_TOP_PWR_CLK"},
+	{"DL Digital Supply", NULL, "AFE_ON"},
+
+	{"DACR", NULL, "DL Digital Supply"},
+	{"DACR", NULL, "DL Analog Supply"},
+	{"DACL", NULL, "DL Digital Supply"},
+	{"DACL", NULL, "DL Analog Supply"},
+
+	{"Line Out Source", "DACR", "DACR"},
+	{"Line Out Source", "Playback", "DACL"},
+	{"Line Out Source", "Test mode", "DACL"},
+
+	{"Handset Source", "DACR", "DACR"},
+	{"Handset Source", "Playback", "DACL"},
+	{"Handset Source", "Test mode", "DACL"},
+
+	{"Headphone Right Source", "DAC", "DACR"},
+	{"Headphone Right Source", "Line Out", "Line Out Source"},
+	{"Headphone Right Source", "Handset", "Handset Source"},
+
+	{"Headphone Left Source", "DAC", "DACL"},
+	{"Headphone Left Source", "Line Out", "Line Out Source"},
+	{"Headphone Left Source", "Handset", "Handset Source"},
+
+	{"Line out", NULL, "Line Out Source"},
+	{"Hansdet", NULL, "Handset Source"},
+
+	{"Headphones", NULL, "Headphone Right Source"},
+	{"Headphones", NULL, "Headphone Left Source"},
+};
+
+static struct snd_soc_dai_driver mtk_6357_dai_codecs[] = {
+	{
+		.name = "mt6357-snd-codec-aif1",
+		.playback = {
+			.stream_name = "MT6357 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_8000_192000,
+			.formats = MT6357_SND_SOC_ADV_MT_FMTS,
+			},
+		.capture = {
+			.stream_name = "MT6357 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = MT6357_SOC_HIGH_USE_RATE,
+			.formats = MT6357_SND_SOC_ADV_MT_FMTS,
+			},
+	},
+};
+
+static void mt6357_codec_init(struct mt6357_priv *priv)
+{
+	/* Enable audio part */
+	regmap_update_bits(priv->regmap, MT6357_DCXO_CW14,
+			   MT6357_XO_AUDIO_EN_M_MASK, MT6357_XO_AUDIO_EN_M_ENABLE);
+	/* Disable HeadphoneL/HeadphoneR short circuit protection */
+	regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
+			   MT6357_AUD_HPR_SC_VAUDP15_MASK |
+			   MT6357_AUD_HPL_SC_VAUDP15_MASK,
+			   MT6357_AUD_HPR_SC_VAUDP15_DISABLE |
+			   MT6357_AUD_HPL_SC_VAUDP15_DISABLE);
+	/* Disable voice short circuit protection */
+	regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
+			   MT6357_AUD_HS_SC_VAUDP15_MASK,
+			   MT6357_AUD_HS_SC_VAUDP15_DISABLE);
+	/* disable LO buffer left short circuit protection */
+	regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
+			   MT6357_AUD_LOL_SC_VAUDP15_MASK,
+			   MT6357_AUD_LOL_SC_VAUDP15_DISABLE);
+	/* set gpio */
+	set_playback_gpio(priv, false);
+	set_capture_gpio(priv, false);
+	/* Disable audio part */
+	regmap_update_bits(priv->regmap, MT6357_DCXO_CW14,
+			   MT6357_XO_AUDIO_EN_M_MASK,
+			   MT6357_XO_AUDIO_EN_M_DISABLE);
+
+	/* gain default values*/
+	regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0, MT6357_AUDPREAMPLGAIN_MASK,
+			   UL_GAIN_0DB << MT6357_AUDPREAMPLGAIN_SFT);
+	regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1, MT6357_AUDPREAMPRGAIN_MASK,
+			   UL_GAIN_0DB << MT6357_AUDPREAMPRGAIN_SFT);
+
+	regmap_update_bits(priv->regmap, MT6357_ZCD_CON1,
+			   MT6357_AUD_LOL_GAIN_MASK |
+			   MT6357_AUD_LOR_GAIN_MASK,
+			   DL_GAIN_0DB << MT6357_AUD_LOL_GAIN_SFT |
+			   DL_GAIN_0DB << MT6357_AUD_LOR_GAIN_SFT);
+
+	regmap_update_bits(priv->regmap, MT6357_ZCD_CON2,
+			   MT6357_AUD_HPL_GAIN_MASK |
+			   MT6357_AUD_HPR_GAIN_MASK,
+			   DL_GAIN_0DB << MT6357_AUD_HPL_GAIN_SFT |
+			   DL_GAIN_0DB << MT6357_AUD_HPR_GAIN_SFT);
+
+	regmap_update_bits(priv->regmap, MT6357_ZCD_CON3,
+			   MT6357_AUD_HS_GAIN_MASK, DL_GAIN_0DB);
+}
+
+static int mt6357_codec_probe(struct snd_soc_component *codec)
+{
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(codec);
+
+	mt6357_codec_init(priv);
+	return 0;
+}
+
+static unsigned int mt6357_read(struct snd_soc_component *codec, unsigned int reg)
+{
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(codec);
+	unsigned int val;
+
+	regmap_read(priv->regmap, reg, &val);
+	return val;
+}
+
+static int mt6357_write(struct snd_soc_component *codec, unsigned int reg, unsigned int value)
+{
+	struct mt6357_priv *priv = snd_soc_component_get_drvdata(codec);
+
+	return regmap_update_bits(priv->regmap, reg, 0xffff, value);
+}
+
+static const struct snd_soc_component_driver mt6357_soc_component_driver = {
+	.probe = mt6357_codec_probe,
+	.read = mt6357_read,
+	.write = mt6357_write,
+	.controls = mt6357_controls,
+	.num_controls = ARRAY_SIZE(mt6357_controls),
+	.dapm_widgets = mt6357_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(mt6357_dapm_widgets),
+	.dapm_routes = mt6357_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(mt6357_dapm_routes),
+};
+
+static const u32 micbias_values[MT6357_MICBIAS_ARRAY_SIZE] = {
+	1700000, 1800000, 1900000, 2000000,
+	2100000, 2500000, 2600000, 2700000
+};
+
+static u32 mt6357_get_micbias_idx(struct device_node *np, const char *micbias)
+{
+	int err;
+	u32 idx, val;
+
+	err = of_property_read_u32(np, micbias,  &val);
+	if (err)
+		return 0;
+
+	for (idx = 0; idx < MT6357_MICBIAS_ARRAY_SIZE; idx++) {
+		if (val == micbias_values[idx])
+			return idx;
+	}
+	return 0;
+}
+
+static int mt6357_parse_dt(struct mt6357_priv *priv)
+{
+	u32 micbias_voltage_index = 0;
+	struct device_node *np;
+
+	np = of_get_child_by_name(priv->dev->parent->of_node, "codec");
+	if (!np)
+		return -EINVAL;
+
+	priv->pull_down_needed = false;
+	if (of_property_read_bool(np, "mediatek,hp-pull-down"))
+		priv->pull_down_needed = true;
+
+	micbias_voltage_index = mt6357_get_micbias_idx(np, "mediatek,micbias0-microvolt");
+	regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON8,
+			   MT6357_AUD_MICBIAS0_VREF_MASK,
+			   micbias_voltage_index << MT6357_AUD_MICBIAS0_VREF_SFT);
+
+	micbias_voltage_index = mt6357_get_micbias_idx(np, "mediatek,micbias1-microvolt");
+	regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON9,
+			   MT6357_AUD_MICBIAS1_VREF_MASK,
+			   micbias_voltage_index << MT6357_AUD_MICBIAS1_VREF_SFT);
+
+	return 0;
+}
+
+static int mt6357_platform_driver_probe(struct platform_device *pdev)
+{
+	struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
+	struct mt6357_priv *priv;
+	int ret;
+
+	ret = devm_regulator_get_enable(&pdev->dev, "vaud28");
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "Failed to enable vaud28 regulator\n");
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	dev_set_drvdata(&pdev->dev, priv);
+	priv->dev = &pdev->dev;
+
+	priv->regmap = mt6397->regmap;
+	if (IS_ERR(priv->regmap))
+		return PTR_ERR(priv->regmap);
+
+	ret = mt6357_parse_dt(priv);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "Failed to parse dts\n", __func__);
+
+	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(64);
+	if (!pdev->dev.dma_mask)
+		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+
+	return devm_snd_soc_register_component(&pdev->dev,
+					       &mt6357_soc_component_driver,
+					       mtk_6357_dai_codecs,
+					       ARRAY_SIZE(mtk_6357_dai_codecs));
+}
+
+static const struct platform_device_id mt6357_platform_ids[] = {
+	{"mt6357-sound", 0},
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(platform, mt6357_platform_ids);
+
+static struct platform_driver mt6357_platform_driver = {
+	.driver = {
+		.name = "mt6357-sound",
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
+	},
+	.probe = mt6357_platform_driver_probe,
+	.id_table = mt6357_platform_ids,
+};
+
+module_platform_driver(mt6357_platform_driver)
+
+MODULE_DESCRIPTION("MT6357 ALSA SoC codec driver");
+MODULE_AUTHOR("Nicolas Belin <nbelin@baylibre.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/mt6357.h b/sound/soc/codecs/mt6357.h
new file mode 100644
index 000000000000..68fd2ed90353
--- /dev/null
+++ b/sound/soc/codecs/mt6357.h
@@ -0,0 +1,662 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mt6357.h  --  mt6357 ALSA SoC audio codec driver
+ *
+ * Copyright (c) 2024 Baylibre
+ * Author: Nicolas Belin <nbelin@baylibre.com>
+ */
+
+#ifndef __MT6357_H__
+#define __MT6357_H__
+
+#include <linux/types.h>
+
+/* Reg bit defines */
+/* MT6357_GPIO_DIR0 */
+#define MT6357_GPIO8_DIR_MASK			BIT(8)
+#define MT6357_GPIO8_DIR_INPUT			0
+#define MT6357_GPIO8_DIR_OUTPUT			BIT(8)
+#define MT6357_GPIO9_DIR_MASK			BIT(9)
+#define MT6357_GPIO9_DIR_INPUT			0
+#define MT6357_GPIO9_DIR_OUTPUT			BIT(9)
+#define MT6357_GPIO10_DIR_MASK			BIT(10)
+#define MT6357_GPIO10_DIR_INPUT			0
+#define MT6357_GPIO10_DIR_OUTPUT		BIT(10)
+#define MT6357_GPIO11_DIR_MASK			BIT(11)
+#define MT6357_GPIO11_DIR_INPUT			0
+#define MT6357_GPIO11_DIR_OUTPUT		BIT(11)
+#define MT6357_GPIO12_DIR_MASK			BIT(12)
+#define MT6357_GPIO12_DIR_INPUT			0
+#define MT6357_GPIO12_DIR_OUTPUT		BIT(12)
+#define MT6357_GPIO13_DIR_MASK			BIT(13)
+#define MT6357_GPIO13_DIR_INPUT			0
+#define MT6357_GPIO13_DIR_OUTPUT		BIT(13)
+#define MT6357_GPIO14_DIR_MASK			BIT(14)
+#define MT6357_GPIO14_DIR_INPUT			0
+#define MT6357_GPIO14_DIR_OUTPUT		BIT(14)
+#define MT6357_GPIO15_DIR_MASK			BIT(15)
+#define MT6357_GPIO15_DIR_INPUT			0
+#define MT6357_GPIO15_DIR_OUTPUT		BIT(15)
+
+/* MT6357_GPIO_MODE2 */
+#define MT6357_GPIO8_MODE_MASK			GENMASK(2, 0)
+#define MT6357_GPIO8_MODE_AUD_CLK_MOSI		BIT(0)
+#define MT6357_GPIO8_MODE_GPIO			0
+#define MT6357_GPIO9_MODE_MASK			GENMASK(5, 3)
+#define MT6357_GPIO9_MODE_AUD_DAT_MOSI0		BIT(3)
+#define MT6357_GPIO9_MODE_GPIO			0
+#define MT6357_GPIO10_MODE_MASK			GENMASK(8, 6)
+#define MT6357_GPIO10_MODE_AUD_DAT_MOSI1	BIT(6)
+#define MT6357_GPIO10_MODE_GPIO			0
+#define MT6357_GPIO11_MODE_MASK			GENMASK(11, 9)
+#define MT6357_GPIO11_MODE_AUD_SYNC_MOSI	BIT(9)
+#define MT6357_GPIO11_MODE_GPIO			0
+
+/* MT6357_GPIO_MODE2_SET */
+#define MT6357_GPIO8_MODE_SET_MASK		GENMASK(2, 0)
+#define MT6357_GPIO8_MODE_SET_AUD_CLK_MOSI	BIT(0)
+#define MT6357_GPIO9_MODE_SET_MASK		GENMASK(5, 3)
+#define MT6357_GPIO9_MODE_SET_AUD_DAT_MOSI0	BIT(3)
+#define MT6357_GPIO10_MODE_SET_MASK		GENMASK(8, 6)
+#define MT6357_GPIO10_MODE_SET_AUD_DAT_MOSI1	BIT(6)
+#define MT6357_GPIO11_MODE_SET_MASK		GENMASK(11, 9)
+#define MT6357_GPIO11_MODE_SET_AUD_SYNC_MOSI	BIT(9)
+
+/* MT6357_GPIO_MODE2_CLR */
+#define MT6357_GPIO_MODE2_CLEAR_ALL		GENMASK(15, 0)
+
+/* MT6357_GPIO_MODE3 */
+#define MT6357_GPIO12_MODE_MASK			GENMASK(2, 0)
+#define MT6357_GPIO12_MODE_AUD_CLK_MISO		BIT(0)
+#define MT6357_GPIO12_MODE_GPIO			0
+#define MT6357_GPIO13_MODE_MASK			GENMASK(5, 3)
+#define MT6357_GPIO13_MODE_AUD_DAT_MISO0	BIT(3)
+#define MT6357_GPIO13_MODE_GPIO			0
+#define MT6357_GPIO14_MODE_MASK			GENMASK(8, 6)
+#define MT6357_GPIO14_MODE_AUD_DAT_MISO1	BIT(6)
+#define MT6357_GPIO14_MODE_GPIO			0
+#define MT6357_GPIO15_MODE_MASK			GENMASK(11, 9)
+#define MT6357_GPIO15_MODE_AUD_SYNC_MISO	BIT(9)
+#define MT6357_GPIO15_MODE_GPIO			0
+
+/* MT6357_GPIO_MODE3_SET */
+#define MT6357_GPIO12_MODE_SET_MASK		GENMASK(2, 0)
+#define MT6357_GPIO12_MODE_SET_AUD_CLK_MISO	BIT(0)
+#define MT6357_GPIO13_MODE_SET_MASK		GENMASK(5, 3)
+#define MT6357_GPIO13_MODE_SET_AUD_DAT_MISO0	BIT(3)
+#define MT6357_GPIO14_MODE_SET_MASK		GENMASK(8, 6)
+#define MT6357_GPIO14_MODE_SET_AUD_DAT_MISO1	BIT(6)
+#define MT6357_GPIO15_MODE_SET_MASK		GENMASK(11, 9)
+#define MT6357_GPIO15_MODE_SET_AUD_SYNC_MISO	BIT(9)
+
+/* MT6357_GPIO_MODE3_CLR */
+#define MT6357_GPIO_MODE3_CLEAR_ALL		GENMASK(15, 0)
+
+/* MT6357_DCXO_CW14 */
+#define MT6357_XO_AUDIO_EN_M_SFT		13
+#define MT6357_XO_AUDIO_EN_M_MASK		BIT(13)
+#define MT6357_XO_AUDIO_EN_M_ENABLE		BIT(13)
+#define MT6357_XO_AUDIO_EN_M_DISABLE		0
+
+/* MT6357_AUD_TOP_CKPDN_CON0 */
+#define MT6357_AUDNCP_CK_PDN_SFT		6
+#define MT6357_ZCD13M_CK_PDN_SFT		5
+#define MT6357_AUDIF_CK_PDN_SFT			2
+#define MT6357_AUD_CK_PDN_SFT			1
+
+/* MT6357_AUDNCP_CLKDIV_CON0 */
+#define MT6357_DIVCKS_CHG			BIT(0)
+
+/* MT6357_AUDNCP_CLKDIV_CON1 */
+#define MT6357_DIVCKS_ON			BIT(0)
+
+/* MT6357_AUDNCP_CLKDIV_CON3 */
+#define MT6357_DIVCKS_PWD_NCP_MASK		BIT(0)
+#define MT6357_DIVCKS_PWD_NCP_DISABLE		BIT(0)
+#define MT6357_DIVCKS_PWD_NCP_ENABLE		0
+
+/* MT6357_AUDNCP_CLKDIV_CON4 */
+#define MT6357_DIVCKS_PWD_NCP_ST_SEL_MASK	GENMASK(1, 0)
+#define MT6357_DIVCKS_PWD_NCP_ST_50US		0
+#define MT6357_DIVCKS_PWD_NCP_ST_100US		1
+#define MT6357_DIVCKS_PWD_NCP_ST_150US		2
+#define MT6357_DIVCKS_PWD_NCP_ST_200US		3
+
+/* MT6357_AFE_UL_DL_CON0 */
+#define MT6357_AFE_UL_LR_SWAP_SFT		15
+#define MT6357_AFE_ON_SFT			0
+
+/* MT6357_AFE_DL_SRC2_CON0_L */
+#define MT6357_DL_2_SRC_ON_TMP_CTL_PRE_SFT	0
+
+/* MT6357_AFE_UL_SRC_CON0_H */
+#define MT6357_C_TWO_DIGITAL_MIC_CTL_MASK	BIT(7)
+#define MT6357_C_TWO_DIGITAL_MIC_ENABLE		BIT(7)
+#define MT6357_C_TWO_DIGITAL_MIC_DISABLE	0
+
+/* MT6357_AFE_UL_SRC_CON0_L */
+#define MT6357_UL_SDM_3_LEVEL_CTL_MASK		BIT(1)
+#define MT6357_UL_SDM_3_LEVEL_SELECT		BIT(1)
+#define MT6357_UL_SDM_3_LEVEL_DESELECT		0
+#define MT6357_UL_SRC_ON_TMP_CTL_MASK		BIT(0)
+#define MT6357_UL_SRC_ENABLE			BIT(0)
+#define MT6357_UL_SRC_DISABLE			0
+
+/* MT6357_AFE_TOP_CON0 */
+#define MT6357_UL_SINE_ON_SFT			1
+#define MT6357_UL_SINE_ON_MASK			BIT(1)
+#define MT6357_DL_SINE_ON_SFT			0
+#define MT6357_DL_SINE_ON_MASK			BIT(0)
+
+/* MT6357_AUDIO_TOP_CON0 */
+#define MT6357_PDN_LPBK_CTL_SFT			15
+#define MT6357_PDN_AFE_CTL_SFT			7
+#define MT6357_PDN_DAC_CTL_SFT			6
+#define MT6357_PDN_ADC_CTL_SFT			5
+#define MT6357_PDN_I2S_DL_CTL_SFT		3
+#define MT6357_PWR_CLK_DIS_CTL_SFT		2
+#define MT6357_PDN_AFE_TESTMODEL_CTL_SFT	1
+#define MT6357_PDN_RESERVED_SFT			0
+
+/* MT6357_AFUNC_AUD_CON0 */
+#define MT6357_CCI_AUD_ANACK_INVERT			BIT(15)
+#define MT6357_CCI_AUD_ANACK_NORMAL			0
+#define MT6357_CCI_AUDIO_FIFO_WPTR_SFT			12
+#define MT6357_CCI_SCRAMBLER_CG_ENABLE			BIT(11)
+#define MT6357_CCI_SCRAMBLER_CG_DISABLE			0
+#define MT6357_CCI_LCK_INV_OUT_OF_PHASE			BIT(10)
+#define MT6357_CCI_LCK_INV_IN_PHASE			0
+#define MT6357_CCI_RAND_ENABLE				BIT(9)
+#define MT6357_CCI_RAND_DISABLE				0
+#define MT6357_CCI_SPLT_SCRMB_CLK_ON			BIT(8)
+#define MT6357_CCI_SPLT_SCRMB_CLK_OFF			0
+#define MT6357_CCI_SPLT_SCRMB_ON			BIT(7)
+#define MT6357_CCI_SPLT_SCRMB_OFF			0
+#define MT6357_CCI_AUD_IDAC_TEST_EN_FROM_TEST_IN	BIT(6)
+#define MT6357_CCI_AUD_IDAC_TEST_EN_NORMAL_PATH		0
+#define MT6357_CCI_ZERO_PADDING_DISABLE			BIT(5)
+#define MT6357_CCI_ZERO_PADDING_ENABLE			0
+#define MT6357_CCI_AUD_SPLIT_TEST_EN_FROM_TEST_IN	BIT(4)
+#define MT6357_CCI_AUD_SPLIT_TEST_EN_NORMAL_PATH	0
+#define MT6357_CCI_AUD_SDM_MUTE_L_REG_CTL		BIT(3)
+#define MT6357_CCI_AUD_SDM_MUTE_L_NO_CTL		0
+#define MT6357_CCI_AUD_SDM_MUTE_R_REG_CTL		BIT(2)
+#define MT6357_CCI_AUD_SDM_MUTE_R_NO_CTL		0
+#define MT6357_CCI_AUD_SDM_7BIT_FROM_SPLITTER3		BIT(1)
+#define MT6357_CCI_AUD_SDM_7BIT_FROM_SPLITTER1		0
+#define MT6357_CCI_SCRAMBLER_ENABLE			BIT(0)
+#define MT6357_CCI_SCRAMBLER_DISABLE			0
+
+/* MT6357_AFUNC_AUD_CON2 */
+#define MT6357_CCI_AUDIO_FIFO_ENABLE		BIT(3)
+#define MT6357_CCI_AUDIO_FIFO_DISABLE		0
+#define MT6357_CCI_ACD_MODE_NORMAL_PATH		BIT(2)
+#define MT6357_CCI_ACD_MODE_TEST_PATH		0
+#define MT6357_CCI_AFIFO_CLK_PWDB_ON		BIT(1)
+#define MT6357_CCI_AFIFO_CLK_PWDB_DOWN		0
+#define MT6357_CCI_ACD_FUNC_RSTB_RELEASE	BIT(0)
+#define MT6357_CCI_ACD_FUNC_RSTB_RESET		0
+
+/* MT6357_AFE_ADDA_MTKAIF_CFG0 */
+#define MT6357_ADDA_MTKAIF_LPBK_CTL_MASK	BIT(1)
+#define MT6357_ADDA_MTKAIF_LPBK_ENABLE		BIT(1)
+#define MT6357_ADDA_MTKAIF_LPBK_DISABLE		0
+
+/* MT6357_AFE_SGEN_CFG0 */
+#define MT6357_SGEN_DAC_EN_CTL_SFT		7
+#define MT6357_SGEN_DAC_ENABLE			BIT(7)
+#define MT6357_SGEN_MUTE_SW_CTL_SFT		6
+#define MT6357_SGEN_MUTE_SW_DISABLE		0
+
+/* MT6357_AFE_DCCLK_CFG0 */
+#define MT6357_DCCLK_DIV_MASK			GENMASK(15, 5)
+#define MT6357_DCCLK_DIV_SFT			5
+#define MT6357_DCCLK_DIV_RUN_VALUE		(32 << MT6357_DCCLK_DIV_SFT)
+#define MT6357_DCCLK_DIV_STOP_VALUE		(259 << MT6357_DCCLK_DIV_SFT)
+#define MT6357_DCCLK_PDN_MASK			BIT(1)
+#define MT6357_DCCLK_PDN			BIT(1)
+#define MT6357_DCCLK_OUTPUT			0
+#define MT6357_DCCLK_GEN_ON_MASK		BIT(0)
+#define MT6357_DCCLK_GEN_ON			BIT(0)
+#define MT6357_DCCLK_GEN_OFF			0
+
+/* MT6357_AFE_DCCLK_CFG1 */
+#define MT6357_DCCLK_RESYNC_BYPASS_MASK		BIT(8)
+#define MT6357_DCCLK_RESYNC_BYPASS		BIT(8)
+
+/* MT6357_AFE_AUD_PAD_TOP */
+#define MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK		GENMASK(15, 8)
+#define MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_ENABLE	(BIT(13) | BIT(12) | BIT(8))
+#define MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_DISABLE	(BIT(13) | BIT(12))
+#define MT6357_AUD_PAD_TX_FIFO_LPBK_MASK		GENMASK(7, 0)
+#define MT6357_AUD_PAD_TX_FIFO_LPBK_ENABLE		(BIT(5) | BIT(4) | BIT(0))
+#define MT6357_AUD_PAD_TX_FIFO_LPBK_DISABLE		0
+
+/* MT6357_AUDENC_ANA_CON0 */
+#define MT6357_AUDADCLINPUTSEL_MASK		GENMASK(14, 13)
+#define MT6357_AUDADCLINPUTSEL_PREAMPLIFIER	BIT(14)
+#define MT6357_AUDADCLINPUTSEL_IDLE		0
+#define MT6357_AUDADCLPWRUP_SFT			12
+#define MT6357_AUDADCLPWRUP_MASK		BIT(12)
+#define MT6357_AUDADCLPWRUP			BIT(12)
+#define MT6357_AUDADCLPWRDOWN			0
+#define MT6357_AUDPREAMPLGAIN_SFT		8
+#define MT6357_AUDPREAMPLGAIN_MASK		GENMASK(10, 8)
+#define MT6357_AUDPREAMPLGAIN_MAX		4
+#define MT6357_AUDPREAMPLINPUTSEL_SFT		6
+#define MT6357_AUDPREAMPLINPUTSEL_MASK_NOSFT	GENMASK(1, 0)
+#define MT6357_AUDPREAMPLDCPRECHARGE_MASK	BIT(2)
+#define MT6357_AUDPREAMPLDCPRECHARGE_ENABLE	BIT(2)
+#define MT6357_AUDPREAMPLDCPRECHARGE_DISABLE	0
+#define MT6357_AUDPREAMPLDCCEN_MASK		BIT(1)
+#define MT6357_AUDPREAMPLDCCEN_DC		BIT(1)
+#define MT6357_AUDPREAMPLDCCEN_AC		0
+#define MT6357_AUDPREAMPLON_MASK		BIT(0)
+#define MT6357_AUDPREAMPLON_ENABLE		BIT(0)
+#define MT6357_AUDPREAMPLON_DISABLE		0
+
+/* MT6357_AUDENC_ANA_CON1 */
+#define MT6357_AUDADCRINPUTSEL_MASK		GENMASK(14, 13)
+#define MT6357_AUDADCRINPUTSEL_PREAMPLIFIER	BIT(14)
+#define MT6357_AUDADCRINPUTSEL_IDLE		0
+#define MT6357_AUDADCRPWRUP_SFT			12
+#define MT6357_AUDADCRPWRUP_MASK		BIT(12)
+#define MT6357_AUDADCRPWRUP			BIT(12)
+#define MT6357_AUDADCRPWRDOWN			0
+#define MT6357_AUDPREAMPRGAIN_SFT		8
+#define MT6357_AUDPREAMPRGAIN_MASK		GENMASK(10, 8)
+#define MT6357_AUDPREAMPRGAIN_MAX		4
+#define MT6357_AUDPREAMPRINPUTSEL_SFT		6
+#define MT6357_AUDPREAMPRINPUTSEL_MASK_NOSFT	GENMASK(1, 0)
+#define MT6357_AUDPREAMPRDCPRECHARGE_MASK	BIT(2)
+#define MT6357_AUDPREAMPRDCPRECHARGE_ENABLE	BIT(2)
+#define MT6357_AUDPREAMPRDCPRECHARGE_DISABLE	0
+#define MT6357_AUDPREAMPRDCCEN_MASK		BIT(1)
+#define MT6357_AUDPREAMPRDCCEN_DC		BIT(1)
+#define MT6357_AUDPREAMPRDCCEN_AC		0
+#define MT6357_AUDPREAMPRON_MASK		BIT(0)
+#define MT6357_AUDPREAMPRON_ENABLE		BIT(0)
+#define MT6357_AUDPREAMPRON_DISABLE		0
+
+/* MT6357_AUDENC_ANA_CON6 */
+#define MT6357_CLKSQ_EN_SFT			0
+
+/* MT6357_AUDENC_ANA_CON7 */
+#define MT6357_AUDDIGMICBIAS_MASK		GENMASK(2, 1)
+#define MT6357_AUDDIGMICBIAS_DEFAULT_VALUE	BIT(2)
+#define MT6357_AUDDIGMICBIAS_OFF		0
+#define MT6357_AUDDIGMICEN_MASK			BIT(0)
+#define MT6357_AUDDIGMICEN_ENABLE		BIT(0)
+#define MT6357_AUDDIGMICEN_DISABLE		0
+
+/* MT6357_AUDENC_ANA_CON8 */
+#define MT6357_AUD_MICBIAS0_DCSW2N_EN_MASK	BIT(14)
+#define MT6357_AUD_MICBIAS0_DCSW2N_ENABLE	BIT(14)
+#define MT6357_AUD_MICBIAS0_DCSW2N_DISABLE	0
+#define MT6357_AUD_MICBIAS0_DCSW2P2_EN_MASK	BIT(13)
+#define MT6357_AUD_MICBIAS0_DCSW2P2_ENABLE	BIT(13)
+#define MT6357_AUD_MICBIAS0_DCSW2P2_DISABLE	0
+#define MT6357_AUD_MICBIAS0_DCSW2P1_EN_MASK	BIT(12)
+#define MT6357_AUD_MICBIAS0_DCSW2P1_ENABLE	BIT(12)
+#define MT6357_AUD_MICBIAS0_DCSW2P1_DISABLE	0
+#define MT6357_AUD_MICBIAS0_DCSW0N_EN_MASK	BIT(10)
+#define MT6357_AUD_MICBIAS0_DCSW0N_ENABLE	BIT(10)
+#define MT6357_AUD_MICBIAS0_DCSWN_DISABLE	0
+#define MT6357_AUD_MICBIAS0_DCSW0P2_EN_MASK	BIT(9)
+#define MT6357_AUD_MICBIAS0_DCSW0P2_ENABLE	BIT(9)
+#define MT6357_AUD_MICBIAS0_DCSW0P2_DISABLE	0
+#define MT6357_AUD_MICBIAS0_DCSW0P1_EN_MASK	BIT(8)
+#define MT6357_AUD_MICBIAS0_DCSW0P1_ENABLE	BIT(8)
+#define MT6357_AUD_MICBIAS0_DCSW0P1_DISABLE	0
+#define MT6357_AUD_MICBIAS0_VREF_MASK		GENMASK(6, 4)
+#define MT6357_AUD_MICBIAS0_VREF_SFT		4
+#define MT6357_AUD_MICBIAS0_PWD_SFT		0
+
+#define MT6357_AUD_MICBIAS0_DC_MASK		(MT6357_AUD_MICBIAS0_DCSW2N_EN_MASK | \
+						 MT6357_AUD_MICBIAS0_DCSW2P2_EN_MASK | \
+						 MT6357_AUD_MICBIAS0_DCSW2P1_EN_MASK | \
+						 MT6357_AUD_MICBIAS0_DCSW0N_EN_MASK | \
+						 MT6357_AUD_MICBIAS0_DCSW0P2_EN_MASK | \
+						 MT6357_AUD_MICBIAS0_DCSW0P1_EN_MASK)
+
+#define MT6357_AUD_MICBIAS0_DC_ENABLE_ALL	(MT6357_AUD_MICBIAS0_DCSW2N_ENABLE | \
+						 MT6357_AUD_MICBIAS0_DCSW2P2_ENABLE | \
+						 MT6357_AUD_MICBIAS0_DCSW2P1_ENABLE | \
+						 MT6357_AUD_MICBIAS0_DCSW0N_ENABLE | \
+						 MT6357_AUD_MICBIAS0_DCSW0P2_ENABLE | \
+						 MT6357_AUD_MICBIAS0_DCSW0P1_ENABLE)
+
+#define MT6357_AUD_MICBIAS0_DC_ENABLE_P1	(MT6357_AUD_MICBIAS0_DCSW2P1_ENABLE | \
+						 MT6357_AUD_MICBIAS0_DCSW0P1_ENABLE)
+
+#define MT6357_AUD_MICBIAS0_DC_DISABLE_ALL	0
+
+/* MT6357_AUDENC_ANA_CON9 */
+#define MT6357_AUD_MICBIAS1_DCSW1P_EN_MASK	BIT(8)
+#define MT6357_AUD_MICBIAS1_DCSW1P_ENABLE	BIT(8)
+#define MT6357_AUD_MICBIAS1_DCSW1P_DISABLE	0
+#define MT6357_AUD_MICBIAS1_VREF_MASK		GENMASK(6, 4)
+#define MT6357_AUD_MICBIAS1_VREF_SFT		4
+#define MT6357_AUD_MICBIAS1_PWD_SFT		0
+
+/* MT6357_AUDDEC_ANA_CON0 */
+#define MT6357_AUD_HPR_SC_VAUDP15_MASK			BIT(13)
+#define MT6357_AUD_HPR_SC_VAUDP15_DISABLE		BIT(13)
+#define MT6357_AUD_HPR_SC_VAUDP15_ENABLE		0
+#define MT6357_AUD_HPL_SC_VAUDP15_MASK			BIT(12)
+#define MT6357_AUD_HPL_SC_VAUDP15_DISABLE		BIT(12)
+#define MT6357_AUD_HPL_SC_VAUDP15_ENABLE		0
+#define MT6357_AUD_HPR_MUX_INPUT_VAUDP15_MASK_NOSFT	GENMASK(1, 0)
+#define MT6357_AUD_HPR_MUX_INPUT_VAUDP15_SFT		10
+#define MT6357_AUD_HPL_MUX_INPUT_VAUDP15_MASK_NOSFT	GENMASK(1, 0)
+#define MT6357_AUD_HPL_MUX_INPUT_VAUDP15_SFT		8
+#define MT6357_AUD_HPR_BIAS_VAUDP15_MASK		BIT(7)
+#define MT6357_AUD_HPR_BIAS_VAUDP15_ENABLE		BIT(7)
+#define MT6357_AUD_HPR_BIAS_VAUDP15_DISABLE		0
+#define MT6357_AUD_HPL_BIAS_VAUDP15_MASK		BIT(6)
+#define MT6357_AUD_HPL_BIAS_VAUDP15_ENABLE		BIT(6)
+#define MT6357_AUD_HPL_BIAS_VAUDP15_DISABLE		0
+#define MT6357_AUD_HPR_PWRUP_VAUDP15_MASK		BIT(5)
+#define MT6357_AUD_HPR_PWRUP_VAUDP15_ENABLE		BIT(5)
+#define MT6357_AUD_HPR_PWRUP_VAUDP15_DISABLE		0
+#define MT6357_AUD_HPL_PWRUP_VAUDP15_MASK		BIT(4)
+#define MT6357_AUD_HPL_PWRUP_VAUDP15_ENABLE		BIT(4)
+#define MT6357_AUD_HPL_PWRUP_VAUDP15_DISABLE		0
+#define MT6357_AUD_DACL_PWRUP_VA28_MASK			BIT(3)
+#define MT6357_AUD_DACL_PWRUP_VA28_ENABLE		BIT(3)
+#define MT6357_AUD_DACL_PWRUP_VA28_DISABLE		0
+#define MT6357_AUD_DACR_PWRUP_VA28_MASK			BIT(2)
+#define MT6357_AUD_DACR_PWRUP_VA28_ENABLE		BIT(2)
+#define MT6357_AUD_DACR_PWRUP_VA28_DISABLE		0
+#define MT6357_AUD_DACR_PWRUP_VAUDP15_MASK		BIT(1)
+#define MT6357_AUD_DACR_PWRUP_VAUDP15_ENABLE		BIT(1)
+#define MT6357_AUD_DACR_PWRUP_VAUDP15_DISABLE		0
+#define MT6357_AUD_DACL_PWRUP_VAUDP15_MASK		BIT(0)
+#define MT6357_AUD_DACL_PWRUP_VAUDP15_ENABLE		BIT(0)
+#define MT6357_AUD_DACL_PWRUP_VAUDP15_DISABLE		0
+
+/* MT6357_AUDDEC_ANA_CON1 */
+#define MT6357_HPROUT_STG_CTRL_VAUDP15_MASK		GENMASK(14, 12)
+#define MT6357_HPROUT_STG_CTRL_VAUDP15_SFT		12
+#define MT6357_HPLOUT_STG_CTRL_VAUDP15_MASK		GENMASK(10, 8)
+#define MT6357_HPLOUT_STG_CTRL_VAUDP15_SFT		8
+#define MT6357_HPLOUT_STG_CTRL_VAUDP15_MAX		7
+#define MT6357_HPR_SHORT2HPR_AUX_VAUDP15_MASK		BIT(7)
+#define MT6357_HPR_SHORT2HPR_AUX_VAUDP15_ENABLE		BIT(7)
+#define MT6357_HPR_SHORT2HPR_AUX_VAUDP15_DISABLE	0
+#define MT6357_HPL_SHORT2HPR_AUX_VAUDP15_MASK		BIT(6)
+#define MT6357_HPL_SHORT2HPR_AUX_VAUDP15_ENABLE		BIT(6)
+#define MT6357_HPL_SHORT2HPR_AUX_VAUDP15_DISABLE	0
+#define MT6357_HPR_AUX_FBRSW_VAUDP15_MASK		BIT(5)
+#define MT6357_HPR_AUX_FBRSW_VAUDP15_ENABLE		BIT(5)
+#define MT6357_HPR_AUX_FBRSW_VAUDP15_DISABLE		0
+#define MT6357_HPL_AUX_FBRSW_VAUDP15_MASK		BIT(4)
+#define MT6357_HPL_AUX_FBRSW_VAUDP15_ENABLE		BIT(4)
+#define MT6357_HPL_AUX_FBRSW_VAUDP15_DISABLE		0
+#define MT6357_HPROUT_AUX_PWRUP_VAUDP15_MASK		BIT(3)
+#define MT6357_HPROUT_AUX_PWRUP_VAUDP15_ENABLE		BIT(3)
+#define MT6357_HPROUT_AUX_PWRUP_VAUDP15_DISABLE	0
+#define MT6357_HPLOUT_AUX_PWRUP_VAUDP15_MASK		BIT(2)
+#define MT6357_HPLOUT_AUX_PWRUP_VAUDP15_ENABLE		BIT(2)
+#define MT6357_HPLOUT_AUX_PWRUP_VAUDP15_DISABLE	0
+#define MT6357_HPROUT_PWRUP_VAUDP15_MASK		BIT(1)
+#define MT6357_HPROUT_PWRUP_VAUDP15_ENABLE		BIT(1)
+#define MT6357_HPROUT_PWRUP_VAUDP15_DISABLE		0
+#define MT6357_HPLOUT_PWRUP_VAUDP15_MASK		BIT(0)
+#define MT6357_HPLOUT_PWRUP_VAUDP15_ENABLE		BIT(0)
+#define MT6357_HPLOUT_PWRUP_VAUDP15_DISABLE		0
+
+/* MT6357_AUDDEC_ANA_CON2 */
+#define MT6357_HPP_SHORT_2VCM_VAUDP15_MASK		BIT(10)
+#define MT6357_HPP_SHORT_2VCM_VAUDP15_ENABLE		BIT(10)
+#define MT6357_HPP_SHORT_2VCM_VAUDP15_DISABLE		0
+#define MT6357_AUD_REFN_DERES_VAUDP15_MASK		BIT(9)
+#define MT6357_AUD_REFN_DERES_VAUDP15_ENABLE		BIT(9)
+#define MT6357_AUD_REFN_DERES_VAUDP15_DISABLE		0
+#define MT6357_HPROUT_STB_ENH_VAUDP15_MASK		GENMASK(6, 4)
+#define MT6357_HPROUT_STB_ENH_VAUDP15_OPEN		0
+#define MT6357_HPROUT_STB_ENH_VAUDP15_NOPEN_P250	BIT(4)
+#define MT6357_HPROUT_STB_ENH_VAUDP15_N470_POPEN	BIT(5)
+#define MT6357_HPROUT_STB_ENH_VAUDP15_N470_P250		(BIT(4) | BIT(5))
+#define MT6357_HPROUT_STB_ENH_VAUDP15_NOPEN_P470	(BIT(4) | BIT(6))
+#define MT6357_HPROUT_STB_ENH_VAUDP15_N470_P470		(BIT(4) | BIT(5) | BIT(6))
+#define MT6357_HPLOUT_STB_ENH_VAUDP15_MASK		GENMASK(2, 0)
+#define MT6357_HPLOUT_STB_ENH_VAUDP15_OPEN		0
+#define MT6357_HPLOUT_STB_ENH_VAUDP15_NOPEN_P250	BIT(0)
+#define MT6357_HPLOUT_STB_ENH_VAUDP15_N470_POPEN	BIT(1)
+#define MT6357_HPLOUT_STB_ENH_VAUDP15_N470_P250		(BIT(0) | BIT(1))
+#define MT6357_HPLOUT_STB_ENH_VAUDP15_NOPEN_P470	(BIT(0) | BIT(2))
+#define MT6357_HPLOUT_STB_ENH_VAUDP15_N470_P470		(BIT(0) | BIT(1) | BIT(2))
+
+/* MT6357_AUDDEC_ANA_CON3 */
+#define MT6357_AUD_HSOUT_STB_ENH_VAUDP15_MASK		BIT(7)
+#define MT6357_AUD_HSOUT_STB_ENH_VAUDP15_ENABLE		BIT(7)
+#define MT6357_AUD_HSOUT_STB_ENH_VAUDP15_DISABLE	0
+#define MT6357_AUD_HS_SC_VAUDP15_MASK			BIT(4)
+#define MT6357_AUD_HS_SC_VAUDP15_DISABLE		BIT(4)
+#define MT6357_AUD_HS_SC_VAUDP15_ENABLE			0
+#define MT6357_AUD_HS_MUX_INPUT_VAUDP15_MASK_NOSFT	GENMASK(1, 0)
+#define MT6357_AUD_HS_MUX_INPUT_VAUDP15_SFT		2
+#define MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_MASK		BIT(1)
+#define MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_ENABLE		BIT(1)
+#define MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_DISABLE	0
+#define MT6357_AUD_HS_PWRUP_VAUDP15_MASK		BIT(0)
+#define MT6357_AUD_HS_PWRUP_VAUDP15_ENABLE		BIT(0)
+#define MT6357_AUD_HS_PWRUP_VAUDP15_DISABLE		0
+
+/* MT6357_AUDDEC_ANA_CON4 */
+#define MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_MASK		BIT(8)
+#define MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_ENABLE	BIT(8)
+#define MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_DISABLE	0
+#define MT6357_AUD_LOL_SC_VAUDP15_MASK			BIT(4)
+#define MT6357_AUD_LOL_SC_VAUDP15_DISABLE		BIT(4)
+#define MT6357_AUD_LOL_SC_VAUDP15_ENABLE		0
+#define MT6357_AUD_LOL_MUX_INPUT_VAUDP15_MASK_NOSFT	GENMASK(1, 0)
+#define MT6357_AUD_LOL_MUX_INPUT_VAUDP15_SFT		2
+#define MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_MASK		BIT(1)
+#define MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_ENABLE	BIT(1)
+#define MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_DISABLE	0
+#define MT6357_AUD_LOL_PWRUP_VAUDP15_MASK		BIT(0)
+#define MT6357_AUD_LOL_PWRUP_VAUDP15_ENABLE		BIT(0)
+#define MT6357_AUD_LOL_PWRUP_VAUDP15_DISABLE		0
+
+/* MT6357_AUDDEC_ANA_CON6 */
+#define MT6357_HP_AUX_LOOP_GAIN_MASK		GENMASK(15, 12)
+#define MT6357_HP_AUX_LOOP_GAIN_SFT		12
+#define MT6357_HP_AUX_LOOP_GAIN_MAX		0x0f
+#define MT6357_HPR_AUX_CMFB_LOOP_MASK		BIT(11)
+#define MT6357_HPR_AUX_CMFB_LOOP_ENABLE		BIT(11)
+#define MT6357_HPR_AUX_CMFB_LOOP_DISABLE	0
+#define MT6357_HPL_AUX_CMFB_LOOP_MASK		BIT(10)
+#define MT6357_HPL_AUX_CMFB_LOOP_ENABLE		BIT(10)
+#define MT6357_HPL_AUX_CMFB_LOOP_DISABLE	0
+#define MT6357_HPRL_MAIN_CMFB_LOOP_MASK		BIT(9)
+#define MT6357_HPRL_MAIN_CMFB_LOOP_ENABLE	BIT(9)
+#define MT6357_HPRL_MAIN_CMFB_LOOP_DISABLE	0
+#define MT6357_HP_CMFB_RST_MASK			BIT(7)
+#define MT6357_HP_CMFB_RST_NORMAL		BIT(7)
+#define MT6357_HP_CMFB_RST_RESET		0
+#define MT6357_DAC_LOW_NOISE_MODE_MASK		BIT(0)
+#define MT6357_DAC_LOW_NOISE_MODE_ENABLE	BIT(0)
+#define MT6357_DAC_LOW_NOISE_MODE_DISABLE	0
+
+/* MT6357_AUDDEC_ANA_CON7 */
+#define MT6357_HP_IVBUF_DEGAIN_SFT		2
+#define MT6357_HP_IVBUF_DEGAIN_MAX		1
+
+/* MT6357_AUDDEC_ANA_CON10 */
+#define MT6357_AUD_IBIAS_PWRDN_VAUDP15_MASK	BIT(8)
+#define MT6357_AUD_IBIAS_PWRDN_VAUDP15_DISABLE	BIT(8)
+#define MT6357_AUD_IBIAS_PWRDN_VAUDP15_ENABLE	0
+
+/* MT6357_AUDDEC_ANA_CON11 */
+#define MT6357_RSTB_ENCODER_VA28_MASK		BIT(5)
+#define MT6357_RSTB_ENCODER_VA28_ENABLE		BIT(5)
+#define MT6357_RSTB_ENCODER_VA28_DISABLE	0
+#define MT6357_AUDGLB_PWRDN_VA28_SFT		4
+#define MT6357_RSTB_DECODER_VA28_MASK		BIT(0)
+#define MT6357_RSTB_DECODER_VA28_ENABLE		BIT(0)
+#define MT6357_RSTB_DECODER_VA28_DISABLE	0
+
+/* MT6357_AUDDEC_ANA_CON12 */
+#define MT6357_VA28REFGEN_EN_VA28_MASK			BIT(13)
+#define MT6357_VA28REFGEN_EN_VA28_ENABLE		BIT(13)
+#define MT6357_VA28REFGEN_EN_VA28_DISABLE		0
+#define MT6357_VA33REFGEN_EN_VA18_MASK			BIT(12)
+#define MT6357_VA33REFGEN_EN_VA18_ENABLE		BIT(12)
+#define MT6357_VA33REFGEN_EN_VA18_DISABLE		0
+#define MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_MASK		BIT(10)
+#define MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_ENABLE	BIT(10)
+#define MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_DISABLE	0
+#define MT6357_LCLDO_ENC_EN_VA28_MASK			BIT(8)
+#define MT6357_LCLDO_ENC_EN_VA28_ENABLE			BIT(8)
+#define MT6357_LCLDO_ENC_EN_VA28_DISABLE		0
+#define MT6357_LCLDO_REMOTE_SENSE_VA18_MASK		BIT(6)
+#define MT6357_LCLDO_REMOTE_SENSE_VA18_ENABLE		BIT(6)
+#define MT6357_LCLDO_REMOTE_SENSE_VA18_DISABLE		0
+#define MT6357_LCLDO_EN_VA18_MASK			BIT(4)
+#define MT6357_LCLDO_EN_VA18_ENABLE			BIT(4)
+#define MT6357_LCLDO_EN_VA18_DISABLE			0
+#define MT6357_HCLDO_REMOTE_SENSE_VA18_MASK		BIT(2)
+#define MT6357_HCLDO_REMOTE_SENSE_VA18_ENABLE		BIT(2)
+#define MT6357_HCLDO_REMOTE_SENSE_VA18_DISABLE		0
+#define MT6357_HCLDO_EN_VA18_MASK			BIT(0)
+#define MT6357_HCLDO_EN_VA18_ENABLE			BIT(0)
+#define MT6357_HCLDO_EN_VA18_DISABLE			0
+
+/* MT6357_AUDDEC_ANA_CON13 */
+#define MT6357_NVREG_EN_VAUDP15_MASK		BIT(0)
+#define MT6357_NVREG_EN_VAUDP15_ENABLE		BIT(0)
+#define MT6357_NVREG_EN_VAUDP15_DISABLE		0
+
+/* MT6357_AUDDEC_ELR_0 */
+#define MT6357_AUD_HP_TRIM_EN_VAUDP15_MASK	BIT(12)
+#define MT6357_AUD_HP_TRIM_EN_VAUDP15_ENABLE	BIT(12)
+#define MT6357_AUD_HP_TRIM_EN_VAUDP15_DISABLE	0
+
+/* MT6357_ZCD_CON1 */
+#define MT6357_AUD_LOL_GAIN_MASK		GENMASK(4, 0)
+#define MT6357_AUD_LOL_GAIN_SFT			0
+#define MT6357_AUD_LOR_GAIN_MASK		GENMASK(11, 7)
+#define MT6357_AUD_LOR_GAIN_SFT			7
+#define MT6357_AUD_LO_GAIN_MAX			0x12
+
+/* MT6357_ZCD_CON2 */
+#define MT6357_AUD_HPL_GAIN_MASK		GENMASK(4, 0)
+#define MT6357_AUD_HPL_GAIN_SFT			0
+#define MT6357_AUD_HPR_GAIN_MASK		GENMASK(11, 7)
+#define MT6357_AUD_HPR_GAIN_SFT			7
+#define MT6357_AUD_HP_GAIN_MAX			0x12
+
+/* MT6357_ZCD_CON3 */
+#define MT6357_AUD_HS_GAIN_MASK			GENMASK(4, 0)
+#define MT6357_AUD_HS_GAIN_SFT			0
+#define MT6357_AUD_HS_GAIN_MAX			0x12
+
+/* Registers list */
+/* gpio direction */
+#define MT6357_GPIO_DIR0			0x0088
+/* mosi */
+#define MT6357_GPIO_MODE2			0x00B6
+#define MT6357_GPIO_MODE2_SET			0x00B8
+#define MT6357_GPIO_MODE2_CLR			0x00BA
+/* miso */
+#define MT6357_GPIO_MODE3			0x00BC
+#define MT6357_GPIO_MODE3_SET			0x00BE
+#define MT6357_GPIO_MODE3_CLR			0x00C0
+
+#define MT6357_DCXO_CW14			0x07AC
+
+#define MT6357_AUD_TOP_CKPDN_CON0		0x208C
+#define MT6357_AUDNCP_CLKDIV_CON0		0x20B4
+#define MT6357_AUDNCP_CLKDIV_CON1		0x20B6
+#define MT6357_AUDNCP_CLKDIV_CON2		0x20B8
+#define MT6357_AUDNCP_CLKDIV_CON3		0x20BA
+#define MT6357_AUDNCP_CLKDIV_CON4		0x20BC
+#define MT6357_AFE_UL_DL_CON0			0x2108
+#define MT6357_AFE_DL_SRC2_CON0_L		0x210A
+#define MT6357_AFE_UL_SRC_CON0_H		0x210C
+#define MT6357_AFE_UL_SRC_CON0_L		0x210E
+#define MT6357_AFE_TOP_CON0			0x2110
+#define MT6357_AUDIO_TOP_CON0			0x2112
+#define MT6357_AFUNC_AUD_CON0			0x2116
+#define MT6357_AFUNC_AUD_CON2			0x211A
+#define MT6357_AFE_ADDA_MTKAIF_CFG0		0x2134
+#define MT6357_AFE_SGEN_CFG0			0x2140
+#define MT6357_AFE_DCCLK_CFG0			0x2146
+#define MT6357_AFE_DCCLK_CFG1			0x2148
+#define MT6357_AFE_AUD_PAD_TOP			0x214C
+#define MT6357_AUDENC_ANA_CON0			0x2188
+#define MT6357_AUDENC_ANA_CON1			0x218A
+#define MT6357_AUDENC_ANA_CON6			0x2194
+#define MT6357_AUDENC_ANA_CON7			0x2196
+#define MT6357_AUDENC_ANA_CON8			0x2198
+#define MT6357_AUDENC_ANA_CON9			0x219A
+#define MT6357_AUDDEC_ANA_CON0			0x2208
+#define MT6357_AUDDEC_ANA_CON1			0x220A
+#define MT6357_AUDDEC_ANA_CON2			0x220C
+#define MT6357_AUDDEC_ANA_CON3			0x220E
+#define MT6357_AUDDEC_ANA_CON4			0x2210
+#define MT6357_AUDDEC_ANA_CON6			0x2214
+#define MT6357_AUDDEC_ANA_CON7			0x2216
+#define MT6357_AUDDEC_ANA_CON10			0x221C
+#define MT6357_AUDDEC_ANA_CON11			0x221E
+#define MT6357_AUDDEC_ANA_CON12			0x2220
+#define MT6357_AUDDEC_ANA_CON13			0x2222
+#define MT6357_AUDDEC_ELR_0			0x2226
+#define MT6357_ZCD_CON1				0x228A
+#define MT6357_ZCD_CON2				0x228C
+#define MT6357_ZCD_CON3				0x228E
+
+enum {
+	DL_GAIN_8DB = 0,
+	DL_GAIN_0DB = 8,
+	DL_GAIN_N_1DB = 9,
+	DL_GAIN_N_10DB = 18,
+	DL_GAIN_N_12DB = 20,
+	DL_GAIN_N_40DB = 0x1f,
+};
+
+enum {
+	UL_GAIN_0DB = 0,
+	UL_GAIN_6DB,
+	UL_GAIN_12DB,
+	UL_GAIN_18DB,
+	UL_GAIN_24DB,
+};
+
+#define MT6357_DL_GAIN_N_40DB_REG		(DL_GAIN_N_40DB << 7 | DL_GAIN_N_40DB)
+#define MT6357_DL_GAIN_REG_LEFT_MASK		0x001f
+#define MT6357_DL_GAIN_REG_LEFT_SHIFT		0
+#define MT6357_DL_GAIN_REG_RIGHT_MASK		0x0f80
+#define MT6357_DL_GAIN_REG_RIGHT_SHIFT		7
+#define MT6357_DL_GAIN_REG_MASK			0x0f9f
+
+#define MT6357_SND_SOC_ADV_MT_FMTS (\
+				SNDRV_PCM_FMTBIT_S16_LE |\
+				SNDRV_PCM_FMTBIT_S16_BE |\
+				SNDRV_PCM_FMTBIT_U16_LE |\
+				SNDRV_PCM_FMTBIT_U16_BE |\
+				SNDRV_PCM_FMTBIT_S24_LE |\
+				SNDRV_PCM_FMTBIT_S24_BE |\
+				SNDRV_PCM_FMTBIT_U24_LE |\
+				SNDRV_PCM_FMTBIT_U24_BE |\
+				SNDRV_PCM_FMTBIT_S32_LE |\
+				SNDRV_PCM_FMTBIT_S32_BE |\
+				SNDRV_PCM_FMTBIT_U32_LE |\
+				SNDRV_PCM_FMTBIT_U32_BE)
+
+#define MT6357_SOC_HIGH_USE_RATE (\
+				SNDRV_PCM_RATE_CONTINUOUS |\
+				SNDRV_PCM_RATE_8000_192000)
+
+#define MT6357_MICBIAS_ARRAY_SIZE	8
+
+/* codec private structure */
+struct mt6357_priv {
+	struct device *dev;
+	struct regmap *regmap;
+	bool pull_down_needed;
+	int hp_channel_number;
+};
+#endif

-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH v2] iommu/arm-smmu-v3: Free MSIs in case of ENOMEM
From: Robin Murphy @ 2024-04-09 11:17 UTC (permalink / raw)
  To: Mostafa Saleh, Aleksandr Aprelkov
  Cc: Will Deacon, Joerg Roedel, Jason Gunthorpe, Nicolin Chen,
	Michael Shavit, Lu Baolu, Marc Zyngier, linux-arm-kernel, iommu,
	linux-kernel
In-Reply-To: <ZhUbw6gAeBjpFz5C@google.com>

On 09/04/2024 11:43 am, Mostafa Saleh wrote:
> Hi Aleksandr,
> 
> On Wed, Apr 03, 2024 at 12:37:59PM +0700, Aleksandr Aprelkov wrote:
>> If devm_add_action() returns ENOMEM, then MSIs allocated but
>> not freed on teardown.
>>
>> Found by Linux Verification Center (linuxtesting.org) with SVACE.
>>
>> Fixes: 166bdbd23161 ("iommu/arm-smmu: Add support for MSI on SMMUv3")
>> Signed-off-by: Aleksandr Aprelkov <aaprelkov@usergate.com>
>> ---
>> v2: Use appropriate function for registration failure as
>> Jonathan Cameron <Jonathan.Cameron@Huawei.com> suggested.
>>
>>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 4 +++-
>>   1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> index 41f93c3ab160..8800af041e5f 100644
>> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
>> @@ -3402,7 +3402,9 @@ static void arm_smmu_setup_msis(struct arm_smmu_device *smmu)
>>   	smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);
>>   
>>   	/* Add callback to free MSIs on teardown */
>> -	devm_add_action(dev, arm_smmu_free_msis, dev);
>> +	ret = devm_add_action_or_reset(dev, arm_smmu_free_msis, dev);
>> +	if (ret)
>> +		dev_warn(dev, "failed to add free MSIs callback - falling back to wired irqs\n");
> 
> I am not sure that is the right fix, as allowing the driver to probe
> without MSIs, seems worse than leaking MSI memory.
> 
> IMHO, we can just add something like:
>      dev_err(smmu->dev, “Can’t allocate devm action, MSIs are never freed! !\n”) ;

Honestly I don't think this matters. If we ever really did fail to 
allocate 16 bytes, SLUB would already be screaming and spewing 
stacktraces, and the system is dead already.

> Also, we can’t unconditionally fallback to wired irqs if MSI exists,
> according to the user manual:
>      An implementation must support one of, or optionally both of,
>      wired interrupts and MSIs
>      ...
>      The discovery of support for wired interrupts is IMPLEMENTATION DEFINED.
> 
> We can add some logic, to check dt/acpi irqs and to choose to fallback
> or not based on that, but, if we get -ENOMEM, (especially early at
> probe) something really went wrong, so I am not sure it’s worth
> the complexity.

That logic already exists in arm_smmu_setup_unique_irqs() - the messages 
here are in the sense of "we're giving up on MSIs and falling back to 
trying whatever wired IRQs we may or may not have." The critical point 
is that we're not using MSIs for some potentially actionable reason, 
i.e. if the user does expect the system to be MSI-capable, then it could 
be an indication of perhaps a wrong or missing msi-parent, for which 
they may pursue a firmware fix. In other cases it's normal and expected 
not to use MSIs though (e.g. the system just doesn't have an ITS), so we 
don't want to be *too* noisy about it.

Thanks,
Robin.

> 
>>   }
>>   
>>   static void arm_smmu_setup_unique_irqs(struct arm_smmu_device *smmu)
>> -- 
>> 2.34.1
>>
> Thanks,
> Mostafa

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* RE: [PATCH v2 3/6] firmware: arm_scmi: add initial support for i.MX BBM protocol
From: Peng Fan @ 2024-04-09 11:19 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: Peng Fan (OSS), Cristian Marussi, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam,
	devicetree@vger.kernel.org, imx@lists.linux.dev,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <ZhUdQ6M0GkL0do_l@bogus>

> Subject: Re: [PATCH v2 3/6] firmware: arm_scmi: add initial support for i.MX
> BBM protocol
> 
> On Tue, Apr 09, 2024 at 09:13:33AM +0000, Peng Fan wrote:
> > Hi Sudeep,
> >
> > > Subject: Re: [PATCH v2 3/6] firmware: arm_scmi: add initial support
> > > for i.MX BBM protocol
> > >
> > > On Mon, Apr 08, 2024 at 07:04:43PM +0100, Cristian Marussi wrote:
> > > > On Fri, Apr 05, 2024 at 08:39:25PM +0800, Peng Fan (OSS) wrote:
> > > > > From: Peng Fan <peng.fan@nxp.com>
> > > > >
> > > > > The i.MX BBM protocol is for managing i.MX BBM module which
> > > > > provides RTC and BUTTON feature.
> > > > >
> > > >
> > > > I appreciate that you added versioning but I think a bit of
> > > > documentation about what the protocol and its comamnds purpose is
> > > > still lacking, as asked by Sudeep previously
> > > >
> > > >
> > > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2F
> > > >
> lore%2F&data=05%7C02%7Cpeng.fan%40nxp.com%7C6a989d0fb4c1454e94
> 3608
> > > >
> dc5882c563%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C6384
> 825658
> > > >
> 71932293%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoi
> V2luM
> > > >
> zIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=OCvYPh3l94
> 0aQ
> > > > 7mbAgrfEJMhYmix9%2FUUOA6kZyZJYWQ%3D&reserved=0
> > > > .kernel.org%2Flinux-arm-
> > > kernel%2FZeGtoJ7ztSe8Kg8R%40bogus%2F%23t&data=
> > > >
> > >
> 05%7C02%7Cpeng.fan%40nxp.com%7Ce92ff78b9126447afe9708dc587358d
> > > 4%7C686e
> > > >
> > >
> a1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C638482499632395762%7C
> > > Unknown%7C
> > > >
> > >
> TWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiL
> > > CJXVC
> > > >
> > >
> I6Mn0%3D%7C0%7C%7C%7C&sdata=7QP%2BkkjHA3Sa0CdcbbObGG4kgYYK
> > > XAGA2r%2F%2F
> > > > x0MogqU%3D&reserved=0
> > > >
> > >
> > > I have decided to ignore all these vendor protocol patches until
> > > they have some documentation to understand what these protocol are
> > > for, what are the commands, their input/output parameter details,
> > > any conditions are the caller and callee,..etc very similar to SCMI spec.
> >
> > Where do you expect the documentation to be put?
> >
> 
> To begin with, we need all these vendor protocols in a directory say
> vendors/nxp under drivers/firmware/arm_scmi. It can be a simple text file
> under that. We can see later if we need any more formal version elsewhere
> but that shouldn't be a blocker for these changes.
> 
> > similar as scmi_protocol.h, put in scmi_imx_protcol.h?
> > >
> > > To start with can you please expand what is BBM or MISC protocol is ?
> >
> > ok. Sorry for missing your previous comment in v1. Let me write here
> > briefly first.
> >
> 
> Thanks
> 
> > The Battery Backup (BB) Domain contains the Battery Backed Security
> > Module (BBSM) and the Battery Backed Non-Secure Module (BBNSM).
> > BBM protocol is to manage i.MX BBSM and BBNSM. This protocol supports
> > #define COMMAND_PROTOCOL_VERSION             0x0U
> > #define COMMAND_PROTOCOL_ATTRIBUTES          0x1U
> > #define COMMAND_PROTOCOL_MESSAGE_ATTRIBUTES  0x2U
> > #define COMMAND_BBM_GPR_SET                  0x3U
> > #define COMMAND_BBM_GPR_GET                  0x4U
> > #define COMMAND_BBM_RTC_ATTRIBUTES           0x5U
> > #define COMMAND_BBM_RTC_TIME_SET             0x6U
> > #define COMMAND_BBM_RTC_TIME_GET             0x7U
> > #define COMMAND_BBM_RTC_ALARM_SET            0x8U
> > #define COMMAND_BBM_BUTTON_GET               0x9U
> > #define COMMAND_BBM_RTC_NOTIFY               0xAU
> > #define COMMAND_BBM_BUTTON_NOTIFY            0xBU
> > #define COMMAND_NEGOTIATE_PROTOCOL_VERSION   0x10U
> >
> 
> Hopefully description of each of these commands cover what GPR above
> means really.

ok, will add more comment in the patch for the commands.

For GPR, there are some general purpose registers in BBM module that
could survive during power cycle, so users could set their own
value and use.

> 
> > For now in this patchset for linux, we only use RTC, and BUTTON for
> > system wakeup
> >
> > For MISC protocol, it is for various misc things, such as discover
> > build info, get rom passed data, get reset reason, get i.mx cfg name,
> > control set(for gpio expander under m33 control and etc). The command
> > as below:
> > #define COMMAND_PROTOCOL_VERSION             0x0U
> > #define COMMAND_PROTOCOL_ATTRIBUTES          0x1U
> > #define COMMAND_PROTOCOL_MESSAGE_ATTRIBUTES  0x2U
> > #define COMMAND_MISC_CONTROL_SET             0x3U
> > #define COMMAND_MISC_CONTROL_GET             0x4U
> > #define COMMAND_MISC_CONTROL_ACTION          0x5U
> > #define COMMAND_MISC_DISCOVER_BUILD_INFO     0x6U
> > #define COMMAND_MISC_ROM_PASSOVER_GET        0x7U
> > #define COMMAND_MISC_CONTROL_NOTIFY          0x8U
> > #define COMMAND_MISC_REASON_ATTRIBUTES       0x9U
> > #define COMMAND_MISC_RESET_REASON            0xAU
> > #define COMMAND_MISC_SI_INFO                 0xBU
> > #define COMMAND_MISC_CFG_INFO                0xCU
> > #define COMMAND_MISC_SYSLOG                  0xDU
> > #define COMMAND_NEGOTIATE_PROTOCOL_VERSION   0x10U
> >
> 
> And same here. Just as an example what BUILD_INFO ? There will be 10s if
> not 100s of different image in the system. What does this BUILD_INFO
> provide ?
> And why is this important over version or release info ?

BUILD_INFO here is to expose the commit hash and patch numbers.
This is firmware developer's decision to add this command, I could not
say it is less or more important.

> 
> These are simple pointers, expect more questions like this if the document is
> not self sufficient in explaining such details.

My plan is to add only the commands that this patch use, not add all the
commands. So in v3, there will be doc only for the commands included,
hope this is ok.

Thanks,
Peng.
> 
> --
> Regards,
> Sudeep

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 2/2] ARM: dts: imx6: exchange fallback and specific compatible string
From: Shengjiu Wang @ 2024-04-09 11:22 UTC (permalink / raw)
  To: Fabio Estevam
  Cc: Shengjiu Wang, lgirdwood, broonie, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, linux-sound, devicetree,
	linux-kernel, shawnguo, s.hauer, kernel, imx, linux-arm-kernel
In-Reply-To: <CAOMZO5BfJBkyw2q3wi4q3yjEmQowg7Zsw8yEFyANMYYez3ai+w@mail.gmail.com>

On Tue, Apr 9, 2024 at 6:06 PM Fabio Estevam <festevam@gmail.com> wrote:
>
> On Tue, Apr 9, 2024 at 7:02 AM Fabio Estevam <festevam@gmail.com> wrote:
> >
> > On Tue, Apr 9, 2024 at 6:08 AM Shengjiu Wang <shengjiu.wang@nxp.com> wrote:
> > >
> > > exchange fallback and specific compatible string for spdif sound card.
> >
> > Ok, but please explain the reason.
>
> I mean, why can't these two .dts files be changed to
>
> compatible =  "fsl,imx-audio-spdif";
>
> , like all the others?

The specific compatible string should be first place
as the dts rules I think. This patch is just to fix this problem.

For removing the specific compatible string,  I think we can
do that.  but this change may be out of the scope of this patch
series I think.

So I just change the order of compatible strings

best regards
wang shengjiu

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2 0/4] Speed up boot with faster linear map creation
From: David Hildenbrand @ 2024-04-09 11:22 UTC (permalink / raw)
  To: Itaru Kitayama, Ryan Roberts
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	Donald Dutile, Eric Chanudet, Linux ARM,
	linux-kernel@vger.kernel.org
In-Reply-To: <268FBD1C-B102-4726-A7F4-1125123BDA7A@linux.dev>

On 09.04.24 12:13, Itaru Kitayama wrote:
> 
> 
>> On Apr 9, 2024, at 19:04, Ryan Roberts <ryan.roberts@arm.com> wrote:
>>
>> On 09/04/2024 01:10, Itaru Kitayama wrote:
>>> Hi Ryan,
>>>
>>>> On Apr 8, 2024, at 16:30, Ryan Roberts <ryan.roberts@arm.com> wrote:
>>>>
>>>> On 06/04/2024 11:31, Itaru Kitayama wrote:
>>>>> Hi Ryan,
>>>>>
>>>>> On Sat, Apr 06, 2024 at 09:32:34AM +0100, Ryan Roberts wrote:
>>>>>> Hi Itaru,
>>>>>>
>>>>>> On 05/04/2024 08:39, Itaru Kitayama wrote:
>>>>>>> On Thu, Apr 04, 2024 at 03:33:04PM +0100, Ryan Roberts wrote:
>>>>>>>> Hi All,
>>>>>>>>
>>>>>>>> It turns out that creating the linear map can take a significant proportion of
>>>>>>>> the total boot time, especially when rodata=full. And most of the time is spent
>>>>>>>> waiting on superfluous tlb invalidation and memory barriers. This series reworks
>>>>>>>> the kernel pgtable generation code to significantly reduce the number of those
>>>>>>>> TLBIs, ISBs and DSBs. See each patch for details.
>>>>>>>>
>>>>>>>> The below shows the execution time of map_mem() across a couple of different
>>>>>>>> systems with different RAM configurations. We measure after applying each patch
>>>>>>>> and show the improvement relative to base (v6.9-rc2):
>>>>>>>>
>>>>>>>>                 | Apple M2 VM | Ampere Altra| Ampere Altra| Ampere Altra
>>>>>>>>                 | VM, 16G     | VM, 64G     | VM, 256G    | Metal, 512G
>>>>>>>> ---------------|-------------|-------------|-------------|-------------
>>>>>>>>                 |   ms    (%) |   ms    (%) |   ms    (%) |    ms    (%)
>>>>>>>> ---------------|-------------|-------------|-------------|-------------
>>>>>>>> base           |  153   (0%) | 2227   (0%) | 8798   (0%) | 17442   (0%)
>>>>>>>> no-cont-remap  |   77 (-49%) |  431 (-81%) | 1727 (-80%) |  3796 (-78%)
>>>>>>>> batch-barriers |   13 (-92%) |  162 (-93%) |  655 (-93%) |  1656 (-91%)
>>>>>>>> no-alloc-remap |   11 (-93%) |  109 (-95%) |  449 (-95%) |  1257 (-93%)
>>>>>>>> lazy-unmap     |    6 (-96%) |   61 (-97%) |  257 (-97%) |   838 (-95%)
>>>>>>>>
>>>>>>>> This series applies on top of v6.9-rc2. All mm selftests pass. I've compile and
>>>>>>>> boot tested various PAGE_SIZE and VA size configs.
>>>>>>>>
>>>>>>>> ---
>>>>>>>>
>>>>>>>> Changes since v1 [1]
>>>>>>>> ====================
>>>>>>>>
>>>>>>>>    - Added Tested-by tags (thanks to Eric and Itaru)
>>>>>>>>    - Renamed ___set_pte() -> __set_pte_nosync() (per Ard)
>>>>>>>>    - Reordered patches (biggest impact & least controversial first)
>>>>>>>>    - Reordered alloc/map/unmap functions in mmu.c to aid reader
>>>>>>>>    - pte_clear() -> __pte_clear() in clear_fixmap_nosync()
>>>>>>>>    - Reverted generic p4d_index() which caused x86 build error. Replaced with
>>>>>>>>      unconditional p4d_index() define under arm64.
>>>>>>>>
>>>>>>>>
>>>>>>>> [1] https://lore.kernel.org/linux-arm-kernel/20240326101448.3453626-1-ryan.roberts@arm.com/<https://lore.kernel.org/linux-arm-kernel/20240326101448.3453626-1-ryan.roberts@arm.com/>
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Ryan
>>>>>>>>
>>>>>>>>
>>>>>>>> Ryan Roberts (4):
>>>>>>>>    arm64: mm: Don't remap pgtables per-cont(pte|pmd) block
>>>>>>>>    arm64: mm: Batch dsb and isb when populating pgtables
>>>>>>>>    arm64: mm: Don't remap pgtables for allocate vs populate
>>>>>>>>    arm64: mm: Lazily clear pte table mappings from fixmap
>>>>>>>>
>>>>>>>> arch/arm64/include/asm/fixmap.h  |   5 +-
>>>>>>>> arch/arm64/include/asm/mmu.h     |   8 +
>>>>>>>> arch/arm64/include/asm/pgtable.h |  13 +-
>>>>>>>> arch/arm64/kernel/cpufeature.c   |  10 +-
>>>>>>>> arch/arm64/mm/fixmap.c           |  11 +
>>>>>>>> arch/arm64/mm/mmu.c              | 377 +++++++++++++++++++++++--------
>>>>>>>> 6 files changed, 319 insertions(+), 105 deletions(-)
>>>>>>>>
>>>>>>>> --
>>>>>>>> 2.25.1
>>>>>>>>
>>>>>>>
>>>>>>> I've build and boot tested the v2 on FVP, base is taken from your
>>>>>>> linux-rr repo. Running run_vmtests.sh on v2 left some gup longterm not oks, would you take a look at it? The mm ksefltests used is from your linux-rr repo too.
>>>>>>
>>>>>> Thanks for taking a look at this.
>>>>>>
>>>>>> I can't reproduce your issue unfortunately; steps as follows on Apple M2 VM:
>>>>>>
>>>>>> Config: arm64 defconfig + the following:
>>>>>>
>>>>>> # Squashfs for snaps, xfs for large file folios.
>>>>>> ./scripts/config --enable CONFIG_SQUASHFS_LZ4
>>>>>> ./scripts/config --enable CONFIG_SQUASHFS_LZO
>>>>>> ./scripts/config --enable CONFIG_SQUASHFS_XZ
>>>>>> ./scripts/config --enable CONFIG_SQUASHFS_ZSTD
>>>>>> ./scripts/config --enable CONFIG_XFS_FS
>>>>>>
>>>>>> # For general mm debug.
>>>>>> ./scripts/config --enable CONFIG_DEBUG_VM
>>>>>> ./scripts/config --enable CONFIG_DEBUG_VM_MAPLE_TREE
>>>>>> ./scripts/config --enable CONFIG_DEBUG_VM_RB
>>>>>> ./scripts/config --enable CONFIG_DEBUG_VM_PGFLAGS
>>>>>> ./scripts/config --enable CONFIG_DEBUG_VM_PGTABLE
>>>>>> ./scripts/config --enable CONFIG_PAGE_TABLE_CHECK
>>>>>>
>>>>>> # For mm selftests.
>>>>>> ./scripts/config --enable CONFIG_USERFAULTFD
>>>>>> ./scripts/config --enable CONFIG_TEST_VMALLOC
>>>>>> ./scripts/config --enable CONFIG_GUP_TEST
>>>>>>
>>>>>> Running on VM with 12G memory, split across 2 (emulated) NUMA nodes (needed by
>>>>>> some mm selftests), with kernel command line to reserve hugetlbs and other
>>>>>> features required by some mm selftests:
>>>>>>
>>>>>> "
>>>>>> transparent_hugepage=madvise earlycon root=/dev/vda2 secretmem.enable
>>>>>> hugepagesz=1G hugepages=0:2,1:2 hugepagesz=32M hugepages=0:2,1:2
>>>>>> default_hugepagesz=2M hugepages=0:64,1:64 hugepagesz=64K hugepages=0:2,1:2
>>>>>> "
>>>>>>
>>>>>> Ubuntu userspace running off XFS rootfs. Build and run mm selftests from same
>>>>>> git tree.
>>>>>>
>>>>>>
>>>>>> Although I don't think any of this config should make a difference to gup_longterm.
>>>>>>
>>>>>> Looks like your errors are all "ftruncate() failed". I've seen this problem on
>>>>>> our CI system. There it is due to running the tests from NFS file system. What
>>>>>> filesystem are you using? Perhaps you are sharing into the FVP using 9p? That
>>>>>> might also be problematic.
>>>>>
>>>>> That was it. This time I booted up the kernel including your series on
>>>>> QEMU on my M1 and executed the gup_longterm program without the ftruncate
>>>>> failures. When testing your kernel on FVP, I was executing the script from the FVP's host filesystem using 9p.
>>>>
>>>> I'm not sure exactly what the root cause is. Perhaps there isn't enough space on
>>>> the disk? It might be worth enhancing the error log to provide the errno in
>>>> tools/testing/selftests/mm/gup_longterm.c.
>>>>
>>>
>>> Attached is the strace’d gup_longterm executiong log on your
>>> pgtable-boot-speedup-v2 kernel.
>>
>> Sorry are you saying that it only fails with the pgtable-boot-speedup-v2 patch
>> set applied? I thought we previously concluded that it was independent of that?
>> I was under the impression that it was filesystem related and not something that
>> I was planning to investigate.
> 
> No, irrespective of the kernel, if using 9p on FVP the test program fails.
> It is indeed 9p filesystem related, as I switched to using NFS all the issues are gone.

Did it never work on 9p? If so, we might have to SKIP that test.

openat(AT_FDCWD, "gup_longterm.c_tmpfile_BLboOt", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
unlinkat(AT_FDCWD, "gup_longterm.c_tmpfile_BLboOt", 0) = 0
fstatfs(3, 0xffffe505a840)              = -1 EOPNOTSUPP (Operation not supported)
ftruncate(3, 4096)                      = -1 ENOENT (No such file or directory)


fstatfs() fails and makes get_fs_type() simply say "0" -- IOW "I don't know",
which should be fine here, as it will make fs_is_unknown() trigger for relevant
cases where the type matters.

ftruncate() failing with ENOENT seems to be the problem.

But that error is a bit weird.

The man page says "ENOENT The named file does not exist.", which should only apply to
truncate() but not ftruncate().

Sound weird, but maybe that's the way to say here "not supported" ?

-- 
Cheers,

David / dhildenb


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [syzbot] [mm?] BUG: unable to handle kernel paging request in copy_from_kernel_nofault (2)
From: syzbot @ 2024-04-09 11:23 UTC (permalink / raw)
  To: akpm, alexei.starovoitov, andrii.nakryiko, bpf, linux-arm-kernel,
	linux-kernel, linux-mm, linux, mark.rutland, puranjay12,
	syzkaller-bugs
In-Reply-To: <mb61p7ch6yetx.fsf@gmail.com>

Hello,

syzbot has tested the proposed patch but the reproducer is still triggering an issue:
INFO: task hung in _vm_unmap_aliases

INFO: task kworker/0:41:4201 blocked for more than 430 seconds.
      Not tainted 6.9.0-rc1-syzkaller #0
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:kworker/0:41    state:D stack:0     pid:4201  tgid:4201  ppid:2      flags:0x00000000
Workqueue: events bpf_prog_free_deferred
Call trace: 
[<8189ad40>] (__schedule) from [<8189b97c>] (__schedule_loop kernel/sched/core.c:6823 [inline])
[<8189ad40>] (__schedule) from [<8189b97c>] (schedule+0x2c/0xfc kernel/sched/core.c:6838)
 r10:82c16005 r9:00000000 r8:82714be8 r7:00000002 r6:dfd0dd94 r5:84dd1800
 r4:84dd1800
[<8189b950>] (schedule) from [<8189bf8c>] (schedule_preempt_disabled+0x18/0x24 kernel/sched/core.c:6895)
 r5:84dd1800 r4:82714be4
[<8189bf74>] (schedule_preempt_disabled) from [<8189e86c>] (__mutex_lock_common kernel/locking/mutex.c:684 [inline])
[<8189bf74>] (schedule_preempt_disabled) from [<8189e86c>] (__mutex_lock.constprop.0+0x2e8/0xae0 kernel/locking/mutex.c:752)
[<8189e584>] (__mutex_lock.constprop.0) from [<8189f138>] (__mutex_lock_slowpath+0x14/0x18 kernel/locking/mutex.c:1040)
 r10:82c16005 r9:dfd0de20 r8:00000000 r7:ffffffff r6:00000000 r5:84c7a680
 r4:00000000
[<8189f124>] (__mutex_lock_slowpath) from [<8189f178>] (mutex_lock+0x3c/0x40 kernel/locking/mutex.c:286)
[<8189f13c>] (mutex_lock) from [<8049c624>] (_vm_unmap_aliases+0x60/0x2e8 mm/vmalloc.c:2788)
[<8049c5c4>] (_vm_unmap_aliases) from [<804a04a8>] (vm_reset_perms mm/vmalloc.c:3235 [inline])
[<8049c5c4>] (_vm_unmap_aliases) from [<804a04a8>] (vfree+0x170/0x1e4 mm/vmalloc.c:3314)
 r10:82c16005 r9:00000001 r8:00000000 r7:ffffffff r6:00000000 r5:84c7a680
 r4:00000000
[<804a0338>] (vfree) from [<802edb08>] (module_memfree+0x30/0x50 kernel/module/main.c:1189)
 r9:84dd1800 r8:00000080 r7:00000000 r6:82c16000 r5:00001000 r4:7f055000
[<802edad8>] (module_memfree) from [<803916b0>] (bpf_jit_free_exec+0x10/0x14 kernel/bpf/core.c:1058)
 r5:00001000 r4:dfe91000
[<803916a0>] (bpf_jit_free_exec) from [<80391870>] (bpf_jit_binary_free kernel/bpf/core.c:1104 [inline])
[<803916a0>] (bpf_jit_free_exec) from [<80391870>] (bpf_jit_free+0x68/0xe4 kernel/bpf/core.c:1228)
[<80391808>] (bpf_jit_free) from [<80392958>] (bpf_prog_free_deferred+0x14c/0x164 kernel/bpf/core.c:2783)
 r5:845b0754 r4:845b0400
[<8039280c>] (bpf_prog_free_deferred) from [<8026678c>] (process_one_work+0x1b8/0x508 kernel/workqueue.c:3254)
 r7:dddd00c0 r6:82c16000 r5:845b0754 r4:84d7cb00
[<802665d4>] (process_one_work) from [<802674b0>] (process_scheduled_works kernel/workqueue.c:3335 [inline])
[<802665d4>] (process_one_work) from [<802674b0>] (worker_thread+0x1ec/0x418 kernel/workqueue.c:3416)
 r10:84dd1800 r9:84d7cb2c r8:61c88647 r7:dddd00e0 r6:82604d40 r5:dddd00c0
 r4:84d7cb00
[<802672c4>] (worker_thread) from [<802701c4>] (kthread+0x104/0x134 kernel/kthread.c:388)
 r10:00000000 r9:dfa55e90 r8:845d8e80 r7:84d7cb00 r6:802672c4 r5:84dd1800
 r4:84c66500
[<802700c0>] (kthread) from [<80200104>] (ret_from_fork+0x14/0x30 arch/arm/kernel/entry-common.S:134)
Exception stack(0xdfd0dfb0 to 0xdfd0dff8)
dfa0:                                     00000000 00000000 00000000 00000000
dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
dfe0: 00000000 00000000 00000000 00000000 00000013 00000000
 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:802700c0 r4:84c66500
INFO: task kworker/1:55:4229 blocked for more than 430 seconds.
      Not tainted 6.9.0-rc1-syzkaller #0
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:kworker/1:55    state:D stack:0     pid:4229  tgid:4229  ppid:2      flags:0x00000000
Workqueue: events bpf_prog_free_deferred
Call trace: 
[<8189ad40>] (__schedule) from [<8189b97c>] (__schedule_loop kernel/sched/core.c:6823 [inline])
[<8189ad40>] (__schedule) from [<8189b97c>] (schedule+0x2c/0xfc kernel/sched/core.c:6838)
 r10:82c16205 r9:00000000 r8:82714be8 r7:00000002 r6:dfe39d94 r5:84e83c00
 r4:84e83c00
[<8189b950>] (schedule) from [<8189bf8c>] (schedule_preempt_disabled+0x18/0x24 kernel/sched/core.c:6895)
 r5:84e83c00 r4:82714be4
[<8189bf74>] (schedule_preempt_disabled) from [<8189e86c>] (__mutex_lock_common kernel/locking/mutex.c:684 [inline])
[<8189bf74>] (schedule_preempt_disabled) from [<8189e86c>] (__mutex_lock.constprop.0+0x2e8/0xae0 kernel/locking/mutex.c:752)
[<8189e584>] (__mutex_lock.constprop.0) from [<8189f138>] (__mutex_lock_slowpath+0x14/0x18 kernel/locking/mutex.c:1040)
 r10:82c16205 r9:dfe39e20 r8:00000000 r7:ffffffff r6:00000000 r5:84c7a240
 r4:00000000
[<8189f124>] (__mutex_lock_slowpath) from [<8189f178>] (mutex_lock+0x3c/0x40 kernel/locking/mutex.c:286)
[<8189f13c>] (mutex_lock) from [<8049c624>] (_vm_unmap_aliases+0x60/0x2e8 mm/vmalloc.c:2788)
[<8049c5c4>] (_vm_unmap_aliases) from [<804a04a8>] (vm_reset_perms mm/vmalloc.c:3235 [inline])
[<8049c5c4>] (_vm_unmap_aliases) from [<804a04a8>] (vfree+0x170/0x1e4 mm/vmalloc.c:3314)
 r10:82c16205 r9:00000001 r8:00000000 r7:ffffffff r6:00000000 r5:84c7a240
 r4:00000000
[<804a0338>] (vfree) from [<802edb08>] (module_memfree+0x30/0x50 kernel/module/main.c:1189)
 r9:84e83c00 r8:00000180 r7:00000000 r6:82c16200 r5:00001000 r4:7f053000
[<802edad8>] (module_memfree) from [<803916b0>] (bpf_jit_free_exec+0x10/0x14 kernel/bpf/core.c:1058)
 r5:00001000 r4:dfe73000
[<803916a0>] (bpf_jit_free_exec) from [<80391870>] (bpf_jit_binary_free kernel/bpf/core.c:1104 [inline])
[<803916a0>] (bpf_jit_free_exec) from [<80391870>] (bpf_jit_free+0x68/0xe4 kernel/bpf/core.c:1228)
[<80391808>] (bpf_jit_free) from [<80392958>] (bpf_prog_free_deferred+0x14c/0x164 kernel/bpf/core.c:2783)
 r5:845b2b54 r4:845b2800
[<8039280c>] (bpf_prog_free_deferred) from [<8026678c>] (process_one_work+0x1b8/0x508 kernel/workqueue.c:3254)
 r7:ddde40c0 r6:82c16200 r5:845b2b54 r4:845d9f80
[<802665d4>] (process_one_work) from [<802674b0>] (process_scheduled_works kernel/workqueue.c:3335 [inline])
[<802665d4>] (process_one_work) from [<802674b0>] (worker_thread+0x1ec/0x418 kernel/workqueue.c:3416)
 r10:84e83c00 r9:845d9fac r8:61c88647 r7:ddde40e0 r6:82604d40 r5:ddde40c0
 r4:845d9f80
[<802672c4>] (worker_thread) from [<802701c4>] (kthread+0x104/0x134 kernel/kthread.c:388)
 r10:00000000 r9:dfde5e90 r8:84640600 r7:845d9f80 r6:802672c4 r5:84e83c00
 r4:84c66300
[<802700c0>] (kthread) from [<80200104>] (ret_from_fork+0x14/0x30 arch/arm/kernel/entry-common.S:134)
Exception stack(0xdfe39fb0 to 0xdfe39ff8)
9fa0:                                     00000000 00000000 00000000 00000000
9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:802700c0 r4:84c66300
NMI backtrace for cpu 0
CPU: 0 PID: 31 Comm: khungtaskd Not tainted 6.9.0-rc1-syzkaller #0
Hardware name: ARM-Versatile Express
Call trace: 
[<818795bc>] (dump_backtrace) from [<818796b8>] (show_stack+0x18/0x1c arch/arm/kernel/traps.c:256)
 r7:00000000 r6:00000113 r5:60000193 r4:81fc4768
[<818796a0>] (show_stack) from [<81896e70>] (__dump_stack lib/dump_stack.c:88 [inline])
[<818796a0>] (show_stack) from [<81896e70>] (dump_stack_lvl+0x70/0x7c lib/dump_stack.c:114)
[<81896e00>] (dump_stack_lvl) from [<81896e94>] (dump_stack+0x18/0x1c lib/dump_stack.c:123)
 r5:00000000 r4:00000001
[<81896e7c>] (dump_stack) from [<81866994>] (nmi_cpu_backtrace+0x160/0x17c lib/nmi_backtrace.c:113)
[<81866834>] (nmi_cpu_backtrace) from [<81866ae0>] (nmi_trigger_cpumask_backtrace+0x130/0x1d8 lib/nmi_backtrace.c:62)
 r7:00000000 r6:8260c590 r5:8261a88c r4:ffffffff
[<818669b0>] (nmi_trigger_cpumask_backtrace) from [<802105b4>] (arch_trigger_cpumask_backtrace+0x18/0x1c arch/arm/kernel/smp.c:851)
 r9:8260c6f4 r8:00007b4d r7:8289dfe0 r6:00007d59 r5:8500ee04 r4:850d4b24
[<8021059c>] (arch_trigger_cpumask_backtrace) from [<8034ec48>] (trigger_all_cpu_backtrace include/linux/nmi.h:160 [inline])
[<8021059c>] (arch_trigger_cpumask_backtrace) from [<8034ec48>] (check_hung_uninterruptible_tasks kernel/hung_task.c:223 [inline])
[<8021059c>] (arch_trigger_cpumask_backtrace) from [<8034ec48>] (watchdog+0x480/0x594 kernel/hung_task.c:380)
[<8034e7c8>] (watchdog) from [<802701c4>] (kthread+0x104/0x134 kernel/kthread.c:388)
 r10:00000000 r9:df819e58 r8:82e98440 r7:00000000 r6:8034e7c8 r5:82ee8c00
 r4:82f42100
[<802700c0>] (kthread) from [<80200104>] (ret_from_fork+0x14/0x30 arch/arm/kernel/entry-common.S:134)
Exception stack(0xdf8ddfb0 to 0xdf8ddff8)
dfa0:                                     00000000 00000000 00000000 00000000
dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
dfe0: 00000000 00000000 00000000 00000000 00000013 00000000
 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:802700c0 r4:82f42100
Sending NMI from CPU 0 to CPUs 1:
NMI backtrace for cpu 1
CPU: 1 PID: 5655 Comm: kworker/1:259 Not tainted 6.9.0-rc1-syzkaller #0
Hardware name: ARM-Versatile Express
Workqueue: wg-crypt-wg0 wg_packet_encrypt_worker
PC is at poly1305_final_arch+0x0/0x80 arch/arm/crypto/poly1305-glue.c:189
LR is at poly1305_final include/crypto/poly1305.h:94 [inline]
LR is at chacha20poly1305_crypt_sg_inplace+0x43c/0x4b4 lib/crypto/chacha20poly1305.c:320
pc : [<80232f80>]    lr : [<807fa0e4>]    psr: 60000113
sp : eafa1990  ip : eafa1990  fp : eafa1bb4
r10: 00000000  r9 : 00000000  r8 : 00000000
r7 : eafa19e0  r6 : 00000000  r5 : 00000000  r4 : eafa19f0
r3 : 00000000  r2 : 00000000  r1 : eafa19f0  r0 : eafa1a68
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: 30c5387d  Table: 8461dec0  DAC: 00000000
Call trace: 
[<807f9ca8>] (chacha20poly1305_crypt_sg_inplace) from [<807fa188>] (chacha20poly1305_encrypt_sg_inplace+0x2c/0x34 lib/crypto/chacha20poly1305.c:338)
 r10:00000000 r9:00000000 r8:00000074 r7:00000001 r6:84dca018 r5:00000000
 r4:00000074
[<807fa15c>] (chacha20poly1305_encrypt_sg_inplace) from [<80bfb0f8>] (encrypt_packet+0x194/0x230 drivers/net/wireguard/send.c:216)
 r5:00000000 r4:00000074
[<80bfaf64>] (encrypt_packet) from [<80bfb8d0>] (wg_packet_encrypt_worker+0xbc/0x270 drivers/net/wireguard/send.c:297)
 r10:846c86e8 r9:82f2a540 r8:00000000 r7:846c86a0 r6:8260eea8 r5:00000000
 r4:82f2a540
[<80bfb814>] (wg_packet_encrypt_worker) from [<8026678c>] (process_one_work+0x1b8/0x508 kernel/workqueue.c:3254)
 r10:84032e05 r9:85156000 r8:00000180 r7:ddde40c0 r6:84032e00 r5:ff7ffcf4
 r4:8505ff00
[<802665d4>] (process_one_work) from [<802674b0>] (process_scheduled_works kernel/workqueue.c:3335 [inline])
[<802665d4>] (process_one_work) from [<802674b0>] (worker_thread+0x1ec/0x418 kernel/workqueue.c:3416)
 r10:85156000 r9:8505ff2c r8:61c88647 r7:ddde40e0 r6:82604d40 r5:ddde40c0
 r4:8505ff00
[<802672c4>] (worker_thread) from [<802701c4>] (kthread+0x104/0x134 kernel/kthread.c:388)
 r10:00000000 r9:eaeb1e90 r8:84ed1a40 r7:8505ff00 r6:802672c4 r5:85156000
 r4:847e7040
[<802700c0>] (kthread) from [<80200104>] (ret_from_fork+0x14/0x30 arch/arm/kernel/entry-common.S:134)
Exception stack(0xeafa1fb0 to 0xeafa1ff8)
1fa0:                                     00000000 00000000 00000000 00000000
1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
1fe0: 00000000 00000000 00000000 00000000 00000013 00000000
 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:802700c0 r4:847e7040


Tested on:

commit:         7deb8d88 arm32, bpf: Fix sign-extension mov instruction
git tree:       https://github.com/puranjaymohan/linux.git arm32_movsx_fix
console output: https://syzkaller.appspot.com/x/log.txt?x=175200cb180000
kernel config:  https://syzkaller.appspot.com/x/.config?x=43f1e0cbdb852271
dashboard link: https://syzkaller.appspot.com/bug?extid=186522670e6722692d86
compiler:       arm-linux-gnueabi-gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40
userspace arch: arm

Note: no patches were applied.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2 0/4] Speed up boot with faster linear map creation
From: David Hildenbrand @ 2024-04-09 11:29 UTC (permalink / raw)
  To: Itaru Kitayama, Ryan Roberts
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	Donald Dutile, Eric Chanudet, Linux ARM,
	linux-kernel@vger.kernel.org
In-Reply-To: <5e4dc2fe-2945-4fc5-a533-c8b2d04668a0@redhat.com>

On 09.04.24 13:22, David Hildenbrand wrote:
> On 09.04.24 12:13, Itaru Kitayama wrote:
>>
>>
>>> On Apr 9, 2024, at 19:04, Ryan Roberts <ryan.roberts@arm.com> wrote:
>>>
>>> On 09/04/2024 01:10, Itaru Kitayama wrote:
>>>> Hi Ryan,
>>>>
>>>>> On Apr 8, 2024, at 16:30, Ryan Roberts <ryan.roberts@arm.com> wrote:
>>>>>
>>>>> On 06/04/2024 11:31, Itaru Kitayama wrote:
>>>>>> Hi Ryan,
>>>>>>
>>>>>> On Sat, Apr 06, 2024 at 09:32:34AM +0100, Ryan Roberts wrote:
>>>>>>> Hi Itaru,
>>>>>>>
>>>>>>> On 05/04/2024 08:39, Itaru Kitayama wrote:
>>>>>>>> On Thu, Apr 04, 2024 at 03:33:04PM +0100, Ryan Roberts wrote:
>>>>>>>>> Hi All,
>>>>>>>>>
>>>>>>>>> It turns out that creating the linear map can take a significant proportion of
>>>>>>>>> the total boot time, especially when rodata=full. And most of the time is spent
>>>>>>>>> waiting on superfluous tlb invalidation and memory barriers. This series reworks
>>>>>>>>> the kernel pgtable generation code to significantly reduce the number of those
>>>>>>>>> TLBIs, ISBs and DSBs. See each patch for details.
>>>>>>>>>
>>>>>>>>> The below shows the execution time of map_mem() across a couple of different
>>>>>>>>> systems with different RAM configurations. We measure after applying each patch
>>>>>>>>> and show the improvement relative to base (v6.9-rc2):
>>>>>>>>>
>>>>>>>>>                  | Apple M2 VM | Ampere Altra| Ampere Altra| Ampere Altra
>>>>>>>>>                  | VM, 16G     | VM, 64G     | VM, 256G    | Metal, 512G
>>>>>>>>> ---------------|-------------|-------------|-------------|-------------
>>>>>>>>>                  |   ms    (%) |   ms    (%) |   ms    (%) |    ms    (%)
>>>>>>>>> ---------------|-------------|-------------|-------------|-------------
>>>>>>>>> base           |  153   (0%) | 2227   (0%) | 8798   (0%) | 17442   (0%)
>>>>>>>>> no-cont-remap  |   77 (-49%) |  431 (-81%) | 1727 (-80%) |  3796 (-78%)
>>>>>>>>> batch-barriers |   13 (-92%) |  162 (-93%) |  655 (-93%) |  1656 (-91%)
>>>>>>>>> no-alloc-remap |   11 (-93%) |  109 (-95%) |  449 (-95%) |  1257 (-93%)
>>>>>>>>> lazy-unmap     |    6 (-96%) |   61 (-97%) |  257 (-97%) |   838 (-95%)
>>>>>>>>>
>>>>>>>>> This series applies on top of v6.9-rc2. All mm selftests pass. I've compile and
>>>>>>>>> boot tested various PAGE_SIZE and VA size configs.
>>>>>>>>>
>>>>>>>>> ---
>>>>>>>>>
>>>>>>>>> Changes since v1 [1]
>>>>>>>>> ====================
>>>>>>>>>
>>>>>>>>>     - Added Tested-by tags (thanks to Eric and Itaru)
>>>>>>>>>     - Renamed ___set_pte() -> __set_pte_nosync() (per Ard)
>>>>>>>>>     - Reordered patches (biggest impact & least controversial first)
>>>>>>>>>     - Reordered alloc/map/unmap functions in mmu.c to aid reader
>>>>>>>>>     - pte_clear() -> __pte_clear() in clear_fixmap_nosync()
>>>>>>>>>     - Reverted generic p4d_index() which caused x86 build error. Replaced with
>>>>>>>>>       unconditional p4d_index() define under arm64.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> [1] https://lore.kernel.org/linux-arm-kernel/20240326101448.3453626-1-ryan.roberts@arm.com/<https://lore.kernel.org/linux-arm-kernel/20240326101448.3453626-1-ryan.roberts@arm.com/>
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Ryan
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Ryan Roberts (4):
>>>>>>>>>     arm64: mm: Don't remap pgtables per-cont(pte|pmd) block
>>>>>>>>>     arm64: mm: Batch dsb and isb when populating pgtables
>>>>>>>>>     arm64: mm: Don't remap pgtables for allocate vs populate
>>>>>>>>>     arm64: mm: Lazily clear pte table mappings from fixmap
>>>>>>>>>
>>>>>>>>> arch/arm64/include/asm/fixmap.h  |   5 +-
>>>>>>>>> arch/arm64/include/asm/mmu.h     |   8 +
>>>>>>>>> arch/arm64/include/asm/pgtable.h |  13 +-
>>>>>>>>> arch/arm64/kernel/cpufeature.c   |  10 +-
>>>>>>>>> arch/arm64/mm/fixmap.c           |  11 +
>>>>>>>>> arch/arm64/mm/mmu.c              | 377 +++++++++++++++++++++++--------
>>>>>>>>> 6 files changed, 319 insertions(+), 105 deletions(-)
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> 2.25.1
>>>>>>>>>
>>>>>>>>
>>>>>>>> I've build and boot tested the v2 on FVP, base is taken from your
>>>>>>>> linux-rr repo. Running run_vmtests.sh on v2 left some gup longterm not oks, would you take a look at it? The mm ksefltests used is from your linux-rr repo too.
>>>>>>>
>>>>>>> Thanks for taking a look at this.
>>>>>>>
>>>>>>> I can't reproduce your issue unfortunately; steps as follows on Apple M2 VM:
>>>>>>>
>>>>>>> Config: arm64 defconfig + the following:
>>>>>>>
>>>>>>> # Squashfs for snaps, xfs for large file folios.
>>>>>>> ./scripts/config --enable CONFIG_SQUASHFS_LZ4
>>>>>>> ./scripts/config --enable CONFIG_SQUASHFS_LZO
>>>>>>> ./scripts/config --enable CONFIG_SQUASHFS_XZ
>>>>>>> ./scripts/config --enable CONFIG_SQUASHFS_ZSTD
>>>>>>> ./scripts/config --enable CONFIG_XFS_FS
>>>>>>>
>>>>>>> # For general mm debug.
>>>>>>> ./scripts/config --enable CONFIG_DEBUG_VM
>>>>>>> ./scripts/config --enable CONFIG_DEBUG_VM_MAPLE_TREE
>>>>>>> ./scripts/config --enable CONFIG_DEBUG_VM_RB
>>>>>>> ./scripts/config --enable CONFIG_DEBUG_VM_PGFLAGS
>>>>>>> ./scripts/config --enable CONFIG_DEBUG_VM_PGTABLE
>>>>>>> ./scripts/config --enable CONFIG_PAGE_TABLE_CHECK
>>>>>>>
>>>>>>> # For mm selftests.
>>>>>>> ./scripts/config --enable CONFIG_USERFAULTFD
>>>>>>> ./scripts/config --enable CONFIG_TEST_VMALLOC
>>>>>>> ./scripts/config --enable CONFIG_GUP_TEST
>>>>>>>
>>>>>>> Running on VM with 12G memory, split across 2 (emulated) NUMA nodes (needed by
>>>>>>> some mm selftests), with kernel command line to reserve hugetlbs and other
>>>>>>> features required by some mm selftests:
>>>>>>>
>>>>>>> "
>>>>>>> transparent_hugepage=madvise earlycon root=/dev/vda2 secretmem.enable
>>>>>>> hugepagesz=1G hugepages=0:2,1:2 hugepagesz=32M hugepages=0:2,1:2
>>>>>>> default_hugepagesz=2M hugepages=0:64,1:64 hugepagesz=64K hugepages=0:2,1:2
>>>>>>> "
>>>>>>>
>>>>>>> Ubuntu userspace running off XFS rootfs. Build and run mm selftests from same
>>>>>>> git tree.
>>>>>>>
>>>>>>>
>>>>>>> Although I don't think any of this config should make a difference to gup_longterm.
>>>>>>>
>>>>>>> Looks like your errors are all "ftruncate() failed". I've seen this problem on
>>>>>>> our CI system. There it is due to running the tests from NFS file system. What
>>>>>>> filesystem are you using? Perhaps you are sharing into the FVP using 9p? That
>>>>>>> might also be problematic.
>>>>>>
>>>>>> That was it. This time I booted up the kernel including your series on
>>>>>> QEMU on my M1 and executed the gup_longterm program without the ftruncate
>>>>>> failures. When testing your kernel on FVP, I was executing the script from the FVP's host filesystem using 9p.
>>>>>
>>>>> I'm not sure exactly what the root cause is. Perhaps there isn't enough space on
>>>>> the disk? It might be worth enhancing the error log to provide the errno in
>>>>> tools/testing/selftests/mm/gup_longterm.c.
>>>>>
>>>>
>>>> Attached is the strace’d gup_longterm executiong log on your
>>>> pgtable-boot-speedup-v2 kernel.
>>>
>>> Sorry are you saying that it only fails with the pgtable-boot-speedup-v2 patch
>>> set applied? I thought we previously concluded that it was independent of that?
>>> I was under the impression that it was filesystem related and not something that
>>> I was planning to investigate.
>>
>> No, irrespective of the kernel, if using 9p on FVP the test program fails.
>> It is indeed 9p filesystem related, as I switched to using NFS all the issues are gone.
> 
> Did it never work on 9p? If so, we might have to SKIP that test.
> 
> openat(AT_FDCWD, "gup_longterm.c_tmpfile_BLboOt", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
> unlinkat(AT_FDCWD, "gup_longterm.c_tmpfile_BLboOt", 0) = 0
> fstatfs(3, 0xffffe505a840)              = -1 EOPNOTSUPP (Operation not supported)
> ftruncate(3, 4096)                      = -1 ENOENT (No such file or directory)

Note: I'm wondering if the unlinkat here is the problem that makes 
ftruncate() with 9p result in weird errors (e.g., the hypervisor 
unlinked the file and cannot reopen it for the fstatfs/ftruncate. ... 
which gives us weird errors here).

Then, we should lookup the fs type in run_with_local_tmpfile() before 
the unlink() and simply skip the test if it is 9p.

-- 
Cheers,

David / dhildenb


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH] clk: Check ops are available in clk_gate_restore_context
From: Stephen Boyd @ 2024-04-09 11:31 UTC (permalink / raw)
  To: Cristian Marussi, linux-arm-kernel, linux-kernel
  Cc: sudeep.holla, peng.fan, Cristian Marussi, Michael Turquette,
	linux-clk
In-Reply-To: <20240120100711.2832897-1-cristian.marussi@arm.com>

Quoting Cristian Marussi (2024-01-20 02:07:11)
> Add a check in clk_gate_restore_context() to assure that the clock enable
> and disable ops are available before calling them.
> 
> CC: Michael Turquette <mturquette@baylibre.com>
> CC: Stephen Boyd <sboyd@kernel.org>
> CC: linux-clk@vger.kernel.org
> Fixes: 9be766274db4 ("clk: Clean up suspend/resume coding style")
> Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
> ---
> Spotted this by code inspection.
> I may be missing something, though, given my limited familiarity with CLK.

It assumes this is for a gate clk, which has enable/disable clk ops.
Also, only TI uses this code and I suggest you don't use it.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2] iommu/arm-smmu-v3: Free MSIs in case of ENOMEM
From: Mostafa Saleh @ 2024-04-09 11:31 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Aleksandr Aprelkov, Will Deacon, Joerg Roedel, Jason Gunthorpe,
	Nicolin Chen, Michael Shavit, Lu Baolu, Marc Zyngier,
	linux-arm-kernel, iommu, linux-kernel
In-Reply-To: <8a7f0218-39e3-4e4b-ba99-7fe4389fb703@arm.com>

Hi Robin,

On Tue, Apr 09, 2024 at 12:17:54PM +0100, Robin Murphy wrote:
> On 09/04/2024 11:43 am, Mostafa Saleh wrote:
> > Hi Aleksandr,
> > 
> > On Wed, Apr 03, 2024 at 12:37:59PM +0700, Aleksandr Aprelkov wrote:
> > > If devm_add_action() returns ENOMEM, then MSIs allocated but
> > > not freed on teardown.
> > > 
> > > Found by Linux Verification Center (linuxtesting.org) with SVACE.
> > > 
> > > Fixes: 166bdbd23161 ("iommu/arm-smmu: Add support for MSI on SMMUv3")
> > > Signed-off-by: Aleksandr Aprelkov <aaprelkov@usergate.com>
> > > ---
> > > v2: Use appropriate function for registration failure as
> > > Jonathan Cameron <Jonathan.Cameron@Huawei.com> suggested.
> > > 
> > >   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 4 +++-
> > >   1 file changed, 3 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > > index 41f93c3ab160..8800af041e5f 100644
> > > --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > > +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> > > @@ -3402,7 +3402,9 @@ static void arm_smmu_setup_msis(struct arm_smmu_device *smmu)
> > >   	smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);
> > >   	/* Add callback to free MSIs on teardown */
> > > -	devm_add_action(dev, arm_smmu_free_msis, dev);
> > > +	ret = devm_add_action_or_reset(dev, arm_smmu_free_msis, dev);
> > > +	if (ret)
> > > +		dev_warn(dev, "failed to add free MSIs callback - falling back to wired irqs\n");
> > 
> > I am not sure that is the right fix, as allowing the driver to probe
> > without MSIs, seems worse than leaking MSI memory.
> > 
> > IMHO, we can just add something like:
> >      dev_err(smmu->dev, “Can’t allocate devm action, MSIs are never freed! !\n”) ;
> 
> Honestly I don't think this matters. If we ever really did fail to allocate
> 16 bytes, SLUB would already be screaming and spewing stacktraces, and the
> system is dead already.
> 
> > Also, we can’t unconditionally fallback to wired irqs if MSI exists,
> > according to the user manual:
> >      An implementation must support one of, or optionally both of,
> >      wired interrupts and MSIs
> >      ...
> >      The discovery of support for wired interrupts is IMPLEMENTATION DEFINED.
> > 
> > We can add some logic, to check dt/acpi irqs and to choose to fallback
> > or not based on that, but, if we get -ENOMEM, (especially early at
> > probe) something really went wrong, so I am not sure it’s worth
> > the complexity.
> 
> That logic already exists in arm_smmu_setup_unique_irqs() - the messages
> here are in the sense of "we're giving up on MSIs and falling back to trying
> whatever wired IRQs we may or may not have." The critical point is that
> we're not using MSIs for some potentially actionable reason, i.e. if the
> user does expect the system to be MSI-capable, then it could be an
> indication of perhaps a wrong or missing msi-parent, for which they may
> pursue a firmware fix. In other cases it's normal and expected not to use
> MSIs though (e.g. the system just doesn't have an ITS), so we don't want to
> be *too* noisy about it.

The case I am worried about in this patch, is for systems with
MSIs only.
With this patch, that means, we fallback to wired irqs which don't
exist, so the driver will probe with no interrupts at all, which in my
opinion worse than leaking the memory.

Thanks,
Mostafa
> 
> Thanks,
> Robin.
> 
> > 
> > >   }
> > >   static void arm_smmu_setup_unique_irqs(struct arm_smmu_device *smmu)
> > > -- 
> > > 2.34.1
> > > 
> > Thanks,
> > Mostafa

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v4 00/18] SoC: Cleanup MediaTek soundcard machine drivers
From: AngeloGioacchino Del Regno @ 2024-04-09 11:32 UTC (permalink / raw)
  To: broonie
  Cc: shraash, alsa-devel, allen-kh.cheng, kuninori.morimoto.gx,
	lgirdwood, tiwai, shane.chien, krzysztof.kozlowski+dt,
	claudiu.beznea, kernel, robh, nfraprado, amergnat, zhourui,
	jiaxin.yu, trevor.wu, wenst, devicetree, conor+dt, ckeepax, arnd,
	frank.li, maso.huang, u.kleine-koenig, eugen.hristev,
	alpernebiyasak, linux-mediatek, linux-sound, matthias.bgg, perex,
	linux-arm-kernel, AngeloGioacchino Del Regno, xiazhengqiao,
	dianders, linux-kernel, jarkko.nikula

Changes in v4:
 - Rebased over next-20240409
 - Dropped the first 4 patches from v3 as were already picked by Mark

Changes in v3:
 - Added audio-routing names in enum in all yaml files
 - Added mention of disallowing old and new properties together in
   commit message of bindings patches
 - Fixed validation errors with sound-card-common.yaml inclusion
   due to missing model property in examples
 - Removed `else` enforcing headset-codec/speaker-codecs requirement
   if xxx-dai-link not present to avoid future commit noise as the
   deprecated statement will disallow deprecated properties as required

Changes in v2:
 - Bindings: Changed link-name/codec/clk-provider to remove `items`
   and leave just the enum
 - Moved .*-dai-link pattern additionalProperties after `type: object`
 - Added ref to sound-card-common.yaml
 - Fixed dai-link-xxx -> xxx-dai-link typo in example comment

This series performs a cleanup of most of the MediaTek AFE drivers and
soundcard machine drivers, reducing code duplication and setting a base
to be consistent with their devicetree bindings, as many of those are
using different properties and nodes for no good reason.

Summarizing:
 - Commonizes functions and ops where possible
 - Adds a common probe mechanism, increasing maintainability of
   soundcard drivers for older MediaTek SoCs
 - Migrates all drivers to support the new bindings
   - Obviously retains compatibility with old device trees
 - Reduces machine-specific parameters hardcoding in drivers
   - Can now set machine-specific params in device tree
   - Uses the `audio-routing` and `dai-link` nodes like some
     other non-MediaTek SoC sound drivers
 - Imposes consistency between MediaTek ASoC machine soundcard
   drivers bindings
 - Reduces code size and greatly reduces the amount of code that
   will be required for newer drivers (retaining compatibility with
   the old bindings was costly in terms of code size, otherwise
   this series would've removed ~1000 more lines, or something
   along that line).

This series was (manually) tested on MT8173, MT8192, MT8195 and MT8186
Chromebooks.

AngeloGioacchino Del Regno (18):
  ASoC: mediatek: Add common machine soundcard driver probe mechanism
  ASoC: mediatek: common: Constify struct mtk_sof_priv
  ASoC: mediatek: mt8188: Migrate to mtk_soundcard_common_probe
  ASoC: mediatek: mt8195: Migrate to mtk_soundcard_common_probe
  ASoC: mediatek: mt8192: Migrate to mtk_soundcard_common_probe
  ASoC: mediatek: mt8186: Migrate to mtk_soundcard_common_probe
  ASoC: mediatek: Add common snd_soc_ops .startup() callback
  ASoC: mediatek: mt8195: Migrate to the common mtk_soundcard_startup
  ASoC: mediatek: mt8192: Migrate to the common mtk_soundcard_startup
  ASoC: mediatek: mt8186-rt1019: Migrate to the common
    mtk_soundcard_startup
  ASoC: mediatek: Add common mtk_afe_component_probe callback
  ASoC: mediatek: Use common mtk_afe_pcm_platform with common probe cb
  ASoC: mediatek: mt8186: Unify mt8186-mt6366 machine drivers
  ASoC: dt-bindings: mt8195: Document audio-routing and dai-link subnode
  ASoC: dt-bindings: mt8192: Document audio-routing and dai-link subnode
  ASoC: dt-bindings: mt8186: Document audio-routing and dai-link subnode
  arm64: dts: mediatek: mt8195-cherry: Specify sound DAI links and
    routing
  arm64: dts: mediatek: mt8186-corsola: Specify sound DAI links and
    routing

 .../sound/mt8186-mt6366-da7219-max98357.yaml  |  131 +-
 .../sound/mt8186-mt6366-rt1019-rt5682s.yaml   |  120 +-
 .../sound/mt8192-mt6359-rt1015-rt5682.yaml    |  139 +-
 .../bindings/sound/mt8195-mt6359.yaml         |  134 ++
 .../boot/dts/mediatek/mt8186-corsola.dtsi     |   42 +-
 .../boot/dts/mediatek/mt8195-cherry.dtsi      |   45 +
 sound/soc/mediatek/Kconfig                    |   24 +-
 .../mediatek/common/mtk-afe-platform-driver.c |   18 +
 .../soc/mediatek/common/mtk-dsp-sof-common.c  |   15 +-
 .../soc/mediatek/common/mtk-dsp-sof-common.h  |    1 -
 sound/soc/mediatek/common/mtk-soc-card.h      |    7 +-
 .../mediatek/common/mtk-soundcard-driver.c    |  199 +++
 .../mediatek/common/mtk-soundcard-driver.h    |   42 +
 sound/soc/mediatek/mt6797/mt6797-afe-pcm.c    |   14 +-
 sound/soc/mediatek/mt7986/mt7986-afe-pcm.c    |   14 +-
 sound/soc/mediatek/mt8183/mt8183-afe-pcm.c    |   14 +-
 sound/soc/mediatek/mt8186/Makefile            |    3 +-
 sound/soc/mediatek/mt8186/mt8186-afe-pcm.c    |   19 +-
 sound/soc/mediatek/mt8186/mt8186-dai-adda.c   |    2 +-
 .../mt8186/mt8186-mt6366-da7219-max98357.c    | 1189 -----------------
 ...t6366-rt1019-rt5682s.c => mt8186-mt6366.c} |  578 ++++----
 sound/soc/mediatek/mt8188/mt8188-afe-pcm.c    |   21 +-
 sound/soc/mediatek/mt8188/mt8188-mt6359.c     |  203 +--
 sound/soc/mediatek/mt8192/mt8192-afe-pcm.c    |   25 +-
 .../mt8192/mt8192-mt6359-rt1015-rt5682.c      |  301 ++---
 sound/soc/mediatek/mt8195/mt8195-afe-pcm.c    |   21 +-
 sound/soc/mediatek/mt8195/mt8195-mt6359.c     |  487 +++----
 27 files changed, 1613 insertions(+), 2195 deletions(-)
 delete mode 100644 sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c
 rename sound/soc/mediatek/mt8186/{mt8186-mt6366-rt1019-rt5682s.c => mt8186-mt6366.c} (72%)

-- 
2.44.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v4 01/18] ASoC: mediatek: Add common machine soundcard driver probe mechanism
From: AngeloGioacchino Del Regno @ 2024-04-09 11:32 UTC (permalink / raw)
  To: broonie
  Cc: shraash, alsa-devel, allen-kh.cheng, kuninori.morimoto.gx,
	lgirdwood, tiwai, shane.chien, krzysztof.kozlowski+dt,
	claudiu.beznea, kernel, robh, nfraprado, amergnat, zhourui,
	jiaxin.yu, trevor.wu, wenst, devicetree, conor+dt, ckeepax, arnd,
	frank.li, maso.huang, u.kleine-koenig, eugen.hristev,
	alpernebiyasak, linux-mediatek, linux-sound, matthias.bgg, perex,
	linux-arm-kernel, AngeloGioacchino Del Regno, xiazhengqiao,
	dianders, linux-kernel, jarkko.nikula
In-Reply-To: <20240409113310.303261-1-angelogioacchino.delregno@collabora.com>

Add a common machine soundcard driver probe function that supports both
DSP and AFE-direct usecases and also provides a hook for legacy machine
soundcard driver probe mechanisms.

Note that the hook is there because, even for legacy probe, a lot of the
actual code can still be commonized, hence still reducing duplication
for the legacy devicetree retrocompatibility cases.

This common probe function deprecates all of the inconsistent previous
probe mechanisms and aims to settle all of the MediaTek card drivers on
consistent and common devicetree properties describing wanted DAIs,
device specific DAI configuration and DAI links to codecs found on
each device/board.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 sound/soc/mediatek/common/mtk-soc-card.h      |   7 +-
 .../mediatek/common/mtk-soundcard-driver.c    | 148 ++++++++++++++++++
 .../mediatek/common/mtk-soundcard-driver.h    |  18 +++
 3 files changed, 172 insertions(+), 1 deletion(-)

diff --git a/sound/soc/mediatek/common/mtk-soc-card.h b/sound/soc/mediatek/common/mtk-soc-card.h
index eeda79370049..d92dc36d4577 100644
--- a/sound/soc/mediatek/common/mtk-soc-card.h
+++ b/sound/soc/mediatek/common/mtk-soc-card.h
@@ -9,9 +9,14 @@
 #ifndef _MTK_SOC_CARD_H_
 #define _MTK_SOC_CARD_H_
 
+struct mtk_platform_card_data;
+struct mtk_sof_priv;
+
 struct mtk_soc_card_data {
+	struct mtk_sof_priv *sof_priv;
+	struct list_head sof_dai_link_list;
+	struct mtk_platform_card_data *card_data;
 	void *mach_priv;
-	void *sof_priv;
 };
 
 #endif
diff --git a/sound/soc/mediatek/common/mtk-soundcard-driver.c b/sound/soc/mediatek/common/mtk-soundcard-driver.c
index 000a086a8cf4..b1db17e392d5 100644
--- a/sound/soc/mediatek/common/mtk-soundcard-driver.c
+++ b/sound/soc/mediatek/common/mtk-soundcard-driver.c
@@ -10,6 +10,8 @@
 #include <linux/of.h>
 #include <sound/soc.h>
 
+#include "mtk-dsp-sof-common.h"
+#include "mtk-soc-card.h"
 #include "mtk-soundcard-driver.h"
 
 static int set_card_codec_info(struct snd_soc_card *card,
@@ -136,3 +138,149 @@ void clean_card_reference(struct snd_soc_card *card)
 		snd_soc_of_put_dai_link_codecs(dai_link);
 }
 EXPORT_SYMBOL_GPL(clean_card_reference);
+
+int mtk_soundcard_common_probe(struct platform_device *pdev)
+{
+	struct device_node *platform_node, *adsp_node;
+	const struct mtk_soundcard_pdata *pdata;
+	struct mtk_soc_card_data *soc_card_data;
+	struct snd_soc_dai_link *orig_dai_link, *dai_link;
+	struct snd_soc_jack *jacks;
+	struct snd_soc_card *card;
+	int i, orig_num_links, ret;
+	bool needs_legacy_probe;
+
+	pdata = device_get_match_data(&pdev->dev);
+	if (!pdata)
+		return -EINVAL;
+
+	card = pdata->card_data->card;
+	card->dev = &pdev->dev;
+	orig_dai_link = card->dai_link;
+	orig_num_links = card->num_links;
+
+	ret = snd_soc_of_parse_card_name(card, "model");
+	if (ret)
+		return ret;
+
+	if (!card->name) {
+		if (!pdata->card_name)
+			return -EINVAL;
+
+		card->name = pdata->card_name;
+	}
+
+	needs_legacy_probe = !of_property_read_bool(pdev->dev.of_node, "audio-routing");
+	if (needs_legacy_probe) {
+		/*
+		 * If we have no .soc_probe() callback there's no way of using
+		 * any legacy probe mechanism, as that cannot not be generic.
+		 */
+		if (!pdata->soc_probe)
+			return -EINVAL;
+
+		dev_info_once(&pdev->dev, "audio-routing not found: using legacy probe\n");
+	} else {
+		ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
+		if (ret)
+			return ret;
+	}
+
+	soc_card_data = devm_kzalloc(&pdev->dev, sizeof(*soc_card_data), GFP_KERNEL);
+	if (!soc_card_data)
+		return -ENOMEM;
+
+	soc_card_data->card_data = pdata->card_data;
+
+	jacks = devm_kcalloc(card->dev, soc_card_data->card_data->num_jacks,
+			     sizeof(*jacks), GFP_KERNEL);
+	if (!jacks)
+		return -ENOMEM;
+
+	soc_card_data->card_data->jacks = jacks;
+
+	platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0);
+	if (!platform_node)
+		return dev_err_probe(&pdev->dev, -EINVAL,
+				     "Property mediatek,platform missing or invalid\n");
+
+	/* Check if this SoC has an Audio DSP */
+	if (pdata->sof_priv)
+		adsp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,adsp", 0);
+	else
+		adsp_node = NULL;
+
+	if (adsp_node) {
+		if (of_property_read_bool(pdev->dev.of_node, "mediatek,dai-link")) {
+			ret = mtk_sof_dailink_parse_of(card, pdev->dev.of_node,
+						       "mediatek,dai-link",
+						       card->dai_link, card->num_links);
+			if (ret) {
+				of_node_put(adsp_node);
+				of_node_put(platform_node);
+				return dev_err_probe(&pdev->dev, ret,
+						     "Cannot parse mediatek,dai-link\n");
+			}
+		}
+
+		soc_card_data->sof_priv = pdata->sof_priv;
+		card->probe = mtk_sof_card_probe;
+		card->late_probe = mtk_sof_card_late_probe;
+		if (!card->topology_shortname_created) {
+			snprintf(card->topology_shortname, 32, "sof-%s", card->name);
+			card->topology_shortname_created = true;
+		}
+		card->name = card->topology_shortname;
+	}
+
+	/*
+	 * Regardless of whether the ADSP is wanted and/or present in a machine
+	 * specific device tree or not and regardless of whether any AFE_SOF
+	 * link is present, we have to make sure that the platforms->of_node
+	 * is not NULL, and set to either ADSP (adsp_node) or AFE (platform_node).
+	 */
+	for_each_card_prelinks(card, i, dai_link) {
+		if (adsp_node && !strncmp(dai_link->name, "AFE_SOF", strlen("AFE_SOF")))
+			dai_link->platforms->of_node = adsp_node;
+		else if (!dai_link->platforms->name && !dai_link->platforms->of_node)
+			dai_link->platforms->of_node = platform_node;
+	}
+
+	if (!needs_legacy_probe) {
+		ret = parse_dai_link_info(card);
+		if (ret)
+			goto err_restore_dais;
+	} else {
+		if (adsp_node)
+			of_node_put(adsp_node);
+		of_node_put(platform_node);
+	}
+
+	if (pdata->soc_probe) {
+		ret = pdata->soc_probe(soc_card_data, needs_legacy_probe);
+		if (ret) {
+			if (!needs_legacy_probe)
+				clean_card_reference(card);
+			goto err_restore_dais;
+		}
+	}
+	snd_soc_card_set_drvdata(card, soc_card_data);
+
+	ret = devm_snd_soc_register_card(&pdev->dev, card);
+
+	if (!needs_legacy_probe)
+		clean_card_reference(card);
+
+	if (ret) {
+		dev_err_probe(&pdev->dev, ret, "Cannot register card\n");
+		goto err_restore_dais;
+	}
+
+	return 0;
+
+err_restore_dais:
+	card->dai_link = orig_dai_link;
+	card->num_links = orig_num_links;
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mtk_soundcard_common_probe);
diff --git a/sound/soc/mediatek/common/mtk-soundcard-driver.h b/sound/soc/mediatek/common/mtk-soundcard-driver.h
index d92cac1d7b72..44320efff5f8 100644
--- a/sound/soc/mediatek/common/mtk-soundcard-driver.h
+++ b/sound/soc/mediatek/common/mtk-soundcard-driver.h
@@ -9,6 +9,24 @@
 #ifndef _MTK_SOUNDCARD_DRIVER_H_
 #define _MTK_SOUNDCARD_DRIVER_H_
 
+struct mtk_sof_priv;
+struct mtk_soc_card_data;
+
+struct mtk_platform_card_data {
+	struct snd_soc_card *card;
+	struct snd_soc_jack *jacks;
+	u8 num_jacks;
+	u8 flags;
+};
+
+struct mtk_soundcard_pdata {
+	const char *card_name;
+	struct mtk_platform_card_data *card_data;
+	struct mtk_sof_priv *sof_priv;
+	int (*soc_probe)(struct mtk_soc_card_data *card_data, bool legacy);
+};
+
 int parse_dai_link_info(struct snd_soc_card *card);
 void clean_card_reference(struct snd_soc_card *card);
+int mtk_soundcard_common_probe(struct platform_device *pdev);
 #endif
-- 
2.44.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v4 02/18] ASoC: mediatek: common: Constify struct mtk_sof_priv
From: AngeloGioacchino Del Regno @ 2024-04-09 11:32 UTC (permalink / raw)
  To: broonie
  Cc: shraash, alsa-devel, allen-kh.cheng, kuninori.morimoto.gx,
	lgirdwood, tiwai, shane.chien, krzysztof.kozlowski+dt,
	claudiu.beznea, kernel, robh, nfraprado, amergnat, zhourui,
	jiaxin.yu, trevor.wu, wenst, devicetree, conor+dt, ckeepax, arnd,
	frank.li, maso.huang, u.kleine-koenig, eugen.hristev,
	alpernebiyasak, linux-mediatek, linux-sound, matthias.bgg, perex,
	linux-arm-kernel, AngeloGioacchino Del Regno, xiazhengqiao,
	dianders, linux-kernel, jarkko.nikula
In-Reply-To: <20240409113310.303261-1-angelogioacchino.delregno@collabora.com>

Apart from a dai_link_list variable, the mtk_sof_priv currently holds
data that never gets modified during runtime.

Constify the mtk_sof_priv structure and move the SOF dai_link_list as
sof_dai_link_list in struct mtk_soc_card_data, which is a structure
that already holds the card's machine specific, runtime modified data.

This allows to safely pass the mtk_sof_priv structure as platform data
for the commonized card probe mechanism.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 sound/soc/mediatek/common/mtk-dsp-sof-common.c   | 15 +++++++--------
 sound/soc/mediatek/common/mtk-dsp-sof-common.h   |  1 -
 sound/soc/mediatek/common/mtk-soc-card.h         |  2 +-
 sound/soc/mediatek/common/mtk-soundcard-driver.h |  2 +-
 4 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/sound/soc/mediatek/common/mtk-dsp-sof-common.c b/sound/soc/mediatek/common/mtk-dsp-sof-common.c
index 7ec8965a70c0..bca758dca2c9 100644
--- a/sound/soc/mediatek/common/mtk-dsp-sof-common.c
+++ b/sound/soc/mediatek/common/mtk-dsp-sof-common.c
@@ -15,7 +15,7 @@ int mtk_sof_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
 {
 	struct snd_soc_card *card = rtd->card;
 	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);
-	struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
+	const struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
 	int i, j, ret = 0;
 
 	for (i = 0; i < sof_priv->num_streams; i++) {
@@ -55,7 +55,6 @@ int mtk_sof_card_probe(struct snd_soc_card *card)
 	int i;
 	struct snd_soc_dai_link *dai_link;
 	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);
-	struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
 
 	/* Set stream_name to help sof bind widgets */
 	for_each_card_prelinks(card, i, dai_link) {
@@ -63,7 +62,7 @@ int mtk_sof_card_probe(struct snd_soc_card *card)
 			dai_link->stream_name = dai_link->name;
 	}
 
-	INIT_LIST_HEAD(&sof_priv->dai_link_list);
+	INIT_LIST_HEAD(&soc_card_data->sof_dai_link_list);
 
 	return 0;
 }
@@ -73,7 +72,7 @@ static struct snd_soc_pcm_runtime *mtk_sof_find_tplg_be(struct snd_soc_pcm_runti
 {
 	struct snd_soc_card *card = rtd->card;
 	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);
-	struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
+	const struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
 	struct snd_soc_pcm_runtime *fe;
 	struct snd_soc_pcm_runtime *be;
 	struct snd_soc_dpcm *dpcm;
@@ -113,7 +112,7 @@ static int mtk_sof_check_tplg_be_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
 {
 	struct snd_soc_card *card = rtd->card;
 	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);
-	struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
+	const struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
 	struct snd_soc_pcm_runtime *sof_be;
 	struct mtk_dai_link *dai_link;
 	int ret = 0;
@@ -125,7 +124,7 @@ static int mtk_sof_check_tplg_be_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
 		else if (sof_be->dai_link->be_hw_params_fixup)
 			ret = sof_be->dai_link->be_hw_params_fixup(sof_be, params);
 	} else {
-		list_for_each_entry(dai_link, &sof_priv->dai_link_list, list) {
+		list_for_each_entry(dai_link, &soc_card_data->sof_dai_link_list, list) {
 			if (strcmp(dai_link->name, rtd->dai_link->name) == 0) {
 				if (dai_link->be_hw_params_fixup)
 					ret = dai_link->be_hw_params_fixup(rtd, params);
@@ -144,7 +143,7 @@ int mtk_sof_card_late_probe(struct snd_soc_card *card)
 	struct snd_soc_component *sof_comp = NULL;
 	struct mtk_soc_card_data *soc_card_data =
 		snd_soc_card_get_drvdata(card);
-	struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
+	const struct mtk_sof_priv *sof_priv = soc_card_data->sof_priv;
 	struct snd_soc_dai_link *dai_link;
 	struct mtk_dai_link *mtk_dai_link;
 	int i;
@@ -173,7 +172,7 @@ int mtk_sof_card_late_probe(struct snd_soc_card *card)
 			mtk_dai_link->be_hw_params_fixup = dai_link->be_hw_params_fixup;
 			mtk_dai_link->name = dai_link->name;
 
-			list_add(&mtk_dai_link->list, &sof_priv->dai_link_list);
+			list_add(&mtk_dai_link->list, &soc_card_data->sof_dai_link_list);
 		}
 
 		if (dai_link->no_pcm)
diff --git a/sound/soc/mediatek/common/mtk-dsp-sof-common.h b/sound/soc/mediatek/common/mtk-dsp-sof-common.h
index 4bc5e1c0c8ed..8784ee471132 100644
--- a/sound/soc/mediatek/common/mtk-dsp-sof-common.h
+++ b/sound/soc/mediatek/common/mtk-dsp-sof-common.h
@@ -30,7 +30,6 @@ struct mtk_sof_priv {
 	int num_streams;
 	int (*sof_dai_link_fixup)(struct snd_soc_pcm_runtime *rtd,
 				  struct snd_pcm_hw_params *params);
-	struct list_head dai_link_list;
 };
 
 int mtk_sof_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
diff --git a/sound/soc/mediatek/common/mtk-soc-card.h b/sound/soc/mediatek/common/mtk-soc-card.h
index d92dc36d4577..3f6e24dd22df 100644
--- a/sound/soc/mediatek/common/mtk-soc-card.h
+++ b/sound/soc/mediatek/common/mtk-soc-card.h
@@ -13,7 +13,7 @@ struct mtk_platform_card_data;
 struct mtk_sof_priv;
 
 struct mtk_soc_card_data {
-	struct mtk_sof_priv *sof_priv;
+	const struct mtk_sof_priv *sof_priv;
 	struct list_head sof_dai_link_list;
 	struct mtk_platform_card_data *card_data;
 	void *mach_priv;
diff --git a/sound/soc/mediatek/common/mtk-soundcard-driver.h b/sound/soc/mediatek/common/mtk-soundcard-driver.h
index 44320efff5f8..4fd2ffb7e486 100644
--- a/sound/soc/mediatek/common/mtk-soundcard-driver.h
+++ b/sound/soc/mediatek/common/mtk-soundcard-driver.h
@@ -22,7 +22,7 @@ struct mtk_platform_card_data {
 struct mtk_soundcard_pdata {
 	const char *card_name;
 	struct mtk_platform_card_data *card_data;
-	struct mtk_sof_priv *sof_priv;
+	const struct mtk_sof_priv *sof_priv;
 	int (*soc_probe)(struct mtk_soc_card_data *card_data, bool legacy);
 };
 
-- 
2.44.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v4 05/18] ASoC: mediatek: mt8192: Migrate to mtk_soundcard_common_probe
From: AngeloGioacchino Del Regno @ 2024-04-09 11:32 UTC (permalink / raw)
  To: broonie
  Cc: shraash, alsa-devel, allen-kh.cheng, kuninori.morimoto.gx,
	lgirdwood, tiwai, shane.chien, krzysztof.kozlowski+dt,
	claudiu.beznea, kernel, robh, nfraprado, amergnat, zhourui,
	jiaxin.yu, trevor.wu, wenst, devicetree, conor+dt, ckeepax, arnd,
	frank.li, maso.huang, u.kleine-koenig, eugen.hristev,
	alpernebiyasak, linux-mediatek, linux-sound, matthias.bgg, perex,
	linux-arm-kernel, AngeloGioacchino Del Regno, xiazhengqiao,
	dianders, linux-kernel, jarkko.nikula
In-Reply-To: <20240409113310.303261-1-angelogioacchino.delregno@collabora.com>

Add mtk_soundcard_pdata platform data for the MediaTek common sound card
probe mechanism, including a driver/soc-specific probe extension (used
for bits that cannot be commonized  hence specific to this driver), and
change the probe function to mtk_soundcard_common_probe.

This is also adding the possibility of specifying the links and routing
with the audio-routing property and (x)-dai-link nodes in device trees
to stop hardcoding machine specific links in the card driver assupported
by the common probe function, but support for legacy device trees is
retained with a legacy_probe function, which is used only in case the
new properties are not found.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 .../mt8192/mt8192-mt6359-rt1015-rt5682.c      | 164 ++++++++++--------
 1 file changed, 91 insertions(+), 73 deletions(-)

diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
index bfcb2c486c39..645bc1aa67c7 100644
--- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
+++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
@@ -20,6 +20,8 @@
 #include "../../codecs/rt1015.h"
 #include "../../codecs/rt5682.h"
 #include "../common/mtk-afe-platform-driver.h"
+#include "../common/mtk-soc-card.h"
+#include "../common/mtk-soundcard-driver.h"
 #include "mt8192-afe-common.h"
 #include "mt8192-afe-clk.h"
 #include "mt8192-afe-gpio.h"
@@ -38,9 +40,10 @@
 #define RT1015P_RT5682_OF_NAME "mediatek,mt8192_mt6359_rt1015p_rt5682"
 #define RT1015P_RT5682S_OF_NAME "mediatek,mt8192_mt6359_rt1015p_rt5682s"
 
-struct mt8192_mt6359_priv {
-	struct snd_soc_jack headset_jack;
-	struct snd_soc_jack hdmi_jack;
+enum mt8192_jacks {
+	MT8192_JACK_HEADSET,
+	MT8192_JACK_HDMI,
+	MT8192_JACK_MAX,
 };
 
 /* Headset jack detection DAPM pins */
@@ -323,13 +326,13 @@ static int mt8192_mt6359_init(struct snd_soc_pcm_runtime *rtd)
 
 static int mt8192_rt5682_init(struct snd_soc_pcm_runtime *rtd)
 {
+	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);
+	struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8192_JACK_HEADSET];
 	struct snd_soc_component *cmpnt_afe =
 		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
 	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
 	struct snd_soc_component *cmpnt_codec =
 		snd_soc_rtd_to_codec(rtd, 0)->component;
-	struct mt8192_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card);
-	struct snd_soc_jack *jack = &priv->headset_jack;
 	int ret;
 
 	ret = mt8192_dai_i2s_set_share(afe, "I2S8", "I2S9");
@@ -359,19 +362,19 @@ static int mt8192_rt5682_init(struct snd_soc_pcm_runtime *rtd)
 
 static int mt8192_mt6359_hdmi_init(struct snd_soc_pcm_runtime *rtd)
 {
+	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);
+	struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8192_JACK_HDMI];
 	struct snd_soc_component *cmpnt_codec =
 		snd_soc_rtd_to_codec(rtd, 0)->component;
-	struct mt8192_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card);
 	int ret;
 
-	ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
-				    &priv->hdmi_jack);
+	ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, jack);
 	if (ret) {
 		dev_err(rtd->dev, "HDMI Jack creation failed: %d\n", ret);
 		return ret;
 	}
 
-	return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL);
+	return snd_soc_component_set_jack(cmpnt_codec, jack, NULL);
 }
 
 static int mt8192_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
@@ -1136,71 +1139,53 @@ static int mt8192_mt6359_card_set_be_link(struct snd_soc_card *card,
 	return 0;
 }
 
-static int mt8192_mt6359_dev_probe(struct platform_device *pdev)
+static int mt8192_mt6359_legacy_probe(struct mtk_soc_card_data *soc_card_data)
 {
-	struct snd_soc_card *card;
-	struct device_node *platform_node, *hdmi_codec, *headset_codec, *speaker_codec;
-	int ret, i;
+	struct mtk_platform_card_data *card_data = soc_card_data->card_data;
+	struct snd_soc_card *card = card_data->card;
+	struct device *dev = card->dev;
+	struct device_node *hdmi_codec, *headset_codec, *speaker_codec;
 	struct snd_soc_dai_link *dai_link;
-	struct mt8192_mt6359_priv *priv;
-
-	card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev);
-	if (!card)
-		return -EINVAL;
-	card->dev = &pdev->dev;
-
-	if (of_device_is_compatible(pdev->dev.of_node, RT1015P_RT5682_OF_NAME))
-		card->name = RT1015P_RT5682_CARD_NAME;
-	else if (of_device_is_compatible(pdev->dev.of_node, RT1015P_RT5682S_OF_NAME))
-		card->name = RT1015P_RT5682S_CARD_NAME;
-	else
-		dev_dbg(&pdev->dev, "No need to set card name\n");
+	int ret, i;
 
-	hdmi_codec = of_parse_phandle(pdev->dev.of_node, "mediatek,hdmi-codec", 0);
+	hdmi_codec = of_parse_phandle(dev->of_node, "mediatek,hdmi-codec", 0);
 	if (!hdmi_codec)
-		dev_dbg(&pdev->dev, "The machine has no hdmi-codec\n");
+		dev_dbg(dev, "The machine has no hdmi-codec\n");
 
-	platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0);
-	if (!platform_node) {
-		ret = -EINVAL;
-		dev_err_probe(&pdev->dev, ret, "Property 'platform' missing or invalid\n");
-		goto err_platform_node;
-	}
-
-	speaker_codec = of_get_child_by_name(pdev->dev.of_node, "speaker-codecs");
+	speaker_codec = of_get_child_by_name(dev->of_node, "speaker-codecs");
 	if (!speaker_codec) {
 		ret = -EINVAL;
-		dev_err_probe(&pdev->dev, ret, "Property 'speaker-codecs' missing or invalid\n");
+		dev_err_probe(dev, ret, "Property 'speaker-codecs' missing or invalid\n");
 		goto err_speaker_codec;
 	}
 
-	headset_codec = of_get_child_by_name(pdev->dev.of_node, "headset-codec");
+	headset_codec = of_get_child_by_name(dev->of_node, "headset-codec");
 	if (!headset_codec) {
 		ret = -EINVAL;
-		dev_err_probe(&pdev->dev, ret, "Property 'headset-codec' missing or invalid\n");
+		dev_err_probe(dev, ret, "Property 'headset-codec' missing or invalid\n");
 		goto err_headset_codec;
 	}
 
 	for_each_card_prelinks(card, i, dai_link) {
 		ret = mt8192_mt6359_card_set_be_link(card, dai_link, speaker_codec, "I2S3");
 		if (ret) {
-			dev_err_probe(&pdev->dev, ret, "%s set speaker_codec fail\n",
+			dev_err_probe(dev, ret, "%s set speaker_codec fail\n",
 				      dai_link->name);
-			goto err_probe;
+			break;
 		}
 
 		ret = mt8192_mt6359_card_set_be_link(card, dai_link, headset_codec, "I2S8");
 		if (ret) {
-			dev_err_probe(&pdev->dev, ret, "%s set headset_codec fail\n",
+			dev_err_probe(dev, ret, "%s set headset_codec fail\n",
 				      dai_link->name);
-			goto err_probe;
+			break;
 		}
 
 		ret = mt8192_mt6359_card_set_be_link(card, dai_link, headset_codec, "I2S9");
 		if (ret) {
-			dev_err_probe(&pdev->dev, ret, "%s set headset_codec fail\n",
+			dev_err_probe(dev, ret, "%s set headset_codec fail\n",
 				      dai_link->name);
-			goto err_probe;
+			break;
 		}
 
 		if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) {
@@ -1211,52 +1196,85 @@ static int mt8192_mt6359_dev_probe(struct platform_device *pdev)
 		if (dai_link->num_codecs && dai_link->codecs[0].dai_name &&
 		    strcmp(dai_link->codecs[0].dai_name, RT1015_CODEC_DAI) == 0)
 			dai_link->ops = &mt8192_rt1015_i2s_ops;
-
-		if (!dai_link->platforms->name)
-			dai_link->platforms->of_node = platform_node;
-	}
-
-	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv) {
-		ret = -ENOMEM;
-		goto err_probe;
-	}
-	snd_soc_card_set_drvdata(card, priv);
-
-	ret = mt8192_afe_gpio_init(&pdev->dev);
-	if (ret) {
-		dev_err_probe(&pdev->dev, ret, "%s init gpio error\n", __func__);
-		goto err_probe;
 	}
 
-	ret = devm_snd_soc_register_card(&pdev->dev, card);
-	if (ret)
-		dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n", __func__);
-
-err_probe:
 	of_node_put(headset_codec);
 err_headset_codec:
 	of_node_put(speaker_codec);
 err_speaker_codec:
-	of_node_put(platform_node);
-err_platform_node:
-	of_node_put(hdmi_codec);
+	if (hdmi_codec)
+		of_node_put(hdmi_codec);
+
 	return ret;
 }
 
+static int mt8192_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, bool legacy)
+{
+	struct mtk_platform_card_data *card_data = soc_card_data->card_data;
+	struct snd_soc_card *card = card_data->card;
+	int ret;
+
+	if (legacy) {
+		ret = mt8192_mt6359_legacy_probe(soc_card_data);
+		if (ret)
+			return ret;
+	} else {
+		struct snd_soc_dai_link *dai_link;
+		int i;
+
+		for_each_card_prelinks(card, i, dai_link)
+			if (dai_link->num_codecs && dai_link->codecs[0].dai_name &&
+			    strcmp(dai_link->codecs[0].dai_name, RT1015_CODEC_DAI) == 0)
+				dai_link->ops = &mt8192_rt1015_i2s_ops;
+	}
+
+	ret = mt8192_afe_gpio_init(card->dev);
+	if (ret)
+		return dev_err_probe(card->dev, ret, "%s init gpio error\n", __func__);
+
+	return 0;
+}
+
+static const struct mtk_soundcard_pdata mt8192_mt6359_rt1015_rt5682_pdata = {
+	.card_name = RT1015_RT5682_CARD_NAME,
+	.card_data = &(struct mtk_platform_card_data) {
+		.card = &mt8192_mt6359_rt1015_rt5682_card,
+		.num_jacks = MT8192_JACK_MAX,
+	},
+	.soc_probe = mt8192_mt6359_soc_card_probe
+};
+
+static const struct mtk_soundcard_pdata mt8192_mt6359_rt1015p_rt5682_pdata = {
+	.card_name = RT1015P_RT5682_CARD_NAME,
+	.card_data = &(struct mtk_platform_card_data) {
+		.card = &mt8192_mt6359_rt1015p_rt5682x_card,
+		.num_jacks = MT8192_JACK_MAX,
+	},
+	.soc_probe = mt8192_mt6359_soc_card_probe
+};
+
+static const struct mtk_soundcard_pdata mt8192_mt6359_rt1015p_rt5682s_pdata = {
+	.card_name = RT1015P_RT5682S_CARD_NAME,
+	.card_data = &(struct mtk_platform_card_data) {
+		.card = &mt8192_mt6359_rt1015p_rt5682x_card,
+		.num_jacks = MT8192_JACK_MAX,
+	},
+	.soc_probe = mt8192_mt6359_soc_card_probe
+};
+
 #ifdef CONFIG_OF
 static const struct of_device_id mt8192_mt6359_dt_match[] = {
 	{
 		.compatible = RT1015_RT5682_OF_NAME,
-		.data = &mt8192_mt6359_rt1015_rt5682_card,
+		.data = &mt8192_mt6359_rt1015_rt5682_pdata,
 	},
 	{
 		.compatible = RT1015P_RT5682_OF_NAME,
-		.data = &mt8192_mt6359_rt1015p_rt5682x_card,
+		.data = &mt8192_mt6359_rt1015p_rt5682_pdata,
 	},
 	{
 		.compatible = RT1015P_RT5682S_OF_NAME,
-		.data = &mt8192_mt6359_rt1015p_rt5682x_card,
+		.data = &mt8192_mt6359_rt1015p_rt5682s_pdata,
 	},
 	{}
 };
@@ -1276,7 +1294,7 @@ static struct platform_driver mt8192_mt6359_driver = {
 #endif
 		.pm = &mt8192_mt6359_pm_ops,
 	},
-	.probe = mt8192_mt6359_dev_probe,
+	.probe = mtk_soundcard_common_probe,
 };
 
 module_platform_driver(mt8192_mt6359_driver);
-- 
2.44.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v4 03/18] ASoC: mediatek: mt8188: Migrate to mtk_soundcard_common_probe
From: AngeloGioacchino Del Regno @ 2024-04-09 11:32 UTC (permalink / raw)
  To: broonie
  Cc: shraash, alsa-devel, allen-kh.cheng, kuninori.morimoto.gx,
	lgirdwood, tiwai, shane.chien, krzysztof.kozlowski+dt,
	claudiu.beznea, kernel, robh, nfraprado, amergnat, zhourui,
	jiaxin.yu, trevor.wu, wenst, devicetree, conor+dt, ckeepax, arnd,
	frank.li, maso.huang, u.kleine-koenig, eugen.hristev,
	alpernebiyasak, linux-mediatek, linux-sound, matthias.bgg, perex,
	linux-arm-kernel, AngeloGioacchino Del Regno, xiazhengqiao,
	dianders, linux-kernel, jarkko.nikula
In-Reply-To: <20240409113310.303261-1-angelogioacchino.delregno@collabora.com>

Add mtk_soundcard_pdata platform data for the MediaTek common sound card
probe mechanism, including a driver/soc-specific probe extension (used
for bits that cannot be commonized  hence specific to this driver), and
change the probe function to mtk_soundcard_common_probe.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 sound/soc/mediatek/mt8188/mt8188-mt6359.c | 203 +++++++---------------
 1 file changed, 64 insertions(+), 139 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c
index a391066ab204..f629fc6bbb53 100644
--- a/sound/soc/mediatek/mt8188/mt8188-mt6359.c
+++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c
@@ -236,11 +236,11 @@ static const struct sof_conn_stream g_sof_conn_streams[] = {
 	},
 };
 
-struct mt8188_mt6359_priv {
-	struct snd_soc_jack dp_jack;
-	struct snd_soc_jack hdmi_jack;
-	struct snd_soc_jack headset_jack;
-	void *private_data;
+enum mt8188_jacks {
+	MT8188_JACK_HEADSET,
+	MT8188_JACK_DP,
+	MT8188_JACK_HDMI,
+	MT8188_JACK_MAX,
 };
 
 static struct snd_soc_jack_pin mt8188_hdmi_jack_pins[] = {
@@ -268,11 +268,6 @@ static struct snd_soc_jack_pin nau8825_jack_pins[] = {
 	},
 };
 
-struct mt8188_card_data {
-	const char *name;
-	unsigned long quirk;
-};
-
 static const struct snd_kcontrol_new mt8188_dumb_spk_controls[] = {
 	SOC_DAPM_PIN_SWITCH("Ext Spk"),
 };
@@ -590,12 +585,12 @@ static int mt8188_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
 static int mt8188_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);
-	struct mt8188_mt6359_priv *priv = soc_card_data->mach_priv;
+	struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8188_JACK_HDMI];
 	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
 	int ret = 0;
 
 	ret = snd_soc_card_jack_new_pins(rtd->card, "HDMI Jack",
-					 SND_JACK_LINEOUT, &priv->hdmi_jack,
+					 SND_JACK_LINEOUT, jack,
 					 mt8188_hdmi_jack_pins,
 					 ARRAY_SIZE(mt8188_hdmi_jack_pins));
 	if (ret) {
@@ -603,7 +598,7 @@ static int mt8188_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)
 		return ret;
 	}
 
-	ret = snd_soc_component_set_jack(component, &priv->hdmi_jack, NULL);
+	ret = snd_soc_component_set_jack(component, jack, NULL);
 	if (ret) {
 		dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n",
 			__func__, component->name, ret);
@@ -616,19 +611,19 @@ static int mt8188_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)
 static int mt8188_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);
-	struct mt8188_mt6359_priv *priv = soc_card_data->mach_priv;
+	struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8188_JACK_DP];
 	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
 	int ret = 0;
 
 	ret = snd_soc_card_jack_new_pins(rtd->card, "DP Jack", SND_JACK_LINEOUT,
-					 &priv->dp_jack, mt8188_dp_jack_pins,
+					 jack, mt8188_dp_jack_pins,
 					 ARRAY_SIZE(mt8188_dp_jack_pins));
 	if (ret) {
 		dev_err(rtd->dev, "%s, new jack failed: %d\n", __func__, ret);
 		return ret;
 	}
 
-	ret = snd_soc_component_set_jack(component, &priv->dp_jack, NULL);
+	ret = snd_soc_component_set_jack(component, jack, NULL);
 	if (ret) {
 		dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n",
 			__func__, component->name, ret);
@@ -736,10 +731,9 @@ static int mt8188_max98390_codec_init(struct snd_soc_pcm_runtime *rtd)
 static int mt8188_headset_codec_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_soc_card *card = rtd->card;
-	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);
-	struct mt8188_mt6359_priv *priv = soc_card_data->mach_priv;
+	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);
+	struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8188_JACK_HEADSET];
 	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
-	struct snd_soc_jack *jack = &priv->headset_jack;
 	int ret;
 
 	ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_nau8825_widgets,
@@ -1224,11 +1218,10 @@ static struct snd_soc_dai_link mt8188_mt6359_dai_links[] = {
 static void mt8188_fixup_controls(struct snd_soc_card *card)
 {
 	struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);
-	struct mt8188_mt6359_priv *priv = soc_card_data->mach_priv;
-	struct mt8188_card_data *card_data = (struct mt8188_card_data *)priv->private_data;
+	struct mtk_platform_card_data *card_data = soc_card_data->card_data;
 	struct snd_kcontrol *kctl;
 
-	if (card_data->quirk & (NAU8825_HS_PRESENT | RT5682S_HS_PRESENT | ES8326_HS_PRESENT)) {
+	if (card_data->flags & (NAU8825_HS_PRESENT | RT5682S_HS_PRESENT | ES8326_HS_PRESENT)) {
 		struct snd_soc_dapm_widget *w, *next_w;
 
 		for_each_card_widgets_safe(card, w, next_w) {
@@ -1259,14 +1252,10 @@ static struct snd_soc_card mt8188_mt6359_soc_card = {
 	.fixup_controls = mt8188_fixup_controls,
 };
 
-static int mt8188_mt6359_dev_probe(struct platform_device *pdev)
+static int mt8188_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, bool legacy)
 {
-	struct snd_soc_card *card = &mt8188_mt6359_soc_card;
-	struct device_node *platform_node;
-	struct device_node *adsp_node;
-	struct mtk_soc_card_data *soc_card_data;
-	struct mt8188_mt6359_priv *priv;
-	struct mt8188_card_data *card_data;
+	struct mtk_platform_card_data *card_data = soc_card_data->card_data;
+	struct snd_soc_card *card = soc_card_data->card_data->card;
 	struct snd_soc_dai_link *dai_link;
 	bool init_mt6359 = false;
 	bool init_es8326 = false;
@@ -1274,91 +1263,12 @@ static int mt8188_mt6359_dev_probe(struct platform_device *pdev)
 	bool init_rt5682s = false;
 	bool init_max98390 = false;
 	bool init_dumb = false;
-	int ret, i;
-
-	card_data = (struct mt8188_card_data *)of_device_get_match_data(&pdev->dev);
-	card->dev = &pdev->dev;
-
-	ret = snd_soc_of_parse_card_name(card, "model");
-	if (ret)
-		return dev_err_probe(&pdev->dev, ret, "%s new card name parsing error\n",
-				     __func__);
-
-	if (!card->name)
-		card->name = card_data->name;
-
-	if (of_property_read_bool(pdev->dev.of_node, "audio-routing")) {
-		ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
-		if (ret)
-			return ret;
-	}
-
-	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
-	soc_card_data = devm_kzalloc(&pdev->dev, sizeof(*card_data), GFP_KERNEL);
-	if (!soc_card_data)
-		return -ENOMEM;
-
-	soc_card_data->mach_priv = priv;
-
-	adsp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,adsp", 0);
-	if (adsp_node) {
-		struct mtk_sof_priv *sof_priv;
-
-		sof_priv = devm_kzalloc(&pdev->dev, sizeof(*sof_priv), GFP_KERNEL);
-		if (!sof_priv) {
-			ret = -ENOMEM;
-			goto err_adsp_node;
-		}
-		sof_priv->conn_streams = g_sof_conn_streams;
-		sof_priv->num_streams = ARRAY_SIZE(g_sof_conn_streams);
-		soc_card_data->sof_priv = sof_priv;
-		card->probe = mtk_sof_card_probe;
-		card->late_probe = mtk_sof_card_late_probe;
-		if (!card->topology_shortname_created) {
-			snprintf(card->topology_shortname, 32, "sof-%s", card->name);
-			card->topology_shortname_created = true;
-		}
-		card->name = card->topology_shortname;
-	}
-
-	if (of_property_read_bool(pdev->dev.of_node, "mediatek,dai-link")) {
-		ret = mtk_sof_dailink_parse_of(card, pdev->dev.of_node,
-					       "mediatek,dai-link",
-					       mt8188_mt6359_dai_links,
-					       ARRAY_SIZE(mt8188_mt6359_dai_links));
-		if (ret) {
-			dev_err_probe(&pdev->dev, ret, "Parse dai-link fail\n");
-			goto err_adsp_node;
-		}
-	} else {
-		if (!adsp_node)
-			card->num_links = DAI_LINK_REGULAR_NUM;
-	}
-
-	platform_node = of_parse_phandle(pdev->dev.of_node,
-					 "mediatek,platform", 0);
-	if (!platform_node) {
-		ret = dev_err_probe(&pdev->dev, -EINVAL,
-				    "Property 'platform' missing or invalid\n");
-		goto err_adsp_node;
-
-	}
+	int i;
 
-	ret = parse_dai_link_info(card);
-	if (ret)
-		goto err;
+	if (legacy)
+		return -EINVAL;
 
 	for_each_card_prelinks(card, i, dai_link) {
-		if (!dai_link->platforms->name) {
-			if (!strncmp(dai_link->name, "AFE_SOF", strlen("AFE_SOF")) && adsp_node)
-				dai_link->platforms->of_node = adsp_node;
-			else
-				dai_link->platforms->of_node = platform_node;
-		}
-
 		if (strcmp(dai_link->name, "DPTX_BE") == 0) {
 			if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))
 				dai_link->init = mt8188_dptx_codec_init;
@@ -1381,7 +1291,7 @@ static int mt8188_mt6359_dev_probe(struct platform_device *pdev)
 				 * mt8188_max98390_ops. Two amps is I2S mode,
 				 * SOC and codec don't require TDM settings.
 				 */
-				if (!(card_data->quirk & MAX98390_TWO_AMP)) {
+				if (!(card_data->flags & MAX98390_TWO_AMP)) {
 					dai_link->ops = &mt8188_max98390_ops;
 				}
 				if (!init_max98390) {
@@ -1420,40 +1330,55 @@ static int mt8188_mt6359_dev_probe(struct platform_device *pdev)
 		}
 	}
 
-	priv->private_data = card_data;
-	snd_soc_card_set_drvdata(card, soc_card_data);
-
-	ret = devm_snd_soc_register_card(&pdev->dev, card);
-	if (ret)
-		dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n",
-			      __func__);
-err:
-	of_node_put(platform_node);
-	clean_card_reference(card);
-
-err_adsp_node:
-	of_node_put(adsp_node);
-
-	return ret;
+	return 0;
 }
 
-static struct mt8188_card_data mt8188_evb_card = {
-	.name = "mt8188_mt6359",
+static const struct mtk_sof_priv mt8188_sof_priv = {
+	.conn_streams = g_sof_conn_streams,
+	.num_streams = ARRAY_SIZE(g_sof_conn_streams),
+};
+
+static const struct mtk_soundcard_pdata mt8188_evb_card = {
+	.card_name = "mt8188_mt6359",
+	.card_data = &(struct mtk_platform_card_data) {
+		.card = &mt8188_mt6359_soc_card,
+		.num_jacks = MT8188_JACK_MAX,
+	},
+	.sof_priv = &mt8188_sof_priv,
+	.soc_probe = mt8188_mt6359_soc_card_probe,
 };
 
-static struct mt8188_card_data mt8188_nau8825_card = {
-	.name = "mt8188_nau8825",
-	.quirk = NAU8825_HS_PRESENT,
+static const struct mtk_soundcard_pdata mt8188_nau8825_card = {
+	.card_name = "mt8188_nau8825",
+	.card_data = &(struct mtk_platform_card_data) {
+		.card = &mt8188_mt6359_soc_card,
+		.num_jacks = MT8188_JACK_MAX,
+		.flags = NAU8825_HS_PRESENT
+	},
+	.sof_priv = &mt8188_sof_priv,
+	.soc_probe = mt8188_mt6359_soc_card_probe,
 };
 
-static struct mt8188_card_data mt8188_rt5682s_card = {
-	.name = "mt8188_rt5682s",
-	.quirk = RT5682S_HS_PRESENT | MAX98390_TWO_AMP,
+static const struct mtk_soundcard_pdata mt8188_rt5682s_card = {
+	.card_name = "mt8188_rt5682s",
+	.card_data = &(struct mtk_platform_card_data) {
+		.card = &mt8188_mt6359_soc_card,
+		.num_jacks = MT8188_JACK_MAX,
+		.flags = RT5682S_HS_PRESENT | MAX98390_TWO_AMP
+	},
+	.sof_priv = &mt8188_sof_priv,
+	.soc_probe = mt8188_mt6359_soc_card_probe,
 };
 
-static struct mt8188_card_data mt8188_es8326_card = {
-	.name = "mt8188_es8326",
-	.quirk = ES8326_HS_PRESENT | MAX98390_TWO_AMP,
+static const struct mtk_soundcard_pdata mt8188_es8326_card = {
+	.card_name = "mt8188_es8326",
+	.card_data = &(struct mtk_platform_card_data) {
+		.card = &mt8188_mt6359_soc_card,
+		.num_jacks = MT8188_JACK_MAX,
+		.flags = ES8326_HS_PRESENT | MAX98390_TWO_AMP
+	},
+	.sof_priv = &mt8188_sof_priv,
+	.soc_probe = mt8188_mt6359_soc_card_probe,
 };
 
 static const struct of_device_id mt8188_mt6359_dt_match[] = {
@@ -1471,7 +1396,7 @@ static struct platform_driver mt8188_mt6359_driver = {
 		.of_match_table = mt8188_mt6359_dt_match,
 		.pm = &snd_soc_pm_ops,
 	},
-	.probe = mt8188_mt6359_dev_probe,
+	.probe = mtk_soundcard_common_probe,
 };
 
 module_platform_driver(mt8188_mt6359_driver);
-- 
2.44.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox