1 #include <linux/mutex.h>
2 #include <linux/notifier.h>
4 static unsigned long system_status = 0;
5 static unsigned long ref_count[32] = {0};
6 static DEFINE_MUTEX(system_status_mutex);
8 static BLOCKING_NOTIFIER_HEAD(rk_system_status_chain_head);
10 int rockchip_register_system_status_notifier(struct notifier_block *nb)
12 return blocking_notifier_chain_register(&rk_system_status_chain_head, nb);
14 EXPORT_SYMBOL_GPL(rockchip_register_system_status_notifier);
16 int rockchip_unregister_system_status_notifier(struct notifier_block *nb)
18 return blocking_notifier_chain_unregister(&rk_system_status_chain_head, nb);
20 EXPORT_SYMBOL_GPL(rockchip_unregister_system_status_notifier);
22 static int rockchip_system_status_notifier_call_chain(unsigned long val)
24 int ret = blocking_notifier_call_chain(&rk_system_status_chain_head, val, NULL);
26 return notifier_to_errno(ret);
29 int rockchip_set_system_status(unsigned long status)
31 unsigned long old_system_status;
32 unsigned int single_status_offset;
34 mutex_lock(&system_status_mutex);
36 old_system_status = system_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;
44 ref_count[single_status_offset]++;
46 if (old_system_status != system_status)
47 rockchip_system_status_notifier_call_chain(system_status);
49 mutex_unlock(&system_status_mutex);
53 int rockchip_clear_system_status(unsigned long status)
55 unsigned long old_system_status;
56 unsigned int single_status_offset;
57 mutex_lock(&system_status_mutex);
59 old_system_status = system_status;
62 single_status_offset = fls(status) - 1;
63 status &= ~(1<<single_status_offset);
64 if (ref_count[single_status_offset] == 0) {
67 if (ref_count[single_status_offset] == 1) {
68 system_status &= ~(1<<single_status_offset);
70 ref_count[single_status_offset]--;
73 if (old_system_status != system_status)
74 rockchip_system_status_notifier_call_chain(system_status);
76 mutex_unlock(&system_status_mutex);
81 unsigned long rockchip_get_system_status(void)
85 mutex_lock(&system_status_mutex);
87 mutex_unlock(&system_status_mutex);