aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 9c8b7c7b89ee..edb6ec3d2bcd 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -153,6 +153,40 @@ static u32 ceu_read(struct sh_mobile_ceu_dev *priv, unsigned long reg_offs)
153 return ioread32(priv->base + reg_offs); 153 return ioread32(priv->base + reg_offs);
154} 154}
155 155
156static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
157{
158 int i, success = 0;
159 struct soc_camera_device *icd = pcdev->icd;
160
161 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
162
163 /* wait CSTSR.CPTON bit */
164 for (i = 0; i < 1000; i++) {
165 if (!(ceu_read(pcdev, CSTSR) & 1)) {
166 success++;
167 break;
168 }
169 udelay(1);
170 }
171
172 /* wait CAPSR.CPKIL bit */
173 for (i = 0; i < 1000; i++) {
174 if (!(ceu_read(pcdev, CAPSR) & (1 << 16))) {
175 success++;
176 break;
177 }
178 udelay(1);
179 }
180
181
182 if (2 != success) {
183 dev_warn(&icd->dev, "soft reset time out\n");
184 return -EIO;
185 }
186
187 return 0;
188}
189
156/* 190/*
157 * Videobuf operations 191 * Videobuf operations
158 */ 192 */
@@ -407,13 +441,9 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
407 441
408 pm_runtime_get_sync(ici->v4l2_dev.dev); 442 pm_runtime_get_sync(ici->v4l2_dev.dev);
409 443
410 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
411 while (ceu_read(pcdev, CSTSR) & 1)
412 msleep(1);
413
414 pcdev->icd = icd; 444 pcdev->icd = icd;
415 445
416 return 0; 446 return sh_mobile_ceu_soft_reset(pcdev);
417} 447}
418 448
419/* Called with .video_lock held */ 449/* Called with .video_lock held */
@@ -427,7 +457,7 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
427 457
428 /* disable capture, disable interrupts */ 458 /* disable capture, disable interrupts */
429 ceu_write(pcdev, CEIER, 0); 459 ceu_write(pcdev, CEIER, 0);
430 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ 460 sh_mobile_ceu_soft_reset(pcdev);
431 461
432 /* make sure active buffer is canceled */ 462 /* make sure active buffer is canceled */
433 spin_lock_irqsave(&pcdev->lock, flags); 463 spin_lock_irqsave(&pcdev->lock, flags);