/* * 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 #include #include #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->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) { pr_debug("shutting down %s: ", dev->bus_id); if (dev->driver && dev->driver->shutdown) { pr_debug("Ok\n"); dev->driver->shutdown(dev); } else pr_debug("Ignored.\n"); } up_write(&devices_subsys.rwsem); sysdev_shutdown(); }