aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2013-12-15 21:49:42 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-07 05:09:15 -0500
commit112eee0c03eb86cb00f1c6769c7a0b05530d636b (patch)
treed1d344ab9fe86837179710155c2c80fde3fe91c4 /drivers/media/platform
parent661112cb7e343c36d8d7899c1c9e6d37271aafd4 (diff)
[media] omap3isp: Refactor modules stop failure handling
Modules failing to stop are fatal errors for the preview engine only. Flag that condition separately from the other stop failures to prepare support for more fatal errors. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Sakari Ailus <sakari.ailus@iki.fi> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/platform')
-rw-r--r--drivers/media/platform/omap3isp/isp.c36
-rw-r--r--drivers/media/platform/omap3isp/isp.h2
2 files changed, 24 insertions, 14 deletions
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 7e09c1dd137a..5807185262fe 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -873,15 +873,12 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
873 unsigned long flags; 873 unsigned long flags;
874 int ret; 874 int ret;
875 875
876 /* If the preview engine crashed it might not respond to read/write 876 /* Refuse to start streaming if an entity included in the pipeline has
877 * operations on the L4 bus. This would result in a bus fault and a 877 * crashed. This check must be performed before the loop below to avoid
878 * kernel oops. Refuse to start streaming in that case. This check must 878 * starting entities if the pipeline won't start anyway (those entities
879 * be performed before the loop below to avoid starting entities if the 879 * would then likely fail to stop, making the problem worse).
880 * pipeline won't start anyway (those entities would then likely fail to
881 * stop, making the problem worse).
882 */ 880 */
883 if ((pipe->entities & isp->crashed) & 881 if (pipe->entities & isp->crashed)
884 (1U << isp->isp_prev.subdev.entity.id))
885 return -EIO; 882 return -EIO;
886 883
887 spin_lock_irqsave(&pipe->lock, flags); 884 spin_lock_irqsave(&pipe->lock, flags);
@@ -1014,13 +1011,23 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
1014 else 1011 else
1015 ret = 0; 1012 ret = 0;
1016 1013
1014 /* Handle stop failures. An entity that fails to stop can
1015 * usually just be restarted. Flag the stop failure nonetheless
1016 * to trigger an ISP reset the next time the device is released,
1017 * just in case.
1018 *
1019 * The preview engine is a special case. A failure to stop can
1020 * mean a hardware crash. When that happens the preview engine
1021 * won't respond to read/write operations on the L4 bus anymore,
1022 * resulting in a bus fault and a kernel oops next time it gets
1023 * accessed. Mark it as crashed to prevent pipelines including
1024 * it from being started.
1025 */
1017 if (ret) { 1026 if (ret) {
1018 dev_info(isp->dev, "Unable to stop %s\n", subdev->name); 1027 dev_info(isp->dev, "Unable to stop %s\n", subdev->name);
1019 /* If the entity failed to stopped, assume it has 1028 isp->stop_failure = true;
1020 * crashed. Mark it as such, the ISP will be reset when 1029 if (subdev == &isp->isp_prev.subdev)
1021 * applications will release it. 1030 isp->crashed |= 1U << subdev->entity.id;
1022 */
1023 isp->crashed |= 1U << subdev->entity.id;
1024 failure = -ETIMEDOUT; 1031 failure = -ETIMEDOUT;
1025 } 1032 }
1026 } 1033 }
@@ -1225,6 +1232,7 @@ static int isp_reset(struct isp_device *isp)
1225 udelay(1); 1232 udelay(1);
1226 } 1233 }
1227 1234
1235 isp->stop_failure = false;
1228 isp->crashed = 0; 1236 isp->crashed = 0;
1229 return 0; 1237 return 0;
1230} 1238}
@@ -1636,7 +1644,7 @@ void omap3isp_put(struct isp_device *isp)
1636 /* Reset the ISP if an entity has failed to stop. This is the 1644 /* Reset the ISP if an entity has failed to stop. This is the
1637 * only way to recover from such conditions. 1645 * only way to recover from such conditions.
1638 */ 1646 */
1639 if (isp->crashed) 1647 if (isp->crashed || isp->stop_failure)
1640 isp_reset(isp); 1648 isp_reset(isp);
1641 isp_disable_clocks(isp); 1649 isp_disable_clocks(isp);
1642 } 1650 }
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index 5b91f8619886..081f5ec5a663 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -154,6 +154,7 @@ struct isp_xclk {
154 * regions. 154 * regions.
155 * @stat_lock: Spinlock for handling statistics 155 * @stat_lock: Spinlock for handling statistics
156 * @isp_mutex: Mutex for serializing requests to ISP. 156 * @isp_mutex: Mutex for serializing requests to ISP.
157 * @stop_failure: Indicates that an entity failed to stop.
157 * @crashed: Bitmask of crashed entities (indexed by entity ID) 158 * @crashed: Bitmask of crashed entities (indexed by entity ID)
158 * @has_context: Context has been saved at least once and can be restored. 159 * @has_context: Context has been saved at least once and can be restored.
159 * @ref_count: Reference count for handling multiple ISP requests. 160 * @ref_count: Reference count for handling multiple ISP requests.
@@ -191,6 +192,7 @@ struct isp_device {
191 /* ISP Obj */ 192 /* ISP Obj */
192 spinlock_t stat_lock; /* common lock for statistic drivers */ 193 spinlock_t stat_lock; /* common lock for statistic drivers */
193 struct mutex isp_mutex; /* For handling ref_count field */ 194 struct mutex isp_mutex; /* For handling ref_count field */
195 bool stop_failure;
194 u32 crashed; 196 u32 crashed;
195 int has_context; 197 int has_context;
196 int ref_count; 198 int ref_count;