Merge "defconfig: msm9625: enable filter table for ebtables."
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 4147b44..bf022ac 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -1170,10 +1170,10 @@
this_dbs_info->cur_policy = NULL;
if (!cpu)
input_unregister_handler(&dbs_input_handler);
- mutex_unlock(&dbs_mutex);
if (!dbs_enable)
sysfs_remove_group(cpufreq_global_kobject,
&dbs_attr_group);
+ mutex_unlock(&dbs_mutex);
break;
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 f6b97d4..d412435 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -184,6 +184,7 @@
struct msm_vfe_stats_hardware_info *stats_hw_info;
struct v4l2_subdev_internal_ops *subdev_internal_ops;
struct v4l2_subdev_ops *subdev_ops;
+ uint32_t dmi_reg_offset;
};
struct msm_vfe_axi_hardware_info {
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
index a522bd6..750963c 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -919,6 +919,7 @@
.get_pingpong_status = msm_vfe32_get_pingpong_status,
},
},
+ .dmi_reg_offset = 0x5A0,
.axi_hw_info = &msm_vfe32_axi_hw_info,
.subdev_ops = &msm_vfe32_subdev_ops,
.subdev_internal_ops = &msm_vfe32_internal_ops,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index dba59d7..ed4aa7f 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -1302,6 +1302,7 @@
.get_pingpong_status = msm_vfe40_get_pingpong_status,
},
},
+ .dmi_reg_offset = 0x918,
.axi_hw_info = &msm_vfe40_axi_hw_info,
.stats_hw_info = &msm_vfe40_stats_hw_info,
.subdev_ops = &msm_vfe40_subdev_ops,
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 606ee89..ac3ce0a 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
@@ -35,6 +35,8 @@
stream_cfg_cmd->axi_stream_handle =
(++axi_data->stream_handle_cnt) << 8 | i;
+ memset(&axi_data->stream_info[i], 0,
+ sizeof(struct msm_vfe_axi_stream));
axi_data->stream_info[i].session_id = stream_cfg_cmd->session_id;
axi_data->stream_info[i].stream_id = stream_cfg_cmd->stream_id;
axi_data->stream_info[i].buf_divert = stream_cfg_cmd->buf_divert;
@@ -621,7 +623,6 @@
int i;
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
uint32_t wm_reload_mask = 0x0, reg_update_mask = 0x1;
- int send_update_complete = 0;
for (i = 0; i < MAX_NUM_STREAM; i++) {
if (axi_data->stream_info[i].state == START_PENDING ||
axi_data->stream_info[i].state ==
@@ -631,9 +632,6 @@
&wm_reload_mask, ®_update_mask);
if (axi_data->stream_info[i].state == STOP_PENDING)
axi_data->stream_info[i].state = STOPPING;
- } else if (axi_data->stream_info[i].state == STOPPING) {
- send_update_complete = 1;
- axi_data->stream_info[i].state = INACTIVE;
}
}
/*Reload AXI*/
@@ -642,47 +640,31 @@
/*Reg update per src*/
vfe_dev->hw_info->vfe_ops.core_ops.
reg_update(vfe_dev, reg_update_mask);
- if (send_update_complete) {
+ if (vfe_dev->axi_data.stream_update) {
ISP_DBG("%s: send update complete\n", __func__);
vfe_dev->axi_data.stream_update = 0;
complete(&vfe_dev->stream_config_complete);
}
}
-int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev,
- struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status,
- struct timeval *tv)
+static void msm_isp_cfg_pong_address(struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream *stream_info)
{
- int i, rc = -1;
- struct msm_isp_buffer *buf = NULL;
- struct msm_isp_event_data buf_event;
- uint32_t pingpong_bit = 0;
- uint32_t bufq_handle = stream_info->bufq_handle;
- uint32_t stream_idx = stream_info->stream_handle & 0xFF;
+ int i;
+ struct msm_isp_buffer *buf = stream_info->buf[1];
+ for (i = 0; i < stream_info->num_planes; i++)
+ vfe_dev->hw_info->vfe_ops.axi_ops.update_ping_pong_addr(
+ vfe_dev, stream_info->wm[i],
+ VFE_PING_FLAG, buf->mapped_info[i].paddr);
+ stream_info->buf[0] = buf;
+}
+static void msm_isp_get_done_buf(struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status,
+ struct msm_isp_buffer **done_buf)
+{
+ uint32_t pingpong_bit = 0, i;
pingpong_bit = (~(pingpong_status >> stream_info->wm[0]) & 0x1);
- rc = vfe_dev->buf_mgr->ops->get_buf(
- vfe_dev->buf_mgr, bufq_handle, &buf);
- if (rc < 0) {
- if (stream_info->stream_type == BURST_STREAM &&
- stream_info->num_burst_capture <= 1) {
- rc = 0;
- if (pingpong_bit)
- buf = stream_info->buf[0];
- else
- buf = stream_info->buf[1];
- } else {
- vfe_dev->error_info.
- stream_framedrop_count[stream_idx]++;
- return rc;
- }
- }
-
- if (buf->num_planes != stream_info->num_planes) {
- pr_err("%s: Invalid buffer\n", __func__);
- rc = -EINVAL;
- goto buf_error;
- }
for (i = 0; i < stream_info->num_planes; i++) {
if (pingpong_bit !=
(~(pingpong_status >> stream_info->wm[i]) & 0x1)) {
@@ -690,19 +672,58 @@
__func__, pingpong_status);
}
}
+ *done_buf = stream_info->buf[pingpong_bit];
+}
+
+static int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status)
+{
+ int i, rc = -1;
+ struct msm_isp_buffer *buf = NULL;
+ uint32_t pingpong_bit = 0;
+ uint32_t bufq_handle = stream_info->bufq_handle;
+ uint32_t stream_idx = stream_info->stream_handle & 0xFF;
+
+ rc = vfe_dev->buf_mgr->ops->get_buf(
+ vfe_dev->buf_mgr, bufq_handle, &buf);
+ if (rc < 0) {
+ vfe_dev->error_info.
+ stream_framedrop_count[stream_idx]++;
+ return rc;
+ }
+
+ if (buf->num_planes != stream_info->num_planes) {
+ pr_err("%s: Invalid buffer\n", __func__);
+ rc = -EINVAL;
+ goto buf_error;
+ }
+
for (i = 0; i < stream_info->num_planes; i++)
vfe_dev->hw_info->vfe_ops.axi_ops.update_ping_pong_addr(
vfe_dev, stream_info->wm[i],
pingpong_status, buf->mapped_info[i].paddr);
- if (stream_info->buf[pingpong_bit] && tv) {
+ pingpong_bit = (~(pingpong_status >> stream_info->wm[0]) & 0x1);
+ stream_info->buf[pingpong_bit] = buf;
+ return 0;
+buf_error:
+ vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr,
+ buf->bufq_handle, buf->buf_idx);
+ return rc;
+}
+
+static void msm_isp_process_done_buf(struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream *stream_info, struct msm_isp_buffer *buf,
+ struct timeval *tv)
+{
+ struct msm_isp_event_data buf_event;
+ uint32_t frame_id = vfe_dev->axi_data.
+ src_info[stream_info->stream_src].frame_id;
+ if (buf && tv) {
if (stream_info->buf_divert) {
vfe_dev->buf_mgr->ops->buf_divert(vfe_dev->buf_mgr,
- stream_info->buf[pingpong_bit]->bufq_handle,
- stream_info->buf[pingpong_bit]->buf_idx,
- tv, stream_info->frame_id);
-
- buf_event.frame_id = stream_info->frame_id;
+ buf->bufq_handle, buf->buf_idx, tv, frame_id);
+ buf_event.frame_id = frame_id;
buf_event.timestamp = *tv;
buf_event.u.buf_done.session_id =
stream_info->session_id;
@@ -710,24 +731,14 @@
stream_info->stream_id;
buf_event.u.buf_done.handle =
stream_info->bufq_handle;
- buf_event.u.buf_done.buf_idx =
- stream_info->buf[pingpong_bit]->buf_idx;
+ buf_event.u.buf_done.buf_idx = buf->buf_idx;
msm_isp_send_event(
vfe_dev, ISP_EVENT_BUF_DIVERT, &buf_event);
} else {
vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr,
- stream_info->buf[pingpong_bit]->bufq_handle,
- stream_info->buf[pingpong_bit]->buf_idx,
- tv, stream_info->frame_id);
+ buf->bufq_handle, buf->buf_idx, tv, frame_id);
}
}
-
- stream_info->buf[pingpong_bit] = buf;
- return 0;
-buf_error:
- vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr,
- buf->bufq_handle, buf->buf_idx);
- return rc;
}
enum msm_isp_camif_update_state
@@ -855,7 +866,6 @@
&axi_data->stream_info[
(stream_cfg_cmd->stream_handle[i] & 0xFF)];
-
if (stream_info->stream_src == RDI)
src_state =
axi_data->src_info[
@@ -869,9 +879,23 @@
if (stream_cfg_cmd->cmd == START_STREAM) {
/*Set address for both PING & PONG register */
rc = msm_isp_cfg_ping_pong_address(vfe_dev,
- stream_info, VFE_PING_FLAG, NULL);
- rc = msm_isp_cfg_ping_pong_address(vfe_dev,
- stream_info, VFE_PONG_FLAG, NULL);
+ stream_info, VFE_PONG_FLAG);
+ if (rc < 0) {
+ pr_err("%s: No buffer for start stream\n",
+ __func__);
+ return rc;
+ }
+ /* For burst stream of one capture, only one buffer
+ * is allocated. Duplicate ping buffer address to pong
+ * buffer to ensure hardware write to a valid address
+ */
+ if (stream_info->stream_type == BURST_STREAM &&
+ stream_info->num_burst_capture <= 1) {
+ msm_isp_cfg_pong_address(vfe_dev, stream_info);
+ } else {
+ rc = msm_isp_cfg_ping_pong_address(vfe_dev,
+ stream_info, VFE_PING_FLAG);
+ }
}
if (src_state && camif_update != DISABLE_CAMIF) {
/*On the fly stream start/stop */
@@ -888,7 +912,8 @@
}
if (!wait_for_complete) {
/*Reload AXI*/
- vfe_dev->hw_info->vfe_ops.axi_ops.
+ if (stream_cfg_cmd->cmd == START_STREAM)
+ vfe_dev->hw_info->vfe_ops.axi_ops.
reload_wm(vfe_dev, wm_reload_mask);
/*Reg update per src*/
vfe_dev->hw_info->vfe_ops.core_ops.
@@ -904,7 +929,8 @@
axi_data->stream_update = 1;
spin_unlock_irqrestore(&vfe_dev->shared_data_lock, flags);
/*Reload AXI*/
- vfe_dev->hw_info->vfe_ops.axi_ops.
+ if (stream_cfg_cmd->cmd == START_STREAM)
+ vfe_dev->hw_info->vfe_ops.axi_ops.
reload_wm(vfe_dev, wm_reload_mask);
/*Reg update per src*/
vfe_dev->hw_info->vfe_ops.core_ops.
@@ -956,7 +982,8 @@
uint32_t irq_status0, uint32_t irq_status1,
struct timeval *tv)
{
- int i;
+ int i, rc = 0;
+ struct msm_isp_buffer *done_buf = NULL;
uint32_t comp_mask = 0, wm_mask = 0;
uint32_t pingpong_status, stream_idx;
struct msm_vfe_axi_stream *stream_info;
@@ -988,8 +1015,18 @@
__func__,
stream_idx, stream_info->frame_id);
stream_info->frame_id++;
- msm_isp_cfg_ping_pong_address(vfe_dev,
- stream_info, pingpong_status, tv);
+ msm_isp_get_done_buf(vfe_dev, stream_info,
+ pingpong_status, &done_buf);
+ if (stream_info->stream_type ==
+ CONTINUOUS_STREAM ||
+ stream_info->num_burst_capture > 1) {
+ rc = msm_isp_cfg_ping_pong_address(
+ vfe_dev, stream_info,
+ pingpong_status);
+ }
+ if (done_buf && !rc)
+ msm_isp_process_done_buf(vfe_dev,
+ stream_info, done_buf, tv);
}
}
wm_mask &= ~(comp_info->stream_composite_mask);
@@ -1005,8 +1042,16 @@
stream_idx = axi_data->free_wm[i] & 0xFF;
stream_info = &axi_data->stream_info[stream_idx];
stream_info->frame_id++;
- msm_isp_cfg_ping_pong_address(vfe_dev,
- stream_info, pingpong_status, tv);
+ msm_isp_get_done_buf(vfe_dev, stream_info,
+ pingpong_status, &done_buf);
+ if (stream_info->stream_type == CONTINUOUS_STREAM ||
+ stream_info->num_burst_capture > 1) {
+ rc = msm_isp_cfg_ping_pong_address(vfe_dev,
+ stream_info, pingpong_status);
+ }
+ if (done_buf && !rc)
+ msm_isp_process_done_buf(vfe_dev,
+ stream_info, done_buf, tv);
}
}
return;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
index 0c64c19..9765ae2 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
@@ -52,10 +52,6 @@
void msm_isp_axi_stream_update(struct vfe_device *vfe_dev);
-int msm_isp_cfg_ping_pong_address(struct vfe_device *vfe_dev,
- struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status,
- struct timeval *tv);
-
void msm_isp_update_framedrop_reg(struct vfe_device *vfe_dev);
void msm_isp_update_framedrop_count(struct vfe_device *vfe_dev);
void msm_isp_sof_notify(struct vfe_device *vfe_dev,
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index ab8dc95..e181b53 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -219,15 +219,15 @@
lo_val1 = lo_val & 0x0000FFFF;
lo_val = (lo_val & 0xFFFF0000)>>16;
msm_camera_io_w(lo_val1, vfe_dev->vfe_base +
- 0x091C);
+ vfe_dev->hw_info->dmi_reg_offset + 0x4);
} else if (reg_cfg_cmd->cmd_type ==
VFE_WRITE_DMI_64BIT) {
hi_val = *hi_tbl_ptr++;
msm_camera_io_w(hi_val, vfe_dev->vfe_base +
- 0x0918);
+ vfe_dev->hw_info->dmi_reg_offset);
}
msm_camera_io_w(lo_val, vfe_dev->vfe_base +
- 0x091C);
+ vfe_dev->hw_info->dmi_reg_offset + 0x4);
}
break;
}
@@ -258,16 +258,16 @@
for (i = 0; i < reg_cfg_cmd->u.dmi_info.len/4; i++) {
if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) {
hi_val = msm_camera_io_r(vfe_dev->vfe_base +
- 0x0918);
+ vfe_dev->hw_info->dmi_reg_offset);
*hi_tbl_ptr++ = hi_val;
}
lo_val = msm_camera_io_r(vfe_dev->vfe_base +
- 0x091C);
+ vfe_dev->hw_info->dmi_reg_offset + 0x4);
if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_16BIT) {
lo_val1 = msm_camera_io_r(vfe_dev->vfe_base +
- 0x091C);
+ vfe_dev->hw_info->dmi_reg_offset + 0x4);
lo_val |= lo_val1 << 16;
}
*lo_tbl_ptr++ = lo_val;