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

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

Merge branches 'pm-cpufreq' and 'pm-sleep' containing PM fixes

* pm-cpufreq:
  cpufreq: Use CONFIG_CPU_FREQ_DEFAULT_* to set initial policy for setpolicy drivers
  cpufreq: remove sysfs files for CPUs which failed to come back after resume

* pm-sleep:
  PM / sleep: Fix memory leak in pm_vt_switch_unregister().
Loading
Loading
Loading
Loading
+37 −32
Original line number Diff line number Diff line
@@ -828,6 +828,12 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy)
	int ret = 0;

	memcpy(&new_policy, policy, sizeof(*policy));

	/* Use the default policy if its valid. */
	if (cpufreq_driver->setpolicy)
		cpufreq_parse_governor(policy->governor->name,
					&new_policy.policy, NULL);

	/* assure that the starting sequence is run in cpufreq_set_policy */
	policy->governor = NULL;

@@ -845,8 +851,7 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy)

#ifdef CONFIG_HOTPLUG_CPU
static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
				  unsigned int cpu, struct device *dev,
				  bool frozen)
				  unsigned int cpu, struct device *dev)
{
	int ret = 0;
	unsigned long flags;
@@ -877,11 +882,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
		}
	}

	/* Don't touch sysfs links during light-weight init */
	if (!frozen)
		ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");

	return ret;
	return sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
}
#endif

@@ -926,6 +927,27 @@ static struct cpufreq_policy *cpufreq_policy_alloc(void)
	return NULL;
}

static void cpufreq_policy_put_kobj(struct cpufreq_policy *policy)
{
	struct kobject *kobj;
	struct completion *cmp;

	down_read(&policy->rwsem);
	kobj = &policy->kobj;
	cmp = &policy->kobj_unregister;
	up_read(&policy->rwsem);
	kobject_put(kobj);

	/*
	 * We need to make sure that the underlying kobj is
	 * actually not referenced anymore by anybody before we
	 * proceed with unloading.
	 */
	pr_debug("waiting for dropping of refcount\n");
	wait_for_completion(cmp);
	pr_debug("wait complete\n");
}

static void cpufreq_policy_free(struct cpufreq_policy *policy)
{
	free_cpumask_var(policy->related_cpus);
@@ -986,7 +1008,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
	list_for_each_entry(tpolicy, &cpufreq_policy_list, policy_list) {
		if (cpumask_test_cpu(cpu, tpolicy->related_cpus)) {
			read_unlock_irqrestore(&cpufreq_driver_lock, flags);
			ret = cpufreq_add_policy_cpu(tpolicy, cpu, dev, frozen);
			ret = cpufreq_add_policy_cpu(tpolicy, cpu, dev);
			up_read(&cpufreq_rwsem);
			return ret;
		}
@@ -1096,7 +1118,10 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
	if (cpufreq_driver->exit)
		cpufreq_driver->exit(policy);
err_set_policy_cpu:
	if (frozen)
		cpufreq_policy_put_kobj(policy);
	cpufreq_policy_free(policy);

nomem_out:
	up_read(&cpufreq_rwsem);

@@ -1118,7 +1143,7 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
}

static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
					   unsigned int old_cpu, bool frozen)
					   unsigned int old_cpu)
{
	struct device *cpu_dev;
	int ret;
@@ -1126,10 +1151,6 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
	/* first sibling now owns the new sysfs dir */
	cpu_dev = get_cpu_device(cpumask_any_but(policy->cpus, old_cpu));

	/* Don't touch sysfs files during light-weight tear-down */
	if (frozen)
		return cpu_dev->id;

	sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
	ret = kobject_move(&policy->kobj, &cpu_dev->kobj);
	if (ret) {
@@ -1196,7 +1217,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,
		if (!frozen)
			sysfs_remove_link(&dev->kobj, "cpufreq");
	} else if (cpus > 1) {
		new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu, frozen);
		new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu);
		if (new_cpu >= 0) {
			update_policy_cpu(policy, new_cpu);

@@ -1218,8 +1239,6 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
	int ret;
	unsigned long flags;
	struct cpufreq_policy *policy;
	struct kobject *kobj;
	struct completion *cmp;

	read_lock_irqsave(&cpufreq_driver_lock, flags);
	policy = per_cpu(cpufreq_cpu_data, cpu);
@@ -1249,22 +1268,8 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
			}
		}

		if (!frozen) {
			down_read(&policy->rwsem);
			kobj = &policy->kobj;
			cmp = &policy->kobj_unregister;
			up_read(&policy->rwsem);
			kobject_put(kobj);

			/*
			 * We need to make sure that the underlying kobj is
			 * actually not referenced anymore by anybody before we
			 * proceed with unloading.
			 */
			pr_debug("waiting for dropping of refcount\n");
			wait_for_completion(cmp);
			pr_debug("wait complete\n");
		}
		if (!frozen)
			cpufreq_policy_put_kobj(policy);

		/*
		 * Perform the ->exit() even during light-weight tear-down,
+1 −0
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ void pm_vt_switch_unregister(struct device *dev)
	list_for_each_entry(tmp, &pm_vt_switch_list, head) {
		if (tmp->dev == dev) {
			list_del(&tmp->head);
			kfree(tmp);
			break;
		}
	}