From febfbaa141125c24d3a40e17034261c5354a0973 Mon Sep 17 00:00:00 2001 From: Jeff Hatch Date: Mon, 16 Nov 2020 15:56:21 -0600 Subject: Add supercap_worker to handle supercap gpio and signal supercap-monitor --- io-module/mts_supercap.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 io-module/mts_supercap.c (limited to 'io-module/mts_supercap.c') diff --git a/io-module/mts_supercap.c b/io-module/mts_supercap.c new file mode 100644 index 0000000..e028408 --- /dev/null +++ b/io-module/mts_supercap.c @@ -0,0 +1,128 @@ + + +#include "mts_supercap.h" + +extern struct gpio_pin *gpio_pin_by_attr_name(const char *name); + +static supercap_info_t supercap = { + .name = "Super Cap", + .label_monitor = "supercap-monitor", + .signal = SIGPWR, + .pid = 0, + .pwf_count = 0, + .pin_is_one = 0, + +}; + +ssize_t mts_attr_show_supercap_monitor(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + + //button_info_t *button = button_by_monitor_name(attr->attr.name); + + //if (!button) { + // return -ENODEV; + //} + + mutex_lock(&mts_io_mutex); + + ret = sprintf(buf, "%d %d\n", supercap.pid, supercap.signal); + + mutex_unlock(&mts_io_mutex); + + return ret; +} + +ssize_t mts_attr_store_supercap_monitor(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + pid_t pid; + int signal; + int result = sscanf(buf, "%i %i", &pid, &signal); + + //button_info_t *button = button_by_monitor_name(attr->attr.name); + + //if (!button) { + // return -ENODEV; + //} + + if (result != 2) { + return -EINVAL; + } + + if(result == 2) { + mutex_lock(&mts_io_mutex); + + supercap.pid = pid; + supercap.signal = signal; + + mutex_unlock(&mts_io_mutex); + } + + return count; +} + +static void supercap_worker(struct work_struct *ignored); + +static DECLARE_DELAYED_WORK(supercap_work, supercap_worker); + +static void supercap_worker(struct work_struct *ignored) +{ + struct gpio_pin *pin; + struct pid *vpid; + int running_on_cap = 0; + + pin = gpio_pin_by_attr_name("power-fail"); + + if (pin) { + running_on_cap = !gpio_get_value(pin->pin.gpio); + } + + if (supercap.pid > 0) { + vpid = find_vpid(supercap.pid); + } + if (vpid) { + if (running_on_cap == 0 && supercap.pwf_count == 0) { + schedule_delayed_work(&supercap_work, SUPERCAP_CHECK_INTERVAL); + } + else if ( (supercap.pwf_count >= 0) && (supercap.pwf_count < SUPERCAP_TOTAL_INTERVALS) ) { + /* check if 90% of checks were running_on_cap == 1 */ + supercap.pwf_count++; + if (running_on_cap == 1) { + supercap.pin_is_one++; + } + if (supercap.pin_is_one >= 45) { + /* send configured signal to reset handler pid */ + log_debug("Super Cap positives %d long signal", supercap.pin_is_one); + kill_pid(vpid, supercap.signal, 1); + /* reset and start over since hit the reset condition (maybe we should clean up and go away?) */ + supercap.pwf_count = 0; + supercap.pin_is_one = 0; + } + } + else if (supercap.pwf_count == SUPERCAP_TOTAL_INTERVALS) { + /* reset and start over since didn't reach 90% at total intervals */ + supercap.pwf_count = 0; + supercap.pin_is_one = 0; + } + } /* vpid */ + + schedule_delayed_work(&supercap_work, SUPERCAP_CHECK_INTERVAL); + +} + +void init_supercap_worker(void) { + supercap_worker(NULL); +} + +void cleanup_sepercap_worker(void) { + cancel_delayed_work_sync(&supercap_work); +} + + +DEVICE_ATTR_MTS(dev_attr_supercap_monitor, + supercap.label_monitor, + mts_attr_show_supercap_monitor, + mts_attr_store_supercap_monitor); -- cgit v1.2.3