~ubuntu-branches/ubuntu/saucy/linux-ti-omap4/saucy-proposed

« back to all changes in this revision

Viewing changes to drivers/gpu/vga/vga_switcheroo.c

  • Committer: Package Import Robot
  • Author(s): Paolo Pisati, Paolo Pisati, Stefan Bader, Upstream Kernel Changes
  • Date: 2012-08-15 17:17:43 UTC
  • Revision ID: package-import@ubuntu.com-20120815171743-h5wnuf51xe7pvdid
Tags: 3.5.0-207.13
[ Paolo Pisati ]

* Start new release

[ Stefan Bader ]

* (config) Enable getabis to use local package copies

[ Upstream Kernel Changes ]

* fixup: gargabe collect iva_seq[0|1] init
* [Config] enable all SND_OMAP_SOC_*s
* fixup: cm2xxx_3xxx.o is needed for omap2_cm_read|write_reg
* fixup: add some snd_soc_dai* helper functions
* fixup: s/snd_soc_dpcm_params/snd_soc_dpcm/g
* fixup: typo, no_host_mode and useless SDP4430 init
* fixup: enable again aess hwmod

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
#include <linux/pci.h>
29
29
#include <linux/vga_switcheroo.h>
30
30
 
 
31
#include <linux/vgaarb.h>
 
32
 
31
33
struct vga_switcheroo_client {
32
34
        struct pci_dev *pdev;
33
35
        struct fb_info *fb_info;
34
36
        int pwr_state;
35
 
        void (*set_gpu_state)(struct pci_dev *pdev, enum vga_switcheroo_state);
36
 
        void (*reprobe)(struct pci_dev *pdev);
37
 
        bool (*can_switch)(struct pci_dev *pdev);
 
37
        const struct vga_switcheroo_client_ops *ops;
38
38
        int id;
39
39
        bool active;
 
40
        struct list_head list;
40
41
};
41
42
 
42
43
static DEFINE_MUTEX(vgasr_mutex);
51
52
        struct dentry *switch_file;
52
53
 
53
54
        int registered_clients;
54
 
        struct vga_switcheroo_client clients[VGA_SWITCHEROO_MAX_CLIENTS];
 
55
        struct list_head clients;
55
56
 
56
57
        struct vga_switcheroo_handler *handler;
57
58
};
58
59
 
 
60
#define ID_BIT_AUDIO            0x100
 
61
#define client_is_audio(c)      ((c)->id & ID_BIT_AUDIO)
 
62
#define client_is_vga(c)        ((c)->id == -1 || !client_is_audio(c))
 
63
#define client_id(c)            ((c)->id & ~ID_BIT_AUDIO)
 
64
 
59
65
static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv);
60
66
static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv);
61
67
 
62
68
/* only one switcheroo per system */
63
 
static struct vgasr_priv vgasr_priv;
 
69
static struct vgasr_priv vgasr_priv = {
 
70
        .clients = LIST_HEAD_INIT(vgasr_priv.clients),
 
71
};
64
72
 
65
73
int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler)
66
74
{
86
94
 
87
95
static void vga_switcheroo_enable(void)
88
96
{
89
 
        int i;
90
97
        int ret;
 
98
        struct vga_switcheroo_client *client;
 
99
 
91
100
        /* call the handler to init */
92
101
        vgasr_priv.handler->init();
93
102
 
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)
 
105
                        continue;
 
106
                ret = vgasr_priv.handler->get_client_id(client->pdev);
96
107
                if (ret < 0)
97
108
                        return;
98
109
 
99
 
                vgasr_priv.clients[i].id = ret;
 
110
                client->id = ret;
100
111
        }
101
112
        vga_switcheroo_debugfs_init(&vgasr_priv);
102
113
        vgasr_priv.active = true;
103
114
}
104
115
 
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,
 
118
                           int id, bool active)
109
119
{
110
 
        int index;
 
120
        struct vga_switcheroo_client *client;
 
121
 
 
122
        client = kzalloc(sizeof(*client), GFP_KERNEL);
 
123
        if (!client)
 
124
                return -ENOMEM;
 
125
 
 
126
        client->pwr_state = VGA_SWITCHEROO_ON;
 
127
        client->pdev = pdev;
 
128
        client->ops = ops;
 
129
        client->id = id;
 
130
        client->active = active;
111
131
 
112
132
        mutex_lock(&vgasr_mutex);
113
 
        /* don't do IGD vs DIS here */
114
 
        if (vgasr_priv.registered_clients & 1)
115
 
                index = 1;
116
 
        else
117
 
                index = 0;
118
 
 
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;
127
 
 
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++;
129
136
 
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();
134
142
        }
135
143
        mutex_unlock(&vgasr_mutex);
136
144
        return 0;
137
145
}
 
146
 
 
147
int vga_switcheroo_register_client(struct pci_dev *pdev,
 
148
                                   const struct vga_switcheroo_client_ops *ops)
 
