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