1/*	$NetBSD: ttm_module.c,v 1.3 2021/12/18 23:45:44 riastradh Exp $	*/
2
3/* SPDX-License-Identifier: GPL-2.0 OR MIT */
4/**************************************************************************
5 *
6 * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
7 * All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the
11 * "Software"), to deal in the Software without restriction, including
12 * without limitation the rights to use, copy, modify, merge, publish,
13 * distribute, sub license, and/or sell copies of the Software, and to
14 * permit persons to whom the Software is furnished to do so, subject to
15 * the following conditions:
16 *
17 * The above copyright notice and this permission notice (including the
18 * next paragraph) shall be included in all copies or substantial portions
19 * of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
24 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
25 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
26 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
27 * USE OR OTHER DEALINGS IN THE SOFTWARE.
28 *
29 **************************************************************************/
30/*
31 * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
32 * 	    Jerome Glisse
33 */
34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: ttm_module.c,v 1.3 2021/12/18 23:45:44 riastradh Exp $");
36
37#include <linux/module.h>
38#include <linux/device.h>
39#include <linux/sched.h>
40#include <drm/ttm/ttm_module.h>
41#include <drm/drm_sysfs.h>
42
43static DECLARE_WAIT_QUEUE_HEAD(exit_q);
44static atomic_t device_released;
45
46static struct device_type ttm_drm_class_type = {
47	.name = "ttm",
48	/**
49	 * Add pm ops here.
50	 */
51};
52
53static void ttm_drm_class_device_release(struct device *dev)
54{
55	atomic_set(&device_released, 1);
56	wake_up_all(&exit_q);
57}
58
59static struct device ttm_drm_class_device = {
60	.type = &ttm_drm_class_type,
61	.release = &ttm_drm_class_device_release
62};
63
64struct kobject *ttm_get_kobj(void)
65{
66	struct kobject *kobj = &ttm_drm_class_device.kobj;
67	BUG_ON(kobj == NULL);
68	return kobj;
69}
70
71static int __init ttm_init(void)
72{
73	int ret;
74
75	ret = dev_set_name(&ttm_drm_class_device, "ttm");
76	if (unlikely(ret != 0))
77		return ret;
78
79	atomic_set(&device_released, 0);
80	ret = drm_class_device_register(&ttm_drm_class_device);
81	if (unlikely(ret != 0))
82		goto out_no_dev_reg;
83
84	return 0;
85out_no_dev_reg:
86	atomic_set(&device_released, 1);
87	wake_up_all(&exit_q);
88	return ret;
89}
90
91static void __exit ttm_exit(void)
92{
93	drm_class_device_unregister(&ttm_drm_class_device);
94
95	/**
96	 * Refuse to unload until the TTM device is released.
97	 * Not sure this is 100% needed.
98	 */
99
100	wait_event(exit_q, atomic_read(&device_released) == 1);
101}
102
103module_init(ttm_init);
104module_exit(ttm_exit);
105
106MODULE_AUTHOR("Thomas Hellstrom, Jerome Glisse");
107MODULE_DESCRIPTION("TTM memory manager subsystem (for DRM device)");
108MODULE_LICENSE("GPL and additional rights");
109