Commit 63dd56a0 authored by Patrick Mochel's avatar Patrick Mochel

[power] Add PM info structure to struct device and PM registration functions.

- struct device_pm_info 
  - Defined in include/linux/pm.h.
  - Statically allocated in struct device (->power)
  - Body is empty if CONFIG_PM=n

- deivce_pm_{add,remove}
  - Called from device_{add,del} respectively.
  - Adds device to internal list of power managed objects and creates
    attribute group for device. 
    (Group currently empty, but placeholder directory is created for now)
  - Are defined as empty statc inline's when CONFIG_PM=n.
parent 274e497b
......@@ -13,3 +13,21 @@ struct class_device_attribute *to_class_dev_attr(struct attribute *_attr)
{
return container_of(_attr,struct class_device_attribute,attr);
}
#ifdef CONFIG_PM
extern int device_pm_add(struct device *);
extern void device_pm_remove(struct device *);
#else
static inline int device_pm_add(struct device * dev)
{
return 0;
}
static inline void device_pm_remove(struct device * dev)
{
}
#endif
......@@ -230,6 +230,8 @@ int device_add(struct device *dev)
bus_add_device(dev);
device_pm_add(dev);
/* notify platform of device entry */
if (platform_notify)
platform_notify(dev);
......@@ -304,6 +306,8 @@ void device_del(struct device * dev)
{
struct device * parent = dev->parent;
device_pm_remove(dev);
down_write(&devices_subsys.rwsem);
if (parent)
list_del_init(&dev->node);
......
obj-y := shutdown.o
obj-$(CONFIG_PM) += suspend.o resume.o
obj-$(CONFIG_PM) += main.o suspend.o resume.o
/*
* 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.
*/
#define DEBUG
#include <linux/device.h>
static LIST_HEAD(dpm_active_list);
static spinlock_t dpm_lock = SPIN_LOCK_UNLOCKED;
static DECLARE_MUTEX(dpm_sem);
static struct attribute power_attrs[] = {
{ .name = NULL },
};
static struct attribute_group pm_attr_group = {
.name = "pm",
.attrs = power_attrs,
};
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_sem);
spin_lock(&dpm_lock);
list_add_tail(&dev->power.entry,&dpm_active_list);
spin_unlock(&dpm_lock);
error = sysfs_create_group(&dev->kobj,&pm_attr_group);
up(&dpm_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_sem);
sysfs_remove_group(&dev->kobj,&pm_attr_group);
spin_lock(&dpm_lock);
list_del(&dev->power.entry);
spin_unlock(&dpm_lock);
up(&dpm_sem);
}
......@@ -19,6 +19,7 @@
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <asm/semaphore.h>
#include <asm/atomic.h>
......@@ -41,13 +42,6 @@ enum {
RESUME_ENABLE,
};
enum device_state {
DEVICE_UNINITIALIZED = 0,
DEVICE_INITIALIZED = 1,
DEVICE_REGISTERED = 2,
DEVICE_GONE = 3,
};
struct device;
struct device_driver;
struct class;
......@@ -64,8 +58,8 @@ struct bus_type {
struct device * (*add) (struct device * parent, char * bus_id);
int (*hotplug) (struct device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);
};
};
extern int bus_register(struct bus_type * bus);
extern void bus_unregister(struct bus_type * bus);
......@@ -267,7 +261,7 @@ struct device {
void *driver_data; /* data private to the driver */
void *platform_data; /* Platform specific data (e.g. ACPI,
BIOS data relevant to device) */
struct dev_pm_info power;
u32 power_state; /* Current operating state. In
ACPI-speak, this is D0-D3, D0
being fully functional, and D3
......
......@@ -188,6 +188,15 @@ static inline void pm_dev_idle(struct pm_dev *dev) {}
extern void (*pm_idle)(void);
extern void (*pm_power_off)(void);
struct dev_pm_info {
#ifdef CONFIG_PM
u32 power_state;
u8 * saved_state;
struct list_head entry;
#endif
};
#endif /* __KERNEL__ */
#endif /* _LINUX_PM_H */
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