From dde5bba2788e93828449019a14201869cd853345 Mon Sep 17 00:00:00 2001 From: Pekka Pessi Date: Thu, 25 Jan 2018 16:40:11 +0200 Subject: tegra: camera: rtcpu: reboot after failed tests Flush the RTCPU tracer and print out the RTCPU log entries after a test run. Reboot rtcpu after a failed test run. An unsuccessful test test may leave RTCPU in a bad state with references to the soon-to-be-unmapped memory, which may crash the whole device. Bug 2036751 Change-Id: I9dbabfbdbb88d9e0afd58451f8d2f25e6d263282 Signed-off-by: Pekka Pessi Reviewed-on: https://git-master.nvidia.com/r/1653628 Reviewed-by: svc-mobile-coverity GVS: Gerrit_Virtual_Submit Reviewed-by: Bhanu Murthy V Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/platform/tegra/rtcpu/debug.c | 28 +++++++++++++++++++----- drivers/platform/tegra/rtcpu/tegra-rtcpu-trace.c | 25 ++++++++++++++++----- 2 files changed, 42 insertions(+), 11 deletions(-) (limited to 'drivers/platform/tegra/rtcpu') diff --git a/drivers/platform/tegra/rtcpu/debug.c b/drivers/platform/tegra/rtcpu/debug.c index a3e29cbac..e22e9f47a 100644 --- a/drivers/platform/tegra/rtcpu/debug.c +++ b/drivers/platform/tegra/rtcpu/debug.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -220,11 +220,11 @@ static int camrtc_ivc_dbg_full_frame_xact( timeout); if (timeout <= 0) { ret = timeout ?: -ETIMEDOUT; - goto out; + break; } if (tegra_ivc_channel_has_been_reset(ch)) { ret = -ECONNRESET; - goto out; + break; } dev_dbg(&ch->dev, "rx msg\n"); @@ -232,7 +232,7 @@ static int camrtc_ivc_dbg_full_frame_xact( ret = tegra_ivc_read_peek(&ch->ivc, resp, 0, resp_size); if (ret < 0) { dev_err(&ch->dev, "IVC read error: %d\n", ret); - goto out; + break; } tegra_ivc_read_advance(&ch->ivc); @@ -244,6 +244,7 @@ static int camrtc_ivc_dbg_full_frame_xact( dev_err(&ch->dev, "unexpected response\n"); } + out: tegra_ivc_channel_runtime_put(ch); unlock: @@ -571,12 +572,24 @@ static int camrtc_test_run_and_show_result(struct seq_file *file, struct camrtc_dbg_request, run_mem_test_data.timeout, struct camrtc_dbg_request, run_test_data.timeout); + ret = tegra_ivc_channel_runtime_get(ch); + if (ret < 0) + return ret; + req->data.run_test_data.timeout = ns; ret = camrtc_ivc_dbg_full_frame_xact(ch, req, req_size, resp, resp_size, timeout); - if (ret < 0) - return ret; + + tegra_camrtc_flush_trace(camrtc_get_device(ch)); + + if (ret < 0) { + if (ret != -ECONNRESET) { + dev_info(&ch->dev, "rebooting after a failed test run"); + (void)tegra_camrtc_reboot(&ch->dev); + } + goto runtime_put; + } BUILD_BUG_ON_MISMATCH( struct camrtc_dbg_response, run_mem_test_data.timeout, @@ -593,6 +606,9 @@ static int camrtc_test_run_and_show_result(struct seq_file *file, else seq_write(file, result, result_size); +runtime_put: + tegra_ivc_channel_runtime_put(ch); + return ret; } diff --git a/drivers/platform/tegra/rtcpu/tegra-rtcpu-trace.c b/drivers/platform/tegra/rtcpu/tegra-rtcpu-trace.c index 614e95bc1..d59abbfe1 100644 --- a/drivers/platform/tegra/rtcpu/tegra-rtcpu-trace.c +++ b/drivers/platform/tegra/rtcpu/tegra-rtcpu-trace.c @@ -14,6 +14,8 @@ * along with this program. If not, see . */ +#include "soc/tegra/camrtc-trace.h" + #include #include #include @@ -41,8 +43,6 @@ #include "rtcpu/device-group.h" #endif -#include "soc/tegra/camrtc-trace.h" - #define CREATE_TRACE_POINTS #include #include @@ -60,6 +60,7 @@ struct tegra_rtcpu_trace { struct device *dev; struct device_node *of_node; + struct mutex lock; /* memory */ void *trace_memory; @@ -992,11 +993,12 @@ static inline void rtcpu_trace_events(struct tegra_rtcpu_trace *tracer) tracer->copy_last_event = *last_event; } -static void rtcpu_trace_worker(struct work_struct *work) +void tegra_rtcpu_trace_flush(struct tegra_rtcpu_trace *tracer) { - struct tegra_rtcpu_trace *tracer; + if (tracer == NULL) + return; - tracer = container_of(work, struct tegra_rtcpu_trace, work.work); + mutex_lock(&tracer->lock); /* invalidate the cache line for the pointers */ dma_sync_single_for_cpu(tracer->dev, tracer->dma_handle_pointers, @@ -1006,6 +1008,18 @@ static void rtcpu_trace_worker(struct work_struct *work) rtcpu_trace_exceptions(tracer); rtcpu_trace_events(tracer); + mutex_unlock(&tracer->lock); +} +EXPORT_SYMBOL(tegra_rtcpu_trace_flush); + +static void rtcpu_trace_worker(struct work_struct *work) +{ + struct tegra_rtcpu_trace *tracer; + + tracer = container_of(work, struct tegra_rtcpu_trace, work.work); + + tegra_rtcpu_trace_flush(tracer); + /* reschedule */ schedule_delayed_work(&tracer->work, tracer->work_interval_jiffies); } @@ -1149,6 +1163,7 @@ struct tegra_rtcpu_trace *tegra_rtcpu_trace_create(struct device *dev, return NULL; tracer->dev = dev; + mutex_init(&tracer->lock); /* Get the trace memory */ ret = rtcpu_trace_setup_memory(tracer); -- cgit v1.2.2