LCOV - code coverage report
Current view: top level - include/linux - cpuidle.h (source / functions) Hit Total Coverage
Test: landlock.info Lines: 5 8 62.5 %
Date: 2021-04-22 12:43:58 Functions: 0 0 -

          Line data    Source code
       1             : /*
       2             :  * cpuidle.h - a generic framework for CPU idle power management
       3             :  *
       4             :  * (C) 2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
       5             :  *          Shaohua Li <shaohua.li@intel.com>
       6             :  *          Adam Belay <abelay@novell.com>
       7             :  *
       8             :  * This code is licenced under the GPL.
       9             :  */
      10             : 
      11             : #ifndef _LINUX_CPUIDLE_H
      12             : #define _LINUX_CPUIDLE_H
      13             : 
      14             : #include <linux/percpu.h>
      15             : #include <linux/list.h>
      16             : #include <linux/hrtimer.h>
      17             : 
      18             : #define CPUIDLE_STATE_MAX       10
      19             : #define CPUIDLE_NAME_LEN        16
      20             : #define CPUIDLE_DESC_LEN        32
      21             : 
      22             : struct module;
      23             : 
      24             : struct cpuidle_device;
      25             : struct cpuidle_driver;
      26             : 
      27             : 
      28             : /****************************
      29             :  * CPUIDLE DEVICE INTERFACE *
      30             :  ****************************/
      31             : 
      32             : #define CPUIDLE_STATE_DISABLED_BY_USER          BIT(0)
      33             : #define CPUIDLE_STATE_DISABLED_BY_DRIVER        BIT(1)
      34             : 
      35             : struct cpuidle_state_usage {
      36             :         unsigned long long      disable;
      37             :         unsigned long long      usage;
      38             :         u64                     time_ns;
      39             :         unsigned long long      above; /* Number of times it's been too deep */
      40             :         unsigned long long      below; /* Number of times it's been too shallow */
      41             :         unsigned long long      rejected; /* Number of times idle entry was rejected */
      42             : #ifdef CONFIG_SUSPEND
      43             :         unsigned long long      s2idle_usage;
      44             :         unsigned long long      s2idle_time; /* in US */
      45             : #endif
      46             : };
      47             : 
      48             : struct cpuidle_state {
      49             :         char            name[CPUIDLE_NAME_LEN];
      50             :         char            desc[CPUIDLE_DESC_LEN];
      51             : 
      52             :         u64             exit_latency_ns;
      53             :         u64             target_residency_ns;
      54             :         unsigned int    flags;
      55             :         unsigned int    exit_latency; /* in US */
      56             :         int             power_usage; /* in mW */
      57             :         unsigned int    target_residency; /* in US */
      58             : 
      59             :         int (*enter)    (struct cpuidle_device *dev,
      60             :                         struct cpuidle_driver *drv,
      61             :                         int index);
      62             : 
      63             :         int (*enter_dead) (struct cpuidle_device *dev, int index);
      64             : 
      65             :         /*
      66             :          * CPUs execute ->enter_s2idle with the local tick or entire timekeeping
      67             :          * suspended, so it must not re-enable interrupts at any point (even
      68             :          * temporarily) or attempt to change states of clock event devices.
      69             :          *
      70             :          * This callback may point to the same function as ->enter if all of
      71             :          * the above requirements are met by it.
      72             :          */
      73             :         int (*enter_s2idle)(struct cpuidle_device *dev,
      74             :                             struct cpuidle_driver *drv,
      75             :                             int index);
      76             : };
      77             : 
      78             : /* Idle State Flags */
      79             : #define CPUIDLE_FLAG_NONE               (0x00)
      80             : #define CPUIDLE_FLAG_POLLING            BIT(0) /* polling state */
      81             : #define CPUIDLE_FLAG_COUPLED            BIT(1) /* state applies to multiple cpus */
      82             : #define CPUIDLE_FLAG_TIMER_STOP         BIT(2) /* timer is stopped on this state */
      83             : #define CPUIDLE_FLAG_UNUSABLE           BIT(3) /* avoid using this state */
      84             : #define CPUIDLE_FLAG_OFF                BIT(4) /* disable this state by default */
      85             : #define CPUIDLE_FLAG_TLB_FLUSHED        BIT(5) /* idle-state flushes TLBs */
      86             : #define CPUIDLE_FLAG_RCU_IDLE           BIT(6) /* idle-state takes care of RCU */
      87             : 
      88             : struct cpuidle_device_kobj;
      89             : struct cpuidle_state_kobj;
      90             : struct cpuidle_driver_kobj;
      91             : 
      92             : struct cpuidle_device {
      93             :         unsigned int            registered:1;
      94             :         unsigned int            enabled:1;
      95             :         unsigned int            poll_time_limit:1;
      96             :         unsigned int            cpu;
      97             :         ktime_t                 next_hrtimer;
      98             : 
      99             :         int                     last_state_idx;
     100             :         u64                     last_residency_ns;
     101             :         u64                     poll_limit_ns;
     102             :         u64                     forced_idle_latency_limit_ns;
     103             :         struct cpuidle_state_usage      states_usage[CPUIDLE_STATE_MAX];
     104             :         struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX];
     105             :         struct cpuidle_driver_kobj *kobj_driver;
     106             :         struct cpuidle_device_kobj *kobj_dev;
     107             :         struct list_head        device_list;
     108             : 
     109             : #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
     110             :         cpumask_t               coupled_cpus;
     111             :         struct cpuidle_coupled  *coupled;
     112             : #endif
     113             : };
     114             : 
     115             : DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
     116             : DECLARE_PER_CPU(struct cpuidle_device, cpuidle_dev);
     117             : 
     118             : /****************************
     119             :  * CPUIDLE DRIVER INTERFACE *
     120             :  ****************************/
     121             : 
     122             : struct cpuidle_driver {
     123             :         const char              *name;
     124             :         struct module           *owner;
     125             : 
     126             :         /* used by the cpuidle framework to setup the broadcast timer */
     127             :         unsigned int            bctimer:1;
     128             :         /* states array must be ordered in decreasing power consumption */
     129             :         struct cpuidle_state    states[CPUIDLE_STATE_MAX];
     130             :         int                     state_count;
     131             :         int                     safe_state_index;
     132             : 
     133             :         /* the driver handles the cpus in cpumask */
     134             :         struct cpumask          *cpumask;
     135             : 
     136             :         /* preferred governor to switch at register time */
     137             :         const char              *governor;
     138             : };
     139             : 
     140             : #ifdef CONFIG_CPU_IDLE
     141             : extern void disable_cpuidle(void);
     142             : extern bool cpuidle_not_available(struct cpuidle_driver *drv,
     143             :                                   struct cpuidle_device *dev);
     144             : 
     145             : extern int cpuidle_select(struct cpuidle_driver *drv,
     146             :                           struct cpuidle_device *dev,
     147             :                           bool *stop_tick);
     148             : extern int cpuidle_enter(struct cpuidle_driver *drv,
     149             :                          struct cpuidle_device *dev, int index);
     150             : extern void cpuidle_reflect(struct cpuidle_device *dev, int index);
     151             : extern u64 cpuidle_poll_time(struct cpuidle_driver *drv,
     152             :                              struct cpuidle_device *dev);
     153             : 
     154             : extern int cpuidle_register_driver(struct cpuidle_driver *drv);
     155             : extern struct cpuidle_driver *cpuidle_get_driver(void);
     156             : extern void cpuidle_driver_state_disabled(struct cpuidle_driver *drv, int idx,
     157             :                                         bool disable);
     158             : extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
     159             : extern int cpuidle_register_device(struct cpuidle_device *dev);
     160             : extern void cpuidle_unregister_device(struct cpuidle_device *dev);
     161             : extern int cpuidle_register(struct cpuidle_driver *drv,
     162             :                             const struct cpumask *const coupled_cpus);
     163             : extern void cpuidle_unregister(struct cpuidle_driver *drv);
     164             : extern void cpuidle_pause_and_lock(void);
     165             : extern void cpuidle_resume_and_unlock(void);
     166             : extern void cpuidle_pause(void);
     167             : extern void cpuidle_resume(void);
     168             : extern int cpuidle_enable_device(struct cpuidle_device *dev);
     169             : extern void cpuidle_disable_device(struct cpuidle_device *dev);
     170             : extern int cpuidle_play_dead(void);
     171             : 
     172             : extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev);
     173             : static inline struct cpuidle_device *cpuidle_get_device(void)
     174             : {return __this_cpu_read(cpuidle_devices); }
     175             : #else
     176             : static inline void disable_cpuidle(void) { }
     177       15378 : static inline bool cpuidle_not_available(struct cpuidle_driver *drv,
     178             :                                          struct cpuidle_device *dev)
     179       15378 : {return true; }
     180             : static inline int cpuidle_select(struct cpuidle_driver *drv,
     181             :                                  struct cpuidle_device *dev, bool *stop_tick)
     182             : {return -ENODEV; }
     183             : static inline int cpuidle_enter(struct cpuidle_driver *drv,
     184             :                                 struct cpuidle_device *dev, int index)
     185             : {return -ENODEV; }
     186             : static inline void cpuidle_reflect(struct cpuidle_device *dev, int index) { }
     187             : static inline u64 cpuidle_poll_time(struct cpuidle_driver *drv,
     188             :                              struct cpuidle_device *dev)
     189             : {return 0; }
     190             : static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
     191             : {return -ENODEV; }
     192             : static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }
     193             : static inline void cpuidle_driver_state_disabled(struct cpuidle_driver *drv,
     194             :                                                int idx, bool disable) { }
     195             : static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { }
     196             : static inline int cpuidle_register_device(struct cpuidle_device *dev)
     197             : {return -ENODEV; }
     198             : static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { }
     199             : static inline int cpuidle_register(struct cpuidle_driver *drv,
     200             :                                    const struct cpumask *const coupled_cpus)
     201             : {return -ENODEV; }
     202             : static inline void cpuidle_unregister(struct cpuidle_driver *drv) { }
     203             : static inline void cpuidle_pause_and_lock(void) { }
     204             : static inline void cpuidle_resume_and_unlock(void) { }
     205             : static inline void cpuidle_pause(void) { }
     206             : static inline void cpuidle_resume(void) { }
     207             : static inline int cpuidle_enable_device(struct cpuidle_device *dev)
     208             : {return -ENODEV; }
     209             : static inline void cpuidle_disable_device(struct cpuidle_device *dev) { }
     210           0 : static inline int cpuidle_play_dead(void) {return -ENODEV; }
     211       15369 : static inline struct cpuidle_driver *cpuidle_get_cpu_driver(
     212       15369 :         struct cpuidle_device *dev) {return NULL; }
     213       15369 : static inline struct cpuidle_device *cpuidle_get_device(void) {return NULL; }
     214             : #endif
     215             : 
     216             : #ifdef CONFIG_CPU_IDLE
     217             : extern int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
     218             :                                       struct cpuidle_device *dev,
     219             :                                       u64 latency_limit_ns);
     220             : extern int cpuidle_enter_s2idle(struct cpuidle_driver *drv,
     221             :                                 struct cpuidle_device *dev);
     222             : extern void cpuidle_use_deepest_state(u64 latency_limit_ns);
     223             : #else
     224             : static inline int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
     225             :                                              struct cpuidle_device *dev,
     226             :                                              u64 latency_limit_ns)
     227             : {return -ENODEV; }
     228             : static inline int cpuidle_enter_s2idle(struct cpuidle_driver *drv,
     229             :                                        struct cpuidle_device *dev)
     230             : {return -ENODEV; }
     231           0 : static inline void cpuidle_use_deepest_state(u64 latency_limit_ns)
     232             : {
     233           0 : }
     234             : #endif
     235             : 
     236             : /* kernel/sched/idle.c */
     237             : extern void sched_idle_set_state(struct cpuidle_state *idle_state);
     238             : extern void default_idle_call(void);
     239             : 
     240             : #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
     241             : void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a);
     242             : #else
     243             : static inline void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a)
     244             : {
     245             : }
     246             : #endif
     247             : 
     248             : #if defined(CONFIG_CPU_IDLE) && defined(CONFIG_ARCH_HAS_CPU_RELAX)
     249             : void cpuidle_poll_state_init(struct cpuidle_driver *drv);
     250             : #else
     251             : static inline void cpuidle_poll_state_init(struct cpuidle_driver *drv) {}
     252             : #endif
     253             : 
     254             : /******************************
     255             :  * CPUIDLE GOVERNOR INTERFACE *
     256             :  ******************************/
     257             : 
     258             : struct cpuidle_governor {
     259             :         char                    name[CPUIDLE_NAME_LEN];
     260             :         struct list_head        governor_list;
     261             :         unsigned int            rating;
     262             : 
     263             :         int  (*enable)          (struct cpuidle_driver *drv,
     264             :                                         struct cpuidle_device *dev);
     265             :         void (*disable)         (struct cpuidle_driver *drv,
     266             :                                         struct cpuidle_device *dev);
     267             : 
     268             :         int  (*select)          (struct cpuidle_driver *drv,
     269             :                                         struct cpuidle_device *dev,
     270             :                                         bool *stop_tick);
     271             :         void (*reflect)         (struct cpuidle_device *dev, int index);
     272             : };
     273             : 
     274             : extern int cpuidle_register_governor(struct cpuidle_governor *gov);
     275             : extern s64 cpuidle_governor_latency_req(unsigned int cpu);
     276             : 
     277             : #define __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter,                   \
     278             :                                 idx,                                    \
     279             :                                 state,                                  \
     280             :                                 is_retention)                           \
     281             : ({                                                                      \
     282             :         int __ret = 0;                                                  \
     283             :                                                                         \
     284             :         if (!idx) {                                                     \
     285             :                 cpu_do_idle();                                          \
     286             :                 return idx;                                             \
     287             :         }                                                               \
     288             :                                                                         \
     289             :         if (!is_retention)                                              \
     290             :                 __ret =  cpu_pm_enter();                                \
     291             :         if (!__ret) {                                                   \
     292             :                 __ret = low_level_idle_enter(state);                    \
     293             :                 if (!is_retention)                                      \
     294             :                         cpu_pm_exit();                                  \
     295             :         }                                                               \
     296             :                                                                         \
     297             :         __ret ? -1 : idx;                                               \
     298             : })
     299             : 
     300             : #define CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx)        \
     301             :         __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, idx, 0)
     302             : 
     303             : #define CPU_PM_CPU_IDLE_ENTER_RETENTION(low_level_idle_enter, idx)      \
     304             :         __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, idx, 1)
     305             : 
     306             : #define CPU_PM_CPU_IDLE_ENTER_PARAM(low_level_idle_enter, idx, state)   \
     307             :         __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, state, 0)
     308             : 
     309             : #define CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM(low_level_idle_enter, idx, state) \
     310             :         __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, state, 1)
     311             : 
     312             : #endif /* _LINUX_CPUIDLE_H */

Generated by: LCOV version 1.14