Merge branches 'pm-domains', 'powercap' and 'pm-tools'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 29 Dec 2014 20:24:00 +0000 (21:24 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 29 Dec 2014 20:24:00 +0000 (21:24 +0100)
* pm-domains:
  PM / Domains: Export of_genpd_get_from_provider function

* powercap:
  powercap / RAPL: add IDs for future Xeon CPUs

* pm-tools:
  tools / cpupower: Fix no idle state information return value
  tools / cpupower: Correctly detect if running as root

1  2  3  4 
drivers/base/power/domain.c
include/linux/pm_domain.h

    #include <linux/pm_runtime.h>
    #include <linux/pm_domain.h>
    #include <linux/pm_qos.h>
  ++#include <linux/pm_clock.h>
    #include <linux/slab.h>
    #include <linux/err.h>
    #include <linux/sched.h>
@@@@@ -152,59 -152,59 -151,6 -151,6 +152,59 @@@@@ static void genpd_recalc_cpu_exit_laten
        genpd->cpuidle_data->idle_state->exit_latency = usecs64;
    }
    
  ++static int genpd_power_on(struct generic_pm_domain *genpd)
  ++{
  ++    ktime_t time_start;
  ++    s64 elapsed_ns;
  ++    int ret;
  ++
  ++    if (!genpd->power_on)
  ++            return 0;
  ++
  ++    time_start = ktime_get();
  ++    ret = genpd->power_on(genpd);
  ++    if (ret)
  ++            return ret;
  ++
  ++    elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
  ++    if (elapsed_ns <= genpd->power_on_latency_ns)
  ++            return ret;
  ++
  ++    genpd->power_on_latency_ns = elapsed_ns;
  ++    genpd->max_off_time_changed = true;
  ++    genpd_recalc_cpu_exit_latency(genpd);
  ++    pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n",
  ++            genpd->name, "on", elapsed_ns);
  ++
  ++    return ret;
  ++}
  ++
  ++static int genpd_power_off(struct generic_pm_domain *genpd)
  ++{
  ++    ktime_t time_start;
  ++    s64 elapsed_ns;
  ++    int ret;
  ++
  ++    if (!genpd->power_off)
  ++            return 0;
  ++
  ++    time_start = ktime_get();
  ++    ret = genpd->power_off(genpd);
  ++    if (ret == -EBUSY)
  ++            return ret;
  ++
  ++    elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
  ++    if (elapsed_ns <= genpd->power_off_latency_ns)
  ++            return ret;
  ++
  ++    genpd->power_off_latency_ns = elapsed_ns;
  ++    genpd->max_off_time_changed = true;
  ++    pr_warn("%s: Power-%s latency exceeded, new value %lld ns\n",
  ++            genpd->name, "off", elapsed_ns);
  ++
  ++    return ret;
  ++}
  ++
    /**
     * __pm_genpd_poweron - Restore power to a given PM domain and its masters.
     * @genpd: PM domain to power up.
@@@@@ -276,9 -276,9 -222,25 -222,25 +276,9 @@@@@ static int __pm_genpd_poweron(struct ge
                }
        }
    
  --    if (genpd->power_on) {
  --            ktime_t time_start = ktime_get();
  --            s64 elapsed_ns;
  --
  --            ret = genpd->power_on(genpd);
  --            if (ret)
  --                    goto err;
  --
  --            elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
  --            if (elapsed_ns > genpd->power_on_latency_ns) {
  --                    genpd->power_on_latency_ns = elapsed_ns;
  --                    genpd->max_off_time_changed = true;
  --                    genpd_recalc_cpu_exit_latency(genpd);
  --                    if (genpd->name)
  --                            pr_warning("%s: Power-on latency exceeded, "
  --                                    "new value %lld ns\n", genpd->name,
  --                                    elapsed_ns);
  --            }
  --    }
  ++    ret = genpd_power_on(genpd);
  ++    if (ret)
  ++            goto err;
    
     out:
        genpd_set_active(genpd);
@@@@@ -318,6 -318,8 -280,8 -280,8 +318,6 @@@@@ int pm_genpd_name_poweron(const char *d
        return genpd ? pm_genpd_poweron(genpd) : -EINVAL;
    }
    
 ---#ifdef CONFIG_PM_RUNTIME
 ---
    static int genpd_start_dev_no_timing(struct generic_pm_domain *genpd,
                                     struct device *dev)
    {
@@@@@ -397,19 -399,19 -361,9 -361,19 +397,19 @@@@@ static int __pm_genpd_save_device(struc
        struct device *dev = pdd->dev;
        int ret = 0;
    
  -     if (gpd_data->need_restore)
  +     if (gpd_data->need_restore > 0)
                return 0;
    
  +     /*
  +      * If the value of the need_restore flag is still unknown at this point,
  +      * we trust that pm_genpd_poweroff() has verified that the device is
  +      * already runtime PM suspended.
  +      */
  +     if (gpd_data->need_restore < 0) {
  +             gpd_data->need_restore = 1;
  +             return 0;
  +     }
  + 
        mutex_unlock(&genpd->lock);
    
        genpd_start_dev(genpd, dev);
        mutex_lock(&genpd->lock);
    
        if (!ret)
  -             gpd_data->need_restore = true;
  +             gpd_data->need_restore = 1;
    
        return ret;
    }
