Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'net-dsa-microchip-fix-resource-releases-in-error-path'

Bastien Curutchet says:

====================
net: dsa: microchip: Fix resource releases in error path

I worked on adding PTP support for the KSZ8463. While doing so, I ran
into a few bugs in the resource release process that occur when things go
wrong arount IRQ initialization.

This small series fixes those bugs.

The next series, which will add the PTP support, depend on this one.

Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
---
Bastien Curutchet (Schneider Electric) (5):
net: dsa: microchip: common: Fix checks on irq_find_mapping()
net: dsa: microchip: ptp: Fix checks on irq_find_mapping()
net: dsa: microchip: Don't free uninitialized ksz_irq
net: dsa: microchip: Free previously initialized ports on init failures
net: dsa: microchip: Fix symetry in ksz_ptp_msg_irq_{setup/free}()

drivers/net/dsa/microchip/ksz_common.c | 31 +++++++++++++++----------------
drivers/net/dsa/microchip/ksz_ptp.c | 22 +++++++++-------------
2 files changed, 24 insertions(+), 29 deletions(-)
---
base-commit: 09652e543e809c2369dca142fee5d9b05be9bdc7
change-id: 20251031-ksz-fix-db345df7635f

Best regards,
====================

Link: https://patch.msgid.link/20251120-ksz-fix-v6-0-891f80ae7f8f@bootlin.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+24 -29
+15 -16
drivers/net/dsa/microchip/ksz_common.c
··· 2587 2587 2588 2588 irq = irq_find_mapping(dev->ports[port].pirq.domain, 2589 2589 PORT_SRC_PHY_INT); 2590 - if (irq < 0) { 2591 - ret = irq; 2590 + if (!irq) { 2591 + ret = -EINVAL; 2592 2592 goto out; 2593 2593 } 2594 2594 ds->user_mii_bus->irq[phy] = irq; ··· 2952 2952 snprintf(pirq->name, sizeof(pirq->name), "port_irq-%d", p); 2953 2953 2954 2954 pirq->irq_num = irq_find_mapping(dev->girq.domain, p); 2955 - if (pirq->irq_num < 0) 2956 - return pirq->irq_num; 2955 + if (!pirq->irq_num) 2956 + return -EINVAL; 2957 2957 2958 2958 return ksz_irq_common_setup(dev, pirq); 2959 2959 } ··· 3038 3038 dsa_switch_for_each_user_port(dp, dev->ds) { 3039 3039 ret = ksz_pirq_setup(dev, dp->index); 3040 3040 if (ret) 3041 - goto out_girq; 3041 + goto port_release; 3042 3042 3043 3043 if (dev->info->ptp_capable) { 3044 3044 ret = ksz_ptp_irq_setup(ds, dp->index); 3045 3045 if (ret) 3046 - goto out_pirq; 3046 + goto pirq_release; 3047 3047 } 3048 3048 } 3049 3049 } ··· 3053 3053 if (ret) { 3054 3054 dev_err(dev->dev, "Failed to register PTP clock: %d\n", 3055 3055 ret); 3056 - goto out_ptpirq; 3056 + goto port_release; 3057 3057 } 3058 3058 } 3059 3059 ··· 3076 3076 out_ptp_clock_unregister: 3077 3077 if (dev->info->ptp_capable) 3078 3078 ksz_ptp_clock_unregister(ds); 3079 - out_ptpirq: 3080 - if (dev->irq > 0 && dev->info->ptp_capable) 3081 - dsa_switch_for_each_user_port(dp, dev->ds) 3082 - ksz_ptp_irq_free(ds, dp->index); 3083 - out_pirq: 3084 - if (dev->irq > 0) 3085 - dsa_switch_for_each_user_port(dp, dev->ds) 3079 + port_release: 3080 + if (dev->irq > 0) { 3081 + dsa_switch_for_each_user_port_continue_reverse(dp, dev->ds) { 3082 + if (dev->info->ptp_capable) 3083 + ksz_ptp_irq_free(ds, dp->index); 3084 + pirq_release: 3086 3085 ksz_irq_free(&dev->ports[dp->index].pirq); 3087 - out_girq: 3088 - if (dev->irq > 0) 3086 + } 3089 3087 ksz_irq_free(&dev->girq); 3088 + } 3090 3089 3091 3090 return ret; 3092 3091 }
+9 -13
drivers/net/dsa/microchip/ksz_ptp.c
··· 1093 1093 static const char * const name[] = {"pdresp-msg", "xdreq-msg", 1094 1094 "sync-msg"}; 1095 1095 const struct ksz_dev_ops *ops = port->ksz_dev->dev_ops; 1096 + struct ksz_irq *ptpirq = &port->ptpirq; 1096 1097 struct ksz_ptp_irq *ptpmsg_irq; 1097 1098 1098 1099 ptpmsg_irq = &port->ptpmsg_irq[n]; 1100 + ptpmsg_irq->num = irq_create_mapping(ptpirq->domain, n); 1101 + if (!ptpmsg_irq->num) 1102 + return -EINVAL; 1099 1103 1100 1104 ptpmsg_irq->port = port; 1101 1105 ptpmsg_irq->ts_reg = ops->get_port_addr(port->num, ts_reg[n]); 1102 1106 1103 1107 strscpy(ptpmsg_irq->name, name[n]); 1104 - 1105 - ptpmsg_irq->num = irq_find_mapping(port->ptpirq.domain, n); 1106 - if (ptpmsg_irq->num < 0) 1107 - return ptpmsg_irq->num; 1108 1108 1109 1109 return request_threaded_irq(ptpmsg_irq->num, NULL, 1110 1110 ksz_ptp_msg_thread_fn, IRQF_ONESHOT, ··· 1135 1135 if (!ptpirq->domain) 1136 1136 return -ENOMEM; 1137 1137 1138 - for (irq = 0; irq < ptpirq->nirqs; irq++) 1139 - irq_create_mapping(ptpirq->domain, irq); 1140 - 1141 1138 ptpirq->irq_num = irq_find_mapping(port->pirq.domain, PORT_SRC_PTP_INT); 1142 - if (ptpirq->irq_num < 0) { 1143 - ret = ptpirq->irq_num; 1139 + if (!ptpirq->irq_num) { 1140 + ret = -EINVAL; 1144 1141 goto out; 1145 1142 } 1146 1143 ··· 1156 1159 1157 1160 out_ptp_msg: 1158 1161 free_irq(ptpirq->irq_num, ptpirq); 1159 - while (irq--) 1162 + while (irq--) { 1160 1163 free_irq(port->ptpmsg_irq[irq].num, &port->ptpmsg_irq[irq]); 1161 - out: 1162 - for (irq = 0; irq < ptpirq->nirqs; irq++) 1163 1164 irq_dispose_mapping(port->ptpmsg_irq[irq].num); 1164 - 1165 + } 1166 + out: 1165 1167 irq_domain_remove(ptpirq->domain); 1166 1168 1167 1169 return ret;