summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/cache/msm_gladiator_erp_v2.txt20
-rw-r--r--Documentation/devicetree/bindings/fb/mdss-dsi.txt4
-rw-r--r--Documentation/devicetree/bindings/media/video/msm-jpegdma.txt31
-rw-r--r--arch/arm/boot/dts/qcom/msm-arm-smmu-cobalt.dtsi17
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-cdp.dtsi6
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi6
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt.dtsi9
-rw-r--r--arch/arm64/configs/msm-perf_defconfig4
-rw-r--r--arch/arm64/configs/msm_defconfig4
-rw-r--r--arch/arm64/configs/msmcortex-perf_defconfig3
-rw-r--r--arch/arm64/configs/msmcortex_defconfig5
-rw-r--r--arch/arm64/kernel/cpu_errata.c8
-rw-r--r--arch/um/include/asm/thread_info.h1
-rw-r--r--drivers/base/regmap/regmap-spmi.c4
-rw-r--r--drivers/clk/msm/clock-mmss-cobalt.c56
-rw-r--r--drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c107
-rw-r--r--drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h7
-rw-r--r--drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c85
-rw-r--r--drivers/platform/msm/msm_11ad/msm_11ad.c10
-rw-r--r--drivers/soc/qcom/Kconfig19
-rw-r--r--drivers/soc/qcom/Makefile1
-rw-r--r--drivers/soc/qcom/gladiator_erp_v2.c799
-rw-r--r--drivers/soc/qcom/glink.c18
-rw-r--r--drivers/usb/gadget/function/f_diag.c22
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c4
-rw-r--r--drivers/video/fbdev/msm/msm_mdss_io_8974.c11
-rw-r--r--include/dt-bindings/clock/msm-clocks-cobalt.h2
-rw-r--r--include/dt-bindings/clock/msm-clocks-hwio-cobalt.h2
-rw-r--r--include/uapi/media/msm_jpeg_dma.h8
29 files changed, 1183 insertions, 90 deletions
diff --git a/Documentation/devicetree/bindings/cache/msm_gladiator_erp_v2.txt b/Documentation/devicetree/bindings/cache/msm_gladiator_erp_v2.txt
new file mode 100644
index 000000000000..3c1c5c010ba1
--- /dev/null
+++ b/Documentation/devicetree/bindings/cache/msm_gladiator_erp_v2.txt
@@ -0,0 +1,20 @@
+* MSM Gladiator error reporting driver
+
+Required properties:
+- compatible: Should be "qcom,msm-gladiator-v2"
+- reg: I/O address Gladiator H/W block
+- reg-names: Should be "gladiator_base"
+- interrupts: Should contain the gladiator error interrupt number
+- clock-names: Should be "atb_clk"
+- clocks: Handles to clocks specified in "clock-names" property.
+
+Example:
+
+qcom,msm-gladiator-v2@b1c0000 {
+ compatible = "qcom,msm-gladiator-v2";
+ reg = <0xb1c0000 0xe000>;
+ reg-names = "gladiator_base";
+ interrupts = <0 34 0>;
+ clock-names = "atb_clk";
+ clocks = <&clock_gcc clk_qdss_clk>;
+}
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi.txt b/Documentation/devicetree/bindings/fb/mdss-dsi.txt
index e978646b54f4..50e12ccde14f 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dsi.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dsi.txt
@@ -84,8 +84,6 @@ Required properties:
- qcom,mdss-fb-map-prim: pHandle that specifies the framebuffer to which the
primary interface is mapped.
- qcom,mdss-mdp: pHandle that specifies the mdss-mdp device.
-- qcom,platform-regulator-settings: An array of length 7 or 5 that specifies the PHY
- regulator settings. It use 5 bytes for 8996 pll.
- qcom,platform-strength-ctrl: An array of length 2 or 10 that specifies the PHY
strengthCtrl settings. It use 10 bytes for 8996 pll.
- qcom,platform-lane-config: An array of length 45 or 20 that specifies the PHY
@@ -113,6 +111,8 @@ Optional properties:
controller. These pin configurations are installed in the pinctrl
device node. Refer to pinctrl-bindings.txt
- qcom,regulator-ldo-mode: Boolean to enable ldo mode for the dsi phy regulator
+- qcom,platform-regulator-settings: An array of length 7 or 5 that specifies the PHY
+ regulator settings. It use 5 bytes for 8996 pll.
- qcom,null-insertion-enabled: Boolean to enable NULL packet insertion
feature for DSI controller.
- qcom,dsi-irq-line: Boolean specifies if DSI has a different irq line than mdp.
diff --git a/Documentation/devicetree/bindings/media/video/msm-jpegdma.txt b/Documentation/devicetree/bindings/media/video/msm-jpegdma.txt
index 035bd6a659d6..6b05e7fa3084 100644
--- a/Documentation/devicetree/bindings/media/video/msm-jpegdma.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-jpegdma.txt
@@ -19,13 +19,18 @@ Required properties:
- clocks : clocks required for the device.
- qcom,clock-rates: should specify clock rates in Hz to each clocks
property defined.
+- Refer to "Documentation/devicetree/bindings/arm/msm/msm_bus.txt" for
+ below optional properties:
+ - qcom,msm-bus,name
+ - qcom,msm-bus,num-cases
+ - qcom,msm-bus,num-paths
+ - qcom,msm-bus,vectors-KBps
+
Optional properties:
-- qcom,qos-regs: relative address offsets of QoS registers.
-- qcom,qos-settings: QoS values to be written to QoS registers.
-- qcom,vbif-regs: relative address offsets of VBIF registers.
-- qcom,vbif-settings: VBIF values to be written to VBIF registers.
-- qcom,prefetch-regs: relative address offsets of MMU prefetch registers.
-- qcom,prefetch-settings: values to be written to MMU Prefetch registers.
+- qcom,vbif-reg-settings: relative address offsets and value pairs for VBIF registers.
+- qcom,qos-reg-settings: relative address offsets and value pairs for QoS registers.
+- qcom,prefetch-reg-settings: relative address offsets and value pairs for
+ MMU prefetch registers.
Example:
qcom,jpegdma@aa0000 {
@@ -53,10 +58,14 @@ Example:
<&clock_gcc clk_mmssnoc_axi_clk>,
<&clock_mmss clk_mmagic_camss_axi_clk>;
qcom,clock-rates = <266670000 0 0 0 0 0 0 0 0>,
- <400000000 0 0 0 0 0 0 0 0>;
- qcom,vbif-regs = <0x4 0xDC 0x124 0x160>;
- qcom,vbif-settings = <0x1 0x7 0x1 0x22222222>;
- qcom,prefetch-regs = <0x18C 0x1A0 0x1B0>;
- qcom,prefetch-settings = <0x11 0x31 0x31>;
+ qcom,vbif-reg-settings = <0x4 0x1>;
+ qcom,prefetch-reg-settings = <0x18c 0x11>,
+ <0x1a0 0x31>,
+ <0x1b0 0x31>;
+ qcom,msm-bus,name = "msm_camera_jpeg_dma";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps = <62 512 0 0>,
+ <62 512 666675 666675>;
status = "ok";
};
diff --git a/arch/arm/boot/dts/qcom/msm-arm-smmu-cobalt.dtsi b/arch/arm/boot/dts/qcom/msm-arm-smmu-cobalt.dtsi
index b0963faab701..f00395b081b8 100644
--- a/arch/arm/boot/dts/qcom/msm-arm-smmu-cobalt.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-arm-smmu-cobalt.dtsi
@@ -11,6 +11,7 @@
*/
#include <dt-bindings/clock/msm-clocks-cobalt.h>
+#include <dt-bindings/msm/msm-bus-ids.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
&soc {
@@ -150,12 +151,7 @@
"mmss_bimc_smmu_ahb_clk",
"mmss_bimc_smmu_axi_clk";
#clock-cells = <1>;
- /*
- * The iommu test framework requires at least one iommu
- * client to populate debugfs. The presence of a device
- * "qcom,smmu-v2" alone is not sufficient.
- */
- iommus = <&mmss_smmu 1>;
+ qcom,bus-master-id = <MSM_BUS_MNOC_BIMC_MAS>;
};
kgsl_smmu: arm,smmu-kgsl@5040000 {
@@ -177,8 +173,13 @@
<GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
vdd-supply = <&gdsc_gpu_cx>;
- clocks = <&clock_gcc clk_gcc_bimc_gfx_clk>;
- clock-name = "kgsl_smmu_clk";
+ clocks = <&clock_gcc clk_gcc_gpu_cfg_ahb_clk>,
+ <&clock_gcc clk_gcc_bimc_gfx_clk>,
+ <&clock_gcc clk_gcc_gpu_bimc_gfx_clk>;
+
+ clock-names = "gcc_gpu_cfg_ahb_clk",
+ "gcc_bimc_gfx_clk",
+ "gcc_gpu_bimc_gfx_clk";
#clock-cells = <1>;
};
};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-cdp.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-cdp.dtsi
index d3ce12850911..d2d6d85847a6 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-cdp.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-cdp.dtsi
@@ -84,3 +84,9 @@
status = "ok";
};
+
+&uartblsp2dm1 {
+ status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart_console_active>;
+};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi
index 0c77a1b4e417..885e71ac9c0f 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-mtp.dtsi
@@ -84,3 +84,9 @@
status = "ok";
};
+
+&uartblsp2dm1 {
+ status = "ok";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart_console_active>;
+};
diff --git a/arch/arm/boot/dts/qcom/msmcobalt.dtsi b/arch/arm/boot/dts/qcom/msmcobalt.dtsi
index 01f0e6a4fd2a..36a7eb9a2469 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt.dtsi
@@ -823,6 +823,15 @@
qcom,config-reg = <0x179d1434>;
};
+ qcom,msm-gladiator-v2@17900000 {
+ compatible = "qcom,msm-gladiator-v2";
+ reg = <0x17900000 0xe000>;
+ reg-names = "gladiator_base";
+ interrupts = <0 22 0>;
+ clock-names = "atb_clk";
+ clocks = <&clock_gcc clk_qdss_clk>;
+ };
+
qcom,smem@86000000 {
compatible = "qcom,smem";
reg = <0x86000000 0x200000>,
diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig
index 5791959408bd..bf58ebcdcf74 100644
--- a/arch/arm64/configs/msm-perf_defconfig
+++ b/arch/arm64/configs/msm-perf_defconfig
@@ -208,6 +208,9 @@ CONFIG_NET_EMATCH_U32=y
CONFIG_NET_EMATCH_META=y
CONFIG_NET_EMATCH_TEXT=y
CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_GACT=y
+CONFIG_NET_ACT_MIRRED=y
+CONFIG_NET_ACT_SKBEDIT=y
CONFIG_RMNET_DATA=y
CONFIG_RMNET_DATA_FC=y
CONFIG_RMNET_DATA_DEBUG_PKT=y
@@ -256,6 +259,7 @@ CONFIG_DM_REQ_CRYPT=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
CONFIG_NETDEVICES=y
+CONFIG_BONDING=y
CONFIG_TUN=y
CONFIG_VIRTIO_NET=y
CONFIG_SKY2=y
diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig
index deffb3241e12..9e58c254e1a8 100644
--- a/arch/arm64/configs/msm_defconfig
+++ b/arch/arm64/configs/msm_defconfig
@@ -210,6 +210,9 @@ CONFIG_NET_EMATCH_U32=y
CONFIG_NET_EMATCH_META=y
CONFIG_NET_EMATCH_TEXT=y
CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_GACT=y
+CONFIG_NET_ACT_MIRRED=y
+CONFIG_NET_ACT_SKBEDIT=y
CONFIG_RMNET_DATA=y
CONFIG_RMNET_DATA_FC=y
CONFIG_RMNET_DATA_DEBUG_PKT=y
@@ -259,6 +262,7 @@ CONFIG_DM_REQ_CRYPT=y
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=y
CONFIG_NETDEVICES=y
+CONFIG_BONDING=y
CONFIG_TUN=y
CONFIG_VIRTIO_NET=y
CONFIG_SKY2=y
diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig
index 0b075acbc8e4..8c5f26f42398 100644
--- a/arch/arm64/configs/msmcortex-perf_defconfig
+++ b/arch/arm64/configs/msmcortex-perf_defconfig
@@ -382,6 +382,8 @@ CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_EFI=y
CONFIG_DMADEVICES=y
CONFIG_QCOM_BAM_DMA=y
+CONFIG_UIO=y
+CONFIG_UIO_MSM_SHAREDMEM=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_MMIO=y
@@ -439,6 +441,7 @@ CONFIG_MEM_SHARE_QMI_SERVICE=y
CONFIG_EXTCON=y
CONFIG_PWM=y
CONFIG_PWM_QPNP=y
+CONFIG_ARM_GIC_V3_ACL=y
CONFIG_PHY_XGENE=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig
index 9c571aab8fc8..a7860f50757f 100644
--- a/arch/arm64/configs/msmcortex_defconfig
+++ b/arch/arm64/configs/msmcortex_defconfig
@@ -401,6 +401,8 @@ CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_EFI=y
CONFIG_DMADEVICES=y
CONFIG_QCOM_BAM_DMA=y
+CONFIG_UIO=y
+CONFIG_UIO_MSM_SHAREDMEM=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_MMIO=y
@@ -449,6 +451,8 @@ CONFIG_QCOM_SCM_XPU=y
CONFIG_QCOM_WATCHDOG_V2=y
CONFIG_QCOM_MEMORY_DUMP_V2=y
CONFIG_ICNSS=y
+CONFIG_MSM_GLADIATOR_ERP_V2=y
+CONFIG_PANIC_ON_GLADIATOR_ERROR_V2=y
CONFIG_MSM_GLADIATOR_HANG_DETECT=y
CONFIG_MSM_CORE_HANG_DETECT=y
CONFIG_MSM_BOOT_STATS=y
@@ -464,6 +468,7 @@ CONFIG_MEM_SHARE_QMI_SERVICE=y
CONFIG_EXTCON=y
CONFIG_PWM=y
CONFIG_PWM_QPNP=y
+CONFIG_ARM_GIC_V3_ACL=y
CONFIG_PHY_XGENE=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index feb6b4efa641..34aa4b3b47e9 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -24,6 +24,8 @@
#define MIDR_CORTEX_A53 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
#define MIDR_CORTEX_A57 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
#define MIDR_THUNDERX MIDR_CPU_PART(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
+#define MIDR_KRYO2XX_SILVER \
+ MIDR_CPU_PART(ARM_CPU_IMP_QCOM, ARM_CPU_PART_KRYO2XX_SILVER)
#define CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
MIDR_ARCHITECTURE_MASK)
@@ -91,6 +93,12 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
.capability = ARM64_WORKAROUND_845719,
MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x04),
},
+ {
+ /* Kryo2xx Silver rAp4 */
+ .desc = "Kryo2xx Silver erratum 845719",
+ .capability = ARM64_WORKAROUND_845719,
+ MIDR_RANGE(MIDR_KRYO2XX_SILVER, 0xA00004, 0xA00004),
+ },
#endif
#ifdef CONFIG_CAVIUM_ERRATUM_23154
{
diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h
index 53968aaf76f9..c51ee50de738 100644
--- a/arch/um/include/asm/thread_info.h
+++ b/arch/um/include/asm/thread_info.h
@@ -62,6 +62,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_SYSCALL_AUDIT 6
#define TIF_RESTORE_SIGMASK 7
#define TIF_NOTIFY_RESUME 8
+#define TIF_MM_RELEASED 9
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
diff --git a/drivers/base/regmap/regmap-spmi.c b/drivers/base/regmap/regmap-spmi.c
index 7e58f6560399..156751544c02 100644
--- a/drivers/base/regmap/regmap-spmi.c
+++ b/drivers/base/regmap/regmap-spmi.c
@@ -1,7 +1,7 @@
/*
* Register map access API - SPMI support
*
- * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013,2016 The Linux Foundation. All rights reserved.
*
* Based on regmap-i2c.c:
* Copyright 2011 Wolfson Microelectronics plc
@@ -142,7 +142,7 @@ static int regmap_spmi_ext_read(void *context,
while (val_size) {
len = min_t(size_t, val_size, 8);
- err = spmi_ext_register_readl(context, addr, val, val_size);
+ err = spmi_ext_register_readl(context, addr, val, len);
if (err)
goto err_out;
diff --git a/drivers/clk/msm/clock-mmss-cobalt.c b/drivers/clk/msm/clock-mmss-cobalt.c
index ba9196b7abc9..777571bb7c96 100644
--- a/drivers/clk/msm/clock-mmss-cobalt.c
+++ b/drivers/clk/msm/clock-mmss-cobalt.c
@@ -1746,13 +1746,36 @@ static struct branch_clk mmss_mdss_byte0_clk = {
},
};
+static struct div_clk mmss_mdss_byte0_intf_div_clk = {
+ .offset = MMSS_MDSS_BYTE0_INTF_DIV,
+ .mask = 0x3,
+ .shift = 0,
+ .data = {
+ .min_div = 1,
+ .max_div = 4,
+ },
+ .base = &virt_base,
+ /*
+ * NOTE: Op does not work for div-3. Current assumption is that div-3
+ * is not a recommended setting for this divider.
+ */
+ .ops = &postdiv_reg_ops,
+ .c = {
+ .dbg_name = "mmss_mdss_byte0_intf_div_clk",
+ .parent = &byte0_clk_src.c,
+ .ops = &clk_ops_slave_div,
+ .flags = CLKFLAG_NO_RATE_CACHE,
+ CLK_INIT(mmss_mdss_byte0_intf_div_clk.c),
+ },
+};
+
static struct branch_clk mmss_mdss_byte0_intf_clk = {
.cbcr_reg = MMSS_MDSS_BYTE0_INTF_CBCR,
- .has_sibling = 1,
+ .has_sibling = 0,
.base = &virt_base,
.c = {
.dbg_name = "mmss_mdss_byte0_intf_clk",
- .parent = &byte0_clk_src.c,
+ .parent = &mmss_mdss_byte0_intf_div_clk.c,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_byte0_intf_clk.c),
},
@@ -1770,13 +1793,36 @@ static struct branch_clk mmss_mdss_byte1_clk = {
},
};
+static struct div_clk mmss_mdss_byte1_intf_div_clk = {
+ .offset = MMSS_MDSS_BYTE1_INTF_DIV,
+ .mask = 0x3,
+ .shift = 0,
+ .data = {
+ .min_div = 1,
+ .max_div = 4,
+ },
+ .base = &virt_base,
+ /*
+ * NOTE: Op does not work for div-3. Current assumption is that div-3
+ * is not a recommended setting for this divider.
+ */
+ .ops = &postdiv_reg_ops,
+ .c = {
+ .dbg_name = "mmss_mdss_byte1_intf_div_clk",
+ .parent = &byte1_clk_src.c,
+ .ops = &clk_ops_slave_div,
+ .flags = CLKFLAG_NO_RATE_CACHE,
+ CLK_INIT(mmss_mdss_byte1_intf_div_clk.c),
+ },
+};
+
static struct branch_clk mmss_mdss_byte1_intf_clk = {
.cbcr_reg = MMSS_MDSS_BYTE1_INTF_CBCR,
- .has_sibling = 1,
+ .has_sibling = 0,
.base = &virt_base,
.c = {
.dbg_name = "mmss_mdss_byte1_intf_clk",
- .parent = &byte1_clk_src.c,
+ .parent = &mmss_mdss_byte1_intf_div_clk.c,
.ops = &clk_ops_branch,
CLK_INIT(mmss_mdss_byte1_intf_clk.c),
},
@@ -2406,8 +2452,10 @@ static struct clk_lookup msm_clocks_mmss_cobalt[] = {
CLK_LIST(mmss_mdss_ahb_clk),
CLK_LIST(mmss_mdss_axi_clk),
CLK_LIST(mmss_mdss_byte0_clk),
+ CLK_LIST(mmss_mdss_byte0_intf_div_clk),
CLK_LIST(mmss_mdss_byte0_intf_clk),
CLK_LIST(mmss_mdss_byte1_clk),
+ CLK_LIST(mmss_mdss_byte0_intf_div_clk),
CLK_LIST(mmss_mdss_byte1_intf_clk),
CLK_LIST(mmss_mdss_dp_aux_clk),
CLK_LIST(mmss_mdss_dp_gtc_clk),
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
index 034789880a1f..2f84ff95a38a 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
@@ -17,6 +17,8 @@
#include <linux/ion.h>
#include <linux/msm_ion.h>
#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/compat.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-event.h>
#include <media/videobuf2-core.h>
@@ -70,18 +72,31 @@ static struct msm_jpegdma_format formats[] = {
.planes[1] = JPEGDMA_PLANE_TYPE_CBCR,
},
{
- .name = "YUV 4:2:0 planar, YCbCr",
- .fourcc = V4L2_PIX_FMT_YUV420,
+ .name = "YVU 4:2:0 planar, YCrCb",
+ .fourcc = V4L2_PIX_FMT_YVU420,
.depth = 12,
.num_planes = 3,
- .colplane_h = 2,
- .colplane_v = 2,
+ .colplane_h = 1,
+ .colplane_v = 4,
.h_align = 2,
.v_align = 2,
.planes[0] = JPEGDMA_PLANE_TYPE_Y,
.planes[1] = JPEGDMA_PLANE_TYPE_CR,
.planes[2] = JPEGDMA_PLANE_TYPE_CB,
},
+ {
+ .name = "YUV 4:2:0 planar, YCbCr",
+ .fourcc = V4L2_PIX_FMT_YUV420,
+ .depth = 12,
+ .num_planes = 3,
+ .colplane_h = 1,
+ .colplane_v = 4,
+ .h_align = 2,
+ .v_align = 2,
+ .planes[0] = JPEGDMA_PLANE_TYPE_Y,
+ .planes[1] = JPEGDMA_PLANE_TYPE_CB,
+ .planes[2] = JPEGDMA_PLANE_TYPE_CR,
+ },
};
/*
@@ -196,7 +211,8 @@ static void msm_jpegdma_align_format(struct v4l2_format *f, int format_idx)
if (formats[format_idx].num_planes > 1)
for (i = 1; i < formats[format_idx].num_planes; i++)
size_image += (f->fmt.pix.bytesperline *
- (f->fmt.pix.height / formats[format_idx].colplane_v));
+ (f->fmt.pix.height /
+ formats[format_idx].colplane_v));
f->fmt.pix.sizeimage = size_image;
f->fmt.pix.field = V4L2_FIELD_NONE;
@@ -250,6 +266,9 @@ static int msm_jpegdma_update_hw_config(struct jpegdma_ctx *ctx)
size.fps = ctx->timeperframe.denominator /
ctx->timeperframe.numerator;
+ size.in_offset = ctx->in_offset;
+ size.out_offset = ctx->out_offset;
+
size.format = formats[ctx->format_idx];
msm_jpegdma_fill_size_from_ctx(ctx, &size);
@@ -364,7 +383,9 @@ static void msm_jpegdma_stop_streaming(struct vb2_queue *q)
dev_err(ctx->jdma_device->dev, "Ctx wait timeout\n");
ret = -ETIME;
}
- msm_jpegdma_hw_put(ctx->jdma_device);
+
+ if (ctx->jdma_device->ref_count > 0)
+ msm_jpegdma_hw_put(ctx->jdma_device);
}
/* Videobuf2 queue callbacks. */
@@ -388,13 +409,29 @@ static void *msm_jpegdma_get_userptr(void *alloc_ctx,
{
struct msm_jpegdma_device *dma = alloc_ctx;
struct msm_jpegdma_buf_handle *buf;
+ struct msm_jpeg_dma_buff __user *up_buff = compat_ptr(vaddr);
+ struct msm_jpeg_dma_buff kp_buff;
int ret;
+ if (!access_ok(VERIFY_READ, up_buff,
+ sizeof(struct msm_jpeg_dma_buff)) ||
+ get_user(kp_buff.fd, &up_buff->fd)) {
+ dev_err(dma->dev, "Error getting user data\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ if (!access_ok(VERIFY_WRITE, up_buff,
+ sizeof(struct msm_jpeg_dma_buff)) ||
+ put_user(kp_buff.fd, &up_buff->fd)) {
+ dev_err(dma->dev, "Error putting user data\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
buf = kzalloc(sizeof(*buf), GFP_KERNEL);
if (!buf)
return ERR_PTR(-ENOMEM);
- ret = msm_jpegdma_hw_map_buffer(dma, vaddr, buf);
+ ret = msm_jpegdma_hw_map_buffer(dma, kp_buff.fd, buf);
if (ret < 0 || buf->size < size)
goto error;
@@ -482,7 +519,6 @@ static int msm_jpegdma_open(struct file *file)
if (!ctx)
return -ENOMEM;
- mutex_init(&ctx->lock);
ctx->jdma_device = device;
dev_dbg(ctx->jdma_device->dev, "Jpeg v4l2 dma open\n");
/* Set ctx defaults */
@@ -531,7 +567,9 @@ static int msm_jpegdma_release(struct file *file)
struct jpegdma_ctx *ctx = msm_jpegdma_ctx_from_fh(file->private_data);
/* release all the resources */
- msm_jpegdma_hw_put(ctx->jdma_device);
+ if (ctx->jdma_device->ref_count > 0)
+ msm_jpegdma_hw_put(ctx->jdma_device);
+
atomic_set(&ctx->active, 0);
complete_all(&ctx->completion);
v4l2_m2m_ctx_release(ctx->m2m_ctx);
@@ -774,16 +812,46 @@ static int msm_jpegdma_qbuf(struct file *file, void *fh,
struct v4l2_buffer *buf)
{
struct jpegdma_ctx *ctx = msm_jpegdma_ctx_from_fh(fh);
+ struct msm_jpeg_dma_buff __user *up_buff = compat_ptr(buf->m.userptr);
+ struct msm_jpeg_dma_buff kp_buff;
int ret;
- mutex_lock(&ctx->lock);
+ if (!access_ok(VERIFY_READ, up_buff,
+ sizeof(struct msm_jpeg_dma_buff)) ||
+ get_user(kp_buff.fd, &up_buff->fd) ||
+ get_user(kp_buff.offset, &up_buff->offset)) {
+ dev_err(ctx->jdma_device->dev, "Error getting user data\n");
+ return -EFAULT;
+ }
+
+ if (!access_ok(VERIFY_WRITE, up_buff,
+ sizeof(struct msm_jpeg_dma_buff)) ||
+ put_user(kp_buff.fd, &up_buff->fd) ||
+ put_user(kp_buff.offset, &up_buff->offset)) {
+ dev_err(ctx->jdma_device->dev, "Error putting user data\n");
+ return -EFAULT;
+ }
+
+ switch (buf->type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ ctx->in_offset = kp_buff.offset;
+ dev_dbg(ctx->jdma_device->dev, "input buf offset %d\n",
+ ctx->in_offset);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ ctx->out_offset = kp_buff.offset;
+ dev_dbg(ctx->jdma_device->dev, "output buf offset %d\n",
+ ctx->out_offset);
+ break;
+ }
+
+ if (atomic_read(&ctx->active))
+ ret = msm_jpegdma_update_hw_config(ctx);
ret = v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
if (ret < 0)
dev_err(ctx->jdma_device->dev, "QBuf fail\n");
- mutex_unlock(&ctx->lock);
-
return ret;
}
@@ -816,14 +884,10 @@ static int msm_jpegdma_streamon(struct file *file,
if (!msm_jpegdma_config_ok(ctx))
return -EINVAL;
- mutex_lock(&ctx->lock);
-
ret = v4l2_m2m_streamon(file, ctx->m2m_ctx, buf_type);
if (ret < 0)
dev_err(ctx->jdma_device->dev, "Stream on fail\n");
- mutex_unlock(&ctx->lock);
-
return ret;
}
@@ -954,14 +1018,10 @@ static int msm_jpegdma_s_crop(struct file *file, void *fh,
if (crop->c.top % formats[ctx->format_idx].v_align)
return -EINVAL;
- mutex_lock(&ctx->lock);
-
ctx->crop = crop->c;
if (atomic_read(&ctx->active))
ret = msm_jpegdma_update_hw_config(ctx);
- mutex_unlock(&ctx->lock);
-
return ret;
}
@@ -1004,7 +1064,7 @@ static int msm_jpegdma_s_parm(struct file *file, void *fh,
return -EINVAL;
if (!a->parm.output.timeperframe.numerator ||
- !a->parm.output.timeperframe.denominator)
+ !a->parm.output.timeperframe.denominator)
return -EINVAL;
/* Frame rate is not supported during streaming */
@@ -1138,16 +1198,15 @@ void msm_jpegdma_isr_processing_done(struct msm_jpegdma_device *dma)
struct jpegdma_ctx *ctx;
mutex_lock(&dma->lock);
+
ctx = v4l2_m2m_get_curr_priv(dma->m2m_dev);
if (ctx) {
- mutex_lock(&ctx->lock);
ctx->plane_idx++;
if (ctx->plane_idx >= formats[ctx->format_idx].num_planes) {
src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
if (src_buf == NULL || dst_buf == NULL) {
dev_err(ctx->jdma_device->dev, "Error, buffer list empty\n");
- mutex_unlock(&ctx->lock);
mutex_unlock(&dma->lock);
return;
}
@@ -1163,13 +1222,11 @@ void msm_jpegdma_isr_processing_done(struct msm_jpegdma_device *dma)
src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
if (src_buf == NULL || dst_buf == NULL) {
dev_err(ctx->jdma_device->dev, "Error, buffer list empty\n");
- mutex_unlock(&ctx->lock);
mutex_unlock(&dma->lock);
return;
}
msm_jpegdma_process_buffers(ctx, src_buf, dst_buf);
}
- mutex_unlock(&ctx->lock);
}
mutex_unlock(&dma->lock);
}
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h
index adb8b94f098c..0a9cab6e4322 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h
+++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.h
@@ -22,7 +22,7 @@
/* Max number of clocks defined in device tree */
#define MSM_JPEGDMA_MAX_CLK 10
/* Core clock index */
-#define MSM_JPEGDMA_CORE_CLK 0
+#define MSM_JPEGDMA_CORE_CLK "core_clk"
/* Max number of regulators defined in device tree */
#define MSM_JPEGDMA_MAX_REGULATOR_NUM 3
/* Max number of planes supported */
@@ -109,6 +109,8 @@ struct msm_jpegdma_size_config {
struct msm_jpegdma_size out_size;
struct msm_jpegdma_format format;
unsigned int fps;
+ unsigned int in_offset;
+ unsigned int out_offset;
};
/*
@@ -252,7 +254,6 @@ struct msm_jpegdma_buf_handle {
* @format_idx: Current format index.
*/
struct jpegdma_ctx {
- struct mutex lock;
struct msm_jpegdma_device *jdma_device;
atomic_t active;
struct completion completion;
@@ -262,6 +263,8 @@ struct jpegdma_ctx {
struct v4l2_format format_out;
struct v4l2_rect crop;
struct v4l2_fract timeperframe;
+ unsigned int in_offset;
+ unsigned int out_offset;
unsigned int config_idx;
struct msm_jpegdma_plane_config plane_config[MSM_JPEGDMA_MAX_CONFIGS];
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c
index 41086936a0b1..e994ce1b8b32 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_hw.c
@@ -166,6 +166,23 @@ static int msm_jpegdma_hw_get_num_pipes(struct msm_jpegdma_device *dma)
}
/*
+ * msm_jpegdma_hw_get_clock_index - Get clock index by name
+ * @dma: Pointer to dma device.
+ * @clk_name: clock name.
+ */
+int msm_jpegdma_hw_get_clock_index(struct msm_jpegdma_device *dma,
+ const char *clk_name)
+{
+ uint32_t i = 0;
+
+ for (i = 0; i < dma->num_clk; i++) {
+ if (!strcmp(clk_name, dma->jpeg_clk_info[i].clk_name))
+ return i;
+ }
+ return -EINVAL;
+}
+
+/*
* msm_jpegdma_hw_reset - Reset jpeg dma core.
* @dma: Pointer to dma device.
*/
@@ -782,12 +799,20 @@ static int msm_jpegdma_hw_calc_speed(struct msm_jpegdma_device *dma,
u64 height;
u64 real_clock;
u64 calc_rate;
+ int core_clk_idx;
width = size->in_size.width + size->in_size.left;
height = size->in_size.height + size->in_size.top;
calc_rate = (width * height * size->format.depth * size->fps) / 16;
- real_clock = clk_round_rate(dma->clk[MSM_JPEGDMA_CORE_CLK], calc_rate);
+ core_clk_idx = msm_jpegdma_hw_get_clock_index(dma,
+ MSM_JPEGDMA_CORE_CLK);
+ if (core_clk_idx < 0) {
+ dev_err(dma->dev, "Can get clock index for dma %s\n",
+ MSM_JPEGDMA_CORE_CLK);
+ }
+
+ real_clock = clk_round_rate(dma->clk[core_clk_idx], calc_rate);
if (real_clock < 0) {
dev_err(dma->dev, "Can not round core clock\n");
return -EINVAL;
@@ -817,6 +842,7 @@ static int msm_jpegdma_hw_set_speed(struct msm_jpegdma_device *dma,
struct msm_jpegdma_speed new_sp;
struct msm_jpegdma_size_config new_size;
int ret;
+ int core_clk_idx;
if (dma->active_clock_rate >= speed->core_clock)
return 0;
@@ -830,7 +856,14 @@ static int msm_jpegdma_hw_set_speed(struct msm_jpegdma_device *dma,
return -EINVAL;
}
- ret = clk_set_rate(dma->clk[MSM_JPEGDMA_CORE_CLK], new_sp.core_clock);
+ core_clk_idx = msm_jpegdma_hw_get_clock_index(dma,
+ MSM_JPEGDMA_CORE_CLK);
+ if (core_clk_idx < 0) {
+ dev_err(dma->dev, "Can get clock index for dma %s\n",
+ MSM_JPEGDMA_CORE_CLK);
+ }
+
+ ret = clk_set_rate(dma->clk[core_clk_idx], new_sp.core_clock);
if (ret < 0) {
dev_err(dma->dev, "Fail Core clock rate %d\n", ret);
return -EINVAL;
@@ -1022,13 +1055,20 @@ int msm_jpegdma_hw_set_config(struct msm_jpegdma_device *dma,
plane_cfg->plane[0].active_pipes = dma->hw_num_pipes;
plane_cfg->plane[0].type = size_cfg->format.planes[0];
msm_jpegdma_hw_calc_config(size_cfg, &plane_cfg->plane[0]);
+
+ in_offset = size_cfg->in_offset;
+ out_offset = size_cfg->out_offset;
+
+ msm_jpegdma_hw_add_plane_offset(&plane_cfg->plane[0],
+ in_offset, out_offset);
+
if (size_cfg->format.num_planes == 1)
return 0;
- in_offset = size_cfg->in_size.scanline *
- size_cfg->in_size.stride;
- out_offset = size_cfg->out_size.scanline *
- size_cfg->out_size.stride;
+ in_offset += (size_cfg->in_size.scanline *
+ size_cfg->in_size.stride);
+ out_offset += (size_cfg->out_size.scanline *
+ size_cfg->out_size.stride);
memset(&plane_size, 0x00, sizeof(plane_size));
for (i = 1; i < size_cfg->format.num_planes; i++) {
@@ -1336,7 +1376,8 @@ int msm_jpegdma_hw_get_qos(struct msm_jpegdma_device *dma)
unsigned int cnt;
const void *property;
- property = of_get_property(dma->dev->of_node, "qcom,qos-regs", &cnt);
+ property = of_get_property(dma->dev->of_node,
+ "qcom,qos-reg-settings", &cnt);
if (!property || !cnt) {
dev_dbg(dma->dev, "Missing qos settings\n");
return 0;
@@ -1347,9 +1388,9 @@ int msm_jpegdma_hw_get_qos(struct msm_jpegdma_device *dma)
if (!dma->qos_regs)
return -ENOMEM;
- for (i = 0; i < cnt; i++) {
+ for (i = 0; i < cnt; i = i + 2) {
ret = of_property_read_u32_index(dma->dev->of_node,
- "qcom,qos-regs", i,
+ "qcom,qos-reg-settings", i,
&dma->qos_regs[i].reg);
if (ret < 0) {
dev_err(dma->dev, "can not read qos reg %d\n", i);
@@ -1357,7 +1398,7 @@ int msm_jpegdma_hw_get_qos(struct msm_jpegdma_device *dma)
}
ret = of_property_read_u32_index(dma->dev->of_node,
- "qcom,qos-settings", i,
+ "qcom,qos-reg-settings", i + 1,
&dma->qos_regs[i].val);
if (ret < 0) {
dev_err(dma->dev, "can not read qos setting %d\n", i);
@@ -1397,7 +1438,8 @@ int msm_jpegdma_hw_get_vbif(struct msm_jpegdma_device *dma)
unsigned int cnt;
const void *property;
- property = of_get_property(dma->dev->of_node, "qcom,vbif-regs", &cnt);
+ property = of_get_property(dma->dev->of_node, "qcom,vbif-reg-settings",
+ &cnt);
if (!property || !cnt) {
dev_dbg(dma->dev, "Missing vbif settings\n");
return 0;
@@ -1408,9 +1450,9 @@ int msm_jpegdma_hw_get_vbif(struct msm_jpegdma_device *dma)
if (!dma->vbif_regs)
return -ENOMEM;
- for (i = 0; i < cnt; i++) {
+ for (i = 0; i < cnt; i = i + 2) {
ret = of_property_read_u32_index(dma->dev->of_node,
- "qcom,vbif-regs", i,
+ "qcom,vbif-reg-settings", i,
&dma->vbif_regs[i].reg);
if (ret < 0) {
dev_err(dma->dev, "can not read vbif reg %d\n", i);
@@ -1418,7 +1460,7 @@ int msm_jpegdma_hw_get_vbif(struct msm_jpegdma_device *dma)
}
ret = of_property_read_u32_index(dma->dev->of_node,
- "qcom,vbif-settings", i,
+ "qcom,vbif-reg-settings", i + 1,
&dma->vbif_regs[i].val);
if (ret < 0) {
dev_err(dma->dev, "can not read vbif setting %d\n", i);
@@ -1459,8 +1501,8 @@ int msm_jpegdma_hw_get_prefetch(struct msm_jpegdma_device *dma)
unsigned int cnt;
const void *property;
- property = of_get_property(dma->dev->of_node, "qcom,prefetch-regs",
- &cnt);
+ property = of_get_property(dma->dev->of_node,
+ "qcom,prefetch-reg-settings", &cnt);
if (!property || !cnt) {
dev_dbg(dma->dev, "Missing prefetch settings\n");
return 0;
@@ -1472,9 +1514,9 @@ int msm_jpegdma_hw_get_prefetch(struct msm_jpegdma_device *dma)
if (!dma->prefetch_regs)
return -ENOMEM;
- for (i = 0; i < cnt; i++) {
+ for (i = 0; i < cnt; i = i + 2) {
ret = of_property_read_u32_index(dma->dev->of_node,
- "qcom,prefetch-regs", i,
+ "qcom,prefetch-reg-settings", i,
&dma->prefetch_regs[i].reg);
if (ret < 0) {
dev_err(dma->dev, "can not read prefetch reg %d\n", i);
@@ -1482,7 +1524,7 @@ int msm_jpegdma_hw_get_prefetch(struct msm_jpegdma_device *dma)
}
ret = of_property_read_u32_index(dma->dev->of_node,
- "qcom,prefetch-settings", i,
+ "qcom,prefetch-reg-settings", i + 1,
&dma->prefetch_regs[i].val);
if (ret < 0) {
dev_err(dma->dev, "can not read prefetch setting %d\n",
@@ -1598,6 +1640,9 @@ int msm_jpegdma_hw_get(struct msm_jpegdma_device *dma)
msm_jpegdma_hw_config_qos(dma);
msm_jpegdma_hw_config_vbif(dma);
+ msm_camera_register_threaded_irq(dma->pdev, dma->irq, NULL,
+ msm_jpegdma_hw_irq, IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+ dev_name(&dma->pdev->dev), dma);
msm_jpegdma_hw_enable_irq(dma);
ret = msm_jpegdma_hw_reset(dma);
@@ -1710,6 +1755,7 @@ error:
static void msm_jpegdma_hw_detach_iommu(struct msm_jpegdma_device *dma)
{
mutex_lock(&dma->lock);
+
if (dma->iommu_attached_cnt == 0) {
dev_err(dma->dev, "There is no attached device\n");
mutex_unlock(&dma->lock);
@@ -1720,6 +1766,7 @@ static void msm_jpegdma_hw_detach_iommu(struct msm_jpegdma_device *dma)
cam_smmu_ops(dma->iommu_hndl, CAM_SMMU_DETACH);
cam_smmu_destroy_handle(dma->iommu_hndl);
}
+
mutex_unlock(&dma->lock);
}
diff --git a/drivers/platform/msm/msm_11ad/msm_11ad.c b/drivers/platform/msm/msm_11ad/msm_11ad.c
index 203e0c4b4339..a8adc2401dbf 100644
--- a/drivers/platform/msm/msm_11ad/msm_11ad.c
+++ b/drivers/platform/msm/msm_11ad/msm_11ad.c
@@ -572,6 +572,7 @@ static int msm_11ad_smmu_init(struct msm11ad_ctx *ctx)
int disable_htw = 1;
int atomic_ctx = 1;
int rc;
+ int bypass_enable = 1;
if (!ctx->use_smmu)
return 0;
@@ -605,6 +606,15 @@ static int msm_11ad_smmu_init(struct msm11ad_ctx *ctx)
goto release_mapping;
}
+ rc = iommu_domain_set_attr(ctx->mapping->domain,
+ DOMAIN_ATTR_S1_BYPASS,
+ &bypass_enable);
+ if (rc) {
+ dev_err(ctx->dev, "Set bypass attribute to SMMU failed (%d)\n",
+ rc);
+ goto release_mapping;
+ }
+
rc = arm_iommu_attach_device(&ctx->pcidev->dev, ctx->mapping);
if (rc) {
dev_err(ctx->dev, "arm_iommu_attach_device failed (%d)\n", rc);
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index b6e2a55d5a9e..ba135e354ace 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -427,6 +427,25 @@ config MSM_GLADIATOR_ERP
If unsure, say N.
+config MSM_GLADIATOR_ERP_V2
+ tristate "GLADIATOR coherency interconnect error reporting driver v2"
+ help
+ Support dumping debug information for the GLADIATOR
+ cache interconnect in the error interrupt handler.
+ Meant to be used for debug scenarios only.
+
+ If unsure, say N.
+
+config PANIC_ON_GLADIATOR_ERROR_V2
+ depends on MSM_GLADIATOR_ERP_V2
+ bool "Panic on GLADIATOR error report v2"
+ help
+ Panic upon detection of an Gladiator coherency interconnect error
+ in order to support dumping debug information.
+ Meant to be used for debug scenarios only.
+
+ If unsure, say N.
+
config MSM_GLADIATOR_HANG_DETECT
tristate "MSM Gladiator Hang Detection Support"
help
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 1a4757f16e77..2433e81a831b 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_MSM_MPM_OF) += mpm-of.o
obj-$(CONFIG_MSM_EVENT_TIMER) += event_timer.o
obj-$(CONFIG_MSM_TZ_SMMU) += msm_tz_smmu.o
obj-$(CONFIG_MSM_GLADIATOR_ERP) += gladiator_erp.o
+obj-$(CONFIG_MSM_GLADIATOR_ERP_V2) += gladiator_erp_v2.o
obj-$(CONFIG_MSM_CORE_HANG_DETECT) += core_hang_detect.o
obj-$(CONFIG_MSM_GLADIATOR_HANG_DETECT) += gladiator_hang_detect.o
obj-$(CONFIG_MSM_RUN_QUEUE_STATS) += msm_rq_stats.o
diff --git a/drivers/soc/qcom/gladiator_erp_v2.c b/drivers/soc/qcom/gladiator_erp_v2.c
new file mode 100644
index 000000000000..70aace270acf
--- /dev/null
+++ b/drivers/soc/qcom/gladiator_erp_v2.c
@@ -0,0 +1,799 @@
+/* Copyright (c) 2015-2016, 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/module.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/cpu_pm.h>
+#include <linux/platform_device.h>
+#include <soc/qcom/scm.h>
+#include <linux/of.h>
+#include <linux/clk.h>
+
+#define MODULE_NAME "gladiator-v2_error_reporting"
+
+/* Register Offsets */
+#define GLADIATOR_ID_COREID 0x0
+#define GLADIATOR_ID_REVISIONID 0x4
+#define GLADIATOR_FAULTEN 0x1010
+#define GLADIATOR_ERRVLD 0x1014
+#define GLADIATOR_ERRCLR 0x1018
+#define GLADIATOR_ERRLOG0 0x101C
+#define GLADIATOR_ERRLOG1 0x1020
+#define GLADIATOR_ERRLOG2 0x1024
+#define GLADIATOR_ERRLOG3 0x1028
+#define GLADIATOR_ERRLOG4 0x102C
+#define GLADIATOR_ERRLOG5 0x1030
+#define GLADIATOR_ERRLOG6 0x1034
+#define GLADIATOR_ERRLOG7 0x1038
+#define GLADIATOR_ERRLOG8 0x103C
+#define OBSERVER_0_ID_COREID 0x8000
+#define OBSERVER_0_FAULTEN 0x8008
+#define OBSERVER_0_ERRVLD 0x800C
+#define OBSERVER_0_ERRCLR 0x8010
+#define OBSERVER_0_ERRLOG0 0x8014
+#define OBSERVER_0_ERRLOG1 0x8018
+#define OBSERVER_0_ERRLOG2 0x801C
+#define OBSERVER_0_ERRLOG3 0x8020
+#define OBSERVER_0_ERRLOG4 0x8024
+#define OBSERVER_0_ERRLOG5 0x8028
+#define OBSERVER_0_ERRLOG6 0x802C
+#define OBSERVER_0_ERRLOG7 0x8030
+#define OBSERVER_0_ERRLOG8 0x8034
+#define OBSERVER_0_STALLEN 0x8038
+#define OBSERVER_0_REVISIONID 0x8004
+
+#define GLD_TRANS_OPCODE_MASK 0xE
+#define GLD_TRANS_OPCODE_SHIFT 1
+#define GLD_ERROR_TYPE_MASK 0x700
+#define GLD_ERROR_TYPE_SHIFT 8
+#define GLD_LEN1_MASK 0xFFF0000
+#define GLD_LEN1_SHIFT 16
+#define GLD_TRANS_SOURCEID_MASK 0x7
+#define GLD_TRANS_SOURCEID_SHIFT 0
+#define GLD_TRANS_TARGETID_MASK 0x7
+#define GLD_TRANS_TARGETID_SHIFT 0
+#define GLD_ERRLOG_ERROR 0x7
+#define GLD_ERRLOG5_ERROR_TYPE_MASK 0xFF000000
+#define GLD_ERRLOG5_ERROR_TYPE_SHIFT 24
+#define GLD_ACE_PORT_PARITY_MASK 0xc000
+#define GLD_ACE_PORT_PARITY_SHIFT 14
+#define GLD_ACE_PORT_DISCONNECT_MASK 0xf0000
+#define GLD_ACE_PORT_DISCONNECT_SHIFT 16
+#define GLD_ACE_PORT_DIRECTORY_MASK 0xf00000
+#define GLD_ACE_PORT_DIRECTORY_SHIFT 20
+#define GLD_INDEX_PARITY_MASK 0x1FFF
+#define GLD_INDEX_PARITY_SHIFT 0
+#define OBS_TRANS_OPCODE_MASK 0x1E
+#define OBS_TRANS_OPCODE_SHIFT 1
+#define OBS_ERROR_TYPE_MASK 0x700
+#define OBS_ERROR_TYPE_SHIFT 8
+#define OBS_LEN1_MASK 0x7F0000
+#define OBS_LEN1_SHIFT 16
+
+struct msm_gladiator_data {
+ void __iomem *gladiator_virt_base;
+ int erp_irq;
+ struct notifier_block pm_notifier_block;
+ struct clk *qdss_clk;
+};
+
+static int enable_panic_on_error;
+module_param(enable_panic_on_error, int, 0);
+
+enum gld_trans_opcode {
+ GLD_RD,
+ GLD_RDX,
+ GLD_RDL,
+ GLD_RESERVED,
+ GLD_WR,
+ GLD_WRC,
+ GLD_PRE,
+};
+
+enum obs_trans_opcode {
+ OBS_RD,
+ OBS_RDW,
+ OBS_RDL,
+ OBS_RDX,
+ OBS_WR,
+ OBS_WRW,
+ OBS_WRC,
+ OBS_RESERVED,
+ OBS_PRE,
+ OBS_URG,
+};
+
+enum obs_err_code {
+ OBS_SLV,
+ OBS_DEC,
+ OBS_UNS,
+ OBS_DISC,
+ OBS_SEC,
+ OBS_HIDE,
+ OBS_TMO,
+ OBS_RSV,
+};
+
+enum err_log {
+ ERR_LOG0,
+ ERR_LOG1,
+ ERR_LOG2,
+ ERR_LOG3,
+ ERR_LOG4,
+ ERR_LOG5,
+ ERR_LOG6,
+ ERR_LOG7,
+ ERR_LOG8,
+ STALLEN,
+};
+
+enum type_logger_error {
+ DATA_TRANSFER_ERROR,
+ DVM_ERROR,
+ TX_ERROR,
+ TXR_ERROR,
+ DISCONNECT_ERROR,
+ DIRECTORY_ERROR,
+ PARITY_ERROR,
+};
+
+static void clear_gladiator_error(void __iomem *gladiator_virt_base)
+{
+ writel_relaxed(1, gladiator_virt_base + GLADIATOR_ERRCLR);
+ writel_relaxed(1, gladiator_virt_base + OBSERVER_0_ERRCLR);
+}
+
+static inline void print_gld_transaction(unsigned int opc)
+{
+ switch (opc) {
+ case GLD_RD:
+ pr_alert("Transaction type: READ\n");
+ break;
+ case GLD_RDX:
+ pr_alert("Transaction type: EXCLUSIVE READ\n");
+ break;
+ case GLD_RDL:
+ pr_alert("Transaction type: LINKED READ\n");
+ break;
+ case GLD_WR:
+ pr_alert("Transaction type: WRITE\n");
+ break;
+ case GLD_WRC:
+ pr_alert("Transaction type: CONDITIONAL WRITE\n");
+ break;
+ case GLD_PRE:
+ pr_alert("Transaction: Preamble packet of linked sequence\n");
+ break;
+ default:
+ pr_alert("Transaction type: Unknown; value:%u\n", opc);
+ }
+}
+
+static inline void print_gld_errtype(unsigned int errtype)
+{
+ if (errtype == 0)
+ pr_alert("Error type: Snoop data transfer\n");
+ else if (errtype == 1)
+ pr_alert("Error type: DVM error\n");
+ else if (errtype == 3)
+ pr_alert("Error type: Disconnect, directory, or parity error\n");
+ else
+ pr_alert("Error type: Unknown; value:%u\n", errtype);
+}
+
+static void decode_gld_errlog0(u32 err_reg)
+{
+ unsigned int opc, errtype, len1;
+
+ opc = (err_reg & GLD_TRANS_OPCODE_MASK) >> GLD_TRANS_OPCODE_SHIFT;
+ errtype = (err_reg & GLD_ERROR_TYPE_MASK) >> GLD_ERROR_TYPE_SHIFT;
+ len1 = (err_reg & GLD_LEN1_MASK) >> GLD_LEN1_SHIFT;
+
+ print_gld_transaction(opc);
+ print_gld_errtype(errtype);
+ pr_alert("number of payload bytes: %d\n", len1 + 1);
+}
+
+static void decode_gld_errlog1(u32 err_reg)
+{
+ if ((err_reg & GLD_ERRLOG_ERROR) == GLD_ERRLOG_ERROR)
+ pr_alert("Transaction issued on IO target generic interface\n");
+ else
+ pr_alert("Transaction source ID: %d\n",
+ (err_reg & GLD_TRANS_SOURCEID_MASK)
+ >> GLD_TRANS_SOURCEID_SHIFT);
+}
+
+static void decode_gld_errlog2(u32 err_reg)
+{
+ if ((err_reg & GLD_ERRLOG_ERROR) == GLD_ERRLOG_ERROR)
+ pr_alert("Error response coming from: external DVM network\n");
+ else
+ pr_alert("Error response coming from: Target ID: %d\n",
+ (err_reg & GLD_TRANS_TARGETID_MASK)
+ >> GLD_TRANS_TARGETID_SHIFT);
+}
+
+static void decode_ace_port_index(u32 type, u32 error)
+{
+ unsigned port;
+
+ switch (type) {
+ case DISCONNECT_ERROR:
+ port = (error & GLD_ACE_PORT_DISCONNECT_MASK)
+ >> GLD_ACE_PORT_DISCONNECT_SHIFT;
+ pr_alert("ACE port index: %d\n", port);
+ break;
+ case DIRECTORY_ERROR:
+ port = (error & GLD_ACE_PORT_DIRECTORY_MASK)
+ >> GLD_ACE_PORT_DIRECTORY_SHIFT;
+ pr_alert("ACE port index: %d\n", port);
+ break;
+ case PARITY_ERROR:
+ port = (error & GLD_ACE_PORT_PARITY_MASK)
+ >> GLD_ACE_PORT_PARITY_SHIFT;
+ pr_alert("ACE port index: %d\n", port);
+ }
+}
+
+static void decode_index_parity(u32 error)
+{
+ pr_alert("Index: %d\n",
+ (error & GLD_INDEX_PARITY_MASK)
+ >> GLD_INDEX_PARITY_SHIFT);
+}
+
+static void decode_gld_logged_error(u32 err_reg5)
+{
+ unsigned int log_err_type, i, value;
+
+ log_err_type = (err_reg5 & GLD_ERRLOG5_ERROR_TYPE_MASK)
+ >> GLD_ERRLOG5_ERROR_TYPE_SHIFT;
+ for (i = 0 ; i <= 6 ; i++) {
+ value = log_err_type & 0x1;
+ switch (i) {
+ case DATA_TRANSFER_ERROR:
+ if (value == 0)
+ continue;
+ pr_alert("Error type: Data transfer error\n");
+ break;
+ case DVM_ERROR:
+ if (value == 0)
+ continue;
+ pr_alert("Error type: DVM error\n");
+ break;
+ case TX_ERROR:
+ if (value == 0)
+ continue;
+ pr_alert("Error type: Tx error\n");
+ break;
+ case TXR_ERROR:
+ if (value == 0)
+ continue;
+ pr_alert("Error type: TxR error\n");
+ break;
+ case DISCONNECT_ERROR:
+ if (value == 0)
+ continue;
+ pr_alert("Error type: Disconnect error\n");
+ decode_ace_port_index(
+ DISCONNECT_ERROR,
+ err_reg5);
+ break;
+ case DIRECTORY_ERROR:
+ if (value == 0)
+ continue;
+ pr_alert("Error type: Directory error\n");
+ decode_ace_port_index(
+ DIRECTORY_ERROR,
+ err_reg5);
+ break;
+ case PARITY_ERROR:
+ if (value == 0)
+ continue;
+ pr_alert("Error type: Parity error\n");
+ decode_ace_port_index(PARITY_ERROR, err_reg5);
+ decode_index_parity(err_reg5);
+ break;
+ }
+ log_err_type = log_err_type >> 1;
+ }
+}
+
+static void decode_gld_errlog(u32 err_reg, unsigned int err_log)
+{
+ switch (err_log) {
+ case ERR_LOG0:
+ decode_gld_errlog0(err_reg);
+ break;
+ case ERR_LOG1:
+ decode_gld_errlog1(err_reg);
+ break;
+ case ERR_LOG2:
+ decode_gld_errlog2(err_reg);
+ break;
+ case ERR_LOG3:
+ pr_alert("Lower 32-bits of error address: %08x\n", err_reg);
+ break;
+ case ERR_LOG4:
+ pr_alert("Upper 32-bits of error address: %08x\n", err_reg);
+ break;
+ case ERR_LOG5:
+ pr_alert("Lower 32-bits of user: %08x\n", err_reg);
+ break;
+ case ERR_LOG6:
+ pr_alert("Mid 32-bits(63-32) of user: %08x\n", err_reg);
+ break;
+ case ERR_LOG7:
+ break;
+ case ERR_LOG8:
+ pr_alert("Upper 32-bits(95-64) of user: %08x\n", err_reg);
+ break;
+ default:
+ pr_alert("Invalid error register; reg num:%u\n", err_log);
+ }
+}
+
+static inline void print_obs_transaction(unsigned int opc)
+{
+ switch (opc) {
+ case OBS_RD:
+ pr_alert("Transaction type: READ\n");
+ break;
+ case OBS_RDW:
+ pr_alert("Transaction type: WRAPPED READ\n");
+ break;
+ case OBS_RDL:
+ pr_alert("Transaction type: LINKED READ\n");
+ break;
+ case OBS_RDX:
+ pr_alert("Transaction type: EXCLUSIVE READ\n");
+ break;
+ case OBS_WR:
+ pr_alert("Transaction type: WRITE\n");
+ break;
+ case OBS_WRW:
+ pr_alert("Transaction type: WRAPPED WRITE\n");
+ break;
+ case OBS_WRC:
+ pr_alert("Transaction type: CONDITIONAL WRITE\n");
+ break;
+ case OBS_PRE:
+ pr_alert("Transaction: Preamble packet of linked sequence\n");
+ break;
+ case OBS_URG:
+ pr_alert("Transaction type: Urgency Packet\n");
+ break;
+ default:
+ pr_alert("Transaction type: Unknown; value:%u\n", opc);
+ }
+}
+
+static inline void print_obs_errcode(unsigned int errcode)
+{
+ switch (errcode) {
+ case OBS_SLV:
+ pr_alert("Error code: Target error detected by slave\n");
+ pr_alert("Source: Target\n");
+ break;
+ case OBS_DEC:
+ pr_alert("Error code: Address decode error\n");
+ pr_alert("Source: Initiator NIU\n");
+ break;
+ case OBS_UNS:
+ pr_alert("Error code: Unsupported request\n");
+ pr_alert("Source: Target NIU\n");
+ break;
+ case OBS_DISC:
+ pr_alert("Error code: Disconnected target or domain\n");
+ pr_alert("Source: Power Disconnect\n");
+ break;
+ case OBS_SEC:
+ pr_alert("Error code: Security violation\n");
+ pr_alert("Source: Initiator NIU or Firewall\n");
+ break;
+ case OBS_HIDE:
+ pr_alert("Error :Hidden security violation, reported as OK\n");
+ pr_alert("Source: Firewall\n");
+ break;
+ case OBS_TMO:
+ pr_alert("Error code: Time-out\n");
+ pr_alert("Source: Target NIU\n");
+ break;
+ default:
+ pr_alert("Error code: Unknown; code:%u\n", errcode);
+ }
+}
+
+static void decode_obs_errlog0(u32 err_reg)
+{
+ unsigned int opc, errcode, len1;
+
+ opc = (err_reg & OBS_TRANS_OPCODE_MASK) >> OBS_TRANS_OPCODE_SHIFT;
+ errcode = (err_reg & OBS_ERROR_TYPE_MASK) >> OBS_ERROR_TYPE_SHIFT;
+ len1 = (err_reg & OBS_LEN1_MASK) >> OBS_LEN1_SHIFT;
+
+ print_obs_transaction(opc);
+ print_obs_errcode(errcode);
+ pr_alert("number of payload bytes: %d\n", len1 + 1);
+}
+
+static void decode_obs_errlog(u32 err_reg, unsigned int err_log)
+{
+ switch (err_log) {
+ case ERR_LOG0:
+ decode_obs_errlog0(err_reg);
+ break;
+ case ERR_LOG1:
+ pr_alert("RouteId of the error: %08x\n", err_reg);
+ break;
+ case ERR_LOG2:
+ /* reserved error log register */
+ break;
+ case ERR_LOG3:
+ pr_alert("Lower 32-bits of error address: %08x\n", err_reg);
+ break;
+ case ERR_LOG4:
+ pr_alert("Upper 12-bits of error address: %08x\n", err_reg);
+ break;
+ case ERR_LOG5:
+ pr_alert("Lower 13-bits of user: %08x\n", err_reg);
+ break;
+ case ERR_LOG6:
+ /* reserved error log register */
+ break;
+ case ERR_LOG7:
+ pr_alert("Security filed of the logged error: %08x\n", err_reg);
+ break;
+ case ERR_LOG8:
+ /* reserved error log register */
+ break;
+ case STALLEN:
+ pr_alert("stall mode of the error logger: %08x\n",
+ err_reg & 0x1);
+ break;
+ default:
+ pr_alert("Invalid error register; reg num:%u\n", err_log);
+ }
+}
+
+static u32 get_gld_offset(unsigned int err_log)
+{
+ u32 offset = 0;
+
+ switch (err_log) {
+ case ERR_LOG0:
+ offset = GLADIATOR_ERRLOG0;
+ break;
+ case ERR_LOG1:
+ offset = GLADIATOR_ERRLOG1;
+ break;
+ case ERR_LOG2:
+ offset = GLADIATOR_ERRLOG2;
+ break;
+ case ERR_LOG3:
+ offset = GLADIATOR_ERRLOG3;
+ break;
+ case ERR_LOG4:
+ offset = GLADIATOR_ERRLOG4;
+ break;
+ case ERR_LOG5:
+ offset = GLADIATOR_ERRLOG5;
+ break;
+ case ERR_LOG6:
+ offset = GLADIATOR_ERRLOG6;
+ break;
+ case ERR_LOG7:
+ offset = GLADIATOR_ERRLOG7;
+ break;
+ case ERR_LOG8:
+ offset = GLADIATOR_ERRLOG8;
+ break;
+ default:
+ pr_alert("Invalid gladiator error register; reg num:%u\n",
+ err_log);
+ }
+ return offset;
+}
+
+static u32 get_obs_offset(unsigned int err_log)
+{
+ u32 offset = 0;
+
+ switch (err_log) {
+ case ERR_LOG0:
+ offset = OBSERVER_0_ERRLOG0;
+ break;
+ case ERR_LOG1:
+ offset = OBSERVER_0_ERRLOG1;
+ break;
+ case ERR_LOG2:
+ offset = OBSERVER_0_ERRLOG2;
+ break;
+ case ERR_LOG3:
+ offset = OBSERVER_0_ERRLOG3;
+ break;
+ case ERR_LOG4:
+ offset = OBSERVER_0_ERRLOG4;
+ break;
+ case ERR_LOG5:
+ offset = OBSERVER_0_ERRLOG5;
+ break;
+ case ERR_LOG6:
+ offset = OBSERVER_0_ERRLOG6;
+ break;
+ case ERR_LOG7:
+ offset = OBSERVER_0_ERRLOG7;
+ break;
+ case ERR_LOG8:
+ offset = OBSERVER_0_ERRLOG8;
+ break;
+ case STALLEN:
+ offset = OBSERVER_0_STALLEN;
+ break;
+ default:
+ pr_alert("Invalid observer error register; reg num:%u\n",
+ err_log);
+ }
+ return offset;
+}
+
+static void decode_gld_errlog5(struct msm_gladiator_data *msm_gld_data)
+{
+ unsigned int errtype;
+ u32 err_reg0, err_reg5;
+
+ err_reg0 = readl_relaxed(msm_gld_data->gladiator_virt_base +
+ get_gld_offset(ERR_LOG0));
+ err_reg5 = readl_relaxed(msm_gld_data->gladiator_virt_base +
+ get_gld_offset(ERR_LOG5));
+
+ errtype = (err_reg0 & GLD_ERROR_TYPE_MASK) >> GLD_ERROR_TYPE_SHIFT;
+ if (errtype == 3)
+ decode_gld_logged_error(err_reg5);
+ else if (errtype == 0 || errtype == 1)
+ pr_alert("Lower 32-bits of user: %08x\n", err_reg5);
+ else
+ pr_alert("Error type: Unknown; value:%u\n", errtype);
+}
+
+static irqreturn_t msm_gladiator_isr(int irq, void *dev_id)
+{
+ u32 err_reg;
+ unsigned int err_log;
+
+ struct msm_gladiator_data *msm_gld_data = dev_id;
+
+ /* Check validity */
+ bool gld_err_valid = readl_relaxed(msm_gld_data->gladiator_virt_base +
+ GLADIATOR_ERRVLD);
+
+ bool obsrv_err_valid = readl_relaxed(
+ msm_gld_data->gladiator_virt_base + OBSERVER_0_ERRVLD);
+
+ if (!gld_err_valid && !obsrv_err_valid) {
+ pr_err("%s Invalid Gladiator error reported, clear it\n",
+ __func__);
+ /* Clear IRQ */
+ clear_gladiator_error(msm_gld_data->gladiator_virt_base);
+ return IRQ_HANDLED;
+ }
+ pr_alert("GLADIATOR ERROR DETECTED\n");
+ if (gld_err_valid) {
+ pr_alert("GLADIATOR error log register data:\n");
+ for (err_log = ERR_LOG0; err_log <= ERR_LOG8; err_log++) {
+ /* skip log register 7 as its reserved */
+ if (err_log == ERR_LOG7)
+ continue;
+ if (err_log == ERR_LOG5) {
+ decode_gld_errlog5(msm_gld_data);
+ continue;
+ }
+ err_reg = readl_relaxed(
+ msm_gld_data->gladiator_virt_base +
+ get_gld_offset(err_log));
+ decode_gld_errlog(err_reg, err_log);
+ }
+ }
+ if (obsrv_err_valid) {
+ pr_alert("Observor error log register data:\n");
+ for (err_log = ERR_LOG0; err_log <= STALLEN; err_log++) {
+ /* skip log register 2, 6 and 8 as they are reserved */
+ if ((err_log == ERR_LOG2) || (err_log == ERR_LOG6)
+ || (err_log == ERR_LOG8))
+ continue;
+ err_reg = readl_relaxed(
+ msm_gld_data->gladiator_virt_base +
+ get_obs_offset(err_log));
+ decode_obs_errlog(err_reg, err_log);
+ }
+ }
+ /* Clear IRQ */
+ clear_gladiator_error(msm_gld_data->gladiator_virt_base);
+ if (enable_panic_on_error)
+ panic("Gladiator Cache Interconnect Error Detected!\n");
+ else
+ WARN(1, "Gladiator Cache Interconnect Error Detected\n");
+
+ return IRQ_HANDLED;
+}
+
+static const struct of_device_id gladiator_erp_v2_match_table[] = {
+ { .compatible = "qcom,msm-gladiator-v2" },
+ {},
+};
+
+static int parse_dt_node(struct platform_device *pdev,
+ struct msm_gladiator_data *msm_gld_data)
+{
+ int ret = 0;
+ struct resource *res;
+
+ res = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, "gladiator_base");
+ if (!res)
+ return -ENODEV;
+ if (!devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res),
+ "msm-gladiator-erp")) {
+
+ dev_err(&pdev->dev, "%s cannot reserve gladiator erp region\n",
+ __func__);
+ return -ENXIO;
+ }
+ msm_gld_data->gladiator_virt_base = devm_ioremap(&pdev->dev,
+ res->start, resource_size(res));
+ if (!msm_gld_data->gladiator_virt_base) {
+ dev_err(&pdev->dev, "%s cannot map gladiator register space\n",
+ __func__);
+ return -ENXIO;
+ }
+ msm_gld_data->erp_irq = platform_get_irq(pdev, 0);
+ if (!msm_gld_data->erp_irq)
+ return -ENODEV;
+
+ /* clear existing errors before enabling the interrupt */
+ clear_gladiator_error(msm_gld_data->gladiator_virt_base);
+ ret = devm_request_irq(&pdev->dev, msm_gld_data->erp_irq,
+ msm_gladiator_isr, IRQF_TRIGGER_HIGH,
+ "gladiator-error", msm_gld_data);
+ if (ret)
+ dev_err(&pdev->dev, "Failed to register irq handler\n");
+
+ return ret;
+}
+
+static inline void gladiator_irq_init(void __iomem *gladiator_virt_base)
+{
+ writel_relaxed(1, gladiator_virt_base + GLADIATOR_FAULTEN);
+ writel_relaxed(1, gladiator_virt_base + OBSERVER_0_FAULTEN);
+}
+
+#define CCI_LEVEL 2
+static int gladiator_erp_pm_callback(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ unsigned int level = (unsigned long) data;
+ struct msm_gladiator_data *msm_gld_data = container_of(nb,
+ struct msm_gladiator_data, pm_notifier_block);
+
+ if (level != CCI_LEVEL)
+ return NOTIFY_DONE;
+
+ switch (val) {
+ case CPU_CLUSTER_PM_EXIT:
+ gladiator_irq_init(msm_gld_data->gladiator_virt_base);
+ break;
+ default:
+ return NOTIFY_DONE;
+ }
+
+ return NOTIFY_OK;
+}
+
+static int gladiator_erp_v2_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct msm_gladiator_data *msm_gld_data;
+
+ msm_gld_data = devm_kzalloc(&pdev->dev,
+ sizeof(struct msm_gladiator_data), GFP_KERNEL);
+ if (!msm_gld_data) {
+ ret = -ENOMEM;
+ goto bail;
+ }
+
+ ret = parse_dt_node(pdev, msm_gld_data);
+ if (ret)
+ goto bail;
+ msm_gld_data->pm_notifier_block.notifier_call =
+ gladiator_erp_pm_callback;
+
+ if (of_property_match_string(pdev->dev.of_node,
+ "clock-names", "atb_clk") >= 0) {
+ msm_gld_data->qdss_clk = devm_clk_get(&pdev->dev, "atb_clk");
+ if (IS_ERR(msm_gld_data->qdss_clk)) {
+ dev_err(&pdev->dev, "Failed to get QDSS ATB clock\n");
+ goto bail;
+ }
+ } else {
+ dev_err(&pdev->dev, "No matching string of QDSS ATB clock\n");
+ goto bail;
+ }
+
+ ret = clk_prepare_enable(msm_gld_data->qdss_clk);
+ if (ret)
+ goto err_atb_clk;
+
+ gladiator_irq_init(msm_gld_data->gladiator_virt_base);
+ platform_set_drvdata(pdev, msm_gld_data);
+ cpu_pm_register_notifier(&msm_gld_data->pm_notifier_block);
+#ifdef CONFIG_PANIC_ON_GLADIATOR_ERROR_V2
+ enable_panic_on_error = 1;
+#endif
+ dev_info(&pdev->dev, "MSM Gladiator Error Reporting V2 Initialized\n");
+ return ret;
+
+err_atb_clk:
+ clk_disable_unprepare(msm_gld_data->qdss_clk);
+
+bail:
+ dev_err(&pdev->dev, "Probe failed bailing out\n");
+ return ret;
+}
+
+static int gladiator_erp_v2_remove(struct platform_device *pdev)
+{
+ struct msm_gladiator_data *msm_gld_data = platform_get_drvdata(pdev);
+
+ platform_set_drvdata(pdev, NULL);
+ cpu_pm_unregister_notifier(&msm_gld_data->pm_notifier_block);
+ clk_disable_unprepare(msm_gld_data->qdss_clk);
+ return 0;
+}
+
+static struct platform_driver gladiator_erp_driver = {
+ .probe = gladiator_erp_v2_probe,
+ .remove = gladiator_erp_v2_remove,
+ .driver = {
+ .name = MODULE_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = gladiator_erp_v2_match_table,
+ },
+};
+
+static int __init init_gladiator_erp_v2(void)
+{
+ int ret;
+
+ ret = scm_is_secure_device();
+ if (ret == 0) {
+ pr_info("Gladiator Error Reporting not available\n");
+ return -ENODEV;
+ }
+
+ return platform_driver_register(&gladiator_erp_driver);
+}
+module_init(init_gladiator_erp_v2);
+
+static void __exit exit_gladiator_erp_v2(void)
+{
+ return platform_driver_unregister(&gladiator_erp_driver);
+}
+module_exit(exit_gladiator_erp_v2);
+
+MODULE_DESCRIPTION("Gladiator Error Reporting V2");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c
index aad67abc709a..388fb70604b6 100644
--- a/drivers/soc/qcom/glink.c
+++ b/drivers/soc/qcom/glink.c
@@ -4338,6 +4338,9 @@ static bool ch_migrate(struct channel_ctx *l_ctx, struct channel_ctx *r_ctx)
list_del_init(&l_ctx->port_list_node);
spin_unlock_irqrestore(&l_ctx->transport_ptr->xprt_ctx_lock_lhb1,
flags);
+ mutex_lock(&l_ctx->transport_ptr->xprt_dbgfs_lock_lhb3);
+ glink_debugfs_remove_channel(l_ctx, l_ctx->transport_ptr);
+ mutex_unlock(&l_ctx->transport_ptr->xprt_dbgfs_lock_lhb3);
memcpy(ctx_clone, l_ctx, sizeof(*ctx_clone));
ctx_clone->local_xprt_req = 0;
@@ -4372,11 +4375,13 @@ static bool ch_migrate(struct channel_ctx *l_ctx, struct channel_ctx *r_ctx)
l_ctx->transport_ptr = xprt;
l_ctx->local_xprt_req = 0;
l_ctx->local_xprt_resp = 0;
- if (new_xprt != r_ctx->transport_ptr->id) {
- r_ctx->local_xprt_req = 0;
- r_ctx->local_xprt_resp = 0;
- r_ctx->remote_xprt_req = 0;
- r_ctx->remote_xprt_resp = 0;
+ if (new_xprt != r_ctx->transport_ptr->id || l_ctx == r_ctx) {
+ if (new_xprt != r_ctx->transport_ptr->id) {
+ r_ctx->local_xprt_req = 0;
+ r_ctx->local_xprt_resp = 0;
+ r_ctx->remote_xprt_req = 0;
+ r_ctx->remote_xprt_resp = 0;
+ }
l_ctx->remote_xprt_req = 0;
l_ctx->remote_xprt_resp = 0;
@@ -4409,6 +4414,9 @@ static bool ch_migrate(struct channel_ctx *l_ctx, struct channel_ctx *r_ctx)
spin_unlock_irqrestore(&xprt->xprt_ctx_lock_lhb1, flags);
}
+ mutex_lock(&xprt->xprt_dbgfs_lock_lhb3);
+ glink_debugfs_add_channel(l_ctx, xprt);
+ mutex_unlock(&xprt->xprt_dbgfs_lock_lhb3);
mutex_lock(&transport_list_lock_lha0);
list_for_each_entry(xprt, &transport_list, list_node)
diff --git a/drivers/usb/gadget/function/f_diag.c b/drivers/usb/gadget/function/f_diag.c
index 7a451b77c4d0..87939140f82e 100644
--- a/drivers/usb/gadget/function/f_diag.c
+++ b/drivers/usb/gadget/function/f_diag.c
@@ -657,7 +657,16 @@ static void diag_function_disable(struct usb_function *f)
static void diag_free_func(struct usb_function *f)
{
- kfree(func_to_diag(f));
+ struct diag_context *ctxt = func_to_diag(f);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctxt->lock, flags);
+ list_del(&ctxt->list_item);
+ if (kref_put(&ctxt->kref, diag_context_release))
+ /* diag_context_release called spin_unlock already */
+ local_irq_restore(flags);
+ else
+ spin_unlock_irqrestore(&ctxt->lock, flags);
}
static int diag_function_set_alt(struct usb_function *f,
@@ -734,16 +743,11 @@ static void diag_function_unbind(struct usb_configuration *c,
*/
if (ctxt->ch && ctxt->ch->priv_usb == ctxt)
ctxt->ch->priv_usb = NULL;
- list_del(&ctxt->list_item);
- /* Free any pending USB requests from last session */
+
spin_lock_irqsave(&ctxt->lock, flags);
+ /* Free any pending USB requests from last session */
free_reqs(ctxt);
-
- if (kref_put(&ctxt->kref, diag_context_release))
- /* diag_context_release called spin_unlock already */
- local_irq_restore(flags);
- else
- spin_unlock_irqrestore(&ctxt->lock, flags);
+ spin_unlock_irqrestore(&ctxt->lock, flags);
}
static int diag_function_bind(struct usb_configuration *c,
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index 646f75653583..bb4114e90b6c 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -3748,9 +3748,9 @@ static int mdss_dsi_parse_ctrl_params(struct platform_device *ctrl_pdev,
data = of_get_property(ctrl_pdev->dev.of_node,
"qcom,platform-regulator-settings", &len);
if (!data) {
- pr_err("%s:%d, Unable to read Phy regulator settings\n",
+ pr_debug("%s:%d, Unable to read Phy regulator settings\n",
__func__, __LINE__);
- return -EINVAL;
+ pinfo->mipi.dsi_phy_db.regulator_len = 0;
} else {
pinfo->mipi.dsi_phy_db.regulator_len = len;
for (i = 0; i < len; i++)
diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
index b23e24362af6..619c671650ea 100644
--- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c
+++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
@@ -564,6 +564,11 @@ static void mdss_dsi_28nm_phy_regulator_enable(
struct mdss_dsi_phy_ctrl *pd;
pd = &(((ctrl_pdata->panel_data).panel_info.mipi).dsi_phy_db);
+ if (pd->regulator_len == 0) {
+ pr_warn("%s: invalid regulator settings\n", __func__);
+ return;
+ }
+
if (pd->reg_ldo_mode) {
/* Regulator ctrl 0 */
MIPI_OUTP(ctrl_pdata->phy_regulator_io.base, 0x0);
@@ -855,6 +860,12 @@ static void mdss_dsi_8996_phy_regulator_enable(
void __iomem *base;
pd = &(((ctrl->panel_data).panel_info.mipi).dsi_phy_db);
+
+ if (pd->regulator_len != 5) {
+ pr_warn("%s: invalid regulator settings\n", __func__);
+ return;
+ }
+
/* 4 lanes + clk lane configuration */
for (ln = 0; ln < 5; ln++) {
/*
diff --git a/include/dt-bindings/clock/msm-clocks-cobalt.h b/include/dt-bindings/clock/msm-clocks-cobalt.h
index 8fb7e73441bc..bd0ae1388487 100644
--- a/include/dt-bindings/clock/msm-clocks-cobalt.h
+++ b/include/dt-bindings/clock/msm-clocks-cobalt.h
@@ -398,8 +398,10 @@
#define clk_mmss_mdss_axi_clk 0xdf04fc1d
#define clk_mmss_mdss_byte0_clk 0x38105d25
#define clk_mmss_mdss_byte0_intf_clk 0x38e5aa79
+#define clk_mmss_mdss_byte0_intf_div_clk 0x8604f181
#define clk_mmss_mdss_byte1_clk 0xe0c21354
#define clk_mmss_mdss_byte1_intf_clk 0xcf654d8e
+#define clk_mmss_mdss_byte1_intf_div_clk 0xcdf334c5
#define clk_mmss_mdss_dp_aux_clk 0x23125eb6
#define clk_mmss_mdss_dp_gtc_clk 0xb59c151a
#define clk_mmss_mdss_esc0_clk 0x5721ff83
diff --git a/include/dt-bindings/clock/msm-clocks-hwio-cobalt.h b/include/dt-bindings/clock/msm-clocks-hwio-cobalt.h
index 22bafd3ee428..9ba814880632 100644
--- a/include/dt-bindings/clock/msm-clocks-hwio-cobalt.h
+++ b/include/dt-bindings/clock/msm-clocks-hwio-cobalt.h
@@ -358,8 +358,10 @@
#define MMSS_MDSS_AXI_CBCR 0x02310
#define MMSS_MDSS_BYTE0_CBCR 0x0233C
#define MMSS_MDSS_BYTE0_INTF_CBCR 0x02374
+#define MMSS_MDSS_BYTE0_INTF_DIV 0x0237C
#define MMSS_MDSS_BYTE1_CBCR 0x02340
#define MMSS_MDSS_BYTE1_INTF_CBCR 0x02378
+#define MMSS_MDSS_BYTE1_INTF_DIV 0x02380
#define MMSS_MDSS_DP_AUX_CBCR 0x02364
#define MMSS_MDSS_DP_CRYPTO_CBCR 0x0235C
#define MMSS_MDSS_DP_GTC_CBCR 0x02368
diff --git a/include/uapi/media/msm_jpeg_dma.h b/include/uapi/media/msm_jpeg_dma.h
index 44fa4ed8af52..df3c7ee5b7cf 100644
--- a/include/uapi/media/msm_jpeg_dma.h
+++ b/include/uapi/media/msm_jpeg_dma.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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,4 +18,10 @@
/* msm jpeg dma control ID's */
#define V4L2_CID_JPEG_DMA_SPEED (V4L2_CID_PRIVATE_BASE)
+/* msm_jpeg_dma_buf */
+struct msm_jpeg_dma_buff {
+ int32_t fd;
+ uint32_t offset;
+};
+
#endif /* __UAPI_MSM_JPEG_DMA__ */