From: Zijun Hu <quic_zijuhu@xxxxxxxxxxx> of_irq_parse_one(@int_gen_dev, i, ...) will leak refcount of @i_th_phandle int_gen_dev { ... interrupts-extended = ..., <&i_th_phandle ...>, ...; ... }; Refcount of @i_th_phandle is increased by of_parse_phandle_with_args() but is not decreased by API of_irq_parse_one() before return, so causes refcount leakage. Fix by putting the node's refcount before return as the other branch does. Also add comments about refcount of node @out_irq->np got by the API. Fixes: 79d9701559a9 ("of/irq: create interrupts-extended property") Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Zijun Hu <quic_zijuhu@xxxxxxxxxxx> --- drivers/of/irq.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 6c843d54ebb116132144e6300d6d7ce94e763cf8..d88719c316a3931502c34a65b2db8921f7528d99 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -339,6 +339,8 @@ EXPORT_SYMBOL_GPL(of_irq_parse_raw); * This function resolves an interrupt for a node by walking the interrupt tree, * finding which interrupt controller node it is attached to, and returning the * interrupt specifier that can be used to retrieve a Linux IRQ number. + * + * Note: refcount of node @out_irq->np is increased by 1 on success. */ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq) { @@ -367,8 +369,11 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar /* Try the new-style interrupts-extended first */ res = of_parse_phandle_with_args(device, "interrupts-extended", "#interrupt-cells", index, out_irq); - if (!res) - return of_irq_parse_raw(addr_buf, out_irq); + if (!res) { + p = out_irq->np; + res = of_irq_parse_raw(addr_buf, out_irq); + goto out; + } /* Look for the interrupt parent. */ p = of_irq_find_parent(device); -- 2.34.1