aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pnp')
-rw-r--r--drivers/pnp/Kconfig2
-rw-r--r--drivers/pnp/pnpacpi/Kconfig2
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c75
3 files changed, 45 insertions, 34 deletions
diff --git a/drivers/pnp/Kconfig b/drivers/pnp/Kconfig
index 6776308a1fe5..c5143201419a 100644
--- a/drivers/pnp/Kconfig
+++ b/drivers/pnp/Kconfig
@@ -6,7 +6,7 @@ menu "Plug and Play support"
6 6
7config PNP 7config PNP
8 bool "Plug and Play support" 8 bool "Plug and Play support"
9 depends on ISA || ACPI_BUS 9 depends on ISA || ACPI
10 ---help--- 10 ---help---
11 Plug and Play (PnP) is a standard for peripherals which allows those 11 Plug and Play (PnP) is a standard for peripherals which allows those
12 peripherals to be configured by software, e.g. assign IRQ's or other 12 peripherals to be configured by software, e.g. assign IRQ's or other
diff --git a/drivers/pnp/pnpacpi/Kconfig b/drivers/pnp/pnpacpi/Kconfig
index 0782cdc5009f..b1854171b963 100644
--- a/drivers/pnp/pnpacpi/Kconfig
+++ b/drivers/pnp/pnpacpi/Kconfig
@@ -3,7 +3,7 @@
3# 3#
4config PNPACPI 4config PNPACPI
5 bool "Plug and Play ACPI support (EXPERIMENTAL)" 5 bool "Plug and Play ACPI support (EXPERIMENTAL)"
6 depends on PNP && ACPI_BUS && EXPERIMENTAL 6 depends on PNP && ACPI && EXPERIMENTAL
7 default y 7 default y
8 ---help--- 8 ---help---
9 Linux uses the PNPACPI to autodetect built-in 9 Linux uses the PNPACPI to autodetect built-in
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 675b76a42403..416d30debe6c 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -73,25 +73,35 @@ static void decode_irq_flags(int flag, int *edge_level, int *active_high_low)
73} 73}
74 74
75static void 75static void
76pnpacpi_parse_allocated_irqresource(struct pnp_resource_table * res, int irq) 76pnpacpi_parse_allocated_irqresource(struct pnp_resource_table * res, u32 gsi,
77 int edge_level, int active_high_low)
77{ 78{
78 int i = 0; 79 int i = 0;
80 int irq;
81
82 if (!valid_IRQ(gsi))
83 return;
84
79 while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) && 85 while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) &&
80 i < PNP_MAX_IRQ) 86 i < PNP_MAX_IRQ)
81 i++; 87 i++;
82 if (i < PNP_MAX_IRQ) { 88 if (i >= PNP_MAX_IRQ)
83 res->irq_resource[i].flags = IORESOURCE_IRQ; //Also clears _UNSET flag 89 return;
84 if (irq == -1) { 90
85 res->irq_resource[i].flags |= IORESOURCE_DISABLED; 91 res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag
86 return; 92 irq = acpi_register_gsi(gsi, edge_level, active_high_low);
87 } 93 if (irq < 0) {
88 res->irq_resource[i].start =(unsigned long) irq; 94 res->irq_resource[i].flags |= IORESOURCE_DISABLED;
89 res->irq_resource[i].end = (unsigned long) irq; 95 return;
90 } 96 }
97
98 res->irq_resource[i].start = irq;
99 res->irq_resource[i].end = irq;
100 pcibios_penalize_isa_irq(irq, 1);
91} 101}
92 102
93static void 103static void
94pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma) 104pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, u32 dma)
95{ 105{
96 int i = 0; 106 int i = 0;
97 while (i < PNP_MAX_DMA && 107 while (i < PNP_MAX_DMA &&
@@ -103,14 +113,14 @@ pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma)
103 res->dma_resource[i].flags |= IORESOURCE_DISABLED; 113 res->dma_resource[i].flags |= IORESOURCE_DISABLED;
104 return; 114 return;
105 } 115 }
106 res->dma_resource[i].start =(unsigned long) dma; 116 res->dma_resource[i].start = dma;
107 res->dma_resource[i].end = (unsigned long) dma; 117 res->dma_resource[i].end = dma;
108 } 118 }
109} 119}
110 120
111static void 121static void
112pnpacpi_parse_allocated_ioresource(struct pnp_resource_table * res, 122pnpacpi_parse_allocated_ioresource(struct pnp_resource_table * res,
113 int io, int len) 123 u32 io, u32 len)
114{ 124{
115 int i = 0; 125 int i = 0;
116 while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && 126 while (!(res->port_resource[i].flags & IORESOURCE_UNSET) &&
@@ -122,14 +132,14 @@ pnpacpi_parse_allocated_ioresource(struct pnp_resource_table * res,
122 res->port_resource[i].flags |= IORESOURCE_DISABLED; 132 res->port_resource[i].flags |= IORESOURCE_DISABLED;
123 return; 133 return;
124 } 134 }
125 res->port_resource[i].start = (unsigned long) io; 135 res->port_resource[i].start = io;
126 res->port_resource[i].end = (unsigned long)(io + len - 1); 136 res->port_resource[i].end = io + len - 1;
127 } 137 }
128} 138}
129 139
130static void 140static void
131pnpacpi_parse_allocated_memresource(struct pnp_resource_table * res, 141pnpacpi_parse_allocated_memresource(struct pnp_resource_table * res,
132 int mem, int len) 142 u64 mem, u64 len)
133{ 143{
134 int i = 0; 144 int i = 0;
135 while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) && 145 while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) &&
@@ -141,8 +151,8 @@ pnpacpi_parse_allocated_memresource(struct pnp_resource_table * res,
141 res->mem_resource[i].flags |= IORESOURCE_DISABLED; 151 res->mem_resource[i].flags |= IORESOURCE_DISABLED;
142 return; 152 return;
143 } 153 }
144 res->mem_resource[i].start = (unsigned long) mem; 154 res->mem_resource[i].start = mem;
145 res->mem_resource[i].end = (unsigned long)(mem + len - 1); 155 res->mem_resource[i].end = mem + len - 1;
146 } 156 }
147} 157}
148 158
@@ -151,27 +161,28 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
151 void *data) 161 void *data)
152{ 162{
153 struct pnp_resource_table * res_table = (struct pnp_resource_table *)data; 163 struct pnp_resource_table * res_table = (struct pnp_resource_table *)data;
164 int i;
154 165
155 switch (res->id) { 166 switch (res->id) {
156 case ACPI_RSTYPE_IRQ: 167 case ACPI_RSTYPE_IRQ:
157 if ((res->data.irq.number_of_interrupts > 0) && 168 /*
158 valid_IRQ(res->data.irq.interrupts[0])) { 169 * Per spec, only one interrupt per descriptor is allowed in
159 pnpacpi_parse_allocated_irqresource(res_table, 170 * _CRS, but some firmware violates this, so parse them all.
160 acpi_register_gsi(res->data.irq.interrupts[0], 171 */
161 res->data.irq.edge_level, 172 for (i = 0; i < res->data.irq.number_of_interrupts; i++) {
162 res->data.irq.active_high_low)); 173 pnpacpi_parse_allocated_irqresource(res_table,
163 pcibios_penalize_isa_irq(res->data.irq.interrupts[0], 1); 174 res->data.irq.interrupts[i],
175 res->data.irq.edge_level,
176 res->data.irq.active_high_low);
164 } 177 }
165 break; 178 break;
166 179
167 case ACPI_RSTYPE_EXT_IRQ: 180 case ACPI_RSTYPE_EXT_IRQ:
168 if ((res->data.extended_irq.number_of_interrupts > 0) && 181 for (i = 0; i < res->data.extended_irq.number_of_interrupts; i++) {
169 valid_IRQ(res->data.extended_irq.interrupts[0])) { 182 pnpacpi_parse_allocated_irqresource(res_table,
170 pnpacpi_parse_allocated_irqresource(res_table, 183 res->data.extended_irq.interrupts[i],
171 acpi_register_gsi(res->data.extended_irq.interrupts[0], 184 res->data.extended_irq.edge_level,
172 res->data.extended_irq.edge_level, 185 res->data.extended_irq.active_high_low);
173 res->data.extended_irq.active_high_low));
174 pcibios_penalize_isa_irq(res->data.extended_irq.interrupts[0], 1);
175 } 186 }
176 break; 187 break;
177 case ACPI_RSTYPE_DMA: 188 case ACPI_RSTYPE_DMA: