vgasr_priv
client = find_client_from_pci(&vgasr_priv.clients, pdev);
vgasr_priv.handler->power_state(client->id, state);
if (vgasr_priv.handler->switchto) {
mutex_lock(&vgasr_priv.mux_hw_lock);
vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD);
mutex_unlock(&vgasr_priv.mux_hw_lock);
static void vga_switcheroo_debugfs_init(struct vgasr_priv *priv);
static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv);
static struct vgasr_priv vgasr_priv = {
.clients = LIST_HEAD_INIT(vgasr_priv.clients),
.mux_hw_lock = __MUTEX_INITIALIZER(vgasr_priv.mux_hw_lock),
return !vgasr_priv.active &&
vgasr_priv.registered_clients == 2 && vgasr_priv.handler;
if (vgasr_priv.handler->init)
vgasr_priv.handler->init();
list_for_each_entry(client, &vgasr_priv.clients, list) {
ret = vgasr_priv.handler->get_client_id(client->pdev);
list_for_each_entry(client, &vgasr_priv.clients, list) {
ret = vgasr_priv.handler->get_client_id(client->vga_dev);
vga_switcheroo_debugfs_init(&vgasr_priv);
vgasr_priv.active = true;
if (vgasr_priv.handler) {
vgasr_priv.handler = handler;
vgasr_priv.handler_flags = handler_flags;
mutex_lock(&vgasr_priv.mux_hw_lock);
vgasr_priv.handler_flags = 0;
vgasr_priv.handler = NULL;
if (vgasr_priv.active) {
vga_switcheroo_debugfs_fini(&vgasr_priv);
vgasr_priv.active = false;
mutex_unlock(&vgasr_priv.mux_hw_lock);
return vgasr_priv.handler_flags;
list_add_tail(&client->list, &vgasr_priv.clients);
vgasr_priv.registered_clients++;
if (vgasr_priv.active) {
id = vgasr_priv.handler->get_client_id(vga_dev);
!vgasr_priv.handler_flags)
client = find_client_from_pci(&vgasr_priv.clients, pdev);
client = find_client_from_pci(&vgasr_priv.clients, pdev);
vgasr_priv.registered_clients--;
if (vgasr_priv.active && vgasr_priv.registered_clients < 2) {
vga_switcheroo_debugfs_fini(&vgasr_priv);
vgasr_priv.active = false;
client = find_client_from_pci(&vgasr_priv.clients, pdev);
mutex_lock(&vgasr_priv.mux_hw_lock);
if (!vgasr_priv.handler || !vgasr_priv.handler->switch_ddc) {
vgasr_priv.old_ddc_owner = -ENODEV;
id = vgasr_priv.handler->get_client_id(pdev);
vgasr_priv.old_ddc_owner = vgasr_priv.handler->switch_ddc(id);
return vgasr_priv.old_ddc_owner;
int ret = vgasr_priv.old_ddc_owner;
if (WARN_ON_ONCE(!mutex_is_locked(&vgasr_priv.mux_hw_lock)))
if (vgasr_priv.old_ddc_owner >= 0) {
id = vgasr_priv.handler->get_client_id(pdev);
if (vgasr_priv.old_ddc_owner != id)
ret = vgasr_priv.handler->switch_ddc(
vgasr_priv.old_ddc_owner);
mutex_unlock(&vgasr_priv.mux_hw_lock);
list_for_each_entry(client, &vgasr_priv.clients, list) {
if (vgasr_priv.handler->power_state)
vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_ON);
if (vgasr_priv.handler->power_state)
vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_OFF);
client = find_client_from_id(&vgasr_priv.clients, id | ID_BIT_AUDIO);
active = find_active_client(&vgasr_priv.clients);
active = find_active_client(&vgasr_priv.clients);
mutex_lock(&vgasr_priv.mux_hw_lock);
ret = vgasr_priv.handler->switchto(new_client->id);
mutex_unlock(&vgasr_priv.mux_hw_lock);
list_for_each_entry(client, &vgasr_priv.clients, list) {
if (!vgasr_priv.active) {
list_for_each_entry(client, &vgasr_priv.clients, list) {
list_for_each_entry(client, &vgasr_priv.clients, list) {
client = find_client_from_id(&vgasr_priv.clients, client_id);
vgasr_priv.delayed_switch_active = false;
mutex_lock(&vgasr_priv.mux_hw_lock);
ret = vgasr_priv.handler->switchto(client_id);
mutex_unlock(&vgasr_priv.mux_hw_lock);
vgasr_priv.delayed_switch_active = true;
vgasr_priv.delayed_client_id = client_id;
static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv)
static void vga_switcheroo_debugfs_init(struct vgasr_priv *priv)
if (!vgasr_priv.delayed_switch_active)
vgasr_priv.delayed_client_id);
client = find_client_from_id(&vgasr_priv.clients,
vgasr_priv.delayed_client_id);
vgasr_priv.delayed_switch_active = false;
if (!vgasr_priv.handler->power_state)