@@@@@ -435,17 -437,17 -389,12 -399,17 +435,17 @@@@@ static void __pm_genpd_restore_device(s
    {
        struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd);
        struct device *dev = pdd->dev;
  -     bool need_restore = gpd_data->need_restore;
  +     int need_restore = gpd_data->need_restore;
    
  -     gpd_data->need_restore = false;
  +     gpd_data->need_restore = 0;
        mutex_unlock(&genpd->lock);
    
        genpd_start_dev(genpd, dev);
  + 
  +     /*
  +      * Call genpd_restore_dev() for recently added devices too (need_restore
  +      * is negative then).
  +      */
        if (need_restore)
                genpd_restore_dev(genpd, dev);
    
@@@@@ -580,11 -582,11 -529,16 -544,16 +580,11 @@@@@ static int pm_genpd_poweroff(struct gen
        }
    
        if (genpd->power_off) {
  --            ktime_t time_start;
  --            s64 elapsed_ns;
  --
                if (atomic_read(&genpd->sd_count) > 0) {
                        ret = -EBUSY;
                        goto out;
                }
    
  --            time_start = ktime_get();
  --
                /*
                 * If sd_count > 0 at this point, one of the subdomains hasn't
                 * managed to call pm_genpd_poweron() for the master yet after
                 * the pm_genpd_poweron() restore power for us (this shouldn't
                 * happen very often).
                 */
  --            ret = genpd->power_off(genpd);
  ++            ret = genpd_power_off(genpd);
                if (ret == -EBUSY) {
                        genpd_set_active(genpd);
                        goto out;
                }
  --
  --            elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
  --            if (elapsed_ns > genpd->power_off_latency_ns) {
  --                    genpd->power_off_latency_ns = elapsed_ns;
  --                    genpd->max_off_time_changed = true;
  --                    if (genpd->name)
  --                            pr_warning("%s: Power-off latency exceeded, "
  --                                    "new value %lld ns\n", genpd->name,
  --                                    elapsed_ns);
  --            }
        }
    
        genpd->status = GPD_STATE_POWER_OFF;
@@@@@ -639,7 -641,7 -603,6 -618,7 +639,7 @@@@@ static void genpd_power_off_work_fn(str
    static int pm_genpd_runtime_suspend(struct device *dev)
    {
        struct generic_pm_domain *genpd;
  +     struct generic_pm_domain_data *gpd_data;
        bool (*stop_ok)(struct device *__dev);
        int ret;
    
                return 0;
    
        mutex_lock(&genpd->lock);
  + 
  +     /*
  +      * If we have an unknown state of the need_restore flag, it means none
  +      * of the runtime PM callbacks has been invoked yet. Let's update the
  +      * flag to reflect that the current state is active.
  +      */
  +     gpd_data = to_gpd_data(dev->power.subsys_data->domain_data);
  +     if (gpd_data->need_restore < 0)
  +             gpd_data->need_restore = 0;
  + 
        genpd->in_progress++;
        pm_genpd_poweroff(genpd);
        genpd->in_progress--;
@@@@@ -776,15 -778,33 -729,33 -755,33 +776,15 @@@@@ static int __init genpd_poweroff_unused
    }
    late_initcall(genpd_poweroff_unused);
    
 ---#else
 ---
 ---static inline int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
 ---                                        unsigned long val, void *ptr)
 ---{
 ---    return NOTIFY_DONE;
 ---}
 ---
 ---static inline void
 ---genpd_queue_power_off_work(struct generic_pm_domain *genpd) {}
 ---
 ---static inline void genpd_power_off_work_fn(struct work_struct *work) {}
 ---
 ---#define pm_genpd_runtime_suspend    NULL
 ---#define pm_genpd_runtime_resume             NULL
 ---
 ---#endif /* CONFIG_PM_RUNTIME */
 ---
    #ifdef CONFIG_PM_SLEEP
    
    /**
     * pm_genpd_present - Check if the given PM domain has been initialized.
     * @genpd: PM domain to check.
     */
  --static bool pm_genpd_present(struct generic_pm_domain *genpd)
  ++static bool pm_genpd_present(const struct generic_pm_domain *genpd)
    {
  --    struct generic_pm_domain *gpd;
  ++    const struct generic_pm_domain *gpd;
    
        if (IS_ERR_OR_NULL(genpd))
                return false;
@@@@@ -825,7 -845,7 -796,8 -822,8 +825,7 @@@@@ static void pm_genpd_sync_poweroff(stru
            || atomic_read(&genpd->sd_count) > 0)
                return;
    
  --    if (genpd->power_off)
  --            genpd->power_off(genpd);
  ++    genpd_power_off(genpd);
    
        genpd->status = GPD_STATE_POWER_OFF;
    
@@@@@ -856,7 -876,7 -828,8 -854,8 +856,7 @@@@@ static void pm_genpd_sync_poweron(struc
                genpd_sd_counter_inc(link->master);
        }
    
  --    if (genpd->power_on)
  --            genpd->power_on(genpd);
  ++    genpd_power_on(genpd);
    
        genpd->status = GPD_STATE_ACTIVE;
    }
@@@@@ -1278,7 -1298,7 -1251,8 -1277,8 +1278,7 @@@@@ static int pm_genpd_restore_noirq(struc
                         * If the domain was off before the hibernation, make
                         * sure it will be off going forward.
                         */
  --                    if (genpd->power_off)
  --                            genpd->power_off(genpd);
  ++                    genpd_power_off(genpd);
    
                        return 0;
                }
@@@@@ -1364,7 -1384,7 -1338,7 -1364,7 +1364,7 @@@@@ void pm_genpd_syscore_poweron(struct de
    }
    EXPORT_SYMBOL_GPL(pm_genpd_syscore_poweron);
    
 ---#else
 +++#else /* !CONFIG_PM_SLEEP */
    
    #define pm_genpd_prepare            NULL
    #define pm_genpd_suspend            NULL
@@@@@ -1463,12 -1483,12 -1437,12 -1463,12 +1463,12 @@@@@ int __pm_genpd_add_device(struct generi
        spin_unlock_irq(&dev->power.lock);
    
        if (genpd->attach_dev)
  -             genpd->attach_dev(dev);
  +             genpd->attach_dev(genpd, dev);
    
        mutex_lock(&gpd_data->lock);
        gpd_data->base.dev = dev;
        list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
  -     gpd_data->need_restore = genpd->status == GPD_STATE_POWER_OFF;
  +     gpd_data->need_restore = -1;
        gpd_data->td.constraint_changed = true;
        gpd_data->td.effective_constraint_ns = -1;
        mutex_unlock(&gpd_data->lock);
@@@@@ -1525,7 -1545,7 -1499,7 -1525,7 +1525,7 @@@@@ int pm_genpd_remove_device(struct gener
        genpd->max_off_time_changed = true;
    
        if (genpd->detach_dev)
  -             genpd->detach_dev(dev);
  +             genpd->detach_dev(genpd, dev);
    
        spin_lock_irq(&dev->power.lock);
    
@@@@@ -1572,7 -1592,7 -1546,7 -1572,7 +1572,7 @@@@@ void pm_genpd_dev_need_restore(struct d
    
        psd = dev_to_psd(dev);
        if (psd && psd->domain_data)
  -             to_gpd_data(psd->domain_data)->need_restore = val;
  +             to_gpd_data(psd->domain_data)->need_restore = val ? 1 : 0;
    
        spin_unlock_irqrestore(&dev->power.lock, flags);
    }
@@@@@ -1929,12 -1949,12 -1903,6 -1929,6 +1929,12 @@@@@ void pm_genpd_init(struct generic_pm_do
        genpd->domain.ops.complete = pm_genpd_complete;
        genpd->dev_ops.save_state = pm_genpd_default_save_state;
        genpd->dev_ops.restore_state = pm_genpd_default_restore_state;
  ++
  ++    if (genpd->flags & GENPD_FLAG_PM_CLK) {
  ++            genpd->dev_ops.stop = pm_clk_suspend;
  ++            genpd->dev_ops.start = pm_clk_resume;
  ++    }
  ++
        mutex_lock(&gpd_list_lock);
        list_add(&genpd->gpd_list_node, &gpd_list);
        mutex_unlock(&gpd_list_lock);
@@@@@ -2088,7 -2108,7 -2056,7 -2082,7 +2088,7 @@@@@ EXPORT_SYMBOL_GPL(of_genpd_del_provider
     * Returns a valid pointer to struct generic_pm_domain on success or ERR_PTR()
     * on failure.
     */
- --static struct generic_pm_domain *of_genpd_get_from_provider(
+ ++struct generic_pm_domain *of_genpd_get_from_provider(
                                        struct of_phandle_args *genpdspec)
    {
        struct generic_pm_domain *genpd = ERR_PTR(-ENOENT);
    
        return genpd;
    }
+ ++EXPORT_SYMBOL_GPL(of_genpd_get_from_provider);
    
    /**
     * genpd_dev_pm_detach - Detach a device from its PM domain.
@@@@@ -2222,12 -2243,12 -2190,11 -2216,11 +2223,12 @@@@@ int genpd_dev_pm_attach(struct device *
        }
    
        dev->pm_domain->detach = genpd_dev_pm_detach;
  ++    pm_genpd_poweron(pd);
    
        return 0;
    }
    EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
 ---#endif
 +++#endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
    
    
    /***        debugfs support        ***/
@@@@@ -2243,8 -2264,10 -2210,10 -2236,10 +2244,8 @@@@@ static struct dentry *pm_genpd_debugfs_
    
    /*
     * TODO: This function is a slightly modified version of rtpm_status_show
 --- * from sysfs.c, but dependencies between PM_GENERIC_DOMAINS and PM_RUNTIME
 --- * are too loose to generalize it.
 +++ * from sysfs.c, so generalize it.
     */
 ---#ifdef CONFIG_PM_RUNTIME
    static void rtpm_status_str(struct seq_file *s, struct device *dev)
    {
        static const char * const status_lookup[] = {
    
        seq_puts(s, p);
    }
 ---#else
 ---static void rtpm_status_str(struct seq_file *s, struct device *dev)
 ---{
 ---    seq_puts(s, "active");
 ---}
 ---#endif
    
    static int pm_genpd_summary_one(struct seq_file *s,
                struct generic_pm_domain *gpd)
    #include <linux/notifier.h>
    #include <linux/cpuidle.h>
    
  ++/* Defines used for the flags field in the struct generic_pm_domain */
  ++#define GENPD_FLAG_PM_CLK   (1U << 0) /* PM domain uses PM clk */
  ++
    enum gpd_status {
        GPD_STATE_ACTIVE = 0,   /* PM domain is active */
        GPD_STATE_WAIT_MASTER,  /* PM domain's master is being waited for */
@@@@@ -75,11 -75,11 -72,8 -72,10 +75,11 @@@@@ struct generic_pm_domain 
        bool max_off_time_changed;
        bool cached_power_down_ok;
        struct gpd_cpuidle_data *cpuidle_data;
  -     void (*attach_dev)(struct device *dev);
  -     void (*detach_dev)(struct device *dev);
  +     int (*attach_dev)(struct generic_pm_domain *domain,
  +                       struct device *dev);
  +     void (*detach_dev)(struct generic_pm_domain *domain,
  +                        struct device *dev);
  ++    unsigned int flags;             /* Bit field of configs for genpd */
    };
    
    static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
@@@@@ -104,18 -104,18 -98,13 -100,13 +104,18 @@@@@ struct gpd_timing_data 
        bool cached_stop_ok;
    };
    
  ++struct pm_domain_data {
  ++    struct list_head list_node;
  ++    struct device *dev;
  ++};
  ++
    struct generic_pm_domain_data {
        struct pm_domain_data base;
        struct gpd_timing_data td;
        struct notifier_block nb;
        struct mutex lock;
        unsigned int refcount;
  -     bool need_restore;
  +     int need_restore;
    };
    
    #ifdef CONFIG_PM_GENERIC_DOMAINS
@@@@@ -156,7 -156,6 -145,6 -147,6 +156,7 @@@@@ extern void pm_genpd_init(struct generi
    
    extern int pm_genpd_poweron(struct generic_pm_domain *genpd);
    extern int pm_genpd_name_poweron(const char *domain_name);
 +++extern void pm_genpd_poweroff_unused(void);
    
    extern struct dev_power_governor simple_qos_governor;
    extern struct dev_power_governor pm_domain_always_on_gov;
@@@@@ -231,7 -230,6 -219,6 -221,6 +231,7 @@@@@ static inline int pm_genpd_name_poweron
    {
        return -ENOSYS;
    }
 +++static inline void pm_genpd_poweroff_unused(void) {}
    #define simple_qos_governor NULL
    #define pm_domain_always_on_gov NULL
    #endif
@@@@@ -248,6 -246,12 -235,12 -237,12 +248,6 @@@@@ static inline int pm_genpd_name_add_dev
        return __pm_genpd_name_add_device(domain_name, dev, NULL);
    }
    
 ---#ifdef CONFIG_PM_GENERIC_DOMAINS_RUNTIME
 ---extern void pm_genpd_poweroff_unused(void);
 ---#else
 ---static inline void pm_genpd_poweroff_unused(void) {}
 ---#endif
 ---
    #ifdef CONFIG_PM_GENERIC_DOMAINS_SLEEP
    extern void pm_genpd_syscore_poweroff(struct device *dev);
    extern void pm_genpd_syscore_poweron(struct device *dev);
@@@@@ -271,6 -275,8 -264,6 -266,6 +271,8 @@@@@ typedef struct generic_pm_domain *(*gen
    int __of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
                        void *data);
    void of_genpd_del_provider(struct device_node *np);
+ ++struct generic_pm_domain *of_genpd_get_from_provider(
+ ++                    struct of_phandle_args *genpdspec);
    
    struct generic_pm_domain *__of_genpd_xlate_simple(
                                        struct of_phandle_args *genpdspec,
@@@@@ -288,6 -294,12 -281,6 -283,6 +290,12 @@@@@ static inline int __of_genpd_add_provid
    }
    static inline void of_genpd_del_provider(struct device_node *np) {}
    
+ ++static inline struct generic_pm_domain *of_genpd_get_from_provider(
+ ++                    struct of_phandle_args *genpdspec)
+ ++{
+ ++    return NULL;
+ ++}
+ ++
    #define __of_genpd_xlate_simple             NULL
    #define __of_genpd_xlate_onecell    NULL