]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: dsa: ocelot: move devm_request_threaded_irq() to felix_setup()
authorVladimir Oltean <vladimir.oltean@nxp.com>
Thu, 30 May 2024 16:33:30 +0000 (19:33 +0300)
committerDavid S. Miller <davem@davemloft.net>
Mon, 3 Jun 2024 12:06:15 +0000 (13:06 +0100)
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 <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/ocelot/felix.c
drivers/net/dsa/ocelot/felix.h
drivers/net/dsa/ocelot/felix_vsc9959.c

index 3aa66bf9eafc373d3a455ce55a968bcc608e7823..09c0800b18ab46bcc84ae34993fc67f4a5d90962 100644 (file)
@@ -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;
index 4d3489aaa659791b1c11cdf4430d5bb33f58b9fa..e67a25f6f816cd742604ab90c1c1609cf158f632 100644 (file)
@@ -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
index 34155a0ffd7e87f7e7e9064dbf2a4793f804d82b..20563abd617f12cd4645d685f591d304ae2d6bdc 100644 (file)
@@ -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;