~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/acpi/pci_link.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  pci_link.c - ACPI PCI Interrupt Link Device Driver ($Revision: 34 $)
 
3
 *
 
4
 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
 
5
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
 
6
 *  Copyright (C) 2002       Dominik Brodowski <devel@brodo.de>
 
7
 *
 
8
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
9
 *
 
10
 *  This program is free software; you can redistribute it and/or modify
 
11
 *  it under the terms of the GNU General Public License as published by
 
12
 *  the Free Software Foundation; either version 2 of the License, or (at
 
13
 *  your option) any later version.
 
14
 *
 
15
 *  This program is distributed in the hope that it will be useful, but
 
16
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
18
 *  General Public License for more details.
 
19
 *
 
20
 *  You should have received a copy of the GNU General Public License along
 
21
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 
22
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 
23
 *
 
24
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
25
 *
 
26
 * TBD: 
 
27
 *      1. Support more than one IRQ resource entry per link device (index).
 
28
 *      2. Implement start/stop mechanism and use ACPI Bus Driver facilities
 
29
 *         for IRQ management (e.g. start()->_SRS).
 
30
 */
 
31
 
 
32
#include <linux/syscore_ops.h>
 
33
#include <linux/kernel.h>
 
34
#include <linux/module.h>
 
35
#include <linux/init.h>
 
36
#include <linux/types.h>
 
37
#include <linux/spinlock.h>
 
38
#include <linux/pm.h>
 
39
#include <linux/pci.h>
 
40
#include <linux/mutex.h>
 
41
#include <linux/slab.h>
 
42
 
 
43
#include <acpi/acpi_bus.h>
 
44
#include <acpi/acpi_drivers.h>
 
45
 
 
46
#define PREFIX "ACPI: "
 
47
 
 
48
#define _COMPONENT                      ACPI_PCI_COMPONENT
 
49
ACPI_MODULE_NAME("pci_link");
 
50
#define ACPI_PCI_LINK_CLASS             "pci_irq_routing"
 
51
#define ACPI_PCI_LINK_DEVICE_NAME       "PCI Interrupt Link"
 
52
#define ACPI_PCI_LINK_FILE_INFO         "info"
 
53
#define ACPI_PCI_LINK_FILE_STATUS       "state"
 
54
#define ACPI_PCI_LINK_MAX_POSSIBLE      16
 
55
 
 
56
static int acpi_pci_link_add(struct acpi_device *device);
 
57
static int acpi_pci_link_remove(struct acpi_device *device, int type);
 
58
 
 
59
static const struct acpi_device_id link_device_ids[] = {
 
60
        {"PNP0C0F", 0},
 
61
        {"", 0},
 
62
};
 
63
MODULE_DEVICE_TABLE(acpi, link_device_ids);
 
64
 
 
65
static struct acpi_driver acpi_pci_link_driver = {
 
66
        .name = "pci_link",
 
67
        .class = ACPI_PCI_LINK_CLASS,
 
68
        .ids = link_device_ids,
 
69
        .ops = {
 
70
                .add = acpi_pci_link_add,
 
71
                .remove = acpi_pci_link_remove,
 
72
        },
 
73
};
 
74
 
 
75
/*
 
76
 * If a link is initialized, we never change its active and initialized
 
77
 * later even the link is disable. Instead, we just repick the active irq
 
78
 */
 
79
struct acpi_pci_link_irq {
 
80
        u8 active;              /* Current IRQ */
 
81
        u8 triggering;          /* All IRQs */
 
82
        u8 polarity;            /* All IRQs */
 
83
        u8 resource_type;
 
84
        u8 possible_count;
 
85
        u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
 
86
        u8 initialized:1;
 
87
        u8 reserved:7;
 
88
};
 
89
 
 
90
struct acpi_pci_link {
 
91
        struct list_head                list;
 
92
        struct acpi_device              *device;
 
93
        struct acpi_pci_link_irq        irq;
 
94
        int                             refcnt;
 
95
};
 
96
 
 
97
static LIST_HEAD(acpi_link_list);
 
98
static DEFINE_MUTEX(acpi_link_lock);
 
99
 
 
100
/* --------------------------------------------------------------------------
 
101
                            PCI Link Device Management
 
102
   -------------------------------------------------------------------------- */
 
103
 
 
104
/*
 
105
 * set context (link) possible list from resource list
 
106
 */
 
107
static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource,
 
108
                                                void *context)
 
