Commit a85a6c86 authored by Bjorn Helgaas's avatar Bjorn Helgaas

driver core: platform: Clarify that IRQ 0 is invalid

These interfaces return a negative error number or an IRQ:

  platform_get_irq()
  platform_get_irq_optional()
  platform_get_irq_byname()
  platform_get_irq_byname_optional()

The function comments suggest checking for error like this:

  irq = platform_get_irq(...);
  if (irq < 0)
    return irq;

which is what most callers (~900 of 1400) do, so it's implicit that IRQ 0
is invalid.  But some callers check for "irq <= 0", and it's not obvious
from the source that we never return an IRQ 0.

Make this more explicit by updating the comments to say that an IRQ number
is always non-zero and adding a WARN() if we ever do return zero.  If we do
return IRQ 0, it likely indicates a bug in the arch-specific parts of
platform_get_irq().

Relevant prior discussion at [1, 2].

[1] https://lore.kernel.org/r/Pine.LNX.4.64.0701250940220.25027@woody.linux-foundation.org/
[2] https://lore.kernel.org/r/Pine.LNX.4.64.0701252029570.25027@woody.linux-foundation.org/Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 8f3d9f35
...@@ -152,23 +152,24 @@ EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource_byname); ...@@ -152,23 +152,24 @@ EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource_byname);
* if (irq < 0) * if (irq < 0)
* return irq; * return irq;
* *
* Return: IRQ number on success, negative error number on failure. * 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_optional(struct platform_device *dev, unsigned int num)
{ {
int ret;
#ifdef CONFIG_SPARC #ifdef CONFIG_SPARC
/* sparc does not have irqs represented as IORESOURCE_IRQ resources */ /* sparc does not have irqs represented as IORESOURCE_IRQ resources */
if (!dev || num >= dev->archdata.num_irqs) if (!dev || num >= dev->archdata.num_irqs)
return -ENXIO; return -ENXIO;
return dev->archdata.irqs[num]; ret = dev->archdata.irqs[num];
goto out;
#else #else
struct resource *r; struct resource *r;
int ret;
if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) { if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) {
ret = of_irq_get(dev->dev.of_node, num); ret = of_irq_get(dev->dev.of_node, num);
if (ret > 0 || ret == -EPROBE_DEFER) if (ret > 0 || ret == -EPROBE_DEFER)
return ret; goto out;
} }
r = platform_get_resource(dev, IORESOURCE_IRQ, num); r = platform_get_resource(dev, IORESOURCE_IRQ, num);
...@@ -176,7 +177,7 @@ int platform_get_irq_optional(struct platform_device *dev, unsigned int num) ...@@ -176,7 +177,7 @@ int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
if (r && r->flags & IORESOURCE_DISABLED) { if (r && r->flags & IORESOURCE_DISABLED) {
ret = acpi_irq_get(ACPI_HANDLE(&dev->dev), num, r); ret = acpi_irq_get(ACPI_HANDLE(&dev->dev), num, r);
if (ret) if (ret)
return ret; goto out;
} }
} }
...@@ -190,13 +191,17 @@ int platform_get_irq_optional(struct platform_device *dev, unsigned int num) ...@@ -190,13 +191,17 @@ int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
struct irq_data *irqd; struct irq_data *irqd;
irqd = irq_get_irq_data(r->start); irqd = irq_get_irq_data(r->start);
if (!irqd) if (!irqd) {
return -ENXIO; ret = -ENXIO;
goto out;
}
irqd_set_trigger_type(irqd, r->flags & IORESOURCE_BITS); irqd_set_trigger_type(irqd, r->flags & IORESOURCE_BITS);
} }
if (r) if (r) {
return r->start; ret = r->start;
goto out;
}
/* /*
* For the index 0 interrupt, allow falling back to GpioInt * For the index 0 interrupt, allow falling back to GpioInt
...@@ -209,11 +214,14 @@ int platform_get_irq_optional(struct platform_device *dev, unsigned int num) ...@@ -209,11 +214,14 @@ int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
ret = acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num); ret = acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num);
/* Our callers expect -ENXIO for missing IRQs. */ /* Our callers expect -ENXIO for missing IRQs. */
if (ret >= 0 || ret == -EPROBE_DEFER) if (ret >= 0 || ret == -EPROBE_DEFER)
return ret; goto out;
} }
return -ENXIO; ret = -ENXIO;
#endif #endif
out:
WARN(ret == 0, "0 is an invalid IRQ number\n");
return ret;
} }
EXPORT_SYMBOL_GPL(platform_get_irq_optional); EXPORT_SYMBOL_GPL(platform_get_irq_optional);
...@@ -231,7 +239,7 @@ EXPORT_SYMBOL_GPL(platform_get_irq_optional); ...@@ -231,7 +239,7 @@ EXPORT_SYMBOL_GPL(platform_get_irq_optional);
* if (irq < 0) * if (irq < 0)
* return irq; * return irq;
* *
* Return: IRQ number on success, negative error number on failure. * Return: non-zero IRQ number on success, negative error number on failure.
*/ */
int platform_get_irq(struct platform_device *dev, unsigned int num) int platform_get_irq(struct platform_device *dev, unsigned int num)
{ {
...@@ -303,8 +311,10 @@ static int __platform_get_irq_byname(struct platform_device *dev, ...@@ -303,8 +311,10 @@ static int __platform_get_irq_byname(struct platform_device *dev,
} }
r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name); r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name);
if (r) if (r) {
WARN(r->start == 0, "0 is an invalid IRQ number\n");
return r->start; return r->start;
}
return -ENXIO; return -ENXIO;
} }
...@@ -316,7 +326,7 @@ static int __platform_get_irq_byname(struct platform_device *dev, ...@@ -316,7 +326,7 @@ static int __platform_get_irq_byname(struct platform_device *dev,
* *
* Get an IRQ like platform_get_irq(), but then by name rather then by index. * Get an IRQ like platform_get_irq(), but then by name rather then by index.
* *
* Return: IRQ number on success, negative error number on failure. * Return: non-zero IRQ number on success, negative error number on failure.
*/ */
int platform_get_irq_byname(struct platform_device *dev, const char *name) int platform_get_irq_byname(struct platform_device *dev, const char *name)
{ {
...@@ -338,7 +348,7 @@ EXPORT_SYMBOL_GPL(platform_get_irq_byname); ...@@ -338,7 +348,7 @@ EXPORT_SYMBOL_GPL(platform_get_irq_byname);
* Get an optional IRQ by name like platform_get_irq_byname(). Except that it * Get an optional IRQ by name like platform_get_irq_byname(). Except that it
* does not print an error message if an IRQ can not be obtained. * does not print an error message if an IRQ can not be obtained.
* *
* Return: IRQ number on success, negative error number on failure. * Return: non-zero IRQ number on success, negative error number on failure.
*/ */
int platform_get_irq_byname_optional(struct platform_device *dev, int platform_get_irq_byname_optional(struct platform_device *dev,
const char *name) const char *name)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment