diff options
-rw-r--r-- | drivers/ata/pata_via.c | 94 |
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 | ||
302 | static struct ata_port_operations via_port_ops = { | 304 | static 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 | |||
383 | static 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 | |||
565 | static 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 | |||
532 | static const struct pci_device_id via[] = { | 588 | static 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 | ||
548 | static int __init via_init(void) | 606 | static int __init via_init(void) |