diff options
Diffstat (limited to 'drivers/gpu/vga/vga_switcheroo.c')
| -rw-r--r-- | drivers/gpu/vga/vga_switcheroo.c | 61 | 
1 files changed, 38 insertions, 23 deletions
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 5b3c7d135dc..e25cf31faab 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -70,27 +70,12 @@ static struct vgasr_priv vgasr_priv = {  	.clients = LIST_HEAD_INIT(vgasr_priv.clients),  }; -int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) -{ -	mutex_lock(&vgasr_mutex); -	if (vgasr_priv.handler) { -		mutex_unlock(&vgasr_mutex); -		return -EINVAL; -	} - -	vgasr_priv.handler = handler; -	mutex_unlock(&vgasr_mutex); -	return 0; -} -EXPORT_SYMBOL(vga_switcheroo_register_handler); - -void vga_switcheroo_unregister_handler(void) +static bool vga_switcheroo_ready(void)  { -	mutex_lock(&vgasr_mutex); -	vgasr_priv.handler = NULL; -	mutex_unlock(&vgasr_mutex); +	/* we're ready if we get two clients + handler */ +	return !vgasr_priv.active && +	       vgasr_priv.registered_clients == 2 && vgasr_priv.handler;  } -EXPORT_SYMBOL(vga_switcheroo_unregister_handler);  static void vga_switcheroo_enable(void)  { @@ -98,7 +83,8 @@ static void vga_switcheroo_enable(void)  	struct vga_switcheroo_client *client;  	/* call the handler to init */ -	vgasr_priv.handler->init(); +	if (vgasr_priv.handler->init) +		vgasr_priv.handler->init();  	list_for_each_entry(client, &vgasr_priv.clients, list) {  		if (client->id != -1) @@ -113,6 +99,37 @@ static void vga_switcheroo_enable(void)  	vgasr_priv.active = true;  } +int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) +{ +	mutex_lock(&vgasr_mutex); +	if (vgasr_priv.handler) { +		mutex_unlock(&vgasr_mutex); +		return -EINVAL; +	} + +	vgasr_priv.handler = handler; +	if (vga_switcheroo_ready()) { +		printk(KERN_INFO "vga_switcheroo: enabled\n"); +		vga_switcheroo_enable(); +	} +	mutex_unlock(&vgasr_mutex); +	return 0; +} +EXPORT_SYMBOL(vga_switcheroo_register_handler); + +void vga_switcheroo_unregister_handler(void) +{ +	mutex_lock(&vgasr_mutex); +	vgasr_priv.handler = NULL; +	if (vgasr_priv.active) { +		pr_info("vga_switcheroo: disabled\n"); +		vga_switcheroo_debugfs_fini(&vgasr_priv); +		vgasr_priv.active = false; +	} +	mutex_unlock(&vgasr_mutex); +} +EXPORT_SYMBOL(vga_switcheroo_unregister_handler); +  static int register_client(struct pci_dev *pdev,  			   const struct vga_switcheroo_client_ops *ops,  			   int id, bool active) @@ -134,9 +151,7 @@ static int register_client(struct pci_dev *pdev,  	if (client_is_vga(client))  		vgasr_priv.registered_clients++; -	/* if we get two clients + handler */ -	if (!vgasr_priv.active && -	    vgasr_priv.registered_clients == 2 && vgasr_priv.handler) { +	if (vga_switcheroo_ready()) {  		printk(KERN_INFO "vga_switcheroo: enabled\n");  		vga_switcheroo_enable();  	}  |