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
...@@ -597,6 +597,20 @@ static inline void __iomem *ahci_port_base(struct ata_port *ap) ...@@ -597,6 +597,20 @@ static inline void __iomem *ahci_port_base(struct ata_port *ap)
return __ahci_port_base(ap->host, ap->port_no); 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 * ahci_save_initial_config - Save and fixup initial config values
* @pdev: target PCI device * @pdev: target PCI device
...@@ -619,6 +633,9 @@ static void ahci_save_initial_config(struct pci_dev *pdev, ...@@ -619,6 +633,9 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
u32 cap, port_map; u32 cap, port_map;
int i; 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 /* Values prefixed with saved_ are written back to host after
* reset. Values without are used for driver operation. * reset. Values without are used for driver operation.
*/ */
...@@ -1043,13 +1060,10 @@ static int ahci_reset_controller(struct ata_host *host) ...@@ -1043,13 +1060,10 @@ static int ahci_reset_controller(struct ata_host *host)
/* we must be in AHCI mode, before using anything /* we must be in AHCI mode, before using anything
* AHCI-specific, such as HOST_RESET. * AHCI-specific, such as HOST_RESET.
*/ */
tmp = readl(mmio + HOST_CTL); ahci_enable_ahci(mmio);
if (!(tmp & HOST_AHCI_EN)) {
tmp |= HOST_AHCI_EN;
writel(tmp, mmio + HOST_CTL);
}
/* global controller reset */ /* global controller reset */
tmp = readl(mmio + HOST_CTL);
if ((tmp & HOST_RESET) == 0) { if ((tmp & HOST_RESET) == 0) {
writel(tmp | HOST_RESET, mmio + HOST_CTL); writel(tmp | HOST_RESET, mmio + HOST_CTL);
readl(mmio + HOST_CTL); /* flush */ readl(mmio + HOST_CTL); /* flush */
...@@ -1068,8 +1082,7 @@ static int ahci_reset_controller(struct ata_host *host) ...@@ -1068,8 +1082,7 @@ static int ahci_reset_controller(struct ata_host *host)
} }
/* turn on AHCI mode */ /* turn on AHCI mode */
writel(HOST_AHCI_EN, mmio + HOST_CTL); ahci_enable_ahci(mmio);
(void) readl(mmio + HOST_CTL); /* flush */
/* some registers might be cleared on reset. restore initial values */ /* some registers might be cleared on reset. restore initial values */
ahci_restore_initial_config(host); ahci_restore_initial_config(host);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment