aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/soc_camera
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2013-04-04 07:21:12 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-06-21 14:35:30 -0400
commitf7f6ce2d09c86bd80ee11bd654a1ac1e8f5dfe13 (patch)
treee2a2e6ea773f4ae593ba07693decdbac5cee3533 /drivers/media/platform/soc_camera
parentb9d4b2da35d44117831c3382710f12a1f9965ed5 (diff)
[media] soc-camera: move common code to soc_camera.c
All soc-camera host drivers include a pointer to an soc-camera device in their host private struct to check, that only one client is connected. Move this common code to soc_camera.c. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/platform/soc_camera')
-rw-r--r--drivers/media/platform/soc_camera/atmel-isi.c10
-rw-r--r--drivers/media/platform/soc_camera/mx1_camera.c20
-rw-r--r--drivers/media/platform/soc_camera/mx2_camera.c13
-rw-r--r--drivers/media/platform/soc_camera/mx3_camera.c9
-rw-r--r--drivers/media/platform/soc_camera/omap1_camera.c14
-rw-r--r--drivers/media/platform/soc_camera/pxa_camera.c18
-rw-r--r--drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c13
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c38
8 files changed, 48 insertions, 87 deletions
diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c
index 1abbb36d0755..c9e080a57a60 100644
--- a/drivers/media/platform/soc_camera/atmel-isi.c
+++ b/drivers/media/platform/soc_camera/atmel-isi.c
@@ -102,7 +102,6 @@ struct atmel_isi {
102 struct list_head video_buffer_list; 102 struct list_head video_buffer_list;
103 struct frame_buffer *active; 103 struct frame_buffer *active;
104 104
105 struct soc_camera_device *icd;
106 struct soc_camera_host soc_host; 105 struct soc_camera_host soc_host;
107}; 106};
108 107
@@ -367,7 +366,7 @@ static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer)
367 366
368 /* Check if already in a frame */ 367 /* Check if already in a frame */
369 if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) { 368 if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
370 dev_err(isi->icd->parent, "Already in frame handling.\n"); 369 dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n");
371 return; 370 return;
372 } 371 }
373 372
@@ -753,9 +752,6 @@ static int isi_camera_add_device(struct soc_camera_device *icd)
753 struct atmel_isi *isi = ici->priv; 752 struct atmel_isi *isi = ici->priv;
754 int ret; 753 int ret;
755 754
756 if (isi->icd)
757 return -EBUSY;
758
759 ret = clk_enable(isi->pclk); 755 ret = clk_enable(isi->pclk);
760 if (ret) 756 if (ret)
761 return ret; 757 return ret;
@@ -766,7 +762,6 @@ static int isi_camera_add_device(struct soc_camera_device *icd)
766 return ret; 762 return ret;
767 } 763 }
768 764
769 isi->icd = icd;
770 dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n", 765 dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n",
771 icd->devnum); 766 icd->devnum);
772 return 0; 767 return 0;
@@ -777,11 +772,8 @@ static void isi_camera_remove_device(struct soc_camera_device *icd)
777 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 772 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
778 struct atmel_isi *isi = ici->priv; 773 struct atmel_isi *isi = ici->priv;
779 774
780 BUG_ON(icd != isi->icd);
781
782 clk_disable(isi->mck); 775 clk_disable(isi->mck);
783 clk_disable(isi->pclk); 776 clk_disable(isi->pclk);
784 isi->icd = NULL;
785 777
786 dev_dbg(icd->parent, "Atmel ISI Camera driver detached from camera %d\n", 778 dev_dbg(icd->parent, "Atmel ISI Camera driver detached from camera %d\n",
787 icd->devnum); 779 icd->devnum);
diff --git a/drivers/media/platform/soc_camera/mx1_camera.c b/drivers/media/platform/soc_camera/mx1_camera.c
index a3fd8d63546c..5f9ec8efd978 100644
--- a/drivers/media/platform/soc_camera/mx1_camera.c
+++ b/drivers/media/platform/soc_camera/mx1_camera.c
@@ -104,7 +104,6 @@ struct mx1_buffer {
104 */ 104 */
105struct mx1_camera_dev { 105struct mx1_camera_dev {
106 struct soc_camera_host soc_host; 106 struct soc_camera_host soc_host;
107 struct soc_camera_device *icd;
108 struct mx1_camera_pdata *pdata; 107 struct mx1_camera_pdata *pdata;
109 struct mx1_buffer *active; 108 struct mx1_buffer *active;
110 struct resource *res; 109 struct resource *res;
@@ -220,7 +219,7 @@ out:
220static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev) 219static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
221{ 220{
222 struct videobuf_buffer *vbuf = &pcdev->active->vb; 221 struct videobuf_buffer *vbuf = &pcdev->active->vb;
223 struct device *dev = pcdev->icd->parent; 222 struct device *dev = pcdev->soc_host.icd->parent;
224 int ret; 223 int ret;
225 224
226 if (unlikely(!pcdev->active)) { 225 if (unlikely(!pcdev->active)) {
@@ -331,7 +330,7 @@ static void mx1_camera_wakeup(struct mx1_camera_dev *pcdev,
331static void mx1_camera_dma_irq(int channel, void *data) 330static void mx1_camera_dma_irq(int channel, void *data)
332{ 331{
333 struct mx1_camera_dev *pcdev = data; 332 struct mx1_camera_dev *pcdev = data;
334 struct device *dev = pcdev->icd->parent; 333 struct device *dev = pcdev->soc_host.icd->parent;
335 struct mx1_buffer *buf; 334 struct mx1_buffer *buf;
336 struct videobuf_buffer *vb; 335 struct videobuf_buffer *vb;
337 unsigned long flags; 336 unsigned long flags;
@@ -389,7 +388,7 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
389 */ 388 */
390 div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1; 389 div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
391 390
392 dev_dbg(pcdev->icd->parent, 391 dev_dbg(pcdev->soc_host.icd->parent,
393 "System clock %lukHz, target freq %dkHz, divisor %lu\n", 392 "System clock %lukHz, target freq %dkHz, divisor %lu\n",
394 lcdclk / 1000, mclk / 1000, div); 393 lcdclk / 1000, mclk / 1000, div);
395 394
@@ -400,7 +399,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
400{ 399{
401 unsigned int csicr1 = CSICR1_EN; 400 unsigned int csicr1 = CSICR1_EN;
402 401
403 dev_dbg(pcdev->icd->parent, "Activate device\n"); 402 dev_dbg(pcdev->soc_host.icd->parent, "Activate device\n");
404 403
405 clk_prepare_enable(pcdev->clk); 404 clk_prepare_enable(pcdev->clk);
406 405
@@ -416,7 +415,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
416 415
417static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) 416static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
418{ 417{
419 dev_dbg(pcdev->icd->parent, "Deactivate device\n"); 418 dev_dbg(pcdev->soc_host.icd->parent, "Deactivate device\n");
420 419
421 /* Disable all CSI interface */ 420 /* Disable all CSI interface */
422 __raw_writel(0x00, pcdev->base + CSICR1); 421 __raw_writel(0x00, pcdev->base + CSICR1);
@@ -433,16 +432,11 @@ static int mx1_camera_add_device(struct soc_camera_device *icd)
433 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 432 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
434 struct mx1_camera_dev *pcdev = ici->priv; 433 struct mx1_camera_dev *pcdev = ici->priv;
435 434
436 if (pcdev->icd)
437 return -EBUSY;
438
439 dev_info(icd->parent, "MX1 Camera driver attached to camera %d\n", 435 dev_info(icd->parent, "MX1 Camera driver attached to camera %d\n",
440 icd->devnum); 436 icd->devnum);
441 437
442 mx1_camera_activate(pcdev); 438 mx1_camera_activate(pcdev);
443 439
444 pcdev->icd = icd;
445
446 return 0; 440 return 0;
447} 441}
448 442
@@ -452,8 +446,6 @@ static void mx1_camera_remove_device(struct soc_camera_device *icd)
452 struct mx1_camera_dev *pcdev = ici->priv; 446 struct mx1_camera_dev *pcdev = ici->priv;
453 unsigned int csicr1; 447 unsigned int csicr1;
454 448
455 BUG_ON(icd != pcdev->icd);
456
457 /* disable interrupts */ 449 /* disable interrupts */
458 csicr1 = __raw_readl(pcdev->base + CSICR1) & ~CSI_IRQ_MASK; 450 csicr1 = __raw_readl(pcdev->base + CSICR1) & ~CSI_IRQ_MASK;
459 __raw_writel(csicr1, pcdev->base + CSICR1); 451 __raw_writel(csicr1, pcdev->base + CSICR1);
@@ -465,8 +457,6 @@ static void mx1_camera_remove_device(struct soc_camera_device *icd)
465 icd->devnum); 457 icd->devnum);
466 458
467 mx1_camera_deactivate(pcdev); 459 mx1_camera_deactivate(pcdev);
468
469 pcdev->icd = NULL;
470} 460}
471 461
472static int mx1_camera_set_bus_param(struct soc_camera_device *icd) 462static int mx1_camera_set_bus_param(struct soc_camera_device *icd)
diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c
index 5bbeb43e4531..772e0710f59b 100644
--- a/drivers/media/platform/soc_camera/mx2_camera.c
+++ b/drivers/media/platform/soc_camera/mx2_camera.c
@@ -236,7 +236,6 @@ enum mx2_camera_type {
236struct mx2_camera_dev { 236struct mx2_camera_dev {
237 struct device *dev; 237 struct device *dev;
238 struct soc_camera_host soc_host; 238 struct soc_camera_host soc_host;
239 struct soc_camera_device *icd;
240 struct clk *clk_emma_ahb, *clk_emma_ipg; 239 struct clk *clk_emma_ahb, *clk_emma_ipg;
241 struct clk *clk_csi_ahb, *clk_csi_per; 240 struct clk *clk_csi_ahb, *clk_csi_per;
242 241
@@ -394,8 +393,8 @@ static void mx27_update_emma_buf(struct mx2_camera_dev *pcdev,
394 writel(phys, pcdev->base_emma + 393 writel(phys, pcdev->base_emma +
395 PRP_DEST_Y_PTR - 0x14 * bufnum); 394 PRP_DEST_Y_PTR - 0x14 * bufnum);
396 if (prp->out_fmt == V4L2_PIX_FMT_YUV420) { 395 if (prp->out_fmt == V4L2_PIX_FMT_YUV420) {
397 u32 imgsize = pcdev->icd->user_height * 396 u32 imgsize = pcdev->soc_host.icd->user_height *
398 pcdev->icd->user_width; 397 pcdev->soc_host.icd->user_width;
399 398
400 writel(phys + imgsize, pcdev->base_emma + 399 writel(phys + imgsize, pcdev->base_emma +
401 PRP_DEST_CB_PTR - 0x14 * bufnum); 400 PRP_DEST_CB_PTR - 0x14 * bufnum);
@@ -424,9 +423,6 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
424 int ret; 423 int ret;
425 u32 csicr1; 424 u32 csicr1;
426 425
427 if (pcdev->icd)
428 return -EBUSY;
429
430 ret = clk_prepare_enable(pcdev->clk_csi_ahb); 426 ret = clk_prepare_enable(pcdev->clk_csi_ahb);
431 if (ret < 0) 427 if (ret < 0)
432 return ret; 428 return ret;
@@ -441,7 +437,6 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
441 pcdev->csicr1 = csicr1; 437 pcdev->csicr1 = csicr1;
442 writel(pcdev->csicr1, pcdev->base_csi + CSICR1); 438 writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
443 439
444 pcdev->icd = icd;
445 pcdev->frame_count = 0; 440 pcdev->frame_count = 0;
446 441
447 dev_info(icd->parent, "Camera driver attached to camera %d\n", 442 dev_info(icd->parent, "Camera driver attached to camera %d\n",
@@ -460,14 +455,10 @@ static void mx2_camera_remove_device(struct soc_camera_device *icd)
460 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 455 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
461 struct mx2_camera_dev *pcdev = ici->priv; 456 struct mx2_camera_dev *pcdev = ici->priv;
462 457
463 BUG_ON(icd != pcdev->icd);
464
465 dev_info(icd->parent, "Camera driver detached from camera %d\n", 458 dev_info(icd->parent, "Camera driver detached from camera %d\n",
466 icd->devnum); 459 icd->devnum);
467 460
468 mx2_camera_deactivate(pcdev); 461 mx2_camera_deactivate(pcdev);
469
470 pcdev->icd = NULL;
471} 462}
472 463
473/* 464/*
diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c
index 5da337736cd8..71b9b191957c 100644
--- a/drivers/media/platform/soc_camera/mx3_camera.c
+++ b/drivers/media/platform/soc_camera/mx3_camera.c
@@ -94,7 +94,6 @@ struct mx3_camera_dev {
94 * Interface. If anyone ever builds hardware to enable more than one 94 * Interface. If anyone ever builds hardware to enable more than one
95 * camera _simultaneously_, they will have to modify this driver too 95 * camera _simultaneously_, they will have to modify this driver too
96 */ 96 */
97 struct soc_camera_device *icd;
98 struct clk *clk; 97 struct clk *clk;
99 98
100 void __iomem *base; 99 void __iomem *base;
@@ -517,13 +516,9 @@ static int mx3_camera_add_device(struct soc_camera_device *icd)
517 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 516 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
518 struct mx3_camera_dev *mx3_cam = ici->priv; 517 struct mx3_camera_dev *mx3_cam = ici->priv;
519 518
520 if (mx3_cam->icd)
521 return -EBUSY;
522
523 mx3_camera_activate(mx3_cam, icd); 519 mx3_camera_activate(mx3_cam, icd);
524 520
525 mx3_cam->buf_total = 0; 521 mx3_cam->buf_total = 0;
526 mx3_cam->icd = icd;
527 522
528 dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n", 523 dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n",
529 icd->devnum); 524 icd->devnum);
@@ -538,8 +533,6 @@ static void mx3_camera_remove_device(struct soc_camera_device *icd)
538 struct mx3_camera_dev *mx3_cam = ici->priv; 533 struct mx3_camera_dev *mx3_cam = ici->priv;
539 struct idmac_channel **ichan = &mx3_cam->idmac_channel[0]; 534 struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
540 535
541 BUG_ON(icd != mx3_cam->icd);
542
543 if (*ichan) { 536 if (*ichan) {
544 dma_release_channel(&(*ichan)->dma_chan); 537 dma_release_channel(&(*ichan)->dma_chan);
545 *ichan = NULL; 538 *ichan = NULL;
@@ -547,8 +540,6 @@ static void mx3_camera_remove_device(struct soc_camera_device *icd)
547 540
548 clk_disable_unprepare(mx3_cam->clk); 541 clk_disable_unprepare(mx3_cam->clk);
549 542
550 mx3_cam->icd = NULL;
551
552 dev_info(icd->parent, "MX3 Camera driver detached from camera %d\n", 543 dev_info(icd->parent, "MX3 Camera driver detached from camera %d\n",
553 icd->devnum); 544 icd->devnum);
554} 545}
diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c
index 9689a6e89b7f..c42c23e4eb72 100644
--- a/drivers/media/platform/soc_camera/omap1_camera.c
+++ b/drivers/media/platform/soc_camera/omap1_camera.c
@@ -150,7 +150,6 @@ struct omap1_cam_buf {
150 150
151struct omap1_cam_dev { 151struct omap1_cam_dev {
152 struct soc_camera_host soc_host; 152 struct soc_camera_host soc_host;
153 struct soc_camera_device *icd;
154 struct clk *clk; 153 struct clk *clk;
155 154
156 unsigned int irq; 155 unsigned int irq;
@@ -564,7 +563,7 @@ static void videobuf_done(struct omap1_cam_dev *pcdev,
564{ 563{
565 struct omap1_cam_buf *buf = pcdev->active; 564 struct omap1_cam_buf *buf = pcdev->active;
566 struct videobuf_buffer *vb; 565 struct videobuf_buffer *vb;
567 struct device *dev = pcdev->icd->parent; 566 struct device *dev = pcdev->soc_host.icd->parent;
568 567
569 if (WARN_ON(!buf)) { 568 if (WARN_ON(!buf)) {
570 suspend_capture(pcdev); 569 suspend_capture(pcdev);
@@ -790,7 +789,7 @@ out:
790static irqreturn_t cam_isr(int irq, void *data) 789static irqreturn_t cam_isr(int irq, void *data)
791{ 790{
792 struct omap1_cam_dev *pcdev = data; 791 struct omap1_cam_dev *pcdev = data;
793 struct device *dev = pcdev->icd->parent; 792 struct device *dev = pcdev->soc_host.icd->parent;
794 struct omap1_cam_buf *buf = pcdev->active; 793 struct omap1_cam_buf *buf = pcdev->active;
795 u32 it_status; 794 u32 it_status;
796 unsigned long flags; 795 unsigned long flags;
@@ -904,9 +903,6 @@ static int omap1_cam_add_device(struct soc_camera_device *icd)
904 struct omap1_cam_dev *pcdev = ici->priv; 903 struct omap1_cam_dev *pcdev = ici->priv;
905 u32 ctrlclock; 904 u32 ctrlclock;
906 905
907 if (pcdev->icd)
908 return -EBUSY;
909
910 clk_enable(pcdev->clk); 906 clk_enable(pcdev->clk);
911 907
912 /* setup sensor clock */ 908 /* setup sensor clock */
@@ -941,8 +937,6 @@ static int omap1_cam_add_device(struct soc_camera_device *icd)
941 937
942 sensor_reset(pcdev, false); 938 sensor_reset(pcdev, false);
943 939
944 pcdev->icd = icd;
945
946 dev_dbg(icd->parent, "OMAP1 Camera driver attached to camera %d\n", 940 dev_dbg(icd->parent, "OMAP1 Camera driver attached to camera %d\n",
947 icd->devnum); 941 icd->devnum);
948 return 0; 942 return 0;
@@ -954,8 +948,6 @@ static void omap1_cam_remove_device(struct soc_camera_device *icd)
954 struct omap1_cam_dev *pcdev = ici->priv; 948 struct omap1_cam_dev *pcdev = ici->priv;
955 u32 ctrlclock; 949 u32 ctrlclock;
956 950
957 BUG_ON(icd != pcdev->icd);
958
959 suspend_capture(pcdev); 951 suspend_capture(pcdev);
960 disable_capture(pcdev); 952 disable_capture(pcdev);
961 953
@@ -974,8 +966,6 @@ static void omap1_cam_remove_device(struct soc_camera_device *icd)
974 966
975 clk_disable(pcdev->clk); 967 clk_disable(pcdev->clk);
976 968
977 pcdev->icd = NULL;
978
979 dev_dbg(icd->parent, 969 dev_dbg(icd->parent,
980 "OMAP1 Camera driver detached from camera %d\n", icd->devnum); 970 "OMAP1 Camera driver detached from camera %d\n", icd->devnum);
981} 971}
diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c
index d665242e8207..686edf7c016c 100644
--- a/drivers/media/platform/soc_camera/pxa_camera.c
+++ b/drivers/media/platform/soc_camera/pxa_camera.c
@@ -200,7 +200,6 @@ struct pxa_camera_dev {
200 * interface. If anyone ever builds hardware to enable more than 200 * interface. If anyone ever builds hardware to enable more than
201 * one camera, they will have to modify this driver too 201 * one camera, they will have to modify this driver too
202 */ 202 */
203 struct soc_camera_device *icd;
204 struct clk *clk; 203 struct clk *clk;
205 204
206 unsigned int irq; 205 unsigned int irq;
@@ -966,13 +965,8 @@ static int pxa_camera_add_device(struct soc_camera_device *icd)
966 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 965 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
967 struct pxa_camera_dev *pcdev = ici->priv; 966 struct pxa_camera_dev *pcdev = ici->priv;
968 967
969 if (pcdev->icd)
970 return -EBUSY;
971
972 pxa_camera_activate(pcdev); 968 pxa_camera_activate(pcdev);
973 969
974 pcdev->icd = icd;
975
976 dev_info(icd->parent, "PXA Camera driver attached to camera %d\n", 970 dev_info(icd->parent, "PXA Camera driver attached to camera %d\n",
977 icd->devnum); 971 icd->devnum);
978 972
@@ -985,8 +979,6 @@ static void pxa_camera_remove_device(struct soc_camera_device *icd)
985 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 979 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
986 struct pxa_camera_dev *pcdev = ici->priv; 980 struct pxa_camera_dev *pcdev = ici->priv;
987 981
988 BUG_ON(icd != pcdev->icd);
989
990 dev_info(icd->parent, "PXA Camera driver detached from camera %d\n", 982 dev_info(icd->parent, "PXA Camera driver detached from camera %d\n",
991 icd->devnum); 983 icd->devnum);
992 984
@@ -999,8 +991,6 @@ static void pxa_camera_remove_device(struct soc_camera_device *icd)
999 DCSR(pcdev->dma_chans[2]) = 0; 991 DCSR(pcdev->dma_chans[2]) = 0;
1000 992
1001 pxa_camera_deactivate(pcdev); 993 pxa_camera_deactivate(pcdev);
1002
1003 pcdev->icd = NULL;
1004} 994}
1005 995
1006static int test_platform_param(struct pxa_camera_dev *pcdev, 996static int test_platform_param(struct pxa_camera_dev *pcdev,
@@ -1596,8 +1586,8 @@ static int pxa_camera_suspend(struct device *dev)
1596 pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR3); 1586 pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR3);
1597 pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR4); 1587 pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR4);
1598 1588
1599 if (pcdev->icd) { 1589 if (pcdev->soc_host.icd) {
1600 struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->icd); 1590 struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->soc_host.icd);
1601 ret = v4l2_subdev_call(sd, core, s_power, 0); 1591 ret = v4l2_subdev_call(sd, core, s_power, 0);
1602 if (ret == -ENOIOCTLCMD) 1592 if (ret == -ENOIOCTLCMD)
1603 ret = 0; 1593 ret = 0;
@@ -1622,8 +1612,8 @@ static int pxa_camera_resume(struct device *dev)
1622 __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR3); 1612 __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR3);
1623 __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR4); 1613 __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR4);
1624 1614
1625 if (pcdev->icd) { 1615 if (pcdev->soc_host.icd) {
1626 struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->icd); 1616 struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->soc_host.icd);
1627 ret = v4l2_subdev_call(sd, core, s_power, 1); 1617 ret = v4l2_subdev_call(sd, core, s_power, 1);
1628 if (ret == -ENOIOCTLCMD) 1618 if (ret == -ENOIOCTLCMD)
1629 ret = 0; 1619 ret = 0;
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
index 143d29fe0137..5b7d8e1dd448 100644
--- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
@@ -95,7 +95,6 @@ struct sh_mobile_ceu_buffer {
95 95
96struct sh_mobile_ceu_dev { 96struct sh_mobile_ceu_dev {
97 struct soc_camera_host ici; 97 struct soc_camera_host ici;
98 struct soc_camera_device *icd;
99 struct platform_device *csi2_pdev; 98 struct platform_device *csi2_pdev;
100 99
101 unsigned int irq; 100 unsigned int irq;
@@ -163,7 +162,7 @@ static u32 ceu_read(struct sh_mobile_ceu_dev *priv, unsigned long reg_offs)
163static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev) 162static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
164{ 163{
165 int i, success = 0; 164 int i, success = 0;
166 struct soc_camera_device *icd = pcdev->icd; 165 struct soc_camera_device *icd = pcdev->ici.icd;
167 166
168 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ 167 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
169 168
@@ -277,7 +276,7 @@ static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
277 */ 276 */
278static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) 277static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
279{ 278{
280 struct soc_camera_device *icd = pcdev->icd; 279 struct soc_camera_device *icd = pcdev->ici.icd;
281 dma_addr_t phys_addr_top, phys_addr_bottom; 280 dma_addr_t phys_addr_top, phys_addr_bottom;
282 unsigned long top1, top2; 281 unsigned long top1, top2;
283 unsigned long bottom1, bottom2; 282 unsigned long bottom1, bottom2;
@@ -552,9 +551,6 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
552 struct v4l2_subdev *csi2_sd; 551 struct v4l2_subdev *csi2_sd;
553 int ret; 552 int ret;
554 553
555 if (pcdev->icd)
556 return -EBUSY;
557
558 dev_info(icd->parent, 554 dev_info(icd->parent,
559 "SuperH Mobile CEU driver attached to camera %d\n", 555 "SuperH Mobile CEU driver attached to camera %d\n",
560 icd->devnum); 556 icd->devnum);
@@ -583,7 +579,6 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
583 */ 579 */
584 if (ret == -ENODEV && csi2_sd) 580 if (ret == -ENODEV && csi2_sd)
585 csi2_sd->grp_id = 0; 581 csi2_sd->grp_id = 0;
586 pcdev->icd = icd;
587 582
588 return 0; 583 return 0;
589} 584}
@@ -595,8 +590,6 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
595 struct sh_mobile_ceu_dev *pcdev = ici->priv; 590 struct sh_mobile_ceu_dev *pcdev = ici->priv;
596 struct v4l2_subdev *csi2_sd = find_csi2(pcdev); 591 struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
597 592
598 BUG_ON(icd != pcdev->icd);
599
600 v4l2_subdev_call(csi2_sd, core, s_power, 0); 593 v4l2_subdev_call(csi2_sd, core, s_power, 0);
601 if (csi2_sd) 594 if (csi2_sd)
602 csi2_sd->grp_id = 0; 595 csi2_sd->grp_id = 0;
@@ -618,8 +611,6 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
618 dev_info(icd->parent, 611 dev_info(icd->parent,
619 "SuperH Mobile CEU driver detached from camera %d\n", 612 "SuperH Mobile CEU driver detached from camera %d\n",
620 icd->devnum); 613 icd->devnum);
621
622 pcdev->icd = NULL;
623} 614}
624 615
625/* 616/*
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index 5099eebf994d..1e831009f914 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -504,6 +504,32 @@ static int soc_camera_set_fmt(struct soc_camera_device *icd,
504 return ici->ops->set_bus_param(icd); 504 return ici->ops->set_bus_param(icd);
505} 505}
506 506
507static int soc_camera_add_device(struct soc_camera_device *icd)
508{
509 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
510 int ret;
511
512 if (ici->icd)
513 return -EBUSY;
514
515 ret = ici->ops->add(icd);
516 if (!ret)
517 ici->icd = icd;
518
519 return ret;
520}
521
522static void soc_camera_remove_device(struct soc_camera_device *icd)
523{
524 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
525
526 if (WARN_ON(icd != ici->icd))
527 return;
528
529 ici->ops->remove(icd);
530 ici->icd = NULL;
531}
532
507static int soc_camera_open(struct file *file) 533static int soc_camera_open(struct file *file)
508{ 534{
509 struct video_device *vdev = video_devdata(file); 535 struct video_device *vdev = video_devdata(file);
@@ -567,7 +593,7 @@ static int soc_camera_open(struct file *file)
567 if (sdesc->subdev_desc.reset) 593 if (sdesc->subdev_desc.reset)
568 sdesc->subdev_desc.reset(icd->pdev); 594 sdesc->subdev_desc.reset(icd->pdev);
569 595
570 ret = ici->ops->add(icd); 596 ret = soc_camera_add_device(icd);
571 if (ret < 0) { 597 if (ret < 0) {
572 dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret); 598 dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret);
573 goto eiciadd; 599 goto eiciadd;
@@ -618,7 +644,7 @@ esfmt:
618eresume: 644eresume:
619 __soc_camera_power_off(icd); 645 __soc_camera_power_off(icd);
620epower: 646epower:
621 ici->ops->remove(icd); 647 soc_camera_remove_device(icd);
622eiciadd: 648eiciadd:
623 icd->use_count--; 649 icd->use_count--;
624 mutex_unlock(&ici->host_lock); 650 mutex_unlock(&ici->host_lock);
@@ -644,7 +670,7 @@ static int soc_camera_close(struct file *file)
644 vb2_queue_release(&icd->vb2_vidq); 670 vb2_queue_release(&icd->vb2_vidq);
645 __soc_camera_power_off(icd); 671 __soc_camera_power_off(icd);
646 672
647 ici->ops->remove(icd); 673 soc_camera_remove_device(icd);
648 } 674 }
649 675
650 if (icd->streamer == file) 676 if (icd->streamer == file)
@@ -1137,7 +1163,7 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1137 ssdd->reset(icd->pdev); 1163 ssdd->reset(icd->pdev);
1138 1164
1139 mutex_lock(&ici->host_lock); 1165 mutex_lock(&ici->host_lock);
1140 ret = ici->ops->add(icd); 1166 ret = soc_camera_add_device(icd);
1141 mutex_unlock(&ici->host_lock); 1167 mutex_unlock(&ici->host_lock);
1142 if (ret < 0) 1168 if (ret < 0)
1143 goto eadd; 1169 goto eadd;
@@ -1210,7 +1236,7 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1210 icd->field = mf.field; 1236 icd->field = mf.field;
1211 } 1237 }
1212 1238
1213 ici->ops->remove(icd); 1239 soc_camera_remove_device(icd);
1214 1240
1215 mutex_unlock(&ici->host_lock); 1241 mutex_unlock(&ici->host_lock);
1216 1242
@@ -1233,7 +1259,7 @@ eadddev:
1233 icd->vdev = NULL; 1259 icd->vdev = NULL;
1234evdc: 1260evdc:
1235 mutex_lock(&ici->host_lock); 1261 mutex_lock(&ici->host_lock);
1236 ici->ops->remove(icd); 1262 soc_camera_remove_device(icd);
1237 mutex_unlock(&ici->host_lock); 1263 mutex_unlock(&ici->host_lock);
1238eadd: 1264eadd:
1239 v4l2_ctrl_handler_free(&icd->ctrl_handler); 1265 v4l2_ctrl_handler_free(&icd->ctrl_handler);