linux/drivers/gpu/vga/vga_switcheroo.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2010 Red Hat Inc.
   3 * Author : Dave Airlie <airlied@redhat.com>
   4 *
   5 *
   6 * Licensed under GPLv2
   7 *
   8 * vga_switcheroo.c - Support for laptop with dual GPU using one set of outputs
   9
  10 Switcher interface - methods require for ATPX and DCM
  11 - switchto - this throws the output MUX switch
  12 - discrete_set_power - sets the power state for the discrete card
  13
  14 GPU driver interface
  15 - set_gpu_state - this should do the equiv of s/r for the card
  16                  - this should *not* set the discrete power state
  17 - switch_check  - check if the device is in a position to switch now
  18 */
  19
  20#include <linux/module.h>
  21#include <linux/seq_file.h>
  22#include <linux/uaccess.h>
  23#include <linux/fs.h>
  24#include <linux/debugfs.h>
  25#include <linux/fb.h>
  26
  27#include <linux/pci.h>
  28#include <linux/console.h>
  29#include <linux/vga_switcheroo.h>
  30#include <linux/pm_runtime.h>
  31
  32#include <linux/vgaarb.h>
  33
  34struct vga_switcheroo_client {
  35        struct pci_dev *pdev;
  36        struct fb_info *fb_info;
  37        int pwr_state;
  38        const struct vga_switcheroo_client_ops *ops;
  39        int id;
  40        bool active;
  41        bool driver_power_control;
  42        struct list_head list;
  43};
  44
  45static DEFINE_MUTEX(vgasr_mutex);
  46
  47struct vgasr_priv {
  48
  49        bool active;
  50        bool delayed_switch_active;
  51        enum vga_switcheroo_client_id delayed_client_id;
  52
  53        struct dentry *debugfs_root;
  54        struct dentry *switch_file;
  55
  56        int registered_clients;
  57        struct list_head clients;
  58
  59        struct vga_switcheroo_handler *handler;
  60};
  61
  62#define ID_BIT_AUDIO            0x100
  63#define client_is_audio(c)      ((c)->id & ID_BIT_AUDIO)
  64#define client_is_vga(c)        ((c)->id == -1 || !client_is_audio(c))
  65#define client_id(c)            ((c)->id & ~ID_BIT_AUDIO)
  66
  67static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv);
  68static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv);
  69
  70/* only one switcheroo per system */
  71static struct vgasr_priv vgasr_priv = {
  72        .clients = LIST_HEAD_INIT(vgasr_priv.clients),
  73};
  74
  75static bool vga_switcheroo_ready(void)
  76{
  77        /* we're ready if we get two clients + handler */
  78        return !vgasr_priv.active &&
  79               vgasr_priv.registered_clients == 2 && vgasr_priv.handler;
  80}
  81
  82static void vga_switcheroo_enable(void)
  83{
  84        int ret;
  85        struct vga_switcheroo_client *client;
  86
  87        /* call the handler to init */
  88        if (vgasr_priv.handler->init)
  89                vgasr_priv.handler->init();
  90
  91        list_for_each_entry(client, &vgasr_priv.clients, list) {
  92                if (client->id != -1)
  93                        continue;
  94                ret = vgasr_priv.handler->get_client_id(client->pdev);
  95                if (ret < 0)
  96                        return;
  97
  98                client->id = ret;
  99        }
 100        vga_switcheroo_debugfs_init(&vgasr_priv);
 101        vgasr_priv.active = true;
 102}
 103
 104int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler)
 105{
 106        mutex_lock(&vgasr_mutex);
 107        if (vgasr_priv.handler) {
 108                mutex_unlock(&vgasr_mutex);
 109                return -EINVAL;
 110        }
 111
 112        vgasr_priv.handler = handler;
 113        if (vga_switcheroo_ready()) {
 114                printk(KERN_INFO "vga_switcheroo: enabled\n");
 115                vga_switcheroo_enable();
 116        }
 117        mutex_unlock(&vgasr_mutex);
 118        return 0;
 119}
 120EXPORT_SYMBOL(vga_switcheroo_register_handler);
 121
 122void vga_switcheroo_unregister_handler(void)
 123{
 124        mutex_lock(&vgasr_mutex);
 125        vgasr_priv.handler = NULL;
 126        if (vgasr_priv.active) {
 127                pr_info("vga_switcheroo: disabled\n");
 128                vga_switcheroo_debugfs_fini(&vgasr_priv);
 129                vgasr_priv.active = false;
 130        }
 131        mutex_unlock(&vgasr_mutex);
 132}
 133EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
 134
 135static int register_client(struct pci_dev *pdev,
 136                           const struct vga_switcheroo_client_ops *ops,
 137                           int id, bool active, bool driver_power_control)
 138{
 139        struct vga_switcheroo_client *client;
 140
 141        client = kzalloc(sizeof(*client), GFP_KERNEL);
 142        if (!client)
 143                return -ENOMEM;
 144
 145        client->pwr_state = VGA_SWITCHEROO_ON;
 146        client->pdev = pdev;
 147        client->ops = ops;
 148        client->id = id;
 149        client->active = active;
 150        client->driver_power_control = driver_power_control;
 151
 152        mutex_lock(&vgasr_mutex);
 153        list_add_tail(&client->list, &vgasr_priv.clients);
 154        if (client_is_vga(client))
 155                vgasr_priv.registered_clients++;
 156
 157        if (vga_switcheroo_ready()) {
 158                printk(KERN_INFO "vga_switcheroo: enabled\n");
 159                vga_switcheroo_enable();
 160        }
 161        mutex_unlock(&vgasr_mutex);
 162        return 0;
 163}
 164
 165int vga_switcheroo_register_client(struct pci_dev *pdev,
 166                                   const struct vga_switcheroo_client_ops *ops,
 167                                   bool driver_power_control)
 168{
 169        return register_client(pdev, ops, -1,
 170                               pdev == vga_default_device(), driver_power_control);
 171}
 172EXPORT_SYMBOL(vga_switcheroo_register_client);
 173
 174int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
 175                                         const struct vga_switcheroo_client_ops *ops,
 176                                         int id, bool active)
 177{
 178        return register_client(pdev, ops, id | ID_BIT_AUDIO, active, false);
 179}
 180EXPORT_SYMBOL(vga_switcheroo_register_audio_client);
 181
 182static struct vga_switcheroo_client *
 183find_client_from_pci(struct list_head *head, struct pci_dev *pdev)
 184{
 185        struct vga_switcheroo_client *client;
 186        list_for_each_entry(client, head, list)
 187                if (client->pdev == pdev)
 188                        return client;
 189        return NULL;
 190}
 191
 192static struct vga_switcheroo_client *
 193find_client_from_id(struct list_head *head, int client_id)
 194{
 195        struct vga_switcheroo_client *client;
 196        list_for_each_entry(client, head, list)
 197                if (client->id == client_id)
 198                        return client;
 199        return NULL;
 200}
 201
 202static struct vga_switcheroo_client *
 203find_active_client(struct list_head *head)
 204{
 205        struct vga_switcheroo_client *client;
 206        list_for_each_entry(client, head, list)
 207                if (client->active && client_is_vga(client))
 208                        return client;
 209        return NULL;
 210}
 211
 212int vga_switcheroo_get_client_state(struct pci_dev *pdev)
 213{
 214        struct vga_switcheroo_client *client;
 215
 216        client = find_client_from_pci(&vgasr_priv.clients, pdev);
 217        if (!client)
 218                return VGA_SWITCHEROO_NOT_FOUND;
 219        if (!vgasr_priv.active)
 220                return VGA_SWITCHEROO_INIT;
 221        return client->pwr_state;
 222}
 223EXPORT_SYMBOL(vga_switcheroo_get_client_state);
 224
 225void vga_switcheroo_unregister_client(struct pci_dev *pdev)
 226{
 227        struct vga_switcheroo_client *client;
 228
 229        mutex_lock(&vgasr_mutex);
 230        client = find_client_from_pci(&vgasr_priv.clients, pdev);
 231        if (client) {
 232                if (client_is_vga(client))
 233                        vgasr_priv.registered_clients--;
 234                list_del(&client->list);
 235                kfree(client);
 236        }
 237        if (vgasr_priv.active && vgasr_priv.registered_clients < 2) {
 238                printk(KERN_INFO "vga_switcheroo: disabled\n");
 239                vga_switcheroo_debugfs_fini(&vgasr_priv);
 240                vgasr_priv.active = false;
 241        }
 242        mutex_unlock(&vgasr_mutex);
 243}
 244EXPORT_SYMBOL(vga_switcheroo_unregister_client);
 245
 246void vga_switcheroo_client_fb_set(struct pci_dev *pdev,
 247                                 struct fb_info *info)
 248{
 249        struct vga_switcheroo_client *client;
 250
 251        mutex_lock(&vgasr_mutex);
 252        client = find_client_from_pci(&vgasr_priv.clients, pdev);
 253        if (client)
 254                client->fb_info = info;
 255        mutex_unlock(&vgasr_mutex);
 256}
 257EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
 258
 259static int vga_switcheroo_show(struct seq_file *m, void *v)
 260{
 261        struct vga_switcheroo_client *client;
 262        int i = 0;
 263        mutex_lock(&vgasr_mutex);
 264        list_for_each_entry(client, &vgasr_priv.clients, list) {
 265                seq_printf(m, "%d:%s%s:%c:%s%s:%s\n", i,
 266                           client_id(client) == VGA_SWITCHEROO_DIS ? "DIS" : "IGD",
 267                           client_is_vga(client) ? "" : "-Audio",
 268                           client->active ? '+' : ' ',
 269                           client->driver_power_control ? "Dyn" : "",
 270                           client->pwr_state ? "Pwr" : "Off",
 271                           pci_name(client->pdev));
 272                i++;
 273        }
 274        mutex_unlock(&vgasr_mutex);
 275        return 0;
 276}
 277
 278static int vga_switcheroo_debugfs_open(struct inode *inode, struct file *file)
 279{
 280        return single_open(file, vga_switcheroo_show, NULL);
 281}
 282
 283static int vga_switchon(struct vga_switcheroo_client *client)
 284{
 285        if (client->driver_power_control)
 286                return 0;
 287        if (vgasr_priv.handler->power_state)
 288                vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_ON);
 289        /* call the driver callback to turn on device */
 290        client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_ON);
 291        client->pwr_state = VGA_SWITCHEROO_ON;
 292        return 0;
 293}
 294
 295static int vga_switchoff(struct vga_switcheroo_client *client)
 296{
 297        if (client->driver_power_control)
 298                return 0;
 299        /* call the driver callback to turn off device */
 300        client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF);
 301        if (vgasr_priv.handler->power_state)
 302                vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_OFF);
 303        client->pwr_state = VGA_SWITCHEROO_OFF;
 304        return 0;
 305}
 306
 307static void set_audio_state(int id, int state)
 308{
 309        struct vga_switcheroo_client *client;
 310
 311        client = find_client_from_id(&vgasr_priv.clients, id | ID_BIT_AUDIO);
 312        if (client && client->pwr_state != state) {
 313                client->ops->set_gpu_state(client->pdev, state);
 314                client->pwr_state = state;
 315        }
 316}
 317
 318/* stage one happens before delay */
 319static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)
 320{
 321        struct vga_switcheroo_client *active;
 322
 323        active = find_active_client(&vgasr_priv.clients);
 324        if (!active)
 325                return 0;
 326
 327        if (new_client->pwr_state == VGA_SWITCHEROO_OFF)
 328                vga_switchon(new_client);
 329
 330        vga_set_default_device(new_client->pdev);
 331        return 0;
 332}
 333
 334/* post delay */
 335static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
 336{
 337        int ret;
 338        struct vga_switcheroo_client *active;
 339
 340        active = find_active_client(&vgasr_priv.clients);
 341        if (!active)
 342                return 0;
 343
 344        active->active = false;
 345
 346        set_audio_state(active->id, VGA_SWITCHEROO_OFF);
 347
 348        if (new_client->fb_info) {
 349                struct fb_event event;
 350                console_lock();
 351                event.info = new_client->fb_info;
 352                fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
 353                console_unlock();
 354        }
 355
 356        ret = vgasr_priv.handler->switchto(new_client->id);
 357        if (ret)
 358                return ret;
 359
 360        if (new_client->ops->reprobe)
 361                new_client->ops->reprobe(new_client->pdev);
 362
 363        if (active->pwr_state == VGA_SWITCHEROO_ON)
 364                vga_switchoff(active);
 365
 366        set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
 367
 368        new_client->active = true;
 369        return 0;
 370}
 371
 372static bool check_can_switch(void)
 373{
 374        struct vga_switcheroo_client *client;
 375
 376        list_for_each_entry(client, &vgasr_priv.clients, list) {
 377                if (!client->ops->can_switch(client->pdev)) {
 378                        printk(KERN_ERR "vga_switcheroo: client %x refused switch\n", client->id);
 379                        return false;
 380                }
 381        }
 382        return true;
 383}
 384
 385static ssize_t
 386vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
 387                             size_t cnt, loff_t *ppos)
 388{
 389        char usercmd[64];
 390        int ret;
 391        bool delay = false, can_switch;
 392        bool just_mux = false;
 393        int client_id = -1;
 394        struct vga_switcheroo_client *client = NULL;
 395
 396        if (cnt > 63)
 397                cnt = 63;
 398
 399        if (copy_from_user(usercmd, ubuf, cnt))
 400                return -EFAULT;
 401
 402        mutex_lock(&vgasr_mutex);
 403
 404        if (!vgasr_priv.active) {
 405                cnt = -EINVAL;
 406                goto out;
 407        }
 408
 409        /* pwr off the device not in use */
 410        if (strncmp(usercmd, "OFF", 3) == 0) {
 411                list_for_each_entry(client, &vgasr_priv.clients, list) {
 412                        if (client->active || client_is_audio(client))
 413                                continue;
 414                        if (client->driver_power_control)
 415                                continue;
 416                        set_audio_state(client->id, VGA_SWITCHEROO_OFF);
 417                        if (client->pwr_state == VGA_SWITCHEROO_ON)
 418                                vga_switchoff(client);
 419                }
 420                goto out;
 421        }
 422        /* pwr on the device not in use */
 423        if (strncmp(usercmd, "ON", 2) == 0) {
 424                list_for_each_entry(client, &vgasr_priv.clients, list) {
 425                        if (client->active || client_is_audio(client))
 426                                continue;
 427                        if (client->driver_power_control)
 428                                continue;
 429                        if (client->pwr_state == VGA_SWITCHEROO_OFF)
 430                                vga_switchon(client);
 431                        set_audio_state(client->id, VGA_SWITCHEROO_ON);
 432                }
 433                goto out;
 434        }
 435
 436        /* request a delayed switch - test can we switch now */
 437        if (strncmp(usercmd, "DIGD", 4) == 0) {
 438                client_id = VGA_SWITCHEROO_IGD;
 439                delay = true;
 440        }
 441
 442        if (strncmp(usercmd, "DDIS", 4) == 0) {
 443                client_id = VGA_SWITCHEROO_DIS;
 444                delay = true;
 445        }
 446
 447        if (strncmp(usercmd, "IGD", 3) == 0)
 448                client_id = VGA_SWITCHEROO_IGD;
 449
 450        if (strncmp(usercmd, "DIS", 3) == 0)
 451                client_id = VGA_SWITCHEROO_DIS;
 452
 453        if (strncmp(usercmd, "MIGD", 4) == 0) {
 454                just_mux = true;
 455                client_id = VGA_SWITCHEROO_IGD;
 456        }
 457        if (strncmp(usercmd, "MDIS", 4) == 0) {
 458                just_mux = true;
 459                client_id = VGA_SWITCHEROO_DIS;
 460        }
 461
 462        if (client_id == -1)
 463                goto out;
 464        client = find_client_from_id(&vgasr_priv.clients, client_id);
 465        if (!client)
 466                goto out;
 467
 468        vgasr_priv.delayed_switch_active = false;
 469
 470        if (just_mux) {
 471                ret = vgasr_priv.handler->switchto(client_id);
 472                goto out;
 473        }
 474
 475        if (client->active)
 476                goto out;
 477
 478        /* okay we want a switch - test if devices are willing to switch */
 479        can_switch = check_can_switch();
 480
 481        if (can_switch == false && delay == false)
 482                goto out;
 483
 484        if (can_switch) {
 485                ret = vga_switchto_stage1(client);
 486                if (ret)
 487                        printk(KERN_ERR "vga_switcheroo: switching failed stage 1 %d\n", ret);
 488
 489                ret = vga_switchto_stage2(client);
 490                if (ret)
 491                        printk(KERN_ERR "vga_switcheroo: switching failed stage 2 %d\n", ret);
 492
 493        } else {
 494                printk(KERN_INFO "vga_switcheroo: setting delayed switch to client %d\n", client->id);
 495                vgasr_priv.delayed_switch_active = true;
 496                vgasr_priv.delayed_client_id = client_id;
 497
 498                ret = vga_switchto_stage1(client);
 499                if (ret)
 500                        printk(KERN_ERR "vga_switcheroo: delayed switching stage 1 failed %d\n", ret);
 501        }
 502
 503out:
 504        mutex_unlock(&vgasr_mutex);
 505        return cnt;
 506}
 507
 508static const struct file_operations vga_switcheroo_debugfs_fops = {
 509        .owner = THIS_MODULE,
 510        .open = vga_switcheroo_debugfs_open,
 511        .write = vga_switcheroo_debugfs_write,
 512        .read = seq_read,
 513        .llseek = seq_lseek,
 514        .release = single_release,
 515};
 516
 517static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv)
 518{
 519        if (priv->switch_file) {
 520                debugfs_remove(priv->switch_file);
 521                priv->switch_file = NULL;
 522        }
 523        if (priv->debugfs_root) {
 524                debugfs_remove(priv->debugfs_root);
 525                priv->debugfs_root = NULL;
 526        }
 527}
 528
 529static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv)
 530{
 531        /* already initialised */
 532        if (priv->debugfs_root)
 533                return 0;
 534        priv->debugfs_root = debugfs_create_dir("vgaswitcheroo", NULL);
 535
 536        if (!priv->debugfs_root) {
 537                printk(KERN_ERR "vga_switcheroo: Cannot create /sys/kernel/debug/vgaswitcheroo\n");
 538                goto fail;
 539        }
 540
 541        priv->switch_file = debugfs_create_file("switch", 0644,
 542                                                priv->debugfs_root, NULL, &vga_switcheroo_debugfs_fops);
 543        if (!priv->switch_file) {
 544                printk(KERN_ERR "vga_switcheroo: cannot create /sys/kernel/debug/vgaswitcheroo/switch\n");
 545                goto fail;
 546        }
 547        return 0;
 548fail:
 549        vga_switcheroo_debugfs_fini(priv);
 550        return -1;
 551}
 552
 553int vga_switcheroo_process_delayed_switch(void)
 554{
 555        struct vga_switcheroo_client *client;
 556        int ret;
 557        int err = -EINVAL;
 558
 559        mutex_lock(&vgasr_mutex);
 560        if (!vgasr_priv.delayed_switch_active)
 561                goto err;
 562
 563        printk(KERN_INFO "vga_switcheroo: processing delayed switch to %d\n", vgasr_priv.delayed_client_id);
 564
 565        client = find_client_from_id(&vgasr_priv.clients,
 566                                     vgasr_priv.delayed_client_id);
 567        if (!client || !check_can_switch())
 568                goto err;
 569
 570        ret = vga_switchto_stage2(client);
 571        if (ret)
 572                printk(KERN_ERR "vga_switcheroo: delayed switching failed stage 2 %d\n", ret);
 573
 574        vgasr_priv.delayed_switch_active = false;
 575        err = 0;
 576err:
 577        mutex_unlock(&vgasr_mutex);
 578        return err;
 579}
 580EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);
 581
 582static void vga_switcheroo_power_switch(struct pci_dev *pdev, enum vga_switcheroo_state state)
 583{
 584        struct vga_switcheroo_client *client;
 585
 586        if (!vgasr_priv.handler->power_state)
 587                return;
 588
 589        client = find_client_from_pci(&vgasr_priv.clients, pdev);
 590        if (!client)
 591                return;
 592
 593        if (!client->driver_power_control)
 594                return;
 595
 596        vgasr_priv.handler->power_state(client->id, state);
 597}
 598
 599/* force a PCI device to a certain state - mainly to turn off audio clients */
 600
 601void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev, enum vga_switcheroo_state dynamic)
 602{
 603        struct vga_switcheroo_client *client;
 604
 605        client = find_client_from_pci(&vgasr_priv.clients, pdev);
 606        if (!client)
 607                return;
 608
 609        if (!client->driver_power_control)
 610                return;
 611
 612        client->pwr_state = dynamic;
 613        set_audio_state(client->id, dynamic);
 614}
 615EXPORT_SYMBOL(vga_switcheroo_set_dynamic_switch);
 616
 617/* switcheroo power domain */
 618static int vga_switcheroo_runtime_suspend(struct device *dev)
 619{
 620        struct pci_dev *pdev = to_pci_dev(dev);
 621        int ret;
 622
 623        ret = dev->bus->pm->runtime_suspend(dev);
 624        if (ret)
 625                return ret;
 626        if (vgasr_priv.handler->switchto)
 627                vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD);
 628        vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF);
 629        return 0;
 630}
 631
 632static int vga_switcheroo_runtime_resume(struct device *dev)
 633{
 634        struct pci_dev *pdev = to_pci_dev(dev);
 635        int ret;
 636
 637        vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON);
 638        ret = dev->bus->pm->runtime_resume(dev);
 639        if (ret)
 640                return ret;
 641
 642        return 0;
 643}
 644
 645/* this version is for the case where the power switch is separate
 646   to the device being powered down. */
 647int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain *domain)
 648{
 649        /* copy over all the bus versions */
 650        if (dev->bus && dev->bus->pm) {
 651                domain->ops = *dev->bus->pm;
 652                domain->ops.runtime_suspend = vga_switcheroo_runtime_suspend;
 653                domain->ops.runtime_resume = vga_switcheroo_runtime_resume;
 654
 655                dev->pm_domain = domain;
 656                return 0;
 657        }
 658        dev->pm_domain = NULL;
 659        return -EINVAL;
 660}
 661EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_ops);
 662
 663void vga_switcheroo_fini_domain_pm_ops(struct device *dev)
 664{
 665        dev->pm_domain = NULL;
 666}
 667EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops);
 668
 669static int vga_switcheroo_runtime_resume_hdmi_audio(struct device *dev)
 670{
 671        struct pci_dev *pdev = to_pci_dev(dev);
 672        int ret;
 673        struct vga_switcheroo_client *client, *found = NULL;
 674
 675        /* we need to check if we have to switch back on the video
 676           device so the audio device can come back */
 677        list_for_each_entry(client, &vgasr_priv.clients, list) {
 678                if (PCI_SLOT(client->pdev->devfn) == PCI_SLOT(pdev->devfn) && client_is_vga(client)) {
 679                        found = client;
 680                        ret = pm_runtime_get_sync(&client->pdev->dev);
 681                        if (ret) {
 682                                if (ret != 1)
 683                                        return ret;
 684                        }
 685                        break;
 686                }
 687        }
 688        ret = dev->bus->pm->runtime_resume(dev);
 689
 690        /* put the reference for the gpu */
 691        if (found) {
 692                pm_runtime_mark_last_busy(&found->pdev->dev);
 693                pm_runtime_put_autosuspend(&found->pdev->dev);
 694        }
 695        return ret;
 696}
 697
 698int vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev, struct dev_pm_domain *domain)
 699{
 700        /* copy over all the bus versions */
 701        if (dev->bus && dev->bus->pm) {
 702                domain->ops = *dev->bus->pm;
 703                domain->ops.runtime_resume = vga_switcheroo_runtime_resume_hdmi_audio;
 704
 705                dev->pm_domain = domain;
 706                return 0;
 707        }
 708        dev->pm_domain = NULL;
 709        return -EINVAL;
 710}
 711EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_optimus_hdmi_audio);
 712