in pnpacpi/rsparser.c [164:268]
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;
}