aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuman Anna2018-03-01 21:06:44 -0600
committerSuman Anna2019-03-04 10:17:26 -0600
commit7405d551db8e9153e1467839d40a901b744109a4 (patch)
treed77eed368528ea05c51fe3e47baa9f4d784afdd7
parent7c282f0c9667adba595780eb9f154f4a65d48346 (diff)
downloadremoteproc-7405d551db8e9153e1467839d40a901b744109a4.tar.gz
remoteproc-7405d551db8e9153e1467839d40a901b744109a4.tar.xz
remoteproc-7405d551db8e9153e1467839d40a901b744109a4.zip
remoteproc/omap: add support for runtime auto-suspend/resume
This patch enhances the PM support in the OMAP remoteproc driver to support the runtime auto-suspend. A remoteproc may not be required to be running all the time, and typically will need to be active only during certain usecases. As such, to save power, it should be turned off during potential long periods of inactivity between usecases. This suspend and resume of the device is a relatively heavy process in terms of latencies, so a remoteproc should be suspended only after a certain period of prolonged inactivity. The OMAP remoteproc driver leverages the runtime pm framework's auto_suspend feature to accomplish this functionality. This feature is automatically enabled when a remote processor has successfully booted. The 'autosuspend_delay_ms' for each device dictates the inactivity period/time to wait for before suspending the device. The runtime auto-suspend design relies on marking the last busy time on every communication (virtqueue kick) to and from the remote processor. When there has been no activity for 'autosuspend_delay_ms' time, the runtime PM framework invokes the driver's runtime pm suspend callback to suspend the device. The remote processor will be woken up on the initiation of the next communication message through the runtime pm resume callback. The current auto-suspend design also allows a remote processor to deny a auto-suspend attempt, if it wishes to, by sending a NACK response to the initial suspend request message sent to the remote processor as part of the suspend process. The auto-suspend request is also only attempted if the remote processor is idled and in standby at the time of inactivity timer expiry. This choice is made to avoid unnecessary messaging, and the auto-suspend is simply rescheduled to be attempted again after a further lapse of autosuspend_delay_ms. The runtime pm callbacks functionality in this patch reuses most of the core logic from the suspend/resume support code, and make use of an additional auto_suspend flag to differentiate the logic in common code from system suspend. The system suspend/resume sequences are also updated to reflect the proper pm_runtime statuses, and also to really perform a suspend/resume only if the remoteproc has not been auto-suspended at the time of request. The remote processor is left in suspended state on a system resume if it has been auto-suspended before, and will be woken up only when a usecase needs to run. The other significant change in this patch is to reset the remoteproc device's pm_domain so as to avoid conflicts with the ordering sequences in the device pm_domain's runtime callbacks and the reset management and clock management implemented within the runtime callbacks in the driver. The OMAP remoteproc driver currently uses a default value of 10 seconds for all OMAP remoteprocs, and a different value can be chosen either by choosing a positive value for the 'autosuspend_delay' in the device's omap_rproc_fw_data in the driver match data or by updating the 'autosuspend_delay_ms' field at runtime through the sysfs interface. Eg: To use 25 seconds for IPU2 on DRA7xx, echo 25000 > /sys/bus/platform/devices/55020000.ipu/power/autosuspend_delay_ms The runtime suspend feature can also be similarly enabled or disabled by writing 'auto' or 'on' to the device's 'control' power field. The default is enabled. Eg: To disable auto-suspend for IPU2 on DRA7xx SoC, echo on > /sys/bus/platform/devices/55020000.ipu/power/control Signed-off-by: Suman Anna <s-anna@ti.com>
-rw-r--r--drivers/remoteproc/omap_remoteproc.c247
1 files changed, 238 insertions, 9 deletions
diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c
index 0d35efb96cc1..2016de9e650d 100644
--- a/drivers/remoteproc/omap_remoteproc.c
+++ b/drivers/remoteproc/omap_remoteproc.c
@@ -21,6 +21,7 @@
21#include <linux/of_address.h> 21#include <linux/of_address.h>
22#include <linux/of_reserved_mem.h> 22#include <linux/of_reserved_mem.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/pm_runtime.h>
24#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
25#include <linux/remoteproc.h> 26#include <linux/remoteproc.h>
26#include <linux/mailbox_client.h> 27#include <linux/mailbox_client.h>
@@ -39,6 +40,9 @@
39#define OMAP_RPROC_DSP_LOCAL_MEM_OFFSET (0x00800000) 40#define OMAP_RPROC_DSP_LOCAL_MEM_OFFSET (0x00800000)
40#define OMAP_RPROC_IPU_L2RAM_DEV_ADDR (0x20000000) 41#define OMAP_RPROC_IPU_L2RAM_DEV_ADDR (0x20000000)
41 42
43/* default auto-suspend delay (ms) */
44#define DEFAULT_AUTOSUSPEND_DELAY 10000
45
42/** 46/**
43 * struct omap_rproc_boot_data - boot data structure for the DSP omap rprocs 47 * struct omap_rproc_boot_data - boot data structure for the DSP omap rprocs
44 * @syscon: regmap handle for the system control configuration module 48 * @syscon: regmap handle for the system control configuration module
@@ -85,6 +89,8 @@ struct omap_rproc_timer {
85 * @num_mems: number of internal memory regions 89 * @num_mems: number of internal memory regions
86 * @num_timers: number of rproc timer(s) 90 * @num_timers: number of rproc timer(s)
87 * @timers: timer(s) info used by rproc 91 * @timers: timer(s) info used by rproc
92 * @autosuspend_delay: auto-suspend delay value to be used for runtime pm
93 * @need_resume: if true a resume is needed in the system resume callback
88 * @rproc: rproc handle 94 * @rproc: rproc handle
89 * @pm_comp: completion primitive to sync for suspend response 95 * @pm_comp: completion primitive to sync for suspend response
90 * @standby_addr: kernel address of the register having module standby status 96 * @standby_addr: kernel address of the register having module standby status
@@ -98,6 +104,8 @@ struct omap_rproc {
98 int num_mems; 104 int num_mems;
99 int num_timers; 105 int num_timers;
100 struct omap_rproc_timer *timers; 106 struct omap_rproc_timer *timers;
107 int autosuspend_delay;
108 bool need_resume;
101 struct rproc *rproc; 109 struct rproc *rproc;
102 struct completion pm_comp; 110 struct completion pm_comp;
103 void __iomem *standby_addr; 111 void __iomem *standby_addr;
@@ -108,10 +116,12 @@ struct omap_rproc {
108 * struct omap_rproc_dev_data - device data for the omap remote processor 116 * struct omap_rproc_dev_data - device data for the omap remote processor
109 * @device_name: device name of the remote processor 117 * @device_name: device name of the remote processor
110 * @fw_name: firmware name to use 118 * @fw_name: firmware name to use
119 * @autosuspend_delay: custom auto-suspend delay value in milliseconds
111 */ 120 */
112struct omap_rproc_dev_data { 121struct omap_rproc_dev_data {
113 const char *device_name; 122 const char *device_name;
114 const char *fw_name; 123 const char *fw_name;
124 int autosuspend_delay;
115}; 125};
116 126
117/** 127/**
@@ -377,11 +387,23 @@ static void omap_rproc_kick(struct rproc *rproc, int vqid)
377 struct device *dev = rproc->dev.parent; 387 struct device *dev = rproc->dev.parent;
378 int ret; 388 int ret;
379 389
390 /* wake up the rproc before kicking it */
391 ret = pm_runtime_get_sync(dev);
392 if (WARN_ON(ret < 0)) {
393 dev_err(dev, "pm_runtime_get_sync() failed during kick, ret = %d\n",
394 ret);
395 pm_runtime_put_noidle(dev);
396 return;
397 }
398
380 /* send the index of the triggered virtqueue in the mailbox payload */ 399 /* send the index of the triggered virtqueue in the mailbox payload */
381 ret = mbox_send_message(oproc->mbox, (void *)vqid); 400 ret = mbox_send_message(oproc->mbox, (void *)vqid);
382 if (ret < 0) 401 if (ret < 0)
383 dev_err(dev, "failed to send mailbox message, status = %d\n", 402 dev_err(dev, "failed to send mailbox message, status = %d\n",
384 ret); 403 ret);
404
405 pm_runtime_mark_last_busy(dev);
406 pm_runtime_put_autosuspend(dev);
385} 407}
386 408
387/** 409/**
@@ -474,6 +496,19 @@ static int omap_rproc_start(struct rproc *rproc)
474 goto reset_timers; 496 goto reset_timers;
475 } 497 }
476 498
499 /*
500 * remote processor is up, so update the runtime pm status and
501 * enable the auto-suspend. The device usage count is incremented
502 * manually for balancing it for auto-suspend
503 */
504 pm_runtime_set_active(dev);
505 pm_runtime_set_autosuspend_delay(dev, oproc->autosuspend_delay);
506 pm_runtime_use_autosuspend(dev);
507 pm_runtime_get_noresume(dev);
508 pm_runtime_enable(dev);
509 pm_runtime_mark_last_busy(dev);
510 pm_runtime_put_autosuspend(dev);
511
477 return 0; 512 return 0;
478 513
479reset_timers: 514reset_timers:
@@ -492,17 +527,49 @@ static int omap_rproc_stop(struct rproc *rproc)
492 struct omap_rproc *oproc = rproc->priv; 527 struct omap_rproc *oproc = rproc->priv;
493 int ret; 528 int ret;
494 529
530 /*
531 * cancel any possible scheduled runtime suspend by incrementing
532 * the device usage count, and resuming the device. The remoteproc
533 * also needs to be woken up if suspended, to avoid the remoteproc
534 * OS to continue to remember any context that it has saved, and
535 * avoid potential issues in misindentifying a subsequent device
536 * reboot as a power restore boot
537 */
538 ret = pm_runtime_get_sync(dev);
539 if (ret < 0) {
540 pm_runtime_put_noidle(dev);
541 return ret;
542 }
543
495 ret = pdata->device_shutdown(pdev); 544 ret = pdata->device_shutdown(pdev);
496 if (ret) 545 if (ret)
497 return ret; 546 goto out;
498 547
499 ret = omap_rproc_disable_timers(rproc, true); 548 ret = omap_rproc_disable_timers(rproc, true);
500 if (ret) 549 if (ret)
501 return ret; 550 goto enable_device;
502 551
503 mbox_free_channel(oproc->mbox); 552 mbox_free_channel(oproc->mbox);
504 553
554 /*
555 * update the runtime pm states and status now that the remoteproc
556 * has stopped
557 */
558 pm_runtime_disable(dev);
559 pm_runtime_dont_use_autosuspend(dev);
560 pm_runtime_put_noidle(dev);
561 pm_runtime_set_suspended(dev);
562
505 return 0; 563 return 0;
564
565enable_device:
566 pdata->device_enable(pdev);
567out:
568 /* schedule the next auto-suspend */
569 pm_runtime_mark_last_busy(dev);
570 pm_runtime_put_autosuspend(dev);
571 return ret;
572
506} 573}
507 574
508/* 575/*
@@ -557,7 +624,7 @@ static bool _is_rproc_in_standby(struct omap_rproc *oproc)
557 624
558/* 1 sec is long enough time to let the remoteproc side suspend the device */ 625/* 1 sec is long enough time to let the remoteproc side suspend the device */
559#define DEF_SUSPEND_TIMEOUT 1000 626#define DEF_SUSPEND_TIMEOUT 1000
560static int _omap_rproc_suspend(struct rproc *rproc) 627static int _omap_rproc_suspend(struct rproc *rproc, bool auto_suspend)
561{ 628{
562 struct device *dev = rproc->dev.parent; 629 struct device *dev = rproc->dev.parent;
563 struct platform_device *pdev = to_platform_device(dev); 630 struct platform_device *pdev = to_platform_device(dev);
@@ -565,11 +632,13 @@ static int _omap_rproc_suspend(struct rproc *rproc)
565 struct omap_rproc *oproc = rproc->priv; 632 struct omap_rproc *oproc = rproc->priv;
566 unsigned long to = msecs_to_jiffies(DEF_SUSPEND_TIMEOUT); 633 unsigned long to = msecs_to_jiffies(DEF_SUSPEND_TIMEOUT);
567 unsigned long ta = jiffies + to; 634 unsigned long ta = jiffies + to;
635 u32 suspend_msg = auto_suspend ?
636 RP_MBOX_SUSPEND_AUTO : RP_MBOX_SUSPEND_SYSTEM;
568 int ret; 637 int ret;
569 638
570 reinit_completion(&oproc->pm_comp); 639 reinit_completion(&oproc->pm_comp);
571 oproc->suspend_acked = false; 640 oproc->suspend_acked = false;
572 ret = mbox_send_message(oproc->mbox, (void *)RP_MBOX_SUSPEND_SYSTEM); 641 ret = mbox_send_message(oproc->mbox, (void *)suspend_msg);
573 if (ret < 0) { 642 if (ret < 0) {
574 dev_err(dev, "PM mbox_send_message failed: %d\n", ret); 643 dev_err(dev, "PM mbox_send_message failed: %d\n", ret);
575 return ret; 644 return ret;
@@ -611,14 +680,31 @@ static int _omap_rproc_suspend(struct rproc *rproc)
611 goto enable_device; 680 goto enable_device;
612 } 681 }
613 682
683 /*
684 * IOMMUs would have to be disabled specifically for runtime suspend.
685 * They are handled automatically through System PM callbacks for
686 * regular system suspend
687 */
688 if (auto_suspend) {
689 ret = omap_iommu_domain_deactivate(rproc->domain);
690 if (ret) {
691 dev_err(dev, "iommu domain deactivate failed %d\n",
692 ret);
693 goto enable_timers;
694 }
695 }
696
614 return 0; 697 return 0;
615 698
699enable_timers:
700 /* ignore errors on re-enabling code */
701 omap_rproc_enable_timers(rproc, false);
616enable_device: 702enable_device:
617 pdata->device_enable(pdev); 703 pdata->device_enable(pdev);
618 return ret; 704 return ret;
619} 705}
620 706
621static int _omap_rproc_resume(struct rproc *rproc) 707static int _omap_rproc_resume(struct rproc *rproc, bool auto_suspend)
622{ 708{
623 struct device *dev = rproc->dev.parent; 709 struct device *dev = rproc->dev.parent;
624 struct platform_device *pdev = to_platform_device(dev); 710 struct platform_device *pdev = to_platform_device(dev);
@@ -626,12 +712,25 @@ static int _omap_rproc_resume(struct rproc *rproc)
626 struct omap_rproc *oproc = rproc->priv; 712 struct omap_rproc *oproc = rproc->priv;
627 int ret; 713 int ret;
628 714
715 /*
716 * IOMMUs would have to be enabled specifically for runtime resume.
717 * They would have been already enabled automatically through System
718 * PM callbacks for regular system resume
719 */
720 if (auto_suspend) {
721 ret = omap_iommu_domain_activate(rproc->domain);
722 if (ret) {
723 dev_err(dev, "omap_iommu activate failed %d\n", ret);
724 goto out;
725 }
726 }
727
629 /* boot address could be lost after suspend, so restore it */ 728 /* boot address could be lost after suspend, so restore it */
630 if (oproc->boot_data) { 729 if (oproc->boot_data) {
631 ret = omap_rproc_write_dsp_boot_addr(rproc); 730 ret = omap_rproc_write_dsp_boot_addr(rproc);
632 if (ret) { 731 if (ret) {
633 dev_err(dev, "boot address restore failed %d\n", ret); 732 dev_err(dev, "boot address restore failed %d\n", ret);
634 goto out; 733 goto suspend_iommu;
635 } 734 }
636 } 735 }
637 736
@@ -639,7 +738,7 @@ static int _omap_rproc_resume(struct rproc *rproc)
639 if (ret) { 738 if (ret) {
640 dev_err(dev, "enabling timers during resume failed %d\n", 739 dev_err(dev, "enabling timers during resume failed %d\n",
641 ret); 740 ret);
642 goto out; 741 goto suspend_iommu;
643 } 742 }
644 743
645 ret = pdata->device_enable(pdev); 744 ret = pdata->device_enable(pdev);
@@ -650,6 +749,9 @@ static int _omap_rproc_resume(struct rproc *rproc)
650 749
651disable_timers: 750disable_timers:
652 omap_rproc_disable_timers(rproc, false); 751 omap_rproc_disable_timers(rproc, false);
752suspend_iommu:
753 if (auto_suspend)
754 omap_iommu_domain_deactivate(rproc->domain);
653out: 755out:
654 return ret; 756 return ret;
655} 757}
@@ -658,6 +760,7 @@ static int __maybe_unused omap_rproc_suspend(struct device *dev)
658{ 760{
659 struct platform_device *pdev = to_platform_device(dev); 761 struct platform_device *pdev = to_platform_device(dev);
660 struct rproc *rproc = platform_get_drvdata(pdev); 762 struct rproc *rproc = platform_get_drvdata(pdev);
763 struct omap_rproc *oproc = rproc->priv;
661 int ret = 0; 764 int ret = 0;
662 765
663 mutex_lock(&rproc->lock); 766 mutex_lock(&rproc->lock);
@@ -672,13 +775,25 @@ static int __maybe_unused omap_rproc_suspend(struct device *dev)
672 goto out; 775 goto out;
673 } 776 }
674 777
675 ret = _omap_rproc_suspend(rproc); 778 ret = _omap_rproc_suspend(rproc, false);
676 if (ret) { 779 if (ret) {
677 dev_err(dev, "suspend failed %d\n", ret); 780 dev_err(dev, "suspend failed %d\n", ret);
678 goto out; 781 goto out;
679 } 782 }
680 783
784 /*
785 * remoteproc is running at the time of system suspend, so remember
786 * it so as to wake it up during system resume
787 */
788 oproc->need_resume = 1;
681 rproc->state = RPROC_SUSPENDED; 789 rproc->state = RPROC_SUSPENDED;
790
791 /*
792 * update the runtime pm status to be suspended, without decrementing
793 * the device usage count
794 */
795 pm_runtime_disable(dev);
796 pm_runtime_set_suspended(dev);
682out: 797out:
683 mutex_unlock(&rproc->lock); 798 mutex_unlock(&rproc->lock);
684 return ret; 799 return ret;
@@ -688,6 +803,7 @@ static int __maybe_unused omap_rproc_resume(struct device *dev)
688{ 803{
689 struct platform_device *pdev = to_platform_device(dev); 804 struct platform_device *pdev = to_platform_device(dev);
690 struct rproc *rproc = platform_get_drvdata(pdev); 805 struct rproc *rproc = platform_get_drvdata(pdev);
806 struct omap_rproc *oproc = rproc->priv;
691 int ret = 0; 807 int ret = 0;
692 808
693 mutex_lock(&rproc->lock); 809 mutex_lock(&rproc->lock);
@@ -699,17 +815,86 @@ static int __maybe_unused omap_rproc_resume(struct device *dev)
699 goto out; 815 goto out;
700 } 816 }
701 817
702 ret = _omap_rproc_resume(rproc); 818 /*
819 * remoteproc was auto-suspended at the time of system suspend,
820 * so no need to wake-up the processor (leave it in suspended
821 * state, will be woken up during a subsequent runtime_resume)
822 */
823 if (!oproc->need_resume)
824 goto out;
825
826 ret = _omap_rproc_resume(rproc, false);
703 if (ret) { 827 if (ret) {
704 dev_err(dev, "resume failed %d\n", ret); 828 dev_err(dev, "resume failed %d\n", ret);
705 goto out; 829 goto out;
706 } 830 }
831 oproc->need_resume = false;
707 832
708 rproc->state = RPROC_RUNNING; 833 rproc->state = RPROC_RUNNING;
834
835 /*
836 * update the runtime pm status to be active, without incrementing
837 * the device usage count
838 */
839 pm_runtime_set_active(dev);
840 pm_runtime_enable(dev);
841 pm_runtime_mark_last_busy(dev);
709out: 842out:
710 mutex_unlock(&rproc->lock); 843 mutex_unlock(&rproc->lock);
711 return ret; 844 return ret;
712} 845}
846
847static int omap_rproc_runtime_suspend(struct device *dev)
848{
849 struct rproc *rproc = dev_get_drvdata(dev);
850 struct omap_rproc *oproc = rproc->priv;
851 int ret;
852
853 if (WARN_ON(rproc->state != RPROC_RUNNING)) {
854 dev_err(dev, "rproc cannot be runtime suspended when not running!\n");
855 return -EBUSY;
856 }
857
858 /*
859 * do not even attempt suspend if the remote processor is not
860 * idled for runtime auto-suspend
861 */
862 if (!_is_rproc_in_standby(oproc)) {
863 ret = -EBUSY;
864 goto abort;
865 }
866
867 ret = _omap_rproc_suspend(rproc, true);
868 if (ret)
869 goto abort;
870
871 rproc->state = RPROC_SUSPENDED;
872 return 0;
873
874abort:
875 pm_runtime_mark_last_busy(dev);
876 return ret;
877}
878
879static int omap_rproc_runtime_resume(struct device *dev)
880{
881 struct rproc *rproc = dev_get_drvdata(dev);
882 int ret;
883
884 if (WARN_ON(rproc->state != RPROC_SUSPENDED)) {
885 dev_err(dev, "rproc cannot be runtime resumed if not suspended!\n");
886 return -EBUSY;
887 }
888
889 ret = _omap_rproc_resume(rproc, true);
890 if (ret) {
891 dev_err(dev, "runtime resume failed %d\n", ret);
892 return ret;
893 }
894
895 rproc->state = RPROC_RUNNING;
896 return 0;
897}
713#endif /* CONFIG_PM */ 898#endif /* CONFIG_PM */
714 899
715static const struct omap_rproc_dev_data omap4_dsp_dev_data = { 900static const struct omap_rproc_dev_data omap4_dsp_dev_data = {
@@ -785,6 +970,33 @@ static const struct of_device_id omap_rproc_of_match[] = {
785}; 970};
786MODULE_DEVICE_TABLE(of, omap_rproc_of_match); 971MODULE_DEVICE_TABLE(of, omap_rproc_of_match);
787 972
973static int omap_rproc_get_autosuspend_delay(struct platform_device *pdev)
974{
975 struct device_node *np = pdev->dev.of_node;
976 const struct omap_rproc_dev_data *data;
977 int delay = -EINVAL;
978
979 data = of_device_get_match_data(&pdev->dev);
980 if (!data)
981 return -ENODEV;
982
983 if (!of_device_is_compatible(np, "ti,dra7-dsp") &&
984 !of_device_is_compatible(np, "ti,dra7-ipu")) {
985 delay = data->autosuspend_delay;
986 goto out;
987 }
988
989 for (; data && data->device_name; data++) {
990 if (!strcmp(dev_name(&pdev->dev), data->device_name)) {
991 delay = data->autosuspend_delay;
992 break;
993 }
994 }
995
996out:
997 return (delay > 0) ? delay : DEFAULT_AUTOSUSPEND_DELAY;
998}
999
788static const char *omap_rproc_get_firmware(struct platform_device *pdev) 1000static const char *omap_rproc_get_firmware(struct platform_device *pdev)
789{ 1001{
790 struct device_node *np = pdev->dev.of_node; 1002 struct device_node *np = pdev->dev.of_node;
@@ -940,6 +1152,16 @@ static int omap_rproc_probe(struct platform_device *pdev)
940 return -ENODEV; 1152 return -ENODEV;
941 } 1153 }
942 1154
1155 /*
1156 * self-manage the ordering dependencies between omap_device_enable/idle
1157 * and omap_device_assert/deassert_hardreset API during runtime suspend
1158 * and resume, rather than relying on the order in omap_device layer.
1159 */
1160 if (pdev->dev.pm_domain) {
1161 dev_dbg(&pdev->dev, "device pm_domain is being reset for this remoteproc device\n");
1162 pdev->dev.pm_domain = NULL;
1163 }
1164
943 if (!pdata || !pdata->device_enable || !pdata->device_shutdown) { 1165 if (!pdata || !pdata->device_enable || !pdata->device_shutdown) {
944 dev_err(&pdev->dev, "platform data is either missing or incomplete\n"); 1166 dev_err(&pdev->dev, "platform data is either missing or incomplete\n");
945 return -ENODEV; 1167 return -ENODEV;
@@ -998,6 +1220,11 @@ static int omap_rproc_probe(struct platform_device *pdev)
998 } 1220 }
999 1221
1000 init_completion(&oproc->pm_comp); 1222 init_completion(&oproc->pm_comp);
1223 oproc->autosuspend_delay = omap_rproc_get_autosuspend_delay(pdev);
1224 if (oproc->autosuspend_delay < 0) {
1225 ret = oproc->autosuspend_delay;
1226 goto free_rproc;
1227 }
1001 1228
1002 ret = of_property_read_u32(np, "ti,rproc-standby-info", &standby_addr); 1229 ret = of_property_read_u32(np, "ti,rproc-standby-info", &standby_addr);
1003 if (ret || !standby_addr) { 1230 if (ret || !standby_addr) {
@@ -1049,6 +1276,8 @@ static int omap_rproc_remove(struct platform_device *pdev)
1049 1276
1050static const struct dev_pm_ops omap_rproc_pm_ops = { 1277static const struct dev_pm_ops omap_rproc_pm_ops = {
1051 SET_SYSTEM_SLEEP_PM_OPS(omap_rproc_suspend, omap_rproc_resume) 1278 SET_SYSTEM_SLEEP_PM_OPS(omap_rproc_suspend, omap_rproc_resume)
1279 SET_RUNTIME_PM_OPS(omap_rproc_runtime_suspend,
1280 omap_rproc_runtime_resume, NULL)
1052}; 1281};
1053 1282
1054static struct platform_driver omap_rproc_driver = { 1283static struct platform_driver omap_rproc_driver = {