diff options
| -rw-r--r-- | drivers/char/diag/diag_dci.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c | 8 | ||||
| -rw-r--r-- | drivers/media/platform/msm/vidc/hfi_response_handler.c | 30 | ||||
| -rw-r--r-- | drivers/media/platform/msm/vidc/vidc_hfi.h | 4 | ||||
| -rw-r--r-- | drivers/media/platform/msm/vidc/vidc_hfi_helper.h | 1 | ||||
| -rw-r--r-- | drivers/soc/qcom/icnss.c | 109 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_tx.c | 5 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_util.c | 6 | ||||
| -rw-r--r-- | include/soc/qcom/icnss.h | 4 | ||||
| -rw-r--r-- | sound/soc/msm/qdsp6v2/q6afe.c | 2 |
10 files changed, 154 insertions, 19 deletions
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index 19fbd702c0e6..ad00b91ae173 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1813,9 +1813,9 @@ static int diag_dci_process_apps_pkt(struct diag_pkt_header_t *pkt_header, unsigned char *req_buf, int req_len, int tag, int pkt_header_len) { - uint8_t cmd_code, subsys_id, i, goto_download = 0; + uint8_t cmd_code = 0, subsys_id = 0, i, goto_download = 0; uint8_t header_len = sizeof(struct diag_dci_pkt_header_t); - uint16_t ss_cmd_code; + uint16_t ss_cmd_code = 0; uint32_t write_len = 0; unsigned char *dest_buf = driver->apps_dci_buf; unsigned char *payload_ptr = driver->apps_dci_buf + header_len; diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c index 252a6289881f..75543c768d45 100644 --- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c +++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.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 @@ -123,6 +123,9 @@ static ssize_t debugfs_state_info_read(struct file *file, dsi_ctrl->clk_info.link_clks.pixel_clk_rate, dsi_ctrl->clk_info.link_clks.esc_clk_rate); + if (len > count) + len = count; + /* TODO: make sure that this does not exceed 4K */ if (copy_to_user(buff, buf, len)) { kfree(buf); @@ -162,6 +165,9 @@ static ssize_t debugfs_reg_dump_read(struct file *file, "Core clocks are not turned on, cannot read\n"); } + if (len > count) + len = count; + /* TODO: make sure that this does not exceed 4K */ if (copy_to_user(buff, buf, len)) { kfree(buf); diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index e3e4c97a5220..ec55bc7b0d89 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -284,6 +284,12 @@ static int hfi_process_evt_release_buffer_ref(u32 device_id, "hal_process_session_init_done: bad_pkt_size\n"); return -E2BIG; } + if (pkt->size < sizeof(struct hfi_msg_event_notify_packet) - sizeof(u32) + + sizeof(struct hfi_msg_release_buffer_ref_event_packet)) { + dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", + __func__, pkt->size); + return -E2BIG; + } data = (struct hfi_msg_release_buffer_ref_event_packet *) pkt->rg_ext_event_data; @@ -1546,15 +1552,13 @@ static int hfi_process_session_etb_done(u32 device_id, struct hfi_msg_session_empty_buffer_done_packet *pkt = _pkt; struct msm_vidc_cb_data_done data_done = {0}; struct hfi_picture_type *hfi_picture_type = NULL; + u32 is_sync_frame; dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%#x]\n", pkt->session_id); if (!pkt || pkt->size < - sizeof(struct hfi_msg_session_empty_buffer_done_packet)) { - dprintk(VIDC_ERR, - "hal_process_session_etb_done: bad_pkt_size\n"); - return -E2BIG; - } + sizeof(struct hfi_msg_session_empty_buffer_done_packet)) + goto bad_packet_size; data_done.device_id = device_id; data_done.session_id = (void *)(uintptr_t)pkt->session_id; @@ -1569,8 +1573,13 @@ static int hfi_process_session_etb_done(u32 device_id, (ion_phys_addr_t)pkt->extra_data_buffer; data_done.input_done.status = hfi_map_err_status(pkt->error_type); - hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[0]; - if (hfi_picture_type->is_sync_frame) { + is_sync_frame = pkt->rgData[0]; + if (is_sync_frame == 1) { + if (pkt->size < + sizeof(struct hfi_msg_session_empty_buffer_done_packet) + + sizeof(struct hfi_picture_type)) + goto bad_packet_size; + hfi_picture_type = (struct hfi_picture_type *)&pkt->rgData[1]; if (hfi_picture_type->picture_type) data_done.input_done.flags = hfi_picture_type->picture_type; @@ -1589,6 +1598,10 @@ static int hfi_process_session_etb_done(u32 device_id, }; return 0; +bad_packet_size: + dprintk(VIDC_ERR, "%s: bad_pkt_size: %d\n", + __func__, pkt ? pkt->size : 0); + return -E2BIG; } static int hfi_process_session_ftb_done( @@ -1829,8 +1842,7 @@ static int hfi_process_session_rel_buf_done(u32 device_id, cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.status = hfi_map_err_status(pkt->error_type); if (pkt->rg_buffer_info) { - cmd_done.data.buffer_info = - *(struct hal_buffer_info *)pkt->rg_buffer_info; + cmd_done.data.buffer_info.buffer_addr = *pkt->rg_buffer_info; cmd_done.size = sizeof(struct hal_buffer_info); } else { dprintk(VIDC_ERR, "invalid payload in rel_buff_done\n"); diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.h b/drivers/media/platform/msm/vidc/vidc_hfi.h index 4cbb59d12f92..978fdc6bbb6d 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-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 @@ -662,7 +662,7 @@ struct hfi_msg_session_empty_buffer_done_packet { u32 input_tag; u32 packet_buffer; u32 extra_data_buffer; - u32 rgData[0]; + u32 rgData[1]; }; struct hfi_msg_session_fill_buffer_done_compressed_packet { diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h index 3709ad9fc658..27acb5fd9ca4 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h +++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h @@ -703,7 +703,6 @@ struct hfi_bit_depth { }; struct hfi_picture_type { - u32 is_sync_frame; u32 picture_type; }; diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 17bfb06a5651..714a4f16cd01 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -196,6 +196,8 @@ enum icnss_driver_event_type { ICNSS_DRIVER_EVENT_REGISTER_DRIVER, ICNSS_DRIVER_EVENT_UNREGISTER_DRIVER, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN, + ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN, + ICNSS_DRIVER_EVENT_IDLE_RESTART, ICNSS_DRIVER_EVENT_MAX, }; @@ -303,6 +305,7 @@ enum icnss_driver_state { ICNSS_REJUVENATE, ICNSS_BLOCK_SHUTDOWN, ICNSS_PDR, + ICNSS_MODEM_CRASHED, }; struct ce_irq_list { @@ -636,6 +639,10 @@ static char *icnss_driver_event_to_str(enum icnss_driver_event_type type) return "UNREGISTER_DRIVER"; case ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN: return "PD_SERVICE_DOWN"; + case ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN: + return "IDLE_SHUTDOWN"; + case ICNSS_DRIVER_EVENT_IDLE_RESTART: + return "IDLE_RESTART"; case ICNSS_DRIVER_EVENT_MAX: return "EVENT_MAX"; } @@ -2303,6 +2310,7 @@ static int icnss_pd_restart_complete(struct icnss_priv *priv) icnss_call_driver_shutdown(priv); clear_bit(ICNSS_PDR, &priv->state); + clear_bit(ICNSS_MODEM_CRASHED, &priv->state); clear_bit(ICNSS_REJUVENATE, &priv->state); clear_bit(ICNSS_PD_RESTART, &priv->state); priv->is_ssr = false; @@ -2494,6 +2502,52 @@ out: return ret; } +static int icnss_driver_event_idle_shutdown(void *data) +{ + int ret = 0; + + if (!penv->ops || !penv->ops->idle_shutdown) + return 0; + + if (test_bit(ICNSS_MODEM_CRASHED, &penv->state) || + test_bit(ICNSS_PDR, &penv->state) || + test_bit(ICNSS_REJUVENATE, &penv->state)) { + icnss_pr_err("SSR/PDR is already in-progress during idle shutdown callback\n"); + ret = -EBUSY; + } else { + icnss_pr_dbg("Calling driver idle shutdown, state: 0x%lx\n", + penv->state); + icnss_block_shutdown(true); + ret = penv->ops->idle_shutdown(&penv->pdev->dev); + icnss_block_shutdown(false); + } + + return ret; +} + +static int icnss_driver_event_idle_restart(void *data) +{ + int ret = 0; + + if (!penv->ops || !penv->ops->idle_restart) + return 0; + + if (test_bit(ICNSS_MODEM_CRASHED, &penv->state) || + test_bit(ICNSS_PDR, &penv->state) || + test_bit(ICNSS_REJUVENATE, &penv->state)) { + icnss_pr_err("SSR/PDR is already in-progress during idle restart callback\n"); + ret = -EBUSY; + } else { + icnss_pr_dbg("Calling driver idle restart, state: 0x%lx\n", + penv->state); + icnss_block_shutdown(true); + ret = penv->ops->idle_restart(&penv->pdev->dev); + icnss_block_shutdown(false); + } + + return ret; +} + static void icnss_driver_event_work(struct work_struct *work) { struct icnss_driver_event *event; @@ -2535,6 +2589,12 @@ static void icnss_driver_event_work(struct work_struct *work) ret = icnss_driver_event_pd_service_down(penv, event->data); break; + case ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN: + ret = icnss_driver_event_idle_shutdown(event->data); + break; + case ICNSS_DRIVER_EVENT_IDLE_RESTART: + ret = icnss_driver_event_idle_restart(event->data); + break; default: icnss_pr_err("Invalid Event type: %d", event->type); kfree(event); @@ -2641,6 +2701,9 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, priv->is_ssr = true; + if (notif->crashed) + set_bit(ICNSS_MODEM_CRASHED, &priv->state); + if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed && test_bit(ICNSS_BLOCK_SHUTDOWN, &priv->state)) { if (!wait_for_completion_timeout(&priv->unblock_shutdown, @@ -3597,6 +3660,48 @@ out: } EXPORT_SYMBOL(icnss_trigger_recovery); +int icnss_idle_shutdown(struct device *dev) +{ + struct icnss_priv *priv = dev_get_drvdata(dev); + + if (!priv) { + icnss_pr_err("Invalid drvdata: dev %pK", dev); + return -EINVAL; + } + + if (test_bit(ICNSS_MODEM_CRASHED, &priv->state) || + test_bit(ICNSS_PDR, &priv->state) || + test_bit(ICNSS_REJUVENATE, &penv->state)) { + icnss_pr_err("SSR/PDR is already in-progress during idle shutdown\n"); + return -EBUSY; + } + + return icnss_driver_event_post(ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN, + ICNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL); +} +EXPORT_SYMBOL(icnss_idle_shutdown); + +int icnss_idle_restart(struct device *dev) +{ + struct icnss_priv *priv = dev_get_drvdata(dev); + + if (!priv) { + icnss_pr_err("Invalid drvdata: dev %pK", dev); + return -EINVAL; + } + + if (test_bit(ICNSS_MODEM_CRASHED, &priv->state) || + test_bit(ICNSS_PDR, &priv->state) || + test_bit(ICNSS_REJUVENATE, &penv->state)) { + icnss_pr_err("SSR/PDR is already in-progress during idle restart\n"); + return -EBUSY; + } + + return icnss_driver_event_post(ICNSS_DRIVER_EVENT_IDLE_RESTART, + ICNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL); +} +EXPORT_SYMBOL(icnss_idle_restart); + static int icnss_smmu_init(struct icnss_priv *priv) { @@ -4053,6 +4158,10 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv) continue; case ICNSS_PDR: seq_puts(s, "PDR TRIGGERED"); + continue; + case ICNSS_MODEM_CRASHED: + seq_puts(s, "MODEM CRASHED"); + continue; } seq_printf(s, "UNKNOWN-%d", i); diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c index 4f30f7864bb0..0778e43fe0ff 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.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 @@ -3742,7 +3742,8 @@ static int hdmi_tx_hdcp_off(struct hdmi_tx_ctrl *hdmi_ctrl) DEV_DBG("%s: Turning off HDCP\n", __func__); hdmi_ctrl->hdcp_ops->off(hdmi_ctrl->hdcp_data); - flush_delayed_work(&hdmi_ctrl->hdcp_cb_work); + hdmi_ctrl->hdcp_status = HDCP_STATE_INACTIVE; + cancel_delayed_work(&hdmi_ctrl->hdcp_cb_work); hdmi_ctrl->hdcp_ops = NULL; diff --git a/drivers/video/fbdev/msm/mdss_hdmi_util.c b/drivers/video/fbdev/msm/mdss_hdmi_util.c index 8b8b4120d3fb..8e854c54bae8 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_util.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_util.c @@ -959,13 +959,17 @@ error: void hdmi_ddc_config(struct hdmi_tx_ddc_ctrl *ddc_ctrl) { + u32 ddc_speed; + if (!ddc_ctrl || !ddc_ctrl->io) { pr_err("invalid input\n"); return; } /* Configure Pre-Scale multiplier & Threshold */ - DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_SPEED, (10 << 16) | (2 << 0)); + ddc_speed = DSS_REG_R_ND(ddc_ctrl->io, HDMI_DDC_SPEED); + ddc_speed |= (12 << 16) | (2 << 0); + DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_SPEED, ddc_speed); /* * Setting 31:24 bits : Time units to wait before timeout diff --git a/include/soc/qcom/icnss.h b/include/soc/qcom/icnss.h index 4de4cd5e89dc..716e28054e60 100644 --- a/include/soc/qcom/icnss.h +++ b/include/soc/qcom/icnss.h @@ -56,6 +56,8 @@ struct icnss_driver_ops { int (*suspend_noirq)(struct device *dev); int (*resume_noirq)(struct device *dev); int (*uevent)(struct device *dev, struct icnss_uevent_data *uevent); + int (*idle_shutdown)(struct device *dev); + int (*idle_restart)(struct device *dev); }; @@ -159,4 +161,6 @@ extern u8 *icnss_get_wlan_mac_address(struct device *dev, uint32_t *num); extern int icnss_trigger_recovery(struct device *dev); extern void icnss_block_shutdown(bool status); extern bool icnss_is_pdr(void); +extern int icnss_idle_restart(struct device *dev); +extern int icnss_idle_shutdown(struct device *dev); #endif /* _ICNSS_WLAN_H_ */ diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index c8a2cc37363c..7ee774ddccf7 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -1241,7 +1241,7 @@ static int q6afe_get_params_v2(u16 port_id, int index, afe_get_param.apr_hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - afe_get_param.apr_hdr.pkt_size = sizeof(afe_get_param) + param_size; + afe_get_param.apr_hdr.pkt_size = sizeof(afe_get_param); afe_get_param.apr_hdr.src_port = 0; afe_get_param.apr_hdr.dest_port = 0; afe_get_param.apr_hdr.token = index; |
