1
2
3
4
5
6
7#define pr_fmt(fmt) "PM: " fmt
8
9#include <linux/device.h>
10#include <linux/slab.h>
11#include <linux/sched/signal.h>
12#include <linux/capability.h>
13#include <linux/export.h>
14#include <linux/suspend.h>
15#include <linux/seq_file.h>
16#include <linux/debugfs.h>
17#include <linux/pm_wakeirq.h>
18#include <trace/events/power.h>
19
20#include "power.h"
21
22#ifndef CONFIG_SUSPEND
23suspend_state_t pm_suspend_target_state;
24#define pm_suspend_target_state (PM_SUSPEND_ON)
25#endif
26
27
28
29
30
31bool events_check_enabled __read_mostly;
32
33
34unsigned int pm_wakeup_irq __read_mostly;
35
36
37static atomic_t pm_abort_suspend __read_mostly;
38
39
40
41
42
43
44static atomic_t combined_event_count = ATOMIC_INIT(0);
45
46#define IN_PROGRESS_BITS (sizeof(int) * 4)
47#define MAX_IN_PROGRESS ((1 << IN_PROGRESS_BITS) - 1)
48
49static void split_counters(unsigned int *cnt, unsigned int *inpr)
50{
51 unsigned int comb = atomic_read(&combined_event_count);
52
53 *cnt = (comb >> IN_PROGRESS_BITS);
54 *inpr = comb & MAX_IN_PROGRESS;
55}
56
57
58static unsigned int saved_count;
59
60static DEFINE_RAW_SPINLOCK(events_lock);
61
62static void pm_wakeup_timer_fn(struct timer_list *t);
63
64static LIST_HEAD(wakeup_sources);
65
66static DECLARE_WAIT_QUEUE_HEAD(wakeup_count_wait_queue);
67
68DEFINE_STATIC_SRCU(wakeup_srcu);
69
70static struct wakeup_source deleted_ws = {
71 .name = "deleted",
72 .lock = __SPIN_LOCK_UNLOCKED(deleted_ws.lock),
73};
74
75
76
77
78
79
80
81
82
83void wakeup_source_prepare(struct wakeup_source *ws, const char *name)
84{
85 if (ws) {
86 memset(ws, 0, sizeof(*ws));
87 ws->name = name;
88 }
89}
90EXPORT_SYMBOL_GPL(wakeup_source_prepare);
91
92
93
94
95
96struct wakeup_source *wakeup_source_create(const char *name)
97{
98 struct wakeup_source *ws;
99
100 ws = kmalloc(sizeof(*ws), GFP_KERNEL);
101 if (!ws)
102 return NULL;
103
104 wakeup_source_prepare(ws, name ? kstrdup_const(name, GFP_KERNEL) : NULL);
105 return ws;
106}
107EXPORT_SYMBOL_GPL(wakeup_source_create);
108
109
110
111
112static void wakeup_source_record(struct wakeup_source *ws)
113{
114 unsigned long flags;
115
116 spin_lock_irqsave(&deleted_ws.lock, flags);
117
118 if (ws->event_count) {
119 deleted_ws.total_time =
120 ktime_add(deleted_ws.total_time, ws->total_time);
121 deleted_ws.prevent_sleep_time =
122 ktime_add(deleted_ws.prevent_sleep_time,
123 ws->prevent_sleep_time);
124 deleted_ws.max_time =
125 ktime_compare(deleted_ws.max_time, ws->max_time) > 0 ?
126 deleted_ws.max_time : ws->max_time;
127 deleted_ws.event_count += ws->event_count;
128 deleted_ws.active_count += ws->active_count;
129 deleted_ws.relax_count += ws->relax_count;
130 deleted_ws.expire_count += ws->expire_count;
131 deleted_ws.wakeup_count += ws->wakeup_count;
132 }
133
134 spin_unlock_irqrestore(&deleted_ws.lock, flags);
135}
136
137
138
139
140
141
142
143void wakeup_source_destroy(struct wakeup_source *ws)
144{
145 if (!ws)
146 return;
147
148 __pm_relax(ws);
149 wakeup_source_record(ws);
150 kfree_const(ws->name);
151 kfree(ws);
152}
153EXPORT_SYMBOL_GPL(wakeup_source_destroy);
154
155
156
157
158
159void wakeup_source_add(struct wakeup_source *ws)
160{
161 unsigned long flags;
162
163 if (WARN_ON(!ws))
164 return;
165
166 spin_lock_init(&ws->lock);
167 timer_setup(&ws->timer, pm_wakeup_timer_fn, 0);
168 ws->active = false;
169
170 raw_spin_lock_irqsave(&events_lock, flags);
171 list_add_rcu(&ws->entry, &wakeup_sources);
172 raw_spin_unlock_irqrestore(&events_lock, flags);
173}
174EXPORT_SYMBOL_GPL(wakeup_source_add);
175
176
177
178
179
180void wakeup_source_remove(struct wakeup_source *ws)
181{
182 unsigned long flags;
183
184 if (WARN_ON(!ws))
185 return;
186
187 raw_spin_lock_irqsave(&events_lock, flags);
188 list_del_rcu(&ws->entry);
189 raw_spin_unlock_irqrestore(&events_lock, flags);
190 synchronize_srcu(&wakeup_srcu);
191
192 del_timer_sync(&ws->timer);
193
194
195
196
197 ws->timer.function = NULL;
198}
199EXPORT_SYMBOL_GPL(wakeup_source_remove);
200
201
202
203
204
205struct wakeup_source *wakeup_source_register(const char *name)
206{
207 struct wakeup_source *ws;
208
209 ws = wakeup_source_create(name);
210 if (ws)
211 wakeup_source_add(ws);
212
213 return ws;
214}
215EXPORT_SYMBOL_GPL(wakeup_source_register);
216
217
218
219
220
221void wakeup_source_unregister(struct wakeup_source *ws)
222{
223 if (ws) {
224 wakeup_source_remove(ws);
225 wakeup_source_destroy(ws);
226 }
227}
228EXPORT_SYMBOL_GPL(wakeup_source_unregister);
229
230
231
232
233
234
235
236
237static int device_wakeup_attach(struct device *dev, struct wakeup_source *ws)
238{
239 spin_lock_irq(&dev->power.lock);
240 if (dev->power.wakeup) {
241 spin_unlock_irq(&dev->power.lock);
242 return -EEXIST;
243 }
244 dev->power.wakeup = ws;
245 if (dev->power.wakeirq)
246 device_wakeup_attach_irq(dev, dev->power.wakeirq);
247 spin_unlock_irq(&dev->power.lock);
248 return 0;
249}
250
251
252
253
254
255
256
257int device_wakeup_enable(struct device *dev)
258{
259 struct wakeup_source *ws;
260 int ret;
261
262 if (!dev || !dev->power.can_wakeup)
263 return -EINVAL;
264
265 if (pm_suspend_target_state != PM_SUSPEND_ON)
266 dev_dbg(dev, "Suspicious %s() during system transition!\n", __func__);
267
268 ws = wakeup_source_register(dev_name(dev));
269 if (!ws)
270 return -ENOMEM;
271
272 ret = device_wakeup_attach(dev, ws);
273 if (ret)
274 wakeup_source_unregister(ws);
275
276 return ret;
277}
278EXPORT_SYMBOL_GPL(device_wakeup_enable);
279
280
281
282
283
284
285
286
287
288
289
290
291void device_wakeup_attach_irq(struct device *dev,
292 struct wake_irq *wakeirq)
293{
294 struct wakeup_source *ws;
295
296 ws = dev->power.wakeup;
297 if (!ws)
298 return;
299
300 if (ws->wakeirq)
301 dev_err(dev, "Leftover wakeup IRQ found, overriding\n");
302
303 ws->wakeirq = wakeirq;
304}
305
306
307
308
309
310
311
312
313
314void device_wakeup_detach_irq(struct device *dev)
315{
316 struct wakeup_source *ws;
317
318 ws = dev->power.wakeup;
319 if (ws)
320 ws->wakeirq = NULL;
321}
322
323
324
325
326
327
328void device_wakeup_arm_wake_irqs(void)
329{
330 struct wakeup_source *ws;
331 int srcuidx;
332
333 srcuidx = srcu_read_lock(&wakeup_srcu);
334 list_for_each_entry_rcu(ws, &wakeup_sources, entry)
335 dev_pm_arm_wake_irq(ws->wakeirq);
336 srcu_read_unlock(&wakeup_srcu, srcuidx);
337}
338
339
340
341
342
343
344void device_wakeup_disarm_wake_irqs(void)
345{
346 struct wakeup_source *ws;
347 int srcuidx;
348
349 srcuidx = srcu_read_lock(&wakeup_srcu);
350 list_for_each_entry_rcu(ws, &wakeup_sources, entry)
351 dev_pm_disarm_wake_irq(ws->wakeirq);
352 srcu_read_unlock(&wakeup_srcu, srcuidx);
353}
354
355
356
357
358
359
360
361static struct wakeup_source *device_wakeup_detach(struct device *dev)
362{
363 struct wakeup_source *ws;
364
365 spin_lock_irq(&dev->power.lock);
366 ws = dev->power.wakeup;
367 dev->power.wakeup = NULL;
368 spin_unlock_irq(&dev->power.lock);
369 return ws;
370}
371
372
373
374
375
376
377
378
379int device_wakeup_disable(struct device *dev)
380{
381 struct wakeup_source *ws;
382
383 if (!dev || !dev->power.can_wakeup)
384 return -EINVAL;
385
386 ws = device_wakeup_detach(dev);
387 wakeup_source_unregister(ws);
388 return 0;
389}
390EXPORT_SYMBOL_GPL(device_wakeup_disable);
391
392
393
394
395
396
397
398
399
400
401
402
403
404void device_set_wakeup_capable(struct device *dev, bool capable)
405{
406 if (!!dev->power.can_wakeup == !!capable)
407 return;
408
409 dev->power.can_wakeup = capable;
410 if (device_is_registered(dev) && !list_empty(&dev->power.entry)) {
411 if (capable) {
412 int ret = wakeup_sysfs_add(dev);
413
414 if (ret)
415 dev_info(dev, "Wakeup sysfs attributes not added\n");
416 } else {
417 wakeup_sysfs_remove(dev);
418 }
419 }
420}
421EXPORT_SYMBOL_GPL(device_set_wakeup_capable);
422
423
424
425
426
427
428
429
430
431
432
433
434int device_init_wakeup(struct device *dev, bool enable)
435{
436 int ret = 0;
437
438 if (!dev)
439 return -EINVAL;
440
441 if (enable) {
442 device_set_wakeup_capable(dev, true);
443 ret = device_wakeup_enable(dev);
444 } else {
445 device_wakeup_disable(dev);
446 device_set_wakeup_capable(dev, false);
447 }
448
449 return ret;
450}
451EXPORT_SYMBOL_GPL(device_init_wakeup);
452
453
454
455
456
457int device_set_wakeup_enable(struct device *dev, bool enable)
458{
459 return enable ? device_wakeup_enable(dev) : device_wakeup_disable(dev);
460}
461EXPORT_SYMBOL_GPL(device_set_wakeup_enable);
462
463
464
465
466
467static bool wakeup_source_not_registered(struct wakeup_source *ws)
468{
469
470
471
472
473 return ws->timer.function != pm_wakeup_timer_fn;
474}
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512static void wakeup_source_activate(struct wakeup_source *ws)
513{
514 unsigned int cec;
515
516 if (WARN_ONCE(wakeup_source_not_registered(ws),
517 "unregistered wakeup source\n"))
518 return;
519
520 ws->active = true;
521 ws->active_count++;
522 ws->last_time = ktime_get();
523 if (ws->autosleep_enabled)
524 ws->start_prevent_time = ws->last_time;
525
526
527 cec = atomic_inc_return(&combined_event_count);
528
529 trace_wakeup_source_activate(ws->name, cec);
530}
531
532
533
534
535
536
537static void wakeup_source_report_event(struct wakeup_source *ws, bool hard)
538{
539 ws->event_count++;
540
541 if (events_check_enabled)
542 ws->wakeup_count++;
543
544 if (!ws->active)
545 wakeup_source_activate(ws);
546
547 if (hard)
548 pm_system_wakeup();
549}
550
551
552
553
554
555
556
557void __pm_stay_awake(struct wakeup_source *ws)
558{
559 unsigned long flags;
560
561 if (!ws)
562 return;
563
564 spin_lock_irqsave(&ws->lock, flags);
565
566 wakeup_source_report_event(ws, false);
567 del_timer(&ws->timer);
568 ws->timer_expires = 0;
569
570 spin_unlock_irqrestore(&ws->lock, flags);
571}
572EXPORT_SYMBOL_GPL(__pm_stay_awake);
573
574
575
576
577
578
579
580
581
582
583
584
585void pm_stay_awake(struct device *dev)
586{
587 unsigned long flags;
588
589 if (!dev)
590 return;
591
592 spin_lock_irqsave(&dev->power.lock, flags);
593 __pm_stay_awake(dev->power.wakeup);
594 spin_unlock_irqrestore(&dev->power.lock, flags);
595}
596EXPORT_SYMBOL_GPL(pm_stay_awake);
597
598#ifdef CONFIG_PM_AUTOSLEEP
599static void update_prevent_sleep_time(struct wakeup_source *ws, ktime_t now)
600{
601 ktime_t delta = ktime_sub(now, ws->start_prevent_time);
602 ws->prevent_sleep_time = ktime_add(ws->prevent_sleep_time, delta);
603}
604#else
605static inline void update_prevent_sleep_time(struct wakeup_source *ws,
606 ktime_t now) {}
607#endif
608
609
610
611
612
613
614
615
616
617static void wakeup_source_deactivate(struct wakeup_source *ws)
618{
619 unsigned int cnt, inpr, cec;
620 ktime_t duration;
621 ktime_t now;
622
623 ws->relax_count++;
624
625
626
627
628
629
630
631
632
633 if (ws->relax_count != ws->active_count) {
634 ws->relax_count--;
635 return;
636 }
637
638 ws->active = false;
639
640 now = ktime_get();
641 duration = ktime_sub(now, ws->last_time);
642 ws->total_time = ktime_add(ws->total_time, duration);
643 if (ktime_to_ns(duration) > ktime_to_ns(ws->max_time))
644 ws->max_time = duration;
645
646 ws->last_time = now;
647 del_timer(&ws->timer);
648 ws->timer_expires = 0;
649
650 if (ws->autosleep_enabled)
651 update_prevent_sleep_time(ws, now);
652
653
654
655
656
657 cec = atomic_add_return(MAX_IN_PROGRESS, &combined_event_count);
658 trace_wakeup_source_deactivate(ws->name, cec);
659
660 split_counters(&cnt, &inpr);
661 if (!inpr && waitqueue_active(&wakeup_count_wait_queue))
662 wake_up(&wakeup_count_wait_queue);
663}
664
665
666
667
668
669
670
671
672
673
674void __pm_relax(struct wakeup_source *ws)
675{
676 unsigned long flags;
677
678 if (!ws)
679 return;
680
681 spin_lock_irqsave(&ws->lock, flags);
682 if (ws->active)
683 wakeup_source_deactivate(ws);
684 spin_unlock_irqrestore(&ws->lock, flags);
685}
686EXPORT_SYMBOL_GPL(__pm_relax);
687
688
689
690
691
692
693
694void pm_relax(struct device *dev)
695{
696 unsigned long flags;
697
698 if (!dev)
699 return;
700
701 spin_lock_irqsave(&dev->power.lock, flags);
702 __pm_relax(dev->power.wakeup);
703 spin_unlock_irqrestore(&dev->power.lock, flags);
704}
705EXPORT_SYMBOL_GPL(pm_relax);
706
707
708
709
710
711
712
713
714
715static void pm_wakeup_timer_fn(struct timer_list *t)
716{
717 struct wakeup_source *ws = from_timer(ws, t, timer);
718 unsigned long flags;
719
720 spin_lock_irqsave(&ws->lock, flags);
721
722 if (ws->active && ws->timer_expires
723 && time_after_eq(jiffies, ws->timer_expires)) {
724 wakeup_source_deactivate(ws);
725 ws->expire_count++;
726 }
727
728 spin_unlock_irqrestore(&ws->lock, flags);
729}
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744void pm_wakeup_ws_event(struct wakeup_source *ws, unsigned int msec, bool hard)
745{
746 unsigned long flags;
747 unsigned long expires;
748
749 if (!ws)
750 return;
751
752 spin_lock_irqsave(&ws->lock, flags);
753
754 wakeup_source_report_event(ws, hard);
755
756 if (!msec) {
757 wakeup_source_deactivate(ws);
758 goto unlock;
759 }
760
761 expires = jiffies + msecs_to_jiffies(msec);
762 if (!expires)
763 expires = 1;
764
765 if (!ws->timer_expires || time_after(expires, ws->timer_expires)) {
766 mod_timer(&ws->timer, expires);
767 ws->timer_expires = expires;
768 }
769
770 unlock:
771 spin_unlock_irqrestore(&ws->lock, flags);
772}
773EXPORT_SYMBOL_GPL(pm_wakeup_ws_event);
774
775
776
777
778
779
780
781
782
783void pm_wakeup_dev_event(struct device *dev, unsigned int msec, bool hard)
784{
785 unsigned long flags;
786
787 if (!dev)
788 return;
789
790 spin_lock_irqsave(&dev->power.lock, flags);
791 pm_wakeup_ws_event(dev->power.wakeup, msec, hard);
792 spin_unlock_irqrestore(&dev->power.lock, flags);
793}
794EXPORT_SYMBOL_GPL(pm_wakeup_dev_event);
795
796void pm_print_active_wakeup_sources(void)
797{
798 struct wakeup_source *ws;
799 int srcuidx, active = 0;
800 struct wakeup_source *last_activity_ws = NULL;
801
802 srcuidx = srcu_read_lock(&wakeup_srcu);
803 list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
804 if (ws->active) {
805 pm_pr_dbg("active wakeup source: %s\n", ws->name);
806 active = 1;
807 } else if (!active &&
808 (!last_activity_ws ||
809 ktime_to_ns(ws->last_time) >
810 ktime_to_ns(last_activity_ws->last_time))) {
811 last_activity_ws = ws;
812 }
813 }
814
815 if (!active && last_activity_ws)
816 pm_pr_dbg("last active wakeup source: %s\n",
817 last_activity_ws->name);
818 srcu_read_unlock(&wakeup_srcu, srcuidx);
819}
820EXPORT_SYMBOL_GPL(pm_print_active_wakeup_sources);
821
822
823
824
825
826
827
828
829
830bool pm_wakeup_pending(void)
831{
832 unsigned long flags;
833 bool ret = false;
834
835 raw_spin_lock_irqsave(&events_lock, flags);
836 if (events_check_enabled) {
837 unsigned int cnt, inpr;
838
839 split_counters(&cnt, &inpr);
840 ret = (cnt != saved_count || inpr > 0);
841 events_check_enabled = !ret;
842 }
843 raw_spin_unlock_irqrestore(&events_lock, flags);
844
845 if (ret) {
846 pm_pr_dbg("Wakeup pending, aborting suspend\n");
847 pm_print_active_wakeup_sources();
848 }
849
850 return ret || atomic_read(&pm_abort_suspend) > 0;
851}
852
853void pm_system_wakeup(void)
854{
855 atomic_inc(&pm_abort_suspend);
856 s2idle_wake();
857}
858EXPORT_SYMBOL_GPL(pm_system_wakeup);
859
860void pm_system_cancel_wakeup(void)
861{
862 atomic_dec(&pm_abort_suspend);
863}
864
865void pm_wakeup_clear(bool reset)
866{
867 pm_wakeup_irq = 0;
868 if (reset)
869 atomic_set(&pm_abort_suspend, 0);
870}
871
872void pm_system_irq_wakeup(unsigned int irq_number)
873{
874 if (pm_wakeup_irq == 0) {
875 pm_wakeup_irq = irq_number;
876 pm_system_wakeup();
877 }
878}
879
880
881
882
883
884
885
886
887
888
889
890
891
892bool pm_get_wakeup_count(unsigned int *count, bool block)
893{
894 unsigned int cnt, inpr;
895
896 if (block) {
897 DEFINE_WAIT(wait);
898
899 for (;;) {
900 prepare_to_wait(&wakeup_count_wait_queue, &wait,
901 TASK_INTERRUPTIBLE);
902 split_counters(&cnt, &inpr);
903 if (inpr == 0 || signal_pending(current))
904 break;
905 pm_print_active_wakeup_sources();
906 schedule();
907 }
908 finish_wait(&wakeup_count_wait_queue, &wait);
909 }
910
911 split_counters(&cnt, &inpr);
912 *count = cnt;
913 return !inpr;
914}
915
916
917
918
919
920
921
922
923
924
925
926bool pm_save_wakeup_count(unsigned int count)
927{
928 unsigned int cnt, inpr;
929 unsigned long flags;
930
931 events_check_enabled = false;
932 raw_spin_lock_irqsave(&events_lock, flags);
933 split_counters(&cnt, &inpr);
934 if (cnt == count && inpr == 0) {
935 saved_count = count;
936 events_check_enabled = true;
937 }
938 raw_spin_unlock_irqrestore(&events_lock, flags);
939 return events_check_enabled;
940}
941
942#ifdef CONFIG_PM_AUTOSLEEP
943
944
945
946
947void pm_wakep_autosleep_enabled(bool set)
948{
949 struct wakeup_source *ws;
950 ktime_t now = ktime_get();
951 int srcuidx;
952
953 srcuidx = srcu_read_lock(&wakeup_srcu);
954 list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
955 spin_lock_irq(&ws->lock);
956 if (ws->autosleep_enabled != set) {
957 ws->autosleep_enabled = set;
958 if (ws->active) {
959 if (set)
960 ws->start_prevent_time = now;
961 else
962 update_prevent_sleep_time(ws, now);
963 }
964 }
965 spin_unlock_irq(&ws->lock);
966 }
967 srcu_read_unlock(&wakeup_srcu, srcuidx);
968}
969#endif
970
971
972
973
974
975
976static int print_wakeup_source_stats(struct seq_file *m,
977 struct wakeup_source *ws)
978{
979 unsigned long flags;
980 ktime_t total_time;
981 ktime_t max_time;
982 unsigned long active_count;
983 ktime_t active_time;
984 ktime_t prevent_sleep_time;
985
986 spin_lock_irqsave(&ws->lock, flags);
987
988 total_time = ws->total_time;
989 max_time = ws->max_time;
990 prevent_sleep_time = ws->prevent_sleep_time;
991 active_count = ws->active_count;
992 if (ws->active) {
993 ktime_t now = ktime_get();
994
995 active_time = ktime_sub(now, ws->last_time);
996 total_time = ktime_add(total_time, active_time);
997 if (active_time > max_time)
998 max_time = active_time;
999
1000 if (ws->autosleep_enabled)
1001 prevent_sleep_time = ktime_add(prevent_sleep_time,
1002 ktime_sub(now, ws->start_prevent_time));
1003 } else {
1004 active_time = 0;
1005 }
1006
1007 seq_printf(m, "%-12s\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%lld\t\t%lld\t\t%lld\t\t%lld\t\t%lld\n",
1008 ws->name, active_count, ws->event_count,
1009 ws->wakeup_count, ws->expire_count,
1010 ktime_to_ms(active_time), ktime_to_ms(total_time),
1011 ktime_to_ms(max_time), ktime_to_ms(ws->last_time),
1012 ktime_to_ms(prevent_sleep_time));
1013
1014 spin_unlock_irqrestore(&ws->lock, flags);
1015
1016 return 0;
1017}
1018
1019static void *wakeup_sources_stats_seq_start(struct seq_file *m,
1020 loff_t *pos)
1021{
1022 struct wakeup_source *ws;
1023 loff_t n = *pos;
1024 int *srcuidx = m->private;
1025
1026 if (n == 0) {
1027 seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t"
1028 "expire_count\tactive_since\ttotal_time\tmax_time\t"
1029 "last_change\tprevent_suspend_time\n");
1030 }
1031
1032 *srcuidx = srcu_read_lock(&wakeup_srcu);
1033 list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
1034 if (n-- <= 0)
1035 return ws;
1036 }
1037
1038 return NULL;
1039}
1040
1041static void *wakeup_sources_stats_seq_next(struct seq_file *m,
1042 void *v, loff_t *pos)
1043{
1044 struct wakeup_source *ws = v;
1045 struct wakeup_source *next_ws = NULL;
1046
1047 ++(*pos);
1048
1049 list_for_each_entry_continue_rcu(ws, &wakeup_sources, entry) {
1050 next_ws = ws;
1051 break;
1052 }
1053
1054 return next_ws;
1055}
1056
1057static void wakeup_sources_stats_seq_stop(struct seq_file *m, void *v)
1058{
1059 int *srcuidx = m->private;
1060
1061 srcu_read_unlock(&wakeup_srcu, *srcuidx);
1062}
1063
1064
1065
1066
1067
1068
1069static int wakeup_sources_stats_seq_show(struct seq_file *m, void *v)
1070{
1071 struct wakeup_source *ws = v;
1072
1073 print_wakeup_source_stats(m, ws);
1074
1075 return 0;
1076}
1077
1078static const struct seq_operations wakeup_sources_stats_seq_ops = {
1079 .start = wakeup_sources_stats_seq_start,
1080 .next = wakeup_sources_stats_seq_next,
1081 .stop = wakeup_sources_stats_seq_stop,
1082 .show = wakeup_sources_stats_seq_show,
1083};
1084
1085static int wakeup_sources_stats_open(struct inode *inode, struct file *file)
1086{
1087 return seq_open_private(file, &wakeup_sources_stats_seq_ops, sizeof(int));
1088}
1089
1090static const struct file_operations wakeup_sources_stats_fops = {
1091 .owner = THIS_MODULE,
1092 .open = wakeup_sources_stats_open,
1093 .read = seq_read,
1094 .llseek = seq_lseek,
1095 .release = seq_release_private,
1096};
1097
1098static int __init wakeup_sources_debugfs_init(void)
1099{
1100 debugfs_create_file("wakeup_sources", S_IRUGO, NULL, NULL,
1101 &wakeup_sources_stats_fops);
1102 return 0;
1103}
1104
1105postcore_initcall(wakeup_sources_debugfs_init);
1106