static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) { struct of_irq oirq; int ret; int i; for (i=0; i < 3; i++) { ret = of_irq_map_one(np, i, &oirq); if (ret) { pr_debug("spu_new: failed to get irq %d\n", i); goto err; } ret = -EINVAL; pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0], oirq.controller->full_name); spu->irqs[i] = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); if (spu->irqs[i] == NO_IRQ) { pr_debug("spu_new: failed to map it !\n"); goto err; } } return 0; err: pr_debug("failed to map irq %x for spu %s\n", *oirq.specifier, spu->name); for (; i >= 0; i--) { if (spu->irqs[i] != NO_IRQ) irq_dispose_mapping(spu->irqs[i]); } return ret; }
void request_event_sources_irqs(struct device_node *np, irq_handler_t handler, const char *name) { int i, index, count = 0; struct of_phandle_args oirq; unsigned int virqs[16]; /* First try to do a proper OF tree parsing */ for (index = 0; of_irq_parse_one(np, index, &oirq) == 0; index++) { if (count > 15) break; virqs[count] = irq_create_of_mapping(&oirq); if (virqs[count] == NO_IRQ) { pr_err("event-sources: Unable to allocate " "interrupt number for %s\n", np->full_name); WARN_ON(1); } else { count++; } } /* Now request them */ for (i = 0; i < count; i++) { if (request_irq(virqs[i], handler, 0, name, NULL)) { pr_err("event-sources: Unable to request interrupt " "%d for %s\n", virqs[i], np->full_name); WARN_ON(1); return; } } }
/** * irq_of_parse_and_map - Parse and map an interrupt into linux virq space * @dev: Device node of the device whose interrupt is to be mapped * @index: Index of the interrupt to map * * This function is a wrapper that chains of_irq_parse_one() and * irq_create_of_mapping() to make things easier to callers */ unsigned int irq_of_parse_and_map(struct device_node *dev, int index) { struct of_phandle_args oirq; if (of_irq_parse_one(dev, index, &oirq)) return 0; return irq_create_of_mapping(&oirq); }
static void request_ras_irqs(struct device_node *np, irqreturn_t (*handler)(int, void *, struct pt_regs *), const char *name) { int i, index, count = 0; struct of_irq oirq; u32 *opicprop; unsigned int opicplen; unsigned int virqs[16]; /* Check for obsolete "open-pic-interrupt" property. If present, then * map those interrupts using the default interrupt host and default * trigger */ opicprop = (u32 *)get_property(np, "open-pic-interrupt", &opicplen); if (opicprop) { opicplen /= sizeof(u32); for (i = 0; i < opicplen; i++) { if (count > 15) break; virqs[count] = irq_create_mapping(NULL, *(opicprop++)); if (virqs[count] == NO_IRQ) printk(KERN_ERR "Unable to allocate interrupt " "number for %s\n", np->full_name); else count++; } } /* Else use normal interrupt tree parsing */ else { /* First try to do a proper OF tree parsing */ for (index = 0; of_irq_map_one(np, index, &oirq) == 0; index++) { if (count > 15) break; virqs[count] = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); if (virqs[count] == NO_IRQ) printk(KERN_ERR "Unable to allocate interrupt " "number for %s\n", np->full_name); else count++; } } /* Now request them */ for (i = 0; i < count; i++) { if (request_irq(virqs[i], handler, 0, name, NULL)) { printk(KERN_ERR "Unable to request interrupt %d for " "%s\n", virqs[i], np->full_name); return; } } }
unsigned int irq_of_parse_and_map(struct device_node *dev, int index) { struct of_irq oirq; if (of_irq_map_one(dev, index, &oirq)) return 0; return irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); }
/** * of_irq_parse_and_map_pci() - Decode a PCI irq from the device tree and map to a virq * @dev: The pci device needing an irq * @slot: PCI slot number; passed when used as map_irq callback. Unused * @pin: PCI irq pin number; passed when used as map_irq callback. Unused * * @slot and @pin are unused, but included in the function so that this * function can be used directly as the map_irq callback to pci_fixup_irqs(). */ int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin) { struct of_phandle_args oirq; int ret; ret = of_irq_parse_pci(dev, &oirq); if (ret) return 0; /* Proper return code 0 == NO_IRQ */ return irq_create_of_mapping(&oirq); }
/** * of_irq_parse_and_map_pci() - Decode a PCI irq from the device tree and map to a virq * @dev: The pci device needing an irq * @slot: PCI slot number; passed when used as map_irq callback. Unused * @pin: PCI irq pin number; passed when used as map_irq callback. Unused * * @slot and @pin are unused, but included in the function so that this * function can be used directly as the map_irq callback to pci_fixup_irqs(). */ int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin) { struct of_phandle_args oirq; int ret; ret = of_irq_parse_pci(dev, &oirq); if (ret) { dev_err(&dev->dev, "of_irq_parse_pci() failed with rc=%d\n", ret); return 0; /* Proper return code 0 == NO_IRQ */ } return irq_create_of_mapping(&oirq); }
/** * of_irq_get - Decode a node's IRQ and return it as a Linux irq number * @dev: pointer to device tree node * @index: zero-based index of the irq * * Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain * is not yet created. * */ int of_irq_get(struct device_node *dev, int index) { int rc; struct of_phandle_args oirq; struct irq_domain *domain; rc = of_irq_parse_one(dev, index, &oirq); if (rc) return rc; domain = irq_find_host(oirq.np); if (!domain) return -EPROBE_DEFER; return irq_create_of_mapping(&oirq); }
void request_event_sources_irqs(struct device_node *np, irq_handler_t handler, const char *name) { int i, index, count = 0; struct of_phandle_args oirq; const u32 *opicprop; unsigned int opicplen; unsigned int virqs[16]; /* Check for obsolete "open-pic-interrupt" property. If present, then * map those interrupts using the default interrupt host and default * trigger */ opicprop = of_get_property(np, "open-pic-interrupt", &opicplen); if (opicprop) { opicplen /= sizeof(u32); for (i = 0; i < opicplen; i++) { if (count > 15) break; virqs[count] = irq_create_mapping(NULL, *(opicprop++)); if (virqs[count] == NO_IRQ) { pr_err("event-sources: Unable to allocate " "interrupt number for %s\n", np->full_name); WARN_ON(1); } else count++; } } /* Else use normal interrupt tree parsing */ else { /* First try to do a proper OF tree parsing */ for (index = 0; of_irq_parse_one(np, index, &oirq) == 0; index++) { if (count > 15) break; virqs[count] = irq_create_of_mapping(&oirq); if (virqs[count] == NO_IRQ) { pr_err("event-sources: Unable to allocate " "interrupt number for %s\n", np->full_name); WARN_ON(1); } else count++; } } /* Now request them */ for (i = 0; i < count; i++) { if (request_irq(virqs[i], handler, 0, name, NULL)) { pr_err("event-sources: Unable to request interrupt " "%d for %s\n", virqs[i], np->full_name); WARN_ON(1); return; } } }
static int of_isp1760_probe(struct platform_device *dev) { struct isp1760 *drvdata; struct device_node *dp = dev->dev.of_node; struct resource *res; struct resource memory; struct of_irq oirq; int virq; resource_size_t res_len; int ret; const unsigned int *prop; unsigned int devflags = 0; enum of_gpio_flags gpio_flags; drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; ret = of_address_to_resource(dp, 0, &memory); if (ret) return -ENXIO; res_len = resource_size(&memory); res = request_mem_region(memory.start, res_len, dev_name(&dev->dev)); if (!res) return -EBUSY; if (of_irq_map_one(dp, 0, &oirq)) { ret = -ENODEV; goto release_reg; } virq = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); if (of_device_is_compatible(dp, "nxp,usb-isp1761")) devflags |= ISP1760_FLAG_ISP1761; /* Some systems wire up only 16 of the 32 data lines */ prop = of_get_property(dp, "bus-width", NULL); if (prop && *prop == 16) devflags |= ISP1760_FLAG_BUS_WIDTH_16; if (of_get_property(dp, "port1-otg", NULL) != NULL) devflags |= ISP1760_FLAG_OTG_EN; if (of_get_property(dp, "analog-oc", NULL) != NULL) devflags |= ISP1760_FLAG_ANALOG_OC; if (of_get_property(dp, "dack-polarity", NULL) != NULL) devflags |= ISP1760_FLAG_DACK_POL_HIGH; if (of_get_property(dp, "dreq-polarity", NULL) != NULL) devflags |= ISP1760_FLAG_DREQ_POL_HIGH; drvdata->rst_gpio = of_get_gpio_flags(dp, 0, &gpio_flags); if (gpio_is_valid(drvdata->rst_gpio)) { ret = gpio_request(drvdata->rst_gpio, dev_name(&dev->dev)); if (!ret) { if (!(gpio_flags & OF_GPIO_ACTIVE_LOW)) { devflags |= ISP1760_FLAG_RESET_ACTIVE_HIGH; gpio_direction_output(drvdata->rst_gpio, 0); } else { gpio_direction_output(drvdata->rst_gpio, 1); } } else { drvdata->rst_gpio = ret; } } drvdata->hcd = isp1760_register(memory.start, res_len, virq, IRQF_SHARED, drvdata->rst_gpio, &dev->dev, dev_name(&dev->dev), devflags); if (IS_ERR(drvdata->hcd)) { ret = PTR_ERR(drvdata->hcd); goto free_gpio; } dev_set_drvdata(&dev->dev, drvdata); return ret; free_gpio: if (gpio_is_valid(drvdata->rst_gpio)) gpio_free(drvdata->rst_gpio); release_reg: release_mem_region(memory.start, res_len); kfree(drvdata); return ret; }
static int of_isp1760_probe(struct platform_device *dev, const struct of_device_id *match) { struct usb_hcd *hcd; struct device_node *dp = dev->dev.of_node; struct resource *res; struct resource memory; struct of_irq oirq; int virq; resource_size_t res_len; int ret; const unsigned int *prop; unsigned int devflags = 0; ret = of_address_to_resource(dp, 0, &memory); if (ret) return -ENXIO; res_len = resource_size(&memory); res = request_mem_region(memory.start, res_len, dev_name(&dev->dev)); if (!res) return -EBUSY; if (of_irq_map_one(dp, 0, &oirq)) { ret = -ENODEV; goto release_reg; } virq = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); if (of_device_is_compatible(dp, "nxp,usb-isp1761")) devflags |= ISP1760_FLAG_ISP1761; /* Some systems wire up only 16 of the 32 data lines */ prop = of_get_property(dp, "bus-width", NULL); if (prop && *prop == 16) devflags |= ISP1760_FLAG_BUS_WIDTH_16; if (of_get_property(dp, "port1-otg", NULL) != NULL) devflags |= ISP1760_FLAG_OTG_EN; if (of_get_property(dp, "analog-oc", NULL) != NULL) devflags |= ISP1760_FLAG_ANALOG_OC; if (of_get_property(dp, "dack-polarity", NULL) != NULL) devflags |= ISP1760_FLAG_DACK_POL_HIGH; if (of_get_property(dp, "dreq-polarity", NULL) != NULL) devflags |= ISP1760_FLAG_DREQ_POL_HIGH; hcd = isp1760_register(memory.start, res_len, virq, IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev), devflags); if (IS_ERR(hcd)) { ret = PTR_ERR(hcd); goto release_reg; } dev_set_drvdata(&dev->dev, hcd); return ret; release_reg: release_mem_region(memory.start, res_len); return ret; }
void request_event_sources_irqs(struct device_node *np, irq_handler_t handler, const char *name) { int i, index, count = 0; struct of_irq oirq; const u32 *opicprop; unsigned int opicplen; unsigned int virqs[16]; /* */ opicprop = of_get_property(np, "open-pic-interrupt", &opicplen); if (opicprop) { opicplen /= sizeof(u32); for (i = 0; i < opicplen; i++) { if (count > 15) break; virqs[count] = irq_create_mapping(NULL, *(opicprop++)); if (virqs[count] == NO_IRQ) { pr_err("event-sources: Unable to allocate " "interrupt number for %s\n", np->full_name); WARN_ON(1); } else count++; } } /* */ else { /* */ for (index = 0; of_irq_map_one(np, index, &oirq) == 0; index++) { if (count > 15) break; virqs[count] = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); if (virqs[count] == NO_IRQ) { pr_err("event-sources: Unable to allocate " "interrupt number for %s\n", np->full_name); WARN_ON(1); } else count++; } } /* */ for (i = 0; i < count; i++) { if (request_irq(virqs[i], handler, 0, name, NULL)) { pr_err("event-sources: Unable to request interrupt " "%d for %s\n", virqs[i], np->full_name); WARN_ON(1); return; } } }
static int __init hidma_mgmt_of_populate_channels(struct device_node *np) { struct platform_device *pdev_parent = of_find_device_by_node(np); struct platform_device_info pdevinfo; struct of_phandle_args out_irq; struct device_node *child; struct resource *res; const __be32 *cell; int ret = 0, size, i, num; u64 addr, addr_size; for_each_available_child_of_node(np, child) { struct resource *res_iter; struct platform_device *new_pdev; cell = of_get_property(child, "reg", &size); if (!cell) { ret = -EINVAL; goto out; } size /= sizeof(*cell); num = size / (of_n_addr_cells(child) + of_n_size_cells(child)) + 1; /* allocate a resource array */ res = kcalloc(num, sizeof(*res), GFP_KERNEL); if (!res) { ret = -ENOMEM; goto out; } /* read each reg value */ i = 0; res_iter = res; while (i < size) { addr = of_read_number(&cell[i], of_n_addr_cells(child)); i += of_n_addr_cells(child); addr_size = of_read_number(&cell[i], of_n_size_cells(child)); i += of_n_size_cells(child); res_iter->start = addr; res_iter->end = res_iter->start + addr_size - 1; res_iter->flags = IORESOURCE_MEM; res_iter++; } ret = of_irq_parse_one(child, 0, &out_irq); if (ret) goto out; res_iter->start = irq_create_of_mapping(&out_irq); res_iter->name = "hidma event irq"; res_iter->flags = IORESOURCE_IRQ; memset(&pdevinfo, 0, sizeof(pdevinfo)); pdevinfo.fwnode = &child->fwnode; pdevinfo.parent = pdev_parent ? &pdev_parent->dev : NULL; pdevinfo.name = child->name; pdevinfo.id = object_counter++; pdevinfo.res = res; pdevinfo.num_res = num; pdevinfo.data = NULL; pdevinfo.size_data = 0; pdevinfo.dma_mask = DMA_BIT_MASK(64); new_pdev = platform_device_register_full(&pdevinfo); if (IS_ERR(new_pdev)) { ret = PTR_ERR(new_pdev); goto out; } of_node_get(child); new_pdev->dev.of_node = child; of_dma_configure(&new_pdev->dev, child); /* * It is assumed that calling of_msi_configure is safe on * platforms with or without MSI support. */ of_msi_configure(&new_pdev->dev, child); of_node_put(child); kfree(res); res = NULL; } out: kfree(res); return ret; }