Merge "msm: mdss: hdmi: wait for power off"
diff --git a/Documentation/devicetree/bindings/arm/msm/pm-8x60.txt b/Documentation/devicetree/bindings/arm/msm/pm-8x60.txt
index 795af3b..2fbe4ca 100644
--- a/Documentation/devicetree/bindings/arm/msm/pm-8x60.txt
+++ b/Documentation/devicetree/bindings/arm/msm/pm-8x60.txt
@@ -12,6 +12,7 @@
The required properties for PM-8x60 are:
- compatible: "qcom,pm-8x60"
+- qcom,lpm-levels: phandle for associated lpm_levels device.
The optional properties are:
@@ -39,4 +40,5 @@
reg = <0xfe800664 0x40>;
qcom,pc-mode = "tz_l2_int";
qcom,use-sync-timer;
+ qcom,lpm-levels = <&lpm_levels>;
};
diff --git a/arch/arm/boot/dts/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index 5e890d3..78e1a63 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -78,7 +78,7 @@
vdd-apc-supply = <&pm8226_s2>;
vdd-mx-supply = <&pm8226_l3_ao>;
- qcom,vdd-mx-vmax = <1350000>;
+ qcom,vdd-mx-vmax = <1337500>;
qcom,vdd-mx-vmin-method = <1>;
qcom,cpr-ref-clk = <19200>;
@@ -109,7 +109,7 @@
qcom,cpr-fuse-uplift-sel = <22 53 1 0 0>;
qcom,cpr-uplift-voltage = <50000>;
qcom,cpr-uplift-quotient = <0 0 120>;
- qcom,cpr-uplift-max-volt = <1350000>;
+ qcom,cpr-uplift-max-volt = <1330000>;
qcom,cpr-uplift-speed-bin = <1>;
qcom,speed-bin-fuse-sel = <22 0 3 0>;
};
diff --git a/arch/arm/boot/dts/msm8226-v1-pm.dtsi b/arch/arm/boot/dts/msm8226-v1-pm.dtsi
index d59fab3..10aff70 100644
--- a/arch/arm/boot/dts/msm8226-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-v1-pm.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014 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
@@ -105,7 +105,7 @@
qcom,L2-spm-is-apcs-master;
};
- qcom,lpm-levels {
+ lpm_levels: qcom,lpm-levels {
compatible = "qcom,lpm-levels";
qcom,default-l2-state = "l2_cache_active";
#address-cells = <1>;
@@ -300,6 +300,7 @@
qcom,pc-resets-timer;
qcom,cpus-as-clocks;
qcom,synced-clocks;
+ qcom,lpm-levels = <&lpm_levels>;
};
qcom,cpu-sleep-status@f9088008{
diff --git a/arch/arm/boot/dts/msm8226-v2-pm.dtsi b/arch/arm/boot/dts/msm8226-v2-pm.dtsi
index bc8fe5d..7af2c7f 100644
--- a/arch/arm/boot/dts/msm8226-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8226-v2-pm.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014 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
@@ -107,7 +107,7 @@
qcom,L2-spm-is-apcs-master;
};
- qcom,lpm-levels {
+ lpm_levels: qcom,lpm-levels {
compatible = "qcom,lpm-levels";
qcom,default-l2-state = "l2_cache_active";
#address-cells = <1>;
@@ -312,6 +312,7 @@
qcom,pc-resets-timer;
qcom,cpus-as-clocks;
qcom,synced-clocks;
+ qcom,lpm-levels = <&lpm_levels>;
};
qcom,cpu-sleep-status@f9088008{
diff --git a/arch/arm/boot/dts/msm8610-v1-pm.dtsi b/arch/arm/boot/dts/msm8610-v1-pm.dtsi
index dc1dc8b..adc66d7 100644
--- a/arch/arm/boot/dts/msm8610-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-v1-pm.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014 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
@@ -105,7 +105,7 @@
qcom,L2-spm-is-apcs-master;
};
- qcom,lpm-levels {
+ lpm_levels: qcom,lpm-levels {
compatible = "qcom,lpm-levels";
qcom,default-l2-state = "l2_cache_active";
#address-cells = <1>;
@@ -296,6 +296,7 @@
qcom,pc-resets-timer;
qcom,cpus-as-clocks;
qcom,synced-clocks;
+ qcom,lpm-levels = <&lpm_levels>;
};
qcom,cpu-sleep-status@f9088008{
diff --git a/arch/arm/boot/dts/msm8610-v2-pm.dtsi b/arch/arm/boot/dts/msm8610-v2-pm.dtsi
index 2859744..b69b061 100644
--- a/arch/arm/boot/dts/msm8610-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8610-v2-pm.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014 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
@@ -107,7 +107,7 @@
qcom,L2-spm-is-apcs-master;
};
- qcom,lpm-levels {
+ lpm_levels: qcom,lpm-levels {
compatible = "qcom,lpm-levels";
qcom,default-l2-state = "l2_cache_active";
#address-cells = <1>;
@@ -308,6 +308,7 @@
qcom,pc-resets-timer;
qcom,cpus-as-clocks;
qcom,synced-clocks;
+ qcom,lpm-levels = <&lpm_levels>;
};
qcom,cpu-sleep-status@f9088008{
diff --git a/arch/arm/boot/dts/msm8974-v1-pm.dtsi b/arch/arm/boot/dts/msm8974-v1-pm.dtsi
index 886177d..516d068 100644
--- a/arch/arm/boot/dts/msm8974-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-v1-pm.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -130,7 +130,7 @@
qcom,L2-spm-is-apcs-master;
};
- qcom,lpm-levels {
+ lpm_levels: qcom,lpm-levels {
compatible = "qcom,lpm-levels";
qcom,default-l2-state = "l2_cache_retention";
#address-cells = <1>;
@@ -311,6 +311,7 @@
qcom,pc-mode = "tz_l2_int";
qcom,use-sync-timer;
qcom,cpus-as-clocks;
+ qcom,lpm-levels = <&lpm_levels>;
};
qcom,cpu-sleep-status@f9088008 {
diff --git a/arch/arm/boot/dts/msm8974-v2-pm.dtsi b/arch/arm/boot/dts/msm8974-v2-pm.dtsi
index 84a8c2d..cde5e5a9 100644
--- a/arch/arm/boot/dts/msm8974-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2-pm.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -126,7 +126,7 @@
qcom,L2-spm-is-apcs-master;
};
- qcom,lpm-levels {
+ lpm_levels: qcom,lpm-levels {
compatible = "qcom,lpm-levels";
qcom,default-l2-state = "l2_cache_retention";
#address-cells = <1>;
@@ -324,6 +324,7 @@
qcom,pc-mode = "tz_l2_int";
qcom,use-sync-timer;
qcom,cpus-as-clocks;
+ qcom,lpm-levels = <&lpm_levels>;
qcom,pm-snoc-client {
compatible = "qcom,pm-snoc-client";
diff --git a/arch/arm/boot/dts/msm8974pro-pm.dtsi b/arch/arm/boot/dts/msm8974pro-pm.dtsi
index f735b65..0307e2a 100644
--- a/arch/arm/boot/dts/msm8974pro-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pm.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -126,7 +126,7 @@
qcom,L2-spm-is-apcs-master;
};
- qcom,lpm-levels {
+ lpm_levels: qcom,lpm-levels {
compatible = "qcom,lpm-levels";
qcom,allow-synced-levels;
qcom,default-l2-state = "l2_cache_retention";
@@ -334,6 +334,7 @@
reg = <0xfe805664 0x40>;
qcom,pc-mode = "tz_l2_int";
qcom,cpus-as-clocks;
+ qcom,lpm-levels = <&lpm_levels>;
qcom,pm-snoc-client {
compatible = "qcom,pm-snoc-client";
diff --git a/arch/arm/boot/dts/msm8974pro.dtsi b/arch/arm/boot/dts/msm8974pro.dtsi
index 813ecaa..ae0547f 100644
--- a/arch/arm/boot/dts/msm8974pro.dtsi
+++ b/arch/arm/boot/dts/msm8974pro.dtsi
@@ -1657,6 +1657,7 @@
};
&mdss_mdp {
+ qcom,max-bandwidth-low-kbps = <2750000>;
qcom,vbif-settings = <0x0004 0x00000001>;
qcom,mdss-wb-off = <0x00011100 0x00011500
diff --git a/arch/arm/boot/dts/msm9625-pm.dtsi b/arch/arm/boot/dts/msm9625-pm.dtsi
index 1e6cdf2..ec62cd4 100644
--- a/arch/arm/boot/dts/msm9625-pm.dtsi
+++ b/arch/arm/boot/dts/msm9625-pm.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -28,7 +28,7 @@
3e 0f];
};
- qcom,lpm-levels {
+ lpm_levels: qcom,lpm-levels {
compatible = "qcom,lpm-levels";
qcom,no-l2-saw;
#address-cells = <1>;
@@ -167,6 +167,7 @@
reg = <0xfe805664 0x40>;
qcom,pc-mode = "tz_l2_ext";
qcom,use-sync-timer;
+ qcom,lpm-levels = <&lpm_levels>;
};
qcom,rpm-log@fc19dc00 {
diff --git a/arch/arm/include/asm/system_misc.h b/arch/arm/include/asm/system_misc.h
index 71f4827..0827df7 100644
--- a/arch/arm/include/asm/system_misc.h
+++ b/arch/arm/include/asm/system_misc.h
@@ -24,6 +24,7 @@
extern void disable_hlt(void);
extern void enable_hlt(void);
extern int get_hlt(void);
+extern char* (*arch_read_hardware_id)(void);
#endif /* !__ASSEMBLY__ */
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 7298f9a..c110f0f 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -110,6 +110,9 @@
unsigned int cold_boot;
EXPORT_SYMBOL(cold_boot);
+char* (*arch_read_hardware_id)(void);
+EXPORT_SYMBOL(arch_read_hardware_id);
+
#ifdef MULTI_CPU
struct processor processor __read_mostly;
#endif
@@ -1108,7 +1111,10 @@
seq_puts(m, "\n");
- seq_printf(m, "Hardware\t: %s\n", machine_name);
+ if (!arch_read_hardware_id)
+ seq_printf(m, "Hardware\t: %s\n", machine_name);
+ else
+ seq_printf(m, "Hardware\t: %s\n", arch_read_hardware_id());
seq_printf(m, "Revision\t: %04x\n", system_rev);
seq_printf(m, "Serial\t\t: %08x%08x\n",
system_serial_high, system_serial_low);
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index b42878d..1771090 100755
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -2197,6 +2197,7 @@
.en_mask = BIT(5),
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &ce1_clk_src.c,
.dbg_name = "gcc_ce1_clk",
.ops = &clk_ops_vote,
CLK_INIT(gcc_ce1_clk.c),
@@ -2233,6 +2234,7 @@
.en_mask = BIT(2),
.base = &virt_bases[GCC_BASE],
.c = {
+ .parent = &ce2_clk_src.c,
.dbg_name = "gcc_ce2_clk",
.ops = &clk_ops_vote,
CLK_INIT(gcc_ce2_clk.c),
diff --git a/arch/arm/mach-msm/include/mach/socinfo.h b/arch/arm/mach-msm/include/mach/socinfo.h
index aeb32f8..24b5181 100644
--- a/arch/arm/mach-msm/include/mach/socinfo.h
+++ b/arch/arm/mach-msm/include/mach/socinfo.h
@@ -138,6 +138,11 @@
MSM_CPU_SAMARIUM,
};
+struct msm_soc_info {
+ enum msm_cpu generic_soc_type;
+ char *soc_id_string;
+};
+
enum pmic_model {
PMIC_MODEL_PM8058 = 13,
PMIC_MODEL_PM8028 = 14,
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index 9857162..defcd43 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.c
@@ -82,6 +82,7 @@
static struct lpm_system_state sys_state;
static bool suspend_in_progress;
+static int64_t suspend_time;
struct lpm_lookup_table {
uint32_t modes;
@@ -779,6 +780,11 @@
static int lpm_suspend_prepare(void)
{
+ struct timespec ts;
+
+ getnstimeofday(&ts);
+ suspend_time = timespec_to_ns(&ts);
+
suspend_in_progress = true;
msm_mpm_suspend_prepare();
return 0;
@@ -786,6 +792,12 @@
static void lpm_suspend_wake(void)
{
+ struct timespec ts;
+
+ getnstimeofday(&ts);
+ suspend_time = timespec_to_ns(&ts) - suspend_time;
+ msm_pm_add_stat(MSM_PM_STAT_SUSPEND, suspend_time);
+
msm_mpm_suspend_wake();
suspend_in_progress = false;
}
diff --git a/arch/arm/mach-msm/msm-pm.c b/arch/arm/mach-msm/msm-pm.c
index f9a9343..cb65a70 100644
--- a/arch/arm/mach-msm/msm-pm.c
+++ b/arch/arm/mach-msm/msm-pm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2014, 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
@@ -25,10 +25,12 @@
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/cpu_pm.h>
+#include <linux/remote_spinlock.h>
#include <asm/uaccess.h>
#include <asm/suspend.h>
#include <asm/cacheflush.h>
#include <asm/outercache.h>
+#include <mach/remote_spinlock.h>
#include <mach/scm.h>
#include <mach/msm_bus.h>
#include <mach/jtag.h>
@@ -117,6 +119,12 @@
DEFINE_PER_CPU(struct clk *, cpu_clks);
static struct clk *l2_clk;
+static int cpu_count;
+static DEFINE_SPINLOCK(cpu_cnt_lock);
+#define SCM_HANDOFF_LOCK_ID "S:7"
+static bool need_scm_handoff_lock;
+static remote_spinlock_t scm_handoff_lock;
+
static void (*msm_pm_disable_l2_fn)(void);
static void (*msm_pm_enable_l2_fn)(void);
static void (*msm_pm_flush_l2_fn)(void);
@@ -478,8 +486,30 @@
static int msm_pm_collapse(unsigned long unused)
{
uint32_t cpu = smp_processor_id();
+ enum msm_pm_l2_scm_flag flag = MSM_SCM_L2_ON;
- if (msm_pm_get_l2_flush_flag() == MSM_SCM_L2_OFF) {
+ spin_lock(&cpu_cnt_lock);
+ cpu_count++;
+ if (cpu_count == num_online_cpus())
+ flag = msm_pm_get_l2_flush_flag();
+
+ pr_debug("cpu:%d cores_in_pc:%d L2 flag: %d\n",
+ cpu, cpu_count, flag);
+
+ /*
+ * The scm_handoff_lock will be release by the secure monitor.
+ * It is used to serialize power-collapses from this point on,
+ * so that both Linux and the secure context have a consistent
+ * view regarding the number of running cpus (cpu_count).
+ *
+ * It must be acquired before releasing cpu_cnt_lock.
+ */
+ if (need_scm_handoff_lock)
+ remote_spin_lock_rlock_id(&scm_handoff_lock,
+ REMOTE_SPINLOCK_TID_START + cpu);
+ spin_unlock(&cpu_cnt_lock);
+
+ if (flag == MSM_SCM_L2_OFF) {
flush_cache_all();
if (msm_pm_flush_l2_fn)
msm_pm_flush_l2_fn();
@@ -491,8 +521,7 @@
msm_pc_inc_debug_count(cpu, MSM_PC_ENTRY_COUNTER);
- scm_call_atomic1(SCM_SVC_BOOT, SCM_CMD_TERMINATE_PC,
- msm_pm_get_l2_flush_flag());
+ scm_call_atomic1(SCM_SVC_BOOT, SCM_CMD_TERMINATE_PC, flag);
msm_pc_inc_debug_count(cpu, MSM_PC_FALLTHRU_COUNTER);
@@ -534,6 +563,12 @@
collapsed = save_cpu_regs ?
!cpu_suspend(0, msm_pm_collapse) : msm_pm_pc_hotplug();
+ if (save_cpu_regs) {
+ spin_lock(&cpu_cnt_lock);
+ cpu_count--;
+ BUG_ON(cpu_count > num_online_cpus());
+ spin_unlock(&cpu_cnt_lock);
+ }
msm_jtag_restore_state();
if (collapsed) {
@@ -764,17 +799,19 @@
pr_info("CPU%u: %s mode:%d\n",
smp_processor_id(), __func__, mode);
- time = sched_clock();
+ if (from_idle)
+ time = sched_clock();
+
if (execute[mode])
exit_stat = execute[mode](from_idle);
- time = sched_clock() - time;
- if (from_idle)
+
+ if (from_idle) {
+ time = sched_clock() - time;
msm_pm_ftrace_lpm_exit(smp_processor_id(), mode, collapsed);
- else
- exit_stat = MSM_PM_STAT_SUSPEND;
- if (exit_stat >= 0)
- msm_pm_add_stat(exit_stat, time);
- do_div(time, 1000);
+ if (exit_stat >= 0)
+ msm_pm_add_stat(exit_stat, time);
+ }
+
return collapsed;
}
@@ -1166,6 +1203,7 @@
struct resource *res = NULL;
int i;
struct msm_pm_init_data_type pdata_local;
+ struct device_node *lpm_node;
int ret = 0;
memset(&pdata_local, 0, sizeof(struct msm_pm_init_data_type));
@@ -1192,6 +1230,23 @@
msm_pc_debug_counters_phys = 0;
}
+ lpm_node = of_parse_phandle(pdev->dev.of_node, "qcom,lpm-levels", 0);
+ if (!lpm_node) {
+ pr_warn("Could not get qcom,lpm-levels handle\n");
+ return -EINVAL;
+ }
+ need_scm_handoff_lock = of_property_read_bool(lpm_node,
+ "qcom,allow-synced-levels");
+ if (need_scm_handoff_lock) {
+ ret = remote_spin_lock_init(&scm_handoff_lock,
+ SCM_HANDOFF_LOCK_ID);
+ if (ret) {
+ pr_err("%s: Failed initializing scm_handoff_lock (%d)\n",
+ __func__, ret);
+ return ret;
+ }
+ }
+
if (pdev->dev.of_node) {
enum msm_pm_pc_mode_type pc_mode;
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index ab03712..8e7adba 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -21,10 +21,12 @@
#include <linux/sys_soc.h>
#include <linux/slab.h>
#include <linux/stat.h>
+#include <linux/string.h>
#include <linux/sysdev.h>
#include <linux/types.h>
#include <asm/mach-types.h>
+#include <asm/system_misc.h>
#include <mach/socinfo.h>
#include <mach/msm_smem.h>
@@ -185,246 +187,247 @@
struct socinfo_v8 v8;
} *socinfo;
-static enum msm_cpu cpu_of_id[] = {
+static struct msm_soc_info cpu_of_id[] = {
/* 7x01 IDs */
- [1] = MSM_CPU_7X01,
- [16] = MSM_CPU_7X01,
- [17] = MSM_CPU_7X01,
- [18] = MSM_CPU_7X01,
- [19] = MSM_CPU_7X01,
- [23] = MSM_CPU_7X01,
- [25] = MSM_CPU_7X01,
- [26] = MSM_CPU_7X01,
- [32] = MSM_CPU_7X01,
- [33] = MSM_CPU_7X01,
- [34] = MSM_CPU_7X01,
- [35] = MSM_CPU_7X01,
+ [0] = {MSM_CPU_UNKNOWN, "Unknown CPU"},
+ [1] = {MSM_CPU_7X01, "MSM7X01"},
+ [16] = {MSM_CPU_7X01, "MSM7X01"},
+ [17] = {MSM_CPU_7X01, "MSM7X01"},
+ [18] = {MSM_CPU_7X01, "MSM7X01"},
+ [19] = {MSM_CPU_7X01, "MSM7X01"},
+ [23] = {MSM_CPU_7X01, "MSM7X01"},
+ [25] = {MSM_CPU_7X01, "MSM7X01"},
+ [26] = {MSM_CPU_7X01, "MSM7X01"},
+ [32] = {MSM_CPU_7X01, "MSM7X01"},
+ [33] = {MSM_CPU_7X01, "MSM7X01"},
+ [34] = {MSM_CPU_7X01, "MSM7X01"},
+ [35] = {MSM_CPU_7X01, "MSM7X01"},
/* 7x25 IDs */
- [20] = MSM_CPU_7X25,
- [21] = MSM_CPU_7X25, /* 7225 */
- [24] = MSM_CPU_7X25, /* 7525 */
- [27] = MSM_CPU_7X25, /* 7625 */
- [39] = MSM_CPU_7X25,
- [40] = MSM_CPU_7X25,
- [41] = MSM_CPU_7X25,
- [42] = MSM_CPU_7X25,
- [62] = MSM_CPU_7X25, /* 7625-1 */
- [63] = MSM_CPU_7X25, /* 7225-1 */
- [66] = MSM_CPU_7X25, /* 7225-2 */
+ [20] = {MSM_CPU_7X25, "MSM7X25"},
+ [21] = {MSM_CPU_7X25, "MSM7X25"},
+ [24] = {MSM_CPU_7X25, "MSM7X25"},
+ [27] = {MSM_CPU_7X25, "MSM7X25"},
+ [39] = {MSM_CPU_7X25, "MSM7X25"},
+ [40] = {MSM_CPU_7X25, "MSM7X25"},
+ [41] = {MSM_CPU_7X25, "MSM7X25"},
+ [42] = {MSM_CPU_7X25, "MSM7X25"},
+ [62] = {MSM_CPU_7X25, "MSM7X25"},
+ [63] = {MSM_CPU_7X25, "MSM7X25"},
+ [66] = {MSM_CPU_7X25, "MSM7X25"},
/* 7x27 IDs */
- [43] = MSM_CPU_7X27,
- [44] = MSM_CPU_7X27,
- [61] = MSM_CPU_7X27,
- [67] = MSM_CPU_7X27, /* 7227-1 */
- [68] = MSM_CPU_7X27, /* 7627-1 */
- [69] = MSM_CPU_7X27, /* 7627-2 */
+ [43] = {MSM_CPU_7X27, "MSM7X27"},
+ [44] = {MSM_CPU_7X27, "MSM7X27"},
+ [61] = {MSM_CPU_7X27, "MSM7X27"},
+ [67] = {MSM_CPU_7X27, "MSM7X27"},
+ [68] = {MSM_CPU_7X27, "MSM7X27"},
+ [69] = {MSM_CPU_7X27, "MSM7X27"},
/* 8x50 IDs */
- [30] = MSM_CPU_8X50,
- [36] = MSM_CPU_8X50,
- [37] = MSM_CPU_8X50,
- [38] = MSM_CPU_8X50,
+ [30] = {MSM_CPU_8X50, "MSM8X50"},
+ [36] = {MSM_CPU_8X50, "MSM8X50"},
+ [37] = {MSM_CPU_8X50, "MSM8X50"},
+ [38] = {MSM_CPU_8X50, "MSM8X50"},
/* 7x30 IDs */
- [59] = MSM_CPU_7X30,
- [60] = MSM_CPU_7X30,
+ [59] = {MSM_CPU_7X30, "MSM7X30"},
+ [60] = {MSM_CPU_7X30, "MSM7X30"},
/* 8x55 IDs */
- [74] = MSM_CPU_8X55,
- [75] = MSM_CPU_8X55,
- [85] = MSM_CPU_8X55,
+ [74] = {MSM_CPU_8X55, "MSM8X55"},
+ [75] = {MSM_CPU_8X55, "MSM8X55"},
+ [85] = {MSM_CPU_8X55, "MSM8X55"},
/* 8x60 IDs */
- [70] = MSM_CPU_8X60,
- [71] = MSM_CPU_8X60,
- [86] = MSM_CPU_8X60,
+ [70] = {MSM_CPU_8X60, "MSM8X60"},
+ [71] = {MSM_CPU_8X60, "MSM8X60"},
+ [86] = {MSM_CPU_8X60, "MSM8X60"},
/* 8960 IDs */
- [87] = MSM_CPU_8960,
+ [87] = {MSM_CPU_8960, "MSM8960"},
/* 7x25A IDs */
- [88] = MSM_CPU_7X25A,
- [89] = MSM_CPU_7X25A,
- [96] = MSM_CPU_7X25A,
+ [88] = {MSM_CPU_7X25A, "MSM7X25A"},
+ [89] = {MSM_CPU_7X25A, "MSM7X25A"},
+ [96] = {MSM_CPU_7X25A, "MSM7X25A"},
/* 7x27A IDs */
- [90] = MSM_CPU_7X27A,
- [91] = MSM_CPU_7X27A,
- [92] = MSM_CPU_7X27A,
- [97] = MSM_CPU_7X27A,
+ [90] = {MSM_CPU_7X27A, "MSM7X27A"},
+ [91] = {MSM_CPU_7X27A, "MSM7X27A"},
+ [92] = {MSM_CPU_7X27A, "MSM7X27A"},
+ [97] = {MSM_CPU_7X27A, "MSM7X27A"},
/* FSM9xxx ID */
- [94] = FSM_CPU_9XXX,
- [95] = FSM_CPU_9XXX,
+ [94] = {FSM_CPU_9XXX, "FSM9XXX"},
+ [95] = {FSM_CPU_9XXX, "FSM9XXX"},
/* 7x25AA ID */
- [98] = MSM_CPU_7X25AA,
- [99] = MSM_CPU_7X25AA,
- [100] = MSM_CPU_7X25AA,
+ [98] = {MSM_CPU_7X25AA, "MSM7X25AA"},
+ [99] = {MSM_CPU_7X25AA, "MSM7X25AA"},
+ [100] = {MSM_CPU_7X25AA, "MSM7X25AA"},
/* 7x27AA ID */
- [101] = MSM_CPU_7X27AA,
- [102] = MSM_CPU_7X27AA,
- [103] = MSM_CPU_7X27AA,
- [136] = MSM_CPU_7X27AA,
+ [101] = {MSM_CPU_7X27AA, "MSM7X27AA"},
+ [102] = {MSM_CPU_7X27AA, "MSM7X27AA"},
+ [103] = {MSM_CPU_7X27AA, "MSM7X27AA"},
+ [136] = {MSM_CPU_7X27AA, "MSM7X27AA"},
/* 9x15 ID */
- [104] = MSM_CPU_9615,
- [105] = MSM_CPU_9615,
- [106] = MSM_CPU_9615,
- [107] = MSM_CPU_9615,
- [171] = MSM_CPU_9615,
+ [104] = {MSM_CPU_9615, "MSM9615"},
+ [105] = {MSM_CPU_9615, "MSM9615"},
+ [106] = {MSM_CPU_9615, "MSM9615"},
+ [107] = {MSM_CPU_9615, "MSM9615"},
+ [171] = {MSM_CPU_9615, "MSM9615"},
/* 8064 IDs */
- [109] = MSM_CPU_8064,
+ [109] = {MSM_CPU_8064, "APQ8064"},
/* 8930 IDs */
- [116] = MSM_CPU_8930,
- [117] = MSM_CPU_8930,
- [118] = MSM_CPU_8930,
- [119] = MSM_CPU_8930,
- [179] = MSM_CPU_8930,
+ [116] = {MSM_CPU_8930, "MSM8930"},
+ [117] = {MSM_CPU_8930, "MSM8930"},
+ [118] = {MSM_CPU_8930, "MSM8930"},
+ [119] = {MSM_CPU_8930, "MSM8930"},
+ [179] = {MSM_CPU_8930, "MSM8930"},
/* 8627 IDs */
- [120] = MSM_CPU_8627,
- [121] = MSM_CPU_8627,
+ [120] = {MSM_CPU_8627, "MSM8627"},
+ [121] = {MSM_CPU_8627, "MSM8627"},
/* 8660A ID */
- [122] = MSM_CPU_8960,
+ [122] = {MSM_CPU_8960, "MSM8960"},
/* 8260A ID */
- [123] = MSM_CPU_8960,
+ [123] = {MSM_CPU_8960, "MSM8960"},
/* 8060A ID */
- [124] = MSM_CPU_8960,
+ [124] = {MSM_CPU_8960, "MSM8960"},
/* 8974 IDs */
- [126] = MSM_CPU_8974,
- [184] = MSM_CPU_8974,
- [185] = MSM_CPU_8974,
- [186] = MSM_CPU_8974,
+ [126] = {MSM_CPU_8974, "MSM8974"},
+ [184] = {MSM_CPU_8974, "MSM8974"},
+ [185] = {MSM_CPU_8974, "MSM8974"},
+ [186] = {MSM_CPU_8974, "MSM8974"},
/* 8974AA IDs */
- [208] = MSM_CPU_8974PRO_AA,
- [211] = MSM_CPU_8974PRO_AA,
- [214] = MSM_CPU_8974PRO_AA,
- [217] = MSM_CPU_8974PRO_AA,
+ [208] = {MSM_CPU_8974PRO_AA, "MSM8974PRO-AA"},
+ [211] = {MSM_CPU_8974PRO_AA, "MSM8974PRO-AA"},
+ [214] = {MSM_CPU_8974PRO_AA, "MSM8974PRO-AA"},
+ [217] = {MSM_CPU_8974PRO_AA, "MSM8974PRO-AA"},
/* 8974AB IDs */
- [209] = MSM_CPU_8974PRO_AB,
- [212] = MSM_CPU_8974PRO_AB,
- [215] = MSM_CPU_8974PRO_AB,
- [218] = MSM_CPU_8974PRO_AB,
+ [209] = {MSM_CPU_8974PRO_AB, "MSM8974PRO-AB"},
+ [212] = {MSM_CPU_8974PRO_AB, "MSM8974PRO-AB"},
+ [215] = {MSM_CPU_8974PRO_AB, "MSM8974PRO-AB"},
+ [218] = {MSM_CPU_8974PRO_AB, "MSM8974PRO-AB"},
/* 8974AC IDs */
- [194] = MSM_CPU_8974PRO_AC,
- [210] = MSM_CPU_8974PRO_AC,
- [213] = MSM_CPU_8974PRO_AC,
- [216] = MSM_CPU_8974PRO_AC,
+ [194] = {MSM_CPU_8974PRO_AC, "MSM8974PRO-AC"},
+ [210] = {MSM_CPU_8974PRO_AC, "MSM8974PRO-AC"},
+ [213] = {MSM_CPU_8974PRO_AC, "MSM8974PRO-AC"},
+ [216] = {MSM_CPU_8974PRO_AC, "MSM8974PRO-AC"},
/* 8625 IDs */
- [127] = MSM_CPU_8625,
- [128] = MSM_CPU_8625,
- [129] = MSM_CPU_8625,
- [137] = MSM_CPU_8625,
- [167] = MSM_CPU_8625,
+ [127] = {MSM_CPU_8625, "MSM8625"},
+ [128] = {MSM_CPU_8625, "MSM8625"},
+ [129] = {MSM_CPU_8625, "MSM8625"},
+ [137] = {MSM_CPU_8625, "MSM8625"},
+ [167] = {MSM_CPU_8625, "MSM8625"},
/* 8064 MPQ ID */
- [130] = MSM_CPU_8064,
+ [130] = {MSM_CPU_8064, "APQ8064"},
/* 7x25AB IDs */
- [131] = MSM_CPU_7X25AB,
- [132] = MSM_CPU_7X25AB,
- [133] = MSM_CPU_7X25AB,
- [135] = MSM_CPU_7X25AB,
+ [131] = {MSM_CPU_7X25AB, "MSM7X25AB"},
+ [132] = {MSM_CPU_7X25AB, "MSM7X25AB"},
+ [133] = {MSM_CPU_7X25AB, "MSM7X25AB"},
+ [135] = {MSM_CPU_7X25AB, "MSM7X25AB"},
/* 9625 IDs */
- [134] = MSM_CPU_9625,
- [148] = MSM_CPU_9625,
- [149] = MSM_CPU_9625,
- [150] = MSM_CPU_9625,
- [151] = MSM_CPU_9625,
- [152] = MSM_CPU_9625,
- [173] = MSM_CPU_9625,
- [174] = MSM_CPU_9625,
- [175] = MSM_CPU_9625,
+ [134] = {MSM_CPU_9625, "MSM9625"},
+ [148] = {MSM_CPU_9625, "MSM9625"},
+ [149] = {MSM_CPU_9625, "MSM9625"},
+ [150] = {MSM_CPU_9625, "MSM9625"},
+ [151] = {MSM_CPU_9625, "MSM9625"},
+ [152] = {MSM_CPU_9625, "MSM9625"},
+ [173] = {MSM_CPU_9625, "MSM9625"},
+ [174] = {MSM_CPU_9625, "MSM9625"},
+ [175] = {MSM_CPU_9625, "MSM9625"},
/* 8960AB IDs */
- [138] = MSM_CPU_8960AB,
- [139] = MSM_CPU_8960AB,
- [140] = MSM_CPU_8960AB,
- [141] = MSM_CPU_8960AB,
+ [138] = {MSM_CPU_8960AB, "MSM8960AB"},
+ [139] = {MSM_CPU_8960AB, "MSM8960AB"},
+ [140] = {MSM_CPU_8960AB, "MSM8960AB"},
+ [141] = {MSM_CPU_8960AB, "MSM8960AB"},
/* 8930AA IDs */
- [142] = MSM_CPU_8930AA,
- [143] = MSM_CPU_8930AA,
- [144] = MSM_CPU_8930AA,
- [160] = MSM_CPU_8930AA,
- [180] = MSM_CPU_8930AA,
+ [142] = {MSM_CPU_8930AA, "MSM8930AA"},
+ [143] = {MSM_CPU_8930AA, "MSM8930AA"},
+ [144] = {MSM_CPU_8930AA, "MSM8930AA"},
+ [160] = {MSM_CPU_8930AA, "MSM8930AA"},
+ [180] = {MSM_CPU_8930AA, "MSM8930AA"},
/* 8226 IDs */
- [145] = MSM_CPU_8226,
- [158] = MSM_CPU_8226,
- [159] = MSM_CPU_8226,
- [198] = MSM_CPU_8226,
- [199] = MSM_CPU_8226,
- [200] = MSM_CPU_8226,
- [205] = MSM_CPU_8226,
- [219] = MSM_CPU_8226,
- [220] = MSM_CPU_8226,
- [221] = MSM_CPU_8226,
- [222] = MSM_CPU_8226,
- [223] = MSM_CPU_8226,
- [224] = MSM_CPU_8226,
+ [145] = {MSM_CPU_8226, "MSM8626"},
+ [158] = {MSM_CPU_8226, "MSM8226"},
+ [159] = {MSM_CPU_8226, "MSM8526"},
+ [198] = {MSM_CPU_8226, "MSM8126"},
+ [199] = {MSM_CPU_8226, "APQ8026"},
+ [200] = {MSM_CPU_8226, "MSM8926"},
+ [205] = {MSM_CPU_8226, "MSM8326"},
+ [219] = {MSM_CPU_8226, "APQ8028"},
+ [220] = {MSM_CPU_8226, "MSM8128"},
+ [221] = {MSM_CPU_8226, "MSM8228"},
+ [222] = {MSM_CPU_8226, "MSM8528"},
+ [223] = {MSM_CPU_8226, "MSM8628"},
+ [224] = {MSM_CPU_8226, "MSM8928"},
/* 8092 IDs */
- [146] = MSM_CPU_8092,
+ [146] = {MSM_CPU_8092, "MSM8092"},
/* 8610 IDs */
- [147] = MSM_CPU_8610,
- [161] = MSM_CPU_8610,
- [162] = MSM_CPU_8610,
- [163] = MSM_CPU_8610,
- [164] = MSM_CPU_8610,
- [165] = MSM_CPU_8610,
- [166] = MSM_CPU_8610,
- [225] = MSM_CPU_8610,
- [226] = MSM_CPU_8610,
+ [147] = {MSM_CPU_8610, "MSM8610"},
+ [161] = {MSM_CPU_8610, "MSM8110"},
+ [162] = {MSM_CPU_8610, "MSM8210"},
+ [163] = {MSM_CPU_8610, "MSM8810"},
+ [164] = {MSM_CPU_8610, "MSM8212"},
+ [165] = {MSM_CPU_8610, "MSM8612"},
+ [166] = {MSM_CPU_8610, "MSM8112"},
+ [225] = {MSM_CPU_8610, "MSM8510"},
+ [226] = {MSM_CPU_8610, "MSM8512"},
/* 8064AB IDs */
- [153] = MSM_CPU_8064AB,
+ [153] = {MSM_CPU_8064AB, "APQ8064AB"},
/* 8930AB IDs */
- [154] = MSM_CPU_8930AB,
- [155] = MSM_CPU_8930AB,
- [156] = MSM_CPU_8930AB,
- [157] = MSM_CPU_8930AB,
- [181] = MSM_CPU_8930AB,
+ [154] = {MSM_CPU_8930AB, "MSM8930AB"},
+ [155] = {MSM_CPU_8930AB, "MSM8930AB"},
+ [156] = {MSM_CPU_8930AB, "MSM8930AB"},
+ [157] = {MSM_CPU_8930AB, "MSM8930AB"},
+ [181] = {MSM_CPU_8930AB, "MSM8930AB"},
/* 8625Q IDs */
- [168] = MSM_CPU_8625Q,
- [169] = MSM_CPU_8625Q,
- [170] = MSM_CPU_8625Q,
+ [168] = {MSM_CPU_8625Q, "MSM8225Q"},
+ [169] = {MSM_CPU_8625Q, "MSM8625Q"},
+ [170] = {MSM_CPU_8625Q, "MSM8125Q"},
/* 8064AA IDs */
- [172] = MSM_CPU_8064AA,
+ [172] = {MSM_CPU_8064AA, "APQ8064AA"},
/* 8084 IDs */
- [178] = MSM_CPU_8084,
+ [178] = {MSM_CPU_8084, "APQ8084"},
/* krypton IDs */
- [187] = MSM_CPU_KRYPTON,
+ [187] = {MSM_CPU_KRYPTON, "MSMKRYPTON"},
/* FSM9900 ID */
- [188] = FSM_CPU_9900,
+ [188] = {FSM_CPU_9900, "FSM9900"},
/* Samarium IDs */
- [195] = MSM_CPU_SAMARIUM,
+ [195] = {MSM_CPU_SAMARIUM, "MSMSAMARIUM"},
/* Uninitialized IDs are not known to run Linux.
MSM_CPU_UNKNOWN is set to 0 to ensure these IDs are
@@ -455,6 +458,25 @@
return (socinfo) ? socinfo->v1.build_id : NULL;
}
+static char *msm_read_hardware_id(void)
+{
+ static char msm_soc_str[128] = "Qualcomm ";
+ static bool string_generated = false;
+
+ if (string_generated)
+ return msm_soc_str;
+ if (!socinfo)
+ goto err_path;
+ if (!cpu_of_id[socinfo->v1.id].soc_id_string)
+ goto err_path;
+
+ string_generated = true;
+ return strncat(msm_soc_str, cpu_of_id[socinfo->v1.id].soc_id_string,
+ sizeof(msm_soc_str) - strlen(msm_soc_str));
+err_path:
+ return "UNKNOWN SOC TYPE";
+}
+
uint32_t socinfo_get_raw_id(void)
{
return socinfo ?
@@ -1437,14 +1459,16 @@
}
WARN(!socinfo_get_id(), "Unknown SOC ID!\n");
- WARN(socinfo_get_id() >= ARRAY_SIZE(cpu_of_id),
- "New IDs added! ID => CPU mapping might need an update.\n");
- if (socinfo->v1.id < ARRAY_SIZE(cpu_of_id))
- cur_cpu = cpu_of_id[socinfo->v1.id];
+ if (socinfo_get_id() >= ARRAY_SIZE(cpu_of_id))
+ BUG_ON("New IDs added! ID => CPU mapping might need an update.\n");
+
+ else
+ cur_cpu = cpu_of_id[socinfo->v1.id].generic_soc_type;
boot_stats_init();
socinfo_print();
+ arch_read_hardware_id = msm_read_hardware_id;
return 0;
}
diff --git a/drivers/gpu/ion/ion_cma_secure_heap.c b/drivers/gpu/ion/ion_cma_secure_heap.c
index d375c00..0aef596 100644
--- a/drivers/gpu/ion/ion_cma_secure_heap.c
+++ b/drivers/gpu/ion/ion_cma_secure_heap.c
@@ -446,6 +446,7 @@
if (ret) {
ret = ion_secure_cma_add_to_pool(sheap, len);
if (ret) {
+ mutex_unlock(&sheap->alloc_lock);
dev_err(sheap->dev, "Fail to allocate buffer\n");
goto err;
}
diff --git a/drivers/hwmon/qpnp-adc-current.c b/drivers/hwmon/qpnp-adc-current.c
index 067a887..44da261 100644
--- a/drivers/hwmon/qpnp-adc-current.c
+++ b/drivers/hwmon/qpnp-adc-current.c
@@ -1014,7 +1014,7 @@
int32_t qpnp_iadc_get_rsense(struct qpnp_iadc_chip *iadc, int32_t *rsense)
{
- uint8_t rslt_rsense;
+ uint8_t rslt_rsense = 0;
int32_t rc = 0, sign_bit = 0;
if (qpnp_iadc_is_valid(iadc) < 0)
@@ -1022,36 +1022,37 @@
if (iadc->external_rsense) {
*rsense = iadc->rsense;
- return rc;
- }
-
- if (iadc->default_internal_rsense) {
+ } else if (iadc->default_internal_rsense) {
*rsense = iadc->rsense_workaround_value;
- return rc;
- }
+ } else {
- rc = qpnp_iadc_read_reg(iadc, QPNP_IADC_NOMINAL_RSENSE, &rslt_rsense);
- if (rc < 0) {
- pr_err("qpnp adc rsense read failed with %d\n", rc);
- return rc;
- }
+ rc = qpnp_iadc_read_reg(iadc, QPNP_IADC_NOMINAL_RSENSE,
+ &rslt_rsense);
+ if (rc < 0) {
+ pr_err("qpnp adc rsense read failed with %d\n", rc);
+ return rc;
+ }
- pr_debug("rsense:0%x\n", rslt_rsense);
+ pr_debug("rsense:0%x\n", rslt_rsense);
- if (rslt_rsense & QPNP_RSENSE_MSB_SIGN_CHECK)
- sign_bit = 1;
+ if (rslt_rsense & QPNP_RSENSE_MSB_SIGN_CHECK)
+ sign_bit = 1;
- rslt_rsense &= ~QPNP_RSENSE_MSB_SIGN_CHECK;
+ rslt_rsense &= ~QPNP_RSENSE_MSB_SIGN_CHECK;
- if (sign_bit)
- *rsense = QPNP_IADC_INTERNAL_RSENSE_N_OHMS_FACTOR -
+ if (sign_bit)
+ *rsense = QPNP_IADC_INTERNAL_RSENSE_N_OHMS_FACTOR -
(rslt_rsense * QPNP_IADC_RSENSE_LSB_N_OHMS_PER_BIT);
- else
- *rsense = QPNP_IADC_INTERNAL_RSENSE_N_OHMS_FACTOR +
+ else
+ *rsense = QPNP_IADC_INTERNAL_RSENSE_N_OHMS_FACTOR +
(rslt_rsense * QPNP_IADC_RSENSE_LSB_N_OHMS_PER_BIT);
-
+ }
pr_debug("rsense value is %d\n", *rsense);
+ if (*rsense == 0)
+ pr_err("incorrect rsens value:%d rslt_rsense:%d\n",
+ *rsense, rslt_rsense);
+
return rc;
}
EXPORT_SYMBOL(qpnp_iadc_get_rsense);
@@ -1215,6 +1216,11 @@
if (qpnp_iadc_is_valid(iadc) < 0)
return -EPROBE_DEFER;
+ if ((iadc->adc->calib.gain_raw - iadc->adc->calib.offset_raw) == 0) {
+ pr_err("raw offset errors! run iadc calibration again\n");
+ return -EINVAL;
+ }
+
mutex_lock(&iadc->adc->adc_lock);
if (iadc->iadc_poll_eoc) {
@@ -1251,6 +1257,11 @@
result_current = i_result->result_uv;
result_current *= QPNP_IADC_NANO_VOLTS_FACTOR;
/* Intentional fall through. Process the result w/o comp */
+ if (!rsense_u_ohms) {
+ pr_err("rsense error=%d\n", rsense_u_ohms);
+ goto fail_release_vadc;
+ }
+
do_div(result_current, rsense_u_ohms);
if (sign) {
diff --git a/drivers/spmi/qpnp-int.c b/drivers/spmi/qpnp-int.c
index 3e14333..9fc7299 100644
--- a/drivers/spmi/qpnp-int.c
+++ b/drivers/spmi/qpnp-int.c
@@ -184,6 +184,22 @@
return 0;
}
+static void qpnpint_irq_ack(struct irq_data *d)
+{
+ struct q_irq_data *irq_d = irq_data_get_irq_chip_data(d);
+ int rc;
+
+ pr_debug("hwirq %lu irq: %d\n", d->hwirq, d->irq);
+
+ rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_LATCHED_CLR,
+ &irq_d->mask_shift, 1);
+ if (rc) {
+ pr_err_ratelimited("spmi write failure on irq %d, rc=%d\n",
+ d->irq, rc);
+ return;
+ }
+}
+
static void qpnpint_irq_mask(struct irq_data *d)
{
struct q_irq_data *irq_d = irq_data_get_irq_chip_data(d);
@@ -223,44 +239,10 @@
static void qpnpint_irq_mask_ack(struct irq_data *d)
{
- struct q_irq_data *irq_d = irq_data_get_irq_chip_data(d);
- struct q_chip_data *chip_d = irq_d->chip_d;
- struct q_perip_data *per_d = irq_d->per_d;
- int rc;
- uint8_t prev_int_en = per_d->int_en;
-
pr_debug("hwirq %lu irq: %d\n", d->hwirq, d->irq);
- if (!chip_d->cb) {
- pr_warn_ratelimited("No arbiter on bus=%u slave=%u offset=%u\n",
- chip_d->bus_nr, irq_d->spmi_slave,
- irq_d->spmi_offset);
- return;
- }
-
- per_d->int_en &= ~irq_d->mask_shift;
-
- if (prev_int_en && !(per_d->int_en)) {
- /*
- * no interrupt on this peripheral is enabled
- * ask the arbiter to ignore this peripheral
- */
- qpnpint_arbiter_op(d, irq_d, chip_d->cb->mask);
- }
-
- rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_EN_CLR,
- &irq_d->mask_shift, 1);
- if (rc) {
- pr_err("spmi failure on irq %d\n", d->irq);
- return;
- }
-
- rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_LATCHED_CLR,
- &irq_d->mask_shift, 1);
- if (rc) {
- pr_err("spmi failure on irq %d\n", d->irq);
- return;
- }
+ qpnpint_irq_mask(d);
+ qpnpint_irq_ack(d);
}
static void qpnpint_irq_unmask(struct irq_data *d)
@@ -269,6 +251,7 @@
struct q_chip_data *chip_d = irq_d->chip_d;
struct q_perip_data *per_d = irq_d->per_d;
int rc;
+ uint8_t buf[2];
uint8_t prev_int_en = per_d->int_en;
pr_debug("hwirq %lu irq: %d\n", d->hwirq, d->irq);
@@ -289,12 +272,29 @@
*/
qpnpint_arbiter_op(d, irq_d, chip_d->cb->unmask);
}
- rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_EN_SET,
- &irq_d->mask_shift, 1);
+
+ /* Check the current state of the interrupt enable bit. */
+ rc = qpnpint_spmi_read(irq_d, QPNPINT_REG_EN_SET, buf, 1);
if (rc) {
- pr_err("spmi failure on irq %d\n", d->irq);
+ pr_err("SPMI read failure for IRQ %d, rc=%d\n", d->irq, rc);
return;
}
+
+ if (!(buf[0] & irq_d->mask_shift)) {
+ /*
+ * Since the interrupt is currently disabled, write to both the
+ * LATCHED_CLR and EN_SET registers so that a spurious interrupt
+ * cannot be triggered when the interrupt is enabled.
+ */
+ buf[0] = irq_d->mask_shift;
+ buf[1] = irq_d->mask_shift;
+ rc = qpnpint_spmi_write(irq_d, QPNPINT_REG_LATCHED_CLR, buf, 2);
+ if (rc) {
+ pr_err("SPMI write failure for IRQ %d, rc=%d\n", d->irq,
+ rc);
+ return;
+ }
+ }
}
static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type)
@@ -336,6 +336,11 @@
return rc;
}
+ if (flow_type & IRQ_TYPE_EDGE_BOTH)
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
+ else
+ __irq_set_handler_locked(d->irq, handle_level_irq);
+
return 0;
}
@@ -363,6 +368,7 @@
static struct irq_chip qpnpint_chip = {
.name = "qpnp-int",
+ .irq_ack = qpnpint_irq_ack,
.irq_mask = qpnpint_irq_mask,
.irq_mask_ack = qpnpint_irq_mask_ack,
.irq_unmask = qpnpint_irq_unmask,
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
index 8c7dc29..78ecf16 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
@@ -418,6 +418,7 @@
{
struct mdss_mdp_cmd_ctx *ctx;
unsigned long flags;
+ bool enable_rdptr = false;
ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
if (!ctx) {
@@ -429,12 +430,14 @@
if (!handle->enabled) {
handle->enabled = true;
list_add(&handle->list, &ctx->vsync_handlers);
- if (!handle->cmd_post_flush)
- ctx->vsync_enabled = 1;
+
+ enable_rdptr = !handle->cmd_post_flush;
+ if (enable_rdptr)
+ ctx->vsync_enabled++;
}
spin_unlock_irqrestore(&ctx->clk_lock, flags);
- if (!handle->cmd_post_flush)
+ if (enable_rdptr)
mdss_mdp_cmd_clk_on(ctx);
return 0;
@@ -443,11 +446,8 @@
static int mdss_mdp_cmd_remove_vsync_handler(struct mdss_mdp_ctl *ctl,
struct mdss_mdp_vsync_handler *handle)
{
-
struct mdss_mdp_cmd_ctx *ctx;
unsigned long flags;
- struct mdss_mdp_vsync_handler *tmp;
- int num_rdptr_vsync = 0;
ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
if (!ctx) {
@@ -455,19 +455,17 @@
return -ENODEV;
}
-
spin_lock_irqsave(&ctx->clk_lock, flags);
if (handle->enabled) {
handle->enabled = false;
list_del_init(&handle->list);
- }
- list_for_each_entry(tmp, &ctx->vsync_handlers, list) {
- if (!tmp->cmd_post_flush)
- num_rdptr_vsync++;
- }
- if (!num_rdptr_vsync) {
- ctx->vsync_enabled = 0;
- ctx->rdptr_enabled = VSYNC_EXPIRE_TICK;
+
+ if (!handle->cmd_post_flush) {
+ if (ctx->vsync_enabled)
+ ctx->vsync_enabled--;
+ else
+ WARN(1, "unbalanced vsync disable");
+ }
}
spin_unlock_irqrestore(&ctx->clk_lock, flags);
return 0;
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 7420f95..d5da709 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -974,6 +974,11 @@
int ret = 0;
int sd_in_pipe = 0;
+ if (!ctl) {
+ pr_warn("kickoff on fb=%d without a ctl attched\n", mfd->index);
+ return ret;
+ }
+
if (ctl->shared_lock)
mutex_lock(ctl->shared_lock);
diff --git a/mm/compaction.c b/mm/compaction.c
index 673142d..35bb243 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -243,7 +243,6 @@
{
int nr_scanned = 0, total_isolated = 0;
struct page *cursor, *valid_page = NULL;
- unsigned long nr_strict_required = end_pfn - blockpfn;
unsigned long flags;
bool locked = false;
@@ -256,11 +255,12 @@
nr_scanned++;
if (!pfn_valid_within(blockpfn))
- continue;
+ goto isolate_fail;
+
if (!valid_page)
valid_page = page;
if (!PageBuddy(page))
- continue;
+ goto isolate_fail;
/*
* The zone lock must be held to isolate freepages.
@@ -281,12 +281,10 @@
/* Recheck this is a buddy page under lock */
if (!PageBuddy(page))
- continue;
+ goto isolate_fail;
/* Found a free page, break it into order-0 pages */
isolated = split_free_page(page);
- if (!isolated && strict)
- break;
total_isolated += isolated;
for (i = 0; i < isolated; i++) {
list_add(&page->lru, freelist);
@@ -297,7 +295,13 @@
if (isolated) {
blockpfn += isolated - 1;
cursor += isolated - 1;
+ continue;
}
+
+isolate_fail:
+ if (strict)
+ break;
+
}
trace_mm_compaction_isolate_freepages(nr_scanned, total_isolated);
@@ -307,7 +311,7 @@
* pages requested were isolated. If there were any failures, 0 is
* returned and CMA will fail.
*/
- if (strict && nr_strict_required > total_isolated)
+ if (strict && blockpfn < end_pfn)
total_isolated = 0;
if (locked)
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 7f38d35..a8d7ed0 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -896,13 +896,13 @@
sin6->sin6_port = 0;
sin6->sin6_addr = ip6->saddr;
+ sin6->sin6_flowinfo = 0;
if (np->sndflow)
sin6->sin6_flowinfo =
*(__be32 *)ip6 & IPV6_FLOWINFO_MASK;
- if (__ipv6_addr_needs_scope_id(
- ipv6_addr_type(&sin6->sin6_addr)))
- sin6->sin6_scope_id = IP6CB(skb)->iif;
+ sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr,
+ IP6CB(skb)->iif);
if (inet6_sk(sk)->rxopt.all)
pingv6_ops.datagram_recv_ctl(sk, msg, skb);