diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common')
-rw-r--r-- | drivers/gpu/nvgpu/common/fifo/channel.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/drivers/gpu/nvgpu/common/fifo/channel.c b/drivers/gpu/nvgpu/common/fifo/channel.c index 2ada3911..0174e369 100644 --- a/drivers/gpu/nvgpu/common/fifo/channel.c +++ b/drivers/gpu/nvgpu/common/fifo/channel.c | |||
@@ -1387,6 +1387,11 @@ u32 nvgpu_get_gp_free_count(struct channel_gk20a *c) | |||
1387 | 1387 | ||
1388 | static void __gk20a_channel_timeout_start(struct channel_gk20a *ch) | 1388 | static void __gk20a_channel_timeout_start(struct channel_gk20a *ch) |
1389 | { | 1389 | { |
1390 | if (gk20a_channel_check_timedout(ch)) { | ||
1391 | ch->timeout.running = false; | ||
1392 | return; | ||
1393 | } | ||
1394 | |||
1390 | ch->timeout.gp_get = ch->g->ops.fifo.userd_gp_get(ch->g, ch); | 1395 | ch->timeout.gp_get = ch->g->ops.fifo.userd_gp_get(ch->g, ch); |
1391 | ch->timeout.pb_get = ch->g->ops.fifo.userd_pb_get(ch->g, ch); | 1396 | ch->timeout.pb_get = ch->g->ops.fifo.userd_pb_get(ch->g, ch); |
1392 | ch->timeout.running = true; | 1397 | ch->timeout.running = true; |
@@ -1484,16 +1489,16 @@ void gk20a_channel_timeout_restart_all_channels(struct gk20a *g) | |||
1484 | for (chid = 0; chid < f->num_channels; chid++) { | 1489 | for (chid = 0; chid < f->num_channels; chid++) { |
1485 | struct channel_gk20a *ch = gk20a_channel_from_id(g, chid); | 1490 | struct channel_gk20a *ch = gk20a_channel_from_id(g, chid); |
1486 | 1491 | ||
1487 | if (ch == NULL) | 1492 | if (ch != NULL) { |
1488 | continue; | 1493 | if (!gk20a_channel_check_timedout(ch)) { |
1489 | 1494 | nvgpu_raw_spinlock_acquire(&ch->timeout.lock); | |
1490 | nvgpu_raw_spinlock_acquire(&ch->timeout.lock); | 1495 | if (ch->timeout.running) { |
1491 | if (ch->timeout.running) { | 1496 | __gk20a_channel_timeout_start(ch); |
1492 | __gk20a_channel_timeout_start(ch); | 1497 | } |
1498 | nvgpu_raw_spinlock_release(&ch->timeout.lock); | ||
1499 | } | ||
1500 | gk20a_channel_put(ch); | ||
1493 | } | 1501 | } |
1494 | nvgpu_raw_spinlock_release(&ch->timeout.lock); | ||
1495 | |||
1496 | gk20a_channel_put(ch); | ||
1497 | } | 1502 | } |
1498 | } | 1503 | } |
1499 | 1504 | ||
@@ -1517,6 +1522,12 @@ static void gk20a_channel_timeout_handler(struct channel_gk20a *ch) | |||
1517 | 1522 | ||
1518 | nvgpu_log_fn(g, " "); | 1523 | nvgpu_log_fn(g, " "); |
1519 | 1524 | ||
1525 | if (gk20a_channel_check_timedout(ch)) { | ||
1526 | /* channel is already recovered */ | ||
1527 | gk20a_channel_timeout_stop(ch); | ||
1528 | return; | ||
1529 | } | ||
1530 | |||
1520 | /* Get status but keep timer running */ | 1531 | /* Get status but keep timer running */ |
1521 | nvgpu_raw_spinlock_acquire(&ch->timeout.lock); | 1532 | nvgpu_raw_spinlock_acquire(&ch->timeout.lock); |
1522 | gp_get = ch->timeout.gp_get; | 1533 | gp_get = ch->timeout.gp_get; |
@@ -1587,7 +1598,9 @@ static void gk20a_channel_poll_timeouts(struct gk20a *g) | |||
1587 | struct channel_gk20a *ch = gk20a_channel_from_id(g, chid); | 1598 | struct channel_gk20a *ch = gk20a_channel_from_id(g, chid); |
1588 | 1599 | ||
1589 | if (ch != NULL) { | 1600 | if (ch != NULL) { |
1590 | gk20a_channel_timeout_check(ch); | 1601 | if (!gk20a_channel_check_timedout(ch)) { |
1602 | gk20a_channel_timeout_check(ch); | ||
1603 | } | ||
1591 | gk20a_channel_put(ch); | 1604 | gk20a_channel_put(ch); |
1592 | } | 1605 | } |
1593 | } | 1606 | } |