1 #include <linux/proc_fs.h> 2 #include <linux/seq_file.h> 3 #include <linux/suspend.h> 4 #include <linux/bcd.h> 5 #include <asm/uaccess.h> 6 7 #include <acpi/acpi_bus.h> 8 #include <acpi/acpi_drivers.h> 9 10 #ifdef CONFIG_X86 11 #include <linux/mc146818rtc.h> 12 #endif 13 14 #include "sleep.h" 15 16 #define _COMPONENT ACPI_SYSTEM_COMPONENT 17 18 /* 19 * this file provides support for: 20 * /proc/acpi/alarm 21 * /proc/acpi/wakeup 22 */ 23 24 ACPI_MODULE_NAME("sleep") 25 26 #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || !defined(CONFIG_X86) 27 /* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */ 28 #else 29 #define HAVE_ACPI_LEGACY_ALARM 30 #endif 31 32 #ifdef HAVE_ACPI_LEGACY_ALARM 33 34 static u32 cmos_bcd_read(int offset, int rtc_control); 35 36 static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) 37 { 38 u32 sec, min, hr; 39 u32 day, mo, yr, cent = 0; 40 u32 today = 0; 41 unsigned char rtc_control = 0; 42 unsigned long flags; 43 44 spin_lock_irqsave(&rtc_lock, flags); 45 46 rtc_control = CMOS_READ(RTC_CONTROL); 47 sec = cmos_bcd_read(RTC_SECONDS_ALARM, rtc_control); 48 min = cmos_bcd_read(RTC_MINUTES_ALARM, rtc_control); 49 hr = cmos_bcd_read(RTC_HOURS_ALARM, rtc_control); 50 51 /* If we ever get an FACP with proper values... */ 52 if (acpi_gbl_FADT.day_alarm) { 53 /* ACPI spec: only low 6 its should be cared */ 54 day = CMOS_READ(acpi_gbl_FADT.day_alarm) & 0x3F; 55 if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) 56 day = bcd2bin(day); 57 } else 58 day = cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control); 59 if (acpi_gbl_FADT.month_alarm) 60 mo = cmos_bcd_read(acpi_gbl_FADT.month_alarm, rtc_control); 61 else { 62 mo = cmos_bcd_read(RTC_MONTH, rtc_control); 63 today = cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control); 64 } 65 if (acpi_gbl_FADT.century) 66 cent = cmos_bcd_read(acpi_gbl_FADT.century, rtc_control); 67 68 yr = cmos_bcd_read(RTC_YEAR, rtc_control); 69 70 spin_unlock_irqrestore(&rtc_lock, flags); 71 72 /* we're trusting the FADT (see above) */ 73 if (!acpi_gbl_FADT.century) 74 /* If we're not trusting the FADT, we should at least make it 75 * right for _this_ century... ehm, what is _this_ century? 76 * 77 * TBD: 78 * ASAP: find piece of code in the kernel, e.g. star tracker driver, 79 * which we can trust to determine the century correctly. Atom 80 * watch driver would be nice, too... 81 * 82 * if that has not happened, change for first release in 2050: 83 * if (yr<50) 84 * yr += 2100; 85 * else 86 * yr += 2000; // current line of code 87 * 88 * if that has not happened either, please do on 2099/12/31:23:59:59 89 * s/2000/2100 90 * 91 */ 92 yr += 2000; 93 else 94 yr += cent * 100; 95 96 /* 97 * Show correct dates for alarms up to a month into the future. 98 * This solves issues for nearly all situations with the common 99 * 30-day alarm clocks in PC hardware. 100 */ 101 if (day < today) { 102 if (mo < 12) { 103 mo += 1; 104 } else { 105 mo = 1; 106 yr += 1; 107 } 108 } 109 110 seq_printf(seq, "%4.4u-", yr); 111 (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo); 112 (day > 31) ? seq_puts(seq, "** ") : seq_printf(seq, "%2.2u ", day); 113 (hr > 23) ? seq_puts(seq, "**:") : seq_printf(seq, "%2.2u:", hr); 114 (min > 59) ? seq_puts(seq, "**:") : seq_printf(seq, "%2.2u:", min); 115 (sec > 59) ? seq_puts(seq, "**\n") : seq_printf(seq, "%2.2u\n", sec); 116 117 return 0; 118 } 119 120 static int acpi_system_alarm_open_fs(struct inode *inode, struct file *file) 121 { 122 return single_open(file, acpi_system_alarm_seq_show, PDE(inode)->data); 123 } 124 125 static int get_date_field(char **p, u32 * value) 126 { 127 char *next = NULL; 128 char *string_end = NULL; 129 int result = -EINVAL; 130 131 /* 132 * Try to find delimeter, only to insert null. The end of the 133 * string won't have one, but is still valid. 134 */ 135 if (*p == NULL) 136 return result; 137 138 next = strpbrk(*p, "- :"); 139 if (next) 140 *next++ = '\0'; 141 142 *value = simple_strtoul(*p, &string_end, 10); 143 144 /* Signal success if we got a good digit */ 145 if (string_end != *p) 146 result = 0; 147 148 if (next) 149 *p = next; 150 else 151 *p = NULL; 152 153 return result; 154 } 155 156 /* Read a possibly BCD register, always return binary */ 157 static u32 cmos_bcd_read(int offset, int rtc_control) 158 { 159 u32 val = CMOS_READ(offset); 160 if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) 161 val = bcd2bin(val); 162 return val; 163 } 164 165 /* Write binary value into possibly BCD register */ 166 static void cmos_bcd_write(u32 val, int offset, int rtc_control) 167 { 168 if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) 169 val = bin2bcd(val); 170 CMOS_WRITE(val, offset); 171 } 172 173 static ssize_t 174 acpi_system_write_alarm(struct file *file, 175 const char __user * buffer, size_t count, loff_t * ppos) 176 { 177 int result = 0; 178 char alarm_string[30] = { '\0' }; 179 char *p = alarm_string; 180 u32 sec, min, hr, day, mo, yr; 181 int adjust = 0; 182 unsigned char rtc_control = 0; 183 184 if (count > sizeof(alarm_string) - 1) 185 return -EINVAL; 186 187 if (copy_from_user(alarm_string, buffer, count)) 188 return -EFAULT; 189 190 alarm_string[count] = '\0'; 191 192 /* check for time adjustment */ 193 if (alarm_string[0] == '+') { 194 p++; 195 adjust = 1; 196 } 197 198 if ((result = get_date_field(&p, &yr))) 199 goto end; 200 if ((result = get_date_field(&p, &mo))) 201 goto end; 202 if ((result = get_date_field(&p, &day))) 203 goto end; 204 if ((result = get_date_field(&p, &hr))) 205 goto end; 206 if ((result = get_date_field(&p, &min))) 207 goto end; 208 if ((result = get_date_field(&p, &sec))) 209 goto end; 210 211 spin_lock_irq(&rtc_lock); 212 213 rtc_control = CMOS_READ(RTC_CONTROL); 214 215 if (adjust) { 216 yr += cmos_bcd_read(RTC_YEAR, rtc_control); 217 mo += cmos_bcd_read(RTC_MONTH, rtc_control); 218 day += cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control); 219 hr += cmos_bcd_read(RTC_HOURS, rtc_control); 220 min += cmos_bcd_read(RTC_MINUTES, rtc_control); 221 sec += cmos_bcd_read(RTC_SECONDS, rtc_control); 222 } 223 224 spin_unlock_irq(&rtc_lock); 225 226 if (sec > 59) { 227 min += sec/60; 228 sec = sec%60; 229 } 230 if (min > 59) { 231 hr += min/60; 232 min = min%60; 233 } 234 if (hr > 23) { 235 day += hr/24; 236 hr = hr%24; 237 } 238 if (day > 31) { 239 mo += day/32; 240 day = day%32; 241 } 242 if (mo > 12) { 243 yr += mo/13; 244 mo = mo%13; 245 } 246 247 spin_lock_irq(&rtc_lock); 248 /* 249 * Disable alarm interrupt before setting alarm timer or else 250 * when ACPI_EVENT_RTC is enabled, a spurious ACPI interrupt occurs 251 */ 252 rtc_control &= ~RTC_AIE; 253 CMOS_WRITE(rtc_control, RTC_CONTROL); 254 CMOS_READ(RTC_INTR_FLAGS); 255 256 /* write the fields the rtc knows about */ 257 cmos_bcd_write(hr, RTC_HOURS_ALARM, rtc_control); 258 cmos_bcd_write(min, RTC_MINUTES_ALARM, rtc_control); 259 cmos_bcd_write(sec, RTC_SECONDS_ALARM, rtc_control); 260 261 /* 262 * If the system supports an enhanced alarm it will have non-zero 263 * offsets into the CMOS RAM here -- which for some reason are pointing 264 * to the RTC area of memory. 265 */ 266 if (acpi_gbl_FADT.day_alarm) 267 cmos_bcd_write(day, acpi_gbl_FADT.day_alarm, rtc_control); 268 if (acpi_gbl_FADT.month_alarm) 269 cmos_bcd_write(mo, acpi_gbl_FADT.month_alarm, rtc_control); 270 if (acpi_gbl_FADT.century) { 271 if (adjust) 272 yr += cmos_bcd_read(acpi_gbl_FADT.century, rtc_control) * 100; 273 cmos_bcd_write(yr / 100, acpi_gbl_FADT.century, rtc_control); 274 } 275 /* enable the rtc alarm interrupt */ 276 rtc_control |= RTC_AIE; 277 CMOS_WRITE(rtc_control, RTC_CONTROL); 278 CMOS_READ(RTC_INTR_FLAGS); 279 280 spin_unlock_irq(&rtc_lock); 281 282 acpi_clear_event(ACPI_EVENT_RTC); 283 acpi_enable_event(ACPI_EVENT_RTC, 0); 284 285 *ppos += count; 286 287 result = 0; 288 end: 289 return result ? result : count; 290 } 291 #endif /* HAVE_ACPI_LEGACY_ALARM */ 292 293 static int 294 acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) 295 { 296 struct list_head *node, *next; 297 298 seq_printf(seq, "Device\tS-state\t Status Sysfs node\n"); 299 300 mutex_lock(&acpi_device_lock); 301 list_for_each_safe(node, next, &acpi_wakeup_device_list) { 302 struct acpi_device *dev = 303 container_of(node, struct acpi_device, wakeup_list); 304 struct device *ldev; 305 306 if (!dev->wakeup.flags.valid) 307 continue; 308 309 ldev = acpi_get_physical_device(dev->handle); 310 seq_printf(seq, "%s\t S%d\t%c%-8s ", 311 dev->pnp.bus_id, 312 (u32) dev->wakeup.sleep_state, 313 dev->wakeup.flags.run_wake ? '*' : ' ', 314 (device_may_wakeup(&dev->dev) 315 || (ldev && device_may_wakeup(ldev))) ? 316 "enabled" : "disabled"); 317 if (ldev) 318 seq_printf(seq, "%s:%s", 319 ldev->bus ? ldev->bus->name : "no-bus", 320 dev_name(ldev)); 321 seq_printf(seq, "\n"); 322 put_device(ldev); 323 324 } 325 mutex_unlock(&acpi_device_lock); 326 return 0; 327 } 328 329 static void physical_device_enable_wakeup(struct acpi_device *adev) 330 { 331 struct device *dev = acpi_get_physical_device(adev->handle); 332 333 if (dev && device_can_wakeup(dev)) { 334 bool enable = !device_may_wakeup(dev); 335 device_set_wakeup_enable(dev, enable); 336 } 337 } 338 339 static ssize_t 340 acpi_system_write_wakeup_device(struct file *file, 341 const char __user * buffer, 342 size_t count, loff_t * ppos) 343 { 344 struct list_head *node, *next; 345 char strbuf[5]; 346 char str[5] = ""; 347 unsigned int len = count; 348 349 if (len > 4) 350 len = 4; 351 if (len < 0) 352 return -EFAULT; 353 354 if (copy_from_user(strbuf, buffer, len)) 355 return -EFAULT; 356 strbuf[len] = '\0'; 357 sscanf(strbuf, "%s", str); 358 359 mutex_lock(&acpi_device_lock); 360 list_for_each_safe(node, next, &acpi_wakeup_device_list) { 361 struct acpi_device *dev = 362 container_of(node, struct acpi_device, wakeup_list); 363 if (!dev->wakeup.flags.valid) 364 continue; 365 366 if (!strncmp(dev->pnp.bus_id, str, 4)) { 367 if (device_can_wakeup(&dev->dev)) { 368 bool enable = !device_may_wakeup(&dev->dev); 369 device_set_wakeup_enable(&dev->dev, enable); 370 } else { 371 physical_device_enable_wakeup(dev); 372 } 373 break; 374 } 375 } 376 mutex_unlock(&acpi_device_lock); 377 return count; 378 } 379 380 static int 381 acpi_system_wakeup_device_open_fs(struct inode *inode, struct file *file) 382 { 383 return single_open(file, acpi_system_wakeup_device_seq_show, 384 PDE(inode)->data); 385 } 386 387 static const struct file_operations acpi_system_wakeup_device_fops = { 388 .owner = THIS_MODULE, 389 .open = acpi_system_wakeup_device_open_fs, 390 .read = seq_read, 391 .write = acpi_system_write_wakeup_device, 392 .llseek = seq_lseek, 393 .release = single_release, 394 }; 395 396 #ifdef HAVE_ACPI_LEGACY_ALARM 397 static const struct file_operations acpi_system_alarm_fops = { 398 .owner = THIS_MODULE, 399 .open = acpi_system_alarm_open_fs, 400 .read = seq_read, 401 .write = acpi_system_write_alarm, 402 .llseek = seq_lseek, 403 .release = single_release, 404 }; 405 406 static u32 rtc_handler(void *context) 407 { 408 acpi_clear_event(ACPI_EVENT_RTC); 409 acpi_disable_event(ACPI_EVENT_RTC, 0); 410 411 return ACPI_INTERRUPT_HANDLED; 412 } 413 #endif /* HAVE_ACPI_LEGACY_ALARM */ 414 415 int __init acpi_sleep_proc_init(void) 416 { 417 #ifdef HAVE_ACPI_LEGACY_ALARM 418 /* 'alarm' [R/W] */ 419 proc_create("alarm", S_IFREG | S_IRUGO | S_IWUSR, 420 acpi_root_dir, &acpi_system_alarm_fops); 421 422 acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); 423 /* 424 * Disable the RTC event after installing RTC handler. 425 * Only when RTC alarm is set will it be enabled. 426 */ 427 acpi_clear_event(ACPI_EVENT_RTC); 428 acpi_disable_event(ACPI_EVENT_RTC, 0); 429 #endif /* HAVE_ACPI_LEGACY_ALARM */ 430 431 /* 'wakeup device' [R/W] */ 432 proc_create("wakeup", S_IFREG | S_IRUGO | S_IWUSR, 433 acpi_root_dir, &acpi_system_wakeup_device_fops); 434 435 return 0; 436 } 437