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

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
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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
+23 −21
Original line number Diff line number Diff line
@@ -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 = {
	.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;