aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorInki Dae <inki.dae@samsung.com>2012-08-17 00:23:25 -0400
committerInki Dae <inki.dae@samsung.com>2012-10-03 21:05:59 -0400
commit41fecf3e8268b8f285c91620c20895e946db9177 (patch)
treedd81af6909343b204aba7dea9454d74a8f96000b /drivers/gpu
parent29cb602532b0a82f22322cece8a89f022368d557 (diff)
drm/exynos: separated subdrv_probe function into two parts.
Changelog v2: fixed the issue that when sub driver is probed, no kms drivers such as fimd or hdmi are failed. no kms drivers have no manager so if manager is null then encoder and connector creation should be ignored. Changelog v1: this patch separates exynos_drm_subdrv_probe function into sub driver's probe call and encoder/connector creation so that exynos drm core module can take exception when some operation was failed properly. Signed-off-by: Inki Dae <inki.dae@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_core.c100
1 files changed, 69 insertions, 31 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 80cba2f413f4..7b0432b7a364 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -34,33 +34,15 @@
34 34
35static LIST_HEAD(exynos_drm_subdrv_list); 35static LIST_HEAD(exynos_drm_subdrv_list);
36 36
37static int exynos_drm_subdrv_probe(struct drm_device *dev, 37static int exynos_drm_create_enc_conn(struct drm_device *dev,
38 struct exynos_drm_subdrv *subdrv) 38 struct exynos_drm_subdrv *subdrv)
39{ 39{
40 struct drm_encoder *encoder; 40 struct drm_encoder *encoder;
41 struct drm_connector *connector; 41 struct drm_connector *connector;
42 int ret;
42 43
43 DRM_DEBUG_DRIVER("%s\n", __FILE__); 44 DRM_DEBUG_DRIVER("%s\n", __FILE__);
44 45
45 if (subdrv->probe) {
46 int ret;
47
48 /*
49 * this probe callback would be called by sub driver
50 * after setting of all resources to this sub driver,
51 * such as clock, irq and register map are done or by load()
52 * of exynos drm driver.
53 *
54 * P.S. note that this driver is considered for modularization.
55 */
56 ret = subdrv->probe(dev, subdrv->dev);
57 if (ret)
58 return ret;
59 }
60
61 if (!subdrv->manager)
62 return 0;
63
64 subdrv->manager->dev = subdrv->dev; 46 subdrv->manager->dev = subdrv->dev;
65 47
66 /* create and initialize a encoder for this sub driver. */ 48 /* create and initialize a encoder for this sub driver. */
@@ -78,24 +60,22 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev,
78 connector = exynos_drm_connector_create(dev, encoder); 60 connector = exynos_drm_connector_create(dev, encoder);
79 if (!connector) { 61 if (!connector) {
80 DRM_ERROR("failed to create connector\n"); 62 DRM_ERROR("failed to create connector\n");
81 encoder->funcs->destroy(encoder); 63 ret = -EFAULT;
82 return -EFAULT; 64 goto err_destroy_encoder;
83 } 65 }
84 66
85 subdrv->encoder = encoder; 67 subdrv->encoder = encoder;
86 subdrv->connector = connector; 68 subdrv->connector = connector;
87 69
88 return 0; 70 return 0;
71
72err_destroy_encoder:
73 encoder->funcs->destroy(encoder);
74 return ret;
89} 75}
90 76
91static void exynos_drm_subdrv_remove(struct drm_device *dev, 77static void exynos_drm_destroy_enc_conn(struct exynos_drm_subdrv *subdrv)
92 struct exynos_drm_subdrv *subdrv)
93{ 78{
94 DRM_DEBUG_DRIVER("%s\n", __FILE__);
95
96 if (subdrv->remove)
97 subdrv->remove(dev, subdrv->dev);
98
99 if (subdrv->encoder) { 79 if (subdrv->encoder) {
100 struct drm_encoder *encoder = subdrv->encoder; 80 struct drm_encoder *encoder = subdrv->encoder;
101 encoder->funcs->destroy(encoder); 81 encoder->funcs->destroy(encoder);
@@ -109,9 +89,43 @@ static void exynos_drm_subdrv_remove(struct drm_device *dev,
109 } 89 }
110} 90}
111 91
92static int exynos_drm_subdrv_probe(struct drm_device *dev,
93 struct exynos_drm_subdrv *subdrv)
94{
95 if (subdrv->probe) {
96 int ret;
97
98 subdrv->drm_dev = dev;
99
100 /*
101 * this probe callback would be called by sub driver
102 * after setting of all resources to this sub driver,
103 * such as clock, irq and register map are done or by load()
104 * of exynos drm driver.
105 *
106 * P.S. note that this driver is considered for modularization.
107 */
108 ret = subdrv->probe(dev, subdrv->dev);
109 if (ret)
110 return ret;
111 }
112
113 return 0;
114}
115
116static void exynos_drm_subdrv_remove(struct drm_device *dev,
117 struct exynos_drm_subdrv *subdrv)
118{
119 DRM_DEBUG_DRIVER("%s\n", __FILE__);
120
121 if (subdrv->remove)
122 subdrv->remove(dev, subdrv->dev);
123}
124
112int exynos_drm_device_register(struct drm_device *dev) 125int exynos_drm_device_register(struct drm_device *dev)
113{ 126{
114 struct exynos_drm_subdrv *subdrv, *n; 127 struct exynos_drm_subdrv *subdrv, *n;
128 unsigned int fine_cnt = 0;
115 int err; 129 int err;
116 130
117 DRM_DEBUG_DRIVER("%s\n", __FILE__); 131 DRM_DEBUG_DRIVER("%s\n", __FILE__);
@@ -120,14 +134,36 @@ int exynos_drm_device_register(struct drm_device *dev)
120 return -EINVAL; 134 return -EINVAL;
121 135
122 list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) { 136 list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) {
123 subdrv->drm_dev = dev;
124 err = exynos_drm_subdrv_probe(dev, subdrv); 137 err = exynos_drm_subdrv_probe(dev, subdrv);
125 if (err) { 138 if (err) {
126 DRM_DEBUG("exynos drm subdrv probe failed.\n"); 139 DRM_DEBUG("exynos drm subdrv probe failed.\n");
127 list_del(&subdrv->list); 140 list_del(&subdrv->list);
141 continue;
142 }
143
144 /*
145 * if manager is null then it means that this sub driver
146 * doesn't need encoder and connector.
147 */
148 if (!subdrv->manager) {
149 fine_cnt++;
150 continue;
128 } 151 }
152
153 err = exynos_drm_create_enc_conn(dev, subdrv);
154 if (err) {
155 DRM_DEBUG("failed to create encoder and connector.\n");
156 exynos_drm_subdrv_remove(dev, subdrv);
157 list_del(&subdrv->list);
158 continue;
159 }
160
161 fine_cnt++;
129 } 162 }
130 163
164 if (!fine_cnt)
165 return -EINVAL;
166
131 return 0; 167 return 0;
132} 168}
133EXPORT_SYMBOL_GPL(exynos_drm_device_register); 169EXPORT_SYMBOL_GPL(exynos_drm_device_register);
@@ -143,8 +179,10 @@ int exynos_drm_device_unregister(struct drm_device *dev)
143 return -EINVAL; 179 return -EINVAL;
144 } 180 }
145 181
146 list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) 182 list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
147 exynos_drm_subdrv_remove(dev, subdrv); 183 exynos_drm_subdrv_remove(dev, subdrv);
184 exynos_drm_destroy_enc_conn(subdrv);
185 }
148 186
149 return 0; 187 return 0;
150} 188}