Ejemplo n.º 1
0
static int xgene_gpio_sb_domain_alloc(struct irq_domain *domain,
					unsigned int virq,
					unsigned int nr_irqs, void *data)
{
	struct irq_fwspec *fwspec = data;
	struct irq_fwspec parent_fwspec;
	struct xgene_gpio_sb *priv = domain->host_data;
	irq_hw_number_t hwirq;
	unsigned int i;

	hwirq = fwspec->param[0];
	for (i = 0; i < nr_irqs; i++)
		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
				&xgene_gpio_sb_irq_chip, priv);

	parent_fwspec.fwnode = domain->parent->fwnode;
	if (is_of_node(parent_fwspec.fwnode)) {
		parent_fwspec.param_count = 3;
		parent_fwspec.param[0] = 0;/* SPI */
		/* Skip SGIs and PPIs*/
		parent_fwspec.param[1] = hwirq + priv->parent_irq_base - 32;
		parent_fwspec.param[2] = fwspec->param[1];
	} else if (is_fwnode_irqchip(parent_fwspec.fwnode)) {
		parent_fwspec.param_count = 2;
		parent_fwspec.param[0] = hwirq + priv->parent_irq_base;
		parent_fwspec.param[1] = fwspec->param[1];
	} else
		return -EINVAL;

	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
			&parent_fwspec);
}
Ejemplo n.º 2
0
/**
 * irq_domain_free_fwnode - Free a non-OF-backed fwnode_handle
 *
 * Free a fwnode_handle allocated with irq_domain_alloc_fwnode.
 */
void irq_domain_free_fwnode(struct fwnode_handle *fwnode)
{
	struct irqchip_fwid *fwid;

	if (WARN_ON(!is_fwnode_irqchip(fwnode)))
		return;

	fwid = container_of(fwnode, struct irqchip_fwid, fwnode);
	kfree(fwid->name);
	kfree(fwid);
}
Ejemplo n.º 3
0
/**
 * __irq_domain_add() - Allocate a new irq_domain data structure
 * @fwnode: firmware node for the interrupt controller
 * @size: Size of linear map; 0 for radix mapping only
 * @hwirq_max: Maximum number of interrupts supported by controller
 * @direct_max: Maximum value of direct maps; Use ~0 for no limit; 0 for no
 *              direct mapping
 * @ops: domain callbacks
 * @host_data: Controller private data pointer
 *
 * Allocates and initialize and irq_domain structure.
 * Returns pointer to IRQ domain, or NULL on failure.
 */
struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
				    irq_hw_number_t hwirq_max, int direct_max,
				    const struct irq_domain_ops *ops,
				    void *host_data)
{
	struct device_node *of_node = to_of_node(fwnode);
	struct irqchip_fwid *fwid;
	struct irq_domain *domain;

	static atomic_t unknown_domains;

	domain = kzalloc_node(sizeof(*domain) + (sizeof(unsigned int) * size),
			      GFP_KERNEL, of_node_to_nid(of_node));
	if (WARN_ON(!domain))
		return NULL;

	if (fwnode && is_fwnode_irqchip(fwnode)) {
		fwid = container_of(fwnode, struct irqchip_fwid, fwnode);

		switch (fwid->type) {
		case IRQCHIP_FWNODE_NAMED:
		case IRQCHIP_FWNODE_NAMED_ID:
			domain->name = kstrdup(fwid->name, GFP_KERNEL);
			if (!domain->name) {
				kfree(domain);
				return NULL;
			}
			domain->flags |= IRQ_DOMAIN_NAME_ALLOCATED;
			break;
		default:
			domain->fwnode = fwnode;
			domain->name = fwid->name;
			break;
		}
#ifdef CONFIG_ACPI
	} else if (is_acpi_device_node(fwnode)) {