summaryrefslogtreecommitdiffstats
path: root/drivers/video/tegra
diff options
context:
space:
mode:
authorBhanu Murthy V <bmurthyv@nvidia.com>2018-07-06 12:45:41 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-07-06 21:30:17 -0400
commit7f203d1da64b5047e3fd0e413011abd039dfb27b (patch)
treed48ec94bbf091c11147a344e15af86fe547f7ac2 /drivers/video/tegra
parentd18a104db897b54d4f30c0c87b676f6e3a9460e8 (diff)
drivers: nvcsi: Fix power sequence race condition
Fix race condition in power sequence of nvcsi, where the power on returns zero but waits to perform calibration sequence and depends on RTCPU to be powered on. If RTCPU is not powered on before power off request is issued then power off sequence will execute before completion of power on. The atomic variable context must be set after the power on/off sequence is complete. Bug 200427615 Change-Id: I336f91415836143285d897ee81c3741ca6291f25 Signed-off-by: Bhanu Murthy V <bmurthyv@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1772893 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: David Bang <dbang@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Frank Chen <frankc@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/video/tegra')
-rw-r--r--drivers/video/tegra/host/nvcsi/nvcsi-t194.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/video/tegra/host/nvcsi/nvcsi-t194.c b/drivers/video/tegra/host/nvcsi/nvcsi-t194.c
index 31648967f..2bafbc715 100644
--- a/drivers/video/tegra/host/nvcsi/nvcsi-t194.c
+++ b/drivers/video/tegra/host/nvcsi/nvcsi-t194.c
@@ -246,6 +246,7 @@ static int nvcsi_prod_apply_thread(void *data)
246 246
247 nvcsi_apply_prod(pdev); 247 nvcsi_apply_prod(pdev);
248 tegra_csi_mipi_calibrate(&nvcsi->csi, true); 248 tegra_csi_mipi_calibrate(&nvcsi->csi, true);
249 atomic_set(&nvcsi->on, 1);
249 return 0; 250 return 0;
250 251
251} 252}
@@ -257,7 +258,6 @@ int tegra194_nvcsi_finalize_poweron(struct platform_device *pdev)
257 258
258 if (atomic_read(&nvcsi->on) == 1) 259 if (atomic_read(&nvcsi->on) == 1)
259 return 0; 260 return 0;
260 atomic_set(&nvcsi->on, 1);
261 261
262 /* rtcpu resets nvcsi registers, so we set prod settings 262 /* rtcpu resets nvcsi registers, so we set prod settings
263 * after rtcpu has finished resetting the registers 263 * after rtcpu has finished resetting the registers
@@ -269,6 +269,7 @@ int tegra194_nvcsi_finalize_poweron(struct platform_device *pdev)
269 else { 269 else {
270 nvcsi_apply_prod(pdev); 270 nvcsi_apply_prod(pdev);
271 tegra_csi_mipi_calibrate(&nvcsi->csi, true); 271 tegra_csi_mipi_calibrate(&nvcsi->csi, true);
272 atomic_set(&nvcsi->on, 1);
272 } 273 }
273 274
274 return 0; 275 return 0;
@@ -278,12 +279,19 @@ EXPORT_SYMBOL_GPL(tegra194_nvcsi_finalize_poweron);
278int tegra194_nvcsi_prepare_poweroff(struct platform_device *pdev) 279int tegra194_nvcsi_prepare_poweroff(struct platform_device *pdev)
279{ 280{
280 struct t194_nvcsi *nvcsi = nvhost_get_private_data(pdev); 281 struct t194_nvcsi *nvcsi = nvhost_get_private_data(pdev);
282 int err = 0;
281 283
282 if (atomic_read(&nvcsi->on) == 0) 284 if (atomic_read(&nvcsi->on) == 0)
283 return 0; 285 return 0;
286
287 err = tegra_csi_mipi_calibrate(&nvcsi->csi, false);
288 if (err) {
289 dev_err(&pdev->dev, "calibration failed\n");
290 return err;
291 }
284 atomic_set(&nvcsi->on, 0); 292 atomic_set(&nvcsi->on, 0);
285 293
286 return tegra_csi_mipi_calibrate(&nvcsi->csi, false); 294 return 0;
287} 295}
288EXPORT_SYMBOL_GPL(tegra194_nvcsi_prepare_poweroff); 296EXPORT_SYMBOL_GPL(tegra194_nvcsi_prepare_poweroff);
289 297