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