diff options
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r-- | drivers/ata/sata_mv.c | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index ef385451ffd5..47184567248d 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -1016,7 +1016,7 @@ static void mv_set_irq_coalescing(struct ata_host *host, | |||
1016 | void __iomem *mmio = hpriv->base, *hc_mmio; | 1016 | void __iomem *mmio = hpriv->base, *hc_mmio; |
1017 | u32 coal_enable = 0; | 1017 | u32 coal_enable = 0; |
1018 | unsigned long flags; | 1018 | unsigned long flags; |
1019 | unsigned int clks; | 1019 | unsigned int clks, is_dual_hc = hpriv->n_ports > MV_PORTS_PER_HC; |
1020 | const u32 coal_disable = PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE | | 1020 | const u32 coal_disable = PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE | |
1021 | ALL_PORTS_COAL_DONE; | 1021 | ALL_PORTS_COAL_DONE; |
1022 | 1022 | ||
@@ -1033,37 +1033,41 @@ static void mv_set_irq_coalescing(struct ata_host *host, | |||
1033 | } | 1033 | } |
1034 | 1034 | ||
1035 | spin_lock_irqsave(&host->lock, flags); | 1035 | spin_lock_irqsave(&host->lock, flags); |
1036 | mv_set_main_irq_mask(host, coal_disable, 0); | ||
1036 | 1037 | ||
1037 | #if 0 /* disabled pending functional clarification from Marvell */ | 1038 | if (is_dual_hc && !IS_GEN_I(hpriv)) { |
1038 | if (!IS_GEN_I(hpriv)) { | ||
1039 | /* | 1039 | /* |
1040 | * GEN_II/GEN_IIE: global thresholds for the entire chip. | 1040 | * GEN_II/GEN_IIE with dual host controllers: |
1041 | * one set of global thresholds for the entire chip. | ||
1041 | */ | 1042 | */ |
1042 | writel(clks, mmio + MV_IRQ_COAL_TIME_THRESHOLD); | 1043 | writel(clks, mmio + MV_IRQ_COAL_TIME_THRESHOLD); |
1043 | writel(count, mmio + MV_IRQ_COAL_IO_THRESHOLD); | 1044 | writel(count, mmio + MV_IRQ_COAL_IO_THRESHOLD); |
1044 | /* clear leftover coal IRQ bit */ | 1045 | /* clear leftover coal IRQ bit */ |
1045 | writelfl(~ALL_PORTS_COAL_IRQ, mmio + MV_IRQ_COAL_CAUSE); | 1046 | writel(~ALL_PORTS_COAL_IRQ, mmio + MV_IRQ_COAL_CAUSE); |
1046 | clks = count = 0; /* so as to clear the alternate regs below */ | 1047 | if (count) |
1047 | coal_enable = ALL_PORTS_COAL_DONE; | 1048 | coal_enable = ALL_PORTS_COAL_DONE; |
1049 | clks = count = 0; /* force clearing of regular regs below */ | ||
1048 | } | 1050 | } |
1049 | #endif | 1051 | |
1050 | /* | 1052 | /* |
1051 | * All chips: independent thresholds for each HC on the chip. | 1053 | * All chips: independent thresholds for each HC on the chip. |
1052 | */ | 1054 | */ |
1053 | hc_mmio = mv_hc_base_from_port(mmio, 0); | 1055 | hc_mmio = mv_hc_base_from_port(mmio, 0); |
1054 | writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS); | 1056 | writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS); |
1055 | writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS); | 1057 | writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS); |
1056 | coal_enable |= PORTS_0_3_COAL_DONE; | 1058 | writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE_OFS); |
1057 | if (hpriv->n_ports > 4) { | 1059 | if (count) |
1060 | coal_enable |= PORTS_0_3_COAL_DONE; | ||
1061 | if (is_dual_hc) { | ||
1058 | hc_mmio = mv_hc_base_from_port(mmio, MV_PORTS_PER_HC); | 1062 | hc_mmio = mv_hc_base_from_port(mmio, MV_PORTS_PER_HC); |
1059 | writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS); | 1063 | writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS); |
1060 | writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS); | 1064 | writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS); |
1061 | coal_enable |= PORTS_4_7_COAL_DONE; | 1065 | writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE_OFS); |
1066 | if (count) | ||
1067 | coal_enable |= PORTS_4_7_COAL_DONE; | ||
1062 | } | 1068 | } |
1063 | if (!count) | ||
1064 | coal_enable = 0; | ||
1065 | mv_set_main_irq_mask(host, coal_disable, coal_enable); | ||
1066 | 1069 | ||
1070 | mv_set_main_irq_mask(host, 0, coal_enable); | ||
1067 | spin_unlock_irqrestore(&host->lock, flags); | 1071 | spin_unlock_irqrestore(&host->lock, flags); |
1068 | } | 1072 | } |
1069 | 1073 | ||