Merge linux-2.6 with linux-acpi-2.6
[firefly-linux-kernel-4.4.55.git] / drivers / pnp / pnpacpi / rsparser.c
index 75575f6c349c65919871f32afe3dc8e83fbc3219..416d30debe6c97a12582c7646d3bb6d3eab46ec8 100644 (file)
@@ -73,25 +73,35 @@ static void decode_irq_flags(int flag, int *edge_level, int *active_high_low)
 }
 
 static void
-pnpacpi_parse_allocated_irqresource(struct pnp_resource_table * res, int irq)
+pnpacpi_parse_allocated_irqresource(struct pnp_resource_table * res, u32 gsi,
+       int edge_level, int active_high_low)
 {
        int i = 0;
+       int irq;
+
+       if (!valid_IRQ(gsi))
+               return;
+
        while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) &&
                        i < PNP_MAX_IRQ)
                i++;
-       if (i < PNP_MAX_IRQ) {
-               res->irq_resource[i].flags = IORESOURCE_IRQ;  //Also clears _UNSET flag
-               if (irq == -1) {
-                       res->irq_resource[i].flags |= IORESOURCE_DISABLED;
-                       return;
-               }
-               res->irq_resource[i].start =(unsigned long) irq;
-               res->irq_resource[i].end = (unsigned long) irq;
+       if (i >= PNP_MAX_IRQ)
+               return;
+
+       res->irq_resource[i].flags = IORESOURCE_IRQ;  // Also clears _UNSET flag
+       irq = acpi_register_gsi(gsi, edge_level, active_high_low);
+       if (irq < 0) {
+               res->irq_resource[i].flags |= IORESOURCE_DISABLED;
+               return;
        }
+
+       res->irq_resource[i].start = irq;
+       res->irq_resource[i].end = irq;
+       pcibios_penalize_isa_irq(irq, 1);
 }
 
 static void
-pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma)
+pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, u32 dma)
 {
        int i = 0;
        while (i < PNP_MAX_DMA &&
@@ -103,14 +113,14 @@ pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma)
                        res->dma_resource[i].flags |= IORESOURCE_DISABLED;
                        return;
                }
-               res->dma_resource[i].start =(unsigned long) dma;
-               res->dma_resource[i].end = (unsigned long) dma;
+               res->dma_resource[i].start = dma;
+               res->dma_resource[i].end = dma;
        }
 }
 
 static void
 pnpacpi_parse_allocated_ioresource(struct pnp_resource_table * res,
-       int io, int len)
+       u32 io, u32 len)
 {
        int i = 0;
        while (!(res->port_resource[i].flags & IORESOURCE_UNSET) &&
@@ -122,14 +132,14 @@ pnpacpi_parse_allocated_ioresource(struct pnp_resource_table * res,
                        res->port_resource[i].flags |= IORESOURCE_DISABLED;
                        return;
                }
-               res->port_resource[i].start = (unsigned long) io;
-               res->port_resource[i].end = (unsigned long)(io + len - 1);
+               res->port_resource[i].start = io;
+               res->port_resource[i].end = io + len - 1;
        }
 }
 
 static void
 pnpacpi_parse_allocated_memresource(struct pnp_resource_table * res,
-       int mem, int len)
+       u64 mem, u64 len)
 {
        int i = 0;
        while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) &&
@@ -141,8 +151,8 @@ pnpacpi_parse_allocated_memresource(struct pnp_resource_table * res,
                        res->mem_resource[i].flags |= IORESOURCE_DISABLED;
                        return;
                }
-               res->mem_resource[i].start = (unsigned long) mem;
-               res->mem_resource[i].end = (unsigned long)(mem + len - 1);
+               res->mem_resource[i].start = mem;
+               res->mem_resource[i].end = mem + len - 1;
        }
 }
 
