Merge branch 'android-msm-barbet-4.19-sc-security' into android-msm-barbet-4.19-sc
Nov 2021.1
Bug: 198397628
Change-Id: I657688f1d4c9812e5463a7eae23e758cc1ceaba7
diff --git a/Documentation/ABI/testing/sysfs-class-udc b/Documentation/ABI/testing/sysfs-class-udc
new file mode 100644
index 0000000..3119a04
--- /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/lito-redbull-battery.dtsi b/arch/arm64/boot/dts/google/lito-redbull-battery.dtsi
index 61cad1b..8c630de 100644
--- a/arch/arm64/boot/dts/google/lito-redbull-battery.dtsi
+++ b/arch/arm64/boot/dts/google/lito-redbull-battery.dtsi
@@ -55,11 +55,12 @@
"batt-id";
qcom,cl-feedback-on;
qcom,qg-ext-sns;
- 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,vbatt-cutoff-mv = <3300>;
qcom,vbatt-low-mv = <3500>;
@@ -213,6 +214,7 @@
google,bd-recharge-soc = <79>;
/* Enable TEMP-DEFEND */
google,bd-temp-enable;
+ google,bd-temp-dry-run;
};
google_charger_pd_5v: google,charger_pd_5v {
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 0ffd25fa..2b2ce7a 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -709,6 +709,7 @@
u32 pyld_sz;
u64 uptr = 0;
u8 *param = NULL;
+ u8 *param2 = NULL;
u8 *kptr = NULL;
if (copy_from_user(header, (const void __user *)arg,
@@ -747,11 +748,20 @@
retval = -EFAULT;
goto free_param_kptr;
}
+
+ param2 = memdup_user((const void __user *)arg,
+ sizeof(struct ipa_ioc_add_rt_rule_v2));
+ if (IS_ERR(param2)) {
+ retval = -EFAULT;
+ goto free_param_kptr;
+ }
+
+
/* add check in case user-space module compromised */
- if (unlikely(((struct ipa_ioc_add_rt_rule_v2 *)param)->num_rules
+ if (unlikely(((struct ipa_ioc_add_rt_rule_v2 *)param2)->num_rules
!= pre_entry)) {
IPAERR_RL("current %d pre %d\n",
- ((struct ipa_ioc_add_rt_rule_v2 *)param)->
+ ((struct ipa_ioc_add_rt_rule_v2 *)param2)->
num_rules, pre_entry);
retval = -EFAULT;
goto free_param_kptr;
@@ -795,6 +805,8 @@
free_param_kptr:
if (!IS_ERR(param))
kfree(param);
+ if (!IS_ERR(param2))
+ kfree(param2);
kfree(kptr);
return retval;
@@ -810,6 +822,7 @@
u32 pyld_sz;
u64 uptr = 0;
u8 *param = NULL;
+ u8 *param2 = NULL;
u8 *kptr = NULL;
if (copy_from_user(header,
@@ -851,11 +864,20 @@
retval = -EFAULT;
goto free_param_kptr;
}
+
+ param2 = memdup_user((const void __user *)arg,
+ sizeof(struct ipa_ioc_add_rt_rule_ext_v2));
+ if (IS_ERR(param2)) {
+ retval = -EFAULT;
+ goto free_param_kptr;
+ }
+
+
/* add check in case user-space module compromised */
- if (unlikely(((struct ipa_ioc_add_rt_rule_ext_v2 *)param)->num_rules
+ if (unlikely(((struct ipa_ioc_add_rt_rule_ext_v2 *)param2)->num_rules
!= pre_entry)) {
IPAERR_RL("current %d pre %d\n",
- ((struct ipa_ioc_add_rt_rule_ext_v2 *)param)->
+ ((struct ipa_ioc_add_rt_rule_ext_v2 *)param2)->
num_rules, pre_entry);
retval = -EFAULT;
goto free_param_kptr;
@@ -901,6 +923,8 @@
free_param_kptr:
if (!IS_ERR(param))
kfree(param);
+ if (!IS_ERR(param2))
+ kfree(param2);
kfree(kptr);
return retval;
@@ -916,6 +940,7 @@
u32 pyld_sz;
u64 uptr = 0;
u8 *param = NULL;
+ u8 *param2 = NULL;
u8 *kptr = NULL;
if (copy_from_user(header, (const void __user *)arg,
@@ -956,11 +981,19 @@
retval = -EFAULT;
goto free_param_kptr;
}
+
+ param2 = memdup_user((const void __user *)arg,
+ sizeof(struct ipa_ioc_add_rt_rule_after_v2));
+ if (IS_ERR(param2)) {
+ retval = -EFAULT;
+ goto free_param_kptr;
+ }
+
/* add check in case user-space module compromised */
- if (unlikely(((struct ipa_ioc_add_rt_rule_after_v2 *)param)->num_rules
+ if (unlikely(((struct ipa_ioc_add_rt_rule_after_v2 *)param2)->num_rules
!= pre_entry)) {
IPAERR_RL("current %d pre %d\n",
- ((struct ipa_ioc_add_rt_rule_after_v2 *)param)->
+ ((struct ipa_ioc_add_rt_rule_after_v2 *)param2)->
num_rules, pre_entry);
retval = -EFAULT;
goto free_param_kptr;
@@ -1004,6 +1037,8 @@
free_param_kptr:
if (!IS_ERR(param))
kfree(param);
+ if (!IS_ERR(param2))
+ kfree(param2);
kfree(kptr);
return retval;
@@ -1019,6 +1054,7 @@
u32 pyld_sz;
u64 uptr = 0;
u8 *param = NULL;
+ u8 *param2 = NULL;
u8 *kptr = NULL;
if (copy_from_user(header, (const void __user *)arg,
@@ -1059,11 +1095,19 @@
retval = -EFAULT;
goto free_param_kptr;
}
+
+ param2 = memdup_user((const void __user *)arg,
+ sizeof(struct ipa_ioc_mdfy_rt_rule_v2));
+ if (IS_ERR(param2)) {
+ retval = -EFAULT;
+ goto free_param_kptr;
+ }
+
/* add check in case user-space module compromised */
- if (unlikely(((struct ipa_ioc_mdfy_rt_rule_v2 *)param)->num_rules
+ if (unlikely(((struct ipa_ioc_mdfy_rt_rule_v2 *)param2)->num_rules
!= pre_entry)) {
IPAERR_RL("current %d pre %d\n",
- ((struct ipa_ioc_mdfy_rt_rule_v2 *)param)->
+ ((struct ipa_ioc_mdfy_rt_rule_v2 *)param2)->
num_rules, pre_entry);
retval = -EFAULT;
goto free_param_kptr;
@@ -1107,6 +1151,8 @@
free_param_kptr:
if (!IS_ERR(param))
kfree(param);
+ if (!IS_ERR(param2))
+ kfree(param2);
kfree(kptr);
return retval;
@@ -1122,6 +1168,7 @@
u32 pyld_sz;
u64 uptr = 0;
u8 *param = NULL;
+ u8 *param2 = NULL;
u8 *kptr = NULL;
if (copy_from_user(header, (const void __user *)arg,
@@ -1161,11 +1208,19 @@
retval = -EFAULT;
goto free_param_kptr;
}
+
+ param2 = memdup_user((const void __user *)arg,
+ sizeof(struct ipa_ioc_add_flt_rule_v2));
+ if (IS_ERR(param2)) {
+ retval = -EFAULT;
+ goto free_param_kptr;
+ }
+
/* add check in case user-space module compromised */
- if (unlikely(((struct ipa_ioc_add_flt_rule_v2 *)param)->num_rules
+ if (unlikely(((struct ipa_ioc_add_flt_rule_v2 *)param2)->num_rules
!= pre_entry)) {
IPAERR_RL("current %d pre %d\n",
- ((struct ipa_ioc_add_flt_rule_v2 *)param)->
+ ((struct ipa_ioc_add_flt_rule_v2 *)param2)->
num_rules, pre_entry);
retval = -EFAULT;
goto free_param_kptr;
@@ -1208,6 +1263,8 @@
free_param_kptr:
if (!IS_ERR(param))
kfree(param);
+ if (!IS_ERR(param2))
+ kfree(param2);
kfree(kptr);
return retval;
@@ -1223,6 +1280,7 @@
u32 pyld_sz;
u64 uptr = 0;
u8 *param = NULL;
+ u8 *param2 = NULL;
u8 *kptr = NULL;
if (copy_from_user(header, (const void __user *)arg,
@@ -1263,11 +1321,19 @@
retval = -EFAULT;
goto free_param_kptr;
}
+
+ param2 = memdup_user((const void __user *)arg,
+ sizeof(struct ipa_ioc_add_flt_rule_after_v2));
+ if (IS_ERR(param2)) {
+ retval = -EFAULT;
+ goto free_param_kptr;
+ }
+
/* add check in case user-space module compromised */
- if (unlikely(((struct ipa_ioc_add_flt_rule_after_v2 *)param)->num_rules
+ if (unlikely(((struct ipa_ioc_add_flt_rule_after_v2 *)param2)->num_rules
!= pre_entry)) {
IPAERR_RL("current %d pre %d\n",
- ((struct ipa_ioc_add_flt_rule_after_v2 *)param)->
+ ((struct ipa_ioc_add_flt_rule_after_v2 *)param2)->
num_rules, pre_entry);
retval = -EFAULT;
goto free_param_kptr;
@@ -1311,6 +1377,8 @@
free_param_kptr:
if (!IS_ERR(param))
kfree(param);
+ if (!IS_ERR(param2))
+ kfree(param2);
kfree(kptr);
return retval;
@@ -1326,6 +1394,7 @@
u32 pyld_sz;
u64 uptr = 0;
u8 *param = NULL;
+ u8 *param2 = NULL;
u8 *kptr = NULL;
if (copy_from_user(header, (const void __user *)arg,
@@ -1366,11 +1435,19 @@
retval = -EFAULT;
goto free_param_kptr;
}
+
+ param2 = memdup_user((const void __user *)arg,
+ sizeof(struct ipa_ioc_mdfy_flt_rule_v2));
+ if (IS_ERR(param2)) {
+ retval = -EFAULT;
+ goto free_param_kptr;
+ }
+
/* add check in case user-space module compromised */
- if (unlikely(((struct ipa_ioc_mdfy_flt_rule_v2 *)param)->num_rules
+ if (unlikely(((struct ipa_ioc_mdfy_flt_rule_v2 *)param2)->num_rules
!= pre_entry)) {
IPAERR_RL("current %d pre %d\n",
- ((struct ipa_ioc_mdfy_flt_rule_v2 *)param)->
+ ((struct ipa_ioc_mdfy_flt_rule_v2 *)param2)->
num_rules, pre_entry);
retval = -EFAULT;
goto free_param_kptr;
@@ -1414,6 +1491,8 @@
free_param_kptr:
if (!IS_ERR(param))
kfree(param);
+ if (!IS_ERR(param2))
+ kfree(param2);
kfree(kptr);
return retval;
diff --git a/drivers/power/supply/google/google_battery.c b/drivers/power/supply/google/google_battery.c
index 24174b2..5206a61 100644
--- a/drivers/power/supply/google/google_battery.c
+++ b/drivers/power/supply/google/google_battery.c
@@ -2741,6 +2741,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)
{
@@ -4128,6 +4134,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)
{
@@ -4181,6 +4207,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 304cc9d..18a7fab 100644
--- a/drivers/power/supply/google/google_charger.c
+++ b/drivers/power/supply/google/google_charger.c
@@ -2691,6 +2691,40 @@
static DEVICE_ATTR_RW(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)
{
@@ -3178,6 +3212,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;
+ }
+
de = debugfs_create_dir("google_charger", 0);
if (!de)
diff --git a/drivers/power/supply/qcom/fg-alg.c b/drivers/power/supply/qcom/fg-alg.c
index 0159f15..0352382 100644
--- a/drivers/power/supply/qcom/fg-alg.c
+++ b/drivers/power/supply/qcom/fg-alg.c
@@ -12,6 +12,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
@@ -294,6 +296,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 */
/**
@@ -331,13 +349,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;
}
}
@@ -346,9 +380,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;
}
}
@@ -541,6 +575,9 @@
{
int rc;
+ if (cl->cl_skip == true)
+ return -ENODATA;
+
rc = cap_learning_process_full_data(cl, batt_soc_cp);
if (rc < 0) {
pr_debug("Error in processing cap learning full data, rc=%d\n",
@@ -630,6 +667,8 @@
if (charge_status == POWER_SUPPLY_STATUS_CHARGING) {
rc = cap_learning_begin(cl, batt_soc_cp);
cl->active = (rc == 0);
+ if (cl->active)
+ cl->cl_skip = false;
} else {
if (charge_status == POWER_SUPPLY_STATUS_DISCHARGING ||
charge_done)
diff --git a/drivers/power/supply/qcom/fg-alg.h b/drivers/power/supply/qcom/fg-alg.h
index 34442c7..df9b3e8 100644
--- a/drivers/power/supply/qcom/fg-alg.h
+++ b/drivers/power/supply/qcom/fg-alg.h
@@ -41,6 +41,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;
@@ -59,6 +60,7 @@
int64_t learned_cap_uah;
int64_t delta_cap_uah;
bool active;
+ bool cl_skip;
struct mutex lock;
struct cl_params dt;
bool (*ok_to_begin)(void *data);
diff --git a/drivers/power/supply/qcom/qpnp-qg.c b/drivers/power/supply/qcom/qpnp-qg.c
index da4777b..f6ff7a2 100644
--- a/drivers/power/supply/qcom/qpnp-qg.c
+++ b/drivers/power/supply/qcom/qpnp-qg.c
@@ -1309,7 +1309,9 @@
} else if (input_present && cc_soc_delta > MAX_CC_SOC_DELTA) {
pr_info("cc_soc %d exceeds FULL, calibrate qg_soc\n",
chip->udata.param[QG_CC_SOC].data);
- qg_trigger_good_ocv(chip);
+ rc = qg_trigger_good_ocv(chip);
+ if (rc == 0)
+ chip->cl->cl_skip = true;
} else {
chip->cc_soc = chip->udata.param[QG_CC_SOC].data;
}
@@ -4394,6 +4396,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 74542a9..1fc4243 100644
--- a/drivers/power/supply/qcom/smb5-lib.c
+++ b/drivers/power/supply/qcom/smb5-lib.c
@@ -2473,7 +2473,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/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 6fc1f87..51ed1c9 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -360,6 +360,7 @@
u64 dummy_gsi_db;
dma_addr_t dummy_gsi_db_dma;
int orientation_override;
+ bool usb_data_enabled;
};
#define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */
@@ -3275,6 +3276,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);
@@ -3336,6 +3340,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);
@@ -3693,6 +3700,34 @@
}
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_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node, *dwc3_node;
@@ -4065,12 +4100,15 @@
dwc3_ext_event_notify(mdwc);
}
+ /* set the initial value */
+ mdwc->usb_data_enabled = true;
device_create_file(&pdev->dev, &dev_attr_orientation);
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;
@@ -4100,6 +4138,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/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index be9a51e..3011668 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1830,19 +1830,11 @@
*/
list_for_each_entry_safe(r, t, &dep->started_list, list)
dwc3_gadget_move_cancelled_request(r);
- /* If GEN1 controller then cleanup the cancelled
- * requests from here as check for
- * DWC3_EP_END_TRANSFER_PENDING in EPCMDCMPLT
- * will prevent the request on cancelled list from
- * getting cleared there.
- */
- if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING)) {
- dbg_log_string("%s:giveback all request\n",
- __func__);
- dwc3_gadget_ep_cleanup_cancelled_requests(dep);
- }
- goto out0;
+ if (dep->flags & DWC3_EP_TRANSFER_STARTED)
+ goto out0;
+ else
+ goto out1;
}
dev_err_ratelimited(dwc->dev, "request %pK was not queued to %s\n",
request, ep->name);
@@ -1850,6 +1842,7 @@
goto out0;
}
+out1:
dbg_ep_dequeue(dep->number, req);
dwc3_gadget_ep_skip_trbs(dep, req);
dwc3_gadget_giveback(dep, req, -ECONNRESET);
@@ -3293,12 +3286,8 @@
case DWC3_DEPEVT_EPCMDCMPLT:
dep->dbg_ep_events.epcmdcomplete++;
cmd = DEPEVT_PARAMETER_CMD(event->parameters);
- /* Prevent GEN1 controllers to cleanup cancelled
- * request twice (one from error path in kick_transfer
- * another from here).
- */
- if (cmd == DWC3_DEPCMD_ENDTRANSFER &&
- (dep->flags & DWC3_EP_END_TRANSFER_PENDING)) {
+
+ if (cmd == DWC3_DEPCMD_ENDTRANSFER) {
dep->flags &= ~(DWC3_EP_END_TRANSFER_PENDING |
DWC3_EP_TRANSFER_STARTED);
dwc3_gadget_ep_cleanup_cancelled_requests(dep);
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index ff03d8a..497a723 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2587,6 +2587,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))
@@ -3949,6 +3951,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 ca637cd..b8dee37 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1331,7 +1331,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)); \
}
@@ -1341,6 +1342,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)); \
@@ -1399,6 +1401,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 4a7cd4b..cdc3e0a 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;
}