[go: nahoru, domu]

1/*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
3 * Authors:
4 *	Inki Dae <inki.dae@samsung.com>
5 *	Joonyoung Shim <jy0922.shim@samsung.com>
6 *	Seung-Woo Kim <sw0312.kim@samsung.com>
7 *
8 * This program is free software; you can redistribute  it and/or modify it
9 * under  the terms of  the GNU General  Public License as published by the
10 * Free Software Foundation;  either version 2 of the  License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/pm_runtime.h>
15#include <drm/drmP.h>
16#include <drm/drm_crtc_helper.h>
17
18#include <linux/component.h>
19
20#include <drm/exynos_drm.h>
21
22#include "exynos_drm_drv.h"
23#include "exynos_drm_crtc.h"
24#include "exynos_drm_encoder.h"
25#include "exynos_drm_fbdev.h"
26#include "exynos_drm_fb.h"
27#include "exynos_drm_gem.h"
28#include "exynos_drm_plane.h"
29#include "exynos_drm_vidi.h"
30#include "exynos_drm_dmabuf.h"
31#include "exynos_drm_g2d.h"
32#include "exynos_drm_ipp.h"
33#include "exynos_drm_iommu.h"
34
35#define DRIVER_NAME	"exynos"
36#define DRIVER_DESC	"Samsung SoC DRM"
37#define DRIVER_DATE	"20110530"
38#define DRIVER_MAJOR	1
39#define DRIVER_MINOR	0
40
41static struct platform_device *exynos_drm_pdev;
42
43static DEFINE_MUTEX(drm_component_lock);
44static LIST_HEAD(drm_component_list);
45
46struct component_dev {
47	struct list_head list;
48	struct device *crtc_dev;
49	struct device *conn_dev;
50	enum exynos_drm_output_type out_type;
51	unsigned int dev_type_flag;
52};
53
54static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
55{
56	struct exynos_drm_private *private;
57	int ret;
58	int nr;
59
60	private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
61	if (!private)
62		return -ENOMEM;
63
64	INIT_LIST_HEAD(&private->pageflip_event_list);
65	dev_set_drvdata(dev->dev, dev);
66	dev->dev_private = (void *)private;
67
68	/*
69	 * create mapping to manage iommu table and set a pointer to iommu
70	 * mapping structure to iommu_mapping of private data.
71	 * also this iommu_mapping can be used to check if iommu is supported
72	 * or not.
73	 */
74	ret = drm_create_iommu_mapping(dev);
75	if (ret < 0) {
76		DRM_ERROR("failed to create iommu mapping.\n");
77		goto err_free_private;
78	}
79
80	drm_mode_config_init(dev);
81
82	exynos_drm_mode_config_init(dev);
83
84	for (nr = 0; nr < MAX_PLANE; nr++) {
85		struct drm_plane *plane;
86		unsigned long possible_crtcs = (1 << MAX_CRTC) - 1;
87
88		plane = exynos_plane_init(dev, possible_crtcs,
89					  DRM_PLANE_TYPE_OVERLAY);
90		if (!IS_ERR(plane))
91			continue;
92
93		ret = PTR_ERR(plane);
94		goto err_mode_config_cleanup;
95	}
96
97	/* setup possible_clones. */
98	exynos_drm_encoder_setup(dev);
99
100	platform_set_drvdata(dev->platformdev, dev);
101
102	/* Try to bind all sub drivers. */
103	ret = component_bind_all(dev->dev, dev);
104	if (ret)
105		goto err_mode_config_cleanup;
106
107	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
108	if (ret)
109		goto err_unbind_all;
110
111	/* Probe non kms sub drivers and virtual display driver. */
112	ret = exynos_drm_device_subdrv_probe(dev);
113	if (ret)
114		goto err_cleanup_vblank;
115
116	/*
117	 * enable drm irq mode.
118	 * - with irq_enabled = true, we can use the vblank feature.
119	 *
120	 * P.S. note that we wouldn't use drm irq handler but
121	 *	just specific driver own one instead because
122	 *	drm framework supports only one irq handler.
123	 */
124	dev->irq_enabled = true;
125
126	/*
127	 * with vblank_disable_allowed = true, vblank interrupt will be disabled
128	 * by drm timer once a current process gives up ownership of
129	 * vblank event.(after drm_vblank_put function is called)
130	 */
131	dev->vblank_disable_allowed = true;
132
133	/* init kms poll for handling hpd */
134	drm_kms_helper_poll_init(dev);
135
136	/* force connectors detection */
137	drm_helper_hpd_irq_event(dev);
138
139	return 0;
140
141err_cleanup_vblank:
142	drm_vblank_cleanup(dev);
143err_unbind_all:
144	component_unbind_all(dev->dev, dev);
145err_mode_config_cleanup:
146	drm_mode_config_cleanup(dev);
147	drm_release_iommu_mapping(dev);
148err_free_private:
149	kfree(private);
150
151	return ret;
152}
153
154static int exynos_drm_unload(struct drm_device *dev)
155{
156	exynos_drm_device_subdrv_remove(dev);
157
158	exynos_drm_fbdev_fini(dev);
159	drm_kms_helper_poll_fini(dev);
160
161	drm_vblank_cleanup(dev);
162	component_unbind_all(dev->dev, dev);
163	drm_mode_config_cleanup(dev);
164	drm_release_iommu_mapping(dev);
165
166	kfree(dev->dev_private);
167	dev->dev_private = NULL;
168
169	return 0;
170}
171
172static int exynos_drm_suspend(struct drm_device *dev, pm_message_t state)
173{
174	struct drm_connector *connector;
175
176	drm_modeset_lock_all(dev);
177	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
178		int old_dpms = connector->dpms;
179
180		if (connector->funcs->dpms)
181			connector->funcs->dpms(connector, DRM_MODE_DPMS_OFF);
182
183		/* Set the old mode back to the connector for resume */
184		connector->dpms = old_dpms;
185	}
186	drm_modeset_unlock_all(dev);
187
188	return 0;
189}
190
191static int exynos_drm_resume(struct drm_device *dev)
192{
193	struct drm_connector *connector;
194
195	drm_modeset_lock_all(dev);
196	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
197		if (connector->funcs->dpms) {
198			int dpms = connector->dpms;
199
200			connector->dpms = DRM_MODE_DPMS_OFF;
201			connector->funcs->dpms(connector, dpms);
202		}
203	}
204	drm_modeset_unlock_all(dev);
205
206	drm_helper_resume_force_mode(dev);
207
208	return 0;
209}
210
211static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
212{
213	struct drm_exynos_file_private *file_priv;
214	int ret;
215
216	file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
217	if (!file_priv)
218		return -ENOMEM;
219
220	file->driver_priv = file_priv;
221
222	ret = exynos_drm_subdrv_open(dev, file);
223	if (ret)
224		goto err_file_priv_free;
225
226	return ret;
227
228err_file_priv_free:
229	kfree(file_priv);
230	file->driver_priv = NULL;
231	return ret;
232}
233
234static void exynos_drm_preclose(struct drm_device *dev,
235					struct drm_file *file)
236{
237	exynos_drm_subdrv_close(dev, file);
238}
239
240static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
241{
242	struct exynos_drm_private *private = dev->dev_private;
243	struct drm_pending_vblank_event *v, *vt;
244	struct drm_pending_event *e, *et;
245	unsigned long flags;
246
247	if (!file->driver_priv)
248		return;
249
250	/* Release all events not unhandled by page flip handler. */
251	spin_lock_irqsave(&dev->event_lock, flags);
252	list_for_each_entry_safe(v, vt, &private->pageflip_event_list,
253			base.link) {
254		if (v->base.file_priv == file) {
255			list_del(&v->base.link);
256			drm_vblank_put(dev, v->pipe);
257			v->base.destroy(&v->base);
258		}
259	}
260
261	/* Release all events handled by page flip handler but not freed. */
262	list_for_each_entry_safe(e, et, &file->event_list, link) {
263		list_del(&e->link);
264		e->destroy(e);
265	}
266	spin_unlock_irqrestore(&dev->event_lock, flags);
267
268	kfree(file->driver_priv);
269	file->driver_priv = NULL;
270}
271
272static void exynos_drm_lastclose(struct drm_device *dev)
273{
274	exynos_drm_fbdev_restore_mode(dev);
275}
276
277static const struct vm_operations_struct exynos_drm_gem_vm_ops = {
278	.fault = exynos_drm_gem_fault,
279	.open = drm_gem_vm_open,
280	.close = drm_gem_vm_close,
281};
282
283static const struct drm_ioctl_desc exynos_ioctls[] = {
284	DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl,
285			DRM_UNLOCKED | DRM_AUTH),
286	DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET,
287			exynos_drm_gem_get_ioctl, DRM_UNLOCKED),
288	DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION,
289			vidi_connection_ioctl, DRM_UNLOCKED | DRM_AUTH),
290	DRM_IOCTL_DEF_DRV(EXYNOS_G2D_GET_VER,
291			exynos_g2d_get_ver_ioctl, DRM_UNLOCKED | DRM_AUTH),
292	DRM_IOCTL_DEF_DRV(EXYNOS_G2D_SET_CMDLIST,
293			exynos_g2d_set_cmdlist_ioctl, DRM_UNLOCKED | DRM_AUTH),
294	DRM_IOCTL_DEF_DRV(EXYNOS_G2D_EXEC,
295			exynos_g2d_exec_ioctl, DRM_UNLOCKED | DRM_AUTH),
296	DRM_IOCTL_DEF_DRV(EXYNOS_IPP_GET_PROPERTY,
297			exynos_drm_ipp_get_property, DRM_UNLOCKED | DRM_AUTH),
298	DRM_IOCTL_DEF_DRV(EXYNOS_IPP_SET_PROPERTY,
299			exynos_drm_ipp_set_property, DRM_UNLOCKED | DRM_AUTH),
300	DRM_IOCTL_DEF_DRV(EXYNOS_IPP_QUEUE_BUF,
301			exynos_drm_ipp_queue_buf, DRM_UNLOCKED | DRM_AUTH),
302	DRM_IOCTL_DEF_DRV(EXYNOS_IPP_CMD_CTRL,
303			exynos_drm_ipp_cmd_ctrl, DRM_UNLOCKED | DRM_AUTH),
304};
305
306static const struct file_operations exynos_drm_driver_fops = {
307	.owner		= THIS_MODULE,
308	.open		= drm_open,
309	.mmap		= exynos_drm_gem_mmap,
310	.poll		= drm_poll,
311	.read		= drm_read,
312	.unlocked_ioctl	= drm_ioctl,
313#ifdef CONFIG_COMPAT
314	.compat_ioctl = drm_compat_ioctl,
315#endif
316	.release	= drm_release,
317};
318
319static struct drm_driver exynos_drm_driver = {
320	.driver_features	= DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
321	.load			= exynos_drm_load,
322	.unload			= exynos_drm_unload,
323	.suspend		= exynos_drm_suspend,
324	.resume			= exynos_drm_resume,
325	.open			= exynos_drm_open,
326	.preclose		= exynos_drm_preclose,
327	.lastclose		= exynos_drm_lastclose,
328	.postclose		= exynos_drm_postclose,
329	.set_busid		= drm_platform_set_busid,
330	.get_vblank_counter	= drm_vblank_count,
331	.enable_vblank		= exynos_drm_crtc_enable_vblank,
332	.disable_vblank		= exynos_drm_crtc_disable_vblank,
333	.gem_free_object	= exynos_drm_gem_free_object,
334	.gem_vm_ops		= &exynos_drm_gem_vm_ops,
335	.dumb_create		= exynos_drm_gem_dumb_create,
336	.dumb_map_offset	= exynos_drm_gem_dumb_map_offset,
337	.dumb_destroy		= drm_gem_dumb_destroy,
338	.prime_handle_to_fd	= drm_gem_prime_handle_to_fd,
339	.prime_fd_to_handle	= drm_gem_prime_fd_to_handle,
340	.gem_prime_export	= exynos_dmabuf_prime_export,
341	.gem_prime_import	= exynos_dmabuf_prime_import,
342	.ioctls			= exynos_ioctls,
343	.num_ioctls		= ARRAY_SIZE(exynos_ioctls),
344	.fops			= &exynos_drm_driver_fops,
345	.name	= DRIVER_NAME,
346	.desc	= DRIVER_DESC,
347	.date	= DRIVER_DATE,
348	.major	= DRIVER_MAJOR,
349	.minor	= DRIVER_MINOR,
350};
351
352#ifdef CONFIG_PM_SLEEP
353static int exynos_drm_sys_suspend(struct device *dev)
354{
355	struct drm_device *drm_dev = dev_get_drvdata(dev);
356	pm_message_t message;
357
358	if (pm_runtime_suspended(dev) || !drm_dev)
359		return 0;
360
361	message.event = PM_EVENT_SUSPEND;
362	return exynos_drm_suspend(drm_dev, message);
363}
364
365static int exynos_drm_sys_resume(struct device *dev)
366{
367	struct drm_device *drm_dev = dev_get_drvdata(dev);
368
369	if (pm_runtime_suspended(dev) || !drm_dev)
370		return 0;
371
372	return exynos_drm_resume(drm_dev);
373}
374#endif
375
376static const struct dev_pm_ops exynos_drm_pm_ops = {
377	SET_SYSTEM_SLEEP_PM_OPS(exynos_drm_sys_suspend, exynos_drm_sys_resume)
378};
379
380int exynos_drm_component_add(struct device *dev,
381				enum exynos_drm_device_type dev_type,
382				enum exynos_drm_output_type out_type)
383{
384	struct component_dev *cdev;
385
386	if (dev_type != EXYNOS_DEVICE_TYPE_CRTC &&
387			dev_type != EXYNOS_DEVICE_TYPE_CONNECTOR) {
388		DRM_ERROR("invalid device type.\n");
389		return -EINVAL;
390	}
391
392	mutex_lock(&drm_component_lock);
393
394	/*
395	 * Make sure to check if there is a component which has two device
396	 * objects, for connector and for encoder/connector.
397	 * It should make sure that crtc and encoder/connector drivers are
398	 * ready before exynos drm core binds them.
399	 */
400	list_for_each_entry(cdev, &drm_component_list, list) {
401		if (cdev->out_type == out_type) {
402			/*
403			 * If crtc and encoder/connector device objects are
404			 * added already just return.
405			 */
406			if (cdev->dev_type_flag == (EXYNOS_DEVICE_TYPE_CRTC |
407						EXYNOS_DEVICE_TYPE_CONNECTOR)) {
408				mutex_unlock(&drm_component_lock);
409				return 0;
410			}
411
412			if (dev_type == EXYNOS_DEVICE_TYPE_CRTC) {
413				cdev->crtc_dev = dev;
414				cdev->dev_type_flag |= dev_type;
415			}
416
417			if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR) {
418				cdev->conn_dev = dev;
419				cdev->dev_type_flag |= dev_type;
420			}
421
422			mutex_unlock(&drm_component_lock);
423			return 0;
424		}
425	}
426
427	mutex_unlock(&drm_component_lock);
428
429	cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
430	if (!cdev)
431		return -ENOMEM;
432
433	if (dev_type == EXYNOS_DEVICE_TYPE_CRTC)
434		cdev->crtc_dev = dev;
435	if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR)
436		cdev->conn_dev = dev;
437
438	cdev->out_type = out_type;
439	cdev->dev_type_flag = dev_type;
440
441	mutex_lock(&drm_component_lock);
442	list_add_tail(&cdev->list, &drm_component_list);
443	mutex_unlock(&drm_component_lock);
444
445	return 0;
446}
447
448void exynos_drm_component_del(struct device *dev,
449				enum exynos_drm_device_type dev_type)
450{
451	struct component_dev *cdev, *next;
452
453	mutex_lock(&drm_component_lock);
454
455	list_for_each_entry_safe(cdev, next, &drm_component_list, list) {
456		if (dev_type == EXYNOS_DEVICE_TYPE_CRTC) {
457			if (cdev->crtc_dev == dev) {
458				cdev->crtc_dev = NULL;
459				cdev->dev_type_flag &= ~dev_type;
460			}
461		}
462
463		if (dev_type == EXYNOS_DEVICE_TYPE_CONNECTOR) {
464			if (cdev->conn_dev == dev) {
465				cdev->conn_dev = NULL;
466				cdev->dev_type_flag &= ~dev_type;
467			}
468		}
469
470		/*
471		 * Release cdev object only in case that both of crtc and
472		 * encoder/connector device objects are NULL.
473		 */
474		if (!cdev->crtc_dev && !cdev->conn_dev) {
475			list_del(&cdev->list);
476			kfree(cdev);
477		}
478
479		break;
480	}
481
482	mutex_unlock(&drm_component_lock);
483}
484
485static int compare_dev(struct device *dev, void *data)
486{
487	return dev == (struct device *)data;
488}
489
490static struct component_match *exynos_drm_match_add(struct device *dev)
491{
492	struct component_match *match = NULL;
493	struct component_dev *cdev;
494	unsigned int attach_cnt = 0;
495
496	mutex_lock(&drm_component_lock);
497
498	/* Do not retry to probe if there is no any kms driver regitered. */
499	if (list_empty(&drm_component_list)) {
500		mutex_unlock(&drm_component_lock);
501		return ERR_PTR(-ENODEV);
502	}
503
504	list_for_each_entry(cdev, &drm_component_list, list) {
505		/*
506		 * Add components to master only in case that crtc and
507		 * encoder/connector device objects exist.
508		 */
509		if (!cdev->crtc_dev || !cdev->conn_dev)
510			continue;
511
512		attach_cnt++;
513
514		mutex_unlock(&drm_component_lock);
515
516		/*
517		 * fimd and dpi modules have same device object so add
518		 * only crtc device object in this case.
519		 */
520		if (cdev->crtc_dev == cdev->conn_dev) {
521			component_match_add(dev, &match, compare_dev,
522						cdev->crtc_dev);
523			goto out_lock;
524		}
525
526		/*
527		 * Do not chage below call order.
528		 * crtc device first should be added to master because
529		 * connector/encoder need pipe number of crtc when they
530		 * are created.
531		 */
532		component_match_add(dev, &match, compare_dev, cdev->crtc_dev);
533		component_match_add(dev, &match, compare_dev, cdev->conn_dev);
534
535out_lock:
536		mutex_lock(&drm_component_lock);
537	}
538
539	mutex_unlock(&drm_component_lock);
540
541	return attach_cnt ? match : ERR_PTR(-EPROBE_DEFER);
542}
543
544static int exynos_drm_bind(struct device *dev)
545{
546	return drm_platform_init(&exynos_drm_driver, to_platform_device(dev));
547}
548
549static void exynos_drm_unbind(struct device *dev)
550{
551	drm_put_dev(dev_get_drvdata(dev));
552}
553
554static const struct component_master_ops exynos_drm_ops = {
555	.bind		= exynos_drm_bind,
556	.unbind		= exynos_drm_unbind,
557};
558
559static int exynos_drm_platform_probe(struct platform_device *pdev)
560{
561	struct component_match *match;
562	int ret;
563
564	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
565	exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
566
567#ifdef CONFIG_DRM_EXYNOS_FIMD
568	ret = platform_driver_register(&fimd_driver);
569	if (ret < 0)
570		return ret;
571#endif
572
573#ifdef CONFIG_DRM_EXYNOS_DP
574	ret = platform_driver_register(&dp_driver);
575	if (ret < 0)
576		goto err_unregister_fimd_drv;
577#endif
578
579#ifdef CONFIG_DRM_EXYNOS_DSI
580	ret = platform_driver_register(&dsi_driver);
581	if (ret < 0)
582		goto err_unregister_dp_drv;
583#endif
584
585#ifdef CONFIG_DRM_EXYNOS_HDMI
586	ret = platform_driver_register(&mixer_driver);
587	if (ret < 0)
588		goto err_unregister_dsi_drv;
589	ret = platform_driver_register(&hdmi_driver);
590	if (ret < 0)
591		goto err_unregister_mixer_drv;
592#endif
593
594	match = exynos_drm_match_add(&pdev->dev);
595	if (IS_ERR(match)) {
596		ret = PTR_ERR(match);
597		goto err_unregister_hdmi_drv;
598	}
599
600	ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
601						match);
602	if (ret < 0)
603		goto err_unregister_hdmi_drv;
604
605#ifdef CONFIG_DRM_EXYNOS_G2D
606	ret = platform_driver_register(&g2d_driver);
607	if (ret < 0)
608		goto err_del_component_master;
609#endif
610
611#ifdef CONFIG_DRM_EXYNOS_FIMC
612	ret = platform_driver_register(&fimc_driver);
613	if (ret < 0)
614		goto err_unregister_g2d_drv;
615#endif
616
617#ifdef CONFIG_DRM_EXYNOS_ROTATOR
618	ret = platform_driver_register(&rotator_driver);
619	if (ret < 0)
620		goto err_unregister_fimc_drv;
621#endif
622
623#ifdef CONFIG_DRM_EXYNOS_GSC
624	ret = platform_driver_register(&gsc_driver);
625	if (ret < 0)
626		goto err_unregister_rotator_drv;
627#endif
628
629#ifdef CONFIG_DRM_EXYNOS_IPP
630	ret = platform_driver_register(&ipp_driver);
631	if (ret < 0)
632		goto err_unregister_gsc_drv;
633
634	ret = exynos_platform_device_ipp_register();
635	if (ret < 0)
636		goto err_unregister_ipp_drv;
637#endif
638
639	return ret;
640
641#ifdef CONFIG_DRM_EXYNOS_IPP
642err_unregister_ipp_drv:
643	platform_driver_unregister(&ipp_driver);
644err_unregister_gsc_drv:
645#endif
646
647#ifdef CONFIG_DRM_EXYNOS_GSC
648	platform_driver_unregister(&gsc_driver);
649err_unregister_rotator_drv:
650#endif
651
652#ifdef CONFIG_DRM_EXYNOS_ROTATOR
653	platform_driver_unregister(&rotator_driver);
654err_unregister_fimc_drv:
655#endif
656
657#ifdef CONFIG_DRM_EXYNOS_FIMC
658	platform_driver_unregister(&fimc_driver);
659err_unregister_g2d_drv:
660#endif
661
662#ifdef CONFIG_DRM_EXYNOS_G2D
663	platform_driver_unregister(&g2d_driver);
664err_del_component_master:
665#endif
666	component_master_del(&pdev->dev, &exynos_drm_ops);
667
668err_unregister_hdmi_drv:
669#ifdef CONFIG_DRM_EXYNOS_HDMI
670	platform_driver_unregister(&hdmi_driver);
671err_unregister_mixer_drv:
672	platform_driver_unregister(&mixer_driver);
673err_unregister_dsi_drv:
674#endif
675
676#ifdef CONFIG_DRM_EXYNOS_DSI
677	platform_driver_unregister(&dsi_driver);
678err_unregister_dp_drv:
679#endif
680
681#ifdef CONFIG_DRM_EXYNOS_DP
682	platform_driver_unregister(&dp_driver);
683err_unregister_fimd_drv:
684#endif
685
686#ifdef CONFIG_DRM_EXYNOS_FIMD
687	platform_driver_unregister(&fimd_driver);
688#endif
689	return ret;
690}
691
692static int exynos_drm_platform_remove(struct platform_device *pdev)
693{
694#ifdef CONFIG_DRM_EXYNOS_IPP
695	exynos_platform_device_ipp_unregister();
696	platform_driver_unregister(&ipp_driver);
697#endif
698
699#ifdef CONFIG_DRM_EXYNOS_GSC
700	platform_driver_unregister(&gsc_driver);
701#endif
702
703#ifdef CONFIG_DRM_EXYNOS_ROTATOR
704	platform_driver_unregister(&rotator_driver);
705#endif
706
707#ifdef CONFIG_DRM_EXYNOS_FIMC
708	platform_driver_unregister(&fimc_driver);
709#endif
710
711#ifdef CONFIG_DRM_EXYNOS_G2D
712	platform_driver_unregister(&g2d_driver);
713#endif
714
715#ifdef CONFIG_DRM_EXYNOS_HDMI
716	platform_driver_unregister(&mixer_driver);
717	platform_driver_unregister(&hdmi_driver);
718#endif
719
720#ifdef CONFIG_DRM_EXYNOS_FIMD
721	platform_driver_unregister(&fimd_driver);
722#endif
723
724#ifdef CONFIG_DRM_EXYNOS_DSI
725	platform_driver_unregister(&dsi_driver);
726#endif
727
728#ifdef CONFIG_DRM_EXYNOS_DP
729	platform_driver_unregister(&dp_driver);
730#endif
731	component_master_del(&pdev->dev, &exynos_drm_ops);
732	return 0;
733}
734
735static struct platform_driver exynos_drm_platform_driver = {
736	.probe	= exynos_drm_platform_probe,
737	.remove	= exynos_drm_platform_remove,
738	.driver	= {
739		.owner	= THIS_MODULE,
740		.name	= "exynos-drm",
741		.pm	= &exynos_drm_pm_ops,
742	},
743};
744
745static int exynos_drm_init(void)
746{
747	int ret;
748
749	/*
750	 * Register device object only in case of Exynos SoC.
751	 *
752	 * Below codes resolves temporarily infinite loop issue incurred
753	 * by Exynos drm driver when using multi-platform kernel.
754	 * So these codes will be replaced with more generic way later.
755	 */
756	if (!of_machine_is_compatible("samsung,exynos3") &&
757			!of_machine_is_compatible("samsung,exynos4") &&
758			!of_machine_is_compatible("samsung,exynos5"))
759		return -ENODEV;
760
761	exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1,
762								NULL, 0);
763	if (IS_ERR(exynos_drm_pdev))
764		return PTR_ERR(exynos_drm_pdev);
765
766#ifdef CONFIG_DRM_EXYNOS_VIDI
767	ret = exynos_drm_probe_vidi();
768	if (ret < 0)
769		goto err_unregister_pd;
770#endif
771
772	ret = platform_driver_register(&exynos_drm_platform_driver);
773	if (ret)
774		goto err_remove_vidi;
775
776	return 0;
777
778err_remove_vidi:
779#ifdef CONFIG_DRM_EXYNOS_VIDI
780	exynos_drm_remove_vidi();
781
782err_unregister_pd:
783#endif
784	platform_device_unregister(exynos_drm_pdev);
785
786	return ret;
787}
788
789static void exynos_drm_exit(void)
790{
791	platform_driver_unregister(&exynos_drm_platform_driver);
792#ifdef CONFIG_DRM_EXYNOS_VIDI
793	exynos_drm_remove_vidi();
794#endif
795	platform_device_unregister(exynos_drm_pdev);
796}
797
798module_init(exynos_drm_init);
799module_exit(exynos_drm_exit);
800
801MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
802MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
803MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>");
804MODULE_DESCRIPTION("Samsung SoC DRM Driver");
805MODULE_LICENSE("GPL");
806