aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_via.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/pata_via.c')
-rw-r--r--drivers/ata/pata_via.c94
1 files changed, 76 insertions, 18 deletions
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index c5f1616d224d..489bd5796e73 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -60,7 +60,7 @@
60#include <linux/libata.h> 60#include <linux/libata.h>
61 61
62#define DRV_NAME "pata_via" 62#define DRV_NAME "pata_via"
63#define DRV_VERSION "0.1.14" 63#define DRV_VERSION "0.2.0"
64 64
65/* 65/*
66 * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx 66 * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
@@ -297,6 +297,8 @@ static struct scsi_host_template via_sht = {
297 .slave_configure = ata_scsi_slave_config, 297 .slave_configure = ata_scsi_slave_config,
298 .slave_destroy = ata_scsi_slave_destroy, 298 .slave_destroy = ata_scsi_slave_destroy,
299 .bios_param = ata_std_bios_param, 299 .bios_param = ata_std_bios_param,
300 .resume = ata_scsi_device_resume,
301 .suspend = ata_scsi_device_suspend,
300}; 302};
301 303
302static struct ata_port_operations via_port_ops = { 304static struct ata_port_operations via_port_ops = {
@@ -370,8 +372,42 @@ static struct ata_port_operations via_port_ops_noirq = {
370}; 372};
371 373
372/** 374/**
375 * via_config_fifo - set up the FIFO
376 * @pdev: PCI device
377 * @flags: configuration flags
378 *
379 * Set the FIFO properties for this device if neccessary. Used both on
380 * set up and on and the resume path
381 */
382
383static void via_config_fifo(struct pci_dev *pdev, unsigned int flags)
384{
385 u8 enable;
386
387 /* 0x40 low bits indicate enabled channels */
388 pci_read_config_byte(pdev, 0x40 , &enable);
389 enable &= 3;
390
391 if (flags & VIA_SET_FIFO) {
392 u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
393 u8 fifo;
394
395 pci_read_config_byte(pdev, 0x43, &fifo);
396
397 /* Clear PREQ# until DDACK# for errata */
398 if (flags & VIA_BAD_PREQ)
399 fifo &= 0x7F;
400 else
401 fifo &= 0x9f;
402 /* Turn on FIFO for enabled channels */
403 fifo |= fifo_setting[enable];
404 pci_write_config_byte(pdev, 0x43, fifo);
405 }
406}
407
408/**
373 * via_init_one - discovery callback 409 * via_init_one - discovery callback
374 * @pdev: PCI device ID 410 * @pdev: PCI device
375 * @id: PCI table info 411 * @id: PCI table info
376 * 412 *
377 * A VIA IDE interface has been discovered. Figure out what revision 413 * 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)
471 } 507 }
472 508
473 /* Initialise the FIFO for the enabled channels. */ 509 /* Initialise the FIFO for the enabled channels. */
474 if (config->flags & VIA_SET_FIFO) { 510 via_config_fifo(pdev, config->flags);
475 u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20}; 511
476 u8 fifo;
477
478 pci_read_config_byte(pdev, 0x43, &fifo);
479
480 /* Clear PREQ# until DDACK# for errata */
481 if (config->flags & VIA_BAD_PREQ)
482 fifo &= 0x7F;
483 else
484 fifo &= 0x9f;
485 /* Turn on FIFO for enabled channels */
486 fifo |= fifo_setting[enable];
487 pci_write_config_byte(pdev, 0x43, fifo);
488 }
489 /* Clock set up */ 512 /* Clock set up */
490 switch(config->flags & VIA_UDMA) { 513 switch(config->flags & VIA_UDMA) {
491 case VIA_UDMA_NONE: 514 case VIA_UDMA_NONE:
@@ -529,6 +552,39 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
529 return ata_pci_init_one(pdev, port_info, 2); 552 return ata_pci_init_one(pdev, port_info, 2);
530} 553}
531 554
555/**
556 * via_reinit_one - reinit after resume
557 * @pdev; PCI device
558 *
559 * Called when the VIA PATA device is resumed. We must then
560 * reconfigure the fifo and other setup we may have altered. In
561 * addition the kernel needs to have the resume methods on PCI
562 * quirk supported.
563 */
564
565static int via_reinit_one(struct pci_dev *pdev)
566{
567 u32 timing;
568 struct ata_host *host = dev_get_drvdata(&pdev->dev);
569 const struct via_isa_bridge *config = host->private_data;
570
571 via_config_fifo(pdev, config->flags);
572
573 if ((config->flags & VIA_UDMA) == VIA_UDMA_66) {
574 /* The 66 MHz devices require we enable the clock */
575 pci_read_config_dword(pdev, 0x50, &timing);
576 timing |= 0x80008;
577 pci_write_config_dword(pdev, 0x50, timing);
578 }
579 if (config->flags & VIA_BAD_CLK66) {
580 /* Disable the 66MHz clock on problem devices */
581 pci_read_config_dword(pdev, 0x50, &timing);
582 timing &= ~0x80008;
583 pci_write_config_dword(pdev, 0x50, timing);
584 }
585 return ata_pci_device_resume(pdev);
586}
587
532static const struct pci_device_id via[] = { 588static const struct pci_device_id via[] = {
533 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), }, 589 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), },
534 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), }, 590 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), },
@@ -542,7 +598,9 @@ static struct pci_driver via_pci_driver = {
542 .name = DRV_NAME, 598 .name = DRV_NAME,
543 .id_table = via, 599 .id_table = via,
544 .probe = via_init_one, 600 .probe = via_init_one,
545 .remove = ata_pci_remove_one 601 .remove = ata_pci_remove_one,
602 .suspend = ata_pci_device_suspend,
603 .resume = via_reinit_one,
546}; 604};
547 605
548static int __init via_init(void) 606static int __init via_init(void)