linux/drivers/base/power/shutdown.c
David Brownell 82428b62aa [PATCH] Driver Core: pm diagnostics update, check for errors
This patch includes various tweaks in the messaging that appears during
system pm state transitions:

  * Warn about certain illegal calls in the device tree, like resuming
    child before parent or suspending parent before child.  This could
    happen easily enough through sysfs, or in some cases when drivers
    use device_pm_set_parent().

  * Be more consistent about dev_dbg() tracing ... do it for resume() and
    shutdown() too, and never if the driver doesn't have that method.

  * Say which type of system sleep state is being entered.

Except for the warnings, these only affect debug messaging.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2005-05-17 14:54:54 -07:00

69 lines
1.5 KiB
C

/*
* shutdown.c - power management functions for the device tree.
*
* Copyright (c) 2002-3 Patrick Mochel
* 2002-3 Open Source Development Lab
*
* This file is released under the GPLv2
*
*/
#include <linux/config.h>
#include <linux/device.h>
#include <asm/semaphore.h>
#include "power.h"
#define to_dev(node) container_of(node, struct device, kobj.entry)
extern struct subsystem devices_subsys;
int device_detach_shutdown(struct device * dev)
{
if (!dev->detach_state)
return 0;
if (dev->detach_state == DEVICE_PM_OFF) {
if (dev->driver && dev->driver->shutdown) {
dev_dbg(dev, "shutdown\n");
dev->driver->shutdown(dev);
}
return 0;
}
return dpm_runtime_suspend(dev, dev->detach_state);
}
/**
* We handle system devices differently - we suspend and shut them
* down last and resume them first. That way, we don't do anything stupid like
* shutting down the interrupt controller before any devices..
*
* Note that there are not different stages for power management calls -
* they only get one called once when interrupts are disabled.
*/
extern int sysdev_shutdown(void);
/**
* device_shutdown - call ->shutdown() on each device to shutdown.
*/
void device_shutdown(void)
{
struct device * dev;
down_write(&devices_subsys.rwsem);
list_for_each_entry_reverse(dev, &devices_subsys.kset.list,
kobj.entry) {
if (dev->driver && dev->driver->shutdown) {
dev_dbg(dev, "shutdown\n");
dev->driver->shutdown(dev);
}
}
up_write(&devices_subsys.rwsem);
sysdev_shutdown();
}