Commit 0367a177 authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller

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: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4510bbd3
...@@ -1597,6 +1597,15 @@ static int felix_setup(struct dsa_switch *ds) ...@@ -1597,6 +1597,15 @@ static int felix_setup(struct dsa_switch *ds)
felix_port_qos_map_init(ocelot, dp->index); 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); err = ocelot_devlink_sb_register(ocelot);
if (err) if (err)
goto out_deinit_ports; goto out_deinit_ports;
......
...@@ -64,6 +64,7 @@ struct felix_info { ...@@ -64,6 +64,7 @@ struct felix_info {
const struct phylink_link_state *state); const struct phylink_link_state *state);
int (*configure_serdes)(struct ocelot *ocelot, int port, int (*configure_serdes)(struct ocelot *ocelot, int port,
struct device_node *portnp); struct device_node *portnp);
int (*request_irq)(struct ocelot *ocelot);
}; };
/* Methods for initializing the hardware resources specific to a tagging /* Methods for initializing the hardware resources specific to a tagging
......
...@@ -2605,6 +2605,28 @@ static void vsc9959_cut_through_fwd(struct ocelot *ocelot) ...@@ -2605,6 +2605,28 @@ static void vsc9959_cut_through_fwd(struct ocelot *ocelot)
} }
} }
/* 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 = { static const struct ocelot_ops vsc9959_ops = {
.reset = vsc9959_reset, .reset = vsc9959_reset,
.wm_enc = vsc9959_wm_enc, .wm_enc = vsc9959_wm_enc,
...@@ -2645,21 +2667,9 @@ static const struct felix_info felix_info_vsc9959 = { ...@@ -2645,21 +2667,9 @@ static const struct felix_info felix_info_vsc9959 = {
.port_modes = vsc9959_port_modes, .port_modes = vsc9959_port_modes,
.port_setup_tc = vsc9959_port_setup_tc, .port_setup_tc = vsc9959_port_setup_tc,
.port_sched_speed_set = vsc9959_sched_speed_set, .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, static int felix_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id) const struct pci_device_id *id)
{ {
...@@ -2690,14 +2700,6 @@ static int felix_pci_probe(struct pci_dev *pdev, ...@@ -2690,14 +2700,6 @@ static int felix_pci_probe(struct pci_dev *pdev,
pci_set_master(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->ptp = 1;
ocelot->mm_supported = true; ocelot->mm_supported = true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment