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

Commit ee13cbde authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq:
  [CPUFREQ] powernow-k8: Limit Pstate transition latency check
  [CPUFREQ] Fix PCC driver error path
  [CPUFREQ] fix double freeing in error path of pcc-cpufreq
  [CPUFREQ] pcc driver should check for pcch method before calling _OSC
  [CPUFREQ] fix memory leak in cpufreq_add_dev
  [CPUFREQ] revert "[CPUFREQ] remove rwsem lock from CPUFREQ_GOV_STOP call (second call site)"
parents 863da955 3581ced3
Loading
Loading
Loading
Loading
+20 −21
Original line number Diff line number Diff line
@@ -368,22 +368,16 @@ static int __init pcc_cpufreq_do_osc(acpi_handle *handle)
		return -ENODEV;

	out_obj = output.pointer;
	if (out_obj->type != ACPI_TYPE_BUFFER) {
		ret = -ENODEV;
		goto out_free;
	}
	if (out_obj->type != ACPI_TYPE_BUFFER)
		return -ENODEV;

	errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
	if (errors) {
		ret = -ENODEV;
		goto out_free;
	}
	if (errors)
		return -ENODEV;

	supported = *((u32 *)(out_obj->buffer.pointer + 4));
	if (!(supported & 0x1)) {
		ret = -ENODEV;
		goto out_free;
	}
	if (!(supported & 0x1))
		return -ENODEV;

out_free:
	kfree(output.pointer);
@@ -397,13 +391,17 @@ static int __init pcc_cpufreq_probe(void)
	struct pcc_memory_resource *mem_resource;
	struct pcc_register_resource *reg_resource;
	union acpi_object *out_obj, *member;
	acpi_handle handle, osc_handle;
	acpi_handle handle, osc_handle, pcch_handle;
	int ret = 0;

	status = acpi_get_handle(NULL, "\\_SB", &handle);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	status = acpi_get_handle(handle, "PCCH", &pcch_handle);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	status = acpi_get_handle(handle, "_OSC", &osc_handle);
	if (ACPI_SUCCESS(status)) {
		ret = pcc_cpufreq_do_osc(&osc_handle);
@@ -543,13 +541,13 @@ static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy)

	if (!pcch_virt_addr) {
		result = -1;
		goto pcch_null;
		goto out;
	}

	result = pcc_get_offset(cpu);
	if (result) {
		dprintk("init: PCCP evaluation failed\n");
		goto free;
		goto out;
	}

	policy->max = policy->cpuinfo.max_freq =
@@ -558,14 +556,15 @@ static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy)
		ioread32(&pcch_hdr->minimum_frequency) * 1000;
	policy->cur = pcc_get_freq(cpu);

	if (!policy->cur) {
		dprintk("init: Unable to get current CPU frequency\n");
		result = -EINVAL;
		goto out;
	}

	dprintk("init: policy->max is %d, policy->min is %d\n",
		policy->max, policy->min);

	return 0;
free:
	pcc_clear_mapping();
	free_percpu(pcc_cpu_info);
pcch_null:
out:
	return result;
}

+5 −6
Original line number Diff line number Diff line
@@ -1023,13 +1023,12 @@ static int get_transition_latency(struct powernow_k8_data *data)
	}
	if (max_latency == 0) {
		/*
		 * Fam 11h always returns 0 as transition latency.
		 * This is intended and means "very fast". While cpufreq core
		 * and governors currently can handle that gracefully, better
		 * set it to 1 to avoid problems in the future.
		 * For all others it's a BIOS bug.
		 * Fam 11h and later may return 0 as transition latency. This
		 * is intended and means "very fast". While cpufreq core and
		 * governors currently can handle that gracefully, better set it
		 * to 1 to avoid problems in the future.
		 */
		if (boot_cpu_data.x86 != 0x11)
		if (boot_cpu_data.x86 < 0x11)
			printk(KERN_ERR FW_WARN PFX "Invalid zero transition "
				"latency\n");
		max_latency = 1;
+2 −10
Original line number Diff line number Diff line
@@ -1077,6 +1077,7 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)

err_unlock_policy:
	unlock_policy_rwsem_write(cpu);
	free_cpumask_var(policy->related_cpus);
err_free_cpumask:
	free_cpumask_var(policy->cpus);
err_free_policy:
@@ -1762,17 +1763,8 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
			dprintk("governor switch\n");

			/* end old governor */
			if (data->governor) {
				/*
				 * Need to release the rwsem around governor
				 * stop due to lock dependency between
				 * cancel_delayed_work_sync and the read lock
				 * taken in the delayed work handler.
				 */
				unlock_policy_rwsem_write(data->cpu);
			if (data->governor)
				__cpufreq_governor(data, CPUFREQ_GOV_STOP);
				lock_policy_rwsem_write(data->cpu);
			}

			/* start new governor */
			data->governor = policy->governor;