aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/serial.c55
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
37struct omap_uart_state { 37struct 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
241static void omap_uart_allow_sleep(struct omap_uart_state *uart) 244static 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
346static u32 sleep_timeout = DEFAULT_TIMEOUT;
347
343static void omap_uart_idle_init(struct omap_uart_state *uart) 348static 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
435static 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
442static 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
465static struct kobj_attribute sleep_timeout_attr =
466 __ATTR(sleep_timeout, 0644, sleep_timeout_show, sleep_timeout_store);
467
430#else 468#else
431static inline void omap_uart_idle_init(struct omap_uart_state *uart) {} 469static 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
497static int __init omap_init(void) 535static 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}
501arch_initcall(omap_init); 548arch_initcall(omap_init);