aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorAlan <alan@lxorguk.ukuu.org.uk>2006-11-27 11:19:36 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-01 22:46:58 -0500
commit627d2d3261a42c9b5b0a02a1f8d0ae5414729cb9 (patch)
tree40e0d04160c34c1a9da0b0ae846d863eab582895 /drivers/ata
parentc304193a005b5262671c1389b1cae96d7afc952a (diff)
[PATCH] pata_via suspend/resume support
The major VIA issues were handled by the quirks update for resume quirks. The ATA driver also has to do some work however when resuming from RAM. Certain chips need the FIFO reconfiguring, and the 66MHz clock setup updating. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-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)