diff options
| -rw-r--r-- | drivers/ata/ahci.c | 32 | ||||
| -rw-r--r-- | drivers/ata/ata_piix.c | 34 | ||||
| -rw-r--r-- | drivers/ata/libata-scsi.c | 20 | ||||
| -rw-r--r-- | drivers/ata/sata_sil.c | 36 | ||||
| -rw-r--r-- | drivers/firmware/dmi_scan.c | 74 | ||||
| -rw-r--r-- | include/linux/dmi.h | 1 | ||||
| -rw-r--r-- | include/linux/libata.h | 2 | ||||
| -rw-r--r-- | include/linux/suspend.h | 2 | ||||
| -rw-r--r-- | kernel/power/disk.c | 10 |
9 files changed, 188 insertions, 23 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 96039671e3b9..77bba4c083cb 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
| @@ -2548,6 +2548,32 @@ static void ahci_p5wdh_workaround(struct ata_host *host) | |||
| 2548 | } | 2548 | } |
| 2549 | } | 2549 | } |
| 2550 | 2550 | ||
| 2551 | static bool ahci_broken_system_poweroff(struct pci_dev *pdev) | ||
| 2552 | { | ||
| 2553 | static const struct dmi_system_id broken_systems[] = { | ||
| 2554 | { | ||
| 2555 | .ident = "HP Compaq nx6310", | ||
| 2556 | .matches = { | ||
| 2557 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
| 2558 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6310"), | ||
| 2559 | }, | ||
| 2560 | /* PCI slot number of the controller */ | ||
| 2561 | .driver_data = (void *)0x1FUL, | ||
| 2562 | }, | ||
| 2563 | |||
| 2564 | { } /* terminate list */ | ||
| 2565 | }; | ||
| 2566 | const struct dmi_system_id *dmi = dmi_first_match(broken_systems); | ||
| 2567 | |||
| 2568 | if (dmi) { | ||
| 2569 | unsigned long slot = (unsigned long)dmi->driver_data; | ||
| 2570 | /* apply the quirk only to on-board controllers */ | ||
| 2571 | return slot == PCI_SLOT(pdev->devfn); | ||
| 2572 | } | ||
| 2573 | |||
| 2574 | return false; | ||
| 2575 | } | ||
| 2576 | |||
| 2551 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 2577 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
| 2552 | { | 2578 | { |
| 2553 | static int printed_version; | 2579 | static int printed_version; |
| @@ -2647,6 +2673,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 2647 | } | 2673 | } |
| 2648 | } | 2674 | } |
| 2649 | 2675 | ||
| 2676 | if (ahci_broken_system_poweroff(pdev)) { | ||
| 2677 | pi.flags |= ATA_FLAG_NO_POWEROFF_SPINDOWN; | ||
| 2678 | dev_info(&pdev->dev, | ||
| 2679 | "quirky BIOS, skipping spindown on poweroff\n"); | ||
| 2680 | } | ||
| 2681 | |||
| 2650 | /* CAP.NP sometimes indicate the index of the last enabled | 2682 | /* CAP.NP sometimes indicate the index of the last enabled |
| 2651 | * port, at other times, that of the last possible port, so | 2683 | * port, at other times, that of the last possible port, so |
| 2652 | * determining the maximum port number requires looking at | 2684 | * determining the maximum port number requires looking at |
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 887d8f46a287..54961c0b2c73 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
| @@ -1387,6 +1387,32 @@ static void piix_iocfg_bit18_quirk(struct ata_host *host) | |||
| 1387 | } | 1387 | } |
| 1388 | } | 1388 | } |
| 1389 | 1389 | ||
| 1390 | static bool piix_broken_system_poweroff(struct pci_dev *pdev) | ||
| 1391 | { | ||
| 1392 | static const struct dmi_system_id broken_systems[] = { | ||
| 1393 | { | ||
| 1394 | .ident = "HP Compaq 2510p", | ||
| 1395 | .matches = { | ||
| 1396 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
| 1397 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 2510p"), | ||
| 1398 | }, | ||
| 1399 | /* PCI slot number of the controller */ | ||
| 1400 | .driver_data = (void *)0x1FUL, | ||
| 1401 | }, | ||
| 1402 | |||
| 1403 | { } /* terminate list */ | ||
| 1404 | }; | ||
| 1405 | const struct dmi_system_id *dmi = dmi_first_match(broken_systems); | ||
| 1406 | |||
| 1407 | if (dmi) { | ||
| 1408 | unsigned long slot = (unsigned long)dmi->driver_data; | ||
| 1409 | /* apply the quirk only to on-board controllers */ | ||
| 1410 | return slot == PCI_SLOT(pdev->devfn); | ||
| 1411 | } | ||
| 1412 | |||
| 1413 | return false; | ||
| 1414 | } | ||
| 1415 | |||
| 1390 | /** | 1416 | /** |
| 1391 | * piix_init_one - Register PIIX ATA PCI device with kernel services | 1417 | * piix_init_one - Register PIIX ATA PCI device with kernel services |
| 1392 | * @pdev: PCI device to register | 1418 | * @pdev: PCI device to register |
| @@ -1422,6 +1448,14 @@ static int __devinit piix_init_one(struct pci_dev *pdev, | |||
| 1422 | if (!in_module_init) | 1448 | if (!in_module_init) |
| 1423 | return -ENODEV; | 1449 | return -ENODEV; |
| 1424 | 1450 | ||
| 1451 | if (piix_broken_system_poweroff(pdev)) { | ||
| 1452 | piix_port_info[ent->driver_data].flags |= | ||
| 1453 | ATA_FLAG_NO_POWEROFF_SPINDOWN | | ||
| 1454 | ATA_FLAG_NO_HIBERNATE_SPINDOWN; | ||
| 1455 | dev_info(&pdev->dev, "quirky BIOS, skipping spindown " | ||
| 1456 | "on poweroff and hibernation\n"); | ||
| 1457 | } | ||
| 1458 | |||
| 1425 | port_info[0] = piix_port_info[ent->driver_data]; | 1459 | port_info[0] = piix_port_info[ent->driver_data]; |
| 1426 | port_info[1] = piix_port_info[ent->driver_data]; | 1460 | port_info[1] = piix_port_info[ent->driver_data]; |
| 1427 | 1461 | ||
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index a1a6e6298c33..3c4c5ae277ba 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | #include <linux/libata.h> | 46 | #include <linux/libata.h> |
| 47 | #include <linux/hdreg.h> | 47 | #include <linux/hdreg.h> |
| 48 | #include <linux/uaccess.h> | 48 | #include <linux/uaccess.h> |
| 49 | #include <linux/suspend.h> | ||
| 49 | 50 | ||
| 50 | #include "libata.h" | 51 | #include "libata.h" |
| 51 | 52 | ||
| @@ -1303,6 +1304,17 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) | |||
| 1303 | 1304 | ||
| 1304 | tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ | 1305 | tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ |
| 1305 | } else { | 1306 | } else { |
| 1307 | /* Some odd clown BIOSen issue spindown on power off (ACPI S4 | ||
| 1308 | * or S5) causing some drives to spin up and down again. | ||
| 1309 | */ | ||
| 1310 | if ((qc->ap->flags & ATA_FLAG_NO_POWEROFF_SPINDOWN) && | ||
| 1311 | system_state == SYSTEM_POWER_OFF) | ||
| 1312 | goto skip; | ||
| 1313 | |||
| 1314 | if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) && | ||
| 1315 | system_entering_hibernation()) | ||
| 1316 | goto skip; | ||
| 1317 | |||
| 1306 | /* XXX: This is for backward compatibility, will be | 1318 | /* XXX: This is for backward compatibility, will be |
| 1307 | * removed. Read Documentation/feature-removal-schedule.txt | 1319 | * removed. Read Documentation/feature-removal-schedule.txt |
| 1308 | * for more info. | 1320 | * for more info. |
| @@ -1326,8 +1338,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) | |||
| 1326 | scmd->scsi_done = qc->scsidone; | 1338 | scmd->scsi_done = qc->scsidone; |
| 1327 | qc->scsidone = ata_delayed_done; | 1339 | qc->scsidone = ata_delayed_done; |
| 1328 | } | 1340 | } |
| 1329 | scmd->result = SAM_STAT_GOOD; | 1341 | goto skip; |
| 1330 | return 1; | ||
| 1331 | } | 1342 | } |
| 1332 | 1343 | ||
| 1333 | /* Issue ATA STANDBY IMMEDIATE command */ | 1344 | /* Issue ATA STANDBY IMMEDIATE command */ |
| @@ -1343,10 +1354,13 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) | |||
| 1343 | 1354 | ||
| 1344 | return 0; | 1355 | return 0; |
| 1345 | 1356 | ||
| 1346 | invalid_fld: | 1357 | invalid_fld: |
| 1347 | ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0); | 1358 | ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0); |
| 1348 | /* "Invalid field in cbd" */ | 1359 | /* "Invalid field in cbd" */ |
| 1349 | return 1; | 1360 | return 1; |
| 1361 | skip: | ||
| 1362 | scmd->result = SAM_STAT_GOOD; | ||
| 1363 | return 1; | ||
| 1350 | } | 1364 | } |
| 1351 | 1365 | ||
| 1352 | 1366 | ||
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 564c142b03b0..bfd55b085ae6 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c | |||
| @@ -695,11 +695,38 @@ static void sil_init_controller(struct ata_host *host) | |||
| 695 | } | 695 | } |
| 696 | } | 696 | } |
| 697 | 697 | ||
| 698 | static bool sil_broken_system_poweroff(struct pci_dev *pdev) | ||
| 699 | { | ||
| 700 | static const struct dmi_system_id broken_systems[] = { | ||
| 701 | { | ||
| 702 | .ident = "HP Compaq nx6325", | ||
| 703 | .matches = { | ||
| 704 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
| 705 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"), | ||
| 706 | }, | ||
| 707 | /* PCI slot number of the controller */ | ||
| 708 | .driver_data = (void *)0x12UL, | ||
| 709 | }, | ||
| 710 | |||
| 711 | { } /* terminate list */ | ||
| 712 | }; | ||
| 713 | const struct dmi_system_id *dmi = dmi_first_match(broken_systems); | ||
| 714 | |||
| 715 | if (dmi) { | ||
| 716 | unsigned long slot = (unsigned long)dmi->driver_data; | ||
| 717 | /* apply the quirk only to on-board controllers */ | ||
| 718 | return slot == PCI_SLOT(pdev->devfn); | ||
| 719 | } | ||
| 720 | |||
| 721 | return false; | ||
| 722 | } | ||
| 723 | |||
| 698 | static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 724 | static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
| 699 | { | 725 | { |
| 700 | static int printed_version; | 726 | static int printed_version; |
| 701 | int board_id = ent->driver_data; | 727 | int board_id = ent->driver_data; |
| 702 | const struct ata_port_info *ppi[] = { &sil_port_info[board_id], NULL }; | 728 | struct ata_port_info pi = sil_port_info[board_id]; |
| 729 | const struct ata_port_info *ppi[] = { &pi, NULL }; | ||
| 703 | struct ata_host *host; | 730 | struct ata_host *host; |
| 704 | void __iomem *mmio_base; | 731 | void __iomem *mmio_base; |
| 705 | int n_ports, rc; | 732 | int n_ports, rc; |
| @@ -713,6 +740,13 @@ static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 713 | if (board_id == sil_3114) | 740 | if (board_id == sil_3114) |
| 714 | n_ports = 4; | 741 | n_ports = 4; |
| 715 | 742 | ||
| 743 | if (sil_broken_system_poweroff(pdev)) { | ||
| 744 | pi.flags |= ATA_FLAG_NO_POWEROFF_SPINDOWN | | ||
| 745 | ATA_FLAG_NO_HIBERNATE_SPINDOWN; | ||
| 746 | dev_info(&pdev->dev, "quirky BIOS, skipping spindown " | ||
| 747 | "on poweroff and hibernation\n"); | ||
| 748 | } | ||
| 749 | |||
| 716 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); | 750 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); |
| 717 | if (!host) | 751 | if (!host) |
| 718 | return -ENOMEM; | 752 | return -ENOMEM; |
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index d76adfea5df7..8f0f7c449305 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
| @@ -415,6 +415,29 @@ void __init dmi_scan_machine(void) | |||
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | /** | 417 | /** |
| 418 | * dmi_matches - check if dmi_system_id structure matches system DMI data | ||
| 419 | * @dmi: pointer to the dmi_system_id structure to check | ||
| 420 | */ | ||
| 421 | static bool dmi_matches(const struct dmi_system_id *dmi) | ||
| 422 | { | ||
| 423 | int i; | ||
| 424 | |||
| 425 | WARN(!dmi_initialized, KERN_ERR "dmi check: not initialized yet.\n"); | ||
| 426 | |||
| 427 | for (i = 0; i < ARRAY_SIZE(dmi->matches); i++) { | ||
| 428 | int s = dmi->matches[i].slot; | ||
| 429 | if (s == DMI_NONE) | ||
| 430 | continue; | ||
| 431 | if (dmi_ident[s] | ||
| 432 | && strstr(dmi_ident[s], dmi->matches[i].substr)) | ||
| 433 | continue; | ||
| 434 | /* No match */ | ||
| 435 | return false; | ||
| 436 | } | ||
| 437 | return true; | ||
| 438 | } | ||
| 439 | |||
| 440 | /** | ||
| 418 | * dmi_check_system - check system DMI data | 441 | * dmi_check_system - check system DMI data |
| 419 | * @list: array of dmi_system_id structures to match against | 442 | * @list: array of dmi_system_id structures to match against |
| 420 | * All non-null elements of the list must match | 443 | * All non-null elements of the list must match |
| @@ -429,32 +452,45 @@ void __init dmi_scan_machine(void) | |||
| 429 | */ | 452 | */ |
| 430 | int dmi_check_system(const struct dmi_system_id *list) | 453 | int dmi_check_system(const struct dmi_system_id *list) |
| 431 | { | 454 | { |
| 432 | int i, count = 0; | 455 | int count = 0; |
| 433 | const struct dmi_system_id *d = list; | 456 | const struct dmi_system_id *d; |
| 434 | 457 | ||
| 435 | WARN(!dmi_initialized, KERN_ERR "dmi check: not initialized yet.\n"); | 458 | for (d = list; d->ident; d++) |
| 436 | 459 | if (dmi_matches(d)) { | |
| 437 | while (d->ident) { | 460 | count++; |
| 438 | for (i = 0; i < ARRAY_SIZE(d->matches); i++) { | 461 | if (d->callback && d->callback(d)) |
| 439 | int s = d->matches[i].slot; | 462 | break; |
| 440 | if (s == DMI_NONE) | ||
| 441 | continue; | ||
| 442 | if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr)) | ||
| 443 | continue; | ||
| 444 | /* No match */ | ||
| 445 | goto fail; | ||
| 446 | } | 463 | } |
| 447 | count++; | ||
| 448 | if (d->callback && d->callback(d)) | ||
| 449 | break; | ||
| 450 | fail: d++; | ||
| 451 | } | ||
| 452 | 464 | ||
| 453 | return count; | 465 | return count; |
| 454 | } | 466 | } |
| 455 | EXPORT_SYMBOL(dmi_check_system); | 467 | EXPORT_SYMBOL(dmi_check_system); |
| 456 | 468 | ||
| 457 | /** | 469 | /** |
| 470 | * dmi_first_match - find dmi_system_id structure matching system DMI data | ||
| 471 | * @list: array of dmi_system_id structures to match against | ||
| 472 | * All non-null elements of the list must match | ||
| 473 | * their slot's (field index's) data (i.e., each | ||
| 474 | * list string must be a substring of the specified | ||
| 475 | * DMI slot's string data) to be considered a | ||
| 476 | * successful match. | ||
| 477 | * | ||
| 478 | * Walk the blacklist table until the first match is found. Return the | ||
| 479 | * pointer to the matching entry or NULL if there's no match. | ||
| 480 | */ | ||
| 481 | const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list) | ||
| 482 | { | ||
| 483 | const struct dmi_system_id *d; | ||
| 484 | |||
| 485 | for (d = list; d->ident; d++) | ||
| 486 | if (dmi_matches(d)) | ||
| 487 | return d; | ||
| 488 | |||
| 489 | return NULL; | ||
| 490 | } | ||
| 491 | EXPORT_SYMBOL(dmi_first_match); | ||
| 492 | |||
| 493 | /** | ||
| 458 | * dmi_get_system_info - return DMI data value | 494 | * dmi_get_system_info - return DMI data value |
| 459 | * @field: data index (see enum dmi_field) | 495 | * @field: data index (see enum dmi_field) |
| 460 | * | 496 | * |
diff --git a/include/linux/dmi.h b/include/linux/dmi.h index 34161907b2f8..aea23105d3ed 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h | |||
| @@ -38,6 +38,7 @@ struct dmi_device { | |||
| 38 | #ifdef CONFIG_DMI | 38 | #ifdef CONFIG_DMI |
| 39 | 39 | ||
| 40 | extern int dmi_check_system(const struct dmi_system_id *list); | 40 | extern int dmi_check_system(const struct dmi_system_id *list); |
| 41 | const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list); | ||
| 41 | extern const char * dmi_get_system_info(int field); | 42 | extern const char * dmi_get_system_info(int field); |
| 42 | extern const struct dmi_device * dmi_find_device(int type, const char *name, | 43 | extern const struct dmi_device * dmi_find_device(int type, const char *name, |
| 43 | const struct dmi_device *from); | 44 | const struct dmi_device *from); |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 2c6bd66209ff..bca3ba25f52a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -187,6 +187,8 @@ enum { | |||
| 187 | ATA_FLAG_PIO_POLLING = (1 << 9), /* use polling PIO if LLD | 187 | ATA_FLAG_PIO_POLLING = (1 << 9), /* use polling PIO if LLD |
| 188 | * doesn't handle PIO interrupts */ | 188 | * doesn't handle PIO interrupts */ |
| 189 | ATA_FLAG_NCQ = (1 << 10), /* host supports NCQ */ | 189 | ATA_FLAG_NCQ = (1 << 10), /* host supports NCQ */ |
| 190 | ATA_FLAG_NO_POWEROFF_SPINDOWN = (1 << 11), /* don't spindown before poweroff */ | ||
| 191 | ATA_FLAG_NO_HIBERNATE_SPINDOWN = (1 << 12), /* don't spindown before hibernation */ | ||
| 190 | ATA_FLAG_DEBUGMSG = (1 << 13), | 192 | ATA_FLAG_DEBUGMSG = (1 << 13), |
| 191 | ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */ | 193 | ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */ |
| 192 | ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */ | 194 | ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */ |
diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 2b409c44db83..c7d9bb1832ba 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h | |||
| @@ -237,6 +237,7 @@ extern int hibernate_nvs_alloc(void); | |||
| 237 | extern void hibernate_nvs_free(void); | 237 | extern void hibernate_nvs_free(void); |
| 238 | extern void hibernate_nvs_save(void); | 238 | extern void hibernate_nvs_save(void); |
| 239 | extern void hibernate_nvs_restore(void); | 239 | extern void hibernate_nvs_restore(void); |
| 240 | extern bool system_entering_hibernation(void); | ||
| 240 | #else /* CONFIG_HIBERNATION */ | 241 | #else /* CONFIG_HIBERNATION */ |
| 241 | static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } | 242 | static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } |
| 242 | static inline void swsusp_set_page_free(struct page *p) {} | 243 | static inline void swsusp_set_page_free(struct page *p) {} |
| @@ -252,6 +253,7 @@ static inline int hibernate_nvs_alloc(void) { return 0; } | |||
| 252 | static inline void hibernate_nvs_free(void) {} | 253 | static inline void hibernate_nvs_free(void) {} |
| 253 | static inline void hibernate_nvs_save(void) {} | 254 | static inline void hibernate_nvs_save(void) {} |
| 254 | static inline void hibernate_nvs_restore(void) {} | 255 | static inline void hibernate_nvs_restore(void) {} |
| 256 | static inline bool system_entering_hibernation(void) { return false; } | ||
| 255 | #endif /* CONFIG_HIBERNATION */ | 257 | #endif /* CONFIG_HIBERNATION */ |
| 256 | 258 | ||
| 257 | #ifdef CONFIG_PM_SLEEP | 259 | #ifdef CONFIG_PM_SLEEP |
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 45e8541ab7e3..432ee575c9ee 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
| @@ -71,6 +71,14 @@ void hibernation_set_ops(struct platform_hibernation_ops *ops) | |||
| 71 | mutex_unlock(&pm_mutex); | 71 | mutex_unlock(&pm_mutex); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | static bool entering_platform_hibernation; | ||
| 75 | |||
| 76 | bool system_entering_hibernation(void) | ||
| 77 | { | ||
| 78 | return entering_platform_hibernation; | ||
| 79 | } | ||
| 80 | EXPORT_SYMBOL(system_entering_hibernation); | ||
| 81 | |||
| 74 | #ifdef CONFIG_PM_DEBUG | 82 | #ifdef CONFIG_PM_DEBUG |
| 75 | static void hibernation_debug_sleep(void) | 83 | static void hibernation_debug_sleep(void) |
| 76 | { | 84 | { |
| @@ -411,6 +419,7 @@ int hibernation_platform_enter(void) | |||
| 411 | if (error) | 419 | if (error) |
| 412 | goto Close; | 420 | goto Close; |
| 413 | 421 | ||
| 422 | entering_platform_hibernation = true; | ||
| 414 | suspend_console(); | 423 | suspend_console(); |
| 415 | error = device_suspend(PMSG_HIBERNATE); | 424 | error = device_suspend(PMSG_HIBERNATE); |
| 416 | if (error) { | 425 | if (error) { |
| @@ -445,6 +454,7 @@ int hibernation_platform_enter(void) | |||
| 445 | Finish: | 454 | Finish: |
| 446 | hibernation_ops->finish(); | 455 | hibernation_ops->finish(); |
| 447 | Resume_devices: | 456 | Resume_devices: |
| 457 | entering_platform_hibernation = false; | ||
| 448 | device_resume(PMSG_RESTORE); | 458 | device_resume(PMSG_RESTORE); |
| 449 | resume_console(); | 459 | resume_console(); |
| 450 | Close: | 460 | Close: |
