diff options
author | Bhanu Murthy V <bmurthyv@nvidia.com> | 2018-07-06 12:45:41 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-07-06 21:30:17 -0400 |
commit | 7f203d1da64b5047e3fd0e413011abd039dfb27b (patch) | |
tree | d48ec94bbf091c11147a344e15af86fe547f7ac2 /drivers/video/tegra | |
parent | d18a104db897b54d4f30c0c87b676f6e3a9460e8 (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.c | 12 |
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); | |||
278 | int tegra194_nvcsi_prepare_poweroff(struct platform_device *pdev) | 279 | int 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 | } |
288 | EXPORT_SYMBOL_GPL(tegra194_nvcsi_prepare_poweroff); | 296 | EXPORT_SYMBOL_GPL(tegra194_nvcsi_prepare_poweroff); |
289 | 297 | ||