• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 HPMicro
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include "device_resource_if.h"
19 #include "hdf_device_desc.h"
20 #include "hdf_log.h"
21 #include "osal_mem.h"
22 #include "watchdog_if.h"
23 #include "watchdog_core.h"
24 #include "hpm_wdg_drv.h"
25 
26 #define HDF_LOG_TAG HPMICRO_WATCHDOG_HDF
27 
28 struct HPMWatchdogDevice {
29     uint32_t id;
30     uint32_t base;
31     int32_t status;
32     uint32_t timeoutSeconds;
33 };
34 
GetStatus(struct WatchdogCntlr * wdt,int32_t * status)35 static int32_t GetStatus(struct WatchdogCntlr *wdt, int32_t *status)
36 {
37     struct HPMWatchdogDevice *hpmDev = (struct HPMWatchdogDevice *)wdt->priv;
38     *status = hpmDev->status;
39     HDF_LOGD("ID: %u, GetStatus: %d\n", hpmDev->id, *status);
40     return HDF_SUCCESS;
41 }
42 
SetTimeout(struct WatchdogCntlr * wdt,uint32_t seconds)43 static int32_t SetTimeout(struct WatchdogCntlr *wdt, uint32_t seconds)
44 {
45     struct HPMWatchdogDevice *hpmDev = (struct HPMWatchdogDevice *)wdt->priv;
46 
47     hpmDev->timeoutSeconds = seconds;
48     HDF_LOGD("ID: %u, SetTimeout: %d\n",hpmDev->id, seconds);
49     return HDF_SUCCESS;
50 }
51 
GetTimeout(struct WatchdogCntlr * wdt,uint32_t * seconds)52 static int32_t GetTimeout(struct WatchdogCntlr *wdt, uint32_t *seconds)
53 {
54     struct HPMWatchdogDevice *hpmDev = (struct HPMWatchdogDevice *)wdt->priv;
55 
56     *seconds = hpmDev->timeoutSeconds;
57     HDF_LOGD("ID: %u, GetTimeout: %d\n",hpmDev->id, *seconds);
58     return HDF_SUCCESS;
59 }
60 
Start(struct WatchdogCntlr * wdt)61 static int32_t Start(struct WatchdogCntlr *wdt)
62 {
63     struct HPMWatchdogDevice *hpmDev = (struct HPMWatchdogDevice *)wdt->priv;
64     WDG_Type *base = (WDG_Type *)hpmDev->base;
65     uint32_t timeoutUs = hpmDev->timeoutSeconds * 1000000;
66     uint32_t interruptUs;
67     uint32_t interruptInterval;
68     uint32_t resetUs;
69     uint32_t resetInterval;
70     wdg_control_t wdgCfg;
71 
72     interruptInterval = wdg_convert_interrupt_interval_from_us(WDG_EXT_CLK_FREQ, timeoutUs);
73     wdgCfg.reset_interval = 0;
74     wdgCfg.interrupt_interval = interruptInterval;
75     wdgCfg.reset_enable = 1;
76     wdgCfg.interrupt_enable = 0;
77     wdgCfg.clksrc = wdg_clksrc_extclk;
78     wdgCfg.wdg_enable = 0;
79     wdg_init(base, &wdgCfg);
80 
81     /*
82      * To calculate high precision "reset_interval"
83      */
84     interruptUs = wdg_get_interrupt_interval_in_us(base, WDG_EXT_CLK_FREQ);
85     if (interruptUs > timeoutUs) {
86         resetUs = 0;
87         resetInterval = 0;
88     } else {
89         resetUs = timeoutUs - interruptUs;
90         resetInterval = wdg_convert_reset_interval_from_us(WDG_EXT_CLK_FREQ, resetUs);
91     }
92 
93     wdgCfg.reset_interval = resetInterval;
94     wdgCfg.wdg_enable = 1;
95     wdg_init(base, &wdgCfg);
96 
97     hpmDev->status = WATCHDOG_START;
98     HDF_LOGD("ID: %u, Start", hpmDev->id);
99     return HDF_SUCCESS;
100 }
101 
Stop(struct WatchdogCntlr * wdt)102 static int32_t Stop(struct WatchdogCntlr *wdt)
103 {
104     struct HPMWatchdogDevice *hpmDev = (struct HPMWatchdogDevice *)wdt->priv;
105     WDG_Type *base = (WDG_Type *)hpmDev->base;
106     wdg_disable(base);
107     hpmDev->status = WATCHDOG_STOP;
108     HDF_LOGD("ID: %u, Stop", hpmDev->id);
109     return HDF_SUCCESS;
110 }
111 
Feed(struct WatchdogCntlr * wdt)112 static int32_t Feed(struct WatchdogCntlr *wdt)
113 {
114     struct HPMWatchdogDevice *hpmDev = (struct HPMWatchdogDevice *)wdt->priv;
115     WDG_Type *base = (WDG_Type *)hpmDev->base;
116     wdg_restart(base);
117     return HDF_SUCCESS;
118 }
119 
120 static struct WatchdogMethod watchdogOps = {
121     .getStatus = GetStatus,
122     .setTimeout = SetTimeout,
123     .getTimeout = GetTimeout,
124     .start = Start,
125     .stop = Stop,
126     .feed = Feed,
127 };
128 
WatchdogDriverBind(struct HdfDeviceObject * device)129 static int32_t WatchdogDriverBind(struct HdfDeviceObject *device)
130 {
131     int32_t ret = HDF_SUCCESS;
132     struct WatchdogCntlr *watchdogCntlr;
133 
134     if (device == NULL) {
135         ret = HDF_FAILURE;
136         HDF_LOGE("Bind: HdfDeviceObject null\n");
137         return ret;
138     }
139 
140     watchdogCntlr = (struct WatchdogCntlr *)OsalMemCalloc(sizeof(struct WatchdogCntlr));
141     if (watchdogCntlr == NULL) {
142         ret = HDF_ERR_MALLOC_FAIL;
143         HDF_LOGE("Bind: Services malloc Failed!!!\n");
144         return ret;
145     }
146 
147     watchdogCntlr->device = device;
148     watchdogCntlr->ops = &watchdogOps;
149 
150     ret = WatchdogCntlrAdd(watchdogCntlr);
151     if (ret) {
152         HDF_LOGE("Bind: WatchdogCntlrAdd Failed: %d!!!\n", ret);
153         OsalMemFree(watchdogCntlr);
154         return ret;
155     }
156 
157     HDF_LOGI("Bind: successed\n");
158     return ret;
159 }
160 
WatchdogDriverInit(struct HdfDeviceObject * device)161 static int32_t WatchdogDriverInit(struct HdfDeviceObject *device)
162 {
163     int32_t ret = HDF_SUCCESS;
164 
165     struct WatchdogCntlr *watchdogCntlr = WatchdogCntlrFromDevice(device);
166     if (watchdogCntlr == NULL) {
167         ret = HDF_FAILURE;
168         HDF_LOGE("Init: get WatchdogCntlr Failed!!!\n");
169         goto ERROR1;
170     }
171 
172     struct HPMWatchdogDevice *hpmWdtDev = (struct HPMWatchdogDevice *)OsalMemCalloc(
173                                         sizeof(struct HPMWatchdogDevice));
174     if (hpmWdtDev == NULL) {
175         ret = HDF_ERR_MALLOC_FAIL;
176         HDF_LOGE("Init: HPMWatchdogDevice malloc Failed!!!\n");
177         goto ERROR1;
178     }
179 
180     struct DeviceResourceIface *dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
181     if (dri == NULL) {
182         ret = HDF_FAILURE;
183         HDF_LOGE("Init: get DeviceResourceIface Failed!!!\n");
184         goto ERROR2;
185     }
186 
187     dri->GetUint32(device->property, "id", &hpmWdtDev->id, 0);
188     dri->GetUint32(device->property, "base", &hpmWdtDev->base, 0);
189     HDF_LOGI("Init: hpmWdtDev->id: %u\n", hpmWdtDev->id);
190     HDF_LOGI("Init: hpmWdtDev->base: 0x%X\n", hpmWdtDev->base);
191 
192     watchdogCntlr->wdtId = hpmWdtDev->id;
193     watchdogCntlr->priv = hpmWdtDev;
194 
195     return ret;
196 
197 ERROR2:
198     OsalMemFree(hpmWdtDev);
199 ERROR1:
200     return ret;
201 }
202 
WatchdogDriverRelease(struct HdfDeviceObject * device)203 static void WatchdogDriverRelease(struct HdfDeviceObject *device)
204 {
205     if (device == NULL) {
206         return;
207     }
208 
209     struct WatchdogCntlr *watchdogCntlr = WatchdogCntlrFromDevice(device);
210     if (watchdogCntlr) {
211         OsalMemFree(watchdogCntlr);
212     }
213     HDF_LOGI("Release");
214     return;
215 }
216 
217 
218 struct HdfDriverEntry g_watchdogDriverEntry = {
219     .moduleVersion = 1,
220     .moduleName = "HPMICRO_WATCHDOG_MODULE_HDF",
221     .Bind = WatchdogDriverBind,
222     .Init = WatchdogDriverInit,
223     .Release = WatchdogDriverRelease,
224 };
225 
226 HDF_INIT(g_watchdogDriverEntry);