@@ -151,27 +161,28 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
        void *data)
 {
        struct pnp_resource_table * res_table = (struct pnp_resource_table *)data;
+       int i;
 
        switch (res->id) {
        case ACPI_RSTYPE_IRQ:
-               if ((res->data.irq.number_of_interrupts > 0) &&
-                       valid_IRQ(res->data.irq.interrupts[0])) {
-                       pnpacpi_parse_allocated_irqresource(res_table, 
-                               acpi_register_gsi(res->data.irq.interrupts[0],
-                                       res->data.irq.edge_level,
-                                       res->data.irq.active_high_low));
-                       pcibios_penalize_isa_irq(res->data.irq.interrupts[0], 1);
+               /*
+                * Per spec, only one interrupt per descriptor is allowed in
+                * _CRS, but some firmware violates this, so parse them all.
+                */
+               for (i = 0; i < res->data.irq.number_of_interrupts; i++) {
+                       pnpacpi_parse_allocated_irqresource(res_table,
+                               res->data.irq.interrupts[i],
+                               res->data.irq.edge_level,
+                               res->data.irq.active_high_low);
                }
                break;
 
        case ACPI_RSTYPE_EXT_IRQ:
-               if ((res->data.extended_irq.number_of_interrupts > 0) &&
-                       valid_IRQ(res->data.extended_irq.interrupts[0])) {
-                       pnpacpi_parse_allocated_irqresource(res_table, 
-                               acpi_register_gsi(res->data.extended_irq.interrupts[0],
-                                       res->data.extended_irq.edge_level,
-                                       res->data.extended_irq.active_high_low));
-                       pcibios_penalize_isa_irq(res->data.extended_irq.interrupts[0], 1);
+               for (i = 0; i < res->data.extended_irq.number_of_interrupts; i++) {
+                       pnpacpi_parse_allocated_irqresource(res_table,
+                               res->data.extended_irq.interrupts[i],
+                               res->data.extended_irq.edge_level,
+                               res->data.extended_irq.active_high_low);
                }
                break;
        case ACPI_RSTYPE_DMA:
@@ -244,7 +255,7 @@ static void pnpacpi_parse_dma_option(struct pnp_option *option, struct acpi_reso
 
        if (p->number_of_channels == 0)
                return;
-       dma = pnpacpi_kmalloc(sizeof(struct pnp_dma), GFP_KERNEL);
+       dma = kcalloc(1, sizeof(struct pnp_dma), GFP_KERNEL);
        if (!dma)
                return;
 
@@ -300,7 +311,7 @@ static void pnpacpi_parse_irq_option(struct pnp_option *option,
        
        if (p->number_of_interrupts == 0)
                return;
-       irq = pnpacpi_kmalloc(sizeof(struct pnp_irq), GFP_KERNEL);
+       irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL);
        if (!irq)
                return;
 
@@ -321,7 +332,7 @@ static void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
 
        if (p->number_of_interrupts == 0)
                return;
-       irq = pnpacpi_kmalloc(sizeof(struct pnp_irq), GFP_KERNEL);
+       irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL);
        if (!irq)
                return;
 
@@ -342,7 +353,7 @@ pnpacpi_parse_port_option(struct pnp_option *option,
 
        if (io->range_length == 0)
                return;
-       port = pnpacpi_kmalloc(sizeof(struct pnp_port), GFP_KERNEL);
+       port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
        if (!port)
                return;
        port->min = io->min_base_address;
@@ -363,7 +374,7 @@ pnpacpi_parse_fixed_port_option(struct pnp_option *option,
 
        if (io->range_length == 0)
                return;
-       port = pnpacpi_kmalloc(sizeof(struct pnp_port), GFP_KERNEL);
+       port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
        if (!port)
                return;
        port->min = port->max = io->base_address;
@@ -382,7 +393,7 @@ pnpacpi_parse_mem24_option(struct pnp_option *option,
 
        if (p->range_length == 0)
                return;
-       mem = pnpacpi_kmalloc(sizeof(struct pnp_mem), GFP_KERNEL);
+       mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
        if (!mem)
                return;
        mem->min = p->min_base_address;
@@ -405,7 +416,7 @@ pnpacpi_parse_mem32_option(struct pnp_option *option,
 
        if (p->range_length == 0)
                return;
-       mem = pnpacpi_kmalloc(sizeof(struct pnp_mem), GFP_KERNEL);
+       mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
        if (!mem)
                return;
        mem->min = p->min_base_address;
@@ -428,7 +439,7 @@ pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
 
        if (p->range_length == 0)
                return;
-       mem = pnpacpi_kmalloc(sizeof(struct pnp_mem), GFP_KERNEL);
+       mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
        if (!mem)
                return;
        mem->min = mem->max = p->range_base_address;
@@ -612,7 +623,7 @@ int pnpacpi_build_resource_template(acpi_handle handle,
        if (!res_cnt)
                return -EINVAL;
        buffer->length = sizeof(struct acpi_resource) * (res_cnt + 1) + 1;
-       buffer->pointer = pnpacpi_kmalloc(buffer->length - 1, GFP_KERNEL);
+       buffer->pointer = kcalloc(1, buffer->length - 1, GFP_KERNEL);
        if (!buffer->pointer)
                return -ENOMEM;
        pnp_dbg("Res cnt %d", res_cnt);