vserver 1.9.5.x5
[linux-2.6.git] / drivers / acpi / sleep / proc.c
index 666498e..607cfdd 100644 (file)
@@ -70,7 +70,7 @@ acpi_system_write_sleep (
        state = simple_strtoul(str, NULL, 0);
 #ifdef CONFIG_SOFTWARE_SUSPEND
        if (state == 4) {
-               software_suspend();
+               error = software_suspend();
                goto Done;
        }
 #endif
@@ -83,6 +83,7 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
 {
        u32                     sec, min, hr;
        u32                     day, mo, yr;
+       unsigned char           rtc_control = 0;
 
        ACPI_FUNCTION_TRACE("acpi_system_alarm_seq_show");
 
@@ -91,10 +92,12 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
        sec = CMOS_READ(RTC_SECONDS_ALARM);
        min = CMOS_READ(RTC_MINUTES_ALARM);
        hr = CMOS_READ(RTC_HOURS_ALARM);
+       rtc_control = CMOS_READ(RTC_CONTROL);
 
-#if 0  /* If we ever get an FACP with proper values... */
+       /* If we ever get an FACP with proper values... */
        if (acpi_gbl_FADT->day_alrm)
-               day = CMOS_READ(acpi_gbl_FADT->day_alrm);
+               /* ACPI spec: only low 6 its should be cared */
+               day = CMOS_READ(acpi_gbl_FADT->day_alrm) & 0x3F;
        else
                day =  CMOS_READ(RTC_DAY_OF_MONTH);
        if (acpi_gbl_FADT->mon_alrm)
@@ -105,24 +108,20 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
                yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + CMOS_READ(RTC_YEAR);
        else
                yr = CMOS_READ(RTC_YEAR);
-#else
-       day = CMOS_READ(RTC_DAY_OF_MONTH);
-       mo = CMOS_READ(RTC_MONTH);
-       yr = CMOS_READ(RTC_YEAR);
-#endif
 
        spin_unlock(&rtc_lock);
 
-       BCD_TO_BIN(sec);
-       BCD_TO_BIN(min);
-       BCD_TO_BIN(hr);
-       BCD_TO_BIN(day);
-       BCD_TO_BIN(mo);
-       BCD_TO_BIN(yr);
+       if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+               BCD_TO_BIN(sec);
+               BCD_TO_BIN(min);
+               BCD_TO_BIN(hr);
+               BCD_TO_BIN(day);
+               BCD_TO_BIN(mo);
+               BCD_TO_BIN(yr);
+       }
 
-#if 0
        /* we're trusting the FADT (see above)*/
-#else
+       if (!acpi_gbl_FADT->century)
        /* If we're not trusting the FADT, we should at least make it
         * right for _this_ century... ehm, what is _this_ century?
         *
@@ -141,8 +140,7 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
         *        s/2000/2100
         *
         */
-       yr += 2000;
-#endif
+               yr += 2000;
 
        seq_printf(seq,"%4.4u-", yr);
        (mo > 12)  ? seq_puts(seq, "**-")  : seq_printf(seq, "%2.2u-", mo);
@@ -316,6 +314,13 @@ acpi_system_write_alarm (
        }
 
        spin_lock_irq(&rtc_lock);
+       /*
+        * Disable alarm interrupt before setting alarm timer or else
+        * when ACPI_EVENT_RTC is enabled, a spurious ACPI interrupt occurs
+        */
+       rtc_control &= ~RTC_AIE;
+       CMOS_WRITE(rtc_control, RTC_CONTROL);
+       CMOS_READ(RTC_INTR_FLAGS);
 
        /* write the fields the rtc knows about */
        CMOS_WRITE(hr, RTC_HOURS_ALARM);
@@ -327,24 +332,21 @@ acpi_system_write_alarm (
         * offsets into the CMOS RAM here -- which for some reason are pointing
         * to the RTC area of memory.
         */
-#if 0
        if (acpi_gbl_FADT->day_alrm)
                CMOS_WRITE(day, acpi_gbl_FADT->day_alrm);
        if (acpi_gbl_FADT->mon_alrm)
                CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm);
        if (acpi_gbl_FADT->century)
                CMOS_WRITE(yr/100, acpi_gbl_FADT->century);
-#endif
        /* enable the rtc alarm interrupt */
-       if (!(rtc_control & RTC_AIE)) {
-               rtc_control |= RTC_AIE;
-               CMOS_WRITE(rtc_control,RTC_CONTROL);
-               CMOS_READ(RTC_INTR_FLAGS);
-       }
+       rtc_control |= RTC_AIE;
+       CMOS_WRITE(rtc_control, RTC_CONTROL);
+       CMOS_READ(RTC_INTR_FLAGS);
 
        spin_unlock_irq(&rtc_lock);
 
-       acpi_set_register(ACPI_BITREG_RT_CLOCK_ENABLE, 1, ACPI_MTX_LOCK);
+       acpi_clear_event(ACPI_EVENT_RTC);
+       acpi_enable_event(ACPI_EVENT_RTC, 0);
 
        *ppos += count;
 
@@ -395,6 +397,7 @@ acpi_system_write_wakeup_device (
        char            strbuf[5];
        char            str[5] = "";
        int             len = count;
+       struct acpi_device *found_dev = NULL;
 
        if (len > 4) len = 4;
 
@@ -411,9 +414,25 @@ acpi_system_write_wakeup_device (
 
                if (!strncmp(dev->pnp.bus_id, str, 4)) {
                        dev->wakeup.state.enabled = dev->wakeup.state.enabled ? 0:1;
+                       found_dev = dev;
                        break;
                }
        }
+       if (found_dev) {
+               list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+                       struct acpi_device * dev = container_of(node,
+                               struct acpi_device, wakeup_list);
+
+                       if ((dev != found_dev) &&
+                               (dev->wakeup.gpe_number == found_dev->wakeup.gpe_number) &&
+                               (dev->wakeup.gpe_device == found_dev->wakeup.gpe_device)) {
+                               printk(KERN_WARNING "ACPI: '%s' and '%s' have the same GPE, "
+                                       "can't disable/enable one seperately\n",
+                                       dev->pnp.bus_id, found_dev->pnp.bus_id);
+                               dev->wakeup.state.enabled = found_dev->wakeup.state.enabled;
+                       }
+               }
+       }
        spin_unlock(&acpi_device_lock);
        return count;
 }
@@ -449,6 +468,14 @@ static struct file_operations acpi_system_alarm_fops = {
 };
 
 
+static u32 rtc_handler(void * context)
+{
+       acpi_clear_event(ACPI_EVENT_RTC);
+       acpi_disable_event(ACPI_EVENT_RTC, 0);
+
+       return ACPI_INTERRUPT_HANDLED;
+}
+
 static int acpi_sleep_proc_init(void)
 {
        struct proc_dir_entry   *entry = NULL;
@@ -474,6 +501,7 @@ static int acpi_sleep_proc_init(void)
        if (entry)
                entry->proc_fops = &acpi_system_wakeup_device_fops;
 
+       acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
        return 0;
 }