![David Brownell](/assets/img/avatar_default.png)
This saves a word from "struct device" ... there's a refcounting mechanism stub that's rather ineffective (the values are never even tested!), which can safely be deleted. With this patch it uses normal device refcounting, so any potential users of the pm_parent mechanism will be more correct. (That mechanism is actually unusable for now though; it does nothing.) Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> drivers/base/power/main.c | 26 +++----------------------- include/linux/pm.h | 1 - 2 files changed, 3 insertions(+), 24 deletions(-)
80 lines
2.3 KiB
C
80 lines
2.3 KiB
C
/*
|
|
* drivers/base/power/main.c - Where the driver meets power management.
|
|
*
|
|
* Copyright (c) 2003 Patrick Mochel
|
|
* Copyright (c) 2003 Open Source Development Lab
|
|
*
|
|
* This file is released under the GPLv2
|
|
*
|
|
*
|
|
* The driver model core calls device_pm_add() when a device is registered.
|
|
* This will intialize the embedded device_pm_info object in the device
|
|
* and add it to the list of power-controlled devices. sysfs entries for
|
|
* controlling device power management will also be added.
|
|
*
|
|
* A different set of lists than the global subsystem list are used to
|
|
* keep track of power info because we use different lists to hold
|
|
* devices based on what stage of the power management process they
|
|
* are in. The power domain dependencies may also differ from the
|
|
* ancestral dependencies that the subsystem list maintains.
|
|
*/
|
|
|
|
#include <linux/config.h>
|
|
#include <linux/device.h>
|
|
#include "power.h"
|
|
|
|
LIST_HEAD(dpm_active);
|
|
LIST_HEAD(dpm_off);
|
|
LIST_HEAD(dpm_off_irq);
|
|
|
|
DECLARE_MUTEX(dpm_sem);
|
|
DECLARE_MUTEX(dpm_list_sem);
|
|
|
|
/**
|
|
* device_pm_set_parent - Specify power dependency.
|
|
* @dev: Device who needs power.
|
|
* @parent: Device that supplies power.
|
|
*
|
|
* This function is used to manually describe a power-dependency
|
|
* relationship. It may be used to specify a transversal relationship
|
|
* (where the power supplier is not the physical (or electrical)
|
|
* ancestor of a specific device.
|
|
* The effect of this is that the supplier will not be powered down
|
|
* before the power dependent.
|
|
*/
|
|
|
|
void device_pm_set_parent(struct device * dev, struct device * parent)
|
|
{
|
|
put_device(dev->power.pm_parent);
|
|
dev->power.pm_parent = get_device(parent);
|
|
}
|
|
EXPORT_SYMBOL_GPL(device_pm_set_parent);
|
|
|
|
int device_pm_add(struct device * dev)
|
|
{
|
|
int error;
|
|
|
|
pr_debug("PM: Adding info for %s:%s\n",
|
|
dev->bus ? dev->bus->name : "No Bus", dev->kobj.name);
|
|
down(&dpm_list_sem);
|
|
list_add_tail(&dev->power.entry, &dpm_active);
|
|
device_pm_set_parent(dev, dev->parent);
|
|
if ((error = dpm_sysfs_add(dev)))
|
|
list_del(&dev->power.entry);
|
|
up(&dpm_list_sem);
|
|
return error;
|
|
}
|
|
|
|
void device_pm_remove(struct device * dev)
|
|
{
|
|
pr_debug("PM: Removing info for %s:%s\n",
|
|
dev->bus ? dev->bus->name : "No Bus", dev->kobj.name);
|
|
down(&dpm_list_sem);
|
|
dpm_sysfs_remove(dev);
|
|
put_device(dev->power.pm_parent);
|
|
list_del_init(&dev->power.entry);
|
|
up(&dpm_list_sem);
|
|
}
|
|
|
|
|