#define pr_fmt(fmt) "[hui] " fmt #include #include "hui_internal.h" #include "leds.h" #include "connect/connect.h" #include "log.h" static inline void hui_update(struct work_struct *work); DEFINE_MUTEX(hui_update_mutex); static DECLARE_WORK(hui_update_work, hui_update); static int ignore_schedule_requests = 1; static void __init _event_node_established_cb(void *completion, unsigned int unused0, unsigned int unused1) { struct completion *init_complete = completion; complete_all(init_complete); } static __init int wait_for_avm_event(void) { DECLARE_COMPLETION_ONSTACK(init_complete); int ret; ret = avm_event_node_established(_event_node_established_cb, &init_complete, 0, 0); if (ret) return ret; wait_for_completion(&init_complete); return 0; } static __init int hui_init(void) { pr_info("Initialize hardware user interface\n"); /* * TODO: quick fix for remote events * * Actually we should just delay the parts actually depending on * avm_event. */ wait_for_avm_event(); hui_sysfs_init(); hui_log_init(); events_init(); leds_init(); connect_init(); device_init(); button_init(); generic_gpio_init(); ignore_schedule_requests = 0; hui_schedule_update(); /*--- initial all leds active, independently display_suspend ---*/ avm_hui_send_event(event_display_suspend_on_idle, 1); return 0; } module_init(hui_init); static void hui_exit(void) { generic_gpio_exit(); button_exit(); connect_exit(); leds_exit(); events_exit(); hui_sysfs_exit(); pr_info("Exit hardware user interface\n"); } module_exit(hui_exit); void hui_schedule_update(void) { if (ignore_schedule_requests) return; schedule_work(&hui_update_work); } static void hui_update(struct work_struct *work) { mutex_lock(&hui_update_mutex); pr_debug("Begin hui update\n"); events_update(); leds_update(); leds_update_output(); pr_debug("End hui update\n"); mutex_unlock(&hui_update_mutex); } MODULE_ALIAS("led"); MODULE_ALIAS("led_module"); MODULE_AUTHOR("AVM GmbH"); MODULE_LICENSE("GPL");