diff options
Diffstat (limited to 'drivers/ata/pata_sl82c105.c')
| -rw-r--r-- | drivers/ata/pata_sl82c105.c | 77 |
1 files changed, 52 insertions, 25 deletions
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c index 69877bd8181..4935f61f629 100644 --- a/drivers/ata/pata_sl82c105.c +++ b/drivers/ata/pata_sl82c105.c @@ -1,7 +1,7 @@ /* * pata_sl82c105.c - SL82C105 PATA for new ATA layer * (C) 2005 Red Hat Inc - * Alan Cox <alan@redhat.com> + * (C) 2011 Bartlomiej Zolnierkiewicz * * Based in part on linux/drivers/ide/pci/sl82c105.c * SL82C105/Winbond 553 IDE driver @@ -19,7 +19,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> -#include <linux/init.h> #include <linux/blkdev.h> #include <linux/delay.h> #include <scsi/scsi_host.h> @@ -228,6 +227,16 @@ static int sl82c105_qc_defer(struct ata_queued_cmd *qc) return 0; } +static bool sl82c105_sff_irq_check(struct ata_port *ap) +{ + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + u32 val, mask = ap->port_no ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; + + pci_read_config_dword(pdev, 0x40, &val); + + return val & mask; +} + static struct scsi_host_template sl82c105_sht = { ATA_BMDMA_SHT(DRV_NAME), }; @@ -240,6 +249,7 @@ static struct ata_port_operations sl82c105_port_ops = { .cable_detect = ata_cable_40wire, .set_piomode = sl82c105_set_piomode, .prereset = sl82c105_pre_reset, + .sff_irq_check = sl82c105_sff_irq_check, }; /** @@ -279,24 +289,31 @@ static int sl82c105_bridge_revision(struct pci_dev *pdev) return bridge->revision; } +static void sl82c105_fixup(struct pci_dev *pdev) +{ + u32 val; + + pci_read_config_dword(pdev, 0x40, &val); + val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; + pci_write_config_dword(pdev, 0x40, val); +} static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id) { static const struct ata_port_info info_dma = { .flags = ATA_FLAG_SLAVE_POSS, - .pio_mask = 0x1f, - .mwdma_mask = 0x07, + .pio_mask = ATA_PIO4, + .mwdma_mask = ATA_MWDMA2, .port_ops = &sl82c105_port_ops }; static const struct ata_port_info info_early = { .flags = ATA_FLAG_SLAVE_POSS, - .pio_mask = 0x1f, + .pio_mask = ATA_PIO4, .port_ops = &sl82c105_port_ops }; /* for now use only the first port */ const struct ata_port_info *ppi[] = { &info_early, NULL }; - u32 val; int rev; int rc; @@ -307,18 +324,35 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id rev = sl82c105_bridge_revision(dev); if (rev == -1) - dev_printk(KERN_WARNING, &dev->dev, "pata_sl82c105: Unable to find bridge, disabling DMA.\n"); + dev_warn(&dev->dev, + "pata_sl82c105: Unable to find bridge, disabling DMA\n"); else if (rev <= 5) - dev_printk(KERN_WARNING, &dev->dev, "pata_sl82c105: Early bridge revision, no DMA available.\n"); + dev_warn(&dev->dev, + "pata_sl82c105: Early bridge revision, no DMA available\n"); else ppi[0] = &info_dma; - pci_read_config_dword(dev, 0x40, &val); - val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; - pci_write_config_dword(dev, 0x40, val); + sl82c105_fixup(dev); + + return ata_pci_bmdma_init_one(dev, ppi, &sl82c105_sht, NULL, 0); +} - return ata_pci_sff_init_one(dev, ppi, &sl82c105_sht, NULL); +#ifdef CONFIG_PM_SLEEP +static int sl82c105_reinit_one(struct pci_dev *pdev) +{ + struct ata_host *host = pci_get_drvdata(pdev); + int rc; + + rc = ata_pci_device_do_resume(pdev); + if (rc) + return rc; + + sl82c105_fixup(pdev); + + ata_host_resume(host); + return 0; } +#endif static const struct pci_device_id sl82c105[] = { { PCI_VDEVICE(WINBOND, PCI_DEVICE_ID_WINBOND_82C105), }, @@ -330,24 +364,17 @@ static struct pci_driver sl82c105_pci_driver = { .name = DRV_NAME, .id_table = sl82c105, .probe = sl82c105_init_one, - .remove = ata_pci_remove_one + .remove = ata_pci_remove_one, +#ifdef CONFIG_PM_SLEEP + .suspend = ata_pci_device_suspend, + .resume = sl82c105_reinit_one, +#endif }; -static int __init sl82c105_init(void) -{ - return pci_register_driver(&sl82c105_pci_driver); -} - -static void __exit sl82c105_exit(void) -{ - pci_unregister_driver(&sl82c105_pci_driver); -} +module_pci_driver(sl82c105_pci_driver); MODULE_AUTHOR("Alan Cox"); MODULE_DESCRIPTION("low-level driver for Sl82c105"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, sl82c105); MODULE_VERSION(DRV_VERSION); - -module_init(sl82c105_init); -module_exit(sl82c105_exit); |
