*     runtime pm. If true, writing ON and OFF to the vga_switcheroo debugfs
  *     interface is a no-op so as not to interfere with runtime pm
  * @list: client list
+ * @vga_dev: pci device, indicate which GPU is bound to current audio client
  *
  * Registered client. A client can be either a GPU or an audio device on a GPU.
- * For audio clients, the @fb_info and @active members are bogus.
+ * For audio clients, the @fb_info and @active members are bogus. For GPU
+ * clients, the @vga_dev is bogus.
  */
 struct vga_switcheroo_client {
        struct pci_dev *pdev;
        bool active;
        bool driver_power_control;
        struct list_head list;
+       struct pci_dev *vga_dev;
 };
 
 /*
 };
 
 #define ID_BIT_AUDIO           0x100
-#define client_is_audio(c)     ((c)->id & ID_BIT_AUDIO)
-#define client_is_vga(c)       ((c)->id == VGA_SWITCHEROO_UNKNOWN_ID || \
-                                !client_is_audio(c))
+#define client_is_audio(c)             ((c)->id & ID_BIT_AUDIO)
+#define client_is_vga(c)               (!client_is_audio(c))
 #define client_id(c)           ((c)->id & ~ID_BIT_AUDIO)
 
 static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv);
                vgasr_priv.handler->init();
 
        list_for_each_entry(client, &vgasr_priv.clients, list) {
-               if (client->id != VGA_SWITCHEROO_UNKNOWN_ID)
+               if (!client_is_vga(client) ||
+                    client_id(client) != VGA_SWITCHEROO_UNKNOWN_ID)
                        continue;
+
                ret = vgasr_priv.handler->get_client_id(client->pdev);
                if (ret < 0)
                        return;
 
                client->id = ret;
        }
+
+       list_for_each_entry(client, &vgasr_priv.clients, list) {
+               if (!client_is_audio(client) ||
+                    client_id(client) != VGA_SWITCHEROO_UNKNOWN_ID)
+                       continue;
+
+               ret = vgasr_priv.handler->get_client_id(client->vga_dev);
+               if (ret < 0)
+                       return;
+
+               client->id = ret | ID_BIT_AUDIO;
+       }
+
        vga_switcheroo_debugfs_init(&vgasr_priv);
        vgasr_priv.active = true;
 }
 
 static int register_client(struct pci_dev *pdev,
                           const struct vga_switcheroo_client_ops *ops,
-                          enum vga_switcheroo_client_id id, bool active,
+                          enum vga_switcheroo_client_id id,
+                          struct pci_dev *vga_dev,
+                          bool active,
                           bool driver_power_control)
 {
        struct vga_switcheroo_client *client;
        client->id = id;
        client->active = active;
        client->driver_power_control = driver_power_control;
+       client->vga_dev = vga_dev;
 
        mutex_lock(&vgasr_mutex);
        list_add_tail(&client->list, &vgasr_priv.clients);
                                   const struct vga_switcheroo_client_ops *ops,
                                   bool driver_power_control)
 {
-       return register_client(pdev, ops, VGA_SWITCHEROO_UNKNOWN_ID,
+       return register_client(pdev, ops, VGA_SWITCHEROO_UNKNOWN_ID, NULL,
                               pdev == vga_default_device(),
                               driver_power_control);
 }
  * vga_switcheroo_register_audio_client - register audio client
  * @pdev: client pci device
  * @ops: client callbacks
- * @id: client identifier
+ * @vga_dev:  pci device which is bound to current audio client
  *
  * Register audio client (audio device on a GPU). The client is assumed
  * to use runtime PM. Beforehand, vga_switcheroo_client_probe_defer()
  * shall be called to ensure that all prerequisites are met.
  *
- * Return: 0 on success, -ENOMEM on memory allocation error.
+ * Return: 0 on success, -ENOMEM on memory allocation error, -EINVAL on getting
+ * client id error.
  */
 int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
                        const struct vga_switcheroo_client_ops *ops,
-                       enum vga_switcheroo_client_id id)
+                       struct pci_dev *vga_dev)
 {
-       return register_client(pdev, ops, id | ID_BIT_AUDIO, false, true);
+       enum vga_switcheroo_client_id id = VGA_SWITCHEROO_UNKNOWN_ID;
+
+       /*
+        * if vga_switcheroo has enabled, that mean two GPU clients and also
+        * handler are registered. Get audio client id from bound GPU client
+        * id directly, otherwise, set it as VGA_SWITCHEROO_UNKNOWN_ID,
+        * it will set to correct id in later when vga_switcheroo_enable()
+        * is called.
+        */
+       mutex_lock(&vgasr_mutex);
+       if (vgasr_priv.active) {
+               id = vgasr_priv.handler->get_client_id(vga_dev);
+               if (id < 0) {
+                       mutex_unlock(&vgasr_mutex);
+                       return -EINVAL;
+               }
+       }
+       mutex_unlock(&vgasr_mutex);
+
+       return register_client(pdev, ops, id | ID_BIT_AUDIO, vga_dev,
+                              false, true);
 }
 EXPORT_SYMBOL(vga_switcheroo_register_audio_client);
 
 
  * Client identifier. Audio clients use the same identifier & 0x100.
  */
 enum vga_switcheroo_client_id {
-       VGA_SWITCHEROO_UNKNOWN_ID = -1,
-       VGA_SWITCHEROO_IGD,
+       VGA_SWITCHEROO_UNKNOWN_ID = 0x1000,
+       VGA_SWITCHEROO_IGD = 0,
        VGA_SWITCHEROO_DIS,
        VGA_SWITCHEROO_MAX_CLIENTS,
 };
                                   bool driver_power_control);
 int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
                                         const struct vga_switcheroo_client_ops *ops,
-                                        enum vga_switcheroo_client_id id);
+                                        struct pci_dev *vga_dev);
 
 void vga_switcheroo_client_fb_set(struct pci_dev *dev,
                                  struct fb_info *info);
                enum vga_switcheroo_handler_flags_t handler_flags) { return 0; }
 static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
        const struct vga_switcheroo_client_ops *ops,
-       enum vga_switcheroo_client_id id) { return 0; }
+       struct pci_dev *vga_dev) { return 0; }
 static inline void vga_switcheroo_unregister_handler(void) {}
 static inline enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(void) { return 0; }
 static inline int vga_switcheroo_lock_ddc(struct pci_dev *pdev) { return -ENODEV; }