-static int acpi_processor_get_psd(struct acpi_processor *pr)
-{
- int result = 0;
- acpi_status status = AE_OK;
- struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
- struct acpi_buffer format = {sizeof("NNNNN"), "NNNNN"};
- struct acpi_buffer state = {0, NULL};
- union acpi_object *psd = NULL;
- struct acpi_psd_package *pdomain;
-
- status = acpi_evaluate_object(pr->handle, "_PSD", NULL, &buffer);
- if (ACPI_FAILURE(status)) {
- return -ENODEV;
- }
-
- psd = (union acpi_object *) buffer.pointer;
- if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
- result = -EFAULT;
- goto end;
- }
-
- if (psd->package.count != 1) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
- result = -EFAULT;
- goto end;
- }
-
- pdomain = &(pr->performance->domain_info);
-
- state.length = sizeof(struct acpi_psd_package);
- state.pointer = pdomain;
-
- status = acpi_extract_package(&(psd->package.elements[0]),
- &format, &state);
- if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
- result = -EFAULT;
- goto end;
- }
-
- if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:num_entries\n"));
- result = -EFAULT;
- goto end;
- }
-
- if (pdomain->revision != ACPI_PSD_REV0_REVISION) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:revision\n"));
- result = -EFAULT;
- goto end;
- }
-
-end:
- kfree(buffer.pointer);
- return result;
-}
-
-int acpi_processor_preregister_performance(
- struct acpi_processor_performance **performance)
-{
- int count, count_target;
- int retval = 0;
- unsigned int i, j;
- cpumask_t covered_cpus;
- struct acpi_processor *pr;
- struct acpi_psd_package *pdomain;
- struct acpi_processor *match_pr;
- struct acpi_psd_package *match_pdomain;
-
- mutex_lock(&performance_mutex);
-
- retval = 0;
-
- /* Call _PSD for all CPUs */
- for_each_possible_cpu(i) {
- pr = processors[i];
- if (!pr) {
- /* Look only at processors in ACPI namespace */
- continue;
- }
-
- if (pr->performance) {
- retval = -EBUSY;
- continue;
- }
-
- if (!performance || !performance[i]) {
- retval = -EINVAL;
- continue;
- }
-
- pr->performance = performance[i];
- cpu_set(i, pr->performance->shared_cpu_map);
- if (acpi_processor_get_psd(pr)) {
- retval = -EINVAL;
- continue;
- }
- }
- if (retval)
- goto err_ret;
-
- /*
- * Now that we have _PSD data from all CPUs, lets setup P-state
- * domain info.
- */
- for_each_possible_cpu(i) {
- pr = processors[i];
- if (!pr)
- continue;
-
- /* Basic validity check for domain info */
- pdomain = &(pr->performance->domain_info);
- if ((pdomain->revision != ACPI_PSD_REV0_REVISION) ||
- (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES)) {
- retval = -EINVAL;
- goto err_ret;
- }
- if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
- pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
- pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
- retval = -EINVAL;
- goto err_ret;
- }
- }
-
- cpus_clear(covered_cpus);
- for_each_possible_cpu(i) {
- pr = processors[i];
- if (!pr)
- continue;
-
- if (cpu_isset(i, covered_cpus))
- continue;
-
- pdomain = &(pr->performance->domain_info);
- cpu_set(i, pr->performance->shared_cpu_map);
- cpu_set(i, covered_cpus);
- if (pdomain->num_processors <= 1)
- continue;
-
- /* Validate the Domain info */
- count_target = pdomain->num_processors;
- count = 1;
- if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL)
- pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ALL;
- else if (pdomain->coord_type == DOMAIN_COORD_TYPE_HW_ALL)
- pr->performance->shared_type = CPUFREQ_SHARED_TYPE_HW;
- else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
- pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ANY;
-
- for_each_possible_cpu(j) {
- if (i == j)
- continue;
-
- match_pr = processors[j];
- if (!match_pr)
- continue;
-
- match_pdomain = &(match_pr->performance->domain_info);
- if (match_pdomain->domain != pdomain->domain)
- continue;
-
- /* Here i and j are in the same domain */
-
- if (match_pdomain->num_processors != count_target) {
- retval = -EINVAL;
- goto err_ret;
- }
-
- if (pdomain->coord_type != match_pdomain->coord_type) {
- retval = -EINVAL;
- goto err_ret;
- }
-
- cpu_set(j, covered_cpus);
- cpu_set(j, pr->performance->shared_cpu_map);
- count++;
- }
-
- for_each_possible_cpu(j) {
- if (i == j)
- continue;
-
- match_pr = processors[j];
- if (!match_pr)
- continue;
-
- match_pdomain = &(match_pr->performance->domain_info);
- if (match_pdomain->domain != pdomain->domain)
- continue;
-
- match_pr->performance->shared_type =
- pr->performance->shared_type;
- match_pr->performance->shared_cpu_map =
- pr->performance->shared_cpu_map;
- }
- }
-
-err_ret:
- if (retval) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error while parsing _PSD domain information. Assuming no coordination\n"));
- }
-
- for_each_possible_cpu(i) {
- pr = processors[i];
- if (!pr || !pr->performance)
- continue;
-
- /* Assume no coordination on any error parsing domain info */
- if (retval) {
- cpus_clear(pr->performance->shared_cpu_map);
- cpu_set(i, pr->performance->shared_cpu_map);
- pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ALL;
- }
- pr->performance = NULL; /* Will be set for real in register */
- }
-
- mutex_unlock(&performance_mutex);
- return retval;
-}
-EXPORT_SYMBOL(acpi_processor_preregister_performance);
-
-