xref: /linux/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c (revision 9f2c9170934eace462499ba0bfe042cc72900173)
1 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2 /*
3  * Rockchip ISP1 Driver - Base driver
4  *
5  * Copyright (C) 2019 Collabora, Ltd.
6  *
7  * Based on Rockchip ISP1 driver by Rockchip Electronics Co., Ltd.
8  * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
9  */
10 
11 #include <linux/clk.h>
12 #include <linux/interrupt.h>
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/of_graph.h>
16 #include <linux/of_platform.h>
17 #include <linux/pinctrl/consumer.h>
18 #include <linux/pm_runtime.h>
19 #include <media/v4l2-fwnode.h>
20 #include <media/v4l2-mc.h>
21 
22 #include "rkisp1-common.h"
23 #include "rkisp1-csi.h"
24 
25 /*
26  * ISP Details
27  * -----------
28  *
29  * ISP Comprises with:
30  *	MIPI serial camera interface
31  *	Image Signal Processing
32  *	Many Image Enhancement Blocks
33  *	Crop
34  *	Resizer
35  *	RBG display ready image
36  *	Image Rotation
37  *
38  * ISP Block Diagram
39  * -----------------
40  *                                                             rkisp1-resizer.c          rkisp1-capture.c
41  *                                                          |====================|  |=======================|
42  *                                rkisp1-isp.c                              Main Picture Path
43  *                        |==========================|      |===============================================|
44  *                        +-----------+  +--+--+--+--+      +--------+  +--------+              +-----------+
45  *                        |           |  |  |  |  |  |      |        |  |        |              |           |
46  * +--------+    |\       |           |  |  |  |  |  |   -->|  Crop  |->|  RSZ   |------------->|           |
47  * |  MIPI  |--->|  \     |           |  |  |  |  |  |   |  |        |  |        |              |           |
48  * +--------+    |   |    |           |  |IE|IE|IE|IE|   |  +--------+  +--------+              |  Memory   |
49  *               |MUX|--->|    ISP    |->|0 |1 |2 |3 |---+                                      | Interface |
50  * +--------+    |   |    |           |  |  |  |  |  |   |  +--------+  +--------+  +--------+  |           |
51  * |Parallel|--->|  /     |           |  |  |  |  |  |   |  |        |  |        |  |        |  |           |
52  * +--------+    |/       |           |  |  |  |  |  |   -->|  Crop  |->|  RSZ   |->|  RGB   |->|           |
53  *                        |           |  |  |  |  |  |      |        |  |        |  | Rotate |  |           |
54  *                        +-----------+  +--+--+--+--+      +--------+  +--------+  +--------+  +-----------+
55  *                                               ^
56  * +--------+                                    |          |===============================================|
57  * |  DMA   |------------------------------------+                          Self Picture Path
58  * +--------+
59  *
60  *         rkisp1-stats.c        rkisp1-params.c
61  *       |===============|      |===============|
62  *       +---------------+      +---------------+
63  *       |               |      |               |
64  *       |      ISP      |      |      ISP      |
65  *       |               |      |               |
66  *       +---------------+      +---------------+
67  *
68  *
69  * Media Topology
70  * --------------
71  *
72  *          +----------+       +----------+
73  *          | Sensor 1 |       | Sensor X |
74  *          ------------  ...  ------------
75  *          |    0     |       |    0     |
76  *          +----------+       +----------+
77  *               |                  |
78  *                \----\       /----/
79  *                     |       |
80  *                     v       v
81  *                  +-------------+
82  *                  |      0      |
83  *                  ---------------
84  *                  |  CSI-2 RX   |
85  *                  ---------------         +-----------+
86  *                  |      1      |         |  params   |
87  *                  +-------------+         | (output)  |
88  *                         |               +-----------+
89  *                         v                     |
90  *                      +------+------+          |
91  *                      |  0   |  1   |<---------+
92  *                      |------+------|
93  *                      |     ISP     |
94  *                      |------+------|
95  *        +-------------|  2   |  3   |----------+
96  *        |             +------+------+          |
97  *        |                |                     |
98  *        v                v                     v
99  *  +- ---------+    +-----------+         +-----------+
100  *  |     0     |    |     0     |         |   stats   |
101  *  -------------    -------------         | (capture) |
102  *  |  Resizer  |    |  Resizer  |         +-----------+
103  *  ------------|    ------------|
104  *  |     1     |    |     1     |
105  *  +-----------+    +-----------+
106  *        |                |
107  *        v                v
108  *  +-----------+    +-----------+
109  *  | selfpath  |    | mainpath  |
110  *  | (capture) |    | (capture) |
111  *  +-----------+    +-----------+
112  */
113 
114 struct rkisp1_isr_data {
115 	const char *name;
116 	irqreturn_t (*isr)(int irq, void *ctx);
117 };
118 
119 /* ----------------------------------------------------------------------------
120  * Sensor DT bindings
121  */
122 
123 static int rkisp1_subdev_notifier_bound(struct v4l2_async_notifier *notifier,
124 					struct v4l2_subdev *sd,
125 					struct v4l2_async_subdev *asd)
126 {
127 	struct rkisp1_device *rkisp1 =
128 		container_of(notifier, struct rkisp1_device, notifier);
129 	struct rkisp1_sensor_async *s_asd =
130 		container_of(asd, struct rkisp1_sensor_async, asd);
131 	int source_pad;
132 	int ret;
133 
134 	s_asd->sd = sd;
135 
136 	source_pad = media_entity_get_fwnode_pad(&sd->entity, s_asd->source_ep,
137 						 MEDIA_PAD_FL_SOURCE);
138 	if (source_pad < 0) {
139 		dev_err(rkisp1->dev, "failed to find source pad for %s\n",
140 			sd->name);
141 		return source_pad;
142 	}
143 
144 	if (s_asd->port == 0)
145 		return rkisp1_csi_link_sensor(rkisp1, sd, s_asd, source_pad);
146 
147 	ret = media_create_pad_link(&sd->entity, source_pad,
148 				    &rkisp1->isp.sd.entity,
149 				    RKISP1_ISP_PAD_SINK_VIDEO,
150 				    !s_asd->index ? MEDIA_LNK_FL_ENABLED : 0);
151 	if (ret) {
152 		dev_err(rkisp1->dev, "failed to link source pad of %s\n",
153 			sd->name);
154 		return ret;
155 	}
156 
157 	return 0;
158 }
159 
160 static int rkisp1_subdev_notifier_complete(struct v4l2_async_notifier *notifier)
161 {
162 	struct rkisp1_device *rkisp1 =
163 		container_of(notifier, struct rkisp1_device, notifier);
164 
165 	return v4l2_device_register_subdev_nodes(&rkisp1->v4l2_dev);
166 }
167 
168 static void rkisp1_subdev_notifier_destroy(struct v4l2_async_subdev *asd)
169 {
170 	struct rkisp1_sensor_async *rk_asd =
171 		container_of(asd, struct rkisp1_sensor_async, asd);
172 
173 	fwnode_handle_put(rk_asd->source_ep);
174 }
175 
176 static const struct v4l2_async_notifier_operations rkisp1_subdev_notifier_ops = {
177 	.bound = rkisp1_subdev_notifier_bound,
178 	.complete = rkisp1_subdev_notifier_complete,
179 	.destroy = rkisp1_subdev_notifier_destroy,
180 };
181 
182 static int rkisp1_subdev_notifier_register(struct rkisp1_device *rkisp1)
183 {
184 	struct v4l2_async_notifier *ntf = &rkisp1->notifier;
185 	struct fwnode_handle *fwnode = dev_fwnode(rkisp1->dev);
186 	struct fwnode_handle *ep;
187 	unsigned int index = 0;
188 	int ret = 0;
189 
190 	v4l2_async_nf_init(ntf);
191 
192 	ntf->ops = &rkisp1_subdev_notifier_ops;
193 
194 	fwnode_graph_for_each_endpoint(fwnode, ep) {
195 		struct fwnode_handle *port;
196 		struct v4l2_fwnode_endpoint vep = { };
197 		struct rkisp1_sensor_async *rk_asd;
198 		struct fwnode_handle *source;
199 		u32 reg = 0;
200 
201 		/* Select the bus type based on the port. */
202 		port = fwnode_get_parent(ep);
203 		fwnode_property_read_u32(port, "reg", &reg);
204 		fwnode_handle_put(port);
205 
206 		switch (reg) {
207 		case 0:
208 			/* MIPI CSI-2 port */
209 			if (!(rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)) {
210 				dev_err(rkisp1->dev,
211 					"internal CSI must be available for port 0\n");
212 				ret = -EINVAL;
213 				break;
214 			}
215 
216 			vep.bus_type = V4L2_MBUS_CSI2_DPHY;
217 			break;
218 
219 		case 1:
220 			/*
221 			 * Parallel port. The bus-type property in DT is
222 			 * mandatory for port 1, it will be used to determine if
223 			 * it's PARALLEL or BT656.
224 			 */
225 			vep.bus_type = V4L2_MBUS_UNKNOWN;
226 			break;
227 		}
228 
229 		/* Parse the endpoint and validate the bus type. */
230 		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
231 		if (ret) {
232 			dev_err(rkisp1->dev, "failed to parse endpoint %pfw\n",
233 				ep);
234 			break;
235 		}
236 
237 		if (vep.base.port == 1) {
238 			if (vep.bus_type != V4L2_MBUS_PARALLEL &&
239 			    vep.bus_type != V4L2_MBUS_BT656) {
240 				dev_err(rkisp1->dev,
241 					"port 1 must be parallel or BT656\n");
242 				ret = -EINVAL;
243 				break;
244 			}
245 		}
246 
247 		/* Add the async subdev to the notifier. */
248 		source = fwnode_graph_get_remote_endpoint(ep);
249 		if (!source) {
250 			dev_err(rkisp1->dev,
251 				"endpoint %pfw has no remote endpoint\n",
252 				ep);
253 			ret = -ENODEV;
254 			break;
255 		}
256 
257 		rk_asd = v4l2_async_nf_add_fwnode(ntf, source,
258 						  struct rkisp1_sensor_async);
259 		if (IS_ERR(rk_asd)) {
260 			fwnode_handle_put(source);
261 			ret = PTR_ERR(rk_asd);
262 			break;
263 		}
264 
265 		rk_asd->index = index++;
266 		rk_asd->source_ep = source;
267 		rk_asd->mbus_type = vep.bus_type;
268 		rk_asd->port = vep.base.port;
269 
270 		if (vep.bus_type == V4L2_MBUS_CSI2_DPHY) {
271 			rk_asd->mbus_flags = vep.bus.mipi_csi2.flags;
272 			rk_asd->lanes = vep.bus.mipi_csi2.num_data_lanes;
273 		} else {
274 			rk_asd->mbus_flags = vep.bus.parallel.flags;
275 		}
276 
277 		dev_dbg(rkisp1->dev, "registered ep id %d, bus type %u, %u lanes\n",
278 			vep.base.id, rk_asd->mbus_type, rk_asd->lanes);
279 	}
280 
281 	if (ret) {
282 		fwnode_handle_put(ep);
283 		v4l2_async_nf_cleanup(ntf);
284 		return ret;
285 	}
286 
287 	if (!index)
288 		dev_dbg(rkisp1->dev, "no remote subdevice found\n");
289 
290 	ret = v4l2_async_nf_register(&rkisp1->v4l2_dev, ntf);
291 	if (ret) {
292 		v4l2_async_nf_cleanup(ntf);
293 		return ret;
294 	}
295 
296 	return 0;
297 }
298 
299 /* ----------------------------------------------------------------------------
300  * Power
301  */
302 
303 static int __maybe_unused rkisp1_runtime_suspend(struct device *dev)
304 {
305 	struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
306 
307 	clk_bulk_disable_unprepare(rkisp1->clk_size, rkisp1->clks);
308 	return pinctrl_pm_select_sleep_state(dev);
309 }
310 
311 static int __maybe_unused rkisp1_runtime_resume(struct device *dev)
312 {
313 	struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
314 	int ret;
315 
316 	ret = pinctrl_pm_select_default_state(dev);
317 	if (ret)
318 		return ret;
319 	ret = clk_bulk_prepare_enable(rkisp1->clk_size, rkisp1->clks);
320 	if (ret)
321 		return ret;
322 
323 	return 0;
324 }
325 
326 static const struct dev_pm_ops rkisp1_pm_ops = {
327 	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
328 				pm_runtime_force_resume)
329 	SET_RUNTIME_PM_OPS(rkisp1_runtime_suspend, rkisp1_runtime_resume, NULL)
330 };
331 
332 /* ----------------------------------------------------------------------------
333  * Core
334  */
335 
336 static int rkisp1_create_links(struct rkisp1_device *rkisp1)
337 {
338 	unsigned int i;
339 	int ret;
340 
341 	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2) {
342 		/* Link the CSI receiver to the ISP. */
343 		ret = media_create_pad_link(&rkisp1->csi.sd.entity,
344 					    RKISP1_CSI_PAD_SRC,
345 					    &rkisp1->isp.sd.entity,
346 					    RKISP1_ISP_PAD_SINK_VIDEO,
347 					    MEDIA_LNK_FL_ENABLED);
348 		if (ret)
349 			return ret;
350 	}
351 
352 	/* create ISP->RSZ->CAP links */
353 	for (i = 0; i < 2; i++) {
354 		struct media_entity *resizer =
355 			&rkisp1->resizer_devs[i].sd.entity;
356 		struct media_entity *capture =
357 			&rkisp1->capture_devs[i].vnode.vdev.entity;
358 
359 		ret = media_create_pad_link(&rkisp1->isp.sd.entity,
360 					    RKISP1_ISP_PAD_SOURCE_VIDEO,
361 					    resizer, RKISP1_RSZ_PAD_SINK,
362 					    MEDIA_LNK_FL_ENABLED);
363 		if (ret)
364 			return ret;
365 
366 		ret = media_create_pad_link(resizer, RKISP1_RSZ_PAD_SRC,
367 					    capture, 0,
368 					    MEDIA_LNK_FL_ENABLED |
369 					    MEDIA_LNK_FL_IMMUTABLE);
370 		if (ret)
371 			return ret;
372 	}
373 
374 	/* params links */
375 	ret = media_create_pad_link(&rkisp1->params.vnode.vdev.entity, 0,
376 				    &rkisp1->isp.sd.entity,
377 				    RKISP1_ISP_PAD_SINK_PARAMS,
378 				    MEDIA_LNK_FL_ENABLED |
379 				    MEDIA_LNK_FL_IMMUTABLE);
380 	if (ret)
381 		return ret;
382 
383 	/* 3A stats links */
384 	return media_create_pad_link(&rkisp1->isp.sd.entity,
385 				     RKISP1_ISP_PAD_SOURCE_STATS,
386 				     &rkisp1->stats.vnode.vdev.entity, 0,
387 				     MEDIA_LNK_FL_ENABLED |
388 				     MEDIA_LNK_FL_IMMUTABLE);
389 }
390 
391 static void rkisp1_entities_unregister(struct rkisp1_device *rkisp1)
392 {
393 	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)
394 		rkisp1_csi_unregister(rkisp1);
395 	rkisp1_params_unregister(rkisp1);
396 	rkisp1_stats_unregister(rkisp1);
397 	rkisp1_capture_devs_unregister(rkisp1);
398 	rkisp1_resizer_devs_unregister(rkisp1);
399 	rkisp1_isp_unregister(rkisp1);
400 }
401 
402 static int rkisp1_entities_register(struct rkisp1_device *rkisp1)
403 {
404 	int ret;
405 
406 	ret = rkisp1_isp_register(rkisp1);
407 	if (ret)
408 		goto error;
409 
410 	ret = rkisp1_resizer_devs_register(rkisp1);
411 	if (ret)
412 		goto error;
413 
414 	ret = rkisp1_capture_devs_register(rkisp1);
415 	if (ret)
416 		goto error;
417 
418 	ret = rkisp1_stats_register(rkisp1);
419 	if (ret)
420 		goto error;
421 
422 	ret = rkisp1_params_register(rkisp1);
423 	if (ret)
424 		goto error;
425 
426 	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2) {
427 		ret = rkisp1_csi_register(rkisp1);
428 		if (ret)
429 			goto error;
430 	}
431 
432 	ret = rkisp1_create_links(rkisp1);
433 	if (ret)
434 		goto error;
435 
436 	return 0;
437 
438 error:
439 	rkisp1_entities_unregister(rkisp1);
440 	return ret;
441 }
442 
443 static irqreturn_t rkisp1_isr(int irq, void *ctx)
444 {
445 	/*
446 	 * Call rkisp1_capture_isr() first to handle the frame that
447 	 * potentially completed using the current frame_sequence number before
448 	 * it is potentially incremented by rkisp1_isp_isr() in the vertical
449 	 * sync.
450 	 */
451 	rkisp1_capture_isr(irq, ctx);
452 	rkisp1_isp_isr(irq, ctx);
453 	rkisp1_csi_isr(irq, ctx);
454 
455 	return IRQ_HANDLED;
456 }
457 
458 static const char * const px30_isp_clks[] = {
459 	"isp",
460 	"aclk",
461 	"hclk",
462 	"pclk",
463 };
464 
465 static const struct rkisp1_isr_data px30_isp_isrs[] = {
466 	{ "isp", rkisp1_isp_isr },
467 	{ "mi", rkisp1_capture_isr },
468 	{ "mipi", rkisp1_csi_isr },
469 };
470 
471 static const struct rkisp1_info px30_isp_info = {
472 	.clks = px30_isp_clks,
473 	.clk_size = ARRAY_SIZE(px30_isp_clks),
474 	.isrs = px30_isp_isrs,
475 	.isr_size = ARRAY_SIZE(px30_isp_isrs),
476 	.isp_ver = RKISP1_V12,
477 	.features = RKISP1_FEATURE_MIPI_CSI2,
478 };
479 
480 static const char * const rk3399_isp_clks[] = {
481 	"isp",
482 	"aclk",
483 	"hclk",
484 };
485 
486 static const struct rkisp1_isr_data rk3399_isp_isrs[] = {
487 	{ NULL, rkisp1_isr },
488 };
489 
490 static const struct rkisp1_info rk3399_isp_info = {
491 	.clks = rk3399_isp_clks,
492 	.clk_size = ARRAY_SIZE(rk3399_isp_clks),
493 	.isrs = rk3399_isp_isrs,
494 	.isr_size = ARRAY_SIZE(rk3399_isp_isrs),
495 	.isp_ver = RKISP1_V10,
496 	.features = RKISP1_FEATURE_MIPI_CSI2,
497 };
498 
499 static const struct of_device_id rkisp1_of_match[] = {
500 	{
501 		.compatible = "rockchip,px30-cif-isp",
502 		.data = &px30_isp_info,
503 	},
504 	{
505 		.compatible = "rockchip,rk3399-cif-isp",
506 		.data = &rk3399_isp_info,
507 	},
508 	{},
509 };
510 MODULE_DEVICE_TABLE(of, rkisp1_of_match);
511 
512 static int rkisp1_probe(struct platform_device *pdev)
513 {
514 	const struct rkisp1_info *info;
515 	struct device *dev = &pdev->dev;
516 	struct rkisp1_device *rkisp1;
517 	struct v4l2_device *v4l2_dev;
518 	unsigned int i;
519 	int ret, irq;
520 	u32 cif_id;
521 
522 	rkisp1 = devm_kzalloc(dev, sizeof(*rkisp1), GFP_KERNEL);
523 	if (!rkisp1)
524 		return -ENOMEM;
525 
526 	info = of_device_get_match_data(dev);
527 	rkisp1->info = info;
528 
529 	dev_set_drvdata(dev, rkisp1);
530 	rkisp1->dev = dev;
531 
532 	mutex_init(&rkisp1->stream_lock);
533 
534 	rkisp1->base_addr = devm_platform_ioremap_resource(pdev, 0);
535 	if (IS_ERR(rkisp1->base_addr))
536 		return PTR_ERR(rkisp1->base_addr);
537 
538 	for (i = 0; i < info->isr_size; i++) {
539 		irq = info->isrs[i].name
540 		    ? platform_get_irq_byname(pdev, info->isrs[i].name)
541 		    : platform_get_irq(pdev, i);
542 		if (irq < 0)
543 			return irq;
544 
545 		ret = devm_request_irq(dev, irq, info->isrs[i].isr, IRQF_SHARED,
546 				       dev_driver_string(dev), dev);
547 		if (ret) {
548 			dev_err(dev, "request irq failed: %d\n", ret);
549 			return ret;
550 		}
551 	}
552 
553 	for (i = 0; i < info->clk_size; i++)
554 		rkisp1->clks[i].id = info->clks[i];
555 	ret = devm_clk_bulk_get(dev, info->clk_size, rkisp1->clks);
556 	if (ret)
557 		return ret;
558 	rkisp1->clk_size = info->clk_size;
559 
560 	pm_runtime_enable(&pdev->dev);
561 
562 	ret = pm_runtime_resume_and_get(&pdev->dev);
563 	if (ret)
564 		goto err_pm_runtime_disable;
565 
566 	cif_id = rkisp1_read(rkisp1, RKISP1_CIF_VI_ID);
567 	dev_dbg(rkisp1->dev, "CIF_ID 0x%08x\n", cif_id);
568 
569 	pm_runtime_put(&pdev->dev);
570 
571 	rkisp1->media_dev.hw_revision = info->isp_ver;
572 	strscpy(rkisp1->media_dev.model, RKISP1_DRIVER_NAME,
573 		sizeof(rkisp1->media_dev.model));
574 	rkisp1->media_dev.dev = &pdev->dev;
575 	strscpy(rkisp1->media_dev.bus_info, RKISP1_BUS_INFO,
576 		sizeof(rkisp1->media_dev.bus_info));
577 	media_device_init(&rkisp1->media_dev);
578 
579 	v4l2_dev = &rkisp1->v4l2_dev;
580 	v4l2_dev->mdev = &rkisp1->media_dev;
581 	strscpy(v4l2_dev->name, RKISP1_DRIVER_NAME, sizeof(v4l2_dev->name));
582 
583 	ret = v4l2_device_register(rkisp1->dev, &rkisp1->v4l2_dev);
584 	if (ret)
585 		goto err_pm_runtime_disable;
586 
587 	ret = media_device_register(&rkisp1->media_dev);
588 	if (ret) {
589 		dev_err(dev, "Failed to register media device: %d\n", ret);
590 		goto err_unreg_v4l2_dev;
591 	}
592 
593 	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2) {
594 		ret = rkisp1_csi_init(rkisp1);
595 		if (ret)
596 			goto err_unreg_media_dev;
597 	}
598 
599 	ret = rkisp1_entities_register(rkisp1);
600 	if (ret)
601 		goto err_cleanup_csi;
602 
603 	ret = rkisp1_subdev_notifier_register(rkisp1);
604 	if (ret)
605 		goto err_unreg_entities;
606 
607 	rkisp1_debug_init(rkisp1);
608 
609 	return 0;
610 
611 err_unreg_entities:
612 	rkisp1_entities_unregister(rkisp1);
613 err_cleanup_csi:
614 	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)
615 		rkisp1_csi_cleanup(rkisp1);
616 err_unreg_media_dev:
617 	media_device_unregister(&rkisp1->media_dev);
618 err_unreg_v4l2_dev:
619 	v4l2_device_unregister(&rkisp1->v4l2_dev);
620 err_pm_runtime_disable:
621 	pm_runtime_disable(&pdev->dev);
622 	return ret;
623 }
624 
625 static int rkisp1_remove(struct platform_device *pdev)
626 {
627 	struct rkisp1_device *rkisp1 = platform_get_drvdata(pdev);
628 
629 	v4l2_async_nf_unregister(&rkisp1->notifier);
630 	v4l2_async_nf_cleanup(&rkisp1->notifier);
631 
632 	rkisp1_entities_unregister(rkisp1);
633 	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)
634 		rkisp1_csi_cleanup(rkisp1);
635 	rkisp1_debug_cleanup(rkisp1);
636 
637 	media_device_unregister(&rkisp1->media_dev);
638 	v4l2_device_unregister(&rkisp1->v4l2_dev);
639 
640 	pm_runtime_disable(&pdev->dev);
641 
642 	return 0;
643 }
644 
645 static struct platform_driver rkisp1_drv = {
646 	.driver = {
647 		.name = RKISP1_DRIVER_NAME,
648 		.of_match_table = of_match_ptr(rkisp1_of_match),
649 		.pm = &rkisp1_pm_ops,
650 	},
651 	.probe = rkisp1_probe,
652 	.remove = rkisp1_remove,
653 };
654 
655 module_platform_driver(rkisp1_drv);
656 MODULE_DESCRIPTION("Rockchip ISP1 platform driver");
657 MODULE_LICENSE("Dual MIT/GPL");
658