Merge tag 'mmc-v4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
[cascardo/linux.git] / drivers / gpu / drm / exynos / exynos_drm_drv.c
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_atomic.h>
17 #include <drm/drm_atomic_helper.h>
18 #include <drm/drm_crtc_helper.h>
19
20 #include <linux/component.h>
21
22 #include <drm/exynos_drm.h>
23
24 #include "exynos_drm_drv.h"
25 #include "exynos_drm_crtc.h"
26 #include "exynos_drm_fbdev.h"
27 #include "exynos_drm_fb.h"
28 #include "exynos_drm_gem.h"
29 #include "exynos_drm_plane.h"
30 #include "exynos_drm_vidi.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
41 struct exynos_atomic_commit {
42         struct work_struct      work;
43         struct drm_device       *dev;
44         struct drm_atomic_state *state;
45         u32                     crtcs;
46 };
47
48 static void exynos_atomic_commit_complete(struct exynos_atomic_commit *commit)
49 {
50         struct drm_device *dev = commit->dev;
51         struct exynos_drm_private *priv = dev->dev_private;
52         struct drm_atomic_state *state = commit->state;
53
54         drm_atomic_helper_commit_modeset_disables(dev, state);
55
56         drm_atomic_helper_commit_modeset_enables(dev, state);
57
58         /*
59          * Exynos can't update planes with CRTCs and encoders disabled,
60          * its updates routines, specially for FIMD, requires the clocks
61          * to be enabled. So it is necessary to handle the modeset operations
62          * *before* the commit_planes() step, this way it will always
63          * have the relevant clocks enabled to perform the update.
64          */
65
66         drm_atomic_helper_commit_planes(dev, state, 0);
67
68         drm_atomic_helper_wait_for_vblanks(dev, state);
69
70         drm_atomic_helper_cleanup_planes(dev, state);
71
72         drm_atomic_state_free(state);
73
74         spin_lock(&priv->lock);
75         priv->pending &= ~commit->crtcs;
76         spin_unlock(&priv->lock);
77
78         wake_up_all(&priv->wait);
79
80         kfree(commit);
81 }
82
83 static void exynos_drm_atomic_work(struct work_struct *work)
84 {
85         struct exynos_atomic_commit *commit = container_of(work,
86                                 struct exynos_atomic_commit, work);
87
88         exynos_atomic_commit_complete(commit);
89 }
90
91 static struct device *exynos_drm_get_dma_device(void);
92
93 static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
94 {
95         struct exynos_drm_private *private;
96         struct drm_encoder *encoder;
97         unsigned int clone_mask;
98         int cnt, ret;
99
100         private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
101         if (!private)
102                 return -ENOMEM;
103
104         init_waitqueue_head(&private->wait);
105         spin_lock_init(&private->lock);
106
107         dev_set_drvdata(dev->dev, dev);
108         dev->dev_private = (void *)private;
109
110         /* the first real CRTC device is used for all dma mapping operations */
111         private->dma_dev = exynos_drm_get_dma_device();
112         if (!private->dma_dev) {
113                 DRM_ERROR("no device found for DMA mapping operations.\n");
114                 ret = -ENODEV;
115                 goto err_free_private;
116         }
117         DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n",
118                  dev_name(private->dma_dev));
119
120         /* create common IOMMU mapping for all devices attached to Exynos DRM */
121         ret = drm_create_iommu_mapping(dev);
122         if (ret < 0) {
123                 DRM_ERROR("failed to create iommu mapping.\n");
124                 goto err_free_private;
125         }
126
127         drm_mode_config_init(dev);
128
129         exynos_drm_mode_config_init(dev);
130
131         /* setup possible_clones. */
132         cnt = 0;
133         clone_mask = 0;
134         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
135                 clone_mask |= (1 << (cnt++));
136
137         list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
138                 encoder->possible_clones = clone_mask;
139
140         platform_set_drvdata(dev->platformdev, dev);
141
142         /* Try to bind all sub drivers. */
143         ret = component_bind_all(dev->dev, dev);
144         if (ret)
145                 goto err_mode_config_cleanup;
146
147         ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
148         if (ret)
149                 goto err_unbind_all;
150
151         /* Probe non kms sub drivers and virtual display driver. */
152         ret = exynos_drm_device_subdrv_probe(dev);
153         if (ret)
154                 goto err_cleanup_vblank;
155
156         drm_mode_config_reset(dev);
157
158         /*
159          * enable drm irq mode.
160          * - with irq_enabled = true, we can use the vblank feature.
161          *
162          * P.S. note that we wouldn't use drm irq handler but
163          *      just specific driver own one instead because
164          *      drm framework supports only one irq handler.
165          */
166         dev->irq_enabled = true;
167
168         /* init kms poll for handling hpd */
169         drm_kms_helper_poll_init(dev);
170
171         /* force connectors detection */
172         drm_helper_hpd_irq_event(dev);
173
174         return 0;
175
176 err_cleanup_vblank:
177         drm_vblank_cleanup(dev);
178 err_unbind_all:
179         component_unbind_all(dev->dev, dev);
180 err_mode_config_cleanup:
181         drm_mode_config_cleanup(dev);
182         drm_release_iommu_mapping(dev);
183 err_free_private:
184         kfree(private);
185
186         return ret;
187 }
188
189 static int exynos_drm_unload(struct drm_device *dev)
190 {
191         exynos_drm_device_subdrv_remove(dev);
192
193         exynos_drm_fbdev_fini(dev);
194         drm_kms_helper_poll_fini(dev);
195
196         drm_vblank_cleanup(dev);
197         component_unbind_all(dev->dev, dev);
198         drm_mode_config_cleanup(dev);
199         drm_release_iommu_mapping(dev);
200
201         kfree(dev->dev_private);
202         dev->dev_private = NULL;
203
204         return 0;
205 }
206
207 static int commit_is_pending(struct exynos_drm_private *priv, u32 crtcs)
208 {
209         bool pending;
210
211         spin_lock(&priv->lock);
212         pending = priv->pending & crtcs;
213         spin_unlock(&priv->lock);
214
215         return pending;
216 }
217
218 int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
219                          bool nonblock)
220 {
221         struct exynos_drm_private *priv = dev->dev_private;
222         struct exynos_atomic_commit *commit;
223         struct drm_crtc *crtc;
224         struct drm_crtc_state *crtc_state;
225         int i, ret;
226
227         commit = kzalloc(sizeof(*commit), GFP_KERNEL);
228         if (!commit)
229                 return -ENOMEM;
230
231         ret = drm_atomic_helper_prepare_planes(dev, state);
232         if (ret) {
233                 kfree(commit);
234                 return ret;
235         }
236
237         /* This is the point of no return */
238
239         INIT_WORK(&commit->work, exynos_drm_atomic_work);
240         commit->dev = dev;
241         commit->state = state;
242
243         /* Wait until all affected CRTCs have completed previous commits and
244          * mark them as pending.
245          */
246         for_each_crtc_in_state(state, crtc, crtc_state, i)
247                 commit->crtcs |= drm_crtc_mask(crtc);
248
249         wait_event(priv->wait, !commit_is_pending(priv, commit->crtcs));
250
251         spin_lock(&priv->lock);
252         priv->pending |= commit->crtcs;
253         spin_unlock(&priv->lock);
254
255         drm_atomic_helper_swap_state(state, true);
256
257         if (nonblock)
258                 schedule_work(&commit->work);
259         else
260                 exynos_atomic_commit_complete(commit);
261
262         return 0;
263 }
264
265 static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
266 {
267         struct drm_exynos_file_private *file_priv;
268         int ret;
269
270         file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
271         if (!file_priv)
272                 return -ENOMEM;
273
274         file->driver_priv = file_priv;
275
276         ret = exynos_drm_subdrv_open(dev, file);
277         if (ret)
278                 goto err_file_priv_free;
279
280         return ret;
281
282 err_file_priv_free:
283         kfree(file_priv);
284         file->driver_priv = NULL;
285         return ret;
286 }
287
288 static void exynos_drm_preclose(struct drm_device *dev,
289                                         struct drm_file *file)
290 {
291         struct drm_crtc *crtc;
292
293         exynos_drm_subdrv_close(dev, file);
294
295         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
296                 exynos_drm_crtc_cancel_page_flip(crtc, file);
297 }
298
299 static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
300 {
301         kfree(file->driver_priv);
302         file->driver_priv = NULL;
303 }
304
305 static void exynos_drm_lastclose(struct drm_device *dev)
306 {
307         exynos_drm_fbdev_restore_mode(dev);
308 }
309
310 static const struct vm_operations_struct exynos_drm_gem_vm_ops = {
311         .fault = exynos_drm_gem_fault,
312         .open = drm_gem_vm_open,
313         .close = drm_gem_vm_close,
314 };
315
316 static const struct drm_ioctl_desc exynos_ioctls[] = {
317         DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl,
318                         DRM_AUTH | DRM_RENDER_ALLOW),
319         DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP, exynos_drm_gem_map_ioctl,
320                         DRM_AUTH | DRM_RENDER_ALLOW),
321         DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET, exynos_drm_gem_get_ioctl,
322                         DRM_RENDER_ALLOW),
323         DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION, vidi_connection_ioctl,
324                         DRM_AUTH),
325         DRM_IOCTL_DEF_DRV(EXYNOS_G2D_GET_VER, exynos_g2d_get_ver_ioctl,
326                         DRM_AUTH | DRM_RENDER_ALLOW),
327         DRM_IOCTL_DEF_DRV(EXYNOS_G2D_SET_CMDLIST, exynos_g2d_set_cmdlist_ioctl,
328                         DRM_AUTH | DRM_RENDER_ALLOW),
329         DRM_IOCTL_DEF_DRV(EXYNOS_G2D_EXEC, exynos_g2d_exec_ioctl,
330                         DRM_AUTH | DRM_RENDER_ALLOW),
331         DRM_IOCTL_DEF_DRV(EXYNOS_IPP_GET_PROPERTY, exynos_drm_ipp_get_property,
332                         DRM_AUTH | DRM_RENDER_ALLOW),
333         DRM_IOCTL_DEF_DRV(EXYNOS_IPP_SET_PROPERTY, exynos_drm_ipp_set_property,
334                         DRM_AUTH | DRM_RENDER_ALLOW),
335         DRM_IOCTL_DEF_DRV(EXYNOS_IPP_QUEUE_BUF, exynos_drm_ipp_queue_buf,
336                         DRM_AUTH | DRM_RENDER_ALLOW),
337         DRM_IOCTL_DEF_DRV(EXYNOS_IPP_CMD_CTRL, exynos_drm_ipp_cmd_ctrl,
338                         DRM_AUTH | DRM_RENDER_ALLOW),
339 };
340
341 static const struct file_operations exynos_drm_driver_fops = {
342         .owner          = THIS_MODULE,
343         .open           = drm_open,
344         .mmap           = exynos_drm_gem_mmap,
345         .poll           = drm_poll,
346         .read           = drm_read,
347         .unlocked_ioctl = drm_ioctl,
348 #ifdef CONFIG_COMPAT
349         .compat_ioctl = drm_compat_ioctl,
350 #endif
351         .release        = drm_release,
352 };
353
354 static struct drm_driver exynos_drm_driver = {
355         .driver_features        = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME
356                                   | DRIVER_ATOMIC | DRIVER_RENDER,
357         .load                   = exynos_drm_load,
358         .unload                 = exynos_drm_unload,
359         .open                   = exynos_drm_open,
360         .preclose               = exynos_drm_preclose,
361         .lastclose              = exynos_drm_lastclose,
362         .postclose              = exynos_drm_postclose,
363         .get_vblank_counter     = drm_vblank_no_hw_counter,
364         .enable_vblank          = exynos_drm_crtc_enable_vblank,
365         .disable_vblank         = exynos_drm_crtc_disable_vblank,
366         .gem_free_object_unlocked = exynos_drm_gem_free_object,
367         .gem_vm_ops             = &exynos_drm_gem_vm_ops,
368         .dumb_create            = exynos_drm_gem_dumb_create,
369         .dumb_map_offset        = exynos_drm_gem_dumb_map_offset,
370         .dumb_destroy           = drm_gem_dumb_destroy,
371         .prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
372         .prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
373         .gem_prime_export       = drm_gem_prime_export,
374         .gem_prime_import       = drm_gem_prime_import,
375         .gem_prime_get_sg_table = exynos_drm_gem_prime_get_sg_table,
376         .gem_prime_import_sg_table      = exynos_drm_gem_prime_import_sg_table,
377         .gem_prime_vmap         = exynos_drm_gem_prime_vmap,
378         .gem_prime_vunmap       = exynos_drm_gem_prime_vunmap,
379         .gem_prime_mmap         = exynos_drm_gem_prime_mmap,
380         .ioctls                 = exynos_ioctls,
381         .num_ioctls             = ARRAY_SIZE(exynos_ioctls),
382         .fops                   = &exynos_drm_driver_fops,
383         .name   = DRIVER_NAME,
384         .desc   = DRIVER_DESC,
385         .date   = DRIVER_DATE,
386         .major  = DRIVER_MAJOR,
387         .minor  = DRIVER_MINOR,
388 };
389
390 #ifdef CONFIG_PM_SLEEP
391 static int exynos_drm_suspend(struct device *dev)
392 {
393         struct drm_device *drm_dev = dev_get_drvdata(dev);
394         struct drm_connector *connector;
395
396         if (pm_runtime_suspended(dev) || !drm_dev)
397                 return 0;
398
399         drm_modeset_lock_all(drm_dev);
400         drm_for_each_connector(connector, drm_dev) {
401                 int old_dpms = connector->dpms;
402
403                 if (connector->funcs->dpms)
404                         connector->funcs->dpms(connector, DRM_MODE_DPMS_OFF);
405
406                 /* Set the old mode back to the connector for resume */
407                 connector->dpms = old_dpms;
408         }
409         drm_modeset_unlock_all(drm_dev);
410
411         return 0;
412 }
413
414 static int exynos_drm_resume(struct device *dev)
415 {
416         struct drm_device *drm_dev = dev_get_drvdata(dev);
417         struct drm_connector *connector;
418
419         if (pm_runtime_suspended(dev) || !drm_dev)
420                 return 0;
421
422         drm_modeset_lock_all(drm_dev);
423         drm_for_each_connector(connector, drm_dev) {
424                 if (connector->funcs->dpms) {
425                         int dpms = connector->dpms;
426
427                         connector->dpms = DRM_MODE_DPMS_OFF;
428                         connector->funcs->dpms(connector, dpms);
429                 }
430         }
431         drm_modeset_unlock_all(drm_dev);
432
433         return 0;
434 }
435 #endif
436
437 static const struct dev_pm_ops exynos_drm_pm_ops = {
438         SET_SYSTEM_SLEEP_PM_OPS(exynos_drm_suspend, exynos_drm_resume)
439 };
440
441 /* forward declaration */
442 static struct platform_driver exynos_drm_platform_driver;
443
444 struct exynos_drm_driver_info {
445         struct platform_driver *driver;
446         unsigned int flags;
447 };
448
449 #define DRM_COMPONENT_DRIVER    BIT(0)  /* supports component framework */
450 #define DRM_VIRTUAL_DEVICE      BIT(1)  /* create virtual platform device */
451 #define DRM_DMA_DEVICE          BIT(2)  /* can be used for dma allocations */
452
453 #define DRV_PTR(drv, cond) (IS_ENABLED(cond) ? &drv : NULL)
454
455 /*
456  * Connector drivers should not be placed before associated crtc drivers,
457  * because connector requires pipe number of its crtc during initialization.
458  */
459 static struct exynos_drm_driver_info exynos_drm_drivers[] = {
460         {
461                 DRV_PTR(fimd_driver, CONFIG_DRM_EXYNOS_FIMD),
462                 DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
463         }, {
464                 DRV_PTR(exynos5433_decon_driver, CONFIG_DRM_EXYNOS5433_DECON),
465                 DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
466         }, {
467                 DRV_PTR(decon_driver, CONFIG_DRM_EXYNOS7_DECON),
468                 DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
469         }, {
470                 DRV_PTR(mixer_driver, CONFIG_DRM_EXYNOS_MIXER),
471                 DRM_COMPONENT_DRIVER | DRM_DMA_DEVICE
472         }, {
473                 DRV_PTR(mic_driver, CONFIG_DRM_EXYNOS_MIC),
474                 DRM_COMPONENT_DRIVER
475         }, {
476                 DRV_PTR(dp_driver, CONFIG_DRM_EXYNOS_DP),
477                 DRM_COMPONENT_DRIVER
478         }, {
479                 DRV_PTR(dsi_driver, CONFIG_DRM_EXYNOS_DSI),
480                 DRM_COMPONENT_DRIVER
481         }, {
482                 DRV_PTR(hdmi_driver, CONFIG_DRM_EXYNOS_HDMI),
483                 DRM_COMPONENT_DRIVER
484         }, {
485                 DRV_PTR(vidi_driver, CONFIG_DRM_EXYNOS_VIDI),
486                 DRM_COMPONENT_DRIVER | DRM_VIRTUAL_DEVICE
487         }, {
488                 DRV_PTR(g2d_driver, CONFIG_DRM_EXYNOS_G2D),
489         }, {
490                 DRV_PTR(fimc_driver, CONFIG_DRM_EXYNOS_FIMC),
491         }, {
492                 DRV_PTR(rotator_driver, CONFIG_DRM_EXYNOS_ROTATOR),
493         }, {
494                 DRV_PTR(gsc_driver, CONFIG_DRM_EXYNOS_GSC),
495         }, {
496                 DRV_PTR(ipp_driver, CONFIG_DRM_EXYNOS_IPP),
497                 DRM_VIRTUAL_DEVICE
498         }, {
499                 &exynos_drm_platform_driver,
500                 DRM_VIRTUAL_DEVICE
501         }
502 };
503
504 static int compare_dev(struct device *dev, void *data)
505 {
506         return dev == (struct device *)data;
507 }
508
509 static struct component_match *exynos_drm_match_add(struct device *dev)
510 {
511         struct component_match *match = NULL;
512         int i;
513
514         for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
515                 struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
516                 struct device *p = NULL, *d;
517
518                 if (!info->driver || !(info->flags & DRM_COMPONENT_DRIVER))
519                         continue;
520
521                 while ((d = bus_find_device(&platform_bus_type, p,
522                                             &info->driver->driver,
523                                             (void *)platform_bus_type.match))) {
524                         put_device(p);
525                         component_match_add(dev, &match, compare_dev, d);
526                         p = d;
527                 }
528                 put_device(p);
529         }
530
531         return match ?: ERR_PTR(-ENODEV);
532 }
533
534 static int exynos_drm_bind(struct device *dev)
535 {
536         return drm_platform_init(&exynos_drm_driver, to_platform_device(dev));
537 }
538
539 static void exynos_drm_unbind(struct device *dev)
540 {
541         drm_put_dev(dev_get_drvdata(dev));
542 }
543
544 static const struct component_master_ops exynos_drm_ops = {
545         .bind           = exynos_drm_bind,
546         .unbind         = exynos_drm_unbind,
547 };
548
549 static int exynos_drm_platform_probe(struct platform_device *pdev)
550 {
551         struct component_match *match;
552
553         pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
554         exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
555
556         match = exynos_drm_match_add(&pdev->dev);
557         if (IS_ERR(match))
558                 return PTR_ERR(match);
559
560         return component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
561                                                match);
562 }
563
564 static int exynos_drm_platform_remove(struct platform_device *pdev)
565 {
566         component_master_del(&pdev->dev, &exynos_drm_ops);
567         return 0;
568 }
569
570 static struct platform_driver exynos_drm_platform_driver = {
571         .probe  = exynos_drm_platform_probe,
572         .remove = exynos_drm_platform_remove,
573         .driver = {
574                 .name   = "exynos-drm",
575                 .pm     = &exynos_drm_pm_ops,
576         },
577 };
578
579 static struct device *exynos_drm_get_dma_device(void)
580 {
581         int i;
582
583         for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
584                 struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
585                 struct device *dev;
586
587                 if (!info->driver || !(info->flags & DRM_DMA_DEVICE))
588                         continue;
589
590                 while ((dev = bus_find_device(&platform_bus_type, NULL,
591                                             &info->driver->driver,
592                                             (void *)platform_bus_type.match))) {
593                         put_device(dev);
594                         return dev;
595                 }
596         }
597         return NULL;
598 }
599
600 static void exynos_drm_unregister_devices(void)
601 {
602         int i;
603
604         for (i = ARRAY_SIZE(exynos_drm_drivers) - 1; i >= 0; --i) {
605                 struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
606                 struct device *dev;
607
608                 if (!info->driver || !(info->flags & DRM_VIRTUAL_DEVICE))
609                         continue;
610
611                 while ((dev = bus_find_device(&platform_bus_type, NULL,
612                                             &info->driver->driver,
613                                             (void *)platform_bus_type.match))) {
614                         put_device(dev);
615                         platform_device_unregister(to_platform_device(dev));
616                 }
617         }
618 }
619
620 static int exynos_drm_register_devices(void)
621 {
622         struct platform_device *pdev;
623         int i;
624
625         for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
626                 struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
627
628                 if (!info->driver || !(info->flags & DRM_VIRTUAL_DEVICE))
629                         continue;
630
631                 pdev = platform_device_register_simple(
632                                         info->driver->driver.name, -1, NULL, 0);
633                 if (IS_ERR(pdev))
634                         goto fail;
635         }
636
637         return 0;
638 fail:
639         exynos_drm_unregister_devices();
640         return PTR_ERR(pdev);
641 }
642
643 static void exynos_drm_unregister_drivers(void)
644 {
645         int i;
646
647         for (i = ARRAY_SIZE(exynos_drm_drivers) - 1; i >= 0; --i) {
648                 struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
649
650                 if (!info->driver)
651                         continue;
652
653                 platform_driver_unregister(info->driver);
654         }
655 }
656
657 static int exynos_drm_register_drivers(void)
658 {
659         int i, ret;
660
661         for (i = 0; i < ARRAY_SIZE(exynos_drm_drivers); ++i) {
662                 struct exynos_drm_driver_info *info = &exynos_drm_drivers[i];
663
664                 if (!info->driver)
665                         continue;
666
667                 ret = platform_driver_register(info->driver);
668                 if (ret)
669                         goto fail;
670         }
671         return 0;
672 fail:
673         exynos_drm_unregister_drivers();
674         return ret;
675 }
676
677 static int exynos_drm_init(void)
678 {
679         int ret;
680
681         ret = exynos_drm_register_devices();
682         if (ret)
683                 return ret;
684
685         ret = exynos_drm_register_drivers();
686         if (ret)
687                 goto err_unregister_pdevs;
688
689         return 0;
690
691 err_unregister_pdevs:
692         exynos_drm_unregister_devices();
693
694         return ret;
695 }
696
697 static void exynos_drm_exit(void)
698 {
699         exynos_drm_unregister_drivers();
700         exynos_drm_unregister_devices();
701 }
702
703 module_init(exynos_drm_init);
704 module_exit(exynos_drm_exit);
705
706 MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
707 MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
708 MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>");
709 MODULE_DESCRIPTION("Samsung SoC DRM Driver");
710 MODULE_LICENSE("GPL");