aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2011-07-01 10:19:58 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-07-27 16:56:08 -0400
commit6b526fed0e688e3926bd43a09f2f36cba3983ce2 (patch)
treec45123c4f78a64e54811ee46c30d3c26da8e3c9f /drivers/media
parent91c7953005247c9563408bbdbf35e27de33e6ec3 (diff)
[media] V4L: sh_mobile_csi2: switch away from using the soc-camera bus notifier
This moves us one more step closer to eliminating the soc-camera bus and devices on it. Besides, as a side effect, CSI-2 runtime PM on sh-mobile secomes finer grained now: we only have to power on the interface, when the device nodes are open. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Acked-by: Paul Mundt <lethal@linux-sh.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c117
-rw-r--r--drivers/media/video/sh_mobile_csi2.c135
2 files changed, 162 insertions, 90 deletions
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 33e126e43b1f..152a65993286 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -38,6 +38,7 @@
38#include <media/v4l2-dev.h> 38#include <media/v4l2-dev.h>
39#include <media/soc_camera.h> 39#include <media/soc_camera.h>
40#include <media/sh_mobile_ceu.h> 40#include <media/sh_mobile_ceu.h>
41#include <media/sh_mobile_csi2.h>
41#include <media/videobuf2-dma-contig.h> 42#include <media/videobuf2-dma-contig.h>
42#include <media/v4l2-mediabus.h> 43#include <media/v4l2-mediabus.h>
43#include <media/soc_mediabus.h> 44#include <media/soc_mediabus.h>
@@ -95,6 +96,7 @@ struct sh_mobile_ceu_buffer {
95struct sh_mobile_ceu_dev { 96struct sh_mobile_ceu_dev {
96 struct soc_camera_host ici; 97 struct soc_camera_host ici;
97 struct soc_camera_device *icd; 98 struct soc_camera_device *icd;
99 struct platform_device *csi2_pdev;
98 100
99 unsigned int irq; 101 unsigned int irq;
100 void __iomem *base; 102 void __iomem *base;
@@ -498,11 +500,26 @@ out:
498 return IRQ_HANDLED; 500 return IRQ_HANDLED;
499} 501}
500 502
503static struct v4l2_subdev *find_csi2(struct sh_mobile_ceu_dev *pcdev)
504{
505 struct v4l2_subdev *sd;
506
507 if (!pcdev->csi2_pdev)
508 return NULL;
509
510 v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev)
511 if (&pcdev->csi2_pdev->dev == v4l2_get_subdevdata(sd))
512 return sd;
513
514 return NULL;
515}
516
501/* Called with .video_lock held */ 517/* Called with .video_lock held */
502static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) 518static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
503{ 519{
504 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 520 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
505 struct sh_mobile_ceu_dev *pcdev = ici->priv; 521 struct sh_mobile_ceu_dev *pcdev = ici->priv;
522 struct v4l2_subdev *csi2_sd;
506 int ret; 523 int ret;
507 524
508 if (pcdev->icd) 525 if (pcdev->icd)
@@ -515,8 +532,16 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
515 pm_runtime_get_sync(ici->v4l2_dev.dev); 532 pm_runtime_get_sync(ici->v4l2_dev.dev);
516 533
517 ret = sh_mobile_ceu_soft_reset(pcdev); 534 ret = sh_mobile_ceu_soft_reset(pcdev);
518 if (!ret) 535
536 csi2_sd = find_csi2(pcdev);
537
538 ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
539 if (ret != -ENODEV && ret != -ENOIOCTLCMD && ret < 0) {
540 pm_runtime_put_sync(ici->v4l2_dev.dev);
541 } else {
519 pcdev->icd = icd; 542 pcdev->icd = icd;
543 ret = 0;
544 }
520 545
521 return ret; 546 return ret;
522} 547}
@@ -526,9 +551,11 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
526{ 551{
527 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 552 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
528 struct sh_mobile_ceu_dev *pcdev = ici->priv; 553 struct sh_mobile_ceu_dev *pcdev = ici->priv;
554 struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
529 555
530 BUG_ON(icd != pcdev->icd); 556 BUG_ON(icd != pcdev->icd);
531 557
558 v4l2_subdev_call(csi2_sd, core, s_power, 0);
532 /* disable capture, disable interrupts */ 559 /* disable capture, disable interrupts */
533 ceu_write(pcdev, CEIER, 0); 560 ceu_write(pcdev, CEIER, 0);
534 sh_mobile_ceu_soft_reset(pcdev); 561 sh_mobile_ceu_soft_reset(pcdev);
@@ -640,7 +667,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
640 } 667 }
641 668
642 /* CSI2 special configuration */ 669 /* CSI2 special configuration */
643 if (pcdev->pdata->csi2_dev) { 670 if (pcdev->pdata->csi2) {
644 in_width = ((in_width - 2) * 2); 671 in_width = ((in_width - 2) * 2);
645 left_offset *= 2; 672 left_offset *= 2;
646 } 673 }
@@ -782,7 +809,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
782 value |= pcdev->is_16bit ? 1 << 12 : 0; 809 value |= pcdev->is_16bit ? 1 << 12 : 0;
783 810
784 /* CSI2 mode */ 811 /* CSI2 mode */
785 if (pcdev->pdata->csi2_dev) 812 if (pcdev->pdata->csi2)
786 value |= 3 << 12; 813 value |= 3 << 12;
787 814
788 ceu_write(pcdev, CAMCR, value); 815 ceu_write(pcdev, CAMCR, value);
@@ -920,7 +947,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
920 return 0; 947 return 0;
921 } 948 }
922 949
923 if (!pcdev->pdata->csi2_dev) { 950 if (!pcdev->pdata->csi2) {
924 ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); 951 ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample);
925 if (ret < 0) 952 if (ret < 0)
926 return 0; 953 return 0;
@@ -1943,7 +1970,7 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
1943 .completion = COMPLETION_INITIALIZER_ONSTACK(wait.completion), 1970 .completion = COMPLETION_INITIALIZER_ONSTACK(wait.completion),
1944 .notifier.notifier_call = bus_notify, 1971 .notifier.notifier_call = bus_notify,
1945 }; 1972 };
1946 struct device *csi2; 1973 struct sh_mobile_ceu_companion *csi2;
1947 1974
1948 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1975 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1949 irq = platform_get_irq(pdev, 0); 1976 irq = platform_get_irq(pdev, 0);
@@ -2016,26 +2043,61 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
2016 pcdev->ici.drv_name = dev_name(&pdev->dev); 2043 pcdev->ici.drv_name = dev_name(&pdev->dev);
2017 pcdev->ici.ops = &sh_mobile_ceu_host_ops; 2044 pcdev->ici.ops = &sh_mobile_ceu_host_ops;
2018 2045
2046 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
2047 if (IS_ERR(pcdev->alloc_ctx)) {
2048 err = PTR_ERR(pcdev->alloc_ctx);
2049 goto exit_free_clk;
2050 }
2051
2052 err = soc_camera_host_register(&pcdev->ici);
2053 if (err)
2054 goto exit_free_ctx;
2055
2019 /* CSI2 interfacing */ 2056 /* CSI2 interfacing */
2020 csi2 = pcdev->pdata->csi2_dev; 2057 csi2 = pcdev->pdata->csi2;
2021 if (csi2) { 2058 if (csi2) {
2022 wait.dev = csi2; 2059 struct platform_device *csi2_pdev =
2060 platform_device_alloc("sh-mobile-csi2", csi2->id);
2061 struct sh_csi2_pdata *csi2_pdata = csi2->platform_data;
2062
2063 if (!csi2_pdev) {
2064 err = -ENOMEM;
2065 goto exit_host_unregister;
2066 }
2067
2068 pcdev->csi2_pdev = csi2_pdev;
2069
2070 err = platform_device_add_data(csi2_pdev, csi2_pdata, sizeof(*csi2_pdata));
2071 if (err < 0)
2072 goto exit_pdev_put;
2073
2074 csi2_pdata = csi2_pdev->dev.platform_data;
2075 csi2_pdata->v4l2_dev = &pcdev->ici.v4l2_dev;
2076
2077 csi2_pdev->resource = csi2->resource;
2078 csi2_pdev->num_resources = csi2->num_resources;
2079
2080 err = platform_device_add(csi2_pdev);
2081 if (err < 0)
2082 goto exit_pdev_put;
2083
2084 wait.dev = &csi2_pdev->dev;
2023 2085
2024 err = bus_register_notifier(&platform_bus_type, &wait.notifier); 2086 err = bus_register_notifier(&platform_bus_type, &wait.notifier);
2025 if (err < 0) 2087 if (err < 0)
2026 goto exit_free_clk; 2088 goto exit_pdev_unregister;
2027 2089
2028 /* 2090 /*
2029 * From this point the driver module will not unload, until 2091 * From this point the driver module will not unload, until
2030 * we complete the completion. 2092 * we complete the completion.
2031 */ 2093 */
2032 2094
2033 if (!csi2->driver) { 2095 if (!csi2_pdev->dev.driver) {
2034 complete(&wait.completion); 2096 complete(&wait.completion);
2035 /* Either too late, or probing failed */ 2097 /* Either too late, or probing failed */
2036 bus_unregister_notifier(&platform_bus_type, &wait.notifier); 2098 bus_unregister_notifier(&platform_bus_type, &wait.notifier);
2037 err = -ENXIO; 2099 err = -ENXIO;
2038 goto exit_free_clk; 2100 goto exit_pdev_unregister;
2039 } 2101 }
2040 2102
2041 /* 2103 /*
@@ -2044,34 +2106,28 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
2044 * the "owner" is safe! 2106 * the "owner" is safe!
2045 */ 2107 */
2046 2108
2047 err = try_module_get(csi2->driver->owner); 2109 err = try_module_get(csi2_pdev->dev.driver->owner);
2048 2110
2049 /* Let notifier complete, if it has been locked */ 2111 /* Let notifier complete, if it has been locked */
2050 complete(&wait.completion); 2112 complete(&wait.completion);
2051 bus_unregister_notifier(&platform_bus_type, &wait.notifier); 2113 bus_unregister_notifier(&platform_bus_type, &wait.notifier);
2052 if (!err) { 2114 if (!err) {
2053 err = -ENODEV; 2115 err = -ENODEV;
2054 goto exit_free_clk; 2116 goto exit_pdev_unregister;
2055 } 2117 }
2056 } 2118 }
2057 2119
2058 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
2059 if (IS_ERR(pcdev->alloc_ctx)) {
2060 err = PTR_ERR(pcdev->alloc_ctx);
2061 goto exit_module_put;
2062 }
2063
2064 err = soc_camera_host_register(&pcdev->ici);
2065 if (err)
2066 goto exit_free_ctx;
2067
2068 return 0; 2120 return 0;
2069 2121
2122exit_pdev_unregister:
2123 platform_device_del(pcdev->csi2_pdev);
2124exit_pdev_put:
2125 pcdev->csi2_pdev->resource = NULL;
2126 platform_device_put(pcdev->csi2_pdev);
2127exit_host_unregister:
2128 soc_camera_host_unregister(&pcdev->ici);
2070exit_free_ctx: 2129exit_free_ctx:
2071 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); 2130 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
2072exit_module_put:
2073 if (csi2 && csi2->driver)
2074 module_put(csi2->driver->owner);
2075exit_free_clk: 2131exit_free_clk:
2076 pm_runtime_disable(&pdev->dev); 2132 pm_runtime_disable(&pdev->dev);
2077 free_irq(pcdev->irq, pcdev); 2133 free_irq(pcdev->irq, pcdev);
@@ -2091,7 +2147,7 @@ static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
2091 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); 2147 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
2092 struct sh_mobile_ceu_dev *pcdev = container_of(soc_host, 2148 struct sh_mobile_ceu_dev *pcdev = container_of(soc_host,
2093 struct sh_mobile_ceu_dev, ici); 2149 struct sh_mobile_ceu_dev, ici);
2094 struct device *csi2 = pcdev->pdata->csi2_dev; 2150 struct platform_device *csi2_pdev = pcdev->csi2_pdev;
2095 2151
2096 soc_camera_host_unregister(soc_host); 2152 soc_camera_host_unregister(soc_host);
2097 pm_runtime_disable(&pdev->dev); 2153 pm_runtime_disable(&pdev->dev);
@@ -2100,8 +2156,13 @@ static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
2100 dma_release_declared_memory(&pdev->dev); 2156 dma_release_declared_memory(&pdev->dev);
2101 iounmap(pcdev->base); 2157 iounmap(pcdev->base);
2102 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); 2158 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
2103 if (csi2 && csi2->driver) 2159 if (csi2_pdev && csi2_pdev->dev.driver) {
2104 module_put(csi2->driver->owner); 2160 struct module *csi2_drv = csi2_pdev->dev.driver->owner;
2161 platform_device_del(csi2_pdev);
2162 csi2_pdev->resource = NULL;
2163 platform_device_put(csi2_pdev);
2164 module_put(csi2_drv);
2165 }
2105 kfree(pcdev); 2166 kfree(pcdev);
2106 2167
2107 return 0; 2168 return 0;
diff --git a/drivers/media/video/sh_mobile_csi2.c b/drivers/media/video/sh_mobile_csi2.c
index 98b87481fa94..2893a0134c7e 100644
--- a/drivers/media/video/sh_mobile_csi2.c
+++ b/drivers/media/video/sh_mobile_csi2.c
@@ -16,6 +16,7 @@
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/videodev2.h> 17#include <linux/videodev2.h>
18 18
19#include <media/sh_mobile_ceu.h>
19#include <media/sh_mobile_csi2.h> 20#include <media/sh_mobile_csi2.h>
20#include <media/soc_camera.h> 21#include <media/soc_camera.h>
21#include <media/v4l2-common.h> 22#include <media/v4l2-common.h>
@@ -33,7 +34,6 @@
33struct sh_csi2 { 34struct sh_csi2 {
34 struct v4l2_subdev subdev; 35 struct v4l2_subdev subdev;
35 struct list_head list; 36 struct list_head list;
36 struct notifier_block notifier;
37 unsigned int irq; 37 unsigned int irq;
38 void __iomem *base; 38 void __iomem *base;
39 struct platform_device *pdev; 39 struct platform_device *pdev;
@@ -132,13 +132,6 @@ static struct v4l2_subdev_video_ops sh_csi2_subdev_video_ops = {
132 .try_mbus_fmt = sh_csi2_try_fmt, 132 .try_mbus_fmt = sh_csi2_try_fmt,
133}; 133};
134 134
135static struct v4l2_subdev_core_ops sh_csi2_subdev_core_ops;
136
137static struct v4l2_subdev_ops sh_csi2_subdev_ops = {
138 .core = &sh_csi2_subdev_core_ops,
139 .video = &sh_csi2_subdev_video_ops,
140};
141
142static void sh_csi2_hwinit(struct sh_csi2 *priv) 135static void sh_csi2_hwinit(struct sh_csi2 *priv)
143{ 136{
144 struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; 137 struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data;
@@ -186,65 +179,84 @@ static unsigned long sh_csi2_query_bus_param(struct soc_camera_device *icd)
186 return soc_camera_apply_sensor_flags(icl, flags); 179 return soc_camera_apply_sensor_flags(icl, flags);
187} 180}
188 181
189static int sh_csi2_notify(struct notifier_block *nb, 182static int sh_csi2_client_connect(struct sh_csi2 *priv)
190 unsigned long action, void *data)
191{ 183{
192 struct device *dev = data;
193 struct soc_camera_device *icd = to_soc_camera_dev(dev);
194 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev->parent);
195 struct sh_csi2 *priv =
196 container_of(nb, struct sh_csi2, notifier);
197 struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; 184 struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data;
198 int ret, i; 185 struct v4l2_subdev *sd, *csi2_sd = &priv->subdev;
186 struct soc_camera_device *icd = NULL;
187 struct device *dev = v4l2_get_subdevdata(&priv->subdev);
188 int i;
189
190 v4l2_device_for_each_subdev(sd, csi2_sd->v4l2_dev)
191 if (sd->grp_id) {
192 icd = (struct soc_camera_device *)sd->grp_id;
193 break;
194 }
195
196 if (!icd)
197 return -EINVAL;
199 198
200 for (i = 0; i < pdata->num_clients; i++) 199 for (i = 0; i < pdata->num_clients; i++)
201 if (&pdata->clients[i].pdev->dev == icd->pdev) 200 if (&pdata->clients[i].pdev->dev == icd->pdev)
202 break; 201 break;
203 202
204 dev_dbg(dev, "%s(%p): action = %lu, found #%d\n", __func__, dev, action, i); 203 dev_dbg(dev, "%s(%p): found #%d\n", __func__, dev, i);
205 204
206 if (i == pdata->num_clients) 205 if (i == pdata->num_clients)
207 return NOTIFY_DONE; 206 return -ENODEV;
208 207
209 switch (action) { 208 priv->client = pdata->clients + i;
210 case BUS_NOTIFY_BOUND_DRIVER:
211 snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s%s",
212 dev_name(v4l2_dev->dev), ".mipi-csi");
213 priv->subdev.grp_id = (long)icd;
214 ret = v4l2_device_register_subdev(v4l2_dev, &priv->subdev);
215 dev_dbg(dev, "%s(%p): ret(register_subdev) = %d\n", __func__, priv, ret);
216 if (ret < 0)
217 return NOTIFY_DONE;
218 209
219 priv->client = pdata->clients + i; 210 priv->set_bus_param = icd->ops->set_bus_param;
211 priv->query_bus_param = icd->ops->query_bus_param;
212 icd->ops->set_bus_param = sh_csi2_set_bus_param;
213 icd->ops->query_bus_param = sh_csi2_query_bus_param;
220 214
221 priv->set_bus_param = icd->ops->set_bus_param; 215 csi2_sd->grp_id = (long)icd;
222 priv->query_bus_param = icd->ops->query_bus_param;
223 icd->ops->set_bus_param = sh_csi2_set_bus_param;
224 icd->ops->query_bus_param = sh_csi2_query_bus_param;
225 216
226 pm_runtime_get_sync(v4l2_get_subdevdata(&priv->subdev)); 217 pm_runtime_get_sync(dev);
227 218
228 sh_csi2_hwinit(priv); 219 sh_csi2_hwinit(priv);
229 break;
230 case BUS_NOTIFY_UNBIND_DRIVER:
231 priv->client = NULL;
232 220
233 /* Driver is about to be unbound */ 221 return 0;
234 icd->ops->set_bus_param = priv->set_bus_param; 222}
235 icd->ops->query_bus_param = priv->query_bus_param;
236 priv->set_bus_param = NULL;
237 priv->query_bus_param = NULL;
238 223
239 v4l2_device_unregister_subdev(&priv->subdev); 224static void sh_csi2_client_disconnect(struct sh_csi2 *priv)
225{
226 struct soc_camera_device *icd = (struct soc_camera_device *)priv->subdev.grp_id;
240 227
241 pm_runtime_put(v4l2_get_subdevdata(&priv->subdev)); 228 priv->client = NULL;
242 break; 229 priv->subdev.grp_id = 0;
243 }
244 230
245 return NOTIFY_OK; 231 /* Driver is about to be unbound */
232 icd->ops->set_bus_param = priv->set_bus_param;
233 icd->ops->query_bus_param = priv->query_bus_param;
234 priv->set_bus_param = NULL;
235 priv->query_bus_param = NULL;
236
237 pm_runtime_put(v4l2_get_subdevdata(&priv->subdev));
246} 238}
247 239
240static int sh_csi2_s_power(struct v4l2_subdev *sd, int on)
241{
242 struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev);
243
244 if (on)
245 return sh_csi2_client_connect(priv);
246
247 sh_csi2_client_disconnect(priv);
248 return 0;
249}
250
251static struct v4l2_subdev_core_ops sh_csi2_subdev_core_ops = {
252 .s_power = sh_csi2_s_power,
253};
254
255static struct v4l2_subdev_ops sh_csi2_subdev_ops = {
256 .core = &sh_csi2_subdev_core_ops,
257 .video = &sh_csi2_subdev_video_ops,
258};
259
248static __devinit int sh_csi2_probe(struct platform_device *pdev) 260static __devinit int sh_csi2_probe(struct platform_device *pdev)
249{ 261{
250 struct resource *res; 262 struct resource *res;
@@ -274,14 +286,6 @@ static __devinit int sh_csi2_probe(struct platform_device *pdev)
274 return -ENOMEM; 286 return -ENOMEM;
275 287
276 priv->irq = irq; 288 priv->irq = irq;
277 priv->notifier.notifier_call = sh_csi2_notify;
278
279 /* We MUST attach after the MIPI sensor */
280 ret = bus_register_notifier(&soc_camera_bus_type, &priv->notifier);
281 if (ret < 0) {
282 dev_err(&pdev->dev, "CSI2 cannot register notifier\n");
283 goto ernotify;
284 }
285 289
286 if (!request_mem_region(res->start, resource_size(res), pdev->name)) { 290 if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
287 dev_err(&pdev->dev, "CSI2 register region already claimed\n"); 291 dev_err(&pdev->dev, "CSI2 register region already claimed\n");
@@ -297,11 +301,17 @@ static __devinit int sh_csi2_probe(struct platform_device *pdev)
297 } 301 }
298 302
299 priv->pdev = pdev; 303 priv->pdev = pdev;
304 platform_set_drvdata(pdev, priv);
300 305
301 v4l2_subdev_init(&priv->subdev, &sh_csi2_subdev_ops); 306 v4l2_subdev_init(&priv->subdev, &sh_csi2_subdev_ops);
302 v4l2_set_subdevdata(&priv->subdev, &pdev->dev); 307 v4l2_set_subdevdata(&priv->subdev, &pdev->dev);
303 308
304 platform_set_drvdata(pdev, priv); 309 snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s.mipi-csi",
310 dev_name(pdata->v4l2_dev->dev));
311 ret = v4l2_device_register_subdev(pdata->v4l2_dev, &priv->subdev);
312 dev_dbg(&pdev->dev, "%s(%p): ret(register_subdev) = %d\n", __func__, priv, ret);
313 if (ret < 0)
314 goto esdreg;
305 315
306 pm_runtime_enable(&pdev->dev); 316 pm_runtime_enable(&pdev->dev);
307 317
@@ -309,11 +319,11 @@ static __devinit int sh_csi2_probe(struct platform_device *pdev)
309 319
310 return 0; 320 return 0;
311 321
322esdreg:
323 iounmap(priv->base);
312eremap: 324eremap:
313 release_mem_region(res->start, resource_size(res)); 325 release_mem_region(res->start, resource_size(res));
314ereqreg: 326ereqreg:
315 bus_unregister_notifier(&soc_camera_bus_type, &priv->notifier);
316ernotify:
317 kfree(priv); 327 kfree(priv);
318 328
319 return ret; 329 return ret;
@@ -324,7 +334,7 @@ static __devexit int sh_csi2_remove(struct platform_device *pdev)
324 struct sh_csi2 *priv = platform_get_drvdata(pdev); 334 struct sh_csi2 *priv = platform_get_drvdata(pdev);
325 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 335 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
326 336
327 bus_unregister_notifier(&soc_camera_bus_type, &priv->notifier); 337 v4l2_device_unregister_subdev(&priv->subdev);
328 pm_runtime_disable(&pdev->dev); 338 pm_runtime_disable(&pdev->dev);
329 iounmap(priv->base); 339 iounmap(priv->base);
330 release_mem_region(res->start, resource_size(res)); 340 release_mem_region(res->start, resource_size(res));
@@ -335,8 +345,9 @@ static __devexit int sh_csi2_remove(struct platform_device *pdev)
335} 345}
336 346
337static struct platform_driver __refdata sh_csi2_pdrv = { 347static struct platform_driver __refdata sh_csi2_pdrv = {
338 .remove = __devexit_p(sh_csi2_remove), 348 .remove = __devexit_p(sh_csi2_remove),
339 .driver = { 349 .probe = sh_csi2_probe,
350 .driver = {
340 .name = "sh-mobile-csi2", 351 .name = "sh-mobile-csi2",
341 .owner = THIS_MODULE, 352 .owner = THIS_MODULE,
342 }, 353 },
@@ -344,7 +355,7 @@ static struct platform_driver __refdata sh_csi2_pdrv = {
344 355
345static int __init sh_csi2_init(void) 356static int __init sh_csi2_init(void)
346{ 357{
347 return platform_driver_probe(&sh_csi2_pdrv, sh_csi2_probe); 358 return platform_driver_register(&sh_csi2_pdrv);
348} 359}
349 360
350static void __exit sh_csi2_exit(void) 361static void __exit sh_csi2_exit(void)