mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
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>
This commit is contained in:
committed by
David S. Miller
parent
4510bbd38c
commit
0367a17759
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user