diff options
author | Hannes Reinecke <hare@suse.de> | 2007-02-07 12:19:37 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-02-07 12:19:37 -0500 |
commit | e3a59b4d9378522479609042836ae930305a67fe (patch) | |
tree | 1dd41aefac4d7f370dd3798818c2ca36c654fe7c /drivers/ide/ide.c | |
parent | 78281c5350029e3fa21758d6db9b45ffc7bf72a1 (diff) |
ACPI support for IDE devices
This patch implements ACPI integration for generic IDE devices.
The ACPI spec mandates that some methods are called during suspend and
resume. And consequently there most modern Laptops cannot resume
properly without it.
According to the spec, we should call '_GTM' (Get Timing) upon suspend
to store the current IDE adapter settings.
Upon resume we should call '_STM' (Set Timing) to initialize the
adapter with the stored settings; afterwards '_GTF' (Get Taskfile)
should be called which returns a buffer with some IDE initialisation
commands. Those commands should be passed to the drive.
There are two module params which control the behaviour of this patch:
'ide=noacpi'
Do not call any ACPI methods (Disables any ACPI method calls)
'ide=acpigtf'
Enable execution of _GTF methods upon resume.
Has no effect if 'ide=noacpi' is set.
'ide=acpionboot'
Enable execution of ACPI methods during boot.
This might be required on some machines if 'ide=acpigtf' is
selected as some machines modify the _GTF information
depending on the drive identification passed down with _STM.
Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide.c')
-rw-r--r-- | drivers/ide/ide.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 6c9bd5165bd..c750f6ce770 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -187,6 +187,12 @@ int noautodma = 1; | |||
187 | 187 | ||
188 | EXPORT_SYMBOL(noautodma); | 188 | EXPORT_SYMBOL(noautodma); |
189 | 189 | ||
190 | #ifdef CONFIG_BLK_DEV_IDEACPI | ||
191 | int ide_noacpi = 0; | ||
192 | int ide_noacpitfs = 1; | ||
193 | int ide_noacpionboot = 1; | ||
194 | #endif | ||
195 | |||
190 | /* | 196 | /* |
191 | * This is declared extern in ide.h, for access by other IDE modules: | 197 | * This is declared extern in ide.h, for access by other IDE modules: |
192 | */ | 198 | */ |
@@ -1214,10 +1220,15 @@ EXPORT_SYMBOL(system_bus_clock); | |||
1214 | static int generic_ide_suspend(struct device *dev, pm_message_t mesg) | 1220 | static int generic_ide_suspend(struct device *dev, pm_message_t mesg) |
1215 | { | 1221 | { |
1216 | ide_drive_t *drive = dev->driver_data; | 1222 | ide_drive_t *drive = dev->driver_data; |
1223 | ide_hwif_t *hwif = HWIF(drive); | ||
1217 | struct request rq; | 1224 | struct request rq; |
1218 | struct request_pm_state rqpm; | 1225 | struct request_pm_state rqpm; |
1219 | ide_task_t args; | 1226 | ide_task_t args; |
1220 | 1227 | ||
1228 | /* Call ACPI _GTM only once */ | ||
1229 | if (!(drive->dn % 2)) | ||
1230 | ide_acpi_get_timing(hwif); | ||
1231 | |||
1221 | memset(&rq, 0, sizeof(rq)); | 1232 | memset(&rq, 0, sizeof(rq)); |
1222 | memset(&rqpm, 0, sizeof(rqpm)); | 1233 | memset(&rqpm, 0, sizeof(rqpm)); |
1223 | memset(&args, 0, sizeof(args)); | 1234 | memset(&args, 0, sizeof(args)); |
@@ -1235,10 +1246,17 @@ static int generic_ide_suspend(struct device *dev, pm_message_t mesg) | |||
1235 | static int generic_ide_resume(struct device *dev) | 1246 | static int generic_ide_resume(struct device *dev) |
1236 | { | 1247 | { |
1237 | ide_drive_t *drive = dev->driver_data; | 1248 | ide_drive_t *drive = dev->driver_data; |
1249 | ide_hwif_t *hwif = HWIF(drive); | ||
1238 | struct request rq; | 1250 | struct request rq; |
1239 | struct request_pm_state rqpm; | 1251 | struct request_pm_state rqpm; |
1240 | ide_task_t args; | 1252 | ide_task_t args; |
1241 | 1253 | ||
1254 | /* Call ACPI _STM only once */ | ||
1255 | if (!(drive->dn % 2)) | ||
1256 | ide_acpi_push_timing(hwif); | ||
1257 | |||
1258 | ide_acpi_exec_tfs(drive); | ||
1259 | |||
1242 | memset(&rq, 0, sizeof(rq)); | 1260 | memset(&rq, 0, sizeof(rq)); |
1243 | memset(&rqpm, 0, sizeof(rqpm)); | 1261 | memset(&rqpm, 0, sizeof(rqpm)); |
1244 | memset(&args, 0, sizeof(args)); | 1262 | memset(&args, 0, sizeof(args)); |
@@ -1543,6 +1561,24 @@ static int __init ide_setup(char *s) | |||
1543 | } | 1561 | } |
1544 | #endif /* CONFIG_BLK_DEV_IDEPCI */ | 1562 | #endif /* CONFIG_BLK_DEV_IDEPCI */ |
1545 | 1563 | ||
1564 | #ifdef CONFIG_BLK_DEV_IDEACPI | ||
1565 | if (!strcmp(s, "ide=noacpi")) { | ||
1566 | //printk(" : Disable IDE ACPI support.\n"); | ||
1567 | ide_noacpi = 1; | ||
1568 | return 1; | ||
1569 | } | ||
1570 | if (!strcmp(s, "ide=acpigtf")) { | ||
1571 | //printk(" : Enable IDE ACPI _GTF support.\n"); | ||
1572 | ide_noacpitfs = 0; | ||
1573 | return 1; | ||
1574 | } | ||
1575 | if (!strcmp(s, "ide=acpionboot")) { | ||
1576 | //printk(" : Call IDE ACPI methods on boot.\n"); | ||
1577 | ide_noacpionboot = 0; | ||
1578 | return 1; | ||
1579 | } | ||
1580 | #endif /* CONFIG_BLK_DEV_IDEACPI */ | ||
1581 | |||
1546 | /* | 1582 | /* |
1547 | * Look for drive options: "hdx=" | 1583 | * Look for drive options: "hdx=" |
1548 | */ | 1584 | */ |