aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2008-01-05 09:11:57 -0500
committerJeff Garzik <jeff@garzik.org>2008-01-23 05:24:16 -0500
commitb710a1f4b34438b624e9c6c2dc8bcf54b0b0ba27 (patch)
treef8bb87bd4cbc2591da8c0b9bdaf01b426902800b /drivers/ata
parentc729072459446885c5c200137de1db32da5db4dc (diff)
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')
-rw-r--r--drivers/ata/ahci.c27
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)
597 return __ahci_port_base(ap->host, ap->port_no); 597 return __ahci_port_base(ap->host, ap->port_no);
598} 598}
599 599
600static void ahci_enable_ahci(void __iomem *mmio)
601{
602 u32 tmp;
603
604 /* turn on AHCI_EN */
605 tmp = readl(mmio + HOST_CTL);
606 if (!(tmp & HOST_AHCI_EN)) {
607 tmp |= HOST_AHCI_EN;
608 writel(tmp, mmio + HOST_CTL);
609 tmp = readl(mmio + HOST_CTL); /* flush && sanity check */
610 WARN_ON(!(tmp & HOST_AHCI_EN));
611 }
612}
613
600/** 614/**
601 * ahci_save_initial_config - Save and fixup initial config values 615 * ahci_save_initial_config - Save and fixup initial config values
602 * @pdev: target PCI device 616 * @pdev: target PCI device
@@ -619,6 +633,9 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
619 u32 cap, port_map; 633 u32 cap, port_map;
620 int i; 634 int i;
621 635
636 /* make sure AHCI mode is enabled before accessing CAP */
637 ahci_enable_ahci(mmio);
638
622 /* Values prefixed with saved_ are written back to host after 639 /* Values prefixed with saved_ are written back to host after
623 * reset. Values without are used for driver operation. 640 * reset. Values without are used for driver operation.
624 */ 641 */
@@ -1043,13 +1060,10 @@ static int ahci_reset_controller(struct ata_host *host)
1043 /* we must be in AHCI mode, before using anything 1060 /* we must be in AHCI mode, before using anything
1044 * AHCI-specific, such as HOST_RESET. 1061 * AHCI-specific, such as HOST_RESET.
1045 */ 1062 */
1046 tmp = readl(mmio + HOST_CTL); 1063 ahci_enable_ahci(mmio);
1047 if (!(tmp & HOST_AHCI_EN)) {
1048 tmp |= HOST_AHCI_EN;
1049 writel(tmp, mmio + HOST_CTL);
1050 }
1051 1064
1052 /* global controller reset */ 1065 /* global controller reset */
1066 tmp = readl(mmio + HOST_CTL);
1053 if ((tmp & HOST_RESET) == 0) { 1067 if ((tmp & HOST_RESET) == 0) {
1054 writel(tmp | HOST_RESET, mmio + HOST_CTL); 1068 writel(tmp | HOST_RESET, mmio + HOST_CTL);
1055 readl(mmio + HOST_CTL); /* flush */ 1069 readl(mmio + HOST_CTL); /* flush */
@@ -1068,8 +1082,7 @@ static int ahci_reset_controller(struct ata_host *host)
1068 } 1082 }
1069 1083
1070 /* turn on AHCI mode */ 1084 /* turn on AHCI mode */
1071 writel(HOST_AHCI_EN, mmio + HOST_CTL); 1085 ahci_enable_ahci(mmio);
1072 (void) readl(mmio + HOST_CTL); /* flush */
1073 1086
1074 /* some registers might be cleared on reset. restore initial values */ 1087 /* some registers might be cleared on reset. restore initial values */
1075 ahci_restore_initial_config(host); 1088 ahci_restore_initial_config(host);