diff options
author | Mark Lord <liml@rtr.ca> | 2008-03-31 19:34:40 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-17 15:44:21 -0400 |
commit | b562468cc3bd0c81decba1f5f39a7173f839e57e (patch) | |
tree | 60239c6f86eb2aa92e59d16f74c1dabd474d2046 /drivers/ata/sata_mv.c | |
parent | e12bef50b7660cf7c19d1cd3eac381b9eff734d7 (diff) |
sata_mv clean up mv_stop_edma usage
Clean up uses of mv_stop_edma{_engine}() to match datasheet requirements.
Signed-off-by: Mark Lord <mlord@pobox.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r-- | drivers/ata/sata_mv.c | 87 |
1 files changed, 42 insertions, 45 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index ee6ca97c4545..5b9f937d0f87 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -517,7 +517,7 @@ static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio); | |||
517 | static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio, | 517 | static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio, |
518 | unsigned int port_no); | 518 | unsigned int port_no); |
519 | static int mv_stop_edma(struct ata_port *ap); | 519 | static int mv_stop_edma(struct ata_port *ap); |
520 | static int mv_stop_edma_engine(struct ata_port *ap); | 520 | static int mv_stop_edma_engine(void __iomem *port_mmio); |
521 | static void mv_edma_cfg(struct ata_port *ap, int want_ncq); | 521 | static void mv_edma_cfg(struct ata_port *ap, int want_ncq); |
522 | 522 | ||
523 | /* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below | 523 | /* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below |
@@ -805,7 +805,7 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, | |||
805 | if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { | 805 | if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { |
806 | int using_ncq = ((pp->pp_flags & MV_PP_FLAG_NCQ_EN) != 0); | 806 | int using_ncq = ((pp->pp_flags & MV_PP_FLAG_NCQ_EN) != 0); |
807 | if (want_ncq != using_ncq) | 807 | if (want_ncq != using_ncq) |
808 | mv_stop_edma_engine(ap); | 808 | mv_stop_edma(ap); |
809 | } | 809 | } |
810 | if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) { | 810 | if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) { |
811 | struct mv_host_priv *hpriv = ap->host->private_data; | 811 | struct mv_host_priv *hpriv = ap->host->private_data; |
@@ -841,57 +841,41 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, | |||
841 | 841 | ||
842 | /** | 842 | /** |
843 | * mv_stop_edma_engine - Disable eDMA engine | 843 | * mv_stop_edma_engine - Disable eDMA engine |
844 | * @ap: ATA channel to manipulate | 844 | * @port_mmio: io base address |
845 | * | ||
846 | * Verify the local cache of the eDMA state is accurate with a | ||
847 | * WARN_ON. | ||
848 | * | 845 | * |
849 | * LOCKING: | 846 | * LOCKING: |
850 | * Inherited from caller. | 847 | * Inherited from caller. |
851 | */ | 848 | */ |
852 | static int mv_stop_edma_engine(struct ata_port *ap) | 849 | static int mv_stop_edma_engine(void __iomem *port_mmio) |
853 | { | 850 | { |
854 | void __iomem *port_mmio = mv_ap_base(ap); | 851 | int i; |
855 | struct mv_port_priv *pp = ap->private_data; | ||
856 | u32 reg; | ||
857 | int i, err = 0; | ||
858 | 852 | ||
859 | if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { | 853 | /* Disable eDMA. The disable bit auto clears. */ |
860 | /* Disable EDMA if active. The disable bit auto clears. | 854 | writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS); |
861 | */ | ||
862 | writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS); | ||
863 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; | ||
864 | } else { | ||
865 | WARN_ON(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS)); | ||
866 | } | ||
867 | 855 | ||
868 | /* now properly wait for the eDMA to stop */ | 856 | /* Wait for the chip to confirm eDMA is off. */ |
869 | for (i = 1000; i > 0; i--) { | 857 | for (i = 10000; i > 0; i--) { |
870 | reg = readl(port_mmio + EDMA_CMD_OFS); | 858 | u32 reg = readl(port_mmio + EDMA_CMD_OFS); |
871 | if (!(reg & EDMA_EN)) | 859 | if (!(reg & EDMA_EN)) |
872 | break; | 860 | return 0; |
873 | 861 | udelay(10); | |
874 | udelay(100); | ||
875 | } | ||
876 | |||
877 | if (reg & EDMA_EN) { | ||
878 | ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n"); | ||
879 | err = -EIO; | ||
880 | } | 862 | } |
881 | 863 | return -EIO; | |
882 | return err; | ||
883 | } | 864 | } |
884 | 865 | ||
885 | static int mv_stop_edma(struct ata_port *ap) | 866 | static int mv_stop_edma(struct ata_port *ap) |
886 | { | 867 | { |
887 | unsigned long flags; | 868 | void __iomem *port_mmio = mv_ap_base(ap); |
888 | int rc; | 869 | struct mv_port_priv *pp = ap->private_data; |
889 | |||
890 | spin_lock_irqsave(&ap->host->lock, flags); | ||
891 | rc = mv_stop_edma_engine(ap); | ||
892 | spin_unlock_irqrestore(&ap->host->lock, flags); | ||
893 | 870 | ||
894 | return rc; | 871 | if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) |
872 | return 0; | ||
873 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; | ||
874 | if (mv_stop_edma_engine(port_mmio)) { | ||
875 | ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n"); | ||
876 | return -EIO; | ||
877 | } | ||
878 | return 0; | ||
895 | } | 879 | } |
896 | 880 | ||
897 | #ifdef ATA_DEBUG | 881 | #ifdef ATA_DEBUG |
@@ -1401,7 +1385,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) | |||
1401 | * port. Turn off EDMA so there won't be problems accessing | 1385 | * port. Turn off EDMA so there won't be problems accessing |
1402 | * shadow block, etc registers. | 1386 | * shadow block, etc registers. |
1403 | */ | 1387 | */ |
1404 | mv_stop_edma_engine(ap); | 1388 | mv_stop_edma(ap); |
1405 | return ata_qc_issue_prot(qc); | 1389 | return ata_qc_issue_prot(qc); |
1406 | } | 1390 | } |
1407 | 1391 | ||
@@ -1915,8 +1899,12 @@ static void mv5_reset_hc_port(struct mv_host_priv *hpriv, void __iomem *mmio, | |||
1915 | { | 1899 | { |
1916 | void __iomem *port_mmio = mv_port_base(mmio, port); | 1900 | void __iomem *port_mmio = mv_port_base(mmio, port); |
1917 | 1901 | ||
1918 | writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS); | 1902 | /* |
1919 | 1903 | * The datasheet warns against setting ATA_RST when EDMA is active | |
1904 | * (but doesn't say what the problem might be). So we first try | ||
1905 | * to disable the EDMA engine before doing the ATA_RST operation. | ||
1906 | */ | ||
1907 | mv_stop_edma_engine(port_mmio); | ||
1920 | mv_reset_channel(hpriv, mmio, port); | 1908 | mv_reset_channel(hpriv, mmio, port); |
1921 | 1909 | ||
1922 | ZERO(0x028); /* command */ | 1910 | ZERO(0x028); /* command */ |
@@ -2191,8 +2179,12 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv, | |||
2191 | { | 2179 | { |
2192 | void __iomem *port_mmio = mv_port_base(mmio, port); | 2180 | void __iomem *port_mmio = mv_port_base(mmio, port); |
2193 | 2181 | ||
2194 | writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS); | 2182 | /* |
2195 | 2183 | * The datasheet warns against setting ATA_RST when EDMA is active | |
2184 | * (but doesn't say what the problem might be). So we first try | ||
2185 | * to disable the EDMA engine before doing the ATA_RST operation. | ||
2186 | */ | ||
2187 | mv_stop_edma_engine(port_mmio); | ||
2196 | mv_reset_channel(hpriv, mmio, port); | 2188 | mv_reset_channel(hpriv, mmio, port); |
2197 | 2189 | ||
2198 | ZERO(0x028); /* command */ | 2190 | ZERO(0x028); /* command */ |
@@ -2250,6 +2242,10 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio) | |||
2250 | return; | 2242 | return; |
2251 | } | 2243 | } |
2252 | 2244 | ||
2245 | /* | ||
2246 | * Caller must ensure that EDMA is not active, | ||
2247 | * by first doing mv_stop_edma() where needed. | ||
2248 | */ | ||
2253 | static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio, | 2249 | static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio, |
2254 | unsigned int port_no) | 2250 | unsigned int port_no) |
2255 | { | 2251 | { |
@@ -2392,10 +2388,11 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class, | |||
2392 | { | 2388 | { |
2393 | struct ata_port *ap = link->ap; | 2389 | struct ata_port *ap = link->ap; |
2394 | struct mv_host_priv *hpriv = ap->host->private_data; | 2390 | struct mv_host_priv *hpriv = ap->host->private_data; |
2391 | struct mv_port_priv *pp = ap->private_data; | ||
2395 | void __iomem *mmio = hpriv->base; | 2392 | void __iomem *mmio = hpriv->base; |
2396 | 2393 | ||
2397 | mv_stop_edma(ap); | ||
2398 | mv_reset_channel(hpriv, mmio, ap->port_no); | 2394 | mv_reset_channel(hpriv, mmio, ap->port_no); |
2395 | pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; | ||
2399 | mv_phy_reset(ap, class, deadline); | 2396 | mv_phy_reset(ap, class, deadline); |
2400 | 2397 | ||
2401 | return 0; | 2398 | return 0; |