Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b710a1f4 authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik
Browse files

ahci: factor out AHCI enabling and enable AHCI before reading CAP



Factor out AHCI enabling into ahci_enable_ahci() and enabling AHCI
before reading CAP in ahci_save_initial_config() as the spec requires
enabling AHCI mode before accessing any other registers.

Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent c7290724
Loading
Loading
Loading
Loading
+20 −7
Original line number Diff line number Diff line
@@ -597,6 +597,20 @@ static inline void __iomem *ahci_port_base(struct ata_port *ap)
	return __ahci_port_base(ap->host, ap->port_no);
}

static void ahci_enable_ahci(void __iomem *mmio)
{
	u32 tmp;

	/* turn on AHCI_EN */
	tmp = readl(mmio + HOST_CTL);
	if (!(tmp & HOST_AHCI_EN)) {
		tmp |= HOST_AHCI_EN;
		writel(tmp, mmio + HOST_CTL);
		tmp = readl(mmio + HOST_CTL);	/* flush && sanity check */
		WARN_ON(!(tmp & HOST_AHCI_EN));
	}
}

/**
 *	ahci_save_initial_config - Save and fixup initial config values
 *	@pdev: target PCI device
@@ -619,6 +633,9 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
	u32 cap, port_map;
	int i;

	/* make sure AHCI mode is enabled before accessing CAP */
	ahci_enable_ahci(mmio);

	/* Values prefixed with saved_ are written back to host after
	 * reset.  Values without are used for driver operation.
	 */
@@ -1043,13 +1060,10 @@ static int ahci_reset_controller(struct ata_host *host)
	/* we must be in AHCI mode, before using anything
	 * AHCI-specific, such as HOST_RESET.
	 */
	tmp = readl(mmio + HOST_CTL);
	if (!(tmp & HOST_AHCI_EN)) {
		tmp |= HOST_AHCI_EN;
		writel(tmp, mmio + HOST_CTL);
	}
	ahci_enable_ahci(mmio);

	/* global controller reset */
	tmp = readl(mmio + HOST_CTL);
	if ((tmp & HOST_RESET) == 0) {
		writel(tmp | HOST_RESET, mmio + HOST_CTL);
		readl(mmio + HOST_CTL); /* flush */
@@ -1068,8 +1082,7 @@ static int ahci_reset_controller(struct ata_host *host)
	}

	/* turn on AHCI mode */
	writel(HOST_AHCI_EN, mmio + HOST_CTL);
	(void) readl(mmio + HOST_CTL);	/* flush */
	ahci_enable_ahci(mmio);

	/* some registers might be cleared on reset.  restore initial values */
	ahci_restore_initial_config(host);