linux/include/linux/pm_domain.h
<<
>>
Prefs
   1/*
   2 * pm_domain.h - Definitions and headers related to device power domains.
   3 *
   4 * Copyright (C) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
   5 *
   6 * This file is released under the GPLv2.
   7 */
   8
   9#ifndef _LINUX_PM_DOMAIN_H
  10#define _LINUX_PM_DOMAIN_H
  11
  12#include <linux/device.h>
  13#include <linux/mutex.h>
  14#include <linux/pm.h>
  15#include <linux/err.h>
  16#include <linux/of.h>
  17#include <linux/notifier.h>
  18
  19enum gpd_status {
  20        GPD_STATE_ACTIVE = 0,   /* PM domain is active */
  21        GPD_STATE_WAIT_MASTER,  /* PM domain's master is being waited for */
  22        GPD_STATE_BUSY,         /* Something is happening to the PM domain */
  23        GPD_STATE_REPEAT,       /* Power off in progress, to be repeated */
  24        GPD_STATE_POWER_OFF,    /* PM domain is off */
  25};
  26
  27struct dev_power_governor {
  28        bool (*power_down_ok)(struct dev_pm_domain *domain);
  29        bool (*stop_ok)(struct device *dev);
  30};
  31
  32struct gpd_dev_ops {
  33        int (*start)(struct device *dev);
  34        int (*stop)(struct device *dev);
  35        int (*save_state)(struct device *dev);
  36        int (*restore_state)(struct device *dev);
  37        int (*suspend)(struct device *dev);
  38        int (*suspend_late)(struct device *dev);
  39        int (*resume_early)(struct device *dev);
  40        int (*resume)(struct device *dev);
  41        int (*freeze)(struct device *dev);
  42        int (*freeze_late)(struct device *dev);
  43        int (*thaw_early)(struct device *dev);
  44        int (*thaw)(struct device *dev);
  45        bool (*active_wakeup)(struct device *dev);
  46};
  47
  48struct generic_pm_domain {
  49        struct dev_pm_domain domain;    /* PM domain operations */
  50        struct list_head gpd_list_node; /* Node in the global PM domains list */
  51        struct list_head master_links;  /* Links with PM domain as a master */
  52        struct list_head slave_links;   /* Links with PM domain as a slave */
  53        struct list_head dev_list;      /* List of devices */
  54        struct mutex lock;
  55        struct dev_power_governor *gov;
  56        struct work_struct power_off_work;
  57        char *name;
  58        unsigned int in_progress;       /* Number of devices being suspended now */
  59        atomic_t sd_count;      /* Number of subdomains with power "on" */
  60        enum gpd_status status; /* Current state of the domain */
  61        wait_queue_head_t status_wait_queue;
  62        struct task_struct *poweroff_task;      /* Powering off task */
  63        unsigned int resume_count;      /* Number of devices being resumed */
  64        unsigned int device_count;      /* Number of devices */
  65        unsigned int suspended_count;   /* System suspend device counter */
  66        unsigned int prepared_count;    /* Suspend counter of prepared devices */
  67        bool suspend_power_off; /* Power status before system suspend */
  68        bool dev_irq_safe;      /* Device callbacks are IRQ-safe */
  69        int (*power_off)(struct generic_pm_domain *domain);
  70        s64 power_off_latency_ns;
  71        int (*power_on)(struct generic_pm_domain *domain);
  72        s64 power_on_latency_ns;
  73        struct gpd_dev_ops dev_ops;
  74        s64 max_off_time_ns;    /* Maximum allowed "suspended" time. */
  75        bool max_off_time_changed;
  76        bool cached_power_down_ok;
  77        struct device_node *of_node; /* Node in device tree */
  78};
  79
  80static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
  81{
  82        return container_of(pd, struct generic_pm_domain, domain);
  83}
  84
  85struct gpd_link {
  86        struct generic_pm_domain *master;
  87        struct list_head master_node;
  88        struct generic_pm_domain *slave;
  89        struct list_head slave_node;
  90};
  91
  92struct gpd_timing_data {
  93        s64 stop_latency_ns;
  94        s64 start_latency_ns;
  95        s64 save_state_latency_ns;
  96        s64 restore_state_latency_ns;
  97        s64 effective_constraint_ns;
  98        bool constraint_changed;
  99        bool cached_stop_ok;
 100};
 101
 102struct generic_pm_domain_data {
 103        struct pm_domain_data base;
 104        struct gpd_dev_ops ops;
 105        struct gpd_timing_data td;
 106        struct notifier_block nb;
 107        struct mutex lock;
 108        bool need_restore;
 109        bool always_on;
 110};
 111
 112#ifdef CONFIG_PM_GENERIC_DOMAINS
 113static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *pdd)
 114{
 115        return container_of(pdd, struct generic_pm_domain_data, base);
 116}
 117
 118static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
 119{
 120        return to_gpd_data(dev->power.subsys_data->domain_data);
 121}
 122
 123extern struct dev_power_governor simple_qos_governor;
 124
 125extern struct generic_pm_domain *dev_to_genpd(struct device *dev);
 126extern int __pm_genpd_add_device(struct generic_pm_domain *genpd,
 127                                 struct device *dev,
 128                                 struct gpd_timing_data *td);
 129
 130extern int __pm_genpd_of_add_device(struct device_node *genpd_node,
 131                                    struct device *dev,
 132                                    struct gpd_timing_data *td);
 133
 134static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
 135                                      struct device *dev)
 136{
 137        return __pm_genpd_add_device(genpd, dev, NULL);
 138}
 139
 140static inline int pm_genpd_of_add_device(struct device_node *genpd_node,
 141                                         struct device *dev)
 142{
 143        return __pm_genpd_of_add_device(genpd_node, dev, NULL);
 144}
 145
 146extern int pm_genpd_remove_device(struct generic_pm_domain *genpd,
 147                                  struct device *dev);
 148extern void pm_genpd_dev_always_on(struct device *dev, bool val);
 149extern void pm_genpd_dev_need_restore(struct device *dev, bool val);
 150extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
 151                                  struct generic_pm_domain *new_subdomain);
 152extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
 153                                     struct generic_pm_domain *target);
 154extern int pm_genpd_add_callbacks(struct device *dev,
 155                                  struct gpd_dev_ops *ops,
 156                                  struct gpd_timing_data *td);
 157extern int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td);
 158extern void pm_genpd_init(struct generic_pm_domain *genpd,
 159                          struct dev_power_governor *gov, bool is_off);
 160
 161extern int pm_genpd_poweron(struct generic_pm_domain *genpd);
 162
 163extern bool default_stop_ok(struct device *dev);
 164
 165extern struct dev_power_governor pm_domain_always_on_gov;
 166#else
 167
 168static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
 169{
 170        return ERR_PTR(-ENOSYS);
 171}
 172static inline struct generic_pm_domain *dev_to_genpd(struct device *dev)
 173{
 174        return ERR_PTR(-ENOSYS);
 175}
 176static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd,
 177                                        struct device *dev,
 178                                        struct gpd_timing_data *td)
 179{
 180        return -ENOSYS;
 181}
 182static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
 183                                      struct device *dev)
 184{
 185        return -ENOSYS;
 186}
 187static inline int pm_genpd_remove_device(struct generic_pm_domain *genpd,
 188                                         struct device *dev)
 189{
 190        return -ENOSYS;
 191}
 192static inline void pm_genpd_dev_always_on(struct device *dev, bool val) {}
 193static inline void pm_genpd_dev_need_restore(struct device *dev, bool val) {}
 194static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
 195                                         struct generic_pm_domain *new_sd)
 196{
 197        return -ENOSYS;
 198}
 199static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
 200                                            struct generic_pm_domain *target)
 201{
 202        return -ENOSYS;
 203}
 204static inline int pm_genpd_add_callbacks(struct device *dev,
 205                                         struct gpd_dev_ops *ops,
 206                                         struct gpd_timing_data *td)
 207{
 208        return -ENOSYS;
 209}
 210static inline int __pm_genpd_remove_callbacks(struct device *dev, bool clear_td)
 211{
 212        return -ENOSYS;
 213}
 214static inline void pm_genpd_init(struct generic_pm_domain *genpd,
 215                                 struct dev_power_governor *gov, bool is_off)
 216{
 217}
 218static inline int pm_genpd_poweron(struct generic_pm_domain *genpd)
 219{
 220        return -ENOSYS;
 221}
 222static inline bool default_stop_ok(struct device *dev)
 223{
 224        return false;
 225}
 226#define simple_qos_governor NULL
 227#define pm_domain_always_on_gov NULL
 228#endif
 229
 230static inline int pm_genpd_remove_callbacks(struct device *dev)
 231{
 232        return __pm_genpd_remove_callbacks(dev, true);
 233}
 234
 235#ifdef CONFIG_PM_GENERIC_DOMAINS_RUNTIME
 236extern void genpd_queue_power_off_work(struct generic_pm_domain *genpd);
 237extern void pm_genpd_poweroff_unused(void);
 238#else
 239static inline void genpd_queue_power_off_work(struct generic_pm_domain *gpd) {}
 240static inline void pm_genpd_poweroff_unused(void) {}
 241#endif
 242
 243#endif /* _LINUX_PM_DOMAIN_H */
 244