diff options
Diffstat (limited to 'arch/arm/mach-omap2/serial.c')
-rw-r--r-- | arch/arm/mach-omap2/serial.c | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 53cbe0620286..a0a280377a8c 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #define UART_OMAP_WER 0x17 /* Wake-up enable register */ | 33 | #define UART_OMAP_WER 0x17 /* Wake-up enable register */ |
34 | 34 | ||
35 | #define DEFAULT_TIMEOUT (2 * HZ) | 35 | #define DEFAULT_TIMEOUT (5 * HZ) |
36 | 36 | ||
37 | struct omap_uart_state { | 37 | struct omap_uart_state { |
38 | int num; | 38 | int num; |
@@ -235,7 +235,10 @@ static void omap_uart_block_sleep(struct omap_uart_state *uart) | |||
235 | 235 | ||
236 | omap_uart_smart_idle_enable(uart, 0); | 236 | omap_uart_smart_idle_enable(uart, 0); |
237 | uart->can_sleep = 0; | 237 | uart->can_sleep = 0; |
238 | mod_timer(&uart->timer, jiffies + uart->timeout); | 238 | if (uart->timeout) |
239 | mod_timer(&uart->timer, jiffies + uart->timeout); | ||
240 | else | ||
241 | del_timer(&uart->timer); | ||
239 | } | 242 | } |
240 | 243 | ||
241 | static void omap_uart_allow_sleep(struct omap_uart_state *uart) | 244 | static void omap_uart_allow_sleep(struct omap_uart_state *uart) |
@@ -340,6 +343,8 @@ static irqreturn_t omap_uart_interrupt(int irq, void *dev_id) | |||
340 | return IRQ_NONE; | 343 | return IRQ_NONE; |
341 | } | 344 | } |
342 | 345 | ||
346 | static u32 sleep_timeout = DEFAULT_TIMEOUT; | ||
347 | |||
343 | static void omap_uart_idle_init(struct omap_uart_state *uart) | 348 | static void omap_uart_idle_init(struct omap_uart_state *uart) |
344 | { | 349 | { |
345 | u32 v; | 350 | u32 v; |
@@ -347,7 +352,7 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) | |||
347 | int ret; | 352 | int ret; |
348 | 353 | ||
349 | uart->can_sleep = 0; | 354 | uart->can_sleep = 0; |
350 | uart->timeout = DEFAULT_TIMEOUT; | 355 | uart->timeout = sleep_timeout; |
351 | setup_timer(&uart->timer, omap_uart_idle_timer, | 356 | setup_timer(&uart->timer, omap_uart_idle_timer, |
352 | (unsigned long) uart); | 357 | (unsigned long) uart); |
353 | mod_timer(&uart->timer, jiffies + uart->timeout); | 358 | mod_timer(&uart->timer, jiffies + uart->timeout); |
@@ -427,6 +432,39 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) | |||
427 | WARN_ON(ret); | 432 | WARN_ON(ret); |
428 | } | 433 | } |
429 | 434 | ||
435 | static ssize_t sleep_timeout_show(struct kobject *kobj, | ||
436 | struct kobj_attribute *attr, | ||
437 | char *buf) | ||
438 | { | ||
439 | return sprintf(buf, "%u\n", sleep_timeout / HZ); | ||
440 | } | ||
441 | |||
442 | static ssize_t sleep_timeout_store(struct kobject *kobj, | ||
443 | struct kobj_attribute *attr, | ||
444 | const char *buf, size_t n) | ||
445 | { | ||
446 | struct omap_uart_state *uart; | ||
447 | unsigned int value; | ||
448 | |||
449 | if (sscanf(buf, "%u", &value) != 1) { | ||
450 | printk(KERN_ERR "sleep_timeout_store: Invalid value\n"); | ||
451 | return -EINVAL; | ||
452 | } | ||
453 | sleep_timeout = value * HZ; | ||
454 | list_for_each_entry(uart, &uart_list, node) { | ||
455 | uart->timeout = sleep_timeout; | ||
456 | if (uart->timeout) | ||
457 | mod_timer(&uart->timer, jiffies + uart->timeout); | ||
458 | else | ||
459 | /* A zero value means disable timeout feature */ | ||
460 | omap_uart_block_sleep(uart); | ||
461 | } | ||
462 | return n; | ||
463 | } | ||
464 | |||
465 | static struct kobj_attribute sleep_timeout_attr = | ||
466 | __ATTR(sleep_timeout, 0644, sleep_timeout_show, sleep_timeout_store); | ||
467 | |||
430 | #else | 468 | #else |
431 | static inline void omap_uart_idle_init(struct omap_uart_state *uart) {} | 469 | static inline void omap_uart_idle_init(struct omap_uart_state *uart) {} |
432 | #endif /* CONFIG_PM */ | 470 | #endif /* CONFIG_PM */ |
@@ -496,6 +534,15 @@ static struct platform_device serial_device = { | |||
496 | 534 | ||
497 | static int __init omap_init(void) | 535 | static int __init omap_init(void) |
498 | { | 536 | { |
499 | return platform_device_register(&serial_device); | 537 | int ret; |
538 | |||
539 | ret = platform_device_register(&serial_device); | ||
540 | |||
541 | #ifdef CONFIG_PM | ||
542 | if (!ret) | ||
543 | ret = sysfs_create_file(&serial_device.dev.kobj, | ||
544 | &sleep_timeout_attr.attr); | ||
545 | #endif | ||
546 | return ret; | ||
500 | } | 547 | } |
501 | arch_initcall(omap_init); | 548 | arch_initcall(omap_init); |