static int __init intel_pstate_init()

in intel_pstate.c [3386:3505]


static int __init intel_pstate_init(void)
{
	static struct cpudata **_all_cpu_data;
	const struct x86_cpu_id *id;
	int rc;

	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
		return -ENODEV;

	id = x86_match_cpu(hwp_support_ids);
	if (id) {
		bool hwp_forced = intel_pstate_hwp_is_enabled();

		if (hwp_forced)
			pr_info("HWP enabled by BIOS\n");
		else if (no_load)
			return -ENODEV;

		copy_cpu_funcs(&core_funcs);
		/*
		 * Avoid enabling HWP for processors without EPP support,
		 * because that means incomplete HWP implementation which is a
		 * corner case and supporting it is generally problematic.
		 *
		 * If HWP is enabled already, though, there is no choice but to
		 * deal with it.
		 */
		if ((!no_hwp && boot_cpu_has(X86_FEATURE_HWP_EPP)) || hwp_forced) {
			WRITE_ONCE(hwp_active, 1);
			hwp_mode_bdw = id->driver_data;
			intel_pstate.attr = hwp_cpufreq_attrs;
			intel_cpufreq.attr = hwp_cpufreq_attrs;
			intel_cpufreq.flags |= CPUFREQ_NEED_UPDATE_LIMITS;
			intel_cpufreq.adjust_perf = intel_cpufreq_adjust_perf;
			if (!default_driver)
				default_driver = &intel_pstate;

			if (boot_cpu_has(X86_FEATURE_HYBRID_CPU))
				intel_pstate_cppc_set_cpu_scaling();

			goto hwp_cpu_matched;
		}
		pr_info("HWP not enabled\n");
	} else {
		if (no_load)
			return -ENODEV;

		id = x86_match_cpu(intel_pstate_cpu_ids);
		if (!id) {
			pr_info("CPU model not supported\n");
			return -ENODEV;
		}

		copy_cpu_funcs((struct pstate_funcs *)id->driver_data);
	}

	if (intel_pstate_msrs_not_valid()) {
		pr_info("Invalid MSRs\n");
		return -ENODEV;
	}
	/* Without HWP start in the passive mode. */
	if (!default_driver)
		default_driver = &intel_cpufreq;

hwp_cpu_matched:
	/*
	 * The Intel pstate driver will be ignored if the platform
	 * firmware has its own power management modes.
	 */
	if (intel_pstate_platform_pwr_mgmt_exists()) {
		pr_info("P-states controlled by the platform\n");
		return -ENODEV;
	}

	if (!hwp_active && hwp_only)
		return -ENOTSUPP;

	pr_info("Intel P-state driver initializing\n");

	_all_cpu_data = vzalloc(array_size(sizeof(void *), num_possible_cpus()));
	if (!_all_cpu_data)
		return -ENOMEM;

	WRITE_ONCE(all_cpu_data, _all_cpu_data);

	intel_pstate_request_control_from_smm();

	intel_pstate_sysfs_expose_params();

	if (hwp_active) {
		const struct x86_cpu_id *id = x86_match_cpu(intel_epp_balance_perf);

		if (id)
			epp_values[EPP_INDEX_BALANCE_PERFORMANCE] = id->driver_data;
	}

	mutex_lock(&intel_pstate_driver_lock);
	rc = intel_pstate_register_driver(default_driver);
	mutex_unlock(&intel_pstate_driver_lock);
	if (rc) {
		intel_pstate_sysfs_remove();
		return rc;
	}

	if (hwp_active) {
		const struct x86_cpu_id *id;

		id = x86_match_cpu(intel_pstate_cpu_ee_disable_ids);
		if (id) {
			set_power_ctl_ee_state(false);
			pr_info("Disabling energy efficiency optimization\n");
		}

		pr_info("HWP enabled\n");
	} else if (boot_cpu_has(X86_FEATURE_HYBRID_CPU)) {
		pr_warn("Problematic setup: Hybrid processor with disabled HWP\n");
	}

	return 0;
}