Re: [PATCH v3 14/15] ata: ahci: add shutdown helpers for AHCI controllers
"Sascha Hauer" <[email protected]> Mon, 03 Aug 2026 21:55:58 +0000
| Newsgroups | org.infradead.lists.barebox |
|---|---|
| Message-ID | <[email protected]> |
On 2026-08-02 15:16, Luca Lauro via B4 Relay wrote: > From: Luca Lauro <[email protected]> >=20 > Introduce helper functions to stop the DMA engine and FIS receive engine > before shutdown. These helpers mirror the libata shutdown sequence and > ensure that no AHCI activity is in progress when the system powers off. >=20 > Signed-off-by: Luca Lauro <[email protected]> > --- > drivers/ata/ahci.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++= ++++++ > 1 file changed, 60 insertions(+) >=20 > diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c > index a9a3f43f21..e9e73069c1 100644 > --- a/drivers/ata/ahci.c > +++ b/drivers/ata/ahci.c > @@ -21,6 +21,7 @@ > #include <linux/sizes.h> > #include <linux/pci.h> > #include <clock.h> > +#include <poweroff.h> > =20 > #include "ahci.h" > =20 > @@ -683,6 +684,65 @@ static int ahci_probe(struct device *dev) > return ret; > } > =20 > +/* -------------------------------- */ > +/* AHCI shutdown helpers */ > +/* -------------------------------- */ > + > +/* Stop DMA engine (clear START, wait LIST_ON=3D0) */ > +static int ahci_stop_engine(struct ahci_port *port) > +{ > + u32 cmd; > + > + cmd =3D ahci_port_read(port, PORT_CMD); > + > + /* Already stopped? */ > + if (!(cmd & (PORT_CMD_START | PORT_CMD_LIST_ON))) > + return 0; > + > + /* Clear START */ > + cmd &=3D ~PORT_CMD_START; > + ahci_port_write_f(port, PORT_CMD, cmd); > + > + /* Wait for LIST_ON to clear */ > + return wait_on_timeout(500 * MSECOND, > + !(ahci_port_read(port, PORT_CMD) & PORT_CMD_LIST_ON)); > +} > + > +/* Stop FIS receive engine (clear FIS_RX, wait FIS_ON=3D0) */ > +static int ahci_stop_fis_rx(struct ahci_port *port) > +{ > + u32 cmd; > + > + cmd =3D ahci_port_read(port, PORT_CMD); > + cmd &=3D ~PORT_CMD_FIS_RX; > + ahci_port_write_f(port, PORT_CMD, cmd); > + > + /* Wait for FIS_ON to clear */ > + return wait_on_timeout(1000 * MSECOND, > + !(ahci_port_read(port, PORT_CMD) & PORT_CMD_FIS_ON)); > +} > + > +/* Stop all ports (libata_pci_shutdown_one equivalent) */ > +static void __maybe_unused ahci_shutdown_host(struct ahci_device *ahci) > +{ > + int i, n_ports; > + > + n_ports =3D max_t(int, ahci->n_ports, fls(ahci->port_map)); > + > + for (i =3D 0; i < n_ports; i++) { > + struct ahci_port *port =3D &ahci->ports[i]; > + > + if (!(ahci->port_map & (1 << i))) > + continue; > + > + /* Stop DMA engine */ > + ahci_stop_engine(port); > + > + /* Stop FIS receive engine */ > + ahci_stop_fis_rx(port); > + } > +} This only adds unused code. If this is used in another patch, please move it there. Sascha -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |