Commit | Line | Data |
---|---|---|
1c248b7d ID |
1 | /* exynos_drm_core.c |
2 | * | |
3 | * Copyright (c) 2011 Samsung Electronics Co., Ltd. | |
4 | * Author: | |
5 | * Inki Dae <inki.dae@samsung.com> | |
6 | * Joonyoung Shim <jy0922.shim@samsung.com> | |
7 | * Seung-Woo Kim <sw0312.kim@samsung.com> | |
8 | * | |
d81aecb5 ID |
9 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License as published by the | |
11 | * Free Software Foundation; either version 2 of the License, or (at your | |
12 | * option) any later version. | |
1c248b7d ID |
13 | */ |
14 | ||
760285e7 | 15 | #include <drm/drmP.h> |
1c248b7d | 16 | #include "exynos_drm_drv.h" |
080be03d | 17 | #include "exynos_drm_crtc.h" |
1c248b7d ID |
18 | #include "exynos_drm_fbdev.h" |
19 | ||
1c248b7d | 20 | static LIST_HEAD(exynos_drm_subdrv_list); |
1c248b7d | 21 | |
f37cd5e8 | 22 | int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv) |
080be03d | 23 | { |
f37cd5e8 ID |
24 | if (!subdrv) |
25 | return -EINVAL; | |
080be03d | 26 | |
f37cd5e8 | 27 | list_add_tail(&subdrv->list, &exynos_drm_subdrv_list); |
080be03d | 28 | |
080be03d | 29 | return 0; |
080be03d SP |
30 | } |
31 | ||
f37cd5e8 | 32 | int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *subdrv) |
080be03d | 33 | { |
f37cd5e8 ID |
34 | if (!subdrv) |
35 | return -EINVAL; | |
080be03d | 36 | |
f37cd5e8 | 37 | list_del(&subdrv->list); |
080be03d | 38 | |
080be03d | 39 | return 0; |
080be03d SP |
40 | } |
41 | ||
f37cd5e8 | 42 | int exynos_drm_device_subdrv_probe(struct drm_device *dev) |
1c248b7d ID |
43 | { |
44 | struct exynos_drm_subdrv *subdrv, *n; | |
45 | int err; | |
46 | ||
1c248b7d ID |
47 | if (!dev) |
48 | return -EINVAL; | |
49 | ||
1c248b7d | 50 | list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) { |
f37cd5e8 ID |
51 | if (subdrv->probe) { |
52 | subdrv->drm_dev = dev; | |
53 | ||
54 | /* | |
55 | * this probe callback would be called by sub driver | |
56 | * after setting of all resources to this sub driver, | |
57 | * such as clock, irq and register map are done. | |
58 | */ | |
59 | err = subdrv->probe(dev, subdrv->dev); | |
60 | if (err) { | |
61 | DRM_DEBUG("exynos drm subdrv probe failed.\n"); | |
62 | list_del(&subdrv->list); | |
63 | continue; | |
64 | } | |
41fecf3e | 65 | } |
1c248b7d ID |
66 | } |
67 | ||
1c248b7d ID |
68 | return 0; |
69 | } | |
1c248b7d | 70 | |
f37cd5e8 | 71 | int exynos_drm_device_subdrv_remove(struct drm_device *dev) |
1c248b7d ID |
72 | { |
73 | struct exynos_drm_subdrv *subdrv; | |
74 | ||
132a5b91 | 75 | if (!dev) { |
1c248b7d ID |
76 | WARN(1, "Unexpected drm device unregister!\n"); |
77 | return -EINVAL; | |
78 | } | |
79 | ||
41fecf3e | 80 | list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { |
f37cd5e8 ID |
81 | if (subdrv->remove) |
82 | subdrv->remove(dev, subdrv->dev); | |
41fecf3e | 83 | } |
1c248b7d | 84 | |
1c248b7d ID |
85 | return 0; |
86 | } | |
9084f7b8 JS |
87 | |
88 | int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) | |
89 | { | |
90 | struct exynos_drm_subdrv *subdrv; | |
91 | int ret; | |
92 | ||
93 | list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { | |
94 | if (subdrv->open) { | |
677e84c1 | 95 | ret = subdrv->open(dev, subdrv->dev, file); |
9084f7b8 JS |
96 | if (ret) |
97 | goto err; | |
98 | } | |
99 | } | |
100 | ||
101 | return 0; | |
102 | ||
103 | err: | |
55c4b906 | 104 | list_for_each_entry_continue_reverse(subdrv, &exynos_drm_subdrv_list, list) { |
9084f7b8 | 105 | if (subdrv->close) |
677e84c1 | 106 | subdrv->close(dev, subdrv->dev, file); |
9084f7b8 JS |
107 | } |
108 | return ret; | |
109 | } | |
9084f7b8 JS |
110 | |
111 | void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file) | |
112 | { | |
113 | struct exynos_drm_subdrv *subdrv; | |
114 | ||
115 | list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { | |
116 | if (subdrv->close) | |
677e84c1 | 117 | subdrv->close(dev, subdrv->dev, file); |
9084f7b8 JS |
118 | } |
119 | } |