109
{
 
110
        struct acpi_pci_link *link = context;
 
111
        u32 i;
 
112
 
 
113
        switch (resource->type) {
 
114
        case ACPI_RESOURCE_TYPE_START_DEPENDENT:
 
115
        case ACPI_RESOURCE_TYPE_END_TAG:
 
116
                return AE_OK;
 
117
        case ACPI_RESOURCE_TYPE_IRQ:
 
118
                {
 
119
                        struct acpi_resource_irq *p = &resource->data.irq;
 
120
                        if (!p || !p->interrupt_count) {
 
121
                                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 
122
                                                  "Blank _PRS IRQ resource\n"));
 
123
                                return AE_OK;
 
124
                        }
 
125
                        for (i = 0;
 
126
                             (i < p->interrupt_count
 
127
                              && i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
 
128
                                if (!p->interrupts[i]) {
 
129
                                        printk(KERN_WARNING PREFIX
 
130
                                               "Invalid _PRS IRQ %d\n",
 
131
                                               p->interrupts[i]);
 
132
                                        continue;
 
133
                                }
 
134
                                link->irq.possible[i] = p->interrupts[i];
 
135
                                link->irq.possible_count++;
 
136
                        }
 
137
                        link->irq.triggering = p->triggering;
 
138
                        link->irq.polarity = p->polarity;
 
139
                        link->irq.resource_type = ACPI_RESOURCE_TYPE_IRQ;
 
140
                        break;
 
141
                }
 
142
        case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 
143
                {
 
144
                        struct acpi_resource_extended_irq *p =
 
145
                            &resource->data.extended_irq;
 
146
                        if (!p || !p->interrupt_count) {
 
147
                                printk(KERN_WARNING PREFIX
 
148
                                              "Blank _PRS EXT IRQ resource\n");
 
149
                                return AE_OK;
 
150
                        }
 
151
                        for (i = 0;
 
152
                             (i < p->interrupt_count
 
153
                              && i < ACPI_PCI_LINK_MAX_POSSIBLE); i++) {
 
154
                                if (!p->interrupts[i]) {
 
155
                                        printk(KERN_WARNING PREFIX
 
156
                                               "Invalid _PRS IRQ %d\n",
 
157
                                               p->interrupts[i]);
 
158
                                        continue;
 
159
                                }
 
160
                                link->irq.possible[i] = p->interrupts[i];
 
161
                                link->irq.possible_count++;
 
162
                        }
 
163
                        link->irq.triggering = p->triggering;
 
164
                        link->irq.polarity = p->polarity;
 
165
                        link->irq.resource_type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ;
 
166
                        break;
 
167
                }
 
168
        default:
 
169
                printk(KERN_ERR PREFIX "_PRS resource type 0x%x isn't an IRQ\n",
 
170
                       resource->type);
 
171
                return AE_OK;
 
172
        }
 
173
 
 
174
        return AE_CTRL_TERMINATE;
 
175
}
 
176
 
 
177
static int acpi_pci_link_get_possible(struct acpi_pci_link *link)
 
178
{
 
179
        acpi_status status;
 
180
 
 
181
        status = acpi_walk_resources(link->device->handle, METHOD_NAME__PRS,
 
182
                                     acpi_pci_link_check_possible, link);
 
183
        if (ACPI_FAILURE(status)) {
 
184
                ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRS"));
 
185
                return -ENODEV;
 
186
        }
 
187
 
 
188
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 
189
                          "Found %d possible IRQs\n",
 
190
                          link->irq.possible_count));
 
191
 
 
192
        return 0;
 
193
}
 
194
 
 
195
static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource,
 
196
                                               void *context)
 
197
{
 
198
        int *irq = context;
 
199
 
 
200
        switch (resource->type) {
 
201
        case ACPI_RESOURCE_TYPE_START_DEPENDENT:
 
202
        case ACPI_RESOURCE_TYPE_END_TAG:
 
203
                return AE_OK;
 
204
        case ACPI_RESOURCE_TYPE_IRQ:
 
205
                {
 
206
                        struct acpi_resource_irq *p = &resource->data.irq;
 
207
                        if (!p || !p->interrupt_count) {
 
208
                                /*
 
209
                                 * IRQ descriptors may have no IRQ# bits set,
 
210
                                 * particularly those those w/ _STA disabled
 
211
                                 */
 
212
                                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 
213
                                                  "Blank _CRS IRQ resource\n"));
 
214
                                return AE_OK;
 
215
                        }
 
216
                        *irq = p->interrupts[0];
 
217
                        break;
 
218
                }
 
219
        case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 
