Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cd0c5bd3 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'pnp', 'powercap', 'pm-runtime' and 'pm-opp'

* pnp:
  MAINTAINERS: Remove Bjorn Helgaas as PNP maintainer
  PNP / resources: remove positive test on unsigned values

* powercap:
  powercap / RAPL: add new CPU IDs
  powercap / RAPL: further relax energy counter checks

* pm-runtime:
  PM / runtime: Update documentation to reflect the current code flow

* pm-opp:
  PM / OPP: discard duplicate OPPs
  PM / OPP: Make OPP invisible to users in Kconfig
  PM / OPP: fix incorrect OPP count handling in of_init_opp_table
Loading
Loading
Loading
Loading
+11 −9
Original line number Diff line number Diff line
@@ -665,15 +665,17 @@ The PM core does its best to reduce the probability of race conditions between
the runtime PM and system suspend/resume (and hibernation) callbacks by carrying
out the following operations:

  * During system suspend it calls pm_runtime_get_noresume() and
    pm_runtime_barrier() for every device right before executing the
    subsystem-level .suspend() callback for it.  In addition to that it calls
    __pm_runtime_disable() with 'false' as the second argument for every device
    right before executing the subsystem-level .suspend_late() callback for it.

  * During system resume it calls pm_runtime_enable() and pm_runtime_put()
    for every device right after executing the subsystem-level .resume_early()
    callback and right after executing the subsystem-level .resume() callback
  * During system suspend pm_runtime_get_noresume() is called for every device
    right before executing the subsystem-level .prepare() callback for it and
    pm_runtime_barrier() is called for every device right before executing the
    subsystem-level .suspend() callback for it.  In addition to that the PM core
    calls  __pm_runtime_disable() with 'false' as the second argument for every
    device right before executing the subsystem-level .suspend_late() callback
    for it.

  * During system resume pm_runtime_enable() and pm_runtime_put() are called for
    every device right after executing the subsystem-level .resume_early()
    callback and right after executing the subsystem-level .complete() callback
    for it, respectively.

7. Generic subsystem callbacks
+0 −1
Original line number Diff line number Diff line
@@ -6938,7 +6938,6 @@ F: drivers/power/

PNP SUPPORT
M:	Rafael J. Wysocki <rafael.j.wysocki@intel.com>
M:	Bjorn Helgaas <bhelgaas@google.com>
S:	Maintained
F:	drivers/pnp/

+26 −5
Original line number Diff line number Diff line
@@ -394,6 +394,13 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor);
 * to keep the integrity of the internal data structures. Callers should ensure
 * that this function is *NOT* called under RCU protection or in contexts where
 * mutex cannot be locked.
 *
 * Return:
 * 0:		On success OR
 *		Duplicate OPPs (both freq and volt are same) and opp->available
 * -EEXIST:	Freq are same and volt are different OR
 *		Duplicate OPPs (both freq and volt are same) and !opp->available
 * -ENOMEM:	Memory allocation failure
 */
int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
{
@@ -443,15 +450,31 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
	new_opp->u_volt = u_volt;
	new_opp->available = true;

	/* Insert new OPP in order of increasing frequency */
	/*
	 * Insert new OPP in order of increasing frequency
	 * and discard if already present
	 */
	head = &dev_opp->opp_list;
	list_for_each_entry_rcu(opp, &dev_opp->opp_list, node) {
		if (new_opp->rate < opp->rate)
		if (new_opp->rate <= opp->rate)
			break;
		else
			head = &opp->node;
	}

	/* Duplicate OPPs ? */
	if (new_opp->rate == opp->rate) {
		int ret = opp->available && new_opp->u_volt == opp->u_volt ?
			0 : -EEXIST;

		dev_warn(dev, "%s: duplicate OPPs detected. Existing: freq: %lu, volt: %lu, enabled: %d. New: freq: %lu, volt: %lu, enabled: %d\n",
			 __func__, opp->rate, opp->u_volt, opp->available,
			 new_opp->rate, new_opp->u_volt, new_opp->available);
		mutex_unlock(&dev_opp_list_lock);
		kfree(new_opp);
		return ret;
	}

	list_add_rcu(&new_opp->node, head);
	mutex_unlock(&dev_opp_list_lock);

@@ -734,11 +757,9 @@ int of_init_opp_table(struct device *dev)
		unsigned long freq = be32_to_cpup(val++) * 1000;
		unsigned long volt = be32_to_cpup(val++);

		if (dev_pm_opp_add(dev, freq, volt)) {
		if (dev_pm_opp_add(dev, freq, volt))
			dev_warn(dev, "%s: Failed to add OPP %ld\n",
				 __func__, freq);
			continue;
		}
		nr -= 2;
	}

