Merge "usb: dwc3: gadget: Fix TRB pointer increment logic"
diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi.txt b/Documentation/devicetree/bindings/fb/mdss-dsi.txt
index 2d689d2..54e3343 100644
--- a/Documentation/devicetree/bindings/fb/mdss-dsi.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-dsi.txt
@@ -67,6 +67,7 @@
- qcom,mmss-ulp-clamp-ctrl-offset: Specifies the offset for dsi ulps clamp control register.
- qcom,mmss-phyreset-ctrl-offset: Specifies the offset for dsi phy reset control register.
- qcom,dsi-clk-ln-recovery: Boolean which enables the clk lane recovery
+- qcom,mdss-skip-clamp: Boolean which skip clamp for lanes.
mdss-dsi-ctrl is a dsi controller device which is treated as a subnode of the mdss-dsi device.
diff --git a/arch/arm64/boot/dts/qcom/msm8953-vidc.dtsi b/arch/arm64/boot/dts/qcom/msm8953-vidc.dtsi
index 1558010..743eb90 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-vidc.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-vidc.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2019, 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
@@ -88,7 +88,7 @@
<&apps_iommu 0x82c 0x01>,
<&apps_iommu 0x821 0x10>;
buffer-types = <0xfff>;
- virtual-addr-pool = <0x79000000 0x28000000
+ virtual-addr-pool = <0x79000000 0x50000000
0xa1000000 0xc9000000>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi
index 57cd8f0..6d78ede 100644
--- a/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm429-spyro-qrd-mdss-panels.dtsi
@@ -64,6 +64,11 @@
};
};
+&mdss_dsi {
+ /* Add for 429w platform */
+ qcom,mdss-skip-clamp;
+};
+
&mdss_dsi0 {
qcom,dsi-pref-prim-pan = <&dsi_edo_rm67162_qvga_cmd>;
pinctrl-names = "mdss_default", "mdss_sleep";
diff --git a/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
index 5200fd2..0648c7d 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -19,6 +19,7 @@
compatible = "qcom,ufs-phy-qmp-v3";
vdda-phy-supply = <&pm660l_l1>; /* 0.88v */
+ vdda-phy-always-on;
vdda-pll-supply = <&pm660_l1>; /* 1.2v */
vdda-phy-max-microamp = <62900>;
vdda-pll-max-microamp = <18300>;
diff --git a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
index 7162257..daf0021 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, 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
@@ -23,6 +23,7 @@
compatible = "qcom,ufs-phy-qmp-v3";
vdda-phy-supply = <&pm660l_l1>; /* 0.88v */
+ vdda-phy-always-on;
vdda-pll-supply = <&pm660_l1>; /* 1.2v */
vdda-phy-max-microamp = <62900>;
vdda-pll-max-microamp = <18300>;
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index 12c8bd9..d8bda0d 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -1000,6 +1000,7 @@
unsigned char *temp = buf;
int save_req_uid = 0;
struct diag_dci_pkt_rsp_header_t pkt_rsp_header;
+ int header_len = sizeof(struct diag_dci_pkt_rsp_header_t);
if (!buf || len <= 0) {
pr_err("diag: Invalid pointer in %s\n", __func__);
@@ -1068,14 +1069,12 @@
mutex_lock(&rsp_buf->data_mutex);
/*
* Check if we can fit the data in the rsp buffer. The total length of
- * the rsp is the rsp length (write_len) + DCI_PKT_RSP_TYPE header (int)
- * + field for length (int) + delete_flag (uint8_t)
+ * the rsp is the rsp length (write_len) + dci response packet header
+ * length (sizeof(struct diag_dci_pkt_rsp_header_t))
*/
- if ((rsp_buf->data_len + 9 + rsp_len) > rsp_buf->capacity) {
+ if ((rsp_buf->data_len + header_len + rsp_len) > rsp_buf->capacity) {
pr_alert("diag: create capacity for pkt rsp\n");
- rsp_buf->capacity += 9 + rsp_len;
- temp_buf = krealloc(rsp_buf->data, rsp_buf->capacity,
- GFP_KERNEL);
+ temp_buf = vzalloc(rsp_buf->capacity + header_len + rsp_len);
if (!temp_buf) {
pr_err("diag: DCI realloc failed\n");
mutex_unlock(&rsp_buf->data_mutex);
@@ -1083,6 +1082,10 @@
mutex_unlock(&driver->dci_mutex);
return;
}
+ rsp_buf->capacity += header_len + rsp_len;
+ if (rsp_buf->capacity > rsp_buf->data_len)
+ memcpy(temp_buf, rsp_buf->data, rsp_buf->data_len);
+ vfree(rsp_buf->data);
rsp_buf->data = temp_buf;
}
@@ -1092,9 +1095,8 @@
pkt_rsp_header.length = rsp_len + sizeof(int);
pkt_rsp_header.delete_flag = delete_flag;
pkt_rsp_header.uid = save_req_uid;
- memcpy(rsp_buf->data + rsp_buf->data_len, &pkt_rsp_header,
- sizeof(struct diag_dci_pkt_rsp_header_t));
- rsp_buf->data_len += sizeof(struct diag_dci_pkt_rsp_header_t);
+ memcpy(rsp_buf->data + rsp_buf->data_len, &pkt_rsp_header, header_len);
+ rsp_buf->data_len += header_len;
memcpy(rsp_buf->data + rsp_buf->data_len, temp, rsp_len);
rsp_buf->data_len += rsp_len;
rsp_buf->data_source = data_source;
diff --git a/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c b/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c
index 97a86ea..d802ad1 100644
--- a/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c
+++ b/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019, 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
@@ -1212,13 +1212,6 @@
struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
struct mdss_pll_resources *pll = vco->priv;
int rc;
- u64 ref_clk = vco->ref_clk_rate;
- u64 vco_rate;
- u64 multiplier;
- u32 frac;
- u32 dec;
- u32 outdiv;
- u64 pll_freq, tmp64;
if (!vco->priv)
pr_err("vco priv is null\n");
@@ -1229,12 +1222,10 @@
}
/*
- * Calculate the vco rate from HW registers only for handoff cases.
- * For other cases where a vco_10nm_set_rate() has already been
- * called, just return the rate that was set earlier. This is due
- * to the fact that recalculating VCO rate requires us to read the
- * correct value of the pll_out_div divider clock, which is only set
- * afterwards.
+ * In the case when vco arte is set, the recalculation function should
+ * return the current rate as to avoid trying to set the vco rate
+ * again. However durng handoff, recalculation should set the flag
+ * according to the status of PLL.
*/
if (pll->vco_current_rate != 0) {
pr_debug("returning vco rate = %lld\n", pll->vco_current_rate);
@@ -1251,40 +1242,9 @@
if (!dsi_pll_10nm_lock_status(pll))
pll->handoff_resources = true;
- dec = MDSS_PLL_REG_R(pll->pll_base, PLL_DECIMAL_DIV_START_1);
- dec &= 0xFF;
-
- frac = MDSS_PLL_REG_R(pll->pll_base, PLL_FRAC_DIV_START_LOW_1);
- frac |= ((MDSS_PLL_REG_R(pll->pll_base, PLL_FRAC_DIV_START_MID_1) &
- 0xFF) <<
- 8);
- frac |= ((MDSS_PLL_REG_R(pll->pll_base, PLL_FRAC_DIV_START_HIGH_1) &
- 0x3) <<
- 16);
-
- /* OUTDIV_1:0 field is (log(outdiv, 2)) */
- outdiv = MDSS_PLL_REG_R(pll->pll_base, PLL_PLL_OUTDIV_RATE);
- outdiv &= 0x3;
- outdiv = 1 << outdiv;
-
- /*
- * TODO:
- * 1. Assumes prescaler is disabled
- * 2. Multiplier is 2^18. it should be 2^(num_of_frac_bits)
- **/
- multiplier = 1 << 18;
- pll_freq = dec * (ref_clk * 2);
- tmp64 = (ref_clk * 2 * frac);
- pll_freq += div_u64(tmp64, multiplier);
-
- vco_rate = div_u64(pll_freq, outdiv);
-
- pr_debug("dec=0x%x, frac=0x%x, outdiv=%d, vco=%llu\n",
- dec, frac, outdiv, vco_rate);
-
(void)mdss_pll_resource_enable(pll, false);
- return (unsigned long)vco_rate;
+ return rc;
}
static int pixel_clk_get_div(void *context, unsigned int reg, unsigned int *div)
diff --git a/drivers/devfreq/governor_msm_adreno_tz.c b/drivers/devfreq/governor_msm_adreno_tz.c
index 3c50c4e..4937801 100644
--- a/drivers/devfreq/governor_msm_adreno_tz.c
+++ b/drivers/devfreq/governor_msm_adreno_tz.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2017, 2019 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
@@ -150,6 +150,8 @@
struct devfreq_msm_adreno_tz_data *priv,
struct devfreq *devfreq)
{
+ u64 busy;
+
spin_lock(&sample_lock);
/*
* Keep collecting the stats till the client
@@ -157,8 +159,10 @@
* is done when the entry is read
*/
acc_total += stats->total_time;
- acc_relative_busy += (stats->busy_time * stats->current_frequency) /
- devfreq->profile->freq_table[0];
+ busy = (u64)stats->busy_time * stats->current_frequency;
+ do_div(busy, devfreq->profile->freq_table[0]);
+ acc_relative_busy += busy;
+
spin_unlock(&sample_lock);
}
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index dca2e09..88af0c0 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -80,6 +80,9 @@
#define SDE_DEBUGFS_DIR "msm_sde"
#define SDE_DEBUGFS_HWMASKNAME "hw_log_mask"
+#define SDE_KMS_MODESET_LOCK_TIMEOUT_US 500
+#define SDE_KMS_MODESET_LOCK_MAX_TRIALS 20
+
/**
* sdecustom - enable certain driver customizations for sde clients
* Enabling this modifies the standard DRM behavior slightly and assumes
@@ -2768,12 +2771,79 @@
return sde_kms->splash_data.cont_splash_en;
}
+static void _sde_kms_null_commit(struct drm_device *dev,
+ struct drm_encoder *enc)
+{
+ struct drm_modeset_acquire_ctx ctx;
+ struct drm_connector *conn = NULL;
+ struct drm_connector *tmp_conn = NULL;
+ struct drm_atomic_state *state = NULL;
+ struct drm_crtc_state *crtc_state = NULL;
+ struct drm_connector_state *conn_state = NULL;
+ int retry_cnt = 0;
+ int ret = 0;
+
+ drm_modeset_acquire_init(&ctx, 0);
+
+retry:
+ ret = drm_modeset_lock_all_ctx(dev, &ctx);
+ if (ret == -EDEADLK && retry_cnt < SDE_KMS_MODESET_LOCK_MAX_TRIALS) {
+ drm_modeset_backoff(&ctx);
+ retry_cnt++;
+ udelay(SDE_KMS_MODESET_LOCK_TIMEOUT_US);
+ goto retry;
+ } else if (WARN_ON(ret)) {
+ goto end;
+ }
+
+ state = drm_atomic_state_alloc(dev);
+ if (!state) {
+ DRM_ERROR("failed to allocate atomic state, %d\n", ret);
+ goto end;
+ }
+
+ state->acquire_ctx = &ctx;
+ drm_for_each_connector(tmp_conn, dev) {
+ if (enc == tmp_conn->state->best_encoder) {
+ conn = tmp_conn;
+ break;
+ }
+ }
+
+ if (!conn) {
+ SDE_ERROR("error in finding conn for enc:%d\n", DRMID(enc));
+ goto end;
+ }
+
+ crtc_state = drm_atomic_get_crtc_state(state, enc->crtc);
+ conn_state = drm_atomic_get_connector_state(state, conn);
+ if (IS_ERR(conn_state)) {
+ SDE_ERROR("error %d getting connector %d state\n",
+ ret, DRMID(conn));
+ goto end;
+ }
+
+ crtc_state->active = true;
+ ret = drm_atomic_set_crtc_for_connector(conn_state, enc->crtc);
+
+ ret = drm_atomic_commit(state);
+ if (ret)
+ SDE_ERROR("Commit failed with %d error\n", ret);
+end:
+ if (state)
+ drm_atomic_state_free(state);
+
+ drm_modeset_drop_locks(&ctx);
+ drm_modeset_acquire_fini(&ctx);
+}
+
static int sde_kms_pm_suspend(struct device *dev)
{
struct drm_device *ddev;
struct drm_modeset_acquire_ctx ctx;
struct drm_connector *conn;
struct drm_atomic_state *state;
+ struct drm_encoder *enc;
struct sde_kms *sde_kms;
int ret = 0, num_crtcs = 0;
@@ -2790,6 +2860,12 @@
/* disable hot-plug polling */
drm_kms_helper_poll_disable(ddev);
+ /* if a display stuck in CS trigger a null commit to complete handoff */
+ drm_for_each_encoder(enc, ddev) {
+ if (sde_kms && sde_kms->splash_data.cont_splash_en && enc->crtc)
+ _sde_kms_null_commit(ddev, enc);
+ }
+
/* acquire modeset lock(s) */
drm_modeset_acquire_init(&ctx, 0);
diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c
index 0f45b4f..7b3bc51 100644
--- a/drivers/gpu/msm/adreno_dispatch.c
+++ b/drivers/gpu/msm/adreno_dispatch.c
@@ -1411,6 +1411,22 @@
user_ts = *timestamp;
+ /*
+ * If there is only one drawobj in the array and it is of
+ * type SYNCOBJ_TYPE, skip comparing user_ts as it can be 0
+ */
+ if (!(count == 1 && drawobj[0]->type == SYNCOBJ_TYPE) &&
+ (drawctxt->base.flags & KGSL_CONTEXT_USER_GENERATED_TS)) {
+ /*
+ * User specified timestamps need to be greater than the last
+ * issued timestamp in the context
+ */
+ if (timestamp_cmp(drawctxt->timestamp, user_ts) >= 0) {
+ spin_unlock(&drawctxt->lock);
+ return -ERANGE;
+ }
+ }
+
for (i = 0; i < count; i++) {
switch (drawobj[i]->type) {
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
index 7541d06..9612fde 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
@@ -1884,10 +1884,12 @@
is_ipp = true;
pxl_reg = csid_reg->ipp_reg;
path_config = &(csid_hw->ipp_path_config);
+ csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_IPP] = 0;
} else {
is_ipp = false;
pxl_reg = csid_reg->ppp_reg;
path_config = &(csid_hw->ppp_path_config);
+ csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_PPP] = 0;
}
if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
@@ -2288,6 +2290,7 @@
res->res_type, res->res_id, res->res_state);
return -EINVAL;
}
+ csid_hw->res_sof_cnt[res->res_id] = 0;
if (path_data->usage_type)
path_data->init_frame_drop = csid_hw->init_frame_drop + 1;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 80513d2..6055911 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -2061,6 +2061,8 @@
case IPA_IOC_GET_PHERIPHERAL_EP_INFO:
IPADBG("Got IPA_IOC_GET_EP_INFO\n");
+ if (ipa3_ctx->ipa_config_is_auto == false)
+ return -ENOTTY;
if (copy_from_user(&ep_info, (const void __user *)arg,
sizeof(struct ipa_ioc_get_ep_info))) {
IPAERR_RL("copy_from_user fails\n");
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
index b68be36..b05ad08 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
@@ -528,6 +528,9 @@
if (attrib->attrib_mask & IPA_FLT_MAC_ETHER_TYPE)
pr_err("ether_type:%x ", attrib->ether_type);
+ if (attrib->attrib_mask & IPA_FLT_VLAN_ID)
+ pr_err("vlan_id:%x ", attrib->vlan_id);
+
if (attrib->attrib_mask & IPA_FLT_TCP_SYN)
pr_err("tcp syn ");
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c
index 35d5efc..c881180 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c
@@ -753,6 +753,24 @@
ofst_meq32++;
}
+ if (attrib->attrib_mask & IPA_FLT_VLAN_ID) {
+ uint32_t vlan_tag;
+
+ if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq32, ofst_meq32)) {
+ IPAHAL_ERR("ran out of meq32 eq\n");
+ goto err;
+ }
+ *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
+ ipa3_0_ofst_meq32[ofst_meq32]);
+ /* -6 => offset of 802_1Q tag in L2 hdr */
+ extra = ipa_write_8((u8)-6, extra);
+ /* filter vlan packets: 0x8100 TPID + required VLAN ID */
+ vlan_tag = (0x8100 << 16) | (attrib->vlan_id & 0xFFF);
+ rest = ipa_write_32(0xFFFF0FFF, rest);
+ rest = ipa_write_32(vlan_tag, rest);
+ ofst_meq32++;
+ }
+
if (attrib->attrib_mask & IPA_FLT_TYPE) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
ihl_ofst_meq32)) {
@@ -1106,6 +1124,24 @@
ofst_meq32++;
}
+ if (attrib->attrib_mask & IPA_FLT_VLAN_ID) {
+ uint32_t vlan_tag;
+
+ if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq32, ofst_meq32)) {
+ IPAHAL_ERR("ran out of meq32 eq\n");
+ goto err;
+ }
+ *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
+ ipa3_0_ofst_meq32[ofst_meq32]);
+ /* -6 => offset of 802_1Q tag in L2 hdr */
+ extra = ipa_write_8((u8)-6, extra);
+ /* filter vlan packets: 0x8100 TPID + required VLAN ID */
+ vlan_tag = (0x8100 << 16) | (attrib->vlan_id & 0xFFF);
+ rest = ipa_write_32(0xFFFF0FFF, rest);
+ rest = ipa_write_32(vlan_tag, rest);
+ ofst_meq32++;
+ }
+
if (attrib->attrib_mask & IPA_FLT_TYPE) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
ihl_ofst_meq32)) {
@@ -1907,6 +1943,24 @@
ofst_meq32++;
}
+ if (attrib->attrib_mask & IPA_FLT_VLAN_ID) {
+ uint32_t vlan_tag;
+
+ if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq32, ofst_meq32)) {
+ IPAHAL_ERR("ran out of meq32 eq\n");
+ return -EPERM;
+ }
+ *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
+ ipa3_0_ofst_meq32[ofst_meq32]);
+ /* -6 => offset of 802_1Q tag in L2 hdr */
+ eq_atrb->offset_meq_32[ofst_meq32].offset = -6;
+ /* filter vlan packets: 0x8100 TPID + required VLAN ID */
+ vlan_tag = (0x8100 << 16) | (attrib->vlan_id & 0xFFF);
+ eq_atrb->offset_meq_32[ofst_meq32].mask = 0xFFFF0FFF;
+ eq_atrb->offset_meq_32[ofst_meq32].value = vlan_tag;
+ ofst_meq32++;
+ }
+
if (attrib->attrib_mask & IPA_FLT_TYPE) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
ihl_ofst_meq32)) {
@@ -2352,6 +2406,24 @@
ofst_meq32++;
}
+ if (attrib->attrib_mask & IPA_FLT_VLAN_ID) {
+ uint32_t vlan_tag;
+
+ if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ofst_meq32, ofst_meq32)) {
+ IPAHAL_ERR("ran out of meq32 eq\n");
+ return -EPERM;
+ }
+ *en_rule |= IPA_GET_RULE_EQ_BIT_PTRN(
+ ipa3_0_ofst_meq32[ofst_meq32]);
+ /* -6 => offset of 802_1Q tag in L2 hdr */
+ eq_atrb->offset_meq_32[ofst_meq32].offset = -6;
+ /* filter vlan packets: 0x8100 TPID + required VLAN ID */
+ vlan_tag = (0x8100 << 16) | (attrib->vlan_id & 0xFFF);
+ eq_atrb->offset_meq_32[ofst_meq32].mask = 0xFFFF0FFF;
+ eq_atrb->offset_meq_32[ofst_meq32].value = vlan_tag;
+ ofst_meq32++;
+ }
+
if (attrib->attrib_mask & IPA_FLT_TYPE) {
if (IPA_IS_RAN_OUT_OF_EQ(ipa3_0_ihl_ofst_meq32,
ihl_ofst_meq32)) {
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index 5a477ba..1164e6f 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -978,7 +978,7 @@
{
struct buf_data *pcmds = file->private_data;
ssize_t ret = 0;
- int blen = 0;
+ unsigned int blen = 0;
char *string_buf;
mutex_lock(&pcmds->dbg_mutex);
@@ -990,6 +990,11 @@
/* Allocate memory for the received string */
blen = count + (pcmds->sblen);
+ if (blen > U32_MAX - 1) {
+ mutex_unlock(&pcmds->dbg_mutex);
+ return -EINVAL;
+ }
+
string_buf = krealloc(pcmds->string_buf, blen + 1, GFP_KERNEL);
if (!string_buf) {
pr_err("%s: Failed to allocate memory\n", __func__);
@@ -997,6 +1002,7 @@
return -ENOMEM;
}
+ pcmds->string_buf = string_buf;
/* Writing in batches is possible */
ret = simple_write_to_buffer(string_buf, blen, ppos, p, count);
if (ret < 0) {
@@ -1006,7 +1012,6 @@
}
string_buf[ret] = '\0';
- pcmds->string_buf = string_buf;
pcmds->sblen = count;
mutex_unlock(&pcmds->dbg_mutex);
return ret;
@@ -3520,6 +3525,10 @@
of_property_read_bool(pdev->dev.of_node,
"qcom,dsi-clk-ln-recovery");
+ sdata->skip_clamp =
+ of_property_read_bool(pdev->dev.of_node,
+ "qcom,mdss-skip-clamp");
+
return 0;
}
diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h
index 5d2d677..94aa0ca 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.h
+++ b/drivers/video/fbdev/msm/mdss_dsi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, 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
@@ -249,6 +249,9 @@
u32 ulps_clamp_ctrl_off;
u32 ulps_phyrst_ctrl_off;
+ /* DSI phy skip clamp */
+ bool skip_clamp;
+
bool cmd_clk_ln_recovery_en;
bool dsi0_active;
bool dsi1_active;
diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c
index 4f8015d..e46cbfe 100644
--- a/drivers/video/fbdev/msm/mdss_dsi_panel.c
+++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c
@@ -572,11 +572,13 @@
return ans;
}
+static char pageset[] = {0xfe, 0x00}; /* DTYPE_DCS_WRITE1 */
static char caset[] = {0x2a, 0x00, 0x00, 0x03, 0x00}; /* DTYPE_DCS_LWRITE */
static char paset[] = {0x2b, 0x00, 0x00, 0x05, 0x00}; /* DTYPE_DCS_LWRITE */
/* pack into one frame before sent */
static struct dsi_cmd_desc set_col_page_addr_cmd[] = {
+ {{DTYPE_DCS_WRITE1, 1, 0, 0, 0, sizeof(pageset)}, pageset},
{{DTYPE_DCS_LWRITE, 0, 0, 0, 1, sizeof(caset)}, caset}, /* packed */
{{DTYPE_DCS_LWRITE, 1, 0, 0, 1, sizeof(paset)}, paset},
};
@@ -586,20 +588,22 @@
{
struct dcs_cmd_req cmdreq;
+ set_col_page_addr_cmd[0].payload = pageset;
+
caset[1] = (((roi->x) & 0xFF00) >> 8);
caset[2] = (((roi->x) & 0xFF));
caset[3] = (((roi->x - 1 + roi->w) & 0xFF00) >> 8);
caset[4] = (((roi->x - 1 + roi->w) & 0xFF));
- set_col_page_addr_cmd[0].payload = caset;
+ set_col_page_addr_cmd[1].payload = caset;
paset[1] = (((roi->y) & 0xFF00) >> 8);
paset[2] = (((roi->y) & 0xFF));
paset[3] = (((roi->y - 1 + roi->h) & 0xFF00) >> 8);
paset[4] = (((roi->y - 1 + roi->h) & 0xFF));
- set_col_page_addr_cmd[1].payload = paset;
+ set_col_page_addr_cmd[2].payload = paset;
memset(&cmdreq, 0, sizeof(cmdreq));
- cmdreq.cmds_cnt = 2;
+ cmdreq.cmds_cnt = 3;
cmdreq.flags = CMD_REQ_COMMIT;
if (unicast)
cmdreq.flags |= CMD_REQ_UNICAST;
diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
index 9ccd428..a0adc17 100644
--- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c
+++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, 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
@@ -1925,6 +1925,7 @@
static int mdss_dsi_clamp_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable)
{
struct mipi_panel_info *mipi = NULL;
+ struct mdss_panel_data *pdata = NULL;
u32 clamp_reg, regval = 0;
u32 clamp_reg_off, phyrst_reg_off;
@@ -1941,6 +1942,7 @@
clamp_reg_off = ctrl->shared_data->ulps_clamp_ctrl_off;
phyrst_reg_off = ctrl->shared_data->ulps_phyrst_ctrl_off;
mipi = &ctrl->panel_data.panel_info.mipi;
+ pdata = &ctrl->panel_data;
/* clock lane will always be clamped */
clamp_reg = BIT(9);
@@ -1970,6 +1972,14 @@
pr_debug("%s: called for ctrl%d, enable=%d, clamp_reg=0x%08x\n",
__func__, ctrl->ndx, enable, clamp_reg);
if (enable && !ctrl->mmss_clamp) {
+ if (!mdss_dsi_ulps_feature_enabled(pdata) &&
+ !pdata->panel_info.ulps_suspend_enabled &&
+ ctrl->shared_data->skip_clamp) {
+
+ ctrl->mmss_clamp = true;
+ return 0;
+ }
+
regval = MIPI_INP(ctrl->mmss_misc_io.base + clamp_reg_off);
/* Enable MMSS DSI Clamps */
if (ctrl->ndx == DSI_CTRL_0) {
@@ -2008,6 +2018,14 @@
wmb();
ctrl->mmss_clamp = true;
} else if (!enable && ctrl->mmss_clamp) {
+ if (!mdss_dsi_ulps_feature_enabled(pdata) &&
+ !pdata->panel_info.ulps_suspend_enabled &&
+ ctrl->shared_data->skip_clamp) {
+
+ ctrl->mmss_clamp = false;
+ return 0;
+ }
+
if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->shared_data->hw_rev,
MDSS_DSI_HW_REV_104) &&
(MDSS_GET_STEP(ctrl->shared_data->hw_rev) !=
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 509b189..bfff3b5 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -3175,7 +3175,7 @@
REG("mountinfo", S_IRUGO, proc_mountinfo_operations),
REG("mountstats", S_IRUSR, proc_mountstats_operations),
#ifdef CONFIG_PROCESS_RECLAIM
- REG("reclaim", S_IWUSR, proc_reclaim_operations),
+ REG("reclaim", 0222, proc_reclaim_operations),
#endif
#ifdef CONFIG_PROC_PAGE_MONITOR
REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
diff --git a/include/uapi/linux/msm_ipa.h b/include/uapi/linux/msm_ipa.h
index 60a5725..6d09d21 100644
--- a/include/uapi/linux/msm_ipa.h
+++ b/include/uapi/linux/msm_ipa.h
@@ -188,6 +188,7 @@
#define IPA_FLT_L2TP_INNER_IP_TYPE (1ul << 25)
#define IPA_FLT_L2TP_INNER_IPV4_DST_ADDR (1ul << 26)
#define IPA_FLT_IS_PURE_ACK (1ul << 27)
+#define IPA_FLT_VLAN_ID (1ul << 28)
/**
* maximal number of NAT PDNs in the PDN config table
@@ -728,6 +729,7 @@
* @u.v6.src_addr_mask: src address mask
* @u.v6.dst_addr: dst address val
* @u.v6.dst_addr_mask: dst address mask
+ * @vlan_id: vlan id value
*/
struct ipa_rule_attrib {
uint32_t attrib_mask;
@@ -768,6 +770,7 @@
uint32_t dst_addr_mask[4];
} v6;
} u;
+ uint16_t vlan_id;
};
/*! @brief The maximum number of Mask Equal 32 Eqns */
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index d6a0b0f..5009fc9 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -267,13 +267,21 @@
.release = single_release,
};
-static inline void pm_qos_set_value_for_cpus(struct pm_qos_constraints *c,
+static inline int pm_qos_set_value_for_cpus(struct pm_qos_constraints *c,
struct cpumask *cpus)
{
struct pm_qos_request *req = NULL;
int cpu;
s32 qos_val[NR_CPUS] = { [0 ... (NR_CPUS - 1)] = c->default_value };
+ /*
+ * pm_qos_constraints can be from different classes,
+ * Update cpumask only only for CPU_DMA_LATENCY classes
+ */
+
+ if (c != pm_qos_array[PM_QOS_CPU_DMA_LATENCY]->constraints)
+ return -EINVAL;
+
plist_for_each_entry(req, &c->list, node) {
for_each_cpu(cpu, &req->cpus_affine) {
switch (c->type) {
@@ -300,6 +308,8 @@
cpumask_set_cpu(cpu, cpus);
c->target_per_cpu[cpu] = qos_val[cpu];
}
+
+ return 0;
}
/**
@@ -353,7 +363,7 @@
curr_value = pm_qos_get_value(c);
cpumask_clear(&cpus);
pm_qos_set_value(c, curr_value);
- pm_qos_set_value_for_cpus(c, &cpus);
+ ret = pm_qos_set_value_for_cpus(c, &cpus);
spin_unlock_irqrestore(&pm_qos_lock, flags);
@@ -364,7 +374,8 @@
* to update the new qos restriction for the cores
*/
- if (!cpumask_empty(&cpus)) {
+ if (!cpumask_empty(&cpus) ||
+ (ret && prev_value != curr_value)) {
ret = 1;
if (c->notifiers)
blocking_notifier_call_chain(c->notifiers,