From: Vladimir Oltean Date: Thu, 30 May 2024 16:33:30 +0000 (+0300) Subject: net: dsa: ocelot: move devm_request_threaded_irq() to felix_setup() X-Git-Tag: v6.11-rc1~163^2~266^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0367a1775933aab80a99ebc91a14efbcaaa45a00;p=thirdparty%2Flinux.git net: dsa: ocelot: move devm_request_threaded_irq() to felix_setup() The current placement of devm_request_threaded_irq() is inconvenient. It is between the allocation of the "felix" structure and dsa_register_switch(), both of which we'd like to refactor into a function that's common for all switches. But the IRQ is specific to felix_vsc9959. A closer inspection of the felix_irq_handler() code suggests that it does things that depend on the data structures having been fully initialized. For example, ocelot_get_txtstamp() takes &port->tx_skbs.lock, which has only been initialized in ocelot_init_port() which has not run yet. It is not one of those IRQF_SHARED IRQs, so CONFIG_DEBUG_SHIRQ_FIXME shouldn't apply here, and thus, it doesn't really matter, because in practice, the IRQ will not be triggered so early. Nonetheless, it is a good practice for the driver to be prepared for it to fire as soon as it is requested. Create a new felix->info method for running custom code for vsc9959 from within felix_setup(), and move the request_irq() call there. The ocelot_ext should have an IRQ as well, so this should be a step in the right direction for that model (VSC7512) as well. Some minor changes are made while moving the code. Casts from void * aren't necessary, so drop them, and rename felix_irq_handler() to the more specific vsc9959_irq_handler(). Signed-off-by: Vladimir Oltean Signed-off-by: David S. Miller --- diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index 3aa66bf9eafc3..09c0800b18ab4 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -1597,6 +1597,15 @@ static int felix_setup(struct dsa_switch *ds) felix_port_qos_map_init(ocelot, dp->index); } + if (felix->info->request_irq) { + err = felix->info->request_irq(ocelot); + if (err) { + dev_err(ocelot->dev, "Failed to request IRQ: %pe\n", + ERR_PTR(err)); + goto out_deinit_ports; + } + } + err = ocelot_devlink_sb_register(ocelot); if (err) goto out_deinit_ports; diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h index 4d3489aaa6597..e67a25f6f816c 100644 --- a/drivers/net/dsa/ocelot/felix.h +++ b/drivers/net/dsa/ocelot/felix.h @@ -64,6 +64,7 @@ struct felix_info { const struct phylink_link_state *state); int (*configure_serdes)(struct ocelot *ocelot, int port, struct device_node *portnp); + int (*request_irq)(struct ocelot *ocelot); }; /* Methods for initializing the hardware resources specific to a tagging diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index 34155a0ffd7e8..20563abd617f1 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -2605,6 +2605,28 @@ set: } } +/* The INTB interrupt is shared between for PTP TX timestamp availability + * notification and MAC Merge status change on each port. + */ +static irqreturn_t vsc9959_irq_handler(int irq, void *data) +{ + struct ocelot *ocelot = data; + + ocelot_get_txtstamp(ocelot); + ocelot_mm_irq(ocelot); + + return IRQ_HANDLED; +} + +static int vsc9959_request_irq(struct ocelot *ocelot) +{ + struct pci_dev *pdev = to_pci_dev(ocelot->dev); + + return devm_request_threaded_irq(ocelot->dev, pdev->irq, NULL, + &vsc9959_irq_handler, IRQF_ONESHOT, + "felix-intb", ocelot); +} + static const struct ocelot_ops vsc9959_ops = { .reset = vsc9959_reset, .wm_enc = vsc9959_wm_enc, @@ -2645,21 +2667,9 @@ static const struct felix_info felix_info_vsc9959 = { .port_modes = vsc9959_port_modes, .port_setup_tc = vsc9959_port_setup_tc, .port_sched_speed_set = vsc9959_sched_speed_set, + .request_irq = vsc9959_request_irq, }; -/* The INTB interrupt is shared between for PTP TX timestamp availability - * notification and MAC Merge status change on each port. - */ -static irqreturn_t felix_irq_handler(int irq, void *data) -{ - struct ocelot *ocelot = (struct ocelot *)data; - - ocelot_get_txtstamp(ocelot); - ocelot_mm_irq(ocelot); - - return IRQ_HANDLED; -} - static int felix_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -2690,14 +2700,6 @@ static int felix_pci_probe(struct pci_dev *pdev, pci_set_master(pdev); - err = devm_request_threaded_irq(dev, pdev->irq, NULL, - &felix_irq_handler, IRQF_ONESHOT, - "felix-intb", ocelot); - if (err) { - dev_err(dev, "Failed to request irq: %pe\n", ERR_PTR(err)); - goto out_disable; - } - ocelot->ptp = 1; ocelot->mm_supported = true;