Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f833f57f authored by Marc Zyngier's avatar Marc Zyngier Committed by Thomas Gleixner
Browse files

irqchip: Convert all alloc/xlate users from of_node to fwnode



Since we now have a generic data structure to express an
interrupt specifier, convert all hierarchical irqchips that
are OF based to use a fwnode_handle as part of their alloc
and xlate (which becomes translate) callbacks.

As most of these drivers have dependencies (they exchange IRQ
specifiers), change them all in a single, massive patch...

Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Reviewed-and-tested-by: default avatarHanjun Guo <hanjun.guo@linaro.org>
Tested-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: <linux-arm-kernel@lists.infradead.org>
Cc: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Cc: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
Cc: Graeme Gregory <graeme@xora.org.uk>
Cc: Jake Oshins <jakeo@microsoft.com>
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Link: http://lkml.kernel.org/r/1444737105-31573-6-git-send-email-marc.zyngier@arm.com


Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 11e4438e
Loading
Loading
Loading
Loading
+29 −26
Original line number Diff line number Diff line
@@ -177,52 +177,55 @@ static struct irq_chip exynos_pmu_chip = {
#endif
};

static int exynos_pmu_domain_xlate(struct irq_domain *domain,
				   struct device_node *controller,
				   const u32 *intspec,
				   unsigned int intsize,
				   unsigned long *out_hwirq,
				   unsigned int *out_type)
static int exynos_pmu_domain_translate(struct irq_domain *d,
				       struct irq_fwspec *fwspec,
				       unsigned long *hwirq,
				       unsigned int *type)
{
	if (irq_domain_get_of_node(domain) != controller)
		return -EINVAL;	/* Shouldn't happen, really... */
	if (intsize != 3)
		return -EINVAL;	/* Not GIC compliant */
	if (intspec[0] != 0)
		return -EINVAL;	/* No PPI should point to this domain */
	if (is_of_node(fwspec->fwnode)) {
		if (fwspec->param_count != 3)
			return -EINVAL;

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

	*out_hwirq = intspec[1];
	*out_type = intspec[2];
		*hwirq = fwspec->param[1];
		*type = fwspec->param[2];
		return 0;
	}

	return -EINVAL;
}

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;
	struct irq_fwspec *fwspec = data;
	struct irq_fwspec parent_fwspec;
	irq_hw_number_t hwirq;
	int i;

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

	hwirq = args->args[1];
	hwirq = fwspec->param[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 = irq_domain_get_of_node(domain->parent);
	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args);
	parent_fwspec = *fwspec;
	parent_fwspec.fwnode = domain->parent->fwnode;
	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
					    &parent_fwspec);
}

static const struct irq_domain_ops exynos_pmu_domain_ops = {
	.xlate	= exynos_pmu_domain_xlate,
	.translate	= exynos_pmu_domain_translate,
	.alloc		= exynos_pmu_domain_alloc,
	.free		= irq_domain_free_irqs_common,
};
+29 −26
Original line number Diff line number Diff line
@@ -181,40 +181,42 @@ static struct irq_chip imx_gpc_chip = {
#endif
};

static int imx_gpc_domain_xlate(struct irq_domain *domain,
				struct device_node *controller,
				const u32 *intspec,
				unsigned int intsize,
				unsigned long *out_hwirq,
				unsigned int *out_type)
static int imx_gpc_domain_translate(struct irq_domain *d,
				    struct irq_fwspec *fwspec,
				    unsigned long *hwirq,
				    unsigned int *type)
{
	if (irq_domain_get_of_node(domain) != controller)
		return -EINVAL;	/* Shouldn't happen, really... */
	if (intsize != 3)
		return -EINVAL;	/* Not GIC compliant */
	if (intspec[0] != 0)
		return -EINVAL;	/* No PPI should point to this domain */
	if (is_of_node(fwspec->fwnode)) {
		if (fwspec->param_count != 3)
			return -EINVAL;

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

	*out_hwirq = intspec[1];
	*out_type = intspec[2];
		*hwirq = fwspec->param[1];
		*type = fwspec->param[2];
		return 0;
	}

	return -EINVAL;
}

