diff options
| -rw-r--r-- | drivers/ata/ata_piix.c | 113 | ||||
| -rw-r--r-- | drivers/ata/pata_ali.c | 2 | ||||
| -rw-r--r-- | drivers/ata/pata_hpt37x.c | 14 | ||||
| -rw-r--r-- | drivers/pci/pci.c | 1 | ||||
| -rw-r--r-- | drivers/pci/pci.h | 1 | ||||
| -rw-r--r-- | include/linux/libata.h | 2 | ||||
| -rw-r--r-- | include/linux/pci.h | 1 |
7 files changed, 123 insertions, 11 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index d9fa329fd157..ad070861bb53 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
| @@ -91,6 +91,7 @@ | |||
| 91 | #include <linux/device.h> | 91 | #include <linux/device.h> |
| 92 | #include <scsi/scsi_host.h> | 92 | #include <scsi/scsi_host.h> |
| 93 | #include <linux/libata.h> | 93 | #include <linux/libata.h> |
| 94 | #include <linux/dmi.h> | ||
| 94 | 95 | ||
| 95 | #define DRV_NAME "ata_piix" | 96 | #define DRV_NAME "ata_piix" |
| 96 | #define DRV_VERSION "2.11" | 97 | #define DRV_VERSION "2.11" |
| @@ -140,6 +141,9 @@ enum { | |||
| 140 | RV = -3, /* reserved */ | 141 | RV = -3, /* reserved */ |
| 141 | 142 | ||
| 142 | PIIX_AHCI_DEVICE = 6, | 143 | PIIX_AHCI_DEVICE = 6, |
| 144 | |||
| 145 | /* host->flags bits */ | ||
| 146 | PIIX_HOST_BROKEN_SUSPEND = (1 << 24), | ||
| 143 | }; | 147 | }; |
| 144 | 148 | ||
| 145 | struct piix_map_db { | 149 | struct piix_map_db { |
| @@ -159,6 +163,10 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev); | |||
| 159 | static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev); | 163 | static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev); |
| 160 | static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev); | 164 | static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev); |
| 161 | static int ich_pata_cable_detect(struct ata_port *ap); | 165 | static int ich_pata_cable_detect(struct ata_port *ap); |
| 166 | #ifdef CONFIG_PM | ||
| 167 | static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); | ||
| 168 | static int piix_pci_device_resume(struct pci_dev *pdev); | ||
| 169 | #endif | ||
| 162 | 170 | ||
| 163 | static unsigned int in_module_init = 1; | 171 | static unsigned int in_module_init = 1; |
| 164 | 172 | ||
| @@ -255,8 +263,8 @@ static struct pci_driver piix_pci_driver = { | |||
| 255 | .probe = piix_init_one, | 263 | .probe = piix_init_one, |
| 256 | .remove = ata_pci_remove_one, | 264 | .remove = ata_pci_remove_one, |
| 257 | #ifdef CONFIG_PM | 265 | #ifdef CONFIG_PM |
| 258 | .suspend = ata_pci_device_suspend, | 266 | .suspend = piix_pci_device_suspend, |
| 259 | .resume = ata_pci_device_resume, | 267 | .resume = piix_pci_device_resume, |
| 260 | #endif | 268 | #endif |
| 261 | }; | 269 | }; |
| 262 | 270 | ||
| @@ -881,6 +889,107 @@ static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev) | |||
| 881 | do_pata_set_dmamode(ap, adev, 1); | 889 | do_pata_set_dmamode(ap, adev, 1); |
| 882 | } | 890 | } |
| 883 | 891 | ||
| 892 | #ifdef CONFIG_PM | ||
| 893 | static struct dmi_system_id piix_broken_suspend_dmi_table[] = { | ||
| 894 | { | ||
| 895 | .ident = "TECRA M5", | ||
| 896 | .matches = { | ||
| 897 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
| 898 | DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M5"), | ||
| 899 | }, | ||
| 900 | }, | ||
| 901 | { | ||
| 902 | .ident = "Satellite U200", | ||
| 903 | .matches = { | ||
| 904 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
| 905 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U200"), | ||
| 906 | }, | ||
| 907 | }, | ||
| 908 | { | ||
| 909 | .ident = "Satellite U205", | ||
| 910 | .matches = { | ||
| 911 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
| 912 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U205"), | ||
| 913 | }, | ||
| 914 | }, | ||
| 915 | { | ||
| 916 | .ident = "Portege M500", | ||
| 917 | .matches = { | ||
| 918 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
| 919 | DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M500"), | ||
| 920 | }, | ||
| 921 | }, | ||
| 922 | { } | ||
| 923 | }; | ||
| 924 | |||
| 925 | static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) | ||
| 926 | { | ||
| 927 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | ||
| 928 | unsigned long flags; | ||
| 929 | int rc = 0; | ||
| 930 | |||
| 931 | rc = ata_host_suspend(host, mesg); | ||
| 932 | if (rc) | ||
| 933 | return rc; | ||
| 934 | |||
| 935 | /* Some braindamaged ACPI suspend implementations expect the | ||
| 936 | * controller to be awake on entry; otherwise, it burns cpu | ||
| 937 | * cycles and power trying to do something to the sleeping | ||
| 938 | * beauty. | ||
| 939 | */ | ||
| 940 | if (dmi_check_system(piix_broken_suspend_dmi_table) && | ||
| 941 | mesg.event == PM_EVENT_SUSPEND) { | ||
| 942 | pci_save_state(pdev); | ||
| 943 | |||
| 944 | /* mark its power state as "unknown", since we don't | ||
| 945 | * know if e.g. the BIOS will change its device state | ||
| 946 | * when we suspend. | ||
| 947 | */ | ||
| 948 | if (pdev->current_state == PCI_D0) | ||
| 949 | pdev->current_state = PCI_UNKNOWN; | ||
| 950 | |||
| 951 | /* tell resume that it's waking up from broken suspend */ | ||
| 952 | spin_lock_irqsave(&host->lock, flags); | ||
| 953 | host->flags |= PIIX_HOST_BROKEN_SUSPEND; | ||
| 954 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 955 | } else | ||
| 956 | ata_pci_device_do_suspend(pdev, mesg); | ||
| 957 | |||
| 958 | return 0; | ||
| 959 | } | ||
| 960 | |||
| 961 | static int piix_pci_device_resume(struct pci_dev *pdev) | ||
| 962 | { | ||
| 963 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | ||
| 964 | unsigned long flags; | ||
| 965 | int rc; | ||
| 966 | |||
| 967 | if (host->flags & PIIX_HOST_BROKEN_SUSPEND) { | ||
| 968 | spin_lock_irqsave(&host->lock, flags); | ||
| 969 | host->flags &= ~PIIX_HOST_BROKEN_SUSPEND; | ||
| 970 | spin_unlock_irqrestore(&host->lock, flags); | ||
| 971 | |||
| 972 | pci_set_power_state(pdev, PCI_D0); | ||
| 973 | pci_restore_state(pdev); | ||
| 974 | |||
| 975 | /* PCI device wasn't disabled during suspend. Use | ||
| 976 | * __pci_reenable_device() to avoid affecting the | ||
| 977 | * enable count. | ||
| 978 | */ | ||
| 979 | rc = __pci_reenable_device(pdev); | ||
| 980 | if (rc) | ||
| 981 | dev_printk(KERN_ERR, &pdev->dev, "failed to enable " | ||
| 982 | "device after resume (%d)\n", rc); | ||
| 983 | } else | ||
| 984 | rc = ata_pci_device_do_resume(pdev); | ||
| 985 | |||
| 986 | if (rc == 0) | ||
| 987 | ata_host_resume(host); | ||
| 988 | |||
| 989 | return rc; | ||
| 990 | } | ||
| 991 | #endif | ||
| 992 | |||
| 884 | #define AHCI_PCI_BAR 5 | 993 | #define AHCI_PCI_BAR 5 |
| 885 | #define AHCI_GLOBAL_CTL 0x04 | 994 | #define AHCI_GLOBAL_CTL 0x04 |
| 886 | #define AHCI_ENABLE (1 << 31) | 995 | #define AHCI_ENABLE (1 << 31) |
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 010436795d20..e8a28e94fe47 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c | |||
| @@ -45,7 +45,7 @@ static struct dmi_system_id cable_dmi_table[] = { | |||
| 45 | .ident = "HP Pavilion N5430", | 45 | .ident = "HP Pavilion N5430", |
| 46 | .matches = { | 46 | .matches = { |
| 47 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), | 47 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), |
| 48 | DMI_MATCH(DMI_BOARD_NAME, "OmniBook N32N-736"), | 48 | DMI_MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736"), |
| 49 | }, | 49 | }, |
| 50 | }, | 50 | }, |
| 51 | { } | 51 | { } |
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index b0af65aadde3..84d9c5568567 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #include <linux/libata.h> | 26 | #include <linux/libata.h> |
| 27 | 27 | ||
| 28 | #define DRV_NAME "pata_hpt37x" | 28 | #define DRV_NAME "pata_hpt37x" |
| 29 | #define DRV_VERSION "0.6.6" | 29 | #define DRV_VERSION "0.6.7" |
| 30 | 30 | ||
| 31 | struct hpt_clock { | 31 | struct hpt_clock { |
| 32 | u8 xfer_speed; | 32 | u8 xfer_speed; |
| @@ -1103,17 +1103,17 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 1103 | 1103 | ||
| 1104 | /* Select the DPLL clock. */ | 1104 | /* Select the DPLL clock. */ |
| 1105 | pci_write_config_byte(dev, 0x5b, 0x21); | 1105 | pci_write_config_byte(dev, 0x5b, 0x21); |
| 1106 | pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); | 1106 | pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100); |
| 1107 | 1107 | ||
| 1108 | for(adjust = 0; adjust < 8; adjust++) { | 1108 | for(adjust = 0; adjust < 8; adjust++) { |
| 1109 | if (hpt37x_calibrate_dpll(dev)) | 1109 | if (hpt37x_calibrate_dpll(dev)) |
| 1110 | break; | 1110 | break; |
| 1111 | /* See if it'll settle at a fractionally different clock */ | 1111 | /* See if it'll settle at a fractionally different clock */ |
| 1112 | if ((adjust & 3) == 3) { | 1112 | if (adjust & 1) |
| 1113 | f_low --; | 1113 | f_low -= adjust >> 1; |
| 1114 | f_high ++; | 1114 | else |
| 1115 | } | 1115 | f_high += adjust >> 1; |
| 1116 | pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); | 1116 | pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100); |
| 1117 | } | 1117 | } |
| 1118 | if (adjust == 8) { | 1118 | if (adjust == 8) { |
| 1119 | printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n"); | 1119 | printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n"); |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 03fd59e80fef..c95485398687 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -1604,6 +1604,7 @@ early_param("pci", pci_setup); | |||
| 1604 | device_initcall(pci_init); | 1604 | device_initcall(pci_init); |
| 1605 | 1605 | ||
| 1606 | EXPORT_SYMBOL_GPL(pci_restore_bars); | 1606 | EXPORT_SYMBOL_GPL(pci_restore_bars); |
| 1607 | EXPORT_SYMBOL(__pci_reenable_device); | ||
| 1607 | EXPORT_SYMBOL(pci_enable_device_bars); | 1608 | EXPORT_SYMBOL(pci_enable_device_bars); |
| 1608 | EXPORT_SYMBOL(pci_enable_device); | 1609 | EXPORT_SYMBOL(pci_enable_device); |
| 1609 | EXPORT_SYMBOL(pcim_enable_device); | 1610 | EXPORT_SYMBOL(pcim_enable_device); |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 3fec13d3add7..7b696cd66dc5 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | /* Functions internal to the PCI core code */ | 1 | /* Functions internal to the PCI core code */ |
| 2 | 2 | ||
| 3 | extern int __must_check __pci_reenable_device(struct pci_dev *); | ||
| 4 | extern int pci_uevent(struct device *dev, char **envp, int num_envp, | 3 | extern int pci_uevent(struct device *dev, char **envp, int num_envp, |
| 5 | char *buffer, int buffer_size); | 4 | char *buffer, int buffer_size); |
| 6 | extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); | 5 | extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 9aa6c10f7bb1..41978a557318 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -216,6 +216,8 @@ enum { | |||
| 216 | ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host only */ | 216 | ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host only */ |
| 217 | ATA_HOST_STARTED = (1 << 1), /* Host started */ | 217 | ATA_HOST_STARTED = (1 << 1), /* Host started */ |
| 218 | 218 | ||
| 219 | /* bits 24:31 of host->flags are reserved for LLD specific flags */ | ||
| 220 | |||
| 219 | /* various lengths of time */ | 221 | /* various lengths of time */ |
| 220 | ATA_TMOUT_BOOT = 30 * HZ, /* heuristic */ | 222 | ATA_TMOUT_BOOT = 30 * HZ, /* heuristic */ |
| 221 | ATA_TMOUT_BOOT_QUICK = 7 * HZ, /* heuristic */ | 223 | ATA_TMOUT_BOOT_QUICK = 7 * HZ, /* heuristic */ |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 5e84f2e8d54c..d8f8a3a96644 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
| @@ -534,6 +534,7 @@ static inline int pci_write_config_dword(struct pci_dev *dev, int where, u32 val | |||
| 534 | 534 | ||
| 535 | int __must_check pci_enable_device(struct pci_dev *dev); | 535 | int __must_check pci_enable_device(struct pci_dev *dev); |
| 536 | int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask); | 536 | int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask); |
| 537 | int __must_check __pci_reenable_device(struct pci_dev *); | ||
| 537 | int __must_check pcim_enable_device(struct pci_dev *pdev); | 538 | int __must_check pcim_enable_device(struct pci_dev *pdev); |
| 538 | void pcim_pin_device(struct pci_dev *pdev); | 539 | void pcim_pin_device(struct pci_dev *pdev); |
| 539 | 540 | ||
