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>
This commit is contained in:
Lakshmi Narayana Kalavala 2016-01-15 17:41:59 -08:00 committed by David Keitel
parent b290459823
commit 1b668751e4
11 changed files with 225 additions and 130 deletions

View file

@ -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 * 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 * 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.h>
#include <linux/msm-bus-board.h> #include <linux/msm-bus-board.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/pm_opp.h>
#include <linux/regulator/rpm-smd-regulator.h>
#include "cam_hw_ops.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 { struct cam_ahb_client {
enum cam_ahb_clk_vote vote; enum cam_ahb_clk_vote vote;
}; };
@ -40,18 +48,6 @@ struct cam_ahb_client_data {
struct mutex lock; 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; static struct cam_ahb_client_data data;
int get_vector_index(char *name) int get_vector_index(char *name)
@ -96,7 +92,7 @@ int cam_ahb_clk_init(struct platform_device *pdev)
return -EINVAL; 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, data.vectors = devm_kzalloc(&pdev->dev,
sizeof(struct cam_bus_vector) * cnt, 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++) { for (i = 0; i < data.cnt; i++) {
rc = of_property_read_string_index(of_node, "bus-vectors", rc = of_property_read_string_index(of_node, "bus-vectors",
i, &(data.vectors[i].name)); 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) { if (rc < 0) {
pr_err("failed\n"); pr_err("failed\n");
rc = -EINVAL; rc = -EINVAL;
@ -160,7 +156,7 @@ int cam_ahb_clk_init(struct platform_device *pdev)
.num_paths = 1, .num_paths = 1,
.vectors = &data.paths[i], .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) { *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 */ /* request for svs in init */
msm_bus_scale_client_update_request(data.ahb_client, msm_bus_scale_client_update_request(data.ahb_client,
index); index);
data.ahb_clk_state = CAMERA_AHB_SUSPEND_VOTE; data.ahb_clk_state = CAM_AHB_SUSPEND_VOTE;
data.probe_done = TRUE; data.probe_done = TRUE;
mutex_init(&data.lock); mutex_init(&data.lock);
pr_debug("dbg, done registering ahb votes\n"); CDBG("dbg, done registering ahb votes\n");
pr_debug("dbg, clk state :%u, probe :%d\n", CDBG("dbg, clk state :%u, probe :%d\n",
data.ahb_clk_state, data.probe_done); data.ahb_clk_state, data.probe_done);
return rc; return rc;
@ -217,57 +213,126 @@ err1:
} }
EXPORT_SYMBOL(cam_ahb_clk_init); 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; int i = 0;
u32 final_vote = 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) { if (data.probe_done != TRUE) {
pr_err("ahb init is not done yet\n"); pr_err("ahb init is not done yet\n");
return -EINVAL; return -EINVAL;
} }
if (vote > CAMERA_AHB_TURBO_VOTE || id >= CAM_AHB_CLIENT_MAX) { CDBG("dbg: id :%u, vote : 0x%x\n", id, vote);
pr_err("err: invalid argument\n"); switch (dyn_vote) {
return -EINVAL; case CAM_AHB_SUSPEND_VOTE:
} case CAM_AHB_SVS_VOTE:
case CAM_AHB_NOMINAL_VOTE:
pr_debug("dbg: id :%u, vote : %u\n", id, vote); case CAM_AHB_TURBO_VOTE:
data.clients[id].vote = vote; break;
case CAM_AHB_DYNAMIC_VOTE:
mutex_lock(&data.lock); if (!dev) {
pr_err("device is NULL\n");
if (vote == data.ahb_clk_state) { return -EINVAL;
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);
} }
} else { opp = dev_pm_opp_find_freq_exact(dev, freq, true);
pr_err("err: no bus vector found\n"); 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; 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); EXPORT_SYMBOL(cam_config_ahb_clk);

View file

@ -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 * 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 * 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 /* need to update the voting requests
* according to dtsi entries. * according to dtsi entries.
*/ */
CAMERA_AHB_SUSPEND_VOTE = 0x01, CAM_AHB_SUSPEND_VOTE = 0x0,
CAMERA_AHB_SVS_VOTE = 0x02, CAM_AHB_SVS_VOTE = 0x01,
CAMERA_AHB_NOMINAL_VOTE = 0x04, CAM_AHB_NOMINAL_VOTE = 0x02,
CAMERA_AHB_TURBO_VOTE = 0x08, CAM_AHB_TURBO_VOTE = 0x03,
CAM_AHB_DYNAMIC_VOTE = 0xFF,
}; };
enum cam_ahb_clk_client { enum cam_ahb_clk_client {
@ -25,13 +26,14 @@ enum cam_ahb_clk_client {
CAM_AHB_CLIENT_CSID, CAM_AHB_CLIENT_CSID,
CAM_AHB_CLIENT_CCI, CAM_AHB_CLIENT_CCI,
CAM_AHB_CLIENT_ISPIF, CAM_AHB_CLIENT_ISPIF,
CAM_AHB_CLIENT_VFE, CAM_AHB_CLIENT_VFE0,
CAM_AHB_CLIENT_VFE1,
CAM_AHB_CLIENT_CPP, CAM_AHB_CLIENT_CPP,
CAM_AHB_CLIENT_FD, CAM_AHB_CLIENT_FD,
CAM_AHB_CLIENT_JPEG, CAM_AHB_CLIENT_JPEG,
CAM_AHB_CLIENT_MAX CAM_AHB_CLIENT_MAX
}; };
int cam_config_ahb_clk(enum cam_ahb_clk_client id, int cam_config_ahb_clk(struct device *dev, unsigned long freq,
enum cam_ahb_clk_vote vote); enum cam_ahb_clk_client id, enum cam_ahb_clk_vote vote);
int cam_ahb_clk_init(struct platform_device *pdev); int cam_ahb_clk_init(struct platform_device *pdev);

View file

@ -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 * 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 * 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; 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) { if (ret < 0) {
pr_err("%s: failed to vote for AHB\n", __func__); pr_err("%s: failed to vote for AHB\n", __func__);
return ret; goto error_ahb_config;
} }
return 0; return 0;
error_ahb_config:
vfree(ctx->stats);
error_stats_vmalloc: error_stats_vmalloc:
vb2_queue_release(&ctx->vb2_q); vb2_queue_release(&ctx->vb2_q);
error_vb2_queue_init: error_vb2_queue_init:
@ -421,8 +424,8 @@ static int msm_fd_release(struct file *file)
kfree(ctx); kfree(ctx);
if (cam_config_ahb_clk(CAM_AHB_CLIENT_FD, if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_FD,
CAMERA_AHB_SUSPEND_VOTE) < 0) CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__); pr_err("%s: failed to remove vote for AHB\n", __func__);
return 0; return 0;

