// SPDX-License-Identifier: GPL-2.0-only
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/jiffies.h>
#include <linux/timer.h>
#include <linux/uaccess.h>
#include <linux/sched/loadavg.h>

#include <asm/auxio.h>

#define LED_MAX_LENGTH 8 /* maximum chars written to proc file */

static inline void led_toggle(void)
{
	unsigned char val = get_auxio();
	unsigned char on, off;

	if (val & AUXIO_LED) {
		on = 0;
		off = AUXIO_LED;
	} else {
		on = AUXIO_LED;
		off = 0;
	}

	set_auxio(on, off);
}

static struct timer_list led_blink_timer;
static unsigned long led_blink_timer_timeout;

static void led_blink(struct timer_list *unused)
{
	unsigned long timeout = led_blink_timer_timeout;

	led_toggle();

	/* reschedule */
	if (!timeout) { /* blink according to load */
		led_blink_timer.expires = jiffies +
			((1 + (avenrun[0] >> FSHIFT)) * HZ);
	} else { /* blink at user specified interval */
		led_blink_timer.expires = jiffies + (timeout * HZ);
	}
	add_timer(&led_blink_timer);
}

#ifdef CONFIG_PROC_FS
static int led_proc_show(struct seq_file *m, void *v)
{
	if (get_auxio() & AUXIO_LED)
		seq_puts(m, "on\n");
	else
		seq_puts(m, "off\n");
	return 0;
}

static int led_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, led_proc_show, NULL);
}

static ssize_t led_proc_write(struct file *file, const char __user *buffer,
			      size_t count, loff_t *ppos)
{
	char *buf = NULL;

	if (count > LED_MAX_LENGTH)
		count = LED_MAX_LENGTH;

	buf = memdup_user_nul(buffer, count);
	if (IS_ERR(buf))
		return PTR_ERR(buf);

	/* work around \n when echo'ing into proc */
	if (count > 0 && buf[count - 1] == '\n')
		buf[count - 1] = '\0';

	/* before we change anything we want to stop any running timers,
	 * otherwise calls such as on will have no persistent effect
	 */
	timer_delete_sync(&led_blink_timer);

	if (!strcmp(buf, "on")) {
		auxio_set_led(AUXIO_LED_ON);
	} else if (!strcmp(buf, "toggle")) {
		led_toggle();
	} else if ((*buf > '0') && (*buf <= '9')) {
		led_blink_timer_timeout = simple_strtoul(buf, NULL, 10);
		led_blink(&led_blink_timer);
	} else if (!strcmp(buf, "load")) {
		led_blink_timer_timeout = 0;
		led_blink(&led_blink_timer);
	} else {
		auxio_set_led(AUXIO_LED_OFF);
	}

	kfree(buf);

	return count;
}

static const struct proc_ops led_proc_ops = {
	.proc_open	= led_proc_open,
	.proc_read	= seq_read,
	.proc_lseek	= seq_lseek,
	.proc_release	= single_release,
	.proc_write	= led_proc_write,
};
#endif

#define LED_VERSION	"0.1"

static int __init led_init(void)
{
	timer_setup(&led_blink_timer, led_blink, 0);

#ifdef CONFIG_PROC_FS
	if (!proc_create("led", 0, NULL, &led_proc_ops))
		return -ENOMEM;
#endif
	printk(KERN_INFO
	       "led: version %s, Lars Kotthoff <metalhead@metalhead.ws>\n",
	       LED_VERSION);

	return 0;
}

static void __exit led_exit(void)
{
	remove_proc_entry("led", NULL);
	timer_delete_sync(&led_blink_timer);
}

module_init(led_init);
module_exit(led_exit);

MODULE_AUTHOR("Lars Kotthoff <metalhead@metalhead.ws>");
MODULE_DESCRIPTION("Provides control of the front LED on SPARC systems.");
MODULE_LICENSE("GPL");
MODULE_VERSION(LED_VERSION);
