Merge branch 'dcache-cleanup'
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 24 Apr 2011 15:51:15 +0000 (08:51 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 24 Apr 2011 15:51:15 +0000 (08:51 -0700)
* dcache-cleanup:
  vfs: get rid of insane dentry hashing rules

17 files changed:
arch/x86/kernel/apm_32.c
drivers/ata/ahci.c
drivers/ata/ahci.h
drivers/ata/ata_piix.c
drivers/ata/libahci.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/pata_at91.c
drivers/base/syscore.c
drivers/xen/manage.c
fs/ubifs/recovery.c
fs/ubifs/super.c
include/linux/libata.h
kernel/kexec.c
kernel/power/hibernate.c
kernel/power/suspend.c
scripts/kconfig/conf.c

index 0b4be431c620ab30ac0bd348888fdf3e9dd3a5b8..adee12e0da1fcaf6e1c8f9ad3ff1e362e2ec736b 100644 (file)
 #include <linux/kthread.h>
 #include <linux/jiffies.h>
 #include <linux/acpi.h>
+#include <linux/syscore_ops.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -1238,6 +1239,7 @@ static int suspend(int vetoable)
 
        local_irq_disable();
        sysdev_suspend(PMSG_SUSPEND);
+       syscore_suspend();
 
        local_irq_enable();
 
@@ -1255,6 +1257,7 @@ static int suspend(int vetoable)
                apm_error("suspend", err);
        err = (err == APM_SUCCESS) ? 0 : -EIO;
 
+       syscore_resume();
        sysdev_resume();
        local_irq_enable();
 
@@ -1280,6 +1283,7 @@ static void standby(void)
 
        local_irq_disable();
        sysdev_suspend(PMSG_SUSPEND);
+       syscore_suspend();
        local_irq_enable();
 
        err = set_system_power_state(APM_STATE_STANDBY);
@@ -1287,6 +1291,7 @@ static void standby(void)
                apm_error("standby", err);
 
        local_irq_disable();
+       syscore_resume();
        sysdev_resume();
        local_irq_enable();
 
index 39d829cd82dd4dfae5f87ee59bdb9f0f300ede8c..71afe0371311d7475e7034bb5ab1e483b2d3ce68 100644 (file)
@@ -150,7 +150,7 @@ static const struct ata_port_info ahci_port_info[] = {
        {
                AHCI_HFLAGS     (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP |
                                 AHCI_HFLAG_YES_NCQ),
-               .flags          = AHCI_FLAG_COMMON,
+               .flags          = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
                .pio_mask       = ATA_PIO4,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
@@ -261,6 +261,12 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x1d06), board_ahci }, /* PBG RAID */
        { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */
        { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */
+       { PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */
+       { PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point AHCI */
+       { PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */
+       { PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */
+       { PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
+       { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */
 
        /* JMicron 360/1/3/5/6, match class to avoid IDE function */
        { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
index 39865009c25117410ba99f1a17141e8fd724dbe5..12c5282e7fca9c6effe1c42a2a7dae0a78395b2e 100644 (file)
@@ -229,6 +229,10 @@ enum {
        EM_CTL_ALHD             = (1 << 26), /* Activity LED */
        EM_CTL_XMT              = (1 << 25), /* Transmit Only */
        EM_CTL_SMB              = (1 << 24), /* Single Message Buffer */
+       EM_CTL_SGPIO            = (1 << 19), /* SGPIO messages supported */
+       EM_CTL_SES              = (1 << 18), /* SES-2 messages supported */
+       EM_CTL_SAFTE            = (1 << 17), /* SAF-TE messages supported */
+       EM_CTL_LED              = (1 << 16), /* LED messages supported */
 
        /* em message type */
        EM_MSG_TYPE_LED         = (1 << 0), /* LED */
index 0bc3fd6c3fdb8ea2f979f0a57b135ecc57a6e770..6f6e7718b05c7ff905ab3ad068aaa15160992581 100644 (file)
@@ -309,6 +309,14 @@ static const struct pci_device_id piix_pci_tbl[] = {
        { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
        /* SATA Controller IDE (PBG) */
        { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (Panther Point) */
+       { 0x8086, 0x1e00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
+       /* SATA Controller IDE (Panther Point) */
+       { 0x8086, 0x1e01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
+       /* SATA Controller IDE (Panther Point) */
+       { 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (Panther Point) */
+       { 0x8086, 0x1e09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
        { }     /* terminate list */
 };
 
index 26d452339e98f59fc483cbc85e9c53f56b2a0183..ff9d832a163de8442c2adc1d8fa18be75ec4f417 100644 (file)
@@ -109,6 +109,8 @@ static ssize_t ahci_read_em_buffer(struct device *dev,
 static ssize_t ahci_store_em_buffer(struct device *dev,
                                    struct device_attribute *attr,
                                    const char *buf, size_t size);
+static ssize_t ahci_show_em_supported(struct device *dev,
+                                     struct device_attribute *attr, char *buf);
 
 static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL);
 static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL);
@@ -116,6 +118,7 @@ static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL);
 static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL);
 static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO,
                   ahci_read_em_buffer, ahci_store_em_buffer);
+static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL);
 
 struct device_attribute *ahci_shost_attrs[] = {
        &dev_attr_link_power_management_policy,
@@ -126,6 +129,7 @@ struct device_attribute *ahci_shost_attrs[] = {
        &dev_attr_ahci_host_version,
        &dev_attr_ahci_port_cmd,
        &dev_attr_em_buffer,
+       &dev_attr_em_message_supported,
        NULL
 };
 EXPORT_SYMBOL_GPL(ahci_shost_attrs);
@@ -343,6 +347,24 @@ static ssize_t ahci_store_em_buffer(struct device *dev,
        return size;
 }
 
+static ssize_t ahci_show_em_supported(struct device *dev,
+                                     struct device_attribute *attr, char *buf)
+{
+       struct Scsi_Host *shost = class_to_shost(dev);
+       struct ata_port *ap = ata_shost_to_port(shost);
+       struct ahci_host_priv *hpriv = ap->host->private_data;
+       void __iomem *mmio = hpriv->mmio;
+       u32 em_ctl;
+
+       em_ctl = readl(mmio + HOST_EM_CTL);
+
+       return sprintf(buf, "%s%s%s%s\n",
+                      em_ctl & EM_CTL_LED ? "led " : "",
+                      em_ctl & EM_CTL_SAFTE ? "saf-te " : "",
+                      em_ctl & EM_CTL_SES ? "ses-2 " : "",
+                      em_ctl & EM_CTL_SGPIO ? "sgpio " : "");
+}
+
 /**
  *     ahci_save_initial_config - Save and fixup initial config values
  *     @dev: target AHCI device
@@ -539,6 +561,27 @@ void ahci_start_engine(struct ata_port *ap)
 {
        void __iomem *port_mmio = ahci_port_base(ap);
        u32 tmp;
+       u8 status;
+
+       status = readl(port_mmio + PORT_TFDATA) & 0xFF;
+
+       /*
+        * At end of section 10.1 of AHCI spec (rev 1.3), it states
+        * Software shall not set PxCMD.ST to 1 until it is determined
+        * that a functoinal device is present on the port as determined by
+        * PxTFD.STS.BSY=0, PxTFD.STS.DRQ=0 and PxSSTS.DET=3h
+        *
+        * Even though most AHCI host controllers work without this check,
+        * specific controller will fail under this condition
+        */
+       if (status & (ATA_BUSY | ATA_DRQ))
+               return;
+       else {
+               ahci_scr_read(&ap->link, SCR_STATUS, &tmp);
+
+               if ((tmp & 0xf) != 0x3)
+                       return;
+       }
 
        /* start DMA */
        tmp = readl(port_mmio + PORT_CMD);
@@ -1897,7 +1940,17 @@ static void ahci_pmp_attach(struct ata_port *ap)
        ahci_enable_fbs(ap);
 
        pp->intr_mask |= PORT_IRQ_BAD_PMP;
-       writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
+
+       /*
+        * We must not change the port interrupt mask register if the
+        * port is marked frozen, the value in pp->intr_mask will be
+        * restored later when the port is thawed.
+        *
+        * Note that during initialization, the port is marked as
+        * frozen since the irq handler is not yet registered.
+        */
+       if (!(ap->pflags & ATA_PFLAG_FROZEN))
+               writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
 }
 
 static void ahci_pmp_detach(struct ata_port *ap)
@@ -1913,7 +1966,10 @@ static void ahci_pmp_detach(struct ata_port *ap)
        writel(cmd, port_mmio + PORT_CMD);
 
        pp->intr_mask &= ~PORT_IRQ_BAD_PMP;
-       writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
+
+       /* see comment above in ahci_pmp_attach() */
+       if (!(ap->pflags & ATA_PFLAG_FROZEN))
+               writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
 }
 
 int ahci_port_resume(struct ata_port *ap)
index 423c0a6952b25af341bdd0360656af2be09019ff..76c3c15cb1e66680e11f9c5fb670d616e564acc5 100644 (file)
@@ -4139,6 +4139,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
         */
        { "PIONEER DVD-RW  DVRTD08",    "1.00", ATA_HORKAGE_NOSETXFER },
        { "PIONEER DVD-RW  DVR-212D",   "1.28", ATA_HORKAGE_NOSETXFER },
+       { "PIONEER DVD-RW  DVR-216D",   "1.08", ATA_HORKAGE_NOSETXFER },
 
        /* End Marker */
        { }
@@ -5480,7 +5481,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
        if (!ap)
                return NULL;
 
-       ap->pflags |= ATA_PFLAG_INITIALIZING;
+       ap->pflags |= ATA_PFLAG_INITIALIZING | ATA_PFLAG_FROZEN;
        ap->lock = &host->lock;
        ap->print_id = -1;
        ap->host = host;
index 88cd22fa65cd82057b217f7b36a5e8657d910781..f26f2fe3480ad0847b6ce059a0b4206e182a9f46 100644 (file)
@@ -3316,6 +3316,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
        struct ata_eh_context *ehc = &link->eh_context;
        struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL;
        enum ata_lpm_policy old_policy = link->lpm_policy;
+       bool no_dipm = ap->flags & ATA_FLAG_NO_DIPM;
        unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM;
        unsigned int err_mask;
        int rc;
@@ -3332,7 +3333,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
         */
        ata_for_each_dev(dev, link, ENABLED) {
                bool hipm = ata_id_has_hipm(dev->id);
-               bool dipm = ata_id_has_dipm(dev->id);
+               bool dipm = ata_id_has_dipm(dev->id) && !no_dipm;
 
                /* find the first enabled and LPM enabled devices */
                if (!link_dev)
@@ -3389,7 +3390,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
 
        /* host config updated, enable DIPM if transitioning to MIN_POWER */
        ata_for_each_dev(dev, link, ENABLED) {
-               if (policy == ATA_LPM_MIN_POWER && ata_id_has_dipm(dev->id)) {
+               if (policy == ATA_LPM_MIN_POWER && !no_dipm &&
+                   ata_id_has_dipm(dev->id)) {
                        err_mask = ata_dev_set_feature(dev,
                                        SETFEATURES_SATA_ENABLE, SATA_DIPM);
                        if (err_mask && err_mask != AC_ERR_DEV) {
index 0da0dcc7dd089427a988171c3f1a8b62c1b8f90f..a5fdbdcb0faf2ed8daa5c4fa77767da6cc3fa7ea 100644 (file)
 
 
 #define DRV_NAME "pata_at91"
-#define DRV_VERSION "0.1"
+#define DRV_VERSION "0.2"
 
 #define CF_IDE_OFFSET      0x00c00000
 #define CF_ALT_IDE_OFFSET   0x00e00000
 #define CF_IDE_RES_SIZE     0x08
+#define NCS_RD_PULSE_LIMIT  0x3f /* maximal value for pulse bitfields */
 
 struct at91_ide_info {
        unsigned long mode;
@@ -49,8 +50,18 @@ struct at91_ide_info {
        void __iomem *alt_addr;
 };
 
-static const struct ata_timing initial_timing =
-       {XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0};
+static const struct ata_timing initial_timing = {
+       .mode           = XFER_PIO_0,
+       .setup          = 70,
+       .act8b          = 290,
+       .rec8b          = 240,
+       .cyc8b          = 600,
+       .active         = 165,
+       .recover        = 150,
+       .dmack_hold     = 0,
+       .cycle          = 600,
+       .udma           = 0
+};
 
 static unsigned long calc_mck_cycles(unsigned long ns, unsigned long mck_hz)
 {
@@ -109,6 +120,11 @@ static void set_smc_timing(struct device *dev,
        /* (CS0, CS1, DIR, OE) <= (CFCE1, CFCE2, CFRNW, NCSX) timings */
        ncs_read_setup = 1;
        ncs_read_pulse = read_cycle - 2;
+       if (ncs_read_pulse > NCS_RD_PULSE_LIMIT) {
+               ncs_read_pulse = NCS_RD_PULSE_LIMIT;
+               dev_warn(dev, "ncs_read_pulse limited to maximal value %lu\n",
+                       ncs_read_pulse);
+       }
 
        /* Write timings same as read timings */
        write_cycle = read_cycle;
index 90af2943f9e4a56bb284aab6ce5bab177cfba794..c126db3cb7d12c92be4b5d62abfd58d4a699a961 100644 (file)
@@ -73,6 +73,7 @@ int syscore_suspend(void)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(syscore_suspend);
 
 /**
  * syscore_resume - Execute all the registered system core resume callbacks.
@@ -95,6 +96,7 @@ void syscore_resume(void)
                                "Interrupts enabled after %pF\n", ops->resume);
                }
 }
+EXPORT_SYMBOL_GPL(syscore_resume);
 #endif /* CONFIG_PM_SLEEP */
 
 /**
index 1ac94125bf93c38bb98342828490e9633a12c75f..a2eee574784e801aec6463a8317267c24f928201 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/sysrq.h>
 #include <linux/stop_machine.h>
 #include <linux/freezer.h>
+#include <linux/syscore_ops.h>
 
 #include <xen/xen.h>
 #include <xen/xenbus.h>
@@ -70,8 +71,13 @@ static int xen_suspend(void *data)
        BUG_ON(!irqs_disabled());
 
        err = sysdev_suspend(PMSG_FREEZE);
+       if (!err) {
+               err = syscore_suspend();
+               if (err)
+                       sysdev_resume();
+       }
        if (err) {
-               printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n",
+               printk(KERN_ERR "xen_suspend: system core suspend failed: %d\n",
                        err);
                return err;
        }
@@ -95,6 +101,7 @@ static int xen_suspend(void *data)
                xen_timer_resume();
        }
 
+       syscore_resume();
        sysdev_resume();
 
        return 0;
index 936f2cbfe6b672437aec08219ad017f0fc6f3074..3dbad6fbd1eba528661e458ae56e97c03c43b609 100644 (file)
@@ -317,6 +317,32 @@ int ubifs_recover_master_node(struct ubifs_info *c)
                        goto out_free;
                }
                memcpy(c->rcvrd_mst_node, c->mst_node, UBIFS_MST_NODE_SZ);
+
+               /*
+                * We had to recover the master node, which means there was an
+                * unclean reboot. However, it is possible that the master node
+                * is clean at this point, i.e., %UBIFS_MST_DIRTY is not set.
+                * E.g., consider the following chain of events:
+                *
+                * 1. UBIFS was cleanly unmounted, so the master node is clean
+                * 2. UBIFS is being mounted R/W and starts changing the master
+                *    node in the first (%UBIFS_MST_LNUM). A power cut happens,
+                *    so this LEB ends up with some amount of garbage at the
+                *    end.
+                * 3. UBIFS is being mounted R/O. We reach this place and
+                *    recover the master node from the second LEB
+                *    (%UBIFS_MST_LNUM + 1). But we cannot update the media
+                *    because we are being mounted R/O. We have to defer the
+                *    operation.
+                * 4. However, this master node (@c->mst_node) is marked as
+                *    clean (since the step 1). And if we just return, the
+                *    mount code will be confused and won't recover the master
+                *    node when it is re-mounter R/W later.
+                *
+                *    Thus, to force the recovery by marking the master node as
+                *    dirty.
+                */
+               c->mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY);
        } else {
                /* Write the recovered master node */
                c->max_sqnum = le64_to_cpu(mst->ch.sqnum) - 1;
index c75f6133206cf5edfbf88d1162a81d5001953cb1..be6c7b008f38233650cc119ff76117d61bb6c4e6 100644 (file)
@@ -1671,14 +1671,25 @@ static int ubifs_remount_rw(struct ubifs_info *c)
        if (err)
                goto out;
 
+       dbg_gen("re-mounted read-write");
+       c->remounting_rw = 0;
+
        if (c->need_recovery) {
                c->need_recovery = 0;
                ubifs_msg("deferred recovery completed");
+       } else {
+               /*
+                * Do not run the debugging space check if the were doing
+                * recovery, because when we saved the information we had the
+                * file-system in a state where the TNC and lprops has been
+                * modified in memory, but all the I/O operations (including a
+                * commit) were deferred. So the file-system was in
+                * "non-committed" state. Now the file-system is in committed
+                * state, and of course the amount of free space will change
+                * because, for example, the old index size was imprecise.
+                */
+               err = dbg_check_space_info(c);
        }
-
-       dbg_gen("re-mounted read-write");
-       c->remounting_rw = 0;
-       err = dbg_check_space_info(c);
        mutex_unlock(&c->umount_mutex);
        return err;
 
@@ -1761,10 +1772,12 @@ static void ubifs_put_super(struct super_block *sb)
         * of the media. For example, there will be dirty inodes if we failed
         * to write them back because of I/O errors.
         */
-       ubifs_assert(atomic_long_read(&c->dirty_pg_cnt) == 0);
-       ubifs_assert(c->budg_idx_growth == 0);
-       ubifs_assert(c->budg_dd_growth == 0);
-       ubifs_assert(c->budg_data_growth == 0);
+       if (!c->ro_error) {
+               ubifs_assert(atomic_long_read(&c->dirty_pg_cnt) == 0);
+               ubifs_assert(c->budg_idx_growth == 0);
+               ubifs_assert(c->budg_dd_growth == 0);
+               ubifs_assert(c->budg_data_growth == 0);
+       }
 
        /*
         * The 'c->umount_lock' prevents races between UBIFS memory shrinker
index 7f675aa81d877795b12e48c78a13f6ae144af606..04f32a3eb26b85dd9ea0b0e786f282c0c799f30d 100644 (file)
@@ -137,8 +137,6 @@ enum {
        ATA_DFLAG_ACPI_PENDING  = (1 << 5), /* ACPI resume action pending */
        ATA_DFLAG_ACPI_FAILED   = (1 << 6), /* ACPI on devcfg has failed */
        ATA_DFLAG_AN            = (1 << 7), /* AN configured */
-       ATA_DFLAG_HIPM          = (1 << 8), /* device supports HIPM */
-       ATA_DFLAG_DIPM          = (1 << 9), /* device supports DIPM */
        ATA_DFLAG_DMADIR        = (1 << 10), /* device requires DMADIR */
        ATA_DFLAG_CFG_MASK      = (1 << 12) - 1,
 
@@ -198,6 +196,7 @@ enum {
                                              * management */
        ATA_FLAG_SW_ACTIVITY    = (1 << 22), /* driver supports sw activity
                                              * led */
+       ATA_FLAG_NO_DIPM        = (1 << 23), /* host not happy with DIPM */
 
        /* bits 24:31 of ap->flags are reserved for LLD specific flags */
 
index 55936f9cb251b9eb114d9b827ee478e18a3448b7..87b77de03dd33942b29953909aaf5727bb5e2bdd 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/vmalloc.h>
 #include <linux/swap.h>
 #include <linux/kmsg_dump.h>
+#include <linux/syscore_ops.h>
 
 #include <asm/page.h>
 #include <asm/uaccess.h>
@@ -1532,6 +1533,11 @@ int kernel_kexec(void)
                local_irq_disable();
                /* Suspend system devices */
                error = sysdev_suspend(PMSG_FREEZE);
+               if (!error) {
+                       error = syscore_suspend();
+                       if (error)
+                               sysdev_resume();
+               }
                if (error)
                        goto Enable_irqs;
        } else
@@ -1546,6 +1552,7 @@ int kernel_kexec(void)
 
 #ifdef CONFIG_KEXEC_JUMP
        if (kexec_image->preserve_context) {
+               syscore_resume();
                sysdev_resume();
  Enable_irqs:
                local_irq_enable();
index aeabd26e3342788e4330cfb4e8e2a5ba40b348d0..50aae660174d6bd0b0697b6a70e4e31b2e1535f3 100644 (file)
@@ -273,8 +273,11 @@ static int create_image(int platform_mode)
        local_irq_disable();
 
        error = sysdev_suspend(PMSG_FREEZE);
-       if (!error)
+       if (!error) {
                error = syscore_suspend();
+               if (error)
+                       sysdev_resume();
+       }
        if (error) {
                printk(KERN_ERR "PM: Some system devices failed to power down, "
                        "aborting hibernation\n");
@@ -407,8 +410,11 @@ static int resume_target_kernel(bool platform_mode)
        local_irq_disable();
 
        error = sysdev_suspend(PMSG_QUIESCE);
-       if (!error)
+       if (!error) {
                error = syscore_suspend();
+               if (error)
+                       sysdev_resume();
+       }
        if (error)
                goto Enable_irqs;
 
index 2814c32aed51c121a7ff9689aa38f6b98d025b15..8935369d503a309a036e75f975a903982fa6af80 100644 (file)
@@ -164,8 +164,11 @@ static int suspend_enter(suspend_state_t state)
        BUG_ON(!irqs_disabled());
 
        error = sysdev_suspend(PMSG_SUSPEND);
-       if (!error)
+       if (!error) {
                error = syscore_suspend();
+               if (error)
+                       sysdev_resume();
+       }
        if (!error) {
                if (!(suspend_test(TEST_CORE) || pm_wakeup_pending())) {
                        error = suspend_ops->enter(state);
index 659326c3e89579b09f86077dbcbe5e1eb3a12d28..006ad817cd5f003023a7308b471eb9c4e46ba5de 100644 (file)
@@ -332,7 +332,7 @@ static int conf_choice(struct menu *menu)
                }
                if (!child)
                        continue;
-               if (line[strlen(line) - 1] == '?') {
+               if (line[0] && line[strlen(line) - 1] == '?') {
                        print_help(child);
                        continue;
                }