1 /*
2 * Copyright (c) 2022 Jiangsu Hoperun Software Co., Ltd.
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 <stdlib.h>
10 #include <stdio.h>
11 #include "device_resource_if.h"
12 #include "hdf_device_desc.h"
13 #include "hdf_log.h"
14 #include "watchdog_if.h"
15 #include "watchdog_core.h"
16 #include "wm_regs.h"
17 #include "wm_cpu.h"
18
19 struct WatchdogResource {
20 int32_t watchdogId;
21 };
22
23 struct WatchdogDevice {
24 struct WatchdogResource resource;
25 };
26
27 static int g_watchdogStart;
28 static int g_watchdogTimeout;
29
30 static int32_t WatchdogDevStart(struct WatchdogCntlr *watchdogCntlr);
31 static int32_t WatchdogDevSetTimeout(struct WatchdogCntlr *watchdogCntlr, uint32_t seconds);
32 static int32_t WatchdogDevGetTimeout(struct WatchdogCntlr *watchdogCntlr, uint32_t *seconds);
33 static int32_t WatchdogDevGetStatus(struct WatchdogCntlr *watchdogCntlr, uint32_t *status);
34 static int32_t WatchdogDevFeed(struct WatchdogCntlr *watchdogCntlr);
35
36 struct WatchdogMethod g_WatchdogCntlrMethod = {
37 .getStatus = WatchdogDevGetStatus,
38 .setTimeout = WatchdogDevSetTimeout,
39 .getTimeout = WatchdogDevGetTimeout,
40 .start = WatchdogDevStart,
41 .stop = NULL, // WatchdogDevStop
42 .feed = WatchdogDevFeed,
43 .getPriv = NULL, // WatchdogDevGetPriv
44 .releasePriv = NULL, // WatchdogDevReleasePriv
45 };
46
WatchdogDevStart(struct WatchdogCntlr * watchdogCntlr)47 static int32_t WatchdogDevStart(struct WatchdogCntlr *watchdogCntlr)
48 {
49 tls_watchdog_start_cal_elapsed_time();
50 g_watchdogStart = 1;
51 return HDF_SUCCESS;
52 }
53
WatchdogDevSetTimeout(struct WatchdogCntlr * watchdogCntlr,uint32_t seconds)54 static int32_t WatchdogDevSetTimeout(struct WatchdogCntlr *watchdogCntlr, uint32_t seconds)
55 {
56 g_watchdogTimeout = seconds;
57 tls_watchdog_init(seconds);
58 return HDF_SUCCESS;
59 }
60
WatchdogDevGetTimeout(struct WatchdogCntlr * watchdogCntlr,uint32_t * seconds)61 static int32_t WatchdogDevGetTimeout(struct WatchdogCntlr *watchdogCntlr, uint32_t *seconds)
62 {
63 if (watchdogCntlr == NULL || seconds == NULL) {
64 HDF_LOGE("%s: PARAM is NULL\r\n", __func__);
65 return HDF_ERR_INVALID_PARAM;
66 }
67
68 g_watchdogTimeout = tls_watchdog_stop_cal_elapsed_time();
69
70 *seconds = g_watchdogTimeout;
71 return HDF_SUCCESS;
72 }
73
WatchdogDevGetStatus(struct WatchdogCntlr * watchdogCntlr,uint32_t * status)74 static int32_t WatchdogDevGetStatus(struct WatchdogCntlr *watchdogCntlr, uint32_t *status)
75 {
76 if (watchdogCntlr == NULL || status == NULL) {
77 HDF_LOGE("%s: PARAM is NULL\r\n", __func__);
78 return HDF_ERR_INVALID_PARAM;
79 }
80 if (g_watchdogStart == 1) {
81 *status = WATCHDOG_START;
82 } else {
83 *status = WATCHDOG_STOP;
84 }
85 return HDF_SUCCESS;
86 }
87
WatchdogDevFeed(struct WatchdogCntlr * watchdogCntlr)88 static int32_t WatchdogDevFeed(struct WatchdogCntlr *watchdogCntlr)
89 {
90 tls_sys_clk sysclk;
91
92 tls_sys_clk_get(&sysclk);
93 if (g_watchdogStart == 1) {
94 tls_sys_reset();
95 }
96 return HDF_SUCCESS;
97 }
98
InitWatchdogDevice(struct WatchdogDevice * watchdogDevice)99 static int InitWatchdogDevice(struct WatchdogDevice *watchdogDevice)
100 {
101 struct WatchdogResource *resource = NULL;
102 if (watchdogDevice == NULL) {
103 HDF_LOGE("%s: invaild parameter\r\n", __func__);
104 return HDF_ERR_INVALID_PARAM;
105 }
106
107 resource = &watchdogDevice->resource;
108 if (resource == NULL) {
109 HDF_LOGE("resource is NULL\r\n");
110 return HDF_ERR_INVALID_OBJECT;
111 }
112
113 return HDF_SUCCESS;
114 }
115
GetWatchdogDeviceResource(struct WatchdogDevice * device,const struct DeviceResourceNode * resourceNode)116 static uint32_t GetWatchdogDeviceResource(
117 struct WatchdogDevice *device, const struct DeviceResourceNode *resourceNode)
118 {
119 struct WatchdogResource *resource = NULL;
120 struct DeviceResourceIface *dri = NULL;
121 if (device == NULL || resourceNode == NULL) {
122 HDF_LOGE("resource or device is NULL\r\n");
123 return HDF_ERR_INVALID_PARAM;
124 }
125
126 resource = &device->resource;
127 if (resource == NULL) {
128 HDF_LOGE("resource is NULL\r\n");
129 return HDF_ERR_INVALID_OBJECT;
130 }
131
132 dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
133 if (dri == NULL || dri->GetUint32 == NULL) {
134 HDF_LOGE("DeviceResourceIface is invalid\r\n");
135 return HDF_ERR_INVALID_OBJECT;
136 }
137
138 return HDF_SUCCESS;
139 }
140
AttachWatchdogDevice(struct WatchdogCntlr * watchdogCntlr,struct HdfDeviceObject * device)141 static int32_t AttachWatchdogDevice(struct WatchdogCntlr *watchdogCntlr, struct HdfDeviceObject *device)
142 {
143 int32_t ret;
144 struct WatchdogDevice *watchdogDevice = NULL;
145
146 if (device == NULL || device->property == NULL) {
147 HDF_LOGE("%s: param is NULL\r\n", __func__);
148 return HDF_FAILURE;
149 }
150
151 watchdogDevice = (struct WatchdogDevice *)OsalMemAlloc(sizeof(struct WatchdogDevice));
152 if (watchdogDevice == NULL) {
153 HDF_LOGE("%s: OsalMemAlloc watchdogDevice error\r\n", __func__);
154 return HDF_ERR_MALLOC_FAIL;
155 }
156
157 ret = GetWatchdogDeviceResource(watchdogDevice, device->property);
158 if (ret != HDF_SUCCESS) {
159 (void)OsalMemFree(watchdogDevice);
160 return HDF_FAILURE;
161 }
162
163 watchdogCntlr->priv = watchdogDevice;
164
165 return InitWatchdogDevice(watchdogDevice);
166 }
167
168 /* HdfDriverEntry method definitions */
169 static int32_t WatchdogDriverBind(struct HdfDeviceObject *device);
170 static int32_t WatchdogDriverInit(struct HdfDeviceObject *device);
171 static void WatchdogDriverRelease(struct HdfDeviceObject *device);
172
WatchdogDriverBind(struct HdfDeviceObject * device)173 static int32_t WatchdogDriverBind(struct HdfDeviceObject *device)
174 {
175 struct WatchdogCntlr *watchdogCntlr = NULL;
176
177 if (device == NULL) {
178 HDF_LOGE("hdfDevice object is null!\r\n");
179 return HDF_FAILURE;
180 }
181
182 watchdogCntlr = (struct WatchdogCntlr *)OsalMemAlloc(sizeof(struct WatchdogCntlr));
183 if (watchdogCntlr == NULL) {
184 HDF_LOGE("%s: OsalMemAlloc watchdogCntlr error\r\n", __func__);
185 return HDF_ERR_MALLOC_FAIL;
186 }
187
188 HDF_LOGI("Enter %s\r\n", __func__);
189 device->service = &watchdogCntlr->service;
190 watchdogCntlr->device = device;
191 watchdogCntlr->priv = NULL;
192 return HDF_SUCCESS;
193 }
194
WatchdogDriverInit(struct HdfDeviceObject * device)195 static int32_t WatchdogDriverInit(struct HdfDeviceObject *device)
196 {
197 int32_t ret;
198 struct WatchdogCntlr *watchdogCntlr = NULL;
199
200 if (device == NULL) {
201 HDF_LOGE("%s: device is NULL\r\n", __func__);
202 return HDF_ERR_INVALID_OBJECT;
203 }
204
205 HDF_LOGI("Enter %s:\r\n", __func__);
206
207 watchdogCntlr = WatchdogCntlrFromDevice(device);
208 if (watchdogCntlr == NULL) {
209 HDF_LOGE("%s: watchdogCntlr is NULL\r\n", __func__);
210 return HDF_ERR_INVALID_PARAM;
211 }
212
213 ret = AttachWatchdogDevice(watchdogCntlr, device);
214 if (ret != HDF_SUCCESS) {
215 OsalMemFree(watchdogCntlr);
216 HDF_LOGE("%s:attach error\r\n", __func__);
217 return HDF_ERR_INVALID_PARAM;
218 }
219
220 watchdogCntlr->ops = &g_WatchdogCntlrMethod;
221
222 HDF_LOGE("WatchdogDriverInit success!\r\n");
223 return ret;
224 }
225
WatchdogDriverRelease(struct HdfDeviceObject * device)226 static void WatchdogDriverRelease(struct HdfDeviceObject *device)
227 {
228 struct WatchdogCntlr *watchdogCntlr = NULL;
229 struct WatchdogDevice *watchdogDevice = NULL;
230
231 if (device == NULL) {
232 HDF_LOGE("device is null\r\n");
233 return;
234 }
235
236 watchdogCntlr = WatchdogCntlrFromDevice(device);
237 if (watchdogCntlr == NULL || watchdogCntlr->priv == NULL) {
238 HDF_LOGE("%s: watchdogCntlr is NULL\r\n", __func__);
239 return HDF_ERR_INVALID_PARAM;
240 }
241
242 watchdogDevice = (struct WatchdogDevice *)watchdogCntlr->priv;
243 OsalMemFree(watchdogDevice);
244 return;
245 }
246
247 /* HdfDriverEntry definitions */
248 struct HdfDriverEntry g_watchdogDriverEntry = {
249 .moduleVersion = 1,
250 .moduleName = "WM_WATCHDOG_MODULE_HDF",
251 .Bind = WatchdogDriverBind,
252 .Init = WatchdogDriverInit,
253 .Release = WatchdogDriverRelease,
254 };
255
256 // Initialize HdfDriverEntry
257 HDF_INIT(g_watchdogDriverEntry);
258