Example #1
0
static int imx_gpcv2_domain_alloc(struct irq_domain *domain,
				  unsigned int irq, unsigned int nr_irqs,
				  void *data)
{
	struct of_phandle_args *args = data;
	struct of_phandle_args parent_args;
	irq_hw_number_t hwirq;
	int i;

	/* Not GIC compliant */
	if (args->args_count != 3)
		return -EINVAL;

	/* No PPI should point to this domain */
	if (args->args[0] != 0)
		return -EINVAL;

	/* Can't deal with this */
	hwirq = args->args[1];
	if (hwirq >= GPC_MAX_IRQS)
		return -EINVAL;

	for (i = 0; i < nr_irqs; i++) {
		irq_domain_set_hwirq_and_chip(domain, irq + i, hwirq + i,
				&gpcv2_irqchip_data_chip, domain->host_data);
	}

	parent_args = *args;
	parent_args.np = domain->parent->of_node;
	return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, &parent_args);
}
Example #2
0
static int mbigen_irq_domain_alloc(struct irq_domain *domain,
					unsigned int virq,
					unsigned int nr_irqs,
					void *args)
{
	struct irq_fwspec *fwspec = args;
	irq_hw_number_t hwirq;
	unsigned int type;
	struct mbigen_device *mgn_chip;
	int i, err;

	err = mbigen_domain_translate(domain, fwspec, &hwirq, &type);
	if (err)
		return err;

	err = platform_msi_domain_alloc(domain, virq, nr_irqs);
	if (err)
		return err;

	mgn_chip = platform_msi_get_host_data(domain);

	for (i = 0; i < nr_irqs; i++)
		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
				      &mbigen_irq_chip, mgn_chip->base);

	return 0;
}
Example #3
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);
}
Example #4
0
static int imx_gpc_domain_alloc(struct irq_domain *domain,
				  unsigned int irq,
				  unsigned int nr_irqs, void *data)
{
	struct irq_fwspec *fwspec = data;
	struct irq_fwspec parent_fwspec;
	irq_hw_number_t hwirq;
	int i;

	if (fwspec->param_count != 3)
		return -EINVAL;	/* Not GIC compliant */
	if (fwspec->param[0] != 0)
		return -EINVAL;	/* No PPI should point to this domain */

	hwirq = fwspec->param[1];
	if (hwirq >= GPC_MAX_IRQS)
		return -EINVAL;	/* Can't deal with this */

	for (i = 0; i < nr_irqs; i++)
		irq_domain_set_hwirq_and_chip(domain, irq + i, hwirq + i,
					      &imx_gpc_chip, NULL);

	parent_fwspec = *fwspec;
	parent_fwspec.fwnode = domain->parent->fwnode;
	return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs,
					    &parent_fwspec);
}
Example #5
0
static int crossbar_domain_alloc(struct irq_domain *d, unsigned int virq,
				 unsigned int nr_irqs, void *data)
{
	struct irq_fwspec *fwspec = data;
	irq_hw_number_t hwirq;
	int i;

	if (fwspec->param_count != 3)
		return -EINVAL;	/* Not GIC compliant */
	if (fwspec->param[0] != 0)
		return -EINVAL;	/* No PPI should point to this domain */

	hwirq = fwspec->param[1];
	if ((hwirq + nr_irqs) > cb->max_crossbar_sources)
		return -EINVAL;	/* Can't deal with this */

	for (i = 0; i < nr_irqs; i++) {
		int err = allocate_gic_irq(d, virq + i, hwirq + i);

		if (err)
			return err;

		irq_domain_set_hwirq_and_chip(d, virq + i, hwirq + i,
					      &crossbar_chip, NULL);
	}

	return 0;
}
Example #6
0
static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
				   unsigned int nr_irqs, void *args)
{
	struct v2m_data *v2m = domain->host_data;
	int hwirq, offset, err = 0;

	spin_lock(&v2m->msi_cnt_lock);
	offset = find_first_zero_bit(v2m->bm, v2m->nr_spis);
	if (offset < v2m->nr_spis)
		__set_bit(offset, v2m->bm);
	else
		err = -ENOSPC;
	spin_unlock(&v2m->msi_cnt_lock);

	if (err)
		return err;

	hwirq = v2m->spi_start + offset;

	err = gicv2m_irq_gic_domain_alloc(domain, virq, hwirq);
	if (err) {
		gicv2m_unalloc_msi(v2m, hwirq);
		return err;
	}

	irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
				      &gicv2m_irq_chip, v2m);

	return 0;
}
Example #7
0
static int platform_msi_init(struct irq_domain *domain,
			     struct msi_domain_info *info,
			     unsigned int virq, irq_hw_number_t hwirq,
			     msi_alloc_info_t *arg)
{
	return irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
					     info->chip, info->chip_data);
}
Example #8
0
File: msi.c Project: 19Dan01/linux
static int msi_domain_ops_init(struct irq_domain *domain,
			       struct msi_domain_info *info,
			       unsigned int virq, irq_hw_number_t hwirq,
			       msi_alloc_info_t *arg)
{
	irq_domain_set_hwirq_and_chip(domain, virq, hwirq, info->chip,
				      info->chip_data);
	if (info->handler && info->handler_name) {
		__irq_set_handler(virq, info->handler, 0, info->handler_name);
		if (info->handler_data)
			irq_set_handler_data(virq, info->handler_data);
	}
	return 0;
}
Example #9
0
static int gicp_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
				 unsigned int nr_irqs, void *args)
{
	struct mvebu_gicp *gicp = domain->host_data;
	struct irq_fwspec fwspec;
	unsigned int hwirq;
	int ret;

	spin_lock(&gicp->spi_lock);
	hwirq = find_first_zero_bit(gicp->spi_bitmap, gicp->spi_cnt);
	if (hwirq == gicp->spi_cnt) {
		spin_unlock(&gicp->spi_lock);
		return -ENOSPC;
	}
	__set_bit(hwirq, gicp->spi_bitmap);
	spin_unlock(&gicp->spi_lock);

	fwspec.fwnode = domain->parent->fwnode;
	fwspec.param_count = 3;
	fwspec.param[0] = GIC_SPI;
	fwspec.param[1] = gicp_idx_to_spi(gicp, hwirq) - 32;
	/*
	 * Assume edge rising for now, it will be properly set when
	 * ->set_type() is called
	 */
	fwspec.param[2] = IRQ_TYPE_EDGE_RISING;

	ret = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
	if (ret) {
		dev_err(gicp->dev, "Cannot allocate parent IRQ\n");
		goto free_hwirq;
	}

	ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
					    &gicp_irq_chip, gicp);
	if (ret)
		goto free_irqs_parent;

	return 0;

