camera: camsys_drv:v0.0x1a.0 oneframe:v0.1.0xb
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rockchip / rk_system_status.c
1 #include <linux/mutex.h>
2 #include <linux/notifier.h>
3
4 static unsigned long system_status = 0;
5 static unsigned long ref_count[32] = {0};
6 static DEFINE_MUTEX(system_status_mutex);
7
8 static BLOCKING_NOTIFIER_HEAD(rk_system_status_chain_head);
9
10 int rockchip_register_system_status_notifier(struct notifier_block *nb)
11 {
12         return blocking_notifier_chain_register(&rk_system_status_chain_head, nb);
13 }
14 EXPORT_SYMBOL_GPL(rockchip_register_system_status_notifier);
15
16 int rockchip_unregister_system_status_notifier(struct notifier_block *nb)
17 {
18         return blocking_notifier_chain_unregister(&rk_system_status_chain_head, nb);
19 }
20 EXPORT_SYMBOL_GPL(rockchip_unregister_system_status_notifier);
21
22 static int rockchip_system_status_notifier_call_chain(unsigned long val)
23 {
24         int ret = blocking_notifier_call_chain(&rk_system_status_chain_head, val, NULL);
25
26         return notifier_to_errno(ret);
27 }
28
29 int rockchip_set_system_status(unsigned long status)
30 {
31         unsigned long old_system_status;
32         unsigned int single_status_offset;
33
34         mutex_lock(&system_status_mutex);
35
36         old_system_status = system_status;
37
38         while (status) {
39                 single_status_offset = fls(status) - 1;
40                 status &= ~(1<<single_status_offset);
41                 if (ref_count[single_status_offset] == 0) {
42                         system_status |= 1 << single_status_offset;
43                 }
44                 ref_count[single_status_offset]++;
45         }
46         if (old_system_status != system_status)
47                 rockchip_system_status_notifier_call_chain(system_status);
48
49         mutex_unlock(&system_status_mutex);
50         return 0;
51 }
52
53 int rockchip_clear_system_status(unsigned long status)
54 {
55         unsigned long old_system_status;
56         unsigned int single_status_offset;
57         mutex_lock(&system_status_mutex);
58
59         old_system_status = system_status;
60
61         while (status) {
62                 single_status_offset = fls(status) - 1;
63                 status &= ~(1<<single_status_offset);
64                 if (ref_count[single_status_offset] == 0) {
65                         continue;
66                 } else {
67                         if (ref_count[single_status_offset] == 1) {
68                                 system_status &= ~(1<<single_status_offset);
69                         }
70                         ref_count[single_status_offset]--;
71                 }
72         }
73         if (old_system_status != system_status)
74                 rockchip_system_status_notifier_call_chain(system_status);
75
76         mutex_unlock(&system_status_mutex);
77
78         return 0;
79 }
80
81 unsigned long rockchip_get_system_status(void)
82 {
83         unsigned long ret;
84
85         mutex_lock(&system_status_mutex);
86         ret = system_status;
87         mutex_unlock(&system_status_mutex);
88
89         return ret;
90 }