diff options
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r-- | drivers/ata/ahci.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 986e3324e302..7c4f886f1f16 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -556,16 +556,27 @@ static inline void __iomem *ahci_port_base(struct ata_port *ap) | |||
556 | 556 | ||
557 | static void ahci_enable_ahci(void __iomem *mmio) | 557 | static void ahci_enable_ahci(void __iomem *mmio) |
558 | { | 558 | { |
559 | int i; | ||
559 | u32 tmp; | 560 | u32 tmp; |
560 | 561 | ||
561 | /* turn on AHCI_EN */ | 562 | /* turn on AHCI_EN */ |
562 | tmp = readl(mmio + HOST_CTL); | 563 | tmp = readl(mmio + HOST_CTL); |
563 | if (!(tmp & HOST_AHCI_EN)) { | 564 | if (tmp & HOST_AHCI_EN) |
565 | return; | ||
566 | |||
567 | /* Some controllers need AHCI_EN to be written multiple times. | ||
568 | * Try a few times before giving up. | ||
569 | */ | ||
570 | for (i = 0; i < 5; i++) { | ||
564 | tmp |= HOST_AHCI_EN; | 571 | tmp |= HOST_AHCI_EN; |
565 | writel(tmp, mmio + HOST_CTL); | 572 | writel(tmp, mmio + HOST_CTL); |
566 | tmp = readl(mmio + HOST_CTL); /* flush && sanity check */ | 573 | tmp = readl(mmio + HOST_CTL); /* flush && sanity check */ |
567 | WARN_ON(!(tmp & HOST_AHCI_EN)); | 574 | if (tmp & HOST_AHCI_EN) |
575 | return; | ||
576 | msleep(10); | ||
568 | } | 577 | } |
578 | |||
579 | WARN_ON(1); | ||
569 | } | 580 | } |
570 | 581 | ||
571 | /** | 582 | /** |