From 92834217e5fe04210e23ec7b4958eb9bf4834b5e Mon Sep 17 00:00:00 2001 From: Ricardo Pardini Date: Thu, 30 Mar 2023 11:36:11 +0800 Subject: [PATCH] khadas: drivers/watchdog - squashed, scripts/packaging/etc removed, grouped by directory - source - https://github.com/khadas/linux/commits/khadas-edges-5.10.y - https://github.com/khadas/linux/commit/85a8b25939a28b66f2147823b62f5861d23d69c1 --- drivers/watchdog/Kconfig | 10 +++ drivers/watchdog/Makefile | 1 + drivers/watchdog/khadas_wdt.c | 157 ++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 drivers/watchdog/khadas_wdt.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index b64bc49c7f30..51c66b8236a8 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -832,6 +832,16 @@ config MEDIATEK_WATCHDOG To compile this driver as a module, choose M here: the module will be called mtk_wdt. +config KHADAS_WATCHDOG + tristate "KHADAS watchdog support" + default y + help + Say Y here to include watchdog support embedded into KHADAS. + If the watchdog timer expires, TPS3851 will shut down all its power + supplies. + To compile this driver as a module, choose M here: the + module will be called KHADAS_wdt. + config DIGICOLOR_WATCHDOG tristate "Conexant Digicolor SoCs watchdog support" depends on ARCH_DIGICOLOR || COMPILE_TEST diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index d41e5f830ae7..5387c78e273a 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC) += pretimeout_panic.o obj-$(CONFIG_PCWATCHDOG) += pcwd.o obj-$(CONFIG_MIXCOMWD) += mixcomwd.o obj-$(CONFIG_WDT) += wdt.o +obj-$(CONFIG_KHADAS_WATCHDOG) += khadas_wdt.o # PCI-based Watchdog Cards obj-$(CONFIG_PCIPCWATCHDOG) += pcwd_pci.o diff --git a/drivers/watchdog/khadas_wdt.c b/drivers/watchdog/khadas_wdt.c new file mode 100644 index 000000000000..3b28a52fd6ae --- /dev/null +++ b/drivers/watchdog/khadas_wdt.c @@ -0,0 +1,157 @@ +//#define DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct timer_list mytimer; +static unsigned int hw_margin = 3; +static int khadas_input_pin; +static unsigned int khadas_enble = 1; + +static void time_pre(struct timer_list *timer) +{ + static unsigned int flag=0; + flag = !flag; + gpio_direction_output(khadas_input_pin, flag); + + //printk("%s\n", __func__); + mytimer.expires = jiffies + hw_margin * HZ/1000; // 500ms 运行一次 + if(khadas_enble) + mod_timer(&mytimer, mytimer.expires); +} + +/* +static void wdt_exit(void) +{ + if(timer_pending(&mytimer)) + { + del_timer(&mytimer); + } + printk("exit Success \n"); +}*/ + +static ssize_t show_enble(struct class *cls, + struct class_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", khadas_enble); +} + +static ssize_t store_enble(struct class *cls, struct class_attribute *attr, + const char *buf, size_t count) +{ + int enable; + + if (kstrtoint(buf, 0, &enable)){ + printk("khadas_enble error\n"); + return -EINVAL; + } + printk("khadas_enble=%d\n",enable); + khadas_enble = enable; + if(khadas_enble){ + mytimer.expires = jiffies + hw_margin * HZ/1000; // 500ms 运行一次 + mod_timer(&mytimer, mytimer.expires); + } + return count; +} + +static ssize_t store_pin_out(struct class *cls, struct class_attribute *attr, + const char *buf, size_t count) +{ + int enable; + + if (kstrtoint(buf, 0, &enable)){ + printk("khadas_pin_out error\n"); + return -EINVAL; + } + printk("khadas_pin_out=%d\n",enable); + gpio_direction_output(khadas_input_pin, enable); + return count; +} + +static struct class_attribute khadas_attrs[] = { + __ATTR(enble, 0644, show_enble, store_enble), + __ATTR(pin_out, 0644, NULL, store_pin_out), +}; + +static void create_khadas_attrs(void) +{ + int i; + struct class *khadas_class; + printk("%s\n",__func__); + khadas_class = class_create(THIS_MODULE, "khadas"); + if (IS_ERR(khadas_class)) { + pr_err("create khadas_class debug class fail\n"); + return; + } + for (i = 0; i < ARRAY_SIZE(khadas_attrs); i++) { + if (class_create_file(khadas_class, &khadas_attrs[i])) + pr_err("create khadas attribute %s fail\n", khadas_attrs[i].attr.name); + } +} + +static int wdt_probe(struct platform_device *pdev) +{ + const char *value; + int ret; + printk("hw_wdt enter probe\n"); + + ret = of_property_read_u32(pdev->dev.of_node,"hw_margin_ms", &hw_margin); + if (ret) + return ret; + + ret = of_property_read_string(pdev->dev.of_node, + "hw-gpios", &value); + if (ret) { + printk("no hw-gpios"); + return -1; + } else { + khadas_input_pin = of_get_named_gpio_flags + (pdev->dev.of_node, + "hw-gpios", + 0, NULL); + printk("hlm hw-gpios: %d.\n", khadas_input_pin); + ret = gpio_request(khadas_input_pin, "khadas"); + } + + timer_setup(&mytimer, time_pre, 0); + mytimer.expires = jiffies + hw_margin * HZ/1000; //// 5ms 运行一次 + add_timer(&mytimer); + create_khadas_attrs(); + return 0; +} + +static const struct of_device_id hw_khadas_wdt_dt_ids[] = { + { .compatible = "linux,wdt-khadas", }, + { } +}; +MODULE_DEVICE_TABLE(of, hw_khadas_wdt_dt_ids); + +static struct platform_driver khadas_wdt_driver = { + .driver = { + .name = "hw_khadas_wdt", + .of_match_table = hw_khadas_wdt_dt_ids, + }, + .probe = wdt_probe, +}; + +static int __init wdt_drv_init(void) +{ + return platform_driver_register(&khadas_wdt_driver); +} +arch_initcall(wdt_drv_init); + +MODULE_LICENSE("GPL");