aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/pci_link.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/pci_link.c')
-rw-r--r--drivers/acpi/pci_link.c147
1 files changed, 48 insertions, 99 deletions
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 6c772ca76bd1..16e0f9d3d17c 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -43,13 +43,14 @@
43#include <acpi/acpi_bus.h> 43#include <acpi/acpi_bus.h>
44#include <acpi/acpi_drivers.h> 44#include <acpi/acpi_drivers.h>
45 45
46#define _COMPONENT ACPI_PCI_COMPONENT 46#define _COMPONENT ACPI_PCI_COMPONENT
47ACPI_MODULE_NAME("pci_link"); 47ACPI_MODULE_NAME("pci_link");
48#define ACPI_PCI_LINK_CLASS "pci_irq_routing" 48#define ACPI_PCI_LINK_CLASS "pci_irq_routing"
49#define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link" 49#define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link"
50#define ACPI_PCI_LINK_FILE_INFO "info" 50#define ACPI_PCI_LINK_FILE_INFO "info"
51#define ACPI_PCI_LINK_FILE_STATUS "state" 51#define ACPI_PCI_LINK_FILE_STATUS "state"
52#define ACPI_PCI_LINK_MAX_POSSIBLE 16 52#define ACPI_PCI_LINK_MAX_POSSIBLE 16
53
53static int acpi_pci_link_add(struct acpi_device *device); 54static int acpi_pci_link_add(struct acpi_device *device);
54static int acpi_pci_link_remove(struct acpi_device *device, int type); 55static int acpi_pci_link_remove(struct acpi_device *device, int type);
55 56
@@ -66,7 +67,7 @@ static struct acpi_driver acpi_pci_link_driver = {
66 .ops = { 67 .ops = {
67 .add = acpi_pci_link_add, 68 .add = acpi_pci_link_add,
68 .remove = acpi_pci_link_remove, 69 .remove = acpi_pci_link_remove,
69 }, 70 },
70}; 71};
71 72
72/* 73/*
@@ -76,7 +77,7 @@ static struct acpi_driver acpi_pci_link_driver = {
76struct acpi_pci_link_irq { 77struct acpi_pci_link_irq {
77 u8 active; /* Current IRQ */ 78 u8 active; /* Current IRQ */
78 u8 triggering; /* All IRQs */ 79 u8 triggering; /* All IRQs */
79 u8 polarity; /* All IRQs */ 80 u8 polarity; /* All IRQs */
80 u8 resource_type; 81 u8 resource_type;
81 u8 possible_count; 82 u8 possible_count;
82 u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE]; 83 u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
@@ -85,16 +86,13 @@ struct acpi_pci_link_irq {
85}; 86};
86 87
87struct acpi_pci_link { 88struct acpi_pci_link {
88 struct list_head node; 89 struct list_head list;
89 struct acpi_device *device; 90 struct acpi_device *device;
90 struct acpi_pci_link_irq irq; 91 struct acpi_pci_link_irq irq;
91 int refcnt; 92 int refcnt;
92}; 93};
93 94
94static struct { 95static LIST_HEAD(acpi_link_list);
95 int count;
96 struct list_head entries;
97} acpi_link;
98static DEFINE_MUTEX(acpi_link_lock); 96static DEFINE_MUTEX(acpi_link_lock);
99 97
100/* -------------------------------------------------------------------------- 98/* --------------------------------------------------------------------------
@@ -104,12 +102,11 @@ static DEFINE_MUTEX(acpi_link_lock);
104/* 102/*
105 * set context (link) possible list from resource list 103 * set context (link) possible list from resource list
106 */ 104 */
107static acpi_status 105static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource,
108acpi_pci_link_check_possible(struct acpi_resource *resource, void *context) 106 void *context)
109{ 107{
110 struct acpi_pci_link *link = context; 108 struct acpi_pci_link *link = context;
111 u32 i = 0; 109 u32 i;
112
113 110
114 switch (resource->type) { 111 switch (resource->type) {
115 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 112 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -179,10 +176,6 @@ static int acpi_pci_link_get_possible(struct acpi_pci_link *link)
179{ 176{
180 acpi_status status; 177 acpi_status status;
181 178
182
183 if (!link)
184 return -EINVAL;
185
186 status = acpi_walk_resources(link->device->handle, METHOD_NAME__PRS, 179 status = acpi_walk_resources(link->device->handle, METHOD_NAME__PRS,
187 acpi_pci_link_check_possible, link); 180 acpi_pci_link_check_possible, link);
188 if (ACPI_FAILURE(status)) { 181 if (ACPI_FAILURE(status)) {
@@ -197,11 +190,10 @@ static int acpi_pci_link_get_possible(struct acpi_pci_link *link)
197 return 0; 190 return 0;
198} 191}
199 192
200static acpi_status 193static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource,
201acpi_pci_link_check_current(struct acpi_resource *resource, void *context) 194 void *context)
202{ 195{
203 int *irq = (int *)context; 196 int *irq = context;
204
205 197
206 switch (resource->type) { 198 switch (resource->type) {
207 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 199 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -258,12 +250,9 @@ acpi_pci_link_check_current(struct acpi_resource *resource, void *context)
258static int acpi_pci_link_get_current(struct acpi_pci_link *link) 250static int acpi_pci_link_get_current(struct acpi_pci_link *link)
259{ 251{
260 int result = 0; 252 int result = 0;
261 acpi_status status = AE_OK; 253 acpi_status status;
262 int irq = 0; 254 int irq = 0;
263 255
264 if (!link)
265 return -EINVAL;
266
267 link->irq.active = 0; 256 link->irq.active = 0;
268 257
269 /* in practice, status disabled is meaningless, ignore it */ 258 /* in practice, status disabled is meaningless, ignore it */
@@ -308,16 +297,15 @@ static int acpi_pci_link_get_current(struct acpi_pci_link *link)
308 297
309static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) 298static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
310{ 299{
311 int result = 0; 300 int result;
312 acpi_status status = AE_OK; 301 acpi_status status;
313 struct { 302 struct {
314 struct acpi_resource res; 303 struct acpi_resource res;
315 struct acpi_resource end; 304 struct acpi_resource end;
316 } *resource; 305 } *resource;
317 struct acpi_buffer buffer = { 0, NULL }; 306 struct acpi_buffer buffer = { 0, NULL };
318 307
319 308 if (!irq)
320 if (!link || !irq)
321 return -EINVAL; 309 return -EINVAL;
322 310
323 resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); 311 resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
@@ -479,30 +467,22 @@ static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
479 PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ9 PCI, often acpi */ 467 PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ9 PCI, often acpi */
480 PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ10 PCI */ 468 PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ10 PCI */
481 PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ11 PCI */ 469 PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ11 PCI */
482 PIRQ_PENALTY_ISA_USED, /* IRQ12 mouse */ 470 PIRQ_PENALTY_ISA_USED, /* IRQ12 mouse */
483 PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */ 471 PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */
484 PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */ 472 PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */
485 PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */ 473 PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */
486 /* >IRQ15 */ 474 /* >IRQ15 */
487}; 475};
488 476
489int __init acpi_irq_penalty_init(void) 477int __init acpi_irq_penalty_init(void)
490{ 478{
491 struct list_head *node = NULL; 479 struct acpi_pci_link *link;
492 struct acpi_pci_link *link = NULL; 480 int i;
493 int i = 0;
494
495 481
496 /* 482 /*
497 * Update penalties to facilitate IRQ balancing. 483 * Update penalties to facilitate IRQ balancing.
498 */ 484 */
499 list_for_each(node, &acpi_link.entries) { 485 list_for_each_entry(link, &acpi_link_list, list) {
500
501 link = list_entry(node, struct acpi_pci_link, node);
502 if (!link) {
503 printk(KERN_ERR PREFIX "Invalid link context\n");
504 continue;
505 }
506 486
507 /* 487 /*
508 * reflect the possible and active irqs in the penalty table -- 488 * reflect the possible and active irqs in the penalty table --
@@ -527,7 +507,6 @@ int __init acpi_irq_penalty_init(void)
527 } 507 }
528 /* Add a penalty for the SCI */ 508 /* Add a penalty for the SCI */
529 acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING; 509 acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING;
530
531 return 0; 510 return 0;
532} 511}
533 512
@@ -538,7 +517,6 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
538 int irq; 517 int irq;
539 int i; 518 int i;
540 519
541
542 if (link->irq.initialized) { 520 if (link->irq.initialized) {
543 if (link->refcnt == 0) 521 if (link->refcnt == 0)
544 /* This means the link is disabled but initialized */ 522 /* This means the link is disabled but initialized */
@@ -566,11 +544,10 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
566 /* 544 /*
567 * if active found, use it; else pick entry from end of possible list. 545 * if active found, use it; else pick entry from end of possible list.
568 */ 546 */
569 if (link->irq.active) { 547 if (link->irq.active)
570 irq = link->irq.active; 548 irq = link->irq.active;
571 } else { 549 else
572 irq = link->irq.possible[link->irq.possible_count - 1]; 550 irq = link->irq.possible[link->irq.possible_count - 1];
573 }
574 551
575 if (acpi_irq_balance || !link->irq.active) { 552 if (acpi_irq_balance || !link->irq.active) {
576 /* 553 /*
@@ -599,7 +576,6 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
599 } 576 }
600 577
601 link->irq.initialized = 1; 578 link->irq.initialized = 1;
602
603 return 0; 579 return 0;
604} 580}
605 581
@@ -608,16 +584,12 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
608 * success: return IRQ >= 0 584 * success: return IRQ >= 0
609 * failure: return -1 585 * failure: return -1
610 */ 586 */
611 587int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,
612int 588 int *polarity, char **name)
613acpi_pci_link_allocate_irq(acpi_handle handle,
614 int index,
615 int *triggering, int *polarity, char **name)
616{ 589{
617 int result = 0; 590 int result;
618 struct acpi_device *device = NULL; 591 struct acpi_device *device;
619 struct acpi_pci_link *link = NULL; 592 struct acpi_pci_link *link;
620
621 593
622 result = acpi_bus_get_device(handle, &device); 594 result = acpi_bus_get_device(handle, &device);
623 if (result) { 595 if (result) {
@@ -669,11 +641,10 @@ acpi_pci_link_allocate_irq(acpi_handle handle,
669 */ 641 */
670int acpi_pci_link_free_irq(acpi_handle handle) 642int acpi_pci_link_free_irq(acpi_handle handle)
671{ 643{
672 struct acpi_device *device = NULL; 644 struct acpi_device *device;
673 struct acpi_pci_link *link = NULL; 645 struct acpi_pci_link *link;
674 acpi_status result; 646 acpi_status result;
675 647
676
677 result = acpi_bus_get_device(handle, &device); 648 result = acpi_bus_get_device(handle, &device);
678 if (result) { 649 if (result) {
679 printk(KERN_ERR PREFIX "Invalid link device\n"); 650 printk(KERN_ERR PREFIX "Invalid link device\n");
@@ -708,9 +679,9 @@ int acpi_pci_link_free_irq(acpi_handle handle)
708 "Link %s is dereferenced\n", 679 "Link %s is dereferenced\n",
709 acpi_device_bid(link->device))); 680 acpi_device_bid(link->device)));
710 681
711 if (link->refcnt == 0) { 682 if (link->refcnt == 0)
712 acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL); 683 acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL);
713 } 684
714 mutex_unlock(&acpi_link_lock); 685 mutex_unlock(&acpi_link_lock);
715 return (link->irq.active); 686 return (link->irq.active);
716} 687}
@@ -721,15 +692,11 @@ int acpi_pci_link_free_irq(acpi_handle handle)
721 692
722static int acpi_pci_link_add(struct acpi_device *device) 693static int acpi_pci_link_add(struct acpi_device *device)
723{ 694{
724 int result = 0; 695 int result;
725 struct acpi_pci_link *link = NULL; 696 struct acpi_pci_link *link;
726 int i = 0; 697 int i;
727 int found = 0; 698 int found = 0;
728 699
729
730 if (!device)
731 return -EINVAL;
732
733 link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL); 700 link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
734 if (!link) 701 if (!link)
735 return -ENOMEM; 702 return -ENOMEM;
@@ -767,9 +734,7 @@ static int acpi_pci_link_add(struct acpi_device *device)
767 734
768 printk("\n"); 735 printk("\n");
769 736
770 /* TBD: Acquire/release lock */ 737 list_add_tail(&link->list, &acpi_link_list);
771 list_add_tail(&link->node, &acpi_link.entries);
772 acpi_link.count++;
773 738
774 end: 739 end:
775 /* disable all links -- to be activated on use */ 740 /* disable all links -- to be activated on use */
@@ -784,24 +749,17 @@ static int acpi_pci_link_add(struct acpi_device *device)
784 749
785static int acpi_pci_link_resume(struct acpi_pci_link *link) 750static int acpi_pci_link_resume(struct acpi_pci_link *link)
786{ 751{
787
788 if (link->refcnt && link->irq.active && link->irq.initialized) 752 if (link->refcnt && link->irq.active && link->irq.initialized)
789 return (acpi_pci_link_set(link, link->irq.active)); 753 return (acpi_pci_link_set(link, link->irq.active));
790 else 754
791 return 0; 755 return 0;
792} 756}
793 757
794static int irqrouter_resume(struct sys_device *dev) 758static int irqrouter_resume(struct sys_device *dev)
795{ 759{
796 struct list_head *node = NULL; 760 struct acpi_pci_link *link;
797 struct acpi_pci_link *link = NULL;
798 761
799 list_for_each(node, &acpi_link.entries) { 762 list_for_each_entry(link, &acpi_link_list, list) {
800 link = list_entry(node, struct acpi_pci_link, node);
801 if (!link) {
802 printk(KERN_ERR PREFIX "Invalid link context\n");
803 continue;
804 }
805 acpi_pci_link_resume(link); 763 acpi_pci_link_resume(link);
806 } 764 }
807 return 0; 765 return 0;
@@ -809,20 +767,15 @@ static int irqrouter_resume(struct sys_device *dev)
809 767
810static int acpi_pci_link_remove(struct acpi_device *device, int type) 768static int acpi_pci_link_remove(struct acpi_device *device, int type)
811{ 769{
812 struct acpi_pci_link *link = NULL; 770 struct acpi_pci_link *link;
813
814
815 if (!device || !acpi_driver_data(device))
816 return -EINVAL;
817 771
818 link = acpi_driver_data(device); 772 link = acpi_driver_data(device);
819 773
820 mutex_lock(&acpi_link_lock); 774 mutex_lock(&acpi_link_lock);
821 list_del(&link->node); 775 list_del(&link->list);
822 mutex_unlock(&acpi_link_lock); 776 mutex_unlock(&acpi_link_lock);
823 777
824 kfree(link); 778 kfree(link);
825
826 return 0; 779 return 0;
827} 780}
828 781
@@ -931,7 +884,6 @@ static int __init irqrouter_init_sysfs(void)
931{ 884{
932 int error; 885 int error;
933 886
934
935 if (acpi_disabled || acpi_noirq) 887 if (acpi_disabled || acpi_noirq)
936 return 0; 888 return 0;
937 889
@@ -957,9 +909,6 @@ static int __init acpi_pci_link_init(void)
957 acpi_irq_balance = 0; 909 acpi_irq_balance = 0;
958 } 910 }
959 911
960 acpi_link.count = 0;
961 INIT_LIST_HEAD(&acpi_link.entries);
962
963 if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0) 912 if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0)
964 return -ENODEV; 913 return -ENODEV;
965 914