static int acpi_system_write_alarm ( struct file *file, const char *buffer, unsigned long count, void *data) { int result = 0; char alarm_string[30] = {'\0'}; char *p = alarm_string; u32 sec, min, hr, day, mo, yr; int adjust = 0; unsigned char rtc_control = 0; ACPI_FUNCTION_TRACE("acpi_system_write_alarm"); if (count > sizeof(alarm_string) - 1) return_VALUE(-EINVAL); if (copy_from_user(alarm_string, buffer, count)) return_VALUE(-EFAULT); alarm_string[count] = '\0'; /* check for time adjustment */ if (alarm_string[0] == '+') { p++; adjust = 1; } if ((result = get_date_field(&p, &yr))) goto end; if ((result = get_date_field(&p, &mo))) goto end; if ((result = get_date_field(&p, &day))) goto end; if ((result = get_date_field(&p, &hr))) goto end; if ((result = get_date_field(&p, &min))) goto end; if ((result = get_date_field(&p, &sec))) goto end; if (sec > 59) { min += 1; sec -= 60; } if (min > 59) { hr += 1; min -= 60; } if (hr > 23) { day += 1; hr -= 24; } if (day > 31) { mo += 1; day -= 31; } if (mo > 12) { yr += 1; mo -= 12; } spin_lock_irq(&rtc_lock); rtc_control = CMOS_READ(RTC_CONTROL); if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { BIN_TO_BCD(yr); BIN_TO_BCD(mo); BIN_TO_BCD(day); BIN_TO_BCD(hr); BIN_TO_BCD(min); BIN_TO_BCD(sec); } if (adjust) { yr += CMOS_READ(RTC_YEAR); mo += CMOS_READ(RTC_MONTH); day += CMOS_READ(RTC_DAY_OF_MONTH); hr += CMOS_READ(RTC_HOURS); min += CMOS_READ(RTC_MINUTES); sec += CMOS_READ(RTC_SECONDS); } spin_unlock_irq(&rtc_lock); if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { BCD_TO_BIN(yr); BCD_TO_BIN(mo); BCD_TO_BIN(day); BCD_TO_BIN(hr); BCD_TO_BIN(min); BCD_TO_BIN(sec); } if (sec > 59) { min++; sec -= 60; } if (min > 59) { hr++; min -= 60; } if (hr > 23) { day++; hr -= 24; } if (day > 31) { mo++; day -= 31; } if (mo > 12) { yr++; mo -= 12; } if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { BIN_TO_BCD(yr); BIN_TO_BCD(mo); BIN_TO_BCD(day); BIN_TO_BCD(hr); BIN_TO_BCD(min); BIN_TO_BCD(sec); } spin_lock_irq(&rtc_lock); /* write the fields the rtc knows about */ CMOS_WRITE(hr, RTC_HOURS_ALARM); CMOS_WRITE(min, RTC_MINUTES_ALARM); CMOS_WRITE(sec, RTC_SECONDS_ALARM); /* * If the system supports an enhanced alarm it will have non-zero * 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); } spin_unlock_irq(&rtc_lock); acpi_set_register(ACPI_BITREG_RT_CLOCK_ENABLE, 1, ACPI_MTX_LOCK); file->f_pos += count; result = 0; end: return_VALUE(result ? result : count); }
int sm_osl_proc_write_alarm ( struct file *file, const char *buffer, unsigned long count, void *data) { char buf[30]; char *str = buf; u32 sec,min,hr; u32 day,mo,yr; int adjust = 0; unsigned char rtc_control; int error = -EINVAL; if (count > sizeof(buf) - 1) return -EINVAL; if (copy_from_user(str,buffer,count)) return -EFAULT; str[count] = '\0'; /* check for time adjustment */ if (str[0] == '+') { str++; adjust = 1; } if ((error = get_date_field(&str,&yr))) goto out; if ((error = get_date_field(&str,&mo))) goto out; if ((error = get_date_field(&str,&day))) goto out; if ((error = get_date_field(&str,&hr))) goto out; if ((error = get_date_field(&str,&min))) goto out; if ((error = get_date_field(&str,&sec))) goto out; if (sec > 59) { min += 1; sec -= 60; } if (min > 59) { hr += 1; min -= 60; } if (hr > 23) { day += 1; hr -= 24; } if (day > 31) { mo += 1; day -= 31; } if (mo > 12) { yr += 1; mo -= 12; } spin_lock_irq(&rtc_lock); rtc_control = CMOS_READ(RTC_CONTROL); if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { BIN_TO_BCD(yr); BIN_TO_BCD(mo); BIN_TO_BCD(day); BIN_TO_BCD(hr); BIN_TO_BCD(min); BIN_TO_BCD(sec); } if (adjust) { yr += CMOS_READ(RTC_YEAR); mo += CMOS_READ(RTC_MONTH); day += CMOS_READ(RTC_DAY_OF_MONTH); hr += CMOS_READ(RTC_HOURS); min += CMOS_READ(RTC_MINUTES); sec += CMOS_READ(RTC_SECONDS); } spin_unlock_irq(&rtc_lock); if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { BCD_TO_BIN(yr); BCD_TO_BIN(mo); BCD_TO_BIN(day); BCD_TO_BIN(hr); BCD_TO_BIN(min); BCD_TO_BIN(sec); } if (sec > 59) { min++; sec -= 60; } if (min > 59) { hr++; min -= 60; } if (hr > 23) { day++; hr -= 24; } if (day > 31) { mo++; day -= 31; } if (mo > 12) { yr++; mo -= 12; } if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { BIN_TO_BCD(yr); BIN_TO_BCD(mo); BIN_TO_BCD(day); BIN_TO_BCD(hr); BIN_TO_BCD(min); BIN_TO_BCD(sec); } spin_lock_irq(&rtc_lock); /* write the fields the rtc knows about */ CMOS_WRITE(hr,RTC_HOURS_ALARM); CMOS_WRITE(min,RTC_MINUTES_ALARM); CMOS_WRITE(sec,RTC_SECONDS_ALARM); /* If the system supports an enhanced alarm, it will have non-zero * 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); } /* unlock the lock on the rtc now that we're done with it */ spin_unlock_irq(&rtc_lock); acpi_hw_register_bit_access(ACPI_WRITE,ACPI_MTX_LOCK, RTC_EN, 1); file->f_pos += count; error = 0; out: return error ? error : count; }