aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libahci.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/ata/libahci.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/ata/libahci.c')
-rw-r--r--drivers/ata/libahci.c246
1 files changed, 107 insertions, 139 deletions
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 8eea309ea212..41223c7f0206 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -56,9 +56,8 @@ MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)
56module_param_named(ignore_sss, ahci_ignore_sss, int, 0444); 56module_param_named(ignore_sss, ahci_ignore_sss, int, 0444);
57MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)"); 57MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)");
58 58
59static int ahci_enable_alpm(struct ata_port *ap, 59static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
60 enum link_pm policy); 60 unsigned hints);
61static void ahci_disable_alpm(struct ata_port *ap);
62static ssize_t ahci_led_show(struct ata_port *ap, char *buf); 61static ssize_t ahci_led_show(struct ata_port *ap, char *buf);
63static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, 62static ssize_t ahci_led_store(struct ata_port *ap, const char *buf,
64 size_t size); 63 size_t size);
@@ -88,10 +87,7 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class,
88static void ahci_postreset(struct ata_link *link, unsigned int *class); 87static void ahci_postreset(struct ata_link *link, unsigned int *class);
89static void ahci_error_handler(struct ata_port *ap); 88static void ahci_error_handler(struct ata_port *ap);
90static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); 89static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
91static int ahci_port_resume(struct ata_port *ap);
92static void ahci_dev_config(struct ata_device *dev); 90static void ahci_dev_config(struct ata_device *dev);
93static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
94 u32 opts);
95#ifdef CONFIG_PM 91#ifdef CONFIG_PM
96static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); 92static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
97#endif 93#endif
@@ -113,6 +109,8 @@ static ssize_t ahci_read_em_buffer(struct device *dev,
113static ssize_t ahci_store_em_buffer(struct device *dev, 109static ssize_t ahci_store_em_buffer(struct device *dev,
114 struct device_attribute *attr, 110 struct device_attribute *attr,
115 const char *buf, size_t size); 111 const char *buf, size_t size);
112static ssize_t ahci_show_em_supported(struct device *dev,
113 struct device_attribute *attr, char *buf);
116 114
117static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); 115static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL);
118static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); 116static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL);
@@ -120,6 +118,7 @@ static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL);
120static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); 118static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL);
121static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, 119static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO,
122 ahci_read_em_buffer, ahci_store_em_buffer); 120 ahci_read_em_buffer, ahci_store_em_buffer);
121static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL);
123 122
124struct device_attribute *ahci_shost_attrs[] = { 123struct device_attribute *ahci_shost_attrs[] = {
125 &dev_attr_link_power_management_policy, 124 &dev_attr_link_power_management_policy,
@@ -130,6 +129,7 @@ struct device_attribute *ahci_shost_attrs[] = {
130 &dev_attr_ahci_host_version, 129 &dev_attr_ahci_host_version,
131 &dev_attr_ahci_port_cmd, 130 &dev_attr_ahci_port_cmd,
132 &dev_attr_em_buffer, 131 &dev_attr_em_buffer,
132 &dev_attr_em_message_supported,
133 NULL 133 NULL
134}; 134};
135EXPORT_SYMBOL_GPL(ahci_shost_attrs); 135EXPORT_SYMBOL_GPL(ahci_shost_attrs);
@@ -164,8 +164,7 @@ struct ata_port_operations ahci_ops = {
164 .pmp_attach = ahci_pmp_attach, 164 .pmp_attach = ahci_pmp_attach,
165 .pmp_detach = ahci_pmp_detach, 165 .pmp_detach = ahci_pmp_detach,
166 166
167 .enable_pm = ahci_enable_alpm, 167 .set_lpm = ahci_set_lpm,
168 .disable_pm = ahci_disable_alpm,
169 .em_show = ahci_led_show, 168 .em_show = ahci_led_show,
170 .em_store = ahci_led_store, 169 .em_store = ahci_led_store,
171 .sw_activity_show = ahci_activity_show, 170 .sw_activity_show = ahci_activity_show,
@@ -348,6 +347,24 @@ static ssize_t ahci_store_em_buffer(struct device *dev,
348 return size; 347 return size;
349} 348}
350 349
350static ssize_t ahci_show_em_supported(struct device *dev,
351 struct device_attribute *attr, char *buf)
352{
353 struct Scsi_Host *shost = class_to_shost(dev);
354 struct ata_port *ap = ata_shost_to_port(shost);
355 struct ahci_host_priv *hpriv = ap->host->private_data;
356 void __iomem *mmio = hpriv->mmio;
357 u32 em_ctl;
358
359 em_ctl = readl(mmio + HOST_EM_CTL);
360
361 return sprintf(buf, "%s%s%s%s\n",
362 em_ctl & EM_CTL_LED ? "led " : "",
363 em_ctl & EM_CTL_SAFTE ? "saf-te " : "",
364 em_ctl & EM_CTL_SES ? "ses-2 " : "",
365 em_ctl & EM_CTL_SGPIO ? "sgpio " : "");
366}
367
351/** 368/**
352 * ahci_save_initial_config - Save and fixup initial config values 369 * ahci_save_initial_config - Save and fixup initial config values
353 * @dev: target AHCI device 370 * @dev: target AHCI device
@@ -435,7 +452,7 @@ void ahci_save_initial_config(struct device *dev,
435 } 452 }
436 453
437 if (mask_port_map) { 454 if (mask_port_map) {
438 dev_printk(KERN_ERR, dev, "masking port_map 0x%x -> 0x%x\n", 455 dev_printk(KERN_WARNING, dev, "masking port_map 0x%x -> 0x%x\n",
439 port_map, 456 port_map,
440 port_map & mask_port_map); 457 port_map & mask_port_map);
441 port_map &= mask_port_map; 458 port_map &= mask_port_map;
@@ -569,7 +586,7 @@ int ahci_stop_engine(struct ata_port *ap)
569 writel(tmp, port_mmio + PORT_CMD); 586 writel(tmp, port_mmio + PORT_CMD);
570 587
571 /* wait for engine to stop. This could be as long as 500 msec */ 588 /* wait for engine to stop. This could be as long as 500 msec */
572 tmp = ata_wait_register(port_mmio + PORT_CMD, 589 tmp = ata_wait_register(ap, port_mmio + PORT_CMD,
573 PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); 590 PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500);
574 if (tmp & PORT_CMD_LIST_ON) 591 if (tmp & PORT_CMD_LIST_ON)
575 return -EIO; 592 return -EIO;
@@ -616,7 +633,7 @@ static int ahci_stop_fis_rx(struct ata_port *ap)
616 writel(tmp, port_mmio + PORT_CMD); 633 writel(tmp, port_mmio + PORT_CMD);
617 634
618 /* wait for completion, spec says 500ms, give it 1000 */ 635 /* wait for completion, spec says 500ms, give it 1000 */
619 tmp = ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_FIS_ON, 636 tmp = ata_wait_register(ap, port_mmio + PORT_CMD, PORT_CMD_FIS_ON,
620 PORT_CMD_FIS_ON, 10, 1000); 637 PORT_CMD_FIS_ON, 10, 1000);
621 if (tmp & PORT_CMD_FIS_ON) 638 if (tmp & PORT_CMD_FIS_ON)
622 return -EBUSY; 639 return -EBUSY;
@@ -642,127 +659,56 @@ static void ahci_power_up(struct ata_port *ap)
642 writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD); 659 writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD);
643} 660}
644 661
645static void ahci_disable_alpm(struct ata_port *ap) 662static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
663 unsigned int hints)
646{ 664{
665 struct ata_port *ap = link->ap;
647 struct ahci_host_priv *hpriv = ap->host->private_data; 666 struct ahci_host_priv *hpriv = ap->host->private_data;
648 void __iomem *port_mmio = ahci_port_base(ap);
649 u32 cmd;
650 struct ahci_port_priv *pp = ap->private_data; 667 struct ahci_port_priv *pp = ap->private_data;
651
652 /* IPM bits should be disabled by libata-core */
653 /* get the existing command bits */
654 cmd = readl(port_mmio + PORT_CMD);
655
656 /* disable ALPM and ASP */
657 cmd &= ~PORT_CMD_ASP;
658 cmd &= ~PORT_CMD_ALPE;
659
660 /* force the interface back to active */
661 cmd |= PORT_CMD_ICC_ACTIVE;
662
663 /* write out new cmd value */
664 writel(cmd, port_mmio + PORT_CMD);
665 cmd = readl(port_mmio + PORT_CMD);
666
667 /* wait 10ms to be sure we've come out of any low power state */
668 msleep(10);
669
670 /* clear out any PhyRdy stuff from interrupt status */
671 writel(PORT_IRQ_PHYRDY, port_mmio + PORT_IRQ_STAT);
672
673 /* go ahead and clean out PhyRdy Change from Serror too */
674 ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18)));
675
676 /*
677 * Clear flag to indicate that we should ignore all PhyRdy
678 * state changes
679 */
680 hpriv->flags &= ~AHCI_HFLAG_NO_HOTPLUG;
681
682 /*
683 * Enable interrupts on Phy Ready.
684 */
685 pp->intr_mask |= PORT_IRQ_PHYRDY;
686 writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
687
688 /*
689 * don't change the link pm policy - we can be called
690 * just to turn of link pm temporarily
691 */
692}
693
694static int ahci_enable_alpm(struct ata_port *ap,
695 enum link_pm policy)
696{
697 struct ahci_host_priv *hpriv = ap->host->private_data;
698 void __iomem *port_mmio = ahci_port_base(ap); 668 void __iomem *port_mmio = ahci_port_base(ap);
699 u32 cmd;
700 struct ahci_port_priv *pp = ap->private_data;
701 u32 asp;
702 669
703 /* Make sure the host is capable of link power management */ 670 if (policy != ATA_LPM_MAX_POWER) {
704 if (!(hpriv->cap & HOST_CAP_ALPM))
705 return -EINVAL;
706
707 switch (policy) {
708 case MAX_PERFORMANCE:
709 case NOT_AVAILABLE:
710 /* 671 /*
711 * if we came here with NOT_AVAILABLE, 672 * Disable interrupts on Phy Ready. This keeps us from
712 * it just means this is the first time we 673 * getting woken up due to spurious phy ready
713 * have tried to enable - default to max performance, 674 * interrupts.
714 * and let the user go to lower power modes on request.
715 */ 675 */
716 ahci_disable_alpm(ap); 676 pp->intr_mask &= ~PORT_IRQ_PHYRDY;
717 return 0; 677 writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
718 case MIN_POWER: 678
719 /* configure HBA to enter SLUMBER */ 679 sata_link_scr_lpm(link, policy, false);
720 asp = PORT_CMD_ASP;
721 break;
722 case MEDIUM_POWER:
723 /* configure HBA to enter PARTIAL */
724 asp = 0;
725 break;
726 default:
727 return -EINVAL;
728 } 680 }
729 681
730 /* 682 if (hpriv->cap & HOST_CAP_ALPM) {
731 * Disable interrupts on Phy Ready. This keeps us from 683 u32 cmd = readl(port_mmio + PORT_CMD);
732 * getting woken up due to spurious phy ready interrupts
733 * TBD - Hot plug should be done via polling now, is
734 * that even supported?
735 */
736 pp->intr_mask &= ~PORT_IRQ_PHYRDY;
737 writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
738 684
739 /* 685 if (policy == ATA_LPM_MAX_POWER || !(hints & ATA_LPM_HIPM)) {
740 * Set a flag to indicate that we should ignore all PhyRdy 686 cmd &= ~(PORT_CMD_ASP | PORT_CMD_ALPE);
741 * state changes since these can happen now whenever we 687 cmd |= PORT_CMD_ICC_ACTIVE;
742 * change link state
743 */
744 hpriv->flags |= AHCI_HFLAG_NO_HOTPLUG;
745 688
746 /* get the existing command bits */ 689 writel(cmd, port_mmio + PORT_CMD);
747 cmd = readl(port_mmio + PORT_CMD); 690 readl(port_mmio + PORT_CMD);
748 691
749 /* 692 /* wait 10ms to be sure we've come out of LPM state */
750 * Set ASP based on Policy 693 ata_msleep(ap, 10);
751 */ 694 } else {
752 cmd |= asp; 695 cmd |= PORT_CMD_ALPE;
696 if (policy == ATA_LPM_MIN_POWER)
697 cmd |= PORT_CMD_ASP;
753 698
754 /* 699 /* write out new cmd value */
755 * Setting this bit will instruct the HBA to aggressively 700 writel(cmd, port_mmio + PORT_CMD);
756 * enter a lower power link state when it's appropriate and 701 }
757 * based on the value set above for ASP 702 }
758 */
759 cmd |= PORT_CMD_ALPE;
760 703
761 /* write out new cmd value */ 704 if (policy == ATA_LPM_MAX_POWER) {
762 writel(cmd, port_mmio + PORT_CMD); 705 sata_link_scr_lpm(link, policy, false);
763 cmd = readl(port_mmio + PORT_CMD); 706
707 /* turn PHYRDY IRQ back on */
708 pp->intr_mask |= PORT_IRQ_PHYRDY;
709 writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
710 }
764 711
765 /* IPM bits should be set by libata-core */
766 return 0; 712 return 0;
767} 713}
768 714
@@ -813,7 +759,7 @@ static void ahci_start_port(struct ata_port *ap)
813 emp->led_state, 759 emp->led_state,
814 4); 760 4);
815 if (rc == -EBUSY) 761 if (rc == -EBUSY)
816 msleep(1); 762 ata_msleep(ap, 1);
817 else 763 else
818 break; 764 break;
819 } 765 }
@@ -872,7 +818,7 @@ int ahci_reset_controller(struct ata_host *host)
872 * reset must complete within 1 second, or 818 * reset must complete within 1 second, or
873 * the hardware should be considered fried. 819 * the hardware should be considered fried.
874 */ 820 */
875 tmp = ata_wait_register(mmio + HOST_CTL, HOST_RESET, 821 tmp = ata_wait_register(NULL, mmio + HOST_CTL, HOST_RESET,
876 HOST_RESET, 10, 1000); 822 HOST_RESET, 10, 1000);
877 823
878 if (tmp & HOST_RESET) { 824 if (tmp & HOST_RESET) {
@@ -1206,8 +1152,8 @@ static unsigned int ahci_dev_classify(struct ata_port *ap)
1206 return ata_dev_classify(&tf); 1152 return ata_dev_classify(&tf);
1207} 1153}
1208 1154
1209static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, 1155void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
1210 u32 opts) 1156 u32 opts)
1211{ 1157{
1212 dma_addr_t cmd_tbl_dma; 1158 dma_addr_t cmd_tbl_dma;
1213 1159
@@ -1218,6 +1164,7 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
1218 pp->cmd_slot[tag].tbl_addr = cpu_to_le32(cmd_tbl_dma & 0xffffffff); 1164 pp->cmd_slot[tag].tbl_addr = cpu_to_le32(cmd_tbl_dma & 0xffffffff);
1219 pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16); 1165 pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16);
1220} 1166}
1167EXPORT_SYMBOL_GPL(ahci_fill_cmd_slot);
1221 1168
1222int ahci_kick_engine(struct ata_port *ap) 1169int ahci_kick_engine(struct ata_port *ap)
1223{ 1170{
@@ -1252,7 +1199,7 @@ int ahci_kick_engine(struct ata_port *ap)
1252 writel(tmp, port_mmio + PORT_CMD); 1199 writel(tmp, port_mmio + PORT_CMD);
1253 1200
1254 rc = 0; 1201 rc = 0;
1255 tmp = ata_wait_register(port_mmio + PORT_CMD, 1202 tmp = ata_wait_register(ap, port_mmio + PORT_CMD,
1256 PORT_CMD_CLO, PORT_CMD_CLO, 1, 500); 1203 PORT_CMD_CLO, PORT_CMD_CLO, 1, 500);
1257 if (tmp & PORT_CMD_CLO) 1204 if (tmp & PORT_CMD_CLO)
1258 rc = -EIO; 1205 rc = -EIO;
@@ -1282,8 +1229,8 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp,
1282 writel(1, port_mmio + PORT_CMD_ISSUE); 1229 writel(1, port_mmio + PORT_CMD_ISSUE);
1283 1230
1284 if (timeout_msec) { 1231 if (timeout_msec) {
1285 tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, 1232 tmp = ata_wait_register(ap, port_mmio + PORT_CMD_ISSUE,
1286 1, timeout_msec); 1233 0x1, 0x1, 1, timeout_msec);
1287 if (tmp & 0x1) { 1234 if (tmp & 0x1) {
1288 ahci_kick_engine(ap); 1235 ahci_kick_engine(ap);
1289 return -EBUSY; 1236 return -EBUSY;
@@ -1330,7 +1277,7 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class,
1330 } 1277 }
1331 1278
1332 /* spec says at least 5us, but be generous and sleep for 1ms */ 1279 /* spec says at least 5us, but be generous and sleep for 1ms */
1333 msleep(1); 1280 ata_msleep(ap, 1);
1334 1281
1335 /* issue the second D2H Register FIS */ 1282 /* issue the second D2H Register FIS */
1336 tf.ctl &= ~ATA_SRST; 1283 tf.ctl &= ~ATA_SRST;
@@ -1660,15 +1607,10 @@ static void ahci_port_intr(struct ata_port *ap)
1660 if (unlikely(resetting)) 1607 if (unlikely(resetting))
1661 status &= ~PORT_IRQ_BAD_PMP; 1608 status &= ~PORT_IRQ_BAD_PMP;
1662 1609
1663 /* If we are getting PhyRdy, this is 1610 /* if LPM is enabled, PHYRDY doesn't mean anything */
1664 * just a power state change, we should 1611 if (ap->link.lpm_policy > ATA_LPM_MAX_POWER) {
1665 * clear out this, plus the PhyRdy/Comm
1666 * Wake bits from Serror
1667 */
1668 if ((hpriv->flags & AHCI_HFLAG_NO_HOTPLUG) &&
1669 (status & PORT_IRQ_PHYRDY)) {
1670 status &= ~PORT_IRQ_PHYRDY; 1612 status &= ~PORT_IRQ_PHYRDY;
1671 ahci_scr_write(&ap->link, SCR_ERROR, ((1 << 16) | (1 << 18))); 1613 ahci_scr_write(&ap->link, SCR_ERROR, SERR_PHYRDY_CHG);
1672 } 1614 }
1673 1615
1674 if (unlikely(status & PORT_IRQ_ERROR)) { 1616 if (unlikely(status & PORT_IRQ_ERROR)) {
@@ -1830,12 +1772,24 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
1830static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc) 1772static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc)
1831{ 1773{
1832 struct ahci_port_priv *pp = qc->ap->private_data; 1774 struct ahci_port_priv *pp = qc->ap->private_data;
1833 u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; 1775 u8 *rx_fis = pp->rx_fis;
1834 1776
1835 if (pp->fbs_enabled) 1777 if (pp->fbs_enabled)
1836 d2h_fis += qc->dev->link->pmp * AHCI_RX_FIS_SZ; 1778 rx_fis += qc->dev->link->pmp * AHCI_RX_FIS_SZ;
1779
1780 /*
1781 * After a successful execution of an ATA PIO data-in command,
1782 * the device doesn't send D2H Reg FIS to update the TF and
1783 * the host should take TF and E_Status from the preceding PIO
1784 * Setup FIS.
1785 */
1786 if (qc->tf.protocol == ATA_PROT_PIO && qc->dma_dir == DMA_FROM_DEVICE &&
1787 !(qc->flags & ATA_QCFLAG_FAILED)) {
1788 ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf);
1789 qc->result_tf.command = (rx_fis + RX_FIS_PIO_SETUP)[15];
1790 } else
1791 ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf);
1837 1792
1838 ata_tf_from_fis(d2h_fis, &qc->result_tf);
1839 return true; 1793 return true;
1840} 1794}
1841 1795
@@ -1965,7 +1919,17 @@ static void ahci_pmp_attach(struct ata_port *ap)
1965 ahci_enable_fbs(ap); 1919 ahci_enable_fbs(ap);
1966 1920
1967 pp->intr_mask |= PORT_IRQ_BAD_PMP; 1921 pp->intr_mask |= PORT_IRQ_BAD_PMP;
1968 writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); 1922
1923 /*
1924 * We must not change the port interrupt mask register if the
1925 * port is marked frozen, the value in pp->intr_mask will be
1926 * restored later when the port is thawed.
1927 *
1928 * Note that during initialization, the port is marked as
1929 * frozen since the irq handler is not yet registered.
1930 */
1931 if (!(ap->pflags & ATA_PFLAG_FROZEN))
1932 writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
1969} 1933}
1970 1934
1971static void ahci_pmp_detach(struct ata_port *ap) 1935static void ahci_pmp_detach(struct ata_port *ap)
@@ -1981,10 +1945,13 @@ static void ahci_pmp_detach(struct ata_port *ap)
1981 writel(cmd, port_mmio + PORT_CMD); 1945 writel(cmd, port_mmio + PORT_CMD);
1982 1946
1983 pp->intr_mask &= ~PORT_IRQ_BAD_PMP; 1947 pp->intr_mask &= ~PORT_IRQ_BAD_PMP;
1984 writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); 1948
1949 /* see comment above in ahci_pmp_attach() */
1950 if (!(ap->pflags & ATA_PFLAG_FROZEN))
1951 writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
1985} 1952}
1986 1953
1987static int ahci_port_resume(struct ata_port *ap) 1954int ahci_port_resume(struct ata_port *ap)
1988{ 1955{
1989 ahci_power_up(ap); 1956 ahci_power_up(ap);
1990 ahci_start_port(ap); 1957 ahci_start_port(ap);
@@ -1996,6 +1963,7 @@ static int ahci_port_resume(struct ata_port *ap)
1996 1963
1997 return 0; 1964 return 0;
1998} 1965}
1966EXPORT_SYMBOL_GPL(ahci_port_resume);
1999 1967
2000#ifdef CONFIG_PM 1968#ifdef CONFIG_PM
2001static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) 1969static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)