static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, void *data) { struct pnp_dev *dev = data; struct acpi_resource_irq *irq; struct acpi_resource_dma *dma; struct acpi_resource_io *io; struct acpi_resource_fixed_io *fixed_io; struct acpi_resource_vendor_typed *vendor_typed; struct acpi_resource_memory24 *memory24; struct acpi_resource_memory32 *memory32; struct acpi_resource_fixed_memory32 *fixed_memory32; struct acpi_resource_extended_irq *extended_irq; int i, flags; switch (res->type) { case ACPI_RESOURCE_TYPE_IRQ: /* * Per spec, only one interrupt per descriptor is allowed in * _CRS, but some firmware violates this, so parse them all. */ irq = &res->data.irq; if (irq->interrupt_count == 0) pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); else { for (i = 0; i < irq->interrupt_count; i++) { pnpacpi_parse_allocated_irqresource(dev, irq->interrupts[i], irq->triggering, irq->polarity, irq->sharable); } /* * The IRQ encoder puts a single interrupt in each * descriptor, so if a _CRS descriptor has more than * one interrupt, we won't be able to re-encode it. */ if (pnp_can_write(dev) && irq->interrupt_count > 1) { dev_warn(&dev->dev, "multiple interrupts in " "_CRS descriptor; configuration can't " "be changed\n"); dev->capabilities &= ~PNP_WRITE; } } break; case ACPI_RESOURCE_TYPE_DMA: dma = &res->data.dma; if (dma->channel_count > 0 && dma->channels[0] != (u8) -1) flags = dma_flags(dev, dma->type, dma->bus_master, dma->transfer); else flags = IORESOURCE_DISABLED; pnp_add_dma_resource(dev, dma->channels[0], flags); break; case ACPI_RESOURCE_TYPE_IO: io = &res->data.io; pnpacpi_parse_allocated_ioresource(dev, io->minimum, io->address_length, io->io_decode); break; case ACPI_RESOURCE_TYPE_START_DEPENDENT: case ACPI_RESOURCE_TYPE_END_DEPENDENT: break; case ACPI_RESOURCE_TYPE_FIXED_IO: fixed_io = &res->data.fixed_io; pnpacpi_parse_allocated_ioresource(dev, fixed_io->address, fixed_io->address_length, ACPI_DECODE_10); break; case ACPI_RESOURCE_TYPE_VENDOR: vendor_typed = &res->data.vendor_typed; pnpacpi_parse_allocated_vendor(dev, vendor_typed); break; case ACPI_RESOURCE_TYPE_END_TAG: break; case ACPI_RESOURCE_TYPE_MEMORY24: memory24 = &res->data.memory24; pnpacpi_parse_allocated_memresource(dev, memory24->minimum, memory24->address_length, memory24->write_protect); break; case ACPI_RESOURCE_TYPE_MEMORY32: memory32 = &res->data.memory32; pnpacpi_parse_allocated_memresource(dev, memory32->minimum, memory32->address_length, memory32->write_protect); break; case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: fixed_memory32 = &res->data.fixed_memory32; pnpacpi_parse_allocated_memresource(dev, fixed_memory32->address, fixed_memory32->address_length, fixed_memory32->write_protect); break; case ACPI_RESOURCE_TYPE_ADDRESS16: case ACPI_RESOURCE_TYPE_ADDRESS32: case ACPI_RESOURCE_TYPE_ADDRESS64: pnpacpi_parse_allocated_address_space(dev, res); break; case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER) return AE_OK; break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: extended_irq = &res->data.extended_irq; if (extended_irq->interrupt_count == 0) pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); else { for (i = 0; i < extended_irq->interrupt_count; i++) { pnpacpi_parse_allocated_irqresource(dev, extended_irq->interrupts[i], extended_irq->triggering, extended_irq->polarity, extended_irq->sharable); } /* * The IRQ encoder puts a single interrupt in each * descriptor, so if a _CRS descriptor has more than * one interrupt, we won't be able to re-encode it. */ if (pnp_can_write(dev) && extended_irq->interrupt_count > 1) { dev_warn(&dev->dev, "multiple interrupts in " "_CRS descriptor; configuration can't " "be changed\n"); dev->capabilities &= ~PNP_WRITE; } } break; case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: break; default: dev_warn(&dev->dev, "unknown resource type %d in _CRS\n", res->type); return AE_ERROR; } return AE_OK; }
static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, void *data) { struct pnp_dev *dev = data; struct acpi_resource_dma *dma; struct acpi_resource_vendor_typed *vendor_typed; struct resource r; int i, flags; if (acpi_dev_resource_memory(res, &r) || acpi_dev_resource_io(res, &r) || acpi_dev_resource_address_space(res, &r) || acpi_dev_resource_ext_address_space(res, &r)) { pnp_add_resource(dev, &r); return AE_OK; } r.flags = 0; if (acpi_dev_resource_interrupt(res, 0, &r)) { pnpacpi_add_irqresource(dev, &r); for (i = 1; acpi_dev_resource_interrupt(res, i, &r); i++) pnpacpi_add_irqresource(dev, &r); if (i > 1) { /* * The IRQ encoder puts a single interrupt in each * descriptor, so if a _CRS descriptor has more than * one interrupt, we won't be able to re-encode it. */ if (pnp_can_write(dev)) { dev_warn(&dev->dev, "multiple interrupts in " "_CRS descriptor; configuration can't " "be changed\n"); dev->capabilities &= ~PNP_WRITE; } } return AE_OK; } else if (r.flags & IORESOURCE_DISABLED) { pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); return AE_OK; } switch (res->type) { case ACPI_RESOURCE_TYPE_DMA: dma = &res->data.dma; if (dma->channel_count > 0 && dma->channels[0] != (u8) -1) flags = dma_flags(dev, dma->type, dma->bus_master, dma->transfer); else flags = IORESOURCE_DISABLED; pnp_add_dma_resource(dev, dma->channels[0], flags); break; case ACPI_RESOURCE_TYPE_START_DEPENDENT: case ACPI_RESOURCE_TYPE_END_DEPENDENT: break; case ACPI_RESOURCE_TYPE_VENDOR: vendor_typed = &res->data.vendor_typed; pnpacpi_parse_allocated_vendor(dev, vendor_typed); break; case ACPI_RESOURCE_TYPE_END_TAG: break; case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: break; default: dev_warn(&dev->dev, "unknown resource type %d in _CRS\n", res->type); return AE_ERROR; } return AE_OK; }
static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, void *data) { struct pnp_dev *dev = data; struct acpi_resource_dma *dma; struct acpi_resource_vendor_typed *vendor_typed; struct acpi_resource_gpio *gpio; struct resource_win win = {{0}, 0}; struct resource *r = &win.res; int i, flags; if (acpi_dev_resource_address_space(res, &win) || acpi_dev_resource_ext_address_space(res, &win)) { pnp_add_resource(dev, &win.res); return AE_OK; } r->flags = 0; if (acpi_dev_resource_interrupt(res, 0, r)) { pnpacpi_add_irqresource(dev, r); for (i = 1; acpi_dev_resource_interrupt(res, i, r); i++) pnpacpi_add_irqresource(dev, r); if (i > 1) { /* * The IRQ encoder puts a single interrupt in each * descriptor, so if a _CRS descriptor has more than * one interrupt, we won't be able to re-encode it. */ if (pnp_can_write(dev)) { dev_warn(&dev->dev, "multiple interrupts in _CRS descriptor; configuration can't be changed\n"); dev->capabilities &= ~PNP_WRITE; } } return AE_OK; } else if (acpi_gpio_get_irq_resource(res, &gpio)) { /* * If the resource is GpioInt() type then extract the IRQ * from GPIO resource and fill it into IRQ resource type. */ i = acpi_dev_gpio_irq_get(dev->data, 0); if (i >= 0) { flags = acpi_dev_irq_flags(gpio->triggering, gpio->polarity, gpio->shareable); } else { flags = IORESOURCE_DISABLED; } pnp_add_irq_resource(dev, i, flags); return AE_OK; } else if (r->flags & IORESOURCE_DISABLED) { pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); return AE_OK; } switch (res->type) { case ACPI_RESOURCE_TYPE_MEMORY24: case ACPI_RESOURCE_TYPE_MEMORY32: case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: if (acpi_dev_resource_memory(res, r)) pnp_add_resource(dev, r); break; case ACPI_RESOURCE_TYPE_IO: case ACPI_RESOURCE_TYPE_FIXED_IO: if (acpi_dev_resource_io(res, r)) pnp_add_resource(dev, r); break; case ACPI_RESOURCE_TYPE_DMA: dma = &res->data.dma; if (dma->channel_count > 0 && dma->channels[0] != (u8) -1) flags = dma_flags(dev, dma->type, dma->bus_master, dma->transfer); else flags = IORESOURCE_DISABLED; pnp_add_dma_resource(dev, dma->channels[0], flags); break; case ACPI_RESOURCE_TYPE_START_DEPENDENT: case ACPI_RESOURCE_TYPE_END_DEPENDENT: break; case ACPI_RESOURCE_TYPE_VENDOR: vendor_typed = &res->data.vendor_typed; pnpacpi_parse_allocated_vendor(dev, vendor_typed); break; case ACPI_RESOURCE_TYPE_END_TAG: break; case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: break; case ACPI_RESOURCE_TYPE_SERIAL_BUS: /* serial bus connections (I2C/SPI/UART) are not pnp */ break; default: dev_warn(&dev->dev, "unknown resource type %d in _CRS\n", res->type); return AE_ERROR; } return AE_OK; }