Commit 1a8a763b authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/amdgpu/swsmu: add interrupt work function



So we can schedule work from interrupts.  This might include
long tasks or things that could sleep.

Fixes: e1188aac ("drm/amdgpu/smu11: add support for SMU AC/DC interrupts")
Reviewed-by: default avatarHawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 346dbbb8
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -453,6 +453,7 @@ struct smu_context

	struct work_struct throttling_logging_work;
	atomic64_t throttle_int_counter;
	struct work_struct interrupt_work;

	unsigned fan_max_rpm;
	unsigned manual_fan_speed_rpm;
@@ -601,6 +602,7 @@ struct pptable_funcs {
	int (*deep_sleep_control)(struct smu_context *smu, bool enablement);
	int (*get_fan_parameters)(struct smu_context *smu);
	int (*post_init)(struct smu_context *smu);
	void (*interrupt_work)(struct smu_context *smu);
};

typedef enum {
+15 −0
Original line number Diff line number Diff line
@@ -780,6 +780,19 @@ static void smu_throttling_logging_work_fn(struct work_struct *work)
	smu_log_thermal_throttling(smu);
}

static void smu_interrupt_work_fn(struct work_struct *work)
{
	struct smu_context *smu = container_of(work, struct smu_context,
					       interrupt_work);

	mutex_lock(&smu->mutex);

	if (smu->ppt_funcs && smu->ppt_funcs->interrupt_work)
		smu->ppt_funcs->interrupt_work(smu);

	mutex_unlock(&smu->mutex);
}

static int smu_sw_init(void *handle)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
@@ -802,6 +815,7 @@ static int smu_sw_init(void *handle)
	mutex_init(&smu->message_lock);

	INIT_WORK(&smu->throttling_logging_work, smu_throttling_logging_work_fn);
	INIT_WORK(&smu->interrupt_work, smu_interrupt_work_fn);
	atomic64_set(&smu->throttle_int_counter, 0);
	smu->watermarks_bitmap = 0;
	smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
@@ -1197,6 +1211,7 @@ static int smu_smc_hw_cleanup(struct smu_context *smu)
	int ret = 0;

	cancel_work_sync(&smu->throttling_logging_work);
	cancel_work_sync(&smu->interrupt_work);

	ret = smu_disable_thermal_alert(smu);
	if (ret) {