220
                {
 
221
                        struct acpi_resource_extended_irq *p =
 
222
                            &resource->data.extended_irq;
 
223
                        if (!p || !p->interrupt_count) {
 
224
                                /*
 
225
                                 * extended IRQ descriptors must
 
226
                                 * return at least 1 IRQ
 
227
                                 */
 
228
                                printk(KERN_WARNING PREFIX
 
229
                                              "Blank _CRS EXT IRQ resource\n");
 
230
                                return AE_OK;
 
231
                        }
 
232
                        *irq = p->interrupts[0];
 
233
                        break;
 
234
                }
 
235
                break;
 
236
        default:
 
237
                printk(KERN_ERR PREFIX "_CRS resource type 0x%x isn't an IRQ\n",
 
238
                       resource->type);
 
239
                return AE_OK;
 
240
        }
 
241
 
 
242
        return AE_CTRL_TERMINATE;
 
243
}
 
244
 
 
245
/*
 
246
 * Run _CRS and set link->irq.active
 
247
 *
 
248
 * return value:
 
249
 * 0 - success
 
250
 * !0 - failure
 
251
 */
 
252
static int acpi_pci_link_get_current(struct acpi_pci_link *link)
 
253
{
 
254
        int result = 0;
 
255
        acpi_status status;
 
256
        int irq = 0;
 
257
 
 
258
        link->irq.active = 0;
 
259
 
 
260
        /* in practice, status disabled is meaningless, ignore it */
 
261
        if (acpi_strict) {
 
262
                /* Query _STA, set link->device->status */
 
263
                result = acpi_bus_get_status(link->device);
 
264
                if (result) {
 
265
                        printk(KERN_ERR PREFIX "Unable to read status\n");
 
266
                        goto end;
 
267
                }
 
268
 
 
269
                if (!link->device->status.enabled) {
 
270
                        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link disabled\n"));
 
271
                        return 0;
 
272
                }
 
273
        }
 
274
 
 
275
        /* 
 
276
         * Query and parse _CRS to get the current IRQ assignment. 
 
277
         */
 
278
 
 
279
        status = acpi_walk_resources(link->device->handle, METHOD_NAME__CRS,
 
280
                                     acpi_pci_link_check_current, &irq);
 
281
        if (ACPI_FAILURE(status)) {
 
282
                ACPI_EXCEPTION((AE_INFO, status, "Evaluating _CRS"));
 
283
                result = -ENODEV;
 
284
                goto end;
 
285
        }
 
286
 
 
287
        if (acpi_strict && !irq) {
 
288
                printk(KERN_ERR PREFIX "_CRS returned 0\n");
 
289
                result = -ENODEV;
 
290
        }
 
291
 
 
292
        link->irq.active = irq;
 
293
 
 
294
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active));
 
295
 
 
296
      end:
 
297
        return result;
 
298
}
 
299
 
 
300
static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
 
