From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: pm list <linux-pm@lists.linux-foundation.org>
Cc: ACPI Devel Maling List <linux-acpi@vger.kernel.org>,
Alan Stern <stern@rowland.harvard.edu>,
Andrew Morton <akpm@linux-foundation.org>,
Len Brown <lenb@kernel.org>, LKML <linux-kernel@vger.kernel.org>,
Pavel Machek <pavel@suse.cz>, Ingo Molnar <mingo@elte.hu>,
Greg KH <gregkh@suse.de>
Subject: [PATCH 1/4] PM: Introduce destroy_suspended_device()
Date: Wed, 2 Jan 2008 00:34:59 +0100 [thread overview]
Message-ID: <200801020035.00301.rjw@sisk.pl> (raw)
In-Reply-To: <200801020032.45529.rjw@sisk.pl>
From: Rafael J. Wysocki <rjw@sisk.pl>
It sometimes is necessary to destroy a device object during a suspend or
hibernation, but the PM core is supposed to control all device objects in that
cases. For this reason, it is necessary to introduce a mechanism allowing one
to ask the PM core to remove a device object corresponding to a suspended
device on one's behalf.
Define function destroy_suspended_device() that will schedule the removal of
a device object corresponding to a suspended device by the PM core during the
subsequent resume.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
drivers/base/core.c | 44 +++++++++++++++++++++++++++++++++++++++-----
drivers/base/power/main.c | 36 +++++++++++++++++++++++++++---------
drivers/base/power/power.h | 1 +
include/linux/device.h | 8 ++++++++
4 files changed, 75 insertions(+), 14 deletions(-)
Index: linux-2.6/drivers/base/core.c
===================================================================
--- linux-2.6.orig/drivers/base/core.c
+++ linux-2.6/drivers/base/core.c
@@ -1156,14 +1156,11 @@ error:
EXPORT_SYMBOL_GPL(device_create);
/**
- * device_destroy - removes a device that was created with device_create()
+ * find_device - finds a device that was created with device_create()
* @class: pointer to the struct class that this device was registered with
* @devt: the dev_t of the device that was previously registered
- *
- * This call unregisters and cleans up a device that was created with a
- * call to device_create().
*/
-void device_destroy(struct class *class, dev_t devt)
+static struct device *find_device(struct class *class, dev_t devt)
{
struct device *dev = NULL;
struct device *dev_tmp;
@@ -1176,12 +1173,49 @@ void device_destroy(struct class *class,
}
}
up(&class->sem);
+ return dev;
+}
+/**
+ * device_destroy - removes a device that was created with device_create()
+ * @class: pointer to the struct class that this device was registered with
+ * @devt: the dev_t of the device that was previously registered
+ *
+ * This call unregisters and cleans up a device that was created with a
+ * call to device_create().
+ */
+void device_destroy(struct class *class, dev_t devt)
+{
+ struct device *dev;
+
+ dev = find_device(class, devt);
if (dev)
device_unregister(dev);
}
EXPORT_SYMBOL_GPL(device_destroy);
+#ifdef CONFIG_PM_SLEEP
+/**
+ * destroy_suspended_device - schedules the removal of a suspended device
+ * @class: pointer to the struct class that this device was registered with
+ * @devt: the dev_t of the device that was previously registered
+ *
+ * This call notifies the PM core of the necessity to unregister a suspended
+ * device created with a call to device_create() (devices cannot be
+ * unregistered directly while suspended, since the PM core controls them in
+ * that cases).
+ */
+void destroy_suspended_device(struct class *class, dev_t devt)
+{
+ struct device *dev;
+
+ dev = find_device(class, devt);
+ if (dev)
+ device_pm_schedule_removal(dev);
+}
+EXPORT_SYMBOL_GPL(destroy_suspended_device);
+#endif /* CONFIG_PM_SLEEP */
+
/**
* device_rename - renames a device
* @dev: the pointer to the struct device to be renamed
Index: linux-2.6/include/linux/device.h
===================================================================
--- linux-2.6.orig/include/linux/device.h
+++ linux-2.6/include/linux/device.h
@@ -521,6 +521,14 @@ extern struct device *device_create(stru
dev_t devt, const char *fmt, ...)
__attribute__((format(printf,4,5)));
extern void device_destroy(struct class *cls, dev_t devt);
+#ifdef CONFIG_PM_SLEEP
+extern void destroy_suspended_device(struct class *cls, dev_t devt);
+#else /* !CONFIG_PM_SLEEP */
+static inline void destroy_suspended_device(struct class *cls, dev_t devt)
+{
+ device_destroy(cls, devt);
+}
+#endif /* !CONFIG_PM_SLEEP */
/*
* Platform "fixup" functions - allow the platform to have their say
Index: linux-2.6/drivers/base/power/power.h
===================================================================
--- linux-2.6.orig/drivers/base/power/power.h
+++ linux-2.6/drivers/base/power/power.h
@@ -20,6 +20,7 @@ static inline struct device *to_device(s
extern void device_pm_add(struct device *);
extern void device_pm_remove(struct device *);
+extern void device_pm_schedule_removal(struct device *);
#else /* CONFIG_PM_SLEEP */
Index: linux-2.6/drivers/base/power/main.c
===================================================================
--- linux-2.6.orig/drivers/base/power/main.c
+++ linux-2.6/drivers/base/power/main.c
@@ -31,6 +31,7 @@
LIST_HEAD(dpm_active);
static LIST_HEAD(dpm_off);
static LIST_HEAD(dpm_off_irq);
+static LIST_HEAD(dpm_destroy);
static DEFINE_MUTEX(dpm_mtx);
static DEFINE_MUTEX(dpm_list_mtx);
@@ -59,6 +60,17 @@ void device_pm_remove(struct device *dev
mutex_unlock(&dpm_list_mtx);
}
+void device_pm_schedule_removal(struct device *dev)
+{
+ pr_debug("PM: Removing info for %s:%s\n",
+ dev->bus ? dev->bus->name : "No Bus",
+ kobject_name(&dev->kobj));
+ mutex_lock(&dpm_list_mtx);
+ dpm_sysfs_remove(dev);
+ list_move_tail(&dev->power.entry, &dpm_destroy);
+ mutex_unlock(&dpm_list_mtx);
+}
+
/*------------------------- Resume routines -------------------------*/
@@ -113,11 +125,14 @@ static int resume_device_early(struct de
return error;
}
-/*
- * Resume the devices that have either not gone through
- * the late suspend, or that did go through it but also
- * went through the early resume
+/**
+ * dpm_resume - Restore state of each device in system.
+ *
+ * Walk the dpm_off list, remove each entry, resume the device,
+ * then add it to the dpm_active list. Unregister devices scheduled for
+ * removal.
*/
+
static void dpm_resume(void)
{
mutex_lock(&dpm_list_mtx);
@@ -134,14 +149,17 @@ static void dpm_resume(void)
put_device(dev);
}
mutex_unlock(&dpm_list_mtx);
-}
+ /* Unregister devices scheduled for removal */
+ while (!list_empty(&dpm_destroy)) {
+ struct list_head *entry = dpm_destroy.next;
+ struct device *dev = to_device(entry);
+ device_unregister(dev);
+ }
+}
/**
- * device_resume - Restore state of each device in system.
- *
- * Walk the dpm_off list, remove each entry, resume the device,
- * then add it to the dpm_active list.
+ * device_resume - Invoke dpm_resume() under dpm_mtx.
*/
void device_resume(void)
next prev parent reply other threads:[~2008-01-01 23:41 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-01 23:32 [PATCH 0/4] PM: Do not destroy/create devices while suspended (rev. 2) Rafael J. Wysocki
2008-01-01 23:34 ` Rafael J. Wysocki [this message]
2008-01-02 13:33 ` [PATCH 1/4] PM: Introduce destroy_suspended_device() Rafael J. Wysocki
2008-01-02 16:41 ` Alan Stern
2008-01-02 16:50 ` Rafael J. Wysocki
2008-01-04 22:05 ` Rafael J. Wysocki
2008-01-04 23:29 ` [RFC][PATCH] PM: Acquire device locks on suspend (was: Re: [PATCH 1/4] PM: Introduce destroy_suspended_device()) Rafael J. Wysocki
2008-01-05 3:11 ` [PATCH 1/4] PM: Introduce destroy_suspended_device() Alan Stern
2008-01-05 11:55 ` Rafael J. Wysocki
2008-01-01 23:40 ` [PATCH 2/4] PM: Do not destroy/create devices while suspended in msr.c (rev. 2) Rafael J. Wysocki
2008-01-01 23:40 ` [PATCH 3/4] PM: Do not destroy/create devices while suspended in mce_64.c Rafael J. Wysocki
2008-01-01 23:42 ` [PATCH 4/4] PM: Do not destroy/create devices while suspended in cpuid.c Rafael J. Wysocki
2008-01-02 10:52 ` [PATCH 0/4] PM: Do not destroy/create devices while suspended (rev. 2) Ingo Molnar
2008-01-02 12:56 ` Rafael J. Wysocki
2008-01-02 13:15 ` Ingo Molnar
2008-01-02 13:28 ` Rafael J. Wysocki
2008-01-03 10:56 ` Pavel Machek
2008-01-02 14:55 ` Kay Sievers
2008-01-02 16:01 ` Ingo Molnar
2008-01-02 17:54 ` David Brownell
2008-01-02 18:05 ` Alessandro Zummo
2008-01-02 18:12 ` David Brownell
2008-01-02 18:34 ` Alessandro Zummo
2008-01-02 20:14 ` Ingo Molnar
2008-01-02 20:29 ` David Brownell
2008-01-02 17:26 ` David Brownell
2008-01-02 20:17 ` Ingo Molnar
2008-01-12 0:46 ` Andrew Morton
2008-01-12 0:49 ` Andrew Morton
2008-01-12 0:56 ` Greg KH
2008-01-12 3:11 ` Alan Stern
2008-01-12 3:15 ` Andi Kleen
2008-01-12 3:21 ` Andrew Morton
2008-01-12 4:29 ` Greg KH
2008-01-12 11:25 ` Rafael J. Wysocki
2008-01-12 11:20 ` Rafael J. Wysocki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200801020035.00301.rjw@sisk.pl \
--to=rjw@sisk.pl \
--cc=akpm@linux-foundation.org \
--cc=gregkh@suse.de \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@lists.linux-foundation.org \
--cc=mingo@elte.hu \
--cc=pavel@suse.cz \
--cc=stern@rowland.harvard.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox