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;  } | 
