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