free_irqs_parent:
	irq_domain_free_irqs_parent(domain, virq, nr_irqs);
free_hwirq:
	spin_lock(&gicp->spi_lock);
	__clear_bit(hwirq, gicp->spi_bitmap);
	spin_unlock(&gicp->spi_lock);
	return ret;
}
Example #10
0
File: suspend.c Project: 3bsa/linux
static int exynos_pmu_domain_alloc(struct irq_domain *domain,
				   unsigned int virq,
				   unsigned int nr_irqs, void *data)
{
	struct of_phandle_args *args = data;
	struct of_phandle_args parent_args;
	irq_hw_number_t hwirq;
	int i;

	if (args->args_count != 3)
		return -EINVAL;	/* Not GIC compliant */
	if (args->args[0] != 0)
		return -EINVAL;	/* No PPI should point to this domain */

	hwirq = args->args[1];

	for (i = 0; i < nr_irqs; i++)
		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
					      &exynos_pmu_chip, NULL);

	parent_args = *args;
	parent_args.np = domain->parent->of_node;
	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args);
}
Example #11
0
static int vf610_mscm_ir_domain_alloc(struct irq_domain *domain, unsigned int virq,
				      unsigned int nr_irqs, void *arg)
{
	int i;
	irq_hw_number_t hwirq;
	struct of_phandle_args *irq_data = arg;
	struct of_phandle_args gic_data;

	if (irq_data->args_count != 2)
		return -EINVAL;

	hwirq = irq_data->args[0];
	for (i = 0; i < nr_irqs; i++)
		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
					      &vf610_mscm_ir_irq_chip,
					      domain->host_data);

	gic_data.np = domain->parent->of_node;
	gic_data.args_count = 3;
	gic_data.args[0] = GIC_SPI;
	gic_data.args[1] = irq_data->args[0];
	gic_data.args[2] = irq_data->args[1];
	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &gic_data);
}