+2 −2
Original line number Diff line number Diff line
@@ -360,7 +360,7 @@ int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
		return 1;

	/* check if the resource is valid */
	if (*irq < 0 || *irq > 15)
	if (*irq > 15)
		return 0;

	/* check if the resource is reserved */
@@ -424,7 +424,7 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
		return 1;

	/* check if the resource is valid */
	if (*dma < 0 || *dma == 4 || *dma > 7)
	if (*dma == 4 || *dma > 7)
		return 0;

	/* check if the resource is reserved */
+12 −21
Original line number Diff line number Diff line
@@ -951,7 +951,9 @@ static const struct x86_cpu_id rapl_ids[] = {
	{ X86_VENDOR_INTEL, 6, 0x2d},/* Sandy Bridge EP */
	{ X86_VENDOR_INTEL, 6, 0x37},/* Valleyview */
	{ X86_VENDOR_INTEL, 6, 0x3a},/* Ivy Bridge */
	{ X86_VENDOR_INTEL, 6, 0x45},/* Haswell */
	{ X86_VENDOR_INTEL, 6, 0x3c},/* Haswell */
	{ X86_VENDOR_INTEL, 6, 0x3d},/* Broadwell */
	{ X86_VENDOR_INTEL, 6, 0x45},/* Haswell ULT */
	/* TODO: Add more CPU IDs after testing */
	{}
};
@@ -1124,8 +1126,7 @@ err_cleanup_package:
static int rapl_check_domain(int cpu, int domain)
{
	unsigned msr;
	u64 val1, val2 = 0;
	int retry = 0;
	u64 val = 0;

	switch (domain) {
	case RAPL_DOMAIN_PACKAGE:
@@ -1144,27 +1145,14 @@ static int rapl_check_domain(int cpu, int domain)
		pr_err("invalid domain id %d\n", domain);
		return -EINVAL;
	}
	if (rdmsrl_safe_on_cpu(cpu, msr, &val1))
	/* make sure domain counters are available and contains non-zero
	 * values, otherwise skip it.
	 */
	if (rdmsrl_safe_on_cpu(cpu, msr, &val) || !val)
		return -ENODEV;

	/* PP1/uncore/graphics domain may not be active at the time of
	 * driver loading. So skip further checks.
	 */
	if (domain == RAPL_DOMAIN_PP1)
		return 0;
	/* energy counters roll slowly on some domains */
	while (++retry < 10) {
		usleep_range(10000, 15000);
		rdmsrl_safe_on_cpu(cpu, msr, &val2);
		if ((val1 & ENERGY_STATUS_MASK) != (val2 & ENERGY_STATUS_MASK))
	return 0;
}
	/* if energy counter does not change, report as bad domain */
	pr_info("domain %s energy ctr %llu:%llu not working, skip\n",
		rapl_domain_names[domain], val1, val2);

	return -ENODEV;
}

/* Detect active and valid domains for the given CPU, caller must
 * ensure the CPU belongs to the targeted package and CPU hotlug is disabled.
@@ -1180,6 +1168,9 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu)
		/* use physical package id to read counters */
		if (!rapl_check_domain(cpu, i))
			rp->domain_map |= 1 << i;
		else
			pr_warn("RAPL domain %s detection failed\n",
				rapl_domain_names[i]);
	}
	rp->nr_domains = bitmap_weight(&rp->domain_map,	RAPL_DOMAIN_MAX);
	if (!rp->nr_domains) {
Loading