diff options
author | Tejun Heo <htejun@gmail.com> | 2008-01-05 15:11:57 +0100 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-01-23 11:24:16 +0100 |
commit | b710a1f4b34438b624e9c6c2dc8bcf54b0b0ba27 (patch) | |
tree | f8bb87bd4cbc2591da8c0b9bdaf01b426902800b /drivers/ata/ahci.c | |
parent | ata_piix: implement SIDPR SCR access (diff) | |
download | linux-b710a1f4b34438b624e9c6c2dc8bcf54b0b0ba27.tar.xz linux-b710a1f4b34438b624e9c6c2dc8bcf54b0b0ba27.zip |
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: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r-- | drivers/ata/ahci.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 49761bc12cf2..6f089b899a1a 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -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); |