diff options
Diffstat (limited to 'drivers')
49 files changed, 677 insertions, 452 deletions
diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_bridge.c index 0c143059b749..5fbe4767ad3a 100644 --- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_bridge.c @@ -578,6 +578,9 @@ static void _sde_hdmi_bridge_disable(struct drm_bridge *bridge) display->sink_hdcp_ver = SDE_HDMI_HDCP_NONE; display->sink_hdcp22_support = false; + if (sde_hdmi_tx_is_hdcp_enabled(display)) + sde_hdmi_hdcp_off(display); + sde_hdmi_clear_hdr_info(bridge); mutex_unlock(&display->display_lock); } @@ -592,9 +595,6 @@ static void _sde_hdmi_bridge_post_disable(struct drm_bridge *bridge) sde_hdmi_notify_clients(display, display->connected); - if (sde_hdmi_tx_is_hdcp_enabled(display)) - sde_hdmi_hdcp_off(display); - sde_hdmi_audio_off(hdmi); DRM_DEBUG("power down"); @@ -603,10 +603,16 @@ static void _sde_hdmi_bridge_post_disable(struct drm_bridge *bridge) if (phy) phy->funcs->powerdown(phy); + /* HDMI teardown sequence */ + sde_hdmi_ctrl_reset(hdmi); + if (hdmi->power_on) { _sde_hdmi_bridge_power_off(bridge); hdmi->power_on = false; } + + /* Powering-on the controller for HPD */ + sde_hdmi_ctrl_cfg(hdmi, 1); } static void _sde_hdmi_bridge_set_avi_infoframe(struct hdmi *hdmi, diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c index 51f5c8d8dde6..a4f47756ad9b 100644 --- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c +++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_hdcp2p2.c @@ -234,10 +234,16 @@ static void sde_hdmi_hdcp2p2_off(void *input) flush_kthread_worker(&ctrl->worker); - sde_hdmi_hdcp2p2_ddc_disable((void *)ctrl->init_data.cb_data); - cdata.context = input; sde_hdmi_hdcp2p2_wakeup(&cdata); + + /* There could be upto one frame delay + * between the time encryption disable is + * requested till the time we get encryption + * disabled interrupt + */ + msleep(20); + sde_hdmi_hdcp2p2_ddc_disable((void *)ctrl->init_data.cb_data); } static int sde_hdmi_hdcp2p2_authenticate(void *input) diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.c b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.c index a291a1112aeb..8ce90b9bc162 100644 --- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.c +++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.c @@ -681,6 +681,78 @@ static void _sde_hdmi_scrambler_ddc_reset(struct hdmi *hdmi) hdmi_write(hdmi, REG_HDMI_SCRAMBLER_STATUS_DDC_CTRL, reg_val); } +void sde_hdmi_ctrl_cfg(struct hdmi *hdmi, bool power_on) +{ + uint32_t ctrl = 0; + unsigned long flags; + + spin_lock_irqsave(&hdmi->reg_lock, flags); + ctrl = hdmi_read(hdmi, REG_HDMI_CTRL); + + if (power_on) + ctrl |= HDMI_CTRL_ENABLE; + else + ctrl &= ~HDMI_CTRL_ENABLE; + + hdmi_write(hdmi, REG_HDMI_CTRL, ctrl); + spin_unlock_irqrestore(&hdmi->reg_lock, flags); + + HDMI_UTIL_DEBUG("HDMI Core: %s, HDMI_CTRL=0x%08x\n", + power_on ? "Enable" : "Disable", ctrl); +} + +static void sde_hdmi_clear_pkt_send(struct hdmi *hdmi) +{ + uint32_t reg_val; + + /* Clear audio sample send */ + reg_val = hdmi_read(hdmi, HDMI_AUDIO_PKT_CTRL); + reg_val &= ~BIT(0); + hdmi_write(hdmi, HDMI_AUDIO_PKT_CTRL, reg_val); + + /* Clear sending VBI ctrl packets */ + reg_val = hdmi_read(hdmi, HDMI_VBI_PKT_CTRL); + reg_val &= ~(BIT(4) | BIT(8) | BIT(12)); + hdmi_write(hdmi, HDMI_VBI_PKT_CTRL, reg_val); + + /* Clear sending infoframe packets */ + reg_val = hdmi_read(hdmi, HDMI_INFOFRAME_CTRL0); + reg_val &= ~(BIT(0) | BIT(4) | BIT(8) | BIT(12) + | BIT(15) | BIT(19)); + hdmi_write(hdmi, HDMI_INFOFRAME_CTRL0, reg_val); + + /* Clear sending general ctrl packets */ + reg_val = hdmi_read(hdmi, HDMI_GEN_PKT_CTRL); + reg_val &= ~(BIT(0) | BIT(4)); + hdmi_write(hdmi, HDMI_GEN_PKT_CTRL, reg_val); +} + +void sde_hdmi_ctrl_reset(struct hdmi *hdmi) +{ + uint32_t reg_val; + + /* Assert HDMI CTRL SW reset */ + reg_val = hdmi_read(hdmi, HDMI_CTRL_SW_RESET); + reg_val |= BIT(0); + hdmi_write(hdmi, HDMI_CTRL_SW_RESET, reg_val); + + /* disable the controller and put to known state */ + sde_hdmi_ctrl_cfg(hdmi, 0); + + /* disable the audio engine */ + reg_val = hdmi_read(hdmi, HDMI_AUDIO_CFG); + reg_val &= ~BIT(0); + hdmi_write(hdmi, HDMI_AUDIO_CFG, reg_val); + + /* clear sending packets to sink */ + sde_hdmi_clear_pkt_send(hdmi); + + /* De-assert HDMI CTRL SW reset */ + reg_val = hdmi_read(hdmi, HDMI_CTRL_SW_RESET); + reg_val &= ~BIT(0); + hdmi_write(hdmi, HDMI_CTRL_SW_RESET, reg_val); +} + void _sde_hdmi_scrambler_ddc_disable(void *hdmi_display) { struct sde_hdmi *display = (struct sde_hdmi *)hdmi_display; diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.h b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.h index 3cef7e6aca39..340e665f2c28 100644 --- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.h +++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi_util.h @@ -198,4 +198,7 @@ int sde_hdmi_sink_dc_support(struct drm_connector *connector, struct drm_display_mode *mode); u8 sde_hdmi_hdr_get_ops(u8 curr_state, u8 new_state); +void sde_hdmi_ctrl_reset(struct hdmi *hdmi); +void sde_hdmi_ctrl_cfg(struct hdmi *hdmi, bool power_on); + #endif /* _SDE_HDMI_UTIL_H_ */ diff --git a/drivers/media/i2c/adv7481.c b/drivers/media/i2c/adv7481.c index b6b89a9eefe2..74d7b9584827 100644 --- a/drivers/media/i2c/adv7481.c +++ b/drivers/media/i2c/adv7481.c @@ -1005,7 +1005,6 @@ static long adv7481_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { struct adv7481_state *state = to_state(sd); int *ret_val = arg; - uint8_t status = 0; long ret = 0; int param = 0; @@ -1040,22 +1039,6 @@ static long adv7481_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case VIDIOC_HDMI_RX_CEC_S_ENABLE: ret = adv7481_cec_powerup(state, arg); break; - case VIDIOC_CVBS_G_FIELD_STATUS: - /* Select SDP read-only Map 1 */ - adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr, - SDP_RW_MAP_REG, 0x02); - status = adv7481_rd_byte(&state->i2c_client, - state->i2c_sdp_addr, SDP_RO_MAP_1_FIELD_ADDR); - adv7481_wr_byte(&state->i2c_client, state->i2c_sdp_addr, - SDP_RW_MAP_REG, 0x00); - if (ret_val) { - *ret_val = ADV_REG_GETFIELD(status, - SDP_RO_MAP_1_EVEN_FIELD); - } else { - pr_err("%s: NULL pointer provided\n", __func__); - ret = -EINVAL; - } - break; default: pr_err("Not a typewriter! Command: 0x%x", cmd); ret = -ENOTTY; diff --git a/drivers/media/i2c/adv7481_reg.h b/drivers/media/i2c/adv7481_reg.h index 96f0a5df10c0..b0bb5784d2ef 100644 --- a/drivers/media/i2c/adv7481_reg.h +++ b/drivers/media/i2c/adv7481_reg.h @@ -411,11 +411,6 @@ #define SDP_RO_MAIN_IN_LOCK_BMSK 0x0001 #define SDP_RO_MAIN_IN_LOCK_SHFT 0 -/* SDP R/O Map 1 Registers */ -#define SDP_RO_MAP_1_FIELD_ADDR 0x45 -#define SDP_RO_MAP_1_EVEN_FIELD_BMSK 0x10 -#define SDP_RO_MAP_1_EVEN_FIELD_SHFT 4 - /* * CSI Map Registers diff --git a/drivers/media/platform/msm/ais/isp/msm_isp.h b/drivers/media/platform/msm/ais/isp/msm_isp.h index d4c6eba78b78..86974eeb4a32 100644 --- a/drivers/media/platform/msm/ais/isp/msm_isp.h +++ b/drivers/media/platform/msm/ais/isp/msm_isp.h @@ -164,8 +164,6 @@ struct msm_vfe_irq_ops { void (*config_irq)(struct vfe_device *vfe_dev, uint32_t irq_status0, uint32_t irq_status1, enum msm_isp_irq_operation); - void (*process_sof_irq)(struct vfe_device *vfe_dev, - uint32_t irq_status0, uint32_t irq_status1); void (*process_eof_irq)(struct vfe_device *vfe_dev, uint32_t irq_status0); }; @@ -413,12 +411,6 @@ struct msm_vfe_frame_request_queue { #define MSM_VFE_REQUESTQ_SIZE 8 -struct msm_vfe_fields_info { - bool even_field; - struct timeval sof_ts; - struct timeval field_ts; -}; - struct msm_vfe_axi_stream { uint32_t frame_id; enum msm_vfe_axi_state state; @@ -465,11 +457,6 @@ struct msm_vfe_axi_stream { enum msm_stream_memory_input_t memory_input; struct msm_isp_sw_framskip sw_skip; uint8_t sw_ping_pong_bit; - - bool interlaced; - struct msm_vfe_fields_info field_info[2]; - uint32_t field_index; - uint32_t field_type; }; struct msm_vfe_axi_composite_info { @@ -811,12 +798,6 @@ struct vfe_device { /* before halt irq info */ uint32_t recovery_irq0_mask; uint32_t recovery_irq1_mask; - - /* interlaced field info */ - void *ba_inst_hdl; - struct task_struct *field_thread_id; - wait_queue_head_t field_waitqueue; - bool wakeupflag; }; struct vfe_parent_device { diff --git a/drivers/media/platform/msm/ais/isp/msm_isp47.c b/drivers/media/platform/msm/ais/isp/msm_isp47.c index 9da7dee59064..04e879fc3bcf 100644 --- a/drivers/media/platform/msm/ais/isp/msm_isp47.c +++ b/drivers/media/platform/msm/ais/isp/msm_isp47.c @@ -662,37 +662,6 @@ void msm_vfe47_process_epoch_irq(struct vfe_device *vfe_dev, } } -static void msm_isp47_process_sof_irq(struct vfe_device *vfe_dev, - uint32_t irq_status0, uint32_t irq_status1) -{ - int i, axi_src_idx[4], src_count = 0; - struct msm_vfe_axi_stream *pstream_info; - struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data; - - if (irq_status0 & BIT(0)) - axi_src_idx[src_count++] = CAMIF_RAW; - if (irq_status1 & BIT(29)) - axi_src_idx[src_count++] = RDI_INTF_0; - if (irq_status1 & BIT(30)) - axi_src_idx[src_count++] = RDI_INTF_1; - if (irq_status1 & BIT(31)) - axi_src_idx[src_count++] = RDI_INTF_2; - - if (src_count == 0) - return; - - for (i = 0; i < src_count; i++) { - pstream_info = &axi_data->stream_info[axi_src_idx[i]]; - - if (pstream_info->interlaced) { - vfe_dev->wakeupflag = true; - wake_up_interruptible(&vfe_dev->field_waitqueue); - /* currently we support only 1 interlaced instance */ - break; - } - } -} - void msm_isp47_process_eof_irq(struct vfe_device *vfe_dev, uint32_t irq_status0) { @@ -2749,7 +2718,6 @@ struct msm_vfe_hardware_info vfe47_hw_info = { .process_stats_irq = msm_isp_process_stats_irq, .process_epoch_irq = msm_vfe47_process_epoch_irq, .config_irq = msm_vfe47_config_irq, - .process_sof_irq = msm_isp47_process_sof_irq, .process_eof_irq = msm_isp47_process_eof_irq, }, .axi_ops = { diff --git a/drivers/media/platform/msm/ais/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/ais/isp/msm_isp_axi_util.c index 9c06ee3b2687..a85ee30769c4 100644 --- a/drivers/media/platform/msm/ais/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/ais/isp/msm_isp_axi_util.c @@ -2042,12 +2042,6 @@ static int msm_isp_process_done_buf(struct vfe_device *vfe_dev, buf_event.u.buf_done.buf_idx = buf->buf_idx; buf_event.u.buf_done.output_format = stream_info->runtime_output_format; - - if (stream_info->interlaced) - buf_event.u.buf_done.field_type = stream_info->field_type; - else - buf_event.u.buf_done.field_type = 0; - if (vfe_dev->fetch_engine_info.is_busy && SRC_TO_INTF(stream_info->stream_src) == VFE_PIX_0) { vfe_dev->fetch_engine_info.is_busy = 0; @@ -3138,7 +3132,6 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev, } } - stream_info->interlaced = false; vfe_dev->reg_update_requested &= ~(BIT(SRC_TO_INTF(stream_info->stream_src))); } @@ -3551,18 +3544,13 @@ int msm_isp_axi_output_cfg(struct vfe_device *vfe_dev, void *arg) INIT_LIST_HEAD(&pstream_info->request_q); pstream_info->frame_based = - pCmd->output_path_cfg[axi_src_idx].frame_based & BIT(0); - pstream_info->interlaced = - (pCmd->output_path_cfg[axi_src_idx].frame_based - & BIT(INTERLACE_OFFSET)) ? true : false; + pCmd->output_path_cfg[axi_src_idx].frame_based; /* send buffers to user through vfe dev node */ pstream_info->buf_divert = 1; pstream_info->output_format = pCmd->output_path_cfg[axi_src_idx].format; - pstream_info->field_index = 0; - msm_isp_axi_get_num_planes( pCmd->output_path_cfg[axi_src_idx].format, pstream_info); diff --git a/drivers/media/platform/msm/ais/isp/msm_isp_util.c b/drivers/media/platform/msm/ais/isp/msm_isp_util.c index 2401ff645057..9e5317eb2920 100644 --- a/drivers/media/platform/msm/ais/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/ais/isp/msm_isp_util.c @@ -14,8 +14,6 @@ #include <linux/io.h> #include <media/v4l2-subdev.h> #include <linux/ratelimit.h> -#include <linux/kthread.h> -#include <linux/sched.h> #include "msm.h" #include "msm_isp_util.h" @@ -25,7 +23,6 @@ #include "cam_smmu_api.h" #define CREATE_TRACE_POINTS #include "trace/events/msm_cam.h" -#include "media/msm_ba.h" #define MAX_ISP_V4l2_EVENTS 100 #define MAX_ISP_REG_LIST 100 @@ -1977,166 +1974,6 @@ void msm_isp_reset_burst_count_and_frame_drop( msm_isp_reset_framedrop(vfe_dev, stream_info); } -static void msm_isp_field_type_read_thread(void *data) -{ - int ret = 0; - uint8_t i, j = 0; - bool even_field = 0; - uint64_t timestamp_us[4]; - struct msm_isp_timestamp ts; - struct msm_vfe_axi_stream *stream_info = NULL; - struct vfe_device *vfe_dev = (struct vfe_device *)data; - - pr_debug("Enter field_type_read_thread\n"); - - vfe_dev->ba_inst_hdl = msm_ba_open(NULL); - if (vfe_dev->ba_inst_hdl == NULL) { - pr_err("%s: ba open failed\n", __func__); - return; - } - - while (!kthread_should_stop()) { - ret = 0; - wait_event_interruptible(vfe_dev->field_waitqueue, - vfe_dev->wakeupflag == true); - if (kthread_should_stop()) { - pr_debug("%s: field thread has stopped\n", __func__); - goto bs_close; - } - - for (i = 0; i < VFE_AXI_SRC_MAX; i++) { - if (vfe_dev->axi_data.stream_info[i].interlaced) - break; - } - if (i == VFE_AXI_SRC_MAX) { - vfe_dev->wakeupflag = false; - continue; - } - - stream_info = &vfe_dev->axi_data.stream_info[i]; - j = stream_info->field_index; - - /* Detect field status from bridge chip */ - ret = msm_ba_private_ioctl(vfe_dev->ba_inst_hdl, - VIDIOC_CVBS_G_FIELD_STATUS, &even_field); - if (ret) { - pr_err("%s: get field status failed: %d\n", - __func__, ret); - } else { - msm_isp_get_timestamp(&ts, vfe_dev); - stream_info->field_info[j%2].even_field = even_field; - stream_info->field_info[j%2].field_ts.tv_sec = - ts.buf_time.tv_sec; - stream_info->field_info[j%2].field_ts.tv_usec = - ts.buf_time.tv_usec; - } - - stream_info->field_index++; - - /* once 2 fields info getting done, do the verification */ - if (stream_info->field_index%2 == 0) { - timestamp_us[0] = - stream_info->field_info[0].sof_ts.tv_sec - * 1000 * 1000 - + stream_info->field_info[0].sof_ts.tv_usec; - timestamp_us[1] = - stream_info->field_info[0].field_ts.tv_sec - * 1000 * 1000 - + stream_info->field_info[0].field_ts.tv_usec; - timestamp_us[2] = - stream_info->field_info[1].sof_ts.tv_sec - * 1000 * 1000 - + stream_info->field_info[1].sof_ts.tv_usec; - timestamp_us[3] = - stream_info->field_info[1].field_ts.tv_sec - * 1000 * 1000 - + stream_info->field_info[1].field_ts.tv_usec; - - /* - * Expected timing: - * field 0 SOF -> field 0 type read -> - * field 1 SOF -> field 1 type read - */ - if ((timestamp_us[0] < timestamp_us[1]) && - (timestamp_us[2] < timestamp_us[3]) && - (timestamp_us[1] < timestamp_us[2]) && - (stream_info->field_info[0].even_field != - stream_info->field_info[1].even_field)) { - /* - * Field type: - * 0 - unknown - * 1 - odd first - * 2 - even first - */ - stream_info->field_type = - stream_info->field_info[0].even_field ? - 2 : 1; - } else { - stream_info->field_type = 0; - pr_err("Field: %llu %llu %llu %llu %d %d\n", - timestamp_us[0], timestamp_us[1], - timestamp_us[2], timestamp_us[3], - stream_info->field_info[0].even_field, - stream_info->field_info[1].even_field); - } - } - - vfe_dev->wakeupflag = false; - } - -bs_close: - ret = msm_ba_close(vfe_dev->ba_inst_hdl); - if (ret) - pr_err("%s: msm ba close failed\n", __func__); - vfe_dev->ba_inst_hdl = NULL; -} - -static int msm_isp_init_field_type_kthread(struct vfe_device *vfe_dev) -{ - init_waitqueue_head(&vfe_dev->field_waitqueue); - - ISP_DBG("%s: Queue initialized\n", __func__); - vfe_dev->field_thread_id = kthread_run( - (void *)msm_isp_field_type_read_thread, - (void *)vfe_dev, "field_type_kthread"); - if (IS_ERR(vfe_dev->field_thread_id)) { - pr_err("%s: Unable to run the thread\n", __func__); - return -ENOMEM; - } - - return 0; -} - -static void msm_isp_field_timestamp(struct vfe_device *vfe_dev, - uint32_t irq_status0, uint32_t irq_status1, - struct timeval *timestamp) -{ - uint8_t i, j = 0; - struct msm_vfe_axi_stream *stream_info = NULL; - - for (i = 0; i < VFE_AXI_SRC_MAX; i++) { - if (vfe_dev->axi_data.stream_info[i].interlaced) - break; - } - - if (i == VFE_AXI_SRC_MAX) - return; - - stream_info = &vfe_dev->axi_data.stream_info[i]; - - /* SOF timestamp */ - if (((i == CAMIF_RAW) && (irq_status0 & BIT(0))) - || ((i == RDI_INTF_0) && (irq_status1 & BIT(29))) - || ((i == RDI_INTF_1) && (irq_status1 & BIT(30))) - || ((i == RDI_INTF_2) && (irq_status1 & BIT(31)))) { - j = stream_info->field_index; - stream_info->field_info[j%2].sof_ts.tv_sec = - timestamp->tv_sec; - stream_info->field_info[j%2].sof_ts.tv_usec = - timestamp->tv_usec; - } -} - static void msm_isp_enqueue_tasklet_cmd(struct vfe_device *vfe_dev, uint32_t irq_status0, uint32_t irq_status1, uint32_t ping_pong_status) @@ -2162,10 +1999,6 @@ static void msm_isp_enqueue_tasklet_cmd(struct vfe_device *vfe_dev, MSM_VFE_TASKLETQ_SIZE; list_add_tail(&queue_cmd->list, &vfe_dev->tasklet_q); spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags); - - msm_isp_field_timestamp(vfe_dev, irq_status0, irq_status1, - &queue_cmd->ts.buf_time); - tasklet_schedule(&vfe_dev->vfe_tasklet); } @@ -2288,7 +2121,6 @@ void msm_isp_do_tasklet(unsigned long data) spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags); ISP_DBG("%s: vfe_id %d status0: 0x%x status1: 0x%x\n", __func__, vfe_dev->pdev->id, irq_status0, irq_status1); - if (vfe_dev->is_split) { spin_lock(&dump_tasklet_lock); tasklet_data.arr[tasklet_data.first]. @@ -2307,8 +2139,6 @@ void msm_isp_do_tasklet(unsigned long data) (tasklet_data.first + 1) % MAX_ISP_PING_PONG_DUMP_SIZE; spin_unlock(&dump_tasklet_lock); } - irq_ops->process_sof_irq(vfe_dev, - irq_status0, irq_status1); irq_ops->process_reset_irq(vfe_dev, irq_status0, irq_status1); irq_ops->process_halt_irq(vfe_dev, @@ -2461,17 +2291,8 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) cam_smmu_reg_client_page_fault_handler( vfe_dev->buf_mgr->iommu_hdl, msm_vfe_iommu_fault_handler, vfe_dev); - - /* to detect interlaced frame type through ba driver */ - rc = msm_isp_init_field_type_kthread(vfe_dev); - if (rc) { - pr_err("%s: init field thread failed\n", __func__); - return rc; - } - mutex_unlock(&vfe_dev->core_mutex); mutex_unlock(&vfe_dev->realtime_mutex); - return 0; } @@ -2540,9 +2361,6 @@ int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) } vfe_dev->is_split = 0; - vfe_dev->wakeupflag = true; - kthread_stop(vfe_dev->field_thread_id); - mutex_unlock(&vfe_dev->core_mutex); mutex_unlock(&vfe_dev->realtime_mutex); return 0; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h index 21fab0590b55..34cac9daea89 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2017, 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 @@ -98,6 +98,8 @@ struct msm_isp_buffer { struct timeval *tv; /* Indicates whether buffer is used as ping ot pong buffer */ uint32_t pingpong_bit; + /* Indicates buffer is reconfig due to drop frame */ + uint32_t is_drop_reconfig; /*Native buffer*/ struct list_head list; diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c index 22eb86f4f875..23e27e1179d1 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c @@ -453,11 +453,69 @@ static long msm_isp_v4l2_fops_ioctl(struct file *file, unsigned int cmd, return video_usercopy(file, cmd, arg, msm_isp_subdev_do_ioctl); } +static void isp_vma_open(struct vm_area_struct *vma) +{ + pr_debug("%s: open called\n", __func__); +} + +static void isp_vma_close(struct vm_area_struct *vma) +{ + pr_debug("%s: close called\n", __func__); +} + +static int isp_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct page *page; + struct vfe_device *vfe_dev = vma->vm_private_data; + struct isp_proc *isp_page = NULL; + + isp_page = vfe_dev->isp_page; + + pr_debug("%s: vfeid:%d u_virt_addr:0x%lx k_virt_addr:%pK\n", + __func__, vfe_dev->pdev->id, vma->vm_start, + (void *)isp_page); + if (isp_page != NULL) { + page = virt_to_page(isp_page); + get_page(page); + vmf->page = page; + isp_page->kernel_sofid = + vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id; + isp_page->vfeid = vfe_dev->pdev->id; + } + return 0; +} + +static const struct vm_operations_struct isp_vm_ops = { + .open = isp_vma_open, + .close = isp_vma_close, + .fault = isp_vma_fault, +}; + +static int msm_isp_v4l2_fops_mmap(struct file *filep, + struct vm_area_struct *vma) +{ + int ret = -EINVAL; + struct video_device *vdev = video_devdata(filep); + struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); + struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd); + + vma->vm_ops = &isp_vm_ops; + vma->vm_flags |= + (unsigned long)(VM_DONTEXPAND | VM_DONTDUMP); + vma->vm_private_data = vfe_dev; + isp_vma_open(vma); + ret = 0; + pr_debug("%s: isp mmap is called vm_start: 0x%lx\n", + __func__, vma->vm_start); + return ret; +} + static struct v4l2_file_operations msm_isp_v4l2_fops = { #ifdef CONFIG_COMPAT .compat_ioctl32 = msm_isp_v4l2_fops_ioctl, #endif - .unlocked_ioctl = msm_isp_v4l2_fops_ioctl + .unlocked_ioctl = msm_isp_v4l2_fops_ioctl, + .mmap = msm_isp_v4l2_fops_mmap }; static int vfe_set_common_data(struct platform_device *pdev) @@ -671,6 +729,8 @@ int vfe_hw_probe(struct platform_device *pdev) msm_isp_v4l2_fops.compat_ioctl32 = msm_isp_v4l2_fops_ioctl; #endif + msm_isp_v4l2_fops.mmap = msm_isp_v4l2_fops_mmap; + vfe_dev->subdev.sd.devnode->fops = &msm_isp_v4l2_fops; vfe_dev->buf_mgr = &vfe_buf_mgr; @@ -687,6 +747,14 @@ int vfe_hw_probe(struct platform_device *pdev) msm_isp_enable_debugfs(vfe_dev, msm_isp_bw_request_history); vfe_dev->buf_mgr->init_done = 1; vfe_dev->vfe_open_cnt = 0; + /*Allocate a page in kernel and map it to camera user process*/ + vfe_dev->isp_page = (struct isp_proc *)get_zeroed_page(GFP_KERNEL); + if (vfe_dev->isp_page == NULL) { + pr_err("%s: no enough memory\n", __func__); + rc = -ENOMEM; + goto probe_fail3; + } + vfe_dev->isp_page->vfeid = vfe_dev->pdev->id; return rc; probe_fail3: diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h index b2d152bf4ef0..d336e1ef1bd7 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h @@ -759,6 +759,11 @@ struct msm_vfe_common_subdev { struct msm_vfe_common_dev_data *common_data; }; +struct isp_proc { + uint32_t kernel_sofid; + uint32_t vfeid; +}; + struct vfe_device { /* Driver private data */ struct platform_device *pdev; @@ -842,6 +847,7 @@ struct vfe_device { uint32_t recovery_irq1_mask; /* total bandwidth per vfe */ uint64_t total_bandwidth; + struct isp_proc *isp_page; }; struct vfe_parent_device { diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index 5bcb3034b82a..15f8061b9919 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -719,13 +719,7 @@ void msm_isp_check_for_output_error(struct vfe_device *vfe_dev, sof_info->stream_get_buf_fail_mask = 0; axi_data = &vfe_dev->axi_data; - /* report that registers are not updated and return empty buffer for - * controllable outputs - */ - if (!vfe_dev->reg_updated) { - sof_info->regs_not_updated = - vfe_dev->reg_update_requested; - } + for (i = 0; i < RDI_INTF_0; i++) { stream_info = msm_isp_get_stream_common_data(vfe_dev, i); @@ -747,6 +741,12 @@ void msm_isp_check_for_output_error(struct vfe_device *vfe_dev, if (stream_info->controllable_output && !vfe_dev->reg_updated) { if (stream_info->undelivered_request_cnt) { + /*report that registers are not updated + * and return empty buffer for controllable + * outputs + */ + sof_info->regs_not_updated = + !vfe_dev->reg_updated; pr_err("Drop frame no reg update\n"); if (msm_isp_drop_frame(vfe_dev, stream_info, ts, sof_info)) { @@ -933,6 +933,8 @@ void msm_isp_increment_frame_id(struct vfe_device *vfe_dev, } if (frame_src == VFE_PIX_0) { + vfe_dev->isp_page->kernel_sofid = + vfe_dev->axi_data.src_info[frame_src].frame_id; if (!src_info->frame_id && !src_info->reg_update_frame_id && ((src_info->frame_id - @@ -1646,23 +1648,30 @@ static void msm_isp_reload_ping_pong_offset( } static int msm_isp_update_deliver_count(struct vfe_device *vfe_dev, - struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_bit) + struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_bit, + struct msm_isp_buffer *done_buf) { int rc = 0; if (!stream_info->controllable_output) goto done; - if (!stream_info->undelivered_request_cnt) { + if (!stream_info->undelivered_request_cnt || + (done_buf == NULL)) { pr_err_ratelimited("%s:%d error undelivered_request_cnt 0\n", __func__, __LINE__); rc = -EINVAL; goto done; } else { + if ((done_buf->is_drop_reconfig == 1) && + (stream_info->sw_ping_pong_bit == -1)) { + goto done; + } /*After wm reload, we get bufdone for ping buffer*/ if (stream_info->sw_ping_pong_bit == -1) stream_info->sw_ping_pong_bit = 0; - stream_info->undelivered_request_cnt--; + if (done_buf->is_drop_reconfig != 1) + stream_info->undelivered_request_cnt--; if (pingpong_bit != stream_info->sw_ping_pong_bit) { pr_err("%s:%d ping pong bit actual %d sw %d\n", __func__, __LINE__, pingpong_bit, @@ -1908,7 +1917,8 @@ int msm_isp_cfg_offline_ping_pong_address(struct vfe_device *vfe_dev, } static int msm_isp_cfg_ping_pong_address( - struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status) + struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status, + struct msm_isp_buffer *buf) { int i; int j; @@ -1917,7 +1927,6 @@ static int msm_isp_cfg_ping_pong_address( uint32_t buffer_size_byte = 0; int32_t word_per_line = 0; dma_addr_t paddr; - struct msm_isp_buffer *buf = NULL; /* Isolate pingpong_bit from pingpong_status */ @@ -1928,10 +1937,11 @@ static int msm_isp_cfg_ping_pong_address( if (stream_info->buf[!pingpong_bit]) { pr_err("stream %x buffer already set for pingpong %d\n", stream_info->stream_src, !pingpong_bit); - return 0; + return 1; } - buf = msm_isp_get_stream_buffer(vfe_dev, stream_info); + if (buf == NULL) + buf = msm_isp_get_stream_buffer(vfe_dev, stream_info); if (!buf) { msm_isp_cfg_stream_scratch(stream_info, pingpong_status); @@ -2165,6 +2175,7 @@ int msm_isp_drop_frame(struct vfe_device *vfe_dev, struct msm_isp_bufq *bufq = NULL; uint32_t pingpong_bit; int vfe_idx; + int rc = -1; if (!vfe_dev || !stream_info || !ts || !sof_info) { pr_err("%s %d vfe_dev %pK stream_info %pK ts %pK op_info %pK\n", @@ -2181,17 +2192,42 @@ int msm_isp_drop_frame(struct vfe_device *vfe_dev, pingpong_bit = (~(pingpong_status >> stream_info->wm[vfe_idx][0]) & 0x1); done_buf = stream_info->buf[pingpong_bit]; - if (done_buf) { - bufq = vfe_dev->buf_mgr->ops->get_bufq(vfe_dev->buf_mgr, - done_buf->bufq_handle); - if (!bufq) { - spin_unlock_irqrestore(&stream_info->lock, flags); - pr_err("%s: Invalid bufq buf_handle %x\n", - __func__, done_buf->bufq_handle); - return -EINVAL; + if (done_buf && + (stream_info->composite_irq[MSM_ISP_COMP_IRQ_EPOCH] == 0)) { + if ((stream_info->sw_ping_pong_bit != -1) && + !vfe_dev->reg_updated) { + rc = msm_isp_cfg_ping_pong_address( + stream_info, ~pingpong_status, done_buf); + if (rc < 0) { + ISP_DBG("%s: Error configuring ping_pong\n", + __func__); + bufq = vfe_dev->buf_mgr->ops->get_bufq( + vfe_dev->buf_mgr, + done_buf->bufq_handle); + if (!bufq) { + spin_unlock_irqrestore( + &stream_info->lock, + flags); + pr_err("%s: Invalid bufq buf_handle %x\n", + __func__, + done_buf->bufq_handle); + return -EINVAL; + } + sof_info->reg_update_fail_mask_ext |= + (bufq->bufq_handle & 0xFF); + } + } + /*Avoid Drop Frame and re-issue pingpong cfg*/ + /*this notify is per ping and pong buffer*/ + done_buf->is_drop_reconfig = 1; + stream_info->current_framedrop_period = 1; + /*Avoid Multiple request frames for single SOF*/ + vfe_dev->axi_data.src_info[VFE_PIX_0].accept_frame = false; + + if (stream_info->current_framedrop_period != + stream_info->requested_framedrop_period) { + msm_isp_cfg_framedrop_reg(stream_info); } - sof_info->reg_update_fail_mask_ext |= - (bufq->bufq_handle & 0xFF); } spin_unlock_irqrestore(&stream_info->lock, flags); @@ -2201,6 +2237,8 @@ int msm_isp_drop_frame(struct vfe_device *vfe_dev, /* no buf done come */ msm_isp_process_axi_irq_stream(vfe_dev, stream_info, pingpong_status, ts); + if (done_buf) + done_buf->is_drop_reconfig = 0; } return 0; } @@ -2505,7 +2543,7 @@ static int msm_isp_init_stream_ping_pong_reg( /* Set address for both PING & PO NG register */ rc = msm_isp_cfg_ping_pong_address( - stream_info, VFE_PING_FLAG); + stream_info, VFE_PING_FLAG, NULL); /* No buffer available on start is not error */ if (rc == -ENOMEM && stream_info->stream_type != BURST_STREAM) return 0; @@ -2517,7 +2555,7 @@ static int msm_isp_init_stream_ping_pong_reg( if (stream_info->stream_type != BURST_STREAM || stream_info->runtime_num_burst_capture > 1) { rc = msm_isp_cfg_ping_pong_address( - stream_info, VFE_PONG_FLAG); + stream_info, VFE_PONG_FLAG, NULL); /* No buffer available on start is not error */ if (rc == -ENOMEM) return 0; @@ -3516,7 +3554,7 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, if (stream_info->undelivered_request_cnt == 1) { rc = msm_isp_cfg_ping_pong_address(stream_info, - VFE_PING_FLAG); + VFE_PING_FLAG, NULL); if (rc) { spin_unlock_irqrestore(&stream_info->lock, flags); stream_info->undelivered_request_cnt--; @@ -3549,10 +3587,10 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, * now. */ rc = msm_isp_cfg_ping_pong_address(stream_info, - VFE_PONG_FLAG); + VFE_PONG_FLAG, NULL); } else { rc = msm_isp_cfg_ping_pong_address( - stream_info, pingpong_status); + stream_info, pingpong_status, NULL); } if (rc) { stream_info->undelivered_request_cnt--; @@ -3574,6 +3612,9 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev, if (0 == rc) msm_isp_reset_framedrop(vfe_dev, stream_info); + /*Avoid Multiple request frames for single SOF*/ + vfe_dev->axi_data.src_info[frame_src].accept_frame = false; + spin_unlock_irqrestore(&stream_info->lock, flags); return rc; @@ -4057,6 +4098,10 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev, done_buf = stream_info->buf[pingpong_bit]; if (vfe_dev->buf_mgr->frameId_mismatch_recovery == 1) { + if (done_buf) { + if (done_buf->is_drop_reconfig == 1) + done_buf->is_drop_reconfig = 0; + } pr_err_ratelimited("%s: Mismatch Recovery in progress, drop frame!\n", __func__); spin_unlock_irqrestore(&stream_info->lock, flags); @@ -4076,14 +4121,26 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev, stream_info->frame_id++; stream_info->buf[pingpong_bit] = NULL; + if (stream_info->controllable_output && + (done_buf != NULL) && + (stream_info->sw_ping_pong_bit == -1) && + (done_buf->is_drop_reconfig == 1)) { + /*When wm reloaded and corresponding reg_update fail + * then buffer is reconfig as PING buffer. so, avoid + * NULL assignment to PING buffer and eventually + * next AXI_DONE or buf_done can be successful + */ + stream_info->buf[pingpong_bit] = done_buf; + } + if (stream_info->stream_type == CONTINUOUS_STREAM || stream_info->runtime_num_burst_capture > 1) { rc = msm_isp_cfg_ping_pong_address( - stream_info, pingpong_status); + stream_info, pingpong_status, NULL); if (rc < 0) ISP_DBG("%s: Error configuring ping_pong\n", __func__); - } else if (done_buf) { + } else if (done_buf && (done_buf->is_drop_reconfig != 1)) { msm_isp_cfg_stream_scratch(stream_info, pingpong_status); } @@ -4107,8 +4164,10 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev, } rc = msm_isp_update_deliver_count(vfe_dev, stream_info, - pingpong_bit); + pingpong_bit, done_buf); if (rc) { + if (done_buf->is_drop_reconfig == 1) + done_buf->is_drop_reconfig = 0; spin_unlock_irqrestore(&stream_info->lock, flags); pr_err_ratelimited("%s:VFE%d get done buf fail\n", __func__, vfe_dev->pdev->id); @@ -4117,17 +4176,28 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev, return; } - spin_unlock_irqrestore(&stream_info->lock, flags); if ((done_buf->frame_id != frame_id) && vfe_dev->axi_data.enable_frameid_recovery) { + if (done_buf->is_drop_reconfig == 1) + done_buf->is_drop_reconfig = 0; + spin_unlock_irqrestore(&stream_info->lock, flags); msm_isp_handle_done_buf_frame_id_mismatch(vfe_dev, stream_info, done_buf, time_stamp, frame_id); return; } - msm_isp_process_done_buf(vfe_dev, stream_info, + if (done_buf->is_drop_reconfig == 1) { + /*When ping/pong buf is already reconfigured + * then dont issue buf-done for current buffer + */ + done_buf->is_drop_reconfig = 0; + spin_unlock_irqrestore(&stream_info->lock, flags); + } else { + spin_unlock_irqrestore(&stream_info->lock, flags); + msm_isp_process_done_buf(vfe_dev, stream_info, done_buf, time_stamp, frame_id); + } } void msm_isp_process_axi_irq(struct vfe_device *vfe_dev, diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c index 08bbed147c86..76e1b60512d0 100644 --- a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c +++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c @@ -2009,6 +2009,18 @@ ioctl32_error: } #endif +static int sde_rotator_ctrl_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + return -EINVAL; +} + +static int sde_rotator_event_unsubscribe(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + return -EINVAL; +} + /* V4l2 ioctl handlers */ static const struct v4l2_ioctl_ops sde_rotator_ioctl_ops = { .vidioc_querycap = sde_rotator_querycap, @@ -2033,8 +2045,8 @@ static const struct v4l2_ioctl_ops sde_rotator_ioctl_ops = { .vidioc_s_parm = sde_rotator_s_parm, .vidioc_default = sde_rotator_private_ioctl, .vidioc_log_status = v4l2_ctrl_log_status, - .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + .vidioc_subscribe_event = sde_rotator_ctrl_subscribe_event, + .vidioc_unsubscribe_event = sde_rotator_event_unsubscribe, }; /* diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c index 1d37b2c8426b..caf63b8bbba4 100644 --- a/drivers/net/wireless/ath/ath10k/hw.c +++ b/drivers/net/wireless/ath/ath10k/hw.c @@ -509,6 +509,7 @@ const struct ath10k_hw_values wcn3990_values = { .num_target_ce_config_wlan = 12, .ce_desc_meta_data_mask = 0xFFF0, .ce_desc_meta_data_lsb = 4, + .default_listen_interval = 1, }; struct fw_flag wcn3990_fw_flags = { diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index e0af0f766b02..8aa696ed2e72 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -369,6 +369,7 @@ struct ath10k_hw_values { u8 num_target_ce_config_wlan; u16 ce_desc_meta_data_mask; u8 ce_desc_meta_data_lsb; + u8 default_listen_interval; }; extern const struct ath10k_hw_values qca988x_values; diff --git a/drivers/net/wireless/ath/ath10k/wow.c b/drivers/net/wireless/ath/ath10k/wow.c index 77100d42f401..dfc4cf016c99 100644 --- a/drivers/net/wireless/ath/ath10k/wow.c +++ b/drivers/net/wireless/ath/ath10k/wow.c @@ -224,6 +224,31 @@ static int ath10k_wow_wakeup(struct ath10k *ar) return 0; } +static int ath10k_config_wow_listen_interval(struct ath10k *ar) +{ + int ret; + u32 param = ar->wmi.vdev_param->listen_interval; + u8 listen_interval = ar->hw_values->default_listen_interval; + struct ath10k_vif *arvif; + + if (!listen_interval) + return 0; + + list_for_each_entry(arvif, &ar->arvifs, list) { + if (arvif->vdev_type != WMI_VDEV_TYPE_STA) + continue; + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, + param, listen_interval); + if (ret) { + ath10k_err(ar, "failed to config LI for vdev_id: %d\n", + arvif->vdev_id); + return ret; + } + } + + return 0; +} + int ath10k_wow_op_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) { @@ -252,6 +277,13 @@ int ath10k_wow_op_suspend(struct ieee80211_hw *hw, goto cleanup; } + ret = ath10k_config_wow_listen_interval(ar); + if (ret) { + ath10k_warn(ar, "failed to config wow listen interval: %d\n", + ret); + goto cleanup; + } + ret = ath10k_wow_enable(ar); if (ret) { ath10k_warn(ar, "failed to start wow: %d\n", ret); diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c index 72542bf6dd5d..c0af295c7362 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c @@ -23,10 +23,10 @@ static int ipa_generate_hw_rule_from_eq( const struct ipa_ipfltri_rule_eq *attrib, u8 **buf) { - int num_offset_meq_32 = attrib->num_offset_meq_32; - int num_ihl_offset_range_16 = attrib->num_ihl_offset_range_16; - int num_ihl_offset_meq_32 = attrib->num_ihl_offset_meq_32; - int num_offset_meq_128 = attrib->num_offset_meq_128; + uint8_t num_offset_meq_32 = attrib->num_offset_meq_32; + uint8_t num_ihl_offset_range_16 = attrib->num_ihl_offset_range_16; + uint8_t num_ihl_offset_meq_32 = attrib->num_ihl_offset_meq_32; + uint8_t num_offset_meq_128 = attrib->num_offset_meq_128; int i; if (attrib->tos_eq_present) { diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c index 119d17cae9f5..e33d0d86ac95 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c @@ -512,6 +512,7 @@ int qmi_filter_request_send(struct ipa_install_fltr_rule_req_msg_v01 *req) struct ipa_install_fltr_rule_resp_msg_v01 resp; struct msg_desc req_desc, resp_desc; int rc; + int i; /* check if the filter rules from IPACM is valid */ if (req->filter_spec_list_len == 0) { @@ -521,6 +522,38 @@ int qmi_filter_request_send(struct ipa_install_fltr_rule_req_msg_v01 *req) req->filter_spec_list_len); } + if (req->filter_spec_list_len >= QMI_IPA_MAX_FILTERS_V01) { + IPAWANDBG( + "IPACM passes the number of filtering rules exceed limit\n"); + return -EINVAL; + } else if (req->source_pipe_index_valid != 0) { + IPAWANDBG( + "IPACM passes source_pipe_index_valid not zero 0 != %d\n", + req->source_pipe_index_valid); + return -EINVAL; + } else if (req->source_pipe_index >= ipa_ctx->ipa_num_pipes) { + IPAWANDBG( + "IPACM passes source pipe index not valid ID = %d\n", + req->source_pipe_index); + return -EINVAL; + } + for (i = 0; i < req->filter_spec_list_len; i++) { + if ((req->filter_spec_list[i].ip_type != + QMI_IPA_IP_TYPE_V4_V01) && + (req->filter_spec_list[i].ip_type != + QMI_IPA_IP_TYPE_V6_V01)) + return -EINVAL; + if (req->filter_spec_list[i].is_mux_id_valid == false) + return -EINVAL; + if (req->filter_spec_list[i].is_routing_table_index_valid + == false) + return -EINVAL; + if ((req->filter_spec_list[i].filter_action <= + QMI_IPA_FILTER_ACTION_INVALID_V01) && + (req->filter_spec_list[i].filter_action > + QMI_IPA_FILTER_ACTION_EXCEPTION_V01)) + return -EINVAL; + } mutex_lock(&ipa_qmi_lock); if (ipa_qmi_ctx != NULL) { /* cache the qmi_filter_request */ @@ -675,6 +708,27 @@ int qmi_filter_notify_send(struct ipa_fltr_installed_notif_req_msg_v01 *req) return -EINVAL; } + if (req->install_status != IPA_QMI_RESULT_SUCCESS_V01) { + IPAWANERR(" UL filter rule for pipe %d install_status = %d\n", + req->source_pipe_index, req->install_status); + return -EINVAL; + } else if (req->source_pipe_index >= ipa_ctx->ipa_num_pipes) { + IPAWANERR("IPACM passes source pipe index not valid ID = %d\n", + req->source_pipe_index); + return -EINVAL; + } else if (((req->embedded_pipe_index_valid != true) || + (req->embedded_call_mux_id_valid != true)) && + ((req->embedded_pipe_index_valid != false) || + (req->embedded_call_mux_id_valid != false))) { + IPAWANERR( + "IPACM passes embedded pipe and mux valid not valid\n"); + return -EINVAL; + } else if (req->embedded_pipe_index >= ipa_ctx->ipa_num_pipes) { + IPAWANERR("IPACM passes source pipe index not valid ID = %d\n", + req->source_pipe_index); + return -EINVAL; + } + mutex_lock(&ipa_qmi_lock); if (ipa_qmi_ctx != NULL) { /* cache the qmi_filter_request */ diff --git a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c index 23e4d2b0d6e8..b158b2b1c326 100644 --- a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c @@ -649,6 +649,8 @@ static int wwan_add_ul_flt_rule_to_ipa(void) return -ENOMEM; } + memset(req, 0, sizeof(struct ipa_fltr_installed_notif_req_msg_v01)); + param->commit = 1; param->ep = IPA_CLIENT_APPS_LAN_WAN_PROD; param->global = false; @@ -1517,8 +1519,8 @@ static int ipa_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /* Get driver name */ case RMNET_IOCTL_GET_DRIVER_NAME: memcpy(&extend_ioctl_data.u.if_name, - ipa_netdevs[0]->name, - sizeof(IFNAMSIZ)); + ipa_netdevs[0]->name, IFNAMSIZ); + extend_ioctl_data.u.if_name[IFNAMSIZ - 1] = '\0'; if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data, &extend_ioctl_data, sizeof(struct rmnet_ioctl_extended_s))) @@ -1664,6 +1666,7 @@ static int ipa_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) sizeof(wan_msg->upstream_ifname); strlcpy(wan_msg->upstream_ifname, extend_ioctl_data.u.if_name, len); + wan_msg->upstream_ifname[len - 1] = '\0'; memset(&msg_meta, 0, sizeof(struct ipa_msg_meta)); msg_meta.msg_type = WAN_XLAT_CONNECT; msg_meta.msg_len = sizeof(struct ipa_wan_msg); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index e9fd1560b1e8..a869b6419e5e 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -4306,6 +4306,7 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p, ipa3_register_panic_hdlr(); ipa3_ctx->q6_proxy_clk_vote_valid = true; + ipa3_ctx->q6_proxy_clk_vote_cnt++; mutex_lock(&ipa3_ctx->lock); ipa3_ctx->ipa_initialization_complete = true; @@ -4413,6 +4414,9 @@ static ssize_t ipa3_write(struct file *file, const char __user *buf, return -EFAULT; } + if (count > 0) + dbg_buff[count - 1] = '\0'; + /* Prevent consequent calls from trying to load the FW again. */ if (ipa3_is_ready()) return count; @@ -4887,6 +4891,7 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, mutex_init(&ipa3_ctx->nat_mem.lock); mutex_init(&ipa3_ctx->q6_proxy_clk_vote_mutex); mutex_init(&ipa3_ctx->ipa_cne_evt_lock); + ipa3_ctx->q6_proxy_clk_vote_cnt = 0; idr_init(&ipa3_ctx->ipa_idr); spin_lock_init(&ipa3_ctx->idr_lock); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 8e6db8f63fc1..a4c5e425dc83 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1240,6 +1240,7 @@ struct ipa3_context { u32 curr_ipa_clk_rate; bool q6_proxy_clk_vote_valid; struct mutex q6_proxy_clk_vote_mutex; + u32 q6_proxy_clk_vote_cnt; u32 ipa_num_pipes; struct ipa3_wlan_comm_memb wc_memb; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c index 4897c4dccf59..afe8db7a7284 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c @@ -603,13 +603,46 @@ int ipa3_qmi_filter_request_send(struct ipa_install_fltr_rule_req_msg_v01 *req) struct ipa_install_fltr_rule_resp_msg_v01 resp; struct msg_desc req_desc, resp_desc; int rc; + int i; /* check if the filter rules from IPACM is valid */ - if (req->filter_spec_ex_list_len == 0) { + if (req->filter_spec_list_len == 0) IPAWANDBG("IPACM pass zero rules to Q6\n"); - } else { + else IPAWANDBG("IPACM pass %u rules to Q6\n", - req->filter_spec_ex_list_len); + req->filter_spec_list_len); + + if (req->filter_spec_list_len >= QMI_IPA_MAX_FILTERS_V01) { + IPAWANDBG( + "IPACM passes the number of filtering rules exceed limit\n"); + return -EINVAL; + } else if (req->source_pipe_index_valid != 0) { + IPAWANDBG( + "IPACM passes source_pipe_index_valid not zero 0 != %d\n", + req->source_pipe_index_valid); + return -EINVAL; + } else if (req->source_pipe_index >= ipa3_ctx->ipa_num_pipes) { + IPAWANDBG( + "IPACM passes source pipe index not valid ID = %d\n", + req->source_pipe_index); + return -EINVAL; + } + for (i = 0; i < req->filter_spec_list_len; i++) { + if ((req->filter_spec_list[i].ip_type != + QMI_IPA_IP_TYPE_V4_V01) && + (req->filter_spec_list[i].ip_type != + QMI_IPA_IP_TYPE_V6_V01)) + return -EINVAL; + if (req->filter_spec_list[i].is_mux_id_valid == false) + return -EINVAL; + if (req->filter_spec_list[i].is_routing_table_index_valid + == false) + return -EINVAL; + if ((req->filter_spec_list[i].filter_action <= + QMI_IPA_FILTER_ACTION_INVALID_V01) && + (req->filter_spec_list[i].filter_action > + QMI_IPA_FILTER_ACTION_EXCEPTION_V01)) + return -EINVAL; } mutex_lock(&ipa3_qmi_lock); @@ -653,6 +686,7 @@ int ipa3_qmi_filter_request_ex_send( struct ipa_install_fltr_rule_resp_ex_msg_v01 resp; struct msg_desc req_desc, resp_desc; int rc; + int i; /* check if the filter rules from IPACM is valid */ if (req->filter_spec_ex_list_len == 0) { @@ -662,6 +696,34 @@ int ipa3_qmi_filter_request_ex_send( req->filter_spec_ex_list_len); } + if (req->filter_spec_ex_list_len >= QMI_IPA_MAX_FILTERS_EX_V01) { + IPAWANDBG( + "IPACM pass the number of filtering rules exceed limit\n"); + return -EINVAL; + } else if (req->source_pipe_index_valid != 0) { + IPAWANDBG( + "IPACM passes source_pipe_index_valid not zero 0 != %d\n", + req->source_pipe_index_valid); + return -EINVAL; + } + + for (i = 0; i < req->filter_spec_ex_list_len-1; i++) { + if ((req->filter_spec_ex_list[i].ip_type != + QMI_IPA_IP_TYPE_V4_V01) && + (req->filter_spec_ex_list[i].ip_type != + QMI_IPA_IP_TYPE_V6_V01)) + return -EINVAL; + if (req->filter_spec_ex_list[i].is_mux_id_valid == false) + return -EINVAL; + if (req->filter_spec_ex_list[i].is_routing_table_index_valid + == false) + return -EINVAL; + if ((req->filter_spec_ex_list[i].filter_action <= + QMI_IPA_FILTER_ACTION_INVALID_V01) && + (req->filter_spec_ex_list[i].filter_action > + QMI_IPA_FILTER_ACTION_EXCEPTION_V01)) + return -EINVAL; + } mutex_lock(&ipa3_qmi_lock); if (ipa3_qmi_ctx != NULL) { /* cache the qmi_filter_request */ @@ -862,6 +924,31 @@ int ipa3_qmi_filter_notify_send( IPAWANERR("Source pipe index invalid\n"); return -EINVAL; } + if (req->install_status != IPA_QMI_RESULT_SUCCESS_V01) { + IPAWANERR(" UL filter rule for pipe %d install_status = %d\n", + req->source_pipe_index, req->install_status); + return -EINVAL; + } else if (req->rule_id_valid != 1) { + IPAWANERR(" UL filter rule for pipe %d rule_id_valid = %d\n", + req->source_pipe_index, req->rule_id_valid); + return -EINVAL; + } else if (req->source_pipe_index >= ipa3_ctx->ipa_num_pipes) { + IPAWANDBG( + "IPACM passes source pipe index not valid ID = %d\n", + req->source_pipe_index); + return -EINVAL; + } else if (((req->embedded_pipe_index_valid != true) || + (req->embedded_call_mux_id_valid != true)) && + ((req->embedded_pipe_index_valid != false) || + (req->embedded_call_mux_id_valid != false))) { + IPAWANERR( + "IPACM passes embedded pipe and mux valid not valid\n"); + return -EINVAL; + } else if (req->embedded_pipe_index >= ipa3_ctx->ipa_num_pipes) { + IPAWANERR("IPACM passes source pipe index not valid ID = %d\n", + req->source_pipe_index); + return -EINVAL; + } mutex_lock(&ipa3_qmi_lock); if (ipa3_qmi_ctx != NULL) { diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index 29f2046610c8..74176d1aa47a 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -2989,7 +2989,9 @@ void ipa3_proxy_clk_unvote(void) mutex_lock(&ipa3_ctx->q6_proxy_clk_vote_mutex); if (ipa3_ctx->q6_proxy_clk_vote_valid) { IPA_ACTIVE_CLIENTS_DEC_SPECIAL("PROXY_CLK_VOTE"); - ipa3_ctx->q6_proxy_clk_vote_valid = false; + ipa3_ctx->q6_proxy_clk_vote_cnt--; + if (ipa3_ctx->q6_proxy_clk_vote_cnt == 0) + ipa3_ctx->q6_proxy_clk_vote_valid = false; } mutex_unlock(&ipa3_ctx->q6_proxy_clk_vote_mutex); } @@ -3005,8 +3007,10 @@ void ipa3_proxy_clk_vote(void) return; mutex_lock(&ipa3_ctx->q6_proxy_clk_vote_mutex); - if (!ipa3_ctx->q6_proxy_clk_vote_valid) { + if (!ipa3_ctx->q6_proxy_clk_vote_valid || + (ipa3_ctx->q6_proxy_clk_vote_cnt > 0)) { IPA_ACTIVE_CLIENTS_INC_SPECIAL("PROXY_CLK_VOTE"); + ipa3_ctx->q6_proxy_clk_vote_cnt++; ipa3_ctx->q6_proxy_clk_vote_valid = true; } mutex_unlock(&ipa3_ctx->q6_proxy_clk_vote_mutex); 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 053a581b1d26..b7ed529e9160 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c @@ -1216,10 +1216,10 @@ static int ipa_fltrt_calc_extra_wrd_bytes( static int ipa_fltrt_generate_hw_rule_bdy_from_eq( const struct ipa_ipfltri_rule_eq *attrib, u8 **buf) { - int num_offset_meq_32 = attrib->num_offset_meq_32; - int num_ihl_offset_range_16 = attrib->num_ihl_offset_range_16; - int num_ihl_offset_meq_32 = attrib->num_ihl_offset_meq_32; - int num_offset_meq_128 = attrib->num_offset_meq_128; + uint8_t num_offset_meq_32 = attrib->num_offset_meq_32; + uint8_t num_ihl_offset_range_16 = attrib->num_ihl_offset_range_16; + uint8_t num_ihl_offset_meq_32 = attrib->num_ihl_offset_meq_32; + uint8_t num_offset_meq_128 = attrib->num_offset_meq_128; int i; int extra_bytes; u8 *extra; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c index d0aa42c81750..9fe7b6c59302 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c @@ -1566,6 +1566,8 @@ void ipahal_get_aggr_force_close_valmask(int ep_idx, return; } + memset(valmask, 0, sizeof(struct ipahal_reg_valmask)); + if (ipahal_ctx->hw_type <= IPA_HW_v3_1) { shft = IPA_AGGR_FORCE_CLOSE_AGGR_FORCE_CLOSE_PIPE_BITMAP_SHFT; bmsk = IPA_AGGR_FORCE_CLOSE_AGGR_FORCE_CLOSE_PIPE_BITMAP_BMSK; diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c index 01ef670dba51..e49402afb6a2 100644 --- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c @@ -678,6 +678,8 @@ static int ipa3_wwan_add_ul_flt_rule_to_ipa(void) param->global = false; param->num_rules = (uint8_t)1; + memset(req, 0, sizeof(struct ipa_fltr_installed_notif_req_msg_v01)); + for (i = 0; i < rmnet_ipa3_ctx->num_q6_rules; i++) { param->ip = ipa3_qmi_ctx->q6_ul_filter_rule[i].ip; memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); @@ -1651,8 +1653,8 @@ static int ipa3_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /* Get driver name */ case RMNET_IOCTL_GET_DRIVER_NAME: memcpy(&extend_ioctl_data.u.if_name, - IPA_NETDEV()->name, - sizeof(IFNAMSIZ)); + IPA_NETDEV()->name, IFNAMSIZ); + extend_ioctl_data.u.if_name[IFNAMSIZ - 1] = '\0'; if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data, &extend_ioctl_data, sizeof(struct rmnet_ioctl_extended_s))) @@ -1745,6 +1747,7 @@ static int ipa3_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) sizeof(wan_msg->upstream_ifname); strlcpy(wan_msg->upstream_ifname, extend_ioctl_data.u.if_name, len); + wan_msg->upstream_ifname[len-1] = '\0'; memset(&msg_meta, 0, sizeof(struct ipa_msg_meta)); msg_meta.msg_type = WAN_XLAT_CONNECT; msg_meta.msg_len = sizeof(struct ipa_wan_msg); diff --git a/drivers/platform/msm/ipa/test/ipa_ut_framework.c b/drivers/platform/msm/ipa/test/ipa_ut_framework.c index 3bf9ac11f2d1..dfc8442e0862 100644 --- a/drivers/platform/msm/ipa/test/ipa_ut_framework.c +++ b/drivers/platform/msm/ipa/test/ipa_ut_framework.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017, 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 @@ -215,6 +215,10 @@ static ssize_t ipa_ut_dbgfs_meta_test_write(struct file *file, IPA_UT_DBG("Entry\n"); mutex_lock(&ipa_ut_ctx->lock); + if (file == NULL) { + rc = -EFAULT; + goto unlock_mutex; + } suite = file->f_inode->i_private; ipa_assert_on(!suite); meta_type = (long)(file->private_data); @@ -470,6 +474,10 @@ static ssize_t ipa_ut_dbgfs_test_write(struct file *file, IPA_UT_DBG("Entry\n"); mutex_lock(&ipa_ut_ctx->lock); + if (file == NULL) { + rc = -EFAULT; + goto unlock_mutex; + } test = file->f_inode->i_private; ipa_assert_on(!test); diff --git a/drivers/platform/msm/mhi/mhi_bhi.c b/drivers/platform/msm/mhi/mhi_bhi.c index 68ef2595f3c3..a931b1c139bc 100644 --- a/drivers/platform/msm/mhi/mhi_bhi.c +++ b/drivers/platform/msm/mhi/mhi_bhi.c @@ -641,7 +641,6 @@ int bhi_probe(struct mhi_device_ctxt *mhi_dev_ctxt) image += to_copy; } - fw_table->sequence++; release_firmware(firmware); /* allocate memory and setup rddm table */ @@ -662,7 +661,6 @@ int bhi_probe(struct mhi_device_ctxt *mhi_dev_ctxt) rddm_table->bhie_mem_info[i].phys_addr; sg_dma_len(itr) = size; } - rddm_table->sequence++; } else { /* out of memory for rddm, not fatal error */ mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, diff --git a/drivers/platform/msm/mhi/mhi_iface.c b/drivers/platform/msm/mhi/mhi_iface.c index ce6d1257cfbb..7423c13842fa 100644 --- a/drivers/platform/msm/mhi/mhi_iface.c +++ b/drivers/platform/msm/mhi/mhi_iface.c @@ -459,6 +459,7 @@ static int mhi_plat_probe(struct platform_device *pdev) return r; } INIT_WORK(&bhi_ctxt->fw_load_work, bhi_firmware_download); + bhi_ctxt->fw_table.sequence = 1; } mhi_dev_ctxt->flags.bb_required = diff --git a/drivers/platform/msm/mhi/mhi_main.c b/drivers/platform/msm/mhi/mhi_main.c index 739915c4af6f..9ee459806ab5 100644 --- a/drivers/platform/msm/mhi/mhi_main.c +++ b/drivers/platform/msm/mhi/mhi_main.c @@ -1898,6 +1898,7 @@ int mhi_register_device(struct mhi_device *mhi_device, if (mhi_device->support_rddm) { mhi_dev_ctxt->bhi_ctxt.support_rddm = true; mhi_dev_ctxt->bhi_ctxt.rddm_size = mhi_device->rddm_size; + mhi_dev_ctxt->bhi_ctxt.rddm_table.sequence = 1; mhi_log(mhi_dev_ctxt, MHI_MSG_INFO, "Device support rddm of size:0x%lx bytes\n", diff --git a/drivers/platform/msm/sps/bam.c b/drivers/platform/msm/sps/bam.c index c94536398dac..8eb29a3fc66d 100644 --- a/drivers/platform/msm/sps/bam.c +++ b/drivers/platform/msm/sps/bam.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2017, 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 @@ -707,7 +707,7 @@ static inline u32 bam_get_register_offset(void *base, enum bam_regs reg, struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return SPS_ERROR; } @@ -756,7 +756,7 @@ static inline u32 bam_read_reg(void *base, enum bam_regs reg, u32 param) struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return SPS_ERROR; } @@ -767,7 +767,7 @@ static inline u32 bam_read_reg(void *base, enum bam_regs reg, u32 param) return offset; } val = ioread32(dev->base + offset); - SPS_DBG(dev, "sps:bam 0x%p(va) offset 0x%x reg 0x%x r_val 0x%x.\n", + SPS_DBG(dev, "sps:bam 0x%pK(va) offset 0x%x reg 0x%x r_val 0x%x.\n", dev->base, offset, reg, val); return val; } @@ -788,7 +788,7 @@ static inline u32 bam_read_reg_field(void *base, enum bam_regs reg, u32 param, struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return SPS_ERROR; } @@ -802,7 +802,7 @@ static inline u32 bam_read_reg_field(void *base, enum bam_regs reg, u32 param, val = ioread32(dev->base + offset); val &= mask; /* clear other bits */ val >>= shift; - SPS_DBG(dev, "sps:bam 0x%p(va) read reg 0x%x mask 0x%x r_val 0x%x.\n", + SPS_DBG(dev, "sps:bam 0x%pK(va) read reg 0x%x mask 0x%x r_val 0x%x.\n", dev->base, offset, mask, val); return val; } @@ -823,7 +823,7 @@ static inline void bam_write_reg(void *base, enum bam_regs reg, struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return; } @@ -834,7 +834,7 @@ static inline void bam_write_reg(void *base, enum bam_regs reg, return; } iowrite32(val, dev->base + offset); - SPS_DBG(dev, "sps:bam 0x%p(va) write reg 0x%x w_val 0x%x.\n", + SPS_DBG(dev, "sps:bam 0x%pK(va) write reg 0x%x w_val 0x%x.\n", dev->base, offset, val); } @@ -854,7 +854,7 @@ static inline void bam_write_reg_field(void *base, enum bam_regs reg, struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return; } @@ -870,7 +870,7 @@ static inline void bam_write_reg_field(void *base, enum bam_regs reg, tmp &= ~mask; /* clear written bits */ val = tmp | (val << shift); iowrite32(val, dev->base + offset); - SPS_DBG(dev, "sps:bam 0x%p(va) write reg 0x%x w_val 0x%x.\n", + SPS_DBG(dev, "sps:bam 0x%pK(va) write reg 0x%x w_val 0x%x.\n", dev->base, offset, val); } @@ -888,28 +888,28 @@ int bam_init(void *base, u32 ee, struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return SPS_ERROR; } - SPS_DBG3(dev, "sps:%s:bam=%pa 0x%p(va).ee=%d.", __func__, + SPS_DBG3(dev, "sps:%s:bam=%pa 0x%pK(va).ee=%d.", __func__, BAM_ID(dev), dev->base, ee); ver = bam_read_reg_field(base, REVISION, 0, BAM_REVISION); if ((ver < BAM_MIN_VERSION) || (ver > BAM_MAX_VERSION)) { - SPS_ERR(dev, "sps:bam 0x%p(va) Invalid BAM REVISION 0x%x.\n", + SPS_ERR(dev, "sps:bam 0x%pK(va) Invalid BAM REVISION 0x%x.\n", dev->base, ver); return -ENODEV; } else - SPS_DBG(dev, "sps:REVISION of BAM 0x%p is 0x%x.\n", + SPS_DBG(dev, "sps:REVISION of BAM 0x%pK is 0x%x.\n", dev->base, ver); if (summing_threshold == 0) { summing_threshold = 4; SPS_ERR(dev, - "sps:bam 0x%p(va) summing_threshold is zero,use default 4.\n", + "sps:bam 0x%pK(va) summing_threshold is zero,use default 4.\n", dev->base); } @@ -1009,12 +1009,12 @@ int bam_security_init(void *base, u32 ee, u32 vmid, u32 pipe_mask) struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return SPS_ERROR; } - SPS_DBG3(dev, "sps:%s:bam=%pa 0x%p(va).", __func__, + SPS_DBG3(dev, "sps:%s:bam=%pa 0x%pK(va).", __func__, BAM_ID(dev), dev->base); /* @@ -1025,14 +1025,14 @@ int bam_security_init(void *base, u32 ee, u32 vmid, u32 pipe_mask) num_pipes = bam_read_reg_field(base, NUM_PIPES, 0, BAM_NUM_PIPES); if (version < 3 || version > 0x1F) { SPS_ERR(dev, - "sps:bam 0x%p(va) security is not supported for this BAM version 0x%x.\n", + "sps:bam 0x%pK(va) security is not supported for this BAM version 0x%x.\n", dev->base, version); return -ENODEV; } if (num_pipes > BAM_MAX_PIPES) { SPS_ERR(dev, - "sps:bam 0x%p(va) the number of pipes is more than the maximum number allowed.\n", + "sps:bam 0x%pK(va) the number of pipes is more than the maximum number allowed.\n", dev->base); return -ENODEV; } @@ -1080,12 +1080,12 @@ int bam_check(void *base, u32 *version, u32 ee, u32 *num_pipes) struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return SPS_ERROR; } - SPS_DBG3(dev, "sps:%s:bam=%pa 0x%p(va).", + SPS_DBG3(dev, "sps:%s:bam=%pa 0x%pK(va).", __func__, BAM_ID(dev), dev->base); if (!enhd_pipe) @@ -1094,7 +1094,7 @@ int bam_check(void *base, u32 *version, u32 ee, u32 *num_pipes) enabled = bam_get_pipe_attr(base, ee, true); if (!enabled) { - SPS_ERR(dev, "sps:%s:bam 0x%p(va) is not enabled.\n", + SPS_ERR(dev, "sps:%s:bam 0x%pK(va) is not enabled.\n", __func__, dev->base); return -ENODEV; } @@ -1110,7 +1110,7 @@ int bam_check(void *base, u32 *version, u32 ee, u32 *num_pipes) /* Check BAM version */ if ((ver < BAM_MIN_VERSION) || (ver > BAM_MAX_VERSION)) { - SPS_ERR(dev, "sps:%s:bam 0x%p(va) Invalid BAM version 0x%x.\n", + SPS_ERR(dev, "sps:%s:bam 0x%pK(va) Invalid BAM version 0x%x.\n", __func__, dev->base, ver); return -ENODEV; } @@ -1127,11 +1127,11 @@ void bam_exit(void *base, u32 ee) struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return; } - SPS_DBG3(dev, "sps:%s:bam=%pa 0x%p(va).ee=%d.", + SPS_DBG3(dev, "sps:%s:bam=%pa 0x%pK(va).ee=%d.", __func__, BAM_ID(dev), dev->base, ee); bam_write_reg_field(base, IRQ_SRCS_MSK_EE, ee, BAM_IRQ, 0); @@ -1155,7 +1155,7 @@ void bam_output_register_content(void *base, u32 ee) struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return; } @@ -1166,7 +1166,7 @@ void bam_output_register_content(void *base, u32 ee) num_pipes = bam_read_reg_field(base, NUM_PIPES, 0, BAM_NUM_PIPES); - SPS_INFO(dev, "sps:bam %pa 0x%p(va) has %d pipes.", + SPS_INFO(dev, "sps:bam %pa 0x%pK(va) has %d pipes.", BAM_ID(dev), dev->base, num_pipes); pipe_attr = enhd_pipe ? @@ -1193,7 +1193,7 @@ u32 bam_check_irq_source(void *base, u32 ee, u32 mask, struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return SPS_ERROR; } @@ -1205,13 +1205,13 @@ u32 bam_check_irq_source(void *base, u32 ee, u32 mask, status = bam_read_reg(base, IRQ_STTS, 0); if (status & IRQ_STTS_BAM_ERROR_IRQ) { - SPS_ERR(dev, "sps:bam %pa 0x%p(va);bam irq status=" + SPS_ERR(dev, "sps:bam %pa 0x%pK(va);bam irq status=" "0x%x.\nsps: BAM_ERROR_IRQ\n", BAM_ID(dev), dev->base, status); bam_output_register_content(base, ee); *cb_case = SPS_CALLBACK_BAM_ERROR_IRQ; } else if (status & IRQ_STTS_BAM_HRESP_ERR_IRQ) { - SPS_ERR(dev, "sps:bam %pa 0x%p(va);bam irq status=" + SPS_ERR(dev, "sps:bam %pa 0x%pK(va);bam irq status=" "0x%x.\nsps: BAM_HRESP_ERR_IRQ\n", BAM_ID(dev), dev->base, status); bam_output_register_content(base, ee); @@ -1219,13 +1219,13 @@ u32 bam_check_irq_source(void *base, u32 ee, u32 mask, #ifdef CONFIG_SPS_SUPPORT_NDP_BAM } else if (status & IRQ_STTS_BAM_TIMER_IRQ) { SPS_DBG1(dev, - "sps:bam 0x%p(va);receive BAM_TIMER_IRQ\n", + "sps:bam 0x%pK(va);receive BAM_TIMER_IRQ\n", dev->base); *cb_case = SPS_CALLBACK_BAM_TIMER_IRQ; #endif } else SPS_INFO(dev, - "sps:bam %pa 0x%p(va);bam irq status=0x%x.\n", + "sps:bam %pa 0x%pK(va);bam irq status=0x%x.\n", BAM_ID(dev), dev->base, status); bam_write_reg(base, IRQ_CLR, 0, status); @@ -1243,11 +1243,11 @@ void bam_pipe_reset(void *base, u32 pipe) struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return; } - SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.", + SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.", __func__, BAM_ID(dev), dev->base, pipe); bam_write_reg(base, P_RST, pipe, 1); @@ -1264,11 +1264,11 @@ void bam_disable_pipe(void *base, u32 pipe) struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return; } - SPS_DBG2(dev, "sps:%s:bam=0x%p(va).pipe=%d.", __func__, base, pipe); + SPS_DBG2(dev, "sps:%s:bam=0x%pK(va).pipe=%d.", __func__, base, pipe); bam_write_reg_field(base, P_CTRL, pipe, P_EN, 0); wmb(); /* ensure pipe is disabled */ } @@ -1281,20 +1281,20 @@ bool bam_pipe_check_zlt(void *base, u32 pipe) struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return false; } if (bam_read_reg_field(base, P_HALT, pipe, P_HALT_P_LAST_DESC_ZLT)) { SPS_DBG(dev, - "sps:%s:bam=0x%p(va).pipe=%d: the last desc is ZLT.", + "sps:%s:bam=0x%pK(va).pipe=%d: the last desc is ZLT.", __func__, base, pipe); return true; } SPS_DBG(dev, - "sps:%s:bam=0x%p(va).pipe=%d: the last desc is not ZLT.", + "sps:%s:bam=0x%pK(va).pipe=%d: the last desc is not ZLT.", __func__, base, pipe); return false; } @@ -1307,20 +1307,20 @@ bool bam_pipe_check_pipe_empty(void *base, u32 pipe) struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return false; } if (bam_read_reg_field(base, P_HALT, pipe, P_HALT_P_PIPE_EMPTY)) { SPS_DBG(dev, - "sps:%s:bam=0x%p(va).pipe=%d: desc FIFO is empty.", + "sps:%s:bam=0x%pK(va).pipe=%d: desc FIFO is empty.", __func__, base, pipe); return true; } SPS_DBG(dev, - "sps:%s:bam=0x%p(va).pipe=%d: desc FIFO is not empty.", + "sps:%s:bam=0x%pK(va).pipe=%d: desc FIFO is not empty.", __func__, base, pipe); return false; } @@ -1334,11 +1334,11 @@ int bam_pipe_init(void *base, u32 pipe, struct bam_pipe_parameters *param, struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return SPS_ERROR; } - SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.", + SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.", __func__, BAM_ID(dev), dev->base, pipe); /* Reset the BAM pipe */ @@ -1372,7 +1372,7 @@ int bam_pipe_init(void *base, u32 pipe, struct bam_pipe_parameters *param, bam_write_reg_field(base, P_CTRL, pipe, P_LOCK_GROUP, param->lock_group); - SPS_DBG(dev, "sps:bam=0x%p(va).pipe=%d.lock_group=%d.\n", + SPS_DBG(dev, "sps:bam=0x%pK(va).pipe=%d.lock_group=%d.\n", dev->base, pipe, param->lock_group); #endif @@ -1388,7 +1388,7 @@ int bam_pipe_init(void *base, u32 pipe, struct bam_pipe_parameters *param, bam_write_reg(base, P_EVNT_DEST_ADDR, pipe, peer_dest_addr); - SPS_DBG2(dev, "sps:bam=0x%p(va).pipe=%d.peer_bam=0x%x." + SPS_DBG2(dev, "sps:bam=0x%pK(va).pipe=%d.peer_bam=0x%x." "peer_pipe=%d.\n", dev->base, pipe, (u32) param->peer_phys_addr, @@ -1424,11 +1424,11 @@ void bam_pipe_exit(void *base, u32 pipe, u32 ee) struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return; } - SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.", + SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.", __func__, BAM_ID(dev), dev->base, pipe); bam_write_reg(base, P_IRQ_EN, pipe, 0); @@ -1449,15 +1449,15 @@ void bam_pipe_enable(void *base, u32 pipe) struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return; } - SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.", + SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.", __func__, BAM_ID(dev), dev->base, pipe); if (bam_read_reg_field(base, P_CTRL, pipe, P_EN)) - SPS_DBG2(dev, "sps:bam=0x%p(va).pipe=%d is already enabled.\n", + SPS_DBG2(dev, "sps:bam=0x%pK(va).pipe=%d is already enabled.\n", dev->base, pipe); else bam_write_reg_field(base, P_CTRL, pipe, P_EN, 1); @@ -1472,11 +1472,11 @@ void bam_pipe_disable(void *base, u32 pipe) struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return; } - SPS_DBG2(dev, "sps:%s:bam=%pa 0x%p(va).pipe=%d.", + SPS_DBG2(dev, "sps:%s:bam=%pa 0x%pK(va).pipe=%d.", __func__, BAM_ID(dev), dev->base, pipe); bam_write_reg_field(base, P_CTRL, pipe, P_EN, 0); @@ -1501,12 +1501,12 @@ void bam_pipe_set_irq(void *base, u32 pipe, enum bam_enable irq_en, struct sps_bam *dev = to_sps_bam_dev(base); if ((dev == NULL) || (&dev->base != base)) { - SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%p\n", + SPS_ERR(sps, "%s:Failed to get dev for base addr 0x%pK\n", __func__, base); return; } SPS_DBG2(dev, - "sps:%s:bam=%pa 0x%p(va).pipe=%d; irq_en:%d; src_mask:0x%x; ee:%d.\n", + "sps:%s:bam=%pa 0x%pK(va).pipe=%d; irq_en:%d; src_mask:0x%x; ee:%d.\n", __func__, BAM_ID(dev), dev->base, pipe, irq_en, src_mask, ee); if (src_mask & BAM_PIPE_IRQ_RST_ERROR) { diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c index e7710f929e71..367e0e39dc23 100644 --- a/drivers/platform/msm/sps/sps.c +++ b/drivers/platform/msm/sps/sps.c @@ -931,7 +931,7 @@ static int sps_device_init(void) goto exit_err; } - SPS_DBG3(sps, "sps:bamdma_bam.phys=%pa.virt=0x%p.", + SPS_DBG3(sps, "sps:bamdma_bam.phys=%pa.virt=0x%pK.", &bamdma_props.phys_addr, bamdma_props.virt_addr); @@ -946,7 +946,7 @@ static int sps_device_init(void) goto exit_err; } - SPS_DBG3(sps, "sps:bamdma_dma.phys=%pa.virt=0x%p.", + SPS_DBG3(sps, "sps:bamdma_dma.phys=%pa.virt=0x%pK.", &bamdma_props.periph_phys_addr, bamdma_props.periph_virt_addr); @@ -2322,11 +2322,8 @@ int sps_deregister_bam_device(unsigned long dev_handle) mutex_lock(&bam->lock); sps_bam_device_de_init(bam); mutex_unlock(&bam->lock); - ipc_log_context_destroy(bam->ipc_log0); ipc_log_context_destroy(bam->ipc_log1); ipc_log_context_destroy(bam->ipc_log2); - ipc_log_context_destroy(bam->ipc_log3); - ipc_log_context_destroy(bam->ipc_log4); if (bam->props.virt_size) (void)iounmap(bam->props.virt_addr); diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c index 38a6474dd06f..74b6894f889f 100644 --- a/drivers/platform/msm/sps/sps_bam.c +++ b/drivers/platform/msm/sps/sps_bam.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2017, 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 @@ -508,12 +508,12 @@ int sps_bam_enable(struct sps_bam *dev) if (dev->props.logging_number > 0) dev->props.logging_number--; SPS_INFO(dev, - "sps:BAM %pa (va:0x%p) enabled: ver:0x%x, number of pipes:%d\n", + "sps:BAM %pa (va:0x%pK) enabled: ver:0x%x, number of pipes:%d\n", BAM_ID(dev), dev->base, dev->version, dev->props.num_pipes); } else SPS_DBG3(dev, - "sps:BAM %pa (va:0x%p) enabled: ver:0x%x, number of pipes:%d\n", + "sps:BAM %pa (va:0x%pK) enabled: ver:0x%x, number of pipes:%d\n", BAM_ID(dev), dev->base, dev->version, dev->props.num_pipes); @@ -2127,7 +2127,7 @@ int sps_bam_pipe_get_event(struct sps_bam *dev, if (pipe->sys.no_queue) { SPS_ERR(dev, - "sps:Invalid connection for event: BAM %pa pipe %d context 0x%p\n", + "sps:Invalid connection for event: BAM %pa pipe %d context 0x%pK\n", BAM_ID(dev), pipe_index, pipe); notify->event_id = SPS_EVENT_INVALID; return SPS_ERROR; diff --git a/drivers/platform/msm/sps/sps_mem.c b/drivers/platform/msm/sps/sps_mem.c index becb9a15882a..db36e64f96d8 100644 --- a/drivers/platform/msm/sps/sps_mem.c +++ b/drivers/platform/msm/sps/sps_mem.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2011-2013, 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2013, 2015, 2017, 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 @@ -129,7 +130,7 @@ int sps_mem_init(phys_addr_t pipemem_phys_base, u32 pipemem_size) iomem_offset = 0; SPS_DBG(sps, - "sps:sps_mem_init.iomem_phys=%pa,iomem_virt=0x%p.", + "sps:sps_mem_init.iomem_phys=%pa,iomem_virt=0x%pK.", &iomem_phys, iomem_virt); } diff --git a/drivers/platform/msm/sps/sps_rm.c b/drivers/platform/msm/sps/sps_rm.c index ec64e6c25465..db5db28d5f9e 100644 --- a/drivers/platform/msm/sps/sps_rm.c +++ b/drivers/platform/msm/sps/sps_rm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2015, 2017, 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 @@ -723,8 +723,7 @@ int sps_rm_state_change(struct sps_pipe *pipe, u32 state) state == SPS_STATE_ALLOCATE) { if (sps_rm_alloc(pipe)) { SPS_ERR(pipe->bam, - "sps:Fail to allocate resource for" - " BAM 0x%p pipe %d.\n", + "sps:Fail to allocate resource for BAM 0x%pK pipe %d.\n", pipe->bam, pipe->pipe_index); return SPS_ERROR; } @@ -745,7 +744,7 @@ int sps_rm_state_change(struct sps_pipe *pipe, u32 state) result = sps_bam_pipe_connect(pipe, ¶ms); if (result) { SPS_ERR(pipe->bam, - "sps:Failed to connect BAM 0x%p pipe %d", + "sps:Failed to connect BAM 0x%pK pipe %d", pipe->bam, pipe->pipe_index); return SPS_ERROR; } diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index 93512f155c52..7acf5fab573b 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -2695,17 +2695,13 @@ int smblib_set_prop_pd_voltage_max(struct smb_charger *chg, return rc; } -int smblib_set_prop_pd_active(struct smb_charger *chg, - const union power_supply_propval *val) +static int __smblib_set_prop_pd_active(struct smb_charger *chg, bool pd_active) { int rc; bool orientation, sink_attached, hvdcp; u8 stat; - if (!get_effective_result(chg->pd_allowed_votable)) - return -EINVAL; - - chg->pd_active = val->intval; + chg->pd_active = pd_active; if (chg->pd_active) { vote(chg->apsd_disable_votable, PD_VOTER, true, 0); vote(chg->pd_allowed_votable, PD_VOTER, true, 0); @@ -2793,6 +2789,15 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, return rc; } +int smblib_set_prop_pd_active(struct smb_charger *chg, + const union power_supply_propval *val) +{ + if (!get_effective_result(chg->pd_allowed_votable)) + return -EINVAL; + + return __smblib_set_prop_pd_active(chg, val->intval); +} + int smblib_set_prop_ship_mode(struct smb_charger *chg, const union power_supply_propval *val) { @@ -3544,6 +3549,13 @@ static void smblib_handle_hvdcp_check_timeout(struct smb_charger *chg, /* enforce DCP ICL if specified */ vote(chg->usb_icl_votable, DCP_VOTER, chg->dcp_icl_ua != -EINVAL, chg->dcp_icl_ua); + + /* + * if pd is not allowed, then set pd_active = false right here, + * so that it starts the hvdcp engine + */ + if (!get_effective_result(chg->pd_allowed_votable)) + __smblib_set_prop_pd_active(chg, 0); } smblib_dbg(chg, PR_INTERRUPT, "IRQ: smblib_handle_hvdcp_check_timeout %s\n", @@ -4188,7 +4200,7 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data) if (chg->cc2_detach_wa_active || chg->typec_en_dis_active || chg->try_sink_active) { - smblib_dbg(chg, PR_INTERRUPT, "Ignoring since %s active\n", + smblib_dbg(chg, PR_MISC | PR_INTERRUPT, "Ignoring since %s active\n", chg->cc2_detach_wa_active ? "cc2_detach_wa" : "typec_en_dis"); return IRQ_HANDLED; @@ -4699,7 +4711,9 @@ static void smblib_legacy_detection_work(struct work_struct *work) smblib_err(chg, "Couldn't disable type-c rc=%d\n", rc); /* wait for the adapter to turn off VBUS */ - msleep(500); + msleep(1000); + + smblib_dbg(chg, PR_MISC, "legacy workaround enabling typec\n"); rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, @@ -4708,7 +4722,7 @@ static void smblib_legacy_detection_work(struct work_struct *work) smblib_err(chg, "Couldn't enable type-c rc=%d\n", rc); /* wait for type-c detection to complete */ - msleep(100); + msleep(400); rc = smblib_read(chg, TYPE_C_STATUS_5_REG, &stat); if (rc < 0) { @@ -4720,6 +4734,8 @@ static void smblib_legacy_detection_work(struct work_struct *work) vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, false, 0); legacy = stat & TYPEC_LEGACY_CABLE_STATUS_BIT; rp_high = chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH; + smblib_dbg(chg, PR_MISC, "legacy workaround done legacy = %d rp_high = %d\n", + legacy, rp_high); if (!legacy || !rp_high) vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, false, 0); diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index b0e2e292e3cb..bb6518159d12 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -510,7 +510,7 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) old_hdr->result = EIO; break; case DID_ERROR: - old_hdr->result = (srp->sense_b[0] == 0 && + old_hdr->result = (srp->sense_b[0] == 0 && hp->masked_status == GOOD) ? 0 : EIO; break; default: @@ -898,8 +898,10 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) return -ENXIO; if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR)) return -EFAULT; + mutex_lock(&sfp->parentdp->open_rel_lock); result = sg_new_write(sfp, filp, p, SZ_SG_IO_HDR, 1, read_only, 1, &srp); + mutex_unlock(&sfp->parentdp->open_rel_lock); if (result < 0) return result; result = wait_event_interruptible(sfp->read_wait, @@ -939,8 +941,10 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) sfp->low_dma = 1; if ((0 == sfp->low_dma) && !sfp->res_in_use) { val = (int) sfp->reserve.bufflen; + mutex_lock(&sfp->parentdp->open_rel_lock); sg_remove_scat(sfp, &sfp->reserve); sg_build_reserve(sfp, val); + mutex_unlock(&sfp->parentdp->open_rel_lock); } } else { if (atomic_read(&sdp->detaching)) @@ -1009,8 +1013,8 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) result = get_user(val, ip); if (result) return result; - if (val < 0) - return -EINVAL; + if (val < 0) + return -EINVAL; val = min_t(int, val, max_sectors_bytes(sdp->device->request_queue)); mutex_lock(&sfp->f_mutex); @@ -1020,9 +1024,10 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) mutex_unlock(&sfp->f_mutex); return -EBUSY; } - + mutex_lock(&sfp->parentdp->open_rel_lock); sg_remove_scat(sfp, &sfp->reserve); sg_build_reserve(sfp, val); + mutex_unlock(&sfp->parentdp->open_rel_lock); } mutex_unlock(&sfp->f_mutex); return 0; @@ -1149,14 +1154,14 @@ static long sg_compat_ioctl(struct file *filp, unsigned int cmd_in, unsigned lon return -ENXIO; sdev = sdp->device; - if (sdev->host->hostt->compat_ioctl) { + if (sdev->host->hostt->compat_ioctl) { int ret; ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg); return ret; } - + return -ENOIOCTLCMD; } #endif @@ -1646,7 +1651,7 @@ init_sg(void) else def_reserved_size = sg_big_buff; - rc = register_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), + rc = register_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), SG_MAX_DEVS, "sg"); if (rc) return rc; @@ -2304,7 +2309,7 @@ static const struct file_operations adio_fops = { }; static int sg_proc_single_open_dressz(struct inode *inode, struct file *file); -static ssize_t sg_proc_write_dressz(struct file *filp, +static ssize_t sg_proc_write_dressz(struct file *filp, const char __user *buffer, size_t count, loff_t *off); static const struct file_operations dressz_fops = { .owner = THIS_MODULE, @@ -2444,7 +2449,7 @@ static int sg_proc_single_open_adio(struct inode *inode, struct file *file) return single_open(file, sg_proc_seq_show_int, &sg_allow_dio); } -static ssize_t +static ssize_t sg_proc_write_adio(struct file *filp, const char __user *buffer, size_t count, loff_t *off) { @@ -2465,7 +2470,7 @@ static int sg_proc_single_open_dressz(struct inode *inode, struct file *file) return single_open(file, sg_proc_seq_show_int, &sg_big_buff); } -static ssize_t +static ssize_t sg_proc_write_dressz(struct file *filp, const char __user *buffer, size_t count, loff_t *off) { @@ -2640,6 +2645,9 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) seq_puts(s, srp->done ? ((1 == srp->done) ? "rcv:" : "fin:") : "act:"); + seq_printf(s, srp->done ? + ((1 == srp->done) ? "rcv:" : "fin:") + : "act:"); seq_printf(s, " id=%d blen=%d", srp->header.pack_id, blen); if (srp->done) diff --git a/drivers/scsi/ufs/ufs-qcom-debugfs.c b/drivers/scsi/ufs/ufs-qcom-debugfs.c index 494ecd1c5f79..db4ecec6cf2f 100644 --- a/drivers/scsi/ufs/ufs-qcom-debugfs.c +++ b/drivers/scsi/ufs/ufs-qcom-debugfs.c @@ -121,7 +121,8 @@ static ssize_t ufs_qcom_dbg_testbus_cfg_write(struct file *file, struct ufs_hba *hba = host->hba; - ret = simple_write_to_buffer(configuration, TESTBUS_CFG_BUFF_LINE_SIZE, + ret = simple_write_to_buffer(configuration, + TESTBUS_CFG_BUFF_LINE_SIZE - 1, &buff_pos, ubuf, cnt); if (ret < 0) { dev_err(host->hba->dev, "%s: failed to read user data\n", diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 35575c071760..d6f91405be09 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -8760,7 +8760,6 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) goto enable_gating; } - flush_work(&hba->eeh_work); ret = ufshcd_link_state_transition(hba, req_link_state, 1); if (ret) goto set_dev_active; diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 83efbbe25e6b..d9d49e861f03 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -2511,8 +2511,17 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb, if (code != SUBSYS_BEFORE_SHUTDOWN) return NOTIFY_OK; - if (test_bit(ICNSS_PDR_REGISTERED, &priv->state)) + if (test_bit(ICNSS_PDR_REGISTERED, &priv->state)) { + set_bit(ICNSS_FW_DOWN, &priv->state); + icnss_ignore_qmi_timeout(true); + + fw_down_data.crashed = !!notif->crashed; + if (test_bit(ICNSS_FW_READY, &priv->state)) + icnss_call_driver_uevent(priv, + ICNSS_UEVENT_FW_DOWN, + &fw_down_data); return NOTIFY_OK; + } icnss_pr_info("Modem went down, state: 0x%lx, crashed: %d\n", priv->state, notif->crashed); @@ -2646,14 +2655,18 @@ static int icnss_service_notifier_notify(struct notifier_block *nb, icnss_pr_info("PD service down, pd_state: %d, state: 0x%lx: cause: %s\n", *state, priv->state, icnss_pdr_cause[cause]); event_post: - set_bit(ICNSS_FW_DOWN, &priv->state); - icnss_ignore_qmi_timeout(true); - clear_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state); + if (!test_bit(ICNSS_FW_DOWN, &priv->state)) { + set_bit(ICNSS_FW_DOWN, &priv->state); + icnss_ignore_qmi_timeout(true); - fw_down_data.crashed = event_data->crashed; - if (test_bit(ICNSS_FW_READY, &priv->state)) - icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_DOWN, - &fw_down_data); + fw_down_data.crashed = event_data->crashed; + if (test_bit(ICNSS_FW_READY, &priv->state)) + icnss_call_driver_uevent(priv, + ICNSS_UEVENT_FW_DOWN, + &fw_down_data); + } + + clear_bit(ICNSS_HOST_TRIGGERED_PDR, &priv->state); icnss_driver_event_post(ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN, ICNSS_EVENT_SYNC, event_data); done: diff --git a/drivers/soc/qcom/qdsp6v2/msm_audio_ion_vm.c b/drivers/soc/qcom/qdsp6v2/msm_audio_ion_vm.c index a3aa8823d8ce..afc40461e8e8 100644 --- a/drivers/soc/qcom/qdsp6v2/msm_audio_ion_vm.c +++ b/drivers/soc/qcom/qdsp6v2/msm_audio_ion_vm.c @@ -22,7 +22,6 @@ #include <linux/msm_audio_ion.h> #include <linux/habmm.h> #include "../../../staging/android/ion/ion_priv.h" -#include "../../../staging/android/ion/ion_hvenv_driver.h" #define MSM_AUDIO_ION_PROBED (1 << 0) @@ -628,7 +627,7 @@ struct ion_client *msm_audio_ion_client_create(const char *name) { struct ion_client *pclient = NULL; - pclient = hvenv_ion_client_create(name); + pclient = msm_ion_client_create(name); return pclient; } diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index c244d908fa4f..24ecbc469eb6 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -282,7 +282,7 @@ out: return ret; } -static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) +void dwc3_ep0_stall_and_restart(struct dwc3 *dwc) { struct dwc3_ep *dep; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 94709587f238..f108aecbfe52 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2882,6 +2882,15 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_DCTL, reg); dwc->test_mode = false; + /* + * From SNPS databook section 8.1.2 + * the EP0 should be in setup phase. So ensure + * that EP0 is in setup phase by issuing a stall + * and restart if EP0 is not in setup phase. + */ + if (dwc->ep0state != EP0_SETUP_PHASE) + dwc3_ep0_stall_and_restart(dwc); + dwc3_stop_active_transfers(dwc); dwc3_clear_stall_all_ep(dwc); diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index baa83cf9638b..5b3ffbe3056d 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h @@ -98,6 +98,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, void dwc3_ep0_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event); void dwc3_ep0_out_start(struct dwc3 *dwc); +void dwc3_ep0_stall_and_restart(struct dwc3 *dwc); int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value); int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value); int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index 18e3c5cdcc24..67f7e75a9219 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -554,6 +554,9 @@ static int ipa_suspend_work_handler(struct gsi_data_port *d_port) if (!usb_gsi_ep_op(gsi->d_port.in_ep, (void *) &f_suspend, GSI_EP_OP_CHECK_FOR_SUSPEND)) { ret = -EFAULT; + block_db = false; + usb_gsi_ep_op(d_port->in_ep, (void *)&block_db, + GSI_EP_OP_SET_CLR_BLOCK_DBL); goto done; } diff --git a/drivers/video/fbdev/msm/mdss_hdmi_panel.c b/drivers/video/fbdev/msm/mdss_hdmi_panel.c index a8a56e3a8745..af72973a3988 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_panel.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_panel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2017, 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 @@ -632,6 +632,19 @@ static int hdmi_panel_setup_dc(struct hdmi_panel *panel) vbi_pkt_reg = DSS_REG_R(panel->io, HDMI_VBI_PKT_CTRL); vbi_pkt_reg |= BIT(5) | BIT(4); DSS_REG_W(panel->io, HDMI_VBI_PKT_CTRL, vbi_pkt_reg); + } else { + hdmi_ctrl_reg = DSS_REG_R(panel->io, HDMI_CTRL); + + /* disable GC CD override */ + hdmi_ctrl_reg &= ~BIT(27); + /* disable deep color for RGB888/YUV444/YUV420 30 bits */ + hdmi_ctrl_reg &= ~BIT(24); + DSS_REG_W(panel->io, HDMI_CTRL, hdmi_ctrl_reg); + + /* disable the GC packet sending */ + vbi_pkt_reg = DSS_REG_R(panel->io, HDMI_VBI_PKT_CTRL); + vbi_pkt_reg &= ~(BIT(5) | BIT(4)); + DSS_REG_W(panel->io, HDMI_VBI_PKT_CTRL, vbi_pkt_reg); } return rc; diff --git a/drivers/video/msm/ba/msm_ba.c b/drivers/video/msm/ba/msm_ba.c index 0fc251f026b1..4200b8f20073 100644 --- a/drivers/video/msm/ba/msm_ba.c +++ b/drivers/video/msm/ba/msm_ba.c @@ -555,24 +555,6 @@ long msm_ba_private_ioctl(void *instance, int cmd, void *arg) } } break; - case VIDIOC_CVBS_G_FIELD_STATUS: { - dprintk(BA_DBG, "VIDIOC_CVBS_G_FIELD_STATUS"); - sd = inst->sd; - if (!sd) { - dprintk(BA_ERR, "No sd registered"); - return -EINVAL; - } - if (s_ioctl) { - rc = v4l2_subdev_call(sd, core, ioctl, cmd, s_ioctl); - if (rc) - dprintk(BA_ERR, "%s failed: %ld on cmd: 0x%x", - __func__, rc, cmd); - } else { - dprintk(BA_ERR, "%s: NULL argument provided", __func__); - rc = -EINVAL; - } - } - break; default: dprintk(BA_WARN, "Not a typewriter! Command: 0x%x", cmd); rc = -ENOTTY; @@ -830,6 +812,11 @@ void *msm_ba_open(const struct msm_ba_ext_ops *ext_ops) dev_ctxt = get_ba_dev(); + if (!dev_ctxt) { + dprintk(BA_ERR, "Failed to get ba dev"); + return NULL; + } + inst = kzalloc(sizeof(*inst), GFP_KERNEL); if (!inst) { |