Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
imx-drm-core.c
Go to the documentation of this file.
1 /*
2  * Freescale i.MX drm driver
3  *
4  * Copyright (C) 2011 Sascha Hauer, Pengutronix
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  */
16 
17 #include <linux/device.h>
18 #include <linux/platform_device.h>
19 #include <drm/drmP.h>
20 #include <drm/drm_fb_helper.h>
21 #include <drm/drm_crtc_helper.h>
22 #include <linux/fb.h>
23 #include <linux/module.h>
24 #include <drm/drm_gem_cma_helper.h>
25 #include <drm/drm_fb_cma_helper.h>
26 
27 #include "imx-drm.h"
28 
29 #define MAX_CRTC 4
30 
31 struct crtc_cookie {
32  void *cookie;
33  int id;
34  struct list_head list;
35 };
36 
38  struct drm_device *drm;
39  struct device *dev;
43  struct mutex mutex;
45  int pipes;
47 };
48 
49 struct imx_drm_crtc {
50  struct drm_crtc *crtc;
51  struct list_head list;
53  int pipe;
55  struct module *owner;
57 };
58 
61  struct list_head list;
62  struct module *owner;
64 };
65 
68  struct list_head list;
69  struct module *owner;
70 };
71 
72 static int imx_drm_driver_firstopen(struct drm_device *drm)
73 {
74  if (!imx_drm_device_get())
75  return -EINVAL;
76 
77  return 0;
78 }
79 
80 static void imx_drm_driver_lastclose(struct drm_device *drm)
81 {
82  struct imx_drm_device *imxdrm = drm->dev_private;
83 
84  if (imxdrm->fbhelper)
86 
88 }
89 
90 static int imx_drm_driver_unload(struct drm_device *drm)
91 {
92  struct imx_drm_device *imxdrm = drm->dev_private;
93 
96 
97  return 0;
98 }
99 
100 /*
101  * We don't care at all for crtc numbers, but the core expects the
102  * crtcs to be numbered
103  */
104 static struct imx_drm_crtc *imx_drm_crtc_by_num(struct imx_drm_device *imxdrm,
105  int num)
106 {
107  struct imx_drm_crtc *imx_drm_crtc;
108 
109  list_for_each_entry(imx_drm_crtc, &imxdrm->crtc_list, list)
110  if (imx_drm_crtc->pipe == num)
111  return imx_drm_crtc;
112  return NULL;
113 }
114 
116  u32 interface_pix_fmt)
117 {
118  struct imx_drm_device *imxdrm = crtc->dev->dev_private;
119  struct imx_drm_crtc *imx_crtc;
120  struct imx_drm_crtc_helper_funcs *helper;
121 
122  mutex_lock(&imxdrm->mutex);
123 
124  list_for_each_entry(imx_crtc, &imxdrm->crtc_list, list)
125  if (imx_crtc->crtc == crtc)
126  goto found;
127 
128  mutex_unlock(&imxdrm->mutex);
129 
130  return -EINVAL;
131 found:
132  mutex_unlock(&imxdrm->mutex);
133 
134  helper = &imx_crtc->imx_drm_helper_funcs;
135  if (helper->set_interface_pix_fmt)
136  return helper->set_interface_pix_fmt(crtc,
137  encoder_type, interface_pix_fmt);
138  return 0;
139 }
141 
142 int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc)
143 {
144  return drm_vblank_get(imx_drm_crtc->imxdrm->drm, imx_drm_crtc->pipe);
145 }
147 
148 void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc)
149 {
150  drm_vblank_put(imx_drm_crtc->imxdrm->drm, imx_drm_crtc->pipe);
151 }
153 
154 void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc)
155 {
156  drm_handle_vblank(imx_drm_crtc->imxdrm->drm, imx_drm_crtc->pipe);
157 }
159 
160 static int imx_drm_enable_vblank(struct drm_device *drm, int crtc)
161 {
162  struct imx_drm_device *imxdrm = drm->dev_private;
163  struct imx_drm_crtc *imx_drm_crtc;
164  int ret;
165 
166  imx_drm_crtc = imx_drm_crtc_by_num(imxdrm, crtc);
167  if (!imx_drm_crtc)
168  return -EINVAL;
169 
170  if (!imx_drm_crtc->imx_drm_helper_funcs.enable_vblank)
171  return -ENOSYS;
172 
173  ret = imx_drm_crtc->imx_drm_helper_funcs.enable_vblank(
174  imx_drm_crtc->crtc);
175 
176  return ret;
177 }
178 
179 static void imx_drm_disable_vblank(struct drm_device *drm, int crtc)
180 {
181  struct imx_drm_device *imxdrm = drm->dev_private;
182  struct imx_drm_crtc *imx_drm_crtc;
183 
184  imx_drm_crtc = imx_drm_crtc_by_num(imxdrm, crtc);
185  if (!imx_drm_crtc)
186  return;
187 
188  if (!imx_drm_crtc->imx_drm_helper_funcs.disable_vblank)
189  return;
190 
191  imx_drm_crtc->imx_drm_helper_funcs.disable_vblank(imx_drm_crtc->crtc);
192 }
193 
194 static const struct file_operations imx_drm_driver_fops = {
195  .owner = THIS_MODULE,
196  .open = drm_open,
197  .release = drm_release,
198  .unlocked_ioctl = drm_ioctl,
199  .mmap = drm_gem_cma_mmap,
200  .poll = drm_poll,
201  .fasync = drm_fasync,
202  .read = drm_read,
203  .llseek = noop_llseek,
204 };
205 
206 static struct imx_drm_device *imx_drm_device;
207 
208 static struct imx_drm_device *__imx_drm_device(void)
209 {
210  return imx_drm_device;
211 }
212 
214 {
215  struct imx_drm_device *imxdrm = __imx_drm_device();
216  struct imx_drm_encoder *enc;
217  struct imx_drm_connector *con;
218  struct imx_drm_crtc *crtc;
219 
220  mutex_lock(&imxdrm->mutex);
221 
222  list_for_each_entry(enc, &imxdrm->encoder_list, list) {
223  if (!try_module_get(enc->owner)) {
224  dev_err(imxdrm->dev, "could not get module %s\n",
225  module_name(enc->owner));
226  goto unwind_enc;
227  }
228  }
229 
230  list_for_each_entry(con, &imxdrm->connector_list, list) {
231  if (!try_module_get(con->owner)) {
232  dev_err(imxdrm->dev, "could not get module %s\n",
233  module_name(con->owner));
234  goto unwind_con;
235  }
236  }
237 
238  list_for_each_entry(crtc, &imxdrm->crtc_list, list) {
239  if (!try_module_get(crtc->owner)) {
240  dev_err(imxdrm->dev, "could not get module %s\n",
241  module_name(crtc->owner));
242  goto unwind_crtc;
243  }
244  }
245 
246  imxdrm->references++;
247 
248  mutex_unlock(&imxdrm->mutex);
249 
250  return imxdrm->drm;
251 
252 unwind_crtc:
254  module_put(crtc->owner);
255 unwind_con:
257  module_put(con->owner);
258 unwind_enc:
260  module_put(enc->owner);
261 
262  mutex_unlock(&imxdrm->mutex);
263 
264  return NULL;
265 
266 }
268 
270 {
271  struct imx_drm_device *imxdrm = __imx_drm_device();
272  struct imx_drm_encoder *enc;
273  struct imx_drm_connector *con;
274  struct imx_drm_crtc *crtc;
275 
276  mutex_lock(&imxdrm->mutex);
277 
278  list_for_each_entry(crtc, &imxdrm->crtc_list, list)
279  module_put(crtc->owner);
280 
281  list_for_each_entry(con, &imxdrm->connector_list, list)
282  module_put(con->owner);
283 
284  list_for_each_entry(enc, &imxdrm->encoder_list, list)
285  module_put(enc->owner);
286 
287  imxdrm->references--;
288 
289  mutex_unlock(&imxdrm->mutex);
290 }
292 
293 static int drm_mode_group_reinit(struct drm_device *dev)
294 {
295  struct drm_mode_group *group = &dev->primary->mode_group;
296  uint32_t *id_list = group->id_list;
297  int ret;
298 
299  ret = drm_mode_group_init_legacy_group(dev, group);
300  if (ret < 0)
301  return ret;
302 
303  kfree(id_list);
304  return 0;
305 }
306 
307 /*
308  * register an encoder to the drm core
309  */
310 static int imx_drm_encoder_register(struct imx_drm_encoder *imx_drm_encoder)
311 {
312  struct imx_drm_device *imxdrm = __imx_drm_device();
313 
314  INIT_LIST_HEAD(&imx_drm_encoder->possible_crtcs);
315 
316  drm_encoder_init(imxdrm->drm, imx_drm_encoder->encoder,
317  imx_drm_encoder->encoder->funcs,
318  imx_drm_encoder->encoder->encoder_type);
319 
320  drm_mode_group_reinit(imxdrm->drm);
321 
322  return 0;
323 }
324 
325 /*
326  * unregister an encoder from the drm core
327  */
328 static void imx_drm_encoder_unregister(struct imx_drm_encoder
330 {
331  struct imx_drm_device *imxdrm = __imx_drm_device();
332 
333  drm_encoder_cleanup(imx_drm_encoder->encoder);
334 
335  drm_mode_group_reinit(imxdrm->drm);
336 }
337 
338 /*
339  * register a connector to the drm core
340  */
341 static int imx_drm_connector_register(
343 {
344  struct imx_drm_device *imxdrm = __imx_drm_device();
345 
346  drm_connector_init(imxdrm->drm, imx_drm_connector->connector,
347  imx_drm_connector->connector->funcs,
348  imx_drm_connector->connector->connector_type);
349  drm_mode_group_reinit(imxdrm->drm);
350 
351  return drm_sysfs_connector_add(imx_drm_connector->connector);
352 }
353 
354 /*
355  * unregister a connector from the drm core
356  */
357 static void imx_drm_connector_unregister(
359 {
360  struct imx_drm_device *imxdrm = __imx_drm_device();
361 
362  drm_sysfs_connector_remove(imx_drm_connector->connector);
363  drm_connector_cleanup(imx_drm_connector->connector);
364 
365  drm_mode_group_reinit(imxdrm->drm);
366 }
367 
368 /*
369  * register a crtc to the drm core
370  */
371 static int imx_drm_crtc_register(struct imx_drm_crtc *imx_drm_crtc)
372 {
373  struct imx_drm_device *imxdrm = __imx_drm_device();
374  int ret;
375 
376  drm_crtc_init(imxdrm->drm, imx_drm_crtc->crtc,
377  imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs);
378  ret = drm_mode_crtc_set_gamma_size(imx_drm_crtc->crtc, 256);
379  if (ret)
380  return ret;
381 
382  drm_crtc_helper_add(imx_drm_crtc->crtc,
383  imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs);
384 
385  drm_mode_group_reinit(imxdrm->drm);
386 
387  return 0;
388 }
389 
390 /*
391  * Called by the CRTC driver when all CRTCs are registered. This
392  * puts all the pieces together and initializes the driver.
393  * Once this is called no more CRTCs can be registered since
394  * the drm core has hardcoded the number of crtcs in several
395  * places.
396  */
397 static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
398 {
399  struct imx_drm_device *imxdrm = __imx_drm_device();
400  int ret;
401 
402  imxdrm->drm = drm;
403 
404  drm->dev_private = imxdrm;
405 
406  /*
407  * enable drm irq mode.
408  * - with irq_enabled = 1, we can use the vblank feature.
409  *
410  * P.S. note that we wouldn't use drm irq handler but
411  * just specific driver own one instead because
412  * drm framework supports only one irq handler and
413  * drivers can well take care of their interrupts
414  */
415  drm->irq_enabled = 1;
416 
419 
420  mutex_lock(&imxdrm->mutex);
421 
422  drm_kms_helper_poll_init(imxdrm->drm);
423 
424  /* setup the grouping for the legacy output */
426  &imxdrm->drm->primary->mode_group);
427  if (ret)
428  goto err_init;
429 
430  ret = drm_vblank_init(imxdrm->drm, MAX_CRTC);
431  if (ret)
432  goto err_init;
433 
434  /*
435  * with vblank_disable_allowed = 1, vblank interrupt will be disabled
436  * by drm timer once a current process gives up ownership of
437  * vblank event.(after drm_vblank_put function is called)
438  */
439  imxdrm->drm->vblank_disable_allowed = 1;
440 
441  ret = 0;
442 
443 err_init:
444  mutex_unlock(&imxdrm->mutex);
445 
446  return ret;
447 }
448 
449 static void imx_drm_update_possible_crtcs(void)
450 {
451  struct imx_drm_device *imxdrm = __imx_drm_device();
452  struct imx_drm_crtc *imx_drm_crtc;
453  struct imx_drm_encoder *enc;
454  struct crtc_cookie *cookie;
455 
456  list_for_each_entry(enc, &imxdrm->encoder_list, list) {
457  u32 possible_crtcs = 0;
458 
459  list_for_each_entry(cookie, &enc->possible_crtcs, list) {
460  list_for_each_entry(imx_drm_crtc, &imxdrm->crtc_list, list) {
461  if (imx_drm_crtc->cookie.cookie == cookie->cookie &&
462  imx_drm_crtc->cookie.id == cookie->id) {
463  possible_crtcs |= 1 << imx_drm_crtc->pipe;
464  }
465  }
466  }
467  enc->encoder->possible_crtcs = possible_crtcs;
468  enc->encoder->possible_clones = possible_crtcs;
469  }
470 }
471 
472 /*
473  * imx_drm_add_crtc - add a new crtc
474  *
475  * The return value if !NULL is a cookie for the caller to pass to
476  * imx_drm_remove_crtc later.
477  */
478 int imx_drm_add_crtc(struct drm_crtc *crtc,
479  struct imx_drm_crtc **new_crtc,
480  const struct imx_drm_crtc_helper_funcs *imx_drm_helper_funcs,
481  struct module *owner, void *cookie, int id)
482 {
483  struct imx_drm_device *imxdrm = __imx_drm_device();
484  struct imx_drm_crtc *imx_drm_crtc;
485  const struct drm_crtc_funcs *crtc_funcs;
486  int ret;
487 
488  mutex_lock(&imxdrm->mutex);
489 
490  if (imxdrm->references) {
491  ret = -EBUSY;
492  goto err_busy;
493  }
494 
495  imx_drm_crtc = kzalloc(sizeof(*imx_drm_crtc), GFP_KERNEL);
496  if (!imx_drm_crtc) {
497  ret = -ENOMEM;
498  goto err_alloc;
499  }
500 
501  imx_drm_crtc->imx_drm_helper_funcs = *imx_drm_helper_funcs;
502  imx_drm_crtc->pipe = imxdrm->pipes++;
503  imx_drm_crtc->cookie.cookie = cookie;
504  imx_drm_crtc->cookie.id = id;
505 
506  crtc_funcs = imx_drm_helper_funcs->crtc_funcs;
507 
508  imx_drm_crtc->crtc = crtc;
509  imx_drm_crtc->imxdrm = imxdrm;
510 
511  imx_drm_crtc->owner = owner;
512 
513  list_add_tail(&imx_drm_crtc->list, &imxdrm->crtc_list);
514 
515  *new_crtc = imx_drm_crtc;
516 
517  ret = imx_drm_crtc_register(imx_drm_crtc);
518  if (ret)
519  goto err_register;
520 
521  imx_drm_update_possible_crtcs();
522 
523  mutex_unlock(&imxdrm->mutex);
524 
525  return 0;
526 
527 err_register:
528  kfree(imx_drm_crtc);
529 err_alloc:
530 err_busy:
531  mutex_unlock(&imxdrm->mutex);
532  return ret;
533 }
535 
536 /*
537  * imx_drm_remove_crtc - remove a crtc
538  */
539 int imx_drm_remove_crtc(struct imx_drm_crtc *imx_drm_crtc)
540 {
541  struct imx_drm_device *imxdrm = imx_drm_crtc->imxdrm;
542 
543  mutex_lock(&imxdrm->mutex);
544 
545  drm_crtc_cleanup(imx_drm_crtc->crtc);
546 
547  list_del(&imx_drm_crtc->list);
548 
549  drm_mode_group_reinit(imxdrm->drm);
550 
551  mutex_unlock(&imxdrm->mutex);
552 
553  kfree(imx_drm_crtc);
554 
555  return 0;
556 }
558 
559 /*
560  * imx_drm_add_encoder - add a new encoder
561  */
562 int imx_drm_add_encoder(struct drm_encoder *encoder,
563  struct imx_drm_encoder **newenc, struct module *owner)
564 {
565  struct imx_drm_device *imxdrm = __imx_drm_device();
567  int ret;
568 
569  mutex_lock(&imxdrm->mutex);
570 
571  if (imxdrm->references) {
572  ret = -EBUSY;
573  goto err_busy;
574  }
575 
576  imx_drm_encoder = kzalloc(sizeof(*imx_drm_encoder), GFP_KERNEL);
577  if (!imx_drm_encoder) {
578  ret = -ENOMEM;
579  goto err_alloc;
580  }
581 
582  imx_drm_encoder->encoder = encoder;
583  imx_drm_encoder->owner = owner;
584 
585  ret = imx_drm_encoder_register(imx_drm_encoder);
586  if (ret) {
587  kfree(imx_drm_encoder);
588  ret = -ENOMEM;
589  goto err_register;
590  }
591 
592  list_add_tail(&imx_drm_encoder->list, &imxdrm->encoder_list);
593 
594  *newenc = imx_drm_encoder;
595 
596  mutex_unlock(&imxdrm->mutex);
597 
598  return 0;
599 
600 err_register:
601  kfree(imx_drm_encoder);
602 err_alloc:
603 err_busy:
604  mutex_unlock(&imxdrm->mutex);
605 
606  return ret;
607 }
609 
612  struct device_node *np)
613 {
614  struct imx_drm_device *imxdrm = __imx_drm_device();
615  struct of_phandle_args args;
616  struct crtc_cookie *c;
617  int ret = 0;
618  int i;
619 
620  if (!list_empty(&imx_drm_encoder->possible_crtcs))
621  return -EBUSY;
622 
623  for (i = 0; !ret; i++) {
624  ret = of_parse_phandle_with_args(np, "crtcs",
625  "#crtc-cells", i, &args);
626  if (ret < 0)
627  break;
628 
629  c = kzalloc(sizeof(*c), GFP_KERNEL);
630  if (!c) {
631  of_node_put(args.np);
632  return -ENOMEM;
633  }
634 
635  c->cookie = args.np;
636  c->id = args.args_count > 0 ? args.args[0] : 0;
637 
638  of_node_put(args.np);
639 
640  mutex_lock(&imxdrm->mutex);
641 
642  list_add_tail(&c->list, &imx_drm_encoder->possible_crtcs);
643 
644  mutex_unlock(&imxdrm->mutex);
645  }
646 
647  imx_drm_update_possible_crtcs();
648 
649  return 0;
650 }
652 
654  struct drm_crtc *crtc)
655 {
656  struct imx_drm_device *imxdrm = __imx_drm_device();
657  struct imx_drm_crtc *imx_crtc;
658  int i = 0;
659 
660  mutex_lock(&imxdrm->mutex);
661 
662  list_for_each_entry(imx_crtc, &imxdrm->crtc_list, list) {
663  if (imx_crtc->crtc == crtc)
664  goto found;
665  i++;
666  }
667 
668  mutex_unlock(&imxdrm->mutex);
669 
670  return -EINVAL;
671 found:
672  mutex_unlock(&imxdrm->mutex);
673 
674  return i;
675 }
676 
677 /*
678  * imx_drm_remove_encoder - remove an encoder
679  */
681 {
682  struct imx_drm_device *imxdrm = __imx_drm_device();
683  struct crtc_cookie *c, *tmp;
684 
685  mutex_lock(&imxdrm->mutex);
686 
687  imx_drm_encoder_unregister(imx_drm_encoder);
688 
689  list_del(&imx_drm_encoder->list);
690 
691  list_for_each_entry_safe(c, tmp, &imx_drm_encoder->possible_crtcs,
692  list)
693  kfree(c);
694 
695  mutex_unlock(&imxdrm->mutex);
696 
697  kfree(imx_drm_encoder);
698 
699  return 0;
700 }
702 
703 /*
704  * imx_drm_add_connector - add a connector
705  */
707  struct imx_drm_connector **new_con,
708  struct module *owner)
709 {
710  struct imx_drm_device *imxdrm = __imx_drm_device();
712  int ret;
713 
714  mutex_lock(&imxdrm->mutex);
715 
716  if (imxdrm->references) {
717  ret = -EBUSY;
718  goto err_busy;
719  }
720 
721  imx_drm_connector = kzalloc(sizeof(*imx_drm_connector), GFP_KERNEL);
722  if (!imx_drm_connector) {
723  ret = -ENOMEM;
724  goto err_alloc;
725  }
726 
727  imx_drm_connector->connector = connector;
728  imx_drm_connector->owner = owner;
729 
730  ret = imx_drm_connector_register(imx_drm_connector);
731  if (ret)
732  goto err_register;
733 
734  list_add_tail(&imx_drm_connector->list, &imxdrm->connector_list);
735 
736  *new_con = imx_drm_connector;
737 
738  mutex_unlock(&imxdrm->mutex);
739 
740  return 0;
741 
742 err_register:
743  kfree(imx_drm_connector);
744 err_alloc:
745 err_busy:
746  mutex_unlock(&imxdrm->mutex);
747 
748  return ret;
749 }
751 
752 void imx_drm_fb_helper_set(struct drm_fbdev_cma *fbdev_helper)
753 {
754  struct imx_drm_device *imxdrm = __imx_drm_device();
755 
756  imxdrm->fbhelper = fbdev_helper;
757 }
759 
760 /*
761  * imx_drm_remove_connector - remove a connector
762  */
764 {
765  struct imx_drm_device *imxdrm = __imx_drm_device();
766 
767  mutex_lock(&imxdrm->mutex);
768 
769  imx_drm_connector_unregister(imx_drm_connector);
770 
771  list_del(&imx_drm_connector->list);
772 
773  mutex_unlock(&imxdrm->mutex);
774 
775  kfree(imx_drm_connector);
776 
777  return 0;
778 }
780 
781 static struct drm_ioctl_desc imx_drm_ioctls[] = {
782  /* none so far */
783 };
784 
785 static struct drm_driver imx_drm_driver = {
786  .driver_features = DRIVER_MODESET | DRIVER_GEM,
787  .load = imx_drm_driver_load,
788  .unload = imx_drm_driver_unload,
789  .firstopen = imx_drm_driver_firstopen,
790  .lastclose = imx_drm_driver_lastclose,
791  .gem_free_object = drm_gem_cma_free_object,
792  .gem_vm_ops = &drm_gem_cma_vm_ops,
793  .dumb_create = drm_gem_cma_dumb_create,
794  .dumb_map_offset = drm_gem_cma_dumb_map_offset,
795  .dumb_destroy = drm_gem_cma_dumb_destroy,
796 
797  .get_vblank_counter = drm_vblank_count,
798  .enable_vblank = imx_drm_enable_vblank,
799  .disable_vblank = imx_drm_disable_vblank,
800  .ioctls = imx_drm_ioctls,
801  .num_ioctls = ARRAY_SIZE(imx_drm_ioctls),
802  .fops = &imx_drm_driver_fops,
803  .name = "imx-drm",
804  .desc = "i.MX DRM graphics",
805  .date = "20120507",
806  .major = 1,
807  .minor = 0,
808  .patchlevel = 0,
809 };
810 
811 static int imx_drm_platform_probe(struct platform_device *pdev)
812 {
813  imx_drm_device->dev = &pdev->dev;
814 
815  return drm_platform_init(&imx_drm_driver, pdev);
816 }
817 
818 static int imx_drm_platform_remove(struct platform_device *pdev)
819 {
820  drm_platform_exit(&imx_drm_driver, pdev);
821 
822  return 0;
823 }
824 
825 static struct platform_driver imx_drm_pdrv = {
826  .probe = imx_drm_platform_probe,
827  .remove = __devexit_p(imx_drm_platform_remove),
828  .driver = {
829  .owner = THIS_MODULE,
830  .name = "imx-drm",
831  },
832 };
833 
834 static struct platform_device *imx_drm_pdev;
835 
836 static int __init imx_drm_init(void)
837 {
838  int ret;
839 
840  imx_drm_device = kzalloc(sizeof(*imx_drm_device), GFP_KERNEL);
841  if (!imx_drm_device)
842  return -ENOMEM;
843 
844  mutex_init(&imx_drm_device->mutex);
845  INIT_LIST_HEAD(&imx_drm_device->crtc_list);
846  INIT_LIST_HEAD(&imx_drm_device->connector_list);
847  INIT_LIST_HEAD(&imx_drm_device->encoder_list);
848 
849  imx_drm_pdev = platform_device_register_simple("imx-drm", -1, NULL, 0);
850  if (!imx_drm_pdev) {
851  ret = -EINVAL;
852  goto err_pdev;
853  }
854 
855  imx_drm_pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32),
856 
857  ret = platform_driver_register(&imx_drm_pdrv);
858  if (ret)
859  goto err_pdrv;
860 
861  return 0;
862 
863 err_pdrv:
864  platform_device_unregister(imx_drm_pdev);
865 err_pdev:
866  kfree(imx_drm_device);
867 
868  return ret;
869 }
870 
871 static void __exit imx_drm_exit(void)
872 {
873  platform_device_unregister(imx_drm_pdev);
874  platform_driver_unregister(&imx_drm_pdrv);
875 
876  kfree(imx_drm_device);
877 }
878 
879 module_init(imx_drm_init);
880 module_exit(imx_drm_exit);
881 
882 MODULE_AUTHOR("Sascha Hauer <[email protected]>");
883 MODULE_DESCRIPTION("i.MX drm driver core");
884 MODULE_LICENSE("GPL");