Misc: Add possibility to remove misc devices during suspend/resume

Make it possible to unregister a misc device object in a safe way during a
suspend/resume cycle.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Michael Buesch <mb@bu3sch.de>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Len Brown <lenb@kernel.org>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Cc: Richard Purdie <rpurdie@rpsys.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Rafael J. Wysocki 2008-02-04 22:30:11 -08:00 committed by Linus Torvalds
parent f011e2e2df
commit 533354d4ac
2 changed files with 18 additions and 5 deletions

View file

@ -232,8 +232,9 @@ int misc_register(struct miscdevice * misc)
} }
/** /**
* misc_deregister - unregister a miscellaneous device * __misc_deregister - unregister a miscellaneous device
* @misc: device to unregister * @misc: device to unregister
* @suspended: to be set if the function is used during suspend/resume
* *
* Unregister a miscellaneous device that was previously * Unregister a miscellaneous device that was previously
* successfully registered with misc_register(). Success * successfully registered with misc_register(). Success
@ -241,7 +242,7 @@ int misc_register(struct miscdevice * misc)
* indicates an error. * indicates an error.
*/ */
int misc_deregister(struct miscdevice * misc) int __misc_deregister(struct miscdevice *misc, bool suspended)
{ {
int i = misc->minor; int i = misc->minor;
@ -250,7 +251,11 @@ int misc_deregister(struct miscdevice * misc)
mutex_lock(&misc_mtx); mutex_lock(&misc_mtx);
list_del(&misc->list); list_del(&misc->list);
device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); if (suspended)
destroy_suspended_device(misc_class,
MKDEV(MISC_MAJOR, misc->minor));
else
device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
if (i < DYNAMIC_MINORS && i>0) { if (i < DYNAMIC_MINORS && i>0) {
misc_minors[i>>3] &= ~(1 << (misc->minor & 7)); misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
} }
@ -259,7 +264,7 @@ int misc_deregister(struct miscdevice * misc)
} }
EXPORT_SYMBOL(misc_register); EXPORT_SYMBOL(misc_register);
EXPORT_SYMBOL(misc_deregister); EXPORT_SYMBOL(__misc_deregister);
static int __init misc_init(void) static int __init misc_init(void)
{ {

View file

@ -43,7 +43,15 @@ struct miscdevice {
}; };
extern int misc_register(struct miscdevice * misc); extern int misc_register(struct miscdevice * misc);
extern int misc_deregister(struct miscdevice * misc); extern int __misc_deregister(struct miscdevice *misc, bool suspended);
static inline int misc_deregister(struct miscdevice *misc)
{
return __misc_deregister(misc, false);
}
static inline int misc_deregister_suspended(struct miscdevice *misc)
{
return __misc_deregister(misc, true);
}
#define MODULE_ALIAS_MISCDEV(minor) \ #define MODULE_ALIAS_MISCDEV(minor) \
MODULE_ALIAS("char-major-" __stringify(MISC_MAJOR) \ MODULE_ALIAS("char-major-" __stringify(MISC_MAJOR) \