Merge "ARM: dts: msm: Add iris camera flash support for sdm845" into dev/msm-4.9-camx
diff --git a/Documentation/devicetree/bindings/media/video/msm-cam-cci.txt b/Documentation/devicetree/bindings/media/video/msm-cam-cci.txt
index 1127544..cd4d222 100644
--- a/Documentation/devicetree/bindings/media/video/msm-cam-cci.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-cam-cci.txt
@@ -180,6 +180,9 @@
should contain phandle of respective ir-cut node
- qcom,special-support-sensors: if only some special sensors are supported
on this board, add sensor name in this property.
+- use-shared-clk : It is booloean property. This property is required
+ if the clk is shared clk between different sensor and ois, if this
+ device need to be opened together.
- clock-rates: clock rate in Hz.
- clock-cntl-level: says what all different cloc level node has.
- clock-cntl-support: Says whether clock control support is present or not
@@ -248,6 +251,9 @@
required from the regulators mentioned in the regulator-names property
(in the same order).
- cam_vaf-supply : should contain regulator from which ois voltage is supplied
+- use-shared-clk : It is booloean property. This property is required
+ if the clk is shared clk between different sensor and ois, if this
+ device need to be opened together.
Example:
@@ -354,8 +360,8 @@
status = "ok";
shared-gpios = <18 19>;
pinctrl-names = "cam_res_mgr_default", "cam_res_mgr_suspend";
- pinctrl-0 = <&cam_res_mgr_active>;
- pinctrl-1 = <&cam_res_mgr_suspend>;
+ pinctrl-0 = <&cam_shared_clk_active &cam_res_mgr_active>;
+ pinctrl-1 = <&cam_shared_clk_suspend &cam_res_mgr_suspend>;
};
qcom,cam-sensor@0 {
@@ -374,7 +380,7 @@
cam_vio-supply = <&pm845_lvs1>;
cam_vana-supply = <&pmi8998_bob>;
regulator-names = "cam_vdig", "cam_vio", "cam_vana";
- rgltr-cntrl-support;
+ rgltr-cntrl-support;
rgltr-min-voltage = <0 3312000 1352000>;
rgltr-max-voltage = <0 3312000 1352000>;
rgltr-load-current = <0 80000 105000>;
@@ -398,6 +404,7 @@
sensor-mode = <0>;
cci-master = <0>;
status = "ok";
+ use-shared-clk;
clocks = <&clock_mmss clk_mclk0_clk_src>,
<&clock_mmss clk_camss_mclk0_clk>;
clock-names = "cam_src_clk", "cam_clk";
diff --git a/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-cdp.dtsi
index c4ca6c5..8b94ca2 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-cdp.dtsi
@@ -197,7 +197,7 @@
rgltr-cntrl-support;
rgltr-min-voltage = <1352000 1800000 2850000 0 2800000>;
rgltr-max-voltage = <1352000 1800000 2850000 0 2800000>;
- rgltr-load-current = <105000 0 80000 0>;
+ rgltr-load-current = <105000 0 80000 0 0>;
gpio-no-mux = <0>;
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk1_active
@@ -234,7 +234,7 @@
rgltr-cntrl-support;
rgltr-min-voltage = <1800000 2850000 1352000 0 2800000>;
rgltr-max-voltage = <1800000 2850000 1352000 0 2800000>;
- rgltr-load-current = <0 80000 105000 0>;
+ rgltr-load-current = <0 80000 105000 0 0>;
gpio-no-mux = <0>;
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk2_active
diff --git a/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-mtp.dtsi
index c4ca6c5..8b94ca2 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-camera-sensor-mtp.dtsi
@@ -197,7 +197,7 @@
rgltr-cntrl-support;
rgltr-min-voltage = <1352000 1800000 2850000 0 2800000>;
rgltr-max-voltage = <1352000 1800000 2850000 0 2800000>;
- rgltr-load-current = <105000 0 80000 0>;
+ rgltr-load-current = <105000 0 80000 0 0>;
gpio-no-mux = <0>;
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk1_active
@@ -234,7 +234,7 @@
rgltr-cntrl-support;
rgltr-min-voltage = <1800000 2850000 1352000 0 2800000>;
rgltr-max-voltage = <1800000 2850000 1352000 0 2800000>;
- rgltr-load-current = <0 80000 105000 0>;
+ rgltr-load-current = <0 80000 105000 0 0>;
gpio-no-mux = <0>;
pinctrl-names = "cam_default", "cam_suspend";
pinctrl-0 = <&cam_sensor_mclk2_active
diff --git a/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
index 163420a..ef01d73 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
@@ -41,6 +41,12 @@
status = "ok";
};
+&pm660l_switch1 {
+ pinctrl-names = "led_enable", "led_disable";
+ pinctrl-0 = <&flash_led3_front_en>;
+ pinctrl-1 = <&flash_led3_front_dis>;
+};
+
&qupv3_se9_2uart {
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
index 307444d..845fe73 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
@@ -42,6 +42,12 @@
status = "ok";
};
+&pm660l_switch1 {
+ pinctrl-names = "led_enable", "led_disable";
+ pinctrl-0 = <&flash_led3_front_en>;
+ pinctrl-1 = <&flash_led3_front_dis>;
+};
+
&qupv3_se9_2uart {
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
index 188da58..d4953c1 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
@@ -1558,6 +1558,36 @@
};
};
+ flash_led3_front {
+ flash_led3_front_en: flash_led3_front_en {
+ mux {
+ pins = "gpio21";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio21";
+ drive_strength = <2>;
+ output-high;
+ bias-disable;
+ };
+ };
+
+ flash_led3_front_dis: flash_led3_front_dis {
+ mux {
+ pins = "gpio21";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio21";
+ drive_strength = <2>;
+ output-low;
+ bias-disable;
+ };
+ };
+ };
+
/* Pinctrl setting for CAMERA GPIO key */
key_cam_snapshot {
key_cam_snapshot_default: key_cam_snapshot_default {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi b/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi
index 5a566e3..35a7774 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-camera.dtsi
@@ -777,7 +777,7 @@
clock-rates =
<0 0 0 0 0 0 384000000 0 0 0 404000000 0>,
<0 0 0 0 0 0 538000000 0 0 0 600000000 0>;
- clock-cntl-level = "svs";
+ clock-cntl-level = "svs", "turbo";
src-clock-name = "ife_csid_clk_src";
status = "ok";
};
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context.c b/drivers/media/platform/msm/camera/cam_core/cam_context.c
index 7447e1d..84402e4 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context.c
@@ -196,30 +196,6 @@
return rc;
}
-int cam_context_handle_crm_process_evt(struct cam_context *ctx,
- struct cam_req_mgr_link_evt_data *process_evt)
-{
- int rc;
-
- if (!ctx->state_machine) {
- CAM_ERR(CAM_CORE, "Context is not ready");
- return -EINVAL;
- }
-
- mutex_lock(&ctx->ctx_mutex);
- if (ctx->state_machine[ctx->state].crm_ops.process_evt) {
- rc = ctx->state_machine[ctx->state].crm_ops.process_evt(ctx,
- process_evt);
- } else {
- CAM_ERR(CAM_CORE, "No crm process evt in dev %d, state %d",
- ctx->dev_hdl, ctx->state);
- rc = -EPROTO;
- }
- mutex_unlock(&ctx->ctx_mutex);
-
- return rc;
-}
-
int cam_context_handle_acquire_dev(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd)
{
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context.h b/drivers/media/platform/msm/camera/cam_core/cam_context.h
index d536663..6d1589e 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context.h
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context.h
@@ -56,7 +56,6 @@
* @num_in_acked: Number of in fence acked
* @num_out_acked: Number of out fence acked
* @flushed: Request is flushed
- * @error_flag: Flag an error
* @ctx: The context to which this request belongs
*
*/
@@ -74,7 +73,6 @@
uint32_t num_in_acked;
uint32_t num_out_acked;
int flushed;
- bool error_flag;
struct cam_context *ctx;
};
@@ -122,8 +120,6 @@
struct cam_req_mgr_apply_request *apply);
int (*flush_req)(struct cam_context *ctx,
struct cam_req_mgr_flush_request *flush);
- int (*process_evt)(struct cam_context *ctx,
- struct cam_req_mgr_link_evt_data *evt_data);
};
@@ -274,18 +270,6 @@
struct cam_req_mgr_flush_request *apply);
/**
- * cam_context_handle_crm_process_evt()
- *
- * @brief: Handle process event command
- *
- * @ctx: Object pointer for cam_context
- * @process_evt: process event command payload
- *
- */
-int cam_context_handle_crm_process_evt(struct cam_context *ctx,
- struct cam_req_mgr_link_evt_data *process_evt);
-
-/**
* cam_context_handle_acquire_dev()
*
* @brief: Handle acquire device command
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
index 40bab1c..0a1c2cf 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_context_utils.c
@@ -201,7 +201,6 @@
return -EINVAL;
}
- cam_context_stop_dev_to_hw(ctx);
arg.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
arg.active_req = false;
diff --git a/drivers/media/platform/msm/camera/cam_core/cam_node.c b/drivers/media/platform/msm/camera/cam_core/cam_node.c
index 3b0adc4..1f0213e 100644
--- a/drivers/media/platform/msm/camera/cam_core/cam_node.c
+++ b/drivers/media/platform/msm/camera/cam_core/cam_node.c
@@ -309,26 +309,6 @@
return cam_context_handle_crm_flush_req(ctx, flush);
}
-static int __cam_node_crm_process_evt(
- struct cam_req_mgr_link_evt_data *evt_data)
-{
- struct cam_context *ctx = NULL;
-
- if (!evt_data) {
- CAM_ERR(CAM_CORE, "Invalid process event request payload");
- return -EINVAL;
- }
-
- ctx = (struct cam_context *) cam_get_device_priv(evt_data->dev_hdl);
- if (!ctx) {
- CAM_ERR(CAM_CORE, "Can not get context for handle %d",
- evt_data->dev_hdl);
- return -EINVAL;
- }
-
- return cam_context_handle_crm_process_evt(ctx, evt_data);
-}
-
int cam_node_deinit(struct cam_node *node)
{
if (node)
@@ -381,7 +361,6 @@
node->crm_node_intf.get_dev_info = __cam_node_crm_get_dev_info;
node->crm_node_intf.link_setup = __cam_node_crm_link_setup;
node->crm_node_intf.flush_req = __cam_node_crm_flush_req;
- node->crm_node_intf.process_evt = __cam_node_crm_process_evt;
mutex_init(&node->list_mutex);
INIT_LIST_HEAD(&node->free_ctx_list);
diff --git a/drivers/media/platform/msm/camera/cam_icp/hfi.c b/drivers/media/platform/msm/camera/cam_icp/hfi.c
index e51d350..a8855ae 100644
--- a/drivers/media/platform/msm/camera/cam_icp/hfi.c
+++ b/drivers/media/platform/msm/camera/cam_icp/hfi.c
@@ -109,7 +109,19 @@
new_write_idx << BYTE_WORD_SHIFT);
}
+ /*
+ * To make sure command data in a command queue before
+ * updating write index
+ */
+ wmb();
+
q->qhdr_write_idx = new_write_idx;
+
+ /*
+ * Before raising interrupt make sure command data is ready for
+ * firmware to process
+ */
+ wmb();
cam_io_w((uint32_t)INTR_ENABLE,
g_hfi->csr_base + HFI_REG_A5_CSR_HOST2ICPINT);
err:
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
index 93926a78..340a1e2 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
@@ -1644,6 +1644,7 @@
for (i = 0; i < CAM_FRAME_CMD_MAX; i++)
clear_bit(i, hw_mgr->ctx_data[ctx_id].hfi_frame_process.bitmap);
kfree(hw_mgr->ctx_data[ctx_id].hfi_frame_process.bitmap);
+ hw_mgr->ctx_data[ctx_id].hfi_frame_process.bitmap = NULL;
cam_icp_hw_mgr_clk_info_update(hw_mgr, &hw_mgr->ctx_data[ctx_id]);
hw_mgr->ctx_data[ctx_id].clk_info.curr_fc = 0;
hw_mgr->ctx_data[ctx_id].clk_info.base_clk = 0;
@@ -2068,6 +2069,7 @@
ctx_data = config_args->ctxt_to_hw_map;
mutex_lock(&ctx_data->ctx_mutex);
if (!ctx_data->in_use) {
+ mutex_unlock(&ctx_data->ctx_mutex);
CAM_ERR(CAM_ICP, "ctx is not in use");
return -EINVAL;
}
diff --git a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
index 5c95dad..cfe5071 100644
--- a/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
+++ b/drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
@@ -216,19 +216,7 @@
continue;
}
- if (req->error_flag || !req_isp->bubble_report) {
- CAM_DBG(CAM_ISP,
- "Sync with failure: req %lld res 0x%x fd 0x%x",
- req->request_id,
- req_isp->fence_map_out[j].resource_handle,
- req_isp->fence_map_out[j].sync_id);
-
- rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
- CAM_SYNC_STATE_SIGNALED_ERROR);
- if (rc)
- CAM_ERR(CAM_ISP, "Sync failed with rc = %d",
- rc);
- } else if (!bubble_state) {
+ if (!bubble_state) {
CAM_DBG(CAM_ISP,
"Sync with success: req %lld res 0x%x fd 0x%x",
req->request_id,
@@ -239,6 +227,18 @@
CAM_SYNC_STATE_SIGNALED_SUCCESS);
if (rc)
CAM_DBG(CAM_ISP, "Sync failed with rc = %d",
+ rc);
+ } else if (!req_isp->bubble_report) {
+ CAM_DBG(CAM_ISP,
+ "Sync with failure: req %lld res 0x%x fd 0x%x",
+ req->request_id,
+ req_isp->fence_map_out[j].resource_handle,
+ req_isp->fence_map_out[j].sync_id);
+
+ rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
+ CAM_SYNC_STATE_SIGNALED_ERROR);
+ if (rc)
+ CAM_ERR(CAM_ISP, "Sync failed with rc = %d",
rc);
} else {
/*
@@ -2091,34 +2091,6 @@
return rc;
}
-static int __cam_isp_ctx_process_evt(struct cam_context *ctx,
- struct cam_req_mgr_link_evt_data *link_evt_data)
-{
- int rc = 0;
- struct cam_ctx_request *req_current;
- struct cam_ctx_request *req_prev;
- bool req_id_found = false;
-
- list_for_each_entry_safe(req_current, req_prev,
- &ctx->pending_req_list, list) {
- if (link_evt_data->req_id == req_current->request_id) {
- req_current->error_flag = true;
- req_id_found = true;
- CAM_DBG(CAM_ISP,
- "flagging req_id=%lld as error on link_hdl: %d for dev_hdl: %d",
- link_evt_data->req_id, link_evt_data->link_hdl,
- link_evt_data->dev_hdl);
- }
- }
-
- if (!req_id_found) {
- CAM_ERR(CAM_ISP,
- "req_id=%lld not found in the pending list ",
- link_evt_data->req_id);
- rc = -EINVAL;
- }
- return rc;
-}
static int __cam_isp_ctx_unlink_in_activated(struct cam_context *ctx,
struct cam_req_mgr_core_dev_link_setup *unlink)
{
@@ -2251,7 +2223,6 @@
.unlink = __cam_isp_ctx_unlink_in_activated,
.apply_req = __cam_isp_ctx_apply_req,
.flush_req = __cam_isp_ctx_flush_req_in_top_state,
- .process_evt = __cam_isp_ctx_process_evt,
},
.irq_ops = __cam_isp_ctx_handle_irq_in_activated,
},
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
index 8880cb5..0362758 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
@@ -203,7 +203,8 @@
}
static int cam_ife_hw_mgr_start_hw_res(
- struct cam_ife_hw_mgr_res *isp_hw_res)
+ struct cam_ife_hw_mgr_res *isp_hw_res,
+ struct cam_ife_hw_mgr_ctx *ctx)
{
int i;
int rc = -1;
@@ -214,6 +215,8 @@
continue;
hw_intf = isp_hw_res->hw_res[i]->hw_intf;
if (hw_intf->hw_ops.start) {
+ isp_hw_res->hw_res[i]->rdi_only_ctx =
+ ctx->is_rdi_only_context;
rc = hw_intf->hw_ops.start(hw_intf->hw_priv,
isp_hw_res->hw_res[i],
sizeof(struct cam_isp_resource_node));
@@ -1749,7 +1752,8 @@
/* start the IFE out devices */
for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++) {
- rc = cam_ife_hw_mgr_start_hw_res(&ctx->res_list_ife_out[i]);
+ rc = cam_ife_hw_mgr_start_hw_res(
+ &ctx->res_list_ife_out[i], ctx);
if (rc) {
CAM_ERR(CAM_ISP, "Can not start IFE OUT (%d)", i);
goto err;
@@ -1759,7 +1763,7 @@
CAM_DBG(CAM_ISP, "START IFE SRC ... in ctx id:%d", ctx->ctx_index);
/* Start the IFE mux in devices */
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
- rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res);
+ rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res, ctx);
if (rc) {
CAM_ERR(CAM_ISP, "Can not start IFE MUX (%d)",
hw_mgr_res->res_id);
@@ -1770,7 +1774,7 @@
CAM_DBG(CAM_ISP, "START CSID HW ... in ctx id:%d", ctx->ctx_index);
/* Start the IFE CSID HW devices */
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
- rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res);
+ rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res, ctx);
if (rc) {
CAM_ERR(CAM_ISP, "Can not start IFE CSID (%d)",
hw_mgr_res->res_id);
@@ -1909,7 +1913,8 @@
ctx->ctx_index);
/* start the IFE out devices */
for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++) {
- rc = cam_ife_hw_mgr_start_hw_res(&ctx->res_list_ife_out[i]);
+ rc = cam_ife_hw_mgr_start_hw_res(
+ &ctx->res_list_ife_out[i], ctx);
if (rc) {
CAM_ERR(CAM_ISP, "Can not start IFE OUT (%d)",
i);
@@ -1921,7 +1926,7 @@
ctx->ctx_index);
/* Start the IFE mux in devices */
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
- rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res);
+ rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res, ctx);
if (rc) {
CAM_ERR(CAM_ISP, "Can not start IFE MUX (%d)",
hw_mgr_res->res_id);
@@ -1933,7 +1938,7 @@
ctx->ctx_index);
/* Start the IFE CSID HW devices */
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
- rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res);
+ rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res, ctx);
if (rc) {
CAM_ERR(CAM_ISP, "Can not start IFE CSID (%d)",
hw_mgr_res->res_id);
@@ -1945,7 +1950,7 @@
ctx->ctx_index);
/* Start the IFE CID HW devices */
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_cid, list) {
- rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res);
+ rc = cam_ife_hw_mgr_start_hw_res(hw_mgr_res, ctx);
if (rc) {
CAM_ERR(CAM_ISP, "Can not start IFE CSID (%d)",
hw_mgr_res->res_id);
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
index b634e38b..257a5ac 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
@@ -112,6 +112,7 @@
* @tasklet_info: Tasklet structure that will be used to
* schedule IRQ events related to this resource
* @irq_handle: handle returned on subscribing for IRQ event
+ * @rdi_only_ctx: resouce belong to rdi only context or not
* @init: function pointer to init the HW resource
* @deinit: function pointer to deinit the HW resource
* @start: function pointer to start the HW resource
@@ -131,6 +132,7 @@
void *cdm_ops;
void *tasklet_info;
int irq_handle;
+ int rdi_only_ctx;
int (*init)(struct cam_isp_resource_node *rsrc_node,
void *init_args, uint32_t arg_size);
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
index d534607..187aeaf 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
@@ -38,7 +38,7 @@
static uint32_t camif_irq_err_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
0x00000000,
- 0x0FFF7E80,
+ 0x0FFF7EBC,
};
static uint32_t rdi_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = {
@@ -531,7 +531,7 @@
struct cam_vfe_hw_core_info *core_info = NULL;
struct cam_hw_info *vfe_hw = hw_priv;
struct cam_isp_resource_node *isp_res;
- int rc = -ENODEV;
+ int rc = 0;
if (!hw_priv || !start_args ||
(arg_size != sizeof(struct cam_isp_resource_node))) {
@@ -545,39 +545,70 @@
mutex_lock(&vfe_hw->hw_mutex);
if (isp_res->res_type == CAM_ISP_RESOURCE_VFE_IN) {
- if (isp_res->res_id == CAM_ISP_HW_VFE_IN_CAMIF)
- isp_res->irq_handle = cam_irq_controller_subscribe_irq(
- core_info->vfe_irq_controller,
- CAM_IRQ_PRIORITY_1,
- camif_irq_reg_mask, &core_info->irq_payload,
- cam_vfe_irq_top_half, cam_ife_mgr_do_tasklet,
- isp_res->tasklet_info, cam_tasklet_enqueue_cmd);
- else
- isp_res->irq_handle = cam_irq_controller_subscribe_irq(
- core_info->vfe_irq_controller,
- CAM_IRQ_PRIORITY_1,
- rdi_irq_reg_mask, &core_info->irq_payload,
- cam_vfe_irq_top_half, cam_ife_mgr_do_tasklet,
- isp_res->tasklet_info, cam_tasklet_enqueue_cmd);
+ if (isp_res->res_id == CAM_ISP_HW_VFE_IN_CAMIF) {
+ isp_res->irq_handle =
+ cam_irq_controller_subscribe_irq(
+ core_info->vfe_irq_controller,
+ CAM_IRQ_PRIORITY_1,
+ camif_irq_reg_mask,
+ &core_info->irq_payload,
+ cam_vfe_irq_top_half,
+ cam_ife_mgr_do_tasklet,
+ isp_res->tasklet_info,
+ cam_tasklet_enqueue_cmd);
+ if (isp_res->irq_handle < 1)
+ rc = -ENOMEM;
+ } else if (isp_res->rdi_only_ctx) {
+ isp_res->irq_handle =
+ cam_irq_controller_subscribe_irq(
+ core_info->vfe_irq_controller,
+ CAM_IRQ_PRIORITY_1,
+ rdi_irq_reg_mask,
+ &core_info->irq_payload,
+ cam_vfe_irq_top_half,
+ cam_ife_mgr_do_tasklet,
+ isp_res->tasklet_info,
+ cam_tasklet_enqueue_cmd);
+ if (isp_res->irq_handle < 1)
+ rc = -ENOMEM;
+ }
- core_info->irq_err_handle = cam_irq_controller_subscribe_irq(
- core_info->vfe_irq_controller, CAM_IRQ_PRIORITY_0,
- camif_irq_err_reg_mask, &core_info->irq_payload,
- cam_vfe_irq_err_top_half, cam_ife_mgr_do_tasklet,
- core_info->tasklet_info, cam_tasklet_enqueue_cmd);
-
- if (isp_res->irq_handle > 0)
+ if (rc == 0) {
rc = core_info->vfe_top->hw_ops.start(
core_info->vfe_top->top_priv, isp_res,
sizeof(struct cam_isp_resource_node));
- else
+ if (rc)
+ CAM_ERR(CAM_ISP, "Start failed. type:%d",
+ isp_res->res_type);
+ } else {
CAM_ERR(CAM_ISP,
"Error! subscribe irq controller failed");
+ }
} else if (isp_res->res_type == CAM_ISP_RESOURCE_VFE_OUT) {
rc = core_info->vfe_bus->hw_ops.start(isp_res, NULL, 0);
} else {
CAM_ERR(CAM_ISP, "Invalid res type:%d", isp_res->res_type);
+ rc = -EFAULT;
}
+
+ if (!core_info->irq_err_handle) {
+ core_info->irq_err_handle =
+ cam_irq_controller_subscribe_irq(
+ core_info->vfe_irq_controller,
+ CAM_IRQ_PRIORITY_0,
+ camif_irq_err_reg_mask,
+ &core_info->irq_payload,
+ cam_vfe_irq_err_top_half,
+ cam_ife_mgr_do_tasklet,
+ core_info->tasklet_info,
+ cam_tasklet_enqueue_cmd);
+ if (core_info->irq_err_handle < 1) {
+ CAM_ERR(CAM_ISP, "Error handle subscribe failure");
+ rc = -ENOMEM;
+ core_info->irq_err_handle = 0;
+ }
+ }
+
mutex_unlock(&vfe_hw->hw_mutex);
return rc;
@@ -607,15 +638,19 @@
core_info->vfe_top->top_priv, isp_res,
sizeof(struct cam_isp_resource_node));
- cam_irq_controller_unsubscribe_irq(
- core_info->vfe_irq_controller, core_info->irq_err_handle);
-
} else if (isp_res->res_type == CAM_ISP_RESOURCE_VFE_OUT) {
rc = core_info->vfe_bus->hw_ops.stop(isp_res, NULL, 0);
} else {
CAM_ERR(CAM_ISP, "Invalid res type:%d", isp_res->res_type);
}
+ if (core_info->irq_err_handle) {
+ cam_irq_controller_unsubscribe_irq(
+ core_info->vfe_irq_controller,
+ core_info->irq_err_handle);
+ core_info->irq_err_handle = 0;
+ }
+
mutex_unlock(&vfe_hw->hw_mutex);
return rc;
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_context.c b/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_context.c
index 6fcd7f6..4589a22 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_context.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/cam_jpeg_context.c
@@ -63,6 +63,20 @@
return cam_context_buf_done_from_hw(ctx, done, evt_id);
}
+static int __cam_jpeg_ctx_stop_dev_in_acquired(struct cam_context *ctx,
+ struct cam_start_stop_dev_cmd *cmd)
+{
+ int rc;
+
+ rc = cam_context_stop_dev_to_hw(ctx);
+ if (rc) {
+ CAM_ERR(CAM_JPEG, "Failed in Stop dev, rc=%d", rc);
+ return rc;
+ }
+
+ return rc;
+}
+
/* top state machine */
static struct cam_ctx_ops
cam_jpeg_ctx_state_machine[CAM_CTX_STATE_MAX] = {
@@ -85,6 +99,7 @@
.ioctl_ops = {
.release_dev = __cam_jpeg_ctx_release_dev_in_acquired,
.config_dev = __cam_jpeg_ctx_config_dev_in_acquired,
+ .stop_dev = __cam_jpeg_ctx_stop_dev_in_acquired,
},
.crm_ops = { },
.irq_ops = __cam_jpeg_ctx_handle_buf_done_in_acquired,
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
index df95100..e401549 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
@@ -80,11 +80,23 @@
dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;
+ mutex_lock(&g_jpeg_hw_mgr.hw_mgr_mutex);
+
+ p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0];
+
+ if (hw_mgr->device_in_use[dev_type][0] == false ||
+ p_cfg_req == NULL) {
+ CAM_ERR(CAM_JPEG, "irq for old request %d", rc);
+ mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
+ return -EINVAL;
+ }
+
irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_cb;
irq_cb.data = NULL;
irq_cb.b_set_cb = false;
if (!hw_mgr->devices[dev_type][0]->hw_ops.process_cmd) {
CAM_ERR(CAM_JPEG, "process_cmd null ");
+ mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
return -EINVAL;
}
rc = hw_mgr->devices[dev_type][0]->hw_ops.process_cmd(
@@ -93,6 +105,7 @@
&irq_cb, sizeof(irq_cb));
if (rc) {
CAM_ERR(CAM_JPEG, "CMD_SET_IRQ_CB failed %d", rc);
+ mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
return rc;
}
@@ -103,9 +116,7 @@
CAM_ERR(CAM_JPEG, "Failed to Deinit %d HW", dev_type);
}
- mutex_lock(&g_jpeg_hw_mgr.hw_mgr_mutex);
hw_mgr->device_in_use[dev_type][0] = false;
- p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0];
hw_mgr->dev_hw_cfg_args[dev_type][0] = NULL;
mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
@@ -167,7 +178,6 @@
list_add_tail(&p_cfg_req->list, &hw_mgr->free_req_list);
-
return rc;
}
@@ -319,8 +329,11 @@
return -EINVAL;
}
+ mutex_lock(&hw_mgr->hw_mgr_mutex);
+
if (list_empty(&hw_mgr->hw_config_req_list)) {
CAM_DBG(CAM_JPEG, "no available request");
+ mutex_unlock(&hw_mgr->hw_mgr_mutex);
rc = -EFAULT;
goto end;
}
@@ -329,11 +342,11 @@
struct cam_jpeg_hw_cfg_req, list);
if (!p_cfg_req) {
CAM_ERR(CAM_JPEG, "no request");
+ mutex_unlock(&hw_mgr->hw_mgr_mutex);
rc = -EFAULT;
goto end;
}
- mutex_lock(&hw_mgr->hw_mgr_mutex);
if (false == hw_mgr->device_in_use[p_cfg_req->dev_type][0]) {
hw_mgr->device_in_use[p_cfg_req->dev_type][0] = true;
hw_mgr->dev_hw_cfg_args[p_cfg_req->dev_type][0] = p_cfg_req;
@@ -344,6 +357,7 @@
rc = -EFAULT;
goto end;
}
+
mutex_unlock(&hw_mgr->hw_mgr_mutex);
config_args = (struct cam_hw_config_args *)&p_cfg_req->hw_cfg_args;
@@ -464,7 +478,7 @@
hw_mgr->devices[dev_type][0]->hw_priv,
NULL, 0);
if (rc) {
- CAM_ERR(CAM_JPEG, "Failed to apply the configs %d",
+ CAM_ERR(CAM_JPEG, "Failed to start hw %d",
rc);
goto end_callcb;
}
@@ -553,12 +567,12 @@
goto err_after_dq_free_list;
}
- mutex_unlock(&hw_mgr->hw_mgr_mutex);
task_data = (struct cam_jpeg_process_frame_work_data_t *)
task->payload;
if (!task_data) {
CAM_ERR(CAM_JPEG, "task_data is NULL");
+ mutex_unlock(&hw_mgr->hw_mgr_mutex);
rc = -EINVAL;
goto err_after_dq_free_list;
}
@@ -567,6 +581,7 @@
p_cfg_req->hw_cfg_args.num_hw_update_entries);
list_add_tail(&p_cfg_req->list, &hw_mgr->hw_config_req_list);
+ mutex_unlock(&hw_mgr->hw_mgr_mutex);
task_data->data = (void *)(int64_t)p_cfg_req->dev_type;
task_data->request_id = request_id;
@@ -719,6 +734,88 @@
return rc;
}
+static int cam_jpeg_mgr_flush(void *hw_mgr_priv,
+ struct cam_jpeg_hw_ctx_data *ctx_data)
+{
+ int rc = 0;
+ struct cam_jpeg_hw_mgr *hw_mgr = hw_mgr_priv;
+ uint32_t dev_type;
+ struct cam_jpeg_hw_cfg_req *p_cfg_req = NULL;
+ struct cam_jpeg_hw_cfg_req *cfg_req, *req_temp;
+
+ if (!hw_mgr || !ctx_data) {
+ CAM_ERR(CAM_JPEG, "Invalid args");
+ return -EINVAL;
+ }
+
+ dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;
+
+ p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0];
+ if (hw_mgr->device_in_use[dev_type][0] == true &&
+ p_cfg_req != NULL) {
+ if ((struct cam_jpeg_hw_ctx_data *)p_cfg_req->
+ hw_cfg_args.ctxt_to_hw_map == ctx_data) {
+ /* stop reset Unregister CB and deinit */
+ if (hw_mgr->devices[dev_type][0]->hw_ops.stop) {
+ rc = hw_mgr->devices[dev_type][0]->hw_ops.stop(
+ hw_mgr->devices[dev_type][0]->hw_priv,
+ NULL, 0);
+ if (rc)
+ CAM_ERR(CAM_JPEG, "stop fail %d", rc);
+ } else {
+ CAM_ERR(CAM_JPEG, "op stop null ");
+ rc = -EINVAL;
+ }
+ }
+
+ hw_mgr->device_in_use[dev_type][0] = false;
+ p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0];
+ hw_mgr->dev_hw_cfg_args[dev_type][0] = NULL;
+ }
+
+ list_for_each_entry_safe(cfg_req, req_temp,
+ &hw_mgr->hw_config_req_list, list) {
+ if ((struct cam_jpeg_hw_ctx_data *)cfg_req->
+ hw_cfg_args.ctxt_to_hw_map != ctx_data)
+ continue;
+
+ CAM_INFO(CAM_JPEG, "deleting req %pK", cfg_req);
+ list_del_init(&cfg_req->list);
+ }
+
+ return rc;
+}
+
+static int cam_jpeg_mgr_hw_stop(void *hw_mgr_priv, void *stop_hw_args)
+{
+ int rc;
+ struct cam_hw_stop_args *stop_args =
+ (struct cam_hw_stop_args *)stop_hw_args;
+ struct cam_jpeg_hw_mgr *hw_mgr = hw_mgr_priv;
+ struct cam_jpeg_hw_ctx_data *ctx_data = NULL;
+
+ if (!hw_mgr || !stop_args || !stop_args->ctxt_to_hw_map) {
+ CAM_ERR(CAM_JPEG, "Invalid args");
+ return -EINVAL;
+ }
+ mutex_lock(&hw_mgr->hw_mgr_mutex);
+
+ ctx_data = (struct cam_jpeg_hw_ctx_data *)stop_args->ctxt_to_hw_map;
+ if (!ctx_data->in_use) {
+ CAM_ERR(CAM_JPEG, "ctx is not in use");
+ mutex_unlock(&hw_mgr->hw_mgr_mutex);
+ return -EINVAL;
+ }
+
+ rc = cam_jpeg_mgr_flush(hw_mgr_priv, ctx_data);
+ if ((rc))
+ CAM_ERR(CAM_JPEG, "flush failed %d", rc);
+
+ mutex_unlock(&hw_mgr->hw_mgr_mutex);
+
+ return rc;
+}
+
static int cam_jpeg_mgr_release_hw(void *hw_mgr_priv, void *release_hw_args)
{
int rc;
@@ -1184,6 +1281,7 @@
hw_mgr_intf->hw_release = cam_jpeg_mgr_release_hw;
hw_mgr_intf->hw_prepare_update = cam_jpeg_mgr_prepare_hw_update;
hw_mgr_intf->hw_config = cam_jpeg_mgr_config_hw;
+ hw_mgr_intf->hw_stop = cam_jpeg_mgr_hw_stop;
mutex_init(&g_jpeg_hw_mgr.hw_mgr_mutex);
spin_lock_init(&g_jpeg_hw_mgr.hw_mgr_lock);
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/cam_jpeg_enc_hw_info_ver_4_2_0.h b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/cam_jpeg_enc_hw_info_ver_4_2_0.h
index 725af47..2ac4db6 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/cam_jpeg_enc_hw_info_ver_4_2_0.h
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/cam_jpeg_enc_hw_info_ver_4_2_0.h
@@ -19,6 +19,9 @@
#define CAM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK 0x10000000
#define CAM_JPEG_HW_IRQ_STATUS_RESET_ACK_SHIFT 0x0000000a
+#define CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_MASK 0x8000000
+#define CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_SHIFT 0x0000001b
+
#define CAM_JPEG_HW_IRQ_STATUS_BUS_ERROR_MASK 0x00000800
#define CAM_JPEG_HW_IRQ_STATUS_BUS_ERROR_SHIFT 0x0000000b
@@ -63,11 +66,13 @@
.int_mask_enable_all = 0xFFFFFFFF,
.hw_cmd_start = 0x00000001,
.reset_cmd = 0x00032093,
+ .hw_cmd_stop = 0x00000002,
},
.int_status = {
.framedone = CAM_JPEG_HW_MASK_COMP_FRAMEDONE,
.resetdone = CAM_JPEG_HW_MASK_COMP_RESET_ACK,
.iserror = CAM_JPEG_HW_MASK_COMP_ERR,
+ .stopdone = CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_MASK,
}
};
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c
index a7c4e06..934b911 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c
@@ -37,6 +37,8 @@
((jpeg_irq_status) & (hi)->int_status.resetdone)
#define CAM_JPEG_HW_IRQ_IS_ERR(jpeg_irq_status, hi) \
((jpeg_irq_status) & (hi)->int_status.iserror)
+#define CAM_JPEG_HW_IRQ_IS_STOP_DONE(jpeg_irq_status, hi) \
+ ((jpeg_irq_status) & (hi)->int_status.stopdone)
#define CAM_JPEG_ENC_RESET_TIMEOUT msecs_to_jiffies(500)
@@ -181,7 +183,9 @@
CAM_DBG(CAM_JPEG, "irq_num %d irq_status = %x , core_state %d",
irq_num, irq_status, core_info->core_state);
+
if (CAM_JPEG_HW_IRQ_IS_FRAME_DONE(irq_status, hw_info)) {
+ spin_lock(&jpeg_enc_dev->hw_lock);
if (core_info->core_state == CAM_JPEG_ENC_CORE_READY) {
encoded_size = cam_io_r_mb(mem_base +
core_info->jpeg_enc_hw_info->reg_offset.
@@ -191,22 +195,42 @@
encoded_size,
core_info->irq_cb.data);
} else {
- CAM_ERR(CAM_JPEG, "unexpected done");
+ CAM_ERR(CAM_JPEG, "unexpected done, no cb");
}
+ } else {
+ CAM_ERR(CAM_JPEG, "unexpected done irq");
}
-
core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY;
+ spin_unlock(&jpeg_enc_dev->hw_lock);
}
if (CAM_JPEG_HW_IRQ_IS_RESET_ACK(irq_status, hw_info)) {
+ spin_lock(&jpeg_enc_dev->hw_lock);
if (core_info->core_state == CAM_JPEG_ENC_CORE_RESETTING) {
core_info->core_state = CAM_JPEG_ENC_CORE_READY;
complete(&jpeg_enc_dev->hw_complete);
} else {
CAM_ERR(CAM_JPEG, "unexpected reset irq");
}
+ spin_unlock(&jpeg_enc_dev->hw_lock);
+ }
+ if (CAM_JPEG_HW_IRQ_IS_STOP_DONE(irq_status, hw_info)) {
+ spin_lock(&jpeg_enc_dev->hw_lock);
+ if (core_info->core_state == CAM_JPEG_ENC_CORE_ABORTING) {
+ core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY;
+ complete(&jpeg_enc_dev->hw_complete);
+ if (core_info->irq_cb.jpeg_hw_mgr_cb) {
+ core_info->irq_cb.jpeg_hw_mgr_cb(irq_status,
+ -1,
+ core_info->irq_cb.data);
+ }
+ } else {
+ CAM_ERR(CAM_JPEG, "unexpected abort irq");
+ }
+ spin_unlock(&jpeg_enc_dev->hw_lock);
}
/* Unexpected/unintended HW interrupt */
if (CAM_JPEG_HW_IRQ_IS_ERR(irq_status, hw_info)) {
+ spin_lock(&jpeg_enc_dev->hw_lock);
core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY;
CAM_ERR_RATE_LIMIT(CAM_JPEG,
"error irq_num %d irq_status = %x , core_state %d",
@@ -217,6 +241,7 @@
-1,
core_info->irq_cb.data);
}
+ spin_unlock(&jpeg_enc_dev->hw_lock);
}
return IRQ_HANDLED;
@@ -244,14 +269,18 @@
hw_info = core_info->jpeg_enc_hw_info;
mem_base = soc_info->reg_map[0].mem_base;
+ mutex_lock(&core_info->core_mutex);
+ spin_lock(&jpeg_enc_dev->hw_lock);
if (core_info->core_state == CAM_JPEG_ENC_CORE_RESETTING) {
CAM_ERR(CAM_JPEG, "alrady resetting");
+ spin_unlock(&jpeg_enc_dev->hw_lock);
+ mutex_unlock(&core_info->core_mutex);
return 0;
}
reinit_completion(&jpeg_enc_dev->hw_complete);
-
core_info->core_state = CAM_JPEG_ENC_CORE_RESETTING;
+ spin_unlock(&jpeg_enc_dev->hw_lock);
cam_io_w_mb(hw_info->reg_val.int_mask_disable_all,
mem_base + hw_info->reg_offset.int_mask);
@@ -269,6 +298,7 @@
core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY;
}
+ mutex_unlock(&core_info->core_mutex);
return 0;
}
@@ -303,6 +333,54 @@
return 0;
}
+int cam_jpeg_enc_stop_hw(void *data,
+ void *stop_args, uint32_t arg_size)
+{
+ struct cam_hw_info *jpeg_enc_dev = data;
+ struct cam_jpeg_enc_device_core_info *core_info = NULL;
+ struct cam_hw_soc_info *soc_info = NULL;
+ struct cam_jpeg_enc_device_hw_info *hw_info = NULL;
+ void __iomem *mem_base;
+ unsigned long rem_jiffies;
+
+ if (!jpeg_enc_dev) {
+ CAM_ERR(CAM_JPEG, "Invalid args");
+ return -EINVAL;
+ }
+ soc_info = &jpeg_enc_dev->soc_info;
+ core_info =
+ (struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev->
+ core_info;
+ hw_info = core_info->jpeg_enc_hw_info;
+ mem_base = soc_info->reg_map[0].mem_base;
+
+ mutex_unlock(&core_info->core_mutex);
+ spin_lock(&jpeg_enc_dev->hw_lock);
+ if (core_info->core_state == CAM_JPEG_ENC_CORE_ABORTING) {
+ CAM_ERR(CAM_JPEG, "alrady stopping");
+ spin_unlock(&jpeg_enc_dev->hw_lock);
+ mutex_unlock(&core_info->core_mutex);
+ return 0;
+ }
+
+ reinit_completion(&jpeg_enc_dev->hw_complete);
+ core_info->core_state = CAM_JPEG_ENC_CORE_ABORTING;
+ spin_unlock(&jpeg_enc_dev->hw_lock);
+
+ cam_io_w_mb(hw_info->reg_val.hw_cmd_stop,
+ mem_base + hw_info->reg_offset.hw_cmd);
+
+ rem_jiffies = wait_for_completion_timeout(&jpeg_enc_dev->hw_complete,
+ CAM_JPEG_ENC_RESET_TIMEOUT);
+ if (!rem_jiffies) {
+ CAM_ERR(CAM_JPEG, "error Reset Timeout");
+ core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY;
+ }
+
+ mutex_unlock(&core_info->core_mutex);
+ return 0;
+}
+
int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type,
void *cmd_args, uint32_t arg_size)
{
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h
index 4f5d625..5fa8f21 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h
@@ -37,12 +37,14 @@
uint32_t int_mask_enable_all;
uint32_t hw_cmd_start;
uint32_t reset_cmd;
+ uint32_t hw_cmd_stop;
};
struct cam_jpeg_enc_int_status {
uint32_t framedone;
uint32_t resetdone;
uint32_t iserror;
+ uint32_t stopdone;
};
struct cam_jpeg_enc_device_hw_info {
@@ -55,6 +57,7 @@
CAM_JPEG_ENC_CORE_NOT_READY,
CAM_JPEG_ENC_CORE_READY,
CAM_JPEG_ENC_CORE_RESETTING,
+ CAM_JPEG_ENC_CORE_ABORTING,
CAM_JPEG_ENC_CORE_STATE_MAX,
};
@@ -73,6 +76,8 @@
void *init_hw_args, uint32_t arg_size);
int cam_jpeg_enc_start_hw(void *device_priv,
void *start_hw_args, uint32_t arg_size);
+int cam_jpeg_enc_stop_hw(void *device_priv,
+ void *stop_hw_args, uint32_t arg_size);
int cam_jpeg_enc_reset_hw(void *device_priv,
void *reset_hw_args, uint32_t arg_size);
int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type,
diff --git a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c
index 735bd21..2180448 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c
@@ -139,6 +139,7 @@
jpeg_enc_dev_intf->hw_ops.init = cam_jpeg_enc_init_hw;
jpeg_enc_dev_intf->hw_ops.deinit = cam_jpeg_enc_deinit_hw;
jpeg_enc_dev_intf->hw_ops.start = cam_jpeg_enc_start_hw;
+ jpeg_enc_dev_intf->hw_ops.stop = cam_jpeg_enc_stop_hw;
jpeg_enc_dev_intf->hw_ops.reset = cam_jpeg_enc_reset_hw;
jpeg_enc_dev_intf->hw_ops.process_cmd = cam_jpeg_enc_process_cmd;
jpeg_enc_dev_intf->hw_type = CAM_JPEG_DEV_ENC;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_dev.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_dev.c
index 9eca4c7..d9b43a4 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_dev.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_ois/cam_ois_dev.c
@@ -259,6 +259,7 @@
return -ENOMEM;
o_ctrl->soc_info.pdev = pdev;
+ o_ctrl->pdev = pdev;
o_ctrl->soc_info.dev = &pdev->dev;
o_ctrl->soc_info.dev_name = pdev->name;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_res_mgr/cam_res_mgr.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_res_mgr/cam_res_mgr.c
index d588b24..bb3789b 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_res_mgr/cam_res_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_res_mgr/cam_res_mgr.c
@@ -51,6 +51,10 @@
kfree(flash_res);
}
mutex_unlock(&cam_res->flash_res_lock);
+
+ mutex_lock(&cam_res->clk_res_lock);
+ cam_res->shared_clk_ref_count = 0;
+ mutex_unlock(&cam_res->clk_res_lock);
}
void cam_res_mgr_led_trigger_register(const char *name, struct led_trigger **tp)
@@ -243,6 +247,9 @@
}
}
+ if (cam_res->shared_clk_ref_count > 1)
+ hold = true;
+
return hold;
}
@@ -258,11 +265,13 @@
mutex_lock(&cam_res->gpio_res_lock);
if (cam_res->pstatus == PINCTRL_STATUS_PUT) {
CAM_DBG(CAM_RES, "The shared pinctrl already been put");
+ mutex_unlock(&cam_res->gpio_res_lock);
return;
}
if (cam_res_mgr_shared_pinctrl_check_hold()) {
CAM_INFO(CAM_RES, "Need hold put this pinctrl");
+ mutex_unlock(&cam_res->gpio_res_lock);
return;
}
@@ -330,10 +339,12 @@
pinctrl_info = &cam_res->dt.pinctrl_info;
/*
- * If no gpio resource in gpio_res_list, it means
- * this device don't have shared gpio
+ * If no gpio resource in gpio_res_list, and
+ * no shared clk now, it means this device
+ * don't have shared gpio.
*/
- if (list_empty(&cam_res->gpio_res_list)) {
+ if (list_empty(&cam_res->gpio_res_list) &&
+ cam_res->shared_clk_ref_count < 1) {
ret = pinctrl_select_state(pinctrl_info->pinctrl,
pinctrl_info->gpio_state_suspend);
devm_pinctrl_put(pinctrl_info->pinctrl);
@@ -576,6 +587,20 @@
}
EXPORT_SYMBOL(cam_res_mgr_gpio_set_value);
+void cam_res_mgr_shared_clk_config(bool value)
+{
+ if (!cam_res)
+ return;
+
+ mutex_lock(&cam_res->clk_res_lock);
+ if (value)
+ cam_res->shared_clk_ref_count++;
+ else
+ cam_res->shared_clk_ref_count--;
+ mutex_unlock(&cam_res->clk_res_lock);
+}
+EXPORT_SYMBOL(cam_res_mgr_shared_clk_config);
+
static int cam_res_mgr_parse_dt(struct device *dev)
{
int rc = 0;
@@ -649,6 +674,7 @@
cam_res->dev = &pdev->dev;
mutex_init(&cam_res->flash_res_lock);
mutex_init(&cam_res->gpio_res_lock);
+ mutex_init(&cam_res->clk_res_lock);
rc = cam_res_mgr_parse_dt(&pdev->dev);
if (rc) {
@@ -659,6 +685,7 @@
cam_res->shared_gpio_enabled = true;
}
+ cam_res->shared_clk_ref_count = 0;
cam_res->pstatus = PINCTRL_STATUS_PUT;
INIT_LIST_HEAD(&cam_res->gpio_res_list);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_res_mgr/cam_res_mgr_api.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_res_mgr/cam_res_mgr_api.h
index 1c4c6c8..7fb13ba 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_res_mgr/cam_res_mgr_api.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_res_mgr/cam_res_mgr_api.h
@@ -134,4 +134,15 @@
*/
int cam_res_mgr_gpio_set_value(unsigned int gpio, int value);
+/**
+ * @brief: Config the shared clk ref count
+ *
+ * Config the shared clk ref count..
+ *
+ * @value : get or put the shared clk.
+ *
+ * @return None
+ */
+void cam_res_mgr_shared_clk_config(bool value);
+
#endif /* __CAM_RES_MGR_API_H__ */
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_res_mgr/cam_res_mgr_private.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_res_mgr/cam_res_mgr_private.h
index 4d46c8e..53a8778 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_res_mgr/cam_res_mgr_private.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_res_mgr/cam_res_mgr_private.h
@@ -96,6 +96,7 @@
* @flash_res_list : List head of the flash resource
* @gpio_res_lock : GPIO resource lock
* @flash_res_lock : Flash resource lock
+ * @clk_res_lock : Clk resource lock
*/
struct cam_res_mgr {
struct device *dev;
@@ -104,10 +105,13 @@
bool shared_gpio_enabled;
enum pinctrl_status pstatus;
+ uint shared_clk_ref_count;
+
struct list_head gpio_res_list;
struct list_head flash_res_list;
struct mutex gpio_res_lock;
struct mutex flash_res_lock;
+ struct mutex clk_res_lock;
};
#endif /* __CAM_RES_MGR_PRIVATE_H__ */
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
index b3de092..0a3878e 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
@@ -1235,6 +1235,9 @@
return -EINVAL;
}
+ if (soc_info->use_shared_clk)
+ cam_res_mgr_shared_clk_config(true);
+
ret = msm_camera_pinctrl_init(&(ctrl->pinctrl_info), ctrl->dev);
if (ret < 0) {
/* Some sensor subdev no pinctrl. */
@@ -1492,6 +1495,7 @@
(power_setting->delay * 1000) + 1000);
}
}
+
if (ctrl->cam_pinctrl_status) {
ret = pinctrl_select_state(
ctrl->pinctrl_info.pinctrl,
@@ -1502,6 +1506,10 @@
pinctrl_put(ctrl->pinctrl_info.pinctrl);
cam_res_mgr_shared_pinctrl_put();
}
+
+ if (soc_info->use_shared_clk)
+ cam_res_mgr_shared_clk_config(false);
+
ctrl->cam_pinctrl_status = 0;
cam_sensor_util_request_gpio_table(soc_info, 0);
@@ -1698,6 +1706,9 @@
cam_res_mgr_shared_pinctrl_put();
}
+ if (soc_info->use_shared_clk)
+ cam_res_mgr_shared_clk_config(false);
+
ctrl->cam_pinctrl_status = 0;
cam_sensor_util_request_gpio_table(soc_info, 0);
diff --git a/drivers/media/platform/msm/camera/cam_sync/cam_sync.c b/drivers/media/platform/msm/camera/cam_sync/cam_sync.c
index 2422016..e7dcbe7 100644
--- a/drivers/media/platform/msm/camera/cam_sync/cam_sync.c
+++ b/drivers/media/platform/msm/camera/cam_sync/cam_sync.c
@@ -230,6 +230,8 @@
spin_unlock_bh(
&sync_dev->row_spinlocks[
parent_info->sync_id]);
+ spin_unlock_bh(
+ &sync_dev->row_spinlocks[sync_obj]);
return rc;
}
}
@@ -344,24 +346,8 @@
int cam_sync_destroy(int32_t sync_obj)
{
- struct sync_table_row *row = NULL;
-
- if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0)
- return -EINVAL;
-
- spin_lock_bh(&sync_dev->row_spinlocks[sync_obj]);
- row = sync_dev->sync_table + sync_obj;
- if (row->state == CAM_SYNC_STATE_INVALID) {
- CAM_ERR(CAM_SYNC,
- "Error: accessing an uninitialized sync obj: idx = %d",
- sync_obj);
- spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);
- return -EINVAL;
- }
cam_sync_deinit_object(sync_dev->sync_table, sync_obj);
- spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);
-
return 0;
}
diff --git a/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h b/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h
index ba9bef4..e2a7fcb 100644
--- a/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h
+++ b/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h
@@ -55,6 +55,18 @@
};
/**
+ * enum sync_list_clean_type - Enum to indicate the type of list clean action
+ * to be peformed, i.e. specific sync ID or all list sync ids.
+ *
+ * @SYNC_CLEAN_ID : Specific object to be cleaned in the list
+ * @SYNC_CLEAN_ALL : Clean all objects in the list
+ */
+enum sync_list_clean_type {
+ SYNC_LIST_CLEAN_ID,
+ SYNC_LIST_CLEAN_ALL
+};
+
+/**
* struct sync_parent_info - Single node of information about a parent
* of a sync object, usually part of the parents linked list
*
diff --git a/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.c b/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.c
index f66b882..6aa7c23 100644
--- a/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.c
+++ b/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.c
@@ -145,7 +145,7 @@
if (!child_info) {
cam_sync_util_cleanup_children_list(
- &row->children_list);
+ &row->children_list, SYNC_LIST_CLEAN_ALL, 0);
return -ENOMEM;
}
@@ -160,9 +160,10 @@
parent_info = kzalloc(sizeof(*parent_info), GFP_ATOMIC);
if (!parent_info) {
cam_sync_util_cleanup_parents_list(
- &child_row->parents_list);
+ &child_row->parents_list,
+ SYNC_LIST_CLEAN_ALL, 0);
cam_sync_util_cleanup_children_list(
- &row->children_list);
+ &row->children_list, SYNC_LIST_CLEAN_ALL, 0);
spin_unlock_bh(&sync_dev->row_spinlocks[sync_objs[i]]);
return -ENOMEM;
}
@@ -197,27 +198,131 @@
int cam_sync_deinit_object(struct sync_table_row *table, uint32_t idx)
{
struct sync_table_row *row = table + idx;
- struct sync_child_info *child_info, *temp_child;
+ struct sync_child_info *child_info, *temp_child, *child_copy_info;
struct sync_callback_info *sync_cb, *temp_cb;
- struct sync_parent_info *parent_info, *temp_parent;
+ struct sync_parent_info *parent_info, *temp_parent, *parent_copy_info;
struct sync_user_payload *upayload_info, *temp_upayload;
+ struct sync_table_row *child_row = NULL, *parent_row = NULL;
+ struct list_head child_copy_list, parent_copy_list;
if (!table || idx <= 0 || idx >= CAM_SYNC_MAX_OBJS)
return -EINVAL;
- clear_bit(idx, sync_dev->bitmap);
- list_for_each_entry_safe(child_info, temp_child,
- &row->children_list, list) {
+ spin_lock_bh(&sync_dev->row_spinlocks[idx]);
+ if (row->state == CAM_SYNC_STATE_INVALID) {
+ CAM_ERR(CAM_SYNC,
+ "Error: accessing an uninitialized sync obj: idx = %d",
+ idx);
+ spin_unlock_bh(&sync_dev->row_spinlocks[idx]);
+ return -EINVAL;
+ }
+
+ /* Objects child and parent objects will be added into this list */
+ INIT_LIST_HEAD(&child_copy_list);
+ INIT_LIST_HEAD(&parent_copy_list);
+
+ list_for_each_entry_safe(child_info, temp_child, &row->children_list,
+ list) {
+ if (child_info->sync_id <= 0)
+ continue;
+
+ child_copy_info = kzalloc(sizeof(*child_copy_info), GFP_ATOMIC);
+ if (!child_copy_info) {
+ /* No free memory, clean up the child_copy_list */
+ while (!list_empty(&child_copy_list)) {
+ child_info = list_first_entry(&child_copy_list,
+ struct sync_child_info, list);
+ list_del_init(&child_info->list);
+ kfree(child_info);
+ }
+ spin_unlock_bh(&sync_dev->row_spinlocks[idx]);
+ goto deinit;
+ }
+ child_copy_info->sync_id = child_info->sync_id;
+ list_add_tail(&child_copy_info->list, &child_copy_list);
+ }
+
+ list_for_each_entry_safe(parent_info, temp_parent, &row->parents_list,
+ list) {
+ if (parent_info->sync_id <= 0)
+ continue;
+ parent_copy_info = kzalloc(sizeof(*parent_copy_info),
+ GFP_ATOMIC);
+ if (!parent_copy_info) {
+ /* No free memory, clean up the parent_copy_list */
+ while (!list_empty(&parent_copy_list)) {
+ parent_info = list_first_entry(
+ &parent_copy_list,
+ struct sync_parent_info, list);
+ list_del_init(&parent_info->list);
+ kfree(parent_info);
+ }
+ /* No free memory, clean up the child_copy_list */
+ while (!list_empty(&child_copy_list)) {
+ child_info = list_first_entry(&child_copy_list,
+ struct sync_child_info, list);
+ list_del_init(&child_info->list);
+ kfree(child_info);
+ }
+ spin_unlock_bh(&sync_dev->row_spinlocks[idx]);
+ goto deinit;
+ }
+ parent_copy_info->sync_id = parent_info->sync_id;
+ list_add_tail(&parent_copy_info->list, &parent_copy_list);
+ }
+
+ spin_unlock_bh(&sync_dev->row_spinlocks[idx]);
+ /* Cleanup the child to parent link from child list*/
+ while (!list_empty(&child_copy_list)) {
+ child_info = list_first_entry(&child_copy_list,
+ struct sync_child_info, list);
+ child_row = sync_dev->sync_table + child_info->sync_id;
+ spin_lock_bh(&sync_dev->row_spinlocks[child_info->sync_id]);
+ if (child_row->state == CAM_SYNC_STATE_INVALID) {
+ spin_unlock_bh(&sync_dev->row_spinlocks[
+ child_info->sync_id]);
+ list_del_init(&child_info->list);
+ kfree(child_info);
+ continue;
+ }
+
+ cam_sync_util_cleanup_parents_list(&child_row->parents_list,
+ SYNC_LIST_CLEAN_ID, idx);
+
+ spin_unlock_bh(&sync_dev->row_spinlocks[child_info->sync_id]);
list_del_init(&child_info->list);
kfree(child_info);
}
- list_for_each_entry_safe(parent_info, temp_parent,
- &row->parents_list, list) {
+ /* Cleanup the parent to child link */
+ while (!list_empty(&parent_copy_list)) {
+ parent_info = list_first_entry(&parent_copy_list,
+ struct sync_parent_info, list);
+ parent_row = sync_dev->sync_table + parent_info->sync_id;
+ spin_lock_bh(&sync_dev->row_spinlocks[parent_info->sync_id]);
+ if (parent_row->state == CAM_SYNC_STATE_INVALID) {
+ spin_unlock_bh(&sync_dev->row_spinlocks[
+ parent_info->sync_id]);
+ list_del_init(&parent_info->list);
+ kfree(parent_info);
+ continue;
+ }
+
+ cam_sync_util_cleanup_children_list(&parent_row->children_list,
+ SYNC_LIST_CLEAN_ID, idx);
+
+ spin_unlock_bh(&sync_dev->row_spinlocks[parent_info->sync_id]);
list_del_init(&parent_info->list);
kfree(parent_info);
}
+deinit:
+ spin_lock_bh(&sync_dev->row_spinlocks[idx]);
+ cam_sync_util_cleanup_children_list(&row->children_list,
+ SYNC_LIST_CLEAN_ALL, 0);
+ cam_sync_util_cleanup_parents_list(&row->parents_list,
+ SYNC_LIST_CLEAN_ALL, 0);
+
list_for_each_entry_safe(upayload_info, temp_upayload,
&row->user_payload_list, list) {
list_del_init(&upayload_info->list);
@@ -232,6 +337,8 @@
row->state = CAM_SYNC_STATE_INVALID;
memset(row, 0, sizeof(*row));
+ clear_bit(idx, sync_dev->bitmap);
+ spin_unlock_bh(&sync_dev->row_spinlocks[idx]);
return 0;
}
@@ -350,26 +457,48 @@
return result;
}
-void cam_sync_util_cleanup_children_list(struct list_head *list_to_clean)
+void cam_sync_util_cleanup_children_list(struct list_head *list_to_clean,
+ uint32_t list_clean_type, uint32_t sync_obj)
{
struct sync_child_info *child_info = NULL;
struct sync_child_info *temp_child_info = NULL;
+ uint32_t curr_sync_obj;
list_for_each_entry_safe(child_info,
temp_child_info, list_to_clean, list) {
+ if ((list_clean_type == SYNC_LIST_CLEAN_ID) &&
+ (child_info->sync_id != sync_obj))
+ continue;
+
+ curr_sync_obj = child_info->sync_id;
list_del_init(&child_info->list);
kfree(child_info);
+
+ if ((list_clean_type == SYNC_LIST_CLEAN_ID) &&
+ (curr_sync_obj == sync_obj))
+ break;
}
}
-void cam_sync_util_cleanup_parents_list(struct list_head *list_to_clean)
+void cam_sync_util_cleanup_parents_list(struct list_head *list_to_clean,
+ uint32_t list_clean_type, uint32_t sync_obj)
{
struct sync_parent_info *parent_info = NULL;
struct sync_parent_info *temp_parent_info = NULL;
+ uint32_t curr_sync_obj;
list_for_each_entry_safe(parent_info,
temp_parent_info, list_to_clean, list) {
+ if ((list_clean_type == SYNC_LIST_CLEAN_ID) &&
+ (parent_info->sync_id != sync_obj))
+ continue;
+
+ curr_sync_obj = parent_info->sync_id;
list_del_init(&parent_info->list);
kfree(parent_info);
+
+ if ((list_clean_type == SYNC_LIST_CLEAN_ID) &&
+ (curr_sync_obj == sync_obj))
+ break;
}
}
diff --git a/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.h b/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.h
index 8b60ce1..1c5c4bf 100644
--- a/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.h
+++ b/drivers/media/platform/msm/camera/cam_sync/cam_sync_util.h
@@ -141,17 +141,25 @@
/**
* @brief: Function to clean up the children of a sync object
* @param list_to_clean : List to clean up
+ * @list_clean_type : Clean specific object or clean all objects
+ * @sync_obj : Sync object to be clean if list clean type is
+ * SYNC_LIST_CLEAN_ID
*
* @return None
*/
-void cam_sync_util_cleanup_children_list(struct list_head *list_to_clean);
+void cam_sync_util_cleanup_children_list(struct list_head *list_to_clean,
+ uint32_t list_clean_type, uint32_t sync_obj);
/**
* @brief: Function to clean up the parents of a sync object
* @param list_to_clean : List to clean up
+ * @list_clean_type : Clean specific object or clean all objects
+ * @sync_obj : Sync object to be clean if list clean type is
+ * SYNC_LIST_CLEAN_ID
*
* @return None
*/
-void cam_sync_util_cleanup_parents_list(struct list_head *list_to_clean);
+void cam_sync_util_cleanup_parents_list(struct list_head *list_to_clean,
+ uint32_t list_clean_type, uint32_t sync_obj);
#endif /* __CAM_SYNC_UTIL_H__ */
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c
index 611c4e9..07fb944 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.c
@@ -410,6 +410,13 @@
of_node = soc_info->dev->of_node;
+ if (!of_property_read_bool(of_node, "use-shared-clk")) {
+ CAM_DBG(CAM_UTIL, "No shared clk parameter defined");
+ soc_info->use_shared_clk = false;
+ } else {
+ soc_info->use_shared_clk = true;
+ }
+
count = of_property_count_strings(of_node, "clock-names");
CAM_DBG(CAM_UTIL, "count = %d", count);
diff --git a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h
index 5123ec4..4a87d50 100644
--- a/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h
+++ b/drivers/media/platform/msm/camera/cam_utils/cam_soc_util.h
@@ -180,6 +180,7 @@
struct regulator *rgltr[CAM_SOC_MAX_REGULATOR];
uint32_t rgltr_delay[CAM_SOC_MAX_REGULATOR];
+ uint32_t use_shared_clk;
uint32_t num_clk;
const char *clk_name[CAM_SOC_MAX_CLK];
struct clk *clk[CAM_SOC_MAX_CLK];