summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/qcom-audio-dev.txt104
-rw-r--r--Documentation/sysctl/fs.txt36
-rw-r--r--MAINTAINERS1
-rw-r--r--Makefile24
-rw-r--r--arch/arc/Kconfig2
-rw-r--r--arch/arc/Makefile2
-rw-r--r--arch/arc/configs/axs101_defconfig2
-rw-r--r--arch/arc/configs/axs103_defconfig1
-rw-r--r--arch/arc/configs/axs103_smp_defconfig1
-rw-r--r--arch/arc/configs/nsim_700_defconfig1
-rw-r--r--arch/arc/configs/nsimosci_defconfig2
-rw-r--r--arch/arc/configs/nsimosci_hs_defconfig1
-rw-r--r--arch/arc/configs/nsimosci_hs_smp_defconfig1
-rw-r--r--arch/arc/configs/tb10x_defconfig1
-rw-r--r--arch/arc/configs/vdk_hs38_defconfig1
-rw-r--r--arch/arc/configs/vdk_hs38_smp_defconfig1
-rw-r--r--arch/arm/boot/dts/qcom/Makefile4
-rw-r--r--arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi28
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi30
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi42
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi28
-rw-r--r--arch/arm/boot/dts/qcom/msm8996.dtsi228
-rw-r--r--arch/arm/boot/dts/qcom/sdm455-internal-codec-rcm.dts24
-rw-r--r--arch/arm/boot/dts/qcom/sdm455-rcm.dts34
-rw-r--r--arch/arm/boot/dts/qcom/sdm455-rcm.dtsi13
-rw-r--r--arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-audio-common.dtsi256
-rw-r--r--arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-usb.dtsi1
-rw-r--r--arch/arm/kernel/ptrace.c13
-rw-r--r--arch/arm64/Makefile2
-rw-r--r--arch/arm64/configs/cuttlefish_defconfig411
-rw-r--r--arch/arm64/kernel/ptrace.c8
-rw-r--r--arch/mips/include/asm/syscall.h2
-rw-r--r--arch/mips/kernel/ptrace.c2
-rw-r--r--arch/mips/ralink/mt7620.c2
-rw-r--r--arch/powerpc/kernel/ptrace.c2
-rw-r--r--arch/powerpc/kvm/trace.h8
-rw-r--r--arch/powerpc/kvm/trace_booke.h9
-rw-r--r--arch/powerpc/kvm/trace_hv.h9
-rw-r--r--arch/powerpc/kvm/trace_pr.h9
-rw-r--r--arch/powerpc/mm/numa.c2
-rw-r--r--arch/s390/kernel/ptrace.c2
-rw-r--r--arch/s390/mm/pgtable.c2
-rw-r--r--arch/tile/kernel/ptrace.c2
-rw-r--r--arch/x86/configs/x86_64_cuttlefish_defconfig1
-rw-r--r--arch/x86/entry/common.c126
-rw-r--r--arch/x86/entry/entry_64.S75
-rw-r--r--arch/x86/entry/syscall_32.c10
-rw-r--r--arch/x86/entry/syscall_64.c13
-rw-r--r--arch/x86/entry/syscalls/syscall_64.tbl16
-rw-r--r--arch/x86/entry/syscalls/syscalltbl.sh58
-rw-r--r--arch/x86/entry/vsyscall/vsyscall_64.c2
-rw-r--r--arch/x86/include/asm/ptrace.h4
-rw-r--r--arch/x86/kernel/asm-offsets_32.c2
-rw-r--r--arch/x86/kernel/asm-offsets_64.c10
-rw-r--r--arch/x86/kvm/mmu.c27
-rw-r--r--arch/x86/um/sys_call_table_32.c4
-rw-r--r--arch/x86/um/sys_call_table_64.c7
-rw-r--r--arch/x86/um/user-offsets.c6
-rw-r--r--arch/xtensa/kernel/asm-offsets.c16
-rw-r--r--arch/xtensa/kernel/process.c5
-rw-r--r--build.config.cuttlefish.aarch6416
-rw-r--r--build.config.cuttlefish.x86_642
-rw-r--r--drivers/android/binder.c21
-rw-r--r--drivers/android/binder_alloc.c14
-rw-r--r--drivers/android/binder_alloc.h3
-rw-r--r--drivers/char/adsprpc.c398
-rw-r--r--drivers/char/adsprpc_compat.c68
-rw-r--r--drivers/char/adsprpc_shared.h29
-rw-r--r--drivers/cpufreq/imx6q-cpufreq.c7
-rw-r--r--drivers/dma/at_hdmac.c10
-rw-r--r--drivers/gpu/drm/ast/ast_drv.c21
-rw-r--r--drivers/gpu/drm/ast/ast_main.c3
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c3
-rw-r--r--drivers/gpu/drm/gma500/mdfld_intel_display.c2
-rw-r--r--drivers/gpu/drm/msm/sde/sde_connector.c28
-rw-r--r--drivers/gpu/drm/msm/sde/sde_crtc.c22
-rw-r--r--drivers/gpu/drm/msm/sde/sde_crtc.h9
-rw-r--r--drivers/gpu/drm/msm/sde/sde_kms.h12
-rw-r--r--drivers/gpu/drm/msm/sde/sde_kms_utils.c60
-rw-r--r--drivers/gpu/drm/msm/sde/sde_plane.c18
-rw-r--r--drivers/gpu/drm/msm/sde/sde_plane.h9
-rw-r--r--drivers/gpu/drm/msm/sde/sde_splash.c100
-rw-r--r--drivers/gpu/drm/msm/sde/sde_splash.h6
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c7
-rw-r--r--drivers/input/joystick/xpad.c806
-rw-r--r--drivers/input/keyboard/matrix_keypad.c23
-rw-r--r--drivers/input/mouse/elan_i2c_core.c3
-rw-r--r--drivers/iommu/intel-iommu.c2
-rw-r--r--drivers/iommu/intel-svm.c2
-rw-r--r--drivers/iommu/ipmmu-vmsa.c3
-rw-r--r--drivers/leds/led-class.c5
-rw-r--r--drivers/leds/leds-gpio.c4
-rw-r--r--drivers/leds/leds-pwm.c1
-rw-r--r--drivers/media/platform/msm/ais/isp/msm_isp_util.c3
-rw-r--r--drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c21
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/laser_led/msm_laser_led.c67
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c3
-rw-r--r--drivers/misc/mic/scif/scif_rma.c2
-rw-r--r--drivers/net/can/dev.c48
-rw-r--r--drivers/net/can/rcar_can.c5
-rw-r--r--drivers/net/ethernet/amd/sunlance.c4
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h7
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c1
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmmii.c2
-rw-r--r--drivers/net/ethernet/faraday/ftmac100.c7
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/alloc.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h4
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mr.c1
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_int.c2
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_main.c2
-rw-r--r--drivers/net/rionet.c2
-rw-r--r--drivers/net/usb/ipheth.c10
-rw-r--r--drivers/net/wireless/Kconfig7
-rw-r--r--drivers/net/wireless/Makefile2
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c6
-rw-r--r--drivers/net/wireless/cw1200/wsm.c16
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c12
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c5
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c8
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c10
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c12
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c6
-rw-r--r--drivers/net/wireless/virt_wifi.c629
-rw-r--r--drivers/nfc/nfcmrvl/uart.c5
-rw-r--r--drivers/of/base.c25
-rw-r--r--drivers/pinctrl/qcom/pinctrl-spmi-gpio.c4
-rw-r--r--drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c4
-rw-r--r--drivers/s390/net/qeth_core_main.c27
-rw-r--r--drivers/s390/virtio/virtio_ccw.c17
-rw-r--r--drivers/scsi/bfa/bfa_fcbuild.c8
-rw-r--r--drivers/scsi/bfa/bfa_fcs.c78
-rw-r--r--drivers/scsi/bfa/bfa_fcs_lport.c62
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c2
-rw-r--r--drivers/scsi/bfa/bfa_svc.c4
-rw-r--r--drivers/scsi/bfa/bfad.c20
-rw-r--r--drivers/scsi/bfa/bfad_attr.c2
-rw-r--r--drivers/scsi/bfa/bfad_bsg.c6
-rw-r--r--drivers/scsi/csiostor/csio_lnode.c43
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c5
-rw-r--r--drivers/scsi/scsi_devinfo.c22
-rw-r--r--drivers/soc/qcom/memshare/msm_memshare.c19
-rw-r--r--drivers/soc/qcom/memshare/msm_memshare.h4
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_obd.c2
-rw-r--r--drivers/staging/rts5208/sd.c6
-rw-r--r--drivers/tty/n_tty.c19
-rw-r--r--drivers/tty/serial/8250/8250_mtk.c16
-rw-r--r--drivers/tty/serial/kgdboc.c47
-rw-r--r--drivers/tty/tty_buffer.c2
-rw-r--r--drivers/usb/core/hub.c6
-rw-r--r--drivers/usb/core/quirks.c7
-rw-r--r--drivers/usb/core/usb.c6
-rw-r--r--drivers/usb/gadget/udc/dummy_hcd.c9
-rw-r--r--drivers/usb/host/hwa-hc.c2
-rw-r--r--drivers/usb/host/xhci-hub.c66
-rw-r--r--drivers/usb/host/xhci-ring.c2
-rw-r--r--drivers/usb/host/xhci.c16
-rw-r--r--drivers/usb/host/xhci.h2
-rw-r--r--drivers/usb/misc/appledisplay.c1
-rw-r--r--drivers/usb/misc/diag_ipc_bridge.c2
-rw-r--r--drivers/usb/misc/ks_bridge.c1
-rw-r--r--drivers/usb/storage/unusual_realtek.h10
-rw-r--r--fs/9p/vfs_dir.c11
-rw-r--r--fs/bfs/inode.c9
-rw-r--r--fs/btrfs/disk-io.c10
-rw-r--r--fs/btrfs/extent-tree.c10
-rw-r--r--fs/btrfs/free-space-cache.c2
-rw-r--r--fs/btrfs/ioctl.c11
-rw-r--r--fs/btrfs/super.c1
-rw-r--r--fs/btrfs/transaction.c6
-rw-r--r--fs/cifs/dir.c2
-rw-r--r--fs/exec.c7
-rw-r--r--fs/ext2/xattr.c2
-rw-r--r--fs/gfs2/ops_fstype.c2
-rw-r--r--fs/kernfs/symlink.c2
-rw-r--r--fs/namei.c53
-rw-r--r--fs/sdcardfs/derived_perm.c7
-rw-r--r--fs/sdcardfs/main.c10
-rw-r--r--fs/sdcardfs/sdcardfs.h1
-rw-r--r--include/dt-bindings/pinctrl/qcom,pmic-gpio.h9
-rw-r--r--include/linux/can/dev.h1
-rw-r--r--include/linux/fs.h2
-rw-r--r--include/linux/of.h8
-rw-r--r--include/linux/sched.h7
-rw-r--r--include/linux/seccomp.h14
-rw-r--r--include/linux/usb.h4
-rw-r--r--include/sound/apr_audio-v2.h138
-rw-r--r--include/sound/pcm_params.h4
-rw-r--r--include/sound/q6afe-v2.h70
-rw-r--r--include/sound/q6asm-v2.h1
-rw-r--r--include/uapi/sound/compress_params.h3
-rw-r--r--kernel/debug/kdb/kdb_io.c15
-rw-r--r--kernel/debug/kdb/kdb_private.h2
-rw-r--r--kernel/debug/kdb/kdb_support.c14
-rw-r--r--kernel/events/uprobes.c12
-rw-r--r--kernel/sched/core.c4
-rw-r--r--kernel/seccomp.c148
-rw-r--r--kernel/sysctl.c18
-rw-r--r--lib/kobject.c2
-rw-r--r--mm/mlock.c3
-rw-r--r--mm/shmem.c4
-rw-r--r--mm/truncate.c8
-rw-r--r--net/batman-adv/fragmentation.c2
-rw-r--r--net/ipv4/ip_tunnel.c4
-rw-r--r--net/llc/af_llc.c11
-rw-r--r--net/mac80211/iface.c2
-rw-r--r--net/mac80211/rx.c1
-rw-r--r--net/mac80211/status.c2
-rw-r--r--net/mac80211/tx.c4
-rw-r--r--net/netfilter/nf_tables_api.c1
-rw-r--r--net/sctp/associola.c10
-rw-r--r--net/sunrpc/auth_generic.c8
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c4
-rw-r--r--scripts/Makefile.extrawarn3
-rwxr-xr-xscripts/clang-android.sh4
-rw-r--r--scripts/unifdef.c4
-rw-r--r--sound/core/control.c80
-rw-r--r--sound/core/pcm_native.c14
-rw-r--r--sound/isa/wss/wss_lib.c2
-rw-r--r--sound/pci/ac97/ac97_codec.c2
-rw-r--r--sound/pci/hda/hda_intel.c4
-rw-r--r--sound/pci/trident/trident.c2
-rw-r--r--sound/soc/codecs/msm_sdw/msm_sdw_cdc.c10
-rw-r--r--sound/soc/msm/apq8096-auto.c710
-rw-r--r--sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c12
-rw-r--r--sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c1382
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c1491
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h52
-rw-r--r--sound/soc/msm/qdsp6v2/q6afe.c332
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c3
-rw-r--r--sound/soc/msm/qdsp6v2/q6audio-v2.c144
-rw-r--r--sound/soc/msm/sdm660-internal.c2
-rw-r--r--sound/sparc/cs4231.c8
-rw-r--r--sound/usb/card.c5
233 files changed, 8601 insertions, 1289 deletions
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index 80c3f7c462b1..102857a13a86 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -2678,3 +2678,107 @@ Example 2:
qcom,spkr-tdm-rx = <&dai_quat_tdm_rx_0>;
qcom,mic-tdm-tx = <&dai_quat_tdm_tx_0>;
};
+
+* msm-dai-group-mi2s
+
+[First Level Nodes]
+
+Required properties:
+
+ - compatible : "qcom,msm-dai-group-mi2s"
+ - qcom,msm-cpudai-mi2s-group-id: ID of the group device. MI2S interface
+ supports up to 8 groups:
+ Secondary RX: 4354
+ Secondary TX: 4355
+ Tertiary RX: 4356
+ Tertiary TX: 4357
+ Quaternary RX: 4358
+ Quaternary TX: 4359
+
+ - qcom,msm-cpudai-mi2s-group-num-ports: Number of ports in
+ msm-cpudai-mi2s-group-port-id array.
+ Max number of ports supported by DSP is 8.
+
+ - qcom,msm-cpudai-mi2s-group-port-id: Array of mi2s port IDs of the group.
+ The size of the array is determined by
+ the value in msm-cpudai-mi2s-group-num-ports.
+ Each group supports up to 4 ports:
+ Secondary RX: 4160, 4162, 4164, 4166,
+ Secondary TX: 4161, 4163, 4165, 4167,
+ Tertiary RX: 4168, 4170, 4172, 4174,
+ Tertiary TX: 4169, 4171, 4173, 4175,
+ Quaternary RX: 4128, 4130, 4132, 4134,
+ Quaternary TX: 4129, 4131, 4133, 4135,
+
+ - qcom,msm-cpudai-mi2s-channel-mode: group mi2s line channel mode.
+ I2S_SD0 : 0x1
+ I2S_SD1 : 0x2
+ I2S_SD2 : 0x3
+ I2S_SD3 : 0x4
+ I2S_QUAD01 : 0x5
+ I2S_QUAD23 : 0x6
+ I2S_6CHS : 0x7
+ I2S_8CHS : 0x8
+
+ - qcom,msm-cpudai-mi2s-sync-mode: group mi2s master mode.
+ 0 - Slave
+ 1 - Master
+
+ - qcom,msm-cpudai-mi2s-mclk: mi2s mclk value if required.
+ 0 - not provided any mclk
+ others - the real mclk value, at least
+ equal with bclk.
+
+ - qcom,msm-cpudai-mi2s-bclk: mi2s bclk value required, the clk value should
+ equal channels * bit_width * rate.
+
+ [Second Level Nodes]
+
+Required properties:
+
+ - compatible : "qcom,msm-dai-group-mi2s-dev"
+ - qcom,msm-dai-q6-mi2s-dev-id: mi2s port ID.
+ - qcom,msm-cpudai-mi2s-channel-mode: mi2s port line channel mode
+ I2S_SD0 : 0x1
+ I2S_SD1 : 0x2
+ I2S_SD2 : 0x3
+ I2S_SD3 : 0x4
+ I2S_QUAD01 : 0x5
+ I2S_QUAD23 : 0x6
+ I2S_6CHS : 0x7
+ I2S_8CHS : 0x8
+
+ - qcom,msm-cpudai-mi2s-data-align: Indicate how data is packed
+ within the slot. For example, 32 slot width in case of
+ sample bit width is 24.
+ 0 - MSB
+ 1 - LSB
+
+Optional properties:
+
+ - pinctrl-names: Pinctrl state names for each pin group
+ configuration.
+
+ - pinctrl-x: Defines pinctrl state for each pin group.
+
+Example:
+ qcom,msm-dai-group-mi2s-tert-tx {
+ compatible = "qcom,msm-dai-group-mi2s";
+ qcom,msm-cpudai-mi2s-group-id = <4357>;
+ qcom,msm-cpudai-mi2s-group-num-ports = <2>;
+ qcom,msm-cpudai-mi2s-group-port-id = <4167 4169>;
+ qcom,msm-cpudai-mi2s-channel-mode = <5>;
+ dai_tert_mi2s_tx_1:qcom,msm-dai-q6-mi2s-tert-tx-1 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4167>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_tert_mi2s_tx_2:qcom,msm-dai-q6-mi2s-tert-tx-2 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4169>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+ };
diff --git a/Documentation/sysctl/fs.txt b/Documentation/sysctl/fs.txt
index 35e17f748ca7..af5859b2d0f9 100644
--- a/Documentation/sysctl/fs.txt
+++ b/Documentation/sysctl/fs.txt
@@ -34,7 +34,9 @@ Currently, these files are in /proc/sys/fs:
- overflowgid
- pipe-user-pages-hard
- pipe-user-pages-soft
+- protected_fifos
- protected_hardlinks
+- protected_regular
- protected_symlinks
- suid_dumpable
- super-max
@@ -182,6 +184,24 @@ applied.
==============================================================
+protected_fifos:
+
+The intent of this protection is to avoid unintentional writes to
+an attacker-controlled FIFO, where a program expected to create a regular
+file.
+
+When set to "0", writing to FIFOs is unrestricted.
+
+When set to "1" don't allow O_CREAT open on FIFOs that we don't own
+in world writable sticky directories, unless they are owned by the
+owner of the directory.
+
+When set to "2" it also applies to group writable sticky directories.
+
+This protection is based on the restrictions in Openwall.
+
+==============================================================
+
protected_hardlinks:
A long-standing class of security issues is the hardlink-based
@@ -202,6 +222,22 @@ This protection is based on the restrictions in Openwall and grsecurity.
==============================================================
+protected_regular:
+
+This protection is similar to protected_fifos, but it
+avoids writes to an attacker-controlled regular file, where a program
+expected to create one.
+
+When set to "0", writing to regular files is unrestricted.
+
+When set to "1" don't allow O_CREAT open on regular files that we
+don't own in world writable sticky directories, unless they are
+owned by the owner of the directory.
+
+When set to "2" it also applies to group writable sticky directories.
+
+==============================================================
+
protected_symlinks:
A long-standing class of security issues is the symlink-based
diff --git a/MAINTAINERS b/MAINTAINERS
index 414c3c43d276..13cc0bc83c1c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10221,6 +10221,7 @@ F: arch/alpha/kernel/srm_env.c
STABLE BRANCH
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+M: Sasha Levin <sashal@kernel.org>
L: stable@vger.kernel.org
S: Supported
F: Documentation/stable_kernel_rules.txt
diff --git a/Makefile b/Makefile
index 89de8908ff2e..4c581af6508c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 4
-SUBLEVEL = 165
+SUBLEVEL = 167
EXTRAVERSION =
NAME = Blurry Fish Butt
@@ -617,7 +617,11 @@ all: vmlinux
ifeq ($(cc-name),clang)
ifneq ($(CROSS_COMPILE),)
-CLANG_TARGET := --target=$(notdir $(CROSS_COMPILE:%-=%))
+CLANG_TRIPLE ?= $(CROSS_COMPILE)
+CLANG_TARGET := --target=$(notdir $(CLANG_TRIPLE:%-=%))
+ifeq ($(shell $(srctree)/scripts/clang-android.sh $(CC) $(CLANG_TARGET)), y)
+$(error "Clang with Android --target detected. Did you specify CLANG_TRIPLE?")
+endif
GCC_TOOLCHAIN_DIR := $(dir $(shell which $(LD)))
CLANG_PREFIX := --prefix=$(GCC_TOOLCHAIN_DIR)
GCC_TOOLCHAIN := $(realpath $(GCC_TOOLCHAIN_DIR)/..)
@@ -725,18 +729,7 @@ ifdef CONFIG_KCOV
endif
ifeq ($(cc-name),clang)
-ifneq ($(CROSS_COMPILE),)
-CLANG_TRIPLE ?= $(CROSS_COMPILE)
-CLANG_TARGET := --target=$(notdir $(CLANG_TRIPLE:%-=%))
-GCC_TOOLCHAIN := $(realpath $(dir $(shell which $(LD)))/..)
-endif
-ifneq ($(GCC_TOOLCHAIN),)
-CLANG_GCC_TC := --gcc-toolchain=$(GCC_TOOLCHAIN)
-endif
-KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
-KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
-KBUILD_CFLAGS += $(call cc-disable-warning, unused-variable)
KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier)
KBUILD_CFLAGS += $(call cc-disable-warning, gnu)
KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member)
@@ -748,8 +741,6 @@ KBUILD_CFLAGS += $(call cc-disable-warning, tautological-compare)
# See modpost pattern 2
KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,)
KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior)
-KBUILD_CFLAGS += $(call cc-option, -no-integrated-as)
-KBUILD_AFLAGS += $(call cc-option, -no-integrated-as)
else
# These warnings generated too much noise in a regular build.
@@ -823,6 +814,9 @@ KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
# disable pointer signed / unsigned warnings in gcc 4.0
KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign)
+# disable stringop warnings in gcc 8+
+KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation)
+
# disable invalid "can't wrap" optimizations for signed / pointers
KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow)
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index c4ee25e88a7b..e983f410135a 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -96,7 +96,7 @@ endmenu
choice
prompt "ARC Instruction Set"
- default ISA_ARCOMPACT
+ default ISA_ARCV2
config ISA_ARCOMPACT
bool "ARCompact ISA"
diff --git a/arch/arc/Makefile b/arch/arc/Makefile
index 9d64eacdd2aa..fffaff9c7b2c 100644
--- a/arch/arc/Makefile
+++ b/arch/arc/Makefile
@@ -12,7 +12,7 @@ ifeq ($(CROSS_COMPILE),)
CROSS_COMPILE := arc-linux-
endif
-KBUILD_DEFCONFIG := nsim_700_defconfig
+KBUILD_DEFCONFIG := nsim_hs_defconfig
cflags-y += -fno-common -pipe -fno-builtin -mmedium-calls -D__linux__
cflags-$(CONFIG_ISA_ARCOMPACT) += -mA7
diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig
index dbee1934dfc6..3023f91c77c2 100644
--- a/arch/arc/configs/axs101_defconfig
+++ b/arch/arc/configs/axs101_defconfig
@@ -17,6 +17,7 @@ CONFIG_PERF_EVENTS=y
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_SLUB_DEBUG is not set
# CONFIG_COMPAT_BRK is not set
+CONFIG_ISA_ARCOMPACT=y
CONFIG_MODULES=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_ARC_PLAT_AXS10X=y
@@ -97,6 +98,7 @@ CONFIG_NTFS_FS=y
CONFIG_TMPFS=y
CONFIG_JFFS2_FS=y
CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig
index 561eac854cc3..f18107185f53 100644
--- a/arch/arc/configs/axs103_defconfig
+++ b/arch/arc/configs/axs103_defconfig
@@ -103,6 +103,7 @@ CONFIG_NTFS_FS=y
CONFIG_TMPFS=y
CONFIG_JFFS2_FS=y
CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig
index aa4f261b6508..6e1dd8521d2a 100644
--- a/arch/arc/configs/axs103_smp_defconfig
+++ b/arch/arc/configs/axs103_smp_defconfig
@@ -104,6 +104,7 @@ CONFIG_NTFS_FS=y
CONFIG_TMPFS=y
CONFIG_JFFS2_FS=y
CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
diff --git a/arch/arc/configs/nsim_700_defconfig b/arch/arc/configs/nsim_700_defconfig
index 138f9d887957..86e5a62556a8 100644
--- a/arch/arc/configs/nsim_700_defconfig
+++ b/arch/arc/configs/nsim_700_defconfig
@@ -16,6 +16,7 @@ CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
# CONFIG_SLUB_DEBUG is not set
# CONFIG_COMPAT_BRK is not set
+CONFIG_ISA_ARCOMPACT=y
CONFIG_KPROBES=y
CONFIG_MODULES=y
# CONFIG_LBDAF is not set
diff --git a/arch/arc/configs/nsimosci_defconfig b/arch/arc/configs/nsimosci_defconfig
index 31e1d95764ff..a4d7b919224a 100644
--- a/arch/arc/configs/nsimosci_defconfig
+++ b/arch/arc/configs/nsimosci_defconfig
@@ -17,6 +17,7 @@ CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
# CONFIG_SLUB_DEBUG is not set
# CONFIG_COMPAT_BRK is not set
+CONFIG_ISA_ARCOMPACT=y
CONFIG_KPROBES=y
CONFIG_MODULES=y
# CONFIG_LBDAF is not set
@@ -69,5 +70,6 @@ CONFIG_EXT2_FS_XATTR=y
CONFIG_TMPFS=y
# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
diff --git a/arch/arc/configs/nsimosci_hs_defconfig b/arch/arc/configs/nsimosci_hs_defconfig
index fcae66683ca0..b3fb49c8bd14 100644
--- a/arch/arc/configs/nsimosci_hs_defconfig
+++ b/arch/arc/configs/nsimosci_hs_defconfig
@@ -69,5 +69,6 @@ CONFIG_EXT2_FS_XATTR=y
CONFIG_TMPFS=y
# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
diff --git a/arch/arc/configs/nsimosci_hs_smp_defconfig b/arch/arc/configs/nsimosci_hs_smp_defconfig
index b01b659168ea..710c167bbdd8 100644
--- a/arch/arc/configs/nsimosci_hs_smp_defconfig
+++ b/arch/arc/configs/nsimosci_hs_smp_defconfig
@@ -88,6 +88,7 @@ CONFIG_EXT2_FS_XATTR=y
CONFIG_TMPFS=y
# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_FTRACE=y
diff --git a/arch/arc/configs/tb10x_defconfig b/arch/arc/configs/tb10x_defconfig
index 3b4dc9cebcf1..7469b754ac77 100644
--- a/arch/arc/configs/tb10x_defconfig
+++ b/arch/arc/configs/tb10x_defconfig
@@ -19,6 +19,7 @@ CONFIG_KALLSYMS_ALL=y
# CONFIG_AIO is not set
CONFIG_EMBEDDED=y
# CONFIG_COMPAT_BRK is not set
+CONFIG_ISA_ARCOMPACT=y
CONFIG_SLAB=y
CONFIG_MODULES=y
CONFIG_MODULE_FORCE_LOAD=y
diff --git a/arch/arc/configs/vdk_hs38_defconfig b/arch/arc/configs/vdk_hs38_defconfig
index a07f20de221b..772073e5ba04 100644
--- a/arch/arc/configs/vdk_hs38_defconfig
+++ b/arch/arc/configs/vdk_hs38_defconfig
@@ -89,6 +89,7 @@ CONFIG_NTFS_FS=y
CONFIG_TMPFS=y
CONFIG_JFFS2_FS=y
CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig
index f36c047b33ca..50e215a163ff 100644
--- a/arch/arc/configs/vdk_hs38_smp_defconfig
+++ b/arch/arc/configs/vdk_hs38_smp_defconfig
@@ -91,6 +91,7 @@ CONFIG_NTFS_FS=y
CONFIG_TMPFS=y
CONFIG_JFFS2_FS=y
CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile
index 09223b41d3d6..a84b606f94db 100644
--- a/arch/arm/boot/dts/qcom/Makefile
+++ b/arch/arm/boot/dts/qcom/Makefile
@@ -293,7 +293,9 @@ dtb-$(CONFIG_ARCH_SDM630) += sdm630-rumi.dtb \
sdm630-pm660a-headset-jacktype-no-rcm.dtb \
sdm455-mtp.dtb \
sdm455-qrd.dtb \
- sdm455-cdp.dtb
+ sdm455-cdp.dtb \
+ sdm455-rcm.dtb \
+ sdm455-internal-codec-rcm.dtb
ifeq ($(CONFIG_ARM64),y)
always := $(dtb-y)
diff --git a/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi b/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi
index 111266ca59f0..f484eea9f01a 100644
--- a/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi
+++ b/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi
@@ -729,7 +729,19 @@
<&dai_quat_tdm_rx_1>, <&dai_quat_tdm_rx_2>,
<&dai_quat_tdm_rx_3>, <&dai_quat_tdm_tx_0>,
<&dai_quat_tdm_tx_1>, <&dai_quat_tdm_tx_2>,
- <&dai_quat_tdm_tx_3>;
+ <&dai_quat_tdm_tx_3>, <&dai_sec_mi2s_rx_1>,
+ <&dai_sec_mi2s_rx_2>, <&dai_sec_mi2s_rx_3>,
+ <&dai_sec_mi2s_rx_4>, <&dai_sec_mi2s_tx_1>,
+ <&dai_sec_mi2s_tx_2>, <&dai_sec_mi2s_tx_3>,
+ <&dai_sec_mi2s_tx_4>, <&dai_tert_mi2s_rx_1>,
+ <&dai_tert_mi2s_rx_2>, <&dai_tert_mi2s_rx_3>,
+ <&dai_tert_mi2s_rx_4>, <&dai_tert_mi2s_tx_1>,
+ <&dai_tert_mi2s_tx_2>, <&dai_tert_mi2s_tx_3>,
+ <&dai_tert_mi2s_tx_4>, <&dai_quat_mi2s_rx_1>,
+ <&dai_quat_mi2s_rx_2>, <&dai_quat_mi2s_rx_3>,
+ <&dai_quat_mi2s_rx_4>, <&dai_quat_mi2s_tx_1>,
+ <&dai_quat_mi2s_tx_2>, <&dai_quat_mi2s_tx_3>,
+ <&dai_quat_mi2s_tx_4>;
asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2",
"msm-dai-q6-hdmi.8", "msm-dai-q6-mi2s.1",
"msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
@@ -753,7 +765,19 @@
"msm-dai-q6-tdm.36914", "msm-dai-q6-tdm.36916",
"msm-dai-q6-tdm.36918", "msm-dai-q6-tdm.36913",
"msm-dai-q6-tdm.36915", "msm-dai-q6-tdm.36917",
- "msm-dai-q6-tdm.36919";
+ "msm-dai-q6-tdm.36919", "msm-dai-q6-mi2s.4160",
+ "msm-dai-q6-mi2s.4162", "msm-dai-q6-mi2s.4164",
+ "msm-dai-q6-mi2s.4166", "msm-dai-q6-mi2s.4161",
+ "msm-dai-q6-mi2s.4163", "msm-dai-q6-mi2s.4165",
+ "msm-dai-q6-mi2s.4167", "msm-dai-q6-mi2s.4168",
+ "msm-dai-q6-mi2s.4170", "msm-dai-q6-mi2s.4172",
+ "msm-dai-q6-mi2s.4174", "msm-dai-q6-mi2s.4169",
+ "msm-dai-q6-mi2s.4171", "msm-dai-q6-mi2s.4173",
+ "msm-dai-q6-mi2s.4175", "msm-dai-q6-mi2s.4128",
+ "msm-dai-q6-mi2s.4130", "msm-dai-q6-mi2s.4132",
+ "msm-dai-q6-mi2s.4134", "msm-dai-q6-mi2s.4129",
+ "msm-dai-q6-mi2s.4131", "msm-dai-q6-mi2s.4133",
+ "msm-dai-q6-mi2s.4135";
asoc-codec = <&stub_codec>;
asoc-codec-names = "msm-stub-codec.1";
};
diff --git a/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi b/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi
index 211bcd607efb..db99055e095f 100644
--- a/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi
@@ -1106,7 +1106,19 @@
<&dai_quat_tdm_rx_1>, <&dai_quat_tdm_rx_2>,
<&dai_quat_tdm_rx_3>, <&dai_quat_tdm_tx_0>,
<&dai_quat_tdm_tx_1>, <&dai_quat_tdm_tx_2>,
- <&dai_quat_tdm_tx_3>;
+ <&dai_quat_tdm_tx_3>, <&dai_sec_mi2s_rx_1>,
+ <&dai_sec_mi2s_rx_2>, <&dai_sec_mi2s_rx_3>,
+ <&dai_sec_mi2s_rx_4>, <&dai_sec_mi2s_tx_1>,
+ <&dai_sec_mi2s_tx_2>, <&dai_sec_mi2s_tx_3>,
+ <&dai_sec_mi2s_tx_4>, <&dai_tert_mi2s_rx_1>,
+ <&dai_tert_mi2s_rx_2>, <&dai_tert_mi2s_rx_3>,
+ <&dai_tert_mi2s_rx_4>, <&dai_tert_mi2s_tx_1>,
+ <&dai_tert_mi2s_tx_2>, <&dai_tert_mi2s_tx_3>,
+ <&dai_tert_mi2s_tx_4>, <&dai_quat_mi2s_rx_1>,
+ <&dai_quat_mi2s_rx_2>, <&dai_quat_mi2s_rx_3>,
+ <&dai_quat_mi2s_rx_4>, <&dai_quat_mi2s_tx_1>,
+ <&dai_quat_mi2s_tx_2>, <&dai_quat_mi2s_tx_3>,
+ <&dai_quat_mi2s_tx_4>;
asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2",
"msm-dai-q6-hdmi.8", "msm-dai-q6-mi2s.1",
"msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
@@ -1130,7 +1142,19 @@
"msm-dai-q6-tdm.36914", "msm-dai-q6-tdm.36916",
"msm-dai-q6-tdm.36918", "msm-dai-q6-tdm.36913",
"msm-dai-q6-tdm.36915", "msm-dai-q6-tdm.36917",
- "msm-dai-q6-tdm.36919";
+ "msm-dai-q6-tdm.36919", "msm-dai-q6-mi2s.4160",
+ "msm-dai-q6-mi2s.4162", "msm-dai-q6-mi2s.4164",
+ "msm-dai-q6-mi2s.4166", "msm-dai-q6-mi2s.4161",
+ "msm-dai-q6-mi2s.4163", "msm-dai-q6-mi2s.4165",
+ "msm-dai-q6-mi2s.4167", "msm-dai-q6-mi2s.4168",
+ "msm-dai-q6-mi2s.4170", "msm-dai-q6-mi2s.4172",
+ "msm-dai-q6-mi2s.4174", "msm-dai-q6-mi2s.4169",
+ "msm-dai-q6-mi2s.4171", "msm-dai-q6-mi2s.4173",
+ "msm-dai-q6-mi2s.4175", "msm-dai-q6-mi2s.4128",
+ "msm-dai-q6-mi2s.4130", "msm-dai-q6-mi2s.4132",
+ "msm-dai-q6-mi2s.4134", "msm-dai-q6-mi2s.4129",
+ "msm-dai-q6-mi2s.4131", "msm-dai-q6-mi2s.4133",
+ "msm-dai-q6-mi2s.4135";
asoc-codec = <&stub_codec>;
asoc-codec-names = "msm-stub-codec.1";
};
@@ -1441,7 +1465,6 @@
&usb2s {
status = "ok";
qcom,no-wakeup-src-in-hostmode;
- qcom,disable-host-mode-pm;
};
&usb3 {
@@ -1450,7 +1473,6 @@
vdda33-supply = <&pm8994_l24>;
vdda18-supply = <&pm8994_l12>;
qcom,no-wakeup-src-in-hostmode;
- qcom,disable-host-mode-pm;
};
&blsp1_uart2 {
diff --git a/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi
index c2f62be67892..b0ff859d560f 100644
--- a/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi
@@ -959,7 +959,19 @@
<&dai_quat_tdm_rx_1>, <&dai_quat_tdm_rx_2>,
<&dai_quat_tdm_rx_3>, <&dai_quat_tdm_tx_0>,
<&dai_quat_tdm_tx_1>, <&dai_quat_tdm_tx_2>,
- <&dai_quat_tdm_tx_3>;
+ <&dai_quat_tdm_tx_3>, <&dai_sec_mi2s_rx_1>,
+ <&dai_sec_mi2s_rx_2>, <&dai_sec_mi2s_rx_3>,
+ <&dai_sec_mi2s_rx_4>, <&dai_sec_mi2s_tx_1>,
+ <&dai_sec_mi2s_tx_2>, <&dai_sec_mi2s_tx_3>,
+ <&dai_sec_mi2s_tx_4>, <&dai_tert_mi2s_rx_1>,
+ <&dai_tert_mi2s_rx_2>, <&dai_tert_mi2s_rx_3>,
+ <&dai_tert_mi2s_rx_4>, <&dai_tert_mi2s_tx_1>,
+ <&dai_tert_mi2s_tx_2>, <&dai_tert_mi2s_tx_3>,
+ <&dai_tert_mi2s_tx_4>, <&dai_quat_mi2s_rx_1>,
+ <&dai_quat_mi2s_rx_2>, <&dai_quat_mi2s_rx_3>,
+ <&dai_quat_mi2s_rx_4>, <&dai_quat_mi2s_tx_1>,
+ <&dai_quat_mi2s_tx_2>, <&dai_quat_mi2s_tx_3>,
+ <&dai_quat_mi2s_tx_4>;
asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2",
"msm-dai-q6-hdmi.8", "msm-dai-q6-mi2s.1",
"msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
@@ -983,7 +995,19 @@
"msm-dai-q6-tdm.36914", "msm-dai-q6-tdm.36916",
"msm-dai-q6-tdm.36918", "msm-dai-q6-tdm.36913",
"msm-dai-q6-tdm.36915", "msm-dai-q6-tdm.36917",
- "msm-dai-q6-tdm.36919";
+ "msm-dai-q6-tdm.36919", "msm-dai-q6-mi2s.4160",
+ "msm-dai-q6-mi2s.4162", "msm-dai-q6-mi2s.4164",
+ "msm-dai-q6-mi2s.4166", "msm-dai-q6-mi2s.4161",
+ "msm-dai-q6-mi2s.4163", "msm-dai-q6-mi2s.4165",
+ "msm-dai-q6-mi2s.4167", "msm-dai-q6-mi2s.4168",
+ "msm-dai-q6-mi2s.4170", "msm-dai-q6-mi2s.4172",
+ "msm-dai-q6-mi2s.4174", "msm-dai-q6-mi2s.4169",
+ "msm-dai-q6-mi2s.4171", "msm-dai-q6-mi2s.4173",
+ "msm-dai-q6-mi2s.4175", "msm-dai-q6-mi2s.4128",
+ "msm-dai-q6-mi2s.4130", "msm-dai-q6-mi2s.4132",
+ "msm-dai-q6-mi2s.4134", "msm-dai-q6-mi2s.4129",
+ "msm-dai-q6-mi2s.4131", "msm-dai-q6-mi2s.4133",
+ "msm-dai-q6-mi2s.4135";
asoc-codec = <&stub_codec>;
asoc-codec-names = "msm-stub-codec.1";
};
@@ -1272,7 +1296,6 @@
status = "ok";
vbus_dwc3-supply = <&usb2_otg_switch>;
qcom,no-wakeup-src-in-hostmode;
- qcom,disable-host-mode-pm;
dwc3@7600000 {
dr_mode = "host";
};
@@ -1284,7 +1307,6 @@
vdda33-supply = <&pm8994_l24>;
vdda18-supply = <&pm8994_l12>;
qcom,no-wakeup-src-in-hostmode;
- qcom,disable-host-mode-pm;
};
&blsp1_uart2 {
@@ -1435,11 +1457,6 @@
/ {
reserved-memory {
- lk_mem: lk_pool@0x91600000 {
- reg = <0 0x91600000 0 0x00600000>;
- label = "lk_pool";
- };
-
early_camera_mem: early_camera_mem@b3fff000 {
reg = <0 0xb3fff000 0 0x800000>;
label = "early_camera_mem";
@@ -1468,3 +1485,10 @@
&ssc_sensors {
status = "disabled";
};
+
+&soc {
+ early_domain: early_domain {
+ compatible = "qcom,early_domain";
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi b/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi
index c0969a6aa106..4367a876a64d 100644
--- a/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi
@@ -554,7 +554,19 @@
<&dai_quat_tdm_rx_1>, <&dai_quat_tdm_rx_2>,
<&dai_quat_tdm_rx_3>, <&dai_quat_tdm_tx_0>,
<&dai_quat_tdm_tx_1>, <&dai_quat_tdm_tx_2>,
- <&dai_quat_tdm_tx_3>;
+ <&dai_quat_tdm_tx_3>, <&dai_sec_mi2s_rx_1>,
+ <&dai_sec_mi2s_rx_2>, <&dai_sec_mi2s_rx_3>,
+ <&dai_sec_mi2s_rx_4>, <&dai_sec_mi2s_tx_1>,
+ <&dai_sec_mi2s_tx_2>, <&dai_sec_mi2s_tx_3>,
+ <&dai_sec_mi2s_tx_4>, <&dai_tert_mi2s_rx_1>,
+ <&dai_tert_mi2s_rx_2>, <&dai_tert_mi2s_rx_3>,
+ <&dai_tert_mi2s_rx_4>, <&dai_tert_mi2s_tx_1>,
+ <&dai_tert_mi2s_tx_2>, <&dai_tert_mi2s_tx_3>,
+ <&dai_tert_mi2s_tx_4>, <&dai_quat_mi2s_rx_1>,
+ <&dai_quat_mi2s_rx_2>, <&dai_quat_mi2s_rx_3>,
+ <&dai_quat_mi2s_rx_4>, <&dai_quat_mi2s_tx_1>,
+ <&dai_quat_mi2s_tx_2>, <&dai_quat_mi2s_tx_3>,
+ <&dai_quat_mi2s_tx_4>;
asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2",
"msm-dai-q6-hdmi.8", "msm-dai-q6-mi2s.1",
"msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
@@ -578,7 +590,19 @@
"msm-dai-q6-tdm.36914", "msm-dai-q6-tdm.36916",
"msm-dai-q6-tdm.36918", "msm-dai-q6-tdm.36913",
"msm-dai-q6-tdm.36915", "msm-dai-q6-tdm.36917",
- "msm-dai-q6-tdm.36919";
+ "msm-dai-q6-tdm.36919", "msm-dai-q6-mi2s.4160",
+ "msm-dai-q6-mi2s.4162", "msm-dai-q6-mi2s.4164",
+ "msm-dai-q6-mi2s.4166", "msm-dai-q6-mi2s.4161",
+ "msm-dai-q6-mi2s.4163", "msm-dai-q6-mi2s.4165",
+ "msm-dai-q6-mi2s.4167", "msm-dai-q6-mi2s.4168",
+ "msm-dai-q6-mi2s.4170", "msm-dai-q6-mi2s.4172",
+ "msm-dai-q6-mi2s.4174", "msm-dai-q6-mi2s.4169",
+ "msm-dai-q6-mi2s.4171", "msm-dai-q6-mi2s.4173",
+ "msm-dai-q6-mi2s.4175", "msm-dai-q6-mi2s.4128",
+ "msm-dai-q6-mi2s.4130", "msm-dai-q6-mi2s.4132",
+ "msm-dai-q6-mi2s.4134", "msm-dai-q6-mi2s.4129",
+ "msm-dai-q6-mi2s.4131", "msm-dai-q6-mi2s.4133",
+ "msm-dai-q6-mi2s.4135";
asoc-codec = <&stub_codec>;
asoc-codec-names = "msm-stub-codec.1";
};
diff --git a/arch/arm/boot/dts/qcom/msm8996.dtsi b/arch/arm/boot/dts/qcom/msm8996.dtsi
index 4ca58d03115c..aa1d28a082a8 100644
--- a/arch/arm/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996.dtsi
@@ -3560,6 +3560,234 @@
};
};
+ qcom,msm-dai-group-mi2s-sec-rx {
+ compatible = "qcom,msm-dai-group-mi2s";
+ qcom,msm-cpudai-mi2s-group-id = <4354>;
+ qcom,msm-cpudai-mi2s-group-num-ports = <4>;
+ qcom,msm-cpudai-mi2s-group-port-id = <4160 4162 4164 4166>;
+ qcom,msm-cpudai-mi2s-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-sync-mode = <1>;
+ qcom,msm-cpudai-mi2s-mclk = <12288000>;
+ qcom,msm-cpudai-mi2s-bclk = <3072000>;
+ dai_sec_mi2s_rx_1:qcom,msm-dai-q6-mi2s-sec-rx-1 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4160>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_sec_mi2s_rx_2:qcom,msm-dai-q6-mi2s-sec-rx-2 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4162>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_sec_mi2s_rx_3:qcom,msm-dai-q6-mi2s-sec-rx-3 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4164>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_sec_mi2s_rx_4:qcom,msm-dai-q6-mi2s-sec-rx-4 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4166>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+ };
+
+ qcom,msm-dai-group-mi2s-sec-tx {
+ compatible = "qcom,msm-dai-group-mi2s";
+ qcom,msm-cpudai-mi2s-group-id = <4355>;
+ qcom,msm-cpudai-mi2s-group-num-ports = <4>;
+ qcom,msm-cpudai-mi2s-group-port-id = <4161 4163 4165 4167>;
+ qcom,msm-cpudai-mi2s-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-sync-mode = <1>;
+ qcom,msm-cpudai-mi2s-mclk = <12288000>;
+ qcom,msm-cpudai-mi2s-bclk = <3072000>;
+ dai_sec_mi2s_tx_1:qcom,msm-dai-q6-mi2s-sec-tx-1 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4161>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_sec_mi2s_tx_2:qcom,msm-dai-q6-mi2s-sec-tx-2 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4163>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_sec_mi2s_tx_3:qcom,msm-dai-q6-mi2s-sec-tx-3 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4165>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_sec_mi2s_tx_4:qcom,msm-dai-q6-mi2s-sec-tx-4 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4167>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+ };
+
+ qcom,msm-dai-group-mi2s-tert-rx {
+ compatible = "qcom,msm-dai-group-mi2s";
+ qcom,msm-cpudai-mi2s-group-id = <4356>;
+ qcom,msm-cpudai-mi2s-group-num-ports = <4>;
+ qcom,msm-cpudai-mi2s-group-port-id = <4168 4170 4172 4174>;
+ qcom,msm-cpudai-mi2s-channel-mode = <5>;
+ qcom,msm-cpudai-mi2s-sync-mode = <1>;
+ qcom,msm-cpudai-mi2s-mclk = <3072000>;
+ qcom,msm-cpudai-mi2s-bclk = <3072000>;
+ dai_tert_mi2s_rx_1:qcom,msm-dai-q6-mi2s-tert-rx-1 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4168>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_tert_mi2s_rx_2:qcom,msm-dai-q6-mi2s-tert-rx-2 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4170>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_tert_mi2s_rx_3:qcom,msm-dai-q6-mi2s-tert-rx-3 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4172>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_tert_mi2s_rx_4:qcom,msm-dai-q6-mi2s-tert-rx-4 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4174>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+ };
+
+ qcom,msm-dai-group-mi2s-tert-tx {
+ compatible = "qcom,msm-dai-group-mi2s";
+ qcom,msm-cpudai-mi2s-group-id = <4357>;
+ qcom,msm-cpudai-mi2s-group-num-ports = <4>;
+ qcom,msm-cpudai-mi2s-group-port-id = <4169 4171 4173 4175>;
+ qcom,msm-cpudai-mi2s-channel-mode = <5>;
+ qcom,msm-cpudai-mi2s-sync-mode = <1>;
+ qcom,msm-cpudai-mi2s-mclk = <3072000>;
+ qcom,msm-cpudai-mi2s-bclk = <3072000>;
+ dai_tert_mi2s_tx_1:qcom,msm-dai-q6-mi2s-tert-tx-1 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4169>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_tert_mi2s_tx_2:qcom,msm-dai-q6-mi2s-tert-tx-2 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4171>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_tert_mi2s_tx_3:qcom,msm-dai-q6-mi2s-tert-tx-3 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4173>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_tert_mi2s_tx_4:qcom,msm-dai-q6-mi2s-tert-tx-4 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4175>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+ };
+
+ qcom,msm-dai-group-mi2s-quat-rx {
+ compatible = "qcom,msm-dai-group-mi2s";
+ qcom,msm-cpudai-mi2s-group-id = <4358>;
+ qcom,msm-cpudai-mi2s-group-num-ports = <4>;
+ qcom,msm-cpudai-mi2s-group-port-id = <4128 4130 4132 4134>;
+ qcom,msm-cpudai-mi2s-channel-mode = <8>;
+ qcom,msm-cpudai-mi2s-sync-mode = <1>;
+ qcom,msm-cpudai-mi2s-mclk = <0>;
+ qcom,msm-cpudai-mi2s-bclk = <3072000>;
+ dai_quat_mi2s_rx_1:qcom,msm-dai-q6-mi2s-quat-rx-1 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4128>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_quat_mi2s_rx_2:qcom,msm-dai-q6-mi2s-quat-rx-2 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4130>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_quat_mi2s_rx_3:qcom,msm-dai-q6-mi2s-quat-rx-3 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4132>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <3>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_quat_mi2s_rx_4:qcom,msm-dai-q6-mi2s-quat-rx-4 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4134>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <4>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+ };
+
+ qcom,msm-dai-group-mi2s-quat-tx {
+ compatible = "qcom,msm-dai-group-mi2s";
+ qcom,msm-cpudai-mi2s-group-id = <4359>;
+ qcom,msm-cpudai-mi2s-group-num-ports = <4>;
+ qcom,msm-cpudai-mi2s-group-port-id = <4129 4131 4133 4135>;
+ qcom,msm-cpudai-mi2s-channel-mode = <7>;
+ qcom,msm-cpudai-mi2s-sync-mode = <1>;
+ qcom,msm-cpudai-mi2s-mclk = <0>;
+ qcom,msm-cpudai-mi2s-bclk = <3072000>;
+ dai_quat_mi2s_tx_1:qcom,msm-dai-q6-mi2s-quat-tx-1 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4129>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_quat_mi2s_tx_2:qcom,msm-dai-q6-mi2s-quat-tx-2 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4131>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_quat_mi2s_tx_3:qcom,msm-dai-q6-mi2s-quat-tx-3 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4133>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <3>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_quat_mi2s_tx_4:qcom,msm-dai-q6-mi2s-quat-tx-4 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4135>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <4>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+ };
+
qcom,msm-dai-tdm-pri-rx {
compatible = "qcom,msm-dai-tdm";
qcom,msm-cpudai-tdm-group-id = <37120>;
diff --git a/arch/arm/boot/dts/qcom/sdm455-internal-codec-rcm.dts b/arch/arm/boot/dts/qcom/sdm455-internal-codec-rcm.dts
new file mode 100644
index 000000000000..a43de6111483
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdm455-internal-codec-rcm.dts
@@ -0,0 +1,24 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm455.dtsi"
+#include "sdm455-rcm.dtsi"
+#include "sdm660-internal-codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM455 Int. Audio Codec RCM";
+ compatible = "qcom,sdm630-cdp", "qcom,sdm630", "qcom,cdp";
+ qcom,board-id = <21 1>;
+};
diff --git a/arch/arm/boot/dts/qcom/sdm455-rcm.dts b/arch/arm/boot/dts/qcom/sdm455-rcm.dts
new file mode 100644
index 000000000000..868f8b940737
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdm455-rcm.dts
@@ -0,0 +1,34 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm455.dtsi"
+#include "sdm455-rcm.dtsi"
+#include "sdm660-external-codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM 630 PM660 + PM660L RCM";
+ compatible = "qcom,sdm630-cdp", "qcom,sdm630", "qcom,cdp";
+ qcom,board-id = <21 0>;
+};
+
+&tavil_snd {
+ qcom,msm-mbhc-hphl-swh = <0>;
+ qcom,msm-mbhc-gnd-swh = <0>;
+};
+
+&tasha_snd {
+ qcom,msm-mbhc-hphl-swh = <0>;
+ qcom,msm-mbhc-gnd-swh = <0>;
+};
diff --git a/arch/arm/boot/dts/qcom/sdm455-rcm.dtsi b/arch/arm/boot/dts/qcom/sdm455-rcm.dtsi
new file mode 100644
index 000000000000..bc54d29450e1
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdm455-rcm.dtsi
@@ -0,0 +1,13 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "sdm630-cdp.dtsi"
diff --git a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-audio-common.dtsi b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-audio-common.dtsi
index 3928836b8e80..1aec20a24824 100644
--- a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-audio-common.dtsi
+++ b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-audio-common.dtsi
@@ -48,7 +48,19 @@
<&dai_quat_tdm_rx_1>, <&dai_quat_tdm_rx_2>,
<&dai_quat_tdm_rx_3>, <&dai_quat_tdm_tx_0>,
<&dai_quat_tdm_tx_1>, <&dai_quat_tdm_tx_2>,
- <&dai_quat_tdm_tx_3>;
+ <&dai_quat_tdm_tx_3>, <&dai_sec_mi2s_rx_1>,
+ <&dai_sec_mi2s_rx_2>, <&dai_sec_mi2s_rx_3>,
+ <&dai_sec_mi2s_rx_4>, <&dai_sec_mi2s_tx_1>,
+ <&dai_sec_mi2s_tx_2>, <&dai_sec_mi2s_tx_3>,
+ <&dai_sec_mi2s_tx_4>, <&dai_tert_mi2s_rx_1>,
+ <&dai_tert_mi2s_rx_2>, <&dai_tert_mi2s_rx_3>,
+ <&dai_tert_mi2s_rx_4>, <&dai_tert_mi2s_tx_1>,
+ <&dai_tert_mi2s_tx_2>, <&dai_tert_mi2s_tx_3>,
+ <&dai_tert_mi2s_tx_4>, <&dai_quat_mi2s_rx_1>,
+ <&dai_quat_mi2s_rx_2>, <&dai_quat_mi2s_rx_3>,
+ <&dai_quat_mi2s_rx_4>, <&dai_quat_mi2s_tx_1>,
+ <&dai_quat_mi2s_tx_2>, <&dai_quat_mi2s_tx_3>,
+ <&dai_quat_mi2s_tx_4>;
asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-auxpcm.2",
"msm-dai-q6-hdmi.8", "msm-dai-q6-mi2s.1",
"msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
@@ -72,7 +84,19 @@
"msm-dai-q6-tdm.36914", "msm-dai-q6-tdm.36916",
"msm-dai-q6-tdm.36918", "msm-dai-q6-tdm.36913",
"msm-dai-q6-tdm.36915", "msm-dai-q6-tdm.36917",
- "msm-dai-q6-tdm.36919";
+ "msm-dai-q6-tdm.36919", "msm-dai-q6-mi2s.4160",
+ "msm-dai-q6-mi2s.4162", "msm-dai-q6-mi2s.4164",
+ "msm-dai-q6-mi2s.4166", "msm-dai-q6-mi2s.4161",
+ "msm-dai-q6-mi2s.4163", "msm-dai-q6-mi2s.4165",
+ "msm-dai-q6-mi2s.4167", "msm-dai-q6-mi2s.4168",
+ "msm-dai-q6-mi2s.4170", "msm-dai-q6-mi2s.4172",
+ "msm-dai-q6-mi2s.4174", "msm-dai-q6-mi2s.4169",
+ "msm-dai-q6-mi2s.4171", "msm-dai-q6-mi2s.4173",
+ "msm-dai-q6-mi2s.4175", "msm-dai-q6-mi2s.4128",
+ "msm-dai-q6-mi2s.4130", "msm-dai-q6-mi2s.4132",
+ "msm-dai-q6-mi2s.4134", "msm-dai-q6-mi2s.4129",
+ "msm-dai-q6-mi2s.4131", "msm-dai-q6-mi2s.4133",
+ "msm-dai-q6-mi2s.4135";
asoc-codec = <&stub_codec>;
asoc-codec-names = "msm-stub-codec.1";
};
@@ -249,6 +273,234 @@
};
};
+ qcom,msm-dai-group-mi2s-sec-rx {
+ compatible = "qcom,msm-dai-group-mi2s";
+ qcom,msm-cpudai-mi2s-group-id = <4354>;
+ qcom,msm-cpudai-mi2s-group-num-ports = <4>;
+ qcom,msm-cpudai-mi2s-group-port-id = <4160 4162 4164 4166>;
+ qcom,msm-cpudai-mi2s-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-sync-mode = <1>;
+ qcom,msm-cpudai-mi2s-mclk = <12288000>;
+ qcom,msm-cpudai-mi2s-bclk = <3072000>;
+ dai_sec_mi2s_rx_1:qcom,msm-dai-q6-mi2s-sec-rx-1 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4160>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_sec_mi2s_rx_2:qcom,msm-dai-q6-mi2s-sec-rx-2 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4162>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_sec_mi2s_rx_3:qcom,msm-dai-q6-mi2s-sec-rx-3 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4164>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_sec_mi2s_rx_4:qcom,msm-dai-q6-mi2s-sec-rx-4 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4166>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+ };
+
+ qcom,msm-dai-group-mi2s-sec-tx {
+ compatible = "qcom,msm-dai-group-mi2s";
+ qcom,msm-cpudai-mi2s-group-id = <4355>;
+ qcom,msm-cpudai-mi2s-group-num-ports = <4>;
+ qcom,msm-cpudai-mi2s-group-port-id = <4161 4163 4165 4167>;
+ qcom,msm-cpudai-mi2s-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-sync-mode = <1>;
+ qcom,msm-cpudai-mi2s-mclk = <12288000>;
+ qcom,msm-cpudai-mi2s-bclk = <3072000>;
+ dai_sec_mi2s_tx_1:qcom,msm-dai-q6-mi2s-sec-tx-1 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4161>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_sec_mi2s_tx_2:qcom,msm-dai-q6-mi2s-sec-tx-2 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4163>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_sec_mi2s_tx_3:qcom,msm-dai-q6-mi2s-sec-tx-3 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4165>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_sec_mi2s_tx_4:qcom,msm-dai-q6-mi2s-sec-tx-4 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4167>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+ };
+
+ qcom,msm-dai-group-mi2s-tert-rx {
+ compatible = "qcom,msm-dai-group-mi2s";
+ qcom,msm-cpudai-mi2s-group-id = <4356>;
+ qcom,msm-cpudai-mi2s-group-num-ports = <4>;
+ qcom,msm-cpudai-mi2s-group-port-id = <4168 4170 4172 4174>;
+ qcom,msm-cpudai-mi2s-channel-mode = <5>;
+ qcom,msm-cpudai-mi2s-sync-mode = <1>;
+ qcom,msm-cpudai-mi2s-mclk = <3072000>;
+ qcom,msm-cpudai-mi2s-bclk = <3072000>;
+ dai_tert_mi2s_rx_1:qcom,msm-dai-q6-mi2s-tert-rx-1 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4168>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_tert_mi2s_rx_2:qcom,msm-dai-q6-mi2s-tert-rx-2 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4170>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_tert_mi2s_rx_3:qcom,msm-dai-q6-mi2s-tert-rx-3 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4172>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_tert_mi2s_rx_4:qcom,msm-dai-q6-mi2s-tert-rx-4 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4174>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+ };
+
+ qcom,msm-dai-group-mi2s-tert-tx {
+ compatible = "qcom,msm-dai-group-mi2s";
+ qcom,msm-cpudai-mi2s-group-id = <4357>;
+ qcom,msm-cpudai-mi2s-group-num-ports = <4>;
+ qcom,msm-cpudai-mi2s-group-port-id = <4169 4171 4173 4175>;
+ qcom,msm-cpudai-mi2s-channel-mode = <5>;
+ qcom,msm-cpudai-mi2s-sync-mode = <1>;
+ qcom,msm-cpudai-mi2s-mclk = <3072000>;
+ qcom,msm-cpudai-mi2s-bclk = <3072000>;
+ dai_tert_mi2s_tx_1:qcom,msm-dai-q6-mi2s-tert-tx-1 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4169>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_tert_mi2s_tx_2:qcom,msm-dai-q6-mi2s-tert-tx-2 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4171>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_tert_mi2s_tx_3:qcom,msm-dai-q6-mi2s-tert-tx-3 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4173>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_tert_mi2s_tx_4:qcom,msm-dai-q6-mi2s-tert-tx-4 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4175>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+ };
+
+ qcom,msm-dai-group-mi2s-quat-rx {
+ compatible = "qcom,msm-dai-group-mi2s";
+ qcom,msm-cpudai-mi2s-group-id = <4358>;
+ qcom,msm-cpudai-mi2s-group-num-ports = <4>;
+ qcom,msm-cpudai-mi2s-group-port-id = <4128 4130 4132 4134>;
+ qcom,msm-cpudai-mi2s-channel-mode = <8>;
+ qcom,msm-cpudai-mi2s-sync-mode = <1>;
+ qcom,msm-cpudai-mi2s-mclk = <0>;
+ qcom,msm-cpudai-mi2s-bclk = <3072000>;
+ dai_quat_mi2s_rx_1:qcom,msm-dai-q6-mi2s-quat-rx-1 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4128>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_quat_mi2s_rx_2:qcom,msm-dai-q6-mi2s-quat-rx-2 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4130>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_quat_mi2s_rx_3:qcom,msm-dai-q6-mi2s-quat-rx-3 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4132>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <3>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_quat_mi2s_rx_4:qcom,msm-dai-q6-mi2s-quat-rx-4 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4134>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <4>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+ };
+
+ qcom,msm-dai-group-mi2s-quat-tx {
+ compatible = "qcom,msm-dai-group-mi2s";
+ qcom,msm-cpudai-mi2s-group-id = <4359>;
+ qcom,msm-cpudai-mi2s-group-num-ports = <4>;
+ qcom,msm-cpudai-mi2s-group-port-id = <4129 4131 4133 4135>;
+ qcom,msm-cpudai-mi2s-channel-mode = <7>;
+ qcom,msm-cpudai-mi2s-sync-mode = <1>;
+ qcom,msm-cpudai-mi2s-mclk = <0>;
+ qcom,msm-cpudai-mi2s-bclk = <3072000>;
+ dai_quat_mi2s_tx_1:qcom,msm-dai-q6-mi2s-quat-tx-1 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4129>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <1>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_quat_mi2s_tx_2:qcom,msm-dai-q6-mi2s-quat-tx-2 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4131>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <2>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_quat_mi2s_tx_3:qcom,msm-dai-q6-mi2s-quat-tx-3 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4133>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <3>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+
+ dai_quat_mi2s_tx_4:qcom,msm-dai-q6-mi2s-quat-tx-4 {
+ compatible = "qcom,msm-dai-group-mi2s-dev";
+ qcom,msm-cpudai-mi2s-dev-id = <4135>;
+ qcom,msm-cpudai-mi2s-dev-channel-mode = <4>;
+ qcom,msm-cpudai-mi2s-data-align = <0>;
+ };
+ };
+
qcom,msm-dai-tdm-pri-rx {
compatible = "qcom,msm-dai-tdm";
qcom,msm-cpudai-tdm-group-id = <37120>;
diff --git a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-usb.dtsi b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-usb.dtsi
index faaf00b6ac25..b7505743986e 100644
--- a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-usb.dtsi
+++ b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-usb.dtsi
@@ -88,7 +88,6 @@
resets = <&clock_virt USB_30_BCR>;
reset-names = "core_reset";
- qcom,disable-host-mode-pm;
dwc3@6a00000 {
compatible = "snps,dwc3";
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index d54c53b7ab63..ae738a6319f6 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -932,18 +932,19 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
{
current_thread_info()->syscall = scno;
- /* Do the secure computing check first; failures should be fast. */
+ if (test_thread_flag(TIF_SYSCALL_TRACE))
+ tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+
+ /* Do seccomp after ptrace; syscall may have changed. */
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
- if (secure_computing() == -1)
+ if (secure_computing(NULL) == -1)
return -1;
#else
/* XXX: remove this once OABI gets fixed */
- secure_computing_strict(scno);
+ secure_computing_strict(current_thread_info()->syscall);
#endif
- if (test_thread_flag(TIF_SYSCALL_TRACE))
- tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
-
+ /* Tracer or seccomp may have changed syscall. */
scno = current_thread_info()->syscall;
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index cc8b41e151b9..e8361ff258f2 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -10,7 +10,7 @@
#
# Copyright (C) 1995-2001 by Russell King
-LDFLAGS_vmlinux :=-p --no-undefined -X
+LDFLAGS_vmlinux :=--no-undefined -X
CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
GZFLAGS :=-9
diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig
new file mode 100644
index 000000000000..c620078b587c
--- /dev/null
+++ b/arch/arm64/configs/cuttlefish_defconfig
@@ -0,0 +1,411 @@
+# CONFIG_USELIB is not set
+CONFIG_AUDIT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CPUSETS=y
+# CONFIG_PROC_PID_CPUSET is not set
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_SCHEDTUNE=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_SCHED_TUNE=y
+CONFIG_DEFAULT_USE_ENERGY_AWARE=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_SGETMASK_SYSCALL=y
+# CONFIG_SYSFS_SYSCALL is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_BPF_SYSCALL=y
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_JUMP_LABEL=y
+CONFIG_CC_STACKPROTECTOR_STRONG=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_HOST_GENERIC=y
+CONFIG_PREEMPT=y
+CONFIG_HZ_100=y
+# CONFIG_SPARSEMEM_VMEMMAP is not set
+CONFIG_KSM=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_ZSMALLOC=y
+CONFIG_SECCOMP=y
+CONFIG_ARMV8_DEPRECATED=y
+CONFIG_SWP_EMULATION=y
+CONFIG_CP15_BARRIER_EMULATION=y
+CONFIG_SETEND_EMULATION=y
+CONFIG_ARM64_SW_TTBR0_PAN=y
+CONFIG_RANDOMIZE_BASE=y
+CONFIG_CMDLINE="console=ttyAMA0"
+CONFIG_CMDLINE_EXTEND=y
+# CONFIG_EFI is not set
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_COMPAT=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
+CONFIG_PM_DEBUG=y
+CONFIG_ARM_CPUIDLE=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_ARM_BIG_LITTLE_CPUFREQ=y
+CONFIG_ARM_DT_BL_CPUFREQ=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_NET_IPGRE_DEMUX=y
+CONFIG_NET_IPVTI=y
+CONFIG_INET_ESP=y
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_UDP_DIAG=y
+CONFIG_INET_DIAG_DESTROY=y
+CONFIG_TCP_CONG_ADVANCED=y
+# CONFIG_TCP_CONG_BIC is not set
+# CONFIG_TCP_CONG_WESTWOOD is not set
+# CONFIG_TCP_CONG_HTCP is not set
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_VTI=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+CONFIG_NETFILTER_XT_MATCH_BPF=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_RPFILTER=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_L2TP=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_CLS_U32=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_U32=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_CFG80211=y
+# CONFIG_CFG80211_DEFAULT_PS is not set
+CONFIG_MAC80211=y
+# CONFIG_MAC80211_RC_MINSTREL is not set
+CONFIG_RFKILL=y
+# CONFIG_UEVENT_HELPER is not set
+CONFIG_DEVTMPFS=y
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+CONFIG_DEBUG_DEVRES=y
+CONFIG_OF_UNITTEST=y
+CONFIG_ZRAM=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_VIRTIO_BLK=y
+CONFIG_UID_SYS_STATS=y
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_VIRTIO=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_DM_UEVENT=y
+CONFIG_DM_VERITY=y
+CONFIG_DM_VERITY_FEC=y
+CONFIG_DM_VERITY_AVB=y
+CONFIG_NETDEVICES=y
+CONFIG_NETCONSOLE=y
+CONFIG_NETCONSOLE_DYNAMIC=y
+CONFIG_TUN=y
+CONFIG_VIRTIO_NET=y
+# CONFIG_ETHERNET is not set
+CONFIG_PHYLIB=y
+CONFIG_PPP=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPTP=y
+CONFIG_PPPOL2TP=y
+CONFIG_USB_USBNET=y
+# CONFIG_USB_NET_AX8817X is not set
+# CONFIG_USB_NET_AX88179_178A is not set
+# CONFIG_USB_NET_CDCETHER is not set
+# CONFIG_USB_NET_CDC_NCM is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+CONFIG_VIRT_WIFI=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_KEYRESET=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_XPAD=y
+CONFIG_JOYSTICK_XPAD_FF=y
+CONFIG_JOYSTICK_XPAD_LEDS=y
+CONFIG_INPUT_TABLET=y
+CONFIG_TABLET_USB_ACECAD=y
+CONFIG_TABLET_USB_AIPTEK=y
+CONFIG_TABLET_USB_GTCO=y
+CONFIG_TABLET_USB_HANWANG=y
+CONFIG_TABLET_USB_KBTAB=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=y
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=48
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_VIRTIO=y
+# CONFIG_DEVPORT is not set
+# CONFIG_I2C_COMPAT is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_GPIOLIB=y
+# CONFIG_HWMON is not set
+CONFIG_CPU_THERMAL=y
+CONFIG_MEDIA_SUPPORT=y
+# CONFIG_DVB_TUNER_DIB0070 is not set
+# CONFIG_DVB_TUNER_DIB0090 is not set
+# CONFIG_VGA_ARB is not set
+CONFIG_DRM=y
+# CONFIG_DRM_FBDEV_EMULATION is not set
+CONFIG_DRM_VIRTIO_GPU=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_HIDRAW=y
+CONFIG_UHID=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_ACRUX=y
+CONFIG_HID_ACRUX_FF=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_PRODIKEYS=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+CONFIG_DRAGONRISE_FF=y
+CONFIG_HID_EMS_FF=y
+CONFIG_HID_ELECOM=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_HOLTEK=y
+CONFIG_HID_KEYTOUCH=y
+CONFIG_HID_KYE=y
+CONFIG_HID_UCLOGIC=y
+CONFIG_HID_WALTOP=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LCPOWER=y
+CONFIG_HID_LOGITECH=y
+CONFIG_HID_LOGITECH_DJ=y
+CONFIG_LOGITECH_FF=y
+CONFIG_LOGIRUMBLEPAD2_FF=y
+CONFIG_LOGIG940_FF=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_ORTEK=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_PANTHERLORD_FF=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_PICOLCD=y
+CONFIG_HID_PRIMAX=y
+CONFIG_HID_ROCCAT=y
+CONFIG_HID_SAITEK=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SPEEDLINK=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+CONFIG_GREENASIA_FF=y
+CONFIG_HID_SMARTJOYPLUS=y
+CONFIG_SMARTJOYPLUS_FF=y
+CONFIG_HID_TIVO=y
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+CONFIG_HID_WACOM=y
+CONFIG_HID_WIIMOTE=y
+CONFIG_HID_ZEROPLUS=y
+CONFIG_HID_ZYDACRON=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_ACC=y
+CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y
+CONFIG_USB_CONFIGFS_UEVENT=y
+CONFIG_USB_CONFIGFS_F_MIDI=y
+CONFIG_MMC=y
+# CONFIG_MMC_BLOCK is not set
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+# CONFIG_RTC_SYSTOHC is not set
+CONFIG_RTC_DRV_PL031=y
+CONFIG_VIRTIO_PCI=y
+# CONFIG_VIRTIO_PCI_LEGACY is not set
+CONFIG_VIRTIO_BALLOON=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
+CONFIG_STAGING=y
+CONFIG_ASHMEM=y
+CONFIG_ANDROID_TIMED_GPIO=y
+CONFIG_SYNC=y
+CONFIG_ANDROID_VSOC=y
+CONFIG_ION=y
+# CONFIG_COMMON_CLK_XGENE is not set
+CONFIG_MAILBOX=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_EXT4_ENCRYPTION=y
+CONFIG_F2FS_FS=y
+CONFIG_F2FS_FS_SECURITY=y
+CONFIG_F2FS_FS_ENCRYPTION=y
+# CONFIG_DNOTIFY is not set
+CONFIG_QUOTA=y
+CONFIG_QFMT_V2=y
+CONFIG_FUSE_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_SDCARD_FS=y
+CONFIG_PSTORE=y
+CONFIG_PSTORE_CONSOLE=y
+CONFIG_PSTORE_RAM=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_PANIC_TIMEOUT=5
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_ENABLE_DEFAULT_TRACERS=y
+CONFIG_DEBUG_SET_MODULE_RONX=y
+CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_LSM_MMAP_MIN_ADDR=65536
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_LZ4=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_XZ_DEC=y
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 6204b7600d1b..c67bd311e815 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -1354,13 +1354,13 @@ static void tracehook_report_syscall(struct pt_regs *regs,
asmlinkage int syscall_trace_enter(struct pt_regs *regs)
{
- /* Do the secure computing check first; failures should be fast. */
- if (secure_computing() == -1)
- return -1;
-
if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+ /* Do the secure computing after ptrace; failures should be fast. */
+ if (secure_computing(NULL) == -1)
+ return -1;
+
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_enter(regs, regs->syscallno);
diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h
index 47bc45a67e9b..032a497356f3 100644
--- a/arch/mips/include/asm/syscall.h
+++ b/arch/mips/include/asm/syscall.h
@@ -51,7 +51,7 @@ static inline unsigned long mips_get_syscall_arg(unsigned long *arg,
#ifdef CONFIG_64BIT
case 4: case 5: case 6: case 7:
#ifdef CONFIG_MIPS32_O32
- if (test_thread_flag(TIF_32BIT_REGS))
+ if (test_tsk_thread_flag(task, TIF_32BIT_REGS))
return get_user(*arg, (int *)usp + n);
else
#endif
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 9d04392f7ef0..816c4b281c0f 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -1023,7 +1023,7 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
current_thread_info()->syscall = syscall;
- if (secure_computing() == -1)
+ if (secure_computing(NULL) == -1)
return -1;
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c
index c5f45fc96c74..9c19f5493b85 100644
--- a/arch/mips/ralink/mt7620.c
+++ b/arch/mips/ralink/mt7620.c
@@ -81,7 +81,7 @@ static struct rt2880_pmx_func pcie_rst_grp[] = {
};
static struct rt2880_pmx_func nd_sd_grp[] = {
FUNC("nand", MT7620_GPIO_MODE_NAND, 45, 15),
- FUNC("sd", MT7620_GPIO_MODE_SD, 45, 15)
+ FUNC("sd", MT7620_GPIO_MODE_SD, 47, 13)
};
static struct rt2880_pmx_group mt7620a_pinmux_data[] = {
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 3b63655efa3c..e776567b281a 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1783,7 +1783,7 @@ static int do_seccomp(struct pt_regs *regs)
* have already loaded -ENOSYS into r3, or seccomp has put
* something else in r3 (via SECCOMP_RET_ERRNO/TRACE).
*/
- if (__secure_computing())
+ if (__secure_computing(NULL))
return -1;
/*
diff --git a/arch/powerpc/kvm/trace.h b/arch/powerpc/kvm/trace.h
index 2e0e67ef3544..e8cedf32345a 100644
--- a/arch/powerpc/kvm/trace.h
+++ b/arch/powerpc/kvm/trace.h
@@ -5,8 +5,6 @@
#undef TRACE_SYSTEM
#define TRACE_SYSTEM kvm
-#define TRACE_INCLUDE_PATH .
-#define TRACE_INCLUDE_FILE trace
/*
* Tracepoint for guest mode entry.
@@ -119,4 +117,10 @@ TRACE_EVENT(kvm_check_requests,
#endif /* _TRACE_KVM_H */
/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace
+
#include <trace/define_trace.h>
diff --git a/arch/powerpc/kvm/trace_booke.h b/arch/powerpc/kvm/trace_booke.h
index 7ec534d1db9f..7eadbf449a1f 100644
--- a/arch/powerpc/kvm/trace_booke.h
+++ b/arch/powerpc/kvm/trace_booke.h
@@ -5,8 +5,6 @@
#undef TRACE_SYSTEM
#define TRACE_SYSTEM kvm_booke
-#define TRACE_INCLUDE_PATH .
-#define TRACE_INCLUDE_FILE trace_booke
#define kvm_trace_symbol_exit \
{0, "CRITICAL"}, \
@@ -217,4 +215,11 @@ TRACE_EVENT(kvm_booke_queue_irqprio,
#endif
/* This part must be outside protection */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace_booke
+
#include <trace/define_trace.h>
diff --git a/arch/powerpc/kvm/trace_hv.h b/arch/powerpc/kvm/trace_hv.h
index 33d9daff5783..d1bfe017d751 100644
--- a/arch/powerpc/kvm/trace_hv.h
+++ b/arch/powerpc/kvm/trace_hv.h
@@ -8,8 +8,6 @@
#undef TRACE_SYSTEM
#define TRACE_SYSTEM kvm_hv
-#define TRACE_INCLUDE_PATH .
-#define TRACE_INCLUDE_FILE trace_hv
#define kvm_trace_symbol_hcall \
{H_REMOVE, "H_REMOVE"}, \
@@ -474,4 +472,11 @@ TRACE_EVENT(kvmppc_run_vcpu_exit,
#endif /* _TRACE_KVM_HV_H */
/* This part must be outside protection */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace_hv
+
#include <trace/define_trace.h>
diff --git a/arch/powerpc/kvm/trace_pr.h b/arch/powerpc/kvm/trace_pr.h
index 810507cb688a..1e40aa2aa5af 100644
--- a/arch/powerpc/kvm/trace_pr.h
+++ b/arch/powerpc/kvm/trace_pr.h
@@ -7,8 +7,6 @@
#undef TRACE_SYSTEM
#define TRACE_SYSTEM kvm_pr
-#define TRACE_INCLUDE_PATH .
-#define TRACE_INCLUDE_FILE trace_pr
TRACE_EVENT(kvm_book3s_reenter,
TP_PROTO(int r, struct kvm_vcpu *vcpu),
@@ -271,4 +269,11 @@ TRACE_EVENT(kvm_unmap_hva,
#endif /* _TRACE_KVM_H */
/* This part must be outside protection */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace_pr
+
#include <trace/define_trace.h>
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 3c4faa4c2742..bb3df222ae71 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1319,7 +1319,7 @@ static long vphn_get_associativity(unsigned long cpu,
switch (rc) {
case H_FUNCTION:
- printk(KERN_INFO
+ printk_once(KERN_INFO
"VPHN is not supported. Disabling polling...\n");
stop_topology_update();
break;
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 02bd587b610b..fe35d5c27d3c 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -826,7 +826,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
long ret = 0;
/* Do the secure computing check first. */
- if (secure_computing()) {
+ if (secure_computing(NULL)) {
/* seccomp failures shouldn't expose any additional code. */
ret = -1;
goto out;
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 05ae254f84cf..1866b6a5171a 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -637,6 +637,8 @@ void gmap_discard(struct gmap *gmap, unsigned long from, unsigned long to)
vmaddr |= gaddr & ~PMD_MASK;
/* Find vma in the parent mm */
vma = find_vma(gmap->mm, vmaddr);
+ if (!vma)
+ continue;
size = min(to - gaddr, PMD_SIZE - (gaddr & ~PMD_MASK));
zap_page_range(vma, vmaddr, size, NULL);
}
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c
index 6239aa155f6d..35d786a840e6 100644
--- a/arch/tile/kernel/ptrace.c
+++ b/arch/tile/kernel/ptrace.c
@@ -262,7 +262,7 @@ int do_syscall_trace_enter(struct pt_regs *regs)
if (work & _TIF_NOHZ)
user_exit();
- if (secure_computing() == -1)
+ if (secure_computing(NULL) == -1)
return -1;
if (work & _TIF_SYSCALL_TRACE) {
diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig
index c5ccb61274c5..8e4a038e9ac2 100644
--- a/arch/x86/configs/x86_64_cuttlefish_defconfig
+++ b/arch/x86/configs/x86_64_cuttlefish_defconfig
@@ -247,6 +247,7 @@ CONFIG_USB_USBNET=y
# CONFIG_USB_NET_CDC_SUBSET is not set
# CONFIG_USB_NET_ZAURUS is not set
CONFIG_MAC80211_HWSIM=y
+CONFIG_VIRT_WIFI=y
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_KEYRESET=y
# CONFIG_INPUT_KEYBOARD is not set
diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
index a9e501303e15..c611c1ed064b 100644
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
@@ -64,22 +64,16 @@ static void do_audit_syscall_entry(struct pt_regs *regs, u32 arch)
}
/*
- * We can return 0 to resume the syscall or anything else to go to phase
- * 2. If we resume the syscall, we need to put something appropriate in
- * regs->orig_ax.
- *
- * NB: We don't have full pt_regs here, but regs->orig_ax and regs->ax
- * are fully functional.
- *
- * For phase 2's benefit, our return value is:
- * 0: resume the syscall
- * 1: go to phase 2; no seccomp phase 2 needed
- * anything else: go to phase 2; pass return value to seccomp
+ * Returns the syscall nr to run (which should match regs->orig_ax) or -1
+ * to skip the syscall.
*/
-unsigned long syscall_trace_enter_phase1(struct pt_regs *regs, u32 arch)
+long syscall_trace_enter(struct pt_regs *regs)
{
+ u32 arch = is_ia32_task() ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64;
+
struct thread_info *ti = pt_regs_to_thread_info(regs);
unsigned long ret = 0;
+ bool emulated = false;
u32 work;
if (IS_ENABLED(CONFIG_DEBUG_ENTRY))
@@ -98,11 +92,29 @@ unsigned long syscall_trace_enter_phase1(struct pt_regs *regs, u32 arch)
}
#endif
+ /*
+ * If we stepped into a sysenter/syscall insn, it trapped in
+ * kernel mode; do_debug() cleared TF and set TIF_SINGLESTEP.
+ * If user-mode had set TF itself, then it's still clear from
+ * do_debug() and we need to set it again to restore the user
+ * state. If we entered on the slow path, TF was already set.
+ */
+ if (work & _TIF_SINGLESTEP)
+ regs->flags |= X86_EFLAGS_TF;
+
+ if (unlikely(work & _TIF_SYSCALL_EMU))
+ emulated = true;
+
+ if ((emulated || (work & _TIF_SYSCALL_TRACE)) &&
+ tracehook_report_syscall_entry(regs))
+ return -1L;
+
+ if (emulated)
+ return -1L;
+
#ifdef CONFIG_SECCOMP
/*
- * Do seccomp first -- it should minimize exposure of other
- * code, and keeping seccomp fast is probably more valuable
- * than the rest of this.
+ * Do seccomp after ptrace, to catch any tracer changes.
*/
if (work & _TIF_SECCOMP) {
struct seccomp_data sd;
@@ -129,79 +141,12 @@ unsigned long syscall_trace_enter_phase1(struct pt_regs *regs, u32 arch)
sd.args[5] = regs->bp;
}
- BUILD_BUG_ON(SECCOMP_PHASE1_OK != 0);
- BUILD_BUG_ON(SECCOMP_PHASE1_SKIP != 1);
-
- ret = seccomp_phase1(&sd);
- if (ret == SECCOMP_PHASE1_SKIP) {
- regs->orig_ax = -1;
- ret = 0;
- } else if (ret != SECCOMP_PHASE1_OK) {
- return ret; /* Go directly to phase 2 */
- }
-
- work &= ~_TIF_SECCOMP;
- }
-#endif
-
- /* Do our best to finish without phase 2. */
- if (work == 0)
- return ret; /* seccomp and/or nohz only (ret == 0 here) */
-
-#ifdef CONFIG_AUDITSYSCALL
- if (work == _TIF_SYSCALL_AUDIT) {
- /*
- * If there is no more work to be done except auditing,
- * then audit in phase 1. Phase 2 always audits, so, if
- * we audit here, then we can't go on to phase 2.
- */
- do_audit_syscall_entry(regs, arch);
- return 0;
+ ret = __secure_computing(&sd);
+ if (ret == -1)
+ return ret;
}
#endif
- return 1; /* Something is enabled that we can't handle in phase 1 */
-}
-
-/* Returns the syscall nr to run (which should match regs->orig_ax). */
-long syscall_trace_enter_phase2(struct pt_regs *regs, u32 arch,
- unsigned long phase1_result)
-{
- struct thread_info *ti = pt_regs_to_thread_info(regs);
- long ret = 0;
- u32 work = ACCESS_ONCE(ti->flags) & _TIF_WORK_SYSCALL_ENTRY;
-
- if (IS_ENABLED(CONFIG_DEBUG_ENTRY))
- BUG_ON(regs != task_pt_regs(current));
-
- /*
- * If we stepped into a sysenter/syscall insn, it trapped in
- * kernel mode; do_debug() cleared TF and set TIF_SINGLESTEP.
- * If user-mode had set TF itself, then it's still clear from
- * do_debug() and we need to set it again to restore the user
- * state. If we entered on the slow path, TF was already set.
- */
- if (work & _TIF_SINGLESTEP)
- regs->flags |= X86_EFLAGS_TF;
-
-#ifdef CONFIG_SECCOMP
- /*
- * Call seccomp_phase2 before running the other hooks so that
- * they can see any changes made by a seccomp tracer.
- */
- if (phase1_result > 1 && seccomp_phase2(phase1_result)) {
- /* seccomp failures shouldn't expose any additional code. */
- return -1;
- }
-#endif
-
- if (unlikely(work & _TIF_SYSCALL_EMU))
- ret = -1L;
-
- if ((ret || test_thread_flag(TIF_SYSCALL_TRACE)) &&
- tracehook_report_syscall_entry(regs))
- ret = -1L;
-
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
trace_sys_enter(regs, regs->orig_ax);
@@ -210,17 +155,6 @@ long syscall_trace_enter_phase2(struct pt_regs *regs, u32 arch,
return ret ?: regs->orig_ax;
}
-long syscall_trace_enter(struct pt_regs *regs)
-{
- u32 arch = is_ia32_task() ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64;
- unsigned long phase1_result = syscall_trace_enter_phase1(regs, arch);
-
- if (phase1_result == 0)
- return regs->orig_ax;
- else
- return syscall_trace_enter_phase2(regs, arch, phase1_result);
-}
-
#define EXIT_TO_USERMODE_LOOP_FLAGS \
(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_UPROBE | \
_TIF_NEED_RESCHED | _TIF_USER_RETURN_NOTIFY)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 9a66d730c78f..4ada6445bc24 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -187,12 +187,19 @@ entry_SYSCALL_64_fastpath:
sbb %rcx, %rcx /* array_index_mask_nospec() */
and %rcx, %rax
movq %r10, %rcx
+
+ /*
+ * This call instruction is handled specially in stub_ptregs_64.
+ * It might end up jumping to the slow path. If it jumps, RAX is
+ * clobbered.
+ */
#ifdef CONFIG_RETPOLINE
movq sys_call_table(, %rax, 8), %rax
call __x86_indirect_thunk_rax
#else
call *sys_call_table(, %rax, 8)
#endif
+.Lentry_SYSCALL_64_after_fastpath_call:
movq %rax, RAX(%rsp)
1:
@@ -254,25 +261,13 @@ GLOBAL(int_ret_from_sys_call_irqs_off)
/* Do syscall entry tracing */
tracesys:
- movq %rsp, %rdi
- movl $AUDIT_ARCH_X86_64, %esi
- call syscall_trace_enter_phase1
- test %rax, %rax
- jnz tracesys_phase2 /* if needed, run the slow path */
- RESTORE_C_REGS_EXCEPT_RAX /* else restore clobbered regs */
- movq ORIG_RAX(%rsp), %rax
- jmp entry_SYSCALL_64_fastpath /* and return to the fast path */
-
-tracesys_phase2:
SAVE_EXTRA_REGS
movq %rsp, %rdi
- movl $AUDIT_ARCH_X86_64, %esi
- movq %rax, %rdx
- call syscall_trace_enter_phase2
+ call syscall_trace_enter
/*
* Reload registers from stack in case ptrace changed them.
- * We don't reload %rax because syscall_trace_entry_phase2() returned
+ * We don't reload %rax because syscall_trace_enter() returned
* the value it wants us to use in the table lookup.
*/
RESTORE_C_REGS_EXCEPT_RAX
@@ -397,6 +392,38 @@ opportunistic_sysret_failed:
jmp restore_c_regs_and_iret
END(entry_SYSCALL_64)
+ENTRY(stub_ptregs_64)
+ /*
+ * Syscalls marked as needing ptregs land here.
+ * If we are on the fast path, we need to save the extra regs.
+ * If we are on the slow path, the extra regs are already saved.
+ *
+ * RAX stores a pointer to the C function implementing the syscall.
+ */
+ cmpq $.Lentry_SYSCALL_64_after_fastpath_call, (%rsp)
+ jne 1f
+
+ /* Called from fast path -- pop return address and jump to slow path */
+ popq %rax
+ jmp tracesys /* called from fast path */
+
+1:
+ /* Called from C */
+ jmp *%rax /* called from C */
+END(stub_ptregs_64)
+
+.macro ptregs_stub func
+ENTRY(ptregs_\func)
+ leaq \func(%rip), %rax
+ jmp stub_ptregs_64
+END(ptregs_\func)
+.endm
+
+/* Instantiate ptregs_stub for each ptregs-using syscall */
+#define __SYSCALL_64_QUAL_(sym)
+#define __SYSCALL_64_QUAL_ptregs(sym) ptregs_stub sym
+#define __SYSCALL_64(nr, sym, qual) __SYSCALL_64_QUAL_##qual(sym)
+#include <asm/syscalls_64.h>
.macro FORK_LIKE func
ENTRY(stub_\func)
@@ -862,7 +889,7 @@ ENTRY(\sym)
call \do_sym
- jmp error_exit /* %ebx: no swapgs flag */
+ jmp error_exit
.endif
END(\sym)
.endm
@@ -1124,7 +1151,6 @@ END(paranoid_exit)
/*
* Save all registers in pt_regs, and switch gs if needed.
- * Return: EBX=0: came from user mode; EBX=1: otherwise
*/
ENTRY(error_entry)
cld
@@ -1137,7 +1163,6 @@ ENTRY(error_entry)
* the kernel CR3 here.
*/
SWITCH_KERNEL_CR3
- xorl %ebx, %ebx
testb $3, CS+8(%rsp)
jz .Lerror_kernelspace
@@ -1171,7 +1196,6 @@ ENTRY(error_entry)
* for these here too.
*/
.Lerror_kernelspace:
- incl %ebx
leaq native_irq_return_iret(%rip), %rcx
cmpq %rcx, RIP+8(%rsp)
je .Lerror_bad_iret
@@ -1202,28 +1226,19 @@ ENTRY(error_entry)
/*
* Pretend that the exception came from user mode: set up pt_regs
- * as if we faulted immediately after IRET and clear EBX so that
- * error_exit knows that we will be returning to user mode.
+ * as if we faulted immediately after IRET.
*/
mov %rsp, %rdi
call fixup_bad_iret
mov %rax, %rsp
- decl %ebx
jmp .Lerror_entry_from_usermode_after_swapgs
END(error_entry)
-
-/*
- * On entry, EBS is a "return to kernel mode" flag:
- * 1: already in kernel mode, don't need SWAPGS
- * 0: user gsbase is loaded, we need SWAPGS and standard preparation for return to usermode
- */
ENTRY(error_exit)
- movl %ebx, %eax
DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF
- testl %eax, %eax
- jnz retint_kernel
+ testb $3, CS(%rsp)
+ jz retint_kernel
jmp retint_user
END(error_exit)
diff --git a/arch/x86/entry/syscall_32.c b/arch/x86/entry/syscall_32.c
index 9a6649857106..8f895ee13a1c 100644
--- a/arch/x86/entry/syscall_32.c
+++ b/arch/x86/entry/syscall_32.c
@@ -6,17 +6,11 @@
#include <asm/asm-offsets.h>
#include <asm/syscall.h>
-#ifdef CONFIG_IA32_EMULATION
-#define SYM(sym, compat) compat
-#else
-#define SYM(sym, compat) sym
-#endif
-
-#define __SYSCALL_I386(nr, sym, compat) extern asmlinkage long SYM(sym, compat)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ;
+#define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ;
#include <asm/syscalls_32.h>
#undef __SYSCALL_I386
-#define __SYSCALL_I386(nr, sym, compat) [nr] = SYM(sym, compat),
+#define __SYSCALL_I386(nr, sym, qual) [nr] = sym,
extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
diff --git a/arch/x86/entry/syscall_64.c b/arch/x86/entry/syscall_64.c
index 41283d22be7a..9dbc5abb6162 100644
--- a/arch/x86/entry/syscall_64.c
+++ b/arch/x86/entry/syscall_64.c
@@ -6,19 +6,14 @@
#include <asm/asm-offsets.h>
#include <asm/syscall.h>
-#define __SYSCALL_COMMON(nr, sym, compat) __SYSCALL_64(nr, sym, compat)
+#define __SYSCALL_64_QUAL_(sym) sym
+#define __SYSCALL_64_QUAL_ptregs(sym) ptregs_##sym
-#ifdef CONFIG_X86_X32_ABI
-# define __SYSCALL_X32(nr, sym, compat) __SYSCALL_64(nr, sym, compat)
-#else
-# define __SYSCALL_X32(nr, sym, compat) /* nothing */
-#endif
-
-#define __SYSCALL_64(nr, sym, compat) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ;
+#define __SYSCALL_64(nr, sym, qual) extern asmlinkage long __SYSCALL_64_QUAL_##qual(sym)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
#include <asm/syscalls_64.h>
#undef __SYSCALL_64
-#define __SYSCALL_64(nr, sym, compat) [nr] = sym,
+#define __SYSCALL_64(nr, sym, qual) [nr] = __SYSCALL_64_QUAL_##qual(sym),
extern long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index 314a90bfc09c..aa51cdd2a11a 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -21,7 +21,7 @@
12 common brk sys_brk
13 64 rt_sigaction sys_rt_sigaction
14 common rt_sigprocmask sys_rt_sigprocmask
-15 64 rt_sigreturn stub_rt_sigreturn
+15 64 rt_sigreturn stub_rt_sigreturn/ptregs
16 64 ioctl sys_ioctl
17 common pread64 sys_pread64
18 common pwrite64 sys_pwrite64
@@ -62,10 +62,10 @@
53 common socketpair sys_socketpair
54 64 setsockopt sys_setsockopt
55 64 getsockopt sys_getsockopt
-56 common clone stub_clone
-57 common fork stub_fork
-58 common vfork stub_vfork
-59 64 execve stub_execve
+56 common clone stub_clone/ptregs
+57 common fork stub_fork/ptregs
+58 common vfork stub_vfork/ptregs
+59 64 execve stub_execve/ptregs
60 common exit sys_exit
61 common wait4 sys_wait4
62 common kill sys_kill
@@ -328,7 +328,7 @@
319 common memfd_create sys_memfd_create
320 common kexec_file_load sys_kexec_file_load
321 common bpf sys_bpf
-322 64 execveat stub_execveat
+322 64 execveat stub_execveat/ptregs
323 common userfaultfd sys_userfaultfd
324 common membarrier sys_membarrier
325 common mlock2 sys_mlock2
@@ -345,7 +345,7 @@
517 x32 recvfrom compat_sys_recvfrom
518 x32 sendmsg compat_sys_sendmsg
519 x32 recvmsg compat_sys_recvmsg
-520 x32 execve stub_x32_execve
+520 x32 execve stub_x32_execve/ptregs
521 x32 ptrace compat_sys_ptrace
522 x32 rt_sigpending compat_sys_rt_sigpending
523 x32 rt_sigtimedwait compat_sys_rt_sigtimedwait
@@ -370,4 +370,4 @@
542 x32 getsockopt compat_sys_getsockopt
543 x32 io_setup compat_sys_io_setup
544 x32 io_submit compat_sys_io_submit
-545 x32 execveat stub_x32_execveat
+545 x32 execveat stub_x32_execveat/ptregs
diff --git a/arch/x86/entry/syscalls/syscalltbl.sh b/arch/x86/entry/syscalls/syscalltbl.sh
index 0e7f8ec071e7..cd3d3015d7df 100644
--- a/arch/x86/entry/syscalls/syscalltbl.sh
+++ b/arch/x86/entry/syscalls/syscalltbl.sh
@@ -3,13 +3,63 @@
in="$1"
out="$2"
+syscall_macro() {
+ abi="$1"
+ nr="$2"
+ entry="$3"
+
+ # Entry can be either just a function name or "function/qualifier"
+ real_entry="${entry%%/*}"
+ qualifier="${entry:${#real_entry}}" # Strip the function name
+ qualifier="${qualifier:1}" # Strip the slash, if any
+
+ echo "__SYSCALL_${abi}($nr, $real_entry, $qualifier)"
+}
+
+emit() {
+ abi="$1"
+ nr="$2"
+ entry="$3"
+ compat="$4"
+
+ if [ "$abi" == "64" -a -n "$compat" ]; then
+ echo "a compat entry for a 64-bit syscall makes no sense" >&2
+ exit 1
+ fi
+
+ if [ -z "$compat" ]; then
+ if [ -n "$entry" ]; then
+ syscall_macro "$abi" "$nr" "$entry"
+ fi
+ else
+ echo "#ifdef CONFIG_X86_32"
+ if [ -n "$entry" ]; then
+ syscall_macro "$abi" "$nr" "$entry"
+ fi
+ echo "#else"
+ syscall_macro "$abi" "$nr" "$compat"
+ echo "#endif"
+ fi
+}
+
grep '^[0-9]' "$in" | sort -n | (
while read nr abi name entry compat; do
abi=`echo "$abi" | tr '[a-z]' '[A-Z]'`
- if [ -n "$compat" ]; then
- echo "__SYSCALL_${abi}($nr, $entry, $compat)"
- elif [ -n "$entry" ]; then
- echo "__SYSCALL_${abi}($nr, $entry, $entry)"
+ if [ "$abi" == "COMMON" -o "$abi" == "64" ]; then
+ # COMMON is the same as 64, except that we don't expect X32
+ # programs to use it. Our expectation has nothing to do with
+ # any generated code, so treat them the same.
+ emit 64 "$nr" "$entry" "$compat"
+ elif [ "$abi" == "X32" ]; then
+ # X32 is equivalent to 64 on an X32-compatible kernel.
+ echo "#ifdef CONFIG_X86_X32_ABI"
+ emit 64 "$nr" "$entry" "$compat"
+ echo "#endif"
+ elif [ "$abi" == "I386" ]; then
+ emit "$abi" "$nr" "$entry" "$compat"
+ else
+ echo "Unknown abi $abi" >&2
+ exit 1
fi
done
) > "$out"
diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
index 2d359991a273..8054f25d9b42 100644
--- a/arch/x86/entry/vsyscall/vsyscall_64.c
+++ b/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -213,7 +213,7 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
*/
regs->orig_ax = syscall_nr;
regs->ax = -ENOSYS;
- tmp = secure_computing();
+ tmp = secure_computing(NULL);
if ((!tmp && regs->orig_ax != syscall_nr) || regs->ip != address) {
warn_bad_vsyscall(KERN_DEBUG, regs,
"seccomp tried to change syscall nr or ip");
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
index 6271281f947d..25479a144894 100644
--- a/arch/x86/include/asm/ptrace.h
+++ b/arch/x86/include/asm/ptrace.h
@@ -83,10 +83,6 @@ extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
int error_code, int si_code);
-extern unsigned long syscall_trace_enter_phase1(struct pt_regs *, u32 arch);
-extern long syscall_trace_enter_phase2(struct pt_regs *, u32 arch,
- unsigned long phase1_result);
-
extern long syscall_trace_enter(struct pt_regs *);
static inline unsigned long regs_return_value(struct pt_regs *regs)
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index 6ce39025f467..fdeb0ce07c16 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -7,7 +7,7 @@
#include <linux/lguest.h>
#include "../../../drivers/lguest/lg.h"
-#define __SYSCALL_I386(nr, sym, compat) [nr] = 1,
+#define __SYSCALL_I386(nr, sym, qual) [nr] = 1,
static char syscalls[] = {
#include <asm/syscalls_32.h>
};
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
index d8f42f902a0f..5de52cf589be 100644
--- a/arch/x86/kernel/asm-offsets_64.c
+++ b/arch/x86/kernel/asm-offsets_64.c
@@ -4,17 +4,11 @@
#include <asm/ia32.h>
-#define __SYSCALL_64(nr, sym, compat) [nr] = 1,
-#define __SYSCALL_COMMON(nr, sym, compat) [nr] = 1,
-#ifdef CONFIG_X86_X32_ABI
-# define __SYSCALL_X32(nr, sym, compat) [nr] = 1,
-#else
-# define __SYSCALL_X32(nr, sym, compat) /* nothing */
-#endif
+#define __SYSCALL_64(nr, sym, qual) [nr] = 1,
static char syscalls_64[] = {
#include <asm/syscalls_64.h>
};
-#define __SYSCALL_I386(nr, sym, compat) [nr] = 1,
+#define __SYSCALL_I386(nr, sym, qual) [nr] = 1,
static char syscalls_ia32[] = {
#include <asm/syscalls_32.h>
};
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 2b71f2c03b9e..a5b533aea958 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -4174,9 +4174,9 @@ static void mmu_pte_write_flush_tlb(struct kvm_vcpu *vcpu, bool zap_page,
}
static u64 mmu_pte_write_fetch_gpte(struct kvm_vcpu *vcpu, gpa_t *gpa,
- const u8 *new, int *bytes)
+ int *bytes)
{
- u64 gentry;
+ u64 gentry = 0;
int r;
/*
@@ -4188,22 +4188,12 @@ static u64 mmu_pte_write_fetch_gpte(struct kvm_vcpu *vcpu, gpa_t *gpa,
/* Handle a 32-bit guest writing two halves of a 64-bit gpte */
*gpa &= ~(gpa_t)7;
*bytes = 8;
- r = kvm_vcpu_read_guest(vcpu, *gpa, &gentry, 8);
- if (r)
- gentry = 0;
- new = (const u8 *)&gentry;
}
- switch (*bytes) {
- case 4:
- gentry = *(const u32 *)new;
- break;
- case 8:
- gentry = *(const u64 *)new;
- break;
- default:
- gentry = 0;
- break;
+ if (*bytes == 4 || *bytes == 8) {
+ r = kvm_vcpu_read_guest_atomic(vcpu, *gpa, &gentry, *bytes);
+ if (r)
+ gentry = 0;
}
return gentry;
@@ -4313,8 +4303,6 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes);
- gentry = mmu_pte_write_fetch_gpte(vcpu, &gpa, new, &bytes);
-
/*
* No need to care whether allocation memory is successful
* or not since pte prefetch is skiped if it does not have
@@ -4323,6 +4311,9 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
mmu_topup_memory_caches(vcpu);
spin_lock(&vcpu->kvm->mmu_lock);
+
+ gentry = mmu_pte_write_fetch_gpte(vcpu, &gpa, &bytes);
+
++vcpu->kvm->stat.mmu_pte_write;
kvm_mmu_audit(vcpu, AUDIT_PRE_PTE_WRITE);
diff --git a/arch/x86/um/sys_call_table_32.c b/arch/x86/um/sys_call_table_32.c
index 439c0994b696..bfce503dffae 100644
--- a/arch/x86/um/sys_call_table_32.c
+++ b/arch/x86/um/sys_call_table_32.c
@@ -25,11 +25,11 @@
#define old_mmap sys_old_mmap
-#define __SYSCALL_I386(nr, sym, compat) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ;
+#define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ;
#include <asm/syscalls_32.h>
#undef __SYSCALL_I386
-#define __SYSCALL_I386(nr, sym, compat) [ nr ] = sym,
+#define __SYSCALL_I386(nr, sym, qual) [ nr ] = sym,
extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
diff --git a/arch/x86/um/sys_call_table_64.c b/arch/x86/um/sys_call_table_64.c
index b74ea6c2c0e7..f306413d3eb6 100644
--- a/arch/x86/um/sys_call_table_64.c
+++ b/arch/x86/um/sys_call_table_64.c
@@ -35,14 +35,11 @@
#define stub_execveat sys_execveat
#define stub_rt_sigreturn sys_rt_sigreturn
-#define __SYSCALL_COMMON(nr, sym, compat) __SYSCALL_64(nr, sym, compat)
-#define __SYSCALL_X32(nr, sym, compat) /* Not supported */
-
-#define __SYSCALL_64(nr, sym, compat) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ;
+#define __SYSCALL_64(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ;
#include <asm/syscalls_64.h>
#undef __SYSCALL_64
-#define __SYSCALL_64(nr, sym, compat) [ nr ] = sym,
+#define __SYSCALL_64(nr, sym, qual) [ nr ] = sym,
extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
diff --git a/arch/x86/um/user-offsets.c b/arch/x86/um/user-offsets.c
index ce7e3607a870..470564bbd08e 100644
--- a/arch/x86/um/user-offsets.c
+++ b/arch/x86/um/user-offsets.c
@@ -9,14 +9,12 @@
#include <asm/types.h>
#ifdef __i386__
-#define __SYSCALL_I386(nr, sym, compat) [nr] = 1,
+#define __SYSCALL_I386(nr, sym, qual) [nr] = 1,
static char syscalls[] = {
#include <asm/syscalls_32.h>
};
#else
-#define __SYSCALL_64(nr, sym, compat) [nr] = 1,
-#define __SYSCALL_COMMON(nr, sym, compat) [nr] = 1,
-#define __SYSCALL_X32(nr, sym, compat) /* Not supported */
+#define __SYSCALL_64(nr, sym, qual) [nr] = 1,
static char syscalls[] = {
#include <asm/syscalls_64.h>
};
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c
index b123ace3b67c..cbefed1800c1 100644
--- a/arch/xtensa/kernel/asm-offsets.c
+++ b/arch/xtensa/kernel/asm-offsets.c
@@ -90,14 +90,14 @@ int main(void)
DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp));
DEFINE(THREAD_CPENABLE, offsetof (struct thread_info, cpenable));
#if XTENSA_HAVE_COPROCESSORS
- DEFINE(THREAD_XTREGS_CP0, offsetof (struct thread_info, xtregs_cp));
- DEFINE(THREAD_XTREGS_CP1, offsetof (struct thread_info, xtregs_cp));
- DEFINE(THREAD_XTREGS_CP2, offsetof (struct thread_info, xtregs_cp));
- DEFINE(THREAD_XTREGS_CP3, offsetof (struct thread_info, xtregs_cp));
- DEFINE(THREAD_XTREGS_CP4, offsetof (struct thread_info, xtregs_cp));
- DEFINE(THREAD_XTREGS_CP5, offsetof (struct thread_info, xtregs_cp));
- DEFINE(THREAD_XTREGS_CP6, offsetof (struct thread_info, xtregs_cp));
- DEFINE(THREAD_XTREGS_CP7, offsetof (struct thread_info, xtregs_cp));
+ DEFINE(THREAD_XTREGS_CP0, offsetof(struct thread_info, xtregs_cp.cp0));
+ DEFINE(THREAD_XTREGS_CP1, offsetof(struct thread_info, xtregs_cp.cp1));
+ DEFINE(THREAD_XTREGS_CP2, offsetof(struct thread_info, xtregs_cp.cp2));
+ DEFINE(THREAD_XTREGS_CP3, offsetof(struct thread_info, xtregs_cp.cp3));
+ DEFINE(THREAD_XTREGS_CP4, offsetof(struct thread_info, xtregs_cp.cp4));
+ DEFINE(THREAD_XTREGS_CP5, offsetof(struct thread_info, xtregs_cp.cp5));
+ DEFINE(THREAD_XTREGS_CP6, offsetof(struct thread_info, xtregs_cp.cp6));
+ DEFINE(THREAD_XTREGS_CP7, offsetof(struct thread_info, xtregs_cp.cp7));
#endif
DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user));
DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t));
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 17a378c15a15..26516094dbd4 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -83,18 +83,21 @@ void coprocessor_release_all(struct thread_info *ti)
void coprocessor_flush_all(struct thread_info *ti)
{
- unsigned long cpenable;
+ unsigned long cpenable, old_cpenable;
int i;
preempt_disable();
+ RSR_CPENABLE(old_cpenable);
cpenable = ti->cpenable;
+ WSR_CPENABLE(cpenable);
for (i = 0; i < XCHAL_CP_MAX; i++) {
if ((cpenable & 1) != 0 && coprocessor_owner[i] == ti)
coprocessor_flush(ti, i);
cpenable >>= 1;
}
+ WSR_CPENABLE(old_cpenable);
preempt_enable();
}
diff --git a/build.config.cuttlefish.aarch64 b/build.config.cuttlefish.aarch64
new file mode 100644
index 000000000000..e36bae42443e
--- /dev/null
+++ b/build.config.cuttlefish.aarch64
@@ -0,0 +1,16 @@
+ARCH=arm64
+BRANCH=android-4.4
+CLANG_TRIPLE=aarch64-linux-gnu-
+CROSS_COMPILE=aarch64-linux-androidkernel-
+DEFCONFIG=cuttlefish_defconfig
+EXTRA_CMDS=''
+KERNEL_DIR=common
+POST_DEFCONFIG_CMDS="check_defconfig"
+CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r346389b/bin
+LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin
+FILES="
+arch/arm64/boot/Image.gz
+vmlinux
+System.map
+"
+STOP_SHIP_TRACEPRINTK=1
diff --git a/build.config.cuttlefish.x86_64 b/build.config.cuttlefish.x86_64
index ce8c226a1db4..0a77fa871e83 100644
--- a/build.config.cuttlefish.x86_64
+++ b/build.config.cuttlefish.x86_64
@@ -6,7 +6,7 @@ DEFCONFIG=x86_64_cuttlefish_defconfig
EXTRA_CMDS=''
KERNEL_DIR=common
POST_DEFCONFIG_CMDS="check_defconfig"
-CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r328903/bin
+CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r346389b/bin
LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin
FILES="
arch/x86/boot/bzImage
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 644b9abcc67f..f22e4abba9b4 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -3138,7 +3138,6 @@ static void binder_transaction(struct binder_proc *proc,
t->buffer = NULL;
goto err_binder_alloc_buf_failed;
}
- t->buffer->allow_user_free = 0;
t->buffer->debug_id = t->debug_id;
t->buffer->transaction = t;
t->buffer->target_node = target_node;
@@ -3634,14 +3633,18 @@ static int binder_thread_write(struct binder_proc *proc,
buffer = binder_alloc_prepare_to_free(&proc->alloc,
data_ptr);
- if (buffer == NULL) {
- binder_user_error("%d:%d BC_FREE_BUFFER u%016llx no match\n",
- proc->pid, thread->pid, (u64)data_ptr);
- break;
- }
- if (!buffer->allow_user_free) {
- binder_user_error("%d:%d BC_FREE_BUFFER u%016llx matched unreturned buffer\n",
- proc->pid, thread->pid, (u64)data_ptr);
+ if (IS_ERR_OR_NULL(buffer)) {
+ if (PTR_ERR(buffer) == -EPERM) {
+ binder_user_error(
+ "%d:%d BC_FREE_BUFFER u%016llx matched unreturned or currently freeing buffer\n",
+ proc->pid, thread->pid,
+ (u64)data_ptr);
+ } else {
+ binder_user_error(
+ "%d:%d BC_FREE_BUFFER u%016llx no match\n",
+ proc->pid, thread->pid,
+ (u64)data_ptr);
+ }
break;
}
binder_debug(BINDER_DEBUG_FREE_BUFFER,
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
index 1d9db2ef26bd..baecb4bf9d9b 100644
--- a/drivers/android/binder_alloc.c
+++ b/drivers/android/binder_alloc.c
@@ -149,14 +149,12 @@ static struct binder_buffer *binder_alloc_prepare_to_free_locked(
else {
/*
* Guard against user threads attempting to
- * free the buffer twice
+ * free the buffer when in use by kernel or
+ * after it's already been freed.
*/
- if (buffer->free_in_progress) {
- pr_err("%d:%d FREE_BUFFER u%016llx user freed buffer twice\n",
- alloc->pid, current->pid, (u64)user_ptr);
- return NULL;
- }
- buffer->free_in_progress = 1;
+ if (!buffer->allow_user_free)
+ return ERR_PTR(-EPERM);
+ buffer->allow_user_free = 0;
return buffer;
}
}
@@ -463,7 +461,7 @@ static struct binder_buffer *binder_alloc_new_buf_locked(
rb_erase(best_fit, &alloc->free_buffers);
buffer->free = 0;
- buffer->free_in_progress = 0;
+ buffer->allow_user_free = 0;
binder_insert_allocated_buffer_locked(alloc, buffer);
binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC,
"%d: binder_alloc_buf size %zd got %pK\n",
diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h
index 9ef64e563856..fb3238c74c8a 100644
--- a/drivers/android/binder_alloc.h
+++ b/drivers/android/binder_alloc.h
@@ -50,8 +50,7 @@ struct binder_buffer {
unsigned free:1;
unsigned allow_user_free:1;
unsigned async_transaction:1;
- unsigned free_in_progress:1;
- unsigned debug_id:28;
+ unsigned debug_id:29;
struct binder_transaction *transaction;
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 24513e5d1e1e..3da8f64444a3 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -55,6 +55,8 @@
#define TZ_PIL_AUTH_QDSP6_PROC 1
#define ADSP_MMAP_HEAP_ADDR 4
#define ADSP_MMAP_REMOTE_HEAP_ADDR 8
+#define ADSP_MMAP_ADD_PAGES 0x1000
+
#define FASTRPC_ENOSUCH 39
#define VMID_SSC_Q6 38
#define VMID_ADSP_Q6 6
@@ -126,6 +128,7 @@ static inline uint64_t buf_num_pages(uint64_t buf, size_t len)
static inline uint64_t buf_page_size(uint32_t size)
{
uint64_t sz = (size + (PAGE_SIZE - 1)) & PAGE_MASK;
+
return sz > PAGE_SIZE ? sz : PAGE_SIZE;
}
@@ -145,10 +148,15 @@ struct fastrpc_file;
struct fastrpc_buf {
struct hlist_node hn;
+ struct hlist_node hn_rem;
struct fastrpc_file *fl;
void *virt;
uint64_t phys;
size_t size;
+ struct dma_attrs attrs;
+ uintptr_t raddr;
+ uint32_t flags;
+ int remote;
};
struct fastrpc_ctx_lst;
@@ -292,9 +300,11 @@ struct fastrpc_file {
struct hlist_node hn;
spinlock_t hlock;
struct hlist_head maps;
- struct hlist_head bufs;
+ struct hlist_head cached_bufs;
+ struct hlist_head remote_bufs;
struct fastrpc_ctx_lst clst;
struct fastrpc_session_ctx *sctx;
+ struct fastrpc_buf *init_mem;
struct fastrpc_session_ctx *secsctx;
uint32_t mode;
uint32_t profile;
@@ -363,10 +373,17 @@ static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache)
return;
if (cache) {
spin_lock(&fl->hlock);
- hlist_add_head(&buf->hn, &fl->bufs);
+ hlist_add_head(&buf->hn, &fl->cached_bufs);
spin_unlock(&fl->hlock);
return;
}
+ if (buf->remote) {
+ spin_lock(&fl->hlock);
+ hlist_del_init(&buf->hn_rem);
+ spin_unlock(&fl->hlock);
+ buf->remote = 0;
+ buf->raddr = 0;
+ }
if (!IS_ERR_OR_NULL(buf->virt)) {
int destVM[1] = {VMID_HLOS};
int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
@@ -380,21 +397,22 @@ static void fastrpc_buf_free(struct fastrpc_buf *buf, int cache)
hyp_assign_phys(buf->phys, buf_page_size(buf->size),
srcVM, 2, destVM, destVMperm, 1);
}
- dma_free_coherent(fl->sctx->smmu.dev, buf->size, buf->virt,
- buf->phys);
+ dma_free_attrs(fl->sctx->smmu.dev, buf->size, buf->virt,
+ buf->phys, (struct dma_attrs *)&buf->attrs);
}
kfree(buf);
}
-static void fastrpc_buf_list_free(struct fastrpc_file *fl)
+static void fastrpc_cached_buf_list_free(struct fastrpc_file *fl)
{
struct fastrpc_buf *buf, *free;
+
do {
struct hlist_node *n;
free = NULL;
spin_lock(&fl->hlock);
- hlist_for_each_entry_safe(buf, n, &fl->bufs, hn) {
+ hlist_for_each_entry_safe(buf, n, &fl->cached_bufs, hn) {
hlist_del_init(&buf->hn);
free = buf;
break;
@@ -405,6 +423,25 @@ static void fastrpc_buf_list_free(struct fastrpc_file *fl)
} while (free);
}
+static void fastrpc_remote_buf_list_free(struct fastrpc_file *fl)
+{
+ struct fastrpc_buf *buf, *free;
+
+ do {
+ struct hlist_node *n;
+
+ free = NULL;
+ spin_lock(&fl->hlock);
+ hlist_for_each_entry_safe(buf, n, &fl->remote_bufs, hn_rem) {
+ free = buf;
+ break;
+ }
+ spin_unlock(&fl->hlock);
+ if (free)
+ fastrpc_buf_free(free, 0);
+ } while (free);
+}
+
static void fastrpc_mmap_add(struct fastrpc_mmap *map)
{
if (map->flags == ADSP_MMAP_HEAP_ADDR ||
@@ -465,23 +502,21 @@ static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd, uintptr_t va,
return -ENOTTY;
}
-static int dma_alloc_memory(phys_addr_t *region_start, size_t size)
+static int dma_alloc_memory(dma_addr_t *region_start, void **vaddr, size_t size,
+ struct dma_attrs *attrs)
{
struct fastrpc_apps *me = &gfa;
- void *vaddr = NULL;
- DEFINE_DMA_ATTRS(attrs);
if (me->dev == NULL) {
pr_err("device adsprpc-mem is not initialized\n");
return -ENODEV;
}
- dma_set_attr(DMA_ATTR_SKIP_ZEROING, &attrs);
- dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
- vaddr = dma_alloc_attrs(me->dev, size, region_start, GFP_KERNEL,
- &attrs);
- if (!vaddr) {
- pr_err("ADSPRPC: Failed to allocate %x remote heap memory\n",
- (unsigned int)size);
+
+ *vaddr = dma_alloc_attrs(me->dev, size, region_start,
+ GFP_KERNEL, attrs);
+ if (IS_ERR_OR_NULL(*vaddr)) {
+ pr_err("adsprpc: %s: %s: dma_alloc_attrs failed for size 0x%zx, returned %pK\n",
+ current->comm, __func__, size, (*vaddr));
return -ENOMEM;
}
return 0;
@@ -617,7 +652,8 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, unsigned attr,
struct fastrpc_channel_ctx *chan = &apps->channel[cid];
struct fastrpc_mmap *map = NULL;
struct dma_attrs attrs;
- phys_addr_t region_start = 0;
+ dma_addr_t region_start = 0;
+ void *region_vaddr = NULL;
unsigned long flags;
int err = 0, vmid;
@@ -635,14 +671,20 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, unsigned attr,
map->attr = attr;
if (mflags == ADSP_MMAP_HEAP_ADDR ||
mflags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
+ DEFINE_DMA_ATTRS(rh_attrs);
+
+ dma_set_attr(DMA_ATTR_SKIP_ZEROING, &rh_attrs);
+ dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &rh_attrs);
+
map->apps = me;
map->fl = NULL;
- VERIFY(err, !dma_alloc_memory(&region_start, len));
+ VERIFY(err, !dma_alloc_memory(&region_start,
+ &region_vaddr, len, &rh_attrs));
if (err)
goto bail;
map->phys = (uintptr_t)region_start;
map->size = len;
- map->va = (uintptr_t)map->phys;
+ map->va = (uintptr_t)region_vaddr;
} else {
VERIFY(err, !IS_ERR_OR_NULL(map->handle =
ion_import_dma_buf(fl->apps->client, fd)));
@@ -741,7 +783,8 @@ bail:
}
static int fastrpc_buf_alloc(struct fastrpc_file *fl, size_t size,
- struct fastrpc_buf **obuf)
+ struct dma_attrs attr, uint32_t rflags,
+ int remote, struct fastrpc_buf **obuf)
{
int err = 0, vmid;
struct fastrpc_buf *buf = NULL, *fr = NULL;
@@ -751,18 +794,20 @@ static int fastrpc_buf_alloc(struct fastrpc_file *fl, size_t size,
if (err)
goto bail;
- /* find the smallest buffer that fits in the cache */
- spin_lock(&fl->hlock);
- hlist_for_each_entry_safe(buf, n, &fl->bufs, hn) {
- if (buf->size >= size && (!fr || fr->size > buf->size))
- fr = buf;
- }
- if (fr)
- hlist_del_init(&fr->hn);
- spin_unlock(&fl->hlock);
- if (fr) {
- *obuf = fr;
- return 0;
+ if (!remote) {
+ /* find the smallest buffer that fits in the cache */
+ spin_lock(&fl->hlock);
+ hlist_for_each_entry_safe(buf, n, &fl->cached_bufs, hn) {
+ if (buf->size >= size && (!fr || fr->size > buf->size))
+ fr = buf;
+ }
+ if (fr)
+ hlist_del_init(&fr->hn);
+ spin_unlock(&fl->hlock);
+ if (fr) {
+ *obuf = fr;
+ return 0;
+ }
}
buf = NULL;
VERIFY(err, NULL != (buf = kzalloc(sizeof(*buf), GFP_KERNEL)));
@@ -773,17 +818,29 @@ static int fastrpc_buf_alloc(struct fastrpc_file *fl, size_t size,
buf->virt = NULL;
buf->phys = 0;
buf->size = size;
- buf->virt = dma_alloc_coherent(fl->sctx->smmu.dev, buf->size,
- (void *)&buf->phys, GFP_KERNEL);
+ memcpy(&buf->attrs, &attr, sizeof(struct dma_attrs));
+ buf->flags = rflags;
+ buf->raddr = 0;
+ buf->remote = 0;
+ buf->virt = dma_alloc_attrs(fl->sctx->smmu.dev, buf->size,
+ (dma_addr_t *)&buf->phys,
+ GFP_KERNEL,
+ (struct dma_attrs *)&buf->attrs);
if (IS_ERR_OR_NULL(buf->virt)) {
/* free cache and retry */
- fastrpc_buf_list_free(fl);
- buf->virt = dma_alloc_coherent(fl->sctx->smmu.dev, buf->size,
- (void *)&buf->phys, GFP_KERNEL);
+ fastrpc_cached_buf_list_free(fl);
+ buf->virt = dma_alloc_attrs(fl->sctx->smmu.dev, buf->size,
+ (dma_addr_t *)&buf->phys,
+ GFP_KERNEL,
+ (struct dma_attrs *)&buf->attrs);
VERIFY(err, !IS_ERR_OR_NULL(buf->virt));
}
- if (err)
+ if (err) {
+ err = -ENOMEM;
+ pr_err("adsprpc: %s: %s: dma_alloc_attrs failed for size 0x%zx\n",
+ current->comm, __func__, size);
goto bail;
+ }
if (fl->sctx->smmu.cb)
buf->phys += ((uint64_t)fl->sctx->smmu.cb << 32);
vmid = fl->apps->channel[fl->cid].vmid;
@@ -799,6 +856,13 @@ static int fastrpc_buf_alloc(struct fastrpc_file *fl, size_t size,
goto bail;
}
+ if (remote) {
+ INIT_HLIST_NODE(&buf->hn_rem);
+ spin_lock(&fl->hlock);
+ hlist_add_head(&buf->hn_rem, &fl->remote_bufs);
+ spin_unlock(&fl->hlock);
+ buf->remote = remote;
+ }
*obuf = buf;
bail:
if (err && buf)
@@ -806,7 +870,6 @@ static int fastrpc_buf_alloc(struct fastrpc_file *fl, size_t size,
return err;
}
-
static int context_restore_interrupted(struct fastrpc_file *fl,
struct fastrpc_ioctl_invoke_attrs *inv,
struct smq_invoke_ctx **po)
@@ -815,6 +878,7 @@ static int context_restore_interrupted(struct fastrpc_file *fl,
struct smq_invoke_ctx *ctx = NULL, *ictx = NULL;
struct hlist_node *n;
struct fastrpc_ioctl_invoke *invoke = &inv->inv;
+
spin_lock(&fl->hlock);
hlist_for_each_entry_safe(ictx, n, &fl->clst.interrupted, hn) {
if (ictx->pid == current->pid) {
@@ -854,6 +918,7 @@ static int context_build_overlap(struct smq_invoke_ctx *ctx)
int outbufs = REMOTE_SCALARS_OUTBUFS(ctx->sc);
int nbufs = inbufs + outbufs;
struct overlap max;
+
for (i = 0; i < nbufs; ++i) {
ctx->overs[i].start = (uintptr_t)lpra[i].buf.pv;
ctx->overs[i].end = ctx->overs[i].start + lpra[i].buf.len;
@@ -1003,12 +1068,13 @@ bail:
static void context_save_interrupted(struct smq_invoke_ctx *ctx)
{
struct fastrpc_ctx_lst *clst = &ctx->fl->clst;
+
spin_lock(&ctx->fl->hlock);
hlist_del_init(&ctx->hn);
hlist_add_head(&ctx->hn, &clst->interrupted);
spin_unlock(&ctx->fl->hlock);
/* free the cache on power collapse */
- fastrpc_buf_list_free(ctx->fl);
+ fastrpc_cached_buf_list_free(ctx->fl);
}
static void context_free(struct smq_invoke_ctx *ctx)
@@ -1044,11 +1110,11 @@ static void context_notify_user(struct smq_invoke_ctx *ctx, int retval)
complete(&ctx->work);
}
-
static void fastrpc_notify_users(struct fastrpc_file *me)
{
struct smq_invoke_ctx *ictx;
struct hlist_node *n;
+
spin_lock(&me->hlock);
hlist_for_each_entry_safe(ictx, n, &me->clst.pending, hn) {
complete(&ictx->work);
@@ -1064,6 +1130,7 @@ static void fastrpc_notify_drivers(struct fastrpc_apps *me, int cid)
{
struct fastrpc_file *fl;
struct hlist_node *n;
+
spin_lock(&me->hlock);
hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
if (fl->cid == cid)
@@ -1072,6 +1139,7 @@ static void fastrpc_notify_drivers(struct fastrpc_apps *me, int cid)
spin_unlock(&me->hlock);
}
+
static void context_list_ctor(struct fastrpc_ctx_lst *me)
{
INIT_HLIST_HEAD(&me->interrupted);
@@ -1083,6 +1151,7 @@ static void fastrpc_context_list_dtor(struct fastrpc_file *fl)
struct fastrpc_ctx_lst *clst = &fl->clst;
struct smq_invoke_ctx *ictx = NULL, *ctxfree;
struct hlist_node *n;
+
do {
ctxfree = NULL;
spin_lock(&fl->hlock);
@@ -1110,10 +1179,12 @@ static void fastrpc_context_list_dtor(struct fastrpc_file *fl)
}
static int fastrpc_file_free(struct fastrpc_file *fl);
+
static void fastrpc_file_list_dtor(struct fastrpc_apps *me)
{
struct fastrpc_file *fl, *free;
struct hlist_node *n;
+
do {
free = NULL;
spin_lock(&me->hlock);
@@ -1187,7 +1258,10 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
/* allocate new buffer */
if (copylen) {
- VERIFY(err, !fastrpc_buf_alloc(ctx->fl, copylen, &ctx->buf));
+ DEFINE_DMA_ATTRS(ctx_attrs);
+
+ err = fastrpc_buf_alloc(ctx->fl, copylen, ctx_attrs,
+ 0, 0, &ctx->buf);
if (err)
goto bail;
}
@@ -1206,6 +1280,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
args = (uintptr_t)ctx->buf->virt + metalen;
for (i = 0; i < bufs; ++i) {
size_t len = lpra[i].buf.len;
+
list[i].num = 0;
list[i].pgidx = 0;
if (!len)
@@ -1220,6 +1295,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
struct fastrpc_mmap *map = ctx->maps[i];
uint64_t buf = ptr_to_uint64(lpra[i].buf.pv);
size_t len = lpra[i].buf.len;
+
rpra[i].buf.pv = 0;
rpra[i].buf.len = len;
if (!len)
@@ -1561,6 +1637,7 @@ static void smd_event_handler(void *priv, unsigned event)
static void fastrpc_init(struct fastrpc_apps *me)
{
int i;
+
INIT_HLIST_HEAD(&me->drivers);
INIT_HLIST_HEAD(&me->maps);
spin_lock_init(&me->hlock);
@@ -1684,6 +1761,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
struct fastrpc_ioctl_init *init = &uproc->init;
struct smq_phy_page pages[1];
struct fastrpc_mmap *file = NULL, *mem = NULL;
+ struct fastrpc_buf *imem = NULL;
char *proc_name = NULL;
int srcVM[1] = {VMID_HLOS};
int destVM[1] = {gcinfo[0].heap_vmid};
@@ -1696,6 +1774,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
if (init->flags == FASTRPC_INIT_ATTACH) {
remote_arg_t ra[1];
int tgid = current->tgid;
+
ra[0].buf.pv = (void *)&tgid;
ra[0].buf.len = sizeof(tgid);
ioctl.inv.handle = 1;
@@ -1712,6 +1791,8 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
remote_arg_t ra[6];
int fds[6];
int mflags = 0;
+ int memlen;
+ DEFINE_DMA_ATTRS(imem_dma_attr);
struct {
int pgid;
unsigned int namelen;
@@ -1734,14 +1815,27 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
if (err)
goto bail;
}
- if (!access_ok(1, (void const __user *)init->mem,
- init->memlen))
- goto bail;
inbuf.pageslen = 1;
- VERIFY(err, !fastrpc_mmap_create(fl, init->memfd, 0,
- init->mem, init->memlen, mflags, &mem));
+
+ VERIFY(err, !init->mem);
+ if (err) {
+ err = -EINVAL;
+ pr_err("adsprpc: %s: %s: ERROR: donated memory allocated in userspace\n",
+ current->comm, __func__);
+ goto bail;
+ }
+ memlen = ALIGN(max(1024*1024*3, (int)init->filelen * 4),
+ 1024*1024);
+
+ dma_set_attr(DMA_ATTR_EXEC_MAPPING, &imem_dma_attr);
+ dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &imem_dma_attr);
+ dma_set_attr(DMA_ATTR_FORCE_NON_COHERENT, &imem_dma_attr);
+
+ err = fastrpc_buf_alloc(fl, memlen, imem_dma_attr, 0, 0, &imem);
if (err)
goto bail;
+ fl->init_mem = imem;
+
inbuf.pageslen = 1;
ra[0].buf.pv = (void *)&inbuf;
ra[0].buf.len = sizeof(inbuf);
@@ -1755,8 +1849,8 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
ra[2].buf.len = inbuf.filelen;
fds[2] = init->filefd;
- pages[0].addr = mem->phys;
- pages[0].size = mem->size;
+ pages[0].addr = imem->phys;
+ pages[0].size = imem->size;
ra[3].buf.pv = (void *)pages;
ra[3].buf.len = 1 * sizeof(*pages);
fds[3] = 0;
@@ -1896,7 +1990,8 @@ bail:
}
static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags,
- struct fastrpc_mmap *map)
+ uintptr_t va, uint64_t phys,
+ size_t size, uintptr_t *raddr)
{
struct fastrpc_ioctl_invoke_attrs ioctl;
struct smq_phy_page page;
@@ -1913,14 +2008,15 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags,
struct {
uintptr_t vaddrout;
} routargs;
+
inargs.pid = current->tgid;
- inargs.vaddrin = (uintptr_t)map->va;
+ inargs.vaddrin = (uintptr_t)va;
inargs.flags = flags;
inargs.num = fl->apps->compat ? num * sizeof(page) : num;
ra[0].buf.pv = (void *)&inargs;
ra[0].buf.len = sizeof(inargs);
- page.addr = map->phys;
- page.size = map->size;
+ page.addr = phys;
+ page.size = size;
ra[1].buf.pv = (void *)&page;
ra[1].buf.len = num * sizeof(page);
@@ -1937,15 +2033,15 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags,
ioctl.attrs = NULL;
VERIFY(err, 0 == (err = fastrpc_internal_invoke(fl,
FASTRPC_MODE_PARALLEL, 1, &ioctl)));
- map->raddr = (uintptr_t)routargs.vaddrout;
+ *raddr = (uintptr_t)routargs.vaddrout;
if (err)
goto bail;
if (flags == ADSP_MMAP_HEAP_ADDR) {
struct scm_desc desc = {0};
desc.args[0] = TZ_PIL_AUTH_QDSP6_PROC;
- desc.args[1] = map->phys;
- desc.args[2] = map->size;
+ desc.args[1] = phys;
+ desc.args[2] = size;
desc.arginfo = SCM_ARGS(3);
err = scm_call2(SCM_SIP_FNID(SCM_SVC_PIL,
TZ_PIL_PROTECT_MEM_SUBSYS_ID), &desc);
@@ -1955,7 +2051,7 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags,
int destVM[1] = {gcinfo[0].heap_vmid};
int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
- VERIFY(err, !hyp_assign_phys(map->phys, (uint64_t)map->size,
+ VERIFY(err, !hyp_assign_phys(phys, (uint64_t)size,
srcVM, 1, destVM, destVMperm, 1));
if (err)
goto bail;
@@ -1964,16 +2060,17 @@ bail:
return err;
}
-static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl,
- struct fastrpc_mmap *map)
+static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl, uint64_t phys,
+ size_t size, uint32_t flags)
{
int err = 0;
int srcVM[1] = {gcinfo[0].heap_vmid};
int destVM[1] = {VMID_HLOS};
int destVMperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
- if (map->flags == ADSP_MMAP_HEAP_ADDR) {
+ if (flags == ADSP_MMAP_HEAP_ADDR) {
struct fastrpc_ioctl_invoke_attrs ioctl;
+
struct scm_desc desc = {0};
remote_arg_t ra[1];
int err = 0;
@@ -1997,14 +2094,14 @@ static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl,
if (err)
goto bail;
desc.args[0] = TZ_PIL_AUTH_QDSP6_PROC;
- desc.args[1] = map->phys;
- desc.args[2] = map->size;
+ desc.args[1] = phys;
+ desc.args[2] = size;
desc.args[3] = routargs.skey;
desc.arginfo = SCM_ARGS(4);
err = scm_call2(SCM_SIP_FNID(SCM_SVC_PIL,
TZ_PIL_CLEAR_PROTECT_MEM_SUBSYS_ID), &desc);
- } else if (map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
- VERIFY(err, !hyp_assign_phys(map->phys, (uint64_t)map->size,
+ } else if (flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
+ VERIFY(err, !hyp_assign_phys(phys, (uint64_t)size,
srcVM, 1, destVM, destVMperm, 1));
if (err)
goto bail;
@@ -2014,8 +2111,8 @@ bail:
return err;
}
-static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl,
- struct fastrpc_mmap *map)
+static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl, uintptr_t raddr,
+ uint64_t phys, size_t size, uint32_t flags)
{
struct fastrpc_ioctl_invoke_attrs ioctl;
remote_arg_t ra[1];
@@ -2027,8 +2124,8 @@ static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl,
} inargs;
inargs.pid = current->tgid;
- inargs.size = map->size;
- inargs.vaddrout = map->raddr;
+ inargs.size = size;
+ inargs.vaddrout = raddr;
ra[0].buf.pv = (void *)&inargs;
ra[0].buf.len = sizeof(inargs);
@@ -2044,9 +2141,9 @@ static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl,
FASTRPC_MODE_PARALLEL, 1, &ioctl)));
if (err)
goto bail;
- if (map->flags == ADSP_MMAP_HEAP_ADDR ||
- map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
- VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, map));
+ if (flags == ADSP_MMAP_HEAP_ADDR ||
+ flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
+ VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, phys, size, flags));
if (err)
goto bail;
}
@@ -2073,7 +2170,8 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl)
spin_unlock(&me->hlock);
if (match) {
- VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, match));
+ VERIFY(err, !fastrpc_munmap_on_dsp_rh(fl, match->phys,
+ match->size, match->flags));
if (err)
goto bail;
if (me->channel[0].ramdumpenabled) {
@@ -2110,12 +2208,37 @@ static int fastrpc_internal_munmap(struct fastrpc_file *fl,
{
int err = 0;
struct fastrpc_mmap *map = NULL;
+ struct fastrpc_buf *rbuf = NULL, *free = NULL;
+ struct hlist_node *n;
mutex_lock(&fl->map_mutex);
+ spin_lock(&fl->hlock);
+ hlist_for_each_entry_safe(rbuf, n, &fl->remote_bufs, hn_rem) {
+ if (rbuf->raddr && (rbuf->flags == ADSP_MMAP_ADD_PAGES)) {
+ if ((rbuf->raddr == ud->vaddrout) &&
+ (rbuf->size == ud->size)) {
+ free = rbuf;
+ break;
+ }
+ }
+ }
+ spin_unlock(&fl->hlock);
+
+ if (free) {
+ VERIFY(err, !fastrpc_munmap_on_dsp(fl, free->raddr,
+ free->phys, free->size, free->flags));
+ if (err)
+ goto bail;
+ fastrpc_buf_free(rbuf, 0);
+ mutex_unlock(&fl->map_mutex);
+ return err;
+ }
+
VERIFY(err, !fastrpc_mmap_remove(fl, ud->vaddrout, ud->size, &map));
if (err)
goto bail;
- VERIFY(err, !fastrpc_munmap_on_dsp(fl, map));
+ VERIFY(err, !fastrpc_munmap_on_dsp(fl, map->raddr,
+ map->phys, map->size, map->flags));
if (err)
goto bail;
fastrpc_mmap_free(map);
@@ -2131,22 +2254,55 @@ static int fastrpc_internal_mmap(struct fastrpc_file *fl,
{
struct fastrpc_mmap *map = NULL;
+ struct fastrpc_buf *rbuf = NULL;
+ uintptr_t raddr = 0;
int err = 0;
mutex_lock(&fl->map_mutex);
- if (!fastrpc_mmap_find(fl, ud->fd, (uintptr_t)ud->vaddrin, ud->size,
- ud->flags, &map)){
- mutex_unlock(&fl->map_mutex);
- return 0;
+
+ if (ud->flags == ADSP_MMAP_ADD_PAGES) {
+ DEFINE_DMA_ATTRS(dma_attr);
+
+ if (ud->vaddrin) {
+ err = -EINVAL;
+ pr_err("adsprpc: %s: %s: ERROR: adding user allocated pages is not supported\n",
+ current->comm, __func__);
+ goto bail;
+ }
+ dma_set_attr(DMA_ATTR_EXEC_MAPPING, &dma_attr);
+ dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &dma_attr);
+ dma_set_attr(DMA_ATTR_FORCE_NON_COHERENT, &dma_attr);
+
+ err = fastrpc_buf_alloc(fl, ud->size, dma_attr, ud->flags,
+ 1, &rbuf);
+ if (err)
+ goto bail;
+ err = fastrpc_mmap_on_dsp(fl, ud->flags, 0,
+ rbuf->phys, rbuf->size, &raddr);
+ if (err)
+ goto bail;
+ rbuf->raddr = raddr;
+ } else {
+ uintptr_t va_to_dsp;
+
+ VERIFY(err, !fastrpc_mmap_create(fl, ud->fd, 0,
+ (uintptr_t)ud->vaddrin, ud->size,
+ ud->flags, &map));
+ if (err)
+ goto bail;
+
+ if (ud->flags == ADSP_MMAP_HEAP_ADDR ||
+ ud->flags == ADSP_MMAP_REMOTE_HEAP_ADDR)
+ va_to_dsp = 0;
+ else
+ va_to_dsp = (uintptr_t)map->va;
+ VERIFY(err, 0 == fastrpc_mmap_on_dsp(fl, ud->flags, va_to_dsp,
+ map->phys, map->size, &raddr));
+ if (err)
+ goto bail;
+ map->raddr = raddr;
}
- VERIFY(err, !fastrpc_mmap_create(fl, ud->fd, 0,
- (uintptr_t)ud->vaddrin, ud->size, ud->flags, &map));
- if (err)
- goto bail;
- VERIFY(err, 0 == fastrpc_mmap_on_dsp(fl, ud->flags, map));
- if (err)
- goto bail;
- ud->vaddrout = map->raddr;
+ ud->vaddrout = raddr;
bail:
if (err && map)
fastrpc_mmap_free(map);
@@ -2321,15 +2477,16 @@ static int fastrpc_file_free(struct fastrpc_file *fl)
spin_unlock(&fl->apps->hlock);
kfree(fl->debug_buf);
- if (!fl->sctx) {
+ if (!fl->sctx)
goto bail;
- }
spin_lock(&fl->hlock);
fl->file_close = 1;
spin_unlock(&fl->hlock);
+ if (!IS_ERR_OR_NULL(fl->init_mem))
+ fastrpc_buf_free(fl->init_mem, 0);
fastrpc_context_list_dtor(fl);
- fastrpc_buf_list_free(fl);
+ fastrpc_cached_buf_list_free(fl);
hlist_for_each_entry_safe(map, n, &fl->maps, hn) {
fastrpc_mmap_free(map);
}
@@ -2341,6 +2498,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl)
if (fl->secsctx)
fastrpc_session_free(&fl->apps->channel[cid], fl->secsctx);
bail:
+ fastrpc_remote_buf_list_free(fl);
mutex_destroy(&fl->map_mutex);
kfree(fl);
return 0;
@@ -2480,7 +2638,6 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
struct fastrpc_apps *me = &gfa;
struct fastrpc_file *fl = filp->private_data;
struct hlist_node *n;
- struct fastrpc_buf *buf = NULL;
struct fastrpc_mmap *map = NULL;
struct fastrpc_mmap *gmaps = NULL;
struct smq_invoke_ctx *ictx = NULL;
@@ -2641,22 +2798,6 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
map->secure, map->attr);
}
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "\n======%s %s %s======\n", title,
- " LIST OF BUFS ", title);
- spin_lock(&fl->hlock);
- len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%-19s|%-19s|%-19s\n",
- "virt", "phys", "size");
- len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
- "%s%s%s%s%s\n", single_line, single_line,
- single_line, single_line, single_line);
- hlist_for_each_entry_safe(buf, n, &fl->bufs, hn) {
- len += scnprintf(fileinfo + len,
- DEBUGFS_SIZE - len,
- "0x%-17p|0x%-17llX|%-19zu\n",
- buf->virt, (uint64_t)buf->phys, buf->size);
- }
- len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"\n%s %s %s\n", title,
" LIST OF PENDING SMQCONTEXTS ", title);
@@ -2800,12 +2941,15 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
context_list_ctor(&fl->clst);
spin_lock_init(&fl->hlock);
INIT_HLIST_HEAD(&fl->maps);
- INIT_HLIST_HEAD(&fl->bufs);
+ INIT_HLIST_HEAD(&fl->cached_bufs);
+ INIT_HLIST_HEAD(&fl->remote_bufs);
INIT_HLIST_NODE(&fl->hn);
fl->tgid = current->tgid;
fl->apps = me;
fl->mode = FASTRPC_MODE_SERIAL;
fl->cid = -1;
+ fl->init_mem = NULL;
+
if (debugfs_file != NULL)
fl->debugfs_file = debugfs_file;
memset(&fl->perf, 0, sizeof(fl->perf));
@@ -2843,6 +2987,30 @@ bail:
return err;
}
+static int fastrpc_internal_control(struct fastrpc_file *fl,
+ struct fastrpc_ioctl_control *cp)
+{
+ int err = 0;
+
+ VERIFY(err, !IS_ERR_OR_NULL(fl) && !IS_ERR_OR_NULL(fl->apps));
+ if (err)
+ goto bail;
+ VERIFY(err, !IS_ERR_OR_NULL(cp));
+ if (err)
+ goto bail;
+
+ switch (cp->req) {
+ case FASTRPC_CONTROL_KALLOC:
+ cp->kalloc.kalloc_support = 1;
+ break;
+ default:
+ err = -ENOTTY;
+ break;
+ }
+bail:
+ return err;
+}
+
static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
unsigned long ioctl_param)
{
@@ -2852,6 +3020,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
struct fastrpc_ioctl_munmap munmap;
struct fastrpc_ioctl_init_attrs init;
struct fastrpc_ioctl_perf perf;
+ struct fastrpc_ioctl_control cp;
} p;
void *param = (char *)ioctl_param;
struct fastrpc_file *fl = (struct fastrpc_file *)file->private_data;
@@ -2967,8 +3136,22 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
if (err)
goto bail;
break;
+ case FASTRPC_IOCTL_CONTROL:
+ K_COPY_FROM_USER(err, 0, &p.cp, param,
+ sizeof(p.cp));
+ if (err)
+ goto bail;
+ VERIFY(err, 0 == (err = fastrpc_internal_control(fl, &p.cp)));
+ if (err)
+ goto bail;
+ if (p.cp.req == FASTRPC_CONTROL_KALLOC) {
+ K_COPY_TO_USER(err, 0, param, &p.cp, sizeof(p.cp));
+ if (err)
+ goto bail;
+ }
+ break;
case FASTRPC_IOCTL_GETINFO:
- K_COPY_FROM_USER(err, 0, &info, param, sizeof(info));
+ K_COPY_FROM_USER(err, 0, &info, param, sizeof(info));
if (err)
goto bail;
VERIFY(err, 0 == (err = fastrpc_get_info(fl, &info)));
@@ -3283,6 +3466,7 @@ static void fastrpc_deinit(void)
}
for (j = 0; j < NUM_SESSIONS; j++) {
struct fastrpc_session_ctx *sess = &chan->session[j];
+
if (sess->smmu.dev) {
arm_iommu_detach_device(sess->smmu.dev);
sess->smmu.dev = NULL;
diff --git a/drivers/char/adsprpc_compat.c b/drivers/char/adsprpc_compat.c
index e1e061748f22..d44ae93d9751 100644
--- a/drivers/char/adsprpc_compat.c
+++ b/drivers/char/adsprpc_compat.c
@@ -36,6 +36,8 @@
_IOWR('R', 9, struct compat_fastrpc_ioctl_perf)
#define COMPAT_FASTRPC_IOCTL_INIT_ATTRS \
_IOWR('R', 10, struct compat_fastrpc_ioctl_init_attrs)
+#define COMPAT_FASTRPC_IOCTL_CONTROL \
+ _IOWR('R', 12, struct compat_fastrpc_ioctl_control)
#define COMPAT_FASTRPC_IOCTL_MMAP_64 \
_IOWR('R', 14, struct compat_fastrpc_ioctl_mmap_64)
#define COMPAT_FASTRPC_IOCTL_MUNMAP_64 \
@@ -117,6 +119,31 @@ struct compat_fastrpc_ioctl_perf { /* kernel performance data */
compat_uptr_t keys;
};
+#define FASTRPC_CONTROL_LATENCY (1)
+struct compat_fastrpc_ctrl_latency {
+ compat_uint_t enable;
+ compat_uint_t level;
+};
+
+#define FASTRPC_CONTROL_SMMU (2)
+struct compat_fastrpc_ctrl_smmu {
+ compat_uint_t sharedcb;
+};
+
+#define FASTRPC_CONTROL_KALLOC (3)
+struct compat_fastrpc_ctrl_kalloc {
+ compat_uint_t kalloc_support; /* Remote memory allocation from kernel */
+};
+
+struct compat_fastrpc_ioctl_control {
+ compat_uint_t req;
+ union {
+ struct compat_fastrpc_ctrl_latency lp;
+ struct compat_fastrpc_ctrl_smmu smmu;
+ struct compat_fastrpc_ctrl_kalloc kalloc;
+ };
+};
+
static int compat_get_fastrpc_ioctl_invoke(
struct compat_fastrpc_ioctl_invoke_attrs __user *inv32,
struct fastrpc_ioctl_invoke_attrs __user **inva,
@@ -322,6 +349,19 @@ static int compat_get_fastrpc_ioctl_perf(
return err;
}
+static int compat_get_fastrpc_ioctl_control(
+ struct compat_fastrpc_ioctl_control __user *ctrl32,
+ struct fastrpc_ioctl_control __user *ctrl)
+{
+ compat_uptr_t p;
+ int err;
+
+ err = get_user(p, &ctrl32->req);
+ err |= put_user(p, &ctrl->req);
+
+ return err;
+}
+
static int compat_get_fastrpc_ioctl_init(
struct compat_fastrpc_ioctl_init_attrs __user *init32,
struct fastrpc_ioctl_init_attrs __user *init,
@@ -513,6 +553,34 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
case FASTRPC_IOCTL_SETMODE:
return filp->f_op->unlocked_ioctl(filp, cmd,
(unsigned long)compat_ptr(arg));
+ case COMPAT_FASTRPC_IOCTL_CONTROL:
+ {
+ struct compat_fastrpc_ioctl_control __user *ctrl32;
+ struct fastrpc_ioctl_control __user *ctrl;
+ compat_uptr_t p;
+
+ ctrl32 = compat_ptr(arg);
+ VERIFY(err, NULL != (ctrl = compat_alloc_user_space(
+ sizeof(*ctrl))));
+ if (err)
+ return -EFAULT;
+ VERIFY(err, 0 == compat_get_fastrpc_ioctl_control(ctrl32,
+ ctrl));
+ if (err)
+ return err;
+ err = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_CONTROL,
+ (unsigned long)ctrl);
+ if (err)
+ return err;
+ err = get_user(p, &ctrl32->req);
+ if (err)
+ return err;
+ if (p == FASTRPC_CONTROL_KALLOC) {
+ err = get_user(p, &ctrl->kalloc.kalloc_support);
+ err |= put_user(p, &ctrl32->kalloc.kalloc_support);
+ }
+ return err;
+ }
case COMPAT_FASTRPC_IOCTL_GETPERF:
{
struct compat_fastrpc_ioctl_perf __user *perf32;
diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h
index a88c668440c7..4371bf6a2ae7 100644
--- a/drivers/char/adsprpc_shared.h
+++ b/drivers/char/adsprpc_shared.h
@@ -29,6 +29,7 @@
#define FASTRPC_IOCTL_GETINFO _IOWR('R', 8, uint32_t)
#define FASTRPC_IOCTL_GETPERF _IOWR('R', 9, struct fastrpc_ioctl_perf)
#define FASTRPC_IOCTL_INIT_ATTRS _IOWR('R', 10, struct fastrpc_ioctl_init_attrs)
+#define FASTRPC_IOCTL_CONTROL _IOWR('R', 12, struct fastrpc_ioctl_control)
#define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp"
#define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp"
@@ -188,7 +189,7 @@ struct fastrpc_ioctl_mmap {
struct fastrpc_ioctl_mmap_64 {
- int fd; /* ion fd */
+ int fd; /* ion fd */
uint32_t flags; /* flags for dsp to map with */
uint64_t vaddrin; /* optional virtual address */
size_t size; /* size */
@@ -201,6 +202,31 @@ struct fastrpc_ioctl_perf { /* kernel performance data */
uintptr_t keys;
};
+#define FASTRPC_CONTROL_LATENCY (1)
+struct fastrpc_ctrl_latency {
+ uint32_t enable; /* latency control enable */
+ uint32_t level; /* level of control */
+};
+
+#define FASTRPC_CONTROL_SMMU (2)
+struct fastrpc_ctrl_smmu {
+ uint32_t sharedcb;
+};
+
+#define FASTRPC_CONTROL_KALLOC (3)
+struct fastrpc_ctrl_kalloc {
+ uint32_t kalloc_support; /* Remote memory allocation from kernel */
+};
+
+struct fastrpc_ioctl_control {
+ uint32_t req;
+ union {
+ struct fastrpc_ctrl_latency lp;
+ struct fastrpc_ctrl_smmu smmu;
+ struct fastrpc_ctrl_kalloc kalloc;
+ };
+};
+
struct smq_null_invoke {
uint64_t ctx; /* invoke caller context */
uint32_t handle; /* handle to invoke */
@@ -245,6 +271,7 @@ static inline struct smq_phy_page *smq_phy_page_start(uint32_t sc,
struct smq_invoke_buf *buf)
{
uint64_t nTotal = REMOTE_SCALARS_INBUFS(sc)+REMOTE_SCALARS_OUTBUFS(sc);
+
return (struct smq_phy_page *)(&buf[nTotal]);
}
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index ef1fa8145419..fa86946d12aa 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -130,8 +130,13 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
/* Ensure the arm clock divider is what we expect */
ret = clk_set_rate(arm_clk, new_freq * 1000);
if (ret) {
+ int ret1;
+
dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);
- regulator_set_voltage_tol(arm_reg, volt_old, 0);
+ ret1 = regulator_set_voltage_tol(arm_reg, volt_old, 0);
+ if (ret1)
+ dev_warn(cpu_dev,
+ "failed to restore vddarm voltage: %d\n", ret1);
return ret;
}
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index be26f625bb3e..941ace052130 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -1781,6 +1781,12 @@ static void atc_free_chan_resources(struct dma_chan *chan)
atchan->descs_allocated = 0;
atchan->status = 0;
+ /*
+ * Free atslave allocated in at_dma_xlate()
+ */
+ kfree(chan->private);
+ chan->private = NULL;
+
dev_vdbg(chan2dev(chan), "free_chan_resources: done\n");
}
@@ -1815,7 +1821,7 @@ static struct dma_chan *at_dma_xlate(struct of_phandle_args *dma_spec,
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
- atslave = devm_kzalloc(&dmac_pdev->dev, sizeof(*atslave), GFP_KERNEL);
+ atslave = kzalloc(sizeof(*atslave), GFP_KERNEL);
if (!atslave)
return NULL;
@@ -2146,6 +2152,8 @@ static int at_dma_remove(struct platform_device *pdev)
struct resource *io;
at_dma_off(atdma);
+ if (pdev->dev.of_node)
+ of_dma_controller_free(pdev->dev.of_node);
dma_async_device_unregister(&atdma->dma_common);
dma_pool_destroy(atdma->memset_pool);
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index 9a32d9dfdd26..011700262824 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -60,8 +60,29 @@ static const struct pci_device_id pciidlist[] = {
MODULE_DEVICE_TABLE(pci, pciidlist);
+static void ast_kick_out_firmware_fb(struct pci_dev *pdev)
+{
+ struct apertures_struct *ap;
+ bool primary = false;
+
+ ap = alloc_apertures(1);
+ if (!ap)
+ return;
+
+ ap->ranges[0].base = pci_resource_start(pdev, 0);
+ ap->ranges[0].size = pci_resource_len(pdev, 0);
+
+#ifdef CONFIG_X86
+ primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
+#endif
+ remove_conflicting_framebuffers(ap, "astdrmfb", primary);
+ kfree(ap);
+}
+
static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
+ ast_kick_out_firmware_fb(pdev);
+
return drm_get_pci_dev(pdev, ent, &driver);
}
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 498a94069e6b..1acebd64fded 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -557,7 +557,8 @@ int ast_driver_unload(struct drm_device *dev)
drm_mode_config_cleanup(dev);
ast_mm_fini(ast);
- pci_iounmap(dev->pdev, ast->ioregs);
+ if (ast->ioregs != ast->regs + AST_IO_MM_OFFSET)
+ pci_iounmap(dev->pdev, ast->ioregs);
pci_iounmap(dev->pdev, ast->regs);
kfree(ast);
return 0;
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 69d19f3304a5..21085f669e21 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -552,6 +552,7 @@ static int ast_crtc_do_set_base(struct drm_crtc *crtc,
}
ast_bo_unreserve(bo);
+ ast_set_offset_reg(crtc);
ast_set_start_address_crt1(crtc, (u32)gpu_addr);
return 0;
@@ -1249,7 +1250,7 @@ static int ast_cursor_move(struct drm_crtc *crtc,
ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, ((y >> 8) & 0x07));
/* dummy write to fire HWC */
- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xCB, 0xFF, 0x00);
+ ast_show_cursor(crtc);
return 0;
}
diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c
index acd38344b302..764094dd30dd 100644
--- a/drivers/gpu/drm/gma500/mdfld_intel_display.c
+++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c
@@ -99,7 +99,7 @@ void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe)
/* Wait for for the pipe enable to take effect. */
for (count = 0; count < COUNT_MAX; count++) {
temp = REG_READ(map->conf);
- if ((temp & PIPEACONF_PIPE_STATE) == 1)
+ if (temp & PIPEACONF_PIPE_STATE)
break;
}
}
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c
index 5f6b93931c35..1bc3d0a926eb 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.c
+++ b/drivers/gpu/drm/msm/sde/sde_connector.c
@@ -17,10 +17,6 @@
#include "sde_connector.h"
#include "sde_backlight.h"
#include "sde_splash.h"
-#include <linux/workqueue.h>
-#include <linux/atomic.h>
-#include <linux/cpu.h>
-#include <linux/device.h>
#define SDE_DEBUG_CONN(c, fmt, ...) SDE_DEBUG("conn%d " fmt,\
(c) ? (c)->base.base.id : -1, ##__VA_ARGS__)
@@ -55,8 +51,6 @@ static const struct drm_prop_enum_list hpd_clock_state[] = {
{SDE_MODE_HPD_OFF, "OFF"},
};
-static struct work_struct cpu_up_work;
-
int sde_connector_get_info(struct drm_connector *connector,
struct msm_display_info *info)
{
@@ -574,25 +568,11 @@ void sde_connector_prepare_fence(struct drm_connector *connector)
sde_fence_prepare(&to_sde_connector(connector)->retire_fence);
}
-static void wake_up_cpu(struct work_struct *work)
-{
- struct device *cpu_dev = NULL;
-
- cpu_dev = get_cpu_device(1);
- if (!cpu_dev) {
- pr_err("Could not get cpu1 device\n");
- return;
- }
- if (!device_online(cpu_dev))
- pr_info("cpu1 is online\n");
-}
-
void sde_connector_complete_commit(struct drm_connector *connector)
{
struct drm_device *dev;
struct msm_drm_private *priv;
struct sde_connector *c_conn;
- static atomic_t cpu_up_scheduled = ATOMIC_INIT(0);
if (!connector) {
SDE_ERROR("invalid connector\n");
@@ -607,8 +587,7 @@ void sde_connector_complete_commit(struct drm_connector *connector)
/*
* After LK totally exits, LK's early splash resource
- * should be released, cpu1 is hot-plugged in case LK's
- * early domain has reserved it.
+ * should be released.
*/
if (sde_splash_get_lk_complete_status(priv->kms)) {
c_conn = to_sde_connector(connector);
@@ -616,11 +595,8 @@ void sde_connector_complete_commit(struct drm_connector *connector)
sde_splash_free_resource(priv->kms, &priv->phandle,
c_conn->connector_type,
c_conn->display);
- if (atomic_add_unless(&cpu_up_scheduled, 1, 1)) {
- INIT_WORK(&cpu_up_work, wake_up_cpu);
- schedule_work(&cpu_up_work);
- }
}
+
}
static int sde_connector_dpms(struct drm_connector *connector,
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 01da32ae5958..86d260e7ca5f 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -1649,7 +1649,7 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc,
*/
if (sde_kms->splash_info.handoff)
sde_kms_info_add_keyint(info, "max_blendstages",
- catalog->max_mixer_blendstages - 1);
+ catalog->max_mixer_blendstages - 2);
else
sde_kms_info_add_keyint(info, "max_blendstages",
catalog->max_mixer_blendstages);
@@ -1995,6 +1995,26 @@ static void _sde_crtc_init_debugfs(struct sde_crtc *sde_crtc,
}
#endif
+void sde_crtc_update_blob_property(struct drm_crtc *crtc,
+ const char *key,
+ int32_t value)
+{
+ struct sde_crtc *sde_crtc;
+ char *kms_info_str = NULL;
+ size_t len;
+
+ sde_crtc = to_sde_crtc(crtc);
+
+ kms_info_str = (char *)msm_property_get_blob(&sde_crtc->property_info,
+ &sde_crtc->blob_info, &len, CRTC_PROP_INFO);
+ if (!kms_info_str) {
+ SDE_ERROR("get crtc property_info failed");
+ return;
+ }
+
+ sde_kms_info_update_keystr(kms_info_str, key, value);
+}
+
/* initialize crtc */
struct drm_crtc *sde_crtc_init(struct drm_device *dev,
struct drm_plane *plane)
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h
index 200073995d43..a1042390b1a9 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.h
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.h
@@ -292,4 +292,13 @@ static inline bool sde_crtc_is_enabled(struct drm_crtc *crtc)
return crtc ? crtc->enabled : false;
}
+/**
+ * sde_crtc_update_blob_property - update blob property of a given crtc
+ * @crtc: Pointer to crtc
+ * @key: Pointer to key string
+ * @value: Signed 32 bit integer value
+ */
+void sde_crtc_update_blob_property(struct drm_crtc *crtc,
+ const char *key,
+ int32_t value);
#endif /* _SDE_CRTC_H_ */
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h
index dee16d119d47..c7355f5bd891 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.h
+++ b/drivers/gpu/drm/msm/sde/sde_kms.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -306,6 +306,16 @@ void sde_kms_info_add_keyint(struct sde_kms_info *info,
int32_t value);
/**
+ * sde_kms_info_update_keystr - update the special string's value.
+ * @info_str: Pointer to source blob str
+ * @key: Pointer to key string
+ * @value: Signed 32-bit integer value
+ */
+void sde_kms_info_update_keystr(char *info_str,
+ const char *key,
+ int32_t value);
+
+/**
* sde_kms_info_add_keystr - add string value to 'sde_kms_info'
* @info: Pointer to sde_kms_info structure
* @key: Pointer to key string
diff --git a/drivers/gpu/drm/msm/sde/sde_kms_utils.c b/drivers/gpu/drm/msm/sde/sde_kms_utils.c
index 30e12c969538..90fd3912eb59 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms_utils.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -41,6 +41,64 @@ void sde_kms_info_add_keyint(struct sde_kms_info *info,
}
}
+void sde_kms_info_update_keystr(char *info_str,
+ const char *key,
+ int32_t value)
+{
+ char *str, *temp, *append_str;
+ uint32_t dst_len = 0, prefix_len = 0;
+ char c;
+ int32_t size = 0;
+
+ if (info_str && key) {
+ str = strnstr(info_str, key, strlen(info_str));
+ if (str) {
+ temp = str + strlen(key);
+ c = *temp;
+ while (c != '\n') {
+ dst_len++;
+ c = *(++temp);
+ }
+ /*
+ * If input key string to update is exactly the last
+ * string in source string, no need to allocate one
+ * memory to store the string after string key. Just
+ * replace the value of the last string.
+ *
+ * If it is not, allocate one new memory to save
+ * the string after string key+"\n". This new allocated
+ * string will be appended to the whole source string
+ * after key value is updated.
+ */
+ size = strlen(str) - strlen(key) - dst_len - 1;
+ if (size > 0) {
+ append_str = kzalloc(size + 1, GFP_KERNEL);
+ if (!append_str) {
+ SDE_ERROR("failed to alloc memory\n");
+ return;
+ }
+ memcpy(append_str,
+ str + strlen(key) + dst_len + 1, size);
+ }
+
+ prefix_len = strlen(info_str) - strlen(str);
+ /* Update string with new value for the string key. */
+ snprintf(info_str + prefix_len,
+ SDE_KMS_INFO_MAX_SIZE - prefix_len,
+ "%s%d\n", key, value);
+
+ /* Append the string save aboved. */
+ if (size > 0 && append_str) {
+ size = prefix_len + strlen(key) + dst_len + 1;
+ snprintf(info_str + size,
+ SDE_KMS_INFO_MAX_SIZE - size,
+ "%s", append_str);
+ kfree(append_str);
+ }
+ }
+ }
+}
+
void sde_kms_info_add_keystr(struct sde_kms_info *info,
const char *key,
const char *value)
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c
index e50577e3eb4b..a35428c93867 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.c
+++ b/drivers/gpu/drm/msm/sde/sde_plane.c
@@ -2732,6 +2732,24 @@ end:
return rc;
}
+void sde_plane_update_blob_property(struct drm_plane *plane,
+ const char *key,
+ int32_t value)
+{
+ char *kms_info_str = NULL;
+ struct sde_plane *sde_plane = to_sde_plane(plane);
+ size_t len;
+
+ kms_info_str = (char *)msm_property_get_blob(&sde_plane->property_info,
+ &sde_plane->blob_info, &len, 0);
+ if (!kms_info_str) {
+ SDE_ERROR("get plane property_info failed\n");
+ return;
+ }
+
+ sde_kms_info_update_keystr(kms_info_str, key, value);
+}
+
/* initialize plane */
struct drm_plane *sde_plane_init(struct drm_device *dev,
uint32_t pipe, bool primary_plane,
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.h b/drivers/gpu/drm/msm/sde/sde_plane.h
index 8ac582643926..c1414e7db74e 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.h
+++ b/drivers/gpu/drm/msm/sde/sde_plane.h
@@ -102,4 +102,13 @@ int sde_plane_wait_input_fence(struct drm_plane *plane, uint32_t wait_ms);
int sde_plane_color_fill(struct drm_plane *plane,
uint32_t color, uint32_t alpha);
+/**
+ * sde_plane_update_blob_property - update plane blob property
+ * @plane: Pointer to DRM plane object
+ * @key: Pointer to key string
+ * @value: Signed 32 bit integer value
+ */
+void sde_plane_update_blob_property(struct drm_plane *plane,
+ const char *key,
+ int32_t value);
#endif /* _SDE_PLANE_H_ */
diff --git a/drivers/gpu/drm/msm/sde/sde_splash.c b/drivers/gpu/drm/msm/sde/sde_splash.c
index 16f9248b7abe..ebb02dba6d5d 100644
--- a/drivers/gpu/drm/msm/sde/sde_splash.c
+++ b/drivers/gpu/drm/msm/sde/sde_splash.c
@@ -14,7 +14,7 @@
#include <linux/of_address.h>
#include <linux/debugfs.h>
#include <linux/memblock.h>
-
+#include <soc/qcom/early_domain.h>
#include "msm_drv.h"
#include "msm_mmu.h"
#include "sde_kms.h"
@@ -26,6 +26,7 @@
#include "dsi_display.h"
#include "sde_hdmi.h"
#include "sde_crtc.h"
+#include "sde_plane.h"
#define MDP_SSPP_TOP0_OFF 0x1000
#define DISP_INTF_SEL 0x004
@@ -65,49 +66,6 @@ static void _sde_splash_free_bootup_memory_to_system(phys_addr_t phys,
free_reserved_page(pfn_to_page(pfn_idx));
}
-static int _sde_splash_parse_dt_get_lk_pool_node(struct drm_device *dev,
- struct sde_splash_info *sinfo)
-{
- struct device_node *parent, *node;
- struct resource r;
- int ret = 0;
-
- if (!sinfo)
- return -EINVAL;
-
- parent = of_find_node_by_path("/reserved-memory");
- if (!parent)
- return -EINVAL;
-
- node = of_find_node_by_name(parent, "lk_pool");
- if (!node) {
- SDE_ERROR("mem reservation for lk_pool is not presented\n");
- ret = -EINVAL;
- goto parent_node_err;
- }
-
- /* find the mode */
- if (of_address_to_resource(node, 0, &r)) {
- ret = -EINVAL;
- goto child_node_err;
- }
-
- sinfo->lk_pool_paddr = (dma_addr_t)r.start;
- sinfo->lk_pool_size = r.end - r.start;
-
- DRM_INFO("lk_pool: addr:%pK, size:%pK\n",
- (void *)sinfo->lk_pool_paddr,
- (void *)sinfo->lk_pool_size);
-
-child_node_err:
- of_node_put(node);
-
-parent_node_err:
- of_node_put(parent);
-
- return ret;
-}
-
static int _sde_splash_parse_dt_get_display_node(struct drm_device *dev,
struct sde_splash_info *sinfo)
{
@@ -182,10 +140,9 @@ error:
return -ENOMEM;
}
-static bool _sde_splash_lk_check(struct sde_hw_intr *intr)
+static bool _sde_splash_lk_check(void)
{
- return (SDE_LK_RUNNING_VALUE == SDE_REG_READ(&intr->hw,
- SCRATCH_REGISTER_1)) ? true : false;
+ return get_early_service_status(EARLY_DISPLAY);
}
/**
@@ -193,10 +150,9 @@ static bool _sde_splash_lk_check(struct sde_hw_intr *intr)
*
* Function to stop early splash in LK.
*/
-static inline void _sde_splash_notify_lk_stop_splash(struct sde_hw_intr *intr)
+static inline void _sde_splash_notify_lk_stop_splash(void)
{
- /* write splash stop signal to scratch register*/
- SDE_REG_WRITE(&intr->hw, SCRATCH_REGISTER_1, SDE_LK_STOP_SPLASH_VALUE);
+ request_early_service_shutdown(EARLY_DISPLAY);
}
static int _sde_splash_gem_new(struct drm_device *dev,
@@ -391,6 +347,28 @@ static bool _sde_splash_validate_commit(struct sde_kms *sde_kms,
return false;
}
+static void _sde_splash_update_property(struct sde_kms *sde_kms)
+{
+ struct drm_device *dev = sde_kms->dev;
+ struct drm_crtc *crtc;
+ struct drm_plane *plane;
+ struct sde_mdss_cfg *catalog = sde_kms->catalog;
+
+ /*
+ * Update plane availability property
+ * after splash handoff is done.
+ */
+ drm_for_each_plane(plane, dev) {
+ sde_plane_update_blob_property(plane,
+ "plane_unavailability=", 0);
+ }
+
+ /* update crtc blend stage property */
+ drm_for_each_crtc(crtc, dev)
+ sde_crtc_update_blob_property(crtc, "max_blendstages=",
+ catalog->max_mixer_blendstages);
+}
+
__ref int sde_splash_init(struct sde_power_handle *phandle, struct msm_kms *kms)
{
struct sde_kms *sde_kms;
@@ -479,12 +457,6 @@ int sde_splash_parse_memory_dt(struct drm_device *dev)
SDE_ERROR("get display node failed\n");
return -EINVAL;
}
-
- if (_sde_splash_parse_dt_get_lk_pool_node(dev, sinfo)) {
- SDE_ERROR("get LK pool node failed\n");
- return -EINVAL;
- }
-
return 0;
}
@@ -758,9 +730,8 @@ bool sde_splash_get_lk_complete_status(struct msm_kms *kms)
if (sde_kms->splash_info.handoff &&
!sde_kms->splash_info.display_splash_enabled &&
- SDE_LK_EXIT_VALUE == SDE_REG_READ(&intr->hw,
- SCRATCH_REGISTER_1)) {
- SDE_DEBUG("LK totoally exits\n");
+ !_sde_splash_lk_check()) {
+ SDE_DEBUG("LK totally exits\n");
return true;
}
@@ -818,10 +789,6 @@ int sde_splash_free_resource(struct msm_kms *kms,
_sde_splash_destroy_splash_node(sinfo);
- /* free lk_pool heap memory */
- _sde_splash_free_bootup_memory_to_system(sinfo->lk_pool_paddr,
- sinfo->lk_pool_size);
-
/* withdraw data bus vote */
sde_power_data_bus_bandwidth_ctrl(phandle,
sde_kms->core_client, false);
@@ -834,6 +801,9 @@ int sde_splash_free_resource(struct msm_kms *kms,
sde_power_resource_enable(phandle,
sde_kms->core_client, false);
+ /* update impacted crtc and plane property by splash */
+ _sde_splash_update_property(sde_kms);
+
/* send uevent to notify user to recycle resource */
_sde_splash_sent_pipe_update_uevent(sde_kms);
@@ -948,8 +918,8 @@ int sde_splash_lk_stop_splash(struct msm_kms *kms,
mutex_lock(&sde_splash_lock);
if (_sde_splash_validate_commit(sde_kms, state) &&
sinfo->display_splash_enabled) {
- if (_sde_splash_lk_check(sde_kms->hw_intr))
- _sde_splash_notify_lk_stop_splash(sde_kms->hw_intr);
+ if (_sde_splash_lk_check())
+ _sde_splash_notify_lk_stop_splash();
sinfo->display_splash_enabled = false;
diff --git a/drivers/gpu/drm/msm/sde/sde_splash.h b/drivers/gpu/drm/msm/sde/sde_splash.h
index c4bb7b08f817..ee94c348e25b 100644
--- a/drivers/gpu/drm/msm/sde/sde_splash.h
+++ b/drivers/gpu/drm/msm/sde/sde_splash.h
@@ -68,12 +68,6 @@ struct sde_splash_info {
/* constructed gem objects for smmu mapping */
struct drm_gem_object **obj;
- /* physical address of lk pool */
- phys_addr_t lk_pool_paddr;
-
- /* memory size of lk pool */
- size_t lk_pool_size;
-
/* enabled statue of displays*/
uint32_t intf_sel_status;
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 0cbc7ceb9a55..1610accfed0b 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -1289,7 +1289,9 @@ u8 iser_check_task_pi_status(struct iscsi_iser_task *iser_task,
IB_MR_CHECK_SIG_STATUS, &mr_status);
if (ret) {
pr_err("ib_check_mr_status failed, ret %d\n", ret);
- goto err;
+ /* Not a lot we can do, return ambiguous guard error */
+ *sector = 0;
+ return 0x1;
}
if (mr_status.fail_status & IB_MR_CHECK_SIG_STATUS) {
@@ -1317,7 +1319,4 @@ u8 iser_check_task_pi_status(struct iscsi_iser_task *iser_task,
}
return 0;
-err:
- /* Not alot we can do here, return ambiguous guard error */
- return 0x1;
}
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 3258baf3282e..f55dcdf99bc5 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -76,18 +76,23 @@
*/
#include <linux/kernel.h>
+#include <linux/input.h>
+#include <linux/rcupdate.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/module.h>
#include <linux/usb/input.h>
+#include <linux/usb/quirks.h>
#define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>"
#define DRIVER_DESC "X-Box pad driver"
-#define XPAD_PKT_LEN 32
+#define XPAD_PKT_LEN 64
-/* xbox d-pads should map to buttons, as is required for DDR pads
- but we map them to axes when possible to simplify things */
+/*
+ * xbox d-pads should map to buttons, as is required for DDR pads
+ * but we map them to axes when possible to simplify things
+ */
#define MAP_DPAD_TO_BUTTONS (1 << 0)
#define MAP_TRIGGERS_TO_BUTTONS (1 << 1)
#define MAP_STICKS_TO_NULL (1 << 2)
@@ -112,6 +117,10 @@ static bool sticks_to_null;
module_param(sticks_to_null, bool, S_IRUGO);
MODULE_PARM_DESC(sticks_to_null, "Do not map sticks at all for unknown pads");
+static bool auto_poweroff = true;
+module_param(auto_poweroff, bool, S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(auto_poweroff, "Power off wireless controllers on suspend");
+
static const struct xpad_device {
u16 idVendor;
u16 idProduct;
@@ -119,43 +128,77 @@ static const struct xpad_device {
u8 mapping;
u8 xtype;
} xpad_device[] = {
+ { 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 },
+ { 0x044f, 0x0f00, "Thrustmaster Wheel", 0, XTYPE_XBOX },
+ { 0x044f, 0x0f03, "Thrustmaster Wheel", 0, XTYPE_XBOX },
+ { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
+ { 0x044f, 0x0f10, "Thrustmaster Modena GT Wheel", 0, XTYPE_XBOX },
+ { 0x044f, 0xb326, "Thrustmaster Gamepad GP XID", 0, XTYPE_XBOX360 },
{ 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", 0, XTYPE_XBOX },
{ 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX },
{ 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX },
+ { 0x045e, 0x0288, "Microsoft Xbox Controller S v2", 0, XTYPE_XBOX },
{ 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX },
{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
- { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
- { 0x045e, 0x02dd, "Microsoft X-Box One pad (Covert Forces)", 0, XTYPE_XBOXONE },
+ { 0x045e, 0x028f, "Microsoft X-Box 360 pad v2", 0, XTYPE_XBOX360 },
{ 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
+ { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
+ { 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE },
+ { 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", 0, XTYPE_XBOXONE },
+ { 0x045e, 0x02ea, "Microsoft X-Box One S pad", 0, XTYPE_XBOXONE },
{ 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
- { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
- { 0x044f, 0xb326, "Thrustmaster Gamepad GP XID", 0, XTYPE_XBOX360 },
{ 0x046d, 0xc21d, "Logitech Gamepad F310", 0, XTYPE_XBOX360 },
{ 0x046d, 0xc21e, "Logitech Gamepad F510", 0, XTYPE_XBOX360 },
{ 0x046d, 0xc21f, "Logitech Gamepad F710", 0, XTYPE_XBOX360 },
{ 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 },
{ 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX },
{ 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX },
+ { 0x046d, 0xca8a, "Logitech Precision Vibration Feedback Wheel", 0, XTYPE_XBOX },
+ { 0x046d, 0xcaa3, "Logitech DriveFx Racing Wheel", 0, XTYPE_XBOX360 },
+ { 0x056e, 0x2004, "Elecom JC-U3613M", 0, XTYPE_XBOX360 },
{ 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX },
{ 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", 0, XTYPE_XBOX },
+ { 0x05fe, 0x3030, "Chic Controller", 0, XTYPE_XBOX },
+ { 0x05fe, 0x3031, "Chic Controller", 0, XTYPE_XBOX },
+ { 0x062a, 0x0020, "Logic3 Xbox GamePad", 0, XTYPE_XBOX },
+ { 0x062a, 0x0033, "Competition Pro Steering Wheel", 0, XTYPE_XBOX },
+ { 0x06a3, 0x0200, "Saitek Racing Wheel", 0, XTYPE_XBOX },
+ { 0x06a3, 0x0201, "Saitek Adrenalin", 0, XTYPE_XBOX },
+ { 0x06a3, 0xf51a, "Saitek P3600", 0, XTYPE_XBOX360 },
+ { 0x0738, 0x4506, "Mad Catz 4506 Wireless Controller", 0, XTYPE_XBOX },
{ 0x0738, 0x4516, "Mad Catz Control Pad", 0, XTYPE_XBOX },
+ { 0x0738, 0x4520, "Mad Catz Control Pad Pro", 0, XTYPE_XBOX },
{ 0x0738, 0x4522, "Mad Catz LumiCON", 0, XTYPE_XBOX },
{ 0x0738, 0x4526, "Mad Catz Control Pad Pro", 0, XTYPE_XBOX },
+ { 0x0738, 0x4530, "Mad Catz Universal MC2 Racing Wheel and Pedals", 0, XTYPE_XBOX },
{ 0x0738, 0x4536, "Mad Catz MicroCON", 0, XTYPE_XBOX },
{ 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
{ 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX },
+ { 0x0738, 0x4586, "Mad Catz MicroCon Wireless Controller", 0, XTYPE_XBOX },
+ { 0x0738, 0x4588, "Mad Catz Blaster", 0, XTYPE_XBOX },
+ { 0x0738, 0x45ff, "Mad Catz Beat Pad (w/ Handle)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
{ 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
{ 0x0738, 0x4718, "Mad Catz Street Fighter IV FightStick SE", 0, XTYPE_XBOX360 },
{ 0x0738, 0x4726, "Mad Catz Xbox 360 Controller", 0, XTYPE_XBOX360 },
{ 0x0738, 0x4728, "Mad Catz Street Fighter IV FightPad", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x0738, 0x4736, "Mad Catz MicroCon Gamepad", 0, XTYPE_XBOX360 },
{ 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
{ 0x0738, 0x4740, "Mad Catz Beat Pad", 0, XTYPE_XBOX360 },
+ { 0x0738, 0x4743, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+ { 0x0738, 0x4758, "Mad Catz Arcade Game Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x0738, 0x4a01, "Mad Catz FightStick TE 2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
{ 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+ { 0x0738, 0x9871, "Mad Catz Portable Drum", 0, XTYPE_XBOX360 },
{ 0x0738, 0xb726, "Mad Catz Xbox controller - MW2", 0, XTYPE_XBOX360 },
+ { 0x0738, 0xb738, "Mad Catz MVC2TE Stick 2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
{ 0x0738, 0xbeef, "Mad Catz JOYTECH NEO SE Advanced GamePad", XTYPE_XBOX360 },
{ 0x0738, 0xcb02, "Saitek Cyborg Rumble Pad - PC/Xbox 360", 0, XTYPE_XBOX360 },
{ 0x0738, 0xcb03, "Saitek P3200 Rumble Pad - PC/Xbox 360", 0, XTYPE_XBOX360 },
+ { 0x0738, 0xcb29, "Saitek Aviator Stick AV8R02", 0, XTYPE_XBOX360 },
{ 0x0738, 0xf738, "Super SFIV FightStick TE S", 0, XTYPE_XBOX360 },
+ { 0x07ff, 0xffff, "Mad Catz GamePad", 0, XTYPE_XBOX360 },
+ { 0x0c12, 0x0005, "Intec wireless", 0, XTYPE_XBOX },
+ { 0x0c12, 0x8801, "Nyko Xbox Controller", 0, XTYPE_XBOX },
{ 0x0c12, 0x8802, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
{ 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", DANCEPAD_MAP_CONFIG, XTYPE_XBOX },
{ 0x0c12, 0x880a, "Pelican Eclipse PL-2023", 0, XTYPE_XBOX },
@@ -163,32 +206,66 @@ static const struct xpad_device {
{ 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX },
{ 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
{ 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX },
+ { 0x0e4c, 0x1103, "Radica Gamester Reflex", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX },
{ 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX },
+ { 0x0e4c, 0x3510, "Radica Gamester", 0, XTYPE_XBOX },
{ 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", 0, XTYPE_XBOX },
{ 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX },
{ 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX },
+ { 0x0e6f, 0x0008, "After Glow Pro Controller", 0, XTYPE_XBOX },
{ 0x0e6f, 0x0105, "HSM3 Xbox360 dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
{ 0x0e6f, 0x0113, "Afterglow AX.1 Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
+ { 0x0e6f, 0x011f, "Rock Candy Gamepad Wired Controller", 0, XTYPE_XBOX360 },
+ { 0x0e6f, 0x0131, "PDP EA Sports Controller", 0, XTYPE_XBOX360 },
+ { 0x0e6f, 0x0133, "Xbox 360 Wired Controller", 0, XTYPE_XBOX360 },
+ { 0x0e6f, 0x0139, "Afterglow Prismatic Wired Controller", 0, XTYPE_XBOXONE },
+ { 0x0e6f, 0x013a, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
+ { 0x0e6f, 0x0146, "Rock Candy Wired Controller for Xbox One", 0, XTYPE_XBOXONE },
+ { 0x0e6f, 0x0147, "PDP Marvel Xbox One Controller", 0, XTYPE_XBOXONE },
+ { 0x0e6f, 0x015c, "PDP Xbox One Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
+ { 0x0e6f, 0x0161, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
+ { 0x0e6f, 0x0162, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
+ { 0x0e6f, 0x0163, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
+ { 0x0e6f, 0x0164, "PDP Battlefield One", 0, XTYPE_XBOXONE },
+ { 0x0e6f, 0x0165, "PDP Titanfall 2", 0, XTYPE_XBOXONE },
{ 0x0e6f, 0x0201, "Pelican PL-3601 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
{ 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
{ 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
+ { 0x0e6f, 0x0246, "Rock Candy Gamepad for Xbox One 2015", 0, XTYPE_XBOXONE },
+ { 0x0e6f, 0x02ab, "PDP Controller for Xbox One", 0, XTYPE_XBOXONE },
+ { 0x0e6f, 0x02a4, "PDP Wired Controller for Xbox One - Stealth Series", 0, XTYPE_XBOXONE },
+ { 0x0e6f, 0x02a6, "PDP Wired Controller for Xbox One - Camo Series", 0, XTYPE_XBOXONE },
{ 0x0e6f, 0x0301, "Logic3 Controller", 0, XTYPE_XBOX360 },
+ { 0x0e6f, 0x0346, "Rock Candy Gamepad for Xbox One 2016", 0, XTYPE_XBOXONE },
{ 0x0e6f, 0x0401, "Logic3 Controller", 0, XTYPE_XBOX360 },
+ { 0x0e6f, 0x0413, "Afterglow AX.1 Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
+ { 0x0e6f, 0x0501, "PDP Xbox 360 Controller", 0, XTYPE_XBOX360 },
+ { 0x0e6f, 0xf900, "PDP Afterglow AX.1", 0, XTYPE_XBOX360 },
{ 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX },
{ 0x0e8f, 0x3008, "Generic xbox control (dealextreme)", 0, XTYPE_XBOX },
{ 0x0f0d, 0x000a, "Hori Co. DOA4 FightStick", 0, XTYPE_XBOX360 },
+ { 0x0f0d, 0x000c, "Hori PadEX Turbo", 0, XTYPE_XBOX360 },
{ 0x0f0d, 0x000d, "Hori Fighting Stick EX2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
{ 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x0f0d, 0x001b, "Hori Real Arcade Pro VX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x0f0d, 0x0063, "Hori Real Arcade Pro Hayabusa (USA) Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
+ { 0x0f0d, 0x0067, "HORIPAD ONE", 0, XTYPE_XBOXONE },
+ { 0x0f0d, 0x0078, "Hori Real Arcade Pro V Kai Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
+ { 0x0f30, 0x010b, "Philips Recoil", 0, XTYPE_XBOX },
{ 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX },
{ 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX },
{ 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", 0, XTYPE_XBOX },
+ { 0x11c9, 0x55f0, "Nacon GC-100XF", 0, XTYPE_XBOX360 },
{ 0x12ab, 0x0004, "Honey Bee Xbox360 dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
{ 0x12ab, 0x0301, "PDP AFTERGLOW AX.1", 0, XTYPE_XBOX360 },
+ { 0x12ab, 0x0303, "Mortal Kombat Klassic FightStick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
{ 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
{ 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", 0, XTYPE_XBOX360 },
{ 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+ { 0x1430, 0xf801, "RedOctane Controller", 0, XTYPE_XBOX360 },
{ 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 },
{ 0x1532, 0x0037, "Razer Sabertooth", 0, XTYPE_XBOX360 },
+ { 0x1532, 0x0a00, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
{ 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE },
{ 0x15e4, 0x3f00, "Power A Mini Pro Elite", 0, XTYPE_XBOX360 },
{ 0x15e4, 0x3f0a, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 },
@@ -196,24 +273,67 @@ static const struct xpad_device {
{ 0x162e, 0xbeef, "Joytech Neo-Se Take2", 0, XTYPE_XBOX360 },
{ 0x1689, 0xfd00, "Razer Onza Tournament Edition", 0, XTYPE_XBOX360 },
{ 0x1689, 0xfd01, "Razer Onza Classic Edition", 0, XTYPE_XBOX360 },
- { 0x24c6, 0x5d04, "Razer Sabertooth", 0, XTYPE_XBOX360 },
+ { 0x1689, 0xfe00, "Razer Sabertooth", 0, XTYPE_XBOX360 },
{ 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 },
{ 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0x0130, "Ion Drum Rocker", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
{ 0x1bad, 0xf016, "Mad Catz Xbox 360 Controller", 0, XTYPE_XBOX360 },
+ { 0x1bad, 0xf018, "Mad Catz Street Fighter IV SE Fighting Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0xf019, "Mad Catz Brawlstick for Xbox 360", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0xf021, "Mad Cats Ghost Recon FS GamePad", 0, XTYPE_XBOX360 },
{ 0x1bad, 0xf023, "MLG Pro Circuit Controller (Xbox)", 0, XTYPE_XBOX360 },
+ { 0x1bad, 0xf025, "Mad Catz Call Of Duty", 0, XTYPE_XBOX360 },
+ { 0x1bad, 0xf027, "Mad Catz FPS Pro", 0, XTYPE_XBOX360 },
{ 0x1bad, 0xf028, "Street Fighter IV FightPad", 0, XTYPE_XBOX360 },
+ { 0x1bad, 0xf02e, "Mad Catz Fightpad", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0xf030, "Mad Catz Xbox 360 MC2 MicroCon Racing Wheel", 0, XTYPE_XBOX360 },
+ { 0x1bad, 0xf036, "Mad Catz MicroCon GamePad Pro", 0, XTYPE_XBOX360 },
{ 0x1bad, 0xf038, "Street Fighter IV FightStick TE", 0, XTYPE_XBOX360 },
+ { 0x1bad, 0xf039, "Mad Catz MvC2 TE", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0xf03a, "Mad Catz SFxT Fightstick Pro", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0xf03d, "Street Fighter IV Arcade Stick TE - Chun Li", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0xf03e, "Mad Catz MLG FightStick TE", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0xf03f, "Mad Catz FightStick SoulCaliber", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0xf042, "Mad Catz FightStick TES+", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0xf080, "Mad Catz FightStick TE2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0xf501, "HoriPad EX2 Turbo", 0, XTYPE_XBOX360 },
+ { 0x1bad, 0xf502, "Hori Real Arcade Pro.VX SA", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0xf503, "Hori Fighting Stick VX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0xf504, "Hori Real Arcade Pro. EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0xf505, "Hori Fighting Stick EX2B", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0xf506, "Hori Real Arcade Pro.EX Premium VLX", 0, XTYPE_XBOX360 },
{ 0x1bad, 0xf900, "Harmonix Xbox 360 Controller", 0, XTYPE_XBOX360 },
{ 0x1bad, 0xf901, "Gamestop Xbox 360 Controller", 0, XTYPE_XBOX360 },
{ 0x1bad, 0xf903, "Tron Xbox 360 controller", 0, XTYPE_XBOX360 },
+ { 0x1bad, 0xf904, "PDP Versus Fighting Pad", 0, XTYPE_XBOX360 },
+ { 0x1bad, 0xf906, "MortalKombat FightStick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x1bad, 0xfa01, "MadCatz GamePad", 0, XTYPE_XBOX360 },
+ { 0x1bad, 0xfd00, "Razer Onza TE", 0, XTYPE_XBOX360 },
+ { 0x1bad, 0xfd01, "Razer Onza", 0, XTYPE_XBOX360 },
{ 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
{ 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 },
{ 0x24c6, 0x5303, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 },
+ { 0x24c6, 0x530a, "Xbox 360 Pro EX Controller", 0, XTYPE_XBOX360 },
+ { 0x24c6, 0x531a, "PowerA Pro Ex", 0, XTYPE_XBOX360 },
+ { 0x24c6, 0x5397, "FUS1ON Tournament Controller", 0, XTYPE_XBOX360 },
+ { 0x24c6, 0x541a, "PowerA Xbox One Mini Wired Controller", 0, XTYPE_XBOXONE },
+ { 0x24c6, 0x542a, "Xbox ONE spectra", 0, XTYPE_XBOXONE },
+ { 0x24c6, 0x543a, "PowerA Xbox One wired controller", 0, XTYPE_XBOXONE },
{ 0x24c6, 0x5500, "Hori XBOX 360 EX 2 with Turbo", 0, XTYPE_XBOX360 },
{ 0x24c6, 0x5501, "Hori Real Arcade Pro VX-SA", 0, XTYPE_XBOX360 },
+ { 0x24c6, 0x5502, "Hori Fighting Stick VX Alt", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x24c6, 0x5503, "Hori Fighting Edge", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
{ 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick", 0, XTYPE_XBOX360 },
+ { 0x24c6, 0x550d, "Hori GEM Xbox controller", 0, XTYPE_XBOX360 },
+ { 0x24c6, 0x550e, "Hori Real Arcade Pro V Kai 360", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x24c6, 0x551a, "PowerA FUSION Pro Controller", 0, XTYPE_XBOXONE },
+ { 0x24c6, 0x561a, "PowerA FUSION Controller", 0, XTYPE_XBOXONE },
+ { 0x24c6, 0x5b00, "ThrustMaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 },
{ 0x24c6, 0x5b02, "Thrustmaster, Inc. GPX Controller", 0, XTYPE_XBOX360 },
{ 0x24c6, 0x5b03, "Thrustmaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 },
+ { 0x24c6, 0x5d04, "Razer Sabertooth", 0, XTYPE_XBOX360 },
+ { 0x24c6, 0xfafe, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
+ { 0x3767, 0x0101, "Fanatec Speedster 3 Forceshock Wheel", 0, XTYPE_XBOX },
{ 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
{ 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
};
@@ -274,15 +394,15 @@ static const signed short xpad_abs_triggers[] = {
* match against vendor id as well. Wired Xbox 360 devices have protocol 1,
* wireless controllers have protocol 129.
*/
-#define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \
+#define XPAD_XBOX360_VENDOR_PROTOCOL(vend, pr) \
.match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \
.idVendor = (vend), \
.bInterfaceClass = USB_CLASS_VENDOR_SPEC, \
.bInterfaceSubClass = 93, \
.bInterfaceProtocol = (pr)
#define XPAD_XBOX360_VENDOR(vend) \
- { XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \
- { XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) }
+ { XPAD_XBOX360_VENDOR_PROTOCOL((vend), 1) }, \
+ { XPAD_XBOX360_VENDOR_PROTOCOL((vend), 129) }
/* The Xbox One controller uses subclass 71 and protocol 208. */
#define XPAD_XBOXONE_VENDOR_PROTOCOL(vend, pr) \
@@ -292,33 +412,134 @@ static const signed short xpad_abs_triggers[] = {
.bInterfaceSubClass = 71, \
.bInterfaceProtocol = (pr)
#define XPAD_XBOXONE_VENDOR(vend) \
- { XPAD_XBOXONE_VENDOR_PROTOCOL(vend, 208) }
+ { XPAD_XBOXONE_VENDOR_PROTOCOL((vend), 208) }
-static struct usb_device_id xpad_table[] = {
+static const struct usb_device_id xpad_table[] = {
{ USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */
+ XPAD_XBOX360_VENDOR(0x0079), /* GPD Win 2 Controller */
XPAD_XBOX360_VENDOR(0x044f), /* Thrustmaster X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */
XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */
XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */
+ XPAD_XBOX360_VENDOR(0x056e), /* Elecom JC-U3613M */
+ XPAD_XBOX360_VENDOR(0x06a3), /* Saitek P3600 */
XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */
{ USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */
+ XPAD_XBOXONE_VENDOR(0x0738), /* Mad Catz FightStick TE 2 */
+ XPAD_XBOX360_VENDOR(0x07ff), /* Mad Catz GamePad */
XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */
+ XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f X-Box One controllers */
+ XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */
+ XPAD_XBOXONE_VENDOR(0x0f0d), /* Hori Controllers */
+ XPAD_XBOX360_VENDOR(0x11c9), /* Nacon GC100XF */
XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */
XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */
- XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */
- XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */
- XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */
- XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */
XPAD_XBOX360_VENDOR(0x1532), /* Razer Sabertooth */
XPAD_XBOXONE_VENDOR(0x1532), /* Razer Wildcat */
XPAD_XBOX360_VENDOR(0x15e4), /* Numark X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x162e), /* Joytech X-Box 360 controllers */
+ XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */
+ XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */
+ XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */
+ XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA Controllers */
{ }
};
MODULE_DEVICE_TABLE(usb, xpad_table);
+struct xboxone_init_packet {
+ u16 idVendor;
+ u16 idProduct;
+ const u8 *data;
+ u8 len;
+};
+
+#define XBOXONE_INIT_PKT(_vid, _pid, _data) \
+ { \
+ .idVendor = (_vid), \
+ .idProduct = (_pid), \
+ .data = (_data), \
+ .len = ARRAY_SIZE(_data), \
+ }
+
+
+/*
+ * This packet is required for all Xbox One pads with 2015
+ * or later firmware installed (or present from the factory).
+ */
+static const u8 xboxone_fw2015_init[] = {
+ 0x05, 0x20, 0x00, 0x01, 0x00
+};
+
+/*
+ * This packet is required for the Titanfall 2 Xbox One pads
+ * (0x0e6f:0x0165) to finish initialization and for Hori pads
+ * (0x0f0d:0x0067) to make the analog sticks work.
+ */
+static const u8 xboxone_hori_init[] = {
+ 0x01, 0x20, 0x00, 0x09, 0x00, 0x04, 0x20, 0x3a,
+ 0x00, 0x00, 0x00, 0x80, 0x00
+};
+
+/*
+ * This packet is required for most (all?) of the PDP pads to start
+ * sending input reports. These pads include: (0x0e6f:0x02ab),
+ * (0x0e6f:0x02a4), (0x0e6f:0x02a6).
+ */
+static const u8 xboxone_pdp_init1[] = {
+ 0x0a, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14
+};
+
+/*
+ * This packet is required for most (all?) of the PDP pads to start
+ * sending input reports. These pads include: (0x0e6f:0x02ab),
+ * (0x0e6f:0x02a4), (0x0e6f:0x02a6).
+ */
+static const u8 xboxone_pdp_init2[] = {
+ 0x06, 0x20, 0x00, 0x02, 0x01, 0x00
+};
+
+/*
+ * A specific rumble packet is required for some PowerA pads to start
+ * sending input reports. One of those pads is (0x24c6:0x543a).
+ */
+static const u8 xboxone_rumblebegin_init[] = {
+ 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
+ 0x1D, 0x1D, 0xFF, 0x00, 0x00
+};
+
+/*
+ * A rumble packet with zero FF intensity will immediately
+ * terminate the rumbling required to init PowerA pads.
+ * This should happen fast enough that the motors don't
+ * spin up to enough speed to actually vibrate the gamepad.
+ */
+static const u8 xboxone_rumbleend_init[] = {
+ 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/*
+ * This specifies the selection of init packets that a gamepad
+ * will be sent on init *and* the order in which they will be
+ * sent. The correct sequence number will be added when the
+ * packet is going to be sent.
+ */
+static const struct xboxone_init_packet xboxone_init_packets[] = {
+ XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init),
+ XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init),
+ XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init),
+ XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init1),
+ XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init2),
+ XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init),
+ XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumblebegin_init),
+ XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumblebegin_init),
+ XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumbleend_init),
+ XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumbleend_init),
+ XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumbleend_init),
+};
+
struct xpad_output_packet {
u8 data[XPAD_PKT_LEN];
u8 len;
@@ -334,23 +555,28 @@ struct xpad_output_packet {
struct usb_xpad {
struct input_dev *dev; /* input device interface */
+ struct input_dev __rcu *x360w_dev;
struct usb_device *udev; /* usb device */
struct usb_interface *intf; /* usb interface */
- int pad_present;
+ bool pad_present;
+ bool input_created;
struct urb *irq_in; /* urb for interrupt in report */
unsigned char *idata; /* input data */
dma_addr_t idata_dma;
struct urb *irq_out; /* urb for interrupt out report */
+ struct usb_anchor irq_out_anchor;
bool irq_out_active; /* we must not use an active URB */
+ u8 odata_serial; /* serial number for xbox one protocol */
unsigned char *odata; /* output data */
dma_addr_t odata_dma;
spinlock_t odata_lock;
struct xpad_output_packet out_packets[XPAD_NUM_OUT_PACKETS];
int last_out_packet;
+ int init_seq;
#if defined(CONFIG_JOYSTICK_XPAD_LEDS)
struct xpad_led *led;
@@ -362,8 +588,13 @@ struct usb_xpad {
int xtype; /* type of xbox device */
int pad_nr; /* the order x360 pads were attached */
const char *name; /* name of the device */
+ struct work_struct work; /* init/remove device from callback */
};
+static int xpad_init_input(struct usb_xpad *xpad);
+static void xpad_deinit_input(struct usb_xpad *xpad);
+static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num);
+
/*
* xpad_process_packet
*
@@ -443,10 +674,12 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
* http://www.free60.org/wiki/Gamepad
*/
-static void xpad360_process_packet(struct usb_xpad *xpad,
+static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
u16 cmd, unsigned char *data)
{
- struct input_dev *dev = xpad->dev;
+ /* valid pad data */
+ if (data[0] != 0x00)
+ return;
/* digital pad */
if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
@@ -514,7 +747,30 @@ static void xpad360_process_packet(struct usb_xpad *xpad,
input_sync(dev);
}
-static void xpad_identify_controller(struct usb_xpad *xpad);
+static void xpad_presence_work(struct work_struct *work)
+{
+ struct usb_xpad *xpad = container_of(work, struct usb_xpad, work);
+ int error;
+
+ if (xpad->pad_present) {
+ error = xpad_init_input(xpad);
+ if (error) {
+ /* complain only, not much else we can do here */
+ dev_err(&xpad->dev->dev,
+ "unable to init device: %d\n", error);
+ } else {
+ rcu_assign_pointer(xpad->x360w_dev, xpad->dev);
+ }
+ } else {
+ RCU_INIT_POINTER(xpad->x360w_dev, NULL);
+ synchronize_rcu();
+ /*
+ * Now that we are sure xpad360w_process_packet is not
+ * using input device we can get rid of it.
+ */
+ xpad_deinit_input(xpad);
+ }
+}
/*
* xpad360w_process_packet
@@ -532,35 +788,61 @@ static void xpad_identify_controller(struct usb_xpad *xpad);
*/
static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
{
+ struct input_dev *dev;
+ bool present;
+
/* Presence change */
if (data[0] & 0x08) {
- if (data[1] & 0x80) {
- xpad->pad_present = 1;
- /*
- * Light up the segment corresponding to
- * controller number.
- */
- xpad_identify_controller(xpad);
- } else
- xpad->pad_present = 0;
+ present = (data[1] & 0x80) != 0;
+
+ if (xpad->pad_present != present) {
+ xpad->pad_present = present;
+ schedule_work(&xpad->work);
+ }
}
/* Valid pad data */
- if (!(data[1] & 0x1))
+ if (data[1] != 0x1)
return;
- xpad360_process_packet(xpad, cmd, &data[4]);
+ rcu_read_lock();
+ dev = rcu_dereference(xpad->x360w_dev);
+ if (dev)
+ xpad360_process_packet(xpad, dev, cmd, &data[4]);
+ rcu_read_unlock();
}
/*
- * xpadone_process_buttons
+ * xpadone_process_packet
*
- * Process a button update packet from an Xbox one controller.
+ * Completes a request by converting the data into events for the
+ * input subsystem. This version is for the Xbox One controller.
+ *
+ * The report format was gleaned from
+ * https://github.com/kylelemons/xbox/blob/master/xbox.go
*/
-static void xpadone_process_buttons(struct usb_xpad *xpad,
- struct input_dev *dev,
- unsigned char *data)
+static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
{
+ struct input_dev *dev = xpad->dev;
+
+ /* the xbox button has its own special report */
+ if (data[0] == 0X07) {
+ /*
+ * The Xbox One S controller requires these reports to be
+ * acked otherwise it continues sending them forever and
+ * won't report further mode button events.
+ */
+ if (data[1] == 0x30)
+ xpadone_ack_mode_report(xpad, data[2]);
+
+ input_report_key(dev, BTN_MODE, data[4] & 0x01);
+ input_sync(dev);
+ return;
+ }
+ /* check invalid packet */
+ else if (data[0] != 0X20)
+ return;
+
/* menu/view buttons */
input_report_key(dev, BTN_START, data[4] & 0x04);
input_report_key(dev, BTN_SELECT, data[4] & 0x08);
@@ -623,34 +905,6 @@ static void xpadone_process_buttons(struct usb_xpad *xpad,
input_sync(dev);
}
-/*
- * xpadone_process_packet
- *
- * Completes a request by converting the data into events for the
- * input subsystem. This version is for the Xbox One controller.
- *
- * The report format was gleaned from
- * https://github.com/kylelemons/xbox/blob/master/xbox.go
- */
-
-static void xpadone_process_packet(struct usb_xpad *xpad,
- u16 cmd, unsigned char *data)
-{
- struct input_dev *dev = xpad->dev;
-
- switch (data[0]) {
- case 0x20:
- xpadone_process_buttons(xpad, dev, data);
- break;
-
- case 0x07:
- /* the xbox button has its own special report */
- input_report_key(dev, BTN_MODE, data[4] & 0x01);
- input_sync(dev);
- break;
- }
-}
-
static void xpad_irq_in(struct urb *urb)
{
struct usb_xpad *xpad = urb->context;
@@ -678,7 +932,7 @@ static void xpad_irq_in(struct urb *urb)
switch (xpad->xtype) {
case XTYPE_XBOX360:
- xpad360_process_packet(xpad, 0, xpad->idata);
+ xpad360_process_packet(xpad, xpad->dev, 0, xpad->idata);
break;
case XTYPE_XBOX360W:
xpad360w_process_packet(xpad, 0, xpad->idata);
@@ -698,11 +952,47 @@ exit:
}
/* Callers must hold xpad->odata_lock spinlock */
+static bool xpad_prepare_next_init_packet(struct usb_xpad *xpad)
+{
+ const struct xboxone_init_packet *init_packet;
+
+ if (xpad->xtype != XTYPE_XBOXONE)
+ return false;
+
+ /* Perform initialization sequence for Xbox One pads that require it */
+ while (xpad->init_seq < ARRAY_SIZE(xboxone_init_packets)) {
+ init_packet = &xboxone_init_packets[xpad->init_seq++];
+
+ if (init_packet->idVendor != 0 &&
+ init_packet->idVendor != xpad->dev->id.vendor)
+ continue;
+
+ if (init_packet->idProduct != 0 &&
+ init_packet->idProduct != xpad->dev->id.product)
+ continue;
+
+ /* This packet applies to our device, so prepare to send it */
+ memcpy(xpad->odata, init_packet->data, init_packet->len);
+ xpad->irq_out->transfer_buffer_length = init_packet->len;
+
+ /* Update packet with current sequence number */
+ xpad->odata[2] = xpad->odata_serial++;
+ return true;
+ }
+
+ return false;
+}
+
+/* Callers must hold xpad->odata_lock spinlock */
static bool xpad_prepare_next_out_packet(struct usb_xpad *xpad)
{
struct xpad_output_packet *pkt, *packet = NULL;
int i;
+ /* We may have init packets to send before we can send user commands */
+ if (xpad_prepare_next_init_packet(xpad))
+ return true;
+
for (i = 0; i < XPAD_NUM_OUT_PACKETS; i++) {
if (++xpad->last_out_packet >= XPAD_NUM_OUT_PACKETS)
xpad->last_out_packet = 0;
@@ -733,11 +1023,13 @@ static int xpad_try_sending_next_out_packet(struct usb_xpad *xpad)
int error;
if (!xpad->irq_out_active && xpad_prepare_next_out_packet(xpad)) {
+ usb_anchor_urb(xpad->irq_out, &xpad->irq_out_anchor);
error = usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
if (error) {
dev_err(&xpad->intf->dev,
"%s - usb_submit_urb failed with result %d\n",
__func__, error);
+ usb_unanchor_urb(xpad->irq_out);
return -EIO;
}
@@ -779,11 +1071,13 @@ static void xpad_irq_out(struct urb *urb)
}
if (xpad->irq_out_active) {
+ usb_anchor_urb(urb, &xpad->irq_out_anchor);
error = usb_submit_urb(urb, GFP_ATOMIC);
if (error) {
dev_err(dev,
"%s - usb_submit_urb failed with result %d\n",
__func__, error);
+ usb_unanchor_urb(urb);
xpad->irq_out_active = false;
}
}
@@ -791,34 +1085,29 @@ static void xpad_irq_out(struct urb *urb)
spin_unlock_irqrestore(&xpad->odata_lock, flags);
}
-static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
+static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad,
+ struct usb_endpoint_descriptor *ep_irq_out)
{
- struct usb_endpoint_descriptor *ep_irq_out;
- int ep_irq_out_idx;
int error;
if (xpad->xtype == XTYPE_UNKNOWN)
return 0;
+ init_usb_anchor(&xpad->irq_out_anchor);
+
xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN,
GFP_KERNEL, &xpad->odata_dma);
- if (!xpad->odata) {
- error = -ENOMEM;
- goto fail1;
- }
+ if (!xpad->odata)
+ return -ENOMEM;
spin_lock_init(&xpad->odata_lock);
xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
if (!xpad->irq_out) {
error = -ENOMEM;
- goto fail2;
+ goto err_free_coherent;
}
- /* Xbox One controller has in/out endpoints swapped. */
- ep_irq_out_idx = xpad->xtype == XTYPE_XBOXONE ? 0 : 1;
- ep_irq_out = &intf->cur_altsetting->endpoint[ep_irq_out_idx].desc;
-
usb_fill_int_urb(xpad->irq_out, xpad->udev,
usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress),
xpad->odata, XPAD_PKT_LEN,
@@ -828,14 +1117,21 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
return 0;
- fail2: usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
- fail1: return error;
+err_free_coherent:
+ usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
+ return error;
}
static void xpad_stop_output(struct usb_xpad *xpad)
{
- if (xpad->xtype != XTYPE_UNKNOWN)
- usb_kill_urb(xpad->irq_out);
+ if (xpad->xtype != XTYPE_UNKNOWN) {
+ if (!usb_wait_anchor_empty_timeout(&xpad->irq_out_anchor,
+ 5000)) {
+ dev_warn(&xpad->intf->dev,
+ "timed out waiting for output URB to complete, killing\n");
+ usb_kill_anchored_urbs(&xpad->irq_out_anchor);
+ }
+ }
}
static void xpad_deinit_output(struct usb_xpad *xpad)
@@ -882,21 +1178,17 @@ static int xpad_inquiry_pad_presence(struct usb_xpad *xpad)
static int xpad_start_xbox_one(struct usb_xpad *xpad)
{
- struct xpad_output_packet *packet =
- &xpad->out_packets[XPAD_OUT_CMD_IDX];
unsigned long flags;
int retval;
spin_lock_irqsave(&xpad->odata_lock, flags);
- /* Xbox one controller needs to be initialized. */
- packet->data[0] = 0x05;
- packet->data[1] = 0x20;
- packet->len = 2;
- packet->pending = true;
-
- /* Reset the sequence so we send out start packet first */
- xpad->last_out_packet = -1;
+ /*
+ * Begin the init sequence by attempting to send a packet.
+ * We will cycle through the init packet sequence before
+ * sending any packets from the output ring.
+ */
+ xpad->init_seq = 0;
retval = xpad_try_sending_next_out_packet(xpad);
spin_unlock_irqrestore(&xpad->odata_lock, flags);
@@ -904,6 +1196,30 @@ static int xpad_start_xbox_one(struct usb_xpad *xpad)
return retval;
}
+static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num)
+{
+ unsigned long flags;
+ struct xpad_output_packet *packet =
+ &xpad->out_packets[XPAD_OUT_CMD_IDX];
+ static const u8 mode_report_ack[] = {
+ 0x01, 0x20, 0x00, 0x09, 0x00, 0x07, 0x20, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ spin_lock_irqsave(&xpad->odata_lock, flags);
+
+ packet->len = sizeof(mode_report_ack);
+ memcpy(packet->data, mode_report_ack, packet->len);
+ packet->data[2] = seq_num;
+ packet->pending = true;
+
+ /* Reset the sequence so we send out the ack now */
+ xpad->last_out_packet = -1;
+ xpad_try_sending_next_out_packet(xpad);
+
+ spin_unlock_irqrestore(&xpad->odata_lock, flags);
+}
+
#ifdef CONFIG_JOYSTICK_XPAD_FF
static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
{
@@ -966,18 +1282,19 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect
case XTYPE_XBOXONE:
packet->data[0] = 0x09; /* activate rumble */
- packet->data[1] = 0x08;
- packet->data[2] = 0x00;
- packet->data[3] = 0x08; /* continuous effect */
- packet->data[4] = 0x00; /* simple rumble mode */
- packet->data[5] = 0x03; /* L and R actuator only */
- packet->data[6] = 0x00; /* TODO: LT actuator */
- packet->data[7] = 0x00; /* TODO: RT actuator */
- packet->data[8] = strong / 256; /* left actuator */
- packet->data[9] = weak / 256; /* right actuator */
- packet->data[10] = 0x80; /* length of pulse */
- packet->data[11] = 0x00; /* stop period of pulse */
- packet->len = 12;
+ packet->data[1] = 0x00;
+ packet->data[2] = xpad->odata_serial++;
+ packet->data[3] = 0x09;
+ packet->data[4] = 0x00;
+ packet->data[5] = 0x0F;
+ packet->data[6] = 0x00;
+ packet->data[7] = 0x00;
+ packet->data[8] = strong / 512; /* left actuator */
+ packet->data[9] = weak / 512; /* right actuator */
+ packet->data[10] = 0xFF; /* on period */
+ packet->data[11] = 0x00; /* off period */
+ packet->data[12] = 0xFF; /* repeat count */
+ packet->len = 13;
packet->pending = true;
break;
@@ -1090,7 +1407,7 @@ static void xpad_send_led_command(struct usb_xpad *xpad, int command)
*/
static void xpad_identify_controller(struct usb_xpad *xpad)
{
- xpad_send_led_command(xpad, (xpad->pad_nr % 4) + 2);
+ led_set_brightness(&xpad->led->led_cdev, (xpad->pad_nr % 4) + 2);
}
static void xpad_led_set(struct led_classdev *led_cdev,
@@ -1127,19 +1444,13 @@ static int xpad_led_probe(struct usb_xpad *xpad)
led_cdev = &led->led_cdev;
led_cdev->name = led->name;
led_cdev->brightness_set = xpad_led_set;
+ led_cdev->flags = LED_CORE_SUSPENDRESUME;
error = led_classdev_register(&xpad->udev->dev, led_cdev);
if (error)
goto err_free_id;
- if (xpad->xtype == XTYPE_XBOX360) {
- /*
- * Light up the segment corresponding to controller
- * number on wired devices. On wireless we'll do that
- * when they respond to "presence" packet.
- */
- xpad_identify_controller(xpad);
- }
+ xpad_identify_controller(xpad);
return 0;
@@ -1164,41 +1475,110 @@ static void xpad_led_disconnect(struct usb_xpad *xpad)
#else
static int xpad_led_probe(struct usb_xpad *xpad) { return 0; }
static void xpad_led_disconnect(struct usb_xpad *xpad) { }
-static void xpad_identify_controller(struct usb_xpad *xpad) { }
#endif
-static int xpad_open(struct input_dev *dev)
+static int xpad_start_input(struct usb_xpad *xpad)
{
- struct usb_xpad *xpad = input_get_drvdata(dev);
-
- /* URB was submitted in probe */
- if (xpad->xtype == XTYPE_XBOX360W)
- return 0;
+ int error;
- xpad->irq_in->dev = xpad->udev;
if (usb_submit_urb(xpad->irq_in, GFP_KERNEL))
return -EIO;
- if (xpad->xtype == XTYPE_XBOXONE)
- return xpad_start_xbox_one(xpad);
+ if (xpad->xtype == XTYPE_XBOXONE) {
+ error = xpad_start_xbox_one(xpad);
+ if (error) {
+ usb_kill_urb(xpad->irq_in);
+ return error;
+ }
+ }
return 0;
}
-static void xpad_close(struct input_dev *dev)
+static void xpad_stop_input(struct usb_xpad *xpad)
{
- struct usb_xpad *xpad = input_get_drvdata(dev);
+ usb_kill_urb(xpad->irq_in);
+}
- if (xpad->xtype != XTYPE_XBOX360W)
+static void xpad360w_poweroff_controller(struct usb_xpad *xpad)
+{
+ unsigned long flags;
+ struct xpad_output_packet *packet =
+ &xpad->out_packets[XPAD_OUT_CMD_IDX];
+
+ spin_lock_irqsave(&xpad->odata_lock, flags);
+
+ packet->data[0] = 0x00;
+ packet->data[1] = 0x00;
+ packet->data[2] = 0x08;
+ packet->data[3] = 0xC0;
+ packet->data[4] = 0x00;
+ packet->data[5] = 0x00;
+ packet->data[6] = 0x00;
+ packet->data[7] = 0x00;
+ packet->data[8] = 0x00;
+ packet->data[9] = 0x00;
+ packet->data[10] = 0x00;
+ packet->data[11] = 0x00;
+ packet->len = 12;
+ packet->pending = true;
+
+ /* Reset the sequence so we send out poweroff now */
+ xpad->last_out_packet = -1;
+ xpad_try_sending_next_out_packet(xpad);
+
+ spin_unlock_irqrestore(&xpad->odata_lock, flags);
+}
+
+static int xpad360w_start_input(struct usb_xpad *xpad)
+{
+ int error;
+
+ error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
+ if (error)
+ return -EIO;
+
+ /*
+ * Send presence packet.
+ * This will force the controller to resend connection packets.
+ * This is useful in the case we activate the module after the
+ * adapter has been plugged in, as it won't automatically
+ * send us info about the controllers.
+ */
+ error = xpad_inquiry_pad_presence(xpad);
+ if (error) {
usb_kill_urb(xpad->irq_in);
+ return error;
+ }
- xpad_stop_output(xpad);
+ return 0;
+}
+
+static void xpad360w_stop_input(struct usb_xpad *xpad)
+{
+ usb_kill_urb(xpad->irq_in);
+
+ /* Make sure we are done with presence work if it was scheduled */
+ flush_work(&xpad->work);
+}
+
+static int xpad_open(struct input_dev *dev)
+{
+ struct usb_xpad *xpad = input_get_drvdata(dev);
+
+ return xpad_start_input(xpad);
+}
+
+static void xpad_close(struct input_dev *dev)
+{
+ struct usb_xpad *xpad = input_get_drvdata(dev);
+
+ xpad_stop_input(xpad);
}
static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
{
struct usb_xpad *xpad = input_get_drvdata(input_dev);
- set_bit(abs, input_dev->absbit);
switch (abs) {
case ABS_X:
@@ -1218,13 +1598,19 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */
input_set_abs_params(input_dev, abs, -1, 1, 0, 0);
break;
+ default:
+ input_set_abs_params(input_dev, abs, 0, 0, 0, 0);
+ break;
}
}
static void xpad_deinit_input(struct usb_xpad *xpad)
{
- xpad_led_disconnect(xpad);
- input_unregister_device(xpad->dev);
+ if (xpad->input_created) {
+ xpad->input_created = false;
+ xpad_led_disconnect(xpad);
+ input_unregister_device(xpad->dev);
+ }
}
static int xpad_init_input(struct usb_xpad *xpad)
@@ -1250,13 +1636,12 @@ static int xpad_init_input(struct usb_xpad *xpad)
input_set_drvdata(input_dev, xpad);
- input_dev->open = xpad_open;
- input_dev->close = xpad_close;
-
- __set_bit(EV_KEY, input_dev->evbit);
+ if (xpad->xtype != XTYPE_XBOX360W) {
+ input_dev->open = xpad_open;
+ input_dev->close = xpad_close;
+ }
if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
- __set_bit(EV_ABS, input_dev->evbit);
/* set up axes */
for (i = 0; xpad_abs[i] >= 0; i++)
xpad_set_up_abs(input_dev, xpad_abs[i]);
@@ -1264,21 +1649,22 @@ static int xpad_init_input(struct usb_xpad *xpad)
/* set up standard buttons */
for (i = 0; xpad_common_btn[i] >= 0; i++)
- __set_bit(xpad_common_btn[i], input_dev->keybit);
+ input_set_capability(input_dev, EV_KEY, xpad_common_btn[i]);
/* set up model-specific ones */
if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W ||
xpad->xtype == XTYPE_XBOXONE) {
for (i = 0; xpad360_btn[i] >= 0; i++)
- __set_bit(xpad360_btn[i], input_dev->keybit);
+ input_set_capability(input_dev, EV_KEY, xpad360_btn[i]);
} else {
for (i = 0; xpad_btn[i] >= 0; i++)
- __set_bit(xpad_btn[i], input_dev->keybit);
+ input_set_capability(input_dev, EV_KEY, xpad_btn[i]);
}
if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
for (i = 0; xpad_btn_pad[i] >= 0; i++)
- __set_bit(xpad_btn_pad[i], input_dev->keybit);
+ input_set_capability(input_dev, EV_KEY,
+ xpad_btn_pad[i]);
}
/*
@@ -1295,7 +1681,8 @@ static int xpad_init_input(struct usb_xpad *xpad)
if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
for (i = 0; xpad_btn_triggers[i] >= 0; i++)
- __set_bit(xpad_btn_triggers[i], input_dev->keybit);
+ input_set_capability(input_dev, EV_KEY,
+ xpad_btn_triggers[i]);
} else {
for (i = 0; xpad_abs_triggers[i] >= 0; i++)
xpad_set_up_abs(input_dev, xpad_abs_triggers[i]);
@@ -1313,6 +1700,7 @@ static int xpad_init_input(struct usb_xpad *xpad)
if (error)
goto err_disconnect_led;
+ xpad->input_created = true;
return 0;
err_disconnect_led:
@@ -1328,8 +1716,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
{
struct usb_device *udev = interface_to_usbdev(intf);
struct usb_xpad *xpad;
- struct usb_endpoint_descriptor *ep_irq_in;
- int ep_irq_in_idx;
+ struct usb_endpoint_descriptor *ep_irq_in, *ep_irq_out;
int i, error;
if (intf->cur_altsetting->desc.bNumEndpoints != 2)
@@ -1366,6 +1753,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
xpad->mapping = xpad_device[i].mapping;
xpad->xtype = xpad_device[i].xtype;
xpad->name = xpad_device[i].name;
+ INIT_WORK(&xpad->work, xpad_presence_work);
if (xpad->xtype == XTYPE_UNKNOWN) {
if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
@@ -1398,13 +1786,28 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
goto err_free_in_urb;
}
- error = xpad_init_output(intf, xpad);
- if (error)
+ ep_irq_in = ep_irq_out = NULL;
+
+ for (i = 0; i < 2; i++) {
+ struct usb_endpoint_descriptor *ep =
+ &intf->cur_altsetting->endpoint[i].desc;
+
+ if (usb_endpoint_xfer_int(ep)) {
+ if (usb_endpoint_dir_in(ep))
+ ep_irq_in = ep;
+ else
+ ep_irq_out = ep;
+ }
+ }
+
+ if (!ep_irq_in || !ep_irq_out) {
+ error = -ENODEV;
goto err_free_in_urb;
+ }
- /* Xbox One controller has in/out endpoints swapped. */
- ep_irq_in_idx = xpad->xtype == XTYPE_XBOXONE ? 1 : 0;
- ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc;
+ error = xpad_init_output(intf, xpad, ep_irq_out);
+ if (error)
+ goto err_free_in_urb;
usb_fill_int_urb(xpad->irq_in, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
@@ -1415,10 +1818,6 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
usb_set_intfdata(intf, xpad);
- error = xpad_init_input(xpad);
- if (error)
- goto err_deinit_output;
-
if (xpad->xtype == XTYPE_XBOX360W) {
/*
* Submit the int URB immediately rather than waiting for open
@@ -1427,28 +1826,24 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
* exactly the message that a controller has arrived that
* we're waiting for.
*/
- xpad->irq_in->dev = xpad->udev;
- error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
+ error = xpad360w_start_input(xpad);
if (error)
- goto err_deinit_input;
-
+ goto err_deinit_output;
/*
- * Send presence packet.
- * This will force the controller to resend connection packets.
- * This is useful in the case we activate the module after the
- * adapter has been plugged in, as it won't automatically
- * send us info about the controllers.
+ * Wireless controllers require RESET_RESUME to work properly
+ * after suspend. Ideally this quirk should be in usb core
+ * quirk list, but we have too many vendors producing these
+ * controllers and we'd need to maintain 2 identical lists
+ * here in this driver and in usb core.
*/
- error = xpad_inquiry_pad_presence(xpad);
+ udev->quirks |= USB_QUIRK_RESET_RESUME;
+ } else {
+ error = xpad_init_input(xpad);
if (error)
- goto err_kill_in_urb;
+ goto err_deinit_output;
}
return 0;
-err_kill_in_urb:
- usb_kill_urb(xpad->irq_in);
-err_deinit_input:
- xpad_deinit_input(xpad);
err_deinit_output:
xpad_deinit_output(xpad);
err_free_in_urb:
@@ -1458,19 +1853,24 @@ err_free_idata:
err_free_mem:
kfree(xpad);
return error;
-
}
static void xpad_disconnect(struct usb_interface *intf)
{
- struct usb_xpad *xpad = usb_get_intfdata (intf);
+ struct usb_xpad *xpad = usb_get_intfdata(intf);
+
+ if (xpad->xtype == XTYPE_XBOX360W)
+ xpad360w_stop_input(xpad);
xpad_deinit_input(xpad);
- xpad_deinit_output(xpad);
- if (xpad->xtype == XTYPE_XBOX360W) {
- usb_kill_urb(xpad->irq_in);
- }
+ /*
+ * Now that both input device and LED device are gone we can
+ * stop output URB.
+ */
+ xpad_stop_output(xpad);
+
+ xpad_deinit_output(xpad);
usb_free_urb(xpad->irq_in);
usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
@@ -1481,10 +1881,72 @@ static void xpad_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
}
+static int xpad_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct usb_xpad *xpad = usb_get_intfdata(intf);
+ struct input_dev *input = xpad->dev;
+
+ if (xpad->xtype == XTYPE_XBOX360W) {
+ /*
+ * Wireless controllers always listen to input so
+ * they are notified when controller shows up
+ * or goes away.
+ */
+ xpad360w_stop_input(xpad);
+
+ /*
+ * The wireless adapter is going off now, so the
+ * gamepads are going to become disconnected.
+ * Unless explicitly disabled, power them down
+ * so they don't just sit there flashing.
+ */
+ if (auto_poweroff && xpad->pad_present)
+ xpad360w_poweroff_controller(xpad);
+ } else {
+ mutex_lock(&input->mutex);
+ if (input->users)
+ xpad_stop_input(xpad);
+ mutex_unlock(&input->mutex);
+ }
+
+ xpad_stop_output(xpad);
+
+ return 0;
+}
+
+static int xpad_resume(struct usb_interface *intf)
+{
+ struct usb_xpad *xpad = usb_get_intfdata(intf);
+ struct input_dev *input = xpad->dev;
+ int retval = 0;
+
+ if (xpad->xtype == XTYPE_XBOX360W) {
+ retval = xpad360w_start_input(xpad);
+ } else {
+ mutex_lock(&input->mutex);
+ if (input->users) {
+ retval = xpad_start_input(xpad);
+ } else if (xpad->xtype == XTYPE_XBOXONE) {
+ /*
+ * Even if there are no users, we'll send Xbox One pads
+ * the startup sequence so they don't sit there and
+ * blink until somebody opens the input device again.
+ */
+ retval = xpad_start_xbox_one(xpad);
+ }
+ mutex_unlock(&input->mutex);
+ }
+
+ return retval;
+}
+
static struct usb_driver xpad_driver = {
.name = "xpad",
.probe = xpad_probe,
.disconnect = xpad_disconnect,
+ .suspend = xpad_suspend,
+ .resume = xpad_resume,
+ .reset_resume = xpad_resume,
.id_table = xpad_table,
};
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 795fa353de7c..c64d87442a62 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -405,7 +405,7 @@ matrix_keypad_parse_dt(struct device *dev)
struct matrix_keypad_platform_data *pdata;
struct device_node *np = dev->of_node;
unsigned int *gpios;
- int i, nrow, ncol;
+ int ret, i, nrow, ncol;
if (!np) {
dev_err(dev, "device lacks DT data\n");
@@ -447,12 +447,19 @@ matrix_keypad_parse_dt(struct device *dev)
return ERR_PTR(-ENOMEM);
}
- for (i = 0; i < pdata->num_row_gpios; i++)
- gpios[i] = of_get_named_gpio(np, "row-gpios", i);
+ for (i = 0; i < nrow; i++) {
+ ret = of_get_named_gpio(np, "row-gpios", i);
+ if (ret < 0)
+ return ERR_PTR(ret);
+ gpios[i] = ret;
+ }
- for (i = 0; i < pdata->num_col_gpios; i++)
- gpios[pdata->num_row_gpios + i] =
- of_get_named_gpio(np, "col-gpios", i);
+ for (i = 0; i < ncol; i++) {
+ ret = of_get_named_gpio(np, "col-gpios", i);
+ if (ret < 0)
+ return ERR_PTR(ret);
+ gpios[nrow + i] = ret;
+ }
pdata->row_gpios = gpios;
pdata->col_gpios = &gpios[pdata->num_row_gpios];
@@ -479,10 +486,8 @@ static int matrix_keypad_probe(struct platform_device *pdev)
pdata = dev_get_platdata(&pdev->dev);
if (!pdata) {
pdata = matrix_keypad_parse_dt(&pdev->dev);
- if (IS_ERR(pdata)) {
- dev_err(&pdev->dev, "no platform data defined\n");
+ if (IS_ERR(pdata))
return PTR_ERR(pdata);
- }
} else if (!pdata->keymap_data) {
dev_err(&pdev->dev, "no keymap data defined\n");
return -EINVAL;
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
index b3119589a444..471984ec2db0 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -1253,6 +1253,9 @@ static const struct acpi_device_id elan_acpi_id[] = {
{ "ELAN0618", 0 },
{ "ELAN061C", 0 },
{ "ELAN061D", 0 },
+ { "ELAN061E", 0 },
+ { "ELAN0620", 0 },
+ { "ELAN0621", 0 },
{ "ELAN0622", 0 },
{ "ELAN1000", 0 },
{ }
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 49b266433f4c..7feaa82f8c7c 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2977,7 +2977,7 @@ static int copy_context_table(struct intel_iommu *iommu,
}
if (old_ce)
- iounmap(old_ce);
+ memunmap(old_ce);
ret = 0;
if (devfn < 0x80)
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index 10068a481e22..cbde03e509c1 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -558,7 +558,7 @@ static irqreturn_t prq_event_thread(int irq, void *d)
pr_err("%s: Page request without PASID: %08llx %08llx\n",
iommu->name, ((unsigned long long *)req)[0],
((unsigned long long *)req)[1]);
- goto bad_req;
+ goto no_pasid;
}
if (!svm || svm->pasid != req->pasid) {
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 624e7ff76166..9101be1a6b59 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -372,6 +372,9 @@ static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain)
static void ipmmu_domain_destroy_context(struct ipmmu_vmsa_domain *domain)
{
+ if (!domain->mmu)
+ return;
+
/*
* Disable the context. Flush the TLB as required when modifying the
* context registers.
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index ba20b8e42fbd..cdb9018c3f02 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -265,12 +265,13 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
up_write(&led_cdev->trigger_lock);
#endif
- cancel_work_sync(&led_cdev->set_brightness_work);
-
/* Stop blinking */
led_stop_software_blink(led_cdev);
+
led_set_brightness(led_cdev, LED_OFF);
+ flush_work(&led_cdev->set_brightness_work);
+
device_unregister(led_cdev->dev);
down_write(&leds_list_lock);
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 5db4515a4fd7..df186b38da78 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -118,8 +118,8 @@ static int create_gpio_led(const struct gpio_led *template,
return ret;
led_dat->gpiod = gpio_to_desc(template->gpio);
- if (IS_ERR(led_dat->gpiod))
- return PTR_ERR(led_dat->gpiod);
+ if (!led_dat->gpiod)
+ return -EINVAL;
}
led_dat->cdev.name = template->name;
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index 1d07e3e83d29..3149dbece146 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -132,6 +132,7 @@ static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
ret = led_classdev_register(dev, &led_data->cdev);
if (ret == 0) {
priv->num_leds++;
+ led_pwm_set(&led_data->cdev, led_data->cdev.brightness);
} else {
dev_err(dev, "failed to register PWM led for %s: %d\n",
led->name, ret);
diff --git a/drivers/media/platform/msm/ais/isp/msm_isp_util.c b/drivers/media/platform/msm/ais/isp/msm_isp_util.c
index 83b3dfe68932..8753592d3dbf 100644
--- a/drivers/media/platform/msm/ais/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/ais/isp/msm_isp_util.c
@@ -24,6 +24,7 @@
#define CREATE_TRACE_POINTS
#include "trace/events/msm_cam.h"
#include "sensor/cci/msm_early_cam.h"
+#include <soc/qcom/early_domain.h>
#define MAX_ISP_V4l2_EVENTS 100
#define MAX_ISP_REG_LIST 100
@@ -2292,6 +2293,8 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
vfe_dev->isp_raw2_debug = 0;
/* Postpone hardware changes until early camera is complete */
+ /* Signal LK early camera that Kernel started running AIS */
+ request_early_service_shutdown(EARLY_CAMERA);
msm_early_camera_wait();
if (vfe_dev->hw_info->vfe_ops.core_ops.init_hw(vfe_dev) < 0) {
diff --git a/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c b/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c
index 1329511440c4..7329dd9ddb27 100644
--- a/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c
+++ b/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c
@@ -17,7 +17,7 @@
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_platform.h>
-#include <linux/iopoll.h>
+#include <soc/qcom/early_domain.h>
#include "msm_sd.h"
#include "msm_early_cam.h"
#include "msm_cam_cci_hwreg.h"
@@ -39,12 +39,6 @@
static struct platform_driver msm_early_camera_driver;
static struct early_cam_device *new_early_cam_dev;
-#define MMSS_A_VFE_0_BASE 0x00A10000
-#define MMSS_A_VFE_0_SIZE 0x1000
-#define EARLY_CAMERA_SIGNAL_DONE 0xa5a5a5a5
-#define EARLY_CAMERA_SIGNAL_DISABLED 0
-#define MMSS_A_VFE_0_SPARE 0xC84
-
int msm_early_cam_disable_clocks(void)
{
int rc = 0;
@@ -263,14 +257,11 @@ int msm_ais_disable_clocks(void)
void msm_early_camera_wait(void)
{
- u32 val = 0;
- void __iomem *base;
-
- base = ioremap(MMSS_A_VFE_0_BASE, MMSS_A_VFE_0_SIZE);
- readl_poll_timeout(base + MMSS_A_VFE_0_SPARE, val,
- ((val == EARLY_CAMERA_SIGNAL_DONE)
- || (val == EARLY_CAMERA_SIGNAL_DISABLED)), 0, 0);
- iounmap(base);
+ while (get_early_service_status(EARLY_CAMERA)) {
+ CDBG("%s: wait for signal of early camera from LK",
+ __func__);
+ msleep(500);
+ }
}
static int msm_early_cam_probe(struct platform_device *pdev)
diff --git a/drivers/media/platform/msm/camera_v2/sensor/laser_led/msm_laser_led.c b/drivers/media/platform/msm/camera_v2/sensor/laser_led/msm_laser_led.c
index c368f081f97b..68d3c71601eb 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/laser_led/msm_laser_led.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/laser_led/msm_laser_led.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -70,18 +70,15 @@ static struct msm_camera_i2c_fn_t msm_sensor_cci_func_tbl = {
.i2c_util = msm_sensor_cci_i2c_util,
.i2c_poll = msm_camera_cci_i2c_poll,
};
-#ifdef CONFIG_COMPAT
-static int32_t msm_laser_led_init(
- struct msm_laser_led_ctrl_t *laser_led_ctrl,
- struct msm_laser_led_cfg_data_t32 __user *laser_led_data)
-#else
+
static int32_t msm_laser_led_init(
struct msm_laser_led_ctrl_t *laser_led_ctrl,
- struct msm_laser_led_cfg_data_t __user *laser_led_data)
-#endif
+ void __user *argp)
{
int32_t rc = -EFAULT;
struct msm_camera_cci_client *cci_client = NULL;
+ struct msm_laser_led_cfg_data_t __user *laser_led_data =
+ (struct msm_laser_led_cfg_data_t __user *) argp;
CDBG("Enter\n");
@@ -263,6 +260,53 @@ static int32_t msm_laser_led_control32(
return rc;
}
+
+static int32_t msm_laser_led_init32(
+ struct msm_laser_led_ctrl_t *laser_led_ctrl,
+ void __user *argp)
+{
+ int32_t rc = -EFAULT;
+ struct msm_laser_led_cfg_data_t32 __user *laser_led_data =
+ (struct msm_laser_led_cfg_data_t32 __user *) argp;
+ struct msm_camera_cci_client *cci_client = NULL;
+
+ CDBG("Enter\n");
+
+ if (laser_led_ctrl->laser_led_state == MSM_CAMERA_LASER_LED_INIT) {
+ pr_err("Invalid laser_led state = %d\n",
+ laser_led_ctrl->laser_led_state);
+ return 0;
+ }
+
+ rc = laser_led_ctrl->i2c_client.i2c_func_tbl->i2c_util(
+ &laser_led_ctrl->i2c_client, MSM_CCI_INIT);
+ if (rc < 0)
+ pr_err("cci_init failed\n");
+
+ cci_client = laser_led_ctrl->i2c_client.cci_client;
+
+ if (copy_from_user(&(cci_client->sid),
+ &(laser_led_data->i2c_addr),
+ sizeof(uint16_t))) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ return -EFAULT;
+ }
+ cci_client->sid = cci_client->sid >> 1;
+ cci_client->retries = 3;
+ cci_client->id_map = 0;
+
+ if (copy_from_user(&(cci_client->i2c_freq_mode),
+ &(laser_led_data->i2c_freq_mode),
+ sizeof(enum i2c_freq_mode_t))) {
+ pr_err("%s:%d failed\n", __func__, __LINE__);
+ return -EFAULT;
+ }
+
+ laser_led_ctrl->laser_led_state = MSM_CAMERA_LASER_LED_INIT;
+
+ CDBG("Exit\n");
+ return 0;
+}
#endif
static int32_t msm_laser_led_control(
@@ -381,7 +425,12 @@ static int32_t msm_laser_led_config(struct msm_laser_led_ctrl_t *laser_led_ctrl,
switch (cfg_type) {
case CFG_LASER_LED_INIT:
- rc = msm_laser_led_init(laser_led_ctrl, laser_led_data);
+#ifdef CONFIG_COMPAT
+ if (is_compat_task())
+ rc = msm_laser_led_init32(laser_led_ctrl, argp);
+ else
+#endif
+ rc = msm_laser_led_init(laser_led_ctrl, argp);
break;
case CFG_LASER_LED_CONTROL:
#ifdef CONFIG_COMPAT
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index 357be76c7a55..5502a0fb94fd 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -1806,6 +1806,8 @@ static int em28xx_dvb_fini(struct em28xx *dev)
}
}
+ em28xx_unregister_dvb(dvb);
+
/* remove I2C SEC */
client = dvb->i2c_client_sec;
if (client) {
@@ -1827,7 +1829,6 @@ static int em28xx_dvb_fini(struct em28xx *dev)
i2c_unregister_device(client);
}
- em28xx_unregister_dvb(dvb);
kfree(dvb);
dev->dvb = NULL;
kref_put(&dev->ref, em28xx_free_device);
diff --git a/drivers/misc/mic/scif/scif_rma.c b/drivers/misc/mic/scif/scif_rma.c
index 6a451bd65bf3..8bd63128d536 100644
--- a/drivers/misc/mic/scif/scif_rma.c
+++ b/drivers/misc/mic/scif/scif_rma.c
@@ -414,7 +414,7 @@ static int scif_create_remote_lookup(struct scif_dev *remote_dev,
if (err)
goto error_window;
err = scif_map_page(&window->num_pages_lookup.lookup[j],
- vmalloc_dma_phys ?
+ vmalloc_num_pages ?
vmalloc_to_page(&window->num_pages[i]) :
virt_to_page(&window->num_pages[i]),
remote_dev);
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index eab132778e67..1dbee1cb3df9 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -423,6 +423,34 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
}
EXPORT_SYMBOL_GPL(can_put_echo_skb);
+struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr)
+{
+ struct can_priv *priv = netdev_priv(dev);
+ struct sk_buff *skb = priv->echo_skb[idx];
+ struct canfd_frame *cf;
+
+ if (idx >= priv->echo_skb_max) {
+ netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
+ __func__, idx, priv->echo_skb_max);
+ return NULL;
+ }
+
+ if (!skb) {
+ netdev_err(dev, "%s: BUG! Trying to echo non existing skb: can_priv::echo_skb[%u]\n",
+ __func__, idx);
+ return NULL;
+ }
+
+ /* Using "struct canfd_frame::len" for the frame
+ * length is supported on both CAN and CANFD frames.
+ */
+ cf = (struct canfd_frame *)skb->data;
+ *len_ptr = cf->len;
+ priv->echo_skb[idx] = NULL;
+
+ return skb;
+}
+
/*
* Get the skb from the stack and loop it back locally
*
@@ -432,22 +460,16 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb);
*/
unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
{
- struct can_priv *priv = netdev_priv(dev);
-
- BUG_ON(idx >= priv->echo_skb_max);
-
- if (priv->echo_skb[idx]) {
- struct sk_buff *skb = priv->echo_skb[idx];
- struct can_frame *cf = (struct can_frame *)skb->data;
- u8 dlc = cf->can_dlc;
+ struct sk_buff *skb;
+ u8 len;
- netif_rx(priv->echo_skb[idx]);
- priv->echo_skb[idx] = NULL;
+ skb = __can_get_echo_skb(dev, idx, &len);
+ if (!skb)
+ return 0;
- return dlc;
- }
+ netif_rx(skb);
- return 0;
+ return len;
}
EXPORT_SYMBOL_GPL(can_get_echo_skb);
diff --git a/drivers/net/can/rcar_can.c b/drivers/net/can/rcar_can.c
index bc46be39549d..9d93492ddfcc 100644
--- a/drivers/net/can/rcar_can.c
+++ b/drivers/net/can/rcar_can.c
@@ -24,6 +24,9 @@
#define RCAR_CAN_DRV_NAME "rcar_can"
+#define RCAR_SUPPORTED_CLOCKS (BIT(CLKR_CLKP1) | BIT(CLKR_CLKP2) | \
+ BIT(CLKR_CLKEXT))
+
/* Mailbox configuration:
* mailbox 60 - 63 - Rx FIFO mailboxes
* mailbox 56 - 59 - Tx FIFO mailboxes
@@ -789,7 +792,7 @@ static int rcar_can_probe(struct platform_device *pdev)
goto fail_clk;
}
- if (clock_select >= ARRAY_SIZE(clock_names)) {
+ if (!(BIT(clock_select) & RCAR_SUPPORTED_CLOCKS)) {
err = -EINVAL;
dev_err(&pdev->dev, "invalid CAN clock selected\n");
goto fail_clk;
diff --git a/drivers/net/ethernet/amd/sunlance.c b/drivers/net/ethernet/amd/sunlance.c
index 7847638bdd22..8914170fccff 100644
--- a/drivers/net/ethernet/amd/sunlance.c
+++ b/drivers/net/ethernet/amd/sunlance.c
@@ -1419,7 +1419,7 @@ static int sparc_lance_probe_one(struct platform_device *op,
prop = of_get_property(nd, "tpe-link-test?", NULL);
if (!prop)
- goto no_link_test;
+ goto node_put;
if (strcmp(prop, "true")) {
printk(KERN_NOTICE "SunLance: warning: overriding option "
@@ -1428,6 +1428,8 @@ static int sparc_lance_probe_one(struct platform_device *op,
"to ecd@skynet.be\n");
auxio_set_lte(AUXIO_LTE_ON);
}
+node_put:
+ of_node_put(nd);
no_link_test:
lp->auto_select = 1;
lp->tpe = 0;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 1ea068815419..2491cdc2535c 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -2291,6 +2291,13 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id,
#define PMF_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \
E1HVN_MAX)
+/* Following is the DMAE channel number allocation for the clients.
+ * MFW: OCBB/OCSD implementations use DMAE channels 14/15 respectively.
+ * Driver: 0-3 and 8-11 (for PF dmae operations)
+ * 4 and 12 (for stats requests)
+ */
+#define BNX2X_FW_DMAE_C 13 /* Channel for FW DMAE operations */
+
/* PCIE link and speed */
#define PCICFG_LINK_WIDTH 0x1f00000
#define PCICFG_LINK_WIDTH_SHIFT 20
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
index ff702a707a91..343e3366d751 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
@@ -5931,6 +5931,7 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp,
rdata->sd_vlan_tag = cpu_to_le16(start_params->sd_vlan_tag);
rdata->path_id = BP_PATH(bp);
rdata->network_cos_mode = start_params->network_cos_mode;
+ rdata->dmae_cmd_id = BNX2X_FW_DMAE_C;
rdata->vxlan_dst_port = cpu_to_le16(start_params->vxlan_dst_port);
rdata->geneve_dst_port = cpu_to_le16(start_params->geneve_dst_port);
diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c
index 4c73feca4842..0565efad6e6e 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -491,7 +491,7 @@ static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
if (!compat)
return -ENOMEM;
- priv->mdio_dn = of_find_compatible_node(dn, NULL, compat);
+ priv->mdio_dn = of_get_compatible_child(dn, compat);
kfree(compat);
if (!priv->mdio_dn) {
dev_err(kdev, "unable to find MDIO bus node\n");
diff --git a/drivers/net/ethernet/faraday/ftmac100.c b/drivers/net/ethernet/faraday/ftmac100.c
index dce5f7b7f772..05e1f923f49e 100644
--- a/drivers/net/ethernet/faraday/ftmac100.c
+++ b/drivers/net/ethernet/faraday/ftmac100.c
@@ -865,11 +865,10 @@ static irqreturn_t ftmac100_interrupt(int irq, void *dev_id)
struct net_device *netdev = dev_id;
struct ftmac100 *priv = netdev_priv(netdev);
- if (likely(netif_running(netdev))) {
- /* Disable interrupts for polling */
- ftmac100_disable_all_int(priv);
+ /* Disable interrupts for polling */
+ ftmac100_disable_all_int(priv);
+ if (likely(netif_running(netdev)))
napi_schedule(&priv->napi);
- }
return IRQ_HANDLED;
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/alloc.c b/drivers/net/ethernet/mellanox/mlx4/alloc.c
index 0c51c69f802f..a4912b11e54f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/alloc.c
+++ b/drivers/net/ethernet/mellanox/mlx4/alloc.c
@@ -339,7 +339,7 @@ void mlx4_zone_allocator_destroy(struct mlx4_zone_allocator *zone_alloc)
static u32 __mlx4_alloc_from_zone(struct mlx4_zone_entry *zone, int count,
int align, u32 skip_mask, u32 *puid)
{
- u32 uid;
+ u32 uid = 0;
u32 res;
struct mlx4_zone_allocator *zone_alloc = zone->allocator;
struct mlx4_zone_entry *curr_node;
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index f5fdbd53d052..db40387ffaf6 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -537,8 +537,8 @@ struct slave_list {
struct resource_allocator {
spinlock_t alloc_lock; /* protect quotas */
union {
- int res_reserved;
- int res_port_rsvd[MLX4_MAX_PORTS];
+ unsigned int res_reserved;
+ unsigned int res_port_rsvd[MLX4_MAX_PORTS];
};
union {
int res_free;
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c
index 93195191f45b..53833c06696f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mr.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mr.c
@@ -366,6 +366,7 @@ int mlx4_mr_hw_write_mpt(struct mlx4_dev *dev, struct mlx4_mr *mmr,
container_of((void *)mpt_entry, struct mlx4_cmd_mailbox,
buf);
+ (*mpt_entry)->lkey = 0;
err = mlx4_SW2HW_MPT(dev, mailbox, key);
}
diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c
index 9cc9d62c1fec..8b15a018d625 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_int.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_int.c
@@ -177,6 +177,8 @@ static int qed_int_attentions(struct qed_hwfn *p_hwfn)
*/
do {
index = p_sb_attn->sb_index;
+ /* finish reading index before the loop condition */
+ dma_rmb();
attn_bits = le32_to_cpu(p_sb_attn->atten_bits);
attn_acks = le32_to_cpu(p_sb_attn->atten_ack);
} while (index != p_sb_attn->sb_index);
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index 35e1468d8196..b8ae6ed5c7ba 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -1124,9 +1124,9 @@ static int qed_drain(struct qed_dev *cdev)
return -EBUSY;
}
rc = qed_mcp_drain(hwfn, ptt);
+ qed_ptt_release(hwfn, ptt);
if (rc)
return rc;
- qed_ptt_release(hwfn, ptt);
}
return 0;
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index e7034c55e796..6ef9188384ce 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -215,9 +215,9 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
* it just report sending a packet to the target
* (without actual packet transfer).
*/
- dev_kfree_skb_any(skb);
ndev->stats.tx_packets++;
ndev->stats.tx_bytes += skb->len;
+ dev_kfree_skb_any(skb);
}
}
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
index 76465b117b72..f1f8227e7342 100644
--- a/drivers/net/usb/ipheth.c
+++ b/drivers/net/usb/ipheth.c
@@ -140,7 +140,6 @@ struct ipheth_device {
struct usb_device *udev;
struct usb_interface *intf;
struct net_device *net;
- struct sk_buff *tx_skb;
struct urb *tx_urb;
struct urb *rx_urb;
unsigned char *tx_buf;
@@ -229,6 +228,7 @@ static void ipheth_rcvbulk_callback(struct urb *urb)
case -ENOENT:
case -ECONNRESET:
case -ESHUTDOWN:
+ case -EPROTO:
return;
case 0:
break;
@@ -280,7 +280,6 @@ static void ipheth_sndbulk_callback(struct urb *urb)
dev_err(&dev->intf->dev, "%s: urb status: %d\n",
__func__, status);
- dev_kfree_skb_irq(dev->tx_skb);
netif_wake_queue(dev->net);
}
@@ -410,7 +409,7 @@ static int ipheth_tx(struct sk_buff *skb, struct net_device *net)
if (skb->len > IPHETH_BUF_SIZE) {
WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len);
dev->net->stats.tx_dropped++;
- dev_kfree_skb_irq(skb);
+ dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
@@ -430,12 +429,11 @@ static int ipheth_tx(struct sk_buff *skb, struct net_device *net)
dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n",
__func__, retval);
dev->net->stats.tx_errors++;
- dev_kfree_skb_irq(skb);
+ dev_kfree_skb_any(skb);
} else {
- dev->tx_skb = skb;
-
dev->net->stats.tx_packets++;
dev->net->stats.tx_bytes += skb->len;
+ dev_consume_skb_any(skb);
netif_stop_queue(net);
}
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 7945b1cd6244..b4c7b36117bd 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -256,6 +256,13 @@ config MAC80211_HWSIM
To compile this driver as a module, choose M here: the module will be
called mac80211_hwsim. If unsure, say N.
+config VIRT_WIFI
+ tristate "Wifi wrapper for ethernet drivers"
+ depends on CFG80211
+ ---help---
+ This option adds support for ethernet connections to appear as if they
+ are wifi connections through a special rtnetlink device.
+
config MWL8K
tristate "Marvell 88W8xxx PCI/PCIe Wireless support"
depends on MAC80211 && PCI
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index f23a2fbc3afa..51f02058adf2 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -51,6 +51,8 @@ obj-$(CONFIG_ATH_CARDS) += ath/
obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
+obj-$(CONFIG_VIRT_WIFI) += virt_wifi.o
+
obj-$(CONFIG_WL_TI) += ti/
obj-$(CONFIG_MWIFIEX) += mwifiex/
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index db0476c44b41..79c1a09a6965 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -5021,7 +5021,9 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
}
ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
+ spin_lock_bh(&ar->data_lock);
list_add(&arvif->list, &ar->arvifs);
+ spin_unlock_bh(&ar->data_lock);
/* It makes no sense to have firmware do keepalives. mac80211 already
* takes care of this with idle connection polling.
@@ -5172,7 +5174,9 @@ err_peer_delete:
err_vdev_delete:
ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
ar->free_vdev_map |= 1LL << arvif->vdev_id;
+ spin_lock_bh(&ar->data_lock);
list_del(&arvif->list);
+ spin_unlock_bh(&ar->data_lock);
err:
if (arvif->beacon_buf) {
@@ -5219,7 +5223,9 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
arvif->vdev_id, ret);
ar->free_vdev_map |= 1LL << arvif->vdev_id;
+ spin_lock_bh(&ar->data_lock);
list_del(&arvif->list);
+ spin_unlock_bh(&ar->data_lock);
if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
diff --git a/drivers/net/wireless/cw1200/wsm.c b/drivers/net/wireless/cw1200/wsm.c
index 3dd46c78c1cc..5a595f9f47ff 100644
--- a/drivers/net/wireless/cw1200/wsm.c
+++ b/drivers/net/wireless/cw1200/wsm.c
@@ -1805,16 +1805,18 @@ static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size)
{
size_t pos = buf->data - buf->begin;
size_t size = pos + extra_size;
+ u8 *tmp;
size = round_up(size, FWLOAD_BLOCK_SIZE);
- buf->begin = krealloc(buf->begin, size, GFP_KERNEL | GFP_DMA);
- if (buf->begin) {
- buf->data = &buf->begin[pos];
- buf->end = &buf->begin[size];
- return 0;
- } else {
- buf->end = buf->data = buf->begin;
+ tmp = krealloc(buf->begin, size, GFP_KERNEL | GFP_DMA);
+ if (!tmp) {
+ wsm_buf_deinit(buf);
return -ENOMEM;
}
+
+ buf->begin = tmp;
+ buf->data = &buf->begin[pos];
+ buf->end = &buf->begin[size];
+ return 0;
}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 984cd2f05c4a..7b2a7d848a56 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -322,8 +322,12 @@ struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy,
goto out;
}
- if (changed)
- *changed = (resp->status == MCC_RESP_NEW_CHAN_PROFILE);
+ if (changed) {
+ u32 status = le32_to_cpu(resp->status);
+
+ *changed = (status == MCC_RESP_NEW_CHAN_PROFILE ||
+ status == MCC_RESP_ILLEGAL);
+ }
regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg,
__le32_to_cpu(resp->n_channels),
@@ -4050,10 +4054,6 @@ static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw,
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
- if (!fw_has_capa(&mvm->fw->ucode_capa,
- IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS))
- return;
-
/* if beacon filtering isn't on mac80211 does it anyway */
if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
return;
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 2ee0f6fe56a1..5509c5024352 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -667,9 +667,8 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
n_channels = __le32_to_cpu(mcc_resp->n_channels);
IWL_DEBUG_LAR(mvm,
- "MCC response status: 0x%x. new MCC: 0x%x ('%c%c') change: %d n_chans: %d\n",
- status, mcc, mcc >> 8, mcc & 0xff,
- !!(status == MCC_RESP_NEW_CHAN_PROFILE), n_channels);
+ "MCC response status: 0x%x. new MCC: 0x%x ('%c%c') n_chans: %d\n",
+ status, mcc, mcc >> 8, mcc & 0xff, n_channels);
resp_len = sizeof(*mcc_resp) + n_channels * sizeof(__le32);
resp_cp = kmemdup(mcc_resp, resp_len, GFP_KERNEL);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 05413176a5d6..ab480ea6d95a 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2515,6 +2515,10 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
if (param->no_vif)
ieee80211_hw_set(hw, NO_AUTO_VIF);
+ tasklet_hrtimer_init(&data->beacon_timer,
+ mac80211_hwsim_beacon,
+ CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+
err = ieee80211_register_hw(hw);
if (err < 0) {
printk(KERN_DEBUG "mac80211_hwsim: ieee80211_register_hw failed (%d)\n",
@@ -2539,10 +2543,6 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
data->debugfs,
data, &hwsim_simulate_radar);
- tasklet_hrtimer_init(&data->beacon_timer,
- mac80211_hwsim_beacon,
- CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
-
spin_lock_bh(&hwsim_radio_lock);
list_add_tail(&data->list, &hwsim_radios);
spin_unlock_bh(&hwsim_radio_lock);
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 9a8982f581c5..1e074eaf613d 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1150,6 +1150,12 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
priv->adapter->curr_iface_comb.p2p_intf--;
priv->adapter->curr_iface_comb.sta_intf++;
dev->ieee80211_ptr->iftype = type;
+ if (mwifiex_deinit_priv_params(priv))
+ return -1;
+ if (mwifiex_init_new_priv_params(priv, dev, type))
+ return -1;
+ if (mwifiex_sta_init_cmd(priv, false, false))
+ return -1;
break;
case NL80211_IFTYPE_ADHOC:
if (mwifiex_cfg80211_deinit_p2p(priv))
@@ -2839,8 +2845,10 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
mwifiex_stop_net_dev_queue(priv->netdev, adapter);
- skb_queue_walk_safe(&priv->bypass_txq, skb, tmp)
+ skb_queue_walk_safe(&priv->bypass_txq, skb, tmp) {
+ skb_unlink(skb, &priv->bypass_txq);
mwifiex_write_data_complete(priv->adapter, skb, 0, -1);
+ }
if (netif_carrier_ok(priv->netdev))
netif_carrier_off(priv->netdev);
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index acccd6734e3b..ed8b69d1d65c 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -501,8 +501,10 @@ mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv,
struct mwifiex_adapter *adapter = priv->adapter;
struct sk_buff *skb, *tmp;
- skb_queue_walk_safe(&ra_list->skb_head, skb, tmp)
+ skb_queue_walk_safe(&ra_list->skb_head, skb, tmp) {
+ skb_unlink(skb, &ra_list->skb_head);
mwifiex_write_data_complete(adapter, skb, 0, -1);
+ }
}
/*
@@ -598,11 +600,15 @@ mwifiex_clean_txrx(struct mwifiex_private *priv)
priv->adapter->if_ops.clean_pcie_ring(priv->adapter);
spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
- skb_queue_walk_safe(&priv->tdls_txq, skb, tmp)
+ skb_queue_walk_safe(&priv->tdls_txq, skb, tmp) {
+ skb_unlink(skb, &priv->tdls_txq);
mwifiex_write_data_complete(priv->adapter, skb, 0, -1);
+ }
- skb_queue_walk_safe(&priv->bypass_txq, skb, tmp)
+ skb_queue_walk_safe(&priv->bypass_txq, skb, tmp) {
+ skb_unlink(skb, &priv->bypass_txq);
mwifiex_write_data_complete(priv->adapter, skb, 0, -1);
+ }
atomic_set(&priv->adapter->bypass_tx_pending, 0);
idr_for_each(&priv->ack_status_frames, mwifiex_free_ack_frame, NULL);
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 15dc7a398b90..f01d24baff7c 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -35,7 +35,6 @@
#include "wl12xx_80211.h"
#include "cmd.h"
#include "event.h"
-#include "ps.h"
#include "tx.h"
#include "hw_ops.h"
@@ -192,10 +191,6 @@ int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl,
timeout_time = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
- ret = wl1271_ps_elp_wakeup(wl);
- if (ret < 0)
- return ret;
-
do {
if (time_after(jiffies, timeout_time)) {
wl1271_debug(DEBUG_CMD, "timeout waiting for event %d",
@@ -227,7 +222,6 @@ int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl,
} while (!event);
out:
- wl1271_ps_elp_sleep(wl);
kfree(events_vector);
return ret;
}
diff --git a/drivers/net/wireless/virt_wifi.c b/drivers/net/wireless/virt_wifi.c
new file mode 100644
index 000000000000..90ecb7e8834f
--- /dev/null
+++ b/drivers/net/wireless/virt_wifi.c
@@ -0,0 +1,629 @@
+// SPDX-License-Identifier: GPL-2.0
+/* drivers/net/wireless/virt_wifi.c
+ *
+ * A fake implementation of cfg80211_ops that can be tacked on to an ethernet
+ * net_device to make it appear as a wireless connection.
+ *
+ * Copyright (C) 2018 Google, Inc.
+ *
+ * Author: schuffelen@google.com
+ */
+
+#include <net/cfg80211.h>
+#include <net/rtnetlink.h>
+#include <linux/etherdevice.h>
+#include <linux/module.h>
+
+#include <net/cfg80211.h>
+#include <net/rtnetlink.h>
+#include <linux/etherdevice.h>
+#include <linux/module.h>
+
+static struct wiphy *common_wiphy;
+
+struct virt_wifi_wiphy_priv {
+ struct delayed_work scan_result;
+ struct cfg80211_scan_request *scan_request;
+ bool being_deleted;
+};
+
+static struct ieee80211_channel channel_2ghz = {
+ .band = IEEE80211_BAND_2GHZ,
+ .center_freq = 2432,
+ .hw_value = 2432,
+ .max_power = 20,
+};
+
+static struct ieee80211_rate bitrates_2ghz[] = {
+ { .bitrate = 10 },
+ { .bitrate = 20 },
+ { .bitrate = 55 },
+ { .bitrate = 110 },
+ { .bitrate = 60 },
+ { .bitrate = 120 },
+ { .bitrate = 240 },
+};
+
+static struct ieee80211_supported_band band_2ghz = {
+ .channels = &channel_2ghz,
+ .bitrates = bitrates_2ghz,
+ .band = IEEE80211_BAND_2GHZ,
+ .n_channels = 1,
+ .n_bitrates = ARRAY_SIZE(bitrates_2ghz),
+ .ht_cap = {
+ .ht_supported = true,
+ .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+ IEEE80211_HT_CAP_GRN_FLD |
+ IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_SGI_40 |
+ IEEE80211_HT_CAP_DSSSCCK40,
+ .ampdu_factor = 0x3,
+ .ampdu_density = 0x6,
+ .mcs = {
+ .rx_mask = {0xff, 0xff},
+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
+ },
+ },
+};
+
+static struct ieee80211_channel channel_5ghz = {
+ .band = IEEE80211_BAND_5GHZ,
+ .center_freq = 5240,
+ .hw_value = 5240,
+ .max_power = 20,
+};
+
+static struct ieee80211_rate bitrates_5ghz[] = {
+ { .bitrate = 60 },
+ { .bitrate = 120 },
+ { .bitrate = 240 },
+};
+
+#define RX_MCS_MAP (IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \
+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | \
+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | \
+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 6 | \
+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 8 | \
+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | \
+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | \
+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 14)
+
+#define TX_MCS_MAP (IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \
+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | \
+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | \
+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 6 | \
+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 8 | \
+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | \
+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | \
+ IEEE80211_VHT_MCS_SUPPORT_0_9 << 14)
+
+static struct ieee80211_supported_band band_5ghz = {
+ .channels = &channel_5ghz,
+ .bitrates = bitrates_5ghz,
+ .band = IEEE80211_BAND_5GHZ,
+ .n_channels = 1,
+ .n_bitrates = ARRAY_SIZE(bitrates_5ghz),
+ .ht_cap = {
+ .ht_supported = true,
+ .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+ IEEE80211_HT_CAP_GRN_FLD |
+ IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_SGI_40 |
+ IEEE80211_HT_CAP_DSSSCCK40,
+ .ampdu_factor = 0x3,
+ .ampdu_density = 0x6,
+ .mcs = {
+ .rx_mask = {0xff, 0xff},
+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
+ },
+ },
+ .vht_cap = {
+ .vht_supported = true,
+ .cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
+ IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ |
+ IEEE80211_VHT_CAP_RXLDPC |
+ IEEE80211_VHT_CAP_SHORT_GI_80 |
+ IEEE80211_VHT_CAP_SHORT_GI_160 |
+ IEEE80211_VHT_CAP_TXSTBC |
+ IEEE80211_VHT_CAP_RXSTBC_1 |
+ IEEE80211_VHT_CAP_RXSTBC_2 |
+ IEEE80211_VHT_CAP_RXSTBC_3 |
+ IEEE80211_VHT_CAP_RXSTBC_4 |
+ IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
+ .vht_mcs = {
+ .rx_mcs_map = cpu_to_le16(RX_MCS_MAP),
+ .tx_mcs_map = cpu_to_le16(TX_MCS_MAP),
+ }
+ },
+};
+
+/* Assigned at module init. Guaranteed locally-administered and unicast. */
+static u8 fake_router_bssid[ETH_ALEN] __ro_after_init = {};
+
+/* Called with the rtnl lock held. */
+static int virt_wifi_scan(struct wiphy *wiphy,
+ struct cfg80211_scan_request *request)
+{
+ struct virt_wifi_wiphy_priv *priv = wiphy_priv(wiphy);
+
+ wiphy_debug(wiphy, "scan\n");
+
+ if (priv->scan_request || priv->being_deleted)
+ return -EBUSY;
+
+ priv->scan_request = request;
+ schedule_delayed_work(&priv->scan_result, HZ * 2);
+
+ return 0;
+}
+
+/* Acquires and releases the rdev BSS lock. */
+static void virt_wifi_scan_result(struct work_struct *work)
+{
+ struct {
+ u8 tag;
+ u8 len;
+ u8 ssid[8];
+ } __packed ssid = {
+ .tag = WLAN_EID_SSID, .len = 8, .ssid = "VirtWifi",
+ };
+ struct cfg80211_bss *informed_bss;
+ struct virt_wifi_wiphy_priv *priv =
+ container_of(work, struct virt_wifi_wiphy_priv,
+ scan_result.work);
+ struct wiphy *wiphy = priv_to_wiphy(priv);
+
+ informed_bss = cfg80211_inform_bss(wiphy, &channel_5ghz,
+ CFG80211_BSS_FTYPE_PRESP,
+ fake_router_bssid,
+ ktime_get_boot_ns(),
+ WLAN_CAPABILITY_ESS, 0,
+ (void *)&ssid, sizeof(ssid),
+ DBM_TO_MBM(-50), GFP_KERNEL);
+ cfg80211_put_bss(wiphy, informed_bss);
+
+ /* Schedules work which acquires and releases the rtnl lock. */
+ cfg80211_scan_done(priv->scan_request, false);
+ priv->scan_request = NULL;
+}
+
+/* May acquire and release the rdev BSS lock. */
+static void virt_wifi_cancel_scan(struct wiphy *wiphy)
+{
+ struct virt_wifi_wiphy_priv *priv = wiphy_priv(wiphy);
+
+ cancel_delayed_work_sync(&priv->scan_result);
+ /* Clean up dangling callbacks if necessary. */
+ if (priv->scan_request) {
+ /* Schedules work which acquires and releases the rtnl lock. */
+ cfg80211_scan_done(priv->scan_request, true);
+ priv->scan_request = NULL;
+ }
+}
+
+struct virt_wifi_netdev_priv {
+ struct delayed_work connect;
+ struct net_device *lowerdev;
+ struct net_device *upperdev;
+ u32 tx_packets;
+ u32 tx_failed;
+ u8 connect_requested_bss[ETH_ALEN];
+ bool is_up;
+ bool is_connected;
+ bool being_deleted;
+};
+
+/* Called with the rtnl lock held. */
+static int virt_wifi_connect(struct wiphy *wiphy, struct net_device *netdev,
+ struct cfg80211_connect_params *sme)
+{
+ struct virt_wifi_netdev_priv *priv = netdev_priv(netdev);
+ bool could_schedule;
+
+ if (priv->being_deleted || !priv->is_up)
+ return -EBUSY;
+
+ could_schedule = schedule_delayed_work(&priv->connect, HZ * 2);
+ if (!could_schedule)
+ return -EBUSY;
+
+ if (sme->bssid)
+ ether_addr_copy(priv->connect_requested_bss, sme->bssid);
+ else
+ eth_zero_addr(priv->connect_requested_bss);
+
+ wiphy_debug(wiphy, "connect\n");
+
+ return 0;
+}
+
+/* Acquires and releases the rdev event lock. */
+static void virt_wifi_connect_complete(struct work_struct *work)
+{
+ struct virt_wifi_netdev_priv *priv =
+ container_of(work, struct virt_wifi_netdev_priv, connect.work);
+ u8 *requested_bss = priv->connect_requested_bss;
+ bool has_addr = !is_zero_ether_addr(requested_bss);
+ bool right_addr = ether_addr_equal(requested_bss, fake_router_bssid);
+ u16 status = WLAN_STATUS_SUCCESS;
+
+ if (!priv->is_up || (has_addr && !right_addr))
+ status = WLAN_STATUS_UNSPECIFIED_FAILURE;
+ else
+ priv->is_connected = true;
+
+ /* Schedules an event that acquires the rtnl lock. */
+ cfg80211_connect_result(priv->upperdev, requested_bss, NULL, 0, NULL, 0,
+ status, GFP_KERNEL);
+ netif_carrier_on(priv->upperdev);
+}
+
+/* May acquire and release the rdev event lock. */
+static void virt_wifi_cancel_connect(struct net_device *netdev)
+{
+ struct virt_wifi_netdev_priv *priv = netdev_priv(netdev);
+
+ /* If there is work pending, clean up dangling callbacks. */
+ if (cancel_delayed_work_sync(&priv->connect)) {
+ /* Schedules an event that acquires the rtnl lock. */
+ cfg80211_connect_result(priv->upperdev,
+ priv->connect_requested_bss, NULL, 0,
+ NULL, 0,
+ WLAN_STATUS_UNSPECIFIED_FAILURE,
+ GFP_KERNEL);
+ }
+}
+
+/* Called with the rtnl lock held. Acquires the rdev event lock. */
+static int virt_wifi_disconnect(struct wiphy *wiphy, struct net_device *netdev,
+ u16 reason_code)
+{
+ struct virt_wifi_netdev_priv *priv = netdev_priv(netdev);
+
+ if (priv->being_deleted)
+ return -EBUSY;
+
+ wiphy_debug(wiphy, "disconnect\n");
+ virt_wifi_cancel_connect(netdev);
+
+ cfg80211_disconnected(netdev, reason_code, NULL, 0, true, GFP_KERNEL);
+ priv->is_connected = false;
+ netif_carrier_off(netdev);
+
+ return 0;
+}
+
+/* Called with the rtnl lock held. */
+static int virt_wifi_get_station(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *mac, struct station_info *sinfo)
+{
+ struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
+
+ wiphy_debug(wiphy, "get_station\n");
+
+ if (!priv->is_connected || !ether_addr_equal(mac, fake_router_bssid))
+ return -ENOENT;
+
+ sinfo->filled = BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
+ BIT_ULL(NL80211_STA_INFO_TX_FAILED) |
+ BIT_ULL(NL80211_STA_INFO_SIGNAL) |
+ BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
+ sinfo->tx_packets = priv->tx_packets;
+ sinfo->tx_failed = priv->tx_failed;
+ /* For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_ */
+ sinfo->signal = -50;
+ sinfo->txrate = (struct rate_info) {
+ .legacy = 10, /* units are 100kbit/s */
+ };
+ return 0;
+}
+
+/* Called with the rtnl lock held. */
+static int virt_wifi_dump_station(struct wiphy *wiphy, struct net_device *dev,
+ int idx, u8 *mac, struct station_info *sinfo)
+{
+ struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
+
+ wiphy_debug(wiphy, "dump_station\n");
+
+ if (idx != 0 || !priv->is_connected)
+ return -ENOENT;
+
+ ether_addr_copy(mac, fake_router_bssid);
+ return virt_wifi_get_station(wiphy, dev, fake_router_bssid, sinfo);
+}
+
+static const struct cfg80211_ops virt_wifi_cfg80211_ops = {
+ .scan = virt_wifi_scan,
+
+ .connect = virt_wifi_connect,
+ .disconnect = virt_wifi_disconnect,
+
+ .get_station = virt_wifi_get_station,
+ .dump_station = virt_wifi_dump_station,
+};
+
+/* Acquires and releases the rtnl lock. */
+static struct wiphy *virt_wifi_make_wiphy(void)
+{
+ struct wiphy *wiphy;
+ struct virt_wifi_wiphy_priv *priv;
+ int err;
+
+ wiphy = wiphy_new(&virt_wifi_cfg80211_ops, sizeof(*priv));
+
+ if (!wiphy)
+ return NULL;
+
+ wiphy->max_scan_ssids = 4;
+ wiphy->max_scan_ie_len = 1000;
+ wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+
+ wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2ghz;
+ wiphy->bands[IEEE80211_BAND_5GHZ] = &band_5ghz;
+ wiphy->bands[IEEE80211_BAND_60GHZ] = NULL;
+
+ wiphy->regulatory_flags = REGULATORY_WIPHY_SELF_MANAGED;
+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+
+ priv = wiphy_priv(wiphy);
+ priv->being_deleted = false;
+ priv->scan_request = NULL;
+ INIT_DELAYED_WORK(&priv->scan_result, virt_wifi_scan_result);
+
+ err = wiphy_register(wiphy);
+ if (err < 0) {
+ wiphy_free(wiphy);
+ return NULL;
+ }
+
+ return wiphy;
+}
+
+/* Acquires and releases the rtnl lock. */
+static void virt_wifi_destroy_wiphy(struct wiphy *wiphy)
+{
+ struct virt_wifi_wiphy_priv *priv;
+
+ WARN(!wiphy, "%s called with null wiphy", __func__);
+ if (!wiphy)
+ return;
+
+ priv = wiphy_priv(wiphy);
+ priv->being_deleted = true;
+ virt_wifi_cancel_scan(wiphy);
+
+ if (wiphy->registered)
+ wiphy_unregister(wiphy);
+ wiphy_free(wiphy);
+}
+
+/* Enters and exits a RCU-bh critical section. */
+static netdev_tx_t virt_wifi_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
+
+ priv->tx_packets++;
+ if (!priv->is_connected) {
+ priv->tx_failed++;
+ return NET_XMIT_DROP;
+ }
+
+ skb->dev = priv->lowerdev;
+ return dev_queue_xmit(skb);
+}
+
+/* Called with rtnl lock held. */
+static int virt_wifi_net_device_open(struct net_device *dev)
+{
+ struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
+
+ priv->is_up = true;
+ return 0;
+}
+
+/* Called with rtnl lock held. */
+static int virt_wifi_net_device_stop(struct net_device *dev)
+{
+ struct virt_wifi_netdev_priv *n_priv = netdev_priv(dev);
+ struct virt_wifi_wiphy_priv *w_priv;
+
+ n_priv->is_up = false;
+
+ if (!dev->ieee80211_ptr)
+ return 0;
+ w_priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
+
+ virt_wifi_cancel_scan(dev->ieee80211_ptr->wiphy);
+ virt_wifi_cancel_connect(dev);
+ netif_carrier_off(dev);
+
+ return 0;
+}
+
+static const struct net_device_ops virt_wifi_ops = {
+ .ndo_start_xmit = virt_wifi_start_xmit,
+ .ndo_open = virt_wifi_net_device_open,
+ .ndo_stop = virt_wifi_net_device_stop,
+};
+
+/* Invoked as part of rtnl lock release. */
+static void virt_wifi_net_device_destructor(struct net_device *dev)
+{
+ /* Delayed past dellink to allow nl80211 to react to the device being
+ * deleted.
+ */
+ kfree(dev->ieee80211_ptr);
+ dev->ieee80211_ptr = NULL;
+ free_netdev(dev);
+}
+
+/* No lock interaction. */
+static void virt_wifi_setup(struct net_device *dev)
+{
+ ether_setup(dev);
+ dev->netdev_ops = &virt_wifi_ops;
+ dev->destructor = virt_wifi_net_device_destructor;
+}
+
+/* Called in a RCU read critical section from netif_receive_skb */
+static rx_handler_result_t virt_wifi_rx_handler(struct sk_buff **pskb)
+{
+ struct sk_buff *skb = *pskb;
+ struct virt_wifi_netdev_priv *priv =
+ rcu_dereference(skb->dev->rx_handler_data);
+
+ if (!priv->is_connected)
+ return RX_HANDLER_PASS;
+
+ /* GFP_ATOMIC because this is a packet interrupt handler. */
+ skb = skb_share_check(skb, GFP_ATOMIC);
+ if (!skb) {
+ dev_err(&priv->upperdev->dev, "can't skb_share_check\n");
+ return RX_HANDLER_CONSUMED;
+ }
+
+ *pskb = skb;
+ skb->dev = priv->upperdev;
+ skb->pkt_type = PACKET_HOST;
+ return RX_HANDLER_ANOTHER;
+}
+
+/* Called with rtnl lock held. */
+static int virt_wifi_newlink(struct net *src_net, struct net_device *dev,
+ struct nlattr *tb[], struct nlattr *data[])
+{
+ struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
+ int err;
+
+ if (!tb[IFLA_LINK])
+ return -EINVAL;
+
+ netif_carrier_off(dev);
+
+ priv->upperdev = dev;
+ priv->lowerdev = __dev_get_by_index(src_net,
+ nla_get_u32(tb[IFLA_LINK]));
+
+ if (!priv->lowerdev)
+ return -ENODEV;
+ if (!tb[IFLA_MTU])
+ dev->mtu = priv->lowerdev->mtu;
+ else if (dev->mtu > priv->lowerdev->mtu)
+ return -EINVAL;
+
+ err = netdev_rx_handler_register(priv->lowerdev, virt_wifi_rx_handler,
+ priv);
+ if (err) {
+ dev_err(&priv->lowerdev->dev,
+ "can't netdev_rx_handler_register: %d\n", err);
+ return err;
+ }
+
+ eth_hw_addr_inherit(dev, priv->lowerdev);
+ netif_stacked_transfer_operstate(priv->lowerdev, dev);
+
+ SET_NETDEV_DEV(dev, &priv->lowerdev->dev);
+ dev->ieee80211_ptr = kzalloc(sizeof(*dev->ieee80211_ptr), GFP_KERNEL);
+
+ if (!dev->ieee80211_ptr)
+ goto remove_handler;
+
+ dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
+ dev->ieee80211_ptr->wiphy = common_wiphy;
+
+ err = register_netdevice(dev);
+ if (err) {
+ dev_err(&priv->lowerdev->dev, "can't register_netdevice: %d\n",
+ err);
+ goto free_wireless_dev;
+ }
+
+ err = netdev_upper_dev_link(priv->lowerdev, dev);
+ if (err) {
+ dev_err(&priv->lowerdev->dev, "can't netdev_upper_dev_link: %d\n",
+ err);
+ goto unregister_netdev;
+ }
+
+ priv->being_deleted = false;
+ priv->is_connected = false;
+ priv->is_up = false;
+ INIT_DELAYED_WORK(&priv->connect, virt_wifi_connect_complete);
+
+ return 0;
+unregister_netdev:
+ unregister_netdevice(dev);
+free_wireless_dev:
+ kfree(dev->ieee80211_ptr);
+ dev->ieee80211_ptr = NULL;
+remove_handler:
+ netdev_rx_handler_unregister(priv->lowerdev);
+
+ return err;
+}
+
+/* Called with rtnl lock held. */
+static void virt_wifi_dellink(struct net_device *dev,
+ struct list_head *head)
+{
+ struct virt_wifi_netdev_priv *priv = netdev_priv(dev);
+
+ if (dev->ieee80211_ptr)
+ virt_wifi_cancel_scan(dev->ieee80211_ptr->wiphy);
+
+ priv->being_deleted = true;
+ virt_wifi_cancel_connect(dev);
+ netif_carrier_off(dev);
+
+ netdev_rx_handler_unregister(priv->lowerdev);
+ netdev_upper_dev_unlink(priv->lowerdev, dev);
+
+ unregister_netdevice_queue(dev, head);
+
+ /* Deleting the wiphy is handled in the module destructor. */
+}
+
+static struct rtnl_link_ops virt_wifi_link_ops = {
+ .kind = "virt_wifi",
+ .setup = virt_wifi_setup,
+ .newlink = virt_wifi_newlink,
+ .dellink = virt_wifi_dellink,
+ .priv_size = sizeof(struct virt_wifi_netdev_priv),
+};
+
+/* Acquires and releases the rtnl lock. */
+static int __init virt_wifi_init_module(void)
+{
+ int err;
+
+ /* Guaranteed to be locallly-administered and not multicast. */
+ eth_random_addr(fake_router_bssid);
+
+ common_wiphy = virt_wifi_make_wiphy();
+ if (!common_wiphy)
+ return -ENOMEM;
+
+ err = rtnl_link_register(&virt_wifi_link_ops);
+ if (err)
+ virt_wifi_destroy_wiphy(common_wiphy);
+
+ return err;
+}
+
+/* Acquires and releases the rtnl lock. */
+static void __exit virt_wifi_cleanup_module(void)
+{
+ /* Will delete any devices that depend on the wiphy. */
+ rtnl_link_unregister(&virt_wifi_link_ops);
+ virt_wifi_destroy_wiphy(common_wiphy);
+}
+
+module_init(virt_wifi_init_module);
+module_exit(virt_wifi_cleanup_module);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Cody Schuffelen <schuffelen@google.com>");
+MODULE_DESCRIPTION("Driver for a wireless wrapper of ethernet devices");
+MODULE_ALIAS_RTNL_LINK("virt_wifi");
diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c
index 6c0c301611c4..1b11ded79c4f 100644
--- a/drivers/nfc/nfcmrvl/uart.c
+++ b/drivers/nfc/nfcmrvl/uart.c
@@ -73,10 +73,9 @@ static int nfcmrvl_uart_parse_dt(struct device_node *node,
struct device_node *matched_node;
int ret;
- matched_node = of_find_compatible_node(node, NULL, "marvell,nfc-uart");
+ matched_node = of_get_compatible_child(node, "marvell,nfc-uart");
if (!matched_node) {
- matched_node = of_find_compatible_node(node, NULL,
- "mrvl,nfc-uart");
+ matched_node = of_get_compatible_child(node, "mrvl,nfc-uart");
if (!matched_node)
return -ENODEV;
}
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 31341290cd91..c6e019208d17 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -713,6 +713,31 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
EXPORT_SYMBOL(of_get_next_available_child);
/**
+ * of_get_compatible_child - Find compatible child node
+ * @parent: parent node
+ * @compatible: compatible string
+ *
+ * Lookup child node whose compatible property contains the given compatible
+ * string.
+ *
+ * Returns a node pointer with refcount incremented, use of_node_put() on it
+ * when done; or NULL if not found.
+ */
+struct device_node *of_get_compatible_child(const struct device_node *parent,
+ const char *compatible)
+{
+ struct device_node *child;
+
+ for_each_child_of_node(parent, child) {
+ if (of_device_is_compatible(child, compatible))
+ break;
+ }
+
+ return child;
+}
+EXPORT_SYMBOL(of_get_compatible_child);
+
+/**
* of_get_child_by_name - Find the child node by name for a given parent
* @node: parent node
* @name: child name to look for.
diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
index 069d167ab410..1a3727aa28a8 100644
--- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
+++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -538,7 +538,7 @@ static int pmic_gpio_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
pad->pullup = arg;
break;
case PMIC_GPIO_CONF_STRENGTH:
- if (arg > PMIC_GPIO_STRENGTH_LOW)
+ if (arg > PMIC_GPIO_STRENGTH_HIGH)
return -EINVAL;
pad->strength = arg;
break;
diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
index ae351167d849..5645b38d6132 100644
--- a/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
+++ b/drivers/pinctrl/qcom/pinctrl-ssbi-gpio.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2015, Sony Mobile Communications AB.
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -379,7 +379,7 @@ static int pm8xxx_pin_config_set(struct pinctrl_dev *pctldev,
banks |= BIT(0);
break;
case PM8XXX_QCOM_DRIVE_STRENGH:
- if (arg > PMIC_GPIO_STRENGTH_LOW) {
+ if (arg > PM8921_GPIO_STRENGTH_LOW) {
dev_err(pctrl->dev, "invalid drive strength\n");
return -EINVAL;
}
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 09ac56317f1b..533bd2467910 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -4519,8 +4519,8 @@ static int qeth_snmp_command_cb(struct qeth_card *card,
{
struct qeth_ipa_cmd *cmd;
struct qeth_arp_query_info *qinfo;
- struct qeth_snmp_cmd *snmp;
unsigned char *data;
+ void *snmp_data;
__u16 data_len;
QETH_CARD_TEXT(card, 3, "snpcmdcb");
@@ -4528,7 +4528,6 @@ static int qeth_snmp_command_cb(struct qeth_card *card,
cmd = (struct qeth_ipa_cmd *) sdata;
data = (unsigned char *)((char *)cmd - reply->offset);
qinfo = (struct qeth_arp_query_info *) reply->param;
- snmp = &cmd->data.setadapterparms.data.snmp;
if (cmd->hdr.return_code) {
QETH_CARD_TEXT_(card, 4, "scer1%x", cmd->hdr.return_code);
@@ -4541,10 +4540,15 @@ static int qeth_snmp_command_cb(struct qeth_card *card,
return 0;
}
data_len = *((__u16 *)QETH_IPA_PDU_LEN_PDU1(data));
- if (cmd->data.setadapterparms.hdr.seq_no == 1)
- data_len -= (__u16)((char *)&snmp->data - (char *)cmd);
- else
- data_len -= (__u16)((char *)&snmp->request - (char *)cmd);
+ if (cmd->data.setadapterparms.hdr.seq_no == 1) {
+ snmp_data = &cmd->data.setadapterparms.data.snmp;
+ data_len -= offsetof(struct qeth_ipa_cmd,
+ data.setadapterparms.data.snmp);
+ } else {
+ snmp_data = &cmd->data.setadapterparms.data.snmp.request;
+ data_len -= offsetof(struct qeth_ipa_cmd,
+ data.setadapterparms.data.snmp.request);
+ }
/* check if there is enough room in userspace */
if ((qinfo->udata_len - qinfo->udata_offset) < data_len) {
@@ -4557,16 +4561,9 @@ static int qeth_snmp_command_cb(struct qeth_card *card,
QETH_CARD_TEXT_(card, 4, "sseqn%i",
cmd->data.setadapterparms.hdr.seq_no);
/*copy entries to user buffer*/
- if (cmd->data.setadapterparms.hdr.seq_no == 1) {
- memcpy(qinfo->udata + qinfo->udata_offset,
- (char *)snmp,
- data_len + offsetof(struct qeth_snmp_cmd, data));
- qinfo->udata_offset += offsetof(struct qeth_snmp_cmd, data);
- } else {
- memcpy(qinfo->udata + qinfo->udata_offset,
- (char *)&snmp->request, data_len);
- }
+ memcpy(qinfo->udata + qinfo->udata_offset, snmp_data, data_len);
qinfo->udata_offset += data_len;
+
/* check if all replies received ... */
QETH_CARD_TEXT_(card, 4, "srtot%i",
cmd->data.setadapterparms.hdr.used_total);
diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c
index 1b831598df7c..ff06bdfd2b20 100644
--- a/drivers/s390/virtio/virtio_ccw.c
+++ b/drivers/s390/virtio/virtio_ccw.c
@@ -59,6 +59,7 @@ struct virtio_ccw_device {
unsigned int revision; /* Transport revision */
wait_queue_head_t wait_q;
spinlock_t lock;
+ struct mutex io_lock; /* Serializes I/O requests */
struct list_head virtqueues;
unsigned long indicators;
unsigned long indicators2;
@@ -307,6 +308,7 @@ static int ccw_io_helper(struct virtio_ccw_device *vcdev,
unsigned long flags;
int flag = intparm & VIRTIO_CCW_INTPARM_MASK;
+ mutex_lock(&vcdev->io_lock);
do {
spin_lock_irqsave(get_ccwdev_lock(vcdev->cdev), flags);
ret = ccw_device_start(vcdev->cdev, ccw, intparm, 0, 0);
@@ -319,7 +321,9 @@ static int ccw_io_helper(struct virtio_ccw_device *vcdev,
cpu_relax();
} while (ret == -EBUSY);
wait_event(vcdev->wait_q, doing_io(vcdev, flag) == 0);
- return ret ? ret : vcdev->err;
+ ret = ret ? ret : vcdev->err;
+ mutex_unlock(&vcdev->io_lock);
+ return ret;
}
static void virtio_ccw_drop_indicator(struct virtio_ccw_device *vcdev,
@@ -833,6 +837,7 @@ static void virtio_ccw_get_config(struct virtio_device *vdev,
int ret;
struct ccw1 *ccw;
void *config_area;
+ unsigned long flags;
ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
if (!ccw)
@@ -851,11 +856,13 @@ static void virtio_ccw_get_config(struct virtio_device *vdev,
if (ret)
goto out_free;
+ spin_lock_irqsave(&vcdev->lock, flags);
memcpy(vcdev->config, config_area, offset + len);
- if (buf)
- memcpy(buf, &vcdev->config[offset], len);
if (vcdev->config_ready < offset + len)
vcdev->config_ready = offset + len;
+ spin_unlock_irqrestore(&vcdev->lock, flags);
+ if (buf)
+ memcpy(buf, config_area + offset, len);
out_free:
kfree(config_area);
@@ -869,6 +876,7 @@ static void virtio_ccw_set_config(struct virtio_device *vdev,
struct virtio_ccw_device *vcdev = to_vc_device(vdev);
struct ccw1 *ccw;
void *config_area;
+ unsigned long flags;
ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL);
if (!ccw)
@@ -881,9 +889,11 @@ static void virtio_ccw_set_config(struct virtio_device *vdev,
/* Make sure we don't overwrite fields. */
if (vcdev->config_ready < offset)
virtio_ccw_get_config(vdev, 0, NULL, offset);
+ spin_lock_irqsave(&vcdev->lock, flags);
memcpy(&vcdev->config[offset], buf, len);
/* Write the config area to the host. */
memcpy(config_area, vcdev->config, sizeof(vcdev->config));
+ spin_unlock_irqrestore(&vcdev->lock, flags);
ccw->cmd_code = CCW_CMD_WRITE_CONF;
ccw->flags = 0;
ccw->count = offset + len;
@@ -1230,6 +1240,7 @@ static int virtio_ccw_online(struct ccw_device *cdev)
init_waitqueue_head(&vcdev->wait_q);
INIT_LIST_HEAD(&vcdev->virtqueues);
spin_lock_init(&vcdev->lock);
+ mutex_init(&vcdev->io_lock);
spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
dev_set_drvdata(&cdev->dev, vcdev);
diff --git a/drivers/scsi/bfa/bfa_fcbuild.c b/drivers/scsi/bfa/bfa_fcbuild.c
index dce787f6cca2..daade591409a 100644
--- a/drivers/scsi/bfa/bfa_fcbuild.c
+++ b/drivers/scsi/bfa/bfa_fcbuild.c
@@ -1249,8 +1249,8 @@ fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s));
rspnid->dap = s_id;
- rspnid->spn_len = (u8) strlen((char *)name);
- strncpy((char *)rspnid->spn, (char *)name, rspnid->spn_len);
+ strlcpy(rspnid->spn, name, sizeof(rspnid->spn));
+ rspnid->spn_len = (u8) strlen(rspnid->spn);
return sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s);
}
@@ -1270,8 +1270,8 @@ fc_rsnn_nn_build(struct fchs_s *fchs, void *pyld, u32 s_id,
memset(rsnn_nn, 0, sizeof(struct fcgs_rsnn_nn_req_s));
rsnn_nn->node_name = node_name;
- rsnn_nn->snn_len = (u8) strlen((char *)name);
- strncpy((char *)rsnn_nn->snn, (char *)name, rsnn_nn->snn_len);
+ strlcpy(rsnn_nn->snn, name, sizeof(rsnn_nn->snn));
+ rsnn_nn->snn_len = (u8) strlen(rsnn_nn->snn);
return sizeof(struct fcgs_rsnn_nn_req_s) + sizeof(struct ct_hdr_s);
}
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c
index 0f19455951ec..475470efb7c6 100644
--- a/drivers/scsi/bfa/bfa_fcs.c
+++ b/drivers/scsi/bfa/bfa_fcs.c
@@ -831,23 +831,23 @@ bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
/* Model name/number */
- strncpy((char *)&port_cfg->sym_name, model,
- BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
- strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
- sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
+ strlcpy(port_cfg->sym_name.symname, model,
+ BFA_SYMNAME_MAXLEN);
+ strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
+ BFA_SYMNAME_MAXLEN);
/* Driver Version */
- strncat((char *)&port_cfg->sym_name, (char *)driver_info->version,
- BFA_FCS_PORT_SYMBNAME_VERSION_SZ);
- strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
- sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
+ strlcat(port_cfg->sym_name.symname, driver_info->version,
+ BFA_SYMNAME_MAXLEN);
+ strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
+ BFA_SYMNAME_MAXLEN);
/* Host machine name */
- strncat((char *)&port_cfg->sym_name,
- (char *)driver_info->host_machine_name,
- BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ);
- strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
- sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
+ strlcat(port_cfg->sym_name.symname,
+ driver_info->host_machine_name,
+ BFA_SYMNAME_MAXLEN);
+ strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
+ BFA_SYMNAME_MAXLEN);
/*
* Host OS Info :
@@ -855,24 +855,24 @@ bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
* OS name string and instead copy the entire OS info string (64 bytes).
*/
if (driver_info->host_os_patch[0] == '\0') {
- strncat((char *)&port_cfg->sym_name,
- (char *)driver_info->host_os_name,
- BFA_FCS_OS_STR_LEN);
- strncat((char *)&port_cfg->sym_name,
+ strlcat(port_cfg->sym_name.symname,
+ driver_info->host_os_name,
+ BFA_SYMNAME_MAXLEN);
+ strlcat(port_cfg->sym_name.symname,
BFA_FCS_PORT_SYMBNAME_SEPARATOR,
- sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
+ BFA_SYMNAME_MAXLEN);
} else {
- strncat((char *)&port_cfg->sym_name,
- (char *)driver_info->host_os_name,
- BFA_FCS_PORT_SYMBNAME_OSINFO_SZ);
- strncat((char *)&port_cfg->sym_name,
+ strlcat(port_cfg->sym_name.symname,
+ driver_info->host_os_name,
+ BFA_SYMNAME_MAXLEN);
+ strlcat(port_cfg->sym_name.symname,
BFA_FCS_PORT_SYMBNAME_SEPARATOR,
- sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
+ BFA_SYMNAME_MAXLEN);
/* Append host OS Patch Info */
- strncat((char *)&port_cfg->sym_name,
- (char *)driver_info->host_os_patch,
- BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ);
+ strlcat(port_cfg->sym_name.symname,
+ driver_info->host_os_patch,
+ BFA_SYMNAME_MAXLEN);
}
/* null terminate */
@@ -892,26 +892,26 @@ bfa_fcs_fabric_nsymb_init(struct bfa_fcs_fabric_s *fabric)
bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model);
/* Model name/number */
- strncpy((char *)&port_cfg->node_sym_name, model,
- BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
- strncat((char *)&port_cfg->node_sym_name,
+ strlcpy(port_cfg->node_sym_name.symname, model,
+ BFA_SYMNAME_MAXLEN);
+ strlcat(port_cfg->node_sym_name.symname,
BFA_FCS_PORT_SYMBNAME_SEPARATOR,
- sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
+ BFA_SYMNAME_MAXLEN);
/* Driver Version */
- strncat((char *)&port_cfg->node_sym_name, (char *)driver_info->version,
- BFA_FCS_PORT_SYMBNAME_VERSION_SZ);
- strncat((char *)&port_cfg->node_sym_name,
+ strlcat(port_cfg->node_sym_name.symname, (char *)driver_info->version,
+ BFA_SYMNAME_MAXLEN);
+ strlcat(port_cfg->node_sym_name.symname,
BFA_FCS_PORT_SYMBNAME_SEPARATOR,
- sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
+ BFA_SYMNAME_MAXLEN);
/* Host machine name */
- strncat((char *)&port_cfg->node_sym_name,
- (char *)driver_info->host_machine_name,
- BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ);
- strncat((char *)&port_cfg->node_sym_name,
+ strlcat(port_cfg->node_sym_name.symname,
+ driver_info->host_machine_name,
+ BFA_SYMNAME_MAXLEN);
+ strlcat(port_cfg->node_sym_name.symname,
BFA_FCS_PORT_SYMBNAME_SEPARATOR,
- sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
+ BFA_SYMNAME_MAXLEN);
/* null terminate */
port_cfg->node_sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0;
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c
index ff75ef891755..aa96f31ebc43 100644
--- a/drivers/scsi/bfa/bfa_fcs_lport.c
+++ b/drivers/scsi/bfa/bfa_fcs_lport.c
@@ -2630,10 +2630,10 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc,
hba_attr->fw_version);
- strncpy(hba_attr->driver_version, (char *)driver_info->version,
+ strlcpy(hba_attr->driver_version, (char *)driver_info->version,
sizeof(hba_attr->driver_version));
- strncpy(hba_attr->os_name, driver_info->host_os_name,
+ strlcpy(hba_attr->os_name, driver_info->host_os_name,
sizeof(hba_attr->os_name));
/*
@@ -2641,23 +2641,23 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi,
* to the os name along with a separator
*/
if (driver_info->host_os_patch[0] != '\0') {
- strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
- sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
- strncat(hba_attr->os_name, driver_info->host_os_patch,
- sizeof(driver_info->host_os_patch));
+ strlcat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
+ sizeof(hba_attr->os_name));
+ strlcat(hba_attr->os_name, driver_info->host_os_patch,
+ sizeof(hba_attr->os_name));
}
/* Retrieve the max frame size from the port attr */
bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
hba_attr->max_ct_pyld = fcs_port_attr.max_frm_size;
- strncpy(hba_attr->node_sym_name.symname,
+ strlcpy(hba_attr->node_sym_name.symname,
port->port_cfg.node_sym_name.symname, BFA_SYMNAME_MAXLEN);
strcpy(hba_attr->vendor_info, "BROCADE");
hba_attr->num_ports =
cpu_to_be32(bfa_ioc_get_nports(&port->fcs->bfa->ioc));
hba_attr->fabric_name = port->fabric->lps->pr_nwwn;
- strncpy(hba_attr->bios_ver, hba_attr->option_rom_ver, BFA_VERSION_LEN);
+ strlcpy(hba_attr->bios_ver, hba_attr->option_rom_ver, BFA_VERSION_LEN);
}
@@ -2724,20 +2724,20 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi,
/*
* OS device Name
*/
- strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name,
+ strlcpy(port_attr->os_device_name, driver_info->os_device_name,
sizeof(port_attr->os_device_name));
/*
* Host name
*/
- strncpy(port_attr->host_name, (char *)driver_info->host_machine_name,
+ strlcpy(port_attr->host_name, driver_info->host_machine_name,
sizeof(port_attr->host_name));
port_attr->node_name = bfa_fcs_lport_get_nwwn(port);
port_attr->port_name = bfa_fcs_lport_get_pwwn(port);
- strncpy(port_attr->port_sym_name.symname,
- (char *)&bfa_fcs_lport_get_psym_name(port), BFA_SYMNAME_MAXLEN);
+ strlcpy(port_attr->port_sym_name.symname,
+ bfa_fcs_lport_get_psym_name(port).symname, BFA_SYMNAME_MAXLEN);
bfa_fcs_lport_get_attr(port, &lport_attr);
port_attr->port_type = cpu_to_be32(lport_attr.port_type);
port_attr->scos = pport_attr.cos_supported;
@@ -3217,7 +3217,7 @@ bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
rsp_str[gmal_entry->len-1] = 0;
/* copy IP Address to fabric */
- strncpy(bfa_fcs_lport_get_fabric_ipaddr(port),
+ strlcpy(bfa_fcs_lport_get_fabric_ipaddr(port),
gmal_entry->ip_addr,
BFA_FCS_FABRIC_IPADDR_SZ);
break;
@@ -4655,21 +4655,13 @@ bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
* to that of the base port.
*/
- strncpy((char *)psymbl,
- (char *) &
- (bfa_fcs_lport_get_psym_name
+ strlcpy(symbl,
+ (char *)&(bfa_fcs_lport_get_psym_name
(bfa_fcs_get_base_port(port->fcs))),
- strlen((char *) &
- bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
- (port->fcs))));
-
- /* Ensure we have a null terminating string. */
- ((char *)psymbl)[strlen((char *) &
- bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port
- (port->fcs)))] = 0;
- strncat((char *)psymbl,
- (char *) &(bfa_fcs_lport_get_psym_name(port)),
- strlen((char *) &bfa_fcs_lport_get_psym_name(port)));
+ sizeof(symbl));
+
+ strlcat(symbl, (char *)&(bfa_fcs_lport_get_psym_name(port)),
+ sizeof(symbl));
} else {
psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port));
}
@@ -5161,7 +5153,6 @@ bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced)
struct fchs_s fchs;
struct bfa_fcxp_s *fcxp;
u8 symbl[256];
- u8 *psymbl = &symbl[0];
int len;
/* Avoid sending RSPN in the following states. */
@@ -5191,22 +5182,17 @@ bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced)
* For Vports, we append the vport's port symbolic name
* to that of the base port.
*/
- strncpy((char *)psymbl, (char *)&(bfa_fcs_lport_get_psym_name
+ strlcpy(symbl, (char *)&(bfa_fcs_lport_get_psym_name
(bfa_fcs_get_base_port(port->fcs))),
- strlen((char *)&bfa_fcs_lport_get_psym_name(
- bfa_fcs_get_base_port(port->fcs))));
-
- /* Ensure we have a null terminating string. */
- ((char *)psymbl)[strlen((char *)&bfa_fcs_lport_get_psym_name(
- bfa_fcs_get_base_port(port->fcs)))] = 0;
+ sizeof(symbl));
- strncat((char *)psymbl,
+ strlcat(symbl,
(char *)&(bfa_fcs_lport_get_psym_name(port)),
- strlen((char *)&bfa_fcs_lport_get_psym_name(port)));
+ sizeof(symbl));
}
len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
- bfa_fcs_lport_get_fcid(port), 0, psymbl);
+ bfa_fcs_lport_get_fcid(port), 0, symbl);
bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index 98f7e8cca52d..e533474748a5 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -2802,7 +2802,7 @@ void
bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer)
{
memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN);
- memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
+ strlcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN);
}
void
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c
index 625225f31081..15d02eb09476 100644
--- a/drivers/scsi/bfa/bfa_svc.c
+++ b/drivers/scsi/bfa/bfa_svc.c
@@ -365,8 +365,8 @@ bfa_plog_str(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
lp.eid = event;
lp.log_type = BFA_PL_LOG_TYPE_STRING;
lp.misc = misc;
- strncpy(lp.log_entry.string_log, log_str,
- BFA_PL_STRING_LOG_SZ - 1);
+ strlcpy(lp.log_entry.string_log, log_str,
+ BFA_PL_STRING_LOG_SZ);
lp.log_entry.string_log[BFA_PL_STRING_LOG_SZ - 1] = '\0';
bfa_plog_add(plog, &lp);
}
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index cc3b9d3d6d40..bfefa2bfde0e 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -987,20 +987,20 @@ bfad_start_ops(struct bfad_s *bfad) {
/* Fill the driver_info info to fcs*/
memset(&driver_info, 0, sizeof(driver_info));
- strncpy(driver_info.version, BFAD_DRIVER_VERSION,
- sizeof(driver_info.version) - 1);
+ strlcpy(driver_info.version, BFAD_DRIVER_VERSION,
+ sizeof(driver_info.version));
if (host_name)
- strncpy(driver_info.host_machine_name, host_name,
- sizeof(driver_info.host_machine_name) - 1);
+ strlcpy(driver_info.host_machine_name, host_name,
+ sizeof(driver_info.host_machine_name));
if (os_name)
- strncpy(driver_info.host_os_name, os_name,
- sizeof(driver_info.host_os_name) - 1);
+ strlcpy(driver_info.host_os_name, os_name,
+ sizeof(driver_info.host_os_name));
if (os_patch)
- strncpy(driver_info.host_os_patch, os_patch,
- sizeof(driver_info.host_os_patch) - 1);
+ strlcpy(driver_info.host_os_patch, os_patch,
+ sizeof(driver_info.host_os_patch));
- strncpy(driver_info.os_device_name, bfad->pci_name,
- sizeof(driver_info.os_device_name) - 1);
+ strlcpy(driver_info.os_device_name, bfad->pci_name,
+ sizeof(driver_info.os_device_name));
/* FCS driver info init */
spin_lock_irqsave(&bfad->bfad_lock, flags);
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c
index 40be670a1cbc..6d21bc6a7713 100644
--- a/drivers/scsi/bfa/bfad_attr.c
+++ b/drivers/scsi/bfa/bfad_attr.c
@@ -842,7 +842,7 @@ bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr,
char symname[BFA_SYMNAME_MAXLEN];
bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr);
- strncpy(symname, port_attr.port_cfg.sym_name.symname,
+ strlcpy(symname, port_attr.port_cfg.sym_name.symname,
BFA_SYMNAME_MAXLEN);
return snprintf(buf, PAGE_SIZE, "%s\n", symname);
}
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 023b9d42ad9a..be2de04179d0 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -126,7 +126,7 @@ bfad_iocmd_ioc_get_attr(struct bfad_s *bfad, void *cmd)
/* fill in driver attr info */
strcpy(iocmd->ioc_attr.driver_attr.driver, BFAD_DRIVER_NAME);
- strncpy(iocmd->ioc_attr.driver_attr.driver_ver,
+ strlcpy(iocmd->ioc_attr.driver_attr.driver_ver,
BFAD_DRIVER_VERSION, BFA_VERSION_LEN);
strcpy(iocmd->ioc_attr.driver_attr.fw_ver,
iocmd->ioc_attr.adapter_attr.fw_ver);
@@ -314,9 +314,9 @@ bfad_iocmd_port_get_attr(struct bfad_s *bfad, void *cmd)
iocmd->attr.port_type = port_attr.port_type;
iocmd->attr.loopback = port_attr.loopback;
iocmd->attr.authfail = port_attr.authfail;
- strncpy(iocmd->attr.port_symname.symname,
+ strlcpy(iocmd->attr.port_symname.symname,
port_attr.port_cfg.sym_name.symname,
- sizeof(port_attr.port_cfg.sym_name.symname));
+ sizeof(iocmd->attr.port_symname.symname));
iocmd->status = BFA_STATUS_OK;
return 0;
diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c
index c00b2ff72b55..be5ee2d37815 100644
--- a/drivers/scsi/csiostor/csio_lnode.c
+++ b/drivers/scsi/csiostor/csio_lnode.c
@@ -238,14 +238,23 @@ csio_osname(uint8_t *buf, size_t buf_len)
}
static inline void
-csio_append_attrib(uint8_t **ptr, uint16_t type, uint8_t *val, uint16_t len)
+csio_append_attrib(uint8_t **ptr, uint16_t type, void *val, size_t val_len)
{
+ uint16_t len;
struct fc_fdmi_attr_entry *ae = (struct fc_fdmi_attr_entry *)*ptr;
+
+ if (WARN_ON(val_len > U16_MAX))
+ return;
+
+ len = val_len;
+
ae->type = htons(type);
len += 4; /* includes attribute type and length */
len = (len + 3) & ~3; /* should be multiple of 4 bytes */
ae->len = htons(len);
- memcpy(ae->value, val, len);
+ memcpy(ae->value, val, val_len);
+ if (len > val_len)
+ memset(ae->value + val_len, 0, len - val_len);
*ptr += len;
}
@@ -335,7 +344,7 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
numattrs++;
val = htonl(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_SUPPORTEDSPEED,
- (uint8_t *)&val,
+ &val,
FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN);
numattrs++;
@@ -346,23 +355,22 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
else
val = htonl(CSIO_HBA_PORTSPEED_UNKNOWN);
csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED,
- (uint8_t *)&val,
- FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN);
+ &val, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN);
numattrs++;
mfs = ln->ln_sparm.csp.sp_bb_data;
csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_MAXFRAMESIZE,
- (uint8_t *)&mfs, FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN);
+ &mfs, sizeof(mfs));
numattrs++;
strcpy(buf, "csiostor");
csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_OSDEVICENAME, buf,
- (uint16_t)strlen(buf));
+ strlen(buf));
numattrs++;
if (!csio_hostname(buf, sizeof(buf))) {
csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_HOSTNAME,
- buf, (uint16_t)strlen(buf));
+ buf, strlen(buf));
numattrs++;
}
attrib_blk->numattrs = htonl(numattrs);
@@ -444,33 +452,32 @@ csio_ln_fdmi_dprt_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req)
strcpy(buf, "Chelsio Communications");
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MANUFACTURER, buf,
- (uint16_t)strlen(buf));
+ strlen(buf));
numattrs++;
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_SERIALNUMBER,
- hw->vpd.sn, (uint16_t)sizeof(hw->vpd.sn));
+ hw->vpd.sn, sizeof(hw->vpd.sn));
numattrs++;
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MODEL, hw->vpd.id,
- (uint16_t)sizeof(hw->vpd.id));
+ sizeof(hw->vpd.id));
numattrs++;
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MODELDESCRIPTION,
- hw->model_desc, (uint16_t)strlen(hw->model_desc));
+ hw->model_desc, strlen(hw->model_desc));
numattrs++;
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_HARDWAREVERSION,
- hw->hw_ver, (uint16_t)sizeof(hw->hw_ver));
+ hw->hw_ver, sizeof(hw->hw_ver));
numattrs++;
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_FIRMWAREVERSION,
- hw->fwrev_str, (uint16_t)strlen(hw->fwrev_str));
+ hw->fwrev_str, strlen(hw->fwrev_str));
numattrs++;
if (!csio_osname(buf, sizeof(buf))) {
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_OSNAMEVERSION,
- buf, (uint16_t)strlen(buf));
+ buf, strlen(buf));
numattrs++;
}
csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MAXCTPAYLOAD,
- (uint8_t *)&maxpayload,
- FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN);
+ &maxpayload, FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN);
len = (uint32_t)(pld - (uint8_t *)cmd);
numattrs++;
attrib_blk->numattrs = htonl(numattrs);
@@ -1794,6 +1801,8 @@ csio_ln_mgmt_submit_req(struct csio_ioreq *io_req,
struct csio_mgmtm *mgmtm = csio_hw_to_mgmtm(hw);
int rv;
+ BUG_ON(pld_len > pld->len);
+
io_req->io_cbfn = io_cbfn; /* Upper layer callback handler */
io_req->fw_handle = (uintptr_t) (io_req);
io_req->eq_idx = mgmtm->eq_idx;
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 18b19744398a..ff5df33fc740 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -685,6 +685,11 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
srb_t *sp;
int rval;
+ if (unlikely(test_bit(UNLOADING, &base_vha->dpc_flags))) {
+ cmd->result = DID_NO_CONNECT << 16;
+ goto qc24_fail_command;
+ }
+
if (ha->flags.eeh_busy) {
if (ha->flags.pci_channel_io_perm_failure) {
ql_dbg(ql_dbg_aer, vha, 0x9010,
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index 6b61b09b3226..75f2179860a7 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -33,7 +33,6 @@ struct scsi_dev_info_list_table {
};
-static const char spaces[] = " "; /* 16 of them */
static unsigned scsi_default_dev_flags;
static LIST_HEAD(scsi_dev_info_list);
static char scsi_dev_flags[256];
@@ -291,20 +290,13 @@ static void scsi_strcpy_devinfo(char *name, char *to, size_t to_length,
size_t from_length;
from_length = strlen(from);
- strncpy(to, from, min(to_length, from_length));
- if (from_length < to_length) {
- if (compatible) {
- /*
- * NUL terminate the string if it is short.
- */
- to[from_length] = '\0';
- } else {
- /*
- * space pad the string if it is short.
- */
- strncpy(&to[from_length], spaces,
- to_length - from_length);
- }
+ /* this zero-pads the destination */
+ strncpy(to, from, to_length);
+ if (from_length < to_length && !compatible) {
+ /*
+ * space pad the string if it is short.
+ */
+ memset(&to[from_length], ' ', to_length - from_length);
}
if (from_length > to_length)
printk(KERN_WARNING "%s: %s string '%s' is too long\n",
diff --git a/drivers/soc/qcom/memshare/msm_memshare.c b/drivers/soc/qcom/memshare/msm_memshare.c
index 6dd4b06bf377..94b535111f24 100644
--- a/drivers/soc/qcom/memshare/msm_memshare.c
+++ b/drivers/soc/qcom/memshare/msm_memshare.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -375,6 +375,7 @@ static int modem_notifier_cb(struct notifier_block *this, unsigned long code,
if (memblock[i].peripheral ==
DHMS_MEM_PROC_MPSS_V01 &&
!memblock[i].guarantee &&
+ !memblock[i].client_request &&
memblock[i].alloted) {
pr_debug("memshare: Freeing memory for client id: %d\n",
memblock[i].client_id);
@@ -630,12 +631,10 @@ static int handle_free_generic_req(void *req_h, void *req, void *conn_h)
__func__);
flag = 1;
} else if (!memblock[client_id].guarantee &&
+ memblock[client_id].client_request &&
memblock[client_id].alloted) {
- pr_debug("In %s: pblk->virtual_addr :%lx, pblk->phy_addr: %lx\n,size: %d",
- __func__,
- (unsigned long int)
- memblock[client_id].virtual_addr,
- (unsigned long int)memblock[client_id].phy_addr,
+ pr_debug("memshare: %s: client_id:%d, size: %d",
+ __func__, client_id,
memblock[client_id].size);
dma_free_attrs(memsh_drv->dev, memblock[client_id].size,
memblock[client_id].virtual_addr,
@@ -643,8 +642,8 @@ static int handle_free_generic_req(void *req_h, void *req, void *conn_h)
&attrs);
free_client(client_id);
} else {
- pr_err("In %s, Request came for a guaranteed client cannot free up the memory\n",
- __func__);
+ pr_err("In %s, Request came for a guaranteed client(client_id: %d) cannot free up the memory\n",
+ __func__, client_id);
}
if (flag) {
@@ -947,6 +946,10 @@ static int memshare_child_probe(struct platform_device *pdev)
pdev->dev.of_node,
"qcom,allocate-boot-time");
+ memblock[num_clients].client_request = of_property_read_bool(
+ pdev->dev.of_node,
+ "qcom,allocate-on-request");
+
rc = of_property_read_string(pdev->dev.of_node, "label",
&name);
if (rc) {
diff --git a/drivers/soc/qcom/memshare/msm_memshare.h b/drivers/soc/qcom/memshare/msm_memshare.h
index c7123fb1314b..8a8657674fcf 100644
--- a/drivers/soc/qcom/memshare/msm_memshare.h
+++ b/drivers/soc/qcom/memshare/msm_memshare.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -39,6 +39,8 @@ struct mem_blocks {
uint32_t guarantee;
/* Memory alloted or not */
uint32_t alloted;
+ /* Allocation on request from a client*/
+ uint32_t client_request;
/* Size required for client */
uint32_t size;
/*
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
index 635a93cc94de..eed7603db5ec 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
@@ -700,7 +700,7 @@ repeat_fid2path:
memmove(ptr + strlen(gf->gf_path) + 1, ptr,
strlen(ori_gf->gf_path));
- strncpy(ptr, gf->gf_path, strlen(gf->gf_path));
+ strcpy(ptr, gf->gf_path);
ptr += strlen(gf->gf_path);
*ptr = '/';
}
diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c
index 9a876ce92dbd..dc91cd29f1d2 100644
--- a/drivers/staging/rts5208/sd.c
+++ b/drivers/staging/rts5208/sd.c
@@ -4165,12 +4165,6 @@ RTY_SEND_CMD:
rtsx_trace(chip);
return STATUS_FAIL;
}
-
- } else if (rsp_type == SD_RSP_TYPE_R0) {
- if ((ptr[3] & 0x1E) != 0x03) {
- rtsx_trace(chip);
- return STATUS_FAIL;
- }
}
}
}
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index b1ec202099b2..b74de014cef1 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -165,15 +165,29 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x,
return put_user(x, ptr);
}
+/* If we are not echoing the data, perhaps this is a secret so erase it */
+static inline void zero_buffer(struct tty_struct *tty, u8 *buffer, int size)
+{
+ bool icanon = !!L_ICANON(tty);
+ bool no_echo = !L_ECHO(tty);
+
+ if (icanon && no_echo)
+ memset(buffer, 0x00, size);
+}
+
static inline int tty_copy_to_user(struct tty_struct *tty,
void __user *to,
- const void *from,
+ void *from,
unsigned long n)
{
struct n_tty_data *ldata = tty->disc_data;
+ int retval;
tty_audit_add_data(tty, from, n, ldata->icanon);
- return copy_to_user(to, from, n);
+ retval = copy_to_user(to, from, n);
+ if (!retval)
+ zero_buffer(tty, from, n);
+ return retval;
}
/**
@@ -2005,6 +2019,7 @@ static int copy_from_read_buf(struct tty_struct *tty,
is_eof = n == 1 && read_buf(ldata, tail) == EOF_CHAR(tty);
tty_audit_add_data(tty, read_buf_addr(ldata, tail), n,
ldata->icanon);
+ zero_buffer(tty, read_buf_addr(ldata, tail), n);
smp_store_release(&ldata->read_tail, ldata->read_tail + n);
/* Turn single EOF into zero-length read */
if (L_EXTPROC(tty) && ldata->icanon && is_eof &&
diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c
index 78883ca64ddd..035810bbcd02 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -231,17 +231,17 @@ static int mtk8250_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, data);
- pm_runtime_enable(&pdev->dev);
- if (!pm_runtime_enabled(&pdev->dev)) {
- err = mtk8250_runtime_resume(&pdev->dev);
- if (err)
- return err;
- }
+ err = mtk8250_runtime_resume(&pdev->dev);
+ if (err)
+ return err;
data->line = serial8250_register_8250_port(&uart);
if (data->line < 0)
return data->line;
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+
return 0;
}
@@ -252,13 +252,11 @@ static int mtk8250_remove(struct platform_device *pdev)
pm_runtime_get_sync(&pdev->dev);
serial8250_unregister_port(data->line);
+ mtk8250_runtime_suspend(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
- if (!pm_runtime_status_suspended(&pdev->dev))
- mtk8250_runtime_suspend(&pdev->dev);
-
return 0;
}
diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
index 2db68dfe497d..f2b0d8cee8ef 100644
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -131,24 +131,6 @@ static void kgdboc_unregister_kbd(void)
#define kgdboc_restore_input()
#endif /* ! CONFIG_KDB_KEYBOARD */
-static int kgdboc_option_setup(char *opt)
-{
- if (!opt) {
- pr_err("kgdboc: config string not provided\n");
- return -EINVAL;
- }
-
- if (strlen(opt) >= MAX_CONFIG_LEN) {
- printk(KERN_ERR "kgdboc: config string too long\n");
- return -ENOSPC;
- }
- strcpy(config, opt);
-
- return 0;
-}
-
-__setup("kgdboc=", kgdboc_option_setup);
-
static void cleanup_kgdboc(void)
{
if (kgdb_unregister_nmi_console())
@@ -162,15 +144,13 @@ static int configure_kgdboc(void)
{
struct tty_driver *p;
int tty_line = 0;
- int err;
+ int err = -ENODEV;
char *cptr = config;
struct console *cons;
- err = kgdboc_option_setup(config);
- if (err || !strlen(config) || isspace(config[0]))
+ if (!strlen(config) || isspace(config[0]))
goto noconfig;
- err = -ENODEV;
kgdboc_io_ops.is_console = 0;
kgdb_tty_driver = NULL;
@@ -252,7 +232,7 @@ static void kgdboc_put_char(u8 chr)
static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp)
{
- int len = strlen(kmessage);
+ size_t len = strlen(kmessage);
if (len >= MAX_CONFIG_LEN) {
printk(KERN_ERR "kgdboc: config string too long\n");
@@ -274,7 +254,7 @@ static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp)
strcpy(config, kmessage);
/* Chop out \n char as a result of echo */
- if (config[len - 1] == '\n')
+ if (len && config[len - 1] == '\n')
config[len - 1] = '\0';
if (configured == 1)
@@ -318,6 +298,25 @@ static struct kgdb_io kgdboc_io_ops = {
};
#ifdef CONFIG_KGDB_SERIAL_CONSOLE
+static int kgdboc_option_setup(char *opt)
+{
+ if (!opt) {
+ pr_err("config string not provided\n");
+ return -EINVAL;
+ }
+
+ if (strlen(opt) >= MAX_CONFIG_LEN) {
+ pr_err("config string too long\n");
+ return -ENOSPC;
+ }
+ strcpy(config, opt);
+
+ return 0;
+}
+
+__setup("kgdboc=", kgdboc_option_setup);
+
+
/* This is only available if kgdboc is a built in for early debugging */
static int __init kgdboc_early_init(char *opt)
{
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index 8f3566cde3eb..355e9cad680d 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -454,6 +454,8 @@ receive_buf(struct tty_struct *tty, struct tty_buffer *head, int count)
if (count && disc->ops->receive_buf)
disc->ops->receive_buf(tty, p, f, count);
}
+ if (count > 0)
+ memset(p, 0, count);
return count;
}
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 1e25aa251c05..ab58cb3a9b6a 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2222,7 +2222,7 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
/* descriptor may appear anywhere in config */
err = __usb_get_extra_descriptor(udev->rawdescriptors[0],
le16_to_cpu(udev->config[0].desc.wTotalLength),
- USB_DT_OTG, (void **) &desc);
+ USB_DT_OTG, (void **) &desc, sizeof(*desc));
if (err || !(desc->bmAttributes & USB_OTG_HNP))
return 0;
@@ -2768,7 +2768,9 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
USB_PORT_FEAT_C_BH_PORT_RESET);
usb_clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_PORT_LINK_STATE);
- usb_clear_port_feature(hub->hdev, port1,
+
+ if (udev)
+ usb_clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_CONNECTION);
/*
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 1e8f68960014..cf378b1ed373 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -64,6 +64,9 @@ static const struct usb_device_id usb_quirk_list[] = {
/* Microsoft LifeCam-VX700 v2.0 */
{ USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Cherry Stream G230 2.0 (G85-231) and 3.0 (G85-232) */
+ { USB_DEVICE(0x046a, 0x0023), .driver_info = USB_QUIRK_RESET_RESUME },
+
/* Logitech HD Pro Webcams C920, C920-C, C925e and C930e */
{ USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
{ USB_DEVICE(0x046d, 0x0841), .driver_info = USB_QUIRK_DELAY_INIT },
@@ -185,6 +188,10 @@ static const struct usb_device_id usb_quirk_list[] = {
/* Midiman M-Audio Keystation 88es */
{ USB_DEVICE(0x0763, 0x0192), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* SanDisk Ultra Fit and Ultra Flair */
+ { USB_DEVICE(0x0781, 0x5583), .driver_info = USB_QUIRK_NO_LPM },
+ { USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM },
+
/* M-Systems Flash Disk Pioneers */
{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 74087b265317..d96ed8fe6442 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -726,14 +726,14 @@ EXPORT_SYMBOL(usb_get_xfer_ring_dma_addr);
*/
int __usb_get_extra_descriptor(char *buffer, unsigned size,
- unsigned char type, void **ptr)
+ unsigned char type, void **ptr, size_t minsize)
{
struct usb_descriptor_header *header;
while (size >= sizeof(struct usb_descriptor_header)) {
header = (struct usb_descriptor_header *)buffer;
- if (header->bLength < 2) {
+ if (header->bLength < 2 || header->bLength > size) {
printk(KERN_ERR
"%s: bogus descriptor, type %d length %d\n",
usbcore_name,
@@ -742,7 +742,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
return -1;
}
- if (header->bDescriptorType == type) {
+ if (header->bDescriptorType == type && header->bLength >= minsize) {
*ptr = header;
return 0;
}
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
index eb876ed96861..85f1f282c1d5 100644
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -379,11 +379,10 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd)
USB_PORT_STAT_CONNECTION) == 0)
dum_hcd->port_status |=
(USB_PORT_STAT_C_CONNECTION << 16);
- if ((dum_hcd->port_status &
- USB_PORT_STAT_ENABLE) == 1 &&
- (dum_hcd->port_status &
- USB_SS_PORT_LS_U0) == 1 &&
- dum_hcd->rh_state != DUMMY_RH_SUSPENDED)
+ if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) &&
+ (dum_hcd->port_status &
+ USB_PORT_STAT_LINK_STATE) == USB_SS_PORT_LS_U0 &&
+ dum_hcd->rh_state != DUMMY_RH_SUSPENDED)
dum_hcd->active = 1;
}
} else {
diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c
index 1db0626c8bf4..97750f162f01 100644
--- a/drivers/usb/host/hwa-hc.c
+++ b/drivers/usb/host/hwa-hc.c
@@ -654,7 +654,7 @@ static int hwahc_security_create(struct hwahc *hwahc)
top = itr + itr_size;
result = __usb_get_extra_descriptor(usb_dev->rawdescriptors[index],
le16_to_cpu(usb_dev->actconfig->desc.wTotalLength),
- USB_DT_SECURITY, (void **) &secd);
+ USB_DT_SECURITY, (void **) &secd, sizeof(*secd));
if (result == -1) {
dev_warn(dev, "BUG? WUSB host has no security descriptors\n");
return 0;
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index ca3517d462da..61da1a22b98a 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -747,7 +747,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
status |= USB_PORT_STAT_SUSPEND;
}
if ((raw_port_status & PORT_PLS_MASK) == XDEV_RESUME &&
- !DEV_SUPERSPEED_ANY(raw_port_status)) {
+ !DEV_SUPERSPEED_ANY(raw_port_status) && hcd->speed < HCD_USB3) {
if ((raw_port_status & PORT_RESET) ||
!(raw_port_status & PORT_PE))
return 0xffffffff;
@@ -793,7 +793,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
time_left = wait_for_completion_timeout(
&bus_state->rexit_done[wIndex],
msecs_to_jiffies(
- XHCI_MAX_REXIT_TIMEOUT));
+ XHCI_MAX_REXIT_TIMEOUT_MS));
spin_lock_irqsave(&xhci->lock, flags);
if (time_left) {
@@ -807,7 +807,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
} else {
int port_status = readl(port_array[wIndex]);
xhci_warn(xhci, "Port resume took longer than %i msec, port status = 0x%x\n",
- XHCI_MAX_REXIT_TIMEOUT,
+ XHCI_MAX_REXIT_TIMEOUT_MS,
port_status);
status |= USB_PORT_STAT_SUSPEND;
clear_bit(wIndex, &bus_state->rexit_ports);
@@ -1473,13 +1473,16 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
__le32 __iomem **port_array;
struct xhci_bus_state *bus_state;
unsigned long flags;
+ u32 portsc_buf[USB_MAXCHILDREN];
+ bool wake_enabled;
max_ports = xhci_get_ports(hcd, &port_array);
bus_state = &xhci->bus_state[hcd_index(hcd)];
+ wake_enabled = hcd->self.root_hub->do_remote_wakeup;
spin_lock_irqsave(&xhci->lock, flags);
- if (hcd->self.root_hub->do_remote_wakeup) {
+ if (wake_enabled) {
if (bus_state->resuming_ports || /* USB2 */
bus_state->port_remote_wakeup) { /* USB3 */
spin_unlock_irqrestore(&xhci->lock, flags);
@@ -1487,26 +1490,36 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
return -EBUSY;
}
}
-
- port_index = max_ports;
+ /*
+ * Prepare ports for suspend, but don't write anything before all ports
+ * are checked and we know bus suspend can proceed
+ */
bus_state->bus_suspended = 0;
+ port_index = max_ports;
while (port_index--) {
- /* suspend the port if the port is not suspended */
u32 t1, t2;
- int slot_id;
t1 = readl(port_array[port_index]);
t2 = xhci_port_state_to_neutral(t1);
+ portsc_buf[port_index] = 0;
- if ((t1 & PORT_PE) && !(t1 & PORT_PLS_MASK)) {
- xhci_dbg(xhci, "port %d not suspended\n", port_index);
- slot_id = xhci_find_slot_id_by_port(hcd, xhci,
- port_index + 1);
- if (slot_id) {
+ /* Bail out if a USB3 port has a new device in link training */
+ if ((t1 & PORT_PLS_MASK) == XDEV_POLLING) {
+ bus_state->bus_suspended = 0;
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ xhci_dbg(xhci, "Bus suspend bailout, port in polling\n");
+ return -EBUSY;
+ }
+
+ /* suspend ports in U0, or bail out for new connect changes */
+ if ((t1 & PORT_PE) && (t1 & PORT_PLS_MASK) == XDEV_U0) {
+ if ((t1 & PORT_CSC) && wake_enabled) {
+ bus_state->bus_suspended = 0;
spin_unlock_irqrestore(&xhci->lock, flags);
- xhci_stop_device(xhci, slot_id, 1);
- spin_lock_irqsave(&xhci->lock, flags);
+ xhci_dbg(xhci, "Bus suspend bailout, port connect change\n");
+ return -EBUSY;
}
+ xhci_dbg(xhci, "port %d not suspended\n", port_index);
t2 &= ~PORT_PLS_MASK;
t2 |= PORT_LINK_STROBE | XDEV_U3;
set_bit(port_index, &bus_state->bus_suspended);
@@ -1515,7 +1528,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
* including the USB 3.0 roothub, but only if CONFIG_PM
* is enabled, so also enable remote wake here.
*/
- if (hcd->self.root_hub->do_remote_wakeup) {
+ if (wake_enabled) {
if (t1 & PORT_CONNECT) {
t2 |= PORT_WKOC_E | PORT_WKDISC_E;
t2 &= ~PORT_WKCONN_E;
@@ -1528,7 +1541,26 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
t1 = xhci_port_state_to_neutral(t1);
if (t1 != t2)
- writel(t2, port_array[port_index]);
+ portsc_buf[port_index] = t2;
+ }
+
+ /* write port settings, stopping and suspending ports if needed */
+ port_index = max_ports;
+ while (port_index--) {
+ if (!portsc_buf[port_index])
+ continue;
+ if (test_bit(port_index, &bus_state->bus_suspended)) {
+ int slot_id;
+
+ slot_id = xhci_find_slot_id_by_port(hcd, xhci,
+ port_index + 1);
+ if (slot_id) {
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ xhci_stop_device(xhci, slot_id, 1);
+ spin_lock_irqsave(&xhci->lock, flags);
+ }
+ }
+ writel(portsc_buf[port_index], port_array[port_index]);
}
hcd->state = HC_STATE_SUSPENDED;
bus_state->next_statechange = jiffies + msecs_to_jiffies(10);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 5bfe47816ac3..e6d366d4e80b 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1673,7 +1673,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
* RExit to a disconnect state). If so, let the the driver know it's
* out of the RExit state.
*/
- if (!DEV_SUPERSPEED_ANY(temp) &&
+ if (!DEV_SUPERSPEED_ANY(temp) && hcd->speed < HCD_USB3 &&
test_and_clear_bit(faked_port_index,
&bus_state->rexit_ports)) {
complete(&bus_state->rexit_done[faked_port_index]);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index abe6d3c17047..3e11317db602 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4442,6 +4442,14 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci,
{
unsigned long long timeout_ns;
+ /* Prevent U1 if service interval is shorter than U1 exit latency */
+ if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) {
+ if (xhci_service_interval_to_ns(desc) <= udev->u1_params.mel) {
+ dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n");
+ return USB3_LPM_DISABLED;
+ }
+ }
+
if (xhci->quirks & XHCI_INTEL_HOST)
timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc);
else
@@ -4498,6 +4506,14 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci,
{
unsigned long long timeout_ns;
+ /* Prevent U2 if service interval is shorter than U2 exit latency */
+ if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) {
+ if (xhci_service_interval_to_ns(desc) <= udev->u2_params.mel) {
+ dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n");
+ return USB3_LPM_DISABLED;
+ }
+ }
+
if (xhci->quirks & XHCI_INTEL_HOST)
timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc);
else
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 72beaa47c15b..b3454c06bb0c 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1490,7 +1490,7 @@ struct xhci_bus_state {
* It can take up to 20 ms to transition from RExit to U0 on the
* Intel Lynx Point LP xHCI host.
*/
-#define XHCI_MAX_REXIT_TIMEOUT (20 * 1000)
+#define XHCI_MAX_REXIT_TIMEOUT_MS 20
static inline unsigned int hcd_index(struct usb_hcd *hcd)
{
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
index b15842c6f916..993f4da065c3 100644
--- a/drivers/usb/misc/appledisplay.c
+++ b/drivers/usb/misc/appledisplay.c
@@ -64,6 +64,7 @@ static const struct usb_device_id appledisplay_table[] = {
{ APPLEDISPLAY_DEVICE(0x921c) },
{ APPLEDISPLAY_DEVICE(0x921d) },
{ APPLEDISPLAY_DEVICE(0x9222) },
+ { APPLEDISPLAY_DEVICE(0x9226) },
{ APPLEDISPLAY_DEVICE(0x9236) },
/* Terminating entry */
diff --git a/drivers/usb/misc/diag_ipc_bridge.c b/drivers/usb/misc/diag_ipc_bridge.c
index 2ff3aa021bf8..cb3aa9375ca3 100644
--- a/drivers/usb/misc/diag_ipc_bridge.c
+++ b/drivers/usb/misc/diag_ipc_bridge.c
@@ -732,6 +732,8 @@ static const struct usb_device_id diag_bridge_ids[] = {
.driver_info = DEV_ID(0), },
{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x901D, 0),
.driver_info = DEV_ID(0), },
+ { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x901F, 0),
+ .driver_info = DEV_ID(0), },
{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9034, 0),
.driver_info = DEV_ID(0), },
{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9048, 0),
diff --git a/drivers/usb/misc/ks_bridge.c b/drivers/usb/misc/ks_bridge.c
index 4004ba0437d5..3497880dea09 100644
--- a/drivers/usb/misc/ks_bridge.c
+++ b/drivers/usb/misc/ks_bridge.c
@@ -462,6 +462,7 @@ static const struct usb_device_id ksb_usb_ids[] = {
{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9025, 0), },
{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9091, 0), },
{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x901D, 0), },
+ { USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x901F, 0), },
{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x900E, 0), },
{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9900, 0), },
{ USB_DEVICE_INTERFACE_NUMBER(0x5c6, 0x9901, 0), },
diff --git a/drivers/usb/storage/unusual_realtek.h b/drivers/usb/storage/unusual_realtek.h
index e41f50c95ed4..f5fc3271e19c 100644
--- a/drivers/usb/storage/unusual_realtek.h
+++ b/drivers/usb/storage/unusual_realtek.h
@@ -38,4 +38,14 @@ UNUSUAL_DEV(0x0bda, 0x0159, 0x0000, 0x9999,
"USB Card Reader",
USB_SC_DEVICE, USB_PR_DEVICE, init_realtek_cr, 0),
+UNUSUAL_DEV(0x0bda, 0x0177, 0x0000, 0x9999,
+ "Realtek",
+ "USB Card Reader",
+ USB_SC_DEVICE, USB_PR_DEVICE, init_realtek_cr, 0),
+
+UNUSUAL_DEV(0x0bda, 0x0184, 0x0000, 0x9999,
+ "Realtek",
+ "USB Card Reader",
+ USB_SC_DEVICE, USB_PR_DEVICE, init_realtek_cr, 0),
+
#endif /* defined(CONFIG_USB_STORAGE_REALTEK) || ... */
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index 5cc00e56206e..7d889f56b8e7 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -76,15 +76,6 @@ static inline int dt_type(struct p9_wstat *mistat)
return rettype;
}
-static void p9stat_init(struct p9_wstat *stbuf)
-{
- stbuf->name = NULL;
- stbuf->uid = NULL;
- stbuf->gid = NULL;
- stbuf->muid = NULL;
- stbuf->extension = NULL;
-}
-
/**
* v9fs_alloc_rdir_buf - Allocate buffer used for read and readdir
* @filp: opened file structure
@@ -145,12 +136,10 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
rdir->tail = n;
}
while (rdir->head < rdir->tail) {
- p9stat_init(&st);
err = p9stat_read(fid->clnt, rdir->buf + rdir->head,
rdir->tail - rdir->head, &st);
if (err) {
p9_debug(P9_DEBUG_VFS, "returned %d\n", err);
- p9stat_free(&st);
return -EIO;
}
reclen = st.size+2;
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index fdcb4d69f430..4714c55c1ae5 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -350,7 +350,8 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
s->s_magic = BFS_MAGIC;
- if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end)) {
+ if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end) ||
+ le32_to_cpu(bfs_sb->s_start) < BFS_BSIZE) {
printf("Superblock is corrupted\n");
goto out1;
}
@@ -359,9 +360,11 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
sizeof(struct bfs_inode)
+ BFS_ROOT_INO - 1;
imap_len = (info->si_lasti / 8) + 1;
- info->si_imap = kzalloc(imap_len, GFP_KERNEL);
- if (!info->si_imap)
+ info->si_imap = kzalloc(imap_len, GFP_KERNEL | __GFP_NOWARN);
+ if (!info->si_imap) {
+ printf("Cannot allocate %u bytes\n", imap_len);
goto out1;
+ }
for (i = 0; i < BFS_ROOT_INO; i++)
set_bit(i, info->si_imap);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index b0875ef48522..1f21c6c33228 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -445,9 +445,9 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root,
int mirror_num = 0;
int failed_mirror = 0;
- clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
io_tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree;
while (1) {
+ clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
ret = read_extent_buffer_pages(io_tree, eb, start,
WAIT_COMPLETE,
btree_get_extent, mirror_num);
@@ -459,14 +459,6 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root,
ret = -EIO;
}
- /*
- * This buffer's crc is fine, but its contents are corrupted, so
- * there is no reason to read the other copies, they won't be
- * any less wrong.
- */
- if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags))
- break;
-
num_copies = btrfs_num_copies(root->fs_info,
eb->start, eb->len);
if (num_copies == 1)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 80cd28456f08..13ff0fdae03e 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -10708,17 +10708,9 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range)
u64 start;
u64 end;
u64 trimmed = 0;
- u64 total_bytes = btrfs_super_total_bytes(fs_info->super_copy);
int ret = 0;
- /*
- * try to trim all FS space, our block group may start from non-zero.
- */
- if (range->len == total_bytes)
- cache = btrfs_lookup_first_block_group(fs_info, range->start);
- else
- cache = btrfs_lookup_block_group(fs_info, range->start);
-
+ cache = btrfs_lookup_first_block_group(fs_info, range->start);
while (cache) {
if (cache->key.objectid >= (range->start + range->len)) {
btrfs_put_block_group(cache);
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 1aa897dd9ce3..6c0161284a9e 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -2469,6 +2469,7 @@ void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
struct rb_node *n;
int count = 0;
+ spin_lock(&ctl->tree_lock);
for (n = rb_first(&ctl->free_space_offset); n; n = rb_next(n)) {
info = rb_entry(n, struct btrfs_free_space, offset_index);
if (info->bytes >= bytes && !block_group->ro)
@@ -2478,6 +2479,7 @@ void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
info->offset, info->bytes,
(info->bitmap) ? "yes" : "no");
}
+ spin_unlock(&ctl->tree_lock);
btrfs_info(block_group->fs_info, "block group has cluster?: %s",
list_empty(&block_group->cluster_list) ? "no" : "yes");
btrfs_info(block_group->fs_info,
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 150d3c891815..3379490ce54d 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -378,7 +378,6 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)
struct fstrim_range range;
u64 minlen = ULLONG_MAX;
u64 num_devices = 0;
- u64 total_bytes = btrfs_super_total_bytes(fs_info->super_copy);
int ret;
if (!capable(CAP_SYS_ADMIN))
@@ -402,11 +401,15 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)
return -EOPNOTSUPP;
if (copy_from_user(&range, arg, sizeof(range)))
return -EFAULT;
- if (range.start > total_bytes ||
- range.len < fs_info->sb->s_blocksize)
+
+ /*
+ * NOTE: Don't truncate the range using super->total_bytes. Bytenr of
+ * block group is in the logical address space, which can be any
+ * sectorsize aligned bytenr in the range [0, U64_MAX].
+ */
+ if (range.len < fs_info->sb->s_blocksize)
return -EINVAL;
- range.len = min(range.len, total_bytes - range.start);
range.minlen = max(range.minlen, minlen);
ret = btrfs_trim_fs(fs_info->tree_root, &range);
if (ret < 0)
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 3bd2233737ac..0f99336c37eb 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -2104,6 +2104,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
vol = memdup_user((void __user *)arg, sizeof(*vol));
if (IS_ERR(vol))
return PTR_ERR(vol);
+ vol->name[BTRFS_PATH_NAME_MAX] = '\0';
switch (cmd) {
case BTRFS_IOC_SCAN_DEV:
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index be8eae80ff65..098016338f98 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1821,6 +1821,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
return ret;
}
+ btrfs_trans_release_metadata(trans, root);
+ trans->block_rsv = NULL;
+
/* make a pass through all the delayed refs we have so far
* any runnings procs may add more while we are here
*/
@@ -1830,9 +1833,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
return ret;
}
- btrfs_trans_release_metadata(trans, root);
- trans->block_rsv = NULL;
-
cur_trans = trans->transaction;
/*
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 76dacd5307b9..afd317eb9db9 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -163,7 +163,7 @@ cifs_bp_rename_retry:
cifs_dbg(FYI, "using cifs_sb prepath <%s>\n", cifs_sb->prepath);
memcpy(full_path+dfsplen+1, cifs_sb->prepath, pplen-1);
- full_path[dfsplen] = '\\';
+ full_path[dfsplen] = dirsep;
for (i = 0; i < pplen-1; i++)
if (full_path[dfsplen+1+i] == '/')
full_path[dfsplen+1+i] = CIFS_DIR_SEP(cifs_sb);
diff --git a/fs/exec.c b/fs/exec.c
index 0428c34d4773..6bbea71c6d92 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1077,15 +1077,14 @@ killed:
return -EAGAIN;
}
-char *get_task_comm(char *buf, struct task_struct *tsk)
+char *__get_task_comm(char *buf, size_t buf_size, struct task_struct *tsk)
{
- /* buf must be at least sizeof(tsk->comm) in size */
task_lock(tsk);
- strncpy(buf, tsk->comm, sizeof(tsk->comm));
+ strncpy(buf, tsk->comm, buf_size);
task_unlock(tsk);
return buf;
}
-EXPORT_SYMBOL_GPL(get_task_comm);
+EXPORT_SYMBOL_GPL(__get_task_comm);
/*
* These functions flushes out all traces of the currently running executable
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
index 24736c8b3d51..e66047d6943f 100644
--- a/fs/ext2/xattr.c
+++ b/fs/ext2/xattr.c
@@ -606,9 +606,9 @@ skip_replace:
}
cleanup:
- brelse(bh);
if (!(bh && header == HDR(bh)))
kfree(header);
+ brelse(bh);
up_write(&EXT2_I(inode)->xattr_sem);
return error;
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index ad23a9257418..9e3f3224e54a 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -71,13 +71,13 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
if (!sdp)
return NULL;
- sb->s_fs_info = sdp;
sdp->sd_vfs = sb;
sdp->sd_lkstats = alloc_percpu(struct gfs2_pcpu_lkstats);
if (!sdp->sd_lkstats) {
kfree(sdp);
return NULL;
}
+ sb->s_fs_info = sdp;
set_bit(SDF_NOJOURNALID, &sdp->sd_flags);
gfs2_tune_init(&sdp->sd_tune);
diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c
index db272528ab5b..b3b293e2c099 100644
--- a/fs/kernfs/symlink.c
+++ b/fs/kernfs/symlink.c
@@ -88,7 +88,7 @@ static int kernfs_get_target_path(struct kernfs_node *parent,
int slen = strlen(kn->name);
len -= slen;
- strncpy(s + len, kn->name, slen);
+ memcpy(s + len, kn->name, slen);
if (len)
s[--len] = '/';
diff --git a/fs/namei.c b/fs/namei.c
index ea6050b6134a..57f030641306 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -884,6 +884,8 @@ static inline void put_link(struct nameidata *nd)
int sysctl_protected_symlinks __read_mostly = 0;
int sysctl_protected_hardlinks __read_mostly = 0;
+int sysctl_protected_fifos __read_mostly;
+int sysctl_protected_regular __read_mostly;
/**
* may_follow_link - Check symlink following for unsafe situations
@@ -997,6 +999,45 @@ static int may_linkat(struct path *link)
return -EPERM;
}
+/**
+ * may_create_in_sticky - Check whether an O_CREAT open in a sticky directory
+ * should be allowed, or not, on files that already
+ * exist.
+ * @dir: the sticky parent directory
+ * @inode: the inode of the file to open
+ *
+ * Block an O_CREAT open of a FIFO (or a regular file) when:
+ * - sysctl_protected_fifos (or sysctl_protected_regular) is enabled
+ * - the file already exists
+ * - we are in a sticky directory
+ * - we don't own the file
+ * - the owner of the directory doesn't own the file
+ * - the directory is world writable
+ * If the sysctl_protected_fifos (or sysctl_protected_regular) is set to 2
+ * the directory doesn't have to be world writable: being group writable will
+ * be enough.
+ *
+ * Returns 0 if the open is allowed, -ve on error.
+ */
+static int may_create_in_sticky(struct dentry * const dir,
+ struct inode * const inode)
+{
+ if ((!sysctl_protected_fifos && S_ISFIFO(inode->i_mode)) ||
+ (!sysctl_protected_regular && S_ISREG(inode->i_mode)) ||
+ likely(!(dir->d_inode->i_mode & S_ISVTX)) ||
+ uid_eq(inode->i_uid, dir->d_inode->i_uid) ||
+ uid_eq(current_fsuid(), inode->i_uid))
+ return 0;
+
+ if (likely(dir->d_inode->i_mode & 0002) ||
+ (dir->d_inode->i_mode & 0020 &&
+ ((sysctl_protected_fifos >= 2 && S_ISFIFO(inode->i_mode)) ||
+ (sysctl_protected_regular >= 2 && S_ISREG(inode->i_mode))))) {
+ return -EACCES;
+ }
+ return 0;
+}
+
static __always_inline
const char *get_link(struct nameidata *nd)
{
@@ -3204,9 +3245,15 @@ finish_open:
error = -ELOOP;
goto out;
}
- error = -EISDIR;
- if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry))
- goto out;
+ if (open_flag & O_CREAT) {
+ error = -EISDIR;
+ if (d_is_dir(nd->path.dentry))
+ goto out;
+ error = may_create_in_sticky(dir,
+ d_backing_inode(nd->path.dentry));
+ if (unlikely(error))
+ goto out;
+ }
error = -ENOTDIR;
if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry))
goto out;
diff --git a/fs/sdcardfs/derived_perm.c b/fs/sdcardfs/derived_perm.c
index 85126ec6533c..1f142fed5a5e 100644
--- a/fs/sdcardfs/derived_perm.c
+++ b/fs/sdcardfs/derived_perm.c
@@ -62,6 +62,7 @@ void get_derived_permission_new(struct dentry *parent, struct dentry *dentry,
int err;
struct qstr q_Android = QSTR_LITERAL("Android");
struct qstr q_data = QSTR_LITERAL("data");
+ struct qstr q_sandbox = QSTR_LITERAL("sandbox");
struct qstr q_obb = QSTR_LITERAL("obb");
struct qstr q_media = QSTR_LITERAL("media");
struct qstr q_cache = QSTR_LITERAL("cache");
@@ -110,6 +111,9 @@ void get_derived_permission_new(struct dentry *parent, struct dentry *dentry,
if (qstr_case_eq(name, &q_data)) {
/* App-specific directories inside; let anyone traverse */
info->data->perm = PERM_ANDROID_DATA;
+ } else if (qstr_case_eq(name, &q_sandbox)) {
+ /* App-specific directories inside; let anyone traverse */
+ info->data->perm = PERM_ANDROID_DATA;
} else if (qstr_case_eq(name, &q_obb)) {
/* App-specific directories inside; let anyone traverse */
info->data->perm = PERM_ANDROID_OBB;
@@ -356,7 +360,8 @@ int need_graft_path(struct dentry *dentry)
struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
struct qstr obb = QSTR_LITERAL("obb");
- if (parent_info->data->perm == PERM_ANDROID &&
+ if (!sbi->options.unshared_obb &&
+ parent_info->data->perm == PERM_ANDROID &&
qstr_case_eq(&dentry->d_name, &obb)) {
/* /Android/obb is the base obbpath of DERIVED_UNIFIED */
diff --git a/fs/sdcardfs/main.c b/fs/sdcardfs/main.c
index 3151ec9cf7e9..6e44903b3d2f 100644
--- a/fs/sdcardfs/main.c
+++ b/fs/sdcardfs/main.c
@@ -35,6 +35,7 @@ enum {
Opt_gid_derivation,
Opt_default_normal,
Opt_nocache,
+ Opt_unshared_obb,
Opt_err,
};
@@ -48,6 +49,7 @@ static const match_table_t sdcardfs_tokens = {
{Opt_multiuser, "multiuser"},
{Opt_gid_derivation, "derive_gid"},
{Opt_default_normal, "default_normal"},
+ {Opt_unshared_obb, "unshared_obb"},
{Opt_reserved_mb, "reserved_mb=%u"},
{Opt_nocache, "nocache"},
{Opt_err, NULL}
@@ -134,6 +136,9 @@ static int parse_options(struct super_block *sb, char *options, int silent,
case Opt_nocache:
opts->nocache = true;
break;
+ case Opt_unshared_obb:
+ opts->unshared_obb = true;
+ break;
/* unknown option */
default:
if (!silent)
@@ -187,13 +192,16 @@ int parse_options_remount(struct super_block *sb, char *options, int silent,
return 0;
vfsopts->mask = option;
break;
+ case Opt_unshared_obb:
case Opt_default_normal:
case Opt_multiuser:
case Opt_userid:
case Opt_fsuid:
case Opt_fsgid:
case Opt_reserved_mb:
- pr_warn("Option \"%s\" can't be changed during remount\n", p);
+ case Opt_gid_derivation:
+ if (!silent)
+ pr_warn("Option \"%s\" can't be changed during remount\n", p);
break;
/* unknown option */
default:
diff --git a/fs/sdcardfs/sdcardfs.h b/fs/sdcardfs/sdcardfs.h
index 57be4761d32b..2bee162921ce 100644
--- a/fs/sdcardfs/sdcardfs.h
+++ b/fs/sdcardfs/sdcardfs.h
@@ -197,6 +197,7 @@ struct sdcardfs_mount_options {
bool multiuser;
bool gid_derivation;
bool default_normal;
+ bool unshared_obb;
unsigned int reserved_mb;
bool nocache;
};
diff --git a/include/dt-bindings/pinctrl/qcom,pmic-gpio.h b/include/dt-bindings/pinctrl/qcom,pmic-gpio.h
index 64e2dc7183f3..7ac6f1631098 100644
--- a/include/dt-bindings/pinctrl/qcom,pmic-gpio.h
+++ b/include/dt-bindings/pinctrl/qcom,pmic-gpio.h
@@ -11,9 +11,14 @@
#define PMIC_GPIO_PULL_UP_1P5_30 3
#define PMIC_GPIO_STRENGTH_NO 0
-#define PMIC_GPIO_STRENGTH_HIGH 1
+#define PMIC_GPIO_STRENGTH_LOW 1
#define PMIC_GPIO_STRENGTH_MED 2
-#define PMIC_GPIO_STRENGTH_LOW 3
+#define PMIC_GPIO_STRENGTH_HIGH 3
+
+#define PM8921_GPIO_STRENGTH_NO 0
+#define PM8921_GPIO_STRENGTH_HIGH 1
+#define PM8921_GPIO_STRENGTH_MED 2
+#define PM8921_GPIO_STRENGTH_LOW 3
/*
* Note: PM8018 GPIO3 and GPIO4 are supporting
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 5f5270941ba0..f7178f44825b 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -154,6 +154,7 @@ void can_change_state(struct net_device *dev, struct can_frame *cf,
void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
unsigned int idx);
+struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr);
unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx);
void can_free_echo_skb(struct net_device *dev, unsigned int idx);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f5f4e7871865..ffa1033ad1ce 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -68,6 +68,8 @@ extern struct inodes_stat_t inodes_stat;
extern int leases_enable, lease_break_time;
extern int sysctl_protected_symlinks;
extern int sysctl_protected_hardlinks;
+extern int sysctl_protected_fifos;
+extern int sysctl_protected_regular;
struct buffer_head;
typedef int (get_block_t)(struct inode *inode, sector_t iblock,
diff --git a/include/linux/of.h b/include/linux/of.h
index dd10626a615f..d9371c9cd88a 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -265,6 +265,8 @@ extern struct device_node *of_get_next_child(const struct device_node *node,
extern struct device_node *of_get_next_available_child(
const struct device_node *node, struct device_node *prev);
+extern struct device_node *of_get_compatible_child(const struct device_node *parent,
+ const char *compatible);
extern struct device_node *of_get_child_by_name(const struct device_node *node,
const char *name);
@@ -462,6 +464,12 @@ static inline bool of_have_populated_dt(void)
return false;
}
+static inline struct device_node *of_get_compatible_child(const struct device_node *parent,
+ const char *compatible)
+{
+ return NULL;
+}
+
static inline struct device_node *of_get_child_by_name(
const struct device_node *node,
const char *name)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 8f6894c6e83c..ded334b5cf8d 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -3082,7 +3082,12 @@ static inline void set_task_comm(struct task_struct *tsk, const char *from)
{
__set_task_comm(tsk, from, false);
}
-extern char *get_task_comm(char *to, struct task_struct *tsk);
+
+extern char *__get_task_comm(char *to, size_t len, struct task_struct *tsk);
+#define get_task_comm(buf, tsk) ({ \
+ BUILD_BUG_ON(sizeof(buf) != TASK_COMM_LEN); \
+ __get_task_comm(buf, sizeof(buf), tsk); \
+})
#ifdef CONFIG_SMP
void scheduler_ipi(void);
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index 5a53d34bba26..50c460a956f1 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -29,19 +29,13 @@ struct seccomp {
};
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
-extern int __secure_computing(void);
-static inline int secure_computing(void)
+extern int __secure_computing(const struct seccomp_data *sd);
+static inline int secure_computing(const struct seccomp_data *sd)
{
if (unlikely(test_thread_flag(TIF_SECCOMP)))
- return __secure_computing();
+ return __secure_computing(sd);
return 0;
}
-
-#define SECCOMP_PHASE1_OK 0
-#define SECCOMP_PHASE1_SKIP 1
-
-extern u32 seccomp_phase1(struct seccomp_data *sd);
-int seccomp_phase2(u32 phase1_result);
#else
extern void secure_computing_strict(int this_syscall);
#endif
@@ -62,7 +56,7 @@ struct seccomp { };
struct seccomp_filter { };
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
-static inline int secure_computing(void) { return 0; }
+static inline int secure_computing(struct seccomp_data *sd) { return 0; }
#else
static inline void secure_computing_strict(int this_syscall) { return; }
#endif
diff --git a/include/linux/usb.h b/include/linux/usb.h
index d88c31c8e6a4..e27df29a298e 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -336,11 +336,11 @@ struct usb_host_bos {
};
int __usb_get_extra_descriptor(char *buffer, unsigned size,
- unsigned char type, void **ptr);
+ unsigned char type, void **ptr, size_t min);
#define usb_get_extra_descriptor(ifpoint, type, ptr) \
__usb_get_extra_descriptor((ifpoint)->extra, \
(ifpoint)->extralen, \
- type, (void **)ptr)
+ type, (void **)ptr, sizeof(**(ptr)))
/* ----------------------------------------------------------------------- */
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 48fe32252e8d..89e05abfd74b 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -1489,11 +1489,35 @@ struct adm_cmd_connect_afe_port_v5 {
#define AFE_PORT_ID_PRIMARY_MI2S_RX 0x1000
#define AFE_PORT_ID_PRIMARY_MI2S_TX 0x1001
#define AFE_PORT_ID_SECONDARY_MI2S_RX 0x1002
+#define AFE_PORT_ID_SECONDARY_MI2S_RX_1 0x1040
+#define AFE_PORT_ID_SECONDARY_MI2S_RX_2 0x1042
+#define AFE_PORT_ID_SECONDARY_MI2S_RX_3 0x1044
+#define AFE_PORT_ID_SECONDARY_MI2S_RX_4 0x1046
#define AFE_PORT_ID_SECONDARY_MI2S_TX 0x1003
+#define AFE_PORT_ID_SECONDARY_MI2S_TX_1 0x1041
+#define AFE_PORT_ID_SECONDARY_MI2S_TX_2 0x1043
+#define AFE_PORT_ID_SECONDARY_MI2S_TX_3 0x1045
+#define AFE_PORT_ID_SECONDARY_MI2S_TX_4 0x1047
#define AFE_PORT_ID_TERTIARY_MI2S_RX 0x1004
+#define AFE_PORT_ID_TERTIARY_MI2S_RX_1 0x1048
+#define AFE_PORT_ID_TERTIARY_MI2S_RX_2 0x104A
+#define AFE_PORT_ID_TERTIARY_MI2S_RX_3 0x104C
+#define AFE_PORT_ID_TERTIARY_MI2S_RX_4 0x104E
#define AFE_PORT_ID_TERTIARY_MI2S_TX 0x1005
+#define AFE_PORT_ID_TERTIARY_MI2S_TX_1 0x1049
+#define AFE_PORT_ID_TERTIARY_MI2S_TX_2 0x104B
+#define AFE_PORT_ID_TERTIARY_MI2S_TX_3 0x104D
+#define AFE_PORT_ID_TERTIARY_MI2S_TX_4 0x104F
#define AFE_PORT_ID_QUATERNARY_MI2S_RX 0x1006
+#define AFE_PORT_ID_QUATERNARY_MI2S_RX_1 0x1020
+#define AFE_PORT_ID_QUATERNARY_MI2S_RX_2 0x1022
+#define AFE_PORT_ID_QUATERNARY_MI2S_RX_3 0x1024
+#define AFE_PORT_ID_QUATERNARY_MI2S_RX_4 0x1026
#define AFE_PORT_ID_QUATERNARY_MI2S_TX 0x1007
+#define AFE_PORT_ID_QUATERNARY_MI2S_TX_1 0x1021
+#define AFE_PORT_ID_QUATERNARY_MI2S_TX_2 0x1023
+#define AFE_PORT_ID_QUATERNARY_MI2S_TX_3 0x1025
+#define AFE_PORT_ID_QUATERNARY_MI2S_TX_4 0x1027
#define AUDIO_PORT_ID_I2S_RX 0x1008
#define AFE_PORT_ID_DIGITAL_MIC_TX 0x1009
#define AFE_PORT_ID_PRIMARY_PCM_RX 0x100A
@@ -10886,6 +10910,7 @@ struct afe_port_cmd_set_aanc_acdb_table {
#define AFE_PARAM_ID_GROUP_DEVICE_CFG 0x00010255
#define AFE_PARAM_ID_GROUP_DEVICE_ENABLE 0x00010256
#define AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX 0x1102
+#define AFE_PARAM_ID_GROUP_DEVICE_I2S_CONFIG 0x00010286
/* Payload of the #AFE_PARAM_ID_GROUP_DEVICE_CFG
* parameter, which configures max of 8 AFE ports
@@ -11069,6 +11094,119 @@ struct afe_param_id_group_device_tdm_cfg {
@values 1 to 2^32 -1 */
} __packed;
+#define AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_TX \
+ (AFE_PORT_ID_SECONDARY_MI2S_TX + 0x100)
+#define AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_RX \
+ (AFE_PORT_ID_TERTIARY_MI2S_RX + 0x100)
+#define AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_TX \
+ (AFE_PORT_ID_TERTIARY_MI2S_TX + 0x100)
+#define AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_RX \
+ (AFE_PORT_ID_QUATERNARY_MI2S_RX + 0x100)
+#define AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_TX \
+ (AFE_PORT_ID_QUATERNARY_MI2S_TX + 0x100)
+
+#define AFE_API_VERSION_GROUP_DEVICE_I2S_CONFIG 0x1
+
+/* Payload of the AFE_PARAM_ID_GROUP_DEVICE_I2S_CONFIG parameter ID
+* used by AFE_MODULE_GROUP_DEVICE.
+*/
+struct afe_param_id_group_device_i2s_cfg_v1 {
+ u32 minor_version;
+ /**< Minor version used to track group device configuration.
+ * @values #AFE_API_VERSION_GROUP_DEVICE_I2S_CONFIG
+ */
+
+ u16 group_id;
+ /**< ID for the group device.
+ * @values
+ * - #AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX
+ * - #AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_TX
+ * - #AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_RX
+ * - #AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_TX
+ * - #AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_RX
+ * - #AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_RX
+ */
+
+ u16 channel_mode;
+ /**< Group line channel mode
+ * @values
+ * - #AFE_PORT_I2S_SD0
+ * - #AFE_PORT_I2S_SD1
+ * - #AFE_PORT_I2S_SD2
+ * - #AFE_PORT_I2S_SD3
+ * - #AFE_PORT_I2S_QUAD01
+ * - #AFE_PORT_I2S_QUAD23
+ * - #AFE_PORT_I2S_6CHS
+ * - #AFE_PORT_I2S_8CHS
+ */
+
+ u32 sample_rate;
+ /**< Sampling rate of the port.
+ * @values
+ * - #AFE_PORT_SAMPLE_RATE_8K
+ * - #AFE_PORT_SAMPLE_RATE_16K
+ * - #AFE_PORT_SAMPLE_RATE_24K
+ * - #AFE_PORT_SAMPLE_RATE_32K
+ */
+
+ u16 port_id[AFE_GROUP_DEVICE_NUM_PORTS];
+ /**< Array of member port IDs of this group.
+ * @values
+ * - #AFE_PORT_ID_SECONDARY_MI2S_RX_1
+ * - #AFE_PORT_ID_SECONDARY_MI2S_RX_2
+ * - #AFE_PORT_ID_SECONDARY_MI2S_RX_3
+ * - #AFE_PORT_ID_SECONDARY_MI2S_RX_4
+
+ * - #AFE_PORT_ID_SECONDARY_MI2S_TX_1
+ * - #AFE_PORT_ID_SECONDARY_MI2S_TX_2
+ * - #AFE_PORT_ID_SECONDARY_MI2S_TX_3
+ * - #AFE_PORT_ID_SECONDARY_MI2S_TX_4
+
+ * - #AFE_PORT_ID_TERTIARY_MI2S_RX_1
+ * - #AFE_PORT_ID_TERTIARY_MI2S_RX_2
+ * - #AFE_PORT_ID_TERTIARY_MI2S_RX_3
+ * - #AFE_PORT_ID_TERTIARY_MI2S_RX_4
+
+ * - #AFE_PORT_ID_TERTIARY_MI2S_TX_1
+ * - #AFE_PORT_ID_TERTIARY_MI2S_TX_2
+ * - #AFE_PORT_ID_TERTIARY_MI2S_TX_3
+ * - #AFE_PORT_ID_TERTIARY_MI2S_TX_4
+
+ * - #AFE_PORT_ID_QUATERNARY_MI2S_RX_1
+ * - #AFE_PORT_ID_QUATERNARY_MI2S_RX_2
+ * - #AFE_PORT_ID_QUATERNARY_MI2S_RX_3
+ * - #AFE_PORT_ID_QUATERNARY_MI2S_RX_4
+
+ * - #AFE_PORT_ID_QUATERNARY_MI2S_TX_1
+ * - #AFE_PORT_ID_QUATERNARY_MI2S_TX_2
+ * - #AFE_PORT_ID_QUATERNARY_MI2S_TX_3
+ * - #AFE_PORT_ID_QUATERNARY_MI2S_TX_4
+ * @tablebulletend
+ */
+
+ u16 bit_width;
+ /**< Bit width of the sample.
+ * @values 16, 24, (32)
+ */
+
+ u16 reserved;
+} __packed;
+
+struct afe_param_id_group_device_enable {
+ u16 group_id;
+ u16 enable;
+} __packed;
+
+union afe_port_group_mi2s_config {
+ struct afe_param_id_group_device_i2s_cfg_v1 i2s_cfg;
+ struct afe_param_id_group_device_enable group_enable;
+} __packed;
+
+struct afe_i2s_port_config {
+ struct afe_param_id_i2s_cfg i2s_cfg;
+ struct afe_param_id_slot_mapping_cfg slot_mapping;
+} __packed;
+
/* Payload of the #AFE_PARAM_ID_GROUP_DEVICE_ENABLE
* parameter, which enables or
* disables any module.
diff --git a/include/sound/pcm_params.h b/include/sound/pcm_params.h
index 747c94a9a3d6..91f6abfb2ce0 100644
--- a/include/sound/pcm_params.h
+++ b/include/sound/pcm_params.h
@@ -251,11 +251,13 @@ static inline int snd_interval_empty(const struct snd_interval *i)
static inline int snd_interval_single(const struct snd_interval *i)
{
return (i->min == i->max ||
- (i->min + 1 == i->max && i->openmax));
+ (i->min + 1 == i->max && (i->openmin || i->openmax)));
}
static inline int snd_interval_value(const struct snd_interval *i)
{
+ if (i->openmin && !i->openmax)
+ return i->max;
return i->min;
}
diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h
index cdbf97023f66..a6d697d6a8f8 100644
--- a/include/sound/q6afe-v2.h
+++ b/include/sound/q6afe-v2.h
@@ -208,6 +208,33 @@ enum {
IDX_AFE_PORT_ID_INT5_MI2S_TX,
IDX_AFE_PORT_ID_INT6_MI2S_RX,
IDX_AFE_PORT_ID_INT6_MI2S_TX,
+ /* IDX 143 -> 150 */
+ IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_1,
+ IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_2,
+ IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_3,
+ IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_4,
+ IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_1,
+ IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_2,
+ IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_3,
+ IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_4,
+ /* IDX 151 -> 158 */
+ IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_1,
+ IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_2,
+ IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_3,
+ IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_4,
+ IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_1,
+ IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_2,
+ IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_3,
+ IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_4,
+ /* IDX 159 -> 166 */
+ IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_1,
+ IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_2,
+ IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_3,
+ IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_4,
+ IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_1,
+ IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_2,
+ IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_3,
+ IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_4,
AFE_MAX_PORTS
};
@@ -292,6 +319,44 @@ enum {
IDX_GROUP_TDM_MAX,
};
+enum {
+ IDX_SECONDARY_MI2S_RX_1,
+ IDX_SECONDARY_MI2S_RX_2,
+ IDX_SECONDARY_MI2S_RX_3,
+ IDX_SECONDARY_MI2S_RX_4,
+ IDX_SECONDARY_MI2S_TX_1,
+ IDX_SECONDARY_MI2S_TX_2,
+ IDX_SECONDARY_MI2S_TX_3,
+ IDX_SECONDARY_MI2S_TX_4,
+ IDX_TERTIARY_MI2S_RX_1,
+ IDX_TERTIARY_MI2S_RX_2,
+ IDX_TERTIARY_MI2S_RX_3,
+ IDX_TERTIARY_MI2S_RX_4,
+ IDX_TERTIARY_MI2S_TX_1,
+ IDX_TERTIARY_MI2S_TX_2,
+ IDX_TERTIARY_MI2S_TX_3,
+ IDX_TERTIARY_MI2S_TX_4,
+ IDX_QUATERNARY_MI2S_RX_1,
+ IDX_QUATERNARY_MI2S_RX_2,
+ IDX_QUATERNARY_MI2S_RX_3,
+ IDX_QUATERNARY_MI2S_RX_4,
+ IDX_QUATERNARY_MI2S_TX_1,
+ IDX_QUATERNARY_MI2S_TX_2,
+ IDX_QUATERNARY_MI2S_TX_3,
+ IDX_QUATERNARY_MI2S_TX_4,
+ IDX_GROUP_MI2S_PORT_MAX,
+};
+
+enum {
+ IDX_GROUP_SECONDARY_MI2S_RX,
+ IDX_GROUP_SECONDARY_MI2S_TX,
+ IDX_GROUP_TERTIARY_MI2S_RX,
+ IDX_GROUP_TERTIARY_MI2S_TX,
+ IDX_GROUP_QUATERNARY_MI2S_RX,
+ IDX_GROUP_QUATERNARY_MI2S_TX,
+ IDX_GROUP_MI2S_MAX,
+};
+
enum afe_mad_type {
MAD_HW_NONE = 0x00,
MAD_HW_AUDIO = 0x01,
@@ -458,4 +523,9 @@ int afe_request_dma_resources(uint8_t dma_type, uint8_t num_read_dma_channels,
int afe_get_dma_idx(bool **ret_rddma_idx,
bool **ret_wrdma_idx);
int afe_release_all_dma_resources(void);
+int afe_i2s_port_start(u16 port_id, struct afe_i2s_port_config *i2s_port,
+ u32 rate, u16 num_groups);
+int afe_port_group_mi2s_enable(u16 group_id,
+ union afe_port_group_mi2s_config *afe_group_config,
+ u16 enable);
#endif /* __Q6AFE_V2_H__ */
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index 8af49bb6a9fa..d2d639ec462f 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -57,6 +57,7 @@
#define FORMAT_GEN_COMPR 0x001f
#define FORMAT_TRUEHD 0x0020
#define FORMAT_IEC61937 0x0021
+#define FORMAT_APTXHD 0x0022
#define ENCDEC_SBCBITRATE 0x0001
#define ENCDEC_IMMEDIATE_DECODE 0x0002
diff --git a/include/uapi/sound/compress_params.h b/include/uapi/sound/compress_params.h
index f4028e805cc7..6f57d4f60ce0 100644
--- a/include/uapi/sound/compress_params.h
+++ b/include/uapi/sound/compress_params.h
@@ -105,7 +105,8 @@
#define SND_AUDIOCODEC_DSD ((__u32) 0x00000021)
#define SND_AUDIOCODEC_APTX ((__u32) 0x00000022)
#define SND_AUDIOCODEC_TRUEHD ((__u32) 0x00000023)
-#define SND_AUDIOCODEC_MAX SND_AUDIOCODEC_TRUEHD
+#define SND_AUDIOCODEC_APTXHD ((__u32) 0x00000024)
+#define SND_AUDIOCODEC_MAX SND_AUDIOCODEC_APTXHD
/*
* Profile and modes are listed with bit masks. This allows for a
* more compact representation of fields that will not evolve
diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c
index 3990c1f73e45..d3c5b15c86c1 100644
--- a/kernel/debug/kdb/kdb_io.c
+++ b/kernel/debug/kdb/kdb_io.c
@@ -215,7 +215,7 @@ static char *kdb_read(char *buffer, size_t bufsize)
int count;
int i;
int diag, dtab_count;
- int key;
+ int key, buf_size, ret;
static int last_crlf;
diag = kdbgetintenv("DTABCOUNT", &dtab_count);
@@ -343,9 +343,8 @@ poll_again:
else
p_tmp = tmpbuffer;
len = strlen(p_tmp);
- count = kallsyms_symbol_complete(p_tmp,
- sizeof(tmpbuffer) -
- (p_tmp - tmpbuffer));
+ buf_size = sizeof(tmpbuffer) - (p_tmp - tmpbuffer);
+ count = kallsyms_symbol_complete(p_tmp, buf_size);
if (tab == 2 && count > 0) {
kdb_printf("\n%d symbols are found.", count);
if (count > dtab_count) {
@@ -357,9 +356,13 @@ poll_again:
}
kdb_printf("\n");
for (i = 0; i < count; i++) {
- if (WARN_ON(!kallsyms_symbol_next(p_tmp, i)))
+ ret = kallsyms_symbol_next(p_tmp, i, buf_size);
+ if (WARN_ON(!ret))
break;
- kdb_printf("%s ", p_tmp);
+ if (ret != -E2BIG)
+ kdb_printf("%s ", p_tmp);
+ else
+ kdb_printf("%s... ", p_tmp);
*(p_tmp + len) = '\0';
}
if (i >= dtab_count)
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h
index 75014d7f4568..533e04e75a9c 100644
--- a/kernel/debug/kdb/kdb_private.h
+++ b/kernel/debug/kdb/kdb_private.h
@@ -83,7 +83,7 @@ typedef struct __ksymtab {
unsigned long sym_start;
unsigned long sym_end;
} kdb_symtab_t;
-extern int kallsyms_symbol_next(char *prefix_name, int flag);
+extern int kallsyms_symbol_next(char *prefix_name, int flag, int buf_size);
extern int kallsyms_symbol_complete(char *prefix_name, int max_len);
/* Exported Symbols for kernel loadable modules to use. */
diff --git a/kernel/debug/kdb/kdb_support.c b/kernel/debug/kdb/kdb_support.c
index d35cc2d3a4cc..61cd704a21c8 100644
--- a/kernel/debug/kdb/kdb_support.c
+++ b/kernel/debug/kdb/kdb_support.c
@@ -129,13 +129,13 @@ int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab)
}
if (i >= ARRAY_SIZE(kdb_name_table)) {
debug_kfree(kdb_name_table[0]);
- memcpy(kdb_name_table, kdb_name_table+1,
+ memmove(kdb_name_table, kdb_name_table+1,
sizeof(kdb_name_table[0]) *
(ARRAY_SIZE(kdb_name_table)-1));
} else {
debug_kfree(knt1);
knt1 = kdb_name_table[i];
- memcpy(kdb_name_table+i, kdb_name_table+i+1,
+ memmove(kdb_name_table+i, kdb_name_table+i+1,
sizeof(kdb_name_table[0]) *
(ARRAY_SIZE(kdb_name_table)-i-1));
}
@@ -221,11 +221,13 @@ int kallsyms_symbol_complete(char *prefix_name, int max_len)
* Parameters:
* prefix_name prefix of a symbol name to lookup
* flag 0 means search from the head, 1 means continue search.
+ * buf_size maximum length that can be written to prefix_name
+ * buffer
* Returns:
* 1 if a symbol matches the given prefix.
* 0 if no string found
*/
-int kallsyms_symbol_next(char *prefix_name, int flag)
+int kallsyms_symbol_next(char *prefix_name, int flag, int buf_size)
{
int prefix_len = strlen(prefix_name);
static loff_t pos;
@@ -235,10 +237,8 @@ int kallsyms_symbol_next(char *prefix_name, int flag)
pos = 0;
while ((name = kdb_walk_kallsyms(&pos))) {
- if (strncmp(name, prefix_name, prefix_len) == 0) {
- strncpy(prefix_name, name, strlen(name)+1);
- return 1;
- }
+ if (!strncmp(name, prefix_name, prefix_len))
+ return strscpy(prefix_name, name, buf_size);
}
return 0;
}
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 7b1b772ab1ce..d8fc54eef51c 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -606,7 +606,7 @@ static int prepare_uprobe(struct uprobe *uprobe, struct file *file,
BUG_ON((uprobe->offset & ~PAGE_MASK) +
UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
- smp_wmb(); /* pairs with rmb() in find_active_uprobe() */
+ smp_wmb(); /* pairs with the smp_rmb() in handle_swbp() */
set_bit(UPROBE_COPY_INSN, &uprobe->flags);
out:
@@ -1891,10 +1891,18 @@ static void handle_swbp(struct pt_regs *regs)
* After we hit the bp, _unregister + _register can install the
* new and not-yet-analyzed uprobe at the same address, restart.
*/
- smp_rmb(); /* pairs with wmb() in install_breakpoint() */
if (unlikely(!test_bit(UPROBE_COPY_INSN, &uprobe->flags)))
goto out;
+ /*
+ * Pairs with the smp_wmb() in prepare_uprobe().
+ *
+ * Guarantees that if we see the UPROBE_COPY_INSN bit set, then
+ * we must also see the stores to &uprobe->arch performed by the
+ * prepare_uprobe() call.
+ */
+ smp_rmb();
+
/* Tracing handlers use ->utask to communicate with fetch methods */
if (!get_utask())
goto out;
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 6a5671bdb792..6b9021b9bc26 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4205,8 +4205,8 @@ static int __sched_setscheduler(struct task_struct *p,
int reset_on_fork;
int queue_flags = DEQUEUE_SAVE | DEQUEUE_MOVE;
- /* may grab non-irq protected spin_locks */
- BUG_ON(in_interrupt());
+ /* The pi code expects interrupts enabled */
+ BUG_ON(pi && in_interrupt());
recheck:
/* double check policy once rq lock held */
if (policy < 0) {
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 9a9203b15cde..a39f81c7e87a 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -175,7 +175,7 @@ static int seccomp_check_filter(struct sock_filter *filter, unsigned int flen)
*
* Returns valid seccomp BPF response codes.
*/
-static u32 seccomp_run_filters(struct seccomp_data *sd)
+static u32 seccomp_run_filters(const struct seccomp_data *sd)
{
struct seccomp_data sd_local;
u32 ret = SECCOMP_RET_ALLOW;
@@ -579,20 +579,10 @@ void secure_computing_strict(int this_syscall)
BUG();
}
#else
-int __secure_computing(void)
-{
- u32 phase1_result = seccomp_phase1(NULL);
-
- if (likely(phase1_result == SECCOMP_PHASE1_OK))
- return 0;
- else if (likely(phase1_result == SECCOMP_PHASE1_SKIP))
- return -1;
- else
- return seccomp_phase2(phase1_result);
-}
#ifdef CONFIG_SECCOMP_FILTER
-static u32 __seccomp_phase1_filter(int this_syscall, struct seccomp_data *sd)
+static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
+ const bool recheck_after_trace)
{
u32 filter_ret, action;
int data;
@@ -624,10 +614,50 @@ static u32 __seccomp_phase1_filter(int this_syscall, struct seccomp_data *sd)
goto skip;
case SECCOMP_RET_TRACE:
- return filter_ret; /* Save the rest for phase 2. */
+ /* We've been put in this state by the ptracer already. */
+ if (recheck_after_trace)
+ return 0;
+
+ /* ENOSYS these calls if there is no tracer attached. */
+ if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) {
+ syscall_set_return_value(current,
+ task_pt_regs(current),
+ -ENOSYS, 0);
+ goto skip;
+ }
+
+ /* Allow the BPF to provide the event message */
+ ptrace_event(PTRACE_EVENT_SECCOMP, data);
+ /*
+ * The delivery of a fatal signal during event
+ * notification may silently skip tracer notification,
+ * which could leave us with a potentially unmodified
+ * syscall that the tracer would have liked to have
+ * changed. Since the process is about to die, we just
+ * force the syscall to be skipped and let the signal
+ * kill the process and correctly handle any tracer exit
+ * notifications.
+ */
+ if (fatal_signal_pending(current))
+ goto skip;
+ /* Check if the tracer forced the syscall to be skipped. */
+ this_syscall = syscall_get_nr(current, task_pt_regs(current));
+ if (this_syscall < 0)
+ goto skip;
+
+ /*
+ * Recheck the syscall, since it may have changed. This
+ * intentionally uses a NULL struct seccomp_data to force
+ * a reload of all registers. This does not goto skip since
+ * a skip would have already been reported.
+ */
+ if (__seccomp_filter(this_syscall, NULL, true))
+ return -1;
+
+ return 0;
case SECCOMP_RET_ALLOW:
- return SECCOMP_PHASE1_OK;
+ return 0;
case SECCOMP_RET_KILL:
default:
@@ -639,96 +669,38 @@ static u32 __seccomp_phase1_filter(int this_syscall, struct seccomp_data *sd)
skip:
audit_seccomp(this_syscall, 0, action);
- return SECCOMP_PHASE1_SKIP;
+ return -1;
+}
+#else
+static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
+ const bool recheck_after_trace)
+{
+ BUG();
}
#endif
-/**
- * seccomp_phase1() - run fast path seccomp checks on the current syscall
- * @arg sd: The seccomp_data or NULL
- *
- * This only reads pt_regs via the syscall_xyz helpers. The only change
- * it will make to pt_regs is via syscall_set_return_value, and it will
- * only do that if it returns SECCOMP_PHASE1_SKIP.
- *
- * If sd is provided, it will not read pt_regs at all.
- *
- * It may also call do_exit or force a signal; these actions must be
- * safe.
- *
- * If it returns SECCOMP_PHASE1_OK, the syscall passes checks and should
- * be processed normally.
- *
- * If it returns SECCOMP_PHASE1_SKIP, then the syscall should not be
- * invoked. In this case, seccomp_phase1 will have set the return value
- * using syscall_set_return_value.
- *
- * If it returns anything else, then the return value should be passed
- * to seccomp_phase2 from a context in which ptrace hooks are safe.
- */
-u32 seccomp_phase1(struct seccomp_data *sd)
+int __secure_computing(const struct seccomp_data *sd)
{
int mode = current->seccomp.mode;
- int this_syscall = sd ? sd->nr :
- syscall_get_nr(current, task_pt_regs(current));
+ int this_syscall;
if (config_enabled(CONFIG_CHECKPOINT_RESTORE) &&
unlikely(current->ptrace & PT_SUSPEND_SECCOMP))
- return SECCOMP_PHASE1_OK;
+ return 0;
+
+ this_syscall = sd ? sd->nr :
+ syscall_get_nr(current, task_pt_regs(current));
switch (mode) {
case SECCOMP_MODE_STRICT:
__secure_computing_strict(this_syscall); /* may call do_exit */
- return SECCOMP_PHASE1_OK;
-#ifdef CONFIG_SECCOMP_FILTER
+ return 0;
case SECCOMP_MODE_FILTER:
- return __seccomp_phase1_filter(this_syscall, sd);
-#endif
+ return __seccomp_filter(this_syscall, sd, false);
default:
BUG();
}
}
-
-/**
- * seccomp_phase2() - finish slow path seccomp work for the current syscall
- * @phase1_result: The return value from seccomp_phase1()
- *
- * This must be called from a context in which ptrace hooks can be used.
- *
- * Returns 0 if the syscall should be processed or -1 to skip the syscall.
- */
-int seccomp_phase2(u32 phase1_result)
-{
- struct pt_regs *regs = task_pt_regs(current);
- u32 action = phase1_result & SECCOMP_RET_ACTION;
- int data = phase1_result & SECCOMP_RET_DATA;
-
- BUG_ON(action != SECCOMP_RET_TRACE);
-
- audit_seccomp(syscall_get_nr(current, regs), 0, action);
-
- /* Skip these calls if there is no tracer. */
- if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) {
- syscall_set_return_value(current, regs,
- -ENOSYS, 0);
- return -1;
- }
-
- /* Allow the BPF to provide the event message */
- ptrace_event(PTRACE_EVENT_SECCOMP, data);
- /*
- * The delivery of a fatal signal during event
- * notification may silently skip tracer notification.
- * Terminating the task now avoids executing a system
- * call that may not be intended.
- */
- if (fatal_signal_pending(current))
- do_exit(SIGSYS);
- if (syscall_get_nr(current, regs) < 0)
- return -1; /* Explicit request to skip. */
-
- return 0;
-}
#endif /* CONFIG_HAVE_ARCH_SECCOMP_FILTER */
long prctl_get_seccomp(void)
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 14f19af9d79a..ae30e357f554 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -2045,6 +2045,24 @@ static struct ctl_table fs_table[] = {
.extra2 = &one,
},
{
+ .procname = "protected_fifos",
+ .data = &sysctl_protected_fifos,
+ .maxlen = sizeof(int),
+ .mode = 0600,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &zero,
+ .extra2 = &two,
+ },
+ {
+ .procname = "protected_regular",
+ .data = &sysctl_protected_regular,
+ .maxlen = sizeof(int),
+ .mode = 0600,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &zero,
+ .extra2 = &two,
+ },
+ {
.procname = "suid_dumpable",
.data = &suid_dumpable,
.maxlen = sizeof(int),
diff --git a/lib/kobject.c b/lib/kobject.c
index 895edb63fba4..35d490b02cdd 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -127,7 +127,7 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length)
int cur = strlen(kobject_name(parent));
/* back up enough to print this name with '/' */
length -= cur;
- strncpy(path + length, kobject_name(parent), cur);
+ memcpy(path + length, kobject_name(parent), cur);
*(path + --length) = '/';
}
diff --git a/mm/mlock.c b/mm/mlock.c
index 206e86b98a03..966dbdcfc322 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -504,6 +504,7 @@ static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
int nr_pages;
int ret = 0;
int lock = !!(newflags & VM_LOCKED);
+ vm_flags_t old_flags = vma->vm_flags;
if (newflags == vma->vm_flags || (vma->vm_flags & VM_SPECIAL) ||
is_vm_hugetlb_page(vma) || vma == get_gate_vma(current->mm))
@@ -538,6 +539,8 @@ success:
nr_pages = (end - start) >> PAGE_SHIFT;
if (!lock)
nr_pages = -nr_pages;
+ else if (old_flags & VM_LOCKED)
+ nr_pages = 0;
mm->locked_vm += nr_pages;
/*
diff --git a/mm/shmem.c b/mm/shmem.c
index 6318fc7883c4..6397dc2e15bc 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1818,9 +1818,7 @@ static loff_t shmem_file_llseek(struct file *file, loff_t offset, int whence)
mutex_lock(&inode->i_mutex);
/* We're holding i_mutex so we can access i_size directly */
- if (offset < 0)
- offset = -EINVAL;
- else if (offset >= inode->i_size)
+ if (offset < 0 || offset >= inode->i_size)
offset = -ENXIO;
else {
start = offset >> PAGE_CACHE_SHIFT;
diff --git a/mm/truncate.c b/mm/truncate.c
index 8ca20a98c327..f6fedb876604 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -499,9 +499,13 @@ void truncate_inode_pages_final(struct address_space *mapping)
*/
spin_lock_irq(&mapping->tree_lock);
spin_unlock_irq(&mapping->tree_lock);
-
- truncate_inode_pages(mapping, 0);
}
+
+ /*
+ * Cleancache needs notification even if there are no pages or shadow
+ * entries.
+ */
+ truncate_inode_pages(mapping, 0);
}
EXPORT_SYMBOL(truncate_inode_pages_final);
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
index 5d2f9d4879b2..d50c3b003dc9 100644
--- a/net/batman-adv/fragmentation.c
+++ b/net/batman-adv/fragmentation.c
@@ -266,7 +266,7 @@ batadv_frag_merge_packets(struct hlist_head *chain)
kfree(entry);
packet = (struct batadv_frag_packet *)skb_out->data;
- size = ntohs(packet->total_size);
+ size = ntohs(packet->total_size) + hdr_size;
/* Make room for the rest of the fragments. */
if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) {
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 9d3176b080a4..91ae061d46ac 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -261,8 +261,8 @@ static struct net_device *__ip_tunnel_create(struct net *net,
} else {
if (strlen(ops->kind) > (IFNAMSIZ - 3))
goto failed;
- strlcpy(name, ops->kind, IFNAMSIZ);
- strncat(name, "%d", 2);
+ strcpy(name, ops->kind);
+ strcat(name, "%d");
}
ASSERT_RTNL();
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 83e8a295c806..c153fc2883a8 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -726,7 +726,6 @@ static int llc_ui_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
struct sk_buff *skb = NULL;
struct sock *sk = sock->sk;
struct llc_sock *llc = llc_sk(sk);
- unsigned long cpu_flags;
size_t copied = 0;
u32 peek_seq = 0;
u32 *seq, skb_len;
@@ -851,9 +850,8 @@ static int llc_ui_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
goto copy_uaddr;
if (!(flags & MSG_PEEK)) {
- spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags);
- sk_eat_skb(sk, skb);
- spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags);
+ skb_unlink(skb, &sk->sk_receive_queue);
+ kfree_skb(skb);
*seq = 0;
}
@@ -874,9 +872,8 @@ copy_uaddr:
llc_cmsg_rcv(msg, skb);
if (!(flags & MSG_PEEK)) {
- spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags);
- sk_eat_skb(sk, skb);
- spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags);
+ skb_unlink(skb, &sk->sk_receive_queue);
+ kfree_skb(skb);
*seq = 0;
}
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 00b25114843f..3678f2d5fcfe 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -988,6 +988,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
if (local->open_count == 0)
ieee80211_clear_tx_pending(local);
+ sdata->vif.bss_conf.beacon_int = 0;
+
/*
* If the interface goes down while suspended, presumably because
* the device was unplugged and that happens before our resume,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index aef0d41e9a9c..b02fcb388640 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1110,6 +1110,7 @@ ieee80211_rx_h_check_dup(struct ieee80211_rx_data *rx)
return RX_CONTINUE;
if (ieee80211_is_ctl(hdr->frame_control) ||
+ ieee80211_is_nullfunc(hdr->frame_control) ||
ieee80211_is_qos_nullfunc(hdr->frame_control) ||
is_multicast_ether_addr(hdr->addr1))
return RX_CONTINUE;
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 2731cf5bf052..d221300e59e5 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -648,6 +648,8 @@ void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
/* Track when last TDLS packet was ACKed */
if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
sta->status_stats.last_tdls_pkt_time = jiffies;
+ } else if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
+ return;
} else {
ieee80211_lost_packet(sta, info);
}
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index a45248a4967b..674fe547ffee 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -431,8 +431,8 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
if (ieee80211_hw_check(&tx->local->hw, QUEUE_CONTROL))
info->hw_queue = tx->sdata->vif.cab_queue;
- /* no stations in PS mode */
- if (!atomic_read(&ps->num_sta_ps))
+ /* no stations in PS mode and no buffered packets */
+ if (!atomic_read(&ps->num_sta_ps) && skb_queue_empty(&ps->bc_buf))
return TX_CONTINUE;
info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 120e9ae04db3..a7967af0da82 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -3452,6 +3452,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
dreg = nft_type_to_reg(set->dtype);
list_for_each_entry(binding, &set->bindings, list) {
struct nft_ctx bind_ctx = {
+ .net = ctx->net,
.afi = ctx->afi,
.table = ctx->table,
.chain = (struct nft_chain *)binding->chain,
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index a40b8b0ef0d5..f085b01b6603 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -486,8 +486,9 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
void sctp_assoc_rm_peer(struct sctp_association *asoc,
struct sctp_transport *peer)
{
- struct list_head *pos;
- struct sctp_transport *transport;
+ struct sctp_transport *transport;
+ struct list_head *pos;
+ struct sctp_chunk *ch;
pr_debug("%s: association:%p addr:%pISpc\n",
__func__, asoc, &peer->ipaddr.sa);
@@ -543,7 +544,6 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
*/
if (!list_empty(&peer->transmitted)) {
struct sctp_transport *active = asoc->peer.active_path;
- struct sctp_chunk *ch;
/* Reset the transport of each chunk on this list */
list_for_each_entry(ch, &peer->transmitted,
@@ -565,6 +565,10 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
sctp_transport_hold(active);
}
+ list_for_each_entry(ch, &asoc->outqueue.out_chunk_list, list)
+ if (ch->transport == peer)
+ ch->transport = NULL;
+
asoc->peer.transport_count--;
sctp_transport_free(peer);
diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
index 41248b1820c7..cc27e38392ea 100644
--- a/net/sunrpc/auth_generic.c
+++ b/net/sunrpc/auth_generic.c
@@ -272,13 +272,7 @@ static bool generic_key_to_expire(struct rpc_cred *cred)
{
struct auth_cred *acred = &container_of(cred, struct generic_cred,
gc_base)->acred;
- bool ret;
-
- get_rpccred(cred);
- ret = test_bit(RPC_CRED_KEY_EXPIRE_SOON, &acred->ac_flags);
- put_rpccred(cred);
-
- return ret;
+ return test_bit(RPC_CRED_KEY_EXPIRE_SOON, &acred->ac_flags);
}
static const struct rpc_credops generic_credops = {
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 1f0687d8e3d7..62fca77bf3c7 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -1722,6 +1722,7 @@ priv_release_snd_buf(struct rpc_rqst *rqstp)
for (i=0; i < rqstp->rq_enc_pages_num; i++)
__free_page(rqstp->rq_enc_pages[i]);
kfree(rqstp->rq_enc_pages);
+ rqstp->rq_release_snd_buf = NULL;
}
static int
@@ -1730,6 +1731,9 @@ alloc_enc_pages(struct rpc_rqst *rqstp)
struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
int first, last, i;
+ if (rqstp->rq_release_snd_buf)
+ rqstp->rq_release_snd_buf(rqstp);
+
if (snd_buf->page_len == 0) {
rqstp->rq_enc_pages_num = 0;
return 0;
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
index abe5f47b1ab0..93e23a73b232 100644
--- a/scripts/Makefile.extrawarn
+++ b/scripts/Makefile.extrawarn
@@ -10,6 +10,8 @@
# are not supported by all versions of the compiler
# ==========================================================================
+KBUILD_CFLAGS += $(call cc-disable-warning, packed-not-aligned)
+
ifeq ("$(origin W)", "command line")
export KBUILD_ENABLE_EXTRA_GCC_CHECKS := $(W)
endif
@@ -25,6 +27,7 @@ warning-1 += -Wold-style-definition
warning-1 += $(call cc-option, -Wmissing-include-dirs)
warning-1 += $(call cc-option, -Wunused-but-set-variable)
warning-1 += $(call cc-option, -Wunused-const-variable)
+warning-1 += $(call cc-option, -Wpacked-not-aligned)
warning-1 += $(call cc-disable-warning, missing-field-initializers)
warning-2 := -Waggregate-return
diff --git a/scripts/clang-android.sh b/scripts/clang-android.sh
new file mode 100755
index 000000000000..9186c4f48576
--- /dev/null
+++ b/scripts/clang-android.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+$* -dM -E - </dev/null 2>&1 | grep -q __ANDROID__ && echo "y"
diff --git a/scripts/unifdef.c b/scripts/unifdef.c
index 7493c0ee51cc..db00e3e30a59 100644
--- a/scripts/unifdef.c
+++ b/scripts/unifdef.c
@@ -395,7 +395,7 @@ usage(void)
* When we have processed a group that starts off with a known-false
* #if/#elif sequence (which has therefore been deleted) followed by a
* #elif that we don't understand and therefore must keep, we edit the
- * latter into a #if to keep the nesting correct. We use strncpy() to
+ * latter into a #if to keep the nesting correct. We use memcpy() to
* overwrite the 4 byte token "elif" with "if " without a '\0' byte.
*
* When we find a true #elif in a group, the following block will
@@ -450,7 +450,7 @@ static void Idrop (void) { Fdrop(); ignoreon(); }
static void Itrue (void) { Ftrue(); ignoreon(); }
static void Ifalse(void) { Ffalse(); ignoreon(); }
/* modify this line */
-static void Mpass (void) { strncpy(keyword, "if ", 4); Pelif(); }
+static void Mpass (void) { memcpy(keyword, "if ", 4); Pelif(); }
static void Mtrue (void) { keywordedit("else"); state(IS_TRUE_MIDDLE); }
static void Melif (void) { keywordedit("endif"); state(IS_FALSE_TRAILER); }
static void Melse (void) { keywordedit("endif"); state(IS_FALSE_ELSE); }
diff --git a/sound/core/control.c b/sound/core/control.c
index bd01d492f46a..2be860a446a2 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -346,6 +346,40 @@ static int snd_ctl_find_hole(struct snd_card *card, unsigned int count)
return 0;
}
+/* add a new kcontrol object; call with card->controls_rwsem locked */
+static int __snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
+{
+ struct snd_ctl_elem_id id;
+ unsigned int idx;
+ unsigned int count;
+
+ id = kcontrol->id;
+ if (id.index > UINT_MAX - kcontrol->count)
+ return -EINVAL;
+
+ if (snd_ctl_find_id(card, &id)) {
+ dev_err(card->dev,
+ "control %i:%i:%i:%s:%i is already present\n",
+ id.iface, id.device, id.subdevice, id.name, id.index);
+ return -EBUSY;
+ }
+
+ if (snd_ctl_find_hole(card, kcontrol->count) < 0)
+ return -ENOMEM;
+
+ list_add_tail(&kcontrol->list, &card->controls);
+ card->controls_count += kcontrol->count;
+ kcontrol->id.numid = card->last_numid + 1;
+ card->last_numid += kcontrol->count;
+
+ id = kcontrol->id;
+ count = kcontrol->count;
+ for (idx = 0; idx < count; idx++, id.index++, id.numid++)
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
+
+ return 0;
+}
+
/**
* snd_ctl_add - add the control instance to the card
* @card: the card instance
@@ -362,45 +396,18 @@ static int snd_ctl_find_hole(struct snd_card *card, unsigned int count)
*/
int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
{
- struct snd_ctl_elem_id id;
- unsigned int idx;
- unsigned int count;
int err = -EINVAL;
if (! kcontrol)
return err;
if (snd_BUG_ON(!card || !kcontrol->info))
goto error;
- id = kcontrol->id;
- if (id.index > UINT_MAX - kcontrol->count)
- goto error;
down_write(&card->controls_rwsem);
- if (snd_ctl_find_id(card, &id)) {
- up_write(&card->controls_rwsem);
- dev_err(card->dev, "control %i:%i:%i:%s:%i is already present\n",
- id.iface,
- id.device,
- id.subdevice,
- id.name,
- id.index);
- err = -EBUSY;
- goto error;
- }
- if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
- up_write(&card->controls_rwsem);
- err = -ENOMEM;
- goto error;
- }
- list_add_tail(&kcontrol->list, &card->controls);
- card->controls_count += kcontrol->count;
- kcontrol->id.numid = card->last_numid + 1;
- card->last_numid += kcontrol->count;
- id = kcontrol->id;
- count = kcontrol->count;
+ err = __snd_ctl_add(card, kcontrol);
up_write(&card->controls_rwsem);
- for (idx = 0; idx < count; idx++, id.index++, id.numid++)
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
+ if (err < 0)
+ goto error;
return 0;
error:
@@ -1322,9 +1329,12 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
kctl->tlv.c = snd_ctl_elem_user_tlv;
/* This function manage to free the instance on failure. */
- err = snd_ctl_add(card, kctl);
- if (err < 0)
- return err;
+ down_write(&card->controls_rwsem);
+ err = __snd_ctl_add(card, kctl);
+ if (err < 0) {
+ snd_ctl_free_one(kctl);
+ goto unlock;
+ }
offset = snd_ctl_get_ioff(kctl, &info->id);
snd_ctl_build_ioff(&info->id, kctl, offset);
/*
@@ -1335,10 +1345,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
* which locks the element.
*/
- down_write(&card->controls_rwsem);
card->user_ctl_count++;
- up_write(&card->controls_rwsem);
+ unlock:
+ up_write(&card->controls_rwsem);
return 0;
}
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 981b18bf2e63..c4b15dd51c24 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -36,6 +36,7 @@
#include <sound/timer.h>
#include <sound/minors.h>
#include <linux/uio.h>
+#include <linux/delay.h>
/*
* Compatibility
@@ -79,12 +80,12 @@ static DECLARE_RWSEM(snd_pcm_link_rwsem);
* and this may lead to a deadlock when the code path takes read sem
* twice (e.g. one in snd_pcm_action_nonatomic() and another in
* snd_pcm_stream_lock()). As a (suboptimal) workaround, let writer to
- * spin until it gets the lock.
+ * sleep until all the readers are completed without blocking by writer.
*/
-static inline void down_write_nonblock(struct rw_semaphore *lock)
+static inline void down_write_nonfifo(struct rw_semaphore *lock)
{
while (!down_write_trylock(lock))
- cond_resched();
+ msleep(1);
}
/**
@@ -1851,7 +1852,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
res = -ENOMEM;
goto _nolock;
}
- down_write_nonblock(&snd_pcm_link_rwsem);
+ down_write_nonfifo(&snd_pcm_link_rwsem);
write_lock_irq(&snd_pcm_link_rwlock);
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN ||
substream->runtime->status->state != substream1->runtime->status->state ||
@@ -1898,7 +1899,7 @@ static int snd_pcm_unlink(struct snd_pcm_substream *substream)
struct snd_pcm_substream *s;
int res = 0;
- down_write_nonblock(&snd_pcm_link_rwsem);
+ down_write_nonfifo(&snd_pcm_link_rwsem);
write_lock_irq(&snd_pcm_link_rwlock);
if (!snd_pcm_stream_linked(substream)) {
res = -EALREADY;
@@ -2251,7 +2252,8 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
static void pcm_release_private(struct snd_pcm_substream *substream)
{
- snd_pcm_unlink(substream);
+ if (snd_pcm_stream_linked(substream))
+ snd_pcm_unlink(substream);
}
void snd_pcm_release_substream(struct snd_pcm_substream *substream)
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c
index 913b731d2236..f40330ddb9b2 100644
--- a/sound/isa/wss/wss_lib.c
+++ b/sound/isa/wss/wss_lib.c
@@ -1531,7 +1531,6 @@ static int snd_wss_playback_open(struct snd_pcm_substream *substream)
if (err < 0) {
if (chip->release_dma)
chip->release_dma(chip, chip->dma_private_data, chip->dma1);
- snd_free_pages(runtime->dma_area, runtime->dma_bytes);
return err;
}
chip->playback_substream = substream;
@@ -1572,7 +1571,6 @@ static int snd_wss_capture_open(struct snd_pcm_substream *substream)
if (err < 0) {
if (chip->release_dma)
chip->release_dma(chip, chip->dma_private_data, chip->dma2);
- snd_free_pages(runtime->dma_area, runtime->dma_bytes);
return err;
}
chip->capture_substream = substream;
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 82259ca61e64..c4840fda44b4 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -824,7 +824,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
{
struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
int reg = kcontrol->private_value & 0xff;
- int shift = (kcontrol->private_value >> 8) & 0xff;
+ int shift = (kcontrol->private_value >> 8) & 0x0f;
int mask = (kcontrol->private_value >> 16) & 0xff;
// int invert = (kcontrol->private_value >> 24) & 0xff;
unsigned short value, old, new;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index ecb07fb036af..f964743b104c 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2363,6 +2363,10 @@ static const struct pci_device_id azx_ids[] = {
/* AMD Hudson */
{ PCI_DEVICE(0x1022, 0x780d),
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },
+ /* AMD Stoney */
+ { PCI_DEVICE(0x1022, 0x157a),
+ .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB |
+ AZX_DCAPS_PM_RUNTIME },
/* AMD Raven */
{ PCI_DEVICE(0x1022, 0x15e3),
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB |
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index cedf13b64803..2f18b1cdc2cd 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -123,7 +123,7 @@ static int snd_trident_probe(struct pci_dev *pci,
} else {
strcpy(card->shortname, "Trident ");
}
- strcat(card->shortname, card->driver);
+ strcat(card->shortname, str);
sprintf(card->longname, "%s PCI Audio at 0x%lx, irq %d",
card->shortname, trident->port, trident->irq);
diff --git a/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c b/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c
index 58df020811f1..1c79e632b8f8 100644
--- a/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c
+++ b/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -471,9 +471,9 @@ static int msm_sdw_codec_enable_vi_feedback(struct snd_soc_dapm_widget *w,
MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x20,
0x20);
snd_soc_update_bits(codec,
- MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x04);
+ MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x00);
snd_soc_update_bits(codec,
- MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x0F, 0x04);
+ MSM_SDW_TX10_SPKR_PROT_PATH_CTL, 0x0F, 0x00);
snd_soc_update_bits(codec,
MSM_SDW_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x10);
snd_soc_update_bits(codec,
@@ -496,10 +496,10 @@ static int msm_sdw_codec_enable_vi_feedback(struct snd_soc_dapm_widget *w,
0x20);
snd_soc_update_bits(codec,
MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x0F,
- 0x04);
+ 0x00);
snd_soc_update_bits(codec,
MSM_SDW_TX12_SPKR_PROT_PATH_CTL, 0x0F,
- 0x04);
+ 0x00);
snd_soc_update_bits(codec,
MSM_SDW_TX11_SPKR_PROT_PATH_CTL, 0x10,
0x10);
diff --git a/sound/soc/msm/apq8096-auto.c b/sound/soc/msm/apq8096-auto.c
index e5d99f5fd7d1..69a1fbfa45aa 100644
--- a/sound/soc/msm/apq8096-auto.c
+++ b/sound/soc/msm/apq8096-auto.c
@@ -160,6 +160,42 @@ static int msm_tert_tdm_slot_num = 8;
static int msm_quat_tdm_slot_width = 32;
static int msm_quat_tdm_slot_num = 8;
+/* Group_MI2S default port channels */
+static int msm_sec_group_mi2s_rx_1_ch = 2;
+static int msm_sec_group_mi2s_rx_2_ch = 2;
+static int msm_sec_group_mi2s_rx_3_ch = 2;
+static int msm_sec_group_mi2s_rx_4_ch = 2;
+static int msm_sec_group_mi2s_tx_1_ch = 2;
+static int msm_sec_group_mi2s_tx_2_ch = 2;
+static int msm_sec_group_mi2s_tx_3_ch = 2;
+static int msm_sec_group_mi2s_tx_4_ch = 2;
+static int msm_tert_group_mi2s_rx_1_ch = 2;
+static int msm_tert_group_mi2s_rx_2_ch = 2;
+static int msm_tert_group_mi2s_rx_3_ch = 2;
+static int msm_tert_group_mi2s_rx_4_ch = 2;
+static int msm_tert_group_mi2s_tx_1_ch = 2;
+static int msm_tert_group_mi2s_tx_2_ch = 2;
+static int msm_tert_group_mi2s_tx_3_ch = 2;
+static int msm_tert_group_mi2s_tx_4_ch = 2;
+static int msm_quat_group_mi2s_rx_1_ch = 2;
+static int msm_quat_group_mi2s_rx_2_ch = 2;
+static int msm_quat_group_mi2s_rx_3_ch = 2;
+static int msm_quat_group_mi2s_rx_4_ch = 2;
+static int msm_quat_group_mi2s_tx_1_ch = 2;
+static int msm_quat_group_mi2s_tx_2_ch = 2;
+static int msm_quat_group_mi2s_tx_3_ch = 2;
+static int msm_quat_group_mi2s_tx_4_ch = 2;
+
+/* Group MI2S default sample rate*/
+static int msm_sec_group_mi2s_rate = SAMPLING_RATE_48KHZ;
+static int msm_tert_group_mi2s_rate = SAMPLING_RATE_48KHZ;
+static int msm_quat_group_mi2s_rate = SAMPLING_RATE_48KHZ;
+
+/* Group MI2S slot width bit format */
+static int msm_sec_group_mi2s_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+static int msm_tert_group_mi2s_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+static int msm_quat_group_mi2s_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+
/* EC Reference default values are set in mixer_paths.xml */
static int msm_ec_ref_ch = 4;
static int msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S16_LE;
@@ -172,6 +208,41 @@ static void *adsp_state_notifier;
static bool dummy_device_registered;
static struct snd_soc_card *sndcard;
+#define GROUP_MI2S_SLOT_OFFSET_MAX 8
+static unsigned int group_mi2s_slot_offset
+ [IDX_GROUP_MI2S_PORT_MAX][GROUP_MI2S_SLOT_OFFSET_MAX] = {
+ /* GROUP_SEC_MI2S_RX */
+ {0, 4, 0xFFFF},
+ {0, 4, 0xFFFF},
+ {0xFFFF},
+ {0xFFFF},
+ /* GROUP_SEC_MI2S_TX */
+ {0, 4, 0xFFFF},
+ {0, 4, 0xFFFF},
+ {0xFFFF},
+ {0xFFFF},
+ /* GROUP_TERT_MI2S_RX */
+ {0, 4, 0xFFFF},
+ {0, 4, 0xFFFF},
+ {0xFFFF},
+ {0xFFFF},
+ /* GROUP_TERT_MI2S_TX */
+ {0, 4, 0xFFFF},
+ {0, 4, 0xFFFF},
+ {0xFFFF},
+ {0xFFFF},
+ /* GROUP_QUAT_MI2S_RX */
+ {0, 4, 0xFFFF},
+ {0, 4, 0xFFFF},
+ {0, 4, 0xFFFF},
+ {0, 4, 0xFFFF},
+ /* GROUP_QUAT_MI2S_TX */
+ {0, 4, 0xFFFF},
+ {0, 4, 0xFFFF},
+ {0, 4, 0xFFFF},
+ {0, 4, 0xFFFF},
+};
+
enum {
QUATERNARY_TDM_RX_0,
QUATERNARY_TDM_RX_1,
@@ -3307,6 +3378,173 @@ static int msm_mi2s_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
return 0;
}
+static int msm_group_mi2s_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_interval *rate =
+ hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *channels =
+ hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ switch (cpu_dai->id) {
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_1:
+ channels->min = channels->max = msm_sec_group_mi2s_rx_1_ch;
+ rate->min = rate->max = msm_sec_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_sec_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_2:
+ channels->min = channels->max = msm_sec_group_mi2s_rx_2_ch;
+ rate->min = rate->max = msm_sec_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_sec_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_3:
+ channels->min = channels->max = msm_sec_group_mi2s_rx_3_ch;
+ rate->min = rate->max = msm_sec_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_sec_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_4:
+ channels->min = channels->max = msm_sec_group_mi2s_rx_4_ch;
+ rate->min = rate->max = msm_sec_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_sec_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_1:
+ channels->min = channels->max = msm_sec_group_mi2s_tx_1_ch;
+ rate->min = rate->max = msm_sec_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_sec_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_2:
+ channels->min = channels->max = msm_sec_group_mi2s_tx_2_ch;
+ rate->min = rate->max = msm_sec_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_sec_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_3:
+ channels->min = channels->max = msm_sec_group_mi2s_tx_3_ch;
+ rate->min = rate->max = msm_sec_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_sec_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_4:
+ channels->min = channels->max = msm_sec_group_mi2s_tx_4_ch;
+ rate->min = rate->max = msm_sec_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_sec_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_1:
+ channels->min = channels->max = msm_tert_group_mi2s_rx_1_ch;
+ rate->min = rate->max = msm_tert_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_2:
+ channels->min = channels->max = msm_tert_group_mi2s_rx_2_ch;
+ rate->min = rate->max = msm_tert_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_3:
+ channels->min = channels->max = msm_tert_group_mi2s_rx_3_ch;
+ rate->min = rate->max = msm_tert_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_4:
+ channels->min = channels->max = msm_tert_group_mi2s_rx_4_ch;
+ rate->min = rate->max = msm_tert_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_1:
+ channels->min = channels->max = msm_tert_group_mi2s_tx_1_ch;
+ rate->min = rate->max = msm_tert_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_2:
+ channels->min = channels->max = msm_tert_group_mi2s_tx_2_ch;
+ rate->min = rate->max = msm_tert_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_3:
+ channels->min = channels->max = msm_tert_group_mi2s_tx_3_ch;
+ rate->min = rate->max = msm_tert_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_4:
+ channels->min = channels->max = msm_tert_group_mi2s_tx_4_ch;
+ rate->min = rate->max = msm_tert_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_tert_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_1:
+ channels->min = channels->max = msm_quat_group_mi2s_rx_1_ch;
+ rate->min = rate->max = msm_quat_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_2:
+ channels->min = channels->max = msm_quat_group_mi2s_rx_2_ch;
+ rate->min = rate->max = msm_quat_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_3:
+ channels->min = channels->max = msm_quat_group_mi2s_rx_3_ch;
+ rate->min = rate->max = msm_quat_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_4:
+ channels->min = channels->max = msm_quat_group_mi2s_rx_4_ch;
+ rate->min = rate->max = msm_quat_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_1:
+ channels->min = channels->max = msm_quat_group_mi2s_tx_1_ch;
+ rate->min = rate->max = msm_quat_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_2:
+ channels->min = channels->max = msm_quat_group_mi2s_tx_2_ch;
+ rate->min = rate->max = msm_quat_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_3:
+ channels->min = channels->max = msm_quat_group_mi2s_tx_3_ch;
+ rate->min = rate->max = msm_quat_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_group_mi2s_bit_format);
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_4:
+ channels->min = channels->max = msm_quat_group_mi2s_tx_4_ch;
+ rate->min = rate->max = msm_quat_group_mi2s_rate;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_quat_group_mi2s_bit_format);
+ break;
+ default:
+ pr_err("%s: dai id 0x%x not supported\n",
+ __func__, cpu_dai->id);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n",
+ __func__, cpu_dai->id, channels->max, rate->max,
+ params_format(params));
+
+ return 0;
+}
+
static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -4085,6 +4323,142 @@ static struct snd_soc_ops apq8096_tdm_be_ops = {
.hw_params = apq8096_tdm_snd_hw_params,
};
+static int apq8096_group_mi2s_snd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+ int channels, rate;
+ unsigned int *slot_offset;
+ int offset_channels = 0;
+ int i;
+
+ rate = params_rate(params);
+ channels = params_channels(params);
+
+ switch (cpu_dai->id) {
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_1:
+ slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_RX_1];
+ break;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_2:
+ slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_RX_2];
+ break;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_3:
+ slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_RX_3];
+ break;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_4:
+ slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_RX_4];
+ break;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_1:
+ slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_TX_1];
+ break;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_2:
+ slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_TX_2];
+ break;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_3:
+ slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_TX_3];
+ break;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_4:
+ slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_TX_4];
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_1:
+ slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_RX_1];
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_2:
+ slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_RX_2];
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_3:
+ slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_RX_3];
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_4:
+ slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_RX_4];
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_1:
+ slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_TX_1];
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_2:
+ slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_TX_2];
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_3:
+ slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_TX_3];
+ break;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_4:
+ slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_TX_4];
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_1:
+ slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_RX_1];
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_2:
+ slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_RX_2];
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_3:
+ slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_RX_3];
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_4:
+ slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_RX_4];
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_1:
+ slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_TX_1];
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_2:
+ slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_TX_2];
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_3:
+ slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_TX_3];
+ break;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_4:
+ slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_TX_4];
+ break;
+ default:
+ pr_err("%s: dai id 0x%x not supported\n",
+ __func__, cpu_dai->id);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < GROUP_MI2S_SLOT_OFFSET_MAX; i++) {
+ if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID)
+ offset_channels++;
+ }
+
+ if (offset_channels == 0) {
+ pr_err("%s: slot offset not supported, offset_channels %d\n",
+ __func__, offset_channels);
+ return -EINVAL;
+ }
+
+ if (channels > offset_channels) {
+ pr_err("%s: channels %d and offset_channels %d not match\n",
+ __func__, channels, offset_channels);
+ return -EINVAL;
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
+ channels, slot_offset);
+ if (ret < 0) {
+ pr_err("%s: failed to set channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ } else {
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ channels, slot_offset,
+ 0, NULL);
+ if (ret < 0) {
+ pr_err("%s: failed to set channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ }
+end:
+ return ret;
+}
+
+static struct snd_soc_ops apq8096_group_mi2s_be_ops = {
+ .hw_params = apq8096_group_mi2s_snd_hw_params,
+};
+
static const struct soc_enum msm_snd_enum[] = {
SOC_ENUM_SINGLE_EXT(2, auxpcm_rate_text),
SOC_ENUM_SINGLE_EXT(7, hdmi_rx_ch_text),
@@ -6546,6 +6920,342 @@ static struct snd_soc_dai_link apq8096_auto_be_dai_links[] = {
.be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
.ops = &apq8096_tdm_be_ops,
.ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_MI2S_TX_1,
+ .stream_name = "Secondary MI2S1 Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4161",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_MI2S_TX_2,
+ .stream_name = "Secondary MI2S2 Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4163",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_MI2S_TX_3,
+ .stream_name = "Secondary MI2S3 Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4165",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_MI2S_TX_4,
+ .stream_name = "Secondary MI2S4 Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4167",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_MI2S_TX_1,
+ .stream_name = "Tertiary MI2S1 Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4169",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_MI2S_TX_2,
+ .stream_name = "Tertiary MI2S2 Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4171",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_MI2S_TX_3,
+ .stream_name = "Tertiary MI2S3 Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4173",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_MI2S_TX_4,
+ .stream_name = "Tertiary MI2S4 Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4175",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_TX_1,
+ .stream_name = "Quaternary MI2S1 Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4129",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_TX_2,
+ .stream_name = "Quaternary MI2S2 Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4131",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_TX_3,
+ .stream_name = "Quaternary MI2S3 Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4133",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_TX_4,
+ .stream_name = "Quaternary MI2S4 Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4135",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_MI2S_RX_1,
+ .stream_name = "Secondary MI2S1 Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4160",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_MI2S_RX_2,
+ .stream_name = "Secondary MI2S2 Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4162",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_MI2S_RX_3,
+ .stream_name = "Secondary MI2S3 Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4164",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_MI2S_RX_4,
+ .stream_name = "Secondary MI2S4 Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4166",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_MI2S_RX_1,
+ .stream_name = "Tertiary MI2S1 Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4168",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_MI2S_RX_2,
+ .stream_name = "Tertiary MI2S2 Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4170",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_MI2S_RX_3,
+ .stream_name = "Tertiary MI2S3 Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4172",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_MI2S_RX_4,
+ .stream_name = "Tertiary MI2S4 Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4174",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_RX_1,
+ .stream_name = "Quaternary MI2S1 Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4128",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_RX_2,
+ .stream_name = "Quaternary MI2S2 Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4130",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_RX_3,
+ .stream_name = "Quaternary MI2S3 Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4132",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_RX_4,
+ .stream_name = "Quaternary MI2S4 Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4134",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup,
+ .ops = &apq8096_group_mi2s_be_ops,
+ .ignore_suspend = 1,
}
};
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index b2aa6bd3f504..edbd6b485dac 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -946,6 +946,7 @@ static void populate_codec_list(struct msm_compr_audio *prtd)
prtd->compr_cap.codecs[14] = SND_AUDIOCODEC_APTX;
prtd->compr_cap.codecs[15] = SND_AUDIOCODEC_TRUEHD;
prtd->compr_cap.codecs[16] = SND_AUDIOCODEC_IEC61937;
+ prtd->compr_cap.codecs[17] = SND_AUDIOCODEC_APTXHD;
}
static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
@@ -1213,6 +1214,8 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
pr_err("%s: CMD IEC61937 Format block failed ret %d\n",
__func__, ret);
break;
+ case FORMAT_APTXHD:
+ pr_debug("SND_AUDIOCODEC_APTXHD\n");
case FORMAT_APTX:
pr_debug("SND_AUDIOCODEC_APTX\n");
memset(&aptx_cfg, 0x0, sizeof(struct aptx_dec_bt_addr_cfg));
@@ -2106,6 +2109,12 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream,
break;
}
+ case SND_AUDIOCODEC_APTXHD: {
+ pr_debug("%s: SND_AUDIOCODEC_APTXHD\n", __func__);
+ prtd->codec = FORMAT_APTXHD;
+ break;
+ }
+
default:
pr_err("codec not supported, id =%d\n", params->codec.id);
return -EINVAL;
@@ -2974,6 +2983,7 @@ static int msm_compr_get_codec_caps(struct snd_compr_stream *cstream,
case SND_AUDIOCODEC_TRUEHD:
case SND_AUDIOCODEC_IEC61937:
case SND_AUDIOCODEC_APTX:
+ case SND_AUDIOCODEC_APTXHD:
break;
default:
pr_err("%s: Unsupported audio codec %d\n",
@@ -3412,6 +3422,7 @@ static int msm_compr_send_dec_params(struct snd_compr_stream *cstream,
case FORMAT_TRUEHD:
case FORMAT_IEC61937:
case FORMAT_APTX:
+ case FORMAT_APTXHD:
pr_debug("%s: no runtime parameters for codec: %d\n", __func__,
prtd->codec);
break;
@@ -3481,6 +3492,7 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol,
case FORMAT_TRUEHD:
case FORMAT_IEC61937:
case FORMAT_APTX:
+ case FORMAT_APTXHD:
pr_debug("%s: no runtime parameters for codec: %d\n", __func__,
prtd->codec);
break;
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index b09f6a1378f0..0c23e1eef483 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -124,6 +124,47 @@ struct msm_dai_q6_mi2s_dai_data {
struct msm_dai_q6_mi2s_dai_config rx_dai;
};
+static DEFINE_MUTEX(group_mi2s_mutex);
+static atomic_t group_mi2s_ref[IDX_GROUP_MI2S_MAX];
+
+/* cache of mi2s group cfg per parent node */
+static struct afe_param_id_group_device_i2s_cfg_v1 group_mi2s_cfg = {
+ AFE_API_VERSION_GROUP_DEVICE_I2S_CONFIG,
+ AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_TX,
+ AFE_PORT_I2S_QUAD01,
+ 48000,
+ {
+ AFE_PORT_ID_INVALID,
+ AFE_PORT_ID_TERTIARY_MI2S_TX_1,
+ AFE_PORT_ID_TERTIARY_MI2S_TX_2,
+ AFE_PORT_ID_INVALID,
+ AFE_PORT_ID_INVALID,
+ AFE_PORT_ID_INVALID,
+ AFE_PORT_ID_INVALID,
+ AFE_PORT_ID_INVALID
+ },
+ 32,
+ 0,
+};
+
+static struct afe_clk_set group_mi2s_bclk_set = {
+ AFE_API_VERSION_CLOCK_SET,
+ Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+};
+
+static struct afe_clk_set group_mi2s_mclk_set = {
+ AFE_API_VERSION_CLOCK_SET,
+ Q6AFE_LPASS_CLK_ID_MCLK_2,
+ Q6AFE_LPASS_OSR_CLK_3_P072_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+};
+
struct msm_dai_q6_auxpcm_dai_data {
/* BITMAP to track Rx and Tx port usage count */
DECLARE_BITMAP(auxpcm_port_status, STATUS_MAX);
@@ -147,6 +188,19 @@ struct msm_dai_q6_tdm_dai_data {
struct afe_tdm_port_config port_cfg; /* hold tdm config */
};
+struct msm_dai_q6_group_mi2s_dai_data {
+ DECLARE_BITMAP(status_mask, STATUS_MAX);
+ u32 rate;
+ u32 channels;
+ u32 bit_width;
+ u32 num_group_ports;
+ u32 sync_mode;
+ struct afe_clk_set bclk_set;
+ struct afe_clk_set mclk_set;
+ union afe_port_group_mi2s_config group_cfg;
+ struct afe_i2s_port_config port_cfg;
+};
+
/* MI2S format field for AFE_PORT_CMD_I2S_CONFIG command
* 0: linear PCM
* 1: non-linear PCM
@@ -455,6 +509,104 @@ int msm_dai_q6_get_port_idx(u16 id)
}
}
+static int msm_dai_q6_get_mi2s_group_idx(u16 id)
+{
+ switch (id) {
+ case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_1:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_2:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_3:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_4:
+ return IDX_GROUP_SECONDARY_MI2S_RX;
+ case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_TX:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_1:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_2:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_3:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_4:
+ return IDX_GROUP_SECONDARY_MI2S_TX;
+ case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_RX:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_1:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_2:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_3:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_4:
+ return IDX_GROUP_TERTIARY_MI2S_RX;
+ case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_TX:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_1:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_2:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_3:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_4:
+ return IDX_GROUP_TERTIARY_MI2S_TX;
+ case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_RX:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_1:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_2:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_3:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_4:
+ return IDX_GROUP_QUATERNARY_MI2S_RX;
+ case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_TX:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_1:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_2:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_3:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_4:
+ return IDX_GROUP_QUATERNARY_MI2S_TX;
+ default: return -EINVAL;
+ }
+}
+
+static int msm_dai_q6_get_mi2s_port_idx(u16 id)
+{
+ switch (id) {
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_1:
+ return IDX_SECONDARY_MI2S_RX_1;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_2:
+ return IDX_SECONDARY_MI2S_RX_2;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_3:
+ return IDX_SECONDARY_MI2S_RX_3;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_4:
+ return IDX_SECONDARY_MI2S_RX_4;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_1:
+ return IDX_SECONDARY_MI2S_TX_1;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_2:
+ return IDX_SECONDARY_MI2S_TX_2;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_3:
+ return IDX_SECONDARY_MI2S_TX_3;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_4:
+ return IDX_SECONDARY_MI2S_TX_4;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_1:
+ return IDX_TERTIARY_MI2S_RX_1;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_2:
+ return IDX_TERTIARY_MI2S_RX_2;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_3:
+ return IDX_TERTIARY_MI2S_RX_3;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_4:
+ return IDX_TERTIARY_MI2S_RX_4;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_1:
+ return IDX_TERTIARY_MI2S_TX_1;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_2:
+ return IDX_TERTIARY_MI2S_TX_2;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_3:
+ return IDX_TERTIARY_MI2S_TX_3;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_4:
+ return IDX_TERTIARY_MI2S_TX_4;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_1:
+ return IDX_QUATERNARY_MI2S_RX_1;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_2:
+ return IDX_QUATERNARY_MI2S_RX_2;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_3:
+ return IDX_QUATERNARY_MI2S_RX_3;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_4:
+ return IDX_QUATERNARY_MI2S_RX_4;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_1:
+ return IDX_QUATERNARY_MI2S_TX_1;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_2:
+ return IDX_QUATERNARY_MI2S_TX_2;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_3:
+ return IDX_QUATERNARY_MI2S_TX_3;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_4:
+ return IDX_QUATERNARY_MI2S_TX_4;
+ default: return -EINVAL;
+ }
+}
+
static u16 msm_dai_q6_max_num_slot(int frame_rate)
{
/* Max num of slots is bits per frame divided
@@ -531,7 +683,7 @@ static int msm_dai_q6_auxpcm_hw_params(
int rc = 0, slot_mapping_copy_len = 0;
if (params_channels(params) != 1 || (params_rate(params) != 8000 &&
- params_rate(params) != 16000)) {
+ params_rate(params) != 16000)) {
dev_err(dai->dev, "%s: invalid param chan %d rate %d\n",
__func__, params_channels(params), params_rate(params));
return -EINVAL;
@@ -540,7 +692,7 @@ static int msm_dai_q6_auxpcm_hw_params(
mutex_lock(&aux_dai_data->rlock);
if (test_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status) ||
- test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status)) {
+ test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status)) {
/* AUXPCM DAI in use */
if (dai_data->rate != params_rate(params)) {
dev_err(dai->dev, "%s: rate mismatch of running DAI\n",
@@ -569,7 +721,7 @@ static int msm_dai_q6_auxpcm_hw_params(
dai_data->port_config.pcm.num_channels = dai_data->channels;
dai_data->port_config.pcm.bit_width = 16;
if (ARRAY_SIZE(dai_data->port_config.pcm.slot_number_mapping) <=
- auxpcm_pdata->mode_8k.num_slots)
+ auxpcm_pdata->mode_8k.num_slots)
slot_mapping_copy_len =
ARRAY_SIZE(
dai_data->port_config.pcm.slot_number_mapping)
@@ -580,8 +732,8 @@ static int msm_dai_q6_auxpcm_hw_params(
if (auxpcm_pdata->mode_8k.slot_mapping) {
memcpy(dai_data->port_config.pcm.slot_number_mapping,
- auxpcm_pdata->mode_8k.slot_mapping,
- slot_mapping_copy_len);
+ auxpcm_pdata->mode_8k.slot_mapping,
+ slot_mapping_copy_len);
} else {
dev_err(dai->dev, "%s 8khz slot mapping is NULL\n",
__func__);
@@ -605,7 +757,7 @@ static int msm_dai_q6_auxpcm_hw_params(
dai_data->port_config.pcm.num_channels = dai_data->channels;
dai_data->port_config.pcm.bit_width = 16;
if (ARRAY_SIZE(dai_data->port_config.pcm.slot_number_mapping) <=
- auxpcm_pdata->mode_16k.num_slots)
+ auxpcm_pdata->mode_16k.num_slots)
slot_mapping_copy_len =
ARRAY_SIZE(
dai_data->port_config.pcm.slot_number_mapping)
@@ -616,8 +768,8 @@ static int msm_dai_q6_auxpcm_hw_params(
if (auxpcm_pdata->mode_16k.slot_mapping) {
memcpy(dai_data->port_config.pcm.slot_number_mapping,
- auxpcm_pdata->mode_16k.slot_mapping,
- slot_mapping_copy_len);
+ auxpcm_pdata->mode_16k.slot_mapping,
+ slot_mapping_copy_len);
} else {
dev_err(dai->dev, "%s 16khz slot mapping is NULL\n",
__func__);
@@ -4322,6 +4474,908 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = {
},
};
+static int msm_dai_q6_group_mi2s_set_clk_param(u32 group_id,
+ struct afe_clk_set *mclk_set,
+ struct afe_clk_set *bclk_set,
+ u32 sync_mode)
+{
+ switch (group_id) {
+ case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX:
+ case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_TX:
+ if (sync_mode)
+ bclk_set->clk_id = Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT;
+ else
+ bclk_set->clk_id = Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT;
+ mclk_set->clk_id = Q6AFE_LPASS_CLK_ID_MCLK_1;
+ break;
+ case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_RX:
+ case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_TX:
+ if (sync_mode)
+ bclk_set->clk_id = Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT;
+ else
+ bclk_set->clk_id = Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT;
+ mclk_set->clk_id = Q6AFE_LPASS_CLK_ID_MCLK_2;
+ break;
+ case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_RX:
+ case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_TX:
+ if (sync_mode)
+ bclk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT;
+ else
+ bclk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT;
+ mclk_set->clk_id = Q6AFE_LPASS_CLK_ID_MCLK_3;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int msm_dai_q6_group_mi2s_set_clk(
+ struct msm_dai_q6_group_mi2s_dai_data *dai_data,
+ u16 port_id, bool enable)
+{
+ int rc = 0;
+
+ dai_data->bclk_set.enable = enable;
+ rc = afe_set_lpass_clock_v2(port_id,
+ &dai_data->bclk_set);
+ if (rc < 0)
+ pr_err("%s: afe lpass bclk failed, err: %d\n",
+ __func__, rc);
+
+ /*non zero mclk freq value means to enable mclk for mi2s intf*/
+ if (dai_data->mclk_set.clk_freq_in_hz != 0) {
+ dai_data->mclk_set.enable = enable;
+ rc = afe_set_lpass_clock_v2(port_id,
+ &dai_data->mclk_set);
+ if (rc < 0)
+ pr_err("%s: afe lpass mclk failed, err: %d\n",
+ __func__, rc);
+ }
+ return rc;
+}
+
+static int msm_dai_q6_dai_group_mi2s_probe(struct snd_soc_dai *dai)
+{
+ int rc = 0;
+
+ msm_dai_q6_set_dai_id(dai);
+ rc = msm_dai_q6_dai_add_route(dai);
+ return rc;
+}
+
+static int msm_dai_q6_dai_group_mi2s_remove(struct snd_soc_dai *dai)
+{
+ int rc = 0;
+ struct msm_dai_q6_group_mi2s_dai_data *dai_data =
+ dev_get_drvdata(dai->dev);
+ u16 group_id = dai_data->group_cfg.i2s_cfg.group_id;
+ int group_idx = 0;
+ atomic_t *group_ref = NULL;
+
+ dev_dbg(dai->dev, "%s rc %d", __func__, rc);
+
+ group_idx = msm_dai_q6_get_mi2s_group_idx(dai->id);
+ if (group_idx < 0 || group_idx > IDX_GROUP_MI2S_MAX) {
+ dev_err(dai->dev, "%s: port id 0x%x not supported\n",
+ __func__, dai->id);
+ return -EINVAL;
+ }
+
+ group_ref = &group_mi2s_ref[group_idx];
+
+ /* if AFE port is still up, close it */
+ if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
+ rc = afe_close(dai->id); /* can block */
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev, "%s: fail to close Group MI2S port 0x%x\n",
+ __func__, dai->id);
+ }
+ atomic_dec(group_ref);
+ clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
+
+ if (atomic_read(group_ref) == 0) {
+ rc = afe_port_group_mi2s_enable(group_id, NULL, false);
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev, "%s: fail to disable Group MI2S group 0x%x\n",
+ __func__, group_id);
+ }
+ rc = msm_dai_q6_group_mi2s_set_clk(dai_data,
+ dai->id, false);
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev, "%s: fail to disable AFE clk 0x%x\n",
+ __func__, dai->id);
+ }
+ }
+ }
+ return 0;
+}
+
+static int msm_dai_q6_group_mi2s_set_channel_map(struct snd_soc_dai *dai,
+ unsigned int tx_num, unsigned int *tx_slot,
+ unsigned int rx_num, unsigned int *rx_slot)
+{
+ int rc = 0;
+ struct msm_dai_q6_group_mi2s_dai_data *dai_data =
+ dev_get_drvdata(dai->dev);
+ int i = 0;
+
+ switch (dai->id) {
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_1:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_2:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_3:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_4:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_1:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_2:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_3:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_4:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_1:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_2:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_3:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_4:
+ if (!rx_slot) {
+ dev_err(dai->dev, "%s: rx slot not found\n",
+ __func__);
+ return -EINVAL;
+ }
+ for (i = 0; i < rx_num; i++)
+ dai_data->port_cfg.slot_mapping.offset[i] = rx_slot[i];
+ for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
+ dai_data->port_cfg.slot_mapping.offset[i] =
+ AFE_SLOT_MAPPING_OFFSET_INVALID;
+ dai_data->port_cfg.slot_mapping.num_channel = rx_num;
+ break;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_1:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_2:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_3:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_4:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_1:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_2:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_3:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_4:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_1:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_2:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_3:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_4:
+ if (!tx_slot) {
+ dev_err(dai->dev, "%s: tx slot not found\n",
+ __func__);
+ return -EINVAL;
+ }
+ for (i = 0; i < tx_num; i++)
+ dai_data->port_cfg.slot_mapping.offset[i] = tx_slot[i];
+ for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
+ dai_data->port_cfg.slot_mapping.offset[i] =
+ AFE_SLOT_MAPPING_OFFSET_INVALID;
+
+ dai_data->port_cfg.slot_mapping.num_channel = tx_num;
+ break;
+ default:
+ dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
+ __func__, dai->id);
+ return -EINVAL;
+ }
+
+ return rc;
+}
+
+static int msm_dai_q6_group_mi2s_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct msm_dai_q6_group_mi2s_dai_data *dai_data =
+ dev_get_drvdata(dai->dev);
+ struct afe_param_id_group_device_i2s_cfg_v1 *group_mi2s_cfg =
+ &dai_data->group_cfg.i2s_cfg;
+ struct afe_param_id_i2s_cfg *dev_i2s_cfg =
+ &dai_data->port_cfg.i2s_cfg;
+ struct afe_param_id_slot_mapping_cfg *slot_mapping =
+ &dai_data->port_cfg.slot_mapping;
+
+ /* update group_mi2s group config param */
+ dai_data->channels = params_channels(params);
+ dai_data->rate = params_rate(params);
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ case SNDRV_PCM_FORMAT_SPECIAL:
+ dai_data->bit_width = 16;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ dai_data->bit_width = 24;
+ break;
+ default:
+ pr_err("%s: format %d\n",
+ __func__, params_format(params));
+ return -EINVAL;
+ }
+
+ /* update group_mi2s config param */
+ group_mi2s_cfg->sample_rate = dai_data->rate;
+ group_mi2s_cfg->bit_width = dai_data->bit_width;
+ pr_debug("%s: Group MI2S GROUP 0x%x:\n"
+ "channel_mode = %d sample_rate = %d bit_width = %d\n",
+ __func__, group_mi2s_cfg->group_id,
+ group_mi2s_cfg->channel_mode,
+ group_mi2s_cfg->sample_rate,
+ group_mi2s_cfg->bit_width);
+ pr_debug("%s: Group MI2S GROUP 0x%x:\n"
+ "port_id[0]=0x%x port_id[1]=0x%x port_id[2]=0x%x port_id[3]=0x%x\n"
+ "port_id[4]=0x%x port_id[5]=0x%x port_id[6]=0x%x port_id[7]=0x%x\n",
+ __func__, group_mi2s_cfg->group_id,
+ group_mi2s_cfg->port_id[0],
+ group_mi2s_cfg->port_id[1],
+ group_mi2s_cfg->port_id[2],
+ group_mi2s_cfg->port_id[3],
+ group_mi2s_cfg->port_id[4],
+ group_mi2s_cfg->port_id[5],
+ group_mi2s_cfg->port_id[6],
+ group_mi2s_cfg->port_id[7]);
+ /*i2s port cfg*/
+ dev_i2s_cfg->i2s_cfg_minor_version =
+ AFE_API_VERSION_I2S_CONFIG;
+ dev_i2s_cfg->bit_width = group_mi2s_cfg->bit_width;
+ dev_i2s_cfg->mono_stereo = AFE_PORT_I2S_STEREO;
+ dev_i2s_cfg->sample_rate = group_mi2s_cfg->sample_rate;
+ dev_i2s_cfg->data_format = AFE_LINEAR_PCM_DATA;
+ dev_i2s_cfg->ws_src = dai_data->sync_mode;
+ pr_debug("%s: MI2S port:\n"
+ "dai id %d dai_data->channels = %d\n"
+ "sample_rate = %u i2s_cfg_minor_version = 0x%x\n"
+ "bit_width = %hu channel_mode = 0x%x mono_stereo = %#x\n"
+ "ws_src = 0x%x sample_rate = %u data_format = 0x%x\n"
+ "reserved = %u\n", __func__, dai->id, dai_data->channels,
+ dai_data->rate, dev_i2s_cfg->i2s_cfg_minor_version,
+ dev_i2s_cfg->bit_width, dev_i2s_cfg->channel_mode,
+ dev_i2s_cfg->mono_stereo, dev_i2s_cfg->ws_src,
+ dev_i2s_cfg->sample_rate, dev_i2s_cfg->data_format,
+ dev_i2s_cfg->reserved);
+
+ /*slot mapping cfg*/
+ slot_mapping->minor_version =
+ AFE_API_VERSION_SLOT_MAPPING_CONFIG;
+ slot_mapping->bitwidth = group_mi2s_cfg->bit_width;
+ slot_mapping->data_align_type =
+ AFE_SLOT_MAPPING_DATA_ALIGN_MSB;
+ pr_debug("%s: Group MI2S port 0x%x SLOT MAPPING:\n"
+ "num_channel=%d bitwidth=%d data_align=0x%x\n",
+ __func__, dai->id,
+ slot_mapping->num_channel,
+ slot_mapping->bitwidth,
+ slot_mapping->data_align_type);
+ pr_debug("%s: Group MI2S port 0x%x SLOT MAPPING:\n"
+ "offset[0]=0x%x offset[1]=0x%x offset[2]=0x%x offset[3]=0x%x\n"
+ "offset[4]=0x%x offset[5]=0x%x offset[6]=0x%x offset[7]=0x%x\n",
+ __func__, dai->id,
+ slot_mapping->offset[0],
+ slot_mapping->offset[1],
+ slot_mapping->offset[2],
+ slot_mapping->offset[3],
+ slot_mapping->offset[4],
+ slot_mapping->offset[5],
+ slot_mapping->offset[6],
+ slot_mapping->offset[7]);
+
+ return 0;
+}
+
+static int msm_dai_q6_group_mi2s_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ int rc = 0;
+ struct msm_dai_q6_group_mi2s_dai_data *dai_data =
+ dev_get_drvdata(dai->dev);
+ u16 group_id = dai_data->group_cfg.i2s_cfg.group_id;
+ int group_idx = 0;
+ atomic_t *group_ref = NULL;
+
+ group_idx = msm_dai_q6_get_mi2s_group_idx(dai->id);
+ if (group_idx < 0 || group_idx > IDX_GROUP_MI2S_MAX) {
+ dev_err(dai->dev, "%s port id 0x%x not supported\n",
+ __func__, dai->id);
+ return -EINVAL;
+ }
+
+ mutex_lock(&group_mi2s_mutex);
+
+ group_ref = &group_mi2s_ref[group_idx];
+
+ if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
+ /* PORT START should be set if prepare called
+ * in active state.
+ */
+ if (atomic_read(group_ref) == 0) {
+ /*
+ * TX and RX share the same clk.
+ * AFE clk is enabled per group to simplify the logic.
+ * DSP will monitor the clk count.
+ */
+ rc = msm_dai_q6_group_mi2s_set_clk(dai_data,
+ dai->id, true);
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev, "%s: fail to enable AFE clk 0x%x\n",
+ __func__, dai->id);
+ goto rtn;
+ }
+
+ /*
+ * if only one port, don't do group enable as there
+ * is no group need for only one port
+ */
+ if (dai_data->num_group_ports > 1) {
+ rc = afe_port_group_mi2s_enable(group_id,
+ &dai_data->group_cfg, true);
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev,
+ "%s: fail to enable AFE group 0x%x\n",
+ __func__, group_id);
+ goto rtn;
+ }
+ }
+ }
+
+ rc = afe_i2s_port_start(dai->id, &dai_data->port_cfg,
+ dai_data->rate, dai_data->num_group_ports);
+ if (IS_ERR_VALUE(rc)) {
+ if (atomic_read(group_ref) == 0) {
+ afe_port_group_mi2s_enable(group_id,
+ NULL, false);
+ msm_dai_q6_group_mi2s_set_clk(dai_data,
+ dai->id, false);
+ }
+ dev_err(dai->dev, "%s: fail to open AFE port 0x%x\n",
+ __func__, dai->id);
+ } else {
+ set_bit(STATUS_PORT_STARTED,
+ dai_data->status_mask);
+ atomic_inc(group_ref);
+ }
+ }
+
+rtn:
+ mutex_unlock(&group_mi2s_mutex);
+ return rc;
+}
+
+static void msm_dai_q6_group_mi2s_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ int rc = 0;
+ struct msm_dai_q6_group_mi2s_dai_data *dai_data =
+ dev_get_drvdata(dai->dev);
+ u16 group_id = dai_data->group_cfg.i2s_cfg.group_id;
+ int group_idx = 0;
+ atomic_t *group_ref = NULL;
+
+ group_idx = msm_dai_q6_get_mi2s_group_idx(dai->id);
+ if (group_idx < 0 || group_idx > IDX_GROUP_MI2S_MAX) {
+ dev_err(dai->dev, "%s port id 0x%x not supported\n",
+ __func__, dai->id);
+ return;
+ }
+
+ mutex_lock(&group_mi2s_mutex);
+ group_ref = &group_mi2s_ref[group_idx];
+
+ if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
+ rc = afe_close(dai->id);
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev, "%s: fail to close AFE port 0x%x\n",
+ __func__, dai->id);
+ }
+ atomic_dec(group_ref);
+ clear_bit(STATUS_PORT_STARTED,
+ dai_data->status_mask);
+
+ if (atomic_read(group_ref) == 0) {
+ rc = afe_port_group_mi2s_enable(group_id,
+ NULL, false);
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev, "%s: fail to disable AFE group 0x%x\n",
+ __func__, group_id);
+ }
+ rc = msm_dai_q6_group_mi2s_set_clk(dai_data,
+ dai->id, false);
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev, "%s: fail to disable AFE clk 0x%x\n",
+ __func__, dai->id);
+ }
+ }
+ }
+
+ mutex_unlock(&group_mi2s_mutex);
+}
+
+static struct snd_soc_dai_ops msm_dai_q6_group_mi2s_ops = {
+ .prepare = msm_dai_q6_group_mi2s_prepare,
+ .hw_params = msm_dai_q6_group_mi2s_hw_params,
+ .set_channel_map = msm_dai_q6_group_mi2s_set_channel_map,
+ .shutdown = msm_dai_q6_group_mi2s_shutdown,
+};
+
+static struct snd_soc_dai_driver msm_dai_q6_group_mi2s_dai[] = {
+ {
+ .playback = {
+ .stream_name = "Secondary MI2S1 Playback",
+ .aif_name = "SEC_MI2S_RX_1",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_SECONDARY_MI2S_RX_1,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "Secondary MI2S2 Playback",
+ .aif_name = "SEC_MI2S_RX_2",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_SECONDARY_MI2S_RX_2,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "Secondary MI2S3 Playback",
+ .aif_name = "SEC_MI2S_RX_3",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_SECONDARY_MI2S_RX_3,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "Secondary MI2S4 Playback",
+ .aif_name = "SEC_MI2S_RX_4",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_SECONDARY_MI2S_RX_4,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .capture = {
+ .stream_name = "Secondary MI2S1 Capture",
+ .aif_name = "SEC_MI2S_TX_1",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_SECONDARY_MI2S_TX_1,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .capture = {
+ .stream_name = "Secondary MI2S2 Capture",
+ .aif_name = "SEC_MI2S_TX_2",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_SECONDARY_MI2S_TX_2,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .capture = {
+ .stream_name = "Secondary MI2S3 Capture",
+ .aif_name = "SEC_MI2S_TX_3",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_SECONDARY_MI2S_TX_3,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .capture = {
+ .stream_name = "Secondary MI2S4 Capture",
+ .aif_name = "SEC_MI2S_TX_4",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_SECONDARY_MI2S_TX_4,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "Tertiary MI2S1 Playback",
+ .aif_name = "TERT_MI2S_RX_1",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_TERTIARY_MI2S_RX_1,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "Tertiary MI2S2 Playback",
+ .aif_name = "TERT_MI2S_RX_2",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_TERTIARY_MI2S_RX_2,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "Tertiary MI2S3 Playback",
+ .aif_name = "TERT_MI2S_RX_3",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_TERTIARY_MI2S_RX_3,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "Tertiary MI2S4 Playback",
+ .aif_name = "TERT_MI2S_RX_4",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_TERTIARY_MI2S_RX_4,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .capture = {
+ .stream_name = "Tertiary MI2S1 Capture",
+ .aif_name = "TERT_MI2S_TX_1",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_TERTIARY_MI2S_TX_1,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .capture = {
+ .stream_name = "Tertiary MI2S2 Capture",
+ .aif_name = "TERT_MI2S_TX_2",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_TERTIARY_MI2S_TX_2,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .capture = {
+ .stream_name = "Tertiary MI2S3 Capture",
+ .aif_name = "TERT_MI2S_TX_3",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_TERTIARY_MI2S_TX_3,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .capture = {
+ .stream_name = "Tertiary MI2S4 Capture",
+ .aif_name = "TERT_MI2S_TX_4",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_TERTIARY_MI2S_TX_4,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "Quaternary MI2S1 Playback",
+ .aif_name = "QUAT_MI2S_RX_1",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_QUATERNARY_MI2S_RX_1,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "Quaternary MI2S2 Playback",
+ .aif_name = "QUAT_MI2S_RX_2",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_QUATERNARY_MI2S_RX_2,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "Quaternary MI2S3 Playback",
+ .aif_name = "QUAT_MI2S_RX_3",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_QUATERNARY_MI2S_RX_3,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .playback = {
+ .stream_name = "Quaternary MI2S4 Playback",
+ .aif_name = "QUAT_MI2S_RX_4",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_QUATERNARY_MI2S_RX_4,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .capture = {
+ .stream_name = "Quaternary MI2S1 Capture",
+ .aif_name = "QUAT_MI2S_TX_1",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_QUATERNARY_MI2S_TX_1,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .capture = {
+ .stream_name = "Quaternary MI2S2 Capture",
+ .aif_name = "QUAT_MI2S_TX_2",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_QUATERNARY_MI2S_TX_2,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .capture = {
+ .stream_name = "Quaternary MI2S3 Capture",
+ .aif_name = "QUAT_MI2S_TX_3",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_QUATERNARY_MI2S_TX_3,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ },
+ {
+ .capture = {
+ .stream_name = "Quaternary MI2S4 Capture",
+ .aif_name = "QUAT_MI2S_TX_4",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_dai_q6_group_mi2s_ops,
+ .id = AFE_PORT_ID_QUATERNARY_MI2S_TX_4,
+ .probe = msm_dai_q6_dai_group_mi2s_probe,
+ .remove = msm_dai_q6_dai_group_mi2s_remove,
+ }
+};
static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr,
unsigned int *ch_cnt)
@@ -4923,6 +5977,297 @@ static struct platform_driver msm_dai_q6_mi2s_driver = {
},
};
+static int msm_dai_group_mi2s_probe(struct platform_device *pdev)
+{
+ int rc = 0;
+
+ /* probe child node info */
+ rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+ if (rc) {
+ dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n",
+ __func__, rc);
+ goto rtn;
+ } else
+ dev_dbg(&pdev->dev, "%s: added child node\n", __func__);
+
+rtn:
+ return rc;
+}
+
+static int msm_dai_group_mi2s_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static int msm_dai_q6_group_mi2s_dev_id_validation(u32 dev_id)
+{
+ switch (dev_id) {
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_1:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_2:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_3:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_4:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_1:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_2:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_3:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_4:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_1:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_2:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_3:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_4:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_1:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_2:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_3:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_4:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_1:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_2:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_3:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_4:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_1:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_2:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_3:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_4:
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct snd_soc_component_driver msm_q6_group_mi2s_dai_component = {
+ .name = "msm-dai-q6-mi2s-group",
+};
+
+static int msm_dai_group_mi2s_dev_probe(struct platform_device *pdev)
+{
+ int rc = 0;
+ struct msm_dai_q6_group_mi2s_dai_data *dai_data = NULL;
+ u32 mi2s_dev_id = 0;
+ u32 ch_mode = 0;
+ int port_idx = 0;
+ struct device_node *mi2s_parent_node = NULL;
+ u32 num_group_mi2s_ports = 0;
+ const uint32_t *port_id_array = NULL;
+ u32 array_length, i = 0;
+ u32 group_idx = 0;
+ u32 sync_mode = 0;
+
+ mi2s_parent_node = of_get_parent(pdev->dev.of_node);
+ /* extract mi2s group info into static */
+ rc = of_property_read_u32(mi2s_parent_node,
+ "qcom,msm-cpudai-mi2s-group-id",
+ (u32 *)&group_mi2s_cfg.group_id);
+ if (rc) {
+ dev_err(&pdev->dev, "%s: Group ID from DT file %s\n",
+ __func__, "qcom,msm-cpudai-mi2s-group-id");
+ goto rtn;
+ }
+
+ rc = of_property_read_u32(mi2s_parent_node,
+ "qcom,msm-cpudai-mi2s-group-num-ports",
+ &num_group_mi2s_ports);
+ if (rc) {
+ dev_err(&pdev->dev, "%s: ch_mode from DT file %s\n",
+ __func__, "qcom,msm-cpudai-mi2s-group-num-ports");
+ goto rtn;
+ }
+
+ if (num_group_mi2s_ports > AFE_GROUP_DEVICE_NUM_PORTS) {
+ dev_err(&pdev->dev, "%s: Group Num Ports %d greater than Man %d\n",
+ __func__, num_group_mi2s_ports,
+ AFE_GROUP_DEVICE_NUM_PORTS);
+ rc = -EINVAL;
+ goto rtn;
+ }
+
+ port_id_array = of_get_property(mi2s_parent_node,
+ "qcom,msm-cpudai-mi2s-group-port-id",
+ &array_length);
+ if (port_id_array == NULL) {
+ dev_err(&pdev->dev, "%s: prot_id_array is not valid\n",
+ __func__);
+ rc = -EINVAL;
+ goto rtn;
+ }
+ if (array_length != sizeof(uint32_t) * num_group_mi2s_ports) {
+ dev_err(&pdev->dev, "%s array_length is %d, expected is %zd\n",
+ __func__, array_length,
+ sizeof(uint32_t) * num_group_mi2s_ports);
+ rc = -EINVAL;
+ goto rtn;
+ }
+
+ for (i = 0; i < num_group_mi2s_ports; i++)
+ group_mi2s_cfg.port_id[i] = (u16)be32_to_cpu(port_id_array[i]);
+ /* Unused index should be filled with AFE_PORT_INVALID */
+ for (i = num_group_mi2s_ports; i < AFE_GROUP_DEVICE_NUM_PORTS; i++)
+ group_mi2s_cfg.port_id[i] = AFE_PORT_INVALID;
+
+ /*extract group_mi2s group sd line info into static */
+ rc = of_property_read_u32(mi2s_parent_node,
+ "qcom,msm-cpudai-mi2s-channel-mode",
+ &ch_mode);
+ if (rc) {
+ dev_err(&pdev->dev, "%s: ch_mode from DT file %s\n",
+ __func__, "qcom,msm-cpudai-mi2s-channel-mode");
+ goto rtn;
+ }
+
+ group_mi2s_cfg.channel_mode = ch_mode;
+ group_mi2s_cfg.minor_version = AFE_API_VERSION_I2S_CONFIG;
+ group_idx = msm_dai_q6_get_mi2s_group_idx(group_mi2s_cfg.group_id);
+ if (group_idx < 0 || group_idx > IDX_GROUP_MI2S_MAX) {
+ dev_err(&pdev->dev, "%s: group id 0x%x not supported\n",
+ __func__, group_mi2s_cfg.group_id);
+ rc = -EINVAL;
+ goto rtn;
+ }
+ atomic_set(&group_mi2s_ref[group_idx], 0);
+
+ rc = of_property_read_u32(mi2s_parent_node,
+ "qcom,msm-cpudai-mi2s-sync-mode",
+ &sync_mode);
+ if (rc) {
+ dev_err(&pdev->dev, "%s: ch_mode from DT file %s\n",
+ __func__, "qcom,msm-cpudai-mi2s-sync-mode");
+ goto rtn;
+ }
+
+ rc = of_property_read_u32(mi2s_parent_node,
+ "qcom,msm-cpudai-mi2s-mclk",
+ &group_mi2s_mclk_set.clk_freq_in_hz);
+ if (rc) {
+ dev_err(&pdev->dev, "%s: mclk from DT file %s\n",
+ __func__, "qcom,msm-cpudai-mi2s-mclk");
+ goto rtn;
+ }
+
+ rc = of_property_read_u32(mi2s_parent_node,
+ "qcom,msm-cpudai-mi2s-bclk",
+ &group_mi2s_bclk_set.clk_freq_in_hz);
+ if (rc) {
+ dev_err(&pdev->dev, "%s: bclk from DT file %s\n",
+ __func__, "qcom,msm-cpudai-mi2s-bclk");
+ goto rtn;
+ }
+
+ /*update default group mi2s clk set for master/slave select*/
+ rc = msm_dai_q6_group_mi2s_set_clk_param(group_mi2s_cfg.group_id,
+ &group_mi2s_mclk_set,
+ &group_mi2s_bclk_set,
+ sync_mode);
+ if (rc) {
+ dev_err(&pdev->dev, "%s: group id not supported 0x%x\n",
+ __func__, tdm_group_cfg.group_id);
+ goto rtn;
+ }
+
+ /* retrieve device/afe id */
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "qcom,msm-cpudai-mi2s-dev-id",
+ &mi2s_dev_id);
+ if (rc) {
+ dev_err(&pdev->dev, "%s: DeviceID missing in DT file\n",
+ __func__);
+ goto rtn;
+ }
+ rc = msm_dai_q6_group_mi2s_dev_id_validation(mi2s_dev_id);
+ if (rc) {
+ dev_err(&pdev->dev, "%s: Invalid GMI2S device ID %d in DT file\n",
+ __func__, mi2s_dev_id);
+ rc = -ENXIO;
+ goto rtn;
+ }
+
+ pdev->id = mi2s_dev_id;
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "qcom,msm-cpudai-mi2s-dev-channel-mode",
+ &ch_mode);
+ if (rc) {
+ dev_err(&pdev->dev, "%s: TX line from DT file %s\n",
+ __func__, "qcom,msm-cpudai-mi2s-dev-channel-mode");
+ goto rtn;
+ }
+
+ dai_data = kzalloc(sizeof(*dai_data),
+ GFP_KERNEL);
+ if (!dai_data) {
+ rc = -ENOMEM;
+ goto rtn;
+ }
+ dev_set_drvdata(&pdev->dev, dai_data);
+
+ dai_data->sync_mode = sync_mode;
+ dai_data->num_group_ports = num_group_mi2s_ports;
+ dai_data->port_cfg.i2s_cfg.channel_mode = ch_mode;
+ dai_data->bclk_set = group_mi2s_bclk_set;
+ dai_data->mclk_set = group_mi2s_mclk_set;
+ dai_data->group_cfg.i2s_cfg = group_mi2s_cfg;
+
+ port_idx = msm_dai_q6_get_mi2s_port_idx(mi2s_dev_id);
+ if (port_idx < 0 || port_idx > IDX_GROUP_MI2S_PORT_MAX) {
+ dev_err(&pdev->dev, "%s: Port id 0x%x not supported\n",
+ __func__, mi2s_dev_id);
+ rc = -EINVAL;
+ goto free_dai_data;
+ }
+
+ rc = snd_soc_register_component(&pdev->dev,
+ &msm_q6_group_mi2s_dai_component,
+ &msm_dai_q6_group_mi2s_dai[port_idx], 1);
+ if (rc) {
+ dev_err(&pdev->dev,
+ "%s: fail to register msm_q6_group_mi2s_dai_component\n",
+ __func__);
+ goto free_dai_data;
+ }
+
+ return 0;
+
+free_dai_data:
+ kfree(dai_data);
+rtn:
+ return rc;
+}
+
+static int msm_dai_group_mi2s_dev_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_component(&pdev->dev);
+ return 0;
+}
+
+static const struct of_device_id msm_dai_group_mi2s_dt_match[] = {
+ { .compatible = "qcom,msm-dai-group-mi2s", },
+ { }
+};
+
+MODULE_DEVICE_TABLE(of, msm_dai_group_mi2s_dt_match);
+
+static struct platform_driver msm_dai_group_mi2s_driver = {
+ .probe = msm_dai_group_mi2s_probe,
+ .remove = msm_dai_group_mi2s_remove,
+ .driver = {
+ .name = "msm-dai-group-mi2s",
+ .owner = THIS_MODULE,
+ .of_match_table = msm_dai_group_mi2s_dt_match,
+ },
+};
+
+static const struct of_device_id msm_dai_group_mi2s_dev_dt_match[] = {
+ { .compatible = "qcom,msm-dai-group-mi2s-dev", },
+ { }
+};
+
+MODULE_DEVICE_TABLE(of, msm_dai_group_mi2s_dev_dt_match);
+
+static struct platform_driver msm_dai_group_mi2s_dev_driver = {
+ .probe = msm_dai_group_mi2s_dev_probe,
+ .remove = msm_dai_group_mi2s_dev_remove,
+ .driver = {
+ .name = "msm-dai-group-mi2s-dev",
+ .owner = THIS_MODULE,
+ .of_match_table = msm_dai_group_mi2s_dev_dt_match,
+ },
+};
+
static int msm_dai_q6_spdif_dev_probe(struct platform_device *pdev)
{
int rc;
@@ -8344,8 +9689,27 @@ static int __init msm_dai_q6_init(void)
pr_err("%s: fail to register dai TDM\n", __func__);
goto dai_tdm_q6_fail;
}
+
+ rc = platform_driver_register(&msm_dai_group_mi2s_dev_driver);
+ if (rc) {
+ pr_err("%s: fail to register dai GMI2S dev drv\n",
+ __func__);
+ goto dai_q6_group_mi2s_dev_fail;
+ }
+
+ rc = platform_driver_register(&msm_dai_group_mi2s_driver);
+ if (rc) {
+ pr_err("%s: fail to register dai GMI2S\n",
+ __func__);
+ goto dai_group_mi2s_fail;
+ }
+
return rc;
+dai_group_mi2s_fail:
+ platform_driver_unregister(&msm_dai_group_mi2s_driver);
+dai_q6_group_mi2s_dev_fail:
+ platform_driver_unregister(&msm_dai_group_mi2s_dev_driver);
dai_tdm_q6_fail:
platform_driver_unregister(&msm_dai_q6_tdm_driver);
dai_q6_tdm_drv_fail:
@@ -8371,6 +9735,8 @@ static void __exit msm_dai_q6_exit(void)
platform_driver_unregister(&msm_dai_q6);
platform_driver_unregister(&msm_auxpcm_dev_driver);
platform_driver_unregister(&msm_dai_q6_spdif_driver);
+ platform_driver_unregister(&msm_dai_group_mi2s_driver);
+ platform_driver_unregister(&msm_dai_group_mi2s_dev_driver);
}
module_exit(msm_dai_q6_exit);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index b0843bca62bf..ee8c42903c99 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -546,6 +546,54 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
LPASS_BE_INT6_MI2S_RX},
{ AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
LPASS_BE_INT6_MI2S_TX},
+ { AFE_PORT_ID_SECONDARY_MI2S_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_SEC_MI2S_RX_1},
+ { AFE_PORT_ID_SECONDARY_MI2S_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_SEC_MI2S_RX_2},
+ { AFE_PORT_ID_SECONDARY_MI2S_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_SEC_MI2S_RX_3},
+ { AFE_PORT_ID_SECONDARY_MI2S_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_SEC_MI2S_RX_4},
+ { AFE_PORT_ID_SECONDARY_MI2S_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_SEC_MI2S_TX_1},
+ { AFE_PORT_ID_SECONDARY_MI2S_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_SEC_MI2S_TX_2},
+ { AFE_PORT_ID_SECONDARY_MI2S_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_SEC_MI2S_TX_3},
+ { AFE_PORT_ID_SECONDARY_MI2S_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_SEC_MI2S_TX_4},
+ { AFE_PORT_ID_TERTIARY_MI2S_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_TERT_MI2S_RX_1},
+ { AFE_PORT_ID_TERTIARY_MI2S_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_TERT_MI2S_RX_2},
+ { AFE_PORT_ID_TERTIARY_MI2S_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_TERT_MI2S_RX_3},
+ { AFE_PORT_ID_TERTIARY_MI2S_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_TERT_MI2S_RX_4},
+ { AFE_PORT_ID_TERTIARY_MI2S_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_TERT_MI2S_TX_1},
+ { AFE_PORT_ID_TERTIARY_MI2S_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_TERT_MI2S_TX_2},
+ { AFE_PORT_ID_TERTIARY_MI2S_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_TERT_MI2S_TX_3},
+ { AFE_PORT_ID_TERTIARY_MI2S_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_TERT_MI2S_TX_4},
+ { AFE_PORT_ID_QUATERNARY_MI2S_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_QUAT_MI2S_RX_1},
+ { AFE_PORT_ID_QUATERNARY_MI2S_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_QUAT_MI2S_RX_2},
+ { AFE_PORT_ID_QUATERNARY_MI2S_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_QUAT_MI2S_RX_3},
+ { AFE_PORT_ID_QUATERNARY_MI2S_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_QUAT_MI2S_RX_4},
+ { AFE_PORT_ID_QUATERNARY_MI2S_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_QUAT_MI2S_TX_1},
+ { AFE_PORT_ID_QUATERNARY_MI2S_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_QUAT_MI2S_TX_2},
+ { AFE_PORT_ID_QUATERNARY_MI2S_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_QUAT_MI2S_TX_3},
+ { AFE_PORT_ID_QUATERNARY_MI2S_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0},
+ LPASS_BE_QUAT_MI2S_TX_4}
};
/* Track ASM playback & capture sessions of DAI
@@ -4723,6 +4771,834 @@ static const struct snd_kcontrol_new secondary_mi2s_rx2_mixer_controls[] = {
msm_routing_put_audio_mixer),
};
+static const struct snd_kcontrol_new secondary_mi2s_rx_1_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new secondary_mi2s_rx_2_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new secondary_mi2s_rx_3_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new secondary_mi2s_rx_4_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new tertiary_mi2s_rx_1_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new tertiary_mi2s_rx_2_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new tertiary_mi2s_rx_3_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new tertiary_mi2s_rx_4_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new quaternary_mi2s_rx_1_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new quaternary_mi2s_rx_2_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new quaternary_mi2s_rx_3_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new quaternary_mi2s_rx_4_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX ,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -7215,6 +8091,42 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_1", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_2", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_3", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_4", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_1", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_2", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_3", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_4", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_1", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_2", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_3", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_4", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mmul2_mixer_controls[] = {
@@ -7308,6 +8220,42 @@ static const struct snd_kcontrol_new mmul2_mixer_controls[] = {
SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX,
MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_1", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_2", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_3", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_4", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_1", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_2", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_3", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_4", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_1", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_2", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_3", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_4", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mmul3_mixer_controls[] = {
@@ -7398,6 +8346,42 @@ static const struct snd_kcontrol_new mmul3_mixer_controls[] = {
SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3,
MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_1", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_2", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_3", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_4", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_1", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_2", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_3", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_4", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_1", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_2", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_3", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_4", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mmul4_mixer_controls[] = {
@@ -7593,6 +8577,42 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = {
SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_1", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_2", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_3", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_4", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_1", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_2", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_3", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_4", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_1", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_2", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_3", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_4", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mmul6_mixer_controls[] = {
@@ -7938,6 +8958,42 @@ static const struct snd_kcontrol_new mmul9_mixer_controls[] = {
SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3,
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_1", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_2", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_3", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_4", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_1", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_2", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_3", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_4", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_1", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_2", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_3", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_4", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mmul17_mixer_controls[] = {
@@ -8091,6 +9147,42 @@ static const struct snd_kcontrol_new mmul20_mixer_controls[] = {
SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3,
MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_1", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_2", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_3", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX_4", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_1", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_2", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_3", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_MI2S_TX_4", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_1", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_2", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_3", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_MI2S_TX_4", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mmul21_mixer_controls[] = {
@@ -12773,6 +13865,56 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
0, 0, 0 , 0),
SND_SOC_DAPM_AIF_IN("PCM_TX", "AFE Capture",
0, 0, 0 , 0),
+ SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX_1", "Secondary MI2S1 Capture",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX_2", "Secondary MI2S2 Capture",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX_3", "Secondary MI2S3 Capture",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX_4", "Secondary MI2S4 Capture",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX_1", "Tertiary MI2S1 Capture",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX_2", "Tertiary MI2S2 Capture",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX_3", "Tertiary MI2S3 Capture",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX_4", "Tertiary MI2S4 Capture",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX_1", "Quaternary MI2S1 Capture",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX_2", "Quaternary MI2S2 Capture",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX_3", "Quaternary MI2S3 Capture",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX_4", "Quaternary MI2S4 Capture",
+ 0, 0, 0, 0),
+
+ SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_1", "Secondary MI2S1 Playback",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_2", "Secondary MI2S2 Playback",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_3", "Secondary MI2S3 Playback",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_4", "Secondary MI2S4 Playback",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX_1", "Tertiary MI2S1 Playback",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX_2", "Tertiary MI2S2 Playback",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX_3", "Tertiary MI2S3 Playback",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX_4", "Tertiary MI2S4 Playback",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX_1", "Quaternary MI2S1 Playback",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX_2", "Quaternary MI2S2 Playback",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX_3", "Quaternary MI2S3 Playback",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX_4", "Quaternary MI2S4 Playback",
+ 0, 0, 0, 0),
+
SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_0", "Primary TDM0 Playback",
0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_0", "Primary TDM0 Capture",
@@ -13024,6 +14166,42 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
SND_SOC_DAPM_MIXER("TERT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
tertiary_mi2s_rx_mixer_controls,
ARRAY_SIZE(tertiary_mi2s_rx_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_MI2S_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ secondary_mi2s_rx_1_mixer_controls,
+ ARRAY_SIZE(secondary_mi2s_rx_1_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_MI2S_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ secondary_mi2s_rx_2_mixer_controls,
+ ARRAY_SIZE(secondary_mi2s_rx_2_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_MI2S_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ secondary_mi2s_rx_3_mixer_controls,
+ ARRAY_SIZE(secondary_mi2s_rx_3_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SEC_MI2S_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ secondary_mi2s_rx_4_mixer_controls,
+ ARRAY_SIZE(secondary_mi2s_rx_4_mixer_controls)),
+ SND_SOC_DAPM_MIXER("TERT_MI2S_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ tertiary_mi2s_rx_1_mixer_controls,
+ ARRAY_SIZE(tertiary_mi2s_rx_1_mixer_controls)),
+ SND_SOC_DAPM_MIXER("TERT_MI2S_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ tertiary_mi2s_rx_2_mixer_controls,
+ ARRAY_SIZE(tertiary_mi2s_rx_2_mixer_controls)),
+ SND_SOC_DAPM_MIXER("TERT_MI2S_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ tertiary_mi2s_rx_3_mixer_controls,
+ ARRAY_SIZE(tertiary_mi2s_rx_3_mixer_controls)),
+ SND_SOC_DAPM_MIXER("TERT_MI2S_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ tertiary_mi2s_rx_4_mixer_controls,
+ ARRAY_SIZE(tertiary_mi2s_rx_4_mixer_controls)),
+ SND_SOC_DAPM_MIXER("QUAT_MI2S_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ quaternary_mi2s_rx_1_mixer_controls,
+ ARRAY_SIZE(quaternary_mi2s_rx_1_mixer_controls)),
+ SND_SOC_DAPM_MIXER("QUAT_MI2S_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ quaternary_mi2s_rx_2_mixer_controls,
+ ARRAY_SIZE(quaternary_mi2s_rx_2_mixer_controls)),
+ SND_SOC_DAPM_MIXER("QUAT_MI2S_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ quaternary_mi2s_rx_3_mixer_controls,
+ ARRAY_SIZE(quaternary_mi2s_rx_3_mixer_controls)),
+ SND_SOC_DAPM_MIXER("QUAT_MI2S_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ quaternary_mi2s_rx_4_mixer_controls,
+ ARRAY_SIZE(quaternary_mi2s_rx_4_mixer_controls)),
SND_SOC_DAPM_MIXER("SEC_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
secondary_mi2s_rx_mixer_controls,
ARRAY_SIZE(secondary_mi2s_rx_mixer_controls)),
@@ -14346,6 +15524,222 @@ static const struct snd_soc_dapm_route intercon[] = {
{"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia26", "MM_DL26"},
{"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Audio Mixer"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"},
+ {"SEC_MI2S_RX_1", NULL, "SEC_MI2S_RX_1 Audio Mixer"},
+
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia26", "MM_DL26"},
+ {"SEC_MI2S_RX_2", NULL, "SEC_MI2S_RX_2 Audio Mixer"},
+
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia26", "MM_DL26"},
+ {"SEC_MI2S_RX_3", NULL, "SEC_MI2S_RX_3 Audio Mixer"},
+
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia26", "MM_DL26"},
+ {"SEC_MI2S_RX_4", NULL, "SEC_MI2S_RX_4 Audio Mixer"},
+
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"},
+ {"TERT_MI2S_RX_1", NULL, "TERT_MI2S_RX_1 Audio Mixer"},
+
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia26", "MM_DL26"},
+ {"TERT_MI2S_RX_2", NULL, "TERT_MI2S_RX_2 Audio Mixer"},
+
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia26", "MM_DL26"},
+ {"TERT_MI2S_RX_3", NULL, "TERT_MI2S_RX_3 Audio Mixer"},
+
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia26", "MM_DL26"},
+ {"TERT_MI2S_RX_4", NULL, "TERT_MI2S_RX_4 Audio Mixer"},
+
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"},
+ {"QUAT_MI2S_RX_1", NULL, "QUAT_MI2S_RX_1 Audio Mixer"},
+
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia26", "MM_DL26"},
+ {"QUAT_MI2S_RX_2", NULL, "QUAT_MI2S_RX_2 Audio Mixer"},
+
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia26", "MM_DL26"},
+ {"QUAT_MI2S_RX_3", NULL, "QUAT_MI2S_RX_3 Audio Mixer"},
+
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia26", "MM_DL26"},
+ {"QUAT_MI2S_RX_4", NULL, "QUAT_MI2S_RX_4 Audio Mixer"},
+
{"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
{"MultiMedia1 Mixer", "MI2S_TX", "MI2S_TX"},
{"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"},
@@ -14423,6 +15817,19 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia1 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
{"MultiMedia1 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"MultiMedia1 Mixer", "SEC_MI2S_TX_1", "SEC_MI2S_TX_1"},
+ {"MultiMedia1 Mixer", "SEC_MI2S_TX_2", "SEC_MI2S_TX_2"},
+ {"MultiMedia1 Mixer", "SEC_MI2S_TX_3", "SEC_MI2S_TX_3"},
+ {"MultiMedia1 Mixer", "SEC_MI2S_TX_4", "SEC_MI2S_TX_4"},
+ {"MultiMedia1 Mixer", "TERT_MI2S_TX_1", "TERT_MI2S_TX_1"},
+ {"MultiMedia1 Mixer", "TERT_MI2S_TX_2", "TERT_MI2S_TX_2"},
+ {"MultiMedia1 Mixer", "TERT_MI2S_TX_3", "TERT_MI2S_TX_3"},
+ {"MultiMedia1 Mixer", "TERT_MI2S_TX_4", "TERT_MI2S_TX_4"},
+ {"MultiMedia1 Mixer", "QUAT_MI2S_TX_1", "QUAT_MI2S_TX_1"},
+ {"MultiMedia1 Mixer", "QUAT_MI2S_TX_2", "QUAT_MI2S_TX_2"},
+ {"MultiMedia1 Mixer", "QUAT_MI2S_TX_3", "QUAT_MI2S_TX_3"},
+ {"MultiMedia1 Mixer", "QUAT_MI2S_TX_4", "QUAT_MI2S_TX_4"},
+
{"MultiMedia2 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
{"MultiMedia2 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
{"MultiMedia2 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
@@ -14439,6 +15846,18 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia2 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
{"MultiMedia2 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
{"MultiMedia2 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"MultiMedia2 Mixer", "SEC_MI2S_TX_1", "SEC_MI2S_TX_1"},
+ {"MultiMedia2 Mixer", "SEC_MI2S_TX_2", "SEC_MI2S_TX_2"},
+ {"MultiMedia2 Mixer", "SEC_MI2S_TX_3", "SEC_MI2S_TX_3"},
+ {"MultiMedia2 Mixer", "SEC_MI2S_TX_4", "SEC_MI2S_TX_4"},
+ {"MultiMedia2 Mixer", "TERT_MI2S_TX_1", "TERT_MI2S_TX_1"},
+ {"MultiMedia2 Mixer", "TERT_MI2S_TX_2", "TERT_MI2S_TX_2"},
+ {"MultiMedia2 Mixer", "TERT_MI2S_TX_3", "TERT_MI2S_TX_3"},
+ {"MultiMedia2 Mixer", "TERT_MI2S_TX_4", "TERT_MI2S_TX_4"},
+ {"MultiMedia2 Mixer", "QUAT_MI2S_TX_1", "QUAT_MI2S_TX_1"},
+ {"MultiMedia2 Mixer", "QUAT_MI2S_TX_2", "QUAT_MI2S_TX_2"},
+ {"MultiMedia2 Mixer", "QUAT_MI2S_TX_3", "QUAT_MI2S_TX_3"},
+ {"MultiMedia2 Mixer", "QUAT_MI2S_TX_4", "QUAT_MI2S_TX_4"},
{"MultiMedia3 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
{"MultiMedia3 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
@@ -14456,6 +15875,18 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia3 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
{"MultiMedia3 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
{"MultiMedia3 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"MultiMedia3 Mixer", "SEC_MI2S_TX_1", "SEC_MI2S_TX_1"},
+ {"MultiMedia3 Mixer", "SEC_MI2S_TX_2", "SEC_MI2S_TX_2"},
+ {"MultiMedia3 Mixer", "SEC_MI2S_TX_3", "SEC_MI2S_TX_3"},
+ {"MultiMedia3 Mixer", "SEC_MI2S_TX_4", "SEC_MI2S_TX_4"},
+ {"MultiMedia3 Mixer", "TERT_MI2S_TX_1", "TERT_MI2S_TX_1"},
+ {"MultiMedia3 Mixer", "TERT_MI2S_TX_2", "TERT_MI2S_TX_2"},
+ {"MultiMedia3 Mixer", "TERT_MI2S_TX_3", "TERT_MI2S_TX_3"},
+ {"MultiMedia3 Mixer", "TERT_MI2S_TX_4", "TERT_MI2S_TX_4"},
+ {"MultiMedia3 Mixer", "QUAT_MI2S_TX_1", "QUAT_MI2S_TX_1"},
+ {"MultiMedia3 Mixer", "QUAT_MI2S_TX_2", "QUAT_MI2S_TX_2"},
+ {"MultiMedia3 Mixer", "QUAT_MI2S_TX_3", "QUAT_MI2S_TX_3"},
+ {"MultiMedia3 Mixer", "QUAT_MI2S_TX_4", "QUAT_MI2S_TX_4"},
{"MultiMedia4 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
{"MultiMedia4 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
@@ -14490,6 +15921,18 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia5 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
{"MultiMedia5 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
{"MultiMedia5 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"MultiMedia5 Mixer", "SEC_MI2S_TX_1", "SEC_MI2S_TX_1"},
+ {"MultiMedia5 Mixer", "SEC_MI2S_TX_2", "SEC_MI2S_TX_2"},
+ {"MultiMedia5 Mixer", "SEC_MI2S_TX_3", "SEC_MI2S_TX_3"},
+ {"MultiMedia5 Mixer", "SEC_MI2S_TX_4", "SEC_MI2S_TX_4"},
+ {"MultiMedia5 Mixer", "TERT_MI2S_TX_1", "TERT_MI2S_TX_1"},
+ {"MultiMedia5 Mixer", "TERT_MI2S_TX_2", "TERT_MI2S_TX_2"},
+ {"MultiMedia5 Mixer", "TERT_MI2S_TX_3", "TERT_MI2S_TX_3"},
+ {"MultiMedia5 Mixer", "TERT_MI2S_TX_4", "TERT_MI2S_TX_4"},
+ {"MultiMedia5 Mixer", "QUAT_MI2S_TX_1", "QUAT_MI2S_TX_1"},
+ {"MultiMedia5 Mixer", "QUAT_MI2S_TX_2", "QUAT_MI2S_TX_2"},
+ {"MultiMedia5 Mixer", "QUAT_MI2S_TX_3", "QUAT_MI2S_TX_3"},
+ {"MultiMedia5 Mixer", "QUAT_MI2S_TX_4", "QUAT_MI2S_TX_4"},
{"MultiMedia6 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
{"MultiMedia6 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
@@ -14533,11 +15976,35 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia9 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
{"MultiMedia9 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
{"MultiMedia9 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"MultiMedia9 Mixer", "SEC_MI2S_TX_1", "SEC_MI2S_TX_1"},
+ {"MultiMedia9 Mixer", "SEC_MI2S_TX_2", "SEC_MI2S_TX_2"},
+ {"MultiMedia9 Mixer", "SEC_MI2S_TX_3", "SEC_MI2S_TX_3"},
+ {"MultiMedia9 Mixer", "SEC_MI2S_TX_4", "SEC_MI2S_TX_4"},
+ {"MultiMedia9 Mixer", "TERT_MI2S_TX_1", "TERT_MI2S_TX_1"},
+ {"MultiMedia9 Mixer", "TERT_MI2S_TX_2", "TERT_MI2S_TX_2"},
+ {"MultiMedia9 Mixer", "TERT_MI2S_TX_3", "TERT_MI2S_TX_3"},
+ {"MultiMedia9 Mixer", "TERT_MI2S_TX_4", "TERT_MI2S_TX_4"},
+ {"MultiMedia9 Mixer", "QUAT_MI2S_TX_1", "QUAT_MI2S_TX_1"},
+ {"MultiMedia9 Mixer", "QUAT_MI2S_TX_2", "QUAT_MI2S_TX_2"},
+ {"MultiMedia9 Mixer", "QUAT_MI2S_TX_3", "QUAT_MI2S_TX_3"},
+ {"MultiMedia9 Mixer", "QUAT_MI2S_TX_4", "QUAT_MI2S_TX_4"},
{"MultiMedia20 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia20 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
{"MultiMedia20 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"MultiMedia20 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"MultiMedia20 Mixer", "SEC_MI2S_TX_1", "SEC_MI2S_TX_1"},
+ {"MultiMedia20 Mixer", "SEC_MI2S_TX_2", "SEC_MI2S_TX_2"},
+ {"MultiMedia20 Mixer", "SEC_MI2S_TX_3", "SEC_MI2S_TX_3"},
+ {"MultiMedia20 Mixer", "SEC_MI2S_TX_4", "SEC_MI2S_TX_4"},
+ {"MultiMedia20 Mixer", "TERT_MI2S_TX_1", "TERT_MI2S_TX_1"},
+ {"MultiMedia20 Mixer", "TERT_MI2S_TX_2", "TERT_MI2S_TX_2"},
+ {"MultiMedia20 Mixer", "TERT_MI2S_TX_3", "TERT_MI2S_TX_3"},
+ {"MultiMedia20 Mixer", "TERT_MI2S_TX_4", "TERT_MI2S_TX_4"},
+ {"MultiMedia20 Mixer", "QUAT_MI2S_TX_1", "QUAT_MI2S_TX_1"},
+ {"MultiMedia20 Mixer", "QUAT_MI2S_TX_2", "QUAT_MI2S_TX_2"},
+ {"MultiMedia20 Mixer", "QUAT_MI2S_TX_3", "QUAT_MI2S_TX_3"},
+ {"MultiMedia20 Mixer", "QUAT_MI2S_TX_4", "QUAT_MI2S_TX_4"},
{"MultiMedia20 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
{"MultiMedia20 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
{"MultiMedia20 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
@@ -16080,6 +17547,18 @@ static const struct snd_soc_dapm_route intercon[] = {
{"BE_OUT", NULL, "QUAT_TDM_RX_1"},
{"BE_OUT", NULL, "QUAT_TDM_RX_2"},
{"BE_OUT", NULL, "QUAT_TDM_RX_3"},
+ {"BE_OUT", NULL, "SEC_MI2S_RX_1"},
+ {"BE_OUT", NULL, "SEC_MI2S_RX_2"},
+ {"BE_OUT", NULL, "SEC_MI2S_RX_3"},
+ {"BE_OUT", NULL, "SEC_MI2S_RX_4"},
+ {"BE_OUT", NULL, "TERT_MI2S_RX_1"},
+ {"BE_OUT", NULL, "TERT_MI2S_RX_2"},
+ {"BE_OUT", NULL, "TERT_MI2S_RX_3"},
+ {"BE_OUT", NULL, "TERT_MI2S_RX_4"},
+ {"BE_OUT", NULL, "QUAT_MI2S_RX_1"},
+ {"BE_OUT", NULL, "QUAT_MI2S_RX_2"},
+ {"BE_OUT", NULL, "QUAT_MI2S_RX_3"},
+ {"BE_OUT", NULL, "QUAT_MI2S_RX_4"},
{"PRI_I2S_TX", NULL, "BE_IN"},
{"MI2S_TX", NULL, "BE_IN"},
@@ -16094,6 +17573,18 @@ static const struct snd_soc_dapm_route intercon[] = {
{"INT5_MI2S_TX", NULL, "BE_IN"},
{"SEC_MI2S_TX", NULL, "BE_IN"},
{"SENARY_MI2S_TX", NULL, "BE_IN" },
+ {"SEC_MI2S_TX_1", NULL, "BE_IN"},
+ {"SEC_MI2S_TX_2", NULL, "BE_IN"},
+ {"SEC_MI2S_TX_3", NULL, "BE_IN"},
+ {"SEC_MI2S_TX_4", NULL, "BE_IN"},
+ {"TERT_MI2S_TX_1", NULL, "BE_IN"},
+ {"TERT_MI2S_TX_2", NULL, "BE_IN"},
+ {"TERT_MI2S_TX_3", NULL, "BE_IN"},
+ {"TERT_MI2S_TX_4", NULL, "BE_IN"},
+ {"QUAT_MI2S_TX_1", NULL, "BE_IN"},
+ {"QUAT_MI2S_TX_2", NULL, "BE_IN"},
+ {"QUAT_MI2S_TX_3", NULL, "BE_IN"},
+ {"QUAT_MI2S_TX_4", NULL, "BE_IN"},
{"SLIMBUS_0_TX", NULL, "BE_IN" },
{"SLIMBUS_1_TX", NULL, "BE_IN" },
{"SLIMBUS_3_TX", NULL, "BE_IN" },
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index 531f83d752b0..bfeee4ad3607 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -167,6 +167,34 @@
#define LPASS_BE_INT5_MI2S_TX "INT5_MI2S_TX"
#define LPASS_BE_INT6_MI2S_RX "INT6_MI2S_RX"
#define LPASS_BE_INT6_MI2S_TX "INT6_MI2S_TX"
+
+#define LPASS_BE_SEC_MI2S_RX_1 "SEC_MI2S_RX_1"
+#define LPASS_BE_SEC_MI2S_RX_2 "SEC_MI2S_RX_2"
+#define LPASS_BE_SEC_MI2S_RX_3 "SEC_MI2S_RX_3"
+#define LPASS_BE_SEC_MI2S_RX_4 "SEC_MI2S_RX_4"
+#define LPASS_BE_SEC_MI2S_TX_1 "SEC_MI2S_TX_1"
+#define LPASS_BE_SEC_MI2S_TX_2 "SEC_MI2S_TX_2"
+#define LPASS_BE_SEC_MI2S_TX_3 "SEC_MI2S_TX_3"
+#define LPASS_BE_SEC_MI2S_TX_4 "SEC_MI2S_TX_4"
+
+#define LPASS_BE_TERT_MI2S_RX_1 "TERT_MI2S_RX_1"
+#define LPASS_BE_TERT_MI2S_RX_2 "TERT_MI2S_RX_2"
+#define LPASS_BE_TERT_MI2S_RX_3 "TERT_MI2S_RX_3"
+#define LPASS_BE_TERT_MI2S_RX_4 "TERT_MI2S_RX_4"
+#define LPASS_BE_TERT_MI2S_TX_1 "TERT_MI2S_TX_1"
+#define LPASS_BE_TERT_MI2S_TX_2 "TERT_MI2S_TX_2"
+#define LPASS_BE_TERT_MI2S_TX_3 "TERT_MI2S_TX_3"
+#define LPASS_BE_TERT_MI2S_TX_4 "TERT_MI2S_TX_4"
+
+#define LPASS_BE_QUAT_MI2S_RX_1 "QUAT_MI2S_RX_1"
+#define LPASS_BE_QUAT_MI2S_RX_2 "QUAT_MI2S_RX_2"
+#define LPASS_BE_QUAT_MI2S_RX_3 "QUAT_MI2S_RX_3"
+#define LPASS_BE_QUAT_MI2S_RX_4 "QUAT_MI2S_RX_4"
+#define LPASS_BE_QUAT_MI2S_TX_1 "QUAT_MI2S_TX_1"
+#define LPASS_BE_QUAT_MI2S_TX_2 "QUAT_MI2S_TX_2"
+#define LPASS_BE_QUAT_MI2S_TX_3 "QUAT_MI2S_TX_3"
+#define LPASS_BE_QUAT_MI2S_TX_4 "QUAT_MI2S_TX_4"
+
/* For multimedia front-ends, asm session is allocated dynamically.
* Hence, asm session/multimedia front-end mapping has to be maintained.
* Due to this reason, additional multimedia front-end must be placed before
@@ -373,6 +401,30 @@ enum {
MSM_BACKEND_DAI_INT5_MI2S_TX,
MSM_BACKEND_DAI_INT6_MI2S_RX,
MSM_BACKEND_DAI_INT6_MI2S_TX,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4,
+ MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1,
+ MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2,
+ MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3,
+ MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4,
+ MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1,
+ MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2,
+ MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3,
+ MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3,
+ MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4,
MSM_BACKEND_DAI_MAX,
};
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index 0524ca21feba..c7aecd5758d4 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -785,6 +785,18 @@ int afe_get_port_type(u16 port_id)
case AFE_PORT_ID_INT4_MI2S_RX:
case AFE_PORT_ID_INT5_MI2S_RX:
case AFE_PORT_ID_INT6_MI2S_RX:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_1:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_2:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_3:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_4:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_1:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_2:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_3:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_4:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_1:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_2:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_3:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_4:
ret = MSM_AFE_PORT_TYPE_RX;
break;
@@ -856,6 +868,18 @@ int afe_get_port_type(u16 port_id)
case AFE_PORT_ID_INT4_MI2S_TX:
case AFE_PORT_ID_INT5_MI2S_TX:
case AFE_PORT_ID_INT6_MI2S_TX:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_1:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_2:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_3:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_4:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_1:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_2:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_3:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_4:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_1:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_2:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_3:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_4:
ret = MSM_AFE_PORT_TYPE_TX;
break;
@@ -2734,6 +2758,118 @@ int afe_send_custom_tdm_header_cfg(
return ret;
}
+int afe_i2s_port_start(u16 port_id, struct afe_i2s_port_config *i2s_port,
+ u32 rate, u16 num_groups)
+{
+ struct param_hdr_v3 param_hdr = {0};
+ int index = 0;
+ uint16_t port_index = 0;
+ enum afe_mad_type mad_type = MAD_HW_NONE;
+ int ret = 0;
+
+ if (!i2s_port) {
+ pr_err("%s: Error, no configuration data\n", __func__);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: port id: 0x%x\n", __func__, port_id);
+
+ index = q6audio_get_port_index(port_id);
+ if (index < 0 || index >= AFE_MAX_PORTS) {
+ pr_err("%s: AFE port index[%d] invalid!\n",
+ __func__, index);
+ return -EINVAL;
+ }
+ ret = q6audio_validate_port(port_id);
+ if (ret < 0) {
+ pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
+ return -EINVAL;
+ }
+
+ ret = afe_q6_interface_prepare();
+ if (ret != 0) {
+ pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
+ return ret;
+ }
+
+ if ((index >= 0) && (index < AFE_MAX_PORTS)) {
+ this_afe.afe_sample_rates[index] = rate;
+
+ if (this_afe.rt_cb)
+ this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id);
+ }
+
+ /* Also send the topology id here if multiple ports: */
+ port_index = afe_get_port_index(port_id);
+ if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE) &&
+ num_groups > 1) {
+ /* One time call: only for first time */
+ afe_send_custom_topology();
+ afe_send_port_topology_id(port_id);
+ afe_send_cal(port_id);
+ afe_send_hw_delay(port_id, rate);
+ }
+
+ /* Start SW MAD module */
+ mad_type = afe_port_get_mad_type(port_id);
+ pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id,
+ mad_type);
+ if (mad_type != MAD_HW_NONE && mad_type != MAD_SW_AUDIO) {
+ if (!afe_has_config(AFE_CDC_REGISTERS_CONFIG) ||
+ !afe_has_config(AFE_SLIMBUS_SLAVE_CONFIG)) {
+ pr_err("%s: AFE isn't configured yet for\n"
+ "HW MAD try Again\n", __func__);
+ ret = -EAGAIN;
+ goto fail_cmd;
+ }
+ ret = afe_turn_onoff_hw_mad(mad_type, true);
+ if (ret) {
+ pr_err("%s: afe_turn_onoff_hw_mad failed %d\n",
+ __func__, ret);
+ goto fail_cmd;
+ }
+ }
+
+ param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_I2S_CONFIG;
+ param_hdr.param_size = sizeof(struct afe_param_id_i2s_cfg);
+
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr,
+ (u8 *) &i2s_port->i2s_cfg);
+ if (ret) {
+ pr_err("%s: AFE enable for port 0x%x failed ret = %d\n",
+ __func__, port_id, ret);
+ goto fail_cmd;
+ }
+
+ port_index = afe_get_port_index(port_id);
+ if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) {
+ this_afe.afe_sample_rates[port_index] = rate;
+ } else {
+ pr_err("%s: Invalid port index %d\n", __func__, port_index);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+ /* slot mapping is not need if there is only one group */
+ if (num_groups > 1) {
+ ret = afe_send_slot_mapping_cfg(
+ &i2s_port->slot_mapping,
+ port_id);
+ if (ret < 0) {
+ pr_err("%s: afe send failed %d\n", __func__, ret);
+ goto fail_cmd;
+ }
+ }
+
+ ret = afe_send_cmd_port_start(port_id);
+
+fail_cmd:
+ return ret;
+}
+
int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port,
u32 rate, u16 num_groups)
{
@@ -3598,6 +3734,54 @@ int afe_get_port_index(u16 port_id)
return IDX_AFE_PORT_ID_INT6_MI2S_RX;
case AFE_PORT_ID_INT6_MI2S_TX:
return IDX_AFE_PORT_ID_INT6_MI2S_TX;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_1:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_1;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_2:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_2;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_3:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_3;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_4:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_4;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_1:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_1;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_2:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_2;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_3:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_3;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_4:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_4;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_1:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_1;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_2:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_2;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_3:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_3;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_4:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_4;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_1:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_1;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_2:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_2;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_3:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_3;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_4:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_4;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_1:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_1;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_2:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_2;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_3:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_3;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_4:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_4;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_1:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_1;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_2:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_2;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_3:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_3;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_4:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_4;
default:
pr_err("%s: port 0x%x\n", __func__, port_id);
return -EINVAL;
@@ -4022,6 +4206,154 @@ int afe_port_group_set_param(u16 group_id,
return ret;
}
+static int afe_port_group_mi2s_set_param(u16 group_id,
+ struct afe_param_id_group_device_i2s_cfg_v1 *afe_group_config)
+{
+ struct param_hdr_v3 param_hdr = {0};
+ int cfg_type;
+ int ret;
+
+ if (!afe_group_config) {
+ pr_err("%s: Error, no configuration data\n", __func__);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: group id: 0x%x\n", __func__, group_id);
+
+ ret = afe_q6_interface_prepare();
+ if (ret != 0) {
+ pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
+ return ret;
+ }
+
+ switch (group_id) {
+ case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX:
+ case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_TX:
+ case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_RX:
+ case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_TX:
+ case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_RX:
+ case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_TX:
+ cfg_type = AFE_PARAM_ID_GROUP_DEVICE_I2S_CONFIG;
+ break;
+ default:
+ pr_err("%s: Invalid group id 0x%x\n", __func__, group_id);
+ return -EINVAL;
+ }
+
+ param_hdr.module_id = AFE_MODULE_GROUP_DEVICE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = cfg_type;
+ param_hdr.param_size =
+ sizeof(struct afe_param_id_group_device_i2s_cfg_v1);
+
+ ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
+ (u8 *) afe_group_config);
+ if (ret)
+ pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_CFG failed %d\n",
+ __func__, ret);
+
+ return ret;
+}
+
+static atomic_t mi2s_gp_en_ref[IDX_GROUP_MI2S_MAX];
+static int afe_get_mi2s_group_idx(u16 group_id)
+{
+ int gp_idx = -1;
+
+ switch (group_id) {
+ case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX:
+ gp_idx = IDX_GROUP_SECONDARY_MI2S_RX;
+ break;
+ case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_TX:
+ gp_idx = IDX_GROUP_SECONDARY_MI2S_TX;
+ break;
+ case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_RX:
+ gp_idx = IDX_GROUP_TERTIARY_MI2S_RX;
+ break;
+ case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_TX:
+ gp_idx = IDX_GROUP_TERTIARY_MI2S_TX;
+ break;
+ case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_RX:
+ gp_idx = IDX_GROUP_QUATERNARY_MI2S_RX;
+ break;
+ case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_TX:
+ gp_idx = IDX_GROUP_QUATERNARY_MI2S_TX;
+ break;
+ default:
+ break;
+ }
+
+ return gp_idx;
+}
+
+int afe_port_group_mi2s_enable(u16 group_id,
+ union afe_port_group_mi2s_config *afe_group_config,
+ u16 enable)
+{
+ struct afe_param_id_group_device_enable group_enable = {0};
+ struct param_hdr_v3 param_hdr = {0};
+ int ret = 0;
+ int gp_idx;
+
+ pr_debug("%s: group id: 0x%x enable: %d\n", __func__,
+ group_id, enable);
+
+ gp_idx = afe_get_mi2s_group_idx(group_id);
+
+ if ((gp_idx >= 0) && (gp_idx < IDX_GROUP_MI2S_MAX)) {
+
+ atomic_t *gp_ref = &mi2s_gp_en_ref[gp_idx];
+
+ if (enable)
+ atomic_inc(gp_ref);
+ else
+ atomic_dec(gp_ref);
+
+ if ((enable) && (atomic_read(gp_ref) > 1)) {
+ pr_err("%s: this TDM group is enabled already %d refs_cnt %d\n",
+ __func__, group_id, atomic_read(gp_ref));
+ goto rtn;
+ }
+
+ if ((!enable) && (atomic_read(gp_ref) > 0)) {
+ pr_err("%s: this TDM group will be disabled in last call %d refs_cnt %d\n",
+ __func__, group_id, atomic_read(gp_ref));
+ goto rtn;
+ }
+ }
+
+ ret = afe_q6_interface_prepare();
+ if (ret != 0) {
+ pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
+ return ret;
+ }
+
+ if (enable) {
+ ret = afe_port_group_mi2s_set_param(
+ group_id, &afe_group_config->i2s_cfg);
+ if (ret < 0) {
+ pr_err("%s: afe send failed %d\n", __func__, ret);
+ return ret;
+ }
+ }
+
+ param_hdr.module_id = AFE_MODULE_GROUP_DEVICE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_GROUP_DEVICE_ENABLE;
+ param_hdr.param_size = sizeof(struct afe_group_device_enable);
+ group_enable.group_id = group_id;
+ group_enable.enable = enable;
+
+ ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
+ (u8 *) &group_enable);
+ if (ret)
+ pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_ENABLE failed %d\n",
+ __func__, ret);
+
+rtn:
+ return ret;
+}
+
int afe_port_group_enable(u16 group_id,
union afe_port_group_config *afe_group_config,
u16 enable)
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index b7f85c504f7a..f6194eade877 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -3245,6 +3245,9 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
case FORMAT_APTX:
open.dec_fmt_id = ASM_MEDIA_FMT_APTX;
break;
+ case FORMAT_APTXHD:
+ open.dec_fmt_id = ASM_MEDIA_FMT_APTX_HD;
+ break;
case FORMAT_GEN_COMPR:
open.dec_fmt_id = ASM_MEDIA_FMT_GENERIC_COMPRESSED;
break;
diff --git a/sound/soc/msm/qdsp6v2/q6audio-v2.c b/sound/soc/msm/qdsp6v2/q6audio-v2.c
index 0062e4cd6432..94a6b0c42dee 100644
--- a/sound/soc/msm/qdsp6v2/q6audio-v2.c
+++ b/sound/soc/msm/qdsp6v2/q6audio-v2.c
@@ -95,6 +95,54 @@ int q6audio_get_port_index(u16 port_id)
return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX;
case AFE_PORT_ID_TERTIARY_MI2S_TX:
return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_1:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_1;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_2:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_2;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_3:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_3;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_4:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_4;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_1:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_1;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_2:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_2;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_3:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_3;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_4:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_4;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_1:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_1;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_2:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_2;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_3:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_3;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_4:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_4;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_1:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_1;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_2:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_2;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_3:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_3;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_4:
+ return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_4;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_1:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_1;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_2:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_2;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_3:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_3;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_4:
+ return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_4;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_1:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_1;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_2:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_2;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_3:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_3;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_4:
+ return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_4;
case AUDIO_PORT_ID_I2S_RX:
return IDX_AUDIO_PORT_ID_I2S_RX;
case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1:
@@ -342,6 +390,54 @@ int q6audio_get_port_id(u16 port_id)
return AFE_PORT_ID_TERTIARY_MI2S_RX;
case AFE_PORT_ID_TERTIARY_MI2S_TX:
return AFE_PORT_ID_TERTIARY_MI2S_TX;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_1:
+ return AFE_PORT_ID_SECONDARY_MI2S_TX_1;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_2:
+ return AFE_PORT_ID_SECONDARY_MI2S_TX_2;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_3:
+ return AFE_PORT_ID_SECONDARY_MI2S_TX_3;
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_4:
+ return AFE_PORT_ID_SECONDARY_MI2S_TX_4;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_1:
+ return AFE_PORT_ID_TERTIARY_MI2S_TX_1;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_2:
+ return AFE_PORT_ID_TERTIARY_MI2S_TX_2;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_3:
+ return AFE_PORT_ID_TERTIARY_MI2S_TX_3;
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_4:
+ return AFE_PORT_ID_TERTIARY_MI2S_TX_4;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_1:
+ return AFE_PORT_ID_QUATERNARY_MI2S_TX_1;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_2:
+ return AFE_PORT_ID_QUATERNARY_MI2S_TX_2;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_3:
+ return AFE_PORT_ID_QUATERNARY_MI2S_TX_3;
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_4:
+ return AFE_PORT_ID_QUATERNARY_MI2S_TX_4;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_1:
+ return AFE_PORT_ID_SECONDARY_MI2S_RX_1;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_2:
+ return AFE_PORT_ID_SECONDARY_MI2S_RX_2;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_3:
+ return AFE_PORT_ID_SECONDARY_MI2S_RX_3;
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_4:
+ return AFE_PORT_ID_SECONDARY_MI2S_RX_4;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_1:
+ return AFE_PORT_ID_TERTIARY_MI2S_RX_1;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_2:
+ return AFE_PORT_ID_TERTIARY_MI2S_RX_2;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_3:
+ return AFE_PORT_ID_TERTIARY_MI2S_RX_3;
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_4:
+ return AFE_PORT_ID_TERTIARY_MI2S_RX_4;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_1:
+ return AFE_PORT_ID_QUATERNARY_MI2S_RX_1;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_2:
+ return AFE_PORT_ID_QUATERNARY_MI2S_RX_2;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_3:
+ return AFE_PORT_ID_QUATERNARY_MI2S_RX_3;
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_4:
+ return AFE_PORT_ID_QUATERNARY_MI2S_RX_4;
case AUDIO_PORT_ID_I2S_RX:
return AUDIO_PORT_ID_I2S_RX;
case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1:
@@ -642,6 +738,30 @@ int q6audio_is_digital_pcm_interface(u16 port_id)
case AFE_PORT_ID_INT5_MI2S_TX:
case AFE_PORT_ID_INT6_MI2S_RX:
case AFE_PORT_ID_INT6_MI2S_TX:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_1:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_2:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_3:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_4:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_1:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_2:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_3:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_4:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_1:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_2:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_3:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_4:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_1:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_2:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_3:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_4:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_1:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_2:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_3:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_4:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_1:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_2:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_3:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_4:
break;
default:
ret = -EINVAL;
@@ -795,6 +915,30 @@ int q6audio_validate_port(u16 port_id)
case AFE_PORT_ID_INT6_MI2S_RX:
case AFE_PORT_ID_INT6_MI2S_TX:
case AFE_PORT_ID_MULTICHAN_HDMI_RX:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_1:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_2:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_3:
+ case AFE_PORT_ID_SECONDARY_MI2S_RX_4:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_1:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_2:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_3:
+ case AFE_PORT_ID_SECONDARY_MI2S_TX_4:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_1:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_2:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_3:
+ case AFE_PORT_ID_TERTIARY_MI2S_RX_4:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_1:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_2:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_3:
+ case AFE_PORT_ID_TERTIARY_MI2S_TX_4:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_1:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_2:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_3:
+ case AFE_PORT_ID_QUATERNARY_MI2S_RX_4:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_1:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_2:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_3:
+ case AFE_PORT_ID_QUATERNARY_MI2S_TX_4:
{
ret = 0;
break;
diff --git a/sound/soc/msm/sdm660-internal.c b/sound/soc/msm/sdm660-internal.c
index 4e2a40319b02..072d586da818 100644
--- a/sound/soc/msm/sdm660-internal.c
+++ b/sound/soc/msm/sdm660-internal.c
@@ -134,7 +134,7 @@ static struct dev_config int_mi2s_cfg[] = {
[INT2_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
[INT3_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
[INT4_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
- [INT5_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+ [INT5_MI2S] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
[INT6_MI2S] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
};
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 30bdc971883b..017e241b0ec9 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -1146,10 +1146,8 @@ static int snd_cs4231_playback_open(struct snd_pcm_substream *substream)
runtime->hw = snd_cs4231_playback;
err = snd_cs4231_open(chip, CS4231_MODE_PLAY);
- if (err < 0) {
- snd_free_pages(runtime->dma_area, runtime->dma_bytes);
+ if (err < 0)
return err;
- }
chip->playback_substream = substream;
chip->p_periods_sent = 0;
snd_pcm_set_sync(substream);
@@ -1167,10 +1165,8 @@ static int snd_cs4231_capture_open(struct snd_pcm_substream *substream)
runtime->hw = snd_cs4231_capture;
err = snd_cs4231_open(chip, CS4231_MODE_RECORD);
- if (err < 0) {
- snd_free_pages(runtime->dma_area, runtime->dma_bytes);
+ if (err < 0)
return err;
- }
chip->capture_substream = substream;
chip->c_periods_sent = 0;
snd_pcm_set_sync(substream);
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 86096532dfba..bbbece670eaf 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -688,9 +688,12 @@ static int usb_audio_probe(struct usb_interface *intf,
__error:
if (chip) {
+ /* chip->active is inside the chip->card object,
+ * decrement before memory is possibly returned.
+ */
+ atomic_dec(&chip->active);
if (!chip->num_interfaces)
snd_card_free(chip->card);
- atomic_dec(&chip->active);
}
mutex_unlock(&register_mutex);
return err;