summaryrefslogtreecommitdiffstats
path: root/drivers/platform/tegra/rtcpu
diff options
context:
space:
mode:
authorPekka Pessi <ppessi@nvidia.com>2018-01-25 09:40:11 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2018-02-22 17:02:55 -0500
commitdde5bba2788e93828449019a14201869cd853345 (patch)
treec910d2851aed84bbcf5cdce687bc642968a65678 /drivers/platform/tegra/rtcpu
parent8c72f20a47e8c25ffbc7ea6f69e2ed1cb140c7ed (diff)
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 <ppessi@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1653628 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Bhanu Murthy V <bmurthyv@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/platform/tegra/rtcpu')
-rw-r--r--drivers/platform/tegra/rtcpu/debug.c28
-rw-r--r--drivers/platform/tegra/rtcpu/tegra-rtcpu-trace.c25
2 files changed, 42 insertions, 11 deletions
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 @@
1/* 1/*
2 * Copyright (c) 2016-2017 NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -220,11 +220,11 @@ static int camrtc_ivc_dbg_full_frame_xact(
220 timeout); 220 timeout);
221 if (timeout <= 0) { 221 if (timeout <= 0) {
222 ret = timeout ?: -ETIMEDOUT; 222 ret = timeout ?: -ETIMEDOUT;
223 goto out; 223 break;
224 } 224 }
225 if (tegra_ivc_channel_has_been_reset(ch)) { 225 if (tegra_ivc_channel_has_been_reset(ch)) {
226 ret = -ECONNRESET; 226 ret = -ECONNRESET;
227 goto out; 227 break;
228 } 228 }
229 229
230 dev_dbg(&ch->dev, "rx msg\n"); 230 dev_dbg(&ch->dev, "rx msg\n");
@@ -232,7 +232,7 @@ static int camrtc_ivc_dbg_full_frame_xact(
232 ret = tegra_ivc_read_peek(&ch->ivc, resp, 0, resp_size); 232 ret = tegra_ivc_read_peek(&ch->ivc, resp, 0, resp_size);
233 if (ret < 0) { 233 if (ret < 0) {
234 dev_err(&ch->dev, "IVC read error: %d\n", ret); 234 dev_err(&ch->dev, "IVC read error: %d\n", ret);
235 goto out; 235 break;
236 } 236 }
237 237
238 tegra_ivc_read_advance(&ch->ivc); 238 tegra_ivc_read_advance(&ch->ivc);
@@ -244,6 +244,7 @@ static int camrtc_ivc_dbg_full_frame_xact(
244 244
245 dev_err(&ch->dev, "unexpected response\n"); 245 dev_err(&ch->dev, "unexpected response\n");
246 } 246 }
247
247out: 248out:
248 tegra_ivc_channel_runtime_put(ch); 249 tegra_ivc_channel_runtime_put(ch);
249unlock: 250unlock:
@@ -571,12 +572,24 @@ static int camrtc_test_run_and_show_result(struct seq_file *file,
571 struct camrtc_dbg_request, run_mem_test_data.timeout, 572 struct camrtc_dbg_request, run_mem_test_data.timeout,
572 struct camrtc_dbg_request, run_test_data.timeout); 573 struct camrtc_dbg_request, run_test_data.timeout);
573 574
575 ret = tegra_ivc_channel_runtime_get(ch);
576 if (ret < 0)
577 return ret;
578
574 req->data.run_test_data.timeout = ns; 579 req->data.run_test_data.timeout = ns;
575 580
576 ret = camrtc_ivc_dbg_full_frame_xact(ch, req, req_size, 581 ret = camrtc_ivc_dbg_full_frame_xact(ch, req, req_size,
577 resp, resp_size, timeout); 582 resp, resp_size, timeout);
578 if (ret < 0) 583
579 return ret; 584 tegra_camrtc_flush_trace(camrtc_get_device(ch));
585
586 if (ret < 0) {
587 if (ret != -ECONNRESET) {
588 dev_info(&ch->dev, "rebooting after a failed test run");
589 (void)tegra_camrtc_reboot(&ch->dev);
590 }
591 goto runtime_put;
592 }
580 593
581 BUILD_BUG_ON_MISMATCH( 594 BUILD_BUG_ON_MISMATCH(
582 struct camrtc_dbg_response, run_mem_test_data.timeout, 595 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,
593 else 606 else
594 seq_write(file, result, result_size); 607 seq_write(file, result, result_size);
595 608
609runtime_put:
610 tegra_ivc_channel_runtime_put(ch);
611
596 return ret; 612 return ret;
597} 613}
598 614
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 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#include "soc/tegra/camrtc-trace.h"
18
17#include <linux/completion.h> 19#include <linux/completion.h>
18#include <linux/debugfs.h> 20#include <linux/debugfs.h>
19#include <linux/dma-mapping.h> 21#include <linux/dma-mapping.h>
@@ -41,8 +43,6 @@
41#include "rtcpu/device-group.h" 43#include "rtcpu/device-group.h"
42#endif 44#endif
43 45
44#include "soc/tegra/camrtc-trace.h"
45
46#define CREATE_TRACE_POINTS 46#define CREATE_TRACE_POINTS
47#include <trace/events/tegra_rtcpu.h> 47#include <trace/events/tegra_rtcpu.h>
48#include <trace/events/freertos.h> 48#include <trace/events/freertos.h>
@@ -60,6 +60,7 @@
60struct tegra_rtcpu_trace { 60struct tegra_rtcpu_trace {
61 struct device *dev; 61 struct device *dev;
62 struct device_node *of_node; 62 struct device_node *of_node;
63 struct mutex lock;
63 64
64 /* memory */ 65 /* memory */
65 void *trace_memory; 66 void *trace_memory;
@@ -992,11 +993,12 @@ static inline void rtcpu_trace_events(struct tegra_rtcpu_trace *tracer)
992 tracer->copy_last_event = *last_event; 993 tracer->copy_last_event = *last_event;
993} 994}
994 995
995static void rtcpu_trace_worker(struct work_struct *work) 996void tegra_rtcpu_trace_flush(struct tegra_rtcpu_trace *tracer)
996{ 997{
997 struct tegra_rtcpu_trace *tracer; 998 if (tracer == NULL)
999 return;
998 1000
999 tracer = container_of(work, struct tegra_rtcpu_trace, work.work); 1001 mutex_lock(&tracer->lock);
1000 1002
1001 /* invalidate the cache line for the pointers */ 1003 /* invalidate the cache line for the pointers */
1002 dma_sync_single_for_cpu(tracer->dev, tracer->dma_handle_pointers, 1004 dma_sync_single_for_cpu(tracer->dev, tracer->dma_handle_pointers,
@@ -1006,6 +1008,18 @@ static void rtcpu_trace_worker(struct work_struct *work)
1006 rtcpu_trace_exceptions(tracer); 1008 rtcpu_trace_exceptions(tracer);
1007 rtcpu_trace_events(tracer); 1009 rtcpu_trace_events(tracer);
1008 1010
1011 mutex_unlock(&tracer->lock);
1012}
1013EXPORT_SYMBOL(tegra_rtcpu_trace_flush);
1014
1015static void rtcpu_trace_worker(struct work_struct *work)
1016{
1017 struct tegra_rtcpu_trace *tracer;
1018
1019 tracer = container_of(work, struct tegra_rtcpu_trace, work.work);
1020
1021 tegra_rtcpu_trace_flush(tracer);
1022
1009 /* reschedule */ 1023 /* reschedule */
1010 schedule_delayed_work(&tracer->work, tracer->work_interval_jiffies); 1024 schedule_delayed_work(&tracer->work, tracer->work_interval_jiffies);
1011} 1025}
@@ -1149,6 +1163,7 @@ struct tegra_rtcpu_trace *tegra_rtcpu_trace_create(struct device *dev,
1149 return NULL; 1163 return NULL;
1150 1164
1151 tracer->dev = dev; 1165 tracer->dev = dev;
1166 mutex_init(&tracer->lock);
1152 1167
1153 /* Get the trace memory */ 1168 /* Get the trace memory */
1154 ret = rtcpu_trace_setup_memory(tracer); 1169 ret = rtcpu_trace_setup_memory(tracer);