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

platform: Add firmware-agnostic irq and affinity retrieval interface



Expand platform_get_irq_optional() to also return an affinity if available,
renaming it to platform_get_irq_affinity() in the process.

platform_get_irq_optional() is preserved with its current semantics by
calling into the new helper with a NULL affinity pointer.

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Tested-by: default avatarWill Deacon <will@kernel.org>
Reviewed-by: default avatarJonathan Cameron <jonathan.cameron@huawei.com>
Link: https://patch.msgid.link/20251020122944.3074811-5-maz@kernel.org
parent 5404f5c0
Loading
Loading
Loading
Loading
+56 −15
Original line number Diff line number Diff line
@@ -150,25 +150,37 @@ devm_platform_ioremap_resource_byname(struct platform_device *pdev,
EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource_byname);
#endif /* CONFIG_HAS_IOMEM */

static const struct cpumask *get_irq_affinity(struct platform_device *dev,
					      unsigned int num)
{
	const struct cpumask *mask = NULL;
#ifndef CONFIG_SPARC
	struct fwnode_handle *fwnode = dev_fwnode(&dev->dev);

	if (is_of_node(fwnode))
		mask = of_irq_get_affinity(to_of_node(fwnode), num);
	else if (is_acpi_device_node(fwnode))
		mask = acpi_irq_get_affinity(ACPI_HANDLE_FWNODE(fwnode), num);
#endif

	return mask ?: cpu_possible_mask;
}

/**
 * platform_get_irq_optional - get an optional IRQ for a device
 * platform_get_irq_affinity - get an optional IRQ and its affinity for a device
 * @dev:	platform device
 * @num: IRQ number index
 * @num:	interrupt number index
 * @affinity:	optional cpumask pointer to get the affinity of a per-cpu interrupt
 *
 * Gets an IRQ for a platform device. Device drivers should check the return
 * value for errors so as to not pass a negative integer value to the
 * request_irq() APIs. This is the same as platform_get_irq(), except that it
 * does not print an error message if an IRQ can not be obtained.
 *
 * For example::
 * Gets an interupt for a platform device. Device drivers should check the
 * return value for errors so as to not pass a negative integer value to
 * the request_irq() APIs. Optional affinity information is provided in the
 * affinity pointer if available, and NULL otherwise.
 *
 *		int irq = platform_get_irq_optional(pdev, 0);
 *		if (irq < 0)
 *			return irq;
 *
 * Return: non-zero IRQ number on success, negative error number on failure.
 * Return: non-zero interrupt number on success, negative error number on failure.
 */
int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
int platform_get_irq_affinity(struct platform_device *dev, unsigned int num,
			      const struct cpumask **affinity)
{
	int ret;
#ifdef CONFIG_SPARC
@@ -236,8 +248,37 @@ int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
out:
	if (WARN(!ret, "0 is an invalid IRQ number\n"))
		return -EINVAL;

	if (ret > 0 && affinity)
		*affinity = get_irq_affinity(dev, num);

	return ret;
}
EXPORT_SYMBOL_GPL(platform_get_irq_affinity);

/**
 * platform_get_irq_optional - get an optional interrupt for a device
 * @dev:	platform device
 * @num:	interrupt number index
 *
 * Gets an interrupt for a platform device. Device drivers should check the
 * return value for errors so as to not pass a negative integer value to
 * the request_irq() APIs. This is the same as platform_get_irq(), except
 * that it does not print an error message if an interrupt can not be
 * obtained.
 *
 * For example::
 *
 *		int irq = platform_get_irq_optional(pdev, 0);
 *		if (irq < 0)
 *			return irq;
 *
 * Return: non-zero interrupt number on success, negative error number on failure.
 */
int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
{
	return platform_get_irq_affinity(dev, num, NULL);
}
EXPORT_SYMBOL_GPL(platform_get_irq_optional);

/**
+2 −0
Original line number Diff line number Diff line
@@ -102,6 +102,8 @@ devm_platform_ioremap_resource_byname(struct platform_device *pdev,

extern int platform_get_irq(struct platform_device *, unsigned int);
extern int platform_get_irq_optional(struct platform_device *, unsigned int);
extern int platform_get_irq_affinity(struct platform_device *, unsigned int,
				     const struct cpumask **);
extern int platform_irq_count(struct platform_device *);
extern int devm_platform_get_irqs_affinity(struct platform_device *dev,
					   struct irq_affinity *affd,