diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-06-09 02:46:42 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-06-09 06:14:43 -0400 |
commit | c91c3faea500da34d42a14735f1f67bb137b6413 (patch) | |
tree | bd475cbbc47c2fa527b1e4dbe0b9028a7a2a15d4 /drivers/gpu/vga | |
parent | 8393ec4a13889339bacfb8b038fb13716eef7a2b (diff) |
vga_switcheroo: Enable/disable audio clients at the right time
The audio clients have to be disabled before disabling the VGA and
switching. Similarly, enabling the audio client should be done at
last. Otherwise the audio-side operation stalls, eventually leading
to Oops or lockups.
Tested-by: Jörg-Volker Peetz <jvpeetz@web.de>
Acked-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'drivers/gpu/vga')
-rw-r--r-- | drivers/gpu/vga/vga_switcheroo.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index eb4f64f0a565..5b3c7d135dc9 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c | |||
@@ -304,8 +304,6 @@ static int vga_switchto_stage1(struct vga_switcheroo_client *new_client) | |||
304 | vga_switchon(new_client); | 304 | vga_switchon(new_client); |
305 | 305 | ||
306 | vga_set_default_device(new_client->pdev); | 306 | vga_set_default_device(new_client->pdev); |
307 | set_audio_state(new_client->id, VGA_SWITCHEROO_ON); | ||
308 | |||
309 | return 0; | 307 | return 0; |
310 | } | 308 | } |
311 | 309 | ||
@@ -321,6 +319,8 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) | |||
321 | 319 | ||
322 | active->active = false; | 320 | active->active = false; |
323 | 321 | ||
322 | set_audio_state(active->id, VGA_SWITCHEROO_OFF); | ||
323 | |||
324 | if (new_client->fb_info) { | 324 | if (new_client->fb_info) { |
325 | struct fb_event event; | 325 | struct fb_event event; |
326 | event.info = new_client->fb_info; | 326 | event.info = new_client->fb_info; |
@@ -334,11 +334,11 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) | |||
334 | if (new_client->ops->reprobe) | 334 | if (new_client->ops->reprobe) |
335 | new_client->ops->reprobe(new_client->pdev); | 335 | new_client->ops->reprobe(new_client->pdev); |
336 | 336 | ||
337 | set_audio_state(active->id, VGA_SWITCHEROO_OFF); | ||
338 | |||
339 | if (active->pwr_state == VGA_SWITCHEROO_ON) | 337 | if (active->pwr_state == VGA_SWITCHEROO_ON) |
340 | vga_switchoff(active); | 338 | vga_switchoff(active); |
341 | 339 | ||
340 | set_audio_state(new_client->id, VGA_SWITCHEROO_ON); | ||
341 | |||
342 | new_client->active = true; | 342 | new_client->active = true; |
343 | return 0; | 343 | return 0; |
344 | } | 344 | } |
@@ -384,8 +384,9 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, | |||
384 | /* pwr off the device not in use */ | 384 | /* pwr off the device not in use */ |
385 | if (strncmp(usercmd, "OFF", 3) == 0) { | 385 | if (strncmp(usercmd, "OFF", 3) == 0) { |
386 | list_for_each_entry(client, &vgasr_priv.clients, list) { | 386 | list_for_each_entry(client, &vgasr_priv.clients, list) { |
387 | if (client->active) | 387 | if (client->active || client_is_audio(client)) |
388 | continue; | 388 | continue; |
389 | set_audio_state(client->id, VGA_SWITCHEROO_OFF); | ||
389 | if (client->pwr_state == VGA_SWITCHEROO_ON) | 390 | if (client->pwr_state == VGA_SWITCHEROO_ON) |
390 | vga_switchoff(client); | 391 | vga_switchoff(client); |
391 | } | 392 | } |
@@ -394,10 +395,11 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, | |||
394 | /* pwr on the device not in use */ | 395 | /* pwr on the device not in use */ |
395 | if (strncmp(usercmd, "ON", 2) == 0) { | 396 | if (strncmp(usercmd, "ON", 2) == 0) { |
396 | list_for_each_entry(client, &vgasr_priv.clients, list) { | 397 | list_for_each_entry(client, &vgasr_priv.clients, list) { |
397 | if (client->active) | 398 | if (client->active || client_is_audio(client)) |
398 | continue; | 399 | continue; |
399 | if (client->pwr_state == VGA_SWITCHEROO_OFF) | 400 | if (client->pwr_state == VGA_SWITCHEROO_OFF) |
400 | vga_switchon(client); | 401 | vga_switchon(client); |
402 | set_audio_state(client->id, VGA_SWITCHEROO_ON); | ||
401 | } | 403 | } |
402 | goto out; | 404 | goto out; |
403 | } | 405 | } |