switch (event) {
case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
saved = pr->performance_platform_limit;
- acpi_processor_ppc_has_changed(pr);
+ acpi_processor_ppc_has_changed(pr, 1);
if (saved == pr->performance_platform_limit)
break;
acpi_bus_generate_proc_event(device, event,
struct acpi_processor *pr = per_cpu(processors, cpu);
if (action == CPU_ONLINE && pr) {
- acpi_processor_ppc_has_changed(pr);
+ acpi_processor_ppc_has_changed(pr, 0);
acpi_processor_cst_has_changed(pr);
acpi_processor_tstate_has_changed(pr);
}
.notifier_call = acpi_cpu_soft_notify,
};
-static int acpi_processor_add(struct acpi_device *device)
+static int __cpuinit acpi_processor_add(struct acpi_device *device)
{
struct acpi_processor *pr = NULL;
int result = 0;
arch_acpi_processor_cleanup_pdc(pr);
#ifdef CONFIG_CPU_FREQ
- acpi_processor_ppc_has_changed(pr);
+ acpi_processor_ppc_has_changed(pr, 0);
#endif
acpi_processor_get_throttling_info(pr);
acpi_processor_get_limit_info(pr);
acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX,
- processor_walk_namespace_cb, &action, NULL);
+ processor_walk_namespace_cb, NULL, &action, NULL);
#endif
register_hotcpu_notifier(&acpi_cpu_notifier);
}
acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX,
- processor_walk_namespace_cb, &action, NULL);
+ processor_walk_namespace_cb, NULL, &action, NULL);
#endif
unregister_hotcpu_notifier(&acpi_cpu_notifier);
}
return 0;
}
- int acpi_processor_ppc_has_changed(struct acpi_processor *pr)
+ #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
+ /*
+ * acpi_processor_ppc_ost: Notify firmware the _PPC evaluation status
+ * @handle: ACPI processor handle
+ * @status: the status code of _PPC evaluation
+ * 0: success. OSPM is now using the performance state specificed.
+ * 1: failure. OSPM has not changed the number of P-states in use
+ */
+ static void acpi_processor_ppc_ost(acpi_handle handle, int status)
+ {
+ union acpi_object params[2] = {
+ {.type = ACPI_TYPE_INTEGER,},
+ {.type = ACPI_TYPE_INTEGER,},
+ };
+ struct acpi_object_list arg_list = {2, params};
+ acpi_handle temp;
+
+ params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE;
+ params[1].integer.value = status;
+
+ /* when there is no _OST , skip it */
+ if (ACPI_FAILURE(acpi_get_handle(handle, "_OST", &temp)))
+ return;
+
+ acpi_evaluate_object(handle, "_OST", &arg_list, NULL);
+ return;
+ }
+
+ int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag)
{
int ret;
- if (ignore_ppc)
+ if (ignore_ppc) {
+ /*
+ * Only when it is notification event, the _OST object
+ * will be evaluated. Otherwise it is skipped.
+ */
+ if (event_flag)
+ acpi_processor_ppc_ost(pr->handle, 1);
return 0;
+ }
ret = acpi_processor_get_platform_limit(pr);
-
+ /*
+ * Only when it is notification event, the _OST object
+ * will be evaluated. Otherwise it is skipped.
+ */
+ if (event_flag) {
+ if (ret < 0)
+ acpi_processor_ppc_ost(pr->handle, 1);
+ else
+ acpi_processor_ppc_ost(pr->handle, 0);
+ }
if (ret < 0)
return (ret);
else
return cpufreq_update_policy(pr->id);
}
+int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
+{
+ struct acpi_processor *pr;
+
+ pr = per_cpu(processors, cpu);
+ if (!pr || !pr->performance || !pr->performance->state_count)
+ return -ENODEV;
+ *limit = pr->performance->states[pr->performance_platform_limit].
+ core_frequency * 1000;
+ return 0;
+}
+EXPORT_SYMBOL(acpi_processor_get_bios_limit);
+
void acpi_processor_ppc_init(void)
{
if (!cpufreq_register_notifier
#ifdef CONFIG_CPU_FREQ
void acpi_processor_ppc_init(void);
void acpi_processor_ppc_exit(void);
- int acpi_processor_ppc_has_changed(struct acpi_processor *pr);
+ int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag);
+extern int acpi_processor_get_bios_limit(int cpu, unsigned int *limit);
#else
static inline void acpi_processor_ppc_init(void)
{
{
return;
}
- static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr)
+ static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr,
+ int event_flag)
{
static unsigned int printout = 1;
if (printout) {
}
return 0;
}
+static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
+{
+ return -ENODEV;
+}
+
#endif /* CONFIG_CPU_FREQ */
/* in processor_throttling.c */