diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-24 18:58:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-24 18:58:51 -0400 |
commit | 1e66239e23dd0422baf891bf6af0b65ac632b676 (patch) | |
tree | 5646c17cef8cea3e37b35ff6b0d54b8e5602e26e /drivers/ata | |
parent | 7742c0bc8594cf1bcbad1f3e876acae5b644dc7b (diff) | |
parent | 64a8170975947978ea4094dd6c4b1f41119d6ae6 (diff) |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev:
pata_hpt37x: Fix 2.6.22 clock PLL regression
pata_ali: Correct HP detect
ata_piix: fix suspend/resume for some TOSHIBA laptops
PCI: export __pci_reenable_device()
Diffstat (limited to 'drivers/ata')
-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 |
3 files changed, 119 insertions, 10 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"); |