149
{
 
150
        return register_client(pdev, ops, -1,
 
151
                               pdev == vga_default_device());
 
152
}
138
153
EXPORT_SYMBOL(vga_switcheroo_register_client);
139
154
 
 
155
int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
 
156
                                         const struct vga_switcheroo_client_ops *ops,
 
157
                                         int id, bool active)
 
158
{
 
159
        return register_client(pdev, ops, id | ID_BIT_AUDIO, active);
 
160
}
 
161
EXPORT_SYMBOL(vga_switcheroo_register_audio_client);
 
162
 
 
163
static struct vga_switcheroo_client *
 
164
find_client_from_pci(struct list_head *head, struct pci_dev *pdev)
 
165
{
 
166
        struct vga_switcheroo_client *client;
 
167
        list_for_each_entry(client, head, list)
 
168
                if (client->pdev == pdev)
 
169
                        return client;
 
170
        return NULL;
 
171
}
 
172
 
 
173
static struct vga_switcheroo_client *
 
174
find_client_from_id(struct list_head *head, int client_id)
 
175
{
 
176
        struct vga_switcheroo_client *client;
 
177
        list_for_each_entry(client, head, list)
 
178
                if (client->id == client_id)
 
179
                        return client;
 
180
        return NULL;
 
181
}
 
182
 
 
183
static struct vga_switcheroo_client *
 
184
find_active_client(struct list_head *head)
 
185
{
 
186
        struct vga_switcheroo_client *client;
 
187
        list_for_each_entry(client, head, list)
 
188
                if (client->active && client_is_vga(client))
 
189
                        return client;
 
190
        return NULL;
 
191
}
 
192
 
 
193
int vga_switcheroo_get_client_state(struct pci_dev *pdev)
 
194
{
 
195
        struct vga_switcheroo_client *client;
 
196
 
 
197
        client = find_client_from_pci(&vgasr_priv.clients, pdev);
 
198
        if (!client)
 
199
                return VGA_SWITCHEROO_NOT_FOUND;
 
200
        if (!vgasr_priv.active)
 
201
                return VGA_SWITCHEROO_INIT;
 
202
        return client->pwr_state;
 
203
}
 
204
EXPORT_SYMBOL(vga_switcheroo_get_client_state);
 
205
 
140
206
void vga_switcheroo_unregister_client(struct pci_dev *pdev)
141
207
{
142
 
        int i;
 
208
        struct vga_switcheroo_client *client;
143
209
 
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);
148
 
                        break;
149
 
                }
150
 
        }
151
 
 
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);
 
212
        if (client) {
 
213
                if (client_is_vga(client))
 
214
                        vgasr_priv.registered_clients--;
 
215
                list_del(&client->list);
 
216
                kfree(client);
 
217
        }
 
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;
 
222
        }
155
223
        mutex_unlock(&vgasr_mutex);
156
224
}
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)
161
229
{
162
 
        int i;
 
230
        struct vga_switcheroo_client *client;
163
231
 
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;
168
 
                        break;
169
 
                }
170
 
        }
 
233
        client = find_client_from_pci(&vgasr_priv.clients, pdev);
 
234
        if (client)
 
235
                client->fb_info = info;
171
236
        mutex_unlock(&vgasr_mutex);
172
237
}
173
238
EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
174
239
 
175
240
static int vga_switcheroo_show(struct seq_file *m, void *v)
176
241
{
177
 
        int i;
 
242
        struct vga_switcheroo_client *client;
 
243
        int i = 0;
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));
 
252
                i++;
185
253
        }
186
254
        mutex_unlock(&vgasr_mutex);
187
255
        return 0;
197
265
        if (vgasr_priv.handler->power_state)
198
266
                vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_ON);
199
267
        /* call the driver callback to turn on device */
200
 
        client->set_gpu_state(client->pdev, VGA_SWITCHEROO_ON);
 
268
        client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_ON);
201
269
        client->pwr_state = VGA_SWITCHEROO_ON;
202
270
        return 0;
203
271
}
205
273
static int vga_switchoff(struct vga_switcheroo_client *client)
206
274
{
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;
212
280
        return 0;
213
281
}
214
282
 
 
283
static void set_audio_state(int id, int state)
 
284
{
 
285
        struct vga_switcheroo_client *client;
 
286
 
 
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;
 
291
        }
 
292
}
 
293
 
215
294
/* stage one happens before delay */
216
295
static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)
217
296
{
218
 
        int i;
219
 
        struct vga_switcheroo_client *active = NULL;
 
297
        struct vga_switcheroo_client *active;
220
298
 
221
 
        for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
222
 
                if (vgasr_priv.clients[i].active == true) {
223
 
                        active = &vgasr_priv.clients[i];
224
 
                        break;
225
 
                }
226
 
        }
 
299
        active = find_active_client(&vgasr_priv.clients);
227
300
        if (!active)
228
301
                return 0;
229
302
 
230
303
        if (new_client->pwr_state == VGA_SWITCHEROO_OFF)
231
304
                vga_switchon(new_client);
