linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC net-next 0/5] net: phy: add support for shared interrupts
@ 2020-10-24 12:14 Ioana Ciornei
  2020-10-24 12:14 ` [RFC net-next 1/5] net: phy: export phy_error and phy_trigger_machine Ioana Ciornei
                   ` (7 more replies)
  0 siblings, 8 replies; 13+ messages in thread
From: Ioana Ciornei @ 2020-10-24 12:14 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit, Russell King, Jakub Kicinski,
	netdev, linux-kernel
  Cc: Ioana Ciornei, Alexandru Ardelean, Andre Edich, Antoine Tenart,
	Baruch Siach, Christophe Leroy, Dan Murphy, Divya Koppera,
	Florian Fainelli, Hauke Mehrtens, Jerome Brunet,
	Kavya Sree Kotagiri, Linus Walleij, Marco Felsch, Marek Vasut,
	Martin Blumenstingl, Mathias Kresin, Maxim Kochetkov,
	Michael Walle, Neil Armstrong, Nisar Sayed, Oleksij Rempel,
	Philippe Schenker, Willy Liu, Yuiko Oshino

This patch set aims to actually add support for shared interrupts in
phylib and not only for multi-PHY devices. While we are at it,
streamline the interrupt handling in phylib.

For a bit of context, at the moment, there are multiple phy_driver ops
that deal with this subject:

- .config_intr() - Enable/disable the interrupt line.

- .ack_interrupt() - Should quiesce any interrupts that may have been
  fired.  It's also used by phylib in conjunction with .config_intr() to
  clear any pending interrupts after the line was disabled, and before
  it is going to be enabled.

- .did_interrupt() - Intended for multi-PHY devices with a shared IRQ
  line and used by phylib to discern which PHY from the package was the
  one that actually fired the interrupt.

- .handle_interrupt() - Completely overrides the default interrupt
  handling logic from phylib. The PHY driver is responsible for checking
  if any interrupt was fired by the respective PHY and choose
  accordingly if it's the one that should trigger the link state machine.

From my point of view, the interrupt handling in phylib has become
somewhat confusing with all these callbacks that actually read the same
PHY register - the interrupt status.  A more streamlined approach would
be to just move the responsibility to write an interrupt handler to the
driver (as any other device driver does) and make .handle_interrupt()
the only way to deal with interrupts.

Another advantage with this approach would be that phylib would gain
support for shared IRQs between different PHY (not just multi-PHY
devices), something which at the moment would require extending every
PHY driver anyway in order to implement their .did_interrupt() callback
and duplicate the same logic as in .ack_interrupt(). The disadvantage
of making .did_interrupt() mandatory would be that we are slightly
changing the semantics of the phylib API and that would increase
confusion instead of reducing it.

What I am proposing is the following:

- As a first step, make the .ack_interrupt() callback optional so that
  we do not break any PHY driver amid the transition.

- Every PHY driver gains a .handle_interrupt() implementation that, for
  the most part, would look like below:

	irq_status = phy_read(phydev, INTR_STATUS);
	if (irq_status < 0) {
		phy_error(phydev);
		return IRQ_NONE;
	}

	if (irq_status == 0)
		return IRQ_NONE;

	phy_trigger_machine(phydev);

	return IRQ_HANDLED;

- Remove each PHY driver's implementation of the .ack_interrupt() by
  actually taking care of quiescing any pending interrupts before
  enabling/after disabling the interrupt line.

- Finally, after all drivers have been ported, remove the
  .ack_interrupt() and .did_interrupt() callbacks from phy_driver.

This RFC just contains the patches for phylib and a single driver -
Atheros. The rest can be found on my Github branch here: TODO
They will be submitted as a multi-part series once the merge window
closes.

I do not have access to most of these PHY's, therefore I Cc-ed the
latest contributors to the individual PHY drivers in order to have
access, hopefully, to more regression testing.

Ioana Ciornei (5):
  net: phy: export phy_error and phy_trigger_machine
  net: phy: add a shutdown procedure
  net: phy: make .ack_interrupt() optional
  net: phy: at803x: implement generic .handle_interrupt() callback
  net: phy: at803x: remove the use of .ack_interrupt()

 drivers/net/phy/at803x.c     | 42 ++++++++++++++++++++++++++++++------
 drivers/net/phy/phy.c        |  6 ++++--
 drivers/net/phy/phy_device.c | 10 ++++++++-
 include/linux/phy.h          |  2 ++
 4 files changed, 50 insertions(+), 10 deletions(-)

Cc: Alexandru Ardelean <alexandru.ardelean@analog.com>
Cc: Andre Edich <andre.edich@microchip.com>
Cc: Antoine Tenart <atenart@kernel.org>
Cc: Baruch Siach <baruch@tkos.co.il>
Cc: Christophe Leroy <christophe.leroy@c-s.fr>
Cc: Dan Murphy <dmurphy@ti.com>
Cc: Divya Koppera <Divya.Koppera@microchip.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Hauke Mehrtens <hauke@hauke-m.de>
Cc: Heiner Kallweit <hkallweit1@gmail.com>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Cc: Kavya Sree Kotagiri <kavyasree.kotagiri@microchip.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Marco Felsch <m.felsch@pengutronix.de>
Cc: Marek Vasut <marex@denx.de>
Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Cc: Mathias Kresin <dev@kresin.me>
Cc: Maxim Kochetkov <fido_max@inbox.ru>
Cc: Michael Walle <michael@walle.cc>
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Nisar Sayed <Nisar.Sayed@microchip.com>
Cc: Oleksij Rempel <o.rempel@pengutronix.de>
Cc: Philippe Schenker <philippe.schenker@toradex.com>
Cc: Willy Liu <willy.liu@realtek.com>
Cc: Yuiko Oshino <yuiko.oshino@microchip.com>

