summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/boot/dts/qcom/msm8998-mdss.dtsi8
-rw-r--r--arch/arm/boot/dts/qcom/msm8998.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/sdm630.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/sdm660.dtsi2
-rw-r--r--drivers/input/touchscreen/st/fts.c28
-rw-r--r--drivers/media/v4l2-core/v4l2-compat-ioctl32.c1
-rw-r--r--drivers/misc/hdcp.c47
-rw-r--r--drivers/net/wireless/cnss2/pci.c30
-rw-r--r--drivers/net/wireless/cnss2/pci.h1
-rw-r--r--drivers/power/supply/qcom/fg-util.c29
-rw-r--r--drivers/usb/gadget/function/f_gsi.c230
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c26
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.c2
14 files changed, 319 insertions, 91 deletions
diff --git a/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi b/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi
index 5708fce44378..fbde8d21f22c 100644
--- a/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998-mdss.dtsi
@@ -497,12 +497,16 @@
<&clock_mmss clk_mmss_mdss_dp_link_clk>,
<&clock_mmss clk_mmss_mdss_dp_link_intf_clk>,
<&clock_mmss clk_mmss_mdss_dp_crypto_clk>,
- <&clock_mmss clk_mmss_mdss_dp_pixel_clk>;
+ <&clock_mmss clk_mmss_mdss_dp_pixel_clk>,
+ <&mdss_dp_pll clk_vco_divided_clk_src_mux>,
+ <&mdss_dp_pll clk_vco_divsel_two_clk_src>,
+ <&mdss_dp_pll clk_vco_divsel_four_clk_src>;
clock-names = "core_mnoc_clk", "core_iface_clk", "core_bus_clk",
"core_mdp_core_clk", "core_alt_iface_clk",
"core_aux_clk", "core_ref_clk_src", "core_ref_clk",
"ctrl_link_clk", "ctrl_link_iface_clk",
- "ctrl_crypto_clk", "ctrl_pixel_clk";
+ "ctrl_crypto_clk", "ctrl_pixel_clk", "pixel_parent",
+ "pixel_clk_two_div", "pixel_clk_four_div";
qcom,dp-usbpd-detection = <&pmi8998_pdphy>;
diff --git a/arch/arm/boot/dts/qcom/msm8998.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi
index 76e3282d327e..132f3e7ce332 100644
--- a/arch/arm/boot/dts/qcom/msm8998.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998.dtsi
@@ -292,7 +292,7 @@
dev = "/dev/block/platform/soc/1da4000.ufshc/by-name/vendor";
type = "ext4";
mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait,slotselect";
+ fsmgr_flags = "wait,slotselect,verify";
status = "ok";
};
};
diff --git a/arch/arm/boot/dts/qcom/sdm630.dtsi b/arch/arm/boot/dts/qcom/sdm630.dtsi
index e918864a3df7..ae110fe22535 100644
--- a/arch/arm/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm630.dtsi
@@ -309,7 +309,7 @@
dev = "/dev/block/platform/soc/c0c4000.sdhci/by-name/vendor";
type = "ext4";
mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait,slotselect";
+ fsmgr_flags = "wait,slotselect,verify";
status = "ok";
};
};
diff --git a/arch/arm/boot/dts/qcom/sdm660.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi
index c626698ffd51..48437ac9d31a 100644
--- a/arch/arm/boot/dts/qcom/sdm660.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660.dtsi
@@ -307,7 +307,7 @@
dev = "/dev/block/platform/soc/c0c4000.sdhci/by-name/vendor";
type = "ext4";
mnt_flags = "ro,barrier=1,discard";
- fsmgr_flags = "wait,slotselect";
+ fsmgr_flags = "wait,slotselect,verify";
status = "ok";
};
};
diff --git a/drivers/input/touchscreen/st/fts.c b/drivers/input/touchscreen/st/fts.c
index 08bfb83a9447..06f7f569f417 100644
--- a/drivers/input/touchscreen/st/fts.c
+++ b/drivers/input/touchscreen/st/fts.c
@@ -105,7 +105,7 @@ static void fts_interrupt_enable(struct fts_ts_info *info);
static int fts_init_hw(struct fts_ts_info *info);
static int fts_mode_handler(struct fts_ts_info *info, int force);
static int fts_command(struct fts_ts_info *info, unsigned char cmd);
-
+static void fts_unblank(struct fts_ts_info *info);
static int fts_chip_initialization(struct fts_ts_info *info);
void touch_callback(unsigned int status)
@@ -1487,8 +1487,12 @@ static int fts_init(struct fts_ts_info *info)
error = fts_interrupt_install(info);
- if (error != OK)
+ if (error != OK) {
logError(1, "%s Init (1) error (ERROR = %08X)\n", error);
+ return error;
+ }
+
+ fts_unblank(info);
return error;
}
@@ -1773,6 +1777,26 @@ static int fts_fb_state_chg_callback(struct notifier_block *nb, unsigned long va
}
+static void fts_unblank(struct fts_ts_info *info)
+{
+ int i;
+
+ for (i = 0; i < TOUCH_ID_MAX; i++) {
+ input_mt_slot(info->input_dev, i);
+ input_mt_report_slot_state(info->input_dev,
+ (i < FINGER_MAX) ? MT_TOOL_FINGER : MT_TOOL_PEN, 0);
+ }
+ input_sync(info->input_dev);
+
+ info->resume_bit = 1;
+
+ fts_mode_handler(info, 0);
+
+ info->sensor_sleep = false;
+
+ fts_enableInterrupt();
+}
+
static struct notifier_block fts_noti_block = {
.notifier_call = fts_fb_state_chg_callback,
};
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 2f1c03783414..9db0dac938d3 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -879,6 +879,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
int compatible_arg = 1;
long err = 0;
+ memset(&karg, 0, sizeof(karg));
/* First, convert the command. */
switch (cmd) {
case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break;
diff --git a/drivers/misc/hdcp.c b/drivers/misc/hdcp.c
index c6f2dbfe573d..687f55bd5afd 100644
--- a/drivers/misc/hdcp.c
+++ b/drivers/misc/hdcp.c
@@ -116,7 +116,7 @@
#define HDCP_CREATE_DEVICE_ID(x) (HDCP_DEVICE_ID | (x))
#define HDCP_TXMTR_HDMI HDCP_CREATE_DEVICE_ID(1)
-
+#define HDCP_TXMTR_DP HDCP_CREATE_DEVICE_ID(2)
#define HDCP_TXMTR_SERVICE_ID 0x0001000
#define SERVICE_CREATE_CMD(x) (HDCP_TXMTR_SERVICE_ID | x)
@@ -639,7 +639,8 @@ static int hdcp_lib_get_next_message(struct hdcp_lib_handle *handle,
case LC_SEND_L_PRIME_MESSAGE_ID:
return SKE_SEND_EKS_MESSAGE_ID;
case SKE_SEND_EKS_MESSAGE_ID:
- if (!handle->repeater_flag)
+ if (!handle->repeater_flag &&
+ handle->device_type == HDCP_TXMTR_DP)
return SKE_SEND_TYPE_ID;
case SKE_SEND_TYPE_ID:
case REPEATER_AUTH_STREAM_READY_MESSAGE_ID:
@@ -1778,6 +1779,19 @@ exit:
return rc;
}
+static void hdcp_lib_prep_type_id(struct hdcp_lib_handle *handle,
+ struct hdmi_hdcp_wakeup_data *cdata)
+{
+ memset(handle->listener_buf, 0, MAX_TX_MESSAGE_SIZE);
+ handle->listener_buf[0] = SKE_SEND_TYPE_ID;
+ handle->msglen = 2;
+ cdata->cmd = HDMI_HDCP_WKUP_CMD_SEND_MESSAGE;
+ cdata->send_msg_buf = handle->listener_buf;
+ cdata->send_msg_len = handle->msglen;
+ handle->last_msg = hdcp_lib_get_next_message(handle,
+ cdata);
+}
+
static void hdcp_lib_msg_sent(struct hdcp_lib_handle *handle)
{
struct hdmi_hdcp_wakeup_data cdata = { HDMI_HDCP_WKUP_CMD_INVALID };
@@ -1802,18 +1816,29 @@ static void hdcp_lib_msg_sent(struct hdcp_lib_handle *handle)
cdata.cmd = HDMI_HDCP_WKUP_CMD_LINK_POLL;
break;
case SKE_SEND_EKS_MESSAGE_ID:
+ /*
+ * a) if its a repeater irrespective of device type we
+ * start CMD_LINK_POLL to trigger repeater auth
+ * b) if its not a repeater and device is DP we
+ * first send the SKE_SEND_TYPE_ID and upon success
+ * enable encryption
+ * c) if its not a repeater and device is HDMI we
+ * dont send SKE_SEND_TYPE_ID and enable encryption
+ * and start part III of authentication
+ */
if (handle->repeater_flag) {
/* poll for link check */
cdata.cmd = HDMI_HDCP_WKUP_CMD_LINK_POLL;
- } else {
- memset(handle->listener_buf, 0, MAX_TX_MESSAGE_SIZE);
- handle->listener_buf[0] = SKE_SEND_TYPE_ID;
- handle->msglen = 2;
- cdata.cmd = HDMI_HDCP_WKUP_CMD_SEND_MESSAGE;
- cdata.send_msg_buf = handle->listener_buf;
- cdata.send_msg_len = handle->msglen;
- handle->last_msg = hdcp_lib_get_next_message(handle,
- &cdata);
+ } else if (handle->device_type == HDCP_TXMTR_DP) {
+ hdcp_lib_prep_type_id(handle, &cdata);
+ } else if (handle->device_type == HDCP_TXMTR_HDMI) {
+ if (!hdcp_lib_enable_encryption(handle)) {
+ handle->authenticated = true;
+ cdata.cmd = HDMI_HDCP_WKUP_CMD_STATUS_SUCCESS;
+ hdcp_lib_wakeup_client(handle, &cdata);
+ }
+ /* poll for link check */
+ cdata.cmd = HDMI_HDCP_WKUP_CMD_LINK_POLL;
}
break;
case REPEATER_AUTH_SEND_ACK_MESSAGE_ID:
diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c
index 2c297fba5c34..22fad9210945 100644
--- a/drivers/net/wireless/cnss2/pci.c
+++ b/drivers/net/wireless/cnss2/pci.c
@@ -60,7 +60,6 @@ MODULE_PARM_DESC(fbc_bypass,
static int cnss_set_pci_config_space(struct cnss_pci_data *pci_priv, bool save)
{
- int ret = 0;
struct pci_dev *pci_dev = pci_priv->pci_dev;
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
bool link_down_or_recovery;
@@ -80,12 +79,8 @@ static int cnss_set_pci_config_space(struct cnss_pci_data *pci_priv, bool save)
}
} else {
if (link_down_or_recovery) {
- ret = msm_pcie_recover_config(pci_dev);
- if (ret) {
- cnss_pr_err("Failed to recover PCI config space, err = %d\n",
- ret);
- return ret;
- }
+ pci_load_saved_state(pci_dev, pci_priv->default_state);
+ pci_restore_state(pci_dev);
} else if (pci_priv->saved_state) {
pci_load_and_free_saved_state(pci_dev,
&pci_priv->saved_state);
@@ -100,27 +95,15 @@ static int cnss_set_pci_link(struct cnss_pci_data *pci_priv, bool link_up)
{
int ret = 0;
struct pci_dev *pci_dev = pci_priv->pci_dev;
- struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
- bool link_down_or_recovery;
-
- if (!plat_priv)
- return -ENODEV;
-
- link_down_or_recovery = pci_priv->pci_link_down_ind ||
- (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state));
ret = msm_pcie_pm_control(link_up ? MSM_PCIE_RESUME :
MSM_PCIE_SUSPEND,
pci_dev->bus->number,
pci_dev, NULL,
- link_down_or_recovery ?
- PM_OPTIONS_LINK_DOWN :
PM_OPTIONS_DEFAULT);
if (ret) {
- cnss_pr_err("Failed to %s PCI link with %s option, err = %d\n",
- link_up ? "resume" : "suspend",
- link_down_or_recovery ? "link down" : "default",
- ret);
+ cnss_pr_err("Failed to %s PCI link with default option, err = %d\n",
+ link_up ? "resume" : "suspend", ret);
return ret;
}
@@ -1443,6 +1426,9 @@ static int cnss_pci_probe(struct pci_dev *pci_dev,
if (ret)
goto dereg_pci_event;
+ pci_save_state(pci_dev);
+ pci_priv->default_state = pci_store_saved_state(pci_dev);
+
switch (pci_dev->device) {
case QCA6174_DEVICE_ID:
pci_read_config_word(pci_dev, QCA6174_REV_ID_OFFSET,
@@ -1514,6 +1500,8 @@ static void cnss_pci_remove(struct pci_dev *pci_dev)
break;
}
+ pci_load_and_free_saved_state(pci_dev, &pci_priv->saved_state);
+
cnss_pci_disable_bus(pci_priv);
cnss_dereg_pci_event(pci_priv);
if (pci_priv->smmu_mapping)
diff --git a/drivers/net/wireless/cnss2/pci.h b/drivers/net/wireless/cnss2/pci.h
index 4dc29c3c1f10..e26e331e2f8a 100644
--- a/drivers/net/wireless/cnss2/pci.h
+++ b/drivers/net/wireless/cnss2/pci.h
@@ -65,6 +65,7 @@ struct cnss_pci_data {
bool pci_link_state;
bool pci_link_down_ind;
struct pci_saved_state *saved_state;
+ struct pci_saved_state *default_state;
struct msm_pcie_register_event msm_pci_event;
atomic_t auto_suspended;
bool monitor_wake_intr;
diff --git a/drivers/power/supply/qcom/fg-util.c b/drivers/power/supply/qcom/fg-util.c
index 0cb1dea7113b..23dd9131d402 100644
--- a/drivers/power/supply/qcom/fg-util.c
+++ b/drivers/power/supply/qcom/fg-util.c
@@ -264,8 +264,7 @@ static inline bool fg_sram_address_valid(u16 address, int len)
int fg_sram_write(struct fg_chip *chip, u16 address, u8 offset,
u8 *val, int len, int flags)
{
- int rc = 0;
- bool tried_again = false;
+ int rc = 0, tries = 0;
bool atomic_access = false;
if (!chip)
@@ -292,7 +291,7 @@ int fg_sram_write(struct fg_chip *chip, u16 address, u8 offset,
} else {
flags = FG_IMA_DEFAULT;
}
-wait:
+
/*
* Atomic access mean waiting upon SOC_UPDATE interrupt from
* FG_ALG and do the transaction after that. This is to make
@@ -301,16 +300,20 @@ wait:
* FG cycle (~1.47 seconds).
*/
if (atomic_access) {
- /* Wait for SOC_UPDATE completion */
- rc = wait_for_completion_interruptible_timeout(
- &chip->soc_update,
- msecs_to_jiffies(SOC_UPDATE_WAIT_MS));
-
- /* If we were interrupted wait again one more time. */
- if (rc == -ERESTARTSYS && !tried_again) {
- tried_again = true;
- goto wait;
- } else if (rc <= 0) {
+ for (tries = 0; tries < 2; tries++) {
+ /* Wait for SOC_UPDATE completion */
+ rc = wait_for_completion_interruptible_timeout(
+ &chip->soc_update,
+ msecs_to_jiffies(SOC_UPDATE_WAIT_MS));
+ if (rc > 0) {
+ rc = 0;
+ break;
+ } else if (!rc) {
+ rc = -ETIMEDOUT;
+ }
+ }
+
+ if (rc < 0) {
pr_err("wait for soc_update timed out rc=%d\n", rc);
goto out;
}
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index 3b925d9b000e..18e3c5cdcc24 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -40,6 +40,15 @@ MODULE_PARM_DESC(qti_packet_debug, "Print QTI Packet's Raw Data");
static struct workqueue_struct *ipa_usb_wq;
+static struct gsi_inst_status {
+ struct mutex gsi_lock;
+ bool inst_exist;
+ struct gsi_opts *opts;
+} inst_status[IPA_USB_MAX_TETH_PROT_SIZE];
+
+/* Deregister misc device and free instance structures */
+static void gsi_inst_clean(struct gsi_opts *opts);
+
static void ipa_disconnect_handler(struct gsi_data_port *d_port);
static int gsi_ctrl_send_notification(struct f_gsi *gsi);
static int gsi_alloc_trb_buffer(struct f_gsi *gsi);
@@ -946,38 +955,71 @@ static int gsi_ctrl_dev_open(struct inode *ip, struct file *fp)
struct gsi_ctrl_port *c_port = container_of(fp->private_data,
struct gsi_ctrl_port,
ctrl_device);
+ struct f_gsi *gsi;
+ struct gsi_inst_status *inst_cur;
if (!c_port) {
- log_event_err("%s: gsi ctrl port %pK", __func__, c_port);
+ pr_err_ratelimited("%s: gsi ctrl port %pK", __func__, c_port);
return -ENODEV;
}
- log_event_dbg("%s: open ctrl dev %s", __func__, c_port->name);
+ pr_devel_ratelimited("%s: open ctrl dev %s", __func__, c_port->name);
+
+ gsi = container_of(c_port, struct f_gsi, c_port);
+ inst_cur = &inst_status[gsi->prot_id];
+
+ mutex_lock(&inst_cur->gsi_lock);
+
+ fp->private_data = &gsi->prot_id;
+
+ if (!inst_cur->inst_exist) {
+ mutex_unlock(&inst_cur->gsi_lock);
+ pr_err_ratelimited(
+ "%s: [prot_id = %d], GSI instance freed already\n",
+ __func__, gsi->prot_id);
+ return -ENODEV;
+ }
if (c_port->is_open) {
- log_event_err("%s: Already opened", __func__);
+ mutex_unlock(&inst_cur->gsi_lock);
+ log_event_err("%s: Already opened\n", __func__);
return -EBUSY;
}
c_port->is_open = true;
+ mutex_unlock(&inst_cur->gsi_lock);
+
return 0;
}
static int gsi_ctrl_dev_release(struct inode *ip, struct file *fp)
{
- struct gsi_ctrl_port *c_port = container_of(fp->private_data,
- struct gsi_ctrl_port,
- ctrl_device);
+ enum ipa_usb_teth_prot prot_id =
+ *(enum ipa_usb_teth_prot *)(fp->private_data);
+ struct gsi_inst_status *inst_cur = &inst_status[prot_id];
- if (!c_port) {
- log_event_err("%s: gsi ctrl port %pK", __func__, c_port);
+ mutex_lock(&inst_cur->gsi_lock);
+
+ if (unlikely(inst_cur->inst_exist == false)) {
+ if (inst_cur->opts) {
+ /* GSI instance clean up */
+ gsi_inst_clean(inst_cur->opts);
+ inst_cur->opts = NULL;
+ }
+ mutex_unlock(&inst_cur->gsi_lock);
+ pr_err_ratelimited(
+ "%s: [prot_id = %d], Delayed free instance memory\n",
+ __func__, prot_id);
return -ENODEV;
}
- log_event_dbg("close ctrl dev %s", c_port->name);
+ inst_cur->opts->gsi->c_port.is_open = false;
+
+ mutex_unlock(&inst_cur->gsi_lock);
- c_port->is_open = false;
+ log_event_dbg("close ctrl dev %s\n",
+ inst_cur->opts->gsi->c_port.name);
return 0;
}
@@ -985,16 +1027,27 @@ static int gsi_ctrl_dev_release(struct inode *ip, struct file *fp)
static ssize_t
gsi_ctrl_dev_read(struct file *fp, char __user *buf, size_t count, loff_t *pos)
{
- struct gsi_ctrl_port *c_port = container_of(fp->private_data,
- struct gsi_ctrl_port,
- ctrl_device);
-
+ struct gsi_ctrl_port *c_port;
struct gsi_ctrl_pkt *cpkt = NULL;
+ enum ipa_usb_teth_prot prot_id =
+ *(enum ipa_usb_teth_prot *)(fp->private_data);
+ struct gsi_inst_status *inst_cur = &inst_status[prot_id];
unsigned long flags;
int ret = 0;
log_event_dbg("%s: Enter %zu", __func__, count);
+ mutex_lock(&inst_cur->gsi_lock);
+ if (unlikely(inst_cur->inst_exist == false)) {
+ mutex_unlock(&inst_cur->gsi_lock);
+ pr_err_ratelimited(
+ "%s: free_inst is called, free memory until dev is closed\n",
+ __func__);
+ return -ENODEV;
+ }
+ mutex_unlock(&inst_cur->gsi_lock);
+
+ c_port = &inst_cur->opts->gsi->c_port;
if (!c_port) {
log_event_err("%s: gsi ctrl port %pK", __func__, c_port);
return -ENODEV;
@@ -1062,14 +1115,29 @@ static ssize_t gsi_ctrl_dev_write(struct file *fp, const char __user *buf,
int ret = 0;
unsigned long flags;
struct gsi_ctrl_pkt *cpkt;
- struct gsi_ctrl_port *c_port = container_of(fp->private_data,
- struct gsi_ctrl_port,
- ctrl_device);
- struct f_gsi *gsi = c_port_to_gsi(c_port);
- struct usb_request *req = c_port->notify_req;
+ struct gsi_ctrl_port *c_port;
+ struct usb_request *req;
+ enum ipa_usb_teth_prot prot_id =
+ *(enum ipa_usb_teth_prot *)(fp->private_data);
+ struct gsi_inst_status *inst_cur = &inst_status[prot_id];
+ struct f_gsi *gsi;
log_event_dbg("Enter %zu", count);
+ mutex_lock(&inst_cur->gsi_lock);
+ if (unlikely(inst_cur->inst_exist == false)) {
+ mutex_unlock(&inst_cur->gsi_lock);
+ pr_err_ratelimited(
+ "%s: free_inst is called, free memory until dev is closed\n",
+ __func__);
+ return -ENODEV;
+ }
+ mutex_unlock(&inst_cur->gsi_lock);
+
+ gsi = inst_cur->opts->gsi;
+ c_port = &gsi->c_port;
+ req = c_port->notify_req;
+
if (!c_port || !req || !req->buf) {
log_event_err("%s: c_port %pK req %pK req->buf %pK",
__func__, c_port, req, req ? req->buf : req);
@@ -1126,15 +1194,29 @@ static ssize_t gsi_ctrl_dev_write(struct file *fp, const char __user *buf,
static long gsi_ctrl_dev_ioctl(struct file *fp, unsigned cmd,
unsigned long arg)
{
- struct gsi_ctrl_port *c_port = container_of(fp->private_data,
- struct gsi_ctrl_port,
- ctrl_device);
- struct f_gsi *gsi = c_port_to_gsi(c_port);
+ struct gsi_ctrl_port *c_port;
+ struct f_gsi *gsi;
struct gsi_ctrl_pkt *cpkt;
struct ep_info info;
+ enum ipa_usb_teth_prot prot_id =
+ *(enum ipa_usb_teth_prot *)(fp->private_data);
+ struct gsi_inst_status *inst_cur = &inst_status[prot_id];
int val, ret = 0;
unsigned long flags;
+ mutex_lock(&inst_cur->gsi_lock);
+ if (unlikely(inst_cur->inst_exist == false)) {
+ mutex_unlock(&inst_cur->gsi_lock);
+ pr_err_ratelimited(
+ "%s: free_inst is called, free memory until dev is closed\n",
+ __func__);
+ return -ENODEV;
+ }
+ mutex_unlock(&inst_cur->gsi_lock);
+
+ gsi = inst_cur->opts->gsi;
+ c_port = &gsi->c_port;
+
if (!c_port) {
log_event_err("%s: gsi ctrl port %pK", __func__, c_port);
return -ENODEV;
@@ -1255,12 +1337,24 @@ exit_ioctl:
static unsigned int gsi_ctrl_dev_poll(struct file *fp, poll_table *wait)
{
- struct gsi_ctrl_port *c_port = container_of(fp->private_data,
- struct gsi_ctrl_port,
- ctrl_device);
+ struct gsi_ctrl_port *c_port;
+ enum ipa_usb_teth_prot prot_id =
+ *(enum ipa_usb_teth_prot *)(fp->private_data);
+ struct gsi_inst_status *inst_cur = &inst_status[prot_id];
unsigned long flags;
unsigned int mask = 0;
+ mutex_lock(&inst_cur->gsi_lock);
+ if (unlikely(inst_cur->inst_exist == false)) {
+ mutex_unlock(&inst_cur->gsi_lock);
+ pr_err_ratelimited(
+ "%s: free_inst is called, free memory until dev is closed\n",
+ __func__);
+ return -ENODEV;
+ }
+ mutex_unlock(&inst_cur->gsi_lock);
+
+ c_port = &inst_cur->opts->gsi->c_port;
if (!c_port) {
log_event_err("%s: gsi ctrl port %pK", __func__, c_port);
return -ENODEV;
@@ -1578,6 +1672,7 @@ static void gsi_rndis_command_complete(struct usb_ep *ep,
struct usb_request *req)
{
struct f_gsi *rndis = req->context;
+ rndis_init_msg_type *buf;
int status;
if (req->status != 0) {
@@ -1590,6 +1685,16 @@ static void gsi_rndis_command_complete(struct usb_ep *ep,
if (status < 0)
log_event_err("RNDIS command error %d, %d/%d",
status, req->actual, req->length);
+
+ buf = (rndis_init_msg_type *)req->buf;
+ if (buf->MessageType == RNDIS_MSG_INIT) {
+ rndis->d_port.in_aggr_size = min_t(u32,
+ rndis->d_port.in_aggr_size,
+ rndis->params->dl_max_xfer_size);
+ log_event_dbg("RNDIS host dl_aggr_size:%d in_aggr_size:%d\n",
+ rndis->params->dl_max_xfer_size,
+ rndis->d_port.in_aggr_size);
+ }
}
static void
@@ -2749,7 +2854,7 @@ static void gsi_unbind(struct usb_configuration *c, struct usb_function *f)
static void gsi_free_func(struct usb_function *f)
{
- pr_debug("%s\n", __func__);
+ log_event_dbg("%s\n", __func__);
}
int gsi_bind_config(struct f_gsi *gsi)
@@ -2845,6 +2950,7 @@ static void gsi_opts_release(struct config_item *item)
{
struct gsi_opts *opts = to_gsi_opts(item);
+ log_event_dbg("Release GSI: %s\n", __func__);
usb_put_function_instance(&opts->func_inst);
}
@@ -3044,48 +3150,89 @@ static struct config_item_type gsi_func_type = {
.ct_owner = THIS_MODULE,
};
+static void gsi_inst_clean(struct gsi_opts *opts)
+{
+ if (opts->gsi->c_port.ctrl_device.fops)
+ misc_deregister(&opts->gsi->c_port.ctrl_device);
+
+ kfree(opts->gsi);
+ kfree(opts);
+}
+
static int gsi_set_inst_name(struct usb_function_instance *fi,
const char *name)
{
- int ret, name_len;
+ int prot_id, name_len;
struct f_gsi *gsi;
- struct gsi_opts *opts = container_of(fi, struct gsi_opts, func_inst);
+ struct gsi_opts *opts, *opts_prev;
+
+ opts = container_of(fi, struct gsi_opts, func_inst);
name_len = strlen(name) + 1;
if (name_len > MAX_INST_NAME_LEN)
return -ENAMETOOLONG;
- ret = name_to_prot_id(name);
- if (ret < 0) {
- pr_err("%s: failed to find prot id for %s instance\n",
+ prot_id = name_to_prot_id(name);
+ if (prot_id < 0) {
+ log_event_err("%s: failed to find prot id for %s instance\n",
__func__, name);
return -EINVAL;
}
- if (ret == IPA_USB_RNDIS)
+ mutex_lock(&inst_status[prot_id].gsi_lock);
+ opts_prev = inst_status[prot_id].opts;
+ if (opts_prev) {
+ mutex_unlock(&inst_status[prot_id].gsi_lock);
+ log_event_err("%s: prot_id = %d, prev inst do not freed yet\n",
+ __func__, prot_id);
+ return -EBUSY;
+ }
+ mutex_unlock(&inst_status[prot_id].gsi_lock);
+
+ if (prot_id == IPA_USB_RNDIS)
config_group_init_type_name(&opts->func_inst.group, "",
&gsi_func_rndis_type);
- gsi = gsi_function_init(ret);
+ gsi = gsi_function_init(prot_id);
if (IS_ERR(gsi))
return PTR_ERR(gsi);
opts->gsi = gsi;
+ /* Set instance status */
+ mutex_lock(&inst_status[prot_id].gsi_lock);
+ inst_status[prot_id].inst_exist = true;
+ inst_status[prot_id].opts = opts;
+ mutex_unlock(&inst_status[prot_id].gsi_lock);
+
return 0;
}
static void gsi_free_inst(struct usb_function_instance *f)
{
struct gsi_opts *opts = container_of(f, struct gsi_opts, func_inst);
+ enum ipa_usb_teth_prot prot_id;
if (!opts->gsi)
return;
- if (opts->gsi->c_port.ctrl_device.fops)
- misc_deregister(&opts->gsi->c_port.ctrl_device);
+ prot_id = opts->gsi->prot_id;
- kfree(opts->gsi);
- kfree(opts);
+ mutex_lock(&inst_status[prot_id].gsi_lock);
+ if (opts->gsi->c_port.is_open) {
+ /* Mark instance exist as false */
+ inst_status[prot_id].inst_exist = false;
+ mutex_unlock(&inst_status[prot_id].gsi_lock);
+ log_event_err(
+ "%s: [prot_id = %d] Dev is open, free mem when dev close\n",
+ __func__, prot_id);
+ return;
+ }
+
+ /* Clear instance status */
+ gsi_inst_clean(opts);
+ inst_status[prot_id].inst_exist = false;
+ inst_status[prot_id].opts = NULL;
+ mutex_unlock(&inst_status[prot_id].gsi_lock);
}
static struct usb_function_instance *gsi_alloc_inst(void)
@@ -3099,7 +3246,7 @@ static struct usb_function_instance *gsi_alloc_inst(void)
opts->func_inst.set_inst_name = gsi_set_inst_name;
opts->func_inst.free_func_inst = gsi_free_inst;
config_group_init_type_name(&opts->func_inst.group, "",
- &gsi_func_type);
+ &gsi_func_type);
return &opts->func_inst;
}
@@ -3124,6 +3271,8 @@ MODULE_DESCRIPTION("GSI function driver");
static int fgsi_init(void)
{
+ int i;
+
ipa_usb_wq = alloc_workqueue("k_ipa_usb",
WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_FREEZABLE, 1);
if (!ipa_usb_wq) {
@@ -3131,6 +3280,9 @@ static int fgsi_init(void)
return -ENOMEM;
}
+ for (i = 0; i < IPA_USB_MAX_TETH_PROT_SIZE; i++)
+ mutex_init(&inst_status[i].gsi_lock);
+
return usb_function_register(&gsiusb_func);
}
module_init(fgsi_init);
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index bc325a91a9bf..6b003239ed34 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -422,6 +422,22 @@ static int mdss_dp_clk_init(struct mdss_dp_drv_pdata *dp_drv,
__func__);
dp_drv->pixel_parent = NULL;
}
+
+ dp_drv->pixel_clk_two_div = devm_clk_get(dev,
+ "pixel_clk_two_div");
+ if (IS_ERR(dp_drv->pixel_clk_two_div)) {
+ pr_debug("%s: Unable to get DP pixel two div clk\n",
+ __func__);
+ dp_drv->pixel_clk_two_div = NULL;
+ }
+
+ dp_drv->pixel_clk_four_div = devm_clk_get(dev,
+ "pixel_clk_four_div");
+ if (IS_ERR(dp_drv->pixel_clk_four_div)) {
+ pr_debug("%s: Unable to get DP pixel four div clk\n",
+ __func__);
+ dp_drv->pixel_clk_four_div = NULL;
+ }
} else {
if (dp_drv->pixel_parent)
devm_clk_put(dev, dp_drv->pixel_parent);
@@ -1418,6 +1434,16 @@ static int mdss_dp_enable_mainlink_clocks(struct mdss_dp_drv_pdata *dp)
return ret;
}
+ if (dp->pixel_parent && dp->pixel_clk_two_div &&
+ dp->pixel_clk_four_div) {
+ if (dp->link_rate == DP_LINK_RATE_540)
+ clk_set_parent(dp->pixel_parent,
+ dp->pixel_clk_four_div);
+ else
+ clk_set_parent(dp->pixel_parent,
+ dp->pixel_clk_two_div);
+ }
+
mdss_dp_set_clock_rate(dp, "ctrl_link_clk",
(dp->link_rate * DP_LINK_RATE_MULTIPLIER) / DP_KHZ_TO_HZ);
diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h
index 983f5e34a515..f3f9ca277762 100644
--- a/drivers/video/fbdev/msm/mdss_dp.h
+++ b/drivers/video/fbdev/msm/mdss_dp.h
@@ -614,6 +614,8 @@ struct mdss_dp_drv_pdata {
/* DP Pixel clock RCG and PLL parent */
struct clk *pixel_clk_rcg;
struct clk *pixel_parent;
+ struct clk *pixel_clk_two_div;
+ struct clk *pixel_clk_four_div;
/* regulators */
struct dss_module_power power_data[DP_MAX_PM];
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c
index f7b3d4664e86..037741df4382 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.c
+++ b/drivers/video/fbdev/msm/mdss_dp_util.c
@@ -835,6 +835,8 @@ void mdss_dp_sw_config_msa(struct mdss_dp_drv_pdata *dp)
pr_debug("pixel_m=0x%x, pixel_n=0x%x\n", pixel_m, pixel_n);
mvid = (pixel_m & 0xFFFF) * 5;
nvid = (0xFFFF & (~pixel_n)) + (pixel_m & 0xFFFF);
+ if (dp->link_rate == DP_LINK_RATE_540)
+ nvid *= 2;
}
pr_debug("mvid=0x%x, nvid=0x%x\n", mvid, nvid);