View file

@ -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 * 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 * 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) static int msm_vfe47_init_hardware(struct vfe_device *vfe_dev)
{ {
int rc = -1; 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) { if (rc < 0) {
pr_err("%s: failed to vote for AHB\n", __func__); pr_err("%s: failed to vote for AHB\n", __func__);
goto ahb_vote_fail; goto ahb_vote_fail;
@ -317,13 +323,16 @@ camss_vdd_regulator_failed:
vfe_dev->fs_vfe = NULL; vfe_dev->fs_vfe = NULL;
msm_isp_deinit_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id); msm_isp_deinit_bandwidth_mgr(ISP_VFE0 + vfe_dev->pdev->id);
bus_scale_register_failed: 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: ahb_vote_fail:
return rc; return rc;
} }
static void msm_vfe47_release_hardware(struct vfe_device *vfe_dev) static void msm_vfe47_release_hardware(struct vfe_device *vfe_dev)
{ {
enum cam_ahb_clk_client id;
/* when closing node, disable all irq */ /* 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 + 0x5C);
msm_camera_io_w_mb(0x0, vfe_dev->vfe_base + 0x60); 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); 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__); pr_err("%s: failed to vote for AHB\n", __func__);
} }

View file

@ -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 * 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 * 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; 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) { if (rc < 0) {
pr_err("%s: failed to vote for AHB\n", __func__); pr_err("%s: failed to vote for AHB\n", __func__);
goto ahb_vote_fail; goto ahb_vote_fail;
@ -1372,10 +1373,9 @@ static int msm_ispif_init(struct ispif_device *ispif,
} }
error_ahb: error_ahb:
rc = cam_config_ahb_clk(CAM_AHB_CLIENT_ISPIF, if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_ISPIF,
CAMERA_AHB_SUSPEND_VOTE); CAM_AHB_SUSPEND_VOTE) < 0)
if (rc < 0) pr_err("%s: failed to remove vote for AHB\n", __func__);
pr_err("%s: failed to vote for AHB\n", __func__);
ahb_vote_fail: ahb_vote_fail:
free_irq(ispif->irq->start, ispif); free_irq(ispif->irq->start, ispif);
error_irq: error_irq:
@ -1413,8 +1413,8 @@ static void msm_ispif_release(struct ispif_device *ispif)
ispif->ispif_state = ISPIF_POWER_DOWN; ispif->ispif_state = ISPIF_POWER_DOWN;
if (cam_config_ahb_clk(CAM_AHB_CLIENT_ISPIF, if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_ISPIF,
CAMERA_AHB_SUSPEND_VOTE) < 0) CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__); pr_err("%s: failed to remove vote for AHB\n", __func__);
} }

View file

@ -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 * 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 * 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); 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) { if (rc < 0) {
pr_err("%s: failed to vote for AHB\n", __func__); pr_err("%s: failed to vote for AHB\n", __func__);
return rc; return rc;
@ -771,8 +772,8 @@ int __msm_jpeg_open(struct msm_jpeg_device *pgmn_dev)
return rc; return rc;
platform_init_fail: platform_init_fail:
if (cam_config_ahb_clk(CAM_AHB_CLIENT_JPEG, if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_JPEG,
CAMERA_AHB_SUSPEND_VOTE) < 0) CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__); pr_err("%s: failed to remove vote for AHB\n", __func__);
return rc; return rc;
} }
@ -805,8 +806,8 @@ int __msm_jpeg_release(struct msm_jpeg_device *pgmn_dev)
JPEG_DBG("%s:%d]\n", __func__, __LINE__); JPEG_DBG("%s:%d]\n", __func__, __LINE__);
if (cam_config_ahb_clk(CAM_AHB_CLIENT_JPEG, if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_JPEG,
CAMERA_AHB_SUSPEND_VOTE) < 0) CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__); pr_err("%s: failed to remove vote for AHB\n", __func__);
return 0; return 0;

View file

@ -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 * 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 * 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); ret = PTR_ERR(ctx->m2m_ctx);
goto error_m2m_init; 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); init_completion(&ctx->completion);
complete_all(&ctx->completion); complete_all(&ctx->completion);
dev_dbg(ctx->jdma_device->dev, "Jpeg v4l2 dma open success\n"); 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; return 0;
ahb_vote_fail:
v4l2_m2m_ctx_release(ctx->m2m_ctx);
error_m2m_init: error_m2m_init:
v4l2_fh_del(&ctx->fh); v4l2_fh_del(&ctx->fh);
v4l2_fh_exit(&ctx->fh); v4l2_fh_exit(&ctx->fh);
@ -536,8 +538,8 @@ static int msm_jpegdma_release(struct file *file)
v4l2_fh_exit(&ctx->fh); v4l2_fh_exit(&ctx->fh);
kfree(ctx); kfree(ctx);
if (cam_config_ahb_clk(CAM_AHB_CLIENT_JPEG, if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_JPEG,
CAMERA_AHB_SUSPEND_VOTE) < 0) CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__); pr_err("%s: failed to remove vote for AHB\n", __func__);
return 0; return 0;

View file

@ -947,7 +947,8 @@ static int cpp_init_hardware(struct cpp_device *cpp_dev)
uint32_t msm_micro_iface_idx; uint32_t msm_micro_iface_idx;
uint32_t vbif_version; 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) { if (rc < 0) {
pr_err("%s: failed to vote for AHB\n", __func__); pr_err("%s: failed to vote for AHB\n", __func__);
goto ahb_vote_fail; goto ahb_vote_fail;
@ -1212,7 +1213,8 @@ fs_mmagic_failed:
else else
msm_isp_deinit_bandwidth_mgr(ISP_CPP); msm_isp_deinit_bandwidth_mgr(ISP_CPP);
bus_scale_register_failed: 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__); pr_err("%s: failed to remove vote for AHB\n", __func__);
ahb_vote_fail: ahb_vote_fail:
return rc; return rc;
@ -1265,9 +1267,8 @@ static void cpp_release_hardware(struct cpp_device *cpp_dev)
else else
msm_isp_deinit_bandwidth_mgr(ISP_CPP); msm_isp_deinit_bandwidth_mgr(ISP_CPP);
rc = cam_config_ahb_clk(CAM_AHB_CLIENT_CPP, if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CPP,
CAMERA_AHB_SUSPEND_VOTE); CAM_AHB_SUSPEND_VOTE) < 0)
if (rc < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__); pr_err("%s: failed to remove vote for AHB\n", __func__);
} }

View file

@ -1262,7 +1262,8 @@ static int32_t msm_cci_init(struct v4l2_subdev *sd,
return rc; 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) { if (rc < 0) {
pr_err("%s: failed to vote for AHB\n", __func__); pr_err("%s: failed to vote for AHB\n", __func__);
return rc; return rc;
@ -1422,8 +1423,8 @@ clk_enable_failed:
cci_dev->cci_gpio_tbl_size, 0); cci_dev->cci_gpio_tbl_size, 0);
request_gpio_failed: request_gpio_failed:
cci_dev->ref_count--; cci_dev->ref_count--;
if (cam_config_ahb_clk(CAM_AHB_CLIENT_CCI, if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CCI,
CAMERA_AHB_SUSPEND_VOTE) < 0) CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__); pr_err("%s: failed to remove vote for AHB\n", __func__);
return rc; return rc;
} }
@ -1480,8 +1481,8 @@ static int32_t msm_cci_release(struct v4l2_subdev *sd)
cci_dev->cci_clk_src = 0; cci_dev->cci_clk_src = 0;
ahb_vote_suspend: ahb_vote_suspend:
if (cam_config_ahb_clk(CAM_AHB_CLIENT_CCI, if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CCI,
CAMERA_AHB_SUSPEND_VOTE) < 0) CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__); pr_err("%s: failed to remove vote for AHB\n", __func__);
return rc; return rc;
} }

View file

@ -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 * 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 * 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; 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) { if (rc < 0) {
pr_err("%s: failed to vote for AHB\n", __func__); pr_err("%s: failed to vote for AHB\n", __func__);
return rc; return rc;
@ -591,8 +592,8 @@ top_vreg_config_failed:
iounmap(csid_dev->base); iounmap(csid_dev->base);
csid_dev->base = NULL; csid_dev->base = NULL;
ioremap_fail: ioremap_fail:
if (cam_config_ahb_clk(CAM_AHB_CLIENT_CSID, if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,
CAMERA_AHB_SUSPEND_VOTE) < 0) CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote from AHB\n", __func__); pr_err("%s: failed to remove vote from AHB\n", __func__);
return rc; return rc;
} }
@ -662,8 +663,8 @@ static int msm_csid_release(struct csid_device *csid_dev)
csid_dev->base = NULL; csid_dev->base = NULL;
csid_dev->csid_state = CSID_POWER_DOWN; csid_dev->csid_state = CSID_POWER_DOWN;
if (cam_config_ahb_clk(CAM_AHB_CLIENT_CSID, if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,
CAMERA_AHB_SUSPEND_VOTE) < 0) CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote from AHB\n", __func__); pr_err("%s: failed to remove vote from AHB\n", __func__);
return 0; return 0;
} }

View file

@ -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 * 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 * 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__); 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) { if (rc < 0) {
csiphy_dev->ref_count--;
pr_err("%s: failed to vote for AHB\n", __func__); pr_err("%s: failed to vote for AHB\n", __func__);
return rc; return rc;
} }
@ -792,8 +794,9 @@ csiphy_base_fail:
iounmap(csiphy_dev->base); iounmap(csiphy_dev->base);
csiphy_dev->base = NULL; csiphy_dev->base = NULL;
ioremap_fail: ioremap_fail:
if (cam_config_ahb_clk(CAM_AHB_CLIENT_CSIPHY, csiphy_dev->ref_count--;
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 vote for AHB\n", __func__); pr_err("%s: failed to vote for AHB\n", __func__);
return rc; return rc;
} }
@ -822,8 +825,10 @@ static int msm_csiphy_init(struct csiphy_device *csiphy_dev)
return rc; return rc;
} }
CDBG("%s:%d called\n", __func__, __LINE__); 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) { if (rc < 0) {
csiphy_dev->ref_count--;
pr_err("%s: failed to vote for AHB\n", __func__); pr_err("%s: failed to vote for AHB\n", __func__);
return rc; return rc;
} }
@ -904,8 +909,9 @@ csiphy_base_fail:
iounmap(csiphy_dev->base); iounmap(csiphy_dev->base);
csiphy_dev->base = NULL; csiphy_dev->base = NULL;
ioremap_fail: ioremap_fail:
if (cam_config_ahb_clk(CAM_AHB_CLIENT_CSIPHY, csiphy_dev->ref_count--;
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 vote for AHB\n", __func__); pr_err("%s: failed to vote for AHB\n", __func__);
return rc; return rc;
} }
@ -1014,11 +1020,9 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
csiphy_dev->base = NULL; csiphy_dev->base = NULL;
csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN; csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN;
rc = cam_config_ahb_clk(CAM_AHB_CLIENT_CSIPHY, CAMERA_AHB_SUSPEND_VOTE); if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
if (rc < 0) { CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__); pr_err("%s: failed to remove vote for AHB\n", __func__);
return rc;
}
return 0; return 0;
} }
#else #else
@ -1121,8 +1125,9 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
iounmap(csiphy_dev->base); iounmap(csiphy_dev->base);
csiphy_dev->base = NULL; csiphy_dev->base = NULL;
csiphy_dev->csiphy_state = CSIPHY_POWER_DOWN; 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__); pr_err("%s: failed to remove vote for AHB\n", __func__);
return 0; return 0;
} }