#define pr_fmt(fmt) "[hui] " fmt
#include <linux/module.h>

#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");