summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLakshmi Narayana Kalavala <lkalaval@codeaurora.org>2016-01-15 17:41:59 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:18:16 -0700
commit1b668751e420df01d4c834dd32db46c4324173a7 (patch)
tree48b24250fa3c77af4d2e2a8b49029ff291ec8462
parentb29045982380abc527aba9086b284b9bfc0ff187 (diff)
msm: camera: support dynamic query for ahb vote
Few of the camera modules need to run ahb at higher voltages like nominal and turbo. Hence add support to query the voltage corner corresponding the core clocks and vote for the corresponding ahb voltage. Change-Id: I75a0ac84d32180f0bd5ce892f35515510e4e2e5f Signed-off-by: Lakshmi Narayana Kalavala <lkalaval@codeaurora.org>
-rw-r--r--drivers/media/platform/msm/camera_v2/common/cam_hw_ops.c171
-rw-r--r--drivers/media/platform/msm/camera_v2/common/cam_hw_ops.h18
-rw-r--r--drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c13
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp47.c22
-rw-r--r--drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c16
-rw-r--r--drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c13
-rw-r--r--drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c20
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c11
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c11
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c13
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c31
11 files changed, 217 insertions, 122 deletions
diff --git a/drivers/media/platform/msm/camera_v2/common/cam_hw_ops.c b/drivers/media/platform/msm/camera_v2/common/cam_hw_ops.c
index e0691a27d856..e8c5cbf2979c 100644
--- a/drivers/media/platform/msm/camera_v2/common/cam_hw_ops.c
+++ b/drivers/media/platform/msm/camera_v2/common/cam_hw_ops.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -16,8 +16,16 @@
#include <linux/msm-bus.h>
#include <linux/msm-bus-board.h>
#include <linux/of_platform.h>
+#include <linux/pm_opp.h>
+#include <linux/regulator/rpm-smd-regulator.h>
#include "cam_hw_ops.h"
+#ifdef CONFIG_CAM_AHB_DBG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+#endif
+
struct cam_ahb_client {
enum cam_ahb_clk_vote vote;
};
@@ -40,18 +48,6 @@ struct cam_ahb_client_data {
struct mutex lock;
};
-/* Note: The mask array defined here should match
- * the order of strings and number of strings
- * in dtsi bus-vectors
- */
-
-static enum cam_ahb_clk_vote mask[] = {
- CAMERA_AHB_SUSPEND_VOTE,
- CAMERA_AHB_SVS_VOTE,
- CAMERA_AHB_NOMINAL_VOTE,
- CAMERA_AHB_TURBO_VOTE
-};
-
static struct cam_ahb_client_data data;
int get_vector_index(char *name)
@@ -96,7 +92,7 @@ int cam_ahb_clk_init(struct platform_device *pdev)
return -EINVAL;
}
- pr_debug("number of bus vectors: %d\n", data.cnt);
+ CDBG("number of bus vectors: %d\n", data.cnt);
data.vectors = devm_kzalloc(&pdev->dev,
sizeof(struct cam_bus_vector) * cnt,
@@ -107,7 +103,7 @@ int cam_ahb_clk_init(struct platform_device *pdev)
for (i = 0; i < data.cnt; i++) {
rc = of_property_read_string_index(of_node, "bus-vectors",
i, &(data.vectors[i].name));
- pr_debug("dbg: names[%d] = %s\n", i, data.vectors[i].name);
+ CDBG("dbg: names[%d] = %s\n", i, data.vectors[i].name);
if (rc < 0) {
pr_err("failed\n");
rc = -EINVAL;
@@ -160,7 +156,7 @@ int cam_ahb_clk_init(struct platform_device *pdev)
.num_paths = 1,
.vectors = &data.paths[i],
};
- pr_debug("dbg: votes[%d] = %u\n", i, data.votes[i]);
+ CDBG("dbg: votes[%d] = %u\n", i, data.votes[i]);
}
*data.pbus_data = (struct msm_bus_scale_pdata) {
@@ -187,12 +183,12 @@ int cam_ahb_clk_init(struct platform_device *pdev)
/* request for svs in init */
msm_bus_scale_client_update_request(data.ahb_client,
index);
- data.ahb_clk_state = CAMERA_AHB_SUSPEND_VOTE;
+ data.ahb_clk_state = CAM_AHB_SUSPEND_VOTE;
data.probe_done = TRUE;
mutex_init(&data.lock);
- pr_debug("dbg, done registering ahb votes\n");
- pr_debug("dbg, clk state :%u, probe :%d\n",
+ CDBG("dbg, done registering ahb votes\n");
+ CDBG("dbg, clk state :%u, probe :%d\n",
data.ahb_clk_state, data.probe_done);
return rc;
@@ -217,57 +213,126 @@ err1:
}
EXPORT_SYMBOL(cam_ahb_clk_init);
-int cam_config_ahb_clk(enum cam_ahb_clk_client id, enum cam_ahb_clk_vote vote)
+int cam_consolidate_ahb_vote(enum cam_ahb_clk_client id,
+ enum cam_ahb_clk_vote vote)
{
- int i = 0, n = 0;
- u32 final_vote = 0;
-
- if (data.probe_done != TRUE) {
- pr_err("ahb init is not done yet\n");
- return -EINVAL;
- }
-
- if (vote > CAMERA_AHB_TURBO_VOTE || id >= CAM_AHB_CLIENT_MAX) {
- pr_err("err: invalid argument\n");
- return -EINVAL;
- }
-
- pr_debug("dbg: id :%u, vote : %u\n", id, vote);
- data.clients[id].vote = vote;
+ int i = 0;
+ u32 max = 0;
+ CDBG("dbg: id :%u, vote : 0x%x\n", id, vote);
mutex_lock(&data.lock);
+ data.clients[id].vote = vote;
if (vote == data.ahb_clk_state) {
- pr_debug("dbg: already at desired vote\n");
+ CDBG("dbg: already at desired vote\n");
mutex_unlock(&data.lock);
return 0;
}
- /* oring all the client votes */
- for (i = 0; i < CAM_AHB_CLIENT_MAX; i++)
- final_vote |= data.clients[i].vote;
-
- pr_debug("dbg: final vote : %u\n", final_vote);
- /* find the max client vote */
- for (n = data.cnt - 1; n >= 0; n--) {
- if (!(final_vote & mask[n]))
- continue;
- else
- break;
+ for (i = 0; i < CAM_AHB_CLIENT_MAX; i++) {
+ if (data.clients[i].vote > max)
+ max = data.clients[i].vote;
}
- if (n >= 0) {
- if (mask[n] != data.ahb_clk_state) {
- msm_bus_scale_client_update_request(data.ahb_client, n);
- data.ahb_clk_state = mask[n];
- pr_debug("dbg: state : %u, vote : %d\n",
- data.ahb_clk_state, n);
+ CDBG("dbg: max vote : %u\n", max);
+ if (max >= 0) {
+ if (max != data.ahb_clk_state) {
+ msm_bus_scale_client_update_request(data.ahb_client,
+ max);
+ data.ahb_clk_state = max;
+ CDBG("dbg: state : %u, vector : %d\n",
+ data.ahb_clk_state, max);
}
} else {
pr_err("err: no bus vector found\n");
+ mutex_unlock(&data.lock);
return -EINVAL;
}
mutex_unlock(&data.lock);
return 0;
}
+
+static int cam_ahb_get_voltage_level(unsigned int corner)
+{
+ switch (corner) {
+ case RPM_REGULATOR_CORNER_NONE:
+ return CAM_AHB_SUSPEND_VOTE;
+
+ case RPM_REGULATOR_CORNER_SVS_KRAIT:
+ case RPM_REGULATOR_CORNER_SVS_SOC:
+ return CAM_AHB_SVS_VOTE;
+
+ case RPM_REGULATOR_CORNER_NORMAL:
+ return CAM_AHB_NOMINAL_VOTE;
+
+ case RPM_REGULATOR_CORNER_SUPER_TURBO:
+ return CAM_AHB_TURBO_VOTE;
+
+ case RPM_REGULATOR_CORNER_TURBO:
+ case RPM_REGULATOR_CORNER_RETENTION:
+ default:
+ return -EINVAL;
+ }
+}
+
+int cam_config_ahb_clk(struct device *dev, unsigned long freq,
+ enum cam_ahb_clk_client id, enum cam_ahb_clk_vote vote)
+{
+ struct dev_pm_opp *opp;
+ unsigned int corner;
+ enum cam_ahb_clk_vote dyn_vote = vote;
+ int rc = -EINVAL;
+
+ if (id >= CAM_AHB_CLIENT_MAX) {
+ pr_err("err: invalid argument\n");
+ return -EINVAL;
+ }
+
+ if (data.probe_done != TRUE) {
+ pr_err("ahb init is not done yet\n");
+ return -EINVAL;
+ }
+
+ CDBG("dbg: id :%u, vote : 0x%x\n", id, vote);
+ switch (dyn_vote) {
+ case CAM_AHB_SUSPEND_VOTE:
+ case CAM_AHB_SVS_VOTE:
+ case CAM_AHB_NOMINAL_VOTE:
+ case CAM_AHB_TURBO_VOTE:
+ break;
+ case CAM_AHB_DYNAMIC_VOTE:
+ if (!dev) {
+ pr_err("device is NULL\n");
+ return -EINVAL;
+ }
+ opp = dev_pm_opp_find_freq_exact(dev, freq, true);
+ if (IS_ERR(opp)) {
+ pr_err("Error on OPP freq :%ld\n", freq);
+ return -EINVAL;
+ }
+ corner = dev_pm_opp_get_voltage(opp);
+ if (corner == 0) {
+ pr_err("Bad voltage corner for OPP freq :%ld\n", freq);
+ return -EINVAL;
+ }
+ dyn_vote = cam_ahb_get_voltage_level(corner);
+ if (dyn_vote < 0) {
+ pr_err("Bad vote requested\n");
+ return -EINVAL;
+ }
+ break;
+ default:
+ pr_err("err: invalid vote argument\n");
+ return -EINVAL;
+ }
+
+ rc = cam_consolidate_ahb_vote(id, dyn_vote);
+ if (rc < 0) {
+ pr_err("%s: failed to vote for AHB\n", __func__);
+ goto end;
+ }
+
+end:
+ return rc;
+}
EXPORT_SYMBOL(cam_config_ahb_clk);
diff --git a/drivers/media/platform/msm/camera_v2/common/cam_hw_ops.h b/drivers/media/platform/msm/camera_v2/common/cam_hw_ops.h
index 2fe35da6b04c..015c2099603c 100644
--- a/drivers/media/platform/msm/camera_v2/common/cam_hw_ops.h
+++ b/drivers/media/platform/msm/camera_v2/common/cam_hw_ops.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -14,10 +14,11 @@ enum cam_ahb_clk_vote {
/* need to update the voting requests
* according to dtsi entries.
*/
- CAMERA_AHB_SUSPEND_VOTE = 0x01,
- CAMERA_AHB_SVS_VOTE = 0x02,
- CAMERA_AHB_NOMINAL_VOTE = 0x04,
- CAMERA_AHB_TURBO_VOTE = 0x08,
+ CAM_AHB_SUSPEND_VOTE = 0x0,
+ CAM_AHB_SVS_VOTE = 0x01,
+ CAM_AHB_NOMINAL_VOTE = 0x02,
+ CAM_AHB_TURBO_VOTE = 0x03,
+ CAM_AHB_DYNAMIC_VOTE = 0xFF,
};
enum cam_ahb_clk_client {
@@ -25,13 +26,14 @@ enum cam_ahb_clk_client {
CAM_AHB_CLIENT_CSID,
CAM_AHB_CLIENT_CCI,
CAM_AHB_CLIENT_ISPIF,
- CAM_AHB_CLIENT_VFE,
+ CAM_AHB_CLIENT_VFE0,
+ CAM_AHB_CLIENT_VFE1,
CAM_AHB_CLIENT_CPP,
CAM_AHB_CLIENT_FD,
CAM_AHB_CLIENT_JPEG,
CAM_AHB_CLIENT_MAX
};
-int cam_config_ahb_clk(enum cam_ahb_clk_client id,
- enum cam_ahb_clk_vote vote);
+int cam_config_ahb_clk(struct device *dev, unsigned long freq,
+ enum cam_ahb_clk_client id, enum cam_ahb_clk_vote vote);
int cam_ahb_clk_init(struct platform_device *pdev);
diff --git a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c
index df803fe82bca..1ac59acc06ee 100644
--- a/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c
+++ b/drivers/media/platform/msm/camera_v2/fd/msm_fd_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 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
@@ -384,14 +384,17 @@ static int msm_fd_open(struct file *file)
goto error_stats_vmalloc;
}
- ret = cam_config_ahb_clk(CAM_AHB_CLIENT_FD, CAMERA_AHB_SVS_VOTE);
+ ret = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_FD,
+ CAM_AHB_SVS_VOTE);
if (ret < 0) {
pr_err("%s: failed to vote for AHB\n", __func__);
- return ret;
+ goto error_ahb_config;
}
return 0;
+error_ahb_config:
+ vfree(ctx->stats);
error_stats_vmalloc:
vb2_queue_release(&ctx->vb2_q);
error_vb2_queue_init:
@@ -421,8 +424,8 @@ static int msm_fd_release(struct file *file)
kfree(ctx);
- if (cam_config_ahb_clk(CAM_AHB_CLIENT_FD,
- CAMERA_AHB_SUSPEND_VOTE) < 0)
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_FD,
+ CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__);
return 0;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
index b217186fe1c5..5d06fa348af2 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2016, 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
@@ -169,8 +169,14 @@ static int32_t msm_vfe47_init_dt_parms(struct vfe_device *vfe_dev,
static int msm_vfe47_init_hardware(struct vfe_device *vfe_dev)
{
int rc = -1;
+ enum cam_ahb_clk_client id;
- rc = cam_config_ahb_clk(CAM_AHB_CLIENT_VFE, CAMERA_AHB_SVS_VOTE);
+ if (vfe_dev->pdev->id == 0)
+ id = CAM_AHB_CLIENT_VFE0;
+ else
+ id = CAM_AHB_CLIENT_VFE1;
+
+ rc = cam_config_ahb_clk(NULL, 0, id, CAM_AHB_SVS_VOTE);
if (rc < 0) {
pr_err("%s: failed to vote for AHB\n", __func__);
goto ahb_vote_fail;
@@ -317,13 +323,16 @@ camss_vdd_regulator_failed:
vfe_dev->fs_vfe = NULL;
msm_isp_deinit_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id);
bus_scale_register_failed:
- cam_config_ahb_clk(CAM_AHB_CLIENT_VFE, CAMERA_AHB_SUSPEND_VOTE);
+ if (cam_config_ahb_clk(NULL, 0, id, CAM_AHB_SUSPEND_VOTE) < 0)
+ pr_err("%s: failed to remove vote for AHB\n", __func__);
ahb_vote_fail:
return rc;
}
static void msm_vfe47_release_hardware(struct vfe_device *vfe_dev)
{
+ enum cam_ahb_clk_client id;
+
/* when closing node, disable all irq */
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x5C);
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x60);
@@ -357,7 +366,12 @@ static void msm_vfe47_release_hardware(struct vfe_device *vfe_dev)
}
msm_isp_deinit_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id);
- if (cam_config_ahb_clk(CAM_AHB_CLIENT_VFE, CAMERA_AHB_SUSPEND_VOTE) < 0)
+ if (vfe_dev->pdev->id == 0)
+ id = CAM_AHB_CLIENT_VFE0;
+ else
+ id = CAM_AHB_CLIENT_VFE1;
+
+ if (cam_config_ahb_clk(NULL, 0, id, CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to vote for AHB\n", __func__);
}
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
index 9d0f2b930696..327cfa07f31c 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2016, 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
@@ -1354,7 +1354,8 @@ static int msm_ispif_init(struct ispif_device *ispif,
goto error_irq;
}
- rc = cam_config_ahb_clk(CAM_AHB_CLIENT_ISPIF, CAMERA_AHB_SVS_VOTE);
+ rc = cam_config_ahb_clk(NULL, 0,
+ CAM_AHB_CLIENT_ISPIF, CAM_AHB_SVS_VOTE);
if (rc < 0) {
pr_err("%s: failed to vote for AHB\n", __func__);
goto ahb_vote_fail;
@@ -1372,10 +1373,9 @@ static int msm_ispif_init(struct ispif_device *ispif,
}
error_ahb:
- rc = cam_config_ahb_clk(CAM_AHB_CLIENT_ISPIF,
- CAMERA_AHB_SUSPEND_VOTE);
- if (rc < 0)
- pr_err("%s: failed to vote for AHB\n", __func__);
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_ISPIF,
+ CAM_AHB_SUSPEND_VOTE) < 0)
+ pr_err("%s: failed to remove vote for AHB\n", __func__);
ahb_vote_fail:
free_irq(ispif->irq->start, ispif);
error_irq:
@@ -1413,8 +1413,8 @@ static void msm_ispif_release(struct ispif_device *ispif)
ispif->ispif_state = ISPIF_POWER_DOWN;
- if (cam_config_ahb_clk(CAM_AHB_CLIENT_ISPIF,
- CAMERA_AHB_SUSPEND_VOTE) < 0)
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_ISPIF,
+ CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__);
}
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
index 034ba79ab5c8..73486e72a19d 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 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
@@ -734,7 +734,8 @@ int __msm_jpeg_open(struct msm_jpeg_device *pgmn_dev)
mutex_unlock(&pgmn_dev->lock);
- rc = cam_config_ahb_clk(CAM_AHB_CLIENT_JPEG, CAMERA_AHB_SVS_VOTE);
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_JPEG,
+ CAM_AHB_SVS_VOTE);
if (rc < 0) {
pr_err("%s: failed to vote for AHB\n", __func__);
return rc;
@@ -771,8 +772,8 @@ int __msm_jpeg_open(struct msm_jpeg_device *pgmn_dev)
return rc;
platform_init_fail:
- if (cam_config_ahb_clk(CAM_AHB_CLIENT_JPEG,
- CAMERA_AHB_SUSPEND_VOTE) < 0)
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_JPEG,
+ CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__);
return rc;
}
@@ -805,8 +806,8 @@ int __msm_jpeg_release(struct msm_jpeg_device *pgmn_dev)
JPEG_DBG("%s:%d]\n", __func__, __LINE__);
- if (cam_config_ahb_clk(CAM_AHB_CLIENT_JPEG,
- CAMERA_AHB_SUSPEND_VOTE) < 0)
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_JPEG,
+ CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__);
return 0;
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
index 6b2d5c5bf515..09d02b351367 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/msm_jpeg_dma_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -502,18 +502,20 @@ static int msm_jpegdma_open(struct file *file)
ret = PTR_ERR(ctx->m2m_ctx);
goto error_m2m_init;
}
- init_completion(&ctx->completion);
- complete_all(&ctx->completion);
- dev_dbg(ctx->jdma_device->dev, "Jpeg v4l2 dma open success\n");
-
- ret = cam_config_ahb_clk(CAM_AHB_CLIENT_JPEG, CAMERA_AHB_SVS_VOTE);
+ ret = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_JPEG,
+ CAM_AHB_SVS_VOTE);
if (ret < 0) {
pr_err("%s: failed to vote for AHB\n", __func__);
- goto error_m2m_init;
+ goto ahb_vote_fail;
}
+ init_completion(&ctx->completion);
+ complete_all(&ctx->completion);
+ dev_dbg(ctx->jdma_device->dev, "Jpeg v4l2 dma open success\n");
return 0;
+ahb_vote_fail:
+ v4l2_m2m_ctx_release(ctx->m2m_ctx);
error_m2m_init:
v4l2_fh_del(&ctx->fh);
v4l2_fh_exit(&ctx->fh);
@@ -536,8 +538,8 @@ static int msm_jpegdma_release(struct file *file)
v4l2_fh_exit(&ctx->fh);
kfree(ctx);
- if (cam_config_ahb_clk(CAM_AHB_CLIENT_JPEG,
- CAMERA_AHB_SUSPEND_VOTE) < 0)
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_JPEG,
+ CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__);
return 0;
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index 439c9bdba1c7..16568c655397 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -947,7 +947,8 @@ static int cpp_init_hardware(struct cpp_device *cpp_dev)
uint32_t msm_micro_iface_idx;
uint32_t vbif_version;
- rc = cam_config_ahb_clk(CAM_AHB_CLIENT_CPP, CAMERA_AHB_SVS_VOTE);
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CPP,
+ CAM_AHB_SVS_VOTE);
if (rc < 0) {
pr_err("%s: failed to vote for AHB\n", __func__);
goto ahb_vote_fail;
@@ -1212,7 +1213,8 @@ fs_mmagic_failed:
else
msm_isp_deinit_bandwidth_mgr(ISP_CPP);
bus_scale_register_failed:
- if (cam_config_ahb_clk(CAM_AHB_CLIENT_CPP, CAMERA_AHB_SUSPEND_VOTE) < 0)
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CPP,
+ CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__);
ahb_vote_fail:
return rc;
@@ -1265,9 +1267,8 @@ static void cpp_release_hardware(struct cpp_device *cpp_dev)
else
msm_isp_deinit_bandwidth_mgr(ISP_CPP);
- rc = cam_config_ahb_clk(CAM_AHB_CLIENT_CPP,
- CAMERA_AHB_SUSPEND_VOTE);
- if (rc < 0)
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CPP,
+ CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__);
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
index bb5942563eac..5b875527e15d 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
@@ -1262,7 +1262,8 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd,
return rc;
}
- rc = cam_config_ahb_clk(CAM_AHB_CLIENT_CCI, CAMERA_AHB_SVS_VOTE);
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CCI,
+ CAM_AHB_SVS_VOTE);
if (rc < 0) {
pr_err("%s: failed to vote for AHB\n", __func__);
return rc;
@@ -1422,8 +1423,8 @@ clk_enable_failed:
cci_dev->cci_gpio_tbl_size, 0);
request_gpio_failed:
cci_dev->ref_count--;
- if (cam_config_ahb_clk(CAM_AHB_CLIENT_CCI,
- CAMERA_AHB_SUSPEND_VOTE) < 0)
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CCI,
+ CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__);
return rc;
}
@@ -1480,8 +1481,8 @@ static int32_t msm_cci_release(struct v4l2_subdev *sd)
cci_dev->cci_clk_src = 0;
ahb_vote_suspend:
- if (cam_config_ahb_clk(CAM_AHB_CLIENT_CCI,
- CAMERA_AHB_SUSPEND_VOTE) < 0)
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CCI,
+ CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__);
return rc;
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
index b09f392481c2..b2ebafdab30d 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2016, 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
@@ -457,7 +457,8 @@ static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version)
return -EINVAL;
}
- rc = cam_config_ahb_clk(CAM_AHB_CLIENT_CSID, CAMERA_AHB_SVS_VOTE);
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,
+ CAM_AHB_SVS_VOTE);
if (rc < 0) {
pr_err("%s: failed to vote for AHB\n", __func__);
return rc;
@@ -591,8 +592,8 @@ top_vreg_config_failed:
iounmap(csid_dev->base);
csid_dev->base = NULL;
ioremap_fail:
- if (cam_config_ahb_clk(CAM_AHB_CLIENT_CSID,
- CAMERA_AHB_SUSPEND_VOTE) < 0)
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,
+ CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote from AHB\n", __func__);
return rc;
}
@@ -662,8 +663,8 @@ static int msm_csid_release(struct csid_device *csid_dev)
csid_dev->base = NULL;
csid_dev->csid_state = CSID_POWER_DOWN;
- if (cam_config_ahb_clk(CAM_AHB_CLIENT_CSID,
- CAMERA_AHB_SUSPEND_VOTE) < 0)
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,
+ CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote from AHB\n", __func__);
return 0;
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
index 69b3b3c2398d..a3b963e4b262 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2016, 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,8 +707,10 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
}
CDBG("%s:%d called\n", __func__, __LINE__);
- rc = cam_config_ahb_clk(CAM_AHB_CLIENT_CSIPHY, CAMERA_AHB_SVS_VOTE);
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
+ CAM_AHB_SVS_VOTE);
if (rc < 0) {
+ csiphy_dev->ref_count--;
pr_err("%s: failed to vote for AHB\n", __func__);
return rc;
}
@@ -792,8 +794,9 @@ csiphy_base_fail:
iounmap(csiphy_dev->base);
csiphy_dev->base = NULL;
ioremap_fail:
- if (cam_config_ahb_clk(CAM_AHB_CLIENT_CSIPHY,
- CAMERA_AHB_SUSPEND_VOTE) < 0)
+ csiphy_dev->ref_count--;
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
+ CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to vote for AHB\n", __func__);
return rc;
}
@@ -822,8 +825,10 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
return rc;
}
CDBG("%s:%d called\n", __func__, __LINE__);
- rc = cam_config_ahb_clk(CAM_AHB_CLIENT_CSIPHY, CAMERA_AHB_SVS_VOTE);
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
+ CAM_AHB_SVS_VOTE);
if (rc < 0) {
+ csiphy_dev->ref_count--;
pr_err("%s: failed to vote for AHB\n", __func__);
return rc;
}
@@ -904,8 +909,9 @@ csiphy_base_fail:
iounmap(csiphy_dev->base);
csiphy_dev->base = NULL;
ioremap_fail:
- if (cam_config_ahb_clk(CAM_AHB_CLIENT_CSIPHY,
- CAMERA_AHB_SUSPEND_VOTE) < 0)
+ csiphy_dev->ref_count--;
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
+ CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to vote for AHB\n", __func__);
return rc;
}
@@ -1014,11 +1020,9 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
csiphy_dev->base = NULL;
csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
- rc = cam_config_ahb_clk(CAM_AHB_CLIENT_CSIPHY, CAMERA_AHB_SUSPEND_VOTE);
- if (rc < 0) {
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
+ CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__);
- return rc;
- }
return 0;
}
#else
@@ -1121,8 +1125,9 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
iounmap(csiphy_dev->base);
csiphy_dev->base = NULL;
csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
- if (cam_config_ahb_clk(CAM_AHB_CLIENT_CSIPHY,
- CAMERA_AHB_SUSPEND_VOTE) < 0)
+
+ if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
+ CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__);
return 0;
}