Merge branches 'powercap', 'pm-cpufreq' and 'pm-domains'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 14 Dec 2015 21:58:57 +0000 (22:58 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 14 Dec 2015 21:58:57 +0000 (22:58 +0100)
* powercap:
  powercap / RAPL: fix BIOS lock check

* pm-cpufreq:
  cpufreq: intel_pstate: Minor cleanup for FRAC_BITS
  cpufreq: tegra: add regulator dependency for T124

* pm-domains:
  PM / Domains: Allow runtime PM callbacks to be re-used during system PM

1  2  3  4 
drivers/base/power/domain.c

index 167418e73445a4f69b372f9205f65ca43f525c9d,16550c63d611ad8e484ccdec663ca1cc7142e144,167418e73445a4f69b372f9205f65ca43f525c9d,8ad59f3e6f8049e2362e52fc928c393cfa386ce6..65f50eccd49b0aa4b6801912fd8d21a73f79a7b9
@@@@@ -389,9 -482,6 -389,9 -389,10 +389,10 @@@@@ static int pm_genpd_runtime_suspend(str
    {
        struct generic_pm_domain *genpd;
        bool (*stop_ok)(struct device *__dev);
 +      struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
+++     bool runtime_pm = pm_runtime_enabled(dev);
 +      ktime_t time_start;
 +      s64 elapsed_ns;
        int ret;
    
        dev_dbg(dev, "%s()\n", __func__);
        if (IS_ERR(genpd))
                return -EINVAL;
    
+++     /*
+++      * A runtime PM centric subsystem/driver may re-use the runtime PM
+++      * callbacks for other purposes than runtime PM. In those scenarios
+++      * runtime PM is disabled. Under these circumstances, we shall skip
+++      * validating/measuring the PM QoS latency.
+++      */
        stop_ok = genpd->gov ? genpd->gov->stop_ok : NULL;
---     if (stop_ok && !stop_ok(dev))
+++     if (runtime_pm && stop_ok && !stop_ok(dev))
                return -EBUSY;
    
- -     time_start = ktime_get();
 +      /* Measure suspend latency. */
+++     if (runtime_pm)
+++             time_start = ktime_get();
 +  
        ret = genpd_save_dev(genpd, dev);
        if (ret)
                return ret;
                return ret;
        }
    
- -     elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
- -     if (elapsed_ns > td->suspend_latency_ns) {
- -             td->suspend_latency_ns = elapsed_ns;
- -             dev_dbg(dev, "suspend latency exceeded, %lld ns\n",
- -                     elapsed_ns);
- -             genpd->max_off_time_changed = true;
- -             td->constraint_changed = true;
 +      /* Update suspend latency value if the measured time exceeds it. */
+++     if (runtime_pm) {
+++             elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
+++             if (elapsed_ns > td->suspend_latency_ns) {
+++                     td->suspend_latency_ns = elapsed_ns;
+++                     dev_dbg(dev, "suspend latency exceeded, %lld ns\n",
+++                             elapsed_ns);
+++                     genpd->max_off_time_changed = true;
+++                     td->constraint_changed = true;
+++             }
 +      }
 +  
        /*
         * If power.irq_safe is set, this routine will be run with interrupts
         * off, so it can't use mutexes.
    static int pm_genpd_runtime_resume(struct device *dev)
    {
        struct generic_pm_domain *genpd;
 +      struct gpd_timing_data *td = &dev_gpd_data(dev)->td;
+++     bool runtime_pm = pm_runtime_enabled(dev);
 +      ktime_t time_start;
 +      s64 elapsed_ns;
        int ret;
        bool timed = true;
    
                return ret;
    
     out:
 -      genpd_start_dev(genpd, dev, timed);
 -      genpd_restore_dev(genpd, dev, timed);
 +      /* Measure resume latency. */
- -     if (timed)
+++     if (timed && runtime_pm)
 +              time_start = ktime_get();
 +  
 +      genpd_start_dev(genpd, dev);
 +      genpd_restore_dev(genpd, dev);
 +  
 +      /* Update resume latency value if the measured time exceeds it. */
- -     if (timed) {
+++     if (timed && runtime_pm) {
 +              elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start));
 +              if (elapsed_ns > td->resume_latency_ns) {
 +                      td->resume_latency_ns = elapsed_ns;
 +                      dev_dbg(dev, "resume latency exceeded, %lld ns\n",
 +                              elapsed_ns);
 +                      genpd->max_off_time_changed = true;
 +                      td->constraint_changed = true;
 +              }
 +      }
    
        return 0;
    }
@@@@@ -1348,11 -1424,38 -1348,11 -1359,10 +1359,11 @@@@@ int pm_genpd_add_subdomain(struct gener
     out:
        mutex_unlock(&subdomain->lock);
        mutex_unlock(&genpd->lock);
 -  
 +      if (ret)
 +              kfree(link);
        return ret;
    }
 -  
 -  /**
 -   * pm_genpd_add_subdomain_names - Add a subdomain to an I/O PM domain.
 -   * @master_name: Name of the master PM domain to add the subdomain to.
 -   * @subdomain_name: Name of the subdomain to be added.
 -   */
 -  int pm_genpd_add_subdomain_names(const char *master_name,
 -                               const char *subdomain_name)
 -  {
 -      struct generic_pm_domain *master = NULL, *subdomain = NULL, *gpd;
 -  
 -      if (IS_ERR_OR_NULL(master_name) || IS_ERR_OR_NULL(subdomain_name))
 -              return -EINVAL;
 -  
 -      mutex_lock(&gpd_list_lock);
 -      list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
 -              if (!master && !strcmp(gpd->name, master_name))
 -                      master = gpd;
 -  
 -              if (!subdomain && !strcmp(gpd->name, subdomain_name))
 -                      subdomain = gpd;
 -  
 -              if (master && subdomain)
 -                      break;
 -      }
 -      mutex_unlock(&gpd_list_lock);
 -  
 -      return pm_genpd_add_subdomain(master, subdomain);
 -  }
 + +EXPORT_SYMBOL_GPL(pm_genpd_add_subdomain);
    
    /**
     * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
    
        return ret;
    }
 -  
 -  /**
 -   * pm_genpd_attach_cpuidle - Connect the given PM domain with cpuidle.
 -   * @genpd: PM domain to be connected with cpuidle.
 -   * @state: cpuidle state this domain can disable/enable.
 -   *
 -   * Make a PM domain behave as though it contained a CPU core, that is, instead
 -   * of calling its power down routine it will enable the given cpuidle state so
 -   * that the cpuidle subsystem can power it down (if possible and desirable).
 -   */
 -  int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
 -  {
 -      struct cpuidle_driver *cpuidle_drv;
 -      struct gpd_cpuidle_data *cpuidle_data;
 -      struct cpuidle_state *idle_state;
 -      int ret = 0;
 -  
 -      if (IS_ERR_OR_NULL(genpd) || state < 0)
 -              return -EINVAL;
 -  
 -      mutex_lock(&genpd->lock);
 -  
 -      if (genpd->cpuidle_data) {
 -              ret = -EEXIST;
 -              goto out;
 -      }
 -      cpuidle_data = kzalloc(sizeof(*cpuidle_data), GFP_KERNEL);
 -      if (!cpuidle_data) {
 -              ret = -ENOMEM;
 -              goto out;
 -      }
 -      cpuidle_drv = cpuidle_driver_ref();
 -      if (!cpuidle_drv) {
 -              ret = -ENODEV;
 -              goto err_drv;
 -      }
 -      if (cpuidle_drv->state_count <= state) {
 -              ret = -EINVAL;
 -              goto err;
 -      }
 -      idle_state = &cpuidle_drv->states[state];
 -      if (!idle_state->disabled) {
 -              ret = -EAGAIN;
 -              goto err;
 -      }
 -      cpuidle_data->idle_state = idle_state;
 -      cpuidle_data->saved_exit_latency = idle_state->exit_latency;
 -      genpd->cpuidle_data = cpuidle_data;
 -      genpd_recalc_cpu_exit_latency(genpd);
 -  
 -   out:
 -      mutex_unlock(&genpd->lock);
 -      return ret;
 -  
 -   err:
 -      cpuidle_driver_unref();
 -  
 -   err_drv:
 -      kfree(cpuidle_data);
 -      goto out;
 -  }
 -  
 -  /**
 -   * pm_genpd_name_attach_cpuidle - Find PM domain and connect cpuidle to it.
 -   * @name: Name of the domain to connect to cpuidle.
 -   * @state: cpuidle state this domain can manipulate.
 -   */
 -  int pm_genpd_name_attach_cpuidle(const char *name, int state)
 -  {
 -      return pm_genpd_attach_cpuidle(pm_genpd_lookup_name(name), state);
 -  }
 -  
 -  /**
 -   * pm_genpd_detach_cpuidle - Remove the cpuidle connection from a PM domain.
 -   * @genpd: PM domain to remove the cpuidle connection from.
 -   *
 -   * Remove the cpuidle connection set up by pm_genpd_attach_cpuidle() from the
 -   * given PM domain.
 -   */
 -  int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd)
 -  {
 -      struct gpd_cpuidle_data *cpuidle_data;
 -      struct cpuidle_state *idle_state;
 -      int ret = 0;
 -  
 -      if (IS_ERR_OR_NULL(genpd))
 -              return -EINVAL;
 -  
 -      mutex_lock(&genpd->lock);
 -  
 -      cpuidle_data = genpd->cpuidle_data;
 -      if (!cpuidle_data) {
 -              ret = -ENODEV;
 -              goto out;
 -      }
 -      idle_state = cpuidle_data->idle_state;
 -      if (!idle_state->disabled) {
 -              ret = -EAGAIN;
 -              goto out;
 -      }
 -      idle_state->exit_latency = cpuidle_data->saved_exit_latency;
 -      cpuidle_driver_unref();
 -      genpd->cpuidle_data = NULL;
 -      kfree(cpuidle_data);
 -  
 -   out:
 -      mutex_unlock(&genpd->lock);
 -      return ret;
 -  }
 -  
 -  /**
 -   * pm_genpd_name_detach_cpuidle - Find PM domain and disconnect cpuidle from it.
 -   * @name: Name of the domain to disconnect cpuidle from.
 -   */
 -  int pm_genpd_name_detach_cpuidle(const char *name)
 -  {
 -      return pm_genpd_detach_cpuidle(pm_genpd_lookup_name(name));
 -  }
 + +EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain);
    
    /* Default device callbacks for generic PM domains. */