232
305
 
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);
236
307
        return 0;
237
308
}
238
309
 
240
311
static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
241
312
{
242
313
        int ret;
243
 
        int i;
244
 
        struct vga_switcheroo_client *active = NULL;
 
314
        struct vga_switcheroo_client *active;
245
315
 
246
 
        for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
247
 
                if (vgasr_priv.clients[i].active == true) {
248
 
                        active = &vgasr_priv.clients[i];
249
 
                        break;
250
 
                }
251
 
        }
 
316
        active = find_active_client(&vgasr_priv.clients);
252
317
        if (!active)
253
318
                return 0;
254
319
 
255
320
        active->active = false;
256
321
 
 
322
        set_audio_state(active->id, VGA_SWITCHEROO_OFF);
 
323
 
257
324
        if (new_client->fb_info) {
258
325
                struct fb_event event;
259
326
                event.info = new_client->fb_info;
264
331
        if (ret)
265
332
                return ret;
266
333
 
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);
269
336
 
270
337
        if (active->pwr_state == VGA_SWITCHEROO_ON)
271
338
                vga_switchoff(active);
272
339
 
 
340
        set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
 
341
 
273
342
        new_client->active = true;
274
343
        return 0;
275
344
}
276
345
 
 
346
static bool check_can_switch(void)
 
347
{
 
348
        struct vga_switcheroo_client *client;
 
349
 
 
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);
 
353
                        return false;
 
354
                }
 
355
        }
 
356
        return true;
 
357
}
 
358
 
277
359
static ssize_t
278
360
vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
279
361
                             size_t cnt, loff_t *ppos)
280
362
{
281
363
        char usercmd[64];
282
364
        const char *pdev_name;
283
 
        int i, ret;
 
365
        int ret;
284
366
        bool delay = false, can_switch;
285
367
        bool just_mux = false;
286
368
        int client_id = -1;
301
383
 
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))
306
388
                                continue;
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);
309
392
                }
310
393
                goto out;
311
394
        }
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))
316
399
                                continue;
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);
319
403
                }
320
404
                goto out;
321
405
        }
348
432
 
349
433
        if (client_id == -1)
350
434
                goto out;
351
 
 
352
 
        for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
353
 
                if (vgasr_priv.clients[i].id == client_id) {
354
 
                        client = &vgasr_priv.clients[i];
355
 
                        break;
356
 
                }
357
 
        }
 
435
        client = find_client_from_id(&vgasr_priv.clients, client_id);
 
436
        if (!client)
 
437
                goto out;
358
438
 
359
439
        vgasr_priv.delayed_switch_active = false;
360
440
 
363
443
                goto out;
364
444
        }
365
445
 
366
 
        if (client->active == true)
 
446
        if (client->active)
367
447
                goto out;
368
448
 
369
449
        /* okay we want a switch - test if devices are willing to switch */
370
 
        can_switch = true;
371
 
        for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
372
 
                can_switch = vgasr_priv.clients[i].can_switch(vgasr_priv.clients[i].pdev);
373
 
                if (can_switch == false) {
374
 
                        printk(KERN_ERR "vga_switcheroo: client %d refused switch\n", i);
375
 
                        break;
376
 
                }
377
 
        }
 
450
        can_switch = check_can_switch();
378
451
 
379
452
        if (can_switch == false && delay == false)
380
453
                goto out;
381
454
 
382
 
        if (can_switch == true) {
 
455
        if (can_switch) {
383
456
                pdev_name = pci_name(client->pdev);
384
457
                ret = vga_switchto_stage1(client);
385
458
                if (ret)
451
524
 
452
525
int vga_switcheroo_process_delayed_switch(void)
453
526
{
454
 
        struct vga_switcheroo_client *client = NULL;
 
527
        struct vga_switcheroo_client *client;
455
528
        const char *pdev_name;
456
 
        bool can_switch = true;
457
 
        int i;
458
529
        int ret;
459
530
        int err = -EINVAL;
460
531
 
464
535
 
465
536
        printk(KERN_INFO "vga_switcheroo: processing delayed switch to %d\n", vgasr_priv.delayed_client_id);
466
537
 
467
 
        for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {
468
 
                if (vgasr_priv.clients[i].id == vgasr_priv.delayed_client_id)
469
 
                        client = &vgasr_priv.clients[i];
470
 
                can_switch = vgasr_priv.clients[i].can_switch(vgasr_priv.clients[i].pdev);
471
 
                if (can_switch == false) {
472
 
                        printk(KERN_ERR "vga_switcheroo: client %d refused switch\n", i);
473
 
                        break;
474
 
                }
475
 
        }
476
 
 
477
 
        if (can_switch == false || client == NULL)
 
538
        client = find_client_from_id(&vgasr_priv.clients,
 
539
                                     vgasr_priv.delayed_client_id);
 
540
        if (!client || !check_can_switch())
478
541
                goto err;
479
542
 
480
543
        pdev_name = pci_name(client->pdev);