aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pnp')
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c75
1 files changed, 43 insertions, 32 deletions
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 1e296cbef004..6db549c9480c 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 < 0) { 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: