Skip to content

Commit

Permalink
irqdomain: Allow quiet failure mode
Browse files Browse the repository at this point in the history
Some interrupt controllers refuse to map interrupts marked as
"protected" by firwmare. Since we try to map everyting in the
device-tree on some platforms, we end up with a lot of nasty
WARN's in the boot log for what is a normal situation on those
machines.

This defines a specific return code (-EPERM) from the host map()
callback which cause irqdomain to fail silently.

MPIC is updated to return this when hitting a protected source
printing only a single line message for diagnostic purposes.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Benjamin Herrenschmidt committed May 6, 2013
1 parent f3d40c2 commit 5fe0c1f
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
14 changes: 11 additions & 3 deletions arch/powerpc/sysdev/mpic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1001,8 +1001,12 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq,

if (hw == mpic->spurious_vec)
return -EINVAL;
if (mpic->protected && test_bit(hw, mpic->protected))
return -EINVAL;
if (mpic->protected && test_bit(hw, mpic->protected)) {
pr_warning("mpic: Mapping of source 0x%x failed, "
"source protected by firmware !\n",\
(unsigned int)hw);
return -EPERM;
}

#ifdef CONFIG_SMP
else if (hw >= mpic->ipi_vecs[0]) {
Expand All @@ -1029,8 +1033,12 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq,
if (mpic_map_error_int(mpic, virq, hw))
return 0;

if (hw >= mpic->num_sources)
if (hw >= mpic->num_sources) {
pr_warning("mpic: Mapping of source 0x%x failed, "
"source out of range !\n",\
(unsigned int)hw);
return -EINVAL;
}

mpic_msi_reserve_hwirq(mpic, hw);

Expand Down
20 changes: 17 additions & 3 deletions kernel/irq/irqdomain.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,9 +462,23 @@ int irq_domain_associate_many(struct irq_domain *domain, unsigned int irq_base,
if (domain->ops->map) {
ret = domain->ops->map(domain, virq, hwirq);
if (ret != 0) {
pr_err("irq-%i==>hwirq-0x%lx mapping failed: %d\n",
virq, hwirq, ret);
WARN_ON(1);
/*
* If map() returns -EPERM, this interrupt is protected
* by the firmware or some other service and shall not
* be mapped.
*
* Since on some platforms we blindly try to map everything
* we end up with a log full of backtraces.
*
* So instead, we silently fail on -EPERM, it is the
* responsibility of the PIC driver to display a relevant
* message if needed.
*/
if (ret != -EPERM) {
pr_err("irq-%i==>hwirq-0x%lx mapping failed: %d\n",
virq, hwirq, ret);
WARN_ON(1);
}
irq_data->domain = NULL;
irq_data->hwirq = 0;
goto err_unmap;
Expand Down

0 comments on commit 5fe0c1f

Please sign in to comment.