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(const struct WatchdogDevice * watchdogDevice)45 static int InitWatchdogDevice(const 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 OsalMemFree(watchdogDevice);
208 return;
209 }
210
WatchdogDevStart(struct WatchdogCntlr * watchdogCntlr)211 static int32_t WatchdogDevStart(struct WatchdogCntlr *watchdogCntlr)
212 {
213 struct WatchdogDevice *watchdogDevice = NULL;
214 int32_t watchdogId;
215
216 if (watchdogCntlr == NULL || watchdogCntlr->priv == NULL) {
217 HDF_LOGE("%s: watchdogCntlr is NULL\r\n", __func__);
218 return HDF_ERR_INVALID_PARAM;
219 }
220
221 watchdogDevice = (struct WatchdogDevice *)watchdogCntlr->priv;
222 watchdogId = watchdogDevice->resource.watchdogId;
223 hal_wdt_start(watchdogId);
224 g_watchdogStart = 1;
225 return HDF_SUCCESS;
226 }
227
WatchdogDevStop(struct WatchdogCntlr * watchdogCntlr)228 static int32_t WatchdogDevStop(struct WatchdogCntlr *watchdogCntlr)
229 {
230 int32_t watchdogId;
231 struct WatchdogDevice *watchdogDevice = NULL;
232
233 if (watchdogCntlr == NULL || watchdogCntlr->priv == NULL) {
234 HDF_LOGE("%s: watchdogCntlr is NULL\r\n", __func__);
235 return HDF_FAILURE;
236 }
237
238 watchdogDevice = (struct WatchdogDevice *)watchdogCntlr->priv;
239 watchdogId = watchdogDevice->resource.watchdogId;
240 hal_wdt_stop(watchdogId);
241 g_watchdogStart = 0;
242 return HDF_SUCCESS;
243 }
244
WatchdogDevSetTimeout(struct WatchdogCntlr * watchdogCntlr,uint32_t seconds)245 static int32_t WatchdogDevSetTimeout(struct WatchdogCntlr *watchdogCntlr, uint32_t seconds)
246 {
247 int32_t watchdogId;
248 struct WatchdogDevice *watchdogDevice = NULL;
249
250 if (watchdogCntlr == NULL || watchdogCntlr->priv == NULL) {
251 HDF_LOGE("%s: watchdogCntlr is NULL\r\n", __func__);
252 return HDF_ERR_INVALID_PARAM;
253 }
254 g_watchdogTimeout = seconds;
255 watchdogDevice = (struct WatchdogDevice *)watchdogCntlr->priv;
256 watchdogId = watchdogDevice->resource.watchdogId;
257 hal_wdt_set_timeout(watchdogId, seconds);
258 return HDF_SUCCESS;
259 }
260
WatchdogDevGetTimeout(struct WatchdogCntlr * watchdogCntlr,uint32_t * seconds)261 static int32_t WatchdogDevGetTimeout(struct WatchdogCntlr *watchdogCntlr, uint32_t *seconds)
262 {
263 if (watchdogCntlr == NULL || seconds == NULL) {
264 HDF_LOGE("%s: PARAM is NULL\r\n", __func__);
265 return HDF_ERR_INVALID_PARAM;
266 }
267 *seconds = g_watchdogTimeout;
268 return HDF_SUCCESS;
269 }
270
WatchdogDevGetStatus(struct WatchdogCntlr * watchdogCntlr,uint32_t * status)271 static int32_t WatchdogDevGetStatus(struct WatchdogCntlr *watchdogCntlr, uint32_t *status)
272 {
273 if (watchdogCntlr == NULL || status == NULL) {
274 HDF_LOGE("%s: PARAM is NULL\r\n", __func__);
275 return HDF_ERR_INVALID_PARAM;
276 }
277 if (g_watchdogStart == 1) {
278 *status = WATCHDOG_START;
279 } else {
280 *status = WATCHDOG_STOP;
281 }
282 return HDF_SUCCESS;
283 }
284
WatchdogDevFeed(struct WatchdogCntlr * watchdogCntlr)285 static int32_t WatchdogDevFeed(struct WatchdogCntlr *watchdogCntlr)
286 {
287 struct WatchdogDevice *watchdogDevice = NULL;
288
289 if (watchdogCntlr == NULL || watchdogCntlr->priv == NULL) {
290 HDF_LOGE("%s: watchdogCntlr is NULL\r\n", __func__);
291 return HDF_ERR_INVALID_PARAM;
292 }
293
294 watchdogDevice = (struct WatchdogDevice *)watchdogCntlr->priv;
295 int32_t watchdogId = watchdogDevice->resource.watchdogId;
296 hal_wdt_ping(watchdogId);
297 return HDF_SUCCESS;
298 }
299
WatchdogDevGetPriv(struct WatchdogCntlr * watchdogCntlr)300 static int32_t WatchdogDevGetPriv(struct WatchdogCntlr *watchdogCntlr)
301 {
302 (void)watchdogCntlr;
303 return HDF_SUCCESS;
304 }
305
WatchdogDevReleasePriv(struct WatchdogCntlr * watchdogCntlr)306 static int32_t WatchdogDevReleasePriv(struct WatchdogCntlr *watchdogCntlr)
307 {
308 (void)watchdogCntlr;
309 return HDF_SUCCESS;
310 }
311