]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/ata/ata_piix.c
Merge branch 'master' into csb1725
[mv-sheeva.git] / drivers / ata / ata_piix.c
index d712675d0a9657d3cc7742b74220aaf05d0fa537..6cb14ca8ee853f44683062c9b5b1274afa50e336 100644 (file)
@@ -158,7 +158,6 @@ struct piix_map_db {
 struct piix_host_priv {
        const int *map;
        u32 saved_iocfg;
-       spinlock_t sidpr_lock;  /* FIXME: remove once locking in EH is fixed */
        void __iomem *sidpr;
 };
 
@@ -175,6 +174,8 @@ static int piix_sidpr_scr_read(struct ata_link *link,
                               unsigned int reg, u32 *val);
 static int piix_sidpr_scr_write(struct ata_link *link,
                                unsigned int reg, u32 val);
+static int piix_sidpr_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
+                             unsigned hints);
 static bool piix_irq_check(struct ata_port *ap);
 #ifdef CONFIG_PM
 static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
@@ -209,6 +210,8 @@ static const struct pci_device_id piix_pci_tbl[] = {
        { 0x8086, 0x248A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
        /* Intel ICH3 (E7500/1) UDMA 100 */
        { 0x8086, 0x248B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
+       /* Intel ICH4-L */
+       { 0x8086, 0x24C1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
        /* Intel ICH4 (i845GV, i845E, i852, i855) UDMA 100 */
        { 0x8086, 0x24CA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
        { 0x8086, 0x24CB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
@@ -348,11 +351,22 @@ static struct ata_port_operations ich_pata_ops = {
        .set_dmamode            = ich_set_dmamode,
 };
 
+static struct device_attribute *piix_sidpr_shost_attrs[] = {
+       &dev_attr_link_power_management_policy,
+       NULL
+};
+
+static struct scsi_host_template piix_sidpr_sht = {
+       ATA_BMDMA_SHT(DRV_NAME),
+       .shost_attrs            = piix_sidpr_shost_attrs,
+};
+
 static struct ata_port_operations piix_sidpr_sata_ops = {
        .inherits               = &piix_sata_ops,
        .hardreset              = sata_std_hardreset,
        .scr_read               = piix_sidpr_scr_read,
        .scr_write              = piix_sidpr_scr_write,
+       .set_lpm                = piix_sidpr_set_lpm,
 };
 
 static const struct piix_map_db ich5_map_db = {
@@ -956,15 +970,12 @@ static int piix_sidpr_scr_read(struct ata_link *link,
                               unsigned int reg, u32 *val)
 {
        struct piix_host_priv *hpriv = link->ap->host->private_data;
-       unsigned long flags;
 
        if (reg >= ARRAY_SIZE(piix_sidx_map))
                return -EINVAL;
 
-       spin_lock_irqsave(&hpriv->sidpr_lock, flags);
        piix_sidpr_sel(link, reg);
        *val = ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
-       spin_unlock_irqrestore(&hpriv->sidpr_lock, flags);
        return 0;
 }
 
@@ -972,18 +983,21 @@ static int piix_sidpr_scr_write(struct ata_link *link,
                                unsigned int reg, u32 val)
 {
        struct piix_host_priv *hpriv = link->ap->host->private_data;
-       unsigned long flags;
 
        if (reg >= ARRAY_SIZE(piix_sidx_map))
                return -EINVAL;
 
-       spin_lock_irqsave(&hpriv->sidpr_lock, flags);
        piix_sidpr_sel(link, reg);
        iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
-       spin_unlock_irqrestore(&hpriv->sidpr_lock, flags);
        return 0;
 }
 
+static int piix_sidpr_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
+                             unsigned hints)
+{
+       return sata_link_scr_lpm(link, policy, false);
+}
+
 static bool piix_irq_check(struct ata_port *ap)
 {
        if (unlikely(!ap->ioaddr.bmdma_addr))
@@ -1543,6 +1557,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
        struct device *dev = &pdev->dev;
        struct ata_port_info port_info[2];
        const struct ata_port_info *ppi[] = { &port_info[0], &port_info[1] };
+       struct scsi_host_template *sht = &piix_sht;
        unsigned long port_flags;
        struct ata_host *host;
        struct piix_host_priv *hpriv;
@@ -1577,7 +1592,6 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
        hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
        if (!hpriv)
                return -ENOMEM;
-       spin_lock_init(&hpriv->sidpr_lock);
 
        /* Save IOCFG, this will be used for cable detection, quirk
         * detection and restoration on detach.  This is necessary
@@ -1612,6 +1626,8 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
                rc = piix_init_sidpr(host);
                if (rc)
                        return rc;
+               if (host->ports[0]->ops == &piix_sidpr_sata_ops)
+                       sht = &piix_sidpr_sht;
        }
 
        /* apply IOCFG bit18 quirk */
@@ -1638,7 +1654,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
        host->flags |= ATA_HOST_PARALLEL_SCAN;
 
        pci_set_master(pdev);
-       return ata_pci_sff_activate_host(host, ata_bmdma_interrupt, &piix_sht);
+       return ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht);
 }
 
 static void piix_remove_one(struct pci_dev *pdev)