aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-24 18:58:51 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-24 18:58:51 -0400
commit1e66239e23dd0422baf891bf6af0b65ac632b676 (patch)
tree5646c17cef8cea3e37b35ff6b0d54b8e5602e26e /drivers/ata
parent7742c0bc8594cf1bcbad1f3e876acae5b644dc7b (diff)
parent64a8170975947978ea4094dd6c4b1f41119d6ae6 (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.c113
-rw-r--r--drivers/ata/pata_ali.c2
-rw-r--r--drivers/ata/pata_hpt37x.c14
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
145struct piix_map_db { 149struct piix_map_db {
@@ -159,6 +163,10 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev);
159static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev); 163static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev);
160static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev); 164static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev);
161static int ich_pata_cable_detect(struct ata_port *ap); 165static int ich_pata_cable_detect(struct ata_port *ap);
166#ifdef CONFIG_PM
167static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
168static int piix_pci_device_resume(struct pci_dev *pdev);
169#endif
162 170
163static unsigned int in_module_init = 1; 171static 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
893static 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
925static 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
961static 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
31struct hpt_clock { 31struct 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");