Merge branch 'android-msm-pixel-4.14-sc-security' into android-msm-pixel-4.14-sc
Oct 2021.1
Bug: 195384623
Change-Id: I56d5a2701708d599d9a7cf3db7092847f2aaf123
diff --git a/Documentation/ABI/testing/sysfs-class-udc b/Documentation/ABI/testing/sysfs-class-udc
new file mode 100644
index 0000000..7501288
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-udc
@@ -0,0 +1,16 @@
+What: /sys/class/udc/<udc name>/device/usb_data_enabled
+Date: December 2020
+Contact: "Ray Chi" <raychi@google.com>
+Description:
+ The attribute can allow user space can check and modify
+ the value to enable or disable usb functionality. Therefore,
+ if the attritube is set to 0, USB host and USB peripheral
+ modes wouldn't be working.
+
+ Example:
+ Enable USB data functionality
+ # echo 1 > /sys/class/udc/.../device/usb_data_enabled
+
+ Disable USB data functionality
+ # echo 0 > /sys/class/udc/.../device/usb_data_enabled
+
diff --git a/arch/arm64/boot/dts/google/sm7150-sunfish-battery.dtsi b/arch/arm64/boot/dts/google/sm7150-sunfish-battery.dtsi
index f6c760a..a3fb8aa 100644
--- a/arch/arm64/boot/dts/google/sm7150-sunfish-battery.dtsi
+++ b/arch/arm64/boot/dts/google/sm7150-sunfish-battery.dtsi
@@ -72,11 +72,12 @@
&pm6150_qg {
qcom,battery-data = <&sunfish_batterydata>;
qcom,cl-feedback-on;
- qcom,cl-max-increment = <5>;
- qcom,cl-max-decrement = <10>;
+ qcom,cl-max-increment = <3>;
+ qcom,cl-max-decrement = <5>;
qcom,cl-min-limit = <500>;
qcom,cl-max-limit = <0>;
qcom,cl-min-delta-batt-soc = <10>;
+ google,cl-degrade = <50>;
qcom,cl-wt-enable;
qcom,qg-iterm-ma = <460>;
qcom,vbatt-cutoff-mv = <3300>;
@@ -258,6 +259,7 @@
google,bd-recharge-soc = <79>;
/* Enable TEMP-DEFEND */
google,bd-temp-enable;
+ google,bd-temp-dry-run;
};
google_overheat_mitigation: google,overheat_mitigation {
diff --git a/arch/arm64/boot/dts/google/sm8150-floral-battery.dtsi b/arch/arm64/boot/dts/google/sm8150-floral-battery.dtsi
index 2a9cec6..84dde38 100644
--- a/arch/arm64/boot/dts/google/sm8150-floral-battery.dtsi
+++ b/arch/arm64/boot/dts/google/sm8150-floral-battery.dtsi
@@ -227,6 +227,7 @@
google,bd-recharge-soc = <79>;
/* Enable TEMP-DEFEND */
google,bd-temp-enable;
+ google,bd-temp-dry-run;
};
google_wlc_charger: google,wlc_charger {
diff --git a/arch/arm64/boot/dts/google/sm8150-floral-usb.dtsi b/arch/arm64/boot/dts/google/sm8150-floral-usb.dtsi
index 79b24fe..d873803 100644
--- a/arch/arm64/boot/dts/google/sm8150-floral-usb.dtsi
+++ b/arch/arm64/boot/dts/google/sm8150-floral-usb.dtsi
@@ -21,6 +21,7 @@
&pm8150b_pdphy {
google,ext_vbus-supported;
ext-vbus-supply = <&ext_5v_boost>;
+ goog,wlc-supported;
usb_con: connector {
compatible = "usb-c-connector";
diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index c8c5151..3264664 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -1836,7 +1836,6 @@
qcom,bark-time = <11000>;
qcom,pet-time = <9360>;
qcom,ipi-ping;
- qcom,wakeup-enable;
qcom,scandump-sizes = <0x10100 0x10100 0x10100 0x10100
0x18100 0x18100 0x18100 0x18100>;
};
diff --git a/build.config.floral_debug_memory b/build.config.floral_debug_memory
index 811d0d0..c64068f 100644
--- a/build.config.floral_debug_memory
+++ b/build.config.floral_debug_memory
@@ -11,7 +11,6 @@
-e CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC \
-e CONFIG_BOOTPARAM_HUNG_TASK_PANIC \
-e CONFIG_WQ_WATCHDOG \
- -e CONFIG_PANIC_ON_RT_THROTTLING \
-e CONFIG_RCU_EQS_DEBUG \
-e CONFIG_DEVMEM \
-e CONFIG_DEBUG_OBJECTS \
diff --git a/build.config.sunfish_debug_memory b/build.config.sunfish_debug_memory
index f82f4bb..ce636cb 100644
--- a/build.config.sunfish_debug_memory
+++ b/build.config.sunfish_debug_memory
@@ -11,7 +11,6 @@
-e CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC \
-e CONFIG_BOOTPARAM_HUNG_TASK_PANIC \
-e CONFIG_WQ_WATCHDOG \
- -e CONFIG_PANIC_ON_RT_THROTTLING \
-e CONFIG_RCU_EQS_DEBUG \
-e CONFIG_DEVMEM \
-e CONFIG_DEBUG_OBJECTS \
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 8ba90ef..6b8fb6b 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2021, 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
@@ -1294,13 +1294,30 @@
if (((ctrl->val >> 16) < inst->capability.frame_rate.min ||
(ctrl->val >> 16) > inst->capability.frame_rate.max) &&
ctrl->val != INT_MAX) {
- dprintk(VIDC_ERR, "Invalid operating rate %u\n",
- (ctrl->val >> 16));
- rc = -ENOTSUPP;
+ if (!is_realtime_session(inst)) {
+ if ((ctrl->val >> 16) <
+ inst->capability.frame_rate.min) {
+ inst->clk_data.operating_rate =
+ inst->capability.frame_rate.min << 16;
+ } else {
+ inst->clk_data.operating_rate =
+ inst->capability.frame_rate.max << 16;
+ }
+ dprintk(VIDC_DBG,
+ "inst(%pK) operating rate capped from %d to %d\n",
+ inst, ctrl->val >> 16,
+ inst->clk_data.operating_rate >> 16);
+ inst->operating_rate_set = true;
+ } else {
+ dprintk(VIDC_ERR, "Invalid operating rate %u\n",
+ (ctrl->val >> 16));
+ rc = -ENOTSUPP;
+ }
} else if (ctrl->val == INT_MAX) {
dprintk(VIDC_DBG,
"inst(%pK) Request for turbo mode\n", inst);
inst->clk_data.turbo_mode = true;
+ inst->operating_rate_set = true;
} else if (msm_vidc_validate_operating_rate(inst, ctrl->val)) {
dprintk(VIDC_ERR, "Failed to set operating rate\n");
rc = -ENOTSUPP;
@@ -1310,6 +1327,7 @@
inst, inst->clk_data.operating_rate >> 16,
ctrl->val >> 16);
inst->clk_data.operating_rate = ctrl->val;
+ inst->operating_rate_set = true;
inst->clk_data.turbo_mode = false;
}
break;
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 785eeb83..0e8609f 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2021, 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
@@ -1185,6 +1185,16 @@
),
.qmenu = roi_map_type,
},
+ {
+ .id = V4L2_CID_MPEG_VIDC_VENC_COMPLEXITY,
+ .name = "Encoder complexity",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 100,
+ .default_value = 100,
+ .step = 1,
+ .qmenu = NULL,
+ },
};
#define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls)
@@ -1462,6 +1472,12 @@
request_iframe.enable = true;
pdata = &request_iframe;
break;
+ case V4L2_CID_MPEG_VIDC_VENC_COMPLEXITY:
+ if (is_realtime_session(inst)) {
+ dprintk(VIDC_DBG,
+ "Client is setting complexity for RT session\n");
+ }
+ break;
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
{
struct hal_buffer_requirements *buff_req_buffer = NULL;
@@ -2080,11 +2096,26 @@
break;
case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE:
if (((ctrl->val >> 16) < inst->capability.frame_rate.min ||
- (ctrl->val >> 16) > inst->capability.frame_rate.max) &&
- ctrl->val != INT_MAX) {
- dprintk(VIDC_ERR, "Invalid operating rate %u\n",
- (ctrl->val >> 16));
- rc = -ENOTSUPP;
+ (ctrl->val >> 16) > inst->capability.frame_rate.max) &&
+ ctrl->val != INT_MAX) {
+ if (!is_realtime_session(inst)) {
+ if ((ctrl->val >> 16) <
+ inst->capability.frame_rate.min) {
+ inst->clk_data.operating_rate =
+ inst->capability.frame_rate.min << 16;
+ } else {
+ inst->clk_data.operating_rate =
+ inst->capability.frame_rate.max << 16;
+ }
+ dprintk(VIDC_DBG,
+ "inst(%pK) operating rate capped from %d to %d\n",
+ inst, ctrl->val >> 16,
+ inst->clk_data.operating_rate >> 16);
+ } else {
+ dprintk(VIDC_ERR, "Invalid operating rate %u\n",
+ (ctrl->val >> 16));
+ rc = -ENOTSUPP;
+ }
} else if (ctrl->val == INT_MAX) {
dprintk(VIDC_DBG, "inst(%pK) Request for turbo mode\n",
inst);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 28a4e6d..e69e631 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2021, 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
@@ -1165,6 +1165,13 @@
goto fail_start;
}
+ if (inst->session_type == MSM_VIDC_DECODER &&
+ !inst->operating_rate_set && !is_realtime_session(inst)) {
+ inst->clk_data.turbo_mode = true;
+ dprintk(VIDC_INFO,
+ "inst(%pK) setting turbo mode ");
+ }
+
/* Assign Core and LP mode for current session */
rc = msm_vidc_decide_core_and_power_mode(inst);
if (rc) {
@@ -1908,6 +1915,7 @@
inst->clk_data.ddr_bw = 0;
inst->clk_data.sys_cache_bw = 0;
inst->clk_data.bitrate = 0;
+ inst->operating_rate_set = false;
inst->clk_data.work_route = 1;
inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT;
inst->bit_depth = MSM_VIDC_BIT_DEPTH_8;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
index 40d3085..573e3c1 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
@@ -1452,6 +1452,7 @@
struct hfi_device *hdev = NULL;
enum hal_perf_mode venc_mode;
u32 rc_mode = 0;
+ int complexity;
hdev = inst->core->device;
if (inst->session_type != MSM_VIDC_ENCODER) {
@@ -1472,7 +1473,10 @@
V4L2_CID_MPEG_VIDEO_BITRATE_MODE);
if (rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)
enable = false;
-
+ complexity = msm_comm_g_ctrl_for_id(inst,
+ V4L2_CID_MPEG_VIDC_VENC_COMPLEXITY);
+ if (!is_realtime_session(inst) && !complexity)
+ enable = true;
prop_id = HAL_CONFIG_VENC_PERF_MODE;
venc_mode = enable ? HAL_PERF_MODE_POWER_SAVE :
HAL_PERF_MODE_POWER_MAX_QUALITY;
@@ -1488,9 +1492,9 @@
inst->flags = enable ?
inst->flags | VIDC_LOW_POWER :
inst->flags & ~VIDC_LOW_POWER;
-
dprintk(VIDC_PROF,
- "Power Save Mode for inst: %pK Enable = %d\n", inst, enable);
+ "Power Save Mode for inst: %pK Enable = %d\n",
+ inst, enable);
fail_power_mode_set:
return rc;
}
@@ -1560,6 +1564,7 @@
u32 current_inst_load = 0, current_inst_lp_load = 0,
min_load = 0, min_lp_load = 0;
u32 min_core_id, min_lp_core_id;
+ u32 complexity;
if (!inst || !inst->core || !inst->core->device) {
dprintk(VIDC_ERR,
@@ -1669,9 +1674,21 @@
inst->clk_data.core_id);
msm_vidc_move_core_to_power_save_mode(core, min_lp_core_id);
} else {
- rc = -EINVAL;
- dprintk(VIDC_ERR,
- "Sorry ... Core Can't support this load\n");
+ complexity = msm_comm_g_ctrl_for_id(inst,
+ V4L2_CID_MPEG_VIDC_VENC_COMPLEXITY);
+ if (!is_realtime_session(inst)) {
+ if (inst->session_type == MSM_VIDC_ENCODER)
+ msm_vidc_power_save_mode_enable(inst,
+ (complexity == 0));
+ inst->clk_data.core_id = min_core_id;
+ dprintk(VIDC_DBG, "Supporting NRT session");
+ goto decision_done;
+
+ } else {
+ rc = -EINVAL;
+ dprintk(VIDC_ERR,
+ "Sorry ... Core Can't support this load\n");
+ }
return rc;
}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 8718371..40bd328 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2021, 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
@@ -500,6 +500,7 @@
struct work_struct batch_work;
bool decode_batching;
u32 max_filled_length;
+ bool operating_rate_set;
};
extern struct msm_vidc_drv *vidc_driver;
diff --git a/drivers/power/supply/google/google_battery.c b/drivers/power/supply/google/google_battery.c
index c904f1a..b534580 100644
--- a/drivers/power/supply/google/google_battery.c
+++ b/drivers/power/supply/google/google_battery.c
@@ -2748,6 +2748,12 @@
ssoc_state->buck_enabled = ben;
}
+static void bd_trickle_reset(struct batt_ssoc_state *ssoc_state)
+{
+ ssoc_state->bd_trickle_cnt = 0;
+ ssoc_state->disconnect_time = 0;
+}
+
/* called holding chg_lock */
static int batt_chg_logic(struct batt_drv *batt_drv)
{
@@ -4135,6 +4141,26 @@
static DEVICE_ATTR_RW(bd_trickle_reset_sec);
+static ssize_t bd_clear_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct power_supply *psy = container_of(dev, struct power_supply, dev);
+ struct batt_drv *batt_drv = power_supply_get_drvdata(psy);
+ int ret = 0, val = 0;
+
+ ret = kstrtoint(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+
+ if (val)
+ bd_trickle_reset(&batt_drv->ssoc_state);
+
+ return count;
+}
+
+static DEVICE_ATTR_WO(bd_clear);
+
static ssize_t health_safety_margin_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -4187,6 +4213,7 @@
&dev_attr_bd_trickle_recharge_soc.attr,
&dev_attr_bd_trickle_dry_run.attr,
&dev_attr_bd_trickle_reset_sec.attr,
+ &dev_attr_bd_clear.attr,
&dev_attr_health_safety_margin.attr,
NULL,
};
diff --git a/drivers/power/supply/google/google_charger.c b/drivers/power/supply/google/google_charger.c
index e3af0fc..98d8f86 100644
--- a/drivers/power/supply/google/google_charger.c
+++ b/drivers/power/supply/google/google_charger.c
@@ -1222,6 +1222,10 @@
pr_info("MSC_CHG disable_charging %d -> %d",
chg_drv->disable_charging, disable_charging);
+ GPSY_SET_PROP(chg_drv->chg_psy,
+ POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE,
+ !disable_charging);
+
/* voted but not applied since msc_interval_votable <= 0 */
vote(chg_drv->msc_fcc_votable,
MSC_USER_CHG_LEVEL_VOTER,
@@ -2657,6 +2661,40 @@
static DEVICE_ATTR(bd_temp_dry_run, 0660,
show_bd_temp_dry_run, set_bd_temp_dry_run);
+static ssize_t bd_clear_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct chg_drv *chg_drv = dev_get_drvdata(dev);
+ int ret = 0, val = 0;
+
+ ret = kstrtoint(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+
+ if (!val)
+ return ret;
+
+ mutex_lock(&chg_drv->bd_lock);
+
+ ret = bd_batt_set_state(chg_drv, false, -1);
+ if (ret < 0)
+ pr_err("MSC_BD set_batt_state (%d)\n", ret);
+
+ bd_reset(&chg_drv->bd_state);
+
+ if (chg_drv->chg_psy)
+ power_supply_changed(chg_drv->chg_psy);
+
+ mutex_unlock(&chg_drv->bd_lock);
+
+ if (chg_drv->bat_psy)
+ power_supply_changed(chg_drv->bat_psy);
+
+ return count;
+}
+
+static DEVICE_ATTR_WO(bd_clear);
+
/* TODO: now created in qcom code, create in chg_create_votables() */
static int chg_find_votables(struct chg_drv *chg_drv)
{
@@ -3121,6 +3159,12 @@
return ret;
}
+ ret = device_create_file(chg_drv->device, &dev_attr_bd_clear);
+ if (ret != 0) {
+ pr_err("Failed to create bd_clear files, ret=%d\n", ret);
+ return ret;
+ }
+
#ifdef CONFIG_DEBUG_FS
de = debugfs_create_dir("google_charger", 0);
if (!de)
diff --git a/drivers/power/supply/google/sm7150_bms.c b/drivers/power/supply/google/sm7150_bms.c
index 20c58a5..909a657 100644
--- a/drivers/power/supply/google/sm7150_bms.c
+++ b/drivers/power/supply/google/sm7150_bms.c
@@ -1081,6 +1081,13 @@
case POWER_SUPPLY_PROP_RERUN_AICL:
(void)sm7150_rerun_aicl(bms);
break;
+ case POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE:
+ val = pval->intval ? FAST_CHARGE_SAFETY_TIMER_EN : 0;
+ rc = sm7150_masked_write(bms->pmic_regmap,
+ CHGR_SAFETY_TIMER_ENABLE_CFG_REG,
+ FAST_CHARGE_SAFETY_TIMER_EN, val);
+ pr_info("SAFETY_TIMER_ENABLE : val=%d (%d)\n", val, rc);
+ break;
default:
pr_err("setting unsupported property: %d\n", psp);
break;
diff --git a/drivers/power/supply/google/sm8150_bms.c b/drivers/power/supply/google/sm8150_bms.c
index 94a002c..0652684 100644
--- a/drivers/power/supply/google/sm8150_bms.c
+++ b/drivers/power/supply/google/sm8150_bms.c
@@ -995,6 +995,13 @@
case POWER_SUPPLY_PROP_RERUN_AICL:
(void)sm8150_rerun_aicl(bms);
break;
+ case POWER_SUPPLY_PROP_SAFETY_TIMER_ENABLE:
+ val = pval->intval ? FAST_CHARGE_SAFETY_TIMER_EN : 0;
+ rc = sm8150_masked_write(bms->pmic_regmap,
+ CHGR_SAFETY_TIMER_ENABLE_CFG_REG,
+ FAST_CHARGE_SAFETY_TIMER_EN, val);
+ pr_info("SAFETY_TIMER_ENABLE : val=%d (%d)\n", val, rc);
+ break;
default:
pr_err("setting unsupported property: %d\n", psp);
break;
diff --git a/drivers/power/supply/max1720x_battery.c b/drivers/power/supply/max1720x_battery.c
index bacd4b0..8cad308 100644
--- a/drivers/power/supply/max1720x_battery.c
+++ b/drivers/power/supply/max1720x_battery.c
@@ -1505,7 +1505,7 @@
if (chip->health_status & MAX1720X_STATUS_TMX) {
chip->health_status &= ~MAX1720X_STATUS_TMX;
- return POWER_SUPPLY_HEALTH_OVERHEAT;
+ return POWER_SUPPLY_HEALTH_HOT;
}
return POWER_SUPPLY_HEALTH_GOOD;
@@ -2848,7 +2848,7 @@
pm_runtime_get_sync(chip->dev);
if (!chip->init_complete || !chip->resume_complete) {
pm_runtime_put_sync(chip->dev);
- return -EAGAIN;
+ return IRQ_HANDLED;
}
pm_runtime_put_sync(chip->dev);
diff --git a/drivers/power/supply/qcom/fg-alg.c b/drivers/power/supply/qcom/fg-alg.c
index 3df3e25..d3178c7 100644
--- a/drivers/power/supply/qcom/fg-alg.c
+++ b/drivers/power/supply/qcom/fg-alg.c
@@ -19,6 +19,8 @@
#include <linux/slab.h>
#include <linux/sort.h>
#include "fg-alg.h"
+#include "qg-sdam.h"
+#include "qg-reg.h"
#define FULL_SOC_RAW 255
#define CAPACITY_DELTA_DECIPCT 500
@@ -301,6 +303,22 @@
return 0;
}
+static int read_cycle_count(void)
+{
+ u16 count[BUCKET_COUNT];
+ int id, rc;
+ int64_t temp = 0;
+
+ rc = qg_sdam_multibyte_read(QG_SDAM_CYCLE_COUNT_OFFSET, (u8 *)count,
+ sizeof(count));
+ if (rc < 0)
+ return -EINVAL;
+ for (id = 0; id < BUCKET_COUNT; id++)
+ temp += count[id];
+
+ return (temp / 100);
+}
+
/* Capacity learning algorithm APIs */
/**
@@ -338,13 +356,29 @@
else
cl->learned_cap_uah = cl->final_cap_uah;
+ if (cl->dt.cap_degrade > 0) {
+ int count = read_cycle_count();
+
+ if (count >= 0) {
+ min_dec_val = (int64_t)cl->nom_cap_uah *
+ (1000 - (cl->dt.cap_degrade *
+ ((count / 100) + 1)));
+ min_dec_val = div64_u64(min_dec_val, 1000);
+ if (cl->learned_cap_uah < min_dec_val) {
+ pr_err("capacity %lld below degrade %lld\n",
+ cl->learned_cap_uah, min_dec_val);
+ cl->learned_cap_uah = min_dec_val;
+ }
+ }
+ }
+
if (cl->dt.max_cap_limit >= 0) {
max_inc_val = (int64_t)cl->nom_cap_uah * (1000 +
cl->dt.max_cap_limit);
max_inc_val = div64_u64(max_inc_val, 1000);
- if (cl->final_cap_uah > max_inc_val) {
+ if (cl->learned_cap_uah > max_inc_val) {
pr_debug("learning capacity %lld goes above max limit %lld\n",
- cl->final_cap_uah, max_inc_val);
+ cl->learned_cap_uah, max_inc_val);
cl->learned_cap_uah = max_inc_val;
}
}
@@ -353,9 +387,9 @@
min_dec_val = (int64_t)cl->nom_cap_uah * (1000 -
cl->dt.min_cap_limit);
min_dec_val = div64_u64(min_dec_val, 1000);
- if (cl->final_cap_uah < min_dec_val) {
+ if (cl->learned_cap_uah < min_dec_val) {
pr_debug("learning capacity %lld goes below min limit %lld\n",
- cl->final_cap_uah, min_dec_val);
+ cl->learned_cap_uah, min_dec_val);
cl->learned_cap_uah = min_dec_val;
}
}
diff --git a/drivers/power/supply/qcom/fg-alg.h b/drivers/power/supply/qcom/fg-alg.h
index 0bf466c..ba9589a 100644
--- a/drivers/power/supply/qcom/fg-alg.h
+++ b/drivers/power/supply/qcom/fg-alg.h
@@ -48,6 +48,7 @@
int max_cap_dec;
int max_cap_limit;
int min_cap_limit;
+ int cap_degrade;
int skew_decipct;
int min_delta_batt_soc;
int ibat_flt_thr_ma;
diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c
index 9d8f528..32ad614 100644
--- a/drivers/power/supply/qcom/qpnp-qg.c
+++ b/drivers/power/supply/qcom/qpnp-qg.c
@@ -4408,6 +4408,12 @@
else
chip->cl->dt.max_cap_limit = temp;
+ rc = of_property_read_u32(node, "google,cl-degrade", &temp);
+ if (rc < 0)
+ chip->cl->dt.cap_degrade = 0;
+ else
+ chip->cl->dt.cap_degrade = temp;
+
chip->cl->dt.min_delta_batt_soc = DEFAULT_CL_DELTA_BATT_SOC;
/* read from DT property and update, if value exists */
of_property_read_u32(node, "qcom,cl-min-delta-batt-soc",
diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c
index 63f0d6c..620ba58 100644
--- a/drivers/power/supply/qcom/smb5-lib.c
+++ b/drivers/power/supply/qcom/smb5-lib.c
@@ -2323,7 +2323,7 @@
if (stat & BAT_TEMP_STATUS_TOO_COLD_BIT)
val->intval = POWER_SUPPLY_HEALTH_COLD;
else if (stat & BAT_TEMP_STATUS_TOO_HOT_BIT)
- val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
+ val->intval = POWER_SUPPLY_HEALTH_HOT;
else if (stat & BAT_TEMP_STATUS_COLD_SOFT_BIT)
val->intval = POWER_SUPPLY_HEALTH_COOL;
else if (stat & BAT_TEMP_STATUS_HOT_SOFT_BIT)
diff --git a/drivers/power/supply/qcom/smb5-reg.h b/drivers/power/supply/qcom/smb5-reg.h
index 3d7c506..42216be 100644
--- a/drivers/power/supply/qcom/smb5-reg.h
+++ b/drivers/power/supply/qcom/smb5-reg.h
@@ -119,6 +119,10 @@
#define CHGR_JEITA_THRESHOLD_BASE_REG(i) (CHGR_BASE + 0x94 + (i * 4))
#define CHGR_JEITA_HOT_THRESHOLD_MSB_REG CHGR_JEITA_THRESHOLD_BASE_REG(0)
+#define CHGR_SAFETY_TIMER_ENABLE_CFG_REG (CHGR_BASE + 0xA0)
+#define PRE_CHARGE_SAFETY_TIMER_EN BIT(1)
+#define FAST_CHARGE_SAFETY_TIMER_EN BIT(0)
+
#define CHGR_FAST_CHARGE_SAFETY_TIMER_CFG_REG (CHGR_BASE + 0xA2)
#define FAST_CHARGE_SAFETY_TIMER_192_MIN 0x0
#define FAST_CHARGE_SAFETY_TIMER_384_MIN 0x1
diff --git a/drivers/soc/qcom/watchdog_v2.c b/drivers/soc/qcom/watchdog_v2.c
index 04fa7ca..797f2dd 100644
--- a/drivers/soc/qcom/watchdog_v2.c
+++ b/drivers/soc/qcom/watchdog_v2.c
@@ -161,6 +161,9 @@
return 0;
__raw_writel(1, wdog_dd->base + WDT0_RST);
if (wdog_dd->wakeup_irq_enable) {
+ u64 timeout = (wdog_dd->bark_time * WDT_HZ)/1000;
+
+ __raw_writel(timeout - WDT_HZ, wdog_dd->base + WDT0_BITE_TIME);
/* Make sure register write is complete before proceeding */
mb();
wdog_dd->last_pet = sched_clock();
@@ -181,7 +184,11 @@
if (!enable)
return 0;
if (wdog_dd->wakeup_irq_enable) {
+ u64 timeout = (wdog_dd->bark_time * WDT_HZ)/1000;
+
__raw_writel(1, wdog_dd->base + WDT0_RST);
+ __raw_writel(timeout + WDOG_BITE_OFFSET_IN_SECONDS*WDT_HZ,
+ wdog_dd->base + WDT0_BITE_TIME);
/* Make sure register write is complete before proceeding */
mb();
wdog_dd->last_pet = sched_clock();
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 3a772ee..6e6d7c6 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -345,6 +345,7 @@
struct device_node *dwc3_node;
struct property *num_gsi_eps;
bool dual_port;
+ bool usb_data_enabled;
};
#define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */
@@ -3449,6 +3450,9 @@
if (!edev || !mdwc)
return NOTIFY_DONE;
+ if (!mdwc->usb_data_enabled)
+ return NOTIFY_DONE;
+
dwc = platform_get_drvdata(mdwc->dwc3);
dbg_event(0xFF, "extcon idx", enb->idx);
@@ -3508,6 +3512,9 @@
if (!edev || !mdwc)
return NOTIFY_DONE;
+ if (!mdwc->usb_data_enabled)
+ return NOTIFY_DONE;
+
dwc = platform_get_drvdata(mdwc->dwc3);
dbg_event(0xFF, "extcon idx", enb->idx);
@@ -3878,6 +3885,33 @@
}
static DEVICE_ATTR_RW(auto_vbus_src_sel_threshold);
+static ssize_t usb_data_enabled_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct dwc3_msm *mdwc = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%s\n",
+ mdwc->usb_data_enabled ? "enabled" : "disabled");
+}
+
+static ssize_t usb_data_enabled_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct dwc3_msm *mdwc = dev_get_drvdata(dev);
+
+ if (kstrtobool(buf, &mdwc->usb_data_enabled))
+ return -EINVAL;
+
+ if (!mdwc->usb_data_enabled) {
+ mdwc->vbus_active = false;
+ mdwc->id_state = DWC3_ID_FLOAT;
+ dwc3_ext_event_notify(mdwc);
+ }
+
+ return count;
+}
+static DEVICE_ATTR_RW(usb_data_enabled);
static int dwc3_msm_populate_gsi_params(struct dwc3_msm *mdwc)
{
@@ -4337,11 +4371,14 @@
dwc3_ext_event_notify(mdwc);
}
+ /* set the initial value */
+ mdwc->usb_data_enabled = true;
device_create_file(&pdev->dev, &dev_attr_mode);
device_create_file(&pdev->dev, &dev_attr_speed);
device_create_file(&pdev->dev, &dev_attr_usb_compliance_mode);
device_create_file(&pdev->dev, &dev_attr_bus_vote);
device_create_file(&pdev->dev, &dev_attr_auto_vbus_src_sel_threshold);
+ device_create_file(&pdev->dev, &dev_attr_usb_data_enabled);
return 0;
@@ -4385,6 +4422,7 @@
}
device_remove_file(&pdev->dev, &dev_attr_auto_vbus_src_sel_threshold);
+ device_create_file(&pdev->dev, &dev_attr_usb_data_enabled);
if (mdwc->usb_psy)
power_supply_put(mdwc->usb_psy);
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 7c636a6..c44237d 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2597,6 +2597,8 @@
return true;
if (f2fs_is_atomic_file(inode))
return true;
+ if (is_sbi_flag_set(sbi, SBI_NEED_FSCK))
+ return true;
/* swap file is migrating in aligned write mode */
if (is_inode_flag_set(inode, FI_ALIGNED_WRITE))
@@ -3959,6 +3961,8 @@
get_page(newpage);
}
+ /* guarantee to start from no stale private field */
+ set_page_private(newpage, 0);
if (PagePrivate(page)) {
set_page_private(newpage, page_private(page));
SetPagePrivate(newpage);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index d15667b4..3c7d4a1 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1333,7 +1333,8 @@
#define PAGE_PRIVATE_GET_FUNC(name, flagname) \
static inline bool page_private_##name(struct page *page) \
{ \
- return test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
+ return PagePrivate(page) && \
+ test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
}
@@ -1343,6 +1344,7 @@
if (!PagePrivate(page)) { \
get_page(page); \
SetPagePrivate(page); \
+ set_page_private(page, 0); \
} \
set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
@@ -1401,6 +1403,7 @@
if (!PagePrivate(page)) {
get_page(page);
SetPagePrivate(page);
+ set_page_private(page, 0);
}
set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page));
page_private(page) |= data << PAGE_PRIVATE_MAX;
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 5be0f1f..51aae16 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -552,7 +552,7 @@
int i;
ni->nid = nid;
-
+retry:
/* Check nat cache */
down_read(&nm_i->nat_tree_lock);
e = __lookup_nat_cache(nm_i, nid);
@@ -564,10 +564,19 @@
return 0;
}
- memset(&ne, 0, sizeof(struct f2fs_nat_entry));
+ /*
+ * Check current segment summary by trying to grab journal_rwsem first.
+ * This sem is on the critical path on the checkpoint requiring the
+ * above nat_tree_lock. Therefore, we should retry, if we failed to grab
+ * here while not bothering checkpoint.
+ */
+ if (!rwsem_is_locked(&sbi->cp_global_sem)) {
+ down_read(&curseg->journal_rwsem);
+ } else if (!down_read_trylock(&curseg->journal_rwsem)) {
+ up_read(&nm_i->nat_tree_lock);
+ goto retry;
+ }
- /* Check current segment summary */
- down_read(&curseg->journal_rwsem);
i = f2fs_lookup_journal_in_cursum(journal, NAT_JOURNAL, nid, 0);
if (i >= 0) {
ne = nat_in_journal(journal, i);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index c961aed..ad214ee 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3562,7 +3562,7 @@
goto drop_bio;
}
- if (is_sbi_flag_set(sbi, SBI_NEED_FSCK) || f2fs_cp_error(sbi)) {
+ if (f2fs_cp_error(sbi)) {
err = -EIO;
goto drop_bio;
}
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 1b829dc..2353058 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -1445,6 +1445,9 @@
V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED = 1
};
+#define V4L2_CID_MPEG_VIDC_VENC_COMPLEXITY \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 167)
+
/* Camera class control IDs */
#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900)
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index efe094b..81fb69c 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -211,6 +211,16 @@
s2idle_state = S2IDLE_STATE_NONE;
}
+static void cpu_show_backtrace(void *unused)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ pr_info("Show CPU%d call trace:\n", smp_processor_id());
+ dump_stack();
+ local_irq_restore(flags);
+}
+
static void s2idle_enter(void)
{
trace_suspend_resume(TPS("machine_suspend"), PM_SUSPEND_TO_IDLE, true);
@@ -232,8 +242,12 @@
/* Push all the CPUs into the idle loop. */
wake_up_all_idle_cpus();
/* Make the current CPU wait so it can enter the idle loop too. */
- wait_event(s2idle_wait_head,
- s2idle_state == S2IDLE_STATE_WAKE);
+ while (!wait_event_timeout(s2idle_wait_head,
+ s2idle_state == S2IDLE_STATE_WAKE,
+ msecs_to_jiffies(2000))) {
+ pr_info("s2idle_wait_head timeout, dump cores\n");
+ smp_call_function(cpu_show_backtrace, NULL, 0);
+ }
cpuidle_pause();
put_online_cpus();