20
20
21
21
#include <linux/clk.h>
22
22
#include <linux/clk-provider.h>
23
+ #include <linux/cpu_pm.h>
23
24
#include <linux/module.h>
24
25
#include <linux/io.h>
25
26
#include <linux/device.h>
@@ -92,6 +93,47 @@ static void omap_timer_restore_context(struct omap_dm_timer *timer)
92
93
timer -> context .tclr );
93
94
}
94
95
96
+ static void omap_timer_save_context (struct omap_dm_timer * timer )
97
+ {
98
+ timer -> context .tclr =
99
+ omap_dm_timer_read_reg (timer , OMAP_TIMER_CTRL_REG );
100
+ timer -> context .twer =
101
+ omap_dm_timer_read_reg (timer , OMAP_TIMER_WAKEUP_EN_REG );
102
+ timer -> context .tldr =
103
+ omap_dm_timer_read_reg (timer , OMAP_TIMER_LOAD_REG );
104
+ timer -> context .tmar =
105
+ omap_dm_timer_read_reg (timer , OMAP_TIMER_MATCH_REG );
106
+ timer -> context .tier = readl_relaxed (timer -> irq_ena );
107
+ timer -> context .tsicr =
108
+ omap_dm_timer_read_reg (timer , OMAP_TIMER_IF_CTRL_REG );
109
+ }
110
+
111
+ static int omap_timer_context_notifier (struct notifier_block * nb ,
112
+ unsigned long cmd , void * v )
113
+ {
114
+ struct omap_dm_timer * timer ;
115
+
116
+ timer = container_of (nb , struct omap_dm_timer , nb );
117
+
118
+ switch (cmd ) {
119
+ case CPU_CLUSTER_PM_ENTER :
120
+ if ((timer -> capability & OMAP_TIMER_ALWON ) ||
121
+ !atomic_read (& timer -> enabled ))
122
+ break ;
123
+ omap_timer_save_context (timer );
124
+ break ;
125
+ case CPU_CLUSTER_PM_ENTER_FAILED :
126
+ case CPU_CLUSTER_PM_EXIT :
127
+ if ((timer -> capability & OMAP_TIMER_ALWON ) ||
128
+ !atomic_read (& timer -> enabled ))
129
+ break ;
130
+ omap_timer_restore_context (timer );
131
+ break ;
132
+ }
133
+
134
+ return NOTIFY_OK ;
135
+ }
136
+
95
137
static int omap_dm_timer_reset (struct omap_dm_timer * timer )
96
138
{
97
139
u32 l , timeout = 100000 ;
@@ -208,21 +250,7 @@ static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
208
250
209
251
static void omap_dm_timer_enable (struct omap_dm_timer * timer )
210
252
{
211
- int c ;
212
-
213
253
pm_runtime_get_sync (& timer -> pdev -> dev );
214
-
215
- if (!(timer -> capability & OMAP_TIMER_ALWON )) {
216
- if (timer -> get_context_loss_count ) {
217
- c = timer -> get_context_loss_count (& timer -> pdev -> dev );
218
- if (c != timer -> ctx_loss_count ) {
219
- omap_timer_restore_context (timer );
220
- timer -> ctx_loss_count = c ;
221
- }
222
- } else {
223
- omap_timer_restore_context (timer );
224
- }
225
- }
226
254
}
227
255
228
256
static void omap_dm_timer_disable (struct omap_dm_timer * timer )
@@ -515,8 +543,6 @@ static int omap_dm_timer_start(struct omap_dm_timer *timer)
515
543
omap_dm_timer_write_reg (timer , OMAP_TIMER_CTRL_REG , l );
516
544
}
517
545
518
- /* Save the context */
519
- timer -> context .tclr = l ;
520
546
return 0 ;
521
547
}
522
548
@@ -532,13 +558,6 @@ static int omap_dm_timer_stop(struct omap_dm_timer *timer)
532
558
533
559
__omap_dm_timer_stop (timer , timer -> posted , rate );
534
560
535
- /*
536
- * Since the register values are computed and written within
537
- * __omap_dm_timer_stop, we need to use read to retrieve the
538
- * context.
539
- */
540
- timer -> context .tclr =
541
- omap_dm_timer_read_reg (timer , OMAP_TIMER_CTRL_REG );
542
561
omap_dm_timer_disable (timer );
543
562
return 0 ;
544
563
}
@@ -561,9 +580,6 @@ static int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
561
580
omap_dm_timer_write_reg (timer , OMAP_TIMER_LOAD_REG , load );
562
581
563
582
omap_dm_timer_write_reg (timer , OMAP_TIMER_TRIGGER_REG , 0 );
564
- /* Save the context */
565
- timer -> context .tclr = l ;
566
- timer -> context .tldr = load ;
567
583
omap_dm_timer_disable (timer );
568
584
return 0 ;
569
585
}
@@ -585,9 +601,6 @@ static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
585
601
omap_dm_timer_write_reg (timer , OMAP_TIMER_MATCH_REG , match );
586
602
omap_dm_timer_write_reg (timer , OMAP_TIMER_CTRL_REG , l );
587
603
588
- /* Save the context */
589
- timer -> context .tclr = l ;
590
- timer -> context .tmar = match ;
591
604
omap_dm_timer_disable (timer );
592
605
return 0 ;
593
606
}
@@ -611,8 +624,6 @@ static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
611
624
l |= trigger << 10 ;
612
625
omap_dm_timer_write_reg (timer , OMAP_TIMER_CTRL_REG , l );
613
626
614
- /* Save the context */
615
- timer -> context .tclr = l ;
616
627
omap_dm_timer_disable (timer );
617
628
return 0 ;
618
629
}
@@ -634,8 +645,6 @@ static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer,
634
645
}
635
646
omap_dm_timer_write_reg (timer , OMAP_TIMER_CTRL_REG , l );
636
647
637
- /* Save the context */
638
- timer -> context .tclr = l ;
639
648
omap_dm_timer_disable (timer );
640
649
return 0 ;
641
650
}
@@ -649,9 +658,6 @@ static int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
649
658
omap_dm_timer_enable (timer );
650
659
__omap_dm_timer_int_enable (timer , value );
651
660
652
- /* Save the context */
653
- timer -> context .tier = value ;
654
- timer -> context .twer = value ;
655
661
omap_dm_timer_disable (timer );
656
662
return 0 ;
657
663
}
@@ -679,9 +685,6 @@ static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
679
685
l = omap_dm_timer_read_reg (timer , OMAP_TIMER_WAKEUP_EN_REG ) & ~mask ;
680
686
omap_dm_timer_write_reg (timer , OMAP_TIMER_WAKEUP_EN_REG , l );
681
687
682
- /* Save the context */
683
- timer -> context .tier &= ~mask ;
684
- timer -> context .twer &= ~mask ;
685
688
omap_dm_timer_disable (timer );
686
689
return 0 ;
687
690
}
@@ -756,13 +759,21 @@ static int __maybe_unused omap_dm_timer_runtime_suspend(struct device *dev)
756
759
757
760
atomic_set (& timer -> enabled , 0 );
758
761
762
+ if (timer -> capability & OMAP_TIMER_ALWON || !timer -> func_base )
763
+ return 0 ;
764
+
765
+ omap_timer_save_context (timer );
766
+
759
767
return 0 ;
760
768
}
761
769
762
770
static int __maybe_unused omap_dm_timer_runtime_resume (struct device * dev )
763
771
{
764
772
struct omap_dm_timer * timer = dev_get_drvdata (dev );
765
773
774
+ if (!(timer -> capability & OMAP_TIMER_ALWON ) && timer -> func_base )
775
+ omap_timer_restore_context (timer );
776
+
766
777
atomic_set (& timer -> enabled , 1 );
767
778
768
779
return 0 ;
@@ -829,7 +840,11 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
829
840
timer -> id = pdev -> id ;
830
841
timer -> capability = pdata -> timer_capability ;
831
842
timer -> reserved = omap_dm_timer_reserved_systimer (timer -> id );
832
- timer -> get_context_loss_count = pdata -> get_context_loss_count ;
843
+ }
844
+
845
+ if (!(timer -> capability & OMAP_TIMER_ALWON )) {
846
+ timer -> nb .notifier_call = omap_timer_context_notifier ;
847
+ cpu_pm_register_notifier (& timer -> nb );
833
848
}
834
849
835
850
if (pdata )
@@ -883,6 +898,8 @@ static int omap_dm_timer_remove(struct platform_device *pdev)
883
898
list_for_each_entry (timer , & omap_timer_list , node )
884
899
if (!strcmp (dev_name (& timer -> pdev -> dev ),
885
900
dev_name (& pdev -> dev ))) {
901
+ if (!(timer -> capability & OMAP_TIMER_ALWON ))
902
+ cpu_pm_unregister_notifier (& timer -> nb );
886
903
list_del (& timer -> node );
887
904
ret = 0 ;
888
905
break ;
0 commit comments