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>
This commit is contained in:
parent
c729072459
commit
b710a1f4b3
1 changed files with 20 additions and 7 deletions
|
@ -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,
|
||||||
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)
|
||||||
/* 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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);
|
||||||
|
|
Loading…
Reference in a new issue