87
95
static void vga_switcheroo_enable(void)
98
struct vga_switcheroo_client *client;
91
100
/* call the handler to init */
92
101
vgasr_priv.handler->init();
94
for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
95
ret = vgasr_priv.handler->get_client_id(vgasr_priv.clients[i].pdev);
103
list_for_each_entry(client, &vgasr_priv.clients, list) {
104
if (client->id != -1)
106
ret = vgasr_priv.handler->get_client_id(client->pdev);
99
vgasr_priv.clients[i].id = ret;
101
112
vga_switcheroo_debugfs_init(&vgasr_priv);
102
113
vgasr_priv.active = true;
105
int vga_switcheroo_register_client(struct pci_dev *pdev,
106
void (*set_gpu_state)(struct pci_dev *pdev, enum vga_switcheroo_state),
107
void (*reprobe)(struct pci_dev *pdev),
108
bool (*can_switch)(struct pci_dev *pdev))
116
static int register_client(struct pci_dev *pdev,
117
const struct vga_switcheroo_client_ops *ops,
120
struct vga_switcheroo_client *client;
122
client = kzalloc(sizeof(*client), GFP_KERNEL);
126
client->pwr_state = VGA_SWITCHEROO_ON;
130
client->active = active;
112
132
mutex_lock(&vgasr_mutex);
113
/* don't do IGD vs DIS here */
114
if (vgasr_priv.registered_clients & 1)
119
vgasr_priv.clients[index].pwr_state = VGA_SWITCHEROO_ON;
120
vgasr_priv.clients[index].pdev = pdev;
121
vgasr_priv.clients[index].set_gpu_state = set_gpu_state;
122
vgasr_priv.clients[index].reprobe = reprobe;
123
vgasr_priv.clients[index].can_switch = can_switch;
124
vgasr_priv.clients[index].id = -1;
125
if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
126
vgasr_priv.clients[index].active = true;
128
vgasr_priv.registered_clients |= (1 << index);
133
list_add_tail(&client->list, &vgasr_priv.clients);
134
if (client_is_vga(client))
135
vgasr_priv.registered_clients++;
130
137
/* if we get two clients + handler */
131
if (vgasr_priv.registered_clients == 0x3 && vgasr_priv.handler) {
138
if (!vgasr_priv.active &&
139
vgasr_priv.registered_clients == 2 && vgasr_priv.handler) {
132
140
printk(KERN_INFO "vga_switcheroo: enabled\n");
133
141
vga_switcheroo_enable();
135
143
mutex_unlock(&vgasr_mutex);
147
int vga_switcheroo_register_client(struct pci_dev *pdev,
148
const struct vga_switcheroo_client_ops *ops)
150
return register_client(pdev, ops, -1,
151
pdev == vga_default_device());
138
153
EXPORT_SYMBOL(vga_switcheroo_register_client);
155
int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
156
const struct vga_switcheroo_client_ops *ops,
159
return register_client(pdev, ops, id | ID_BIT_AUDIO, active);
161
EXPORT_SYMBOL(vga_switcheroo_register_audio_client);
163
static struct vga_switcheroo_client *
164
find_client_from_pci(struct list_head *head, struct pci_dev *pdev)
166
struct vga_switcheroo_client *client;
167
list_for_each_entry(client, head, list)
168
if (client->pdev == pdev)
173
static struct vga_switcheroo_client *
174
find_client_from_id(struct list_head *head, int client_id)
176
struct vga_switcheroo_client *client;
177
list_for_each_entry(client, head, list)
178
if (client->id == client_id)
183
static struct vga_switcheroo_client *
184
find_active_client(struct list_head *head)
186
struct vga_switcheroo_client *client;
187
list_for_each_entry(client, head, list)
188
if (client->active && client_is_vga(client))
193
int vga_switcheroo_get_client_state(struct pci_dev *pdev)
195
struct vga_switcheroo_client *client;
197
client = find_client_from_pci(&vgasr_priv.clients, pdev);
199
return VGA_SWITCHEROO_NOT_FOUND;
200
if (!vgasr_priv.active)
201
return VGA_SWITCHEROO_INIT;
202
return client->pwr_state;
204
EXPORT_SYMBOL(vga_switcheroo_get_client_state);
140
206
void vga_switcheroo_unregister_client(struct pci_dev *pdev)
208
struct vga_switcheroo_client *client;
144
210
mutex_lock(&vgasr_mutex);
145
for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
146
if (vgasr_priv.clients[i].pdev == pdev) {
147
vgasr_priv.registered_clients &= ~(1 << i);
152
printk(KERN_INFO "vga_switcheroo: disabled\n");
153
vga_switcheroo_debugfs_fini(&vgasr_priv);
154
vgasr_priv.active = false;
211
client = find_client_from_pci(&vgasr_priv.clients, pdev);
213
if (client_is_vga(client))
214
vgasr_priv.registered_clients--;
215
list_del(&client->list);
218
if (vgasr_priv.active && vgasr_priv.registered_clients < 2) {
219
printk(KERN_INFO "vga_switcheroo: disabled\n");
220
vga_switcheroo_debugfs_fini(&vgasr_priv);
221
vgasr_priv.active = false;
155
223
mutex_unlock(&vgasr_mutex);
157
225
EXPORT_SYMBOL(vga_switcheroo_unregister_client);
159
227
void vga_switcheroo_client_fb_set(struct pci_dev *pdev,
160
228
struct fb_info *info)
230
struct vga_switcheroo_client *client;
164
232
mutex_lock(&vgasr_mutex);
165
for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
166
if (vgasr_priv.clients[i].pdev == pdev) {
167
vgasr_priv.clients[i].fb_info = info;
233
client = find_client_from_pci(&vgasr_priv.clients, pdev);
235
client->fb_info = info;
171
236
mutex_unlock(&vgasr_mutex);
173
238
EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
175
240
static int vga_switcheroo_show(struct seq_file *m, void *v)
242
struct vga_switcheroo_client *client;
178
244
mutex_lock(&vgasr_mutex);
179
for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
180
seq_printf(m, "%d:%s:%c:%s:%s\n", i,
181
vgasr_priv.clients[i].id == VGA_SWITCHEROO_DIS ? "DIS" : "IGD",
182
vgasr_priv.clients[i].active ? '+' : ' ',
183
vgasr_priv.clients[i].pwr_state ? "Pwr" : "Off",
184
pci_name(vgasr_priv.clients[i].pdev));
245
list_for_each_entry(client, &vgasr_priv.clients, list) {
246
seq_printf(m, "%d:%s%s:%c:%s:%s\n", i,
247
client_id(client) == VGA_SWITCHEROO_DIS ? "DIS" : "IGD",
248
client_is_vga(client) ? "" : "-Audio",
249
client->active ? '+' : ' ',
250
client->pwr_state ? "Pwr" : "Off",
251
pci_name(client->pdev));
186
254
mutex_unlock(&vgasr_mutex);
205
273
static int vga_switchoff(struct vga_switcheroo_client *client)
207
275
/* call the driver callback to turn off device */
208
client->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF);
276
client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF);
209
277
if (vgasr_priv.handler->power_state)
210
278
vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_OFF);
211
279
client->pwr_state = VGA_SWITCHEROO_OFF;
283
static void set_audio_state(int id, int state)
285
struct vga_switcheroo_client *client;
287
client = find_client_from_id(&vgasr_priv.clients, id | ID_BIT_AUDIO);
288
if (client && client->pwr_state != state) {
289
client->ops->set_gpu_state(client->pdev, state);
290
client->pwr_state = state;
215
294
/* stage one happens before delay */
216
295
static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)
219
struct vga_switcheroo_client *active = NULL;
297
struct vga_switcheroo_client *active;
221
for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
222
if (vgasr_priv.clients[i].active == true) {
223
active = &vgasr_priv.clients[i];
299
active = find_active_client(&vgasr_priv.clients);
230
303
if (new_client->pwr_state == VGA_SWITCHEROO_OFF)
231
304
vga_switchon(new_client);
233
/* swap shadow resource to denote boot VGA device has changed so X starts on new device */
234
active->pdev->resource[PCI_ROM_RESOURCE].flags &= ~IORESOURCE_ROM_SHADOW;
235
new_client->pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
306
vga_set_default_device(new_client->pdev);
267
if (new_client->reprobe)
268
new_client->reprobe(new_client->pdev);
334
if (new_client->ops->reprobe)
335
new_client->ops->reprobe(new_client->pdev);
270
337
if (active->pwr_state == VGA_SWITCHEROO_ON)
271
338
vga_switchoff(active);
340
set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
273
342
new_client->active = true;
346
static bool check_can_switch(void)
348
struct vga_switcheroo_client *client;
350
list_for_each_entry(client, &vgasr_priv.clients, list) {
351
if (!client->ops->can_switch(client->pdev)) {
352
printk(KERN_ERR "vga_switcheroo: client %x refused switch\n", client->id);
278
360
vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
279
361
size_t cnt, loff_t *ppos)
281
363
char usercmd[64];
282
364
const char *pdev_name;
284
366
bool delay = false, can_switch;
285
367
bool just_mux = false;
286
368
int client_id = -1;
302
384
/* pwr off the device not in use */
303
385
if (strncmp(usercmd, "OFF", 3) == 0) {
304
for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
305
if (vgasr_priv.clients[i].active)
386
list_for_each_entry(client, &vgasr_priv.clients, list) {
387
if (client->active || client_is_audio(client))
307
if (vgasr_priv.clients[i].pwr_state == VGA_SWITCHEROO_ON)
308
vga_switchoff(&vgasr_priv.clients[i]);
389
set_audio_state(client->id, VGA_SWITCHEROO_OFF);
390
if (client->pwr_state == VGA_SWITCHEROO_ON)
391
vga_switchoff(client);
312
395
/* pwr on the device not in use */
313
396
if (strncmp(usercmd, "ON", 2) == 0) {
314
for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
315
if (vgasr_priv.clients[i].active)
397
list_for_each_entry(client, &vgasr_priv.clients, list) {
398
if (client->active || client_is_audio(client))
317
if (vgasr_priv.clients[i].pwr_state == VGA_SWITCHEROO_OFF)
318
vga_switchon(&vgasr_priv.clients[i]);
400
if (client->pwr_state == VGA_SWITCHEROO_OFF)
401
vga_switchon(client);
402
set_audio_state(client->id, VGA_SWITCHEROO_ON);