static int imx_gpc_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;
	struct irq_fwspec *fwspec = data;
	struct irq_fwspec parent_fwspec;
	irq_hw_number_t hwirq;
	int i;

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

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

@@ -222,13 +224,14 @@ static int imx_gpc_domain_alloc(struct irq_domain *domain,
		irq_domain_set_hwirq_and_chip(domain, irq + i, hwirq + i,
					      &imx_gpc_chip, NULL);

	parent_args = *args;
	parent_args.np = irq_domain_get_of_node(domain->parent);
	return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, &parent_args);
	parent_fwspec = *fwspec;
	parent_fwspec.fwnode = domain->parent->fwnode;
	return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs,
					    &parent_fwspec);
}

static const struct irq_domain_ops imx_gpc_domain_ops = {
	.xlate	= imx_gpc_domain_xlate,
	.translate	= imx_gpc_domain_translate,
	.alloc		= imx_gpc_domain_alloc,
	.free		= irq_domain_free_irqs_common,
};
+29 −26
Original line number Diff line number Diff line
@@ -399,40 +399,42 @@ static struct irq_chip wakeupgen_chip = {
#endif
};

static int wakeupgen_domain_xlate(struct irq_domain *domain,
				  struct device_node *controller,
				  const u32 *intspec,
				  unsigned int intsize,
				  unsigned long *out_hwirq,
				  unsigned int *out_type)
static int wakeupgen_domain_translate(struct irq_domain *d,
				      struct irq_fwspec *fwspec,
				      unsigned long *hwirq,
				      unsigned int *type)
{
	if (irq_domain_get_of_node(domain) != controller)
		return -EINVAL;	/* Shouldn't happen, really... */
	if (intsize != 3)
		return -EINVAL;	/* Not GIC compliant */
	if (intspec[0] != 0)
		return -EINVAL;	/* No PPI should point to this domain */
	if (is_of_node(fwspec->fwnode)) {
		if (fwspec->param_count != 3)
			return -EINVAL;

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

	*out_hwirq = intspec[1];
	*out_type = intspec[2];
		*hwirq = fwspec->param[1];
		*type = fwspec->param[2];
		return 0;
	}

	return -EINVAL;
}

static int wakeupgen_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;
	struct irq_fwspec *fwspec = data;
	struct irq_fwspec parent_fwspec;
	irq_hw_number_t hwirq;
	int i;

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

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

@@ -440,13 +442,14 @@ static int wakeupgen_domain_alloc(struct irq_domain *domain,
		irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
					      &wakeupgen_chip, NULL);

	parent_args = *args;
	parent_args.np = irq_domain_get_of_node(domain->parent);
	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args);
	parent_fwspec = *fwspec;
	parent_fwspec.fwnode = domain->parent->fwnode;
	return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
					    &parent_fwspec);
}