-- 
2.28.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [RFC net-next 1/5] net: phy: export phy_error and phy_trigger_machine
  2020-10-24 12:14 [RFC net-next 0/5] net: phy: add support for shared interrupts Ioana Ciornei
@ 2020-10-24 12:14 ` Ioana Ciornei
  2020-10-24 12:14 ` [RFC net-next 2/5] net: phy: add a shutdown procedure Ioana Ciornei
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Ioana Ciornei @ 2020-10-24 12:14 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit, Russell King, Jakub Kicinski,
	netdev, linux-kernel
  Cc: Ioana Ciornei, Alexandru Ardelean, Andre Edich, Antoine Tenart,
	Baruch Siach, Christophe Leroy, Dan Murphy, Divya Koppera,
	Florian Fainelli, Hauke Mehrtens, Jerome Brunet,
	Kavya Sree Kotagiri, Linus Walleij, Marco Felsch, Marek Vasut,
	Martin Blumenstingl, Mathias Kresin, Maxim Kochetkov,
	Michael Walle, Neil Armstrong, Nisar Sayed, Oleksij Rempel,
	Philippe Schenker, Willy Liu, Yuiko Oshino

These functions are currently used by phy_interrupt() to either signal
an error condition or to trigger the link state machine. In an attempt
to actually support shared PHY IRQs, export these two functions so that
the actual PHY drivers can use them.

Cc: Alexandru Ardelean <alexandru.ardelean@analog.com>
Cc: Andre Edich <andre.edich@microchip.com>
Cc: Antoine Tenart <atenart@kernel.org>
Cc: Baruch Siach <baruch@tkos.co.il>
Cc: Christophe Leroy <christophe.leroy@c-s.fr>
Cc: Dan Murphy <dmurphy@ti.com>
Cc: Divya Koppera <Divya.Koppera@microchip.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Hauke Mehrtens <hauke@hauke-m.de>
Cc: Heiner Kallweit <hkallweit1@gmail.com>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Cc: Kavya Sree Kotagiri <kavyasree.kotagiri@microchip.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Marco Felsch <m.felsch@pengutronix.de>
Cc: Marek Vasut <marex@denx.de>
Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Cc: Mathias Kresin <dev@kresin.me>
Cc: Maxim Kochetkov <fido_max@inbox.ru>
Cc: Michael Walle <michael@walle.cc>
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Nisar Sayed <Nisar.Sayed@microchip.com>
Cc: Oleksij Rempel <o.rempel@pengutronix.de>
Cc: Philippe Schenker <philippe.schenker@toradex.com>
Cc: Willy Liu <willy.liu@realtek.com>
Cc: Yuiko Oshino <yuiko.oshino@microchip.com>
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/net/phy/phy.c | 6 ++++--
 include/linux/phy.h   | 2 ++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 35525a671400..477bdf2f94df 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -493,10 +493,11 @@ EXPORT_SYMBOL(phy_queue_state_machine);
  *
  * @phydev: the phy_device struct
  */
-static void phy_trigger_machine(struct phy_device *phydev)
+void phy_trigger_machine(struct phy_device *phydev)
 {
 	phy_queue_state_machine(phydev, 0);
 }
+EXPORT_SYMBOL(phy_trigger_machine);
 
 static void phy_abort_cable_test(struct phy_device *phydev)
 {
@@ -924,7 +925,7 @@ void phy_stop_machine(struct phy_device *phydev)
  * Must not be called from interrupt context, or while the
  * phydev->lock is held.
  */
-static void phy_error(struct phy_device *phydev)
+void phy_error(struct phy_device *phydev)
 {
 	WARN_ON(1);
 
@@ -934,6 +935,7 @@ static void phy_error(struct phy_device *phydev)
 
 	phy_trigger_machine(phydev);
 }
+EXPORT_SYMBOL(phy_error);
 
 /**
  * phy_disable_interrupts - Disable the PHY interrupts from the PHY side
diff --git a/include/linux/phy.h b/include/linux/phy.h
index eb3cb1a98b45..566b39f6cd64 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1570,8 +1570,10 @@ void phy_drivers_unregister(struct phy_driver *drv, int n);
 int phy_driver_register(struct phy_driver *new_driver, struct module *owner);
 int phy_drivers_register(struct phy_driver *new_driver, int n,
 			 struct module *owner);
+void phy_error(struct phy_device *phydev);
 void phy_state_machine(struct work_struct *work);
 void phy_queue_state_machine(struct phy_device *phydev, unsigned long jiffies);
+void phy_trigger_machine(struct phy_device *phydev);
 void phy_mac_interrupt(struct phy_device *phydev);
 void phy_start_machine(struct phy_device *phydev);
 void phy_stop_machine(struct phy_device *phydev);
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC net-next 2/5] net: phy: add a shutdown procedure
  2020-10-24 12:14 [RFC net-next 0/5] net: phy: add support for shared interrupts Ioana Ciornei
  2020-10-24 12:14 ` [RFC net-next 1/5] net: phy: export phy_error and phy_trigger_machine Ioana Ciornei
@ 2020-10-24 12:14 ` Ioana Ciornei
  2020-10-24 12:14 ` [RFC net-next 3/5] net: phy: make .ack_interrupt() optional Ioana Ciornei
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Ioana Ciornei @ 2020-10-24 12:14 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit, Russell King, Jakub Kicinski,
	netdev, linux-kernel
  Cc: Ioana Ciornei, Alexandru Ardelean, Andre Edich, Antoine Tenart,
	Baruch Siach, Christophe Leroy, Dan Murphy, Divya Koppera,
	Florian Fainelli, Hauke Mehrtens, Jerome Brunet,
	Kavya Sree Kotagiri, Linus Walleij, Marco Felsch, Marek Vasut,
	Martin Blumenstingl, Mathias Kresin, Maxim Kochetkov,
	Michael Walle, Neil Armstrong, Nisar Sayed, Oleksij Rempel,
	Philippe Schenker, Willy Liu, Yuiko Oshino

In case of a board which uses a shared IRQ we can easily end up with an
IRQ storm after a forced reboot.

For example, a 'reboot -f' will trigger a call to the .shutdown()
callbacks of all devices. Because phylib does not implement that hook,
the PHY is not quiesced, thus it can very well leave its IRQ enabled.

At the next boot, if that IRQ line is found asserted by the first PHY
driver that uses it, but _before_ the driver that is _actually_ keeping
the shared IRQ asserted is probed, the IRQ is not going to be
acknowledged, thus it will keep being fired preventing the boot process
of the kernel to continue. This is even worse when the second PHY driver
is a module.

To fix this, implement the .shutdown() callback and disable the
interrupts if these are used.

Note that we are still susceptible to IRQ storms if the previous kernel
exited with a panic or if the bootloader left the shared IRQ active, but
there is absolutely nothing we can do about these cases.

Cc: Alexandru Ardelean <alexandru.ardelean@analog.com>
Cc: Andre Edich <andre.edich@microchip.com>
Cc: Antoine Tenart <atenart@kernel.org>
Cc: Baruch Siach <baruch@tkos.co.il>
Cc: Christophe Leroy <christophe.leroy@c-s.fr>
Cc: Dan Murphy <dmurphy@ti.com>
Cc: Divya Koppera <Divya.Koppera@microchip.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Hauke Mehrtens <hauke@hauke-m.de>
Cc: Heiner Kallweit <hkallweit1@gmail.com>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Cc: Kavya Sree Kotagiri <kavyasree.kotagiri@microchip.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Marco Felsch <m.felsch@pengutronix.de>
Cc: Marek Vasut <marex@denx.de>
Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Cc: Mathias Kresin <dev@kresin.me>
Cc: Maxim Kochetkov <fido_max@inbox.ru>
Cc: Michael Walle <michael@walle.cc>
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Nisar Sayed <Nisar.Sayed@microchip.com>
Cc: Oleksij Rempel <o.rempel@pengutronix.de>
Cc: Philippe Schenker <philippe.schenker@toradex.com>
Cc: Willy Liu <willy.liu@realtek.com>
Cc: Yuiko Oshino <yuiko.oshino@microchip.com>
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/net/phy/phy_device.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 5dab6be6fc38..413a0a2c5d51 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -2947,6 +2947,13 @@ static int phy_remove(struct device *dev)
 	return 0;
 }
 
+static void phy_shutdown(struct device *dev)
+{
+	struct phy_device *phydev = to_phy_device(dev);
+
+	phy_disable_interrupts(phydev);
+}
+
 /**
  * phy_driver_register - register a phy_driver with the PHY layer
  * @new_driver: new phy_driver to register
@@ -2970,6 +2977,7 @@ int phy_driver_register(struct phy_driver *new_driver, struct module *owner)
 	new_driver->mdiodrv.driver.bus = &mdio_bus_type;
 	new_driver->mdiodrv.driver.probe = phy_probe;
 	new_driver->mdiodrv.driver.remove = phy_remove;
+	new_driver->mdiodrv.driver.shutdown = phy_shutdown;
 	new_driver->mdiodrv.driver.owner = owner;
 	new_driver->mdiodrv.driver.probe_type = PROBE_FORCE_SYNCHRONOUS;
 
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC net-next 3/5] net: phy: make .ack_interrupt() optional
  2020-10-24 12:14 [RFC net-next 0/5] net: phy: add support for shared interrupts Ioana Ciornei
  2020-10-24 12:14 ` [RFC net-next 1/5] net: phy: export phy_error and phy_trigger_machine Ioana Ciornei
  2020-10-24 12:14 ` [RFC net-next 2/5] net: phy: add a shutdown procedure Ioana Ciornei
@ 2020-10-24 12:14 ` Ioana Ciornei
  2020-10-24 12:14 ` [RFC net-next 4/5] net: phy: at803x: implement generic .handle_interrupt() callback Ioana Ciornei
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Ioana Ciornei @ 2020-10-24 12:14 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit, Russell King, Jakub Kicinski,
	netdev, linux-kernel
  Cc: Ioana Ciornei, Alexandru Ardelean, Andre Edich, Antoine Tenart,
	Baruch Siach, Christophe Leroy, Dan Murphy, Divya Koppera,
	Florian Fainelli, Hauke Mehrtens, Jerome Brunet,
	Kavya Sree Kotagiri, Linus Walleij, Marco Felsch, Marek Vasut,
	Martin Blumenstingl, Mathias Kresin, Maxim Kochetkov,
	Michael Walle, Neil Armstrong, Nisar Sayed, Oleksij Rempel,
	Philippe Schenker, Willy Liu, Yuiko Oshino

As a first step into making phylib and all PHY drivers to actually
have support for shared IRQs, make the .ack_interrupt() callback
optional.

After all drivers have been moved to implement the generic
interrupt handle, the phy_drv_supports_irq() check will be
changed again to only require the .handle_interrupts() callback.

Cc: Alexandru Ardelean <alexandru.ardelean@analog.com>
Cc: Andre Edich <andre.edich@microchip.com>
Cc: Antoine Tenart <atenart@kernel.org>
Cc: Baruch Siach <baruch@tkos.co.il>
Cc: Christophe Leroy <christophe.leroy@c-s.fr>
Cc: Dan Murphy <dmurphy@ti.com>
Cc: Divya Koppera <Divya.Koppera@microchip.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Hauke Mehrtens <hauke@hauke-m.de>
Cc: Heiner Kallweit <hkallweit1@gmail.com>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Cc: Kavya Sree Kotagiri <kavyasree.kotagiri@microchip.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Marco Felsch <m.felsch@pengutronix.de>
Cc: Marek Vasut <marex@denx.de>
Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Cc: Mathias Kresin <dev@kresin.me>
Cc: Maxim Kochetkov <fido_max@inbox.ru>
Cc: Michael Walle <michael@walle.cc>
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Nisar Sayed <Nisar.Sayed@microchip.com>
Cc: Oleksij Rempel <o.rempel@pengutronix.de>
Cc: Philippe Schenker <philippe.schenker@toradex.com>
Cc: Willy Liu <willy.liu@realtek.com>
Cc: Yuiko Oshino <yuiko.oshino@microchip.com>
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/net/phy/phy_device.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 413a0a2c5d51..f54f483d7fd6 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -2815,7 +2815,7 @@ EXPORT_SYMBOL(phy_get_internal_delay);
 
 static bool phy_drv_supports_irq(struct phy_driver *phydrv)
 {
-	return phydrv->config_intr && phydrv->ack_interrupt;
+	return phydrv->config_intr && (phydrv->ack_interrupt || phydrv->handle_interrupt);
 }
 
 /**
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC net-next 4/5] net: phy: at803x: implement generic .handle_interrupt() callback
  2020-10-24 12:14 [RFC net-next 0/5] net: phy: add support for shared interrupts Ioana Ciornei
                   ` (2 preceding siblings ...)
  2020-10-24 12:14 ` [RFC net-next 3/5] net: phy: make .ack_interrupt() optional Ioana Ciornei
@ 2020-10-24 12:14 ` Ioana Ciornei
  2020-10-24 12:14 ` [RFC net-next 5/5] net: phy: at803x: remove the use of .ack_interrupt() Ioana Ciornei
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Ioana Ciornei @ 2020-10-24 12:14 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit, Russell King, Jakub Kicinski,
	netdev, linux-kernel
  Cc: Ioana Ciornei, Oleksij Rempel, Michael Walle

In an attempt to actually support shared IRQs in phylib, we now move the
responsibility of triggering the phylib state machine or just returning
IRQ_NONE, based on the IRQ status register, to the PHY driver. Having
3 different IRQ handling callbacks (.handle_interrupt(),
.did_interrupt() and .ack_interrupt() ) is confusing so let the PHY
driver implement directly an IRQ handler like any other device driver.
Make this driver follow the new convention.

Cc: Oleksij Rempel <o.rempel@pengutronix.de>
Cc: Michael Walle <michael@walle.cc>
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/net/phy/at803x.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index ed601a7e46a0..106c6f53755f 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -628,6 +628,24 @@ static int at803x_config_intr(struct phy_device *phydev)
 	return err;
 }
 
+static irqreturn_t at803x_handle_interrupt(struct phy_device *phydev)
+{
+	int irq_status;
+
+	irq_status = phy_read(phydev, AT803X_INTR_STATUS);
+	if (irq_status < 0) {
+		phy_error(phydev);
+		return IRQ_NONE;
+	}
+
+	if (irq_status == 0)
+		return IRQ_NONE;
+
+	phy_trigger_machine(phydev);
+
+	return IRQ_HANDLED;
+}
+
 static void at803x_link_change_notify(struct phy_device *phydev)
 {
 	/*
@@ -1064,6 +1082,7 @@ static struct phy_driver at803x_driver[] = {
 	.read_status		= at803x_read_status,
 	.ack_interrupt		= at803x_ack_interrupt,
 	.config_intr		= at803x_config_intr,
+	.handle_interrupt	= at803x_handle_interrupt,
 	.get_tunable		= at803x_get_tunable,
 	.set_tunable		= at803x_set_tunable,
 	.cable_test_start	= at803x_cable_test_start,
@@ -1084,6 +1103,7 @@ static struct phy_driver at803x_driver[] = {
 	/* PHY_BASIC_FEATURES */
 	.ack_interrupt		= at803x_ack_interrupt,
 	.config_intr		= at803x_config_intr,
+	.handle_interrupt	= at803x_handle_interrupt,
 }, {
 	/* Qualcomm Atheros AR8031/AR8033 */
 	PHY_ID_MATCH_EXACT(ATH8031_PHY_ID),
@@ -1102,6 +1122,7 @@ static struct phy_driver at803x_driver[] = {
 	.aneg_done		= at803x_aneg_done,
 	.ack_interrupt		= &at803x_ack_interrupt,
 	.config_intr		= &at803x_config_intr,
+	.handle_interrupt	= at803x_handle_interrupt,
 	.get_tunable		= at803x_get_tunable,
 	.set_tunable		= at803x_set_tunable,
 	.cable_test_start	= at803x_cable_test_start,
@@ -1122,6 +1143,7 @@ static struct phy_driver at803x_driver[] = {
 	/* PHY_BASIC_FEATURES */
 	.ack_interrupt		= at803x_ack_interrupt,
 	.config_intr		= at803x_config_intr,
+	.handle_interrupt	= at803x_handle_interrupt,
 	.cable_test_start	= at803x_cable_test_start,
 	.cable_test_get_status	= at803x_cable_test_get_status,
 }, {
@@ -1134,6 +1156,7 @@ static struct phy_driver at803x_driver[] = {
 	/* PHY_BASIC_FEATURES */
 	.ack_interrupt		= &at803x_ack_interrupt,
 	.config_intr		= &at803x_config_intr,
+	.handle_interrupt	= at803x_handle_interrupt,
 	.cable_test_start	= at803x_cable_test_start,
 	.cable_test_get_status	= at803x_cable_test_get_status,
 	.read_status		= at803x_read_status,
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [RFC net-next 5/5] net: phy: at803x: remove the use of .ack_interrupt()
  2020-10-24 12:14 [RFC net-next 0/5] net: phy: add support for shared interrupts Ioana Ciornei
                   ` (3 preceding siblings ...)
  2020-10-24 12:14 ` [RFC net-next 4/5] net: phy: at803x: implement generic .handle_interrupt() callback Ioana Ciornei
@ 2020-10-24 12:14 ` Ioana Ciornei
  2020-10-24 14:09 ` [RFC net-next 0/5] net: phy: add support for shared interrupts Ioana Ciornei
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Ioana Ciornei @ 2020-10-24 12:14 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit, Russell King, Jakub Kicinski,
	netdev, linux-kernel
  Cc: Ioana Ciornei, Oleksij Rempel, Michael Walle

In preparation of removing the .ack_interrupt() callback, we must replace
its occurrences (aka phy_clear_interrupt), from the 2 places where it is
called from (phy_enable_interrupts and phy_disable_interrupts), with
equivalent functionality.

This means that clearing interrupts now becomes something that the PHY
driver is responsible of doing, before enabling interrupts and after
clearing them. Make this driver follow the new contract.

Cc: Oleksij Rempel <o.rempel@pengutronix.de>
Cc: Michael Walle <michael@walle.cc>
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
 drivers/net/phy/at803x.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 106c6f53755f..aba198adf62d 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -614,6 +614,11 @@ static int at803x_config_intr(struct phy_device *phydev)
 	value = phy_read(phydev, AT803X_INTR_ENABLE);
 
 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
+		/* Clear any pending interrupts */
+		err = at803x_ack_interrupt(phydev);
+		if (err)
+			return err;
+
 		value |= AT803X_INTR_ENABLE_AUTONEG_ERR;
 		value |= AT803X_INTR_ENABLE_SPEED_CHANGED;
 		value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED;
@@ -621,9 +626,14 @@ static int at803x_config_intr(struct phy_device *phydev)
 		value |= AT803X_INTR_ENABLE_LINK_SUCCESS;
 
 		err = phy_write(phydev, AT803X_INTR_ENABLE, value);
-	}
-	else
+	} else {
 		err = phy_write(phydev, AT803X_INTR_ENABLE, 0);
+		if (err)
+			return err;
+
+		/* Clear any pending interrupts */
+		err = at803x_ack_interrupt(phydev);
+	}
 
 	return err;
 }
@@ -1080,7 +1090,6 @@ static struct phy_driver at803x_driver[] = {
 	.resume			= at803x_resume,
 	/* PHY_GBIT_FEATURES */
 	.read_status		= at803x_read_status,
-	.ack_interrupt		= at803x_ack_interrupt,
 	.config_intr		= at803x_config_intr,
 	.handle_interrupt	= at803x_handle_interrupt,
 	.get_tunable		= at803x_get_tunable,
@@ -1101,7 +1110,6 @@ static struct phy_driver at803x_driver[] = {
 	.suspend		= at803x_suspend,
 	.resume			= at803x_resume,
 	/* PHY_BASIC_FEATURES */
-	.ack_interrupt		= at803x_ack_interrupt,
 	.config_intr		= at803x_config_intr,
 	.handle_interrupt	= at803x_handle_interrupt,
 }, {
@@ -1120,7 +1128,6 @@ static struct phy_driver at803x_driver[] = {
 	/* PHY_GBIT_FEATURES */
 	.read_status		= at803x_read_status,
 	.aneg_done		= at803x_aneg_done,
-	.ack_interrupt		= &at803x_ack_interrupt,
 	.config_intr		= &at803x_config_intr,
 	.handle_interrupt	= at803x_handle_interrupt,
 	.get_tunable		= at803x_get_tunable,
@@ -1141,7 +1148,6 @@ static struct phy_driver at803x_driver[] = {
 	.suspend		= at803x_suspend,
 	.resume			= at803x_resume,
 	/* PHY_BASIC_FEATURES */
-	.ack_interrupt		= at803x_ack_interrupt,
 	.config_intr		= at803x_config_intr,
 	.handle_interrupt	= at803x_handle_interrupt,
 	.cable_test_start	= at803x_cable_test_start,
@@ -1154,7 +1160,6 @@ static struct phy_driver at803x_driver[] = {
 	.resume			= at803x_resume,
 	.flags			= PHY_POLL_CABLE_TEST,
 	/* PHY_BASIC_FEATURES */
-	.ack_interrupt		= &at803x_ack_interrupt,
 	.config_intr		= &at803x_config_intr,
 	.handle_interrupt	= at803x_handle_interrupt,
 	.cable_test_start	= at803x_cable_test_start,
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [RFC net-next 0/5] net: phy: add support for shared interrupts
  2020-10-24 12:14 [RFC net-next 0/5] net: phy: add support for shared interrupts Ioana Ciornei
                   ` (4 preceding siblings ...)
  2020-10-24 12:14 ` [RFC net-next 5/5] net: phy: at803x: remove the use of .ack_interrupt() Ioana Ciornei
@ 2020-10-24 14:09 ` Ioana Ciornei
  2020-10-24 17:17 ` Andrew Lunn
  2020-10-25  8:17 ` Michael Walle
  7 siblings, 0 replies; 13+ messages in thread
From: Ioana Ciornei @ 2020-10-24 14:09 UTC (permalink / raw)
  To: Andrew Lunn, Heiner Kallweit, Russell King, Jakub Kicinski,
	netdev, linux-kernel
  Cc: Alexandru Ardelean, Andre Edich, Antoine Tenart, Baruch Siach,
	Christophe Leroy, Dan Murphy, Divya Koppera, Florian Fainelli,
	Hauke Mehrtens, Jerome Brunet, Kavya Sree Kotagiri,
	Linus Walleij, Marco Felsch, Marek Vasut, Martin Blumenstingl,
	Mathias Kresin, Maxim Kochetkov, Michael Walle, Neil Armstrong,
	Nisar Sayed, Oleksij Rempel, Philippe Schenker, Willy Liu,
	Yuiko Oshino

On Sat, Oct 24, 2020 at 03:14:07PM +0300, Ioana Ciornei wrote:

> This RFC just contains the patches for phylib and a single driver -
> Atheros. The rest can be found on my Github branch here: TODO
> They will be submitted as a multi-part series once the merge window
> closes.
> 

It seems that I forgot to add a link to the Github branch. Here it is:

https://github.com/IoanaCiornei/linux/commits/phylib-shared-irq

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC net-next 0/5] net: phy: add support for shared interrupts
  2020-10-24 12:14 [RFC net-next 0/5] net: phy: add support for shared interrupts Ioana Ciornei
                   ` (5 preceding siblings ...)
  2020-10-24 14:09 ` [RFC net-next 0/5] net: phy: add support for shared interrupts Ioana Ciornei
@ 2020-10-24 17:17 ` Andrew Lunn
  2020-10-24 18:09   ` Russell King - ARM Linux admin
  2020-10-24 18:19   ` Ioana Ciornei
  2020-10-25  8:17 ` Michael Walle
  7 siblings, 2 replies; 13+ messages in thread
From: Andrew Lunn @ 2020-10-24 17:17 UTC (permalink / raw)
  To: Ioana Ciornei
  Cc: Heiner Kallweit, Russell King, Jakub Kicinski, netdev,
	linux-kernel, Alexandru Ardelean, Andre Edich, Antoine Tenart,
	Baruch Siach, Christophe Leroy, Dan Murphy, Divya Koppera,
	Florian Fainelli, Hauke Mehrtens, Jerome Brunet,
	Kavya Sree Kotagiri, Linus Walleij, Marco Felsch, Marek Vasut,
	Martin Blumenstingl, Mathias Kresin, Maxim Kochetkov,
	Michael Walle, Neil Armstrong, Nisar Sayed, Oleksij Rempel,
	Philippe Schenker, Willy Liu, Yuiko Oshino

> - Every PHY driver gains a .handle_interrupt() implementation that, for
>   the most part, would look like below:
> 
> 	irq_status = phy_read(phydev, INTR_STATUS);
> 	if (irq_status < 0) {
> 		phy_error(phydev);
> 		return IRQ_NONE;
> 	}
> 
> 	if (irq_status == 0)
> 		return IRQ_NONE;
> 
> 	phy_trigger_machine(phydev);
> 
> 	return IRQ_HANDLED;

Hi Ioana

It looks like phy_trigger_machine(phydev) could be left in the core,
phy_interrupt(). It just needs to look at the return code, IRQ_HANDLED
means trigger the state machine.

      Andrew

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC net-next 0/5] net: phy: add support for shared interrupts
  2020-10-24 17:17 ` Andrew Lunn
@ 2020-10-24 18:09   ` Russell King - ARM Linux admin
  2020-10-24 20:07     ` Andrew Lunn
  2020-10-24 18:19   ` Ioana Ciornei
  1 sibling, 1 reply; 13+ messages in thread
From: Russell King - ARM Linux admin @ 2020-10-24 18:09 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Ioana Ciornei, Heiner Kallweit, Jakub Kicinski, netdev,
	linux-kernel, Alexandru Ardelean, Andre Edich, Antoine Tenart,
	Baruch Siach, Christophe Leroy, Dan Murphy, Divya Koppera,
	Florian Fainelli, Hauke Mehrtens, Jerome Brunet,
	Kavya Sree Kotagiri, Linus Walleij, Marco Felsch, Marek Vasut,
	Martin Blumenstingl, Mathias Kresin, Maxim Kochetkov,
	Michael Walle, Neil Armstrong, Nisar Sayed, Oleksij Rempel,
	Philippe Schenker, Willy Liu, Yuiko Oshino

On Sat, Oct 24, 2020 at 07:17:05PM +0200, Andrew Lunn wrote:
> > - Every PHY driver gains a .handle_interrupt() implementation that, for
> >   the most part, would look like below:
> > 
> > 	irq_status = phy_read(phydev, INTR_STATUS);
> > 	if (irq_status < 0) {
> > 		phy_error(phydev);
> > 		return IRQ_NONE;
> > 	}
> > 
> > 	if (irq_status == 0)
> > 		return IRQ_NONE;
> > 
> > 	phy_trigger_machine(phydev);
> > 
> > 	return IRQ_HANDLED;
> 
> Hi Ioana
> 
> It looks like phy_trigger_machine(phydev) could be left in the core,
> phy_interrupt(). It just needs to look at the return code, IRQ_HANDLED
> means trigger the state machine.

Is this appropriate for things such as the existing user of
handle_interrupt - vsc8584_handle_interrupt() ?

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC net-next 0/5] net: phy: add support for shared interrupts
  2020-10-24 17:17 ` Andrew Lunn
  2020-10-24 18:09   ` Russell King - ARM Linux admin
@ 2020-10-24 18:19   ` Ioana Ciornei
  1 sibling, 0 replies; 13+ messages in thread
From: Ioana Ciornei @ 2020-10-24 18:19 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Heiner Kallweit, Russell King, Jakub Kicinski, netdev,
	linux-kernel, Alexandru Ardelean, Andre Edich, Antoine Tenart,
	Baruch Siach, Christophe Leroy, Dan Murphy, Divya Koppera,
	Florian Fainelli, Hauke Mehrtens, Jerome Brunet,
	Kavya Sree Kotagiri, Linus Walleij, Marco Felsch, Marek Vasut,
	Martin Blumenstingl, Mathias Kresin, Maxim Kochetkov,
	Michael Walle, Neil Armstrong, Nisar Sayed, Oleksij Rempel,
	Philippe Schenker, Willy Liu, Yuiko Oshino

On Sat, Oct 24, 2020 at 07:17:05PM +0200, Andrew Lunn wrote:
> > - Every PHY driver gains a .handle_interrupt() implementation that, for
> >   the most part, would look like below:
> > 
> > 	irq_status = phy_read(phydev, INTR_STATUS);
> > 	if (irq_status < 0) {
> > 		phy_error(phydev);
> > 		return IRQ_NONE;
> > 	}
> > 
> > 	if (irq_status == 0)
> > 		return IRQ_NONE;
> > 
> > 	phy_trigger_machine(phydev);
> > 
> > 	return IRQ_HANDLED;
> 
> Hi Ioana
> 
> It looks like phy_trigger_machine(phydev) could be left in the core,
> phy_interrupt(). It just needs to look at the return code, IRQ_HANDLED
> means trigger the state machine.

I tend to disagree that this would bring us any benefit.

Keeping the phy_trigger_machine() inside the phy_interrupt() would mean
that we are changing the convention of what the implementation of
.handle_interrupt() should do.

At the moment, there are drivers which use it to handle multiple
interrupt sources within the same PHY device (e.g. MACSEC, 1588, link
state). With your suggestion, when a MACSEC interrupt is received, the
PHY driver would be forced to return IRQ_NONE just so phylib does not
trigger the link state machine. I think this would eventually lead to
some "irq X: nobody cared".

Also, the vsc8584_handle_interrupt() already calls a wrapper over
phy_trigger_machine() called phy_mac_interrupt() which was intended for
MAC driver use only.

Ioana

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC net-next 0/5] net: phy: add support for shared interrupts
  2020-10-24 18:09   ` Russell King - ARM Linux admin
@ 2020-10-24 20:07     ` Andrew Lunn
  0 siblings, 0 replies; 13+ messages in thread
From: Andrew Lunn @ 2020-10-24 20:07 UTC (permalink / raw)
  To: Russell King - ARM Linux admin
  Cc: Ioana Ciornei, Heiner Kallweit, Jakub Kicinski, netdev,
	linux-kernel, Alexandru Ardelean, Andre Edich, Antoine Tenart,
	Baruch Siach, Christophe Leroy, Dan Murphy, Divya Koppera,
	Florian Fainelli, Hauke Mehrtens, Jerome Brunet,
	Kavya Sree Kotagiri, Linus Walleij, Marco Felsch, Marek Vasut,
	Martin Blumenstingl, Mathias Kresin, Maxim Kochetkov,
	Michael Walle, Neil Armstrong, Nisar Sayed, Oleksij Rempel,
	Philippe Schenker, Willy Liu, Yuiko Oshino

On Sat, Oct 24, 2020 at 07:09:53PM +0100, Russell King - ARM Linux admin wrote:
> On Sat, Oct 24, 2020 at 07:17:05PM +0200, Andrew Lunn wrote:
> > > - Every PHY driver gains a .handle_interrupt() implementation that, for
> > >   the most part, would look like below:
> > > 
> > > 	irq_status = phy_read(phydev, INTR_STATUS);
> > > 	if (irq_status < 0) {
> > > 		phy_error(phydev);
> > > 		return IRQ_NONE;
> > > 	}
> > > 
> > > 	if (irq_status == 0)
> > > 		return IRQ_NONE;
> > > 
> > > 	phy_trigger_machine(phydev);
> > > 
> > > 	return IRQ_HANDLED;
> > 
> > Hi Ioana
> > 
> > It looks like phy_trigger_machine(phydev) could be left in the core,
> > phy_interrupt(). It just needs to look at the return code, IRQ_HANDLED
> > means trigger the state machine.
> 
> Is this appropriate for things such as the existing user of
> handle_interrupt - vsc8584_handle_interrupt() ?

Ah, yes, you are likely to get a lot more ptp interrupts than link
up/down interrupts, and there is no point running the phy state
machine after each ptp interrupt. So Ioana's structure is better.

And now that phy_trigger_machine is exported, that driver can swap
from phy_mac_interrupt() to phy_trigger_machine().

	Andrew

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC net-next 0/5] net: phy: add support for shared interrupts
  2020-10-24 12:14 [RFC net-next 0/5] net: phy: add support for shared interrupts Ioana Ciornei
                   ` (6 preceding siblings ...)
  2020-10-24 17:17 ` Andrew Lunn
@ 2020-10-25  8:17 ` Michael Walle
  2020-10-25 10:18   ` Ioana Ciornei
  7 siblings, 1 reply; 13+ messages in thread
From: Michael Walle @ 2020-10-25  8:17 UTC (permalink / raw)
  To: Ioana Ciornei
  Cc: Andrew Lunn, Heiner Kallweit, Russell King, Jakub Kicinski,
	netdev, linux-kernel, Alexandru Ardelean, Andre Edich,
	Antoine Tenart, Baruch Siach, Christophe Leroy, Dan Murphy,
	Divya Koppera, Florian Fainelli, Hauke Mehrtens, Jerome Brunet,
	Kavya Sree Kotagiri, Linus Walleij, Marco Felsch, Marek Vasut,
	Martin Blumenstingl, Mathias Kresin, Maxim Kochetkov,
	Neil Armstrong, Nisar Sayed, Oleksij Rempel, Philippe Schenker,
	Willy Liu, Yuiko Oshino

Am 2020-10-24 14:14, schrieb Ioana Ciornei:
> - Every PHY driver gains a .handle_interrupt() implementation that, for
>   the most part, would look like below:
> 
> 	irq_status = phy_read(phydev, INTR_STATUS);
> 	if (irq_status < 0) {
> 		phy_error(phydev);
> 		return IRQ_NONE;
> 	}
> 
> 	if (irq_status == 0)
> 		return IRQ_NONE;
> 
> 	phy_trigger_machine(phydev);
> 
> 	return IRQ_HANDLED;

Would it make sense to provide this (default) version inside the core?
Simple PHY drivers then just could set the callback to this function.
(There must be some property for the INTR_STATUS, which is likely to
be different between different PHYs, though).

-michael

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC net-next 0/5] net: phy: add support for shared interrupts
  2020-10-25  8:17 ` Michael Walle
@ 2020-10-25 10:18   ` Ioana Ciornei
  0 siblings, 0 replies; 13+ messages in thread
From: Ioana Ciornei @ 2020-10-25 10:18 UTC (permalink / raw)
  To: Michael Walle
  Cc: Andrew Lunn, Heiner Kallweit, Russell King, Jakub Kicinski,
	netdev, linux-kernel, Alexandru Ardelean, Andre Edich,
	Antoine Tenart, Baruch Siach, Christophe Leroy, Dan Murphy,
	Divya Koppera, Florian Fainelli, Hauke Mehrtens, Jerome Brunet,
	Kavya Sree Kotagiri, Linus Walleij, Marco Felsch, Marek Vasut,
	Martin Blumenstingl, Mathias Kresin, Maxim Kochetkov,
	Neil Armstrong, Nisar Sayed, Oleksij Rempel, Philippe Schenker,
	Willy Liu, Yuiko Oshino

On Sun, Oct 25, 2020 at 09:17:58AM +0100, Michael Walle wrote:
> Am 2020-10-24 14:14, schrieb Ioana Ciornei:
> > - Every PHY driver gains a .handle_interrupt() implementation that, for
> >   the most part, would look like below:
> > 
> > 	irq_status = phy_read(phydev, INTR_STATUS);
> > 	if (irq_status < 0) {
> > 		phy_error(phydev);
> > 		return IRQ_NONE;
> > 	}
> > 
> > 	if (irq_status == 0)
> > 		return IRQ_NONE;
> > 
> > 	phy_trigger_machine(phydev);
> > 
> > 	return IRQ_HANDLED;
> 
> Would it make sense to provide this (default) version inside the core?
> Simple PHY drivers then just could set the callback to this function.
> (There must be some property for the INTR_STATUS, which is likely to
> be different between different PHYs, though).

Yes, the interrupt status register's address differs even between PHYs
from the same vendor so making this somehow into a default handler would
mean to add even another callback that actually reads the register.

For simple PHY drivers, the .handle_interrupt() implementation would
mean 15-20 lines of code for a much more straightforward implementation.
I think that's fair.

Ioana

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2020-10-25 10:18 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-24 12:14 [RFC net-next 0/5] net: phy: add support for shared interrupts Ioana Ciornei
2020-10-24 12:14 ` [RFC net-next 1/5] net: phy: export phy_error and phy_trigger_machine Ioana Ciornei
2020-10-24 12:14 ` [RFC net-next 2/5] net: phy: add a shutdown procedure Ioana Ciornei
2020-10-24 12:14 ` [RFC net-next 3/5] net: phy: make .ack_interrupt() optional Ioana Ciornei
2020-10-24 12:14 ` [RFC net-next 4/5] net: phy: at803x: implement generic .handle_interrupt() callback Ioana Ciornei
2020-10-24 12:14 ` [RFC net-next 5/5] net: phy: at803x: remove the use of .ack_interrupt() Ioana Ciornei
2020-10-24 14:09 ` [RFC net-next 0/5] net: phy: add support for shared interrupts Ioana Ciornei
2020-10-24 17:17 ` Andrew Lunn
2020-10-24 18:09   ` Russell King - ARM Linux admin
2020-10-24 20:07     ` Andrew Lunn
2020-10-24 18:19   ` Ioana Ciornei
2020-10-25  8:17 ` Michael Walle
2020-10-25 10:18   ` Ioana Ciornei

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).