diff options
Diffstat (limited to 'drivers/gpu/drm/sun4i/sun4i_drv.c')
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_drv.c | 50 |
1 files changed, 21 insertions, 29 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index 76e922bb60e5..257d2b4f3645 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c | |||
@@ -24,34 +24,6 @@ | |||
24 | #include "sun4i_layer.h" | 24 | #include "sun4i_layer.h" |
25 | #include "sun4i_tcon.h" | 25 | #include "sun4i_tcon.h" |
26 | 26 | ||
27 | static int sun4i_drv_connector_plug_all(struct drm_device *drm) | ||
28 | { | ||
29 | struct drm_connector *connector, *failed; | ||
30 | int ret; | ||
31 | |||
32 | mutex_lock(&drm->mode_config.mutex); | ||
33 | list_for_each_entry(connector, &drm->mode_config.connector_list, head) { | ||
34 | ret = drm_connector_register(connector); | ||
35 | if (ret) { | ||
36 | failed = connector; | ||
37 | goto err; | ||
38 | } | ||
39 | } | ||
40 | mutex_unlock(&drm->mode_config.mutex); | ||
41 | return 0; | ||
42 | |||
43 | err: | ||
44 | list_for_each_entry(connector, &drm->mode_config.connector_list, head) { | ||
45 | if (failed == connector) | ||
46 | break; | ||
47 | |||
48 | drm_connector_unregister(connector); | ||
49 | } | ||
50 | mutex_unlock(&drm->mode_config.mutex); | ||
51 | |||
52 | return ret; | ||
53 | } | ||
54 | |||
55 | static int sun4i_drv_enable_vblank(struct drm_device *drm, unsigned int pipe) | 27 | static int sun4i_drv_enable_vblank(struct drm_device *drm, unsigned int pipe) |
56 | { | 28 | { |
57 | struct sun4i_drv *drv = drm->dev_private; | 29 | struct sun4i_drv *drv = drm->dev_private; |
@@ -125,6 +97,22 @@ static struct drm_driver sun4i_drv_driver = { | |||
125 | .disable_vblank = sun4i_drv_disable_vblank, | 97 | .disable_vblank = sun4i_drv_disable_vblank, |
126 | }; | 98 | }; |
127 | 99 | ||
100 | static void sun4i_remove_framebuffers(void) | ||
101 | { | ||
102 | struct apertures_struct *ap; | ||
103 | |||
104 | ap = alloc_apertures(1); | ||
105 | if (!ap) | ||
106 | return; | ||
107 | |||
108 | /* The framebuffer can be located anywhere in RAM */ | ||
109 | ap->ranges[0].base = 0; | ||
110 | ap->ranges[0].size = ~0; | ||
111 | |||
112 | remove_conflicting_framebuffers(ap, "sun4i-drm-fb", false); | ||
113 | kfree(ap); | ||
114 | } | ||
115 | |||
128 | static int sun4i_drv_bind(struct device *dev) | 116 | static int sun4i_drv_bind(struct device *dev) |
129 | { | 117 | { |
130 | struct drm_device *drm; | 118 | struct drm_device *drm; |
@@ -172,6 +160,9 @@ static int sun4i_drv_bind(struct device *dev) | |||
172 | } | 160 | } |
173 | drm->irq_enabled = true; | 161 | drm->irq_enabled = true; |
174 | 162 | ||
163 | /* Remove early framebuffers (ie. simplefb) */ | ||
164 | sun4i_remove_framebuffers(); | ||
165 | |||
175 | /* Create our framebuffer */ | 166 | /* Create our framebuffer */ |
176 | drv->fbdev = sun4i_framebuffer_init(drm); | 167 | drv->fbdev = sun4i_framebuffer_init(drm); |
177 | if (IS_ERR(drv->fbdev)) { | 168 | if (IS_ERR(drv->fbdev)) { |
@@ -187,7 +178,7 @@ static int sun4i_drv_bind(struct device *dev) | |||
187 | if (ret) | 178 | if (ret) |
188 | goto free_drm; | 179 | goto free_drm; |
189 | 180 | ||
190 | ret = sun4i_drv_connector_plug_all(drm); | 181 | ret = drm_connector_register_all(drm); |
191 | if (ret) | 182 | if (ret) |
192 | goto unregister_drm; | 183 | goto unregister_drm; |
193 | 184 | ||
@@ -204,6 +195,7 @@ static void sun4i_drv_unbind(struct device *dev) | |||
204 | { | 195 | { |
205 | struct drm_device *drm = dev_get_drvdata(dev); | 196 | struct drm_device *drm = dev_get_drvdata(dev); |
206 | 197 | ||
198 | drm_connector_unregister_all(drm); | ||
207 | drm_dev_unregister(drm); | 199 | drm_dev_unregister(drm); |
208 | drm_kms_helper_poll_fini(drm); | 200 | drm_kms_helper_poll_fini(drm); |
209 | sun4i_framebuffer_free(drm); | 201 | sun4i_framebuffer_free(drm); |