Commit 533354d4 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Linus Torvalds

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: default avatarRafael 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f011e2e2
...@@ -232,8 +232,9 @@ int misc_register(struct miscdevice * misc) ...@@ -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) ...@@ -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,6 +251,10 @@ int misc_deregister(struct miscdevice * misc) ...@@ -250,6 +251,10 @@ int misc_deregister(struct miscdevice * misc)
mutex_lock(&misc_mtx); mutex_lock(&misc_mtx);
list_del(&misc->list); list_del(&misc->list);
if (suspended)
destroy_suspended_device(misc_class,
MKDEV(MISC_MAJOR, misc->minor));
else
device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); 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) ...@@ -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)
{ {
......
...@@ -43,7 +43,15 @@ struct miscdevice { ...@@ -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) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment