aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2018-04-16 13:26:46 -0400
committerTony Lindgren <tony@atomide.com>2018-05-01 09:54:17 -0400
commite7420c2d4495cbb9c14dd8bf8b3b4e5bdded6e20 (patch)
tree05673f25226d0e46ad54bf6e2a9116f33c878070
parent09dfe5810762cd6ac09a24342cc23d94d7a8ab70 (diff)
bus: ti-sysc: Tag some modules resource providers for noirq suspend
Modules that provide resources for other modules need to be suspended and resumed in the noirq calls. Tag the resource providing modules. Signed-off-by: Tony Lindgren <tony@atomide.com>
-rw-r--r--drivers/bus/ti-sysc.c77
-rw-r--r--include/linux/platform_data/ti-sysc.h1
2 files changed, 78 insertions, 0 deletions
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
index f27b182384cd..1f90b91dbfae 100644
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -665,6 +665,10 @@ static int sysc_suspend(struct device *dev)
665 665
666 ddata = dev_get_drvdata(dev); 666 ddata = dev_get_drvdata(dev);
667 667
668 if (ddata->cfg.quirks & (SYSC_QUIRK_RESOURCE_PROVIDER |
669 SYSC_QUIRK_LEGACY_IDLE))
670 return 0;
671
668 if (!ddata->enabled) 672 if (!ddata->enabled)
669 return 0; 673 return 0;
670 674
@@ -678,6 +682,58 @@ static int sysc_resume(struct device *dev)
678 struct sysc *ddata; 682 struct sysc *ddata;
679 683
680 ddata = dev_get_drvdata(dev); 684 ddata = dev_get_drvdata(dev);
685
686 if (ddata->cfg.quirks & (SYSC_QUIRK_RESOURCE_PROVIDER |
687 SYSC_QUIRK_LEGACY_IDLE))
688 return 0;
689
690 if (ddata->needs_resume) {
691 dev_dbg(ddata->dev, "%s %s\n", __func__,
692 ddata->name ? ddata->name : "");
693
694 ddata->needs_resume = false;
695
696 return sysc_runtime_resume(dev);
697 }
698
699 return 0;
700}
701
702static int sysc_noirq_suspend(struct device *dev)
703{
704 struct sysc *ddata;
705
706 ddata = dev_get_drvdata(dev);
707
708 if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE)
709 return 0;
710
711 if (!(ddata->cfg.quirks & SYSC_QUIRK_RESOURCE_PROVIDER))
712 return 0;
713
714 if (!ddata->enabled)
715 return 0;
716
717 dev_dbg(ddata->dev, "%s %s\n", __func__,
718 ddata->name ? ddata->name : "");
719
720 ddata->needs_resume = true;
721
722 return sysc_runtime_suspend(dev);
723}
724
725static int sysc_noirq_resume(struct device *dev)
726{
727 struct sysc *ddata;
728
729 ddata = dev_get_drvdata(dev);
730
731 if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE)
732 return 0;
733
734 if (!(ddata->cfg.quirks & SYSC_QUIRK_RESOURCE_PROVIDER))
735 return 0;
736
681 if (ddata->needs_resume) { 737 if (ddata->needs_resume) {
682 ddata->needs_resume = false; 738 ddata->needs_resume = false;
683 739
@@ -690,6 +746,7 @@ static int sysc_resume(struct device *dev)
690 746
691static const struct dev_pm_ops sysc_pm_ops = { 747static const struct dev_pm_ops sysc_pm_ops = {
692 SET_SYSTEM_SLEEP_PM_OPS(sysc_suspend, sysc_resume) 748 SET_SYSTEM_SLEEP_PM_OPS(sysc_suspend, sysc_resume)
749 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sysc_noirq_suspend, sysc_noirq_resume)
693 SET_RUNTIME_PM_OPS(sysc_runtime_suspend, 750 SET_RUNTIME_PM_OPS(sysc_runtime_suspend,
694 sysc_runtime_resume, 751 sysc_runtime_resume,
695 NULL) 752 NULL)
@@ -721,6 +778,26 @@ struct sysc_revision_quirk {
721 } 778 }
722 779
723static const struct sysc_revision_quirk sysc_revision_quirks[] = { 780static const struct sysc_revision_quirk sysc_revision_quirks[] = {
781 /* These need to use noirq_suspend */
782 SYSC_QUIRK("control", 0, 0, 0x10, -1, 0x40000900, 0xffffffff,
783 SYSC_QUIRK_RESOURCE_PROVIDER),
784 SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xffffffff,
785 SYSC_QUIRK_RESOURCE_PROVIDER),
786 SYSC_QUIRK("mcspi", 0, 0, 0x10, -1, 0x40300a0b, 0xffffffff,
787 SYSC_QUIRK_RESOURCE_PROVIDER),
788 SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000100, 0xffffffff,
789 SYSC_QUIRK_RESOURCE_PROVIDER),
790 SYSC_QUIRK("ocp2scp", 0, 0, 0x10, 0x14, 0x50060005, 0xffffffff,
791 SYSC_QUIRK_RESOURCE_PROVIDER),
792 SYSC_QUIRK("padconf", 0, 0, 0x10, -1, 0x4fff0800, 0xffffffff,
793 SYSC_QUIRK_RESOURCE_PROVIDER),
794 SYSC_QUIRK("scm", 0, 0, 0x10, -1, 0x40000900, 0xffffffff,
795 SYSC_QUIRK_RESOURCE_PROVIDER),
796 SYSC_QUIRK("scrm", 0, 0, -1, -1, 0x00000010, 0xffffffff,
797 SYSC_QUIRK_RESOURCE_PROVIDER),
798 SYSC_QUIRK("sdma", 0, 0, 0x2c, 0x28, 0x00010900, 0xffffffff,
799 SYSC_QUIRK_RESOURCE_PROVIDER),
800
724 /* These drivers need to be fixed to not use pm_runtime_irq_safe() */ 801 /* These drivers need to be fixed to not use pm_runtime_irq_safe() */
725 SYSC_QUIRK("gpio", 0, 0, 0x10, 0x114, 0x50600801, 0xffffffff, 802 SYSC_QUIRK("gpio", 0, 0, 0x10, 0x114, 0x50600801, 0xffffffff,
726 SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_OPT_CLKS_IN_RESET), 803 SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_OPT_CLKS_IN_RESET),
diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h
index 80ce28d40832..990aad477458 100644
--- a/include/linux/platform_data/ti-sysc.h
+++ b/include/linux/platform_data/ti-sysc.h
@@ -45,6 +45,7 @@ struct sysc_regbits {
45 s8 emufree_shift; 45 s8 emufree_shift;
46}; 46};
47 47
48#define SYSC_QUIRK_RESOURCE_PROVIDER BIT(9)
48#define SYSC_QUIRK_LEGACY_IDLE BIT(8) 49#define SYSC_QUIRK_LEGACY_IDLE BIT(8)
49#define SYSC_QUIRK_RESET_STATUS BIT(7) 50#define SYSC_QUIRK_RESET_STATUS BIT(7)
50#define SYSC_QUIRK_NO_IDLE_ON_INIT BIT(6) 51#define SYSC_QUIRK_NO_IDLE_ON_INIT BIT(6)