Commit 32c87fca authored by Tejun Heo's avatar Tejun Heo Committed by Dave Airlie

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: default avatarTejun Heo <tj@kernel.org>
Acked-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent af5dd83b
...@@ -2756,7 +2756,7 @@ int evergreen_irq_process(struct radeon_device *rdev) ...@@ -2756,7 +2756,7 @@ int evergreen_irq_process(struct radeon_device *rdev)
if (wptr != rdev->ih.wptr) if (wptr != rdev->ih.wptr)
goto restart_ih; goto restart_ih;
if (queue_hotplug) if (queue_hotplug)
queue_work(rdev->wq, &rdev->hotplug_work); schedule_work(&rdev->hotplug_work);
rdev->ih.rptr = rptr; rdev->ih.rptr = rptr;
WREG32(IH_RB_RPTR, rdev->ih.rptr); WREG32(IH_RB_RPTR, rdev->ih.rptr);
spin_unlock_irqrestore(&rdev->ih.lock, flags); spin_unlock_irqrestore(&rdev->ih.lock, flags);
......
...@@ -682,7 +682,7 @@ int r100_irq_process(struct radeon_device *rdev) ...@@ -682,7 +682,7 @@ int r100_irq_process(struct radeon_device *rdev)
/* reset gui idle ack. the status bit is broken */ /* reset gui idle ack. the status bit is broken */
rdev->irq.gui_idle_acked = false; rdev->irq.gui_idle_acked = false;
if (queue_hotplug) if (queue_hotplug)
queue_work(rdev->wq, &rdev->hotplug_work); schedule_work(&rdev->hotplug_work);
if (rdev->msi_enabled) { if (rdev->msi_enabled) {
switch (rdev->family) { switch (rdev->family) {
case CHIP_RS400: case CHIP_RS400:
......
...@@ -3442,7 +3442,7 @@ int r600_irq_process(struct radeon_device *rdev) ...@@ -3442,7 +3442,7 @@ int r600_irq_process(struct radeon_device *rdev)
if (wptr != rdev->ih.wptr) if (wptr != rdev->ih.wptr)
goto restart_ih; goto restart_ih;
if (queue_hotplug) if (queue_hotplug)
queue_work(rdev->wq, &rdev->hotplug_work); schedule_work(&rdev->hotplug_work);
rdev->ih.rptr = rptr; rdev->ih.rptr = rptr;
WREG32(IH_RB_RPTR, rdev->ih.rptr); WREG32(IH_RB_RPTR, rdev->ih.rptr);
spin_unlock_irqrestore(&rdev->ih.lock, flags); spin_unlock_irqrestore(&rdev->ih.lock, flags);
......
...@@ -1152,7 +1152,6 @@ struct radeon_device { ...@@ -1152,7 +1152,6 @@ struct radeon_device {
struct r700_vram_scratch vram_scratch; struct r700_vram_scratch vram_scratch;
int msi_enabled; /* msi enabled */ int msi_enabled; /* msi enabled */
struct r600_ih ih; /* r6/700 interrupt ring */ struct r600_ih ih; /* r6/700 interrupt ring */
struct workqueue_struct *wq;
struct work_struct hotplug_work; struct work_struct hotplug_work;
int num_crtc; /* number of crtcs */ int num_crtc; /* number of crtcs */
struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */
......
...@@ -710,11 +710,6 @@ int radeon_device_init(struct radeon_device *rdev, ...@@ -710,11 +710,6 @@ int radeon_device_init(struct radeon_device *rdev,
init_waitqueue_head(&rdev->irq.vblank_queue); init_waitqueue_head(&rdev->irq.vblank_queue);
init_waitqueue_head(&rdev->irq.idle_queue); init_waitqueue_head(&rdev->irq.idle_queue);
/* setup workqueue */
rdev->wq = create_workqueue("radeon");
if (rdev->wq == NULL)
return -ENOMEM;
/* Set asic functions */ /* Set asic functions */
r = radeon_asic_init(rdev); r = radeon_asic_init(rdev);
if (r) if (r)
...@@ -813,7 +808,6 @@ void radeon_device_fini(struct radeon_device *rdev) ...@@ -813,7 +808,6 @@ void radeon_device_fini(struct radeon_device *rdev)
/* evict vram memory */ /* evict vram memory */
radeon_bo_evict_vram(rdev); radeon_bo_evict_vram(rdev);
radeon_fini(rdev); radeon_fini(rdev);
destroy_workqueue(rdev->wq);
vga_switcheroo_unregister_client(rdev->pdev); vga_switcheroo_unregister_client(rdev->pdev);
vga_client_register(rdev->pdev, NULL, NULL, NULL); vga_client_register(rdev->pdev, NULL, NULL, NULL);
if (rdev->rio_mem) if (rdev->rio_mem)
......
...@@ -64,8 +64,6 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev) ...@@ -64,8 +64,6 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
unsigned i; unsigned i;
INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
/* Disable *all* interrupts */ /* Disable *all* interrupts */
rdev->irq.sw_int = false; rdev->irq.sw_int = false;
rdev->irq.gui_idle = false; rdev->irq.gui_idle = false;
...@@ -114,6 +112,8 @@ int radeon_irq_kms_init(struct radeon_device *rdev) ...@@ -114,6 +112,8 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
{ {
int r = 0; int r = 0;
INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
spin_lock_init(&rdev->irq.sw_lock); spin_lock_init(&rdev->irq.sw_lock);
r = drm_vblank_init(rdev->ddev, rdev->num_crtc); r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
if (r) { if (r) {
...@@ -152,6 +152,7 @@ void radeon_irq_kms_fini(struct radeon_device *rdev) ...@@ -152,6 +152,7 @@ void radeon_irq_kms_fini(struct radeon_device *rdev)
if (rdev->msi_enabled) if (rdev->msi_enabled)
pci_disable_msi(rdev->pdev); pci_disable_msi(rdev->pdev);
} }
flush_work_sync(&rdev->hotplug_work);
} }
void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev) void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev)
......
...@@ -405,20 +405,13 @@ static ssize_t radeon_set_pm_method(struct device *dev, ...@@ -405,20 +405,13 @@ static ssize_t radeon_set_pm_method(struct device *dev,
rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT;
mutex_unlock(&rdev->pm.mutex); mutex_unlock(&rdev->pm.mutex);
} else if (strncmp("profile", buf, strlen("profile")) == 0) { } else if (strncmp("profile", buf, strlen("profile")) == 0) {
bool flush_wq = false;
mutex_lock(&rdev->pm.mutex); 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 */ /* disable dynpm */
rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; rdev->pm.dynpm_state = DYNPM_STATE_DISABLED;
rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE;
rdev->pm.pm_method = PM_METHOD_PROFILE; rdev->pm.pm_method = PM_METHOD_PROFILE;
mutex_unlock(&rdev->pm.mutex); mutex_unlock(&rdev->pm.mutex);
if (flush_wq) cancel_delayed_work_sync(&rdev->pm.dynpm_idle_work);
flush_workqueue(rdev->wq);
} else { } else {
DRM_ERROR("invalid power method!\n"); DRM_ERROR("invalid power method!\n");
goto fail; goto fail;
...@@ -524,18 +517,14 @@ static void radeon_hwmon_fini(struct radeon_device *rdev) ...@@ -524,18 +517,14 @@ static void radeon_hwmon_fini(struct radeon_device *rdev)
void radeon_pm_suspend(struct radeon_device *rdev) void radeon_pm_suspend(struct radeon_device *rdev)
{ {
bool flush_wq = false;
mutex_lock(&rdev->pm.mutex); mutex_lock(&rdev->pm.mutex);
if (rdev->pm.pm_method == PM_METHOD_DYNPM) { if (rdev->pm.pm_method == PM_METHOD_DYNPM) {
cancel_delayed_work(&rdev->pm.dynpm_idle_work);
if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE) if (rdev->pm.dynpm_state == DYNPM_STATE_ACTIVE)
rdev->pm.dynpm_state = DYNPM_STATE_SUSPENDED; rdev->pm.dynpm_state = DYNPM_STATE_SUSPENDED;
flush_wq = true;
} }
mutex_unlock(&rdev->pm.mutex); 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) void radeon_pm_resume(struct radeon_device *rdev)
...@@ -550,8 +539,8 @@ 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 if (rdev->pm.pm_method == PM_METHOD_DYNPM
&& rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) { && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) {
rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE;
queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, schedule_delayed_work(&rdev->pm.dynpm_idle_work,
msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
} }
mutex_unlock(&rdev->pm.mutex); mutex_unlock(&rdev->pm.mutex);
radeon_pm_compute_clocks(rdev); radeon_pm_compute_clocks(rdev);
...@@ -585,6 +574,9 @@ int radeon_pm_init(struct radeon_device *rdev) ...@@ -585,6 +574,9 @@ int radeon_pm_init(struct radeon_device *rdev)
ret = radeon_hwmon_init(rdev); ret = radeon_hwmon_init(rdev);
if (ret) if (ret)
return ret; return ret;
INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler);
if (rdev->pm.num_power_states > 1) { if (rdev->pm.num_power_states > 1) {
/* where's the best place to put these? */ /* where's the best place to put these? */
ret = device_create_file(rdev->dev, &dev_attr_power_profile); ret = device_create_file(rdev->dev, &dev_attr_power_profile);
...@@ -598,8 +590,6 @@ int radeon_pm_init(struct radeon_device *rdev) ...@@ -598,8 +590,6 @@ int radeon_pm_init(struct radeon_device *rdev)
rdev->acpi_nb.notifier_call = radeon_acpi_event; rdev->acpi_nb.notifier_call = radeon_acpi_event;
register_acpi_notifier(&rdev->acpi_nb); register_acpi_notifier(&rdev->acpi_nb);
#endif #endif
INIT_DELAYED_WORK(&rdev->pm.dynpm_idle_work, radeon_dynpm_idle_work_handler);
if (radeon_debugfs_pm_init(rdev)) { if (radeon_debugfs_pm_init(rdev)) {
DRM_ERROR("Failed to register debugfs file for PM!\n"); DRM_ERROR("Failed to register debugfs file for PM!\n");
} }
...@@ -613,25 +603,20 @@ int radeon_pm_init(struct radeon_device *rdev) ...@@ -613,25 +603,20 @@ int radeon_pm_init(struct radeon_device *rdev)
void radeon_pm_fini(struct radeon_device *rdev) void radeon_pm_fini(struct radeon_device *rdev)
{ {
if (rdev->pm.num_power_states > 1) { if (rdev->pm.num_power_states > 1) {
bool flush_wq = false;
mutex_lock(&rdev->pm.mutex); mutex_lock(&rdev->pm.mutex);
if (rdev->pm.pm_method == PM_METHOD_PROFILE) { if (rdev->pm.pm_method == PM_METHOD_PROFILE) {
rdev->pm.profile = PM_PROFILE_DEFAULT; rdev->pm.profile = PM_PROFILE_DEFAULT;
radeon_pm_update_profile(rdev); radeon_pm_update_profile(rdev);
radeon_pm_set_clocks(rdev); radeon_pm_set_clocks(rdev);
} else if (rdev->pm.pm_method == PM_METHOD_DYNPM) { } 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 */ /* reset default clocks */
rdev->pm.dynpm_state = DYNPM_STATE_DISABLED; rdev->pm.dynpm_state = DYNPM_STATE_DISABLED;
rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT; rdev->pm.dynpm_planned_action = DYNPM_ACTION_DEFAULT;
radeon_pm_set_clocks(rdev); radeon_pm_set_clocks(rdev);
} }
mutex_unlock(&rdev->pm.mutex); 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_profile);
device_remove_file(rdev->dev, &dev_attr_power_method); device_remove_file(rdev->dev, &dev_attr_power_method);
...@@ -690,12 +675,12 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev) ...@@ -690,12 +675,12 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)
radeon_pm_get_dynpm_state(rdev); radeon_pm_get_dynpm_state(rdev);
radeon_pm_set_clocks(rdev); radeon_pm_set_clocks(rdev);
queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, schedule_delayed_work(&rdev->pm.dynpm_idle_work,
msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
} else if (rdev->pm.dynpm_state == DYNPM_STATE_PAUSED) { } else if (rdev->pm.dynpm_state == DYNPM_STATE_PAUSED) {
rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE;
queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, schedule_delayed_work(&rdev->pm.dynpm_idle_work,
msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
DRM_DEBUG_DRIVER("radeon: dynamic power management activated\n"); DRM_DEBUG_DRIVER("radeon: dynamic power management activated\n");
} }
} else { /* count == 0 */ } else { /* count == 0 */
...@@ -800,8 +785,8 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work) ...@@ -800,8 +785,8 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work)
radeon_pm_set_clocks(rdev); radeon_pm_set_clocks(rdev);
} }
queue_delayed_work(rdev->wq, &rdev->pm.dynpm_idle_work, schedule_delayed_work(&rdev->pm.dynpm_idle_work,
msecs_to_jiffies(RADEON_IDLE_LOOP_MS)); msecs_to_jiffies(RADEON_IDLE_LOOP_MS));
} }
mutex_unlock(&rdev->pm.mutex); mutex_unlock(&rdev->pm.mutex);
ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
......
...@@ -692,7 +692,7 @@ int rs600_irq_process(struct radeon_device *rdev) ...@@ -692,7 +692,7 @@ int rs600_irq_process(struct radeon_device *rdev)
/* reset gui idle ack. the status bit is broken */ /* reset gui idle ack. the status bit is broken */
rdev->irq.gui_idle_acked = false; rdev->irq.gui_idle_acked = false;
if (queue_hotplug) if (queue_hotplug)
queue_work(rdev->wq, &rdev->hotplug_work); schedule_work(&rdev->hotplug_work);
if (rdev->msi_enabled) { if (rdev->msi_enabled) {
switch (rdev->family) { switch (rdev->family) {
case CHIP_RS600: case CHIP_RS600:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment