summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/msm/subsystem_notif_virt.txt35
-rw-r--r--Makefile2
-rw-r--r--arch/arm/boot/dts/ls1021a-qds.dts2
-rw-r--r--arch/arm/boot/dts/ls1021a-twr.dts2
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-auto-mizar.dts19
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi54
-rw-r--r--arch/arm/boot/dts/qcom/msm8996.dtsi22
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-blsp.dtsi62
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi146
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-blsp.dtsi42
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi98
-rw-r--r--arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-blsp.dtsi13
-rw-r--r--arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-pinctrl.dtsi28
-rw-r--r--arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-telematics.dts14
-rw-r--r--arch/arm/lib/csumpartialcopyuser.S4
-rw-r--r--arch/arm64/configs/msm-auto-perf_defconfig1
-rw-r--r--arch/arm64/configs/msm-auto_defconfig1
-rw-r--r--arch/arm64/kernel/traps.c2
-rw-r--r--arch/mips/lib/Makefile3
-rw-r--r--arch/mips/lib/libgcc.h17
-rw-r--r--arch/mips/lib/multi3.c54
-rw-r--r--arch/powerpc/kernel/setup_64.c2
-rw-r--r--arch/sh/boards/mach-se/770x/setup.c10
-rw-r--r--arch/x86/oprofile/nmi_int.c2
-rw-r--r--drivers/clk/qcom/mmcc-sdm660.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c2
-rw-r--r--drivers/gpu/drm/drm_edid.c3
-rw-r--r--drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c4
-rw-r--r--drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_1_4.c4
-rw-r--r--drivers/gpu/drm/msm/dsi-staging/dsi_display.c6
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi.c25
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_host.c6
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_manager.c16
-rw-r--r--drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c2
-rw-r--r--drivers/gpu/drm/msm/msm_fb.c73
-rw-r--r--drivers/gpu/drm/msm/sde/sde_crtc.c25
-rw-r--r--drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c18
-rw-r--r--drivers/gpu/drm/msm/sde/sde_formats.c179
-rw-r--r--drivers/gpu/drm/msm/sde/sde_kms.c6
-rw-r--r--drivers/gpu/drm/msm/sde/sde_plane.c21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c7
-rw-r--r--drivers/gpu/drm/ttm/ttm_page_alloc.c2
-rw-r--r--drivers/gpu/msm/adreno.c2
-rw-r--r--drivers/gpu/msm/adreno_dispatch.c12
-rw-r--r--drivers/gpu/msm/adreno_dispatch.h5
-rw-r--r--drivers/gpu/msm/kgsl.c3
-rw-r--r--drivers/gpu/msm/kgsl_device.h2
-rw-r--r--drivers/gpu/msm/kgsl_pwrctrl.c6
-rw-r--r--drivers/hid/hid-core.c3
-rw-r--r--drivers/hid/hid-ids.h3
-rw-r--r--drivers/iio/imu/adis_trigger.c7
-rw-r--r--drivers/iio/industrialio-buffer.c2
-rw-r--r--drivers/infiniband/hw/mlx4/mr.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c25
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c5
-rw-r--r--drivers/input/misc/keychord.c2
-rw-r--r--drivers/input/touchscreen/atmel_maxtouch_ts.c42
-rw-r--r--drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c18
-rw-r--r--drivers/irqchip/irq-gic-v3.c2
-rw-r--r--drivers/leds/led-core.c2
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp.h5
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp47.c9
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c8
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h4
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c13
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.h4
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c21
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_core.c2
-rw-r--r--drivers/misc/profiler.c3
-rw-r--r--drivers/mmc/core/sd.c20
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c6
-rw-r--r--drivers/net/can/flexcan.c2
-rw-r--r--drivers/net/ethernet/arc/emac_main.c53
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c4
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c14
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c2
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c13
-rw-r--r--drivers/net/ethernet/broadcom/tg3.h4
-rw-r--r--drivers/net/ethernet/freescale/gianfar_ptp.c3
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000.h3
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_main.c27
-rw-r--r--drivers/net/phy/mdio-sun4i.c6
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/testmode.c7
-rw-r--r--drivers/net/xen-netfront.c1
-rw-r--r--drivers/pci/host/pci-keystone.c9
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_rt.c65
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_rt.c64
-rw-r--r--drivers/s390/block/dasd_3990_erp.c10
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.h2
-rw-r--r--drivers/scsi/storvsc_drv.c3
-rw-r--r--drivers/scsi/ufs/ufshcd.c5
-rw-r--r--drivers/soc/qcom/Makefile1
-rw-r--r--drivers/soc/qcom/subsystem_notif_virt.c163
-rw-r--r--drivers/spi/spi-atmel.c2
-rw-r--r--drivers/usb/core/quirks.c3
-rw-r--r--drivers/usb/dwc3/gadget.c2
-rw-r--r--drivers/usb/gadget/function/f_fs.c4
-rw-r--r--drivers/usb/host/ohci-q.c17
-rw-r--r--drivers/usb/misc/ldusb.c6
-rw-r--r--drivers/usb/renesas_usbhs/fifo.c5
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c1
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_aux.c2
-rw-r--r--drivers/video/fbdev/msm/mdss_hdcp.h5
-rw-r--r--drivers/video/fbdev/msm/mdss_hdcp_1x.c178
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_edid.c5
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_edid.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c38
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.c23
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_util.c6
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c7
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp.c14
-rw-r--r--drivers/video/fbdev/msm/msm_dba/adv7533.c12
-rw-r--r--drivers/xen/gntdev.c8
-rw-r--r--fs/sdcardfs/packagelist.c1
-rw-r--r--fs/super.c6
-rw-r--r--fs/xfs/xfs_qm.c46
-rw-r--r--include/linux/migrate.h2
-rw-r--r--include/net/ip_tunnels.h9
-rw-r--r--include/sound/apr_audio-v2.h3
-rw-r--r--include/sound/q6afe-v2.h1
-rw-r--r--kernel/time/hrtimer.c7
-rw-r--r--lib/mpi/longlong.h18
-rw-r--r--mm/compaction.c2
-rw-r--r--mm/memory_hotplug.c30
-rw-r--r--mm/migrate.c6
-rw-r--r--mm/page_alloc.c8
-rw-r--r--net/ipv4/Kconfig1
-rw-r--r--net/ipv4/ip_sockglue.c7
-rw-r--r--net/ipv4/ip_tunnel.c78
-rw-r--r--net/ipv6/ipv6_sockglue.c10
-rw-r--r--net/ipv6/route.c1
-rw-r--r--net/ipv6/sit.c17
-rw-r--r--net/mac80211/cfg.c2
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/sctp/socket.c16
-rw-r--r--sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c13
-rw-r--r--sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c223
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c8
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c11
-rw-r--r--sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c13
-rw-r--r--sound/soc/msm/qdsp6v2/q6afe.c75
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c25
143 files changed, 2212 insertions, 509 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/subsystem_notif_virt.txt b/Documentation/devicetree/bindings/arm/msm/subsystem_notif_virt.txt
new file mode 100644
index 000000000000..50fffbe8284c
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/subsystem_notif_virt.txt
@@ -0,0 +1,35 @@
+Subsystem Notification Virtual Driver
+
+The guest VM uses this driver to communicate
+subsystem state notifications to a backend driver
+via the virtual device's registers.
+
+[Root level node]
+Required Properties:
+-compatible : Should be "qcom,subsys-notif-virt"
+ for notifications regarding state.
+-reg : The start and size of the virtual device's
+ register set.
+-reg-names : Should be "vdev_base" for virtual device's
+ base address.
+-subsys-names : The name of the subsystem that the
+ driver is registering to notifications for.
+-offset : The offset from the virtual device's register
+ base where the subsystem state will be written.
+
+Example:
+
+ subsys_notif_virt: qcom,subsys_notif_virt@2D000000 {
+ compatible = "qcom,subsys-notif-virt";
+ reg = <0x2D000000 0x10>;
+ reg-names = "vdev_base";
+ adsp {
+ subsys-name = "adsp";
+ offset = <0>;
+ };
+ mpss {
+ subsys-name = "modem";
+ offset = <8>;
+ };
+ };
+
diff --git a/Makefile b/Makefile
index 77063ad039a2..9b7c0925903e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 4
-SUBLEVEL = 118
+SUBLEVEL = 120
EXTRAVERSION =
NAME = Blurry Fish Butt
diff --git a/arch/arm/boot/dts/ls1021a-qds.dts b/arch/arm/boot/dts/ls1021a-qds.dts
index 0521e6864cb7..76fce89d4f69 100644
--- a/arch/arm/boot/dts/ls1021a-qds.dts
+++ b/arch/arm/boot/dts/ls1021a-qds.dts
@@ -215,7 +215,7 @@
reg = <0x2a>;
VDDA-supply = <&reg_3p3v>;
VDDIO-supply = <&reg_3p3v>;
- clocks = <&sys_mclk 1>;
+ clocks = <&sys_mclk>;
};
};
};
diff --git a/arch/arm/boot/dts/ls1021a-twr.dts b/arch/arm/boot/dts/ls1021a-twr.dts
index fbb89d13401e..674df87629bd 100644
--- a/arch/arm/boot/dts/ls1021a-twr.dts
+++ b/arch/arm/boot/dts/ls1021a-twr.dts
@@ -167,7 +167,7 @@
reg = <0x0a>;
VDDA-supply = <&reg_3p3v>;
VDDIO-supply = <&reg_3p3v>;
- clocks = <&sys_mclk 1>;
+ clocks = <&sys_mclk>;
};
};
diff --git a/arch/arm/boot/dts/qcom/msm8996-auto-mizar.dts b/arch/arm/boot/dts/qcom/msm8996-auto-mizar.dts
index e7af060c0aba..8c750dab8707 100644
--- a/arch/arm/boot/dts/qcom/msm8996-auto-mizar.dts
+++ b/arch/arm/boot/dts/qcom/msm8996-auto-mizar.dts
@@ -42,6 +42,7 @@
qcom,ntn_avb {
qcom,ntn-rc-num = <2>;
+ pinctrl-0 = <&ntn_clk_sync &ntn2_clk_sync>;
};
i2c@75b6000 { /* BLSP8 */
@@ -55,6 +56,10 @@
};
};
+ clock_audio: audio_ext_clk {
+ /delete-property/pinctrl-0;
+ /delete-property/pinctrl-1;
+ };
};
&cci {
@@ -107,6 +112,20 @@
output-high;
};
};
+
+ ntn2_clk_sync: ntn2_clk_sync {
+ mux {
+ pins = "gpio98";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio98";
+ drive-strength = <8>; /* 8 mA */
+ output-low;
+ bias-pull-down; /* PULL down */
+ };
+ };
};
&pil_modem {
diff --git a/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi
index 50312a57059a..0982ead00f8c 100644
--- a/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-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
@@ -713,6 +713,19 @@
bias-pull-down;
};
};
+
+ i2c_12_bitbang: i2c_12_bitbang {
+ mux {
+ pins = "gpio87", "gpio88";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio87", "gpio88";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_6 {
@@ -741,6 +754,19 @@
bias-pull-up;
};
};
+
+ i2c_6_bitbang: i2c_6_bitbang {
+ mux {
+ pins = "gpio27", "gpio28";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio27", "gpio28";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_7 {
@@ -769,6 +795,19 @@
bias-pull-up;
};
};
+
+ i2c_7_bitbang: i2c_7_bitbang {
+ mux {
+ pins = "gpio55", "gpio56";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio55", "gpio56";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_8 {
@@ -797,6 +836,19 @@
bias-pull-up;
};
};
+
+ i2c_8_bitbang: i2c_8_bitbang {
+ mux {
+ pins = "gpio6", "gpio7";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio6", "gpio7";
+ drive-strength = <4>;
+ bias-pull-up;
+ };
+ };
};
pmx_fm_int {
diff --git a/arch/arm/boot/dts/qcom/msm8996.dtsi b/arch/arm/boot/dts/qcom/msm8996.dtsi
index 3b067e6090e6..2d30aab29a0e 100644
--- a/arch/arm/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-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
@@ -405,9 +405,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>,
<&clock_gcc clk_gcc_blsp2_qup6_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 87 0x00>;
+ qcom,i2c-clk = <&tlmm 88 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_12_active>;
pinctrl-1 = <&i2c_12_sleep>;
+ pinctrl-2 = <&i2c_12_bitbang>;
};
@@ -444,9 +447,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
<&clock_gcc clk_gcc_blsp1_qup6_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 27 0x00>;
+ qcom,i2c-clk = <&tlmm 28 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_6_active>;
pinctrl-1 = <&i2c_6_sleep>;
+ pinctrl-2 = <&i2c_6_bitbang>;
};
i2c_7: i2c@75b5000 { /* BLSP2 QUP1 */
@@ -466,9 +472,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>,
<&clock_gcc clk_gcc_blsp2_qup1_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 55 0x00>;
+ qcom,i2c-clk = <&tlmm 56 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_7_active>;
pinctrl-1 = <&i2c_7_sleep>;
+ pinctrl-2 = <&i2c_7_bitbang>;
};
i2c_8: i2c@75b6000 { /* BLSP2 QUP2 */
@@ -488,9 +497,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>,
<&clock_gcc clk_gcc_blsp2_qup2_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 6 0x00>;
+ qcom,i2c-clk = <&tlmm 7 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_8_active>;
pinctrl-1 = <&i2c_8_sleep>;
+ pinctrl-2 = <&i2c_8_bitbang>;
};
blsp1_uart2: uart@07570000 { /* BLSP1 UART2 */
diff --git a/arch/arm/boot/dts/qcom/msm8998-blsp.dtsi b/arch/arm/boot/dts/qcom/msm8998-blsp.dtsi
index b9e323d894c3..cc258d15a780 100644
--- a/arch/arm/boot/dts/qcom/msm8998-blsp.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-blsp.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-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
@@ -75,9 +75,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
<&clock_gcc clk_gcc_blsp1_qup1_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 2 0x00>;
+ qcom,i2c-clk = <&tlmm 3 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_1_active>;
pinctrl-1 = <&i2c_1_sleep>;
+ pinctrl-2 = <&i2c_1_bitbang>;
status = "disabled";
};
@@ -98,9 +101,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
<&clock_gcc clk_gcc_blsp1_qup2_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 33 0x00>;
+ qcom,i2c-clk = <&tlmm 32 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_2_active>;
pinctrl-1 = <&i2c_2_sleep>;
+ pinctrl-2 = <&i2c_2_bitbang>;
status = "disabled";
};
@@ -121,9 +127,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
<&clock_gcc clk_gcc_blsp1_qup3_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 47 0x00>;
+ qcom,i2c-clk = <&tlmm 48 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_3_active>;
pinctrl-1 = <&i2c_3_sleep>;
+ pinctrl-2 = <&i2c_3_bitbang>;
status = "disabled";
};
@@ -144,9 +153,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
<&clock_gcc clk_gcc_blsp1_qup4_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 10 0x00>;
+ qcom,i2c-clk = <&tlmm 11 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_4_active>;
pinctrl-1 = <&i2c_4_sleep>;
+ pinctrl-2 = <&i2c_4_bitbang>;
status = "disabled";
};
@@ -167,9 +179,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
<&clock_gcc clk_gcc_blsp1_qup5_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 87 0x00>;
+ qcom,i2c-clk = <&tlmm 88 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_5_active>;
pinctrl-1 = <&i2c_5_sleep>;
+ pinctrl-2 = <&i2c_5_bitbang>;
status = "disabled";
};
@@ -190,9 +205,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
<&clock_gcc clk_gcc_blsp1_qup6_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 43 0x00>;
+ qcom,i2c-clk = <&tlmm 44 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_6_active>;
pinctrl-1 = <&i2c_6_sleep>;
+ pinctrl-2 = <&i2c_6_bitbang>;
status = "disabled";
};
@@ -213,9 +231,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>,
<&clock_gcc clk_gcc_blsp2_qup1_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 55 0x00>;
+ qcom,i2c-clk = <&tlmm 56 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_7_active>;
pinctrl-1 = <&i2c_7_sleep>;
+ pinctrl-2 = <&i2c_7_bitbang>;
status = "disabled";
};
@@ -236,9 +257,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>,
<&clock_gcc clk_gcc_blsp2_qup2_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 6 0x00>;
+ qcom,i2c-clk = <&tlmm 7 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_8_active>;
pinctrl-1 = <&i2c_8_sleep>;
+ pinctrl-2 = <&i2c_8_bitbang>;
status = "disabled";
};
@@ -259,9 +283,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>,
<&clock_gcc clk_gcc_blsp2_qup3_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 51 0x00>;
+ qcom,i2c-clk = <&tlmm 52 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_9_active>;
pinctrl-1 = <&i2c_9_sleep>;
+ pinctrl-2 = <&i2c_9_bitbang>;
status = "disabled";
};
@@ -282,9 +309,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>,
<&clock_gcc clk_gcc_blsp2_qup4_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 67 0x00>;
+ qcom,i2c-clk = <&tlmm 68 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_10_active>;
pinctrl-1 = <&i2c_10_sleep>;
+ pinctrl-2 = <&i2c_10_bitbang>;
status = "disabled";
};
@@ -305,9 +335,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>,
<&clock_gcc clk_gcc_blsp2_qup5_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 60 0x00>;
+ qcom,i2c-clk = <&tlmm 61 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_11_active>;
pinctrl-1 = <&i2c_11_sleep>;
+ pinctrl-2 = <&i2c_11_bitbang>;
status = "disabled";
};
@@ -328,9 +361,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>,
<&clock_gcc clk_gcc_blsp2_qup6_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 83 0x00>;
+ qcom,i2c-clk = <&tlmm 84 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_12_active>;
pinctrl-1 = <&i2c_12_sleep>;
+ pinctrl-2 = <&i2c_12_bitbang>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi
index 1abb28897fbd..e066d483b350 100644
--- a/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi
@@ -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
@@ -76,6 +76,18 @@
bias-pull-up;
};
};
+ i2c_1_bitbang: i2c_1_bitbang {
+ mux {
+ pins = "gpio2", "gpio3";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio2", "gpio3";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_2 {
@@ -104,6 +116,18 @@
bias-pull-up;
};
};
+ i2c_2_bitbang: i2c_2_bitbang {
+ mux {
+ pins = "gpio32", "gpio33";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio32", "gpio33";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_3 {
@@ -132,6 +156,18 @@
bias-pull-up;
};
};
+ i2c_3_bitbang: i2c_3_bitbang {
+ mux {
+ pins = "gpio47", "gpio48";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio47", "gpio48";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_4 {
@@ -160,6 +196,18 @@
bias-pull-up;
};
};
+ i2c_4_bitbang: i2c_4_bitbang {
+ mux {
+ pins = "gpio10", "gpio11";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio10", "gpio11";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_5 {
@@ -188,6 +236,18 @@
bias-disable;
};
};
+ i2c_5_bitbang: i2c_5_bitbang {
+ mux {
+ pins = "gpio87", "gpio88";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio87", "gpio88";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_6 {
@@ -216,6 +276,18 @@
bias-pull-up;
};
};
+ i2c_6_bitbang: i2c_6_bitbang {
+ mux {
+ pins = "gpio43", "gpio44";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio43", "gpio44";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
nfc {
@@ -306,6 +378,18 @@
bias-pull-up;
};
};
+ i2c_7_bitbang: i2c_7_bitbang {
+ mux {
+ pins = "gpio55", "gpio56";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio55", "gpio56";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_8 {
@@ -334,6 +418,18 @@
bias-pull-up;
};
};
+ i2c_8_bitbang: i2c_8_bitbang {
+ mux {
+ pins = "gpio6", "gpio7";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio6", "gpio7";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_9 {
@@ -362,6 +458,18 @@
bias-pull-up;
};
};
+ i2c_9_bitbang: i2c_9_bitbang {
+ mux {
+ pins = "gpio51", "gpio52";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio51", "gpio52";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_10 {
@@ -390,6 +498,18 @@
bias-pull-up;
};
};
+ i2c_10_bitbang: i2c_10_bitbang {
+ mux {
+ pins = "gpio67", "gpio68";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio67", "gpio68";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_11 {
@@ -418,6 +538,18 @@
bias-pull-up;
};
};
+ i2c_11_bitbang: i2c_11_bitbang {
+ mux {
+ pins = "gpio60", "gpio61";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio60", "gpio61";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_12 {
@@ -446,6 +578,18 @@
bias-pull-up;
};
};
+ i2c_12_bitbang: i2c_12_bitbang {
+ mux {
+ pins = "gpio83", "gpio84";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio83", "gpio84";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
/* SPI CONFIGURATION */
diff --git a/arch/arm/boot/dts/qcom/sdm660-blsp.dtsi b/arch/arm/boot/dts/qcom/sdm660-blsp.dtsi
index 555d9a285102..f3b9431f39bc 100644
--- a/arch/arm/boot/dts/qcom/sdm660-blsp.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-blsp.dtsi
@@ -1,5 +1,5 @@
/*
- * 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
@@ -52,9 +52,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
<&clock_gcc GCC_BLSP1_QUP1_I2C_APPS_CLK>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 2 0x00>;
+ qcom,i2c-clk = <&tlmm 3 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_1_active>;
pinctrl-1 = <&i2c_1_sleep>;
+ pinctrl-2 = <&i2c_1_bitbang>;
status = "disabled";
};
@@ -75,9 +78,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
<&clock_gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 6 0x00>;
+ qcom,i2c-clk = <&tlmm 7 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_2_active>;
pinctrl-1 = <&i2c_2_sleep>;
+ pinctrl-2 = <&i2c_2_bitbang>;
status = "disabled";
};
@@ -98,9 +104,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
<&clock_gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 10 0x00>;
+ qcom,i2c-clk = <&tlmm 11 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_3_active>;
pinctrl-1 = <&i2c_3_sleep>;
+ pinctrl-2 = <&i2c_3_bitbang>;
status = "disabled";
};
@@ -121,9 +130,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
<&clock_gcc GCC_BLSP1_QUP4_I2C_APPS_CLK>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 14 0x00>;
+ qcom,i2c-clk = <&tlmm 15 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_4_active>;
pinctrl-1 = <&i2c_4_sleep>;
+ pinctrl-2 = <&i2c_4_bitbang>;
status = "disabled";
};
@@ -144,9 +156,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>,
<&clock_gcc GCC_BLSP2_QUP1_I2C_APPS_CLK>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 18 0x00>;
+ qcom,i2c-clk = <&tlmm 19 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_5_active>;
pinctrl-1 = <&i2c_5_sleep>;
+ pinctrl-2 = <&i2c_5_bitbang>;
status = "disabled";
};
@@ -167,9 +182,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>,
<&clock_gcc GCC_BLSP2_QUP2_I2C_APPS_CLK>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 22 0x00>;
+ qcom,i2c-clk = <&tlmm 23 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_6_active>;
pinctrl-1 = <&i2c_6_sleep>;
+ pinctrl-2 = <&i2c_6_bitbang>;
status = "disabled";
};
@@ -190,9 +208,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>,
<&clock_gcc GCC_BLSP2_QUP3_I2C_APPS_CLK>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 26 0x00>;
+ qcom,i2c-clk = <&tlmm 27 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_7_active>;
pinctrl-1 = <&i2c_7_sleep>;
+ pinctrl-2 = <&i2c_7_bitbang>;
status = "disabled";
};
@@ -213,9 +234,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>,
<&clock_gcc GCC_BLSP2_QUP4_I2C_APPS_CLK>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 30 0x00>;
+ qcom,i2c-clk = <&tlmm 31 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_8_active>;
pinctrl-1 = <&i2c_8_sleep>;
+ pinctrl-2 = <&i2c_8_bitbang>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi b/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi
index e55a67e68b36..5b97aea1c013 100644
--- a/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-pinctrl.dtsi
@@ -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
@@ -240,6 +240,18 @@
bias-pull-up;
};
};
+ i2c_1_bitbang: i2c_1_bitbang {
+ mux {
+ pins = "gpio2", "gpio3";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio2", "gpio3";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_2 {
@@ -268,6 +280,18 @@
bias-pull-up;
};
};
+ i2c_2_bitbang: i2c_2_bitbang {
+ mux {
+ pins = "gpio6", "gpio7";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio6", "gpio7";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_3 {
@@ -296,6 +320,18 @@
bias-pull-up;
};
};
+ i2c_3_bitbang: i2c_3_bitbang {
+ mux {
+ pins = "gpio10", "gpio11";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio10", "gpio11";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_4 {
@@ -324,6 +360,18 @@
bias-pull-up;
};
};
+ i2c_4_bitbang: i2c_4_bitbang {
+ mux {
+ pins = "gpio14", "gpio15";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio14", "gpio15";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_5 {
@@ -352,6 +400,18 @@
bias-pull-up;
};
};
+ i2c_5_bitbang: i2c_5_bitbang {
+ mux {
+ pins = "gpio18", "gpio19";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio18", "gpio19";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_6 {
@@ -380,6 +440,18 @@
bias-pull-up;
};
};
+ i2c_6_bitbang: i2c_6_bitbang {
+ mux {
+ pins = "gpio22", "gpio23";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio22", "gpio23";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
nfc {
@@ -472,6 +544,18 @@
bias-pull-up;
};
};
+ i2c_7_bitbang: i2c_7_bitbang {
+ mux {
+ pins = "gpio26", "gpio27";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio26", "gpio27";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_8 {
@@ -500,6 +584,18 @@
bias-pull-up;
};
};
+ i2c_8_bitbang: i2c_8_bitbang {
+ mux {
+ pins = "gpio30", "gpio31";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio30", "gpio31";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
/* SPI CONFIGURATION */
diff --git a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-blsp.dtsi b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-blsp.dtsi
index eb78cfd8b133..61b48802540a 100644
--- a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-blsp.dtsi
+++ b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-blsp.dtsi
@@ -1,5 +1,5 @@
/*
- * 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
@@ -56,9 +56,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_virt clk_gcc_blsp1_ahb_clk>,
<&clock_virt clk_gcc_blsp1_qup6_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 27 0x00>;
+ qcom,i2c-clk = <&tlmm 28 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_6_active>;
pinctrl-1 = <&i2c_6_sleep>;
+ pinctrl-2 = <&i2c_6_bitbang>;
status = "disabled";
};
@@ -77,10 +80,12 @@
clock-names = "iface_clk", "core_clk";
clocks = <&clock_virt clk_gcc_blsp2_ahb_clk>,
<&clock_virt clk_gcc_blsp2_qup2_i2c_apps_clk>;
- pinctrl-names = "i2c_active", "i2c_sleep";
+ qcom,i2c-dat = <&tlmm 6 0x00>;
+ qcom,i2c-clk = <&tlmm 7 0x00>;
+ pinctrl-names = "i2c_active", "i2c_sleep", "i2c_bitbang";
pinctrl-0 = <&i2c_8_active>;
pinctrl-1 = <&i2c_8_sleep>;
- status = "disabled";
+ pinctrl-2 = <&i2c_8_bitbang>;
};
blsp1_uart2: uart@07570000 { /* BLSP1 UART2 */
diff --git a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-pinctrl.dtsi b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-pinctrl.dtsi
index 02162e64e35f..f1aa0ce19cfb 100644
--- a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-pinctrl.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-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
@@ -89,6 +89,19 @@
bias-pull-up;
};
};
+
+ i2c_6_bitbang: i2c_6_bitbang {
+ mux {
+ pins = "gpio27", "gpio28";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio27", "gpio28";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
};
i2c_8 {
@@ -117,6 +130,19 @@
bias-pull-up;
};
};
+
+ i2c_8_bitbang: i2c_8_bitbang {
+ mux {
+ pins = "gpio6", "gpio7";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio6", "gpio7";
+ drive-strength = <4>;
+ bias-pull-up;
+ };
+ };
};
spi_9 {
diff --git a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-telematics.dts b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-telematics.dts
index 0fc629e960c4..94cfabf78d82 100644
--- a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-telematics.dts
+++ b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-telematics.dts
@@ -147,6 +147,20 @@
qcom,notify-edges = <&glink_mpss>;
qcom,xprt = "smem";
};
+
+ subsys_notif_virt: qcom,subsys_notif_virt@2D000000 {
+ compatible = "qcom,subsys-notif-virt";
+ reg = <0x2D000000 0x10>;
+ reg-names = "vdev_base";
+ adsp {
+ subsys-name = "adsp";
+ offset = <0>;
+ };
+ mpss {
+ subsys-name = "modem";
+ offset = <8>;
+ };
+ };
};
&spi_9 {
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
index 1712f132b80d..b83fdc06286a 100644
--- a/arch/arm/lib/csumpartialcopyuser.S
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -85,7 +85,11 @@
.pushsection .text.fixup,"ax"
.align 4
9001: mov r4, #-EFAULT
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+ ldr r5, [sp, #9*4] @ *err_ptr
+#else
ldr r5, [sp, #8*4] @ *err_ptr
+#endif
str r4, [r5]
ldmia sp, {r1, r2} @ retrieve dst, len
add r2, r2, r1
diff --git a/arch/arm64/configs/msm-auto-perf_defconfig b/arch/arm64/configs/msm-auto-perf_defconfig
index 10bd4c45be06..44d4c072dd29 100644
--- a/arch/arm64/configs/msm-auto-perf_defconfig
+++ b/arch/arm64/configs/msm-auto-perf_defconfig
@@ -544,7 +544,6 @@ CONFIG_MSM_SERVICE_NOTIFIER=y
CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y
CONFIG_MSM_RPM_LOG=y
CONFIG_MSM_RPM_STATS_LOG=y
-CONFIG_QCOM_SMCINVOKE=y
CONFIG_MSM_CACHE_M4M_ERP64=y
CONFIG_MSM_CACHE_M4M_ERP64_PANIC_ON_CE=y
CONFIG_MSM_CACHE_M4M_ERP64_PANIC_ON_UE=y
diff --git a/arch/arm64/configs/msm-auto_defconfig b/arch/arm64/configs/msm-auto_defconfig
index 6cc8fd6300e3..b691690187c2 100644
--- a/arch/arm64/configs/msm-auto_defconfig
+++ b/arch/arm64/configs/msm-auto_defconfig
@@ -553,7 +553,6 @@ CONFIG_MSM_SERVICE_NOTIFIER=y
CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y
CONFIG_MSM_RPM_LOG=y
CONFIG_MSM_RPM_STATS_LOG=y
-CONFIG_QCOM_SMCINVOKE=y
CONFIG_MSM_CACHE_M4M_ERP64=y
CONFIG_MSM_CACHE_M4M_ERP64_PANIC_ON_CE=y
CONFIG_MSM_CACHE_M4M_ERP64_PANIC_ON_UE=y
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index f80faf3547c6..5767e1d83170 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -55,7 +55,7 @@ static const char *handler[]= {
"Error"
};
-int show_unhandled_signals = 1;
+int show_unhandled_signals = 0;
/*
* Dump out the contents of some memory nicely...
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 0344e575f522..fba4ca56e46a 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -15,4 +15,5 @@ obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o
obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o
# libgcc-style stuff needed in the kernel
-obj-y += ashldi3.o ashrdi3.o bswapsi.o bswapdi.o cmpdi2.o lshrdi3.o ucmpdi2.o
+obj-y += ashldi3.o ashrdi3.o bswapsi.o bswapdi.o cmpdi2.o lshrdi3.o multi3.o \
+ ucmpdi2.o
diff --git a/arch/mips/lib/libgcc.h b/arch/mips/lib/libgcc.h
index 05909d58e2fe..56ea0df60a44 100644
--- a/arch/mips/lib/libgcc.h
+++ b/arch/mips/lib/libgcc.h
@@ -9,10 +9,18 @@ typedef int word_type __attribute__ ((mode (__word__)));
struct DWstruct {
int high, low;
};
+
+struct TWstruct {
+ long long high, low;
+};
#elif defined(__LITTLE_ENDIAN)
struct DWstruct {
int low, high;
};
+
+struct TWstruct {
+ long long low, high;
+};
#else
#error I feel sick.
#endif
@@ -22,4 +30,13 @@ typedef union {
long long ll;
} DWunion;
+#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6)
+typedef int ti_type __attribute__((mode(TI)));
+
+typedef union {
+ struct TWstruct s;
+ ti_type ti;
+} TWunion;
+#endif
+
#endif /* __ASM_LIBGCC_H */
diff --git a/arch/mips/lib/multi3.c b/arch/mips/lib/multi3.c
new file mode 100644
index 000000000000..111ad475aa0c
--- /dev/null
+++ b/arch/mips/lib/multi3.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/export.h>
+
+#include "libgcc.h"
+
+/*
+ * GCC 7 suboptimally generates __multi3 calls for mips64r6, so for that
+ * specific case only we'll implement it here.
+ *
+ * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82981
+ */
+#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6) && (__GNUC__ == 7)
+
+/* multiply 64-bit values, low 64-bits returned */
+static inline long long notrace dmulu(long long a, long long b)
+{
+ long long res;
+
+ asm ("dmulu %0,%1,%2" : "=r" (res) : "r" (a), "r" (b));
+ return res;
+}
+
+/* multiply 64-bit unsigned values, high 64-bits of 128-bit result returned */
+static inline long long notrace dmuhu(long long a, long long b)
+{
+ long long res;
+
+ asm ("dmuhu %0,%1,%2" : "=r" (res) : "r" (a), "r" (b));
+ return res;
+}
+
+/* multiply 128-bit values, low 128-bits returned */
+ti_type notrace __multi3(ti_type a, ti_type b)
+{
+ TWunion res, aa, bb;
+
+ aa.ti = a;
+ bb.ti = b;
+
+ /*
+ * a * b = (a.lo * b.lo)
+ * + 2^64 * (a.hi * b.lo + a.lo * b.hi)
+ * [+ 2^128 * (a.hi * b.hi)]
+ */
+ res.s.low = dmulu(aa.s.low, bb.s.low);
+ res.s.high = dmuhu(aa.s.low, bb.s.low);
+ res.s.high += dmulu(aa.s.high, bb.s.low);
+ res.s.high += dmulu(aa.s.low, bb.s.high);
+
+ return res.ti;
+}
+EXPORT_SYMBOL(__multi3);
+
+#endif /* 64BIT && CPU_MIPSR6 && GCC7 */
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index df4a87eb8da4..9eb469bed22b 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -835,6 +835,7 @@ static int __init disable_hardlockup_detector(void)
return 0;
}
early_initcall(disable_hardlockup_detector);
+#endif
#ifdef CONFIG_PPC_BOOK3S_64
static enum l1d_flush_type enabled_flush_types;
@@ -973,4 +974,3 @@ ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, cha
return sprintf(buf, "Vulnerable\n");
}
#endif /* CONFIG_PPC_BOOK3S_64 */
-#endif
diff --git a/arch/sh/boards/mach-se/770x/setup.c b/arch/sh/boards/mach-se/770x/setup.c
index 658326f44df8..5e0267624d8d 100644
--- a/arch/sh/boards/mach-se/770x/setup.c
+++ b/arch/sh/boards/mach-se/770x/setup.c
@@ -8,6 +8,7 @@
*/
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/sh_eth.h>
#include <mach-se/mach/se.h>
#include <mach-se/mach/mrshpc.h>
#include <asm/machvec.h>
@@ -114,6 +115,11 @@ static struct platform_device heartbeat_device = {
#if defined(CONFIG_CPU_SUBTYPE_SH7710) ||\
defined(CONFIG_CPU_SUBTYPE_SH7712)
/* SH771X Ethernet driver */
+static struct sh_eth_plat_data sh_eth_plat = {
+ .phy = PHY_ID,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
static struct resource sh_eth0_resources[] = {
[0] = {
.start = SH_ETH0_BASE,
@@ -131,7 +137,7 @@ static struct platform_device sh_eth0_device = {
.name = "sh771x-ether",
.id = 0,
.dev = {
- .platform_data = PHY_ID,
+ .platform_data = &sh_eth_plat,
},
.num_resources = ARRAY_SIZE(sh_eth0_resources),
.resource = sh_eth0_resources,
@@ -154,7 +160,7 @@ static struct platform_device sh_eth1_device = {
.name = "sh771x-ether",
.id = 1,
.dev = {
- .platform_data = PHY_ID,
+ .platform_data = &sh_eth_plat,
},
.num_resources = ARRAY_SIZE(sh_eth1_resources),
.resource = sh_eth1_resources,
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 1d2e6392f5fa..f24bd7249536 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -471,7 +471,7 @@ static int nmi_setup(void)
goto fail;
for_each_possible_cpu(cpu) {
- if (!cpu)
+ if (!IS_ENABLED(CONFIG_SMP) || !cpu)
continue;
memcpy(per_cpu(cpu_msrs, cpu).counters,
diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c
index 542737e4d204..05606f1b23dc 100644
--- a/drivers/clk/qcom/mmcc-sdm660.c
+++ b/drivers/clk/qcom/mmcc-sdm660.c
@@ -1,5 +1,5 @@
/*
- * 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
@@ -2419,7 +2419,7 @@ static struct clk_regmap_div mmss_mdss_byte0_intf_div_clk = {
},
.num_parents = 1,
.ops = &clk_regmap_div_ops,
- .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
+ .flags = CLK_GET_RATE_NOCACHE,
},
},
};
@@ -2476,7 +2476,7 @@ static struct clk_regmap_div mmss_mdss_byte1_intf_div_clk = {
},
.num_parents = 1,
.ops = &clk_regmap_div_ops,
- .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
+ .flags = CLK_GET_RATE_NOCACHE,
},
},
};
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index fc9f14747f70..a36230d1331c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -1467,8 +1467,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
* ignore it */
vga_client_register(adev->pdev, adev, NULL, amdgpu_vga_set_decode);
- if (amdgpu_runtime_pm == 1)
- runtime = true;
if (amdgpu_device_is_px(ddev))
runtime = true;
vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime);
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 6bf4588de46c..65d4c5d8d94b 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -114,6 +114,9 @@ static struct edid_quirk {
/* AEO model 0 reports 8 bpc, but is a 6 bpc panel */
{ "AEO", 0, EDID_QUIRK_FORCE_6BPC },
+ /* CPT panel of Asus UX303LA reports 8 bpc, but is a 6 bpc panel */
+ { "CPT", 0x17df, EDID_QUIRK_FORCE_6BPC },
+
/* Belinea 10 15 55 */
{ "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 },
{ "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 },
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index fb9617ce572a..6015cf35e030 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -1,5 +1,5 @@
/*
- * 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
@@ -1089,7 +1089,7 @@ error:
static int dsi_enable_ulps(struct dsi_ctrl *dsi_ctrl)
{
int rc = 0;
- u32 lanes;
+ u32 lanes = 0;
u32 ulps_lanes;
if (dsi_ctrl->host_config.panel_mode == DSI_OP_CMD_MODE)
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_1_4.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_1_4.c
index 2f0f6c2f1b01..caba50832cca 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_1_4.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_1_4.c
@@ -1,5 +1,5 @@
/*
- * 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
@@ -565,7 +565,7 @@ u32 dsi_ctrl_hw_14_get_cmd_read_data(struct dsi_ctrl_hw *ctrl,
u32 read_cnt;
u32 rx_byte = 0;
u32 repeated_bytes = 0;
- u8 reg[16];
+ u8 reg[16] = {0};
u32 pkt_size = 0;
int buf_offset = read_offset;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index f2412daee8b6..09ab14cc4746 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -1,5 +1,5 @@
/*
- * 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
@@ -1481,8 +1481,8 @@ static int dsi_display_dfps_update(struct dsi_display *display,
m_ctrl = &display->ctrl[display->clk_master_idx];
rc = dsi_ctrl_async_timing_update(m_ctrl->ctrl, timing);
if (rc) {
- pr_err("[%s] failed to dfps update host_%d, rc=%d\n",
- display->name, i, rc);
+ pr_err("[%s] failed to dfps update clock master, rc=%d\n",
+ display->name, rc);
goto error;
}
diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
index 6edcd6f57e70..f9bed1058f38 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.c
+++ b/drivers/gpu/drm/msm/dsi/dsi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 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
@@ -193,6 +193,9 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
struct drm_bridge *ext_bridge;
int ret, i;
+ if (!msm_dsi)
+ return -EINVAL;
+
if (WARN_ON(!encoders[MSM_DSI_VIDEO_ENCODER_ID] ||
!encoders[MSM_DSI_CMD_ENCODER_ID]))
return -EINVAL;
@@ -246,19 +249,17 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
return 0;
fail:
- if (msm_dsi) {
- /* bridge/connector are normally destroyed by drm: */
- if (msm_dsi->bridge) {
- msm_dsi_manager_bridge_destroy(msm_dsi->bridge);
- msm_dsi->bridge = NULL;
- }
+ /* bridge/connector are normally destroyed by drm: */
+ if (msm_dsi->bridge) {
+ msm_dsi_manager_bridge_destroy(msm_dsi->bridge);
+ msm_dsi->bridge = NULL;
+ }
- /* don't destroy connector if we didn't make it */
- if (msm_dsi->connector && !msm_dsi->external_bridge)
- msm_dsi->connector->funcs->destroy(msm_dsi->connector);
+ /* don't destroy connector if we didn't make it */
+ if (msm_dsi->connector && !msm_dsi->external_bridge)
+ msm_dsi->connector->funcs->destroy(msm_dsi->connector);
- msm_dsi->connector = NULL;
- }
+ msm_dsi->connector = NULL;
return ret;
}
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index e2b8deda46c2..845e4ad7b464 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015,2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015,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
@@ -898,7 +898,7 @@ static int dsi_cmd_dma_add(struct drm_gem_object *tx_gem,
data = msm_gem_vaddr(tx_gem);
- if (IS_ERR(data)) {
+ if (IS_ERR_OR_NULL(data)) {
ret = PTR_ERR(data);
pr_err("%s: get vaddr failed, %d\n", __func__, ret);
return ret;
@@ -1006,7 +1006,7 @@ static int dsi_cmd_dma_rx(struct msm_dsi_host *msm_host,
u32 *lp, *temp, data;
int i, j = 0, cnt;
u32 read_cnt;
- u8 reg[16];
+ u8 reg[16] = {0};
int repeated_bytes = 0;
int buf_offset = buf - msm_host->rx_buf;
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index 2091b748abbb..5d20e17d97d2 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015,2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015,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
@@ -618,16 +618,26 @@ fail:
struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id)
{
struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
- struct drm_device *dev = msm_dsi->dev;
+ struct drm_device *dev;
struct drm_encoder *encoder;
struct drm_bridge *int_bridge, *ext_bridge;
struct drm_connector *connector;
struct list_head *connector_list;
+ if (!msm_dsi)
+ return ERR_PTR(-EINVAL);
+
+ dev = msm_dsi->dev;
+
int_bridge = msm_dsi->bridge;
ext_bridge = msm_dsi->external_bridge =
msm_dsi_host_get_bridge(msm_dsi->host);
+ if (!int_bridge || !ext_bridge) {
+ pr_err("%s: failed to get bridge info\n", __func__);
+ return ERR_PTR(-EINVAL);
+ }
+
/*
* HACK: we may not know the external DSI bridge device's mode
* flags here. We'll get to know them only when the device
@@ -797,7 +807,7 @@ int msm_dsi_manager_register(struct msm_dsi *msm_dsi)
int id = msm_dsi->id;
int ret;
- if (id > DSI_MAX) {
+ if (id >= DSI_MAX) {
pr_err("%s: invalid id %d\n", __func__, id);
return -EINVAL;
}
diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c
index 9d7e6f1f14c3..4b6eeb6d1abc 100644
--- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c
@@ -1704,7 +1704,7 @@ static int _sde_hdmi_ext_disp_init(struct sde_hdmi *display)
const char *phandle = "qcom,msm_ext_disp";
if (!display) {
- SDE_ERROR("[%s]Invalid params\n", display->name);
+ SDE_ERROR("Invalid params\n");
return -EINVAL;
}
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
index a3f0392c2f88..d222fdd69a57 100644
--- a/drivers/gpu/drm/msm/msm_fb.c
+++ b/drivers/gpu/drm/msm/msm_fb.c
@@ -33,15 +33,31 @@ static int msm_framebuffer_create_handle(struct drm_framebuffer *fb,
struct drm_file *file_priv,
unsigned int *handle)
{
- struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+ struct msm_framebuffer *msm_fb;
+
+ if (!fb) {
+ DRM_ERROR("from:%pS null fb\n", __builtin_return_address(0));
+ return -EINVAL;
+ }
+
+ msm_fb = to_msm_framebuffer(fb);
+
return drm_gem_handle_create(file_priv,
msm_fb->planes[0], handle);
}
static void msm_framebuffer_destroy(struct drm_framebuffer *fb)
{
- struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
- int i, n = drm_format_num_planes(fb->pixel_format);
+ struct msm_framebuffer *msm_fb;
+ int i, n;
+
+ if (!fb) {
+ DRM_ERROR("from:%pS null fb\n", __builtin_return_address(0));
+ return;
+ }
+
+ msm_fb = to_msm_framebuffer(fb);
+ n = drm_format_num_planes(fb->pixel_format);
DBG("destroy: FB ID: %d (%p)", fb->base.id, fb);
@@ -72,9 +88,16 @@ static const struct drm_framebuffer_funcs msm_framebuffer_funcs = {
#ifdef CONFIG_DEBUG_FS
void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m)
{
- struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
- int i, n = drm_format_num_planes(fb->pixel_format);
+ struct msm_framebuffer *msm_fb;
+ int i, n;
+ if (!fb) {
+ DRM_ERROR("from:%pS null fb\n", __builtin_return_address(0));
+ return;
+ }
+
+ msm_fb = to_msm_framebuffer(fb);
+ n = drm_format_num_planes(fb->pixel_format);
seq_printf(m, "fb: %dx%d@%4.4s (%2d, ID:%d)\n",
fb->width, fb->height, (char *)&fb->pixel_format,
fb->refcount.refcount.counter, fb->base.id);
@@ -95,10 +118,17 @@ void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m)
int msm_framebuffer_prepare(struct drm_framebuffer *fb,
struct msm_gem_address_space *aspace)
{
- struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
- int ret, i, n = drm_format_num_planes(fb->pixel_format);
+ struct msm_framebuffer *msm_fb;
+ int ret, i, n;
uint64_t iova;
+ if (!fb) {
+ DRM_ERROR("from:%pS null fb\n", __builtin_return_address(0));
+ return -EINVAL;
+ }
+
+ msm_fb = to_msm_framebuffer(fb);
+ n = drm_format_num_planes(fb->pixel_format);
for (i = 0; i < n; i++) {
ret = msm_gem_get_iova(msm_fb->planes[i], aspace, &iova);
DBG("FB[%u]: iova[%d]: %08llx (%d)", fb->base.id, i, iova, ret);
@@ -112,8 +142,16 @@ int msm_framebuffer_prepare(struct drm_framebuffer *fb,
void msm_framebuffer_cleanup(struct drm_framebuffer *fb,
struct msm_gem_address_space *aspace)
{
- struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
- int i, n = drm_format_num_planes(fb->pixel_format);
+ struct msm_framebuffer *msm_fb;
+ int i, n;
+
+ if (fb == NULL) {
+ DRM_ERROR("from:%pS null fb\n", __builtin_return_address(0));
+ return;
+ }
+
+ msm_fb = to_msm_framebuffer(fb);
+ n = drm_format_num_planes(fb->pixel_format);
for (i = 0; i < n; i++)
msm_gem_put_iova(msm_fb->planes[i], aspace);
@@ -123,9 +161,15 @@ void msm_framebuffer_cleanup(struct drm_framebuffer *fb,
uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb,
struct msm_gem_address_space *aspace, int plane)
{
- struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+ struct msm_framebuffer *msm_fb;
uint64_t iova;
+ if (!fb) {
+ DRM_ERROR("from:%pS null fb\n", __builtin_return_address(0));
+ return -EINVAL;
+ }
+
+ msm_fb = to_msm_framebuffer(fb);
if (!msm_fb->planes[plane])
return 0;
@@ -137,7 +181,14 @@ uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb,
struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane)
{
- struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+ struct msm_framebuffer *msm_fb;
+
+ if (!fb) {
+ DRM_ERROR("from:%pS null fb\n", __builtin_return_address(0));
+ return ERR_PTR(-EINVAL);
+ }
+
+ msm_fb = to_msm_framebuffer(fb);
return msm_fb->planes[plane];
}
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 3f5aa4d276c9..96ef909e14f4 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -240,6 +240,10 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc,
plane->state->fb->base.id : -1);
format = to_sde_format(msm_framebuffer_format(pstate->base.fb));
+ if (!format) {
+ SDE_ERROR("%s: get sde format failed\n", __func__);
+ return;
+ }
/* blend config update */
if (pstate->stage != SDE_STAGE_BASE) {
@@ -915,6 +919,11 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc)
dev = crtc->dev;
sde_crtc = to_sde_crtc(crtc);
sde_kms = _sde_crtc_get_kms(crtc);
+ if (!sde_kms) {
+ SDE_ERROR("invalid sde_kms\n");
+ return;
+ }
+
priv = sde_kms->dev->dev_private;
/*
@@ -1543,6 +1552,10 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc,
sde_crtc = to_sde_crtc(crtc);
dev = crtc->dev;
sde_kms = _sde_crtc_get_kms(crtc);
+ if (!sde_kms) {
+ SDE_ERROR("invalid sde_kms\n");
+ return;
+ }
info = kzalloc(sizeof(struct sde_kms_info), GFP_KERNEL);
if (!info) {
@@ -1683,7 +1696,6 @@ static int sde_crtc_atomic_get_property(struct drm_crtc *crtc,
struct sde_crtc *sde_crtc;
struct sde_crtc_state *cstate;
int i, ret = -EINVAL;
- bool conn_offset = 0;
if (!crtc || !state) {
SDE_ERROR("invalid argument(s)\n");
@@ -1691,20 +1703,13 @@ static int sde_crtc_atomic_get_property(struct drm_crtc *crtc,
sde_crtc = to_sde_crtc(crtc);
cstate = to_sde_crtc_state(state);
- for (i = 0; i < cstate->num_connectors; ++i) {
- conn_offset = sde_connector_needs_offset(
- cstate->connectors[i]);
- if (conn_offset)
- break;
- }
-
i = msm_property_index(&sde_crtc->property_info, property);
if (i == CRTC_PROP_OUTPUT_FENCE) {
int offset = sde_crtc_get_property(cstate,
CRTC_PROP_OUTPUT_FENCE_OFFSET);
ret = sde_fence_create(&sde_crtc->output_fence, val,
- offset + conn_offset);
+ offset);
if (ret)
SDE_ERROR("fence create failed\n");
} else {
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
index d58c06de1684..2f89c571fcfc 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c
@@ -333,10 +333,24 @@ static void sde_encoder_phys_vid_underrun_irq(void *arg, int irq_idx)
phys_enc);
}
+static bool _sde_encoder_phys_is_ppsplit(struct sde_encoder_phys *phys_enc)
+{
+ enum sde_rm_topology_name topology;
+
+ if (!phys_enc)
+ return false;
+
+ topology = sde_connector_get_topology_name(phys_enc->connector);
+ if (topology == SDE_RM_TOPOLOGY_PPSPLIT)
+ return true;
+
+ return false;
+}
+
static bool sde_encoder_phys_vid_needs_single_flush(
struct sde_encoder_phys *phys_enc)
{
- return phys_enc && phys_enc->split_role != ENC_ROLE_SOLO;
+ return phys_enc && _sde_encoder_phys_is_ppsplit(phys_enc);
}
static int sde_encoder_phys_vid_register_irq(struct sde_encoder_phys *phys_enc,
@@ -674,7 +688,7 @@ static int sde_encoder_phys_vid_wait_for_vblank(
KICKOFF_TIMEOUT_MS);
if (ret <= 0) {
irq_status = sde_core_irq_read(phys_enc->sde_kms,
- INTR_IDX_VSYNC, true);
+ vid_enc->irq_idx[INTR_IDX_VSYNC], true);
if (irq_status) {
SDE_EVT32(DRMID(phys_enc->parent),
vid_enc->hw_intf->idx - INTF_0);
diff --git a/drivers/gpu/drm/msm/sde/sde_formats.c b/drivers/gpu/drm/msm/sde/sde_formats.c
index 2187d221a352..340cba536367 100644
--- a/drivers/gpu/drm/msm/sde/sde_formats.c
+++ b/drivers/gpu/drm/msm/sde/sde_formats.c
@@ -22,6 +22,11 @@
#define SDE_UBWC_META_BLOCK_SIZE 256
#define SDE_UBWC_PLANE_SIZE_ALIGNMENT 4096
+#define SDE_TILE_HEIGHT_DEFAULT 1
+#define SDE_TILE_HEIGHT_TILED 4
+#define SDE_TILE_HEIGHT_UBWC 4
+#define SDE_TILE_HEIGHT_NV12 8
+
#define SDE_MAX_IMG_WIDTH 0x3FFF
#define SDE_MAX_IMG_HEIGHT 0x3FFF
@@ -48,9 +53,30 @@ bp, flg, fm, np) \
.bpp = bp, \
.fetch_mode = fm, \
.flag = {(flg)}, \
- .num_planes = np \
+ .num_planes = np, \
+ .tile_height = SDE_TILE_HEIGHT_DEFAULT \
}
+#define INTERLEAVED_RGB_FMT_TILED(fmt, a, r, g, b, e0, e1, e2, e3, uc, \
+alpha, bp, flg, fm, np, th) \
+{ \
+ .base.pixel_format = DRM_FORMAT_ ## fmt, \
+ .fetch_planes = SDE_PLANE_INTERLEAVED, \
+ .alpha_enable = alpha, \
+ .element = { (e0), (e1), (e2), (e3) }, \
+ .bits = { g, b, r, a }, \
+ .chroma_sample = SDE_CHROMA_RGB, \
+ .unpack_align_msb = 0, \
+ .unpack_tight = 1, \
+ .unpack_count = uc, \
+ .bpp = bp, \
+ .fetch_mode = fm, \
+ .flag = {(flg)}, \
+ .num_planes = np, \
+ .tile_height = th \
+}
+
+
#define INTERLEAVED_YUV_FMT(fmt, a, r, g, b, e0, e1, e2, e3, \
alpha, chroma, count, bp, flg, fm, np) \
{ \
@@ -66,7 +92,8 @@ alpha, chroma, count, bp, flg, fm, np) \
.bpp = bp, \
.fetch_mode = fm, \
.flag = {(flg)}, \
- .num_planes = np \
+ .num_planes = np, \
+ .tile_height = SDE_TILE_HEIGHT_DEFAULT \
}
#define PSEUDO_YUV_FMT(fmt, a, r, g, b, e0, e1, chroma, flg, fm, np) \
@@ -83,7 +110,27 @@ alpha, chroma, count, bp, flg, fm, np) \
.bpp = 2, \
.fetch_mode = fm, \
.flag = {(flg)}, \
- .num_planes = np \
+ .num_planes = np, \
+ .tile_height = SDE_TILE_HEIGHT_DEFAULT \
+}
+
+#define PSEUDO_YUV_FMT_TILED(fmt, a, r, g, b, e0, e1, chroma, \
+flg, fm, np, th) \
+{ \
+ .base.pixel_format = DRM_FORMAT_ ## fmt, \
+ .fetch_planes = SDE_PLANE_PSEUDO_PLANAR, \
+ .alpha_enable = false, \
+ .element = { (e0), (e1), 0, 0 }, \
+ .bits = { g, b, r, a }, \
+ .chroma_sample = chroma, \
+ .unpack_align_msb = 0, \
+ .unpack_tight = 1, \
+ .unpack_count = 2, \
+ .bpp = 2, \
+ .fetch_mode = fm, \
+ .flag = {(flg)}, \
+ .num_planes = np, \
+ .tile_height = th \
}
#define PSEUDO_YUV_FMT_LOOSE(fmt, a, r, g, b, e0, e1, chroma, flg, fm, np)\
@@ -100,9 +147,30 @@ alpha, chroma, count, bp, flg, fm, np) \
.bpp = 2, \
.fetch_mode = fm, \
.flag = {(flg)}, \
- .num_planes = np \
+ .num_planes = np, \
+ .tile_height = SDE_TILE_HEIGHT_DEFAULT \
}
+#define PSEUDO_YUV_FMT_LOOSE_TILED(fmt, a, r, g, b, e0, e1, chroma, \
+flg, fm, np, th) \
+{ \
+ .base.pixel_format = DRM_FORMAT_ ## fmt, \
+ .fetch_planes = SDE_PLANE_PSEUDO_PLANAR, \
+ .alpha_enable = false, \
+ .element = { (e0), (e1), 0, 0 }, \
+ .bits = { g, b, r, a }, \
+ .chroma_sample = chroma, \
+ .unpack_align_msb = 1, \
+ .unpack_tight = 0, \
+ .unpack_count = 2, \
+ .bpp = 2, \
+ .fetch_mode = fm, \
+ .flag = {(flg)}, \
+ .num_planes = np, \
+ .tile_height = th \
+}
+
+
#define PLANAR_YUV_FMT(fmt, a, r, g, b, e0, e1, e2, alpha, chroma, bp, \
flg, fm, np) \
{ \
@@ -118,7 +186,8 @@ flg, fm, np) \
.bpp = bp, \
.fetch_mode = fm, \
.flag = {(flg)}, \
- .num_planes = np \
+ .num_planes = np, \
+ .tile_height = SDE_TILE_HEIGHT_DEFAULT \
}
/*
@@ -414,75 +483,99 @@ static const struct sde_format sde_format_map[] = {
* These tables hold the A5x tile formats supported.
*/
static const struct sde_format sde_format_map_tile[] = {
- INTERLEAVED_RGB_FMT(ARGB8888,
+ INTERLEAVED_RGB_FMT_TILED(BGR565,
+ 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
+ C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
+ false, 2, 0,
+ SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
+
+ INTERLEAVED_RGB_FMT_TILED(ARGB8888,
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
true, 4, 0,
- SDE_FETCH_UBWC, 1),
+ SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
- INTERLEAVED_RGB_FMT(ABGR8888,
+ INTERLEAVED_RGB_FMT_TILED(ABGR8888,
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
true, 4, 0,
- SDE_FETCH_UBWC, 1),
+ SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
- INTERLEAVED_RGB_FMT(RGBA8888,
+ INTERLEAVED_RGB_FMT_TILED(XBGR8888,
+ COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+ false, 4, 0,
+ SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
+
+ INTERLEAVED_RGB_FMT_TILED(RGBA8888,
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
true, 4, 0,
- SDE_FETCH_UBWC, 1),
+ SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
- INTERLEAVED_RGB_FMT(BGRA8888,
+ INTERLEAVED_RGB_FMT_TILED(BGRA8888,
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
true, 4, 0,
- SDE_FETCH_UBWC, 1),
+ SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
- INTERLEAVED_RGB_FMT(BGRX8888,
+ INTERLEAVED_RGB_FMT_TILED(BGRX8888,
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
false, 4, 0,
- SDE_FETCH_UBWC, 1),
+ SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
- INTERLEAVED_RGB_FMT(XRGB8888,
+ INTERLEAVED_RGB_FMT_TILED(XRGB8888,
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
false, 4, 0,
- SDE_FETCH_UBWC, 1),
+ SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
- INTERLEAVED_RGB_FMT(RGBX8888,
+ INTERLEAVED_RGB_FMT_TILED(RGBX8888,
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
false, 4, 0,
- SDE_FETCH_UBWC, 1),
+ SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
- PSEUDO_YUV_FMT(NV12,
+ INTERLEAVED_RGB_FMT_TILED(ABGR2101010,
+ COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+ true, 4, SDE_FORMAT_FLAG_DX,
+ SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
+
+ INTERLEAVED_RGB_FMT_TILED(XBGR2101010,
+ COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+ C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+ true, 4, SDE_FORMAT_FLAG_DX,
+ SDE_FETCH_UBWC, 1, SDE_TILE_HEIGHT_TILED),
+
+ PSEUDO_YUV_FMT_TILED(NV12,
0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C1_B_Cb, C2_R_Cr,
SDE_CHROMA_420, SDE_FORMAT_FLAG_YUV,
- SDE_FETCH_UBWC, 2),
+ SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_NV12),
- PSEUDO_YUV_FMT(NV21,
+ PSEUDO_YUV_FMT_TILED(NV21,
0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C2_R_Cr, C1_B_Cb,
SDE_CHROMA_420, SDE_FORMAT_FLAG_YUV,
- SDE_FETCH_UBWC, 2),
+ SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_NV12),
};
static const struct sde_format sde_format_map_p010_tile[] = {
- PSEUDO_YUV_FMT_LOOSE(NV12,
+ PSEUDO_YUV_FMT_LOOSE_TILED(NV12,
0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C1_B_Cb, C2_R_Cr,
SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX),
- SDE_FETCH_UBWC, 2),
+ SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_NV12),
};
static const struct sde_format sde_format_map_tp10_tile[] = {
- PSEUDO_YUV_FMT(NV12,
+ PSEUDO_YUV_FMT_TILED(NV12,
0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C1_B_Cb, C2_R_Cr,
SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX),
- SDE_FETCH_UBWC, 2),
+ SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_NV12),
};
/*
@@ -492,42 +585,42 @@ static const struct sde_format sde_format_map_tp10_tile[] = {
* the data will be passed by user-space.
*/
static const struct sde_format sde_format_map_ubwc[] = {
- INTERLEAVED_RGB_FMT(BGR565,
+ INTERLEAVED_RGB_FMT_TILED(BGR565,
0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
false, 2, SDE_FORMAT_FLAG_COMPRESSED,
- SDE_FETCH_UBWC, 2),
+ SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_UBWC),
- INTERLEAVED_RGB_FMT(ABGR8888,
+ INTERLEAVED_RGB_FMT_TILED(ABGR8888,
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
true, 4, SDE_FORMAT_FLAG_COMPRESSED,
- SDE_FETCH_UBWC, 2),
+ SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_UBWC),
- INTERLEAVED_RGB_FMT(XBGR8888,
+ INTERLEAVED_RGB_FMT_TILED(XBGR8888,
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
false, 4, SDE_FORMAT_FLAG_COMPRESSED,
- SDE_FETCH_UBWC, 2),
+ SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_UBWC),
- INTERLEAVED_RGB_FMT(ABGR2101010,
+ INTERLEAVED_RGB_FMT_TILED(ABGR2101010,
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
true, 4, SDE_FORMAT_FLAG_DX | SDE_FORMAT_FLAG_COMPRESSED,
- SDE_FETCH_UBWC, 2),
+ SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_UBWC),
- INTERLEAVED_RGB_FMT(XBGR2101010,
+ INTERLEAVED_RGB_FMT_TILED(XBGR2101010,
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
true, 4, SDE_FORMAT_FLAG_DX | SDE_FORMAT_FLAG_COMPRESSED,
- SDE_FETCH_UBWC, 2),
+ SDE_FETCH_UBWC, 2, SDE_TILE_HEIGHT_UBWC),
- PSEUDO_YUV_FMT(NV12,
+ PSEUDO_YUV_FMT_TILED(NV12,
0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C1_B_Cb, C2_R_Cr,
SDE_CHROMA_420, SDE_FORMAT_FLAG_YUV |
SDE_FORMAT_FLAG_COMPRESSED,
- SDE_FETCH_UBWC, 4),
+ SDE_FETCH_UBWC, 4, SDE_TILE_HEIGHT_NV12),
};
static const struct sde_format sde_format_map_p010[] = {
@@ -539,21 +632,21 @@ static const struct sde_format sde_format_map_p010[] = {
};
static const struct sde_format sde_format_map_p010_ubwc[] = {
- PSEUDO_YUV_FMT_LOOSE(NV12,
+ PSEUDO_YUV_FMT_LOOSE_TILED(NV12,
0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C1_B_Cb, C2_R_Cr,
SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX |
SDE_FORMAT_FLAG_COMPRESSED),
- SDE_FETCH_UBWC, 4),
+ SDE_FETCH_UBWC, 4, SDE_TILE_HEIGHT_NV12),
};
static const struct sde_format sde_format_map_tp10_ubwc[] = {
- PSEUDO_YUV_FMT(NV12,
+ PSEUDO_YUV_FMT_TILED(NV12,
0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C1_B_Cb, C2_R_Cr,
SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX |
SDE_FORMAT_FLAG_COMPRESSED),
- SDE_FETCH_UBWC, 4),
+ SDE_FETCH_UBWC, 4, SDE_TILE_HEIGHT_NV12),
};
/* _sde_get_v_h_subsample_rate - Get subsample rates for all formats we support
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 34a32d79f22c..93b8a69597a5 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -385,7 +385,7 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms,
struct drm_crtc *crtc)
{
struct drm_encoder *encoder;
- struct drm_device *dev = crtc->dev;
+ struct drm_device *dev;
int ret;
if (!kms || !crtc || !crtc->state) {
@@ -393,6 +393,8 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms,
return;
}
+ dev = crtc->dev;
+
if (!crtc->state->enable) {
SDE_DEBUG("[crtc:%d] not enable\n", crtc->base.id);
return;
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c
index f5f125c3f71c..43ff508975dd 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.c
+++ b/drivers/gpu/drm/msm/sde/sde_plane.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2014-2018 The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -303,6 +303,11 @@ static void _sde_plane_set_qos_lut(struct sde_phy_plane *pp,
fb->pixel_format,
fb->modifier,
drm_format_num_planes(fb->pixel_format));
+ if (!fmt) {
+ SDE_ERROR("%s: faile to get fmt\n", __func__);
+ return;
+ }
+
total_fl = _sde_plane_calc_fill_level(pp, fmt,
pp->pipe_cfg.src_rect.w);
@@ -362,6 +367,10 @@ static void _sde_plane_set_danger_lut(struct sde_phy_plane *pp,
fb->pixel_format,
fb->modifier,
drm_format_num_planes(fb->pixel_format));
+ if (!fmt) {
+ SDE_ERROR("%s: fail to get fmt\n", __func__);
+ return;
+ }
if (SDE_FORMAT_IS_LINEAR(fmt)) {
danger_lut = pp->pipe_sblk->danger_lut_linear;
@@ -694,11 +703,11 @@ static inline void _sde_plane_set_scanout(struct sde_phy_plane *pp,
static int _sde_plane_setup_scaler3_lut(struct sde_phy_plane *pp,
struct sde_plane_state *pstate)
{
- struct sde_plane *psde = pp->sde_plane;
+ struct sde_plane *psde;
struct sde_hw_scaler3_cfg *cfg;
int ret = 0;
- if (!pp || !pp->scaler3_cfg) {
+ if (!pp || !pp->sde_plane || !pp->scaler3_cfg) {
SDE_ERROR("invalid args\n");
return -EINVAL;
} else if (!pstate) {
@@ -707,6 +716,7 @@ static int _sde_plane_setup_scaler3_lut(struct sde_phy_plane *pp,
return -EINVAL;
}
+ psde = pp->sde_plane;
cfg = pp->scaler3_cfg;
cfg->dir_lut = msm_property_get_blob(
@@ -1450,7 +1460,7 @@ static int _sde_plane_mode_set(struct drm_plane *plane,
static int sde_plane_prepare_fb(struct drm_plane *plane,
const struct drm_plane_state *new_state)
{
- struct drm_framebuffer *fb = new_state->fb;
+ struct drm_framebuffer *fb;
struct sde_plane *psde = to_sde_plane(plane);
struct sde_plane_state *pstate;
int rc;
@@ -1461,6 +1471,7 @@ static int sde_plane_prepare_fb(struct drm_plane *plane,
if (!new_state->fb)
return 0;
+ fb = new_state->fb;
pstate = to_sde_plane_state(new_state);
rc = _sde_plane_get_aspace(psde, pstate, &psde->aspace);
@@ -1800,7 +1811,7 @@ static void _sde_plane_install_properties(struct drm_plane *plane,
{SDE_DRM_FB_NON_SEC_DIR_TRANS, "non_sec_direct_translation"},
{SDE_DRM_FB_SEC_DIR_TRANS, "sec_direct_translation"},
};
- const struct sde_format_extended *format_list;
+ const struct sde_format_extended *format_list = NULL;
struct sde_kms_info *info;
struct sde_plane *psde = to_sde_plane(plane);
int zpos_max = 255;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
index 4896474da320..3021fcd0a3df 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
@@ -127,6 +127,13 @@ nvkm_pci_init(struct nvkm_subdev *subdev)
return ret;
pci->irq = pdev->irq;
+
+ /* Ensure MSI interrupts are armed, for the case where there are
+ * already interrupts pending (for whatever reason) at load time.
+ */
+ if (pci->msi)
+ pci->func->msi_rearm(pci);
+
return ret;
}
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
index 5d8dfe027b30..75d51ec98e06 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
@@ -818,6 +818,8 @@ int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages)
pr_info("Initializing pool allocator\n");
_manager = kzalloc(sizeof(*_manager), GFP_KERNEL);
+ if (!_manager)
+ return -ENOMEM;
ttm_page_pool_init_locked(&_manager->wc_pool, GFP_HIGHUSER, "wc");
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index f96a7a2cee21..7af2af483f10 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -2839,6 +2839,8 @@ static const struct kgsl_functable adreno_functable = {
.clk_set_options = adreno_clk_set_options,
.gpu_model = adreno_gpu_model,
.stop_fault_timer = adreno_dispatcher_stop_fault_timer,
+ .dispatcher_halt = adreno_dispatcher_halt,
+ .dispatcher_unhalt = adreno_dispatcher_unhalt,
};
static struct platform_driver adreno_platform_driver = {
diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c
index fc7799722026..6dd9f6040fae 100644
--- a/drivers/gpu/msm/adreno_dispatch.c
+++ b/drivers/gpu/msm/adreno_dispatch.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
@@ -2816,6 +2816,16 @@ int adreno_dispatcher_init(struct adreno_device *adreno_dev)
return ret;
}
+void adreno_dispatcher_halt(struct kgsl_device *device)
+{
+ adreno_get_gpu_halt(ADRENO_DEVICE(device));
+}
+
+void adreno_dispatcher_unhalt(struct kgsl_device *device)
+{
+ adreno_put_gpu_halt(ADRENO_DEVICE(device));
+}
+
/*
* adreno_dispatcher_idle() - Wait for dispatcher to idle
* @adreno_dev: Adreno device whose dispatcher needs to idle
diff --git a/drivers/gpu/msm/adreno_dispatch.h b/drivers/gpu/msm/adreno_dispatch.h
index 48f0cdc546ff..f55f8cbf928b 100644
--- a/drivers/gpu/msm/adreno_dispatch.h
+++ b/drivers/gpu/msm/adreno_dispatch.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-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
@@ -103,6 +103,9 @@ enum adreno_dispatcher_flags {
};
void adreno_dispatcher_start(struct kgsl_device *device);
+void adreno_dispatcher_halt(struct kgsl_device *device);
+void adreno_dispatcher_unhalt(struct kgsl_device *device);
+
int adreno_dispatcher_init(struct adreno_device *adreno_dev);
void adreno_dispatcher_close(struct adreno_device *adreno_dev);
int adreno_dispatcher_idle(struct adreno_device *adreno_dev);
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index bb8ab4c20485..db9e5f7d6d6b 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -746,6 +746,8 @@ static int kgsl_suspend_device(struct kgsl_device *device, pm_message_t state)
mutex_lock(&device->mutex);
status = kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND);
+ if (status == 0)
+ device->ftbl->dispatcher_halt(device);
mutex_unlock(&device->mutex);
KGSL_PWR_WARN(device, "suspend end\n");
@@ -760,6 +762,7 @@ static int kgsl_resume_device(struct kgsl_device *device)
KGSL_PWR_WARN(device, "resume start\n");
mutex_lock(&device->mutex);
if (device->state == KGSL_STATE_SUSPEND) {
+ device->ftbl->dispatcher_unhalt(device);
kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER);
} else if (device->state != KGSL_STATE_INIT) {
/*
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index b6c787ecac36..57d4fe4d9120 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -171,6 +171,8 @@ struct kgsl_functable {
void (*gpu_model)(struct kgsl_device *device, char *str,
size_t bufsz);
void (*stop_fault_timer)(struct kgsl_device *device);
+ void (*dispatcher_halt)(struct kgsl_device *device);
+ void (*dispatcher_unhalt)(struct kgsl_device *device);
};
struct kgsl_ioctl {
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index ff6fae7c739b..b1b0b69d55ba 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -2675,6 +2675,7 @@ _aware(struct kgsl_device *device)
break;
default:
status = -EINVAL;
+ return status;
}
if (status)
kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
@@ -2781,8 +2782,9 @@ static int _suspend(struct kgsl_device *device)
{
int ret = 0;
- if ((KGSL_STATE_NONE == device->state) ||
- (KGSL_STATE_INIT == device->state))
+ if ((device->state == KGSL_STATE_NONE) ||
+ (device->state == KGSL_STATE_INIT) ||
+ (device->state == KGSL_STATE_SUSPEND))
return ret;
/* drain to prevent from more commands being submitted */
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 27f80e91f223..bbb3b473c185 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2387,6 +2387,9 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTIME) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYPH) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERANALYSERCASSY) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETESTCASSY) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index b554d17c9156..b316ab7e8996 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -570,6 +570,9 @@
#define USB_DEVICE_ID_LD_MICROCASSYTIME 0x1033
#define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE 0x1035
#define USB_DEVICE_ID_LD_MICROCASSYPH 0x1038
+#define USB_DEVICE_ID_LD_POWERANALYSERCASSY 0x1040
+#define USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY 0x1042
+#define USB_DEVICE_ID_LD_MACHINETESTCASSY 0x1043
#define USB_DEVICE_ID_LD_JWM 0x1080
#define USB_DEVICE_ID_LD_DMMP 0x1081
#define USB_DEVICE_ID_LD_UMIP 0x1090
diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c
index f53e9a803a0e..93b99bd93738 100644
--- a/drivers/iio/imu/adis_trigger.c
+++ b/drivers/iio/imu/adis_trigger.c
@@ -47,6 +47,10 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
if (adis->trig == NULL)
return -ENOMEM;
+ adis->trig->dev.parent = &adis->spi->dev;
+ adis->trig->ops = &adis_trigger_ops;
+ iio_trigger_set_drvdata(adis->trig, adis);
+
ret = request_irq(adis->spi->irq,
&iio_trigger_generic_data_rdy_poll,
IRQF_TRIGGER_RISING,
@@ -55,9 +59,6 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
if (ret)
goto error_free_trig;
- adis->trig->dev.parent = &adis->spi->dev;
- adis->trig->ops = &adis_trigger_ops;
- iio_trigger_set_drvdata(adis->trig, adis);
ret = iio_trigger_register(adis->trig);
indio_dev->trig = iio_trigger_get(adis->trig);
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index 32bb036069eb..961afb5588be 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -174,7 +174,7 @@ unsigned int iio_buffer_poll(struct file *filp,
struct iio_dev *indio_dev = filp->private_data;
struct iio_buffer *rb = indio_dev->buffer;
- if (!indio_dev->info)
+ if (!indio_dev->info || rb == NULL)
return 0;
poll_wait(filp, &rb->pollq, wait);
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c
index 4d1e1c632603..ce87e9cc7eff 100644
--- a/drivers/infiniband/hw/mlx4/mr.c
+++ b/drivers/infiniband/hw/mlx4/mr.c
@@ -424,7 +424,6 @@ struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd,
goto err_free_mr;
mr->max_pages = max_num_sg;
-
err = mlx4_mr_enable(dev->dev, &mr->mmr);
if (err)
goto err_free_pl;
@@ -435,6 +434,7 @@ struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd,
return &mr->ibmr;
err_free_pl:
+ mr->ibmr.device = pd->device;
mlx4_free_priv_pages(mr);
err_free_mr:
(void) mlx4_mr_free(dev->dev, &mr->mmr);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index bad76eed06b3..5c653669e736 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -844,8 +844,8 @@ static int path_rec_start(struct net_device *dev,
return 0;
}
-static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
- struct net_device *dev)
+static struct ipoib_neigh *neigh_add_path(struct sk_buff *skb, u8 *daddr,
+ struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_path *path;
@@ -858,7 +858,15 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
spin_unlock_irqrestore(&priv->lock, flags);
++dev->stats.tx_dropped;
dev_kfree_skb_any(skb);
- return;
+ return NULL;
+ }
+
+ /* To avoid race condition, make sure that the
+ * neigh will be added only once.
+ */
+ if (unlikely(!list_empty(&neigh->list))) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return neigh;
}
path = __path_find(dev, daddr + 4);
@@ -896,7 +904,7 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
spin_unlock_irqrestore(&priv->lock, flags);
ipoib_send(dev, skb, path->ah, IPOIB_QPN(daddr));
ipoib_neigh_put(neigh);
- return;
+ return NULL;
}
} else {
neigh->ah = NULL;
@@ -913,7 +921,7 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
spin_unlock_irqrestore(&priv->lock, flags);
ipoib_neigh_put(neigh);
- return;
+ return NULL;
err_path:
ipoib_neigh_free(neigh);
@@ -923,6 +931,8 @@ err_drop:
spin_unlock_irqrestore(&priv->lock, flags);
ipoib_neigh_put(neigh);
+
+ return NULL;
}
static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
@@ -1028,8 +1038,9 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
case htons(ETH_P_TIPC):
neigh = ipoib_neigh_get(dev, phdr->hwaddr);
if (unlikely(!neigh)) {
- neigh_add_path(skb, phdr->hwaddr, dev);
- return NETDEV_TX_OK;
+ neigh = neigh_add_path(skb, phdr->hwaddr, dev);
+ if (likely(!neigh))
+ return NETDEV_TX_OK;
}
break;
case htons(ETH_P_ARP):
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 5580ab0b5781..8bf48165f32c 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -775,7 +775,10 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb)
spin_lock_irqsave(&priv->lock, flags);
if (!neigh) {
neigh = ipoib_neigh_alloc(daddr, dev);
- if (neigh) {
+ /* Make sure that the neigh will be added only
+ * once to mcast list.
+ */
+ if (neigh && list_empty(&neigh->list)) {
kref_get(&mcast->ah->ref);
neigh->ah = mcast->ah;
list_add_tail(&neigh->list, &mcast->neigh_list);
diff --git a/drivers/input/misc/keychord.c b/drivers/input/misc/keychord.c
index fdcc14653b64..82fefdff366a 100644
--- a/drivers/input/misc/keychord.c
+++ b/drivers/input/misc/keychord.c
@@ -276,7 +276,7 @@ static ssize_t keychord_write(struct file *file, const char __user *buffer,
size_t resid = count;
size_t key_bytes;
- if (count < sizeof(struct input_keychord))
+ if (count < sizeof(struct input_keychord) || count > PAGE_SIZE)
return -EINVAL;
keychords = kzalloc(count, GFP_KERNEL);
if (!keychords)
diff --git a/drivers/input/touchscreen/atmel_maxtouch_ts.c b/drivers/input/touchscreen/atmel_maxtouch_ts.c
index f58fc8555156..99a4b40e432e 100644
--- a/drivers/input/touchscreen/atmel_maxtouch_ts.c
+++ b/drivers/input/touchscreen/atmel_maxtouch_ts.c
@@ -1,7 +1,7 @@
/*
* Atmel maXTouch Touchscreen driver
*
- * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015, 2018 The Linux Foundation. All rights reserved.
*
* Linux foundation chooses to take subject only to the GPLv2 license terms,
* and distributes only under these terms.
@@ -529,6 +529,8 @@ static ssize_t mxt_debug_msg_read(struct file *filp, struct kobject *kobj,
static int mxt_debug_msg_init(struct mxt_data *data)
{
+ int ret;
+
sysfs_bin_attr_init(&data->debug_msg_attr);
data->debug_msg_attr.attr.name = "debug_msg";
data->debug_msg_attr.attr.mode = 0666;
@@ -536,11 +538,20 @@ static int mxt_debug_msg_init(struct mxt_data *data)
data->debug_msg_attr.write = mxt_debug_msg_write;
data->debug_msg_attr.size = data->T5_msg_size * DEBUG_MSG_MAX;
- if (sysfs_create_bin_file(&data->client->dev.kobj,
- &data->debug_msg_attr) < 0)
- dev_info(&data->client->dev, "Debugfs already exists\n");
+ ret = sysfs_create_bin_file(&data->client->dev.kobj,
+ &data->debug_msg_attr);
+ if (ret < 0) {
+ if (ret == -EEXIST) {
+ dev_info(&data->client->dev,
+ "Debugfs already exists\n");
+ ret = 0;
+ } else {
+ dev_err(&data->client->dev,
+ "Failed to create 'debug_msg' file\n");
+ }
+ }
- return 0;
+ return ret;
}
static void mxt_debug_msg_remove(struct mxt_data *data)
@@ -1462,7 +1473,7 @@ static int mxt_t6_command(struct mxt_data *data, u16 cmd_offset,
u8 value, bool wait)
{
u16 reg;
- u8 command_register;
+ u8 command_register = 0;
int timeout_counter = 0;
int ret;
@@ -1567,7 +1578,7 @@ static int mxt_check_retrigen(struct mxt_data *data)
{
struct i2c_client *client = data->client;
int error;
- int val;
+ int val = 0;
if (data->pdata->irqflags & IRQF_TRIGGER_LOW)
return 0;
@@ -1612,9 +1623,11 @@ static int mxt_update_t100_resolution(struct mxt_data *data)
struct i2c_client *client = data->client;
int error;
struct mxt_object *object;
- u16 range_x, range_y, temp;
- u8 cfg, tchaux;
- u8 aux;
+ u16 range_x = 0;
+ u16 range_y = 0;
+ u16 temp;
+ u8 cfg = 0;
+ u8 tchaux, aux;
bool update = false;
object = mxt_get_object(data, MXT_TOUCH_MULTITOUCHSCREEN_T100);
@@ -1653,10 +1666,6 @@ static int mxt_update_t100_resolution(struct mxt_data *data)
if (range_x == 0)
range_x = 1023;
- /* Handle default values */
- if (range_x == 0)
- range_x = 1023;
-
if (range_y == 0)
range_y = 1023;
@@ -1728,8 +1737,8 @@ static int mxt_update_t9_resolution(struct mxt_data *data)
{
struct i2c_client *client = data->client;
int error;
- struct t9_range range;
- unsigned char orient;
+ struct t9_range range = {0};
+ unsigned char orient = 0;
struct mxt_object *object;
u16 temp;
bool update = false;
@@ -4014,6 +4023,7 @@ static int mxt_probe(struct i2c_client *client,
len = strlen(data->pdata->cfg_name);
if (len > MXT_NAME_MAX_LEN - 1) {
dev_err(&client->dev, "Invalid config name\n");
+ error = -EINVAL;
goto err_destroy_mutex;
}
diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c
index 93c9c3c373b8..6f6cb35d90da 100644
--- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c
+++ b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_core.c
@@ -5,7 +5,7 @@
*
* Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
* Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
- * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-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 as published by
@@ -472,7 +472,7 @@ static int synaptics_i2c_change_pipe_owner(
struct synaptics_rmi4_data *rmi4_data, enum subsystem subsystem)
{
/*scm call descriptor */
- struct scm_desc desc;
+ struct scm_desc desc = {0};
struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent);
int ret = 0;
@@ -3808,6 +3808,13 @@ static int synaptics_rmi4_probe(struct platform_device *pdev)
}
exp_data.workqueue = create_singlethread_workqueue("dsx_exp_workqueue");
+ if (exp_data.workqueue == NULL) {
+ dev_err(&pdev->dev,
+ "%s: Failed to create workqueue\n", __func__);
+ retval = -ENOMEM;
+ goto err_create_wq;
+ }
+
INIT_DELAYED_WORK(&exp_data.work, synaptics_rmi4_exp_fn_work);
exp_data.rmi4_data = rmi4_data;
exp_data.queue_work = true;
@@ -3859,10 +3866,9 @@ err_create_debugfs_file:
debugfs_remove_recursive(rmi4_data->dir);
err_create_debugfs_dir:
cancel_delayed_work_sync(&exp_data.work);
- if (exp_data.workqueue != NULL) {
- flush_workqueue(exp_data.workqueue);
- destroy_workqueue(exp_data.workqueue);
- }
+ flush_workqueue(exp_data.workqueue);
+ destroy_workqueue(exp_data.workqueue);
+err_create_wq:
synaptics_rmi4_irq_enable(rmi4_data, false);
free_irq(rmi4_data->irq, rmi4_data);
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 9e96d81bc5cd..9a22494a2371 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -765,7 +765,7 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
* Ensure that stores to Normal memory are visible to the
* other CPUs before issuing the IPI.
*/
- smp_wmb();
+ wmb();
for_each_cpu(cpu, mask) {
unsigned long cluster_id = cpu_logical_map(cpu) & ~0xffUL;
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
index c1c3af089634..92b6798ef5b3 100644
--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -149,7 +149,7 @@ void led_blink_set(struct led_classdev *led_cdev,
unsigned long *delay_on,
unsigned long *delay_off)
{
- del_timer_sync(&led_cdev->blink_timer);
+ led_stop_software_blink(led_cdev);
led_cdev->flags &= ~LED_BLINK_ONESHOT;
led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index d336e1ef1bd7..acf0a90ed93d 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.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
@@ -155,9 +155,11 @@ struct msm_vfe_irq_ops {
struct msm_isp_timestamp *ts);
void (*process_axi_irq)(struct vfe_device *vfe_dev,
uint32_t irq_status0, uint32_t irq_status1,
+ uint32_t pingpong_status,
struct msm_isp_timestamp *ts);
void (*process_stats_irq)(struct vfe_device *vfe_dev,
uint32_t irq_status0, uint32_t irq_status1,
+ uint32_t pingpong_status,
struct msm_isp_timestamp *ts);
void (*config_irq)(struct vfe_device *vfe_dev,
uint32_t irq_status0, uint32_t irq_status1,
@@ -596,6 +598,7 @@ struct msm_vfe_tasklet_queue_cmd {
struct list_head list;
uint32_t vfeInterruptStatus0;
uint32_t vfeInterruptStatus1;
+ uint32_t vfe_pingpong_status;
struct msm_isp_timestamp ts;
uint8_t cmd_used;
struct vfe_device *vfe_dev;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
index 121f1ab8bcd1..b4308cc63cba 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
@@ -570,6 +570,7 @@ void msm_vfe47_process_error_status(struct vfe_device *vfe_dev)
void msm_vfe47_read_and_clear_irq_status(struct vfe_device *vfe_dev,
uint32_t *irq_status0, uint32_t *irq_status1)
{
+ uint32_t count = 0;
*irq_status0 = msm_camera_io_r(vfe_dev->vfe_base + 0x6C);
*irq_status1 = msm_camera_io_r(vfe_dev->vfe_base + 0x70);
/* Mask off bits that are not enabled */
@@ -578,6 +579,14 @@ void msm_vfe47_read_and_clear_irq_status(struct vfe_device *vfe_dev,
msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x58);
*irq_status0 &= vfe_dev->irq0_mask;
*irq_status1 &= vfe_dev->irq1_mask;
+ /* check if status register is cleared if not clear again*/
+ while (*irq_status0 &&
+ (*irq_status0 & msm_camera_io_r(vfe_dev->vfe_base + 0x6C)) &&
+ (count < MAX_RECOVERY_THRESHOLD)) {
+ msm_camera_io_w(*irq_status0, vfe_dev->vfe_base + 0x64);
+ msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x58);
+ count++;
+ }
if (*irq_status1 & (1 << 0)) {
vfe_dev->error_info.camif_status =
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index 15f8061b9919..7079044526b2 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.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
@@ -4202,11 +4202,11 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev,
void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
uint32_t irq_status0, uint32_t irq_status1,
- struct msm_isp_timestamp *ts)
+ uint32_t pingpong_status, struct msm_isp_timestamp *ts)
{
int i, rc = 0;
uint32_t comp_mask = 0, wm_mask = 0;
- uint32_t pingpong_status, stream_idx;
+ uint32_t stream_idx;
struct msm_vfe_axi_stream *stream_info;
struct msm_vfe_axi_composite_info *comp_info;
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
@@ -4220,8 +4220,6 @@ void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
return;
ISP_DBG("%s: status: 0x%x\n", __func__, irq_status0);
- pingpong_status =
- vfe_dev->hw_info->vfe_ops.axi_ops.get_pingpong_status(vfe_dev);
for (i = 0; i < axi_data->hw_info->num_comp_mask; i++) {
rc = 0;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
index 0f029c0d5178..9794db5a1b9c 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.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
@@ -54,7 +54,7 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type,
void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
uint32_t irq_status0, uint32_t irq_status1,
- struct msm_isp_timestamp *ts);
+ uint32_t pingpong_status, struct msm_isp_timestamp *ts);
void msm_isp_axi_disable_all_wm(struct vfe_device *vfe_dev);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
index f0831e64f250..6c1d9ddc4232 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.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
@@ -256,13 +256,12 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev,
static int32_t msm_isp_stats_configure(struct vfe_device *vfe_dev,
uint32_t stats_irq_mask, struct msm_isp_timestamp *ts,
- bool is_composite)
+ uint32_t pingpong_status, bool is_composite)
{
int i, rc = 0;
struct msm_isp_event_data buf_event;
struct msm_isp_stats_event *stats_event = &buf_event.u.stats;
struct msm_vfe_stats_stream *stream_info = NULL;
- uint32_t pingpong_status;
uint32_t comp_stats_type_mask = 0;
int result = 0;
@@ -271,8 +270,6 @@ static int32_t msm_isp_stats_configure(struct vfe_device *vfe_dev,
buf_event.mono_timestamp = ts->buf_time;
buf_event.frame_id = vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
- pingpong_status = vfe_dev->hw_info->
- vfe_ops.stats_ops.get_pingpong_status(vfe_dev);
for (i = 0; i < vfe_dev->hw_info->stats_hw_info->num_stats_type; i++) {
if (!(stats_irq_mask & (1 << i)))
@@ -309,7 +306,7 @@ static int32_t msm_isp_stats_configure(struct vfe_device *vfe_dev,
void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
uint32_t irq_status0, uint32_t irq_status1,
- struct msm_isp_timestamp *ts)
+ uint32_t pingpong_status, struct msm_isp_timestamp *ts)
{
int j, rc;
uint32_t atomic_stats_mask = 0;
@@ -337,7 +334,7 @@ void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
/* Process non-composite irq */
if (stats_irq_mask) {
rc = msm_isp_stats_configure(vfe_dev, stats_irq_mask, ts,
- comp_flag);
+ pingpong_status, comp_flag);
}
/* Process composite irq */
@@ -350,7 +347,7 @@ void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
&vfe_dev->stats_data.stats_comp_mask[j]);
rc = msm_isp_stats_configure(vfe_dev, atomic_stats_mask,
- ts, !comp_flag);
+ ts, pingpong_status, !comp_flag);
}
}
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.h
index 2e3a24dd1f0d..3efd5b57a029 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-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
@@ -17,7 +17,7 @@
void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
uint32_t irq_status0, uint32_t irq_status1,
- struct msm_isp_timestamp *ts);
+ uint32_t pingpong_status, struct msm_isp_timestamp *ts);
void msm_isp_stats_stream_update(struct vfe_device *vfe_dev);
int msm_isp_cfg_stats_stream(struct vfe_device *vfe_dev, void *arg);
int msm_isp_update_stats_stream(struct vfe_device *vfe_dev, void *arg);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index 242ed33b2b29..1a27a5d7e361 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -2064,7 +2064,8 @@ void msm_isp_prepare_tasklet_debug_info(struct vfe_device *vfe_dev,
}
static void msm_isp_enqueue_tasklet_cmd(struct vfe_device *vfe_dev,
- uint32_t irq_status0, uint32_t irq_status1)
+ uint32_t irq_status0, uint32_t irq_status1,
+ uint32_t ping_pong_status)
{
unsigned long flags;
struct msm_vfe_tasklet_queue_cmd *queue_cmd = NULL;
@@ -2087,8 +2088,8 @@ static void msm_isp_enqueue_tasklet_cmd(struct vfe_device *vfe_dev,
}
queue_cmd->vfeInterruptStatus0 = irq_status0;
queue_cmd->vfeInterruptStatus1 = irq_status1;
+ queue_cmd->vfe_pingpong_status = ping_pong_status;
msm_isp_get_timestamp(&queue_cmd->ts, vfe_dev);
-
queue_cmd->cmd_used = 1;
queue_cmd->vfe_dev = vfe_dev;
@@ -2102,7 +2103,7 @@ static void msm_isp_enqueue_tasklet_cmd(struct vfe_device *vfe_dev,
irqreturn_t msm_isp_process_irq(int irq_num, void *data)
{
struct vfe_device *vfe_dev = (struct vfe_device *) data;
- uint32_t irq_status0, irq_status1;
+ uint32_t irq_status0, irq_status1, ping_pong_status;
uint32_t error_mask0, error_mask1;
vfe_dev->hw_info->vfe_ops.irq_ops.
@@ -2113,6 +2114,8 @@ irqreturn_t msm_isp_process_irq(int irq_num, void *data)
__func__, vfe_dev->pdev->id);
return IRQ_HANDLED;
}
+ ping_pong_status = vfe_dev->hw_info->vfe_ops.axi_ops.
+ get_pingpong_status(vfe_dev);
if (vfe_dev->hw_info->vfe_ops.irq_ops.preprocess_camif_irq) {
vfe_dev->hw_info->vfe_ops.irq_ops.preprocess_camif_irq(
vfe_dev, irq_status0);
@@ -2140,7 +2143,8 @@ irqreturn_t msm_isp_process_irq(int irq_num, void *data)
return IRQ_HANDLED;
}
msm_isp_prepare_irq_debug_info(vfe_dev, irq_status0, irq_status1);
- msm_isp_enqueue_tasklet_cmd(vfe_dev, irq_status0, irq_status1);
+ msm_isp_enqueue_tasklet_cmd(vfe_dev, irq_status0, irq_status1,
+ ping_pong_status);
return IRQ_HANDLED;
}
@@ -2153,7 +2157,7 @@ void msm_isp_do_tasklet(unsigned long data)
struct msm_vfe_irq_ops *irq_ops;
struct msm_vfe_tasklet_queue_cmd *queue_cmd;
struct msm_isp_timestamp ts;
- uint32_t irq_status0, irq_status1;
+ uint32_t irq_status0, irq_status1, pingpong_status;
while (1) {
spin_lock_irqsave(&tasklet->tasklet_lock, flags);
@@ -2169,6 +2173,7 @@ void msm_isp_do_tasklet(unsigned long data)
queue_cmd->vfe_dev = NULL;
irq_status0 = queue_cmd->vfeInterruptStatus0;
irq_status1 = queue_cmd->vfeInterruptStatus1;
+ pingpong_status = queue_cmd->vfe_pingpong_status;
ts = queue_cmd->ts;
spin_unlock_irqrestore(&tasklet->tasklet_lock, flags);
if (vfe_dev->vfe_open_cnt == 0) {
@@ -2193,9 +2198,11 @@ void msm_isp_do_tasklet(unsigned long data)
}
msm_isp_process_error_info(vfe_dev);
irq_ops->process_stats_irq(vfe_dev,
- irq_status0, irq_status1, &ts);
+ irq_status0, irq_status1,
+ pingpong_status, &ts);
irq_ops->process_axi_irq(vfe_dev,
- irq_status0, irq_status1, &ts);
+ irq_status0, irq_status1,
+ pingpong_status, &ts);
irq_ops->process_camif_irq(vfe_dev,
irq_status0, irq_status1, &ts);
irq_ops->process_reg_update(vfe_dev,
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
index 422c7a590a45..2dbf02e1e47a 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
@@ -540,7 +540,7 @@ static int _sde_rotator_secure_session_ctrl(bool enable)
{
struct sde_rot_data_type *mdata = sde_rot_get_mdata();
uint32_t sid_info;
- struct scm_desc desc;
+ struct scm_desc desc = {0};
unsigned int resp = 0;
int ret = 0;
diff --git a/drivers/misc/profiler.c b/drivers/misc/profiler.c
index a2887fcefbab..92e6a6651b68 100644
--- a/drivers/misc/profiler.c
+++ b/drivers/misc/profiler.c
@@ -1,5 +1,5 @@
/*
- * 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
@@ -169,6 +169,7 @@ static int bw_profiling_get(void __user *argp, struct tz_bw_svc_buf *bwbuf)
const int numberofregs = 3;
struct profiler_bw_cntrs_req cnt_buf;
+ memset(&cnt_buf, 0, sizeof(cnt_buf));
bwgetreq = (struct tz_bw_svc_get_req *) &bwbuf->bwreq;
/* Allocate memory for get buffer */
buf = kzalloc(PAGE_ALIGN(numberofregs * sizeof(uint32_t)), GFP_KERNEL);
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 65d7dbe1dea4..2aa04b6bdfb3 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -335,6 +335,7 @@ static int mmc_read_switch(struct mmc_card *card)
card->sw_caps.sd3_bus_mode = status[13];
/* Driver Strengths supported by the card */
card->sw_caps.sd3_drv_type = status[9];
+ card->sw_caps.sd3_curr_limit = status[7] | status[6] << 8;
}
out:
@@ -557,14 +558,25 @@ static int sd_set_current_limit(struct mmc_card *card, u8 *status)
* when we set current limit to 200ma, the card will draw 200ma, and
* when we set current limit to 400/600/800ma, the card will draw its
* maximum 300ma from the host.
+ *
+ * The above is incorrect: if we try to set a current limit that is
+ * not supported by the card, the card can rightfully error out the
+ * attempt, and remain at the default current limit. This results
+ * in a 300mA card being limited to 200mA even though the host
+ * supports 800mA. Failures seen with SanDisk 8GB UHS cards with
+ * an iMX6 host. --rmk
*/
- if (max_current >= 800)
+ if (max_current >= 800 &&
+ card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_800)
current_limit = SD_SET_CURRENT_LIMIT_800;
- else if (max_current >= 600)
+ else if (max_current >= 600 &&
+ card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_600)
current_limit = SD_SET_CURRENT_LIMIT_600;
- else if (max_current >= 400)
+ else if (max_current >= 400 &&
+ card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_400)
current_limit = SD_SET_CURRENT_LIMIT_400;
- else if (max_current >= 200)
+ else if (max_current >= 200 &&
+ card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_200)
current_limit = SD_SET_CURRENT_LIMIT_200;
if (current_limit != SD_SET_CURRENT_NO_CHANGE) {
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 2064adac1d17..e2a239c1f40b 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1029,9 +1029,6 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
return ret;
}
- /* handle the block mark swapping */
- block_mark_swapping(this, payload_virt, auxiliary_virt);
-
/* Loop over status bytes, accumulating ECC status. */
status = auxiliary_virt + nfc_geo->auxiliary_status_offset;
@@ -1047,6 +1044,9 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
max_bitflips = max_t(unsigned int, max_bitflips, *status);
}
+ /* handle the block mark swapping */
+ block_mark_swapping(this, buf, auxiliary_virt);
+
if (oob_required) {
/*
* It's time to deliver the OOB bytes. See gpmi_ecc_read_oob()
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 16f7cadda5c3..47f43bdecd51 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -493,7 +493,7 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
data = be32_to_cpup((__be32 *)&cf->data[0]);
flexcan_write(data, &regs->mb[FLEXCAN_TX_BUF_ID].data[0]);
}
- if (cf->can_dlc > 3) {
+ if (cf->can_dlc > 4) {
data = be32_to_cpup((__be32 *)&cf->data[4]);
flexcan_write(data, &regs->mb[FLEXCAN_TX_BUF_ID].data[1]);
}
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index abe1eabc0171..9cc5daed13ed 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -250,39 +250,48 @@ static int arc_emac_rx(struct net_device *ndev, int budget)
continue;
}
- pktlen = info & LEN_MASK;
- stats->rx_packets++;
- stats->rx_bytes += pktlen;
- skb = rx_buff->skb;
- skb_put(skb, pktlen);
- skb->dev = ndev;
- skb->protocol = eth_type_trans(skb, ndev);
-
- dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr),
- dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE);
-
- /* Prepare the BD for next cycle */
- rx_buff->skb = netdev_alloc_skb_ip_align(ndev,
- EMAC_BUFFER_SIZE);
- if (unlikely(!rx_buff->skb)) {
+ /* Prepare the BD for next cycle. netif_receive_skb()
+ * only if new skb was allocated and mapped to avoid holes
+ * in the RX fifo.
+ */
+ skb = netdev_alloc_skb_ip_align(ndev, EMAC_BUFFER_SIZE);
+ if (unlikely(!skb)) {
+ if (net_ratelimit())
+ netdev_err(ndev, "cannot allocate skb\n");
+ /* Return ownership to EMAC */
+ rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE);
stats->rx_errors++;
- /* Because receive_skb is below, increment rx_dropped */
stats->rx_dropped++;
continue;
}
- /* receive_skb only if new skb was allocated to avoid holes */
- netif_receive_skb(skb);
-
- addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data,
+ addr = dma_map_single(&ndev->dev, (void *)skb->data,
EMAC_BUFFER_SIZE, DMA_FROM_DEVICE);
if (dma_mapping_error(&ndev->dev, addr)) {
if (net_ratelimit())
- netdev_err(ndev, "cannot dma map\n");
- dev_kfree_skb(rx_buff->skb);
+ netdev_err(ndev, "cannot map dma buffer\n");
+ dev_kfree_skb(skb);
+ /* Return ownership to EMAC */
+ rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE);
stats->rx_errors++;
+ stats->rx_dropped++;
continue;
}
+
+ /* unmap previosly mapped skb */
+ dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr),
+ dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE);
+
+ pktlen = info & LEN_MASK;
+ stats->rx_packets++;
+ stats->rx_bytes += pktlen;
+ skb_put(rx_buff->skb, pktlen);
+ rx_buff->skb->dev = ndev;
+ rx_buff->skb->protocol = eth_type_trans(rx_buff->skb, ndev);
+
+ netif_receive_skb(rx_buff->skb);
+
+ rx_buff->skb = skb;
dma_unmap_addr_set(rx_buff, addr, addr);
dma_unmap_len_set(rx_buff, len, EMAC_BUFFER_SIZE);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index e5911ccb2148..74bece5897c9 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -3052,7 +3052,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link)
del_timer_sync(&bp->timer);
- if (IS_PF(bp)) {
+ if (IS_PF(bp) && !BP_NOMCP(bp)) {
/* Set ALWAYS_ALIVE bit in shmem */
bp->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE;
bnx2x_drv_pulse(bp);
@@ -3134,7 +3134,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link)
bp->cnic_loaded = false;
/* Clear driver version indication in shmem */
- if (IS_PF(bp))
+ if (IS_PF(bp) && !BP_NOMCP(bp))
bnx2x_update_mng_version(bp);
/* Check if there are pending parity attentions. If there are - set
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index abb3ff6498dc..8ddb68a3fdb6 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -9570,6 +9570,15 @@ static int bnx2x_init_shmem(struct bnx2x *bp)
do {
bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
+
+ /* If we read all 0xFFs, means we are in PCI error state and
+ * should bail out to avoid crashes on adapter's FW reads.
+ */
+ if (bp->common.shmem_base == 0xFFFFFFFF) {
+ bp->flags |= NO_MCP_FLAG;
+ return -ENODEV;
+ }
+
if (bp->common.shmem_base) {
val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]);
if (val & SHR_MEM_VALIDITY_MB)
@@ -14214,7 +14223,10 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev)
BNX2X_ERR("IO slot reset --> driver unload\n");
/* MCP should have been reset; Need to wait for validity */
- bnx2x_init_shmem(bp);
+ if (bnx2x_init_shmem(bp)) {
+ rtnl_unlock();
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) {
u32 v;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
index ea044bbcd384..3eebb57975e3 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
@@ -29,7 +29,7 @@ static int bnxt_vf_ndo_prep(struct bnxt *bp, int vf_id)
netdev_err(bp->dev, "vf ndo called though sriov is disabled\n");
return -EINVAL;
}
- if (vf_id >= bp->pf.max_vfs) {
+ if (vf_id >= bp->pf.active_vfs) {
netdev_err(bp->dev, "Invalid VF id %d\n", vf_id);
return -EINVAL;
}
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index ab53e0cfb4dc..3bba92fc9c1a 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -10051,6 +10051,16 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy)
tw32(GRC_MODE, tp->grc_mode | val);
+ /* On one of the AMD platform, MRRS is restricted to 4000 because of
+ * south bridge limitation. As a workaround, Driver is setting MRRS
+ * to 2048 instead of default 4096.
+ */
+ if (tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
+ tp->pdev->subsystem_device == TG3PCI_SUBDEVICE_ID_DELL_5762) {
+ val = tr32(TG3PCI_DEV_STATUS_CTRL) & ~MAX_READ_REQ_MASK;
+ tw32(TG3PCI_DEV_STATUS_CTRL, val | MAX_READ_REQ_SIZE_2048);
+ }
+
/* Setup the timer prescalar register. Clock is always 66Mhz. */
val = tr32(GRC_MISC_CFG);
val &= ~0xff;
@@ -14230,7 +14240,8 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
*/
if (tg3_asic_rev(tp) == ASIC_REV_57766 ||
tg3_asic_rev(tp) == ASIC_REV_5717 ||
- tg3_asic_rev(tp) == ASIC_REV_5719)
+ tg3_asic_rev(tp) == ASIC_REV_5719 ||
+ tg3_asic_rev(tp) == ASIC_REV_5720)
reset_phy = true;
err = tg3_restart_hw(tp, reset_phy);
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 31c9f8295953..19532961e173 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -95,6 +95,7 @@
#define TG3PCI_SUBDEVICE_ID_DELL_JAGUAR 0x0106
#define TG3PCI_SUBDEVICE_ID_DELL_MERLOT 0x0109
#define TG3PCI_SUBDEVICE_ID_DELL_SLIM_MERLOT 0x010a
+#define TG3PCI_SUBDEVICE_ID_DELL_5762 0x07f0
#define TG3PCI_SUBVENDOR_ID_COMPAQ PCI_VENDOR_ID_COMPAQ
#define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE 0x007c
#define TG3PCI_SUBDEVICE_ID_COMPAQ_BANSHEE_2 0x009a
@@ -280,6 +281,9 @@
#define TG3PCI_STD_RING_PROD_IDX 0x00000098 /* 64-bit */
#define TG3PCI_RCV_RET_RING_CON_IDX 0x000000a0 /* 64-bit */
/* 0xa8 --> 0xb8 unused */
+#define TG3PCI_DEV_STATUS_CTRL 0x000000b4
+#define MAX_READ_REQ_SIZE_2048 0x00004000
+#define MAX_READ_REQ_MASK 0x00007000
#define TG3PCI_DUAL_MAC_CTRL 0x000000b8
#define DUAL_MAC_CTRL_CH_MASK 0x00000003
#define DUAL_MAC_CTRL_ID 0x00000004
diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c
index b40fba929d65..d540ee190038 100644
--- a/drivers/net/ethernet/freescale/gianfar_ptp.c
+++ b/drivers/net/ethernet/freescale/gianfar_ptp.c
@@ -314,11 +314,10 @@ static int ptp_gianfar_adjtime(struct ptp_clock_info *ptp, s64 delta)
now = tmr_cnt_read(etsects);
now += delta;
tmr_cnt_write(etsects, now);
+ set_fipers(etsects);
spin_unlock_irqrestore(&etsects->lock, flags);
- set_fipers(etsects);
-
return 0;
}
diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h
index 98fe5a2cd6e3..481e994490ce 100644
--- a/drivers/net/ethernet/intel/e1000/e1000.h
+++ b/drivers/net/ethernet/intel/e1000/e1000.h
@@ -331,7 +331,8 @@ struct e1000_adapter {
enum e1000_state_t {
__E1000_TESTING,
__E1000_RESETTING,
- __E1000_DOWN
+ __E1000_DOWN,
+ __E1000_DISABLED
};
#undef pr_fmt
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 068023595d84..2a1d4a9d3c19 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -940,7 +940,7 @@ static int e1000_init_hw_struct(struct e1000_adapter *adapter,
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct net_device *netdev;
- struct e1000_adapter *adapter;
+ struct e1000_adapter *adapter = NULL;
struct e1000_hw *hw;
static int cards_found = 0;
@@ -950,6 +950,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
u16 tmp = 0;
u16 eeprom_apme_mask = E1000_EEPROM_APME;
int bars, need_ioport;
+ bool disable_dev = false;
/* do not allocate ioport bars when not needed */
need_ioport = e1000_is_need_ioport(pdev);
@@ -1250,11 +1251,13 @@ err_mdio_ioremap:
iounmap(hw->ce4100_gbe_mdio_base_virt);
iounmap(hw->hw_addr);
err_ioremap:
+ disable_dev = !test_and_set_bit(__E1000_DISABLED, &adapter->flags);
free_netdev(netdev);
err_alloc_etherdev:
pci_release_selected_regions(pdev, bars);
err_pci_reg:
- pci_disable_device(pdev);
+ if (!adapter || disable_dev)
+ pci_disable_device(pdev);
return err;
}
@@ -1272,6 +1275,7 @@ static void e1000_remove(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ bool disable_dev;
e1000_down_and_stop(adapter);
e1000_release_manageability(adapter);
@@ -1290,9 +1294,11 @@ static void e1000_remove(struct pci_dev *pdev)
iounmap(hw->flash_address);
pci_release_selected_regions(pdev, adapter->bars);
+ disable_dev = !test_and_set_bit(__E1000_DISABLED, &adapter->flags);
free_netdev(netdev);
- pci_disable_device(pdev);
+ if (disable_dev)
+ pci_disable_device(pdev);
}
/**
@@ -5135,7 +5141,8 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
if (netif_running(netdev))
e1000_free_irq(adapter);
- pci_disable_device(pdev);
+ if (!test_and_set_bit(__E1000_DISABLED, &adapter->flags))
+ pci_disable_device(pdev);
return 0;
}
@@ -5179,6 +5186,10 @@ static int e1000_resume(struct pci_dev *pdev)
pr_err("Cannot enable PCI device from suspend\n");
return err;
}
+
+ /* flush memory to make sure state is correct */
+ smp_mb__before_atomic();
+ clear_bit(__E1000_DISABLED, &adapter->flags);
pci_set_master(pdev);
pci_enable_wake(pdev, PCI_D3hot, 0);
@@ -5253,7 +5264,9 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
if (netif_running(netdev))
e1000_down(adapter);
- pci_disable_device(pdev);
+
+ if (!test_and_set_bit(__E1000_DISABLED, &adapter->flags))
+ pci_disable_device(pdev);
/* Request a slot slot reset. */
return PCI_ERS_RESULT_NEED_RESET;
@@ -5281,6 +5294,10 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
pr_err("Cannot re-enable PCI device after reset.\n");
return PCI_ERS_RESULT_DISCONNECT;
}
+
+ /* flush memory to make sure state is correct */
+ smp_mb__before_atomic();
+ clear_bit(__E1000_DISABLED, &adapter->flags);
pci_set_master(pdev);
pci_enable_wake(pdev, PCI_D3hot, 0);
diff --git a/drivers/net/phy/mdio-sun4i.c b/drivers/net/phy/mdio-sun4i.c
index 15bc7f9ea224..afd76e07088b 100644
--- a/drivers/net/phy/mdio-sun4i.c
+++ b/drivers/net/phy/mdio-sun4i.c
@@ -128,8 +128,10 @@ static int sun4i_mdio_probe(struct platform_device *pdev)
data->regulator = devm_regulator_get(&pdev->dev, "phy");
if (IS_ERR(data->regulator)) {
- if (PTR_ERR(data->regulator) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
+ if (PTR_ERR(data->regulator) == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto err_out_free_mdiobus;
+ }
dev_info(&pdev->dev, "no regulator found\n");
} else {
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index ece0eee5cf7c..784a11a74443 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -1303,7 +1303,7 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
int ret;
struct ath10k_fw_file *fw_file;
- if (!ar->is_bmi && QCA_REV_WCN3990(ar)) {
+ if (!ar->is_bmi) {
fw_file = &ar->normal_mode_fw.fw_file;
fw_file->wmi_op_version = ATH10K_FW_WMI_OP_VERSION_TLV;
fw_file->htt_op_version = ATH10K_FW_HTT_OP_VERSION_TLV;
diff --git a/drivers/net/wireless/ath/ath10k/testmode.c b/drivers/net/wireless/ath/ath10k/testmode.c
index ed85f938e3c0..f760481026db 100644
--- a/drivers/net/wireless/ath/ath10k/testmode.c
+++ b/drivers/net/wireless/ath/ath10k/testmode.c
@@ -174,8 +174,15 @@ static int ath10k_tm_fetch_utf_firmware_api_1(struct ath10k *ar,
static int ath10k_tm_fetch_firmware(struct ath10k *ar)
{
struct ath10k_fw_components *utf_mode_fw;
+ struct ath10k_fw_file *fw_file;
int ret;
+ if (!ar->is_bmi) {
+ fw_file = &ar->testmode.utf_mode_fw.fw_file;
+ fw_file->wmi_op_version = ATH10K_FW_WMI_OP_VERSION_TLV;
+ fw_file->htt_op_version = ATH10K_FW_HTT_OP_VERSION_TLV;
+ return 0;
+ }
ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_UTF_API2_FILE,
&ar->testmode.utf_mode_fw.fw_file);
if (ret == 0) {
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index eb7a9e62371c..0b8d2655985f 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1331,6 +1331,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
netif_carrier_off(netdev);
+ xenbus_switch_state(dev, XenbusStateInitialising);
return netdev;
exit:
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
index 0aa81bd3de12..fb682e8af74d 100644
--- a/drivers/pci/host/pci-keystone.c
+++ b/drivers/pci/host/pci-keystone.c
@@ -179,14 +179,16 @@ static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie,
}
/* interrupt controller is in a child node */
- *np_temp = of_find_node_by_name(np_pcie, controller);
+ *np_temp = of_get_child_by_name(np_pcie, controller);
if (!(*np_temp)) {
dev_err(dev, "Node for %s is absent\n", controller);
goto out;
}
temp = of_irq_count(*np_temp);
- if (!temp)
+ if (!temp) {
+ of_node_put(*np_temp);
goto out;
+ }
if (temp > max_host_irqs)
dev_warn(dev, "Too many %s interrupts defined %u\n",
(legacy ? "legacy" : "MSI"), temp);
@@ -200,6 +202,9 @@ static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie,
if (!host_irqs[temp])
break;
}
+
+ of_node_put(*np_temp);
+
if (temp) {
*num_irqs = temp;
ret = 0;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
index 4a68b96ca89a..7cc3c380ee71 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
@@ -51,6 +51,7 @@ int __ipa_generate_rt_hw_rule_v2(enum ipa_ip_type ip,
u32 tmp[IPA_RT_FLT_HW_RULE_BUF_SIZE/4];
u8 *start;
int pipe_idx;
+ struct ipa_hdr_entry *hdr_entry;
if (buf == NULL) {
memset(tmp, 0, (IPA_RT_FLT_HW_RULE_BUF_SIZE/4));
@@ -74,6 +75,18 @@ int __ipa_generate_rt_hw_rule_v2(enum ipa_ip_type ip,
}
rule_hdr->u.hdr.pipe_dest_idx = pipe_idx;
rule_hdr->u.hdr.system = !ipa_ctx->hdr_tbl_lcl;
+
+ /* Adding check to confirm still
+ * header entry present in header table or not
+ */
+
+ if (entry->hdr) {
+ hdr_entry = ipa_id_find(entry->rule.hdr_hdl);
+ if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
+ IPAERR_RL("Header entry already deleted\n");
+ return -EPERM;
+ }
+ }
if (entry->hdr) {
if (entry->hdr->cookie == IPA_HDR_COOKIE) {
rule_hdr->u.hdr.hdr_offset =
@@ -140,6 +153,8 @@ int __ipa_generate_rt_hw_rule_v2_5(enum ipa_ip_type ip,
u32 tmp[IPA_RT_FLT_HW_RULE_BUF_SIZE/4];
u8 *start;
int pipe_idx;
+ struct ipa_hdr_entry *hdr_entry;
+ struct ipa_hdr_proc_ctx_entry *hdr_proc_entry;
if (buf == NULL) {
memset(tmp, 0, IPA_RT_FLT_HW_RULE_BUF_SIZE);
@@ -162,6 +177,24 @@ int __ipa_generate_rt_hw_rule_v2_5(enum ipa_ip_type ip,
return -EPERM;
}
rule_hdr->u.hdr_v2_5.pipe_dest_idx = pipe_idx;
+ /* Adding check to confirm still
+ * header entry present in header table or not
+ */
+
+ if (entry->hdr) {
+ hdr_entry = ipa_id_find(entry->rule.hdr_hdl);
+ if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
+ IPAERR_RL("Header entry already deleted\n");
+ return -EPERM;
+ }
+ } else if (entry->proc_ctx) {
+ hdr_proc_entry = ipa_id_find(entry->rule.hdr_proc_ctx_hdl);
+ if (!hdr_proc_entry ||
+ hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) {
+ IPAERR_RL("Proc header entry already deleted\n");
+ return -EPERM;
+ }
+ }
if (entry->proc_ctx || (entry->hdr && entry->hdr->is_hdr_proc_ctx)) {
struct ipa_hdr_proc_ctx_entry *proc_ctx;
@@ -1130,6 +1163,8 @@ int __ipa_del_rt_rule(u32 rule_hdl)
{
struct ipa_rt_entry *entry;
int id;
+ struct ipa_hdr_entry *hdr_entry;
+ struct ipa_hdr_proc_ctx_entry *hdr_proc_entry;
entry = ipa_id_find(rule_hdl);
@@ -1151,6 +1186,24 @@ int __ipa_del_rt_rule(u32 rule_hdl)
return -EINVAL;
}
}
+ /* Adding check to confirm still
+ * header entry present in header table or not
+ */
+
+ if (entry->hdr) {
+ hdr_entry = ipa_id_find(entry->rule.hdr_hdl);
+ if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
+ IPAERR_RL("Header entry already deleted\n");
+ return -EINVAL;
+ }
+ } else if (entry->proc_ctx) {
+ hdr_proc_entry = ipa_id_find(entry->rule.hdr_proc_ctx_hdl);
+ if (!hdr_proc_entry ||
+ hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) {
+ IPAERR_RL("Proc header entry already deleted\n");
+ return -EINVAL;
+ }
+ }
if (entry->hdr)
__ipa_release_hdr(entry->hdr->id);
@@ -1463,6 +1516,7 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
{
struct ipa_rt_entry *entry;
struct ipa_hdr_entry *hdr = NULL;
+ struct ipa_hdr_entry *hdr_entry;
if (rtrule->rule.hdr_hdl) {
hdr = ipa_id_find(rtrule->rule.hdr_hdl);
@@ -1483,6 +1537,17 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
goto error;
}
+ /* Adding check to confirm still
+ * header entry present in header table or not
+ */
+
+ if (entry->hdr) {
+ hdr_entry = ipa_id_find(entry->rule.hdr_hdl);
+ if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
+ IPAERR_RL("Header entry already deleted\n");
+ return -EPERM;
+ }
+ }
if (entry->hdr)
entry->hdr->ref_cnt--;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
index a10e2cb9ce8b..fd455f72e09e 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
@@ -50,6 +50,8 @@ static int ipa_generate_rt_hw_rule(enum ipa_ip_type ip,
struct ipa3_rt_entry *entry, u8 *buf)
{
struct ipahal_rt_rule_gen_params gen_params;
+ struct ipa3_hdr_entry *hdr_entry;
+ struct ipa3_hdr_proc_ctx_entry *hdr_proc_entry;
int res = 0;
memset(&gen_params, 0, sizeof(gen_params));
@@ -69,6 +71,25 @@ static int ipa_generate_rt_hw_rule(enum ipa_ip_type ip,
return -EPERM;
}
+ /* Adding check to confirm still
+ * header entry present in header table or not
+ */
+
+ if (entry->hdr) {
+ hdr_entry = ipa3_id_find(entry->rule.hdr_hdl);
+ if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
+ IPAERR_RL("Header entry already deleted\n");
+ return -EPERM;
+ }
+ } else if (entry->proc_ctx) {
+ hdr_proc_entry = ipa3_id_find(entry->rule.hdr_proc_ctx_hdl);
+ if (!hdr_proc_entry ||
+ hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) {
+ IPAERR_RL("Proc header entry already deleted\n");
+ return -EPERM;
+ }
+ }
+
if (entry->proc_ctx || (entry->hdr && entry->hdr->is_hdr_proc_ctx)) {
struct ipa3_hdr_proc_ctx_entry *proc_ctx;
proc_ctx = (entry->proc_ctx) ? : entry->hdr->proc_ctx;
@@ -1268,6 +1289,8 @@ int __ipa3_del_rt_rule(u32 rule_hdl)
{
struct ipa3_rt_entry *entry;
int id;
+ struct ipa3_hdr_entry *hdr_entry;
+ struct ipa3_hdr_proc_ctx_entry *hdr_proc_entry;
entry = ipa3_id_find(rule_hdl);
@@ -1290,6 +1313,25 @@ int __ipa3_del_rt_rule(u32 rule_hdl)
}
}
+ /* Adding check to confirm still
+ * header entry present in header table or not
+ */
+
+ if (entry->hdr) {
+ hdr_entry = ipa3_id_find(entry->rule.hdr_hdl);
+ if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
+ IPAERR_RL("Header entry already deleted\n");
+ return -EINVAL;
+ }
+ } else if (entry->proc_ctx) {
+ hdr_proc_entry = ipa3_id_find(entry->rule.hdr_proc_ctx_hdl);
+ if (!hdr_proc_entry ||
+ hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) {
+ IPAERR_RL("Proc header entry already deleted\n");
+ return -EINVAL;
+ }
+ }
+
if (entry->hdr)
__ipa3_release_hdr(entry->hdr->id);
else if (entry->proc_ctx)
@@ -1609,7 +1651,8 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
struct ipa3_rt_entry *entry;
struct ipa3_hdr_entry *hdr = NULL;
struct ipa3_hdr_proc_ctx_entry *proc_ctx = NULL;
-
+ struct ipa3_hdr_entry *hdr_entry;
+ struct ipa3_hdr_proc_ctx_entry *hdr_proc_entry;
if (rtrule->rule.hdr_hdl) {
hdr = ipa3_id_find(rtrule->rule.hdr_hdl);
if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
@@ -1636,6 +1679,25 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
goto error;
}
+ /* Adding check to confirm still
+ * header entry present in header table or not
+ */
+
+ if (entry->hdr) {
+ hdr_entry = ipa3_id_find(entry->rule.hdr_hdl);
+ if (!hdr_entry || hdr_entry->cookie != IPA_HDR_COOKIE) {
+ IPAERR_RL("Header entry already deleted\n");
+ return -EPERM;
+ }
+ } else if (entry->proc_ctx) {
+ hdr_proc_entry = ipa3_id_find(entry->rule.hdr_proc_ctx_hdl);
+ if (!hdr_proc_entry ||
+ hdr_proc_entry->cookie != IPA_PROC_HDR_COOKIE) {
+ IPAERR_RL("Proc header entry already deleted\n");
+ return -EPERM;
+ }
+ }
+
if (entry->hdr)
entry->hdr->ref_cnt--;
if (entry->proc_ctx)
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index d26134713682..d05c553eb552 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -2743,6 +2743,16 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
erp = dasd_3990_erp_handle_match_erp(cqr, erp);
}
+
+ /*
+ * For path verification work we need to stick with the path that was
+ * originally chosen so that the per path configuration data is
+ * assigned correctly.
+ */
+ if (test_bit(DASD_CQR_VERIFY_PATH, &erp->flags) && cqr->lpm) {
+ erp->lpm = cqr->lpm;
+ }
+
if (device->features & DASD_FEATURE_ERPLOG) {
/* print current erp_chain */
dev_err(&device->cdev->dev,
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h
index 8fae03215a85..543c10266984 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.h
+++ b/drivers/scsi/ibmvscsi/ibmvfc.h
@@ -366,7 +366,7 @@ enum ibmvfc_fcp_rsp_info_codes {
};
struct ibmvfc_fcp_rsp_info {
- __be16 reserved;
+ u8 reserved[3];
u8 rsp_code;
u8 reserved2[4];
}__attribute__((packed, aligned (2)));
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 5e4e1ba96f10..351d81dc2200 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -890,10 +890,11 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
case TEST_UNIT_READY:
break;
default:
- set_host_byte(scmnd, DID_TARGET_FAILURE);
+ set_host_byte(scmnd, DID_ERROR);
}
break;
case SRB_STATUS_INVALID_LUN:
+ set_host_byte(scmnd, DID_NO_CONNECT);
do_work = true;
process_err_fn = storvsc_remove_lun;
break;
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 9bf7f57d9a17..10021f25afdd 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -3,7 +3,7 @@
*
* This code is based on drivers/scsi/ufs/ufshcd.c
* Copyright (C) 2011-2013 Samsung India Software Operations
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* Authors:
* Santosh Yaraganavi <santosh.sy@samsung.com>
@@ -8431,7 +8431,8 @@ static void ufshcd_hba_exit(struct ufs_hba *hba)
if (ufshcd_is_clkscaling_supported(hba)) {
if (hba->devfreq)
ufshcd_suspend_clkscaling(hba);
- destroy_workqueue(hba->clk_scaling.workq);
+ if (hba->clk_scaling.workq)
+ destroy_workqueue(hba->clk_scaling.workq);
}
ufshcd_disable_clocks(hba, false);
ufshcd_setup_hba_vreg(hba, false);
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index ba2ff8326cac..8605b750c11d 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -47,6 +47,7 @@ ifdef CONFIG_MSM_SUBSYSTEM_RESTART
obj-y += subsystem_notif.o
obj-y += subsystem_restart.o
obj-y += ramdump.o
+ obj-$(CONFIG_MSM_GVM_QUIN) += subsystem_notif_virt.o
endif
obj-$(CONFIG_QPNP_HAPTIC) += qpnp-haptic.o
diff --git a/drivers/soc/qcom/subsystem_notif_virt.c b/drivers/soc/qcom/subsystem_notif_virt.c
new file mode 100644
index 000000000000..739600f2498d
--- /dev/null
+++ b/drivers/soc/qcom/subsystem_notif_virt.c
@@ -0,0 +1,163 @@
+/* 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 <linux/err.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/notifier.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/io.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <soc/qcom/subsystem_notif.h>
+
+static void __iomem *base_reg;
+
+struct state_notifier_block {
+ const char *subsystem;
+ struct notifier_block nb;
+ u32 offset;
+ void *handle;
+ struct list_head notifier_list;
+};
+
+static LIST_HEAD(notifier_block_list);
+
+static int subsys_state_callback(struct notifier_block *this,
+ unsigned long value, void *priv)
+{
+ struct state_notifier_block *notifier =
+ container_of(this, struct state_notifier_block, nb);
+
+ writel_relaxed(value, base_reg + notifier->offset);
+
+ return NOTIFY_OK;
+}
+
+static int subsys_notif_virt_probe(struct platform_device *pdev)
+{
+ struct device_node *node;
+ struct device_node *child = NULL;
+ struct resource *res;
+ struct state_notifier_block *notif_block;
+ int ret = 0;
+
+ if (!pdev) {
+ dev_err(&pdev->dev, "pdev is NULL\n");
+ return -EINVAL;
+ }
+
+ node = pdev->dev.of_node;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vdev_base");
+ base_reg = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR_OR_NULL(base_reg)) {
+ dev_err(&pdev->dev, "Memory mapping failed\n");
+ return -ENOMEM;
+ }
+
+ for_each_child_of_node(node, child) {
+
+ notif_block = devm_kmalloc(&pdev->dev,
+ sizeof(struct state_notifier_block),
+ GFP_KERNEL);
+ if (!notif_block)
+ return -ENOMEM;
+
+ notif_block->subsystem =
+ of_get_property(child, "subsys-name", NULL);
+ if (IS_ERR_OR_NULL(notif_block->subsystem)) {
+ dev_err(&pdev->dev, "Could not find subsystem name\n");
+ ret = -EINVAL;
+ goto err_nb;
+ }
+
+ notif_block->nb.notifier_call = subsys_state_callback;
+
+ notif_block->handle =
+ subsys_notif_register_notifier(notif_block->subsystem,
+ &notif_block->nb);
+ if (IS_ERR_OR_NULL(notif_block->handle)) {
+ dev_err(&pdev->dev, "Could not register SSR notifier cb\n");
+ ret = -EINVAL;
+ goto err_nb;
+ }
+
+ ret = of_property_read_u32(child, "offset",
+ &notif_block->offset);
+ if (ret) {
+ dev_err(&pdev->dev, "offset reading for %s failed\n",
+ notif_block->subsystem);
+ ret = -EINVAL;
+ goto err_offset;
+ }
+
+ list_add_tail(&notif_block->notifier_list,
+ &notifier_block_list);
+
+ }
+ return 0;
+
+err_offset:
+ subsys_notif_unregister_notifier(notif_block->handle,
+ &notif_block->nb);
+err_nb:
+ kfree(notif_block);
+ return ret;
+}
+
+static int subsys_notif_virt_remove(struct platform_device *pdev)
+{
+ struct state_notifier_block *notif_block;
+
+ list_for_each_entry(notif_block, &notifier_block_list,
+ notifier_list) {
+ subsys_notif_unregister_notifier(notif_block->handle,
+ &notif_block->nb);
+ list_del(&notif_block->notifier_list);
+ }
+ return 0;
+}
+
+static const struct of_device_id match_table[] = {
+ { .compatible = "qcom,subsys-notif-virt" },
+ {},
+};
+
+static struct platform_driver subsys_notif_virt_driver = {
+ .probe = subsys_notif_virt_probe,
+ .remove = subsys_notif_virt_remove,
+ .driver = {
+ .name = "subsys_notif_virt",
+ .owner = "THIS_MODULE",
+ .of_match_table = match_table,
+ },
+};
+
+static int __init subsys_notif_virt_init(void)
+{
+ return platform_driver_register(&subsys_notif_virt_driver);
+}
+module_init(subsys_notif_virt_init);
+
+static void __exit subsys_notif_virt_exit(void)
+{
+ platform_driver_unregister(&subsys_notif_virt_driver);
+}
+module_exit(subsys_notif_virt_exit);
+
+MODULE_DESCRIPTION("Subsystem Notification Virtual Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 8feac599e9ab..44be6b593b30 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -1669,12 +1669,12 @@ static int atmel_spi_remove(struct platform_device *pdev)
pm_runtime_get_sync(&pdev->dev);
/* reset the hardware and block queue progress */
- spin_lock_irq(&as->lock);
if (as->use_dma) {
atmel_spi_stop_dma(as);
atmel_spi_release_dma(as);
}
+ spin_lock_irq(&as->lock);
spi_writel(as, CR, SPI_BIT(SWRST));
spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
spi_readl(as, SR);
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index c05c4f877750..774c97bb1c08 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -225,6 +225,9 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x1a0a, 0x0200), .driver_info =
USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
+ /* Corsair K70 RGB */
+ { USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT },
+
/* Corsair Strafe RGB */
{ USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT },
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index f108aecbfe52..f6117ac0e301 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2984,6 +2984,8 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
break;
}
+ dwc->eps[1]->endpoint.maxpacket = dwc->gadget.ep0->maxpacket;
+
/* Enable USB2 LPM Capability */
if ((dwc->revision > DWC3_REVISION_194A)
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 7d7197e2cfc4..1ffde9c5408c 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -3226,8 +3226,8 @@ static int _ffs_func_bind(struct usb_configuration *c,
struct ffs_data *ffs = func->ffs;
const int full = !!func->ffs->fs_descs_count;
- const int high = func->ffs->hs_descs_count;
- const int super = func->ffs->ss_descs_count;
+ const int high = !!func->ffs->hs_descs_count;
+ const int super = !!func->ffs->ss_descs_count;
int fs_len, hs_len, ss_len, ret, i;
struct ffs_ep *eps_ptr;
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index 4365dc36be8d..48200a89f7aa 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -1018,6 +1018,8 @@ skip_ed:
* have modified this list. normally it's just prepending
* entries (which we'd ignore), but paranoia won't hurt.
*/
+ *last = ed->ed_next;
+ ed->ed_next = NULL;
modified = 0;
/* unlink urbs as requested, but rescan the list after
@@ -1076,21 +1078,22 @@ rescan_this:
goto rescan_this;
/*
- * If no TDs are queued, take ED off the ed_rm_list.
+ * If no TDs are queued, ED is now idle.
* Otherwise, if the HC is running, reschedule.
- * If not, leave it on the list for further dequeues.
+ * If the HC isn't running, add ED back to the
+ * start of the list for later processing.
*/
if (list_empty(&ed->td_list)) {
- *last = ed->ed_next;
- ed->ed_next = NULL;
ed->state = ED_IDLE;
list_del(&ed->in_use_list);
} else if (ohci->rh_state == OHCI_RH_RUNNING) {
- *last = ed->ed_next;
- ed->ed_next = NULL;
ed_schedule(ohci, ed);
} else {
- last = &ed->ed_next;
+ ed->ed_next = ohci->ed_rm_list;
+ ohci->ed_rm_list = ed;
+ /* Don't loop on the same ED */
+ if (last == &ohci->ed_rm_list)
+ last = &ed->ed_next;
}
if (modified)
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index cce22ff1c2eb..e9113238d9e3 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -46,6 +46,9 @@
#define USB_DEVICE_ID_LD_MICROCASSYTIME 0x1033 /* USB Product ID of Micro-CASSY Time (reserved) */
#define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE 0x1035 /* USB Product ID of Micro-CASSY Temperature */
#define USB_DEVICE_ID_LD_MICROCASSYPH 0x1038 /* USB Product ID of Micro-CASSY pH */
+#define USB_DEVICE_ID_LD_POWERANALYSERCASSY 0x1040 /* USB Product ID of Power Analyser CASSY */
+#define USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY 0x1042 /* USB Product ID of Converter Controller CASSY */
+#define USB_DEVICE_ID_LD_MACHINETESTCASSY 0x1043 /* USB Product ID of Machine Test CASSY */
#define USB_DEVICE_ID_LD_JWM 0x1080 /* USB Product ID of Joule and Wattmeter */
#define USB_DEVICE_ID_LD_DMMP 0x1081 /* USB Product ID of Digital Multimeter P (reserved) */
#define USB_DEVICE_ID_LD_UMIP 0x1090 /* USB Product ID of UMI P */
@@ -88,6 +91,9 @@ static const struct usb_device_id ld_usb_table[] = {
{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTIME) },
{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE) },
{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYPH) },
+ { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERANALYSERCASSY) },
+ { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY) },
+ { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETESTCASSY) },
{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) },
{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) },
{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) },
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index 8bb9367ada45..6f37966ea54b 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -999,6 +999,10 @@ static int usbhsf_dma_prepare_pop_with_usb_dmac(struct usbhs_pkt *pkt,
if ((uintptr_t)pkt->buf & (USBHS_USB_DMAC_XFER_SIZE - 1))
goto usbhsf_pio_prepare_pop;
+ /* return at this time if the pipe is running */
+ if (usbhs_pipe_is_running(pipe))
+ return 0;
+
usbhs_pipe_config_change_bfre(pipe, 1);
ret = usbhsf_fifo_select(pipe, fifo, 0);
@@ -1189,6 +1193,7 @@ static int usbhsf_dma_pop_done_with_usb_dmac(struct usbhs_pkt *pkt,
usbhsf_fifo_clear(pipe, fifo);
pkt->actual = usbhs_dma_calc_received_size(pkt, chan, rcv_len);
+ usbhs_pipe_running(pipe, 0);
usbhsf_dma_stop(pipe, fifo);
usbhsf_dma_unmap(pkt);
usbhsf_fifo_unselect(pipe, pipe->fifo);
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index 71584dff75cb..3240c0e71fb6 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -1967,6 +1967,7 @@ static int mdss_dp_edid_init(struct mdss_panel_data *pdata)
edid_init_data.kobj = dp_drv->kobj;
edid_init_data.max_pclk_khz = dp_drv->max_pclk_khz;
+ edid_init_data.yc420_support = false;
edid_data = hdmi_edid_init(&edid_init_data);
if (!edid_data) {
diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c
index 407f230ca71e..662e55be8b94 100644
--- a/drivers/video/fbdev/msm/mdss_dp_aux.c
+++ b/drivers/video/fbdev/msm/mdss_dp_aux.c
@@ -1558,7 +1558,7 @@ static void dp_sink_parse_sink_count(struct mdss_dp_drv_pdata *ep)
data = *bp++;
/* BIT 7, BIT 5:0 */
- ep->sink_count.count = (data & BIT(7)) << 6 | (data & 0x63);
+ ep->sink_count.count = (data & BIT(7)) >> 1 | (data & 0x3F);
/* BIT 6*/
ep->sink_count.cp_ready = data & BIT(6);
diff --git a/drivers/video/fbdev/msm/mdss_hdcp.h b/drivers/video/fbdev/msm/mdss_hdcp.h
index 40089d96ea78..8570abf2d0c0 100644
--- a/drivers/video/fbdev/msm/mdss_hdcp.h
+++ b/drivers/video/fbdev/msm/mdss_hdcp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012, 2014-2017, 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
@@ -18,6 +18,8 @@
#include <video/msm_hdmi_modes.h>
#include <soc/qcom/scm.h>
+#define HDCP_SRM_CHECK_FAIL 29
+
enum hdcp_client_id {
HDCP_CLIENT_HDMI,
HDCP_CLIENT_DP,
@@ -28,6 +30,7 @@ enum hdcp_states {
HDCP_STATE_AUTHENTICATING,
HDCP_STATE_AUTHENTICATED,
HDCP_STATE_AUTH_FAIL,
+ HDCP_STATE_AUTH_FAIL_NOREAUTH,
HDCP_STATE_AUTH_ENC_NONE,
HDCP_STATE_AUTH_ENC_1X,
HDCP_STATE_AUTH_ENC_2P2
diff --git a/drivers/video/fbdev/msm/mdss_hdcp_1x.c b/drivers/video/fbdev/msm/mdss_hdcp_1x.c
index 2dc9c8f96c5b..8df9080129b9 100644
--- a/drivers/video/fbdev/msm/mdss_hdcp_1x.c
+++ b/drivers/video/fbdev/msm/mdss_hdcp_1x.c
@@ -789,13 +789,118 @@ error:
return rc;
}
+static u8 *hdcp_1x_swap_byte_order(u8 *bksv_in, int num_dev)
+{
+ u8 *bksv_out;
+ u8 *tmp_out;
+ u8 *tmp_in;
+ int i, j;
+
+ /* Dont exceed max downstream devices */
+ if (num_dev > MAX_DEVICES_SUPPORTED) {
+ pr_err("invalid params\n");
+ return NULL;
+ }
+
+ bksv_out = kzalloc(RECV_ID_SIZE * num_dev, GFP_KERNEL);
+
+ if (!bksv_out)
+ return NULL;
+
+ pr_debug("num_dev = %d\n", num_dev);
+
+ /* Store temporarily for return */
+ tmp_out = bksv_out;
+ tmp_in = bksv_in;
+
+ for (i = 0; i < num_dev; i++) {
+ for (j = 0; j < RECV_ID_SIZE; j++)
+ bksv_out[j] = tmp_in[RECV_ID_SIZE - j - 1];
+
+ /* Each KSV is 5 bytes long */
+ bksv_out += RECV_ID_SIZE;
+ tmp_in += RECV_ID_SIZE;
+ }
+
+ return tmp_out;
+}
+
+static int hdcp_1x_revoked_rcv_chk(struct hdcp_1x *hdcp)
+{
+ int rc = 0;
+ u8 *bksv = hdcp->current_tp.bksv;
+ u8 *bksv_out;
+ struct hdcp_srm_device_id_t *bksv_srm;
+
+ bksv_out = hdcp_1x_swap_byte_order(bksv, 1);
+
+ if (!bksv_out) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ pr_debug("bksv_out : 0x%2x%2x%2x%2x%2x\n",
+ bksv_out[4], bksv_out[3], bksv_out[2],
+ bksv_out[1], bksv_out[0]);
+
+ bksv_srm = (struct hdcp_srm_device_id_t *)bksv_out;
+ /* Here we are checking only receiver ID
+ * hence the device count is one
+ */
+ rc = hdcp1_validate_receiver_ids(bksv_srm, 1);
+
+ kfree(bksv_out);
+
+exit:
+ return rc;
+}
+
+static int hdcp_1x_revoked_rpt_chk(struct hdcp_1x *hdcp)
+{
+ int rc = 0;
+ int i;
+ u8 *bksv = hdcp->current_tp.ksv_list;
+ u8 *bksv_out;
+ struct hdcp_srm_device_id_t *bksv_srm;
+
+ for (i = 0; i < hdcp->sink_addr.ksv_fifo.len;
+ i += RECV_ID_SIZE) {
+ pr_debug("bksv : 0x%2x%2x%2x%2x%2x\n",
+ bksv[i + 4],
+ bksv[i + 3], bksv[i + 2],
+ bksv[i + 1], bksv[i]);
+ }
+
+ bksv_out = hdcp_1x_swap_byte_order(bksv,
+ hdcp->current_tp.dev_count);
+
+ if (!bksv_out) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ bksv_srm = (struct hdcp_srm_device_id_t *)bksv_out;
+ /* Here we are checking repeater ksv list */
+ rc = hdcp1_validate_receiver_ids(bksv_srm,
+ hdcp->current_tp.dev_count);
+
+ kfree(bksv_out);
+
+exit:
+ return rc;
+}
+
static void hdcp_1x_enable_sink_irq_hpd(struct hdcp_1x *hdcp)
{
int rc;
u8 enable_hpd_irq = 0x1;
- u16 version = *hdcp->init_data.version;
+ u16 version;
const int major = 1, minor = 2;
+ if (hdcp->init_data.client_id == HDCP_CLIENT_HDMI)
+ return;
+
+ version = *hdcp->init_data.version;
pr_debug("version 0x%x\n", version);
if (((version & 0xFF) < minor) ||
@@ -906,6 +1011,12 @@ static int hdcp_1x_authentication_part1(struct hdcp_1x *hdcp)
if (rc)
goto error;
+ rc = hdcp_1x_revoked_rcv_chk(hdcp);
+ if (rc) {
+ rc = -HDCP_SRM_CHECK_FAIL;
+ goto error;
+ }
+
rc = hdcp_1x_send_an_aksv_to_sink(hdcp);
if (rc)
goto error;
@@ -1230,14 +1341,22 @@ static int hdcp_1x_authentication_part2(struct hdcp_1x *hdcp)
if (rc)
goto error;
+ rc = hdcp_1x_revoked_rpt_chk(hdcp);
+ if (rc) {
+ rc = -HDCP_SRM_CHECK_FAIL;
+ goto error;
+ }
+
do {
rc = hdcp_1x_transfer_v_h(hdcp);
if (rc)
goto error;
/* do not proceed further if no device connected */
- if (!hdcp->current_tp.dev_count)
+ if (!hdcp->current_tp.dev_count) {
+ rc = -EINVAL;
goto error;
+ }
rc = hdcp_1x_write_ksv_fifo(hdcp);
} while (--v_retry && rc);
@@ -1344,7 +1463,7 @@ static void hdcp_1x_auth_work(struct work_struct *work)
goto end;
} else {
hdcp->hdcp_state = HDCP_STATE_AUTHENTICATED;
- goto end;
+ goto disable_sw_ddc;
}
hdcp->ksv_ready = false;
@@ -1353,6 +1472,7 @@ static void hdcp_1x_auth_work(struct work_struct *work)
if (rc)
goto end;
+disable_sw_ddc:
/*
* Disabling software DDC before going into part3 to make sure
* there is no Arbitration between software and hardware for DDC
@@ -1361,9 +1481,11 @@ static void hdcp_1x_auth_work(struct work_struct *work)
DSS_REG_W_ND(io, HDMI_DDC_ARBITRATION, DSS_REG_R(io,
HDMI_DDC_ARBITRATION) | (BIT(4)));
end:
- if (rc && !hdcp_1x_state(HDCP_STATE_INACTIVE))
+ if (rc && !hdcp_1x_state(HDCP_STATE_INACTIVE)) {
hdcp->hdcp_state = HDCP_STATE_AUTH_FAIL;
-
+ if (rc == -HDCP_SRM_CHECK_FAIL)
+ hdcp->hdcp_state = HDCP_STATE_AUTH_FAIL_NOREAUTH;
+ }
hdcp_1x_update_auth_status(hdcp);
@@ -1751,6 +1873,7 @@ void hdcp_1x_deinit(void *input)
sysfs_remove_group(hdcp->init_data.sysfs_kobj,
&hdcp_1x_fs_attr_group);
+ hdcp1_client_unregister();
kfree(hdcp);
} /* hdcp_1x_deinit */
@@ -1853,6 +1976,44 @@ irq_not_handled:
return -EINVAL;
}
+static void hdcp_1x_srm_cb(void *input)
+{
+
+ struct hdcp_1x *hdcp = (struct hdcp_1x *)input;
+ int rc = 0;
+
+ if (!hdcp) {
+ pr_err("invalid input\n");
+ return;
+ }
+
+ rc = hdcp_1x_revoked_rcv_chk(hdcp);
+
+ if (rc) {
+ pr_err("receiver failed SRM check\n");
+ goto fail_noreauth;
+ }
+
+ /* If its not a repeater we are done */
+ if (hdcp->current_tp.ds_type != DS_REPEATER)
+ return;
+
+
+ /* Check the repeater KSV against SRM */
+ rc = hdcp_1x_revoked_rpt_chk(hdcp);
+ if (rc) {
+ pr_err("repeater failed SRM check\n");
+ goto fail_noreauth;
+ }
+
+ return;
+
+ fail_noreauth:
+ /* No reauth in case of SRM failure */
+ hdcp->hdcp_state = HDCP_STATE_AUTH_FAIL_NOREAUTH;
+ hdcp_1x_update_auth_status(hdcp);
+}
+
void *hdcp_1x_init(struct hdcp_init_data *init_data)
{
struct hdcp_1x *hdcp = NULL;
@@ -1865,6 +2026,10 @@ void *hdcp_1x_init(struct hdcp_init_data *init_data)
.off = hdcp_1x_off
};
+ static struct hdcp_client_ops client_ops = {
+ .srm_cb = hdcp_1x_srm_cb,
+ };
+
if (!init_data || !init_data->core_io || !init_data->qfprom_io ||
!init_data->mutex || !init_data->notify_status ||
!init_data->workq || !init_data->cb_data) {
@@ -1907,6 +2072,9 @@ void *hdcp_1x_init(struct hdcp_init_data *init_data)
init_completion(&hdcp->r0_checked);
init_completion(&hdcp->sink_r0_available);
+ /* Register client ctx and the srm_cb with hdcp lib */
+ hdcp1_client_register((void *)hdcp, &client_ops);
+
pr_debug("HDCP module initialized. HDCP_STATE=%s\n",
HDCP_STATE_NAME);
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.c b/drivers/video/fbdev/msm/mdss_hdmi_edid.c
index a49c5290753c..0c04fd35c0d5 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_edid.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.c
@@ -165,6 +165,10 @@ static bool hdmi_edid_is_mode_supported(struct hdmi_edid_ctrl *edid_ctrl,
pclk > edid_ctrl->init_data.max_pclk_khz)
return false;
+ if ((out_format == MDP_Y_CBCR_H2V2) &&
+ !edid_ctrl->init_data.yc420_support)
+ return false;
+
return true;
}
@@ -204,6 +208,7 @@ static int hdmi_edid_reset_parser(struct hdmi_edid_ctrl *edid_ctrl)
sizeof(edid_ctrl->spkr_alloc_data_block));
edid_ctrl->adb_size = 0;
edid_ctrl->sadb_size = 0;
+ edid_ctrl->basic_audio_supp = false;
hdmi_edid_set_video_resolution(edid_ctrl, edid_ctrl->default_vic, true);
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.h b/drivers/video/fbdev/msm/mdss_hdmi_edid.h
index af802bb45f89..63785e95bd59 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_edid.h
+++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.h
@@ -24,6 +24,7 @@ struct hdmi_edid_init_data {
struct kobject *kobj;
struct hdmi_util_ds_data ds_data;
u32 max_pclk_khz;
+ bool yc420_support;
u8 *buf;
u32 buf_size;
};
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c b/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c
index eadb90f3ce88..46e289b6dbd3 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, 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
@@ -463,6 +463,41 @@ static void hdmi_hdcp2p2_auth_failed(struct hdmi_hdcp2p2_ctrl *ctrl)
HDCP_STATE_AUTH_FAIL);
}
+static void hdmi_hdcp2p2_fail_noreauth(struct hdmi_hdcp2p2_ctrl *ctrl)
+{
+ if (!ctrl) {
+ pr_err("invalid input\n");
+ return;
+ }
+
+ atomic_set(&ctrl->auth_state, HDCP_STATE_AUTH_FAIL);
+
+ hdmi_hdcp2p2_ddc_disable(ctrl->init_data.cb_data);
+
+ /* notify hdmi tx about HDCP failure */
+ ctrl->init_data.notify_status(ctrl->init_data.cb_data,
+ HDCP_STATE_AUTH_FAIL_NOREAUTH);
+}
+
+static void hdmi_hdcp2p2_srm_cb(void *client_ctx)
+{
+ struct hdmi_hdcp2p2_ctrl *ctrl =
+ (struct hdmi_hdcp2p2_ctrl *)client_ctx;
+ struct hdcp_lib_wakeup_data cdata = {
+ HDCP_LIB_WKUP_CMD_INVALID};
+
+ if (!ctrl) {
+ pr_err("invalid input\n");
+ return;
+ }
+
+ cdata.context = ctrl->lib_ctx;
+ cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
+ hdmi_hdcp2p2_wakeup_lib(ctrl, &cdata);
+
+ hdmi_hdcp2p2_fail_noreauth(ctrl);
+}
+
static int hdmi_hdcp2p2_ddc_read_message(struct hdmi_hdcp2p2_ctrl *ctrl,
u8 *buf, int size, u32 timeout)
{
@@ -995,6 +1030,7 @@ void *hdmi_hdcp2p2_init(struct hdcp_init_data *init_data)
static struct hdcp_client_ops client_ops = {
.wakeup = hdmi_hdcp2p2_wakeup,
+ .srm_cb = hdmi_hdcp2p2_srm_cb,
};
static struct hdcp_txmtr_ops txmtr_ops;
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
index 5cb436261115..5d9e7072ae33 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
@@ -415,13 +415,13 @@ static inline void hdmi_tx_send_audio_notification(
struct hdmi_tx_ctrl *hdmi_ctrl, int val)
{
if (hdmi_ctrl && hdmi_ctrl->ext_audio_data.intf_ops.hpd) {
- u32 flags = 0;
+ u32 flags = 0;
- if (!hdmi_tx_is_dvi_mode(hdmi_ctrl))
- flags |= MSM_EXT_DISP_HPD_AUDIO;
+ if (!hdmi_tx_is_dvi_mode(hdmi_ctrl))
+ flags |= MSM_EXT_DISP_HPD_AUDIO;
- if (flags)
- hdmi_ctrl->ext_audio_data.intf_ops.hpd(
+ if (flags)
+ hdmi_ctrl->ext_audio_data.intf_ops.hpd(
hdmi_ctrl->ext_pdev,
hdmi_ctrl->ext_audio_data.type, val, flags);
}
@@ -450,8 +450,6 @@ static inline void hdmi_tx_ack_state(
!hdmi_tx_is_dvi_mode(hdmi_ctrl))
hdmi_ctrl->ext_audio_data.intf_ops.notify(hdmi_ctrl->ext_pdev,
val);
-
- hdmi_tx_send_audio_notification(hdmi_ctrl, val);
}
static struct hdmi_tx_ctrl *hdmi_tx_get_drvdata_from_panel_data(
@@ -1610,6 +1608,15 @@ static void hdmi_tx_hdcp_cb_work(struct work_struct *work)
}
break;
+ case HDCP_STATE_AUTH_FAIL_NOREAUTH:
+ if (hdmi_ctrl->hdcp1_use_sw_keys && hdmi_ctrl->hdcp14_present) {
+ if (hdmi_ctrl->auth_state && !hdmi_ctrl->hdcp22_present)
+ hdcp1_set_enc(false);
+ }
+
+ hdmi_ctrl->auth_state = false;
+
+ break;
case HDCP_STATE_AUTH_ENC_NONE:
hdmi_ctrl->enc_lvl = HDCP_STATE_AUTH_ENC_NONE;
@@ -1825,6 +1832,7 @@ static int hdmi_tx_init_edid(struct hdmi_tx_ctrl *hdmi_ctrl)
edid_init_data.kobj = hdmi_ctrl->kobj;
edid_init_data.ds_data = hdmi_ctrl->ds_data;
edid_init_data.max_pclk_khz = hdmi_ctrl->max_pclk_khz;
+ edid_init_data.yc420_support = true;
edid_data = hdmi_edid_init(&edid_init_data);
if (!edid_data) {
@@ -4045,6 +4053,7 @@ static int hdmi_tx_pre_evt_handle_update_fps(struct hdmi_tx_ctrl *hdmi_ctrl)
static int hdmi_tx_post_evt_handle_unblank(struct hdmi_tx_ctrl *hdmi_ctrl)
{
hdmi_tx_ack_state(hdmi_ctrl, true);
+ hdmi_tx_send_audio_notification(hdmi_ctrl, true);
return 0;
}
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_util.c b/drivers/video/fbdev/msm/mdss_hdmi_util.c
index 5bc46d8c8f92..1384c39d4c6f 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_util.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_util.c
@@ -632,6 +632,12 @@ const char *msm_hdmi_mode_2string(u32 mode)
case HDMI_RES_AR_16_10:
aspect_ratio = "16/10";
break;
+ case HDMI_RES_AR_64_27:
+ aspect_ratio = "64/27";
+ break;
+ case HDMI_RES_AR_256_135:
+ aspect_ratio = "256/135";
+ break;
default:
aspect_ratio = "???";
};
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index 54fb21a5f35d..632d73e909a3 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -5912,9 +5912,7 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg,
} else {
sctl_flush_bits = sctl->flush_bits;
}
- sctl->commit_in_progress = true;
}
- ctl->commit_in_progress = true;
ctl_flush_bits = ctl->flush_bits;
ATRACE_END("postproc_programming");
@@ -5928,6 +5926,9 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg,
MDP_COMMIT_STAGE_SETUP_DONE,
commit_cb->data);
ret = mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_READY);
+ ctl->commit_in_progress = true;
+ if (sctl)
+ sctl->commit_in_progress = true;
/*
* When wait for fence timed out, driver ignores the fences
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c
index ee338ba88c4d..5b9798e2c24e 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c
@@ -453,6 +453,13 @@ static u32 igc_limited[IGC_LUT_ENTRIES] = {
#define PP_FLAGS_DIRTY_SHARP 0x200
#define PP_FLAGS_DIRTY_PA_DITHER 0x400
+#define PP_EARLY_PROGRAM_DIRTY_MASK (PP_FLAGS_DIRTY_PCC | \
+ PP_FLAGS_DIRTY_ENHIST | PP_FLAGS_DIRTY_HIST_COL)
+#define PP_DEFERRED_PROGRAM_DIRTY_MASK (PP_FLAGS_DIRTY_IGC | \
+ PP_FLAGS_DIRTY_PGC | PP_FLAGS_DIRTY_ARGC | \
+ PP_FLAGS_DIRTY_GAMUT | PP_FLAGS_DIRTY_PA | \
+ PP_FLAGS_DIRTY_DITHER | PP_FLAGS_DIRTY_PA_DITHER)
+
/* Leave space for future features */
#define PP_FLAGS_RESUME_COMMIT 0x10000000
@@ -2860,10 +2867,15 @@ int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl,
}
}
+ if (info->pp_program_mask & PP_NORMAL_PROGRAM_MASK) {
+ mdss_pp_res->pp_disp_flags[disp_num] &=
+ ~PP_EARLY_PROGRAM_DIRTY_MASK;
+ }
if (info->pp_program_mask & PP_DEFER_PROGRAM_MASK) {
/* clear dirty flag */
if (disp_num < MDSS_BLOCK_DISP_NUM) {
- mdss_pp_res->pp_disp_flags[disp_num] = 0;
+ mdss_pp_res->pp_disp_flags[disp_num] &=
+ ~PP_DEFERRED_PROGRAM_DIRTY_MASK;
if (disp_num < mdata->nad_cfgs)
mdata->ad_cfgs[disp_num].reg_sts = 0;
}
diff --git a/drivers/video/fbdev/msm/msm_dba/adv7533.c b/drivers/video/fbdev/msm/msm_dba/adv7533.c
index bb3a5518d309..086946e806d2 100644
--- a/drivers/video/fbdev/msm/msm_dba/adv7533.c
+++ b/drivers/video/fbdev/msm/msm_dba/adv7533.c
@@ -761,7 +761,7 @@ static void adv7533_notify_clients(struct msm_dba_device_info *dev,
u32 adv7533_read_edid(struct adv7533 *pdata, u32 size, char *edid_buf)
{
u32 ret = 0, read_size = size / 2;
- u8 edid_addr;
+ u8 edid_addr = 0;
int ndx;
if (!pdata || !edid_buf)
@@ -1008,7 +1008,7 @@ end:
static void *adv7533_handle_hpd_intr(struct adv7533 *pdata)
{
int ret = 0;
- u8 hpd_state;
+ u8 hpd_state = 0;
u8 connected = 0, disconnected = 0;
if (!pdata) {
@@ -1040,7 +1040,8 @@ end:
static int adv7533_enable_interrupts(struct adv7533 *pdata, int interrupts)
{
int ret = 0;
- u8 reg_val, init_reg_val;
+ u8 reg_val = 0;
+ u8 init_reg_val;
if (!pdata) {
pr_err("%s: invalid input\n", __func__);
@@ -1086,7 +1087,8 @@ end:
static int adv7533_disable_interrupts(struct adv7533 *pdata, int interrupts)
{
int ret = 0;
- u8 reg_val, init_reg_val;
+ u8 reg_val = 0;
+ u8 init_reg_val;
if (!pdata) {
pr_err("%s: invalid input\n", __func__);
@@ -1652,7 +1654,7 @@ static int adv7533_hdcp_enable(void *client, bool hdcp_on,
bool enc_on, u32 flags)
{
int ret = -EINVAL;
- u8 reg_val;
+ u8 reg_val = 0;
struct adv7533 *pdata =
adv7533_get_platform_data(client);
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index a4d749665c9f..1865bcfa869b 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -378,10 +378,8 @@ static int unmap_grant_pages(struct grant_map *map, int offset, int pages)
}
range = 0;
while (range < pages) {
- if (map->unmap_ops[offset+range].handle == -1) {
- range--;
+ if (map->unmap_ops[offset+range].handle == -1)
break;
- }
range++;
}
err = __unmap_grant_pages(map, offset, range);
@@ -876,8 +874,10 @@ unlock_out:
out_unlock_put:
mutex_unlock(&priv->lock);
out_put_map:
- if (use_ptemod)
+ if (use_ptemod) {
map->vma = NULL;
+ unmap_grant_pages(map, 0, map->count);
+ }
gntdev_put_map(priv, map);
return err;
}
diff --git a/fs/sdcardfs/packagelist.c b/fs/sdcardfs/packagelist.c
index 66c6f8e72a02..947388294a07 100644
--- a/fs/sdcardfs/packagelist.c
+++ b/fs/sdcardfs/packagelist.c
@@ -659,6 +659,7 @@ static struct config_item *extension_details_make_item(struct config_group *grou
return ERR_PTR(-ENOMEM);
}
qstr_init(&extension_details->name, tmp);
+ extension_details->num = extensions_value->num;
ret = insert_ext_gid_entry(&extension_details->name, extensions_value->num);
if (ret) {
diff --git a/fs/super.c b/fs/super.c
index cbd4fab271d4..bc7ae0f327d0 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -497,7 +497,11 @@ retry:
hlist_add_head(&s->s_instances, &type->fs_supers);
spin_unlock(&sb_lock);
get_filesystem(type);
- register_shrinker(&s->s_shrink);
+ err = register_shrinker(&s->s_shrink);
+ if (err) {
+ deactivate_locked_super(s);
+ s = ERR_PTR(err);
+ }
return s;
}
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index 572b64a135b3..b148aa0e10f7 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -47,7 +47,7 @@
STATIC int xfs_qm_init_quotainos(xfs_mount_t *);
STATIC int xfs_qm_init_quotainfo(xfs_mount_t *);
-
+STATIC void xfs_qm_destroy_quotainos(xfs_quotainfo_t *qi);
STATIC void xfs_qm_dqfree_one(struct xfs_dquot *dqp);
/*
* We use the batch lookup interface to iterate over the dquots as it
@@ -660,9 +660,17 @@ xfs_qm_init_quotainfo(
qinf->qi_shrinker.scan_objects = xfs_qm_shrink_scan;
qinf->qi_shrinker.seeks = DEFAULT_SEEKS;
qinf->qi_shrinker.flags = SHRINKER_NUMA_AWARE;
- register_shrinker(&qinf->qi_shrinker);
+
+ error = register_shrinker(&qinf->qi_shrinker);
+ if (error)
+ goto out_free_inos;
+
return 0;
+out_free_inos:
+ mutex_destroy(&qinf->qi_quotaofflock);
+ mutex_destroy(&qinf->qi_tree_lock);
+ xfs_qm_destroy_quotainos(qinf);
out_free_lru:
list_lru_destroy(&qinf->qi_lru);
out_free_qinf:
@@ -671,7 +679,6 @@ out_free_qinf:
return error;
}
-
/*
* Gets called when unmounting a filesystem or when all quotas get
* turned off.
@@ -688,19 +695,8 @@ xfs_qm_destroy_quotainfo(
unregister_shrinker(&qi->qi_shrinker);
list_lru_destroy(&qi->qi_lru);
-
- if (qi->qi_uquotaip) {
- IRELE(qi->qi_uquotaip);
- qi->qi_uquotaip = NULL; /* paranoia */
- }
- if (qi->qi_gquotaip) {
- IRELE(qi->qi_gquotaip);
- qi->qi_gquotaip = NULL;
- }
- if (qi->qi_pquotaip) {
- IRELE(qi->qi_pquotaip);
- qi->qi_pquotaip = NULL;
- }
+ xfs_qm_destroy_quotainos(qi);
+ mutex_destroy(&qi->qi_tree_lock);
mutex_destroy(&qi->qi_quotaofflock);
kmem_free(qi);
mp->m_quotainfo = NULL;
@@ -1562,6 +1558,24 @@ error_rele:
}
STATIC void
+xfs_qm_destroy_quotainos(
+ xfs_quotainfo_t *qi)
+{
+ if (qi->qi_uquotaip) {
+ IRELE(qi->qi_uquotaip);
+ qi->qi_uquotaip = NULL; /* paranoia */
+ }
+ if (qi->qi_gquotaip) {
+ IRELE(qi->qi_gquotaip);
+ qi->qi_gquotaip = NULL;
+ }
+ if (qi->qi_pquotaip) {
+ IRELE(qi->qi_pquotaip);
+ qi->qi_pquotaip = NULL;
+ }
+}
+
+STATIC void
xfs_qm_dqfree_one(
struct xfs_dquot *dqp)
{
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index ae8d475a9385..43d5deb0c4cc 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -37,7 +37,7 @@ extern int migrate_page(struct address_space *,
struct page *, struct page *, enum migrate_mode);
extern int migrate_pages(struct list_head *l, new_page_t new, free_page_t free,
unsigned long private, enum migrate_mode mode, int reason);
-extern bool isolate_movable_page(struct page *page, isolate_mode_t mode);
+extern int isolate_movable_page(struct page *page, isolate_mode_t mode);
extern void putback_movable_page(struct page *page);
extern int migrate_prep(void);
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 86a7bdd61d1a..74bc08d82e14 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -13,6 +13,7 @@
#include <net/netns/generic.h>
#include <net/rtnetlink.h>
#include <net/lwtunnel.h>
+#include <net/dst_cache.h>
#if IS_ENABLED(CONFIG_IPV6)
#include <net/ipv6.h>
@@ -85,11 +86,6 @@ struct ip_tunnel_prl_entry {
struct rcu_head rcu_head;
};
-struct ip_tunnel_dst {
- struct dst_entry __rcu *dst;
- __be32 saddr;
-};
-
struct metadata_dst;
struct ip_tunnel {
@@ -108,7 +104,7 @@ struct ip_tunnel {
int tun_hlen; /* Precalculated header length */
int mlink;
- struct ip_tunnel_dst __percpu *dst_cache;
+ struct dst_cache dst_cache;
struct ip_tunnel_parm parms;
@@ -248,7 +244,6 @@ int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
struct ip_tunnel_parm *p);
void ip_tunnel_setup(struct net_device *dev, int net_id);
-void ip_tunnel_dst_reset_all(struct ip_tunnel *t);
int ip_tunnel_encap_setup(struct ip_tunnel *t,
struct ip_tunnel_encap *ipencap);
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index cd85a4a40d3a..65316c63ee90 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -132,6 +132,9 @@ struct module_instance_info {
/* Begin service specific definitions and structures */
#define ADSP_ADM_VERSION 0x00070000
+#define ADSP_ASM_API_VERSION_V2 2
+#define ADSP_ADM_API_VERSION_V3 3
+#define ADSP_AFE_API_VERSION_V3 3
#define ADM_CMD_SHARED_MEM_MAP_REGIONS 0x00010322
#define ADM_CMDRSP_SHARED_MEM_MAP_REGIONS 0x00010323
diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h
index b1c3b0baf4b3..5031e62beb17 100644
--- a/include/sound/q6afe-v2.h
+++ b/include/sound/q6afe-v2.h
@@ -368,4 +368,5 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port,
void afe_set_routing_callback(routing_cb);
int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats,
u16 port);
+int afe_get_svc_version(uint32_t service_id);
#endif /* __Q6AFE_V2_H__ */
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 0605755c246f..beafdf94b3b5 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1118,7 +1118,12 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
cpu_base = raw_cpu_ptr(&hrtimer_bases);
- if (clock_id == CLOCK_REALTIME && mode != HRTIMER_MODE_ABS)
+ /*
+ * POSIX magic: Relative CLOCK_REALTIME timers are not affected by
+ * clock modifications, so they needs to become CLOCK_MONOTONIC to
+ * ensure POSIX compliance.
+ */
+ if (clock_id == CLOCK_REALTIME && mode & HRTIMER_MODE_REL)
clock_id = CLOCK_MONOTONIC;
base = hrtimer_clockid_to_base(clock_id);
diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h
index b90e255c2a68..d2ecf0a09180 100644
--- a/lib/mpi/longlong.h
+++ b/lib/mpi/longlong.h
@@ -671,7 +671,23 @@ do { \
************** MIPS/64 **************
***************************************/
#if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64
-#if (__GNUC__ >= 5) || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 4)
+#if defined(__mips_isa_rev) && __mips_isa_rev >= 6
+/*
+ * GCC ends up emitting a __multi3 intrinsic call for MIPS64r6 with the plain C
+ * code below, so we special case MIPS64r6 until the compiler can do better.
+ */
+#define umul_ppmm(w1, w0, u, v) \
+do { \
+ __asm__ ("dmulu %0,%1,%2" \
+ : "=d" ((UDItype)(w0)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v))); \
+ __asm__ ("dmuhu %0,%1,%2" \
+ : "=d" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v))); \
+} while (0)
+#elif (__GNUC__ >= 5) || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 4)
#define umul_ppmm(w1, w0, u, v) \
do { \
typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \
diff --git a/mm/compaction.c b/mm/compaction.c
index faee4807b1d2..86687ec1d034 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -853,7 +853,7 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
locked = false;
}
- if (isolate_movable_page(page, isolate_mode))
+ if (!isolate_movable_page(page, isolate_mode))
goto isolate_success;
}
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 2e80a7bedef3..191b9eff7fc3 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1423,10 +1423,10 @@ int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn,
}
/*
- * Scan pfn range [start,end) to find movable/migratable pages (LRU pages
- * and hugepages). We scan pfn because it's much easier than scanning over
- * linked list. This function returns the pfn of the first found movable
- * page if it's found, otherwise 0.
+ * Scan pfn range [start,end) to find movable/migratable pages (LRU pages,
+ * non-lru movable pages and hugepages). We scan pfn because it's much
+ * easier than scanning over linked list. This function returns the pfn
+ * of the first found movable page if it's found, otherwise 0.
*/
static unsigned long scan_movable_pages(unsigned long start, unsigned long end)
{
@@ -1437,6 +1437,8 @@ static unsigned long scan_movable_pages(unsigned long start, unsigned long end)
page = pfn_to_page(pfn);
if (PageLRU(page))
return pfn;
+ if (__PageMovable(page))
+ return pfn;
if (PageHuge(page)) {
if (page_huge_active(page))
return pfn;
@@ -1480,22 +1482,24 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
if (!get_page_unless_zero(page))
continue;
/*
- * We can skip free pages. And we can only deal with pages on
- * LRU.
+ * We can skip free pages. And we can deal with pages on
+ * LRU and non-lru movable pages.
*/
- ret = isolate_lru_page(page);
+ if (PageLRU(page))
+ ret = isolate_lru_page(page);
+ else
+ ret = isolate_movable_page(page, ISOLATE_UNEVICTABLE);
if (!ret) { /* Success */
put_page(page);
list_add_tail(&page->lru, &source);
move_pages--;
- inc_zone_page_state(page, NR_ISOLATED_ANON +
- page_is_file_cache(page));
-
+ if (!__PageMovable(page))
+ inc_zone_page_state(page, NR_ISOLATED_ANON +
+ page_is_file_cache(page));
} else {
#ifdef CONFIG_DEBUG_VM
- printk(KERN_ALERT "removing pfn %lx from LRU failed\n",
- pfn);
- dump_page(page, "failed to remove from LRU");
+ pr_alert("failed to isolate pfn %lx\n", pfn);
+ dump_page(page, "isolation failed");
#endif
put_page(page);
/* Because we don't have big zone->lock. we should
diff --git a/mm/migrate.c b/mm/migrate.c
index a021071eceaf..921cf12b03ce 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -75,7 +75,7 @@ int migrate_prep_local(void)
return 0;
}
-bool isolate_movable_page(struct page *page, isolate_mode_t mode)
+int isolate_movable_page(struct page *page, isolate_mode_t mode)
{
struct address_space *mapping;
@@ -126,14 +126,14 @@ bool isolate_movable_page(struct page *page, isolate_mode_t mode)
__SetPageIsolated(page);
unlock_page(page);
- return true;
+ return 0;
out_no_isolated:
unlock_page(page);
out_putpage:
put_page(page);
out:
- return false;
+ return -EBUSY;
}
/* It should be called on page which is PG_movable */
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 3c3d8139f594..bad5f32a9765 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6652,8 +6652,9 @@ void set_pfnblock_flags_mask(struct page *page, unsigned long flags,
* If @count is not zero, it is okay to include less @count unmovable pages
*
* PageLRU check without isolation or lru_lock could race so that
- * MIGRATE_MOVABLE block might include unmovable pages. It means you can't
- * expect this function should be exact.
+ * MIGRATE_MOVABLE block might include unmovable pages. And __PageMovable
+ * check without lock_page also may miss some movable non-lru pages at
+ * race condition. So you can't expect this function should be exact.
*/
bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
bool skip_hwpoisoned_pages)
@@ -6709,6 +6710,9 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
if (skip_hwpoisoned_pages && PageHWPoison(page))
continue;
+ if (__PageMovable(page))
+ continue;
+
if (!PageLRU(page))
found++;
/*
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index c22920525e5d..154e7423cdeb 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -186,6 +186,7 @@ config NET_IPGRE_DEMUX
config NET_IP_TUNNEL
tristate
+ select DST_CACHE
default n
config NET_IPGRE
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 3a819d2cc04b..d35509212013 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -1527,10 +1527,7 @@ int ip_getsockopt(struct sock *sk, int level,
if (get_user(len, optlen))
return -EFAULT;
- lock_sock(sk);
- err = nf_getsockopt(sk, PF_INET, optname, optval,
- &len);
- release_sock(sk);
+ err = nf_getsockopt(sk, PF_INET, optname, optval, &len);
if (err >= 0)
err = put_user(len, optlen);
return err;
@@ -1562,9 +1559,7 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname,
if (get_user(len, optlen))
return -EFAULT;
- lock_sock(sk);
err = compat_nf_getsockopt(sk, PF_INET, optname, optval, &len);
- release_sock(sk);
if (err >= 0)
err = put_user(len, optlen);
return err;
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index c18245e05d26..80e2d1b0c08c 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -69,61 +69,6 @@ static unsigned int ip_tunnel_hash(__be32 key, __be32 remote)
IP_TNL_HASH_BITS);
}
-static void __tunnel_dst_set(struct ip_tunnel_dst *idst,
- struct dst_entry *dst, __be32 saddr)
-{
- struct dst_entry *old_dst;
-
- dst_clone(dst);
- old_dst = xchg((__force struct dst_entry **)&idst->dst, dst);
- dst_release(old_dst);
- idst->saddr = saddr;
-}
-
-static noinline void tunnel_dst_set(struct ip_tunnel *t,
- struct dst_entry *dst, __be32 saddr)
-{
- __tunnel_dst_set(raw_cpu_ptr(t->dst_cache), dst, saddr);
-}
-
-static void tunnel_dst_reset(struct ip_tunnel *t)
-{
- tunnel_dst_set(t, NULL, 0);
-}
-
-void ip_tunnel_dst_reset_all(struct ip_tunnel *t)
-{
- int i;
-
- for_each_possible_cpu(i)
- __tunnel_dst_set(per_cpu_ptr(t->dst_cache, i), NULL, 0);
-}
-EXPORT_SYMBOL(ip_tunnel_dst_reset_all);
-
-static struct rtable *tunnel_rtable_get(struct ip_tunnel *t,
- u32 cookie, __be32 *saddr)
-{
- struct ip_tunnel_dst *idst;
- struct dst_entry *dst;
-
- rcu_read_lock();
- idst = raw_cpu_ptr(t->dst_cache);
- dst = rcu_dereference(idst->dst);
- if (dst && !atomic_inc_not_zero(&dst->__refcnt))
- dst = NULL;
- if (dst) {
- if (!dst->obsolete || dst->ops->check(dst, cookie)) {
- *saddr = idst->saddr;
- } else {
- tunnel_dst_reset(t);
- dst_release(dst);
- dst = NULL;
- }
- }
- rcu_read_unlock();
- return (struct rtable *)dst;
-}
-
static bool ip_tunnel_key_match(const struct ip_tunnel_parm *p,
__be16 flags, __be32 key)
{
@@ -382,11 +327,12 @@ static int ip_tunnel_bind_dev(struct net_device *dev)
if (!IS_ERR(rt)) {
tdev = rt->dst.dev;
- tunnel_dst_set(tunnel, &rt->dst, fl4.saddr);
ip_rt_put(rt);
}
if (dev->type != ARPHRD_ETHER)
dev->flags |= IFF_POINTOPOINT;
+
+ dst_cache_reset(&tunnel->dst_cache);
}
if (!tdev && tunnel->parms.link)
@@ -733,7 +679,8 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0)
goto tx_error;
- rt = connected ? tunnel_rtable_get(tunnel, 0, &fl4.saddr) : NULL;
+ rt = connected ? dst_cache_get_ip4(&tunnel->dst_cache, &fl4.saddr) :
+ NULL;
if (!rt) {
rt = ip_route_output_key(tunnel->net, &fl4);
@@ -743,7 +690,8 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
goto tx_error;
}
if (connected)
- tunnel_dst_set(tunnel, &rt->dst, fl4.saddr);
+ dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst,
+ fl4.saddr);
}
if (rt->dst.dev == dev) {
@@ -841,7 +789,7 @@ static void ip_tunnel_update(struct ip_tunnel_net *itn,
if (set_mtu)
dev->mtu = mtu;
}
- ip_tunnel_dst_reset_all(t);
+ dst_cache_reset(&t->dst_cache);
netdev_state_change(dev);
}
@@ -980,7 +928,7 @@ static void ip_tunnel_dev_free(struct net_device *dev)
struct ip_tunnel *tunnel = netdev_priv(dev);
gro_cells_destroy(&tunnel->gro_cells);
- free_percpu(tunnel->dst_cache);
+ dst_cache_destroy(&tunnel->dst_cache);
free_percpu(dev->tstats);
free_netdev(dev);
}
@@ -1174,15 +1122,15 @@ int ip_tunnel_init(struct net_device *dev)
if (!dev->tstats)
return -ENOMEM;
- tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst);
- if (!tunnel->dst_cache) {
+ err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL);
+ if (err) {
free_percpu(dev->tstats);
- return -ENOMEM;
+ return err;
}
err = gro_cells_init(&tunnel->gro_cells, dev);
if (err) {
- free_percpu(tunnel->dst_cache);
+ dst_cache_destroy(&tunnel->dst_cache);
free_percpu(dev->tstats);
return err;
}
@@ -1212,7 +1160,7 @@ void ip_tunnel_uninit(struct net_device *dev)
if (itn->fb_tunnel_dev != dev)
ip_tunnel_del(itn, netdev_priv(dev));
- ip_tunnel_dst_reset_all(tunnel);
+ dst_cache_reset(&tunnel->dst_cache);
}
EXPORT_SYMBOL_GPL(ip_tunnel_uninit);
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index ede9d0e20538..8d11a034ca3f 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -1340,10 +1340,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname,
if (get_user(len, optlen))
return -EFAULT;
- lock_sock(sk);
- err = nf_getsockopt(sk, PF_INET6, optname, optval,
- &len);
- release_sock(sk);
+ err = nf_getsockopt(sk, PF_INET6, optname, optval, &len);
if (err >= 0)
err = put_user(len, optlen);
}
@@ -1382,10 +1379,7 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
if (get_user(len, optlen))
return -EFAULT;
- lock_sock(sk);
- err = compat_nf_getsockopt(sk, PF_INET6,
- optname, optval, &len);
- release_sock(sk);
+ err = compat_nf_getsockopt(sk, PF_INET6, optname, optval, &len);
if (err >= 0)
err = put_user(len, optlen);
}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index a165c871daa8..5842430a122a 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1612,6 +1612,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
}
rt->dst.flags |= DST_HOST;
+ rt->dst.input = ip6_input;
rt->dst.output = ip6_output;
atomic_set(&rt->dst.__refcnt, 1);
rt->rt6i_gateway = fl6->daddr;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index b7ea5eaa4fd1..d17d64edb718 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -475,7 +475,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
ipip6_tunnel_unlink(sitn, tunnel);
ipip6_tunnel_del_prl(tunnel, NULL);
}
- ip_tunnel_dst_reset_all(tunnel);
+ dst_cache_reset(&tunnel->dst_cache);
dev_put(dev);
}
@@ -1098,7 +1098,7 @@ static void ipip6_tunnel_update(struct ip_tunnel *t, struct ip_tunnel_parm *p)
t->parms.link = p->link;
ipip6_tunnel_bind_dev(t->dev);
}
- ip_tunnel_dst_reset_all(t);
+ dst_cache_reset(&t->dst_cache);
netdev_state_change(t->dev);
}
@@ -1129,7 +1129,7 @@ static int ipip6_tunnel_update_6rd(struct ip_tunnel *t,
t->ip6rd.relay_prefix = relay_prefix;
t->ip6rd.prefixlen = ip6rd->prefixlen;
t->ip6rd.relay_prefixlen = ip6rd->relay_prefixlen;
- ip_tunnel_dst_reset_all(t);
+ dst_cache_reset(&t->dst_cache);
netdev_state_change(t->dev);
return 0;
}
@@ -1283,7 +1283,7 @@ ipip6_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL);
break;
}
- ip_tunnel_dst_reset_all(t);
+ dst_cache_reset(&t->dst_cache);
netdev_state_change(dev);
break;
@@ -1344,7 +1344,7 @@ static void ipip6_dev_free(struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
- free_percpu(tunnel->dst_cache);
+ dst_cache_destroy(&tunnel->dst_cache);
free_percpu(dev->tstats);
free_netdev(dev);
}
@@ -1377,6 +1377,7 @@ static void ipip6_tunnel_setup(struct net_device *dev)
static int ipip6_tunnel_init(struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
+ int err;
tunnel->dev = dev;
tunnel->net = dev_net(dev);
@@ -1387,11 +1388,11 @@ static int ipip6_tunnel_init(struct net_device *dev)
if (!dev->tstats)
return -ENOMEM;
- tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst);
- if (!tunnel->dst_cache) {
+ err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL);
+ if (err) {
free_percpu(dev->tstats);
dev->tstats = NULL;
- return -ENOMEM;
+ return err;
}
return 0;
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 19322c047386..00a8cc572a22 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2877,7 +2877,7 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon)
}
if (beacon->probe_resp_len) {
new_beacon->probe_resp_len = beacon->probe_resp_len;
- beacon->probe_resp = pos;
+ new_beacon->probe_resp = pos;
memcpy(pos, beacon->probe_resp, beacon->probe_resp_len);
pos += beacon->probe_resp_len;
}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 7e88153a3350..aef0d41e9a9c 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -3368,6 +3368,8 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
}
return true;
case NL80211_IFTYPE_MESH_POINT:
+ if (ether_addr_equal(sdata->vif.addr, hdr->addr2))
+ return false;
if (multicast)
return true;
return ether_addr_equal(sdata->vif.addr, hdr->addr1);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index e9851198a850..df6a4b2d0728 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4445,7 +4445,7 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv
len = sizeof(int);
if (put_user(len, optlen))
return -EFAULT;
- if (copy_to_user(optval, &sctp_sk(sk)->autoclose, sizeof(int)))
+ if (copy_to_user(optval, &sctp_sk(sk)->autoclose, len))
return -EFAULT;
return 0;
}
@@ -5022,6 +5022,9 @@ copy_getaddrs:
err = -EFAULT;
goto out;
}
+ /* XXX: We should have accounted for sizeof(struct sctp_getaddrs) too,
+ * but we can't change it anymore.
+ */
if (put_user(bytes_copied, optlen))
err = -EFAULT;
out:
@@ -5458,7 +5461,7 @@ static int sctp_getsockopt_maxseg(struct sock *sk, int len,
params.assoc_id = 0;
} else if (len >= sizeof(struct sctp_assoc_value)) {
len = sizeof(struct sctp_assoc_value);
- if (copy_from_user(&params, optval, sizeof(params)))
+ if (copy_from_user(&params, optval, len))
return -EFAULT;
} else
return -EINVAL;
@@ -5627,7 +5630,9 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,
if (len < sizeof(struct sctp_authkeyid))
return -EINVAL;
- if (copy_from_user(&val, optval, sizeof(struct sctp_authkeyid)))
+
+ len = sizeof(struct sctp_authkeyid);
+ if (copy_from_user(&val, optval, len))
return -EFAULT;
asoc = sctp_id2assoc(sk, val.scact_assoc_id);
@@ -5639,7 +5644,6 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,
else
val.scact_keynumber = ep->active_key_id;
- len = sizeof(struct sctp_authkeyid);
if (put_user(len, optlen))
return -EFAULT;
if (copy_to_user(optval, &val, len))
@@ -5665,7 +5669,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
if (len < sizeof(struct sctp_authchunks))
return -EINVAL;
- if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks)))
+ if (copy_from_user(&val, optval, sizeof(val)))
return -EFAULT;
to = p->gauth_chunks;
@@ -5710,7 +5714,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
if (len < sizeof(struct sctp_authchunks))
return -EINVAL;
- if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks)))
+ if (copy_from_user(&val, optval, sizeof(val)))
return -EFAULT;
to = p->gauth_chunks;
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index 45a3f42b6f55..15134a0d662e 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -3701,6 +3701,7 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
struct msm_compr_audio *prtd;
int ret = 0;
struct msm_adsp_event_data *event_data = NULL;
+ uint64_t actual_payload_len = 0;
if (fe_id >= MSM_FRONTEND_DAI_MAX) {
pr_err("%s Received invalid fe_id %lu\n",
@@ -3738,6 +3739,16 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
goto done;
}
+ actual_payload_len = sizeof(struct msm_adsp_event_data) +
+ event_data->payload_len;
+ if (actual_payload_len >= U32_MAX) {
+ pr_err("%s payload length 0x%X exceeds limit",
+ __func__, event_data->payload_len);
+ ret = -EINVAL;
+ goto done;
+ }
+
+
if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >=
sizeof(ucontrol->value.bytes.data)) {
pr_err("%s param length=%d exceeds limit",
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index 292b3d04f7d5..27daa3a3f061 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -27,6 +27,7 @@
#include <sound/q6afe-v2.h>
#include <sound/msm-dai-q6-v2.h>
#include <sound/pcm_params.h>
+#include <sound/q6core.h>
#define MSM_DAI_PRI_AUXPCM_DT_DEV_ID 1
#define MSM_DAI_SEC_AUXPCM_DT_DEV_ID 2
@@ -6160,6 +6161,9 @@ static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai,
case 16:
cap_mask = 0xFFFF;
break;
+ case 32:
+ cap_mask = 0xFFFFFFFF;
+ break;
default:
dev_err(dai->dev, "%s: invalid slots %d\n",
__func__, slots);
@@ -6292,6 +6296,8 @@ static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai,
dev_get_drvdata(dai->dev);
struct afe_param_id_slot_mapping_cfg *slot_mapping =
&dai_data->port_cfg.slot_mapping;
+ struct afe_param_id_slot_mapping_cfg_v2 *slot_mapping_v2 =
+ &dai_data->port_cfg.slot_mapping_v2;
int i = 0;
dev_dbg(dai->dev, "%s: dai id = 0x%x\n", __func__, dai->id);
@@ -6329,23 +6335,49 @@ static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai,
case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
- if (!rx_slot) {
- dev_err(dai->dev, "%s: rx slot not found\n", __func__);
- return -EINVAL;
- }
- if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
- dev_err(dai->dev, "%s: invalid rx num %d\n", __func__,
- rx_num);
- return -EINVAL;
- }
+ if (afe_get_svc_version(APR_SVC_AFE) >=
+ ADSP_AFE_API_VERSION_V3) {
+ if (!rx_slot) {
+ dev_err(dai->dev, "%s: rx slot not found\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT_V2) {
+ dev_err(dai->dev, "%s: invalid rx num %d\n",
+ __func__,
+ rx_num);
+ return -EINVAL;
+ }
- for (i = 0; i < rx_num; i++)
- slot_mapping->offset[i] = rx_slot[i];
- for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
- slot_mapping->offset[i] =
- AFE_SLOT_MAPPING_OFFSET_INVALID;
+ for (i = 0; i < rx_num; i++)
+ slot_mapping_v2->offset[i] = rx_slot[i];
+ for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT_V2;
+ i++)
+ slot_mapping_v2->offset[i] =
+ AFE_SLOT_MAPPING_OFFSET_INVALID;
- slot_mapping->num_channel = rx_num;
+ slot_mapping_v2->num_channel = rx_num;
+ } else {
+ if (!rx_slot) {
+ dev_err(dai->dev, "%s: rx slot not found\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
+ dev_err(dai->dev, "%s: invalid rx num %d\n",
+ __func__,
+ rx_num);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < rx_num; i++)
+ slot_mapping->offset[i] = rx_slot[i];
+ for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
+ slot_mapping->offset[i] =
+ AFE_SLOT_MAPPING_OFFSET_INVALID;
+
+ slot_mapping->num_channel = rx_num;
+ }
break;
case AFE_PORT_ID_PRIMARY_TDM_TX:
case AFE_PORT_ID_PRIMARY_TDM_TX_1:
@@ -6379,23 +6411,49 @@ static int msm_dai_q6_tdm_set_channel_map(struct snd_soc_dai *dai,
case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
- if (!tx_slot) {
- dev_err(dai->dev, "%s: tx slot not found\n", __func__);
- return -EINVAL;
- }
- if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
- dev_err(dai->dev, "%s: invalid tx num %d\n", __func__,
- tx_num);
- return -EINVAL;
- }
+ if (afe_get_svc_version(APR_SVC_AFE) >=
+ ADSP_AFE_API_VERSION_V3) {
+ if (!tx_slot) {
+ dev_err(dai->dev, "%s: tx slot not found\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT_V2) {
+ dev_err(dai->dev, "%s: invalid tx num %d\n",
+ __func__,
+ tx_num);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < tx_num; i++)
+ slot_mapping_v2->offset[i] = tx_slot[i];
+ for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT_V2;
+ i++)
+ slot_mapping_v2->offset[i] =
+ AFE_SLOT_MAPPING_OFFSET_INVALID;
- for (i = 0; i < tx_num; i++)
- slot_mapping->offset[i] = tx_slot[i];
- for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
- slot_mapping->offset[i] =
- AFE_SLOT_MAPPING_OFFSET_INVALID;
+ slot_mapping_v2->num_channel = tx_num;
+ } else {
+ if (!tx_slot) {
+ dev_err(dai->dev, "%s: tx slot not found\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
+ dev_err(dai->dev, "%s: invalid tx num %d\n",
+ __func__,
+ tx_num);
+ return -EINVAL;
+ }
- slot_mapping->num_channel = tx_num;
+ for (i = 0; i < tx_num; i++)
+ slot_mapping->offset[i] = tx_slot[i];
+ for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
+ slot_mapping->offset[i] =
+ AFE_SLOT_MAPPING_OFFSET_INVALID;
+
+ slot_mapping->num_channel = tx_num;
+ }
break;
default:
dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
@@ -6419,6 +6477,8 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream,
&dai_data->port_cfg.tdm;
struct afe_param_id_slot_mapping_cfg *slot_mapping =
&dai_data->port_cfg.slot_mapping;
+ struct afe_param_id_slot_mapping_cfg_v2 *slot_mapping_v2 =
+ &dai_data->port_cfg.slot_mapping_v2;
struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header =
&dai_data->port_cfg.custom_tdm_header;
@@ -6426,7 +6486,7 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream,
__func__, dev_name(dai->dev));
if ((params_channels(params) == 0) ||
- (params_channels(params) > 8)) {
+ (params_channels(params) > 32)) {
dev_err(dai->dev, "%s: invalid param channels %d\n",
__func__, params_channels(params));
return -EINVAL;
@@ -6514,32 +6574,88 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream,
tdm->ctrl_data_out_enable,
tdm->ctrl_invert_sync_pulse,
tdm->ctrl_sync_data_delay);
+ if (afe_get_svc_version(APR_SVC_AFE) >=
+ ADSP_AFE_API_VERSION_V3) {
+ /*
+ * update slot mapping v2 config param
+ * NOTE: channels/rate/bitwidth are per stream property
+ */
+ slot_mapping_v2->bitwidth = dai_data->bitwidth;
- /*
- * update slot mapping config param
- * NOTE: channels/rate/bitwidth are per stream property
- */
- slot_mapping->bitwidth = dai_data->bitwidth;
-
- pr_debug("%s: SLOT MAPPING:\n"
+ pr_debug("%s: SLOT MAPPING_V2:\n"
"num_channel=%d bitwidth=%d data_align=0x%x\n",
__func__,
- slot_mapping->num_channel,
- slot_mapping->bitwidth,
- slot_mapping->data_align_type);
- pr_debug("%s: SLOT MAPPING:\n"
+ slot_mapping_v2->num_channel,
+ slot_mapping_v2->bitwidth,
+ slot_mapping_v2->data_align_type);
+ pr_debug("%s: SLOT MAPPING V2:\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",
+ "offset[4]=0x%x offset[5]=0x%x offset[6]=0x%x offset[7]=0x%x\n"
+ "offset[8]=0x%x offset[9]=0x%x offset[10]=0x%x offset[11]=0x%x\n"
+ "offset[12]=0x%x offset[13]=0x%x offset[14]=0x%x offset[15]=0x%x\n"
+ "offset[16]=0x%x offset[17]=0x%x offset[18]=0x%x offset[19]=0x%x\n"
+ "offset[20]=0x%x offset[21]=0x%x offset[22]=0x%x offset[23]=0x%x\n"
+ "offset[24]=0x%x offset[25]=0x%x offset[26]=0x%x offset[27]=0x%x\n"
+ "offset[28]=0x%x offset[29]=0x%x offset[30]=0x%x offset[31]=0x%x\n",
__func__,
- 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]);
+ slot_mapping_v2->offset[0],
+ slot_mapping_v2->offset[1],
+ slot_mapping_v2->offset[2],
+ slot_mapping_v2->offset[3],
+ slot_mapping_v2->offset[4],
+ slot_mapping_v2->offset[5],
+ slot_mapping_v2->offset[6],
+ slot_mapping_v2->offset[7],
+ slot_mapping_v2->offset[8],
+ slot_mapping_v2->offset[9],
+ slot_mapping_v2->offset[10],
+ slot_mapping_v2->offset[11],
+ slot_mapping_v2->offset[12],
+ slot_mapping_v2->offset[13],
+ slot_mapping_v2->offset[14],
+ slot_mapping_v2->offset[15],
+ slot_mapping_v2->offset[16],
+ slot_mapping_v2->offset[17],
+ slot_mapping_v2->offset[18],
+ slot_mapping_v2->offset[19],
+ slot_mapping_v2->offset[20],
+ slot_mapping_v2->offset[21],
+ slot_mapping_v2->offset[22],
+ slot_mapping_v2->offset[23],
+ slot_mapping_v2->offset[24],
+ slot_mapping_v2->offset[25],
+ slot_mapping_v2->offset[26],
+ slot_mapping_v2->offset[27],
+ slot_mapping_v2->offset[28],
+ slot_mapping_v2->offset[29],
+ slot_mapping_v2->offset[30],
+ slot_mapping_v2->offset[31]);
+ } else {
+ /*
+ * update slot mapping config param
+ * NOTE: channels/rate/bitwidth are per stream property
+ */
+ slot_mapping->bitwidth = dai_data->bitwidth;
+ pr_debug("%s: SLOT MAPPING:\n"
+ "num_channel=%d bitwidth=%d data_align=0x%x\n",
+ __func__,
+ slot_mapping->num_channel,
+ slot_mapping->bitwidth,
+ slot_mapping->data_align_type);
+ pr_debug("%s: 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__,
+ 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]);
+ }
/*
* update custom header config param
* NOTE: channels/rate/bitwidth are per playback stream property.
@@ -8121,6 +8237,9 @@ static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev)
dai_data->port_cfg.slot_mapping.minor_version =
AFE_API_VERSION_SLOT_MAPPING_CONFIG;
+ dai_data->port_cfg.slot_mapping_v2.minor_version =
+ AFE_API_VERSION_SLOT_MAPPING_CONFIG_V2;
+
/* CUSTOM TDM HEADER CFG */
custom_tdm_header = &dai_data->port_cfg.custom_tdm_header;
if (of_find_property(pdev->dev.of_node,
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
index 476789c67535..15f4b49749a1 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-loopback-v2.c
@@ -416,6 +416,12 @@ static int msm_pcm_prepare(struct snd_pcm_substream *substream)
dev_dbg(rtd->platform->dev, "%s: ASM loopback stream:%d\n",
__func__, substream->stream);
+
+ if (pcm->playback_start && pcm->capture_start) {
+ mutex_unlock(&pcm->lock);
+ return ret;
+ }
+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (!pcm->playback_start)
pcm->playback_start = 1;
@@ -424,7 +430,7 @@ static int msm_pcm_prepare(struct snd_pcm_substream *substream)
pcm->capture_start = 1;
}
- if (pcm->instance == 2) {
+ if (pcm->playback_start && pcm->capture_start) {
struct snd_soc_pcm_runtime *soc_pcm_rx =
pcm->playback_substream->private_data;
struct snd_soc_pcm_runtime *soc_pcm_tx =
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index 730452c611e0..f7c288d43b08 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -52,6 +52,7 @@ static struct audio_locks the_locks;
static const DECLARE_TLV_DB_LINEAR(msm_pcm_vol_gain, 0,
PCM_MASTER_VOL_MAX_STEPS);
+
struct snd_msm {
struct snd_card *card;
struct snd_pcm *pcm;
@@ -1084,6 +1085,7 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
struct msm_audio *prtd;
int ret = 0;
struct msm_adsp_event_data *event_data = NULL;
+ uint64_t actual_payload_len = 0;
if (!pdata) {
pr_err("%s pdata is NULL\n", __func__);
@@ -1120,6 +1122,15 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
goto done;
}
+ actual_payload_len = sizeof(struct msm_adsp_event_data) +
+ event_data->payload_len;
+ if (actual_payload_len >= U32_MAX) {
+ pr_err("%s payload length 0x%X exceeds limit",
+ __func__, event_data->payload_len);
+ ret = -EINVAL;
+ goto done;
+ }
+
if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >=
sizeof(ucontrol->value.bytes.data)) {
pr_err("%s param length=%d exceeds limit",
diff --git a/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c
index 18cac3424054..72dd751bb0d8 100644
--- a/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.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
@@ -645,6 +645,7 @@ static int msm_transcode_stream_cmd_put(struct snd_kcontrol *kcontrol,
struct msm_transcode_loopback *prtd;
int ret = 0;
struct msm_adsp_event_data *event_data = NULL;
+ uint64_t actual_payload_len = 0;
if (fe_id >= MSM_FRONTEND_DAI_MAX) {
pr_err("%s Received invalid fe_id %lu\n",
@@ -682,6 +683,16 @@ static int msm_transcode_stream_cmd_put(struct snd_kcontrol *kcontrol,
goto done;
}
+ actual_payload_len = sizeof(struct msm_adsp_event_data) +
+ event_data->payload_len;
+ if (actual_payload_len >= U32_MAX) {
+ pr_err("%s payload length 0x%X exceeds limit",
+ __func__, event_data->payload_len);
+ ret = -EINVAL;
+ goto done;
+ }
+
+
if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >=
sizeof(ucontrol->value.bytes.data)) {
pr_err("%s param length=%d exceeds limit",
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index 96580207e676..352ea9257832 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -28,6 +28,7 @@
#include <sound/audio_cal_utils.h>
#include <sound/adsp_err.h>
#include <linux/qdsp6v2/apr_tal.h>
+#include <sound/q6core.h>
#define WAKELOCK_TIMEOUT 5000
enum {
@@ -144,6 +145,39 @@ static int afe_get_cal_hw_delay(int32_t path,
struct audio_cal_hw_delay_entry *entry);
static int remap_cal_data(struct cal_block_data *cal_block, int cal_index);
+int afe_get_svc_version(uint32_t service_id)
+{
+ int ret = 0;
+ static int afe_cached_version;
+ size_t ver_size;
+ struct avcs_fwk_ver_info *ver_info = NULL;
+
+ if (service_id == AVCS_SERVICE_ID_ALL) {
+ pr_err("%s: Invalid service id: %d", __func__,
+ AVCS_SERVICE_ID_ALL);
+ return -EINVAL;
+ }
+
+ if (afe_cached_version != 0)
+ return afe_cached_version;
+
+ ver_size = sizeof(struct avcs_get_fwk_version) +
+ sizeof(struct avs_svc_api_info);
+ ver_info = kzalloc(ver_size, GFP_KERNEL);
+ if (ver_info == NULL)
+ return -ENOMEM;
+
+ ret = q6core_get_service_version(service_id, ver_info, ver_size);
+ if (ret < 0)
+ goto done;
+
+ ret = ver_info->services[0].api_version;
+ afe_cached_version = ret;
+done:
+ kfree(ver_info);
+ return ret;
+}
+
int afe_get_topology(int port_id)
{
int topology;
@@ -2447,6 +2481,36 @@ fail_cmd:
return ret;
}
+static int afe_send_slot_mapping_cfg_v2(
+ struct afe_param_id_slot_mapping_cfg_v2 *slot_mapping_cfg,
+ u16 port_id)
+{
+ struct param_hdr_v3 param_hdr = {0};
+ int ret = 0;
+
+ if (!slot_mapping_cfg) {
+ pr_err("%s: Error, no configuration data\n", __func__);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: port id: 0x%x\n", __func__, port_id);
+
+ param_hdr.module_id = AFE_MODULE_TDM;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG;
+ param_hdr.param_size = sizeof(struct afe_param_id_slot_mapping_cfg_v2);
+
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr,
+ (u8 *) slot_mapping_cfg);
+ if (ret < 0)
+ pr_err("%s: AFE send slot mapping for port 0x%x failed ret = %d\n",
+ __func__, port_id, ret);
+ return ret;
+}
+
+
int afe_send_slot_mapping_cfg(
struct afe_param_id_slot_mapping_cfg *slot_mapping_cfg,
u16 port_id)
@@ -2603,8 +2667,15 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port,
}
/* slot mapping is not need if there is only one group */
if (num_groups > 1) {
- ret = afe_send_slot_mapping_cfg(&tdm_port->slot_mapping,
- port_id);
+ if (afe_get_svc_version(APR_SVC_AFE) >=
+ ADSP_AFE_API_VERSION_V3)
+ ret = afe_send_slot_mapping_cfg_v2(
+ &tdm_port->slot_mapping_v2,
+ port_id);
+ else
+ ret = afe_send_slot_mapping_cfg(
+ &tdm_port->slot_mapping,
+ port_id);
if (ret < 0) {
pr_err("%s: afe send failed %d\n", __func__, ret);
goto fail_cmd;
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 201234a25bd9..9e14b341448a 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -47,6 +47,7 @@
#define FALSE 0x00
#define SESSION_MAX 9
#define ASM_MAX_CHANNELS 8
+
enum {
ASM_TOPOLOGY_CAL = 0,
ASM_CUSTOM_TOP_CAL,
@@ -286,6 +287,11 @@ static ssize_t audio_output_latency_dbgfs_read(struct file *file,
pr_err("%s: out_buffer is null\n", __func__);
return 0;
}
+ if (count < OUT_BUFFER_SIZE) {
+ pr_err("%s: read size %d exceeds buf size %zd\n", __func__,
+ OUT_BUFFER_SIZE, count);
+ return 0;
+ }
snprintf(out_buffer, OUT_BUFFER_SIZE, "%ld,%ld,%ld,%ld,%ld,%ld,",\
out_cold_tv.tv_sec, out_cold_tv.tv_usec, out_warm_tv.tv_sec,\
out_warm_tv.tv_usec, out_cont_tv.tv_sec, out_cont_tv.tv_usec);
@@ -339,6 +345,11 @@ static ssize_t audio_input_latency_dbgfs_read(struct file *file,
pr_err("%s: in_buffer is null\n", __func__);
return 0;
}
+ if (count < IN_BUFFER_SIZE) {
+ pr_err("%s: read size %d exceeds buf size %zd\n", __func__,
+ IN_BUFFER_SIZE, count);
+ return 0;
+ }
snprintf(in_buffer, IN_BUFFER_SIZE, "%ld,%ld,",\
in_cont_tv.tv_sec, in_cont_tv.tv_usec);
return simple_read_from_buffer(buf, IN_BUFFER_SIZE, ppos,
@@ -1159,7 +1170,9 @@ int q6asm_send_stream_cmd(struct audio_client *ac,
{
char *asm_params = NULL;
struct apr_hdr hdr;
- int sz, rc;
+ int rc;
+ uint32_t sz = 0;
+ uint64_t actual_sz = 0;
if (!data || !ac) {
pr_err("%s: %s is NULL\n", __func__,
@@ -1176,7 +1189,15 @@ int q6asm_send_stream_cmd(struct audio_client *ac,
goto done;
}
- sz = sizeof(struct apr_hdr) + data->payload_len;
+ actual_sz = sizeof(struct apr_hdr) + data->payload_len;
+ if (actual_sz > U32_MAX) {
+ pr_err("%s: payload size 0x%X exceeds limit\n",
+ __func__, data->payload_len);
+ rc = -EINVAL;
+ goto done;
+ }
+
+ sz = (uint32_t)actual_sz;
asm_params = kzalloc(sz, GFP_KERNEL);
if (!asm_params) {
rc = -ENOMEM;