aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ahci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r--drivers/ata/ahci.c95
1 files changed, 72 insertions, 23 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index fd27227771b4..c31b66366326 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -188,8 +188,10 @@ struct ahci_sg {
188}; 188};
189 189
190struct ahci_host_priv { 190struct ahci_host_priv {
191 u32 cap; /* cache of HOST_CAP register */ 191 u32 cap; /* cap to use */
192 u32 port_map; /* cache of HOST_PORTS_IMPL reg */ 192 u32 port_map; /* port map to use */
193 u32 saved_cap; /* saved initial cap */
194 u32 saved_port_map; /* saved initial port_map */
193}; 195};
194 196
195struct ahci_port_priv { 197struct ahci_port_priv {
@@ -477,6 +479,65 @@ static inline void __iomem *ahci_port_base(void __iomem *base,
477 return base + 0x100 + (port * 0x80); 479 return base + 0x100 + (port * 0x80);
478} 480}
479 481
482/**
483 * ahci_save_initial_config - Save and fixup initial config values
484 * @probe_ent: probe_ent of target device
485 *
486 * Some registers containing configuration info might be setup by
487 * BIOS and might be cleared on reset. This function saves the
488 * initial values of those registers into @hpriv such that they
489 * can be restored after controller reset.
490 *
491 * If inconsistent, config values are fixed up by this function.
492 *
493 * LOCKING:
494 * None.
495 */
496static void ahci_save_initial_config(struct ata_probe_ent *probe_ent)
497{
498 struct ahci_host_priv *hpriv = probe_ent->private_data;
499 void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR];
500 u32 cap, port_map;
501
502 /* Values prefixed with saved_ are written back to host after
503 * reset. Values without are used for driver operation.
504 */
505 hpriv->saved_cap = cap = readl(mmio + HOST_CAP);
506 hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL);
507
508 /* fixup zero port_map */
509 if (!port_map) {
510 port_map = (1 << ahci_nr_ports(hpriv->cap)) - 1;
511 dev_printk(KERN_WARNING, probe_ent->dev,
512 "PORTS_IMPL is zero, forcing 0x%x\n", port_map);
513
514 /* write the fixed up value to the PI register */
515 hpriv->saved_port_map = port_map;
516 }
517
518 /* record values to use during operation */
519 hpriv->cap = cap;
520 hpriv->port_map = port_map;
521}
522
523/**
524 * ahci_restore_initial_config - Restore initial config
525 * @mmio: MMIO base for the host
526 * @hpriv: host private data
527 *
528 * Restore initial config stored by ahci_save_initial_config().
529 *
530 * LOCKING:
531 * None.
532 */
533static void ahci_restore_initial_config(void __iomem *mmio,
534 struct ahci_host_priv *hpriv)
535{
536 writel(hpriv->saved_cap, mmio + HOST_CAP);
537 writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL);
538 (void) readl(mmio + HOST_PORTS_IMPL); /* flush */
539}
540
480static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) 541static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
481{ 542{
482 unsigned int sc_reg; 543 unsigned int sc_reg;
@@ -653,12 +714,10 @@ static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg)
653 return 0; 714 return 0;
654} 715}
655 716
656static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev) 717static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev,
718 struct ahci_host_priv *hpriv)
657{ 719{
658 u32 cap_save, impl_save, tmp; 720 u32 tmp;
659
660 cap_save = readl(mmio + HOST_CAP);
661 impl_save = readl(mmio + HOST_PORTS_IMPL);
662 721
663 /* global controller reset */ 722 /* global controller reset */
664 tmp = readl(mmio + HOST_CTL); 723 tmp = readl(mmio + HOST_CTL);
@@ -683,18 +742,8 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
683 writel(HOST_AHCI_EN, mmio + HOST_CTL); 742 writel(HOST_AHCI_EN, mmio + HOST_CTL);
684 (void) readl(mmio + HOST_CTL); /* flush */ 743 (void) readl(mmio + HOST_CTL); /* flush */
685 744
686 /* These write-once registers are normally cleared on reset. 745 /* some registers might be cleared on reset. restore initial values */
687 * Restore BIOS values... which we HOPE were present before 746 ahci_restore_initial_config(mmio, hpriv);
688 * reset.
689 */
690 if (!impl_save) {
691 impl_save = (1 << ahci_nr_ports(cap_save)) - 1;
692 dev_printk(KERN_WARNING, &pdev->dev,
693 "PORTS_IMPL is zero, forcing 0x%x\n", impl_save);
694 }
695 writel(cap_save, mmio + HOST_CAP);
696 writel(impl_save, mmio + HOST_PORTS_IMPL);
697 (void) readl(mmio + HOST_PORTS_IMPL); /* flush */
698 747
699 if (pdev->vendor == PCI_VENDOR_ID_INTEL) { 748 if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
700 u16 tmp16; 749 u16 tmp16;
@@ -1432,7 +1481,7 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
1432 return rc; 1481 return rc;
1433 1482
1434 if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { 1483 if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
1435 rc = ahci_reset_controller(mmio, pdev); 1484 rc = ahci_reset_controller(mmio, pdev, hpriv);
1436 if (rc) 1485 if (rc)
1437 return rc; 1486 return rc;
1438 1487
@@ -1543,12 +1592,10 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
1543 unsigned int i, cap_n_ports, using_dac; 1592 unsigned int i, cap_n_ports, using_dac;
1544 int rc; 1593 int rc;
1545 1594
1546 rc = ahci_reset_controller(mmio, pdev); 1595 rc = ahci_reset_controller(mmio, pdev, hpriv);
1547 if (rc) 1596 if (rc)
1548 return rc; 1597 return rc;
1549 1598
1550 hpriv->cap = readl(mmio + HOST_CAP);
1551 hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
1552 cap_n_ports = ahci_nr_ports(hpriv->cap); 1599 cap_n_ports = ahci_nr_ports(hpriv->cap);
1553 1600
1554 VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n", 1601 VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n",
@@ -1739,6 +1786,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1739 probe_ent->private_data = hpriv; 1786 probe_ent->private_data = hpriv;
1740 1787
1741 /* initialize adapter */ 1788 /* initialize adapter */
1789 ahci_save_initial_config(probe_ent);
1790
1742 rc = ahci_host_init(probe_ent); 1791 rc = ahci_host_init(probe_ent);
1743 if (rc) 1792 if (rc)
1744 return rc; 1793 return rc;