aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/sata_mv.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index b3f35a6af32b..552006853cd7 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -735,6 +735,24 @@ static inline unsigned int mv_hardport_from_port(unsigned int port)
735 return port & MV_PORT_MASK; 735 return port & MV_PORT_MASK;
736} 736}
737 737
738/*
739 * Consolidate some rather tricky bit shift calculations.
740 * This is hot-path stuff, so not a function.
741 * Simple code, with two return values, so macro rather than inline.
742 *
743 * port is the sole input, in range 0..7.
744 * shift is one output, for use with the main_cause and main_mask registers.
745 * hardport is the other output, in range 0..3
746 *
747 * Note that port and hardport may be the same variable in some cases.
748 */
749#define MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport) \
750{ \
751 shift = mv_hc_from_port(port) * HC_SHIFT; \
752 hardport = mv_hardport_from_port(port); \
753 shift += hardport * 2; \
754}
755
738static inline void __iomem *mv_hc_base(void __iomem *base, unsigned int hc) 756static inline void __iomem *mv_hc_base(void __iomem *base, unsigned int hc)
739{ 757{
740 return (base + MV_SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ)); 758 return (base + MV_SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ));
@@ -2412,15 +2430,13 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class,
2412static void mv_eh_freeze(struct ata_port *ap) 2430static void mv_eh_freeze(struct ata_port *ap)
2413{ 2431{
2414 struct mv_host_priv *hpriv = ap->host->private_data; 2432 struct mv_host_priv *hpriv = ap->host->private_data;
2415 unsigned int hc = (ap->port_no > 3) ? 1 : 0; 2433 unsigned int shift, hardport, port = ap->port_no;
2416 unsigned int shift;
2417 u32 main_mask; 2434 u32 main_mask;
2418 2435
2419 /* FIXME: handle coalescing completion events properly */ 2436 /* FIXME: handle coalescing completion events properly */
2420 2437
2421 shift = ap->port_no * 2; 2438 mv_stop_edma(ap);
2422 if (hc > 0) 2439 MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport);
2423 shift++;
2424 2440
2425 /* disable assertion of portN err, done events */ 2441 /* disable assertion of portN err, done events */
2426 main_mask = readl(hpriv->main_mask_reg_addr); 2442 main_mask = readl(hpriv->main_mask_reg_addr);
@@ -2431,28 +2447,22 @@ static void mv_eh_freeze(struct ata_port *ap)
2431static void mv_eh_thaw(struct ata_port *ap) 2447static void mv_eh_thaw(struct ata_port *ap)
2432{ 2448{
2433 struct mv_host_priv *hpriv = ap->host->private_data; 2449 struct mv_host_priv *hpriv = ap->host->private_data;
2434 void __iomem *mmio = hpriv->base; 2450 unsigned int shift, hardport, port = ap->port_no;
2435 unsigned int hc = (ap->port_no > 3) ? 1 : 0; 2451 void __iomem *hc_mmio = mv_hc_base_from_port(hpriv->base, port);
2436 void __iomem *hc_mmio = mv_hc_base(mmio, hc);
2437 void __iomem *port_mmio = mv_ap_base(ap); 2452 void __iomem *port_mmio = mv_ap_base(ap);
2438 unsigned int shift, hc_port_no = ap->port_no;
2439 u32 main_mask, hc_irq_cause; 2453 u32 main_mask, hc_irq_cause;
2440 2454
2441 /* FIXME: handle coalescing completion events properly */ 2455 /* FIXME: handle coalescing completion events properly */
2442 2456
2443 shift = ap->port_no * 2; 2457 MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport);
2444 if (hc > 0) {
2445 shift++;
2446 hc_port_no -= 4;
2447 }
2448 2458
2449 /* clear EDMA errors on this port */ 2459 /* clear EDMA errors on this port */
2450 writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); 2460 writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
2451 2461
2452 /* clear pending irq events */ 2462 /* clear pending irq events */
2453 hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS); 2463 hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
2454 hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hc_port_no); 2464 hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport);
2455 writel(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); 2465 writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
2456 2466
2457 /* enable assertion of portN err, done events */ 2467 /* enable assertion of portN err, done events */
2458 main_mask = readl(hpriv->main_mask_reg_addr); 2468 main_mask = readl(hpriv->main_mask_reg_addr);