diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-21 19:03:38 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-21 19:03:38 -0700 |
commit | e10117d36ef758da0690c95ecffc09d5dd7da479 (patch) | |
tree | f2bb867cfc33f24d9c6bbb36dd189869e62ecce2 /drivers/ata/ata_piix.c | |
parent | f3270b16e00f0614fa418dcc50883da5949375b4 (diff) | |
parent | 89692c03226a066a017048cf7fbacbaa645f0e79 (diff) |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev: (26 commits)
include/linux/libata.h: fix typo
pata_bf54x: fix return type of bfin_set_devctl
Drivers: ata: Makefile: replace the use of <module>-objs with <module>-y
libahci: fix result_tf handling after an ATA PIO data-in command
pata_sl82c105: implement sff_irq_check() method
pata_sil680: implement sff_irq_check() method
pata_pdc202xx_old: implement sff_irq_check() method
pata_cmd640: implement sff_irq_check() method
ata_piix: Add device ID for ICH4-L
pata_sil680: make sil680_sff_exec_command() 'static'
ata: Intel IDE-R support
libata: reorder ata_queued_cmd to remove alignment padding on 64 bit builds
libata: Signal that our SATL supports WRITE SAME(16) with UNMAP
ata_piix: remove SIDPR locking
libata: implement cross-port EH exclusion
libata: add @ap to ata_wait_register() and introduce ata_msleep()
ata_piix: implement LPM support
libata: implement LPM support for port multipliers
libata: reimplement link power management
libata: implement sata_link_scr_lpm() and make ata_dev_set_feature() global
...
Diffstat (limited to 'drivers/ata/ata_piix.c')
-rw-r--r-- | drivers/ata/ata_piix.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index d712675d0a9..6cb14ca8ee8 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -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) |