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#include <linux/spinlock.h>
  19
  20/* Defines used for the flags field in the struct generic_pm_domain */
  21#define GENPD_FLAG_PM_CLK        (1U << 0) /* PM domain uses PM clk */
  22#define GENPD_FLAG_IRQ_SAFE      (1U << 1) /* PM domain operates in atomic */
  23#define GENPD_FLAG_ALWAYS_ON     (1U << 2) /* PM domain is always powered on */
  24#define GENPD_FLAG_ACTIVE_WAKEUP (1U << 3) /* Keep devices active if wakeup */
  25
  26enum gpd_status {
  27        GPD_STATE_ACTIVE = 0,   /* PM domain is active */
  28        GPD_STATE_POWER_OFF,    /* PM domain is off */
  29};
  30
  31struct dev_power_governor {
  32        bool (*power_down_ok)(struct dev_pm_domain *domain);
  33        bool (*suspend_ok)(struct device *dev);
  34};
  35
  36struct gpd_dev_ops {
  37        int (*start)(struct device *dev);
  38        int (*stop)(struct device *dev);
  39};
  40
  41struct genpd_power_state {
  42        s64 power_off_latency_ns;
  43        s64 power_on_latency_ns;
  44        s64 residency_ns;
  45        struct fwnode_handle *fwnode;
  46        ktime_t idle_time;
  47};
  48
  49struct genpd_lock_ops;
  50
  51struct generic_pm_domain {
  52        struct dev_pm_domain domain;    /* PM domain operations */
  53        struct list_head gpd_list_node; /* Node in the global PM domains list */
  54        struct list_head master_links;  /* Links with PM domain as a master */
  55        struct list_head slave_links;   /* Links with PM domain as a slave */
  56        struct list_head dev_list;      /* List of devices */
  57        struct dev_power_governor *gov;
  58        struct work_struct power_off_work;
  59        struct fwnode_handle *provider; /* Identity of the domain provider */
  60        bool has_provider;
  61        const char *name;
  62        atomic_t sd_count;      /* Number of subdomains with power "on" */
  63        enum gpd_status status; /* Current state of the domain */
  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        unsigned int performance_state; /* Aggregated max performance state */
  68        int (*power_off)(struct generic_pm_domain *domain);
  69        int (*power_on)(struct generic_pm_domain *domain);
  70        int (*set_performance_state)(struct generic_pm_domain *genpd,
  71                                     unsigned int state);
  72        struct gpd_dev_ops dev_ops;
  73        s64 max_off_time_ns;    /* Maximum allowed "suspended" time. */
  74        bool max_off_time_changed;
  75        bool cached_power_down_ok;
  76        int (*attach_dev)(struct generic_pm_domain *domain,
  77                          struct device *dev);
  78        void (*detach_dev)(struct generic_pm_domain *domain,
  79                           struct device *dev);
  80        unsigned int flags;             /* Bit field of configs for genpd */
  81        struct genpd_power_state *states;
  82        unsigned int state_count; /* number of states */
  83        unsigned int state_idx; /* state that genpd will go to when off */
  84        void *free; /* Free the state that was allocated for default */
  85        ktime_t on_time;
  86        ktime_t accounting_time;
  87        const struct genpd_lock_ops *lock_ops;
  88        union {
  89                struct mutex mlock;
  90                struct {
  91                        spinlock_t slock;
  92                        unsigned long lock_flags;
  93                };
  94        };
  95
  96};
  97
  98static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
  99{
 100        return container_of(pd, struct generic_pm_domain, domain);
 101}
 102
 103struct gpd_link {
 104        struct generic_pm_domain *master;
 105        struct list_head master_node;
 106        struct generic_pm_domain *slave;
 107        struct list_head slave_node;
 108};
 109
 110struct gpd_timing_data {
 111        s64 suspend_latency_ns;
 112        s64 resume_latency_ns;
 113        s64 effective_constraint_ns;
 114        bool constraint_changed;
 115        bool cached_suspend_ok;
 116};
 117
 118struct pm_domain_data {
 119        struct list_head list_node;
 120        struct device *dev;
 121};
 122
 123struct generic_pm_domain_data {
 124        struct pm_domain_data base;
 125        struct gpd_timing_data td;
 126        struct notifier_block nb;
 127        unsigned int performance_state;
 128        void *data;
 129};
 130
 131#ifdef CONFIG_PM_GENERIC_DOMAINS
 132static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *pdd)
 133{
 134        return container_of(pdd, struct generic_pm_domain_data, base);
 135}
 136
 137static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
 138{
 139        return to_gpd_data(dev->power.subsys_data->domain_data);
 140}
 141
 142extern int __pm_genpd_add_device(struct generic_pm_domain *genpd,
 143                                 struct device *dev,
 144                                 struct gpd_timing_data *td);
 145
 146extern int pm_genpd_remove_device(struct generic_pm_domain *genpd,
 147                                  struct device *dev);
 148extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
 149                                  struct generic_pm_domain *new_subdomain);
 150extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
 151                                     struct generic_pm_domain *target);
 152extern int pm_genpd_init(struct generic_pm_domain *genpd,
 153                         struct dev_power_governor *gov, bool is_off);
 154extern int pm_genpd_remove(struct generic_pm_domain *genpd);
 155extern int dev_pm_genpd_set_performance_state(struct device *dev,
 156                                              unsigned int state);
 157
 158extern struct dev_power_governor simple_qos_governor;
 159extern struct dev_power_governor pm_domain_always_on_gov;
 160#else
 161
 162static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
 163{
 164        return ERR_PTR(-ENOSYS);
 165}
 166static inline int __pm_genpd_add_device(struct generic_pm_domain *genpd,
 167                                        struct device *dev,
 168                                        struct gpd_timing_data *td)
 169{
 170        return -ENOSYS;
 171}
 172static inline int pm_genpd_remove_device(struct generic_pm_domain *genpd,
 173                                         struct device *dev)
 174{
 175        return -ENOSYS;
 176}
 177static inline int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
 178                                         struct generic_pm_domain *new_sd)
 179{
 180        return -ENOSYS;
 181}
 182static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
 183                                            struct generic_pm_domain *target)
 184{
 185        return -ENOSYS;
 186}
 187static inline int pm_genpd_init(struct generic_pm_domain *genpd,
 188                                struct dev_power_governor *gov, bool is_off)
 189{
 190        return -ENOSYS;
 191}
 192static inline int pm_genpd_remove(struct generic_pm_domain *genpd)
 193{
 194        return -ENOTSUPP;
 195}
 196
 197static inline int dev_pm_genpd_set_performance_state(struct device *dev,
 198                                                     unsigned int state)
 199{
 200        return -ENOTSUPP;
 201}
 202
 203#define simple_qos_governor             (*(struct dev_power_governor *)(NULL))
 204#define pm_domain_always_on_gov         (*(struct dev_power_governor *)(NULL))
 205#endif
 206
 207static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
 208                                      struct device *dev)
 209{
 210        return __pm_genpd_add_device(genpd, dev, NULL);
 211}
 212
 213#ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP
 214extern void pm_genpd_syscore_poweroff(struct device *dev);
 215extern void pm_genpd_syscore_poweron(struct device *dev);
 216#else
 217static inline void pm_genpd_syscore_poweroff(struct device *dev) {}
 218static inline void pm_genpd_syscore_poweron(struct device *dev) {}
 219#endif
 220
 221/* OF PM domain providers */
 222struct of_device_id;
 223
 224typedef struct generic_pm_domain *(*genpd_xlate_t)(struct of_phandle_args *args,
 225                                                   void *data);
 226
 227struct genpd_onecell_data {
 228        struct generic_pm_domain **domains;
 229        unsigned int num_domains;
 230        genpd_xlate_t xlate;
 231};
 232
 233#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
 234int of_genpd_add_provider_simple(struct device_node *np,
 235                                 struct generic_pm_domain *genpd);
 236int of_genpd_add_provider_onecell(struct device_node *np,
 237                                  struct genpd_onecell_data *data);
 238void of_genpd_del_provider(struct device_node *np);
 239extern int of_genpd_add_device(struct of_phandle_args *args,
 240                               struct device *dev);
 241extern int of_genpd_add_subdomain(struct of_phandle_args *parent,
 242                                  struct of_phandle_args *new_subdomain);
 243extern struct generic_pm_domain *of_genpd_remove_last(struct device_node *np);
 244extern int of_genpd_parse_idle_states(struct device_node *dn,
 245                        struct genpd_power_state **states, int *n);
 246
 247int genpd_dev_pm_attach(struct device *dev);
 248#else /* !CONFIG_PM_GENERIC_DOMAINS_OF */
 249static inline int of_genpd_add_provider_simple(struct device_node *np,
 250                                        struct generic_pm_domain *genpd)
 251{
 252        return -ENOTSUPP;
 253}
 254
 255static inline int of_genpd_add_provider_onecell(struct device_node *np,
 256                                        struct genpd_onecell_data *data)
 257{
 258        return -ENOTSUPP;
 259}
 260
 261static inline void of_genpd_del_provider(struct device_node *np) {}
 262
 263static inline int of_genpd_add_device(struct of_phandle_args *args,
 264                                      struct device *dev)
 265{
 266        return -ENODEV;
 267}
 268
 269static inline int of_genpd_add_subdomain(struct of_phandle_args *parent,
 270                                         struct of_phandle_args *new_subdomain)
 271{
 272        return -ENODEV;
 273}
 274
 275static inline int of_genpd_parse_idle_states(struct device_node *dn,
 276                        struct genpd_power_state **states, int *n)
 277{
 278        return -ENODEV;
 279}
 280
 281static inline int genpd_dev_pm_attach(struct device *dev)
 282{
 283        return -ENODEV;
 284}
 285
 286static inline
 287struct generic_pm_domain *of_genpd_remove_last(struct device_node *np)
 288{
 289        return ERR_PTR(-ENOTSUPP);
 290}
 291#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
 292
 293#ifdef CONFIG_PM
 294extern int dev_pm_domain_attach(struct device *dev, bool power_on);
 295extern void dev_pm_domain_detach(struct device *dev, bool power_off);
 296extern void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd);
 297#else
 298static inline int dev_pm_domain_attach(struct device *dev, bool power_on)
 299{
 300        return -ENODEV;
 301}
 302static inline void dev_pm_domain_detach(struct device *dev, bool power_off) {}
 303static inline void dev_pm_domain_set(struct device *dev,
 304                                     struct dev_pm_domain *pd) {}
 305#endif
 306
 307#endif /* _LINUX_PM_DOMAIN_H */
 308