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 5b3c7d135dc9..e25cf31faab2 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 = { | |||
70 | .clients = LIST_HEAD_INIT(vgasr_priv.clients), | 70 | .clients = LIST_HEAD_INIT(vgasr_priv.clients), |
71 | }; | 71 | }; |
72 | 72 | ||
73 | int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) | 73 | static bool vga_switcheroo_ready(void) |
74 | { | ||
75 | mutex_lock(&vgasr_mutex); | ||
76 | if (vgasr_priv.handler) { | ||
77 | mutex_unlock(&vgasr_mutex); | ||
78 | return -EINVAL; | ||
79 | } | ||
80 | |||
81 | vgasr_priv.handler = handler; | ||
82 | mutex_unlock(&vgasr_mutex); | ||
83 | return 0; | ||
84 | } | ||
85 | EXPORT_SYMBOL(vga_switcheroo_register_handler); | ||
86 | |||
87 | void vga_switcheroo_unregister_handler(void) | ||
88 | { | 74 | { |
89 | mutex_lock(&vgasr_mutex); | 75 | /* we're ready if we get two clients + handler */ |
90 | vgasr_priv.handler = NULL; | 76 | return !vgasr_priv.active && |
91 | mutex_unlock(&vgasr_mutex); | 77 | vgasr_priv.registered_clients == 2 && vgasr_priv.handler; |
92 | } | 78 | } |
93 | EXPORT_SYMBOL(vga_switcheroo_unregister_handler); | ||
94 | 79 | ||
95 | static void vga_switcheroo_enable(void) | 80 | static void vga_switcheroo_enable(void) |
96 | { | 81 | { |
@@ -98,7 +83,8 @@ static void vga_switcheroo_enable(void) | |||
98 | struct vga_switcheroo_client *client; | 83 | struct vga_switcheroo_client *client; |
99 | 84 | ||
100 | /* call the handler to init */ | 85 | /* call the handler to init */ |
101 | vgasr_priv.handler->init(); | 86 | if (vgasr_priv.handler->init) |
87 | vgasr_priv.handler->init(); | ||
102 | 88 | ||
103 | list_for_each_entry(client, &vgasr_priv.clients, list) { | 89 | list_for_each_entry(client, &vgasr_priv.clients, list) { |
104 | if (client->id != -1) | 90 | if (client->id != -1) |
@@ -113,6 +99,37 @@ static void vga_switcheroo_enable(void) | |||
113 | vgasr_priv.active = true; | 99 | vgasr_priv.active = true; |
114 | } | 100 | } |
115 | 101 | ||
102 | int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) | ||
103 | { | ||
104 | mutex_lock(&vgasr_mutex); | ||
105 | if (vgasr_priv.handler) { | ||
106 | mutex_unlock(&vgasr_mutex); | ||
107 | return -EINVAL; | ||
108 | } | ||
109 | |||
110 | vgasr_priv.handler = handler; | ||
111 | if (vga_switcheroo_ready()) { | ||
112 | printk(KERN_INFO "vga_switcheroo: enabled\n"); | ||
113 | vga_switcheroo_enable(); | ||
114 | } | ||
115 | mutex_unlock(&vgasr_mutex); | ||
116 | return 0; | ||
117 | } | ||
118 | EXPORT_SYMBOL(vga_switcheroo_register_handler); | ||
119 | |||
120 | void vga_switcheroo_unregister_handler(void) | ||
121 | { | ||
122 | mutex_lock(&vgasr_mutex); | ||
123 | vgasr_priv.handler = NULL; | ||
124 | if (vgasr_priv.active) { | ||
125 | pr_info("vga_switcheroo: disabled\n"); | ||
126 | vga_switcheroo_debugfs_fini(&vgasr_priv); | ||
127 | vgasr_priv.active = false; | ||
128 | } | ||
129 | mutex_unlock(&vgasr_mutex); | ||
130 | } | ||
131 | EXPORT_SYMBOL(vga_switcheroo_unregister_handler); | ||
132 | |||
116 | static int register_client(struct pci_dev *pdev, | 133 | static int register_client(struct pci_dev *pdev, |
117 | const struct vga_switcheroo_client_ops *ops, | 134 | const struct vga_switcheroo_client_ops *ops, |
118 | int id, bool active) | 135 | int id, bool active) |
@@ -134,9 +151,7 @@ static int register_client(struct pci_dev *pdev, | |||
134 | if (client_is_vga(client)) | 151 | if (client_is_vga(client)) |
135 | vgasr_priv.registered_clients++; | 152 | vgasr_priv.registered_clients++; |
136 | 153 | ||
137 | /* if we get two clients + handler */ | 154 | if (vga_switcheroo_ready()) { |
138 | if (!vgasr_priv.active && | ||
139 | vgasr_priv.registered_clients == 2 && vgasr_priv.handler) { | ||
140 | printk(KERN_INFO "vga_switcheroo: enabled\n"); | 155 | printk(KERN_INFO "vga_switcheroo: enabled\n"); |
141 | vga_switcheroo_enable(); | 156 | vga_switcheroo_enable(); |
142 | } | 157 | } |