diff options
author | Joshua Widen <jwiden@nvidia.com> | 2018-06-05 01:13:56 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-07-05 12:07:02 -0400 |
commit | 946c53285235c578a3b58ff49f2511c56832dd30 (patch) | |
tree | ad2b9df6d9287ac37c86337d09f9732b040e0393 | |
parent | fbb7b1cd8d663d713f4aa24a22f571e070834b39 (diff) |
media: tegra: camera: Additional abort support
Complete waiters and return EIO on reset.
Bug 2047639
Change-Id: I0038713e52d91fbcdd2eab8390b697e98a77b66a
Signed-off-by: Joshua Widen <jwiden@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1753906
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r-- | drivers/media/platform/tegra/camera/isp/capture_isp.c | 67 |
1 files changed, 59 insertions, 8 deletions
diff --git a/drivers/media/platform/tegra/camera/isp/capture_isp.c b/drivers/media/platform/tegra/camera/isp/capture_isp.c index aa1af5435..efa541f3f 100644 --- a/drivers/media/platform/tegra/camera/isp/capture_isp.c +++ b/drivers/media/platform/tegra/camera/isp/capture_isp.c | |||
@@ -70,6 +70,10 @@ struct isp_capture { | |||
70 | 70 | ||
71 | struct mutex control_msg_lock; | 71 | struct mutex control_msg_lock; |
72 | struct CAPTURE_CONTROL_MSG control_resp_msg; | 72 | struct CAPTURE_CONTROL_MSG control_resp_msg; |
73 | |||
74 | struct mutex reset_lock; | ||
75 | bool reset_capture_program_flag; | ||
76 | bool reset_capture_flag; | ||
73 | }; | 77 | }; |
74 | 78 | ||
75 | static void isp_capture_ivc_control_callback(const void *ivc_resp, | 79 | static void isp_capture_ivc_control_callback(const void *ivc_resp, |
@@ -133,9 +137,10 @@ static void isp_capture_ivc_status_callback(const void *ivc_resp, | |||
133 | buffer_index = status_msg->capture_isp_status_ind.buffer_index; | 137 | buffer_index = status_msg->capture_isp_status_ind.buffer_index; |
134 | isp_capture_request_unpin(chan, buffer_index); | 138 | isp_capture_request_unpin(chan, buffer_index); |
135 | dma_sync_single_range_for_cpu(capture->rtcpu_dev, | 139 | dma_sync_single_range_for_cpu(capture->rtcpu_dev, |
136 | capture->capture_desc_ctx.requests.iova, | 140 | capture->capture_desc_ctx.requests.iova, |
137 | buffer_index * capture->capture_desc_ctx.request_size, | 141 | buffer_index * capture->capture_desc_ctx.request_size, |
138 | capture->capture_desc_ctx.request_size, DMA_FROM_DEVICE); | 142 | capture->capture_desc_ctx.request_size, |
143 | DMA_FROM_DEVICE); | ||
139 | complete(&capture->capture_resp); | 144 | complete(&capture->capture_resp); |
140 | dev_dbg(chan->isp_dev, "%s: status chan_id %u msg_id %u\n", | 145 | dev_dbg(chan->isp_dev, "%s: status chan_id %u msg_id %u\n", |
141 | __func__, status_msg->header.channel_id, | 146 | __func__, status_msg->header.channel_id, |
@@ -146,9 +151,10 @@ static void isp_capture_ivc_status_callback(const void *ivc_resp, | |||
146 | status_msg->capture_isp_program_status_ind.buffer_index; | 151 | status_msg->capture_isp_program_status_ind.buffer_index; |
147 | isp_capture_program_request_unpin(chan, buffer_index); | 152 | isp_capture_program_request_unpin(chan, buffer_index); |
148 | dma_sync_single_range_for_cpu(capture->rtcpu_dev, | 153 | dma_sync_single_range_for_cpu(capture->rtcpu_dev, |
149 | capture->program_desc_ctx.requests.iova, | 154 | capture->program_desc_ctx.requests.iova, |
150 | buffer_index * capture->program_desc_ctx.request_size, | 155 | buffer_index * capture->program_desc_ctx.request_size, |
151 | capture->program_desc_ctx.request_size, DMA_FROM_DEVICE); | 156 | capture->program_desc_ctx.request_size, |
157 | DMA_FROM_DEVICE); | ||
152 | complete(&capture->capture_program_resp); | 158 | complete(&capture->capture_program_resp); |
153 | dev_dbg(chan->isp_dev, | 159 | dev_dbg(chan->isp_dev, |
154 | "%s: isp_ program status chan_id %u msg_id %u\n", | 160 | "%s: isp_ program status chan_id %u msg_id %u\n", |
@@ -195,12 +201,16 @@ int isp_capture_init(struct tegra_isp_channel *chan) | |||
195 | mutex_init(&capture->control_msg_lock); | 201 | mutex_init(&capture->control_msg_lock); |
196 | mutex_init(&capture->capture_desc_ctx.unpins_list_lock); | 202 | mutex_init(&capture->capture_desc_ctx.unpins_list_lock); |
197 | mutex_init(&capture->program_desc_ctx.unpins_list_lock); | 203 | mutex_init(&capture->program_desc_ctx.unpins_list_lock); |
204 | mutex_init(&capture->reset_lock); | ||
198 | 205 | ||
199 | capture->isp_channel = chan; | 206 | capture->isp_channel = chan; |
200 | chan->capture_data = capture; | 207 | chan->capture_data = capture; |
201 | 208 | ||
202 | capture->channel_id = CAPTURE_CHANNEL_ISP_INVALID_ID; | 209 | capture->channel_id = CAPTURE_CHANNEL_ISP_INVALID_ID; |
203 | 210 | ||
211 | capture->reset_capture_program_flag = false; | ||
212 | capture->reset_capture_flag = false; | ||
213 | |||
204 | return 0; | 214 | return 0; |
205 | } | 215 | } |
206 | 216 | ||
@@ -585,6 +595,11 @@ int isp_capture_reset(struct tegra_isp_channel *chan, | |||
585 | return -ENODEV; | 595 | return -ENODEV; |
586 | } | 596 | } |
587 | 597 | ||
598 | mutex_lock(&capture->reset_lock); | ||
599 | capture->reset_capture_program_flag = true; | ||
600 | capture->reset_capture_flag = true; | ||
601 | mutex_unlock(&capture->reset_lock); | ||
602 | |||
588 | memset(&control_msg, 0, sizeof(control_msg)); | 603 | memset(&control_msg, 0, sizeof(control_msg)); |
589 | control_msg.header.msg_id = CAPTURE_CHANNEL_ISP_RESET_REQ; | 604 | control_msg.header.msg_id = CAPTURE_CHANNEL_ISP_RESET_REQ; |
590 | control_msg.header.channel_id = capture->channel_id; | 605 | control_msg.header.channel_id = capture->channel_id; |
@@ -602,11 +617,15 @@ int isp_capture_reset(struct tegra_isp_channel *chan, | |||
602 | goto error; | 617 | goto error; |
603 | } | 618 | } |
604 | 619 | ||
605 | for (i = 0; i < capture->program_desc_ctx.queue_depth; i++) | 620 | for (i = 0; i < capture->program_desc_ctx.queue_depth; i++) { |
606 | isp_capture_program_request_unpin(chan, i); | 621 | isp_capture_program_request_unpin(chan, i); |
622 | complete(&capture->capture_program_resp); | ||
623 | } | ||
607 | 624 | ||
608 | for (i = 0; i < capture->capture_desc_ctx.queue_depth; i++) | 625 | for (i = 0; i < capture->capture_desc_ctx.queue_depth; i++) { |
609 | isp_capture_request_unpin(chan, i); | 626 | isp_capture_request_unpin(chan, i); |
627 | complete(&capture->capture_resp); | ||
628 | } | ||
610 | 629 | ||
611 | return 0; | 630 | return 0; |
612 | 631 | ||
@@ -970,6 +989,15 @@ int isp_capture_program_request(struct tegra_isp_channel *chan, | |||
970 | return -EINVAL; | 989 | return -EINVAL; |
971 | } | 990 | } |
972 | 991 | ||
992 | mutex_lock(&capture->reset_lock); | ||
993 | if (capture->reset_capture_program_flag) { | ||
994 | /* consume any pending completions when coming out of reset */ | ||
995 | while (try_wait_for_completion(&capture->capture_program_resp)) | ||
996 | ; /* do nothing */ | ||
997 | } | ||
998 | capture->reset_capture_program_flag = false; | ||
999 | mutex_unlock(&capture->reset_lock); | ||
1000 | |||
973 | memset(&capture_msg, 0, sizeof(capture_msg)); | 1001 | memset(&capture_msg, 0, sizeof(capture_msg)); |
974 | capture_msg.header.msg_id = CAPTURE_ISP_PROGRAM_REQUEST_REQ; | 1002 | capture_msg.header.msg_id = CAPTURE_ISP_PROGRAM_REQUEST_REQ; |
975 | capture_msg.header.channel_id = capture->channel_id; | 1003 | capture_msg.header.channel_id = capture->channel_id; |
@@ -1048,6 +1076,13 @@ int isp_capture_program_status(struct tegra_isp_channel *chan) | |||
1048 | return err; | 1076 | return err; |
1049 | } | 1077 | } |
1050 | 1078 | ||
1079 | mutex_lock(&capture->reset_lock); | ||
1080 | if (capture->reset_capture_program_flag) { | ||
1081 | mutex_unlock(&capture->reset_lock); | ||
1082 | return -EIO; | ||
1083 | } | ||
1084 | mutex_unlock(&capture->reset_lock); | ||
1085 | |||
1051 | return 0; | 1086 | return 0; |
1052 | } | 1087 | } |
1053 | 1088 | ||
@@ -1084,6 +1119,15 @@ int isp_capture_request(struct tegra_isp_channel *chan, | |||
1084 | return -EINVAL; | 1119 | return -EINVAL; |
1085 | } | 1120 | } |
1086 | 1121 | ||
1122 | mutex_lock(&capture->reset_lock); | ||
1123 | if (capture->reset_capture_flag) { | ||
1124 | /* consume any pending completions when coming out of reset */ | ||
1125 | while (try_wait_for_completion(&capture->capture_resp)) | ||
1126 | ; /* do nothing */ | ||
1127 | } | ||
1128 | capture->reset_capture_flag = false; | ||
1129 | mutex_unlock(&capture->reset_lock); | ||
1130 | |||
1087 | memset(&capture_msg, 0, sizeof(capture_msg)); | 1131 | memset(&capture_msg, 0, sizeof(capture_msg)); |
1088 | capture_msg.header.msg_id = CAPTURE_ISP_REQUEST_REQ; | 1132 | capture_msg.header.msg_id = CAPTURE_ISP_REQUEST_REQ; |
1089 | capture_msg.header.channel_id = capture->channel_id; | 1133 | capture_msg.header.channel_id = capture->channel_id; |
@@ -1198,6 +1242,13 @@ int isp_capture_status(struct tegra_isp_channel *chan, | |||
1198 | return err; | 1242 | return err; |
1199 | } | 1243 | } |
1200 | 1244 | ||
1245 | mutex_lock(&capture->reset_lock); | ||
1246 | if (capture->reset_capture_flag) { | ||
1247 | mutex_unlock(&capture->reset_lock); | ||
1248 | return -EIO; | ||
1249 | } | ||
1250 | mutex_unlock(&capture->reset_lock); | ||
1251 | |||
1201 | return 0; | 1252 | return 0; |
1202 | } | 1253 | } |
1203 | 1254 | ||