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 #include #include +#include +#include #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; + 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) { + CDBG("dbg: already at desired vote\n"); + mutex_unlock(&data.lock); + return 0; + } + + for (i = 0; i < CAM_AHB_CLIENT_MAX; i++) { + if (data.clients[i].vote > max) + max = data.clients[i].vote; + } + + 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; } - 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; - - mutex_lock(&data.lock); - - if (vote == data.ahb_clk_state) { - pr_debug("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; - } - - 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: 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; } - } else { - pr_err("err: no bus vector found\n"); + 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; } - mutex_unlock(&data.lock); - return 0; + + 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; } + 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 ahb_vote_fail; + } 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); - if (ret < 0) { - pr_err("%s: failed to vote for AHB\n", __func__); - goto error_m2m_init; - } - 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; }