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/platform_device.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
114struct rkisp1_isr_data {
115	const char *name;
116	irqreturn_t (*isr)(int irq, void *ctx);
117	u32 line_mask;
118};
119
120/* ----------------------------------------------------------------------------
121 * Sensor DT bindings
122 */
123
124static int rkisp1_subdev_notifier_bound(struct v4l2_async_notifier *notifier,
125					struct v4l2_subdev *sd,
126					struct v4l2_async_connection *asc)
127{
128	struct rkisp1_device *rkisp1 =
129		container_of(notifier, struct rkisp1_device, notifier);
130	struct rkisp1_sensor_async *s_asd =
131		container_of(asc, struct rkisp1_sensor_async, asd);
132	int source_pad;
133	int ret;
134
135	s_asd->sd = sd;
136
137	source_pad = media_entity_get_fwnode_pad(&sd->entity, s_asd->source_ep,
138						 MEDIA_PAD_FL_SOURCE);
139	if (source_pad < 0) {
140		dev_err(rkisp1->dev, "failed to find source pad for %s\n",
141			sd->name);
142		return source_pad;
143	}
144
145	if (s_asd->port == 0)
146		return rkisp1_csi_link_sensor(rkisp1, sd, s_asd, source_pad);
147
148	ret = media_create_pad_link(&sd->entity, source_pad,
149				    &rkisp1->isp.sd.entity,
150				    RKISP1_ISP_PAD_SINK_VIDEO,
151				    !s_asd->index ? MEDIA_LNK_FL_ENABLED : 0);
152	if (ret) {
153		dev_err(rkisp1->dev, "failed to link source pad of %s\n",
154			sd->name);
155		return ret;
156	}
157
158	return 0;
159}
160
161static int rkisp1_subdev_notifier_complete(struct v4l2_async_notifier *notifier)
162{
163	struct rkisp1_device *rkisp1 =
164		container_of(notifier, struct rkisp1_device, notifier);
165
166	return v4l2_device_register_subdev_nodes(&rkisp1->v4l2_dev);
167}
168
169static void rkisp1_subdev_notifier_destroy(struct v4l2_async_connection *asc)
170{
171	struct rkisp1_sensor_async *rk_asd =
172		container_of(asc, struct rkisp1_sensor_async, asd);
173
174	fwnode_handle_put(rk_asd->source_ep);
175}
176
177static const struct v4l2_async_notifier_operations rkisp1_subdev_notifier_ops = {
178	.bound = rkisp1_subdev_notifier_bound,
179	.complete = rkisp1_subdev_notifier_complete,
180	.destroy = rkisp1_subdev_notifier_destroy,
181};
182
183static int rkisp1_subdev_notifier_register(struct rkisp1_device *rkisp1)
184{
185	struct v4l2_async_notifier *ntf = &rkisp1->notifier;
186	struct fwnode_handle *fwnode = dev_fwnode(rkisp1->dev);
187	struct fwnode_handle *ep;
188	unsigned int index = 0;
189	int ret = 0;
190
191	v4l2_async_nf_init(ntf, &rkisp1->v4l2_dev);
192
193	ntf->ops = &rkisp1_subdev_notifier_ops;
194
195	fwnode_graph_for_each_endpoint(fwnode, ep) {
196		struct fwnode_handle *port;
197		struct v4l2_fwnode_endpoint vep = { };
198		struct rkisp1_sensor_async *rk_asd;
199		struct fwnode_handle *source;
200		u32 reg = 0;
201
202		/* Select the bus type based on the port. */
203		port = fwnode_get_parent(ep);
204		fwnode_property_read_u32(port, "reg", &reg);
205		fwnode_handle_put(port);
206
207		switch (reg) {
208		case 0:
209			/* MIPI CSI-2 port */
210			if (!(rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)) {
211				dev_err(rkisp1->dev,
212					"internal CSI must be available for port 0\n");
213				ret = -EINVAL;
214				break;
215			}
216
217			vep.bus_type = V4L2_MBUS_CSI2_DPHY;
218			break;
219
220		case 1:
221			/*
222			 * Parallel port. The bus-type property in DT is
223			 * mandatory for port 1, it will be used to determine if
224			 * it's PARALLEL or BT656.
225			 */
226			vep.bus_type = V4L2_MBUS_UNKNOWN;
227			break;
228		}
229
230		/* Parse the endpoint and validate the bus type. */
231		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
232		if (ret) {
233			dev_err(rkisp1->dev, "failed to parse endpoint %pfw\n",
234				ep);
235			break;
236		}
237
238		if (vep.base.port == 1) {
239			if (vep.bus_type != V4L2_MBUS_PARALLEL &&
240			    vep.bus_type != V4L2_MBUS_BT656) {
241				dev_err(rkisp1->dev,
242					"port 1 must be parallel or BT656\n");
243				ret = -EINVAL;
244				break;
245			}
246		}
247
248		/* Add the async subdev to the notifier. */
249		source = fwnode_graph_get_remote_endpoint(ep);
250		if (!source) {
251			dev_err(rkisp1->dev,
252				"endpoint %pfw has no remote endpoint\n",
253				ep);
254			ret = -ENODEV;
255			break;
256		}
257
258		rk_asd = v4l2_async_nf_add_fwnode(ntf, source,
259						  struct rkisp1_sensor_async);
260		if (IS_ERR(rk_asd)) {
261			fwnode_handle_put(source);
262			ret = PTR_ERR(rk_asd);
263			break;
264		}
265
266		rk_asd->index = index++;
267		rk_asd->source_ep = source;
268		rk_asd->mbus_type = vep.bus_type;
269		rk_asd->port = vep.base.port;
270
271		if (vep.bus_type == V4L2_MBUS_CSI2_DPHY) {
272			rk_asd->mbus_flags = vep.bus.mipi_csi2.flags;
273			rk_asd->lanes = vep.bus.mipi_csi2.num_data_lanes;
274		} else {
275			rk_asd->mbus_flags = vep.bus.parallel.flags;
276		}
277
278		dev_dbg(rkisp1->dev, "registered ep id %d, bus type %u, %u lanes\n",
279			vep.base.id, rk_asd->mbus_type, rk_asd->lanes);
280	}
281
282	if (ret) {
283		fwnode_handle_put(ep);
284		v4l2_async_nf_cleanup(ntf);
285		return ret;
286	}
287
288	if (!index)
289		dev_dbg(rkisp1->dev, "no remote subdevice found\n");
290
291	ret = v4l2_async_nf_register(ntf);
292	if (ret) {
293		v4l2_async_nf_cleanup(ntf);
294		return ret;
295	}
296
297	return 0;
298}
299
300/* ----------------------------------------------------------------------------
301 * Power
302 */
303
304static int __maybe_unused rkisp1_runtime_suspend(struct device *dev)
305{
306	struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
307
308	rkisp1->irqs_enabled = false;
309	/* Make sure the IRQ handler will see the above */
310	mb();
311
312	/*
313	 * Wait until any running IRQ handler has returned. The IRQ handler
314	 * may get called even after this (as it's a shared interrupt line)
315	 * but the 'irqs_enabled' flag will make the handler return immediately.
316	 */
317	for (unsigned int il = 0; il < ARRAY_SIZE(rkisp1->irqs); ++il) {
318		if (rkisp1->irqs[il] == -1)
319			continue;
320
321		/* Skip if the irq line is the same as previous */
322		if (il == 0 || rkisp1->irqs[il - 1] != rkisp1->irqs[il])
323			synchronize_irq(rkisp1->irqs[il]);
324	}
325
326	clk_bulk_disable_unprepare(rkisp1->clk_size, rkisp1->clks);
327	return pinctrl_pm_select_sleep_state(dev);
328}
329
330static int __maybe_unused rkisp1_runtime_resume(struct device *dev)
331{
332	struct rkisp1_device *rkisp1 = dev_get_drvdata(dev);
333	int ret;
334
335	ret = pinctrl_pm_select_default_state(dev);
336	if (ret)
337		return ret;
338	ret = clk_bulk_prepare_enable(rkisp1->clk_size, rkisp1->clks);
339	if (ret)
340		return ret;
341
342	rkisp1->irqs_enabled = true;
343	/* Make sure the IRQ handler will see the above */
344	mb();
345
346	return 0;
347}
348
349static const struct dev_pm_ops rkisp1_pm_ops = {
350	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
351				pm_runtime_force_resume)
352	SET_RUNTIME_PM_OPS(rkisp1_runtime_suspend, rkisp1_runtime_resume, NULL)
353};
354
355/* ----------------------------------------------------------------------------
356 * Core
357 */
358
359static int rkisp1_create_links(struct rkisp1_device *rkisp1)
360{
361	unsigned int i;
362	int ret;
363
364	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2) {
365		/* Link the CSI receiver to the ISP. */
366		ret = media_create_pad_link(&rkisp1->csi.sd.entity,
367					    RKISP1_CSI_PAD_SRC,
368					    &rkisp1->isp.sd.entity,
369					    RKISP1_ISP_PAD_SINK_VIDEO,
370					    MEDIA_LNK_FL_ENABLED);
371		if (ret)
372			return ret;
373	}
374
375	/* create ISP->RSZ->CAP links */
376	for (i = 0; i < 2; i++) {
377		struct media_entity *resizer =
378			&rkisp1->resizer_devs[i].sd.entity;
379		struct media_entity *capture =
380			&rkisp1->capture_devs[i].vnode.vdev.entity;
381
382		ret = media_create_pad_link(&rkisp1->isp.sd.entity,
383					    RKISP1_ISP_PAD_SOURCE_VIDEO,
384					    resizer, RKISP1_RSZ_PAD_SINK,
385					    MEDIA_LNK_FL_ENABLED);
386		if (ret)
387			return ret;
388
389		ret = media_create_pad_link(resizer, RKISP1_RSZ_PAD_SRC,
390					    capture, 0,
391					    MEDIA_LNK_FL_ENABLED |
392					    MEDIA_LNK_FL_IMMUTABLE);
393		if (ret)
394			return ret;
395	}
396
397	/* params links */
398	ret = media_create_pad_link(&rkisp1->params.vnode.vdev.entity, 0,
399				    &rkisp1->isp.sd.entity,
400				    RKISP1_ISP_PAD_SINK_PARAMS,
401				    MEDIA_LNK_FL_ENABLED |
402				    MEDIA_LNK_FL_IMMUTABLE);
403	if (ret)
404		return ret;
405
406	/* 3A stats links */
407	return media_create_pad_link(&rkisp1->isp.sd.entity,
408				     RKISP1_ISP_PAD_SOURCE_STATS,
409				     &rkisp1->stats.vnode.vdev.entity, 0,
410				     MEDIA_LNK_FL_ENABLED |
411				     MEDIA_LNK_FL_IMMUTABLE);
412}
413
414static void rkisp1_entities_unregister(struct rkisp1_device *rkisp1)
415{
416	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)
417		rkisp1_csi_unregister(rkisp1);
418	rkisp1_params_unregister(rkisp1);
419	rkisp1_stats_unregister(rkisp1);
420	rkisp1_capture_devs_unregister(rkisp1);
421	rkisp1_resizer_devs_unregister(rkisp1);
422	rkisp1_isp_unregister(rkisp1);
423}
424
425static int rkisp1_entities_register(struct rkisp1_device *rkisp1)
426{
427	int ret;
428
429	ret = rkisp1_isp_register(rkisp1);
430	if (ret)
431		goto error;
432
433	ret = rkisp1_resizer_devs_register(rkisp1);
434	if (ret)
435		goto error;
436
437	ret = rkisp1_capture_devs_register(rkisp1);
438	if (ret)
439		goto error;
440
441	ret = rkisp1_stats_register(rkisp1);
442	if (ret)
443		goto error;
444
445	ret = rkisp1_params_register(rkisp1);
446	if (ret)
447		goto error;
448
449	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2) {
450		ret = rkisp1_csi_register(rkisp1);
451		if (ret)
452			goto error;
453	}
454
455	ret = rkisp1_create_links(rkisp1);
456	if (ret)
457		goto error;
458
459	return 0;
460
461error:
462	rkisp1_entities_unregister(rkisp1);
463	return ret;
464}
465
466static irqreturn_t rkisp1_isr(int irq, void *ctx)
467{
468	irqreturn_t ret = IRQ_NONE;
469
470	/*
471	 * Call rkisp1_capture_isr() first to handle the frame that
472	 * potentially completed using the current frame_sequence number before
473	 * it is potentially incremented by rkisp1_isp_isr() in the vertical
474	 * sync.
475	 */
476
477	if (rkisp1_capture_isr(irq, ctx) == IRQ_HANDLED)
478		ret = IRQ_HANDLED;
479
480	if (rkisp1_isp_isr(irq, ctx) == IRQ_HANDLED)
481		ret = IRQ_HANDLED;
482
483	if (rkisp1_csi_isr(irq, ctx) == IRQ_HANDLED)
484		ret = IRQ_HANDLED;
485
486	return ret;
487}
488
489static const char * const px30_isp_clks[] = {
490	"isp",
491	"aclk",
492	"hclk",
493	"pclk",
494};
495
496static const struct rkisp1_isr_data px30_isp_isrs[] = {
497	{ "isp", rkisp1_isp_isr, BIT(RKISP1_IRQ_ISP) },
498	{ "mi", rkisp1_capture_isr, BIT(RKISP1_IRQ_MI) },
499	{ "mipi", rkisp1_csi_isr, BIT(RKISP1_IRQ_MIPI) },
500};
501
502static const struct rkisp1_info px30_isp_info = {
503	.clks = px30_isp_clks,
504	.clk_size = ARRAY_SIZE(px30_isp_clks),
505	.isrs = px30_isp_isrs,
506	.isr_size = ARRAY_SIZE(px30_isp_isrs),
507	.isp_ver = RKISP1_V12,
508	.features = RKISP1_FEATURE_MIPI_CSI2,
509};
510
511static const char * const rk3399_isp_clks[] = {
512	"isp",
513	"aclk",
514	"hclk",
515};
516
517static const struct rkisp1_isr_data rk3399_isp_isrs[] = {
518	{ NULL, rkisp1_isr, BIT(RKISP1_IRQ_ISP) | BIT(RKISP1_IRQ_MI) | BIT(RKISP1_IRQ_MIPI) },
519};
520
521static const struct rkisp1_info rk3399_isp_info = {
522	.clks = rk3399_isp_clks,
523	.clk_size = ARRAY_SIZE(rk3399_isp_clks),
524	.isrs = rk3399_isp_isrs,
525	.isr_size = ARRAY_SIZE(rk3399_isp_isrs),
526	.isp_ver = RKISP1_V10,
527	.features = RKISP1_FEATURE_MIPI_CSI2,
528};
529
530static const struct of_device_id rkisp1_of_match[] = {
531	{
532		.compatible = "rockchip,px30-cif-isp",
533		.data = &px30_isp_info,
534	},
535	{
536		.compatible = "rockchip,rk3399-cif-isp",
537		.data = &rk3399_isp_info,
538	},
539	{},
540};
541MODULE_DEVICE_TABLE(of, rkisp1_of_match);
542
543static int rkisp1_probe(struct platform_device *pdev)
544{
545	const struct rkisp1_info *info;
546	struct device *dev = &pdev->dev;
547	struct rkisp1_device *rkisp1;
548	struct v4l2_device *v4l2_dev;
549	unsigned int i;
550	int ret, irq;
551	u32 cif_id;
552
553	rkisp1 = devm_kzalloc(dev, sizeof(*rkisp1), GFP_KERNEL);
554	if (!rkisp1)
555		return -ENOMEM;
556
557	info = of_device_get_match_data(dev);
558	rkisp1->info = info;
559
560	dev_set_drvdata(dev, rkisp1);
561	rkisp1->dev = dev;
562
563	mutex_init(&rkisp1->stream_lock);
564
565	rkisp1->base_addr = devm_platform_ioremap_resource(pdev, 0);
566	if (IS_ERR(rkisp1->base_addr))
567		return PTR_ERR(rkisp1->base_addr);
568
569	for (unsigned int il = 0; il < ARRAY_SIZE(rkisp1->irqs); ++il)
570		rkisp1->irqs[il] = -1;
571
572	for (i = 0; i < info->isr_size; i++) {
573		irq = info->isrs[i].name
574		    ? platform_get_irq_byname(pdev, info->isrs[i].name)
575		    : platform_get_irq(pdev, i);
576		if (irq < 0)
577			return irq;
578
579		for (unsigned int il = 0; il < ARRAY_SIZE(rkisp1->irqs); ++il) {
580			if (info->isrs[i].line_mask & BIT(il))
581				rkisp1->irqs[il] = irq;
582		}
583
584		ret = devm_request_irq(dev, irq, info->isrs[i].isr, IRQF_SHARED,
585				       dev_driver_string(dev), dev);
586		if (ret) {
587			dev_err(dev, "request irq failed: %d\n", ret);
588			return ret;
589		}
590	}
591
592	for (i = 0; i < info->clk_size; i++)
593		rkisp1->clks[i].id = info->clks[i];
594	ret = devm_clk_bulk_get(dev, info->clk_size, rkisp1->clks);
595	if (ret)
596		return ret;
597	rkisp1->clk_size = info->clk_size;
598
599	pm_runtime_enable(&pdev->dev);
600
601	ret = pm_runtime_resume_and_get(&pdev->dev);
602	if (ret)
603		goto err_pm_runtime_disable;
604
605	cif_id = rkisp1_read(rkisp1, RKISP1_CIF_VI_ID);
606	dev_dbg(rkisp1->dev, "CIF_ID 0x%08x\n", cif_id);
607
608	pm_runtime_put(&pdev->dev);
609
610	rkisp1->media_dev.hw_revision = info->isp_ver;
611	strscpy(rkisp1->media_dev.model, RKISP1_DRIVER_NAME,
612		sizeof(rkisp1->media_dev.model));
613	rkisp1->media_dev.dev = &pdev->dev;
614	strscpy(rkisp1->media_dev.bus_info, RKISP1_BUS_INFO,
615		sizeof(rkisp1->media_dev.bus_info));
616	media_device_init(&rkisp1->media_dev);
617
618	v4l2_dev = &rkisp1->v4l2_dev;
619	v4l2_dev->mdev = &rkisp1->media_dev;
620	strscpy(v4l2_dev->name, RKISP1_DRIVER_NAME, sizeof(v4l2_dev->name));
621
622	ret = v4l2_device_register(rkisp1->dev, &rkisp1->v4l2_dev);
623	if (ret)
624		goto err_media_dev_cleanup;
625
626	ret = media_device_register(&rkisp1->media_dev);
627	if (ret) {
628		dev_err(dev, "Failed to register media device: %d\n", ret);
629		goto err_unreg_v4l2_dev;
630	}
631
632	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2) {
633		ret = rkisp1_csi_init(rkisp1);
634		if (ret)
635			goto err_unreg_media_dev;
636	}
637
638	ret = rkisp1_entities_register(rkisp1);
639	if (ret)
640		goto err_cleanup_csi;
641
642	ret = rkisp1_subdev_notifier_register(rkisp1);
643	if (ret)
644		goto err_unreg_entities;
645
646	rkisp1_debug_init(rkisp1);
647
648	return 0;
649
650err_unreg_entities:
651	rkisp1_entities_unregister(rkisp1);
652err_cleanup_csi:
653	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)
654		rkisp1_csi_cleanup(rkisp1);
655err_unreg_media_dev:
656	media_device_unregister(&rkisp1->media_dev);
657err_unreg_v4l2_dev:
658	v4l2_device_unregister(&rkisp1->v4l2_dev);
659err_media_dev_cleanup:
660	media_device_cleanup(&rkisp1->media_dev);
661err_pm_runtime_disable:
662	pm_runtime_disable(&pdev->dev);
663	return ret;
664}
665
666static void rkisp1_remove(struct platform_device *pdev)
667{
668	struct rkisp1_device *rkisp1 = platform_get_drvdata(pdev);
669
670	v4l2_async_nf_unregister(&rkisp1->notifier);
671	v4l2_async_nf_cleanup(&rkisp1->notifier);
672
673	rkisp1_entities_unregister(rkisp1);
674	if (rkisp1->info->features & RKISP1_FEATURE_MIPI_CSI2)
675		rkisp1_csi_cleanup(rkisp1);
676	rkisp1_debug_cleanup(rkisp1);
677
678	media_device_unregister(&rkisp1->media_dev);
679	v4l2_device_unregister(&rkisp1->v4l2_dev);
680
681	media_device_cleanup(&rkisp1->media_dev);
682
683	pm_runtime_disable(&pdev->dev);
684}
685
686static struct platform_driver rkisp1_drv = {
687	.driver = {
688		.name = RKISP1_DRIVER_NAME,
689		.of_match_table = of_match_ptr(rkisp1_of_match),
690		.pm = &rkisp1_pm_ops,
691	},
692	.probe = rkisp1_probe,
693	.remove_new = rkisp1_remove,
694};
695
696module_platform_driver(rkisp1_drv);
697MODULE_DESCRIPTION("Rockchip ISP1 platform driver");
698MODULE_LICENSE("Dual MIT/GPL");
699