mirror of https://github.com/torvalds/linux.git
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: Marc Zyngier <maz@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Will Deacon <will@kernel.org> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Link: https://patch.msgid.link/20251020122944.3074811-5-maz@kernel.org
This commit is contained in:
parent
5404f5c06d
commit
0d5daa938c
|
|
@ -150,25 +150,37 @@ devm_platform_ioremap_resource_byname(struct platform_device *pdev,
|
||||||
EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource_byname);
|
EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource_byname);
|
||||||
#endif /* CONFIG_HAS_IOMEM */
|
#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
|
* @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
|
* Gets an interupt for a platform device. Device drivers should check the
|
||||||
* value for errors so as to not pass a negative integer value to the
|
* return value for errors so as to not pass a negative integer value to
|
||||||
* request_irq() APIs. This is the same as platform_get_irq(), except that it
|
* the request_irq() APIs. Optional affinity information is provided in the
|
||||||
* does not print an error message if an IRQ can not be obtained.
|
* affinity pointer if available, and NULL otherwise.
|
||||||
*
|
*
|
||||||
* For example::
|
* Return: non-zero interrupt number on success, negative error number on failure.
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
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;
|
int ret;
|
||||||
#ifdef CONFIG_SPARC
|
#ifdef CONFIG_SPARC
|
||||||
|
|
@ -236,8 +248,37 @@ int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
|
||||||
out:
|
out:
|
||||||
if (WARN(!ret, "0 is an invalid IRQ number\n"))
|
if (WARN(!ret, "0 is an invalid IRQ number\n"))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (ret > 0 && affinity)
|
||||||
|
*affinity = get_irq_affinity(dev, num);
|
||||||
|
|
||||||
return ret;
|
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);
|
EXPORT_SYMBOL_GPL(platform_get_irq_optional);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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(struct platform_device *, unsigned int);
|
||||||
extern int platform_get_irq_optional(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 platform_irq_count(struct platform_device *);
|
||||||
extern int devm_platform_get_irqs_affinity(struct platform_device *dev,
|
extern int devm_platform_get_irqs_affinity(struct platform_device *dev,
|
||||||
struct irq_affinity *affd,
|
struct irq_affinity *affd,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue