int acpi_processor_register_performance(struct acpi_processor_performance *performance, unsigned int cpu) { struct acpi_processor *pr; if (!(acpi_processor_ppc_status & PPC_REGISTERED)) return -EINVAL; mutex_lock(&performance_mutex); pr = per_cpu(processors, cpu); if (!pr) { mutex_unlock(&performance_mutex); return -ENODEV; } if (pr->performance) { mutex_unlock(&performance_mutex); return -EBUSY; } WARN_ON(!performance); pr->performance = performance; if (acpi_processor_get_performance_info(pr)) { pr->performance = NULL; mutex_unlock(&performance_mutex); return -EIO; } mutex_unlock(&performance_mutex); return 0; }
int acpi_processor_register_performance(struct acpi_processor_performance *performance, unsigned int cpu) { struct acpi_processor *pr; ACPI_FUNCTION_TRACE("acpi_processor_register_performance"); if (!(acpi_processor_ppc_status & PPC_REGISTERED)) return_VALUE(-EINVAL); down(&performance_sem); pr = processors[cpu]; if (!pr) { up(&performance_sem); return_VALUE(-ENODEV); } if (pr->performance) { up(&performance_sem); return_VALUE(-EBUSY); } WARN_ON(!performance); pr->performance = performance; if (acpi_processor_get_performance_info(pr)) { pr->performance = NULL; up(&performance_sem); return_VALUE(-EIO); } acpi_cpufreq_add_file(pr); up(&performance_sem); return_VALUE(0); }
/**ltl * 功能: 对cpu的P-state初始化 * 参数: performane ->cpu性能对象 * cpu ->cpu id * 返回值: * 说明: 1.读取_PCT和_PSS两个对象信息 * 2.创建文件/proc/acpi/processor/CPU1/proformance */ int acpi_processor_register_performance(struct acpi_processor_performance *performance, unsigned int cpu) { struct acpi_processor *pr; if (!(acpi_processor_ppc_status & PPC_REGISTERED)) return -EINVAL; mutex_lock(&performance_mutex); /* acpi_process对象 */ pr = processors[cpu]; if (!pr) { mutex_unlock(&performance_mutex); return -ENODEV; } if (pr->performance) { mutex_unlock(&performance_mutex); return -EBUSY; } WARN_ON(!performance); pr->performance = performance; /* 设置cpu性能 */ /* 读取_PCT、_PSS两个对象信息 */ if (acpi_processor_get_performance_info(pr)) { pr->performance = NULL; mutex_unlock(&performance_mutex); return -EIO; } /* 创建文件/proc/acpi/processor/CPU1/proformance */ acpi_cpufreq_add_file(pr); mutex_unlock(&performance_mutex); return 0; }
/* * Existing ACPI module does parse performance states at some point, * when acpi-cpufreq driver is loaded which however is something * we'd like to disable to avoid confliction with external control * logic. So we have to collect raw performance information here * when ACPI processor object is found and started. */ static int processor_extcntl_get_performance(struct acpi_processor *pr) { int ret; struct acpi_processor_performance *perf; struct acpi_psd_package *pdomain; if (pr->performance) return -EBUSY; perf = kzalloc(sizeof(struct acpi_processor_performance), GFP_KERNEL); if (!perf) return -ENOMEM; pr->performance = perf; /* Get basic performance state information */ ret = acpi_processor_get_performance_info(pr); if (ret < 0) goto err_out; /* * Well, here we need retrieve performance dependency information * from _PSD object. The reason why existing interface is not used * is due to the reason that existing interface sticks to Linux cpu * id to construct some bitmap, however we want to split ACPI * processor objects from Linux cpu id logic. For example, even * when Linux is configured as UP, we still want to parse all ACPI * processor objects to external logic. In this case, it's preferred * to use ACPI ID instead. */ pdomain = &pr->performance->domain_info; pdomain->num_processors = 0; ret = acpi_processor_get_psd(pr); if (ret < 0) { /* * _PSD is optional - assume no coordination if absent (or * broken), matching native kernels' behavior. */ pdomain->num_entries = ACPI_PSD_REV0_ENTRIES; pdomain->revision = ACPI_PSD_REV0_REVISION; pdomain->domain = pr->acpi_id; pdomain->coord_type = DOMAIN_COORD_TYPE_SW_ALL; pdomain->num_processors = 1; } /* Some sanity check */ if ((pdomain->revision != ACPI_PSD_REV0_REVISION) || (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) || ((pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL) && (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY) && (pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL))) { ret = -EINVAL; goto err_out; } /* Last step is to notify BIOS that external logic exists */ processor_notify_smm(); processor_notify_external(pr, PROCESSOR_PM_INIT, PM_TYPE_PERF); return 0; err_out: pr->performance = NULL; kfree(perf); return ret; }