/** * platform_get_irq - get an IRQ for a device * @dev: platform device * @num: IRQ number index */ int platform_get_irq(struct platform_device *dev, unsigned int num) { #ifdef CONFIG_SPARC /* sparc does not have irqs represented as IORESOURCE_IRQ resources */ if (!dev || num >= dev->archdata.num_irqs) return -ENXIO; return dev->archdata.irqs[num]; #else struct resource *r; if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) { int ret; ret = of_irq_get(dev->dev.of_node, num); if (ret > 0 || ret == -EPROBE_DEFER) return ret; } r = platform_get_resource(dev, IORESOURCE_IRQ, num); if (has_acpi_companion(&dev->dev)) { if (r && r->flags & IORESOURCE_DISABLED) { int ret; ret = acpi_irq_get(ACPI_HANDLE(&dev->dev), num, r); if (ret) return ret; } } /* * The resources may pass trigger flags to the irqs that need * to be set up. It so happens that the trigger flags for * IORESOURCE_BITS correspond 1-to-1 to the IRQF_TRIGGER* * settings. */ if (r && r->flags & IORESOURCE_BITS) { struct irq_data *irqd; irqd = irq_get_irq_data(r->start); if (!irqd) return -ENXIO; irqd_set_trigger_type(irqd, r->flags & IORESOURCE_BITS); } if (r) return r->start; /* * For the index 0 interrupt, allow falling back to GpioInt * resources. While a device could have both Interrupt and GpioInt * resources, making this fallback ambiguous, in many common cases * the device will only expose one IRQ, and this fallback * allows a common code path across either kind of resource. */ if (num == 0 && has_acpi_companion(&dev->dev)) return acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num); return -ENXIO; #endif }
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; }