On 2026-08-02 15:16, Luca Lauro via B4 Relay wrote: > From: Luca Lauro <[email protected]> > > 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. > > Signed-off-by: Luca Lauro <[email protected]> > --- > drivers/ata/ahci.c | 60 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 60 insertions(+) > > 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> > > #include "ahci.h" > > @@ -683,6 +684,65 @@ static int ahci_probe(struct device *dev) > return ret; > } > > +/* -------------------------------- */ > +/* AHCI shutdown helpers */ > +/* -------------------------------- */ > + > +/* Stop DMA engine (clear START, wait LIST_ON=0) */ > +static int ahci_stop_engine(struct ahci_port *port) > +{ > + u32 cmd; > + > + cmd = ahci_port_read(port, PORT_CMD); > + > + /* Already stopped? */ > + if (!(cmd & (PORT_CMD_START | PORT_CMD_LIST_ON))) > + return 0; > + > + /* Clear START */ > + cmd &= ~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=0) */ > +static int ahci_stop_fis_rx(struct ahci_port *port) > +{ > + u32 cmd; > + > + cmd = ahci_port_read(port, PORT_CMD); > + cmd &= ~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 = max_t(int, ahci->n_ports, fls(ahci->port_map)); > + > + for (i = 0; i < n_ports; i++) { > + struct ahci_port *port = &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 |
