1 /*
2 * Copyright (c) 2021-2022 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
3 *
4 * This file is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "watchdog_bes.h"
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include "device_resource_if.h"
13 #include "hdf_device_desc.h"
14 #include "hdf_log.h"
15 #include "hal_trace.h"
16 #include "hal_sleep.h"
17 #include "watchdog_if.h"
18
19 static int g_watchdogStart;
20 static int g_watchdogTimeout;
21
22 static int32_t WatchdogDevStart(struct WatchdogCntlr *watchdogCntlr);
23 static int32_t WatchdogDevStop(struct WatchdogCntlr *watchdogCntlr);
24 static int32_t WatchdogDevSetTimeout(struct WatchdogCntlr *watchdogCntlr, uint32_t seconds);
25 static int32_t WatchdogDevGetTimeout(struct WatchdogCntlr *watchdogCntlr, uint32_t *seconds);
26 static int32_t WatchdogDevGetStatus(struct WatchdogCntlr *watchdogCntlr, uint32_t *status);
27 static int32_t WatchdogDevFeed(struct WatchdogCntlr *watchdogCntlr);
28
29 struct WatchdogMethod g_WatchdogCntlrMethod = {
30 .getStatus = WatchdogDevGetStatus,
31 .setTimeout = WatchdogDevSetTimeout,
32 .getTimeout = WatchdogDevGetTimeout,
33 .start = WatchdogDevStart,
34 .stop = WatchdogDevStop,
35 .feed = WatchdogDevFeed,
36 .getPriv = NULL, // WatchdogDevGetPriv
37 .releasePriv = NULL, // WatchdogDevReleasePriv
38 };
39
WatchdogIrqHandler(enum HAL_WDT_ID_T id,enum HAL_WDT_EVENT_T event)40 static void WatchdogIrqHandler(enum HAL_WDT_ID_T id, enum HAL_WDT_EVENT_T event)
41 {
42 HDF_LOGD("%s: id %d event %d\r\n", __func__, id, event);
43 }
44
InitWatchdogDevice(struct WatchdogDevice * watchdogDevice)45 static int InitWatchdogDevice(struct WatchdogDevice *watchdogDevice)
46 {
47 struct WatchdogResource *resource = NULL;
48 int32_t watchdogId;
49 if (watchdogDevice == NULL) {
50 HDF_LOGE("%s: invalid parameter\r\n", __func__);
51 return HDF_ERR_INVALID_PARAM;
52 }
53
54 resource = &watchdogDevice->resource;
55 if (resource == NULL) {
56 HDF_LOGE("resource is NULL\r\n");
57 return HDF_ERR_INVALID_OBJECT;
58 }
59
60 watchdogId = resource->watchdogId;
61 hal_wdt_set_irq_callback(watchdogId, WatchdogIrqHandler);
62 return HDF_SUCCESS;
63 }
64
GetWatchdogDeviceResource(struct WatchdogDevice * device,const struct DeviceResourceNode * resourceNode)65 static uint32_t GetWatchdogDeviceResource(
66 struct WatchdogDevice *device, const struct DeviceResourceNode *resourceNode)
67 {
68 struct WatchdogResource *resource = NULL;
69 struct DeviceResourceIface *dri = NULL;
70 if (device == NULL || resourceNode == NULL) {
71 HDF_LOGE("resource or device is NULL\r\n");
72 return HDF_ERR_INVALID_PARAM;
73 }
74
75 resource = &device->resource;
76 if (resource == NULL) {
77 HDF_LOGE("resource is NULL\r\n");
78 return HDF_ERR_INVALID_OBJECT;
79 }
80
81 dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
82 if (dri == NULL || dri->GetUint32 == NULL) {
83 HDF_LOGE("DeviceResourceIface is invalid\r\n");
84 return HDF_ERR_INVALID_OBJECT;
85 }
86 if (dri->GetUint32(resourceNode, "watchdogId", &resource->watchdogId, 0) != HDF_SUCCESS) {
87 HDF_LOGE("read watchdogId fail\r\n");
88 return HDF_FAILURE;
89 }
90 return HDF_SUCCESS;
91 }
92
AttachWatchdogDevice(struct WatchdogCntlr * watchdogCntlr,struct HdfDeviceObject * device)93 static int32_t AttachWatchdogDevice(struct WatchdogCntlr *watchdogCntlr, struct HdfDeviceObject *device)
94 {
95 int32_t ret;
96 struct WatchdogDevice *watchdogDevice = NULL;
97
98 if (device == NULL || device->property == NULL) {
99 HDF_LOGE("%s: param is NULL\r\n", __func__);
100 return HDF_FAILURE;
101 }
102
103 watchdogDevice = (struct WatchdogDevice *)OsalMemAlloc(sizeof(struct WatchdogDevice));
104 if (watchdogDevice == NULL) {
105 HDF_LOGE("%s: OsalMemAlloc watchdogDevice error\r\n", __func__);
106 return HDF_ERR_MALLOC_FAIL;
107 }
108
109 ret = GetWatchdogDeviceResource(watchdogDevice, device->property);
110 if (ret != HDF_SUCCESS) {
111 (void)OsalMemFree(watchdogDevice);
112 return HDF_FAILURE;
113 }
114
115 watchdogCntlr->priv = watchdogDevice;
116 watchdogCntlr->wdtId = watchdogDevice->resource.watchdogId;
117
118 return InitWatchdogDevice(watchdogDevice);
119 }
120 /* HdfDriverEntry method definitions */
121 static int32_t WatchdogDriverBind(struct HdfDeviceObject *device);
122 static int32_t WatchdogDriverInit(struct HdfDeviceObject *device);
123 static void WatchdogDriverRelease(struct HdfDeviceObject *device);
124
125 /* HdfDriverEntry definitions */
126 struct HdfDriverEntry g_watchdogDriverEntry = {
127 .moduleVersion = 1,
128 .moduleName = "BES_WATCHDOG_MODULE_HDF",
129 .Bind = WatchdogDriverBind,
130 .Init = WatchdogDriverInit,
131 .Release = WatchdogDriverRelease,
132 };
133
134 // Initialize HdfDriverEntry
135 HDF_INIT(g_watchdogDriverEntry);
136
WatchdogDriverBind(struct HdfDeviceObject * device)137 static int32_t WatchdogDriverBind(struct HdfDeviceObject *device)
138 {
139 struct WatchdogCntlr *watchdogCntlr = NULL;
140
141 if (device == NULL) {
142 HDF_LOGE("hdfDevice object is null!\r\n");
143 return HDF_FAILURE;
144 }
145
146 watchdogCntlr = (struct WatchdogCntlr *)OsalMemAlloc(sizeof(struct WatchdogCntlr));
147 if (watchdogCntlr == NULL) {
148 HDF_LOGE("%s: OsalMemAlloc watchdogCntlr error\r\n", __func__);
149 return HDF_ERR_MALLOC_FAIL;
150 }
151
152 HDF_LOGI("Enter %s\r\n", __func__);
153 device->service = &watchdogCntlr->service;
154 watchdogCntlr->device = device;
155 watchdogCntlr->priv = NULL;
156 return HDF_SUCCESS;
157 }
158
WatchdogDriverInit(struct HdfDeviceObject * device)159 static int32_t WatchdogDriverInit(struct HdfDeviceObject *device)
160 {
161 int32_t ret;
162 struct WatchdogCntlr *watchdogCntlr = NULL;
163
164 if (device == NULL) {
165 HDF_LOGE("%s: device is NULL\r\n", __func__);
166 return HDF_ERR_INVALID_OBJECT;
167 }
168
169 HDF_LOGI("Enter %s:\r\n", __func__);
170
171 watchdogCntlr = WatchdogCntlrFromDevice(device);
172 if (watchdogCntlr == NULL) {
173 HDF_LOGE("%s: watchdogCntlr is NULL\r\n", __func__);
174 return HDF_ERR_INVALID_PARAM;
175 }
176
177 ret = AttachWatchdogDevice(watchdogCntlr, device);
178 if (ret != HDF_SUCCESS) {
179 OsalMemFree(watchdogCntlr);
180 HDF_LOGE("%s:attach error\r\n", __func__);
181 return HDF_ERR_INVALID_PARAM;
182 }
183
184 watchdogCntlr->ops = &g_WatchdogCntlrMethod;
185
186 HDF_LOGE("WatchdogDriverInit success!\r\n");
187 return ret;
188 }
189
WatchdogDriverRelease(struct HdfDeviceObject * device)190 static void WatchdogDriverRelease(struct HdfDeviceObject *device)
191 {
192 struct WatchdogCntlr *watchdogCntlr = NULL;
193 struct WatchdogDevice *watchdogDevice = NULL;
194
195 if (device == NULL) {
196 HDF_LOGE("device is null\r\n");
197 return;
198 }
199
200 watchdogCntlr = WatchdogCntlrFromDevice(device);
201 if (watchdogCntlr == NULL || watchdogCntlr->priv == NULL) {
202 HDF_LOGE("%s: watchdogCntlr is NULL\r\n", __func__);
203 return HDF_ERR_INVALID_PARAM;
204 }
205
206 watchdogDevice = (struct WatchdogDevice *)watchdogCntlr->priv;
207 if (watchdogDevice != NULL) {
208 OsalMemFree(watchdogDevice);
209 }
210 return;
211 }
212
WatchdogDevStart(struct WatchdogCntlr * watchdogCntlr)213 static int32_t WatchdogDevStart(struct WatchdogCntlr *watchdogCntlr)
214 {
215 struct WatchdogDevice *watchdogDevice = NULL;
216 int32_t watchdogId;
217 if (watchdogCntlr == NULL || watchdogCntlr->priv == NULL) {
218 HDF_LOGE("%s: watchdogCntlr is NULL\r\n", __func__);
219 return HDF_ERR_INVALID_PARAM;
220 }
221
222 watchdogDevice = (struct WatchdogDevice *)watchdogCntlr->priv;
223 if (watchdogDevice == NULL) {
224 HDF_LOGE("%s: OBJECT is NULL\r\n", __func__);
225 return HDF_ERR_INVALID_OBJECT;
226 }
227 watchdogId = watchdogDevice->resource.watchdogId;
228
229 hal_wdt_start(watchdogId);
230 g_watchdogStart = 1;
231 return HDF_SUCCESS;
232 }
233
WatchdogDevStop(struct WatchdogCntlr * watchdogCntlr)234 static int32_t WatchdogDevStop(struct WatchdogCntlr *watchdogCntlr)
235 {
236 int32_t watchdogId;
237 struct WatchdogDevice *watchdogDevice = NULL;
238
239 if (watchdogCntlr == NULL || watchdogCntlr->priv == NULL) {
240 HDF_LOGE("%s: watchdogCntlr is NULL\r\n", __func__);
241 return HDF_FAILURE;
242 }
243
244 watchdogDevice = (struct WatchdogDevice *)watchdogCntlr->priv;
245 if (watchdogDevice == NULL) {
246 HDF_LOGE("%s: OBJECT is NULL\r\n", __func__);
247 return HDF_ERR_INVALID_OBJECT;
248 }
249 watchdogId = watchdogDevice->resource.watchdogId;
250 hal_wdt_stop(watchdogId);
251 g_watchdogStart = 0;
252 return HDF_SUCCESS;
253 }
254
WatchdogDevSetTimeout(struct WatchdogCntlr * watchdogCntlr,uint32_t seconds)255 static int32_t WatchdogDevSetTimeout(struct WatchdogCntlr *watchdogCntlr, uint32_t seconds)
256 {
257 int32_t watchdogId;
258 struct WatchdogDevice *watchdogDevice = NULL;
259 if (watchdogCntlr == NULL || watchdogCntlr->priv == NULL) {
260 HDF_LOGE("%s: watchdogCntlr is NULL\r\n", __func__);
261 return HDF_ERR_INVALID_PARAM;
262 }
263 g_watchdogTimeout = seconds;
264 watchdogDevice = (struct WatchdogDevice *)watchdogCntlr->priv;
265 if (watchdogDevice == NULL) {
266 HDF_LOGE("%s: OBJECT is NULL\r\n", __func__);
267 return HDF_ERR_INVALID_OBJECT;
268 }
269 watchdogId = watchdogDevice->resource.watchdogId;
270 hal_wdt_set_timeout(watchdogId, seconds);
271 return HDF_SUCCESS;
272 }
273
WatchdogDevGetTimeout(struct WatchdogCntlr * watchdogCntlr,uint32_t * seconds)274 static int32_t WatchdogDevGetTimeout(struct WatchdogCntlr *watchdogCntlr, uint32_t *seconds)
275 {
276 if (watchdogCntlr == NULL || seconds == NULL) {
277 HDF_LOGE("%s: PARAM is NULL\r\n", __func__);
278 return HDF_ERR_INVALID_PARAM;
279 }
280 *seconds = g_watchdogTimeout;
281 return HDF_SUCCESS;
282 }
283
WatchdogDevGetStatus(struct WatchdogCntlr * watchdogCntlr,uint32_t * status)284 static int32_t WatchdogDevGetStatus(struct WatchdogCntlr *watchdogCntlr, uint32_t *status)
285 {
286 if (watchdogCntlr == NULL || status == NULL) {
287 HDF_LOGE("%s: PARAM is NULL\r\n", __func__);
288 return HDF_ERR_INVALID_PARAM;
289 }
290 if (g_watchdogStart == 1) {
291 *status = WATCHDOG_START;
292 } else {
293 *status = WATCHDOG_STOP;
294 }
295 return HDF_SUCCESS;
296 }
297
WatchdogDevFeed(struct WatchdogCntlr * watchdogCntlr)298 static int32_t WatchdogDevFeed(struct WatchdogCntlr *watchdogCntlr)
299 {
300 struct WatchdogDevice *watchdogDevice = NULL;
301
302 if (watchdogCntlr == NULL || watchdogCntlr->priv == NULL) {
303 HDF_LOGE("%s: watchdogCntlr is NULL\r\n", __func__);
304 return HDF_ERR_INVALID_PARAM;
305 }
306
307 watchdogDevice = (struct WatchdogDevice *)watchdogCntlr->priv;
308 int32_t watchdogId = watchdogDevice->resource.watchdogId;
309 hal_wdt_ping(watchdogId);
310 return HDF_SUCCESS;
311 }
312
WatchdogDevGetPriv(struct WatchdogCntlr * watchdogCntlr)313 static int32_t WatchdogDevGetPriv(struct WatchdogCntlr *watchdogCntlr)
314 {
315 (void)watchdogCntlr;
316 return HDF_SUCCESS;
317 }
318
WatchdogDevReleasePriv(struct WatchdogCntlr * watchdogCntlr)319 static int32_t WatchdogDevReleasePriv(struct WatchdogCntlr *watchdogCntlr)
320 {
321 (void)watchdogCntlr;
322 return HDF_SUCCESS;
323 }
324