static const struct irq_domain_ops wakeupgen_domain_ops = {
	.xlate	= wakeupgen_domain_xlate,
	.translate	= wakeupgen_domain_translate,
	.alloc		= wakeupgen_domain_alloc,
	.free		= irq_domain_free_irqs_common,
};
+34 −28
Original line number Diff line number Diff line
@@ -78,10 +78,13 @@ static struct irq_chip crossbar_chip = {
static int allocate_gic_irq(struct irq_domain *domain, unsigned virq,
			    irq_hw_number_t hwirq)
{
	struct of_phandle_args args;
	struct irq_fwspec fwspec;
	int i;
	int err;

	if (!irq_domain_get_of_node(domain->parent))
		return -EINVAL;

	raw_spin_lock(&cb->lock);
	for (i = cb->int_max - 1; i >= 0; i--) {
		if (cb->irq_map[i] == IRQ_FREE) {
@@ -94,13 +97,13 @@ static int allocate_gic_irq(struct irq_domain *domain, unsigned virq,
	if (i < 0)
		return -ENODEV;

	args.np = irq_domain_get_of_node(domain->parent);
	args.args_count = 3;
	args.args[0] = 0;	/* SPI */
	args.args[1] = i;
	args.args[2] = IRQ_TYPE_LEVEL_HIGH;
	fwspec.fwnode = domain->parent->fwnode;
	fwspec.param_count = 3;
	fwspec.param[0] = 0;	/* SPI */
	fwspec.param[1] = i;
	fwspec.param[2] = IRQ_TYPE_LEVEL_HIGH;

	err = irq_domain_alloc_irqs_parent(domain, virq, 1, &args);
	err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
	if (err)
		cb->irq_map[i] = IRQ_FREE;
	else
@@ -112,16 +115,16 @@ static int allocate_gic_irq(struct irq_domain *domain, unsigned virq,
static int crossbar_domain_alloc(struct irq_domain *d, unsigned int virq,
				 unsigned int nr_irqs, void *data)
{
	struct of_phandle_args *args = data;
	struct irq_fwspec *fwspec = data;
	irq_hw_number_t hwirq;
	int i;

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

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

@@ -166,28 +169,31 @@ static void crossbar_domain_free(struct irq_domain *domain, unsigned int virq,
	raw_spin_unlock(&cb->lock);
}

static int crossbar_domain_xlate(struct irq_domain *d,
				 struct device_node *controller,
				 const u32 *intspec, unsigned int intsize,
				 unsigned long *out_hwirq,
				 unsigned int *out_type)
static int crossbar_domain_translate(struct irq_domain *d,
				     struct irq_fwspec *fwspec,
				     unsigned long *hwirq,
				     unsigned int *type)
{
	if (irq_domain_get_of_node(d) != controller)
		return -EINVAL;	/* Shouldn't happen, really... */
	if (intsize != 3)
		return -EINVAL;	/* Not GIC compliant */
	if (intspec[0] != 0)
		return -EINVAL;	/* No PPI should point to this domain */
	if (is_of_node(fwspec->fwnode)) {
		if (fwspec->param_count != 3)
			return -EINVAL;

	*out_hwirq = intspec[1];
	*out_type = intspec[2];
		/* No PPI should point to this domain */
		if (fwspec->param[0] != 0)
			return -EINVAL;

		*hwirq = fwspec->param[1];
		*type = fwspec->param[2];
		return 0;
	}

	return -EINVAL;
}

static const struct irq_domain_ops crossbar_domain_ops = {
	.alloc		= crossbar_domain_alloc,
	.free		= crossbar_domain_free,
	.xlate	= crossbar_domain_xlate,
	.translate	= crossbar_domain_translate,
};

static int __init crossbar_of_init(struct device_node *node)
+11 −7
Original line number Diff line number Diff line
@@ -124,17 +124,21 @@ static int gicv2m_irq_gic_domain_alloc(struct irq_domain *domain,
				       unsigned int virq,
				       irq_hw_number_t hwirq)
{
	struct of_phandle_args args;
	struct irq_fwspec fwspec;
	struct irq_data *d;
	int err;

	args.np = irq_domain_get_of_node(domain->parent);
	args.args_count = 3;
	args.args[0] = 0;
	args.args[1] = hwirq - 32;
	args.args[2] = IRQ_TYPE_EDGE_RISING;
	if (is_of_node(domain->parent->fwnode)) {
		fwspec.fwnode = domain->parent->fwnode;
		fwspec.param_count = 3;
		fwspec.param[0] = 0;
		fwspec.param[1] = hwirq - 32;
		fwspec.param[2] = IRQ_TYPE_EDGE_RISING;
	} else {
		return -EINVAL;
	}

	err = irq_domain_alloc_irqs_parent(domain, virq, 1, &args);
	err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
	if (err)
		return err;

Loading