hc
2024-08-19 eb6b9ee90f50f13c5abb885ce483802d6262f2b5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//#define DEBUG
 
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/module.h>
#include <linux/device.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
 
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");