diff options
| -rw-r--r-- | drivers/gpu/vga/vga_switcheroo.c | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 2b8e1d25e8d..d2d8543686d 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c | |||
| @@ -212,7 +212,8 @@ static int vga_switchoff(struct vga_switcheroo_client *client) | |||
| 212 | return 0; | 212 | return 0; |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | static int vga_switchto(struct vga_switcheroo_client *new_client) | 215 | /* stage one happens before delay */ |
| 216 | static int vga_switchto_stage1(struct vga_switcheroo_client *new_client) | ||
| 216 | { | 217 | { |
| 217 | int ret; | 218 | int ret; |
| 218 | int i; | 219 | int i; |
| @@ -239,10 +240,28 @@ static int vga_switchto(struct vga_switcheroo_client *new_client) | |||
| 239 | vga_switchon(new_client); | 240 | vga_switchon(new_client); |
| 240 | 241 | ||
| 241 | /* swap shadow resource to denote boot VGA device has changed so X starts on new device */ | 242 | /* swap shadow resource to denote boot VGA device has changed so X starts on new device */ |
| 242 | active->active = false; | ||
| 243 | |||
| 244 | active->pdev->resource[PCI_ROM_RESOURCE].flags &= ~IORESOURCE_ROM_SHADOW; | 243 | active->pdev->resource[PCI_ROM_RESOURCE].flags &= ~IORESOURCE_ROM_SHADOW; |
| 245 | new_client->pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; | 244 | new_client->pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; |
| 245 | return 0; | ||
| 246 | } | ||
| 247 | |||
| 248 | /* post delay */ | ||
| 249 | static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) | ||
| 250 | { | ||
| 251 | int ret; | ||
| 252 | int i; | ||
| 253 | struct vga_switcheroo_client *active = NULL; | ||
| 254 | |||
| 255 | for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) { | ||
| 256 | if (vgasr_priv.clients[i].active == true) { | ||
| 257 | active = &vgasr_priv.clients[i]; | ||
| 258 | break; | ||
| 259 | } | ||
| 260 | } | ||
| 261 | if (!active) | ||
| 262 | return 0; | ||
| 263 | |||
| 264 | active->active = false; | ||
| 246 | 265 | ||
| 247 | if (new_client->fb_info) { | 266 | if (new_client->fb_info) { |
| 248 | struct fb_event event; | 267 | struct fb_event event; |
| @@ -368,18 +387,22 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, | |||
| 368 | 387 | ||
| 369 | if (can_switch == true) { | 388 | if (can_switch == true) { |
| 370 | pdev_name = pci_name(client->pdev); | 389 | pdev_name = pci_name(client->pdev); |
| 371 | ret = vga_switchto(client); | 390 | ret = vga_switchto_stage1(client); |
| 391 | if (ret) | ||
| 392 | printk(KERN_ERR "vga_switcheroo: switching failed stage 1 %d\n", ret); | ||
| 393 | |||
| 394 | ret = vga_switchto_stage2(client); | ||
| 372 | if (ret) | 395 | if (ret) |
| 373 | printk(KERN_ERR "vga_switcheroo: switching failed %d\n", ret); | 396 | printk(KERN_ERR "vga_switcheroo: switching failed stage 2 %d\n", ret); |
| 397 | |||
| 374 | } else { | 398 | } else { |
| 375 | printk(KERN_INFO "vga_switcheroo: setting delayed switch to client %d\n", client->id); | 399 | printk(KERN_INFO "vga_switcheroo: setting delayed switch to client %d\n", client->id); |
| 376 | vgasr_priv.delayed_switch_active = true; | 400 | vgasr_priv.delayed_switch_active = true; |
| 377 | vgasr_priv.delayed_client_id = client_id; | 401 | vgasr_priv.delayed_client_id = client_id; |
| 378 | 402 | ||
| 379 | /* we should at least power up the card to | 403 | ret = vga_switchto_stage1(client); |
| 380 | make the switch faster */ | 404 | if (ret) |
| 381 | if (client->pwr_state == VGA_SWITCHEROO_OFF) | 405 | printk(KERN_ERR "vga_switcheroo: delayed switching stage 1 failed %d\n", ret); |
| 382 | vga_switchon(client); | ||
| 383 | } | 406 | } |
| 384 | 407 | ||
| 385 | out: | 408 | out: |
| @@ -461,9 +484,9 @@ int vga_switcheroo_process_delayed_switch(void) | |||
| 461 | goto err; | 484 | goto err; |
| 462 | 485 | ||
| 463 | pdev_name = pci_name(client->pdev); | 486 | pdev_name = pci_name(client->pdev); |
| 464 | ret = vga_switchto(client); | 487 | ret = vga_switchto_stage2(client); |
| 465 | if (ret) | 488 | if (ret) |
| 466 | printk(KERN_ERR "vga_switcheroo: delayed switching failed %d\n", ret); | 489 | printk(KERN_ERR "vga_switcheroo: delayed switching failed stage 2 %d\n", ret); |
| 467 | 490 | ||
| 468 | vgasr_priv.delayed_switch_active = false; | 491 | vgasr_priv.delayed_switch_active = false; |
| 469 | err = 0; | 492 | err = 0; |
