mirror of
https://github.com/torvalds/linux.git
synced 2025-11-30 23:16:01 +07:00
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>
This commit is contained in:
@@ -2587,8 +2587,8 @@ static int ksz_irq_phy_setup(struct ksz_device *dev)
|
||||
|
||||
irq = irq_find_mapping(dev->ports[port].pirq.domain,
|
||||
PORT_SRC_PHY_INT);
|
||||
if (irq < 0) {
|
||||
ret = irq;
|
||||
if (!irq) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
ds->user_mii_bus->irq[phy] = irq;
|
||||
@@ -2952,8 +2952,8 @@ static int ksz_pirq_setup(struct ksz_device *dev, u8 p)
|
||||
snprintf(pirq->name, sizeof(pirq->name), "port_irq-%d", p);
|
||||
|
||||
pirq->irq_num = irq_find_mapping(dev->girq.domain, p);
|
||||
if (pirq->irq_num < 0)
|
||||
return pirq->irq_num;
|
||||
if (!pirq->irq_num)
|
||||
return -EINVAL;
|
||||
|
||||
return ksz_irq_common_setup(dev, pirq);
|
||||
}
|
||||
@@ -3038,12 +3038,12 @@ static int ksz_setup(struct dsa_switch *ds)
|
||||
dsa_switch_for_each_user_port(dp, dev->ds) {
|
||||
ret = ksz_pirq_setup(dev, dp->index);
|
||||
if (ret)
|
||||
goto out_girq;
|
||||
goto port_release;
|
||||
|
||||
if (dev->info->ptp_capable) {
|
||||
ret = ksz_ptp_irq_setup(ds, dp->index);
|
||||
if (ret)
|
||||
goto out_pirq;
|
||||
goto pirq_release;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3053,7 +3053,7 @@ static int ksz_setup(struct dsa_switch *ds)
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "Failed to register PTP clock: %d\n",
|
||||
ret);
|
||||
goto out_ptpirq;
|
||||
goto port_release;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3076,17 +3076,16 @@ static int ksz_setup(struct dsa_switch *ds)
|
||||
out_ptp_clock_unregister:
|
||||
if (dev->info->ptp_capable)
|
||||
ksz_ptp_clock_unregister(ds);
|
||||
out_ptpirq:
|
||||
if (dev->irq > 0 && dev->info->ptp_capable)
|
||||
dsa_switch_for_each_user_port(dp, dev->ds)
|
||||
ksz_ptp_irq_free(ds, dp->index);
|
||||
out_pirq:
|
||||
if (dev->irq > 0)
|
||||
dsa_switch_for_each_user_port(dp, dev->ds)
|
||||
port_release:
|
||||
if (dev->irq > 0) {
|
||||
dsa_switch_for_each_user_port_continue_reverse(dp, dev->ds) {
|
||||
if (dev->info->ptp_capable)
|
||||
ksz_ptp_irq_free(ds, dp->index);
|
||||
pirq_release:
|
||||
ksz_irq_free(&dev->ports[dp->index].pirq);
|
||||
out_girq:
|
||||
if (dev->irq > 0)
|
||||
}
|
||||
ksz_irq_free(&dev->girq);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1093,19 +1093,19 @@ static int ksz_ptp_msg_irq_setup(struct ksz_port *port, u8 n)
|
||||
static const char * const name[] = {"pdresp-msg", "xdreq-msg",
|
||||
"sync-msg"};
|
||||
const struct ksz_dev_ops *ops = port->ksz_dev->dev_ops;
|
||||
struct ksz_irq *ptpirq = &port->ptpirq;
|
||||
struct ksz_ptp_irq *ptpmsg_irq;
|
||||
|
||||
ptpmsg_irq = &port->ptpmsg_irq[n];
|
||||
ptpmsg_irq->num = irq_create_mapping(ptpirq->domain, n);
|
||||
if (!ptpmsg_irq->num)
|
||||
return -EINVAL;
|
||||
|
||||
ptpmsg_irq->port = port;
|
||||
ptpmsg_irq->ts_reg = ops->get_port_addr(port->num, ts_reg[n]);
|
||||
|
||||
strscpy(ptpmsg_irq->name, name[n]);
|
||||
|
||||
ptpmsg_irq->num = irq_find_mapping(port->ptpirq.domain, n);
|
||||
if (ptpmsg_irq->num < 0)
|
||||
return ptpmsg_irq->num;
|
||||
|
||||
return request_threaded_irq(ptpmsg_irq->num, NULL,
|
||||
ksz_ptp_msg_thread_fn, IRQF_ONESHOT,
|
||||
ptpmsg_irq->name, ptpmsg_irq);
|
||||
@@ -1135,12 +1135,9 @@ int ksz_ptp_irq_setup(struct dsa_switch *ds, u8 p)
|
||||
if (!ptpirq->domain)
|
||||
return -ENOMEM;
|
||||
|
||||
for (irq = 0; irq < ptpirq->nirqs; irq++)
|
||||
irq_create_mapping(ptpirq->domain, irq);
|
||||
|
||||
ptpirq->irq_num = irq_find_mapping(port->pirq.domain, PORT_SRC_PTP_INT);
|
||||
if (ptpirq->irq_num < 0) {
|
||||
ret = ptpirq->irq_num;
|
||||
if (!ptpirq->irq_num) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1159,12 +1156,11 @@ int ksz_ptp_irq_setup(struct dsa_switch *ds, u8 p)
|
||||
|
||||
out_ptp_msg:
|
||||
free_irq(ptpirq->irq_num, ptpirq);
|
||||
while (irq--)
|
||||
while (irq--) {
|
||||
free_irq(port->ptpmsg_irq[irq].num, &port->ptpmsg_irq[irq]);
|
||||
out:
|
||||
for (irq = 0; irq < ptpirq->nirqs; irq++)
|
||||
irq_dispose_mapping(port->ptpmsg_irq[irq].num);
|
||||
|
||||
}
|
||||
out:
|
||||
irq_domain_remove(ptpirq->domain);
|
||||
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user