summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorVladimir Oltean <vladimir.oltean@nxp.com>2024-05-30 19:33:30 +0300
committerDavid S. Miller <davem@davemloft.net>2024-06-03 13:06:15 +0100
commit0367a1775933aab80a99ebc91a14efbcaaa45a00 (patch)
tree1078b7bb9ec1c3112f3f6059e940d8235d8be0f6 /drivers
parent4510bbd38cbef7e6fc1a786f3e0213ba07fe0a00 (diff)
downloadlwn-0367a1775933aab80a99ebc91a14efbcaaa45a00.tar.gz
lwn-0367a1775933aab80a99ebc91a14efbcaaa45a00.zip
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 <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/dsa/ocelot/felix.c9
-rw-r--r--drivers/net/dsa/ocelot/felix.h1
-rw-r--r--drivers/net/dsa/ocelot/felix_vsc9959.c44
3 files changed, 33 insertions, 21 deletions
diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index 3aa66bf9eafc..09c0800b18ab 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 4d3489aaa659..e67a25f6f816 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 34155a0ffd7e..20563abd617f 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;