aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/gpio.c2
-rw-r--r--arch/arm/mach-omap2/serial.c1
-rw-r--r--arch/arm/plat-omap/include/plat/omap_device.h9
-rw-r--r--arch/arm/plat-omap/omap_device.c49
4 files changed, 58 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 9529842ae054..48e5eced6b51 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -87,6 +87,8 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
87 return PTR_ERR(od); 87 return PTR_ERR(od);
88 } 88 }
89 89
90 omap_device_disable_idle_on_suspend(od);
91
90 gpio_bank_count++; 92 gpio_bank_count++;
91 return 0; 93 return 0;
92} 94}
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 1ac361b7b8cb..466fc722fa0f 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -805,6 +805,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
805 WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n", 805 WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n",
806 name, oh->name); 806 name, oh->name);
807 807
808 omap_device_disable_idle_on_suspend(od);
808 oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); 809 oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
809 810
810 uart->irq = oh->mpu_irqs[0].irq; 811 uart->irq = oh->mpu_irqs[0].irq;
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index e4c349ff9fd8..ee405b36df4b 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -44,6 +44,10 @@ extern struct device omap_device_parent;
44#define OMAP_DEVICE_STATE_IDLE 2 44#define OMAP_DEVICE_STATE_IDLE 2
45#define OMAP_DEVICE_STATE_SHUTDOWN 3 45#define OMAP_DEVICE_STATE_SHUTDOWN 3
46 46
47/* omap_device.flags values */
48#define OMAP_DEVICE_SUSPENDED BIT(0)
49#define OMAP_DEVICE_NO_IDLE_ON_SUSPEND BIT(1)
50
47/** 51/**
48 * struct omap_device - omap_device wrapper for platform_devices 52 * struct omap_device - omap_device wrapper for platform_devices
49 * @pdev: platform_device 53 * @pdev: platform_device
@@ -73,6 +77,7 @@ struct omap_device {
73 s8 pm_lat_level; 77 s8 pm_lat_level;
74 u8 hwmods_cnt; 78 u8 hwmods_cnt;
75 u8 _state; 79 u8 _state;
80 u8 flags;
76}; 81};
77 82
78/* Device driver interface (call via platform_data fn ptrs) */ 83/* Device driver interface (call via platform_data fn ptrs) */
@@ -117,6 +122,10 @@ int omap_device_enable_hwmods(struct omap_device *od);
117int omap_device_disable_clocks(struct omap_device *od); 122int omap_device_disable_clocks(struct omap_device *od);
118int omap_device_enable_clocks(struct omap_device *od); 123int omap_device_enable_clocks(struct omap_device *od);
119 124
125static inline void omap_device_disable_idle_on_suspend(struct omap_device *od)
126{
127 od->flags |= OMAP_DEVICE_NO_IDLE_ON_SUSPEND;
128}
120 129
121/* 130/*
122 * Entries should be kept in latency order ascending 131 * Entries should be kept in latency order ascending
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index d21579b2c11e..2526fa312b8a 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -537,6 +537,7 @@ int omap_early_device_register(struct omap_device *od)
537 return 0; 537 return 0;
538} 538}
539 539
540#ifdef CONFIG_PM_RUNTIME
540static int _od_runtime_suspend(struct device *dev) 541static int _od_runtime_suspend(struct device *dev)
541{ 542{
542 struct platform_device *pdev = to_platform_device(dev); 543 struct platform_device *pdev = to_platform_device(dev);
@@ -563,13 +564,55 @@ static int _od_runtime_resume(struct device *dev)
563 564
564 return pm_generic_runtime_resume(dev); 565 return pm_generic_runtime_resume(dev);
565} 566}
567#endif
568
569#ifdef CONFIG_SUSPEND
570static int _od_suspend_noirq(struct device *dev)
571{
572 struct platform_device *pdev = to_platform_device(dev);
573 struct omap_device *od = to_omap_device(pdev);
574 int ret;
575
576 if (od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND)
577 return pm_generic_suspend_noirq(dev);
578
579 ret = pm_generic_suspend_noirq(dev);
580
581 if (!ret && !pm_runtime_status_suspended(dev)) {
582 if (pm_generic_runtime_suspend(dev) == 0) {
583 omap_device_idle(pdev);
584 od->flags |= OMAP_DEVICE_SUSPENDED;
585 }
586 }
587
588 return ret;
589}
590
591static int _od_resume_noirq(struct device *dev)
592{
593 struct platform_device *pdev = to_platform_device(dev);
594 struct omap_device *od = to_omap_device(pdev);
595
596 if (od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND)
597 return pm_generic_resume_noirq(dev);
598
599 if ((od->flags & OMAP_DEVICE_SUSPENDED) &&
600 !pm_runtime_status_suspended(dev)) {
601 od->flags &= ~OMAP_DEVICE_SUSPENDED;
602 omap_device_enable(pdev);
603 pm_generic_runtime_resume(dev);
604 }
605
606 return pm_generic_resume_noirq(dev);
607}
608#endif
566 609
567static struct dev_pm_domain omap_device_pm_domain = { 610static struct dev_pm_domain omap_device_pm_domain = {
568 .ops = { 611 .ops = {
569 .runtime_suspend = _od_runtime_suspend, 612 SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume,
570 .runtime_idle = _od_runtime_idle, 613 _od_runtime_idle)
571 .runtime_resume = _od_runtime_resume,
572 USE_PLATFORM_PM_SLEEP_OPS 614 USE_PLATFORM_PM_SLEEP_OPS
615 SET_SYSTEM_SLEEP_PM_OPS(_od_suspend_noirq, _od_resume_noirq)
573 } 616 }
574}; 617};
575 618