|
@@ -60,7 +60,7 @@
|
|
#include <linux/libata.h>
|
|
#include <linux/libata.h>
|
|
|
|
|
|
#define DRV_NAME "pata_via"
|
|
#define DRV_NAME "pata_via"
|
|
-#define DRV_VERSION "0.1.14"
|
|
|
|
|
|
+#define DRV_VERSION "0.2.0"
|
|
|
|
|
|
/*
|
|
/*
|
|
* The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
|
|
* The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
|
|
@@ -297,6 +297,8 @@ static struct scsi_host_template via_sht = {
|
|
.slave_configure = ata_scsi_slave_config,
|
|
.slave_configure = ata_scsi_slave_config,
|
|
.slave_destroy = ata_scsi_slave_destroy,
|
|
.slave_destroy = ata_scsi_slave_destroy,
|
|
.bios_param = ata_std_bios_param,
|
|
.bios_param = ata_std_bios_param,
|
|
|
|
+ .resume = ata_scsi_device_resume,
|
|
|
|
+ .suspend = ata_scsi_device_suspend,
|
|
};
|
|
};
|
|
|
|
|
|
static struct ata_port_operations via_port_ops = {
|
|
static struct ata_port_operations via_port_ops = {
|
|
@@ -369,9 +371,43 @@ static struct ata_port_operations via_port_ops_noirq = {
|
|
.host_stop = ata_host_stop
|
|
.host_stop = ata_host_stop
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * via_config_fifo - set up the FIFO
|
|
|
|
+ * @pdev: PCI device
|
|
|
|
+ * @flags: configuration flags
|
|
|
|
+ *
|
|
|
|
+ * Set the FIFO properties for this device if neccessary. Used both on
|
|
|
|
+ * set up and on and the resume path
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+static void via_config_fifo(struct pci_dev *pdev, unsigned int flags)
|
|
|
|
+{
|
|
|
|
+ u8 enable;
|
|
|
|
+
|
|
|
|
+ /* 0x40 low bits indicate enabled channels */
|
|
|
|
+ pci_read_config_byte(pdev, 0x40 , &enable);
|
|
|
|
+ enable &= 3;
|
|
|
|
+
|
|
|
|
+ if (flags & VIA_SET_FIFO) {
|
|
|
|
+ u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
|
|
|
|
+ u8 fifo;
|
|
|
|
+
|
|
|
|
+ pci_read_config_byte(pdev, 0x43, &fifo);
|
|
|
|
+
|
|
|
|
+ /* Clear PREQ# until DDACK# for errata */
|
|
|
|
+ if (flags & VIA_BAD_PREQ)
|
|
|
|
+ fifo &= 0x7F;
|
|
|
|
+ else
|
|
|
|
+ fifo &= 0x9f;
|
|
|
|
+ /* Turn on FIFO for enabled channels */
|
|
|
|
+ fifo |= fifo_setting[enable];
|
|
|
|
+ pci_write_config_byte(pdev, 0x43, fifo);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* via_init_one - discovery callback
|
|
* via_init_one - discovery callback
|
|
- * @pdev: PCI device ID
|
|
|
|
|
|
+ * @pdev: PCI device
|
|
* @id: PCI table info
|
|
* @id: PCI table info
|
|
*
|
|
*
|
|
* A VIA IDE interface has been discovered. Figure out what revision
|
|
* A VIA IDE interface has been discovered. Figure out what revision
|
|
@@ -471,21 +507,8 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
}
|
|
}
|
|
|
|
|
|
/* Initialise the FIFO for the enabled channels. */
|
|
/* Initialise the FIFO for the enabled channels. */
|
|
- if (config->flags & VIA_SET_FIFO) {
|
|
|
|
- u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
|
|
|
|
- u8 fifo;
|
|
|
|
-
|
|
|
|
- pci_read_config_byte(pdev, 0x43, &fifo);
|
|
|
|
-
|
|
|
|
- /* Clear PREQ# until DDACK# for errata */
|
|
|
|
- if (config->flags & VIA_BAD_PREQ)
|
|
|
|
- fifo &= 0x7F;
|
|
|
|
- else
|
|
|
|
- fifo &= 0x9f;
|
|
|
|
- /* Turn on FIFO for enabled channels */
|
|
|
|
- fifo |= fifo_setting[enable];
|
|
|
|
- pci_write_config_byte(pdev, 0x43, fifo);
|
|
|
|
- }
|
|
|
|
|
|
+ via_config_fifo(pdev, config->flags);
|
|
|
|
+
|
|
/* Clock set up */
|
|
/* Clock set up */
|
|
switch(config->flags & VIA_UDMA) {
|
|
switch(config->flags & VIA_UDMA) {
|
|
case VIA_UDMA_NONE:
|
|
case VIA_UDMA_NONE:
|
|
@@ -529,6 +552,39 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
return ata_pci_init_one(pdev, port_info, 2);
|
|
return ata_pci_init_one(pdev, port_info, 2);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * via_reinit_one - reinit after resume
|
|
|
|
+ * @pdev; PCI device
|
|
|
|
+ *
|
|
|
|
+ * Called when the VIA PATA device is resumed. We must then
|
|
|
|
+ * reconfigure the fifo and other setup we may have altered. In
|
|
|
|
+ * addition the kernel needs to have the resume methods on PCI
|
|
|
|
+ * quirk supported.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+static int via_reinit_one(struct pci_dev *pdev)
|
|
|
|
+{
|
|
|
|
+ u32 timing;
|
|
|
|
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
|
|
|
|
+ const struct via_isa_bridge *config = host->private_data;
|
|
|
|
+
|
|
|
|
+ via_config_fifo(pdev, config->flags);
|
|
|
|
+
|
|
|
|
+ if ((config->flags & VIA_UDMA) == VIA_UDMA_66) {
|
|
|
|
+ /* The 66 MHz devices require we enable the clock */
|
|
|
|
+ pci_read_config_dword(pdev, 0x50, &timing);
|
|
|
|
+ timing |= 0x80008;
|
|
|
|
+ pci_write_config_dword(pdev, 0x50, timing);
|
|
|
|
+ }
|
|
|
|
+ if (config->flags & VIA_BAD_CLK66) {
|
|
|
|
+ /* Disable the 66MHz clock on problem devices */
|
|
|
|
+ pci_read_config_dword(pdev, 0x50, &timing);
|
|
|
|
+ timing &= ~0x80008;
|
|
|
|
+ pci_write_config_dword(pdev, 0x50, timing);
|
|
|
|
+ }
|
|
|
|
+ return ata_pci_device_resume(pdev);
|
|
|
|
+}
|
|
|
|
+
|
|
static const struct pci_device_id via[] = {
|
|
static const struct pci_device_id via[] = {
|
|
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), },
|
|
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), },
|
|
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), },
|
|
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), },
|
|
@@ -542,7 +598,9 @@ static struct pci_driver via_pci_driver = {
|
|
.name = DRV_NAME,
|
|
.name = DRV_NAME,
|
|
.id_table = via,
|
|
.id_table = via,
|
|
.probe = via_init_one,
|
|
.probe = via_init_one,
|
|
- .remove = ata_pci_remove_one
|
|
|
|
|
|
+ .remove = ata_pci_remove_one,
|
|
|
|
+ .suspend = ata_pci_device_suspend,
|
|
|
|
+ .resume = via_reinit_one,
|
|
};
|
|
};
|
|
|
|
|
|
static int __init via_init(void)
|
|
static int __init via_init(void)
|