• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3  *
4  * HDF 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_core.h"
10 #include "hdf_log.h"
11 #include "watchdog_if.h"
12 
13 #define HDF_LOG_TAG watchdog_core
14 
15 static int32_t WatchdogIoDispatch(struct HdfDeviceIoClient *client, int cmd,
16     struct HdfSBuf *data, struct HdfSBuf *reply);
WatchdogCntlrAdd(struct WatchdogCntlr * cntlr)17 int32_t WatchdogCntlrAdd(struct WatchdogCntlr *cntlr)
18 {
19     int32_t ret;
20 
21     if (cntlr == NULL) {
22         return HDF_ERR_INVALID_OBJECT;
23     }
24 
25     if (cntlr->device == NULL) {
26         HDF_LOGE("WatchdogCntlrAdd: no device associated!");
27         return HDF_ERR_INVALID_OBJECT;
28     }
29 
30     if (cntlr->ops == NULL) {
31         HDF_LOGE("WatchdogCntlrAdd: no ops supplied!");
32         return HDF_ERR_INVALID_OBJECT;
33     }
34 
35     ret = OsalSpinInit(&cntlr->lock);
36     if (ret != HDF_SUCCESS) {
37         HDF_LOGE("WatchdogCntlrAdd: spinlock init fail!");
38         return ret;
39     }
40 
41     cntlr->device->service = &cntlr->service;
42     cntlr->device->service->Dispatch = WatchdogIoDispatch;
43     return HDF_SUCCESS;
44 }
45 
WatchdogCntlrRemove(struct WatchdogCntlr * cntlr)46 void WatchdogCntlrRemove(struct WatchdogCntlr *cntlr)
47 {
48     if (cntlr == NULL) {
49         return;
50     }
51 
52     if (cntlr->device == NULL) {
53         HDF_LOGE("WatchdogCntlrRemove: no device associated!");
54         return;
55     }
56 
57     cntlr->device->service = NULL;
58     (void)OsalSpinDestroy(&cntlr->lock);
59 }
60 
WatchdogGetPrivData(struct WatchdogCntlr * cntlr)61 int32_t WatchdogGetPrivData(struct WatchdogCntlr *cntlr)
62 {
63     if (cntlr == NULL || cntlr->ops == NULL) {
64         return HDF_ERR_INVALID_OBJECT;
65     }
66     if (cntlr->ops->getPriv != NULL) {
67         return cntlr->ops->getPriv(cntlr);
68     }
69     return HDF_SUCCESS;
70 }
71 
WatchdogReleasePriv(struct WatchdogCntlr * cntlr)72 int32_t WatchdogReleasePriv(struct WatchdogCntlr *cntlr)
73 {
74     if (cntlr == NULL || cntlr->ops == NULL) {
75         HDF_LOGE("cntlr or cntlr->ops is null");
76         return HDF_SUCCESS;
77     }
78     if (cntlr->ops->releasePriv != NULL) {
79         cntlr->ops->releasePriv(cntlr);
80     }
81     return HDF_SUCCESS;
82 }
83 
WatchdogCntlrGetStatus(struct WatchdogCntlr * cntlr,int32_t * status)84 int32_t WatchdogCntlrGetStatus(struct WatchdogCntlr *cntlr, int32_t *status)
85 {
86     int32_t ret;
87     uint32_t flags;
88 
89     if (cntlr == NULL) {
90         return HDF_ERR_INVALID_OBJECT;
91     }
92     if (cntlr->ops == NULL || cntlr->ops->getStatus == NULL) {
93         return HDF_ERR_NOT_SUPPORT;
94     }
95     if (status == NULL) {
96         return HDF_ERR_INVALID_PARAM;
97     }
98 
99     if (OsalSpinLockIrqSave(&cntlr->lock, &flags) != HDF_SUCCESS) {
100         return HDF_ERR_DEVICE_BUSY;
101     }
102     ret = cntlr->ops->getStatus(cntlr, status);
103     if (ret != HDF_SUCCESS) {
104         HDF_LOGE("%s:getStatus fail", __func__);
105         return ret;
106     }
107     (void)OsalSpinUnlockIrqRestore(&cntlr->lock, &flags);
108     return ret;
109 }
110 
WatchdogCntlrStart(struct WatchdogCntlr * cntlr)111 int32_t WatchdogCntlrStart(struct WatchdogCntlr *cntlr)
112 {
113     int32_t ret;
114     uint32_t flags;
115 
116     if (cntlr == NULL) {
117         return HDF_ERR_INVALID_OBJECT;
118     }
119     if (cntlr->ops == NULL || cntlr->ops->start == NULL) {
120         return HDF_ERR_NOT_SUPPORT;
121     }
122 
123     if (OsalSpinLockIrqSave(&cntlr->lock, &flags) != HDF_SUCCESS) {
124         return HDF_ERR_DEVICE_BUSY;
125     }
126     ret = cntlr->ops->start(cntlr);
127     (void)OsalSpinUnlockIrqRestore(&cntlr->lock, &flags);
128     return ret;
129 }
130 
WatchdogCntlrStop(struct WatchdogCntlr * cntlr)131 int32_t WatchdogCntlrStop(struct WatchdogCntlr *cntlr)
132 {
133     int32_t ret;
134     uint32_t flags;
135 
136     if (cntlr == NULL) {
137         return HDF_ERR_INVALID_OBJECT;
138     }
139     if (cntlr->ops == NULL || cntlr->ops->stop == NULL) {
140         return HDF_ERR_NOT_SUPPORT;
141     }
142 
143     if (OsalSpinLockIrqSave(&cntlr->lock, &flags) != HDF_SUCCESS) {
144         return HDF_ERR_DEVICE_BUSY;
145     }
146     ret = cntlr->ops->stop(cntlr);
147     (void)OsalSpinUnlockIrqRestore(&cntlr->lock, &flags);
148     return ret;
149 }
150 
WatchdogCntlrSetTimeout(struct WatchdogCntlr * cntlr,uint32_t seconds)151 int32_t WatchdogCntlrSetTimeout(struct WatchdogCntlr *cntlr, uint32_t seconds)
152 {
153     int32_t ret;
154     uint32_t flags;
155 
156     if (cntlr == NULL) {
157         return HDF_ERR_INVALID_OBJECT;
158     }
159     if (cntlr->ops == NULL || cntlr->ops->setTimeout == NULL) {
160         return HDF_ERR_NOT_SUPPORT;
161     }
162 
163     if (OsalSpinLockIrqSave(&cntlr->lock, &flags) != HDF_SUCCESS) {
164         return HDF_ERR_DEVICE_BUSY;
165     }
166     ret = cntlr->ops->setTimeout(cntlr, seconds);
167     (void)OsalSpinUnlockIrqRestore(&cntlr->lock, &flags);
168     return ret;
169 }
170 
WatchdogCntlrGetTimeout(struct WatchdogCntlr * cntlr,uint32_t * seconds)171 int32_t WatchdogCntlrGetTimeout(struct WatchdogCntlr *cntlr, uint32_t *seconds)
172 {
173     int32_t ret;
174     uint32_t flags;
175 
176     if (cntlr == NULL) {
177         return HDF_ERR_INVALID_OBJECT;
178     }
179     if (cntlr->ops == NULL || cntlr->ops->getTimeout == NULL) {
180         return HDF_ERR_NOT_SUPPORT;
181     }
182     if (seconds == NULL) {
183         return HDF_ERR_INVALID_PARAM;
184     }
185 
186     if (OsalSpinLockIrqSave(&cntlr->lock, &flags) != HDF_SUCCESS) {
187         return HDF_ERR_DEVICE_BUSY;
188     }
189     ret = cntlr->ops->getTimeout(cntlr, seconds);
190     (void)OsalSpinUnlockIrqRestore(&cntlr->lock, &flags);
191     return ret;
192 }
193 
WatchdogCntlrFeed(struct WatchdogCntlr * cntlr)194 int32_t WatchdogCntlrFeed(struct WatchdogCntlr *cntlr)
195 {
196     int32_t ret;
197     uint32_t flags;
198 
199     if (cntlr == NULL) {
200         return HDF_ERR_INVALID_OBJECT;
201     }
202     if (cntlr->ops == NULL || cntlr->ops->feed == NULL) {
203         return HDF_ERR_NOT_SUPPORT;
204     }
205 
206     if (OsalSpinLockIrqSave(&cntlr->lock, &flags) != HDF_SUCCESS) {
207         return HDF_ERR_DEVICE_BUSY;
208     }
209     ret = cntlr->ops->feed(cntlr);
210     (void)OsalSpinUnlockIrqRestore(&cntlr->lock, &flags);
211     return ret;
212 }
213 
WatchdogUserGetPrivData(struct WatchdogCntlr * cntlr,struct HdfSBuf * reply)214 static int32_t WatchdogUserGetPrivData(struct WatchdogCntlr *cntlr, struct HdfSBuf *reply)
215 {
216     int32_t ret;
217     if (reply == NULL) {
218         HDF_LOGE("%s: invalid param", __func__);
219         return HDF_ERR_INVALID_OBJECT;
220     }
221     ret = WatchdogGetPrivData(cntlr);
222     if (!HdfSbufWriteInt32(reply, ret)) {
223         HDF_LOGE("%s: sbuf write buffer failed", __func__);
224         return HDF_ERR_IO;
225     }
226     return HDF_SUCCESS;
227 }
228 
WatchdogUserGetStatus(struct WatchdogCntlr * cntlr,struct HdfSBuf * reply)229 static int32_t WatchdogUserGetStatus(struct WatchdogCntlr *cntlr, struct HdfSBuf *reply)
230 {
231     int32_t ret;
232     int32_t status;
233 
234     if (reply == NULL) {
235         HDF_LOGE("%s: invalid param", __func__);
236         return HDF_ERR_INVALID_OBJECT;
237     }
238     ret = WatchdogCntlrGetStatus(cntlr, &status);
239     if (ret != HDF_SUCCESS) {
240         HDF_LOGE("%s: WatchdogCntlrGetStatus failed, ret: %d", __func__, ret);
241         return ret;
242     }
243     if (!HdfSbufWriteInt32(reply, status)) {
244         HDF_LOGE("%s: sbuf write status failed", __func__);
245         return HDF_ERR_IO;
246     }
247     return HDF_SUCCESS;
248 }
249 
WatchdogUserSetTimeout(struct WatchdogCntlr * cntlr,struct HdfSBuf * data)250 static int32_t WatchdogUserSetTimeout(struct WatchdogCntlr *cntlr, struct HdfSBuf *data)
251 {
252     uint32_t seconds;
253 
254     if (data == NULL) {
255         HDF_LOGE("%s: invalid param", __func__);
256         return HDF_ERR_INVALID_OBJECT;
257     }
258 
259     if (!HdfSbufReadUint32(data, &seconds)) {
260         HDF_LOGE("%s: sbuf read seconds failed", __func__);
261         return HDF_ERR_IO;
262     }
263 
264     return WatchdogCntlrSetTimeout(cntlr, seconds);
265 }
266 
WatchdogUserGetTimeout(struct WatchdogCntlr * cntlr,struct HdfSBuf * reply)267 static int32_t WatchdogUserGetTimeout(struct WatchdogCntlr *cntlr, struct HdfSBuf *reply)
268 {
269     int32_t ret;
270     uint32_t seconds;
271     if (reply == NULL) {
272         HDF_LOGE("%s: invalid param", __func__);
273         return HDF_ERR_INVALID_OBJECT;
274     }
275     ret = WatchdogCntlrGetTimeout(cntlr, &seconds);
276     if (ret != HDF_SUCCESS) {
277         HDF_LOGE("%s: WatchdogCntlrGetTimeout failed, ret: %d", __func__, ret);
278         return ret;
279     }
280 
281     if (!HdfSbufWriteUint32(reply, seconds)) {
282         HDF_LOGE("%s: sbuf write buffer failed", __func__);
283         return HDF_ERR_IO;
284     }
285     return HDF_SUCCESS;
286 }
287 
WatchdogIoDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)288 static int32_t WatchdogIoDispatch(struct HdfDeviceIoClient *client, int cmd,
289     struct HdfSBuf *data, struct HdfSBuf *reply)
290 {
291     struct WatchdogCntlr *cntlr = NULL;
292 
293     if (client == NULL) {
294         HDF_LOGE("%s: client is NULL", __func__);
295         return HDF_ERR_INVALID_OBJECT;
296     }
297     if (client->device == NULL) {
298         HDF_LOGE("%s: client->device is NULL", __func__);
299         return HDF_ERR_INVALID_OBJECT;
300     }
301     if (client->device->service == NULL) {
302         HDF_LOGE("%s: client->device->service is NULL", __func__);
303         return HDF_ERR_INVALID_OBJECT;
304     }
305 
306     cntlr = (struct WatchdogCntlr *)client->device->service;
307     switch (cmd) {
308         case WATCHDOG_IO_GET_PRIV:
309             return WatchdogUserGetPrivData(cntlr, reply);
310         case WATCHDOG_IO_RELEASE_PRIV:
311             return WatchdogReleasePriv(cntlr);
312         case WATCHDOG_IO_GET_STATUS:
313             return WatchdogUserGetStatus(cntlr, reply);
314         case WATCHDOG_IO_START:
315             return WatchdogCntlrStart(cntlr);
316         case WATCHDOG_IO_STOP:
317             return WatchdogCntlrStop(cntlr);
318         case WATCHDOG_IO_SET_TIMEOUT:
319             return WatchdogUserSetTimeout(cntlr, data);
320         case WATCHDOG_IO_GET_TIMEOUT:
321             return WatchdogUserGetTimeout(cntlr, reply);
322         case WATCHDOG_IO_FEED:
323             return WatchdogCntlrFeed(cntlr);
324         default:
325             HDF_LOGE("%s: cmd %d not support", __func__, cmd);
326             return HDF_ERR_NOT_SUPPORT;
327     }
328 }
329