Commit f0feb1b9a225185b540e8ebdcdbe97e908a31e8e

Authored by Anand Balagopalakrishnan
Committed by Jacob Stiffler
1 parent f2978651e3

drm: remove automatic load of omapdrm_pvr

omapdrm plugin patch automatically tries to load the SGX (omapdrm_pvr) kernel
module as part of dev_open. The name of SGX kernel module in Android is
pvrsrvkm.

This patch removes the auto-load of omapdrm_pvr kernel module to ensure common
code base across Linux and Android.

Change-Id: I03d7e92b9e6f9addd41e83614e8878d8cfc244b7
Signed-off-by: Anand Balagopalakrishnan <anandb@ti.com>

Showing 1 changed file with 0 additions and 13 deletions Inline Diff

drivers/gpu/drm/omapdrm/omap_drv.c
1 /* 1 /*
2 * drivers/gpu/drm/omapdrm/omap_drv.c 2 * drivers/gpu/drm/omapdrm/omap_drv.c
3 * 3 *
4 * Copyright (C) 2011 Texas Instruments 4 * Copyright (C) 2011 Texas Instruments
5 * Author: Rob Clark <rob@ti.com> 5 * Author: Rob Clark <rob@ti.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by 8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation. 9 * the Free Software Foundation.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT 11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details. 14 * more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License along with 16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>. 17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */ 18 */
19 19
20 #include "omap_drv.h" 20 #include "omap_drv.h"
21 21
22 #include "drm_crtc_helper.h" 22 #include "drm_crtc_helper.h"
23 #include "drm_fb_helper.h" 23 #include "drm_fb_helper.h"
24 #include "omap_dmm_tiler.h" 24 #include "omap_dmm_tiler.h"
25 25
26 #define DRIVER_NAME MODULE_NAME 26 #define DRIVER_NAME MODULE_NAME
27 #define DRIVER_DESC "OMAP DRM" 27 #define DRIVER_DESC "OMAP DRM"
28 #define DRIVER_DATE "20110917" 28 #define DRIVER_DATE "20110917"
29 #define DRIVER_MAJOR 1 29 #define DRIVER_MAJOR 1
30 #define DRIVER_MINOR 0 30 #define DRIVER_MINOR 0
31 #define DRIVER_PATCHLEVEL 0 31 #define DRIVER_PATCHLEVEL 0
32 32
33 struct drm_device *drm_device; 33 struct drm_device *drm_device;
34 34
35 static int num_crtc = CONFIG_DRM_OMAP_NUM_CRTCS; 35 static int num_crtc = CONFIG_DRM_OMAP_NUM_CRTCS;
36 36
37 MODULE_PARM_DESC(num_crtc, "Number of overlays to use as CRTCs"); 37 MODULE_PARM_DESC(num_crtc, "Number of overlays to use as CRTCs");
38 module_param(num_crtc, int, 0600); 38 module_param(num_crtc, int, 0600);
39 39
40 /* TODO: think about how to handle more than one plugin.. ie. some ops 40 /* TODO: think about how to handle more than one plugin.. ie. some ops
41 * me might want to stop on the first plugin that doesn't return an 41 * me might want to stop on the first plugin that doesn't return an
42 * error, etc.. 42 * error, etc..
43 */ 43 */
44 LIST_HEAD(plugin_list); 44 LIST_HEAD(plugin_list);
45 45
46 /* keep track of whether we are already loaded.. we may need to call 46 /* keep track of whether we are already loaded.. we may need to call
47 * plugin's load() if they register after we are already loaded 47 * plugin's load() if they register after we are already loaded
48 */ 48 */
49 static __read_mostly bool loaded = false; 49 static __read_mostly bool loaded = false;
50 50
51 /* 51 /*
52 * mode config funcs 52 * mode config funcs
53 */ 53 */
54 54
55 /* Notes about mapping DSS and DRM entities: 55 /* Notes about mapping DSS and DRM entities:
56 * CRTC: overlay 56 * CRTC: overlay
57 * encoder: manager.. with some extension to allow one primary CRTC 57 * encoder: manager.. with some extension to allow one primary CRTC
58 * and zero or more video CRTC's to be mapped to one encoder? 58 * and zero or more video CRTC's to be mapped to one encoder?
59 * connector: dssdev.. manager can be attached/detached from different 59 * connector: dssdev.. manager can be attached/detached from different
60 * devices 60 * devices
61 */ 61 */
62 62
63 static void omap_fb_output_poll_changed(struct drm_device *dev) 63 static void omap_fb_output_poll_changed(struct drm_device *dev)
64 { 64 {
65 struct omap_drm_private *priv = dev->dev_private; 65 struct omap_drm_private *priv = dev->dev_private;
66 DBG("dev=%p", dev); 66 DBG("dev=%p", dev);
67 if (priv->fbdev) 67 if (priv->fbdev)
68 drm_fb_helper_hotplug_event(priv->fbdev); 68 drm_fb_helper_hotplug_event(priv->fbdev);
69 } 69 }
70 70
71 static const struct drm_mode_config_funcs omap_mode_config_funcs = { 71 static const struct drm_mode_config_funcs omap_mode_config_funcs = {
72 .fb_create = omap_framebuffer_create, 72 .fb_create = omap_framebuffer_create,
73 .output_poll_changed = omap_fb_output_poll_changed, 73 .output_poll_changed = omap_fb_output_poll_changed,
74 }; 74 };
75 75
76 static int get_connector_type(struct omap_dss_device *dssdev) 76 static int get_connector_type(struct omap_dss_device *dssdev)
77 { 77 {
78 switch (dssdev->type) { 78 switch (dssdev->type) {
79 case OMAP_DISPLAY_TYPE_HDMI: 79 case OMAP_DISPLAY_TYPE_HDMI:
80 return DRM_MODE_CONNECTOR_HDMIA; 80 return DRM_MODE_CONNECTOR_HDMIA;
81 case OMAP_DISPLAY_TYPE_DVI: 81 case OMAP_DISPLAY_TYPE_DVI:
82 return DRM_MODE_CONNECTOR_DVID; 82 return DRM_MODE_CONNECTOR_DVID;
83 default: 83 default:
84 return DRM_MODE_CONNECTOR_Unknown; 84 return DRM_MODE_CONNECTOR_Unknown;
85 } 85 }
86 } 86 }
87 87
88 static bool channel_used(struct drm_device *dev, enum omap_channel channel) 88 static bool channel_used(struct drm_device *dev, enum omap_channel channel)
89 { 89 {
90 struct omap_drm_private *priv = dev->dev_private; 90 struct omap_drm_private *priv = dev->dev_private;
91 int i; 91 int i;
92 92
93 for (i = 0; i < priv->num_crtcs; i++) { 93 for (i = 0; i < priv->num_crtcs; i++) {
94 struct drm_crtc *crtc = priv->crtcs[i]; 94 struct drm_crtc *crtc = priv->crtcs[i];
95 95
96 if (omap_crtc_channel(crtc) == channel) 96 if (omap_crtc_channel(crtc) == channel)
97 return true; 97 return true;
98 } 98 }
99 99
100 return false; 100 return false;
101 } 101 }
102 static void omap_disconnect_dssdevs(void) 102 static void omap_disconnect_dssdevs(void)
103 { 103 {
104 struct omap_dss_device *dssdev = NULL; 104 struct omap_dss_device *dssdev = NULL;
105 105
106 for_each_dss_dev(dssdev) 106 for_each_dss_dev(dssdev)
107 dssdev->driver->disconnect(dssdev); 107 dssdev->driver->disconnect(dssdev);
108 } 108 }
109 109
110 static bool dssdev_with_alias_exists(const char *alias) 110 static bool dssdev_with_alias_exists(const char *alias)
111 { 111 {
112 struct omap_dss_device *dssdev = NULL; 112 struct omap_dss_device *dssdev = NULL;
113 113
114 for_each_dss_dev(dssdev) { 114 for_each_dss_dev(dssdev) {
115 if (strcmp(alias, dssdev->alias) == 0) { 115 if (strcmp(alias, dssdev->alias) == 0) {
116 omap_dss_put_device(dssdev); 116 omap_dss_put_device(dssdev);
117 return true; 117 return true;
118 } 118 }
119 } 119 }
120 120
121 return false; 121 return false;
122 } 122 }
123 123
124 static int omap_connect_dssdevs(void) 124 static int omap_connect_dssdevs(void)
125 { 125 {
126 int r; 126 int r;
127 struct omap_dss_device *dssdev = NULL; 127 struct omap_dss_device *dssdev = NULL;
128 bool no_displays = true; 128 bool no_displays = true;
129 struct device_node *aliases; 129 struct device_node *aliases;
130 struct property *pp; 130 struct property *pp;
131 131
132 aliases = of_find_node_by_path("/aliases"); 132 aliases = of_find_node_by_path("/aliases");
133 if (aliases) { 133 if (aliases) {
134 for_each_property_of_node(aliases, pp) { 134 for_each_property_of_node(aliases, pp) {
135 if (strncmp(pp->name, "display", 7) != 0) 135 if (strncmp(pp->name, "display", 7) != 0)
136 continue; 136 continue;
137 137
138 if (dssdev_with_alias_exists(pp->name) == false) 138 if (dssdev_with_alias_exists(pp->name) == false)
139 return -EPROBE_DEFER; 139 return -EPROBE_DEFER;
140 } 140 }
141 } 141 }
142 142
143 for_each_dss_dev(dssdev) { 143 for_each_dss_dev(dssdev) {
144 r = dssdev->driver->connect(dssdev); 144 r = dssdev->driver->connect(dssdev);
145 if (r == -EPROBE_DEFER) { 145 if (r == -EPROBE_DEFER) {
146 omap_dss_put_device(dssdev); 146 omap_dss_put_device(dssdev);
147 goto cleanup; 147 goto cleanup;
148 } else if (r) { 148 } else if (r) {
149 dev_warn(dssdev->dev, "could not connect display: %s\n", 149 dev_warn(dssdev->dev, "could not connect display: %s\n",
150 dssdev->name); 150 dssdev->name);
151 } else { 151 } else {
152 no_displays = false; 152 no_displays = false;
153 } 153 }
154 } 154 }
155 155
156 if (no_displays) 156 if (no_displays)
157 return -EPROBE_DEFER; 157 return -EPROBE_DEFER;
158 158
159 return 0; 159 return 0;
160 160
161 cleanup: 161 cleanup:
162 /* 162 /*
163 * if we are deferring probe, we disconnect the devices we previously 163 * if we are deferring probe, we disconnect the devices we previously
164 * connected 164 * connected
165 */ 165 */
166 omap_disconnect_dssdevs(); 166 omap_disconnect_dssdevs();
167 167
168 return r; 168 return r;
169 } 169 }
170 170
171 static int omap_modeset_init(struct drm_device *dev) 171 static int omap_modeset_init(struct drm_device *dev)
172 { 172 {
173 struct omap_drm_private *priv = dev->dev_private; 173 struct omap_drm_private *priv = dev->dev_private;
174 struct omap_dss_device *dssdev = NULL; 174 struct omap_dss_device *dssdev = NULL;
175 int num_ovls = dss_feat_get_num_ovls(); 175 int num_ovls = dss_feat_get_num_ovls();
176 int num_mgrs = dss_feat_get_num_mgrs(); 176 int num_mgrs = dss_feat_get_num_mgrs();
177 int num_crtcs; 177 int num_crtcs;
178 int i, id = 0; 178 int i, id = 0;
179 179
180 drm_mode_config_init(dev); 180 drm_mode_config_init(dev);
181 181
182 omap_drm_irq_install(dev); 182 omap_drm_irq_install(dev);
183 183
184 /* 184 /*
185 * We usually don't want to create a CRTC for each manager, at least 185 * We usually don't want to create a CRTC for each manager, at least
186 * not until we have a way to expose private planes to userspace. 186 * not until we have a way to expose private planes to userspace.
187 * Otherwise there would not be enough video pipes left for drm planes. 187 * Otherwise there would not be enough video pipes left for drm planes.
188 * We use the num_crtc argument to limit the number of crtcs we create. 188 * We use the num_crtc argument to limit the number of crtcs we create.
189 */ 189 */
190 num_crtcs = min3(num_crtc, num_mgrs, num_ovls); 190 num_crtcs = min3(num_crtc, num_mgrs, num_ovls);
191 191
192 dssdev = NULL; 192 dssdev = NULL;
193 193
194 for_each_dss_dev(dssdev) { 194 for_each_dss_dev(dssdev) {
195 struct drm_connector *connector; 195 struct drm_connector *connector;
196 struct drm_encoder *encoder; 196 struct drm_encoder *encoder;
197 enum omap_channel channel; 197 enum omap_channel channel;
198 struct omap_overlay_manager *mgr; 198 struct omap_overlay_manager *mgr;
199 199
200 if (!omapdss_device_is_connected(dssdev)) 200 if (!omapdss_device_is_connected(dssdev))
201 continue; 201 continue;
202 202
203 encoder = omap_encoder_init(dev, dssdev); 203 encoder = omap_encoder_init(dev, dssdev);
204 204
205 if (!encoder) { 205 if (!encoder) {
206 dev_err(dev->dev, "could not create encoder: %s\n", 206 dev_err(dev->dev, "could not create encoder: %s\n",
207 dssdev->name); 207 dssdev->name);
208 return -ENOMEM; 208 return -ENOMEM;
209 } 209 }
210 210
211 connector = omap_connector_init(dev, 211 connector = omap_connector_init(dev,
212 get_connector_type(dssdev), dssdev, encoder); 212 get_connector_type(dssdev), dssdev, encoder);
213 213
214 if (!connector) { 214 if (!connector) {
215 dev_err(dev->dev, "could not create connector: %s\n", 215 dev_err(dev->dev, "could not create connector: %s\n",
216 dssdev->name); 216 dssdev->name);
217 return -ENOMEM; 217 return -ENOMEM;
218 } 218 }
219 219
220 BUG_ON(priv->num_encoders >= ARRAY_SIZE(priv->encoders)); 220 BUG_ON(priv->num_encoders >= ARRAY_SIZE(priv->encoders));
221 BUG_ON(priv->num_connectors >= ARRAY_SIZE(priv->connectors)); 221 BUG_ON(priv->num_connectors >= ARRAY_SIZE(priv->connectors));
222 222
223 priv->encoders[priv->num_encoders++] = encoder; 223 priv->encoders[priv->num_encoders++] = encoder;
224 priv->connectors[priv->num_connectors++] = connector; 224 priv->connectors[priv->num_connectors++] = connector;
225 225
226 drm_mode_connector_attach_encoder(connector, encoder); 226 drm_mode_connector_attach_encoder(connector, encoder);
227 227
228 /* 228 /*
229 * if we have reached the limit of the crtcs we are allowed to 229 * if we have reached the limit of the crtcs we are allowed to
230 * create, let's not try to look for a crtc for this 230 * create, let's not try to look for a crtc for this
231 * panel/encoder and onwards, we will, of course, populate the 231 * panel/encoder and onwards, we will, of course, populate the
232 * the possible_crtcs field for all the encoders with the final 232 * the possible_crtcs field for all the encoders with the final
233 * set of crtcs we create 233 * set of crtcs we create
234 */ 234 */
235 if (id == num_crtcs) 235 if (id == num_crtcs)
236 continue; 236 continue;
237 237
238 /* 238 /*
239 * get the recommended DISPC channel for this encoder. For now, 239 * get the recommended DISPC channel for this encoder. For now,
240 * we only try to get create a crtc out of the recommended, the 240 * we only try to get create a crtc out of the recommended, the
241 * other possible channels to which the encoder can connect are 241 * other possible channels to which the encoder can connect are
242 * not considered. 242 * not considered.
243 */ 243 */
244 244
245 mgr = omapdss_find_mgr_from_display(dssdev); 245 mgr = omapdss_find_mgr_from_display(dssdev);
246 channel = mgr->id; 246 channel = mgr->id;
247 /* 247 /*
248 * if this channel hasn't already been taken by a previously 248 * if this channel hasn't already been taken by a previously
249 * allocated crtc, we create a new crtc for it 249 * allocated crtc, we create a new crtc for it
250 */ 250 */
251 if (!channel_used(dev, channel)) { 251 if (!channel_used(dev, channel)) {
252 struct drm_plane *plane; 252 struct drm_plane *plane;
253 struct drm_crtc *crtc; 253 struct drm_crtc *crtc;
254 254
255 plane = omap_plane_init(dev, id, true); 255 plane = omap_plane_init(dev, id, true);
256 crtc = omap_crtc_init(dev, plane, channel, id); 256 crtc = omap_crtc_init(dev, plane, channel, id);
257 257
258 BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); 258 BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs));
259 priv->crtcs[id] = crtc; 259 priv->crtcs[id] = crtc;
260 priv->num_crtcs++; 260 priv->num_crtcs++;
261 261
262 priv->planes[id] = plane; 262 priv->planes[id] = plane;
263 priv->num_planes++; 263 priv->num_planes++;
264 264
265 id++; 265 id++;
266 } 266 }
267 } 267 }
268 268
269 /* 269 /*
270 * we have allocated crtcs according to the need of the panels/encoders, 270 * we have allocated crtcs according to the need of the panels/encoders,
271 * adding more crtcs here if needed 271 * adding more crtcs here if needed
272 */ 272 */
273 for (; id < num_crtcs; id++) { 273 for (; id < num_crtcs; id++) {
274 274
275 /* find a free manager for this crtc */ 275 /* find a free manager for this crtc */
276 for (i = 0; i < num_mgrs; i++) { 276 for (i = 0; i < num_mgrs; i++) {
277 if (!channel_used(dev, i)) { 277 if (!channel_used(dev, i)) {
278 struct drm_plane *plane; 278 struct drm_plane *plane;
279 struct drm_crtc *crtc; 279 struct drm_crtc *crtc;
280 280
281 plane = omap_plane_init(dev, id, true); 281 plane = omap_plane_init(dev, id, true);
282 crtc = omap_crtc_init(dev, plane, i, id); 282 crtc = omap_crtc_init(dev, plane, i, id);
283 283
284 BUG_ON(priv->num_crtcs >= 284 BUG_ON(priv->num_crtcs >=
285 ARRAY_SIZE(priv->crtcs)); 285 ARRAY_SIZE(priv->crtcs));
286 286
287 priv->crtcs[id] = crtc; 287 priv->crtcs[id] = crtc;
288 priv->num_crtcs++; 288 priv->num_crtcs++;
289 289
290 priv->planes[id] = plane; 290 priv->planes[id] = plane;
291 priv->num_planes++; 291 priv->num_planes++;
292 292
293 break; 293 break;
294 } else { 294 } else {
295 continue; 295 continue;
296 } 296 }
297 } 297 }
298 298
299 if (i == num_mgrs) { 299 if (i == num_mgrs) {
300 /* this shouldn't really happen */ 300 /* this shouldn't really happen */
301 dev_err(dev->dev, "no managers left for crtc\n"); 301 dev_err(dev->dev, "no managers left for crtc\n");
302 return -ENOMEM; 302 return -ENOMEM;
303 } 303 }
304 } 304 }
305 305
306 /* 306 /*
307 * Create normal planes for the remaining overlays: 307 * Create normal planes for the remaining overlays:
308 */ 308 */
309 for (; id < num_ovls; id++) { 309 for (; id < num_ovls; id++) {
310 struct drm_plane *plane = omap_plane_init(dev, id, false); 310 struct drm_plane *plane = omap_plane_init(dev, id, false);
311 311
312 BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)); 312 BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes));
313 priv->planes[priv->num_planes++] = plane; 313 priv->planes[priv->num_planes++] = plane;
314 } 314 }
315 315
316 for (i = 0; i < priv->num_encoders; i++) { 316 for (i = 0; i < priv->num_encoders; i++) {
317 struct drm_encoder *encoder = priv->encoders[i]; 317 struct drm_encoder *encoder = priv->encoders[i];
318 struct omap_dss_device *dssdev = 318 struct omap_dss_device *dssdev =
319 omap_encoder_get_dssdev(encoder); 319 omap_encoder_get_dssdev(encoder);
320 struct omap_dss_device *output; 320 struct omap_dss_device *output;
321 321
322 output = omapdss_find_output_from_display(dssdev); 322 output = omapdss_find_output_from_display(dssdev);
323 323
324 /* figure out which crtc's we can connect the encoder to: */ 324 /* figure out which crtc's we can connect the encoder to: */
325 encoder->possible_crtcs = 0; 325 encoder->possible_crtcs = 0;
326 for (id = 0; id < priv->num_crtcs; id++) { 326 for (id = 0; id < priv->num_crtcs; id++) {
327 struct drm_crtc *crtc = priv->crtcs[id]; 327 struct drm_crtc *crtc = priv->crtcs[id];
328 enum omap_channel crtc_channel; 328 enum omap_channel crtc_channel;
329 329
330 crtc_channel = omap_crtc_channel(crtc); 330 crtc_channel = omap_crtc_channel(crtc);
331 331
332 if (output->dispc_channel == crtc_channel) { 332 if (output->dispc_channel == crtc_channel) {
333 encoder->possible_crtcs |= (1 << id); 333 encoder->possible_crtcs |= (1 << id);
334 break; 334 break;
335 } 335 }
336 } 336 }
337 337
338 omap_dss_put_device(output); 338 omap_dss_put_device(output);
339 } 339 }
340 340
341 DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n", 341 DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n",
342 priv->num_planes, priv->num_crtcs, priv->num_encoders, 342 priv->num_planes, priv->num_crtcs, priv->num_encoders,
343 priv->num_connectors); 343 priv->num_connectors);
344 344
345 dev->mode_config.min_width = 32; 345 dev->mode_config.min_width = 32;
346 dev->mode_config.min_height = 32; 346 dev->mode_config.min_height = 32;
347 347
348 /* note: eventually will need some cpu_is_omapXYZ() type stuff here 348 /* note: eventually will need some cpu_is_omapXYZ() type stuff here
349 * to fill in these limits properly on different OMAP generations.. 349 * to fill in these limits properly on different OMAP generations..
350 */ 350 */
351 dev->mode_config.max_width = 2048; 351 dev->mode_config.max_width = 2048;
352 dev->mode_config.max_height = 2048; 352 dev->mode_config.max_height = 2048;
353 353
354 dev->mode_config.funcs = &omap_mode_config_funcs; 354 dev->mode_config.funcs = &omap_mode_config_funcs;
355 355
356 return 0; 356 return 0;
357 } 357 }
358 358
359 static void omap_modeset_free(struct drm_device *dev) 359 static void omap_modeset_free(struct drm_device *dev)
360 { 360 {
361 drm_mode_config_cleanup(dev); 361 drm_mode_config_cleanup(dev);
362 } 362 }
363 363
364 /* 364 /*
365 * drm ioctl funcs 365 * drm ioctl funcs
366 */ 366 */
367 367
368 368
369 static int ioctl_get_param(struct drm_device *dev, void *data, 369 static int ioctl_get_param(struct drm_device *dev, void *data,
370 struct drm_file *file_priv) 370 struct drm_file *file_priv)
371 { 371 {
372 struct omap_drm_private *priv = dev->dev_private; 372 struct omap_drm_private *priv = dev->dev_private;
373 struct drm_omap_param *args = data; 373 struct drm_omap_param *args = data;
374 374
375 DBG("%p: param=%llu", dev, args->param); 375 DBG("%p: param=%llu", dev, args->param);
376 376
377 switch (args->param) { 377 switch (args->param) {
378 case OMAP_PARAM_CHIPSET_ID: 378 case OMAP_PARAM_CHIPSET_ID:
379 args->value = priv->omaprev; 379 args->value = priv->omaprev;
380 break; 380 break;
381 default: 381 default:
382 DBG("unknown parameter %lld", args->param); 382 DBG("unknown parameter %lld", args->param);
383 return -EINVAL; 383 return -EINVAL;
384 } 384 }
385 385
386 return 0; 386 return 0;
387 } 387 }
388 388
389 static int ioctl_set_param(struct drm_device *dev, void *data, 389 static int ioctl_set_param(struct drm_device *dev, void *data,
390 struct drm_file *file_priv) 390 struct drm_file *file_priv)
391 { 391 {
392 struct drm_omap_param *args = data; 392 struct drm_omap_param *args = data;
393 393
394 switch (args->param) { 394 switch (args->param) {
395 default: 395 default:
396 DBG("unknown parameter %lld", args->param); 396 DBG("unknown parameter %lld", args->param);
397 return -EINVAL; 397 return -EINVAL;
398 } 398 }
399 399
400 return 0; 400 return 0;
401 } 401 }
402 402
403 static int ioctl_get_base(struct drm_device *dev, void *data, 403 static int ioctl_get_base(struct drm_device *dev, void *data,
404 struct drm_file *file_priv) 404 struct drm_file *file_priv)
405 { 405 {
406 struct drm_omap_get_base *args = data; 406 struct drm_omap_get_base *args = data;
407 struct omap_drm_plugin *plugin; 407 struct omap_drm_plugin *plugin;
408 408
409 /* be safe: */ 409 /* be safe: */
410 args->plugin_name[ARRAY_SIZE(args->plugin_name) - 1] = '\0'; 410 args->plugin_name[ARRAY_SIZE(args->plugin_name) - 1] = '\0';
411 411
412 DBG("%p: plugin_name=%s", dev, args->plugin_name); 412 DBG("%p: plugin_name=%s", dev, args->plugin_name);
413 413
414 list_for_each_entry(plugin, &plugin_list, list) { 414 list_for_each_entry(plugin, &plugin_list, list) {
415 if (!strcmp(args->plugin_name, plugin->name)) { 415 if (!strcmp(args->plugin_name, plugin->name)) {
416 args->ioctl_base = plugin->ioctl_base; 416 args->ioctl_base = plugin->ioctl_base;
417 return 0; 417 return 0;
418 } 418 }
419 } 419 }
420 420
421 return -EINVAL; 421 return -EINVAL;
422 } 422 }
423 423
424 static int ioctl_gem_new(struct drm_device *dev, void *data, 424 static int ioctl_gem_new(struct drm_device *dev, void *data,
425 struct drm_file *file_priv) 425 struct drm_file *file_priv)
426 { 426 {
427 struct drm_omap_gem_new *args = data; 427 struct drm_omap_gem_new *args = data;
428 VERB("%p:%p: size=0x%08x, flags=%08x", dev, file_priv, 428 VERB("%p:%p: size=0x%08x, flags=%08x", dev, file_priv,
429 args->size.bytes, args->flags); 429 args->size.bytes, args->flags);
430 return omap_gem_new_handle(dev, file_priv, args->size, 430 return omap_gem_new_handle(dev, file_priv, args->size,
431 args->flags, &args->handle); 431 args->flags, &args->handle);
432 } 432 }
433 433
434 static int ioctl_gem_cpu_prep(struct drm_device *dev, void *data, 434 static int ioctl_gem_cpu_prep(struct drm_device *dev, void *data,
435 struct drm_file *file_priv) 435 struct drm_file *file_priv)
436 { 436 {
437 struct drm_omap_gem_cpu_prep *args = data; 437 struct drm_omap_gem_cpu_prep *args = data;
438 struct drm_gem_object *obj; 438 struct drm_gem_object *obj;
439 int ret; 439 int ret;
440 440
441 VERB("%p:%p: handle=%d, op=%x", dev, file_priv, args->handle, args->op); 441 VERB("%p:%p: handle=%d, op=%x", dev, file_priv, args->handle, args->op);
442 442
443 obj = drm_gem_object_lookup(dev, file_priv, args->handle); 443 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
444 if (!obj) 444 if (!obj)
445 return -ENOENT; 445 return -ENOENT;
446 446
447 ret = omap_gem_op_sync(obj, args->op); 447 ret = omap_gem_op_sync(obj, args->op);
448 448
449 if (!ret) 449 if (!ret)
450 ret = omap_gem_op_start(obj, args->op); 450 ret = omap_gem_op_start(obj, args->op);
451 451
452 drm_gem_object_unreference_unlocked(obj); 452 drm_gem_object_unreference_unlocked(obj);
453 453
454 return ret; 454 return ret;
455 } 455 }
456 456
457 static int ioctl_gem_cpu_fini(struct drm_device *dev, void *data, 457 static int ioctl_gem_cpu_fini(struct drm_device *dev, void *data,
458 struct drm_file *file_priv) 458 struct drm_file *file_priv)
459 { 459 {
460 struct drm_omap_gem_cpu_fini *args = data; 460 struct drm_omap_gem_cpu_fini *args = data;
461 struct drm_gem_object *obj; 461 struct drm_gem_object *obj;
462 int ret; 462 int ret;
463 463
464 VERB("%p:%p: handle=%d", dev, file_priv, args->handle); 464 VERB("%p:%p: handle=%d", dev, file_priv, args->handle);
465 465
466 obj = drm_gem_object_lookup(dev, file_priv, args->handle); 466 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
467 if (!obj) 467 if (!obj)
468 return -ENOENT; 468 return -ENOENT;
469 469
470 /* XXX flushy, flushy */ 470 /* XXX flushy, flushy */
471 ret = 0; 471 ret = 0;
472 472
473 if (!ret) 473 if (!ret)
474 ret = omap_gem_op_finish(obj, args->op); 474 ret = omap_gem_op_finish(obj, args->op);
475 475
476 drm_gem_object_unreference_unlocked(obj); 476 drm_gem_object_unreference_unlocked(obj);
477 477
478 return ret; 478 return ret;
479 } 479 }
480 480
481 static int ioctl_gem_info(struct drm_device *dev, void *data, 481 static int ioctl_gem_info(struct drm_device *dev, void *data,
482 struct drm_file *file_priv) 482 struct drm_file *file_priv)
483 { 483 {
484 struct drm_omap_gem_info *args = data; 484 struct drm_omap_gem_info *args = data;
485 struct drm_gem_object *obj; 485 struct drm_gem_object *obj;
486 int ret = 0; 486 int ret = 0;
487 487
488 VERB("%p:%p: handle=%d", dev, file_priv, args->handle); 488 VERB("%p:%p: handle=%d", dev, file_priv, args->handle);
489 489
490 obj = drm_gem_object_lookup(dev, file_priv, args->handle); 490 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
491 if (!obj) 491 if (!obj)
492 return -ENOENT; 492 return -ENOENT;
493 493
494 args->size = omap_gem_mmap_size(obj); 494 args->size = omap_gem_mmap_size(obj);
495 args->offset = omap_gem_mmap_offset(obj); 495 args->offset = omap_gem_mmap_offset(obj);
496 496
497 drm_gem_object_unreference_unlocked(obj); 497 drm_gem_object_unreference_unlocked(obj);
498 498
499 return ret; 499 return ret;
500 } 500 }
501 501
502 static struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = { 502 static struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = {
503 DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), 503 DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
504 DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, ioctl_set_param, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 504 DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, ioctl_set_param, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
505 DRM_IOCTL_DEF_DRV(OMAP_GET_BASE, ioctl_get_base, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), 505 DRM_IOCTL_DEF_DRV(OMAP_GET_BASE, ioctl_get_base, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
506 DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), 506 DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
507 DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_PREP, ioctl_gem_cpu_prep, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), 507 DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_PREP, ioctl_gem_cpu_prep, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
508 DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_FINI, ioctl_gem_cpu_fini, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), 508 DRM_IOCTL_DEF_DRV(OMAP_GEM_CPU_FINI, ioctl_gem_cpu_fini, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
509 DRM_IOCTL_DEF_DRV(OMAP_GEM_INFO, ioctl_gem_info, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), 509 DRM_IOCTL_DEF_DRV(OMAP_GEM_INFO, ioctl_gem_info, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
510 }; 510 };
511 511
512 /* 512 /*
513 * drm driver funcs 513 * drm driver funcs
514 */ 514 */
515 515
516 /** 516 /**
517 * load - setup chip and create an initial config 517 * load - setup chip and create an initial config
518 * @dev: DRM device 518 * @dev: DRM device
519 * @flags: startup flags 519 * @flags: startup flags
520 * 520 *
521 * The driver load routine has to do several things: 521 * The driver load routine has to do several things:
522 * - initialize the memory manager 522 * - initialize the memory manager
523 * - allocate initial config memory 523 * - allocate initial config memory
524 * - setup the DRM framebuffer with the allocated memory 524 * - setup the DRM framebuffer with the allocated memory
525 */ 525 */
526 static int dev_load(struct drm_device *dev, unsigned long flags) 526 static int dev_load(struct drm_device *dev, unsigned long flags)
527 { 527 {
528 struct omap_drm_platform_data *pdata = dev->dev->platform_data; 528 struct omap_drm_platform_data *pdata = dev->dev->platform_data;
529 struct omap_drm_private *priv; 529 struct omap_drm_private *priv;
530 struct omap_drm_plugin *plugin; 530 struct omap_drm_plugin *plugin;
531 int ret; 531 int ret;
532 532
533 DBG("load: dev=%p", dev); 533 DBG("load: dev=%p", dev);
534 534
535 drm_device = dev; 535 drm_device = dev;
536 536
537 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 537 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
538 if (!priv) 538 if (!priv)
539 return -ENOMEM; 539 return -ENOMEM;
540 540
541 priv->omaprev = pdata->omaprev; 541 priv->omaprev = pdata->omaprev;
542 542
543 dev->dev_private = priv; 543 dev->dev_private = priv;
544 544
545 priv->wq = alloc_ordered_workqueue("omapdrm", 0); 545 priv->wq = alloc_ordered_workqueue("omapdrm", 0);
546 546
547 spin_lock_init(&priv->list_lock); 547 spin_lock_init(&priv->list_lock);
548 INIT_LIST_HEAD(&priv->obj_list); 548 INIT_LIST_HEAD(&priv->obj_list);
549 549
550 omap_gem_init(dev); 550 omap_gem_init(dev);
551 551
552 ret = omap_modeset_init(dev); 552 ret = omap_modeset_init(dev);
553 if (ret) { 553 if (ret) {
554 dev_err(dev->dev, "omap_modeset_init failed: ret=%d\n", ret); 554 dev_err(dev->dev, "omap_modeset_init failed: ret=%d\n", ret);
555 dev->dev_private = NULL; 555 dev->dev_private = NULL;
556 kfree(priv); 556 kfree(priv);
557 return ret; 557 return ret;
558 } 558 }
559 559
560 ret = drm_vblank_init(dev, priv->num_crtcs); 560 ret = drm_vblank_init(dev, priv->num_crtcs);
561 if (ret) 561 if (ret)
562 dev_warn(dev->dev, "could not init vblank\n"); 562 dev_warn(dev->dev, "could not init vblank\n");
563 563
564 priv->fbdev = omap_fbdev_init(dev); 564 priv->fbdev = omap_fbdev_init(dev);
565 if (!priv->fbdev) { 565 if (!priv->fbdev) {
566 dev_warn(dev->dev, "omap_fbdev_init failed\n"); 566 dev_warn(dev->dev, "omap_fbdev_init failed\n");
567 /* well, limp along without an fbdev.. maybe X11 will work? */ 567 /* well, limp along without an fbdev.. maybe X11 will work? */
568 } 568 }
569 569
570 /* store off drm_device for use in pm ops */ 570 /* store off drm_device for use in pm ops */
571 dev_set_drvdata(dev->dev, dev); 571 dev_set_drvdata(dev->dev, dev);
572 572
573 drm_kms_helper_poll_init(dev); 573 drm_kms_helper_poll_init(dev);
574 574
575 loaded = true; 575 loaded = true;
576 576
577 list_for_each_entry(plugin, &plugin_list, list) { 577 list_for_each_entry(plugin, &plugin_list, list) {
578 ret = plugin->load(dev, flags); 578 ret = plugin->load(dev, flags);
579 } 579 }
580 580
581 return 0; 581 return 0;
582 } 582 }
583 583
584 static int dev_unload(struct drm_device *dev) 584 static int dev_unload(struct drm_device *dev)
585 { 585 {
586 struct omap_drm_private *priv = dev->dev_private; 586 struct omap_drm_private *priv = dev->dev_private;
587 int i; 587 int i;
588 struct omap_drm_plugin *plugin; 588 struct omap_drm_plugin *plugin;
589 int ret; 589 int ret;
590 590
591 DBG("unload: dev=%p", dev); 591 DBG("unload: dev=%p", dev);
592 592
593 list_for_each_entry(plugin, &plugin_list, list) { 593 list_for_each_entry(plugin, &plugin_list, list) {
594 ret = plugin->unload(dev); 594 ret = plugin->unload(dev);
595 } 595 }
596 596
597 drm_kms_helper_poll_fini(dev); 597 drm_kms_helper_poll_fini(dev);
598 598
599 if (priv->fbdev) 599 if (priv->fbdev)
600 omap_fbdev_free(dev); 600 omap_fbdev_free(dev);
601 601
602 /* flush crtcs so the fbs get released */ 602 /* flush crtcs so the fbs get released */
603 for (i = 0; i < priv->num_crtcs; i++) 603 for (i = 0; i < priv->num_crtcs; i++)
604 omap_crtc_flush(priv->crtcs[i]); 604 omap_crtc_flush(priv->crtcs[i]);
605 605
606 omap_modeset_free(dev); 606 omap_modeset_free(dev);
607 omap_gem_deinit(dev); 607 omap_gem_deinit(dev);
608 608
609 destroy_workqueue(priv->wq); 609 destroy_workqueue(priv->wq);
610 610
611 drm_vblank_cleanup(dev); 611 drm_vblank_cleanup(dev);
612 omap_drm_irq_uninstall(dev); 612 omap_drm_irq_uninstall(dev);
613 613
614 kfree(dev->dev_private); 614 kfree(dev->dev_private);
615 dev->dev_private = NULL; 615 dev->dev_private = NULL;
616 616
617 dev_set_drvdata(dev->dev, NULL); 617 dev_set_drvdata(dev->dev, NULL);
618 618
619 loaded = false; 619 loaded = false;
620 620
621 return 0; 621 return 0;
622 } 622 }
623 623
624 static int dev_open(struct drm_device *dev, struct drm_file *file) 624 static int dev_open(struct drm_device *dev, struct drm_file *file)
625 { 625 {
626 struct omap_drm_plugin *plugin; 626 struct omap_drm_plugin *plugin;
627 bool found_pvr = false;
628 int ret; 627 int ret;
629 628
630 file->driver_priv = kzalloc(sizeof(void *) * MAX_MAPPERS, GFP_KERNEL); 629 file->driver_priv = kzalloc(sizeof(void *) * MAX_MAPPERS, GFP_KERNEL);
631 630
632 DBG("open: dev=%p, file=%p", dev, file); 631 DBG("open: dev=%p, file=%p", dev, file);
633
634 list_for_each_entry(plugin, &plugin_list, list) {
635 if (!strcmp(DRIVER_NAME "_pvr", plugin->name)) {
636 found_pvr = true;
637 break;
638 }
639 }
640
641 if (!found_pvr) {
642 DBG("open: PVR submodule not loaded.. let's try now");
643 request_module(DRIVER_NAME "_pvr");
644 }
645 632
646 list_for_each_entry(plugin, &plugin_list, list) { 633 list_for_each_entry(plugin, &plugin_list, list) {
647 ret = plugin->open(dev, file); 634 ret = plugin->open(dev, file);
648 } 635 }
649 636
650 return 0; 637 return 0;
651 } 638 }
652 639
653 /** 640 /**
654 * lastclose - clean up after all DRM clients have exited 641 * lastclose - clean up after all DRM clients have exited
655 * @dev: DRM device 642 * @dev: DRM device
656 * 643 *
657 * Take care of cleaning up after all DRM clients have exited. In the 644 * Take care of cleaning up after all DRM clients have exited. In the
658 * mode setting case, we want to restore the kernel's initial mode (just 645 * mode setting case, we want to restore the kernel's initial mode (just
659 * in case the last client left us in a bad state). 646 * in case the last client left us in a bad state).
660 */ 647 */
661 static void dev_lastclose(struct drm_device *dev) 648 static void dev_lastclose(struct drm_device *dev)
662 { 649 {
663 int i; 650 int i;
664 651
665 /* we don't support vga-switcheroo.. so just make sure the fbdev 652 /* we don't support vga-switcheroo.. so just make sure the fbdev
666 * mode is active 653 * mode is active
667 */ 654 */
668 struct omap_drm_private *priv = dev->dev_private; 655 struct omap_drm_private *priv = dev->dev_private;
669 int ret; 656 int ret;
670 657
671 DBG("lastclose: dev=%p", dev); 658 DBG("lastclose: dev=%p", dev);
672 659
673 if (priv->rotation_prop) { 660 if (priv->rotation_prop) {
674 /* need to restore default rotation state.. not sure 661 /* need to restore default rotation state.. not sure
675 * if there is a cleaner way to restore properties to 662 * if there is a cleaner way to restore properties to
676 * default state? Maybe a flag that properties should 663 * default state? Maybe a flag that properties should
677 * automatically be restored to default state on 664 * automatically be restored to default state on
678 * lastclose? 665 * lastclose?
679 */ 666 */
680 for (i = 0; i < priv->num_crtcs; i++) { 667 for (i = 0; i < priv->num_crtcs; i++) {
681 drm_object_property_set_value(&priv->crtcs[i]->base, 668 drm_object_property_set_value(&priv->crtcs[i]->base,
682 priv->rotation_prop, 0); 669 priv->rotation_prop, 0);
683 } 670 }
684 671
685 for (i = 0; i < priv->num_planes; i++) { 672 for (i = 0; i < priv->num_planes; i++) {
686 drm_object_property_set_value(&priv->planes[i]->base, 673 drm_object_property_set_value(&priv->planes[i]->base,
687 priv->rotation_prop, 0); 674 priv->rotation_prop, 0);
688 } 675 }
689 } 676 }
690 677
691 if (priv->fbdev) { 678 if (priv->fbdev) {
692 drm_modeset_lock_all(dev); 679 drm_modeset_lock_all(dev);
693 ret = drm_fb_helper_restore_fbdev_mode(priv->fbdev); 680 ret = drm_fb_helper_restore_fbdev_mode(priv->fbdev);
694 drm_modeset_unlock_all(dev); 681 drm_modeset_unlock_all(dev);
695 if (ret) 682 if (ret)
696 DBG("failed to restore crtc mode"); 683 DBG("failed to restore crtc mode");
697 /* 684 /*
698 * Flush crtcs to finish any pending work. 685 * Flush crtcs to finish any pending work.
699 * This makes sure the fbdev mode has been restored. 686 * This makes sure the fbdev mode has been restored.
700 */ 687 */
701 for (i = 0; i < priv->num_crtcs; i++) 688 for (i = 0; i < priv->num_crtcs; i++)
702 omap_crtc_flush(priv->crtcs[i]); 689 omap_crtc_flush(priv->crtcs[i]);
703 } 690 }
704 } 691 }
705 692
706 static void dev_preclose(struct drm_device *dev, struct drm_file *file) 693 static void dev_preclose(struct drm_device *dev, struct drm_file *file)
707 { 694 {
708 struct omap_drm_private *priv = dev->dev_private; 695 struct omap_drm_private *priv = dev->dev_private;
709 int i; 696 int i;
710 struct omap_drm_plugin *plugin; 697 struct omap_drm_plugin *plugin;
711 int ret; 698 int ret;
712 699
713 DBG("preclose: dev=%p", dev); 700 DBG("preclose: dev=%p", dev);
714 701
715 list_for_each_entry(plugin, &plugin_list, list) { 702 list_for_each_entry(plugin, &plugin_list, list) {
716 ret = plugin->release(dev, file); 703 ret = plugin->release(dev, file);
717 } 704 }
718 705
719 /* 706 /*
720 * Flush crtcs to finish any pending work. 707 * Flush crtcs to finish any pending work.
721 * Note: this may not be correct if there are multiple applications 708 * Note: this may not be correct if there are multiple applications
722 * using the drm device, and could possibly result in a timeout from 709 * using the drm device, and could possibly result in a timeout from
723 * omap_crtc_flush() if an other application is actively queuing new 710 * omap_crtc_flush() if an other application is actively queuing new
724 * work. 711 * work.
725 */ 712 */
726 for (i = 0; i < priv->num_crtcs; i++) 713 for (i = 0; i < priv->num_crtcs; i++)
727 omap_crtc_flush(priv->crtcs[i]); 714 omap_crtc_flush(priv->crtcs[i]);
728 715
729 kfree(file->driver_priv); 716 kfree(file->driver_priv);
730 } 717 }
731 718
732 static void dev_postclose(struct drm_device *dev, struct drm_file *file) 719 static void dev_postclose(struct drm_device *dev, struct drm_file *file)
733 { 720 {
734 DBG("postclose: dev=%p, file=%p", dev, file); 721 DBG("postclose: dev=%p, file=%p", dev, file);
735 } 722 }
736 723
737 static const struct vm_operations_struct omap_gem_vm_ops = { 724 static const struct vm_operations_struct omap_gem_vm_ops = {
738 .fault = omap_gem_fault, 725 .fault = omap_gem_fault,
739 .open = omap_gem_vm_open, 726 .open = omap_gem_vm_open,
740 .close = omap_gem_vm_close, 727 .close = omap_gem_vm_close,
741 }; 728 };
742 729
743 static const struct file_operations omapdriver_fops = { 730 static const struct file_operations omapdriver_fops = {
744 .owner = THIS_MODULE, 731 .owner = THIS_MODULE,
745 .open = drm_open, 732 .open = drm_open,
746 .unlocked_ioctl = drm_ioctl, 733 .unlocked_ioctl = drm_ioctl,
747 .release = drm_release, 734 .release = drm_release,
748 .mmap = omap_gem_mmap, 735 .mmap = omap_gem_mmap,
749 .poll = drm_poll, 736 .poll = drm_poll,
750 .read = drm_read, 737 .read = drm_read,
751 .llseek = noop_llseek, 738 .llseek = noop_llseek,
752 }; 739 };
753 740
754 static struct drm_driver omap_drm_driver = { 741 static struct drm_driver omap_drm_driver = {
755 .driver_features = 742 .driver_features =
756 DRIVER_HAVE_IRQ | DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER, 743 DRIVER_HAVE_IRQ | DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER,
757 .load = dev_load, 744 .load = dev_load,
758 .unload = dev_unload, 745 .unload = dev_unload,
759 .open = dev_open, 746 .open = dev_open,
760 .lastclose = dev_lastclose, 747 .lastclose = dev_lastclose,
761 .preclose = dev_preclose, 748 .preclose = dev_preclose,
762 .postclose = dev_postclose, 749 .postclose = dev_postclose,
763 .get_vblank_counter = drm_vblank_count, 750 .get_vblank_counter = drm_vblank_count,
764 .enable_vblank = omap_irq_enable_vblank, 751 .enable_vblank = omap_irq_enable_vblank,
765 .disable_vblank = omap_irq_disable_vblank, 752 .disable_vblank = omap_irq_disable_vblank,
766 .irq_preinstall = omap_irq_preinstall, 753 .irq_preinstall = omap_irq_preinstall,
767 .irq_postinstall = omap_irq_postinstall, 754 .irq_postinstall = omap_irq_postinstall,
768 .irq_uninstall = omap_irq_uninstall, 755 .irq_uninstall = omap_irq_uninstall,
769 .irq_handler = omap_irq_handler, 756 .irq_handler = omap_irq_handler,
770 #ifdef CONFIG_DEBUG_FS 757 #ifdef CONFIG_DEBUG_FS
771 .debugfs_init = omap_debugfs_init, 758 .debugfs_init = omap_debugfs_init,
772 .debugfs_cleanup = omap_debugfs_cleanup, 759 .debugfs_cleanup = omap_debugfs_cleanup,
773 #endif 760 #endif
774 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 761 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
775 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 762 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
776 .gem_prime_export = omap_gem_prime_export, 763 .gem_prime_export = omap_gem_prime_export,
777 .gem_prime_import = omap_gem_prime_import, 764 .gem_prime_import = omap_gem_prime_import,
778 .gem_free_object = omap_gem_free_object, 765 .gem_free_object = omap_gem_free_object,
779 .gem_vm_ops = &omap_gem_vm_ops, 766 .gem_vm_ops = &omap_gem_vm_ops,
780 .dumb_create = omap_gem_dumb_create, 767 .dumb_create = omap_gem_dumb_create,
781 .dumb_map_offset = omap_gem_dumb_map_offset, 768 .dumb_map_offset = omap_gem_dumb_map_offset,
782 .dumb_destroy = drm_gem_dumb_destroy, 769 .dumb_destroy = drm_gem_dumb_destroy,
783 .ioctls = ioctls, 770 .ioctls = ioctls,
784 .num_ioctls = DRM_OMAP_NUM_IOCTLS, 771 .num_ioctls = DRM_OMAP_NUM_IOCTLS,
785 .fops = &omapdriver_fops, 772 .fops = &omapdriver_fops,
786 .name = DRIVER_NAME, 773 .name = DRIVER_NAME,
787 .desc = DRIVER_DESC, 774 .desc = DRIVER_DESC,
788 .date = DRIVER_DATE, 775 .date = DRIVER_DATE,
789 .major = DRIVER_MAJOR, 776 .major = DRIVER_MAJOR,
790 .minor = DRIVER_MINOR, 777 .minor = DRIVER_MINOR,
791 .patchlevel = DRIVER_PATCHLEVEL, 778 .patchlevel = DRIVER_PATCHLEVEL,
792 }; 779 };
793 780
794 int omap_drm_register_plugin(struct omap_drm_plugin *plugin) 781 int omap_drm_register_plugin(struct omap_drm_plugin *plugin)
795 { 782 {
796 struct drm_device *dev = drm_device; 783 struct drm_device *dev = drm_device;
797 static int ioctl_base = DRM_OMAP_NUM_IOCTLS; 784 static int ioctl_base = DRM_OMAP_NUM_IOCTLS;
798 int i; 785 int i;
799 786
800 DBG("register plugin: %p (%s)", plugin, plugin->name); 787 DBG("register plugin: %p (%s)", plugin, plugin->name);
801 788
802 plugin->ioctl_base = ioctl_base; 789 plugin->ioctl_base = ioctl_base;
803 790
804 list_add_tail(&plugin->list, &plugin_list); 791 list_add_tail(&plugin->list, &plugin_list);
805 792
806 /* register the plugin's ioctl's */ 793 /* register the plugin's ioctl's */
807 for (i = 0; i < plugin->num_ioctls; i++) { 794 for (i = 0; i < plugin->num_ioctls; i++) {
808 int nr = i + ioctl_base; 795 int nr = i + ioctl_base;
809 796
810 /* check for out of bounds ioctl nr or 797 /* check for out of bounds ioctl nr or
811 already registered ioctl */ 798 already registered ioctl */
812 if (nr > ARRAY_SIZE(ioctls) || ioctls[nr].func) { 799 if (nr > ARRAY_SIZE(ioctls) || ioctls[nr].func) {
813 dev_err(dev->dev, "invalid ioctl: %d (nr=%d)\n", i, nr); 800 dev_err(dev->dev, "invalid ioctl: %d (nr=%d)\n", i, nr);
814 return -EINVAL; 801 return -EINVAL;
815 } 802 }
816 803
817 DBG("register ioctl: %d %08x", nr, plugin->ioctls[i].cmd); 804 DBG("register ioctl: %d %08x", nr, plugin->ioctls[i].cmd);
818 805
819 ioctls[nr] = plugin->ioctls[i]; 806 ioctls[nr] = plugin->ioctls[i];
820 807
821 if (nr >= omap_drm_driver.num_ioctls) 808 if (nr >= omap_drm_driver.num_ioctls)
822 omap_drm_driver.num_ioctls = nr + 1; 809 omap_drm_driver.num_ioctls = nr + 1;
823 810
824 } 811 }
825 812
826 ioctl_base += plugin->num_ioctls; 813 ioctl_base += plugin->num_ioctls;
827 814
828 if (loaded) 815 if (loaded)
829 plugin->load(dev, 0); 816 plugin->load(dev, 0);
830 817
831 return 0; 818 return 0;
832 } 819 }
833 EXPORT_SYMBOL(omap_drm_register_plugin); 820 EXPORT_SYMBOL(omap_drm_register_plugin);
834 821
835 int omap_drm_unregister_plugin(struct omap_drm_plugin *plugin) 822 int omap_drm_unregister_plugin(struct omap_drm_plugin *plugin)
836 { 823 {
837 list_del(&plugin->list); 824 list_del(&plugin->list);
838 /* TODO remove ioctl fxns */ 825 /* TODO remove ioctl fxns */
839 return 0; 826 return 0;
840 } 827 }
841 EXPORT_SYMBOL(omap_drm_unregister_plugin); 828 EXPORT_SYMBOL(omap_drm_unregister_plugin);
842 829
843 static int nmappers = 0; 830 static int nmappers = 0;
844 831
845 /* create buffer mapper id, to access per-mapper private data. See 832 /* create buffer mapper id, to access per-mapper private data. See
846 * omap_gem_{get,set}_priv(). 833 * omap_gem_{get,set}_priv().
847 */ 834 */
848 int omap_drm_register_mapper(void) 835 int omap_drm_register_mapper(void)
849 { 836 {
850 if (nmappers >= MAX_MAPPERS) 837 if (nmappers >= MAX_MAPPERS)
851 return -ENOMEM; 838 return -ENOMEM;
852 return nmappers++; 839 return nmappers++;
853 } 840 }
854 EXPORT_SYMBOL(omap_drm_register_mapper); 841 EXPORT_SYMBOL(omap_drm_register_mapper);
855 842
856 /* retire a mapper id, previously acquired from omap_drm_register_mapper() 843 /* retire a mapper id, previously acquired from omap_drm_register_mapper()
857 */ 844 */
858 void omap_drm_unregister_mapper(int mapper_id) 845 void omap_drm_unregister_mapper(int mapper_id)
859 { 846 {
860 /* currently no-op.. */ 847 /* currently no-op.. */
861 } 848 }
862 EXPORT_SYMBOL(omap_drm_unregister_mapper); 849 EXPORT_SYMBOL(omap_drm_unregister_mapper);
863 850
864 void *omap_drm_file_priv(struct drm_file *file, int mapper_id) 851 void *omap_drm_file_priv(struct drm_file *file, int mapper_id)
865 { 852 {
866 BUG_ON((mapper_id >= MAX_MAPPERS) || (mapper_id < 0)); 853 BUG_ON((mapper_id >= MAX_MAPPERS) || (mapper_id < 0));
867 if (file->driver_priv) 854 if (file->driver_priv)
868 return ((void **)file->driver_priv)[mapper_id]; 855 return ((void **)file->driver_priv)[mapper_id];
869 return NULL; 856 return NULL;
870 } 857 }
871 EXPORT_SYMBOL(omap_drm_file_priv); 858 EXPORT_SYMBOL(omap_drm_file_priv);
872 859
873 void omap_drm_file_set_priv(struct drm_file *file, int mapper_id, void *priv) 860 void omap_drm_file_set_priv(struct drm_file *file, int mapper_id, void *priv)
874 { 861 {
875 BUG_ON((mapper_id >= MAX_MAPPERS) || (mapper_id < 0)); 862 BUG_ON((mapper_id >= MAX_MAPPERS) || (mapper_id < 0));
876 ((void **)file->driver_priv)[mapper_id] = priv; 863 ((void **)file->driver_priv)[mapper_id] = priv;
877 } 864 }
878 EXPORT_SYMBOL(omap_drm_file_set_priv); 865 EXPORT_SYMBOL(omap_drm_file_set_priv);
879 866
880 867
881 static int pdev_probe(struct platform_device *device) 868 static int pdev_probe(struct platform_device *device)
882 { 869 {
883 int r; 870 int r;
884 871
885 if (omapdss_is_initialized() == false) 872 if (omapdss_is_initialized() == false)
886 return -EPROBE_DEFER; 873 return -EPROBE_DEFER;
887 874
888 omap_crtc_pre_init(); 875 omap_crtc_pre_init();
889 876
890 r = omap_connect_dssdevs(); 877 r = omap_connect_dssdevs();
891 if (r) { 878 if (r) {
892 omap_crtc_pre_uninit(); 879 omap_crtc_pre_uninit();
893 return r; 880 return r;
894 } 881 }
895 882
896 DBG("%s", device->name); 883 DBG("%s", device->name);
897 return drm_platform_init(&omap_drm_driver, device); 884 return drm_platform_init(&omap_drm_driver, device);
898 } 885 }
899 886
900 static int pdev_remove(struct platform_device *device) 887 static int pdev_remove(struct platform_device *device)
901 { 888 {
902 DBG(""); 889 DBG("");
903 890
904 drm_put_dev(platform_get_drvdata(device)); 891 drm_put_dev(platform_get_drvdata(device));
905 892
906 omap_disconnect_dssdevs(); 893 omap_disconnect_dssdevs();
907 omap_crtc_pre_uninit(); 894 omap_crtc_pre_uninit();
908 895
909 return 0; 896 return 0;
910 } 897 }
911 898
912 static int omap_drm_suspend(struct device *dev) 899 static int omap_drm_suspend(struct device *dev)
913 { 900 {
914 struct drm_device *drm_dev = dev_get_drvdata(dev); 901 struct drm_device *drm_dev = dev_get_drvdata(dev);
915 902
916 drm_kms_helper_poll_disable(drm_dev); 903 drm_kms_helper_poll_disable(drm_dev);
917 904
918 return 0; 905 return 0;
919 } 906 }
920 907
921 static int omap_drm_resume(struct device *dev) 908 static int omap_drm_resume(struct device *dev)
922 { 909 {
923 struct drm_device *drm_dev = dev_get_drvdata(dev); 910 struct drm_device *drm_dev = dev_get_drvdata(dev);
924 911
925 drm_kms_helper_poll_enable(drm_dev); 912 drm_kms_helper_poll_enable(drm_dev);
926 913
927 return omap_gem_resume(dev); 914 return omap_gem_resume(dev);
928 } 915 }
929 916
930 #ifdef CONFIG_PM 917 #ifdef CONFIG_PM
931 static const struct dev_pm_ops omapdrm_pm_ops = { 918 static const struct dev_pm_ops omapdrm_pm_ops = {
932 .suspend = omap_drm_suspend, 919 .suspend = omap_drm_suspend,
933 .resume = omap_drm_resume, 920 .resume = omap_drm_resume,
934 }; 921 };
935 #endif 922 #endif
936 923
937 static struct platform_driver pdev = { 924 static struct platform_driver pdev = {
938 .driver = { 925 .driver = {
939 .name = DRIVER_NAME, 926 .name = DRIVER_NAME,
940 .owner = THIS_MODULE, 927 .owner = THIS_MODULE,
941 #ifdef CONFIG_PM 928 #ifdef CONFIG_PM
942 .pm = &omapdrm_pm_ops, 929 .pm = &omapdrm_pm_ops,
943 #endif 930 #endif
944 }, 931 },
945 .probe = pdev_probe, 932 .probe = pdev_probe,
946 .remove = pdev_remove, 933 .remove = pdev_remove,
947 }; 934 };
948 935
949 static int __init omap_drm_init(void) 936 static int __init omap_drm_init(void)
950 { 937 {
951 int r; 938 int r;
952 939
953 DBG("init"); 940 DBG("init");
954 941
955 r = platform_driver_register(&omap_dmm_driver); 942 r = platform_driver_register(&omap_dmm_driver);
956 if (r) { 943 if (r) {
957 pr_err("DMM driver registration failed\n"); 944 pr_err("DMM driver registration failed\n");
958 return r; 945 return r;
959 } 946 }
960 947
961 r = platform_driver_register(&pdev); 948 r = platform_driver_register(&pdev);
962 if (r) { 949 if (r) {
963 pr_err("omapdrm driver registration failed\n"); 950 pr_err("omapdrm driver registration failed\n");
964 platform_driver_unregister(&omap_dmm_driver); 951 platform_driver_unregister(&omap_dmm_driver);
965 return r; 952 return r;
966 } 953 }
967 954
968 return 0; 955 return 0;
969 } 956 }
970 957
971 static void __exit omap_drm_fini(void) 958 static void __exit omap_drm_fini(void)
972 { 959 {
973 DBG("fini"); 960 DBG("fini");
974 961
975 platform_driver_unregister(&pdev); 962 platform_driver_unregister(&pdev);
976 963
977 platform_driver_unregister(&omap_dmm_driver); 964 platform_driver_unregister(&omap_dmm_driver);
978 } 965 }
979 966
980 /* need late_initcall() so we load after dss_driver's are loaded */ 967 /* need late_initcall() so we load after dss_driver's are loaded */
981 late_initcall(omap_drm_init); 968 late_initcall(omap_drm_init);
982 module_exit(omap_drm_fini); 969 module_exit(omap_drm_fini);
983 970
984 MODULE_AUTHOR("Rob Clark <rob@ti.com>"); 971 MODULE_AUTHOR("Rob Clark <rob@ti.com>");
985 MODULE_DESCRIPTION("OMAP DRM Display Driver"); 972 MODULE_DESCRIPTION("OMAP DRM Display Driver");
986 MODULE_ALIAS("platform:" DRIVER_NAME); 973 MODULE_ALIAS("platform:" DRIVER_NAME);
987 MODULE_LICENSE("GPL v2"); 974 MODULE_LICENSE("GPL v2");
988 975