Merge "diag: Synchronize command registration table access"
diff --git a/Documentation/devicetree/bindings/cnss/icnss.txt b/Documentation/devicetree/bindings/cnss/icnss.txt
index c801e848..700a8f7 100644
--- a/Documentation/devicetree/bindings/cnss/icnss.txt
+++ b/Documentation/devicetree/bindings/cnss/icnss.txt
@@ -28,6 +28,7 @@
- qcom,icnss-vadc: VADC handle for vph_pwr read APIs.
- qcom,icnss-adc_tm: VADC handle for vph_pwr notification APIs.
- qcom,smmu-s1-bypass: Boolean context flag to set SMMU to S1 bypass
+ - qcom,wlan-msa-fixed-region: phandle, specifier pairs to children of /reserved-memory
Example:
@@ -54,6 +55,7 @@
<0 140 0 /* CE10 */ >,
<0 141 0 /* CE11 */ >;
qcom,wlan-msa-memory = <0x200000>;
+ qcom,wlan-msa-fixed-region = <&wlan_msa_mem>;
qcom,smmu-s1-bypass;
vdd-0.8-cx-mx-supply = <&pm8998_l5>;
qcom,vdd-0.8-cx-mx-config = <800000 800000 2400 1000>;
diff --git a/Documentation/devicetree/bindings/usb/msm-phy.txt b/Documentation/devicetree/bindings/usb/msm-phy.txt
index a9480be..6109fad 100644
--- a/Documentation/devicetree/bindings/usb/msm-phy.txt
+++ b/Documentation/devicetree/bindings/usb/msm-phy.txt
@@ -152,6 +152,7 @@
and reset lines used by this controller.
- reset-names: reset signal name strings sorted in the same order as the resets
property.
+ - qcom,qusb-phy-reg-offset: Provides important phy register offsets in an order defined in phy driver.
Optional properties:
- reg-names: Additional registers corresponding with the following:
@@ -174,7 +175,6 @@
- qcom,hold-reset: Indicates that hold QUSB PHY into reset state.
- qcom,phy-clk-scheme: Should be one of "cml" or "cmos" if ref_clk_addr is provided.
- qcom,major-rev: provide major revision number to differentiate power up sequence. default is 2.0
- - qcom,phy-auto-resume-offset: Provides phy auto-resume register offset.
Example:
qusb_phy: qusb@f9b39000 {
@@ -185,6 +185,13 @@
vdda18-supply = <&pm8994_l6>;
vdda33-supply = <&pm8994_l24>;
qcom,vdd-voltage-level = <1 5 7>;
+ qcom,qusb-phy-reg-offset =
+ <0x240 /* QUSB2PHY_PORT_TUNE1 */
+ 0x1a0 /* QUSB2PHY_PLL_COMMON_STATUS_ONE */
+ 0x210 /* QUSB2PHY_PWR_CTRL1 */
+ 0x230 /* QUSB2PHY_INTR_CTRL */
+ 0x0a8 /* QUSB2PHY_PLL_CORE_INPUT_OVERRIDE */
+ 0x254>; /* QUSB2PHY_TEST1 */
qcom,efuse-bit-pos = <21>;
qcom,efuse-num-bits = <3>;
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 84867ba..842c38a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -108,6 +108,7 @@
select POWER_SUPPLY
select SPARSE_IRQ
select SYSCTL_EXCEPTION_TRACE
+ select THREAD_INFO_IN_TASK
help
ARM 64-bit (AArch64) Linux support.
diff --git a/arch/arm64/boot/dts/qcom/sdm845-bus.dtsi b/arch/arm64/boot/dts/qcom/sdm845-bus.dtsi
index 3ce5611..5fbb1db 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-bus.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-bus.dtsi
@@ -572,6 +572,18 @@
qcom,prio = <2>;
};
+ mas_xm_pcie_0: mas-xm-pcie-0 {
+ cell-id = <MSM_BUS_MASTER_PCIE>;
+ label = "mas-xm-pcie-0";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,qport = <5>;
+ qcom,connections = <&slv_qns_pcie_a1noc_snoc>;
+ qcom,bus-dev = <&fab_aggre1_noc>;
+ qcom,ap-owned;
+ qcom,prio = <2>;
+ };
+
mas_qhm_a2noc_cfg: mas-qhm-a2noc-cfg {
cell-id = <MSM_BUS_MASTER_A2NOC_CFG>;
label = "mas-qhm-a2noc-cfg";
@@ -648,18 +660,6 @@
qcom,prio = <2>;
};
- mas_xm_pcie_0: mas-xm-pcie-0 {
- cell-id = <MSM_BUS_MASTER_PCIE>;
- label = "mas-xm-pcie-0";
- qcom,buswidth = <8>;
- qcom,agg-ports = <1>;
- qcom,qport = <5>;
- qcom,connections = <&slv_qns_pcie_snoc>;
- qcom,bus-dev = <&fab_aggre1_noc>;
- qcom,ap-owned;
- qcom,prio = <2>;
- };
-
mas_xm_qdss_etr: mas-xm-qdss-etr {
cell-id = <MSM_BUS_MASTER_QDSS_ETR>;
label = "mas-xm-qdss-etr";
@@ -715,6 +715,7 @@
qcom,agg-ports = <1>;
qcom,connections = <&slv_qns_camnoc_uncomp>;
qcom,bus-dev = <&fab_camnoc_virt>;
+ qcom,bcms = <&bcm_mm1>;
};
mas_qxm_camnoc_hf1_uncomp: mas-qxm-camnoc-hf1-uncomp {
@@ -724,6 +725,7 @@
qcom,agg-ports = <1>;
qcom,connections = <&slv_qns_camnoc_uncomp>;
qcom,bus-dev = <&fab_camnoc_virt>;
+ qcom,bcms = <&bcm_mm1>;
};
mas_qxm_camnoc_sf_uncomp: mas-qxm-camnoc-sf-uncomp {
@@ -733,6 +735,7 @@
qcom,agg-ports = <1>;
qcom,connections = <&slv_qns_camnoc_uncomp>;
qcom,bus-dev = <&fab_camnoc_virt>;
+ qcom,bcms = <&bcm_mm1>;
};
mas_qhm_spdm: mas-qhm-spdm {
@@ -1222,6 +1225,19 @@
qcom,prio = <2>;
};
+ mas_xm_gic: mas-xm-gic {
+ cell-id = <MSM_BUS_MASTER_GIC>;
+ label = "mas-xm-gic";
+ qcom,buswidth = <8>;
+ qcom,agg-ports = <1>;
+ qcom,qport = <0>;
+ qcom,connections = <&slv_qxs_imem &slv_qns_memnoc_gc>;
+ qcom,bus-dev = <&fab_system_noc>;
+ qcom,bcms = <&bcm_sn12>;
+ qcom,ap-owned;
+ qcom,prio = <1>;
+ };
+
mas_alc: mas-alc {
cell-id = <MSM_BUS_MASTER_ALC>;
label = "mas-alc";
@@ -1315,6 +1331,15 @@
qcom,bcms = <&bcm_sn9>;
};
+ slv_qns_pcie_a1noc_snoc:slv-qns-pcie-a1noc-snoc {
+ cell-id = <MSM_BUS_SLAVE_ANOC_PCIE_A1NOC_SNOC>;
+ label = "slv-qns-pcie-a1noc-snoc";
+ qcom,buswidth = <16>;
+ qcom,agg-ports = <1>;
+ qcom,bus-dev = <&fab_aggre1_noc>;
+ qcom,connections = <&mas_qnm_pcie_anoc>;
+ };
+
slv_qns_a2noc_snoc:slv-qns-a2noc-snoc {
cell-id = <MSM_BUS_A2NOC_SNOC_SLV>;
label = "slv-qns-a2noc-snoc";
@@ -1348,7 +1373,6 @@
qcom,buswidth = <32>;
qcom,agg-ports = <1>;
qcom,bus-dev = <&fab_camnoc_virt>;
- qcom,bcms = <&bcm_mm1>;
};
slv_qhs_a1_noc_cfg:slv-qhs-a1-noc-cfg {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-usb.dtsi b/arch/arm64/boot/dts/qcom/sdm845-usb.dtsi
index 53cb27e..ac16d03 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-usb.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-usb.dtsi
@@ -113,13 +113,24 @@
/* Primary USB port related QUSB2 PHY */
qusb_phy0: qusb@88e2000 {
compatible = "qcom,qusb2phy-v2";
- reg = <0x088e2000 0x400>;
- reg-names = "qusb_phy_base";
+ reg = <0x088e2000 0x400>,
+ <0x007801e8 0x4>;
+ reg-names = "qusb_phy_base", "efuse_addr";
+ qcom,efuse-bit-pos = <25>;
+ qcom,efuse-num-bits = <3>;
vdd-supply = <&pm8998_l1>;
vdda18-supply = <&pm8998_l12>;
vdda33-supply = <&pm8998_l24>;
qcom,vdd-voltage-level = <0 880000 880000>;
+ qcom,qusb-phy-reg-offset =
+ <0x240 /* QUSB2PHY_PORT_TUNE1 */
+ 0x1a0 /* QUSB2PHY_PLL_COMMON_STATUS_ONE */
+ 0x210 /* QUSB2PHY_PWR_CTRL1 */
+ 0x230 /* QUSB2PHY_INTR_CTRL */
+ 0x0a8 /* QUSB2PHY_PLL_CORE_INPUT_OVERRIDE */
+ 0x254>; /* QUSB2PHY_TEST1 */
+
qcom,qusb-phy-init-seq =
/* <value reg_offset> */
<0x23 0x210 /* PWR_CTRL1 */
@@ -133,7 +144,7 @@
0x21 0x214 /* PWR_CTRL2 */
0x00 0x220 /* IMP_CTRL1 */
0x58 0x224 /* IMP_CTRL2 */
- 0x32 0x240 /* TUNE1 */
+ 0x30 0x240 /* TUNE1 */
0x29 0x244 /* TUNE2 */
0xca 0x248 /* TUNE3 */
0x04 0x24c /* TUNE4 */
@@ -141,8 +152,6 @@
0x00 0x23c /* CHG_CTRL2 */
0x22 0x210>; /* PWR_CTRL1 */
- qcom,phy-auto-resume-offset = <0x254>;
-
phy_type= "utmi";
clocks = <&clock_rpmh RPMH_CXO_CLK>,
<&clock_gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>;
@@ -385,6 +394,14 @@
vdda18-supply = <&pm8998_l12>;
vdda33-supply = <&pm8998_l24>;
qcom,vdd-voltage-level = <0 880000 880000>;
+ qcom,qusb-phy-reg-offset =
+ <0x240 /* QUSB2PHY_PORT_TUNE1 */
+ 0x1a0 /* QUSB2PHY_PLL_COMMON_STATUS_ONE */
+ 0x210 /* QUSB2PHY_PWR_CTRL1 */
+ 0x230 /* QUSB2PHY_INTR_CTRL */
+ 0x0a8 /* QUSB2PHY_PLL_CORE_INPUT_OVERRIDE */
+ 0x254>; /* QUSB2PHY_TEST1 */
+
qcom,qusb-phy-init-seq =
/* <value reg_offset> */
<0x23 0x210 /* PWR_CTRL1 */
@@ -398,7 +415,7 @@
0x21 0x214 /* PWR_CTRL2 */
0x00 0x220 /* IMP_CTRL1 */
0x58 0x224 /* IMP_CTRL2 */
- 0x32 0x240 /* TUNE1 */
+ 0x20 0x240 /* TUNE1 */
0x29 0x244 /* TUNE2 */
0xca 0x248 /* TUNE3 */
0x04 0x24c /* TUNE4 */
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 78036eb..8f9618d 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -476,6 +476,10 @@
method = "smc";
};
+ chosen {
+ bootargs = "rcupdate.rcu_expedited=1";
+ };
+
soc: soc { };
vendor: vendor {
diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig
index 9f98841..b60dd01 100644
--- a/arch/arm64/configs/sdm845-perf_defconfig
+++ b/arch/arm64/configs/sdm845-perf_defconfig
@@ -264,9 +264,15 @@
CONFIG_PPP=y
CONFIG_PPP_BSDCOMP=y
CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_FILTER=y
CONFIG_PPP_MPPE=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
CONFIG_PPPOLAC=y
CONFIG_PPPOPNS=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
CONFIG_USB_USBNET=y
CONFIG_WIL6210=m
# CONFIG_WIL6210_TRACING is not set
diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig
index cd4cbb1..37f7d32 100644
--- a/arch/arm64/configs/sdm845_defconfig
+++ b/arch/arm64/configs/sdm845_defconfig
@@ -271,9 +271,15 @@
CONFIG_PPP=y
CONFIG_PPP_BSDCOMP=y
CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_FILTER=y
CONFIG_PPP_MPPE=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
CONFIG_PPPOLAC=y
CONFIG_PPPOPNS=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
CONFIG_USB_USBNET=y
CONFIG_WIL6210=m
CONFIG_WCNSS_MEM_PRE_ALLOC=y
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 44e1d7f..28196b1 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -1,7 +1,6 @@
generic-y += bugs.h
generic-y += clkdev.h
generic-y += cputime.h
-generic-y += current.h
generic-y += delay.h
generic-y += div64.h
generic-y += dma.h
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index a4ae545..ef5970e 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -241,14 +241,25 @@
.endm
/*
+ * @dst: Result of per_cpu(sym, smp_processor_id())
* @sym: The name of the per-cpu variable
- * @reg: Result of per_cpu(sym, smp_processor_id())
* @tmp: scratch register
*/
- .macro this_cpu_ptr, sym, reg, tmp
- adr_l \reg, \sym
+ .macro adr_this_cpu, dst, sym, tmp
+ adr_l \dst, \sym
mrs \tmp, tpidr_el1
- add \reg, \reg, \tmp
+ add \dst, \dst, \tmp
+ .endm
+
+ /*
+ * @dst: Result of READ_ONCE(per_cpu(sym, smp_processor_id()))
+ * @sym: The name of the per-cpu variable
+ * @tmp: scratch register
+ */
+ .macro ldr_this_cpu dst, sym, tmp
+ adr_l \dst, \sym
+ mrs \tmp, tpidr_el1
+ ldr \dst, [\dst, \tmp]
.endm
/*
diff --git a/arch/arm64/include/asm/current.h b/arch/arm64/include/asm/current.h
new file mode 100644
index 0000000..86c4041
--- /dev/null
+++ b/arch/arm64/include/asm/current.h
@@ -0,0 +1,30 @@
+#ifndef __ASM_CURRENT_H
+#define __ASM_CURRENT_H
+
+#include <linux/compiler.h>
+
+#include <asm/sysreg.h>
+
+#ifndef __ASSEMBLY__
+
+struct task_struct;
+
+/*
+ * We don't use read_sysreg() as we want the compiler to cache the value where
+ * possible.
+ */
+static __always_inline struct task_struct *get_current(void)
+{
+ unsigned long sp_el0;
+
+ asm ("mrs %0, sp_el0" : "=r" (sp_el0));
+
+ return (struct task_struct *)sp_el0;
+}
+
+#define current get_current()
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_CURRENT_H */
+
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 0226447..d050d72 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -29,11 +29,22 @@
#ifndef __ASSEMBLY__
+#include <asm/percpu.h>
+
#include <linux/threads.h>
#include <linux/cpumask.h>
#include <linux/thread_info.h>
-#define raw_smp_processor_id() (current_thread_info()->cpu)
+DECLARE_PER_CPU_READ_MOSTLY(int, cpu_number);
+
+/*
+ * We don't use this_cpu_read(cpu_number) as that has implicit writes to
+ * preempt_count, and associated (compiler) barriers, that we'd like to avoid
+ * the expense of. If we're preemptible, the value can be stale at use anyway.
+ * And we can't use this_cpu_ptr() either, as that winds up recursing back
+ * here under CONFIG_DEBUG_PREEMPT=y.
+ */
+#define raw_smp_processor_id() (*raw_cpu_ptr(&cpu_number))
struct seq_file;
@@ -73,6 +84,7 @@
*/
struct secondary_data {
void *stack;
+ struct task_struct *task;
long status;
};
diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h
index b8a313f..de5600f 100644
--- a/arch/arm64/include/asm/suspend.h
+++ b/arch/arm64/include/asm/suspend.h
@@ -1,7 +1,7 @@
#ifndef __ASM_SUSPEND_H
#define __ASM_SUSPEND_H
-#define NR_CTX_REGS 10
+#define NR_CTX_REGS 12
#define NR_CALLEE_SAVED_REGS 12
/*
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index f3a0169..ebd18b7 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -43,50 +43,24 @@
/*
* low level task data that entry.S needs immediate access to.
- * __switch_to() assumes cpu_context follows immediately after cpu_domain.
*/
struct thread_info {
unsigned long flags; /* low level flags */
mm_segment_t addr_limit; /* address limit */
- struct task_struct *task; /* main task structure */
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
u64 ttbr0; /* saved TTBR0_EL1 */
#endif
int preempt_count; /* 0 => preemptable, <0 => bug */
- int cpu; /* cpu */
};
#define INIT_THREAD_INFO(tsk) \
{ \
- .task = &tsk, \
- .flags = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
}
-#define init_thread_info (init_thread_union.thread_info)
#define init_stack (init_thread_union.stack)
-/*
- * how to get the thread information struct from C
- */
-static inline struct thread_info *current_thread_info(void) __attribute_const__;
-
-/*
- * struct thread_info can be accessed directly via sp_el0.
- *
- * We don't use read_sysreg() as we want the compiler to cache the value where
- * possible.
- */
-static inline struct thread_info *current_thread_info(void)
-{
- unsigned long sp_el0;
-
- asm ("mrs %0, sp_el0" : "=r" (sp_el0));
-
- return (struct thread_info *)sp_el0;
-}
-
#define thread_saved_pc(tsk) \
((unsigned long)(tsk->thread.cpu_context.pc))
#define thread_saved_sp(tsk) \
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index fd1c4f6..b3bb7ef 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -36,12 +36,13 @@
{
DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
BLANK();
- DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
- DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
- DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
+ DEFINE(TSK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags));
+ DEFINE(TSK_TI_PREEMPT, offsetof(struct task_struct, thread_info.preempt_count));
+ DEFINE(TSK_TI_ADDR_LIMIT, offsetof(struct task_struct, thread_info.addr_limit));
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
- DEFINE(TSK_TI_TTBR0, offsetof(struct thread_info, ttbr0));
+ DEFINE(TSK_TI_TTBR0, offsetof(struct task_struct, thread_info.ttbr0));
#endif
+ DEFINE(TSK_STACK, offsetof(struct task_struct, stack));
BLANK();
DEFINE(THREAD_CPU_CONTEXT, offsetof(struct task_struct, thread.cpu_context));
BLANK();
@@ -124,6 +125,7 @@
DEFINE(TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
BLANK();
DEFINE(CPU_BOOT_STACK, offsetof(struct secondary_data, stack));
+ DEFINE(CPU_BOOT_TASK, offsetof(struct secondary_data, task));
BLANK();
#ifdef CONFIG_KVM_ARM_HOST
DEFINE(VCPU_CONTEXT, offsetof(struct kvm_vcpu, arch.ctxt));
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index c44a933..718c4c8 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -93,9 +93,8 @@
.if \el == 0
mrs x21, sp_el0
- mov tsk, sp
- and tsk, tsk, #~(THREAD_SIZE - 1) // Ensure MDSCR_EL1.SS is clear,
- ldr x19, [tsk, #TI_FLAGS] // since we can unmask debug
+ ldr_this_cpu tsk, __entry_task, x20 // Ensure MDSCR_EL1.SS is clear,
+ ldr x19, [tsk, #TSK_TI_FLAGS] // since we can unmask debug
disable_step_tsk x19, x20 // exceptions when scheduling.
mov x29, xzr // fp pointed to user-space
@@ -103,10 +102,10 @@
add x21, sp, #S_FRAME_SIZE
get_thread_info tsk
/* Save the task's original addr_limit and set USER_DS (TASK_SIZE_64) */
- ldr x20, [tsk, #TI_ADDR_LIMIT]
+ ldr x20, [tsk, #TSK_TI_ADDR_LIMIT]
str x20, [sp, #S_ORIG_ADDR_LIMIT]
mov x20, #TASK_SIZE_64
- str x20, [tsk, #TI_ADDR_LIMIT]
+ str x20, [tsk, #TSK_TI_ADDR_LIMIT]
/* No need to reset PSTATE.UAO, hardware's already set it to 0 for us */
.endif /* \el == 0 */
mrs x22, elr_el1
@@ -168,7 +167,7 @@
.if \el != 0
/* Restore the task's original addr_limit. */
ldr x20, [sp, #S_ORIG_ADDR_LIMIT]
- str x20, [tsk, #TI_ADDR_LIMIT]
+ str x20, [tsk, #TSK_TI_ADDR_LIMIT]
/* No need to restore UAO, it will be restored from SPSR_EL1 */
.endif
@@ -252,15 +251,16 @@
mov x19, sp // preserve the original sp
/*
- * Compare sp with the current thread_info, if the top
- * ~(THREAD_SIZE - 1) bits match, we are on a task stack, and
- * should switch to the irq stack.
+ * Compare sp with the base of the task stack.
+ * If the top ~(THREAD_SIZE - 1) bits match, we are on a task stack,
+ * and should switch to the irq stack.
*/
- and x25, x19, #~(THREAD_SIZE - 1)
- cmp x25, tsk
- b.ne 9998f
+ ldr x25, [tsk, TSK_STACK]
+ eor x25, x25, x19
+ and x25, x25, #~(THREAD_SIZE - 1)
+ cbnz x25, 9998f
- this_cpu_ptr irq_stack, x25, x26
+ adr_this_cpu x25, irq_stack, x26
mov x26, #IRQ_STACK_START_SP
add x26, x25, x26
@@ -488,9 +488,9 @@
irq_handler
#ifdef CONFIG_PREEMPT
- ldr w24, [tsk, #TI_PREEMPT] // get preempt count
+ ldr w24, [tsk, #TSK_TI_PREEMPT] // get preempt count
cbnz w24, 1f // preempt count != 0
- ldr x0, [tsk, #TI_FLAGS] // get flags
+ ldr x0, [tsk, #TSK_TI_FLAGS] // get flags
tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling?
bl el1_preempt
1:
@@ -505,7 +505,7 @@
el1_preempt:
mov x24, lr
1: bl preempt_schedule_irq // irq en/disable is done inside
- ldr x0, [tsk, #TI_FLAGS] // get new tasks TI_FLAGS
+ ldr x0, [tsk, #TSK_TI_FLAGS] // get new tasks TI_FLAGS
tbnz x0, #TIF_NEED_RESCHED, 1b // needs rescheduling?
ret x24
#endif
@@ -735,8 +735,7 @@
ldp x29, x9, [x8], #16
ldr lr, [x8]
mov sp, x9
- and x9, x9, #~(THREAD_SIZE - 1)
- msr sp_el0, x9
+ msr sp_el0, x1
ret
ENDPROC(cpu_switch_to)
@@ -747,7 +746,7 @@
ret_fast_syscall:
disable_irq // disable interrupts
str x0, [sp, #S_X0] // returned x0
- ldr x1, [tsk, #TI_FLAGS] // re-check for syscall tracing
+ ldr x1, [tsk, #TSK_TI_FLAGS] // re-check for syscall tracing
and x2, x1, #_TIF_SYSCALL_WORK
cbnz x2, ret_fast_syscall_trace
and x2, x1, #_TIF_WORK_MASK
@@ -767,14 +766,14 @@
#ifdef CONFIG_TRACE_IRQFLAGS
bl trace_hardirqs_on // enabled while in userspace
#endif
- ldr x1, [tsk, #TI_FLAGS] // re-check for single-step
+ ldr x1, [tsk, #TSK_TI_FLAGS] // re-check for single-step
b finish_ret_to_user
/*
* "slow" syscall return path.
*/
ret_to_user:
disable_irq // disable interrupts
- ldr x1, [tsk, #TI_FLAGS]
+ ldr x1, [tsk, #TSK_TI_FLAGS]
and x2, x1, #_TIF_WORK_MASK
cbnz x2, work_pending
finish_ret_to_user:
@@ -807,7 +806,7 @@
enable_dbg_and_irq
ct_user_exit 1
- ldr x16, [tsk, #TI_FLAGS] // check for syscall hooks
+ ldr x16, [tsk, #TSK_TI_FLAGS] // check for syscall hooks
tst x16, #_TIF_SYSCALL_WORK
b.ne __sys_trace
cmp scno, sc_nr // check upper syscall limit
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index c7d26bb..7ee6d74 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -428,7 +428,8 @@
__primary_switched:
adrp x4, init_thread_union
add sp, x4, #THREAD_SIZE
- msr sp_el0, x4 // Save thread_info
+ adr_l x5, init_task
+ msr sp_el0, x5 // Save thread_info
adr_l x8, vectors // load VBAR_EL1 with virtual
msr vbar_el1, x8 // vector table address
@@ -699,10 +700,10 @@
isb
adr_l x0, secondary_data
- ldr x0, [x0, #CPU_BOOT_STACK] // get secondary_data.stack
- mov sp, x0
- and x0, x0, #~(THREAD_SIZE - 1)
- msr sp_el0, x0 // save thread_info
+ ldr x1, [x0, #CPU_BOOT_STACK] // get secondary_data.stack
+ mov sp, x1
+ ldr x2, [x0, #CPU_BOOT_TASK]
+ msr sp_el0, x2
mov x29, #0
b secondary_start_kernel
ENDPROC(__secondary_switched)
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index fc1a286..5fe594e 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -45,6 +45,7 @@
#include <linux/personality.h>
#include <linux/notifier.h>
#include <trace/events/power.h>
+#include <linux/percpu.h>
#include <asm/alternative.h>
#include <asm/compat.h>
@@ -390,6 +391,20 @@
}
/*
+ * We store our current task in sp_el0, which is clobbered by userspace. Keep a
+ * shadow copy so that we can restore this upon entry from userspace.
+ *
+ * This is *only* for exception entry from EL0, and is not valid until we
+ * __switch_to() a user task.
+ */
+DEFINE_PER_CPU(struct task_struct *, __entry_task);
+
+static void entry_task_switch(struct task_struct *next)
+{
+ __this_cpu_write(__entry_task, next);
+}
+
+/*
* Thread switching.
*/
struct task_struct *__switch_to(struct task_struct *prev,
@@ -401,6 +416,7 @@
tls_thread_switch(next);
hw_breakpoint_thread_switch(next);
contextidr_thread_switch(next);
+ entry_task_switch(next);
uao_thread_switch(next);
/*
@@ -418,27 +434,35 @@
unsigned long get_wchan(struct task_struct *p)
{
struct stackframe frame;
- unsigned long stack_page;
+ unsigned long stack_page, ret = 0;
int count = 0;
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
+ stack_page = (unsigned long)try_get_task_stack(p);
+ if (!stack_page)
+ return 0;
+
frame.fp = thread_saved_fp(p);
frame.sp = thread_saved_sp(p);
frame.pc = thread_saved_pc(p);
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
frame.graph = p->curr_ret_stack;
#endif
- stack_page = (unsigned long)task_stack_page(p);
do {
if (frame.sp < stack_page ||
frame.sp >= stack_page + THREAD_SIZE ||
unwind_frame(p, &frame))
- return 0;
- if (!in_sched_functions(frame.pc))
- return frame.pc;
+ goto out;
+ if (!in_sched_functions(frame.pc)) {
+ ret = frame.pc;
+ goto out;
+ }
} while (count ++ < 16);
- return 0;
+
+out:
+ put_task_stack(p);
+ return ret;
}
unsigned long arch_align_stack(unsigned long sp)
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 49f3ae0..ae02756 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -312,7 +312,7 @@
* faults in case uaccess_enable() is inadvertently called by the init
* thread.
*/
- init_thread_info.ttbr0 = virt_to_phys(empty_zero_page);
+ init_task.thread_info.ttbr0 = virt_to_phys(empty_zero_page);
#endif
#ifdef CONFIG_VT
diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
index 1bec41b..df67652 100644
--- a/arch/arm64/kernel/sleep.S
+++ b/arch/arm64/kernel/sleep.S
@@ -125,9 +125,6 @@
/* load sp from context */
ldr x2, [x0, #CPU_CTX_SP]
mov sp, x2
- /* save thread_info */
- and x2, x2, #~(THREAD_SIZE - 1)
- msr sp_el0, x2
/*
* cpu_do_resume expects x0 to contain context address pointer
*/
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index df95830..2437f15 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -58,6 +58,9 @@
#define CREATE_TRACE_POINTS
#include <trace/events/ipi.h>
+DEFINE_PER_CPU_READ_MOSTLY(int, cpu_number);
+EXPORT_PER_CPU_SYMBOL(cpu_number);
+
/*
* as from 2.5, kernels no longer have an init_tasks structure
* so we need some other way of telling a new secondary core
@@ -147,6 +150,7 @@
* We need to tell the secondary core where to find its stack and the
* page tables.
*/
+ secondary_data.task = idle;
secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
update_cpu_boot_status(CPU_MMU_OFF);
__flush_dcache_area(&secondary_data, sizeof(secondary_data));
@@ -171,6 +175,7 @@
pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
}
+ secondary_data.task = NULL;
secondary_data.stack = NULL;
status = READ_ONCE(secondary_data.status);
if (ret && status) {
@@ -209,7 +214,10 @@
asmlinkage void secondary_start_kernel(void)
{
struct mm_struct *mm = &init_mm;
- unsigned int cpu = smp_processor_id();
+ unsigned int cpu;
+
+ cpu = task_cpu(current);
+ set_my_cpu_offset(per_cpu_offset(cpu));
/*
* All kernel threads share the same mm context; grab a
@@ -218,8 +226,6 @@
atomic_inc(&mm->mm_count);
current->active_mm = mm;
- set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
-
pr_debug("CPU%u: Booted secondary processor\n", cpu);
/*
@@ -733,6 +739,8 @@
*/
for_each_possible_cpu(cpu) {
+ per_cpu(cpu_number, cpu) = cpu;
+
if (cpu == smp_processor_id())
continue;
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 2e940b1..900c1ec 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -181,6 +181,9 @@
struct stack_trace_data data;
struct stackframe frame;
+ if (!try_get_task_stack(tsk))
+ return;
+
data.trace = trace;
data.skip = trace->skip;
@@ -202,6 +205,8 @@
walk_stackframe(tsk, &frame, save_trace, &data);
if (trace->nr_entries < trace->max_entries)
trace->entries[trace->nr_entries++] = ULONG_MAX;
+
+ put_task_stack(tsk);
}
EXPORT_SYMBOL(save_stack_trace_tsk);
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index bb0cd78..1e3be90 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -47,12 +47,6 @@
cpu_uninstall_idmap();
/*
- * Restore per-cpu offset before any kernel
- * subsystem relying on it has a chance to run.
- */
- set_my_cpu_offset(per_cpu_offset(cpu));
-
- /*
* PSTATE was not saved over suspend/resume, re-enable any detected
* features that might not have been set correctly.
*/
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index cd6c4d9..e576c1d 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -148,6 +148,9 @@
if (!tsk)
tsk = current;
+ if (!try_get_task_stack(tsk))
+ return;
+
/*
* Switching between stacks is valid when tracing current and in
* non-preemptible context.
@@ -213,6 +216,8 @@
stack + sizeof(struct pt_regs));
}
}
+
+ put_task_stack(tsk);
}
void show_stack(struct task_struct *tsk, unsigned long *sp)
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 0a34644..d0ffade 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -40,7 +40,6 @@
#include <asm/system_misc.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
-#include <asm/kryo3xx-arm64-edac.h>
#include <soc/qcom/scm.h>
struct fault_info {
@@ -521,7 +520,6 @@
*/
static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs)
{
- kryo3xx_poll_cache_errors(NULL);
return 1;
}
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 61330c9..8d21250 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -116,11 +116,14 @@
mrs x8, mdscr_el1
mrs x9, oslsr_el1
mrs x10, sctlr_el1
+ mrs x11, tpidr_el1
+ mrs x12, sp_el0
stp x2, x3, [x0]
stp x4, xzr, [x0, #16]
stp x5, x6, [x0, #32]
stp x7, x8, [x0, #48]
stp x9, x10, [x0, #64]
+ stp x11, x12, [x0, #80]
ret
ENDPROC(cpu_do_suspend)
@@ -136,6 +139,7 @@
ldp x6, x8, [x0, #32]
ldp x9, x10, [x0, #48]
ldp x11, x12, [x0, #64]
+ ldp x13, x14, [x0, #80]
msr tpidr_el0, x2
msr tpidrro_el0, x3
msr contextidr_el1, x4
@@ -158,6 +162,8 @@
msr mdscr_el1, x10
msr sctlr_el1, x12
+ msr tpidr_el1, x13
+ msr sp_el0, x14
/*
* Restore oslsr_el1 by writing oslar_el1
*/
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 810d0d6..81929b8 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -126,21 +126,10 @@
int msm_atomic_check(struct drm_device *dev,
struct drm_atomic_state *state)
{
- struct msm_drm_private *priv;
-
- if (!dev)
- return -EINVAL;
-
if (msm_is_suspend_blocked(dev)) {
DRM_DEBUG("rejecting commit during suspend\n");
return -EBUSY;
}
-
- priv = dev->dev_private;
- if (priv && priv->kms && priv->kms->funcs &&
- priv->kms->funcs->atomic_check)
- return priv->kms->funcs->atomic_check(priv->kms, state);
-
return drm_atomic_helper_check(dev, state);
}
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index eb10d6b..35e6b71 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -75,9 +75,6 @@
const struct msm_format *msm_fmt,
const struct drm_mode_fb_cmd2 *cmd,
struct drm_gem_object **bos);
- /* perform complete atomic check of given atomic state */
- int (*atomic_check)(struct msm_kms *kms,
- struct drm_atomic_state *state);
/* misc: */
long (*round_pixclk)(struct msm_kms *kms, unsigned long rate,
struct drm_encoder *encoder);
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 368181f..63979dd 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -2021,6 +2021,16 @@
if (unlikely(!sde_crtc->num_mixers))
return;
+ /*
+ * For planes without commit update, drm framework will not add
+ * those planes to current state since hardware update is not
+ * required. However, if those planes were power collapsed since
+ * last commit cycle, driver has to restore the hardware state
+ * of those planes explicitly here prior to plane flush.
+ */
+ drm_atomic_crtc_for_each_plane(plane, crtc)
+ sde_plane_restore(plane);
+
/* wait for acquire fences before anything else is done */
_sde_crtc_wait_for_fences(crtc);
@@ -2339,8 +2349,6 @@
_sde_crtc_rp_duplicate(&old_cstate->rp, &cstate->rp);
- cstate->idle_pc = sde_crtc->idle_pc;
-
return &cstate->base;
}
@@ -2441,24 +2449,6 @@
sde_encoder_virt_restore(encoder);
}
- } else if (event_type == SDE_POWER_EVENT_PRE_DISABLE) {
- /*
- * Serialize h/w idle state update with crtc atomic check.
- * Grab the modeset lock to ensure that there is no on-going
- * atomic check, then increment the idle_pc counter. The next
- * atomic check will detect a new idle_pc since the counter
- * has advanced between the old_state and new_state, and
- * therefore properly reprogram all relevant drm objects'
- * hardware.
- */
- drm_modeset_lock_crtc(crtc, NULL);
-
- sde_crtc->idle_pc++;
-
- SDE_DEBUG("crtc%d idle_pc:%d\n", crtc->base.id,
- sde_crtc->idle_pc);
- SDE_EVT32(DRMID(crtc), sde_crtc->idle_pc);
-
} else if (event_type == SDE_POWER_EVENT_POST_DISABLE) {
struct drm_plane *plane;
@@ -2469,7 +2459,6 @@
drm_atomic_crtc_for_each_plane(plane, crtc)
sde_plane_set_revalidate(plane, true);
- drm_modeset_unlock_crtc(crtc);
sde_cp_crtc_suspend(crtc);
}
@@ -2599,8 +2588,7 @@
sde_crtc->power_event = sde_power_handle_register_event(
&priv->phandle,
- SDE_POWER_EVENT_POST_ENABLE | SDE_POWER_EVENT_POST_DISABLE |
- SDE_POWER_EVENT_PRE_DISABLE,
+ SDE_POWER_EVENT_POST_ENABLE | SDE_POWER_EVENT_POST_DISABLE,
sde_crtc_handle_power_event, crtc, sde_crtc->name);
}
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h
index f021477..0d72ff1 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.h
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.h
@@ -125,7 +125,6 @@
* @vblank_cb_time : ktime at vblank count reset
* @vblank_refcount : reference count for vblank enable request
* @suspend : whether or not a suspend operation is in progress
- * @idle_pc : count of current idle power collapse request
* @feature_list : list of color processing features supported on a crtc
* @active_list : list of color processing features are active
* @dirty_list : list of color processing features are dirty
@@ -174,7 +173,6 @@
ktime_t vblank_cb_time;
atomic_t vblank_refcount;
bool suspend;
- u32 idle_pc;
struct list_head feature_list;
struct list_head active_list;
@@ -280,7 +278,6 @@
* @sbuf_cfg: stream buffer configuration
* @sbuf_prefill_line: number of line for inline rotator prefetch
* @sbuf_flush_mask: flush mask for inline rotator
- * @idle_pc: count of idle power collapse request when state is duplicated
*/
struct sde_crtc_state {
struct drm_crtc_state base;
@@ -310,8 +307,6 @@
u32 sbuf_prefill_line;
u32 sbuf_flush_mask;
- u32 idle_pc;
-
struct sde_crtc_respool rp;
};
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 7b620bf..b9fbd62 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -1376,48 +1376,6 @@
sde_crtc_cancel_pending_flip(priv->crtcs[i], file);
}
-static int sde_kms_atomic_check(struct msm_kms *kms,
- struct drm_atomic_state *state)
-{
- struct sde_kms *sde_kms = to_sde_kms(kms);
- struct drm_device *dev = sde_kms->dev;
- struct drm_crtc *crtc;
- struct drm_crtc_state *crtc_state;
- int rc, i;
-
- if (!kms || !state)
- return -EINVAL;
-
- /*
- * Add planes (and other affected DRM objects, if any) to new state
- * if idle power collapse occurred since previous commit.
- * Since atomic state is a delta from the last, if the user-space
- * did not request any changes on a plane/connector, that object
- * will not be included in the new atomic state. Idle power collapse
- * is driver-autonomous, so the driver needs to ensure that all
- * hardware is reprogrammed as the power comes back on by forcing
- * the drm objects attached to the CRTC into the new atomic state.
- */
- for_each_crtc_in_state(state, crtc, crtc_state, i) {
- struct sde_crtc_state *cstate = to_sde_crtc_state(crtc_state);
- struct sde_crtc_state *old_cstate =
- to_sde_crtc_state(crtc->state);
-
- if (cstate->idle_pc != old_cstate->idle_pc) {
- SDE_DEBUG("crtc%d idle_pc:%d/%d\n",
- crtc->base.id, cstate->idle_pc,
- old_cstate->idle_pc);
- SDE_EVT32(DRMID(crtc), cstate->idle_pc,
- old_cstate->idle_pc);
- rc = drm_atomic_add_affected_planes(state, crtc);
- if (rc)
- return rc;
- }
- }
-
- return drm_atomic_helper_check(dev, state);
-}
-
static struct msm_gem_address_space*
_sde_kms_get_address_space(struct msm_kms *kms,
unsigned int domain)
@@ -1458,7 +1416,6 @@
.enable_vblank = sde_kms_enable_vblank,
.disable_vblank = sde_kms_disable_vblank,
.check_modified_format = sde_format_check_modified_format,
- .atomic_check = sde_kms_atomic_check,
.get_format = sde_get_msm_format,
.round_pixclk = sde_kms_round_pixclk,
.destroy = sde_kms_destroy,
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c
index b185359..8077756 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.c
+++ b/drivers/gpu/drm/msm/sde/sde_plane.c
@@ -3574,6 +3574,29 @@
}
}
+void sde_plane_restore(struct drm_plane *plane)
+{
+ struct sde_plane *psde;
+
+ if (!plane || !plane->state) {
+ SDE_ERROR("invalid plane\n");
+ return;
+ }
+
+ psde = to_sde_plane(plane);
+
+ /*
+ * Revalidate is only true here if idle PC occurred and
+ * there is no plane state update in current commit cycle.
+ */
+ if (!psde->revalidate)
+ return;
+
+ SDE_DEBUG_PLANE(psde, "\n");
+
+ /* last plane state is same as current state */
+ sde_plane_atomic_update(plane, plane->state);
+}
/* helper to install properties which are common to planes and crtcs */
static void _sde_plane_install_properties(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.h b/drivers/gpu/drm/msm/sde/sde_plane.h
index 3a36ea0..be0ea67 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.h
+++ b/drivers/gpu/drm/msm/sde/sde_plane.h
@@ -217,6 +217,12 @@
bool sde_plane_is_sbuf_mode(struct drm_plane *plane, u32 *prefill);
/**
+ * sde_plane_restore - restore hw state if previously power collapsed
+ * @plane: Pointer to drm plane structure
+ */
+void sde_plane_restore(struct drm_plane *plane);
+
+/**
* sde_plane_flush - final plane operations before commit flush
* @plane: Pointer to drm plane structure
*/
diff --git a/drivers/gpu/msm/adreno_a6xx_snapshot.c b/drivers/gpu/msm/adreno_a6xx_snapshot.c
index ed0129f..1f97888 100644
--- a/drivers/gpu/msm/adreno_a6xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a6xx_snapshot.c
@@ -205,13 +205,16 @@
0x3410, 0x3410, 0x3800, 0x3801,
};
-static const unsigned int a6xx_gmu_registers[] = {
+static const unsigned int a6xx_gmu_gx_registers[] = {
/* GMU GX */
0x1A800, 0x1A800, 0x1A810, 0x1A813, 0x1A816, 0x1A816, 0x1A818, 0x1A81B,
0x1A81E, 0x1A81E, 0x1A820, 0x1A823, 0x1A826, 0x1A826, 0x1A828, 0x1A82B,
0x1A82E, 0x1A82E, 0x1A830, 0x1A833, 0x1A836, 0x1A836, 0x1A838, 0x1A83B,
0x1A83E, 0x1A83E, 0x1A840, 0x1A843, 0x1A846, 0x1A846, 0x1A880, 0x1A884,
0x1A900, 0x1A92B, 0x1A940, 0x1A940,
+};
+
+static const unsigned int a6xx_gmu_registers[] = {
/* GMU TCM */
0x1B400, 0x1C3FF, 0x1C400, 0x1D3FF,
/* GMU CX */
@@ -1321,11 +1324,19 @@
static void a6xx_snapshot_gmu(struct kgsl_device *device,
struct kgsl_snapshot *snapshot)
{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
+
if (!kgsl_gmu_isenabled(device))
return;
adreno_snapshot_registers(device, snapshot, a6xx_gmu_registers,
ARRAY_SIZE(a6xx_gmu_registers) / 2);
+
+ if (gpudev->gx_is_on(adreno_dev))
+ adreno_snapshot_registers(device, snapshot,
+ a6xx_gmu_gx_registers,
+ ARRAY_SIZE(a6xx_gmu_gx_registers) / 2);
}
/* a6xx_snapshot_sqe() - Dump SQE data in snapshot */
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 4e67efb..129e99c 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -2225,21 +2225,23 @@
if (fd != 0)
dmabuf = dma_buf_get(fd - 1);
}
- up_read(¤t->mm->mmap_sem);
- if (IS_ERR_OR_NULL(dmabuf))
+ if (IS_ERR_OR_NULL(dmabuf)) {
+ up_read(¤t->mm->mmap_sem);
return dmabuf ? PTR_ERR(dmabuf) : -ENODEV;
+ }
ret = kgsl_setup_dma_buf(device, pagetable, entry, dmabuf);
if (ret) {
dma_buf_put(dmabuf);
+ up_read(¤t->mm->mmap_sem);
return ret;
}
/* Setup the user addr/cache mode for cache operations */
entry->memdesc.useraddr = hostptr;
_setup_cache_mode(entry, vma);
-
+ up_read(¤t->mm->mmap_sem);
return 0;
}
#else
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index 051ab8e..6aa2e36 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -123,32 +123,40 @@
static void geni_i2c_err(struct geni_i2c_dev *gi2c, int err)
{
- u32 m_stat = readl_relaxed(gi2c->base + SE_GENI_M_IRQ_STATUS);
- u32 rx_st = readl_relaxed(gi2c->base + SE_GENI_RX_FIFO_STATUS);
- u32 tx_st = readl_relaxed(gi2c->base + SE_GENI_TX_FIFO_STATUS);
u32 m_cmd = readl_relaxed(gi2c->base + SE_GENI_M_CMD0);
+ u32 m_stat = readl_relaxed(gi2c->base + SE_GENI_M_IRQ_STATUS);
u32 geni_s = readl_relaxed(gi2c->base + SE_GENI_STATUS);
u32 geni_ios = readl_relaxed(gi2c->base + SE_GENI_IOS);
+ u32 dma = readl_relaxed(gi2c->base + SE_GENI_DMA_MODE_EN);
+ u32 rx_st, tx_st;
+
+ if (gi2c->cur)
+ GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev,
+ "len:%d, slv-addr:0x%x, RD/WR:%d\n", gi2c->cur->len,
+ gi2c->cur->addr, gi2c->cur->flags);
if (err == I2C_NACK || err == GENI_ABORT_DONE) {
GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s\n",
- gi2c_log[err].msg);
- GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev,
- "m_stat:0x%x, tx_stat:0x%x, rx_stat:0x%x, ",
- m_stat, tx_st, rx_st);
- GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev,
- "m_cmd:0x%x, geni_status:0x%x, geni_ios:0x%x\n",
- m_cmd, geni_s, geni_ios);
+ gi2c_log[err].msg);
+ goto err_ret;
} else {
GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "%s\n",
gi2c_log[err].msg);
- GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev,
- "m_stat:0x%x, tx_stat:0x%x, rx_stat:0x%x, ",
- m_stat, tx_st, rx_st);
- GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev,
+ }
+ if (dma) {
+ rx_st = readl_relaxed(gi2c->base + SE_DMA_RX_IRQ_STAT);
+ tx_st = readl_relaxed(gi2c->base + SE_DMA_TX_IRQ_STAT);
+ } else {
+ rx_st = readl_relaxed(gi2c->base + SE_GENI_RX_FIFO_STATUS);
+ tx_st = readl_relaxed(gi2c->base + SE_GENI_TX_FIFO_STATUS);
+ }
+ GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev,
+ "DMA:%d tx_stat:0x%x, rx_stat:0x%x, irq-stat:0x%x\n",
+ dma, tx_st, rx_st, m_stat);
+ GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev,
"m_cmd:0x%x, geni_status:0x%x, geni_ios:0x%x\n",
m_cmd, geni_s, geni_ios);
- }
+err_ret:
gi2c->err = gi2c_log[err].err;
}
@@ -185,7 +193,6 @@
if (!dma)
writel_relaxed(0, (gi2c->base +
SE_GENI_TX_WATERMARK_REG));
- gi2c->err = -EIO;
goto irqret;
}
@@ -310,11 +317,12 @@
ret = geni_se_rx_dma_prep(gi2c->wrapper_dev,
gi2c->base, msgs[i].buf,
msgs[i].len, &rx_dma);
- if (ret)
+ if (ret) {
mode = FIFO_MODE;
+ ret = geni_se_select_mode(gi2c->base,
+ mode);
+ }
}
- if (mode == FIFO_MODE)
- geni_se_select_mode(gi2c->base, mode);
} else {
dev_dbg(gi2c->dev,
"WRITE:n:%d,i:%d len:%d, stretch:%d, m_param:0x%x\n",
@@ -327,15 +335,15 @@
ret = geni_se_tx_dma_prep(gi2c->wrapper_dev,
gi2c->base, msgs[i].buf,
msgs[i].len, &tx_dma);
- if (ret)
+ if (ret) {
mode = FIFO_MODE;
+ ret = geni_se_select_mode(gi2c->base,
+ mode);
+ }
}
- if (mode == FIFO_MODE) {
- geni_se_select_mode(gi2c->base, mode);
- /* Get FIFO IRQ */
+ if (mode == FIFO_MODE) /* Get FIFO IRQ */
geni_write_reg(1, gi2c->base,
SE_GENI_TX_WATERMARK_REG);
- }
}
/* Ensure FIFO write go through before waiting for Done evet */
mb();
diff --git a/drivers/irqchip/qcom/pdc-sdm670.c b/drivers/irqchip/qcom/pdc-sdm670.c
index 046a595..7bd6333 100644
--- a/drivers/irqchip/qcom/pdc-sdm670.c
+++ b/drivers/irqchip/qcom/pdc-sdm670.c
@@ -126,7 +126,7 @@
{122, 669}, /* core_bi_px_gpio_41 */
{123, 670}, /* core_bi_px_gpio_89 */
{124, 671}, /* core_bi_px_gpio_31 */
- {125, 672}, /* core_bi_px_gpio_49 */
+ {125, 95}, /* core_bi_px_gpio_49 */
{-1}
};
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index acca9f4..6e28e70 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -804,6 +804,10 @@
}
bufreq->buffer_count_min =
MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS;
+ bufreq->buffer_count_min_host =
+ MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS;
+ bufreq->buffer_count_actual =
+ MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS;
if (msm_comm_get_stream_output_mode(inst) ==
HAL_VIDEO_DECODER_SECONDARY) {
@@ -819,6 +823,10 @@
bufreq->buffer_count_min =
MIN_NUM_THUMBNAIL_MODE_CAPTURE_BUFFERS;
+ bufreq->buffer_count_min_host =
+ MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS;
+ bufreq->buffer_count_actual =
+ MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS;
bufreq = get_buff_req_buffer(inst,
HAL_BUFFER_OUTPUT2);
@@ -831,6 +839,11 @@
bufreq->buffer_count_min =
MIN_NUM_THUMBNAIL_MODE_CAPTURE_BUFFERS;
+ bufreq->buffer_count_min_host =
+ MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS;
+ bufreq->buffer_count_actual =
+ MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS;
+
} else {
bufreq = get_buff_req_buffer(inst,
@@ -843,6 +856,10 @@
}
bufreq->buffer_count_min =
MIN_NUM_THUMBNAIL_MODE_CAPTURE_BUFFERS;
+ bufreq->buffer_count_min_host =
+ MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS;
+ bufreq->buffer_count_actual =
+ MIN_NUM_THUMBNAIL_MODE_OUTPUT_BUFFERS;
}
diff --git a/drivers/platform/msm/seemp_core/seemp_logk.c b/drivers/platform/msm/seemp_core/seemp_logk.c
index a528e16..e55260d 100644
--- a/drivers/platform/msm/seemp_core/seemp_logk.c
+++ b/drivers/platform/msm/seemp_core/seemp_logk.c
@@ -13,6 +13,11 @@
#define pr_fmt(fmt) "seemp: %s: " fmt, __func__
+#include <linux/delay.h>
+#include <linux/kthread.h>
+#include <linux/seemp_instrumentation.h>
+#include <soc/qcom/scm.h>
+
#include "seemp_logk.h"
#include "seemp_ringbuf.h"
@@ -24,6 +29,8 @@
#define FOUR_MB 4
#define YEAR_BASE 1900
+#define EL2_SCM_ID 0x02001902
+
static struct seemp_logk_dev *slogk_dev;
static unsigned int ring_sz = FOUR_MB;
@@ -49,11 +56,15 @@
static struct seemp_source_mask *pmask;
static unsigned int num_sources;
+static void *el2_shared_mem;
+static struct task_struct *rtic_thread;
+
static long seemp_logk_reserve_rdblks(
struct seemp_logk_dev *sdev, unsigned long arg);
static long seemp_logk_set_mask(unsigned long arg);
static long seemp_logk_set_mapping(unsigned long arg);
static long seemp_logk_check_filter(unsigned long arg);
+static int seemp_logk_rtic_thread(void *data);
void* (*seemp_logk_kernel_begin)(char **buf);
@@ -569,6 +580,15 @@
}
}
+ if (!rtic_thread && el2_shared_mem) {
+ rtic_thread = kthread_run(seemp_logk_rtic_thread,
+ NULL, "seemp_logk_rtic_thread");
+ if (IS_ERR(rtic_thread)) {
+ pr_err("rtic_thread creation failed");
+ rtic_thread = NULL;
+ }
+ }
+
return 0;
}
@@ -580,10 +600,59 @@
.mmap = seemp_logk_mmap,
};
+static int seemp_logk_rtic_thread(void *data)
+{
+ struct el2_report_header_t *header;
+ __u64 last_sequence_number = 0;
+ int last_pos = -1;
+ int i;
+ int num_entries = (PAGE_SIZE - sizeof(struct el2_report_header_t))
+ / sizeof(struct el2_report_data_t);
+ header = (struct el2_report_header_t *) el2_shared_mem;
+
+ while (!kthread_should_stop()) {
+ for (i = 1; i < num_entries + 1; i++) {
+ struct el2_report_data_t *report;
+ int cur_pos = last_pos + i;
+
+ if (cur_pos >= num_entries)
+ cur_pos -= num_entries;
+
+ report = el2_shared_mem +
+ sizeof(struct el2_report_header_t) +
+ cur_pos * sizeof(struct el2_report_data_t);
+
+ /* determine legitimacy of report */
+ if (report->report_valid &&
+ report->sequence_number <=
+ header->num_incidents &&
+ (last_sequence_number == 0
+ || report->sequence_number >
+ last_sequence_number)) {
+ seemp_logk_rtic(report->report_type,
+ report->report.incident.actor,
+ report->report.incident.asset_id,
+ report->report.incident.asset_category,
+ report->report.incident.response);
+ last_sequence_number = report->sequence_number;
+ } else {
+ last_pos = cur_pos - 1;
+ break;
+ }
+ }
+
+ /* periodically check el2 report every second */
+ ssleep(1);
+ }
+
+ return 0;
+}
+
__init int seemp_logk_init(void)
{
int ret;
int devno = 0;
+ struct scm_desc desc = {0};
num_sources = 0;
kmalloc_flag = 0;
@@ -650,6 +719,21 @@
init_waitqueue_head(&slogk_dev->readers_wq);
init_waitqueue_head(&slogk_dev->writers_wq);
rwlock_init(&filter_lock);
+
+ el2_shared_mem = (void *) __get_free_page(GFP_KERNEL);
+ if (el2_shared_mem) {
+ desc.arginfo = SCM_ARGS(2, SCM_RW, SCM_VAL);
+ desc.args[0] = (uint64_t) virt_to_phys(el2_shared_mem);
+ desc.args[1] = PAGE_SIZE;
+ ret = scm_call2(EL2_SCM_ID, &desc);
+ if (ret || desc.ret[0] || desc.ret[1]) {
+ pr_err("SCM call failed with ret val = %d %d %d",
+ ret, (int)desc.ret[0], (int)desc.ret[1]);
+ free_page((unsigned long) el2_shared_mem);
+ el2_shared_mem = NULL;
+ }
+ }
+
return 0;
class_destroy_fail:
class_destroy(cl);
@@ -666,6 +750,11 @@
{
dev_t devno = MKDEV(slogk_dev->major, slogk_dev->minor);
+ if (rtic_thread) {
+ kthread_stop(rtic_thread);
+ rtic_thread = NULL;
+ }
+
seemp_logk_detach();
cdev_del(&slogk_dev->cdev);
diff --git a/drivers/platform/msm/seemp_core/seemp_logk.h b/drivers/platform/msm/seemp_core/seemp_logk.h
index 1a41d4c..871de0e 100644
--- a/drivers/platform/msm/seemp_core/seemp_logk.h
+++ b/drivers/platform/msm/seemp_core/seemp_logk.h
@@ -158,4 +158,45 @@
__u32 hash;
bool isOn;
};
+
+/* report region header */
+struct el2_report_header_t {
+ __u64 report_version; /* Version of the EL2 report */
+ __u64 mp_catalog_version;
+ /* Version of MP catalogue used for kernel protection */
+ __u8 protection_enabled; /* Kernel Assets protected by EL2 */
+ __u8 pad1;
+ __u8 pad2;
+ __u8 pad3;
+ __u32 pad4;
+ __u64 num_incidents; /* Number of Incidents Observed by EL2 */
+};
+
+/* individual report contents */
+union el2_report {
+ struct {
+ __u8 asset_id[0x20]; /* Asset Identifier */
+ __u64 actor;
+ /* Actor that caused the Incident. */
+ __u8 asset_category; /* Asset Category */
+ __u8 response; /* Response From EL2 */
+ __u16 pad1;
+ __u32 pad2;
+ } incident;
+ struct {
+ __u64 reserved; /* TBD */
+ } info;
+};
+
+/* individual report */
+struct el2_report_data_t {
+ __u8 report_valid;
+ /* Flag to indicate whether report instance is valid */
+ __u8 report_type; /* Report Type */
+ __u8 pad1;
+ __u8 pad2;
+ __u64 sequence_number; /* Sequence number of the report */
+ union el2_report report; /* Report Contents */
+};
+
#endif
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 4c67c80..ae44f01 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -3688,6 +3688,7 @@
vote(chg->usb_icl_votable, DCP_VOTER, false, 0);
vote(chg->usb_icl_votable, PL_USBIN_USBIN_VOTER, false, 0);
vote(chg->usb_icl_votable, SW_QC3_VOTER, false, 0);
+ vote(chg->usb_icl_votable, OTG_VOTER, false, 0);
/* reset hvdcp voters */
vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, true, 0);
@@ -3849,6 +3850,12 @@
smblib_handle_typec_removal(chg);
}
+ /* suspend usb if sink */
+ if (chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT)
+ vote(chg->usb_icl_votable, OTG_VOTER, true, 0);
+ else
+ vote(chg->usb_icl_votable, OTG_VOTER, false, 0);
+
smblib_dbg(chg, PR_INTERRUPT, "IRQ: cc-state-change; Type-C %s detected\n",
smblib_typec_mode_name[chg->typec_mode]);
}
@@ -3896,6 +3903,12 @@
return IRQ_HANDLED;
}
+ if (chg->pr_swap_in_progress) {
+ smblib_dbg(chg, PR_INTERRUPT,
+ "Ignoring since pr_swap_in_progress\n");
+ return IRQ_HANDLED;
+ }
+
mutex_lock(&chg->lock);
smblib_usb_typec_change(chg);
mutex_unlock(&chg->lock);
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index a2168f0..5c7819e 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -65,6 +65,7 @@
#define OTG_DELAY_VOTER "OTG_DELAY_VOTER"
#define USBIN_I_VOTER "USBIN_I_VOTER"
#define WEAK_CHARGER_VOTER "WEAK_CHARGER_VOTER"
+#define OTG_VOTER "OTG_VOTER"
#define VCONN_MAX_ATTEMPTS 3
#define OTG_MAX_ATTEMPTS 3
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 7ad650e..d75f157 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2408,6 +2408,14 @@
count = rdev->deferred_disables;
rdev->deferred_disables = 0;
+ /*
+ * Workqueue functions queue the new work instance while the previous
+ * work instance is being processed. Cancel the queued work instance
+ * as the work instance under processing does the job of the queued
+ * work instance.
+ */
+ cancel_delayed_work(&rdev->disable_work);
+
for (i = 0; i < count; i++) {
ret = _regulator_disable(rdev);
if (ret != 0)
@@ -2451,10 +2459,10 @@
mutex_lock(&rdev->mutex);
rdev->deferred_disables++;
+ mod_delayed_work(system_power_efficient_wq, &rdev->disable_work,
+ msecs_to_jiffies(ms));
mutex_unlock(&rdev->mutex);
- queue_delayed_work(system_power_efficient_wq, &rdev->disable_work,
- msecs_to_jiffies(ms));
return 0;
}
EXPORT_SYMBOL_GPL(regulator_disable_deferred);
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 28f89bf..cded512 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -13,6 +13,7 @@
#define pr_fmt(fmt) "icnss: " fmt
#include <asm/dma-iommu.h>
+#include <linux/of_address.h>
#include <linux/clk.h>
#include <linux/iommu.h>
#include <linux/export.h>
@@ -4160,6 +4161,9 @@
int i;
struct device *dev = &pdev->dev;
struct icnss_priv *priv;
+ const __be32 *addrp;
+ u64 prop_size = 0;
+ struct device_node *np;
if (penv) {
icnss_pr_err("Driver is already initialized\n");
@@ -4231,24 +4235,53 @@
}
}
- ret = of_property_read_u32(dev->of_node, "qcom,wlan-msa-memory",
- &priv->msa_mem_size);
+ np = of_parse_phandle(dev->of_node,
+ "qcom,wlan-msa-fixed-region", 0);
+ if (np) {
+ addrp = of_get_address(np, 0, &prop_size, NULL);
+ if (!addrp) {
+ icnss_pr_err("Failed to get assigned-addresses or property\n");
+ ret = -EINVAL;
+ goto out;
+ }
- if (ret || priv->msa_mem_size == 0) {
- icnss_pr_err("Fail to get MSA Memory Size: %u, ret: %d\n",
- priv->msa_mem_size, ret);
- goto out;
+ priv->msa_pa = of_translate_address(np, addrp);
+ if (priv->msa_pa == OF_BAD_ADDR) {
+ icnss_pr_err("Failed to translate MSA PA from device-tree\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ priv->msa_va = memremap(priv->msa_pa,
+ (unsigned long)prop_size, MEMREMAP_WT);
+ if (!priv->msa_va) {
+ icnss_pr_err("MSA PA ioremap failed: phy addr: %pa\n",
+ &priv->msa_pa);
+ ret = -EINVAL;
+ goto out;
+ }
+ priv->msa_mem_size = prop_size;
+ } else {
+ ret = of_property_read_u32(dev->of_node, "qcom,wlan-msa-memory",
+ &priv->msa_mem_size);
+ if (ret || priv->msa_mem_size == 0) {
+ icnss_pr_err("Fail to get MSA Memory Size: %u ret: %d\n",
+ priv->msa_mem_size, ret);
+ goto out;
+ }
+
+ priv->msa_va = dmam_alloc_coherent(&pdev->dev,
+ priv->msa_mem_size, &priv->msa_pa, GFP_KERNEL);
+
+ if (!priv->msa_va) {
+ icnss_pr_err("DMA alloc failed for MSA\n");
+ ret = -ENOMEM;
+ goto out;
+ }
}
- priv->msa_va = dmam_alloc_coherent(&pdev->dev, priv->msa_mem_size,
- &priv->msa_pa, GFP_KERNEL);
- if (!priv->msa_va) {
- icnss_pr_err("DMA alloc failed for MSA\n");
- ret = -ENOMEM;
- goto out;
- }
- icnss_pr_dbg("MSA pa: %pa, MSA va: 0x%p\n", &priv->msa_pa,
- priv->msa_va);
+ icnss_pr_dbg("MSA pa: %pa, MSA va: 0x%p MSA Memory Size: 0x%x\n",
+ &priv->msa_pa, (void *)priv->msa_va, priv->msa_mem_size);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"smmu_iova_base");
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 9ea4a9f..4082a7d 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -3,7 +3,7 @@
* drivers/staging/android/ion/ion.c
*
* Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -76,7 +76,7 @@
* @dev: backpointer to ion device
* @handles: an rb tree of all the handles in this client
* @idr: an idr space for allocating handle ids
- * @lock: lock protecting the tree of handles
+ * @lock: lock protecting the tree of handles and idr
* @name: used for debugging
* @display_name: used for debugging (unique version of @name)
* @display_serial: used for debugging (to make display_name unique)
@@ -91,7 +91,6 @@
struct ion_device *dev;
struct rb_root handles;
struct idr idr;
- /* Protects idr */
struct mutex lock;
char *name;
char *display_name;
@@ -671,8 +670,8 @@
mutex_unlock(&client->lock);
return -ENODEV;
}
- mutex_unlock(&client->lock);
ret = buffer->heap->ops->phys(buffer->heap, buffer, addr, len);
+ mutex_unlock(&client->lock);
return ret;
}
EXPORT_SYMBOL(ion_phys);
@@ -777,33 +776,7 @@
}
EXPORT_SYMBOL(ion_unmap_kernel);
-static struct mutex debugfs_mutex;
static struct rb_root *ion_root_client;
-static int is_client_alive(struct ion_client *client)
-{
- struct rb_node *node;
- struct ion_client *tmp;
- struct ion_device *dev;
-
- node = ion_root_client->rb_node;
- dev = container_of(ion_root_client, struct ion_device, clients);
-
- down_read(&dev->lock);
- while (node) {
- tmp = rb_entry(node, struct ion_client, node);
- if (client < tmp) {
- node = node->rb_left;
- } else if (client > tmp) {
- node = node->rb_right;
- } else {
- up_read(&dev->lock);
- return 1;
- }
- }
-
- up_read(&dev->lock);
- return 0;
-}
static int ion_debug_client_show(struct seq_file *s, void *unused)
{
@@ -814,14 +787,6 @@
"heap_name", "size_in_bytes", "handle refcount",
"buffer");
- mutex_lock(&debugfs_mutex);
- if (!is_client_alive(client)) {
- seq_printf(s, "ion_client 0x%p dead, can't dump its buffers\n",
- client);
- mutex_unlock(&debugfs_mutex);
- return 0;
- }
-
mutex_lock(&client->lock);
for (n = rb_first(&client->handles); n; n = rb_next(n)) {
struct ion_handle *handle = rb_entry(n, struct ion_handle,
@@ -836,7 +801,6 @@
seq_puts(s, "\n");
}
mutex_unlock(&client->lock);
- mutex_unlock(&debugfs_mutex);
return 0;
}
@@ -967,27 +931,27 @@
struct rb_node *n;
pr_debug("%s: %d\n", __func__, __LINE__);
- mutex_lock(&debugfs_mutex);
+ down_write(&dev->lock);
+ rb_erase(&client->node, &dev->clients);
+ up_write(&dev->lock);
+
+ /* After this completes, there are no more references to client */
+ debugfs_remove_recursive(client->debug_root);
+
+ mutex_lock(&client->lock);
while ((n = rb_first(&client->handles))) {
struct ion_handle *handle = rb_entry(n, struct ion_handle,
node);
ion_handle_destroy(&handle->ref);
}
+ mutex_unlock(&client->lock);
idr_destroy(&client->idr);
-
- down_write(&dev->lock);
if (client->task)
put_task_struct(client->task);
- rb_erase(&client->node, &dev->clients);
- debugfs_remove_recursive(client->debug_root);
-
- up_write(&dev->lock);
-
kfree(client->display_name);
kfree(client->name);
kfree(client);
- mutex_unlock(&debugfs_mutex);
}
EXPORT_SYMBOL(ion_client_destroy);
@@ -1794,7 +1758,7 @@
seq_printf(s, "%16s %16s %16s\n", "client", "pid", "size");
seq_puts(s, "----------------------------------------------------\n");
- mutex_lock(&debugfs_mutex);
+ down_read(&dev->lock);
for (n = rb_first(&dev->clients); n; n = rb_next(n)) {
struct ion_client *client = rb_entry(n, struct ion_client,
node);
@@ -1813,7 +1777,7 @@
client->pid, size);
}
}
- mutex_unlock(&debugfs_mutex);
+ up_read(&dev->lock);
seq_puts(s, "----------------------------------------------------\n");
seq_puts(s, "orphaned allocations (info is from last known client):\n");
@@ -2048,7 +2012,6 @@
plist_head_init(&idev->heaps);
idev->clients = RB_ROOT;
ion_root_client = &idev->clients;
- mutex_init(&debugfs_mutex);
return idev;
}
EXPORT_SYMBOL(ion_device_create);
diff --git a/drivers/usb/dwc3/dbm.c b/drivers/usb/dwc3/dbm.c
index 285cd5a..3860a1a 100644
--- a/drivers/usb/dwc3/dbm.c
+++ b/drivers/usb/dwc3/dbm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -129,7 +129,7 @@
enum dbm_reg reg, int ep,
const u32 mask, u32 val)
{
- u32 shift = find_first_bit((void *)&mask, 32);
+ u32 shift = __ffs(mask);
u32 offset = dbm->reg_table[reg].offset +
(dbm->reg_table[reg].ep_mult * ep);
u32 tmp = ioread32(dbm->base + offset);
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index a496468..81f3384 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -319,7 +319,7 @@
u32 offset,
const u32 mask)
{
- u32 shift = ffs(mask);
+ u32 shift = __ffs(mask);
u32 val = ioread32(base + offset);
val &= mask; /* clear other bits */
@@ -353,7 +353,7 @@
static inline void dwc3_msm_write_reg_field(void __iomem *base, u32 offset,
const u32 mask, u32 val)
{
- u32 shift = find_first_bit((void *)&mask, 32);
+ u32 shift = __ffs(mask);
u32 tmp = ioread32(base + offset);
tmp &= ~mask; /* clear written bits */
diff --git a/drivers/usb/phy/phy-msm-qusb-v2.c b/drivers/usb/phy/phy-msm-qusb-v2.c
index 1210188e..675e50e 100644
--- a/drivers/usb/phy/phy-msm-qusb-v2.c
+++ b/drivers/usb/phy/phy-msm-qusb-v2.c
@@ -27,29 +27,23 @@
#include <linux/usb/phy.h>
#include <linux/reset.h>
-#define QUSB2PHY_PWR_CTRL1 0x210
+/* QUSB2PHY_PWR_CTRL1 register related bits */
#define PWR_CTRL1_POWR_DOWN BIT(0)
-#define QUSB2PHY_PLL_COMMON_STATUS_ONE 0x1A0
+/* QUSB2PHY_PLL_COMMON_STATUS_ONE register related bits */
#define CORE_READY_STATUS BIT(0)
/* Get TUNE value from efuse bit-mask */
#define TUNE_VAL_MASK(val, pos, mask) ((val >> pos) & mask)
-#define QUSB2PHY_INTR_CTRL 0x22C
+/* QUSB2PHY_INTR_CTRL register related bits */
#define DMSE_INTR_HIGH_SEL BIT(4)
#define DPSE_INTR_HIGH_SEL BIT(3)
#define CHG_DET_INTR_EN BIT(2)
#define DMSE_INTR_EN BIT(1)
#define DPSE_INTR_EN BIT(0)
-#define QUSB2PHY_INTR_STAT 0x230
-#define DMSE_INTERRUPT BIT(1)
-#define DPSE_INTERRUPT BIT(0)
-
-#define QUSB2PHY_PORT_TUNE1 0x23c
-
-#define QUSB2PHY_PLL_CORE_INPUT_OVERRIDE 0x0a8
+/* QUSB2PHY_PLL_CORE_INPUT_OVERRIDE register related bits */
#define CORE_PLL_RATE BIT(0)
#define CORE_PLL_RATE_MUX BIT(1)
#define CORE_PLL_EN BIT(2)
@@ -73,6 +67,16 @@
module_param(phy_tune1, uint, 0644);
MODULE_PARM_DESC(phy_tune1, "QUSB PHY v2 TUNE1");
+enum qusb_phy_reg {
+ PORT_TUNE1,
+ PLL_COMMON_STATUS_ONE,
+ PWR_CTRL1,
+ INTR_CTRL,
+ PLL_CORE_INPUT_OVERRIDE,
+ TEST1,
+ USB2_PHY_REG_MAX,
+};
+
struct qusb_phy {
struct usb_phy phy;
void __iomem *base;
@@ -92,8 +96,10 @@
int host_init_seq_len;
int *qusb_phy_host_init_seq;
+ unsigned int *phy_reg;
+ int qusb_phy_reg_offset_cnt;
+
u32 tune_val;
- u32 phy_auto_resume_offset;
int efuse_bit_pos;
int efuse_num_of_bits;
@@ -316,7 +322,7 @@
qphy->tune_val = TUNE_VAL_MASK(qphy->tune_val,
qphy->efuse_bit_pos, bit_mask);
- reg = readb_relaxed(qphy->base + QUSB2PHY_PORT_TUNE1);
+ reg = readb_relaxed(qphy->base + qphy->phy_reg[PORT_TUNE1]);
if (qphy->tune_val) {
reg = reg & 0x0f;
reg |= (qphy->tune_val << 4);
@@ -372,7 +378,7 @@
/* Require to get phy pll lock successfully */
usleep_range(150, 160);
- reg = readb_relaxed(qphy->base + QUSB2PHY_PLL_COMMON_STATUS_ONE);
+ reg = readb_relaxed(qphy->base + qphy->phy_reg[PLL_COMMON_STATUS_ONE]);
dev_dbg(phy->dev, "QUSB2PHY_PLL_COMMON_STATUS_ONE:%x\n", reg);
if (!(reg & CORE_READY_STATUS)) {
dev_err(phy->dev, "QUSB PHY PLL LOCK fails:%x\n", reg);
@@ -421,9 +427,9 @@
}
/* Disable the PHY */
- writel_relaxed(readl_relaxed(qphy->base + QUSB2PHY_PWR_CTRL1) |
+ writel_relaxed(readl_relaxed(qphy->base + qphy->phy_reg[PWR_CTRL1]) |
PWR_CTRL1_POWR_DOWN,
- qphy->base + QUSB2PHY_PWR_CTRL1);
+ qphy->base + qphy->phy_reg[PWR_CTRL1]);
if (qphy->qusb_phy_init_seq)
qusb_phy_write_seq(qphy->base, qphy->qusb_phy_init_seq,
@@ -435,7 +441,7 @@
pr_debug("%s(): Programming TUNE1 parameter as:%x\n", __func__,
qphy->tune_val);
writel_relaxed(qphy->tune_val,
- qphy->base + QUSB2PHY_PORT_TUNE1);
+ qphy->base + qphy->phy_reg[PORT_TUNE1]);
}
/* If phy_tune1 modparam set, override tune1 value */
@@ -443,16 +449,16 @@
pr_debug("%s(): (modparam) TUNE1 val:0x%02x\n",
__func__, phy_tune1);
writel_relaxed(phy_tune1,
- qphy->base + QUSB2PHY_PORT_TUNE1);
+ qphy->base + qphy->phy_reg[PORT_TUNE1]);
}
/* ensure above writes are completed before re-enabling PHY */
wmb();
/* Enable the PHY */
- writel_relaxed(readl_relaxed(qphy->base + QUSB2PHY_PWR_CTRL1) &
+ writel_relaxed(readl_relaxed(qphy->base + qphy->phy_reg[PWR_CTRL1]) &
~PWR_CTRL1_POWR_DOWN,
- qphy->base + QUSB2PHY_PWR_CTRL1);
+ qphy->base + qphy->phy_reg[PWR_CTRL1]);
/* Ensure above write is completed before turning ON ref clk */
wmb();
@@ -460,7 +466,7 @@
/* Require to get phy pll lock successfully */
usleep_range(150, 160);
- reg = readb_relaxed(qphy->base + QUSB2PHY_PLL_COMMON_STATUS_ONE);
+ reg = readb_relaxed(qphy->base + qphy->phy_reg[PLL_COMMON_STATUS_ONE]);
dev_dbg(phy->dev, "QUSB2PHY_PLL_COMMON_STATUS_ONE:%x\n", reg);
if (!(reg & CORE_READY_STATUS)) {
dev_err(phy->dev, "QUSB PHY PLL LOCK fails:%x\n", reg);
@@ -478,9 +484,9 @@
qusb_phy_enable_clocks(qphy, true);
/* Disable the PHY */
- writel_relaxed(readl_relaxed(qphy->base + QUSB2PHY_PWR_CTRL1) |
+ writel_relaxed(readl_relaxed(qphy->base + qphy->phy_reg[PWR_CTRL1]) |
PWR_CTRL1_POWR_DOWN,
- qphy->base + QUSB2PHY_PWR_CTRL1);
+ qphy->base + qphy->phy_reg[PWR_CTRL1]);
/* Makes sure that above write goes through */
wmb();
@@ -525,7 +531,7 @@
(qphy->phy.flags & PHY_HOST_MODE)) {
/* Disable all interrupts */
writel_relaxed(0x00,
- qphy->base + QUSB2PHY_INTR_CTRL);
+ qphy->base + qphy->phy_reg[INTR_CTRL]);
linestate = qusb_phy_get_linestate(qphy);
/*
@@ -537,29 +543,27 @@
* e.g. if currently D+ high, D- low (HS 'J'/Suspend),
* configure the mask to trigger on D+ low OR D- high
*/
- intr_mask = DMSE_INTERRUPT | DPSE_INTERRUPT;
+ intr_mask = DPSE_INTR_EN | DMSE_INTR_EN;
if (!(linestate & LINESTATE_DP)) /* D+ low */
intr_mask |= DPSE_INTR_HIGH_SEL;
if (!(linestate & LINESTATE_DM)) /* D- low */
intr_mask |= DMSE_INTR_HIGH_SEL;
writel_relaxed(intr_mask,
- qphy->base + QUSB2PHY_INTR_CTRL);
+ qphy->base + qphy->phy_reg[INTR_CTRL]);
/* hold core PLL into reset */
writel_relaxed(CORE_PLL_EN_FROM_RESET |
CORE_RESET | CORE_RESET_MUX,
- qphy->base + QUSB2PHY_PLL_CORE_INPUT_OVERRIDE);
+ qphy->base +
+ qphy->phy_reg[PLL_CORE_INPUT_OVERRIDE]);
- if (qphy->phy_auto_resume_offset) {
- /* enable phy auto-resume */
- writel_relaxed(0x91,
- qphy->base + qphy->phy_auto_resume_offset);
- /* flush the previous write before next write */
- wmb();
- writel_relaxed(0x90,
- qphy->base + qphy->phy_auto_resume_offset);
- }
+ /* enable phy auto-resume */
+ writel_relaxed(0x91, qphy->base + qphy->phy_reg[TEST1]);
+ /* flush the previous write before next write */
+ wmb();
+ writel_relaxed(0x90, qphy->base + qphy->phy_reg[TEST1]);
+
dev_dbg(phy->dev, "%s: intr_mask = %x\n",
__func__, intr_mask);
@@ -569,7 +573,7 @@
} else { /* Cable disconnect case */
/* Disable all interrupts */
writel_relaxed(0x00,
- qphy->base + QUSB2PHY_INTR_CTRL);
+ qphy->base + qphy->phy_reg[INTR_CTRL]);
qusb_phy_reset(qphy);
qusb_phy_enable_clocks(qphy, false);
qusb_phy_enable_power(qphy, false, true);
@@ -582,11 +586,11 @@
qusb_phy_enable_clocks(qphy, true);
/* Clear all interrupts on resume */
writel_relaxed(0x00,
- qphy->base + QUSB2PHY_INTR_CTRL);
+ qphy->base + qphy->phy_reg[INTR_CTRL]);
/* bring core PLL out of reset */
- writel_relaxed(CORE_PLL_EN_FROM_RESET,
- qphy->base + QUSB2PHY_PLL_CORE_INPUT_OVERRIDE);
+ writel_relaxed(CORE_PLL_EN_FROM_RESET, qphy->base +
+ qphy->phy_reg[PLL_CORE_INPUT_OVERRIDE]);
/* Makes sure that above write goes through */
wmb();
@@ -870,6 +874,31 @@
}
size = 0;
+ of_get_property(dev->of_node, "qcom,qusb-phy-reg-offset", &size);
+ if (size) {
+ qphy->phy_reg = devm_kzalloc(dev, size, GFP_KERNEL);
+ if (qphy->phy_reg) {
+ qphy->qusb_phy_reg_offset_cnt =
+ size / sizeof(*qphy->phy_reg);
+ if (qphy->qusb_phy_reg_offset_cnt > USB2_PHY_REG_MAX) {
+ dev_err(dev, "invalid reg offset count\n");
+ return -EINVAL;
+ }
+
+ of_property_read_u32_array(dev->of_node,
+ "qcom,qusb-phy-reg-offset",
+ qphy->phy_reg,
+ qphy->qusb_phy_reg_offset_cnt);
+ } else {
+ dev_err(dev, "err mem alloc for qusb_phy_reg_offset\n");
+ return -ENOMEM;
+ }
+ } else {
+ dev_err(dev, "err provide qcom,qmp-phy-reg-offset\n");
+ return -EINVAL;
+ }
+
+ size = 0;
of_get_property(dev->of_node, "qcom,qusb-phy-init-seq", &size);
if (size) {
qphy->qusb_phy_init_seq = devm_kzalloc(dev,
@@ -917,12 +946,6 @@
return ret;
}
- ret = of_property_read_u32(dev->of_node, "qcom,phy-auto-resume-offset",
- &qphy->phy_auto_resume_offset);
- if (ret)
- dev_dbg(dev, "error reading qcom,phy-auto-resume-offset %d\n",
- ret);
-
qphy->vdd = devm_regulator_get(dev, "vdd");
if (IS_ERR(qphy->vdd)) {
dev_err(dev, "unable to get vdd supply\n");
diff --git a/include/dt-bindings/msm/msm-bus-ids.h b/include/dt-bindings/msm/msm-bus-ids.h
index 8bd30d4..bc87beb 100644
--- a/include/dt-bindings/msm/msm-bus-ids.h
+++ b/include/dt-bindings/msm/msm-bus-ids.h
@@ -250,7 +250,8 @@
#define MSM_BUS_MASTER_CAMNOC_HF0_UNCOMP 146
#define MSM_BUS_MASTER_CAMNOC_HF1_UNCOMP 147
#define MSM_BUS_MASTER_CAMNOC_SF_UNCOMP 148
-#define MSM_BUS_MASTER_MASTER_LAST 149
+#define MSM_BUS_MASTER_GIC 149
+#define MSM_BUS_MASTER_MASTER_LAST 150
#define MSM_BUS_MASTER_LLCC_DISPLAY 20000
#define MSM_BUS_MASTER_MNOC_HF_MEM_NOC_DISPLAY 20001
@@ -330,7 +331,8 @@
#define MSM_BUS_A2NOC_SNOC_SLV 10065
#define MSM_BUS_SNOC_INT_2 10066
#define MSM_BUS_A0NOC_QDSS_INT 10067
-#define MSM_BUS_INT_LAST 10068
+#define MSM_BUS_SLAVE_ANOC_PCIE_A1NOC_SNOC 10068
+#define MSM_BUS_INT_LAST 10069
#define MSM_BUS_INT_TEST_ID 20000
#define MSM_BUS_INT_TEST_LAST 20050
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 864c7d7..ff65b44 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1499,6 +1499,7 @@
*/
u64 mark_start;
u32 sum, demand;
+ u32 coloc_demand;
u32 sum_history[RAVG_HIST_SIZE_MAX];
u32 *curr_window_cpu, *prev_window_cpu;
u32 curr_window, prev_window;
diff --git a/include/linux/seemp_instrumentation.h b/include/linux/seemp_instrumentation.h
index 21bc436..ff09bd2 100644
--- a/include/linux/seemp_instrumentation.h
+++ b/include/linux/seemp_instrumentation.h
@@ -15,6 +15,8 @@
#ifdef CONFIG_SEEMP_CORE
#include <linux/kernel.h>
+#include <linux/seemp_api.h>
+#include <linux/socket.h>
#define MAX_BUF_SIZE 188
@@ -66,11 +68,33 @@
seemp_logk_kernel_end(blck);
}
+
+static inline void seemp_logk_rtic(__u8 type, __u64 actor, __u8 asset_id[0x20],
+ __u8 asset_category, __u8 response)
+{
+ char *buf = NULL;
+ void *blck = NULL;
+
+ blck = seemp_setup_buf(&buf);
+ if (!blck)
+ return;
+
+ SEEMP_LOGK_RECORD(SEEMP_API_kernel__rtic,
+ "app_pid=%llu,rtic_type=%u,asset_id=%s,asset_category=%u,response=%u",
+ actor, type, asset_id, asset_category, response);
+
+ seemp_logk_kernel_end(blck);
+}
#else
static inline void seemp_logk_sendto(int fd, void __user *buff,
size_t len, unsigned int flags, struct sockaddr __user *addr,
int addr_len)
{
}
+
+static inline void seemp_logk_rtic(__u8 type, __u64 actor, __u8 asset_id[0x20],
+ __u8 asset_category, __u8 response)
+{
+}
#endif
#endif
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index bf8f149..e94a82b 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -236,6 +236,7 @@
__field( int, samples )
__field(enum task_event, evt )
__field(unsigned int, demand )
+ __field(unsigned int, coloc_demand )
__field(unsigned int, pred_demand )
__array( u32, hist, RAVG_HIST_SIZE_MAX)
__field(unsigned int, nr_big_tasks )
@@ -249,6 +250,7 @@
__entry->samples = samples;
__entry->evt = evt;
__entry->demand = p->ravg.demand;
+ __entry->coloc_demand = p->ravg.coloc_demand;
__entry->pred_demand = p->ravg.pred_demand;
memcpy(__entry->hist, p->ravg.sum_history,
RAVG_HIST_SIZE_MAX * sizeof(u32));
@@ -256,12 +258,12 @@
__entry->cpu = rq->cpu;
),
- TP_printk("%d (%s): runtime %u samples %d event %s demand %u pred_demand %u"
+ TP_printk("%d (%s): runtime %u samples %d event %s demand %u coloc_demand %u pred_demand %u"
" (hist: %u %u %u %u %u) cpu %d nr_big %u",
__entry->pid, __entry->comm,
__entry->runtime, __entry->samples,
task_event_names[__entry->evt],
- __entry->demand, __entry->pred_demand,
+ __entry->demand, __entry->coloc_demand, __entry->pred_demand,
__entry->hist[0], __entry->hist[1],
__entry->hist[2], __entry->hist[3],
__entry->hist[4], __entry->cpu, __entry->nr_big_tasks)
@@ -317,6 +319,7 @@
__field( u64, irqtime )
__field(enum task_event, evt )
__field(unsigned int, demand )
+ __field(unsigned int, coloc_demand )
__field(unsigned int, sum )
__field( int, cpu )
__field(unsigned int, pred_demand )
@@ -350,6 +353,7 @@
__entry->mark_start = p->ravg.mark_start;
__entry->delta_m = (wallclock - p->ravg.mark_start);
__entry->demand = p->ravg.demand;
+ __entry->coloc_demand = p->ravg.coloc_demand;
__entry->sum = p->ravg.sum;
__entry->irqtime = irqtime;
__entry->pred_demand = p->ravg.pred_demand;
@@ -370,12 +374,12 @@
__entry->prev_top = rq->prev_top;
),
- TP_printk("wc %llu ws %llu delta %llu event %s cpu %d cur_freq %u cur_pid %d task %d (%s) ms %llu delta %llu demand %u sum %u irqtime %llu pred_demand %u rq_cs %llu rq_ps %llu cur_window %u (%s) prev_window %u (%s) nt_cs %llu nt_ps %llu active_wins %u grp_cs %lld grp_ps %lld, grp_nt_cs %llu, grp_nt_ps: %llu curr_top %u prev_top %u",
+ TP_printk("wc %llu ws %llu delta %llu event %s cpu %d cur_freq %u cur_pid %d task %d (%s) ms %llu delta %llu demand %u coloc_demand: %u sum %u irqtime %llu pred_demand %u rq_cs %llu rq_ps %llu cur_window %u (%s) prev_window %u (%s) nt_cs %llu nt_ps %llu active_wins %u grp_cs %lld grp_ps %lld, grp_nt_cs %llu, grp_nt_ps: %llu curr_top %u prev_top %u",
__entry->wallclock, __entry->win_start, __entry->delta,
task_event_names[__entry->evt], __entry->cpu,
__entry->cur_freq, __entry->cur_pid,
__entry->pid, __entry->comm, __entry->mark_start,
- __entry->delta_m, __entry->demand,
+ __entry->delta_m, __entry->demand, __entry->coloc_demand,
__entry->sum, __entry->irqtime, __entry->pred_demand,
__entry->rq_cs, __entry->rq_ps, __entry->curr_window,
__window_print(p, __get_dynamic_array(curr_sum), nr_cpu_ids),
diff --git a/include/uapi/linux/seemp_api.h b/include/uapi/linux/seemp_api.h
index 4dfc257..a42ad4b 100644
--- a/include/uapi/linux/seemp_api.h
+++ b/include/uapi/linux/seemp_api.h
@@ -1,6 +1,8 @@
#ifndef _SEEMP_API_H_
#define _SEEMP_API_H_
+#define SEEMP_API_kernel__rtic 100000
+
#define SEEMP_API_kernel__oom_adjust_write 0
#define SEEMP_API_kernel__sendto 1
#define SEEMP_API_kernel__recvfrom 2
diff --git a/include/uapi/linux/seemp_param_id.h b/include/uapi/linux/seemp_param_id.h
index c72c579..d8b9f78 100644
--- a/include/uapi/linux/seemp_param_id.h
+++ b/include/uapi/linux/seemp_param_id.h
@@ -15,7 +15,11 @@
#define PARAM_ID_SENSOR 8
#define PARAM_ID_WINDOW_TYPE 9
#define PARAM_ID_WINDOW_FLAG 10
-#define NUM_PARAM_IDS 11
+#define PARAM_ID_RTIC_TYPE 11
+#define PARAM_ID_RTIC_ASSET_ID 12
+#define PARAM_ID_RTIC_ASSET_CATEGORY 13
+#define PARAM_ID_RTIC_RESPONSE 14
+#define NUM_PARAM_IDS 15
static inline int param_id_index(const char *param, const char *end)
{
@@ -44,6 +48,14 @@
id = 9;
else if ((len == 11) && !memcmp(param, "window_flag", 11))
id = 10;
+ else if ((len == 9) && !memcmp(param, "rtic_type", 9))
+ id = 11;
+ else if ((len == 8) && !memcmp(param, "asset_id", 8))
+ id = 12;
+ else if ((len == 14) && !memcmp(param, "asset_category", 14))
+ id = 13;
+ else if ((len == 8) && !memcmp(param, "response", 8))
+ id = 14;
return id;
}
@@ -86,6 +98,18 @@
case 10:
name = "window_flag";
break;
+ case 11:
+ name = "rtic_type";
+ break;
+ case 12:
+ name = "asset_id";
+ break;
+ case 13:
+ name = "asset_category";
+ break;
+ case 14:
+ name = "response";
+ break;
}
return name;
}
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 3577ec6a..7e3dfa6 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -409,12 +409,25 @@
cpu_notify(CPU_ONLINE, cpu);
return 0;
}
+static void __cpuhp_kick_ap_work(struct cpuhp_cpu_state *st);
static int bringup_wait_for_ap(unsigned int cpu)
{
struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
+ /* Wait for the CPU to reach CPUHP_AP_ONLINE_IDLE */
wait_for_completion(&st->done);
+ BUG_ON(!cpu_online(cpu));
+
+ /* Unpark the stopper thread and the hotplug thread of the target cpu */
+ stop_machine_unpark(cpu);
+ kthread_unpark(st->thread);
+
+ /* Should we go further up ? */
+ if (st->target > CPUHP_AP_ONLINE_IDLE) {
+ __cpuhp_kick_ap_work(st);
+ wait_for_completion(&st->done);
+ }
return st->result;
}
@@ -437,9 +450,7 @@
cpu_notify(CPU_UP_CANCELED, cpu);
return ret;
}
- ret = bringup_wait_for_ap(cpu);
- BUG_ON(!cpu_online(cpu));
- return ret;
+ return bringup_wait_for_ap(cpu);
}
/*
@@ -979,31 +990,20 @@
}
/*
- * Called from the idle task. We need to set active here, so we can kick off
- * the stopper thread and unpark the smpboot threads. If the target state is
- * beyond CPUHP_AP_ONLINE_IDLE we kick cpuhp thread and let it bring up the
- * cpu further.
+ * Called from the idle task. Wake up the controlling task which brings the
+ * stopper and the hotplug thread of the upcoming CPU up and then delegates
+ * the rest of the online bringup to the hotplug thread.
*/
void cpuhp_online_idle(enum cpuhp_state state)
{
struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
- unsigned int cpu = smp_processor_id();
/* Happens for the boot cpu */
if (state != CPUHP_AP_ONLINE_IDLE)
return;
st->state = CPUHP_AP_ONLINE_IDLE;
-
- /* Unpark the stopper thread and the hotplug thread of this cpu */
- stop_machine_unpark(cpu);
- kthread_unpark(st->thread);
-
- /* Should we go further up ? */
- if (st->target > CPUHP_AP_ONLINE_IDLE)
- __cpuhp_kick_ap_work(st);
- else
- complete(&st->done);
+ complete(&st->done);
}
/* Requires cpu_add_remove_lock to be held */
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 80bf7ba..b65854c 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -160,11 +160,9 @@
{
__set_current_state(TASK_PARKED);
while (test_bit(KTHREAD_SHOULD_PARK, &self->flags)) {
- preempt_disable();
if (!test_and_set_bit(KTHREAD_IS_PARKED, &self->flags))
complete(&self->parked);
- schedule_preempt_disabled();
- preempt_enable();
+ schedule();
__set_current_state(TASK_PARKED);
}
clear_bit(KTHREAD_IS_PARKED, &self->flags);
diff --git a/kernel/sched/walt.c b/kernel/sched/walt.c
index ae45283..69bbce2 100644
--- a/kernel/sched/walt.c
+++ b/kernel/sched/walt.c
@@ -1704,6 +1704,7 @@
pred_demand);
p->ravg.demand = demand;
+ p->ravg.coloc_demand = div64_u64(sum, sched_ravg_hist_size);
p->ravg.pred_demand = pred_demand;
if (__task_in_cum_window_demand(rq, p))
@@ -1982,6 +1983,7 @@
(u64)sched_ravg_window, 100);
p->ravg.demand = init_load_windows;
+ p->ravg.coloc_demand = init_load_windows;
p->ravg.pred_demand = 0;
for (i = 0; i < RAVG_HIST_SIZE_MAX; ++i)
p->ravg.sum_history[i] = init_load_windows;
@@ -2505,7 +2507,7 @@
(sched_ravg_window * sched_ravg_hist_size))
continue;
- combined_demand += p->ravg.demand;
+ combined_demand += p->ravg.coloc_demand;
}
diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c
index 04a1b97..14e3d85 100644
--- a/net/netfilter/xt_IDLETIMER.c
+++ b/net/netfilter/xt_IDLETIMER.c
@@ -76,6 +76,7 @@
bool send_nl_msg;
bool active;
uid_t uid;
+ bool suspend_time_valid;
};
static LIST_HEAD(idletimer_tg_list);
@@ -245,8 +246,13 @@
switch (pm_event) {
case PM_SUSPEND_PREPARE:
get_monotonic_boottime(&timer->last_suspend_time);
+ timer->suspend_time_valid = true;
break;
case PM_POST_SUSPEND:
+ if (!timer->suspend_time_valid)
+ break;
+ timer->suspend_time_valid = false;
+
spin_lock_bh(×tamp_lock);
if (!timer->active) {
spin_unlock_bh(×tamp_lock);
@@ -281,7 +287,7 @@
{
int ret;
- info->timer = kmalloc(sizeof(*info->timer), GFP_KERNEL);
+ info->timer = kzalloc(sizeof(*info->timer), GFP_KERNEL);
if (!info->timer) {
ret = -ENOMEM;
goto out;
diff --git a/sound/soc/msm/qdsp6v2/audio_calibration.c b/sound/soc/msm/qdsp6v2/audio_calibration.c
index 808a0e4..d709b09 100644
--- a/sound/soc/msm/qdsp6v2/audio_calibration.c
+++ b/sound/soc/msm/qdsp6v2/audio_calibration.c
@@ -460,6 +460,12 @@
data->cal_type.cal_hdr.buffer_number);
ret = -EINVAL;
goto done;
+ } else if ((data->hdr.cal_type_size + sizeof(data->hdr)) > size) {
+ pr_err("%s: cal type hdr size %zd + cal type size %d is greater than user buffer size %d\n",
+ __func__, sizeof(data->hdr), data->hdr.cal_type_size,
+ size);
+ ret = -EFAULT;
+ goto done;
}
@@ -497,13 +503,7 @@
goto unlock;
if (data == NULL)
goto unlock;
- if ((sizeof(data->hdr) + data->hdr.cal_type_size) > size) {
- pr_err("%s: header size %zd plus cal type size %d are greater than data buffer size %d\n",
- __func__, sizeof(data->hdr),
- data->hdr.cal_type_size, size);
- ret = -EFAULT;
- goto unlock;
- } else if (copy_to_user((void *)arg, data,
+ if (copy_to_user(arg, data,
sizeof(data->hdr) + data->hdr.cal_type_size)) {
pr_err("%s: Could not copy cal type to user\n",
__func__);