301
{
 
302
        int result;
 
303
        acpi_status status;
 
304
        struct {
 
305
                struct acpi_resource res;
 
306
                struct acpi_resource end;
 
307
        } *resource;
 
308
        struct acpi_buffer buffer = { 0, NULL };
 
309
 
 
310
        if (!irq)
 
311
                return -EINVAL;
 
312
 
 
313
        resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
 
314
        if (!resource)
 
315
                return -ENOMEM;
 
316
 
 
317
        buffer.length = sizeof(*resource) + 1;
 
318
        buffer.pointer = resource;
 
319
 
 
320
        switch (link->irq.resource_type) {
 
321
        case ACPI_RESOURCE_TYPE_IRQ:
 
322
                resource->res.type = ACPI_RESOURCE_TYPE_IRQ;
 
323
                resource->res.length = sizeof(struct acpi_resource);
 
324
                resource->res.data.irq.triggering = link->irq.triggering;
 
325
                resource->res.data.irq.polarity =
 
326
                    link->irq.polarity;
 
327
                if (link->irq.triggering == ACPI_EDGE_SENSITIVE)
 
328
                        resource->res.data.irq.sharable =
 
329
                            ACPI_EXCLUSIVE;
 
330
                else
 
331
                        resource->res.data.irq.sharable = ACPI_SHARED;
 
332
                resource->res.data.irq.interrupt_count = 1;
 
333
                resource->res.data.irq.interrupts[0] = irq;
 
334
                break;
 
335
 
 
336
        case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 
337
                resource->res.type = ACPI_RESOURCE_TYPE_EXTENDED_IRQ;
 
338
                resource->res.length = sizeof(struct acpi_resource);
 
339
                resource->res.data.extended_irq.producer_consumer =
 
340
                    ACPI_CONSUMER;
 
341
                resource->res.data.extended_irq.triggering =
 
342
                    link->irq.triggering;
 
343
                resource->res.data.extended_irq.polarity =
 
344
                    link->irq.polarity;
 
345
                if (link->irq.triggering == ACPI_EDGE_SENSITIVE)
 
346
                        resource->res.data.irq.sharable =
 
347
                            ACPI_EXCLUSIVE;
 
348
                else
 
349
                        resource->res.data.irq.sharable = ACPI_SHARED;
 
350
                resource->res.data.extended_irq.interrupt_count = 1;
 
351
                resource->res.data.extended_irq.interrupts[0] = irq;
 
352
                /* ignore resource_source, it's optional */
 
353
                break;
 
354
        default:
 
355
                printk(KERN_ERR PREFIX "Invalid Resource_type %d\n", link->irq.resource_type);
 
356
                result = -EINVAL;
 
357
                goto end;
 
358
 
 
359
        }
 
360
        resource->end.type = ACPI_RESOURCE_TYPE_END_TAG;
 
361
 
 
362
        /* Attempt to set the resource */
 
363
        status = acpi_set_current_resources(link->device->handle, &buffer);
 
364
 
 
365
        /* check for total failure */
 
366
        if (ACPI_FAILURE(status)) {
 
367
                ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SRS"));
 
368
                result = -ENODEV;
 
369
                goto end;
 
370
        }
 
371
 
 
372
        /* Query _STA, set device->status */
 
373
        result = acpi_bus_get_status(link->device);
 
374
        if (result) {
 
375
                printk(KERN_ERR PREFIX "Unable to read status\n");
 
376
                goto end;
 
377
        }
 
378
        if (!link->device->status.enabled) {
 
379
                printk(KERN_WARNING PREFIX
 
380
                              "%s [%s] disabled and referenced, BIOS bug\n",
 
381
                              acpi_device_name(link->device),
 
382
                              acpi_device_bid(link->device));
 
383
        }
 
384
 
 
385
        /* Query _CRS, set link->irq.active */
 
386
        result = acpi_pci_link_get_current(link);
 
387
        if (result) {
 
388
                goto end;
 
389
        }
 
390
 
 
391
        /*
 
392
         * Is current setting not what we set?
 
393
         * set link->irq.active
 
394
         */
 
395
        if (link->irq.active != irq) {
 
396
                /*
 
397
                 * policy: when _CRS doesn't return what we just _SRS
 
398
                 * assume _SRS worked and override _CRS value.
 
399
                 */
 
400
                printk(KERN_WARNING PREFIX
 
401
                              "%s [%s] BIOS reported IRQ %d, using IRQ %d\n",
 
402
                              acpi_device_name(link->device),
 
403
                              acpi_device_bid(link->device), link->irq.active, irq);
 
404
                link->irq.active = irq;
 
405
        }
 
406
 
 
407
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Set IRQ %d\n", link->irq.active));
 
408
 
 
409
      end:
 
410
        kfree(resource);
 
411
        return result;
 
412
}
 
413
 
 
414
/* --------------------------------------------------------------------------
 
415
                            PCI Link IRQ Management
 
416
   -------------------------------------------------------------------------- */
 
417
 
 
418
/*
 
419
 * "acpi_irq_balance" (default in APIC mode) enables ACPI to use PIC Interrupt
 
420
 * Link Devices to move the PIRQs around to minimize sharing.
 
421
 * 
 
422
 * "acpi_irq_nobalance" (default in PIC mode) tells ACPI not to move any PIC IRQs
 
423
 * that the BIOS has already set to active.  This is necessary because
 
424
 * ACPI has no automatic means of knowing what ISA IRQs are used.  Note that
 
425
 * if the BIOS doesn't set a Link Device active, ACPI needs to program it
 
426
 * even if acpi_irq_nobalance is set.
 
427
 *
 
428
 * A tables of penalties avoids directing PCI interrupts to well known
 
429
 * ISA IRQs. Boot params are available to over-ride the default table:
 
430
 *
 
431
 * List interrupts that are free for PCI use.
 
432
 * acpi_irq_pci=n[,m]
 
433
 *
 
434
 * List interrupts that should not be used for PCI:
 
435
 * acpi_irq_isa=n[,m]
 
436
 *
 
437
 * Note that PCI IRQ routers have a list of possible IRQs,
 
438
 * which may not include the IRQs this table says are available.
 
439
 * 
 
440
 * Since this heuristic can't tell the difference between a link
 
441
 * that no device will attach to, vs. a link which may be shared
 
442
 * by multiple active devices -- it is not optimal.
 
443
 *
 
444
 * If interrupt performance is that important, get an IO-APIC system
 
445
 * with a pin dedicated to each device.  Or for that matter, an MSI
 
446
 * enabled system.
 
447
 */
 
448
 
 
449
#define ACPI_MAX_IRQS           256
 
450
#define ACPI_MAX_ISA_IRQ        16
 
451
 
 
452
#define PIRQ_PENALTY_PCI_AVAILABLE      (0)
 
453
#define PIRQ_PENALTY_PCI_POSSIBLE       (16*16)
 
454
#define PIRQ_PENALTY_PCI_USING          (16*16*16)
 
455
#define PIRQ_PENALTY_ISA_TYPICAL        (16*16*16*16)
 
456
#define PIRQ_PENALTY_ISA_USED           (16*16*16*16*16)
 
457
#define PIRQ_PENALTY_ISA_ALWAYS         (16*16*16*16*16*16)
 
458
 
 
459
static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
 
460
        PIRQ_PENALTY_ISA_ALWAYS,        /* IRQ0 timer */
 
461
        PIRQ_PENALTY_ISA_ALWAYS,        /* IRQ1 keyboard */
 
462
        PIRQ_PENALTY_ISA_ALWAYS,        /* IRQ2 cascade */
 
463
        PIRQ_PENALTY_ISA_TYPICAL,       /* IRQ3 serial */
 
464
        PIRQ_PENALTY_ISA_TYPICAL,       /* IRQ4 serial */
 
465
        PIRQ_PENALTY_ISA_TYPICAL,       /* IRQ5 sometimes SoundBlaster */
 
466
        PIRQ_PENALTY_ISA_TYPICAL,       /* IRQ6 */
 
467
        PIRQ_PENALTY_ISA_TYPICAL,       /* IRQ7 parallel, spurious */
 
468
        PIRQ_PENALTY_ISA_TYPICAL,       /* IRQ8 rtc, sometimes */
 
469
        PIRQ_PENALTY_PCI_AVAILABLE,     /* IRQ9  PCI, often acpi */
 
470
        PIRQ_PENALTY_PCI_AVAILABLE,     /* IRQ10 PCI */
 
471
        PIRQ_PENALTY_PCI_AVAILABLE,     /* IRQ11 PCI */
 
472
        PIRQ_PENALTY_ISA_USED,          /* IRQ12 mouse */
 
473
        PIRQ_PENALTY_ISA_USED,          /* IRQ13 fpe, sometimes */
 
474
        PIRQ_PENALTY_ISA_USED,          /* IRQ14 ide0 */
 
475
        PIRQ_PENALTY_ISA_USED,          /* IRQ15 ide1 */
 
476
        /* >IRQ15 */
 
477
};
 
478
 
 
479
int __init acpi_irq_penalty_init(void)
 
480
{
 
481
        struct acpi_pci_link *link;
 
482
        int i;
 
483
 
 
484
        /*
 
485
         * Update penalties to facilitate IRQ balancing.
 
486
         */
 
487
        list_for_each_entry(link, &acpi_link_list, list) {
 
488
 
 
489
                /*
 
490
                 * reflect the possible and active irqs in the penalty table --
 
491
                 * useful for breaking ties.
 
492
                 */
 
493
                if (link->irq.possible_count) {
 
494
                        int penalty =
 
495
                            PIRQ_PENALTY_PCI_POSSIBLE /
 
496
                            link->irq.possible_count;
 
497
 
 
498
                        for (i = 0; i < link->irq.possible_count; i++) {
 
499
                                if (link->irq.possible[i] < ACPI_MAX_ISA_IRQ)
 
500
                                        acpi_irq_penalty[link->irq.
 
501
                                                         possible[i]] +=
 
502
                                            penalty;
 
503
                        }
 
504
 
 
505
                } else if (link->irq.active) {
 
506
                        acpi_irq_penalty[link->irq.active] +=
 
507
                            PIRQ_PENALTY_PCI_POSSIBLE;
 
508
                }
 
509
        }
 
510
        /* Add a penalty for the SCI */
 
511
        acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING;
 
512
        return 0;
 
513
}
 
514
 
 
515
static int acpi_irq_balance = -1;       /* 0: static, 1: balance */
 
516
 
 
517
static int acpi_pci_link_allocate(struct acpi_pci_link *link)
 
518
{
 
519
        int irq;
 
520
        int i;
 
521
 
 
522
        if (link->irq.initialized) {
 
523
                if (link->refcnt == 0)
 
524
                        /* This means the link is disabled but initialized */
 
525
                        acpi_pci_link_set(link, link->irq.active);
 
526
                return 0;
 
527
        }
 
528
 
 
529
        /*
 
530
         * search for active IRQ in list of possible IRQs.
 
531
         */
 
532
        for (i = 0; i < link->irq.possible_count; ++i) {
 
533
                if (link->irq.active == link->irq.possible[i])
 
534
                        break;
 
535
        }
 
536
        /*
 
537
         * forget active IRQ that is not in possible list
 
538
         */
 
539
        if (i == link->irq.possible_count) {
 
540
                if (acpi_strict)
 
541
                        printk(KERN_WARNING PREFIX "_CRS %d not found"
 
542
                                      " in _PRS\n", link->irq.active);
 
543
                link->irq.active = 0;
 
544
        }
 
545
 
 
546
        /*
 
547
         * if active found, use it; else pick entry from end of possible list.
 
548
         */
 
549
        if (link->irq.active)
 
550
                irq = link->irq.active;
 
551
        else
 
552
                irq = link->irq.possible[link->irq.possible_count - 1];
 
553
 
 
554
        if (acpi_irq_balance || !link->irq.active) {
 
555
                /*
 
556
                 * Select the best IRQ.  This is done in reverse to promote
 
557
                 * the use of IRQs 9, 10, 11, and >15.
 
558
                 */
 
559
                for (i = (link->irq.possible_count - 1); i >= 0; i--) {
 
560
                        if (acpi_irq_penalty[irq] >
 
561
                            acpi_irq_penalty[link->irq.possible[i]])
 
562
                                irq = link->irq.possible[i];
 
563
                }
 
564
        }
 
565
 
 
566
        /* Attempt to enable the link device at this IRQ. */
 
567
        if (acpi_pci_link_set(link, irq)) {
 
568
                printk(KERN_ERR PREFIX "Unable to set IRQ for %s [%s]. "
 
569
                            "Try pci=noacpi or acpi=off\n",
 
570
                            acpi_device_name(link->device),
 
571
                            acpi_device_bid(link->device));
 
572
                return -ENODEV;
 
573
        } else {
 
574
                acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING;
 
575
                printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n",
 
576
                       acpi_device_name(link->device),
 
577
                       acpi_device_bid(link->device), link->irq.active);
 
578
        }
 
579
 
 
580
        link->irq.initialized = 1;
 
581
        return 0;
 
582
}
 
583
 
 
584
/*
 
585
 * acpi_pci_link_allocate_irq
 
586
 * success: return IRQ >= 0
 
587
 * failure: return -1
 
588
 */
 
589
int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,
 
590
                               int *polarity, char **name)
 
591
{
 
592
        int result;
 
593
        struct acpi_device *device;
 
594
        struct acpi_pci_link *link;
 
595
 
 
596
        result = acpi_bus_get_device(handle, &device);
 
597
        if (result) {
 
598
                printk(KERN_ERR PREFIX "Invalid link device\n");
 
599
                return -1;
 
600
        }
 
601
 
 
602
        link = acpi_driver_data(device);
 
603
        if (!link) {
 
604
                printk(KERN_ERR PREFIX "Invalid link context\n");
 
605
                return -1;
 
606
        }
 
607
 
 
608
        /* TBD: Support multiple index (IRQ) entries per Link Device */
 
609
        if (index) {
 
610
                printk(KERN_ERR PREFIX "Invalid index %d\n", index);
 
611
                return -1;
 
612
        }
 
613
 
 
614
        mutex_lock(&acpi_link_lock);
 
615
        if (acpi_pci_link_allocate(link)) {
 
616
                mutex_unlock(&acpi_link_lock);
 
617
                return -1;
 
618
        }
 
619
 
 
620
        if (!link->irq.active) {
 
621
                mutex_unlock(&acpi_link_lock);
 
622
                printk(KERN_ERR PREFIX "Link active IRQ is 0!\n");
 
623
                return -1;
 
624
        }
 
625
        link->refcnt++;
 
626
        mutex_unlock(&acpi_link_lock);
 
627
 
 
628
        if (triggering)
 
629
                *triggering = link->irq.triggering;
 
630
        if (polarity)
 
631
                *polarity = link->irq.polarity;
 
632
        if (name)
 
633
                *name = acpi_device_bid(link->device);
 
634
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 
635
                          "Link %s is referenced\n",
 
636
                          acpi_device_bid(link->device)));
 
637
        return (link->irq.active);
 
638
}
 
639
 
 
640
/*
 
641
 * We don't change link's irq information here.  After it is reenabled, we
 
642
 * continue use the info
 
643
 */
 
644
int acpi_pci_link_free_irq(acpi_handle handle)
 
645
{
 
646
        struct acpi_device *device;
 
647
        struct acpi_pci_link *link;
 
648
        acpi_status result;
 
649
 
 
650
        result = acpi_bus_get_device(handle, &device);
 
651
        if (result) {
 
652
                printk(KERN_ERR PREFIX "Invalid link device\n");
 
653
                return -1;
 
654
        }
 
655
 
 
656
        link = acpi_driver_data(device);
 
657
        if (!link) {
 
658
                printk(KERN_ERR PREFIX "Invalid link context\n");
 
659
                return -1;
 
660
        }
 
661
 
 
662
        mutex_lock(&acpi_link_lock);
 
663
        if (!link->irq.initialized) {
 
664
                mutex_unlock(&acpi_link_lock);
 
665
                printk(KERN_ERR PREFIX "Link isn't initialized\n");
 
666
                return -1;
 
667
        }
 
668
#ifdef  FUTURE_USE
 
669
        /*
 
670
         * The Link reference count allows us to _DISable an unused link
 
671
         * and suspend time, and set it again  on resume.
 
672
         * However, 2.6.12 still has irq_router.resume
 
673
         * which blindly restores the link state.
 
674
         * So we disable the reference count method
 
675
         * to prevent duplicate acpi_pci_link_set()
 
676
         * which would harm some systems
 
677
         */
 
678
        link->refcnt--;
 
679
#endif
 
680
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 
681
                          "Link %s is dereferenced\n",
 
682
                          acpi_device_bid(link->device)));
 
683
 
 
684
        if (link->refcnt == 0)
 
685
                acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL);
 
686
 
 
687
        mutex_unlock(&acpi_link_lock);
 
688
        return (link->irq.active);
 
689
}
 
690
 
 
691
/* --------------------------------------------------------------------------
 
692
                                 Driver Interface
 
693
   -------------------------------------------------------------------------- */
 
694
 
 
695
static int acpi_pci_link_add(struct acpi_device *device)
 
696
{
 
697
        int result;
 
698
        struct acpi_pci_link *link;
 
699
        int i;
 
700
        int found = 0;
 
701
 
 
702
        link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
 
703
        if (!link)
 
704
                return -ENOMEM;
 
705
 
 
706
        link->device = device;
 
707
        strcpy(acpi_device_name(device), ACPI_PCI_LINK_DEVICE_NAME);
 
708
        strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS);
 
709
        device->driver_data = link;
 
710
 
 
711
        mutex_lock(&acpi_link_lock);
 
712
        result = acpi_pci_link_get_possible(link);
 
713
        if (result)
 
714
                goto end;
 
715
 
 
716
        /* query and set link->irq.active */
 
717
        acpi_pci_link_get_current(link);
 
718
 
 
719
        printk(KERN_INFO PREFIX "%s [%s] (IRQs", acpi_device_name(device),
 
720
               acpi_device_bid(device));
 
721
        for (i = 0; i < link->irq.possible_count; i++) {
 
722
                if (link->irq.active == link->irq.possible[i]) {
 
723
                        printk(" *%d", link->irq.possible[i]);
 
724
                        found = 1;
 
725
                } else
 
726
                        printk(" %d", link->irq.possible[i]);
 
727
        }
 
728
 
 
729
        printk(")");
 
730
 
 
731
        if (!found)
 
732
                printk(" *%d", link->irq.active);
 
733
 
 
734
        if (!link->device->status.enabled)
 
735
                printk(", disabled.");
 
736
 
 
737
        printk("\n");
 
738
 
 
739
        list_add_tail(&link->list, &acpi_link_list);
 
740
 
 
741
      end:
 
742
        /* disable all links -- to be activated on use */
 
743
        acpi_evaluate_object(device->handle, "_DIS", NULL, NULL);
 
744
        mutex_unlock(&acpi_link_lock);
 
745
 
 
746
        if (result)
 
747
                kfree(link);
 
748
 
 
749
        return result;
 
750
}
 
751
 
 
752
static int acpi_pci_link_resume(struct acpi_pci_link *link)
 
753
{
 
754
        if (link->refcnt && link->irq.active && link->irq.initialized)
 
755
                return (acpi_pci_link_set(link, link->irq.active));
 
756
 
 
757
        return 0;
 
758
}
 
759
 
 
760
static void irqrouter_resume(void)
 
761
{
 
762
        struct acpi_pci_link *link;
 
763
 
 
764
        list_for_each_entry(link, &acpi_link_list, list) {
 
765
                acpi_pci_link_resume(link);
 
766
        }
 
767
}
 
768
 
 
769
static int acpi_pci_link_remove(struct acpi_device *device, int type)
 
770
{
 
771
        struct acpi_pci_link *link;
 
772
 
 
773
        link = acpi_driver_data(device);
 
774
 
 
775
        mutex_lock(&acpi_link_lock);
 
776
        list_del(&link->list);
 
777
        mutex_unlock(&acpi_link_lock);
 
778
 
 
779
        kfree(link);
 
780
        return 0;
 
781
}
 
782
 
 
783
/*
 
784
 * modify acpi_irq_penalty[] from cmdline
 
785
 */
 
786
static int __init acpi_irq_penalty_update(char *str, int used)
 
787
{
 
788
        int i;
 
789
 
 
790
        for (i = 0; i < 16; i++) {
 
791
                int retval;
 
792
                int irq;
 
793
 
 
794
                retval = get_option(&str, &irq);
 
795
 
 
796
                if (!retval)
 
797
                        break;  /* no number found */
 
798
 
 
799
                if (irq < 0)
 
800
                        continue;
 
801
 
 
802
                if (irq >= ARRAY_SIZE(acpi_irq_penalty))
 
803
                        continue;
 
804
 
 
805
                if (used)
 
806
                        acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
 
807
                else
 
808
                        acpi_irq_penalty[irq] = PIRQ_PENALTY_PCI_AVAILABLE;
 
809
 
 
810
                if (retval != 2)        /* no next number */
 
811
                        break;
 
812
        }
 
813
        return 1;
 
814
}
 
815
 
 
816
/*
 
817
 * We'd like PNP to call this routine for the
 
818
 * single ISA_USED value for each legacy device.
 
819
 * But instead it calls us with each POSSIBLE setting.
 
820
 * There is no ISA_POSSIBLE weight, so we simply use
 
821
 * the (small) PCI_USING penalty.
 
822
 */
 
823
void acpi_penalize_isa_irq(int irq, int active)
 
824
{
 
825
        if (irq >= 0 && irq < ARRAY_SIZE(acpi_irq_penalty)) {
 
826
                if (active)
 
827
                        acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
 
828
                else
 
829
                        acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
 
830
        }
 
831
}
 
832
 
 
833
/*
 
834
 * Over-ride default table to reserve additional IRQs for use by ISA
 
835
 * e.g. acpi_irq_isa=5
 
836
 * Useful for telling ACPI how not to interfere with your ISA sound card.
 
837
 */
 
838
static int __init acpi_irq_isa(char *str)
 
839
{
 
840
        return acpi_irq_penalty_update(str, 1);
 
841
}
 
842
 
 
843
__setup("acpi_irq_isa=", acpi_irq_isa);
 
844
 
 
845
/*
 
846
 * Over-ride default table to free additional IRQs for use by PCI
 
847
 * e.g. acpi_irq_pci=7,15
 
848
 * Used for acpi_irq_balance to free up IRQs to reduce PCI IRQ sharing.
 
849
 */
 
850
static int __init acpi_irq_pci(char *str)
 
851
{
 
852
        return acpi_irq_penalty_update(str, 0);
 
853
}
 
854
 
 
855
__setup("acpi_irq_pci=", acpi_irq_pci);
 
856
 
 
857
static int __init acpi_irq_nobalance_set(char *str)
 
858
{
 
859
        acpi_irq_balance = 0;
 
860
        return 1;
 
861
}
 
862
 
 
863
__setup("acpi_irq_nobalance", acpi_irq_nobalance_set);
 
864
 
 
865
static int __init acpi_irq_balance_set(char *str)
 
866
{
 
867
        acpi_irq_balance = 1;
 
868
        return 1;
 
869
}
 
870
 
 
871
__setup("acpi_irq_balance", acpi_irq_balance_set);
 
872
 
 
873
static struct syscore_ops irqrouter_syscore_ops = {
 
874
        .resume = irqrouter_resume,
 
875
};
 
876
 
 
877
static int __init irqrouter_init_ops(void)
 
878
{
 
879
        if (!acpi_disabled && !acpi_noirq)
 
880
                register_syscore_ops(&irqrouter_syscore_ops);
 
881
 
 
882
        return 0;
 
883
}
 
884
 
 
885
device_initcall(irqrouter_init_ops);
 
886
 
 
887
static int __init acpi_pci_link_init(void)
 
888
{
 
889
        if (acpi_noirq)
 
890
                return 0;
 
891
 
 
892
        if (acpi_irq_balance == -1) {
 
893
                /* no command line switch: enable balancing in IOAPIC mode */
 
894
                if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
 
895
                        acpi_irq_balance = 1;
 
896
                else
 
897
                        acpi_irq_balance = 0;
 
898
        }
 
899
 
 
900
        if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0)
 
901
                return -ENODEV;
 
902
 
 
903
        return 0;
 
904
}
 
905
 
 
906
subsys_initcall(acpi_pci_link_init);