summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/radeon/radeon_pm.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-01-03 14:49:32 +0100
committerDave Airlie <airlied@redhat.com>2011-01-06 14:32:16 +1000
commit32c87fca2fac490e34a9fa900b45f2fbb4faacf9 (patch)
tree181e9c1d1493124f0a0f5a8a65be4bf29053b77e /drivers/gpu/drm/radeon/radeon_pm.c
parentaf5dd83b873efd4e1477f2265b6fa15a825aff26 (diff)
drm/radeon: use system_wq instead of dev_priv->wq
With cmwq, there's no reason for radeon to use a dedicated workqueue. Drop dev_priv->wq and use system_wq instead. Because radeon_driver_irq_uninstall_kms() may be called from unsleepable context, the work items can't be flushed from there. Instead, init and flush from radeon_irq_kms_init/fini(). While at it, simplify canceling/flushing of rdev->pm.dynpm_idle_work. Always initialize and sync cancel instead of being unnecessarily smart about it. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Alex Deucher <alexdeucher@gmail.com> Cc: dri-devel@lists.freedesktop.org Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_pm.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c47
1 files changed, 16 insertions, 31 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 4de7776bd1c5..0afd26ccccfa 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -405,20 +405,13 @@ static ssize_t radeon_set_pm_method(struct device *dev,
rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT;
mutex_unlock(&rdev->pm.mutex);
} else if (strncmp("profile", buf, strlen("profile")) == 0) {
- bool flush_wq = false;
-
mutex_lock(&rdev->pm.mutex);
- if (rdev->pm.pm_method == PM_METHOD_DYNPM) {
- cancel_delayed_work(&rdev->pm.dynpm_idle_work);
- flush_wq = true;
- }
/* disable dynpm */
rdev->pm.dynpm_state = DYNPM_STATE_DISABLED;
rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE;
rdev->pm.pm_method = PM_METHOD_PROFILE;
mutex_unlock(&rdev->pm.mutex);
- if (flush_wq)
- flush_workqueue(rdev->wq);
+ cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work);
} else {
DRM_ERROR("invalid power method!\n");
goto fail;
@@ -524,18 +517,14 @@ static void radeon_hwmon_fini(struct radeon_device *rdev)
void radeon_pm_suspend(struct radeon_device *rdev)
{
- bool flush_wq = false;
-
mutex_lock(&rdev->pm.mutex);
if (rdev->pm.pm_method == PM_METHOD_DYNPM) {
- cancel_delayed_work(&rdev->pm.dynpm_idle_work);
if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE)
rdev->pm.dynpm_state = DYNPM_STATE_SUSPENDED;
- flush_wq = true;
}
mutex_unlock(&rdev->pm.mutex);
- if (flush_wq)
- flush_workqueue(rdev->wq);
+
+ cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work);
}
void radeon_pm_resume(struct radeon_device *rdev)
@@ -550,8 +539,8 @@ void radeon_pm_resume(struct radeon_device *rdev)
if (rdev->pm.pm_method == PM_METHOD_DYNPM
&& rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) {
rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE;
- queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work,
- msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
+ schedule_delayed_work(&rdev->pm.dynpm_idle_work,
+ msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
}
mutex_unlock(&rdev->pm.mutex);
radeon_pm_compute_clocks(rdev);
@@ -585,6 +574,9 @@ int radeon_pm_init(struct radeon_device *rdev)
ret = radeon_hwmon_init(rdev);
if (ret)
return ret;
+
+ INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler);
+
if (rdev->pm.num_power_states > 1) {
/* where's the best place to put these? */
ret = device_create_file(rdev->dev, &dev_attr_power_profile);
@@ -598,8 +590,6 @@ int radeon_pm_init(struct radeon_device *rdev)
rdev->acpi_nb.notifier_call = radeon_acpi_event;
register_acpi_notifier(&rdev->acpi_nb);
#endif
- INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler);
-
if (radeon_debugfs_pm_init(rdev)) {
DRM_ERROR("Failed to register debugfs file for PM!\n");
}
@@ -613,25 +603,20 @@ int radeon_pm_init(struct radeon_device *rdev)
void radeon_pm_fini(struct radeon_device *rdev)
{
if (rdev->pm.num_power_states > 1) {
- bool flush_wq = false;
-
mutex_lock(&rdev->pm.mutex);
if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
rdev->pm.profile = PM_PROFILE_DEFAULT;
radeon_pm_update_profile(rdev);
radeon_pm_set_clocks(rdev);
} else if (rdev->pm.pm_method == PM_METHOD_DYNPM) {
- /* cancel work */
- cancel_delayed_work(&rdev->pm.dynpm_idle_work);
- flush_wq = true;
/* reset default clocks */
rdev->pm.dynpm_state = DYNPM_STATE_DISABLED;
rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT;
radeon_pm_set_clocks(rdev);
}
mutex_unlock(&rdev->pm.mutex);
- if (flush_wq)
- flush_workqueue(rdev->wq);
+
+ cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work);
device_remove_file(rdev->dev, &dev_attr_power_profile);
device_remove_file(rdev->dev, &dev_attr_power_method);
@@ -690,12 +675,12 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)
radeon_pm_get_dynpm_state(rdev);
radeon_pm_set_clocks(rdev);
- queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work,
- msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
+ schedule_delayed_work(&rdev->pm.dynpm_idle_work,
+ msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
} else if (rdev->pm.dynpm_state == DYNPM_STATE_PAUSED) {
rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE;
- queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work,
- msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
+ schedule_delayed_work(&rdev->pm.dynpm_idle_work,
+ msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
DRM_DEBUG_DRIVER("radeon: dynamic power management activated\n");
}
} else { /* count == 0 */
@@ -800,8 +785,8 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work)
radeon_pm_set_clocks(rdev);
}
- queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work,
- msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
+ schedule_delayed_work(&rdev->pm.dynpm_idle_work,
+ msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
}
mutex_unlock(&rdev->pm.mutex);
ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);