diff options
Diffstat (limited to 'linux-core')
-rw-r--r-- | linux-core/drmP.h | 12 | ||||
-rw-r--r-- | linux-core/drm_stub.c | 35 |
2 files changed, 44 insertions, 3 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h index ac54abb5..c61bac1d 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -243,6 +243,18 @@ static inline unsigned iminor(struct inode *inode) #define old_encode_dev(x) (x) +struct class_simple; +struct device; + +static inline void *class_simple_device_add(struct class_simple *cs, dev_t dev, struct device *device, const char *fmt, ...) +{ return NULL;} + +static inline void class_simple_device_remove(dev_t dev){}; + +static inline void class_simple_destroy(struct class_simple *cs){}; + +static inline struct class_simple *class_simple_create(struct module *owner, char *name) { return NULL; } + #endif #ifndef REMAP_PAGE_RANGE_5_ARGS diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 40904799..ea33096d 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -36,6 +36,8 @@ #define DRM_STUB_MAXCARDS 16 /* Enough for one machine */ +static struct class_simple *drm_class; + /** Stub list. One for each minor. */ static struct drm_stub_list { const char *name; @@ -118,6 +120,7 @@ static int DRM(stub_getminor)(const char *name, struct file_operations *fops, DRM(stub_root) = DRM(proc_init)(dev, i, DRM(stub_root), &DRM(stub_list)[i] .dev_root); + class_simple_device_add(drm_class, MKDEV(DRM_MAJOR, i), NULL, name); return i; } } @@ -142,6 +145,7 @@ static int DRM(stub_putminor)(int minor) DRM(proc_cleanup)(minor, DRM(stub_root), DRM(stub_list)[minor].dev_root); if (minor) { + class_simple_device_remove(MKDEV(DRM_MAJOR, minor)); inter_module_put("drm"); } else { inter_module_unregister("drm"); @@ -149,6 +153,8 @@ static int DRM(stub_putminor)(int minor) sizeof(*DRM(stub_list)) * DRM_STUB_MAXCARDS, DRM_MEM_STUB); unregister_chrdev(DRM_MAJOR, "drm"); + class_simple_device_remove(MKDEV(DRM_MAJOR, minor)); + class_simple_destroy(drm_class); } return 0; } @@ -171,10 +177,23 @@ int DRM(stub_register)(const char *name, struct file_operations *fops, drm_device_t *dev) { struct drm_stub_info *i = NULL; + int ret1; + int ret2; DRM_DEBUG("\n"); - if (register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops))) + ret1 = register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops)); + if (!ret1) { + drm_class = class_simple_create(THIS_MODULE, "drm"); + if (IS_ERR(drm_class)) { + printk (KERN_ERR "Error creating drm class.\n"); + unregister_chrdev(DRM_MAJOR, "drm"); + return PTR_ERR(drm_class); + } + } + else if (ret1 == -EBUSY) i = (struct drm_stub_info *)inter_module_get("drm"); + else + return -1; if (i) { /* Already registered */ @@ -187,8 +206,18 @@ int DRM(stub_register)(const char *name, struct file_operations *fops, DRM_DEBUG("calling inter_module_register\n"); inter_module_register("drm", THIS_MODULE, &DRM(stub_info)); } - if (DRM(stub_info).info_register) - return DRM(stub_info).info_register(name, fops, dev); + if (DRM(stub_info).info_register) { + ret2 = DRM(stub_info).info_register(name, fops, dev); + if (ret2) { + if (!ret1) { + unregister_chrdev(DRM_MAJOR, "drm"); + class_simple_destroy(drm_class); + } + if (!i) + inter_module_unregister("drm"); + } + return ret2; + } return -1; } |