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

Commit 64f3bf2f authored by Sebastian Andrzej Siewior's avatar Sebastian Andrzej Siewior Committed by Thomas Gleixner
Browse files

ACPI/processor: Convert to hotplug state machine



Install the callbacks via the state machine.

Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Acked-by: default avatar"Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: linux-acpi@vger.kernel.org
Cc: rt@linutronix.de
Cc: Len Brown <lenb@kernel.org>
Link: http://lkml.kernel.org/r/20160906170457.32393-12-bigeasy@linutronix.de


Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 8904f5a5
Loading
Loading
Loading
Loading
+47 −44
Original line number Diff line number Diff line
@@ -110,26 +110,13 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)

static int __acpi_processor_start(struct acpi_device *device);

static int acpi_cpu_soft_notify(struct notifier_block *nfb,
					  unsigned long action, void *hcpu)
static int acpi_soft_cpu_online(unsigned int cpu)
{
	unsigned int cpu = (unsigned long)hcpu;
	struct acpi_processor *pr = per_cpu(processors, cpu);
	struct acpi_device *device;
	action &= ~CPU_TASKS_FROZEN;

	switch (action) {
	case CPU_ONLINE:
	case CPU_DEAD:
		break;
	default:
		return NOTIFY_DONE;
	}

	if (!pr || acpi_bus_get_device(pr->handle, &device))
		return NOTIFY_DONE;

	if (action == CPU_ONLINE) {
		return 0;
	/*
	 * CPU got physically hotplugged and onlined for the first time:
	 * Initialize missing things.
@@ -146,19 +133,23 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
		/* Normal CPU soft online event. */
		acpi_processor_ppc_has_changed(pr, 0);
		acpi_processor_hotplug(pr);
			acpi_processor_reevaluate_tstate(pr, action);
		acpi_processor_reevaluate_tstate(pr, false);
		acpi_processor_tstate_has_changed(pr);
	}
	} else if (action == CPU_DEAD) {
		/* Invalidate flag.throttling after the CPU is offline. */
		acpi_processor_reevaluate_tstate(pr, action);
	}
	return NOTIFY_OK;
	return 0;
}

static struct notifier_block acpi_cpu_notifier = {
	    .notifier_call = acpi_cpu_soft_notify,
};
static int acpi_soft_cpu_dead(unsigned int cpu)
{
	struct acpi_processor *pr = per_cpu(processors, cpu);
	struct acpi_device *device;

	if (!pr || acpi_bus_get_device(pr->handle, &device))
		return 0;

	acpi_processor_reevaluate_tstate(pr, true);
	return 0;
}

#ifdef CONFIG_ACPI_CPU_FREQ_PSS
static int acpi_pss_perf_init(struct acpi_processor *pr,
@@ -303,7 +294,7 @@ static int acpi_processor_stop(struct device *dev)
 * This is needed for the powernow-k8 driver, that works even without
 * ACPI, but needs symbols from this driver
 */

static enum cpuhp_state hp_online;
static int __init acpi_processor_driver_init(void)
{
	int result = 0;
@@ -315,11 +306,22 @@ static int __init acpi_processor_driver_init(void)
	if (result < 0)
		return result;

	register_hotcpu_notifier(&acpi_cpu_notifier);
	result = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
					   "acpi/cpu-drv:online",
					   acpi_soft_cpu_online, NULL);
	if (result < 0)
		goto err;
	hp_online = result;
	cpuhp_setup_state_nocalls(CPUHP_ACPI_CPUDRV_DEAD, "acpi/cpu-drv:dead",
				  NULL, acpi_soft_cpu_dead);

	acpi_thermal_cpufreq_init();
	acpi_processor_ppc_init();
	acpi_processor_throttling_init();
	return 0;
err:
	driver_unregister(&acpi_processor_driver);
	return result;
}

static void __exit acpi_processor_driver_exit(void)
@@ -329,7 +331,8 @@ static void __exit acpi_processor_driver_exit(void)

	acpi_processor_ppc_exit();
	acpi_thermal_cpufreq_exit();
	unregister_hotcpu_notifier(&acpi_cpu_notifier);
	cpuhp_remove_state_nocalls(hp_online);
	cpuhp_remove_state_nocalls(CPUHP_ACPI_CPUDRV_DEAD);
	driver_unregister(&acpi_processor_driver);
}

+2 −2
Original line number Diff line number Diff line
@@ -375,11 +375,11 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
 *	3. TSD domain
 */
void acpi_processor_reevaluate_tstate(struct acpi_processor *pr,
					unsigned long action)
					bool is_dead)
{
	int result = 0;

	if (action == CPU_DEAD) {
	if (is_dead) {
		/* When one CPU is offline, the T-state throttling
		 * will be invalidated.
		 */
+2 −2
Original line number Diff line number Diff line
@@ -359,7 +359,7 @@ extern int acpi_processor_set_throttling(struct acpi_processor *pr,
 * onlined/offlined. In such case the flags.throttling will be updated.
 */
extern void acpi_processor_reevaluate_tstate(struct acpi_processor *pr,
			unsigned long action);
			bool is_dead);
extern const struct file_operations acpi_processor_throttling_fops;
extern void acpi_processor_throttling_init(void);
#else
@@ -380,7 +380,7 @@ static inline int acpi_processor_set_throttling(struct acpi_processor *pr,
}

static inline void acpi_processor_reevaluate_tstate(struct acpi_processor *pr,
			unsigned long action) {}
			bool is_dead) {}

static inline void acpi_processor_throttling_init(void) {}
#endif	/* CONFIG_ACPI_CPU_FREQ_PSS */
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ enum cpuhp_state {
	CPUHP_IRQ_POLL_DEAD,
	CPUHP_BLOCK_SOFTIRQ_DEAD,
	CPUHP_VIRT_SCSI_DEAD,
	CPUHP_ACPI_CPUDRV_DEAD,
	CPUHP_WORKQUEUE_PREP,
	CPUHP_POWER_NUMA_PREPARE,
	CPUHP_HRTIMERS_PREPARE,