Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  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#include "exynos_drm_drv.h"
 17#include "exynos_drm_crtc.h"
 18#include "exynos_drm_fbdev.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}