linux/drivers/gpu/drm/exynos/exynos_drm_core.c
<<
>>
Prefs
   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 *
   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.
  13 */
  14
  15#include <drm/drmP.h>
  16
  17#include "exynos_drm_drv.h"
  18#include "exynos_drm_crtc.h"
  19
  20static LIST_HEAD(exynos_drm_subdrv_list);
  21
  22int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv)
  23{
  24        if (!subdrv)
  25                return -EINVAL;
  26
  27        list_add_tail(&subdrv->list, &exynos_drm_subdrv_list);
  28
  29        return 0;
  30}
  31
  32int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *subdrv)
  33{
  34        if (!subdrv)
  35                return -EINVAL;
  36
  37        list_del(&subdrv->list);
  38
  39        return 0;
  40}
  41
  42int exynos_drm_device_subdrv_probe(struct drm_device *dev)
  43{
  44        struct exynos_drm_subdrv *subdrv, *n;
  45        int err;
  46
  47        if (!dev)
  48                return -EINVAL;
  49
  50        list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) {
  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                        }
  65                }
  66        }
  67
  68        return 0;
  69}
  70
  71int exynos_drm_device_subdrv_remove(struct drm_device *dev)
  72{
  73        struct exynos_drm_subdrv *subdrv;
  74
  75        if (!dev) {
  76                WARN(1, "Unexpected drm device unregister!\n");
  77                return -EINVAL;
  78        }
  79
  80        list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
  81                if (subdrv->remove)
  82                        subdrv->remove(dev, subdrv->dev);
  83        }
  84
  85        return 0;
  86}
  87
  88int 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) {
  95                        ret = subdrv->open(dev, subdrv->dev, file);
  96                        if (ret)
  97                                goto err;
  98                }
  99        }
 100
 101        return 0;
 102
 103err:
 104        list_for_each_entry_continue_reverse(subdrv, &exynos_drm_subdrv_list, list) {
 105                if (subdrv->close)
 106                        subdrv->close(dev, subdrv->dev, file);
 107        }
 108        return ret;
 109}
 110
 111void 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)
 117                        subdrv->close(dev, subdrv->dev, file);
 118        }
 119}
 120