• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
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 "stm32mp1_gpio.h"
17 
18 
ToMp1xxGpioCntlr(struct GpioCntlr * cntlr)19 static inline struct Mp1xxGpioCntlr *ToMp1xxGpioCntlr(struct GpioCntlr *cntlr)
20 {
21     return (struct Mp1xxGpioCntlr *)cntlr;
22 }
23 
Mp1xxToGroupNum(uint16_t gpio)24 static inline uint16_t Mp1xxToGroupNum(uint16_t gpio)
25 {
26     return (uint16_t)(gpio / g_Mp1xxGpioCntlr.bitNum);
27 }
28 
Mp1xxToBitNum(uint16_t gpio)29 static inline uint16_t Mp1xxToBitNum(uint16_t gpio)
30 {
31     return (uint16_t)(gpio % g_Mp1xxGpioCntlr.bitNum);
32 }
Mp1xxToGpioNum(uint16_t group,uint16_t bit)33 static inline uint16_t Mp1xxToGpioNum(uint16_t group, uint16_t bit)
34 {
35     return (uint16_t)(group * g_Mp1xxGpioCntlr.bitNum + bit);
36 }
37 
Mp1xxGetGroupByGpioNum(struct GpioCntlr * cntlr,uint16_t gpio,struct GpioGroup ** group)38 static int32_t Mp1xxGetGroupByGpioNum(struct GpioCntlr *cntlr, uint16_t gpio, struct GpioGroup **group)
39 {
40     struct Mp1xxGpioCntlr *stm32gpio = NULL;
41     uint16_t groupIndex = Mp1xxToGroupNum(gpio);
42 
43     if (cntlr == NULL || cntlr->priv == NULL) {
44         HDF_LOGE("%s: cntlr or priv is NULL", __func__);
45         return HDF_ERR_INVALID_OBJECT;
46     }
47     stm32gpio = ToMp1xxGpioCntlr(cntlr);
48     if (groupIndex >= stm32gpio->groupNum) {
49         HDF_LOGE("%s: err group index:%u", __func__, groupIndex);
50         return HDF_ERR_INVALID_PARAM;
51     }
52     *group = &stm32gpio->groups[groupIndex];
53     return HDF_SUCCESS;
54 }
55 
56 
Mp1xxGpioSetDir(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t dir)57 static int32_t Mp1xxGpioSetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t dir)
58 {
59     int32_t ret;
60 
61     unsigned int val;
62     volatile unsigned char *addr = NULL;
63 
64     unsigned int bitNum = Mp1xxToBitNum(gpio);
65     struct GpioGroup *group = NULL;
66 
67     ret = Mp1xxGetGroupByGpioNum(cntlr, gpio, &group);
68     if (ret != HDF_SUCCESS) {
69         HDF_LOGE("Mp1xxGetGroupByGpioNum failed\n");
70         return ret;
71     }
72 
73     if (OsalSpinLockIrqSave(&group->lock, &group->irqSave) != HDF_SUCCESS) {
74         HDF_LOGE("OsalSpinLockIrqSave failed\n");
75         return HDF_ERR_DEVICE_BUSY;
76     }
77     addr = STM32MP1XX_GPIO_MODER(group->regBase);
78     val = OSAL_READL(addr);
79     if (dir == GPIO_DIR_IN) {
80         val &= ~(0X3 << (bitNum * 2)); /* bit0:1 清零 */
81     } else if (dir == GPIO_DIR_OUT) {
82         val &= ~(0X3 << (bitNum * 2)); /* bit0:1 清零 */
83         val |= (0X1 << (bitNum * 2)); /* bit0:1 设置 01 */
84     }
85     OSAL_WRITEL(val, addr);
86     (void)OsalSpinUnlockIrqRestore(&group->lock, &group->irqSave);
87     return HDF_SUCCESS;
88 }
Mp1xxGpioGetDir(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t * dir)89 static int32_t Mp1xxGpioGetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *dir)
90 {
91     int32_t ret;
92     unsigned int val;
93     volatile unsigned char *addr = NULL;
94     unsigned int bitNum = Mp1xxToBitNum(gpio);
95     struct GpioGroup *group = NULL;
96 
97     ret = Mp1xxGetGroupByGpioNum(cntlr, gpio, &group);
98     if (ret != HDF_SUCCESS) {
99         return ret;
100     }
101 
102     addr = STM32MP1XX_GPIO_MODER(group->regBase);
103     val = OSAL_READL(addr);
104     if (val & (1 << (bitNum * 2))) {
105         *dir = GPIO_DIR_OUT;
106     } else {
107         *dir = GPIO_DIR_IN;
108     }
109     return HDF_SUCCESS;
110 }
Mp1xxGpioWrite(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t val)111 static int32_t Mp1xxGpioWrite(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t val)
112 {
113     int32_t ret;
114 
115     unsigned int valCur;
116     unsigned int bitNum = Mp1xxToBitNum(gpio);
117     volatile unsigned char *addr = NULL;
118     struct GpioGroup *group = NULL;
119 
120     ret = Mp1xxGetGroupByGpioNum(cntlr, gpio, &group);
121     if (ret != HDF_SUCCESS) {
122         return ret;
123     }
124     if (OsalSpinLockIrqSave(&group->lock, &group->irqSave) != HDF_SUCCESS) {
125         return HDF_ERR_DEVICE_BUSY;
126     }
127     addr = STM32MP1XX_GPIO_BSRR(group->regBase);
128     valCur = OSAL_READL(addr);
129     if (val == GPIO_VAL_LOW) {
130         valCur &= ~(0x1 << bitNum);
131         valCur |= (0x1 << (bitNum + 16));
132     } else {
133         valCur |= (0x1 << bitNum);
134     }
135     OSAL_WRITEL(valCur, addr);
136     (void)OsalSpinUnlockIrqRestore(&group->lock, &group->irqSave);
137 
138     return HDF_SUCCESS;
139 }
140 
Mp1xxGpioRead(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t * val)141 static int32_t Mp1xxGpioRead(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *val)
142 {
143     int32_t ret;
144     unsigned int valCur;
145     volatile unsigned char *addr = NULL;
146     unsigned int bitNum = Mp1xxToBitNum(gpio);
147     struct GpioGroup *group = NULL;
148 
149     ret = Mp1xxGetGroupByGpioNum(cntlr, gpio, &group);
150     if (ret != HDF_SUCCESS) {
151         return ret;
152     }
153 
154     addr = STM32MP1XX_GPIO_IDR(group->regBase);
155     valCur = OSAL_READL(addr);
156     if (valCur & (1 << bitNum)) {
157         *val = GPIO_VAL_HIGH;
158     } else {
159         *val = GPIO_VAL_LOW;
160     }
161     return HDF_SUCCESS;
162 }
163 
IrqHandleNoShare(uint32_t irq,void * data)164 static uint32_t IrqHandleNoShare(uint32_t irq, void *data)
165 {
166     unsigned int i;
167     (void)irq;
168     struct GpioGroup *group = (struct GpioGroup *)data;
169 
170     if (data == NULL) {
171         HDF_LOGW("%s: data is NULL!", __func__);
172         return HDF_ERR_INVALID_PARAM;
173     }
174     for (i = 0; i < g_Mp1xxGpioCntlr.bitNum; i++) {
175         if (__HAL_GPIO_EXTI_GET_IT(1 << i, group->exitBase) != 0) {
176             __HAL_GPIO_EXTI_CLEAR_IT(1 << i, group->exitBase);
177             GpioCntlrIrqCallback(&g_Mp1xxGpioCntlr.cntlr, Mp1xxToGpioNum(group->index, i));
178         }
179     }
180     return HDF_SUCCESS;
181 }
182 
GetGpioIrqNum(uint16_t pinNum)183 static uint32_t  GetGpioIrqNum(uint16_t pinNum)
184 {
185     if (pinNum > PIN_15) {
186         HDF_LOGE("%s: get gpio irq num fail!", __func__);
187         return 0;
188     }
189     switch (pinNum) {
190         case PIN_0:
191             return EXTI0_IRQn;
192             break;
193         case PIN_1:
194             return EXTI1_IRQn;
195             break;
196         case PIN_2:
197             return EXTI2_IRQn;
198             break;
199         case PIN_3:
200             return EXTI3_IRQn;
201             break;
202         case PIN_4:
203             return EXTI4_IRQn;
204             break;
205         case PIN_5:
206             return EXTI5_IRQn;
207             break;
208         case PIN_6:
209             return EXTI6_IRQn;
210             break;
211         case PIN_7:
212             return EXTI7_IRQn;
213             break;
214         case PIN_8:
215             return EXTI8_IRQn;
216             break;
217         case PIN_9:
218             return EXTI9_IRQn;
219             break;
220         case PIN_10:
221             return EXTI10_IRQn;
222             break;
223         case PIN_11:
224             return EXTI11_IRQn;
225             break;
226         case PIN_12:
227             return EXTI12_IRQn;
228             break;
229         case PIN_13:
230             return EXTI13_IRQn;
231             break;
232         case PIN_14:
233             return EXTI14_IRQn;
234             break;
235         case PIN_15:
236             return EXTI15_IRQn;
237             break;
238         default:
239             break;
240     }
241     return 0;
242 }
243 
GpioRegisterGroupIrqUnsafe(uint16_t pinNum,struct GpioGroup * group)244 static int32_t GpioRegisterGroupIrqUnsafe(uint16_t pinNum, struct GpioGroup *group)
245 {
246     int ret;
247 
248     ret = OsalRegisterIrq(GetGpioIrqNum(pinNum), 0, IrqHandleNoShare, "GPIO", group);
249     if (ret != 0) {
250         (void)OsalUnregisterIrq(GetGpioIrqNum(pinNum), group);
251         ret = OsalRegisterIrq(GetGpioIrqNum(pinNum), 0, IrqHandleNoShare, "GPIO", group);
252     }
253 
254     if (ret != 0) {
255         HDF_LOGE("%s: irq reg fail:%d!", __func__, ret);
256         return HDF_FAILURE;
257     }
258 
259     ret = OsalEnableIrq(GetGpioIrqNum(pinNum));
260     if (ret != 0) {
261         HDF_LOGE("%s: irq enable fail:%d!", __func__, ret);
262         (void)OsalUnregisterIrq(GetGpioIrqNum(pinNum), group);
263         return HDF_FAILURE;
264     }
265 
266     group->irqFunc = IrqHandleNoShare;
267 
268     return HDF_SUCCESS;
269 }
GpioClearIrqUnsafe(struct GpioGroup * group,uint16_t bitNum)270 static void GpioClearIrqUnsafe(struct GpioGroup *group, uint16_t bitNum)
271 {
272     __HAL_GPIO_EXTI_CLEAR_IT(bitNum, group->exitBase);
273 }
Mp1xxGpioSetIrq(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t mode)274 static int32_t Mp1xxGpioSetIrq(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t mode)
275 {
276     int32_t ret = HDF_SUCCESS;
277     struct GpioGroup *group = NULL;
278     unsigned int bitNum = Mp1xxToBitNum(gpio);
279 
280     ret = Mp1xxGetGroupByGpioNum(cntlr, gpio, &group);
281     if (ret != HDF_SUCCESS) {
282         return ret;
283     }
284     Mp1xxGpioSetDir(cntlr, gpio, GPIO_DIR_IN);
285 
286     if (OsalSpinLockIrqSave(&group->lock, &group->irqSave) != HDF_SUCCESS) {
287         return HDF_ERR_DEVICE_BUSY;
288     }
289 
290     EXTI_ConfigTypeDef EXTI_ConfigStructure;
291     EXTI_HandleTypeDef hexti;
292 
293     EXTI_ConfigStructure.Line = EXTI_GPIO | EXTI_EVENT | EXTI_REG1 | bitNum;
294     EXTI_ConfigStructure.Trigger = mode;
295     EXTI_ConfigStructure.GPIOSel = Mp1xxToGroupNum(gpio);
296     EXTI_ConfigStructure.Mode = EXTI_MODE_C1_INTERRUPT;
297 
298     HAL_EXTI_SetConfigLine(&hexti, &EXTI_ConfigStructure);
299     GpioClearIrqUnsafe(group, bitNum);        // clear irq on set
300     if (group->irqFunc != NULL) {
301         (void)OsalSpinUnlockIrqRestore(&group->lock, &group->irqSave);
302         HDF_LOGI("%s: group irq(%p) already registered!", __func__, group->irqFunc);
303         return HDF_SUCCESS;
304     }
305     ret = GpioRegisterGroupIrqUnsafe(bitNum, group);
306     (void)OsalSpinUnlockIrqRestore(&group->lock, &group->irqSave);
307     HDF_LOGI("%s: group irq(%p) registered!", __func__, group->irqFunc);
308     return ret;
309 }
310 
Mp1xxGpioUnsetIrq(struct GpioCntlr * cntlr,uint16_t gpio)311 static int32_t Mp1xxGpioUnsetIrq(struct GpioCntlr *cntlr, uint16_t gpio)
312 {
313     int32_t ret = HDF_SUCCESS;
314     (void)gpio;
315 
316     if (cntlr == NULL || cntlr->priv == NULL) {
317         HDF_LOGE("%s: GpioCntlr or cntlr.priv null!", __func__);
318         return HDF_ERR_INVALID_OBJECT;
319     }
320 
321     return ret;
322 }
323 
Mp1xxGpioEnableIrq(struct GpioCntlr * cntlr,uint16_t gpio)324 static int32_t Mp1xxGpioEnableIrq(struct GpioCntlr *cntlr, uint16_t gpio)
325 {
326     int32_t ret = HDF_SUCCESS;
327     struct GpioGroup *group = NULL;
328     unsigned int bitNum = Mp1xxToBitNum(gpio);
329 
330     if (cntlr == NULL || cntlr->priv == NULL) {
331         HDF_LOGE("%s: GpioCntlr or cntlr.priv null!", __func__);
332         return HDF_ERR_INVALID_OBJECT;
333     }
334 
335     ret = Mp1xxGetGroupByGpioNum(cntlr, gpio, &group);
336     if (ret != HDF_SUCCESS) {
337         HDF_LOGE("Mp1xxGetGroupByGpioNum failed\n");
338         return ret;
339     }
340 
341     EXTI_ConfigTypeDef EXTI_ConfigStructure;
342     EXTI_HandleTypeDef hexti;
343 
344     Mp1xxGpioSetDir(cntlr, gpio, GPIO_DIR_IN);
345 
346     EXTI_ConfigStructure.Line = EXTI_GPIO | EXTI_EVENT | EXTI_REG1 | bitNum;
347     EXTI_ConfigStructure.Trigger = EXTI_TRIGGER_FALLING;
348     EXTI_ConfigStructure.GPIOSel = Mp1xxToGroupNum(gpio);
349     EXTI_ConfigStructure.Mode = EXTI_MODE_C1_INTERRUPT;
350 
351     HAL_EXTI_SetConfigLine(&hexti, &EXTI_ConfigStructure);
352 
353     return ret;
354 }
355 
Mp1xxGpioDisableIrq(struct GpioCntlr * cntlr,uint16_t gpio)356 static int32_t Mp1xxGpioDisableIrq(struct GpioCntlr *cntlr, uint16_t gpio)
357 {
358     int32_t ret = HDF_SUCCESS;
359 
360     if (cntlr == NULL || cntlr->priv == NULL) {
361         HDF_LOGE("%s: GpioCntlr or cntlr.priv null!", __func__);
362         return HDF_ERR_INVALID_OBJECT;
363     }
364     struct GpioGroup *group = NULL;
365 
366     ret = Mp1xxGetGroupByGpioNum(cntlr, gpio, &group);
367     if (ret != HDF_SUCCESS) {
368         HDF_LOGE("Mp1xxGetGroupByGpioNum failed\n");
369         return ret;
370     }
371 
372     EXTI_HandleTypeDef hexti;
373     HAL_EXTI_ClearConfigLine(&hexti);
374 
375     return ret;
376 }
377 /* GpioMethod definition */
378 struct GpioMethod g_GpioMethod = {
379     .request = NULL,
380     .release = NULL,
381     .write = Mp1xxGpioWrite,
382     .read = Mp1xxGpioRead,
383     .setDir = Mp1xxGpioSetDir,
384     .getDir = Mp1xxGpioGetDir,
385     .toIrq = NULL,
386     .setIrq = Mp1xxGpioSetIrq,
387     .unsetIrq = Mp1xxGpioUnsetIrq,
388     .enableIrq = Mp1xxGpioEnableIrq,
389     .disableIrq = Mp1xxGpioDisableIrq,
390 };
391 
Mp1xxGpioReadDrs(struct Mp1xxGpioCntlr * stm32gpio,const struct DeviceResourceNode * node)392 static int32_t Mp1xxGpioReadDrs(struct Mp1xxGpioCntlr *stm32gpio, const struct DeviceResourceNode *node)
393 {
394     int32_t ret;
395     struct DeviceResourceIface *drsOps = NULL;
396 
397     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
398     if (drsOps == NULL || drsOps->GetUint32 == NULL) {
399         HDF_LOGE("%s: invalid drs ops fail!", __func__);
400         return HDF_FAILURE;
401     }
402 
403     ret = drsOps->GetUint32(node, "gpioRegBase", &stm32gpio->gpioPhyBase, 0);
404     if (ret != HDF_SUCCESS) {
405         HDF_LOGE("%s: read regBase fail!", __func__);
406         return ret;
407     }
408 
409     ret = drsOps->GetUint32(node, "gpioRegStep", &stm32gpio->gpioRegStep, 0);
410     if (ret != HDF_SUCCESS) {
411         HDF_LOGE("%s: read gpioRegStep fail!", __func__);
412         return ret;
413     }
414 
415     ret = drsOps->GetUint16(node, "groupNum", &stm32gpio->groupNum, 0);
416     if (ret != HDF_SUCCESS) {
417         HDF_LOGE("%s: read groupNum fail!", __func__);
418         return ret;
419     }
420 
421     ret = drsOps->GetUint16(node, "bitNum", &stm32gpio->bitNum, 0);
422     if (ret != HDF_SUCCESS) {
423         HDF_LOGE("%s: read bitNum fail!", __func__);
424         return ret;
425     }
426 
427     ret = drsOps->GetUint32(node, "irqRegBase", &stm32gpio->irqPhyBase, 0);
428     if (ret != HDF_SUCCESS) {
429         HDF_LOGE("%s: read regBase fail!", __func__);
430         return ret;
431     }
432 
433     ret = drsOps->GetUint32(node, "irqRegStep", &stm32gpio->iqrRegStep, 0);
434     if (ret != HDF_SUCCESS) {
435         HDF_LOGE("%s: read gpioRegStep fail!", __func__);
436         return ret;
437     }
438     return HDF_SUCCESS;
439 }
440 
InitGpioCntlrMem(struct Mp1xxGpioCntlr * cntlr)441 static int32_t InitGpioCntlrMem(struct Mp1xxGpioCntlr *cntlr)
442 {
443     size_t groupMemSize;
444     struct GpioGroup *groups = NULL;
445 
446     if (cntlr == NULL) {
447         return HDF_ERR_INVALID_PARAM;
448     }
449 
450     groupMemSize = sizeof(struct GpioGroup) * cntlr->groupNum;
451     groups = (struct GpioGroup *)OsalMemCalloc(groupMemSize);
452     if (groups == NULL) {
453         return HDF_ERR_MALLOC_FAIL;
454     }
455     cntlr->groups = groups;
456 
457     for (uint16_t i = 0; i < cntlr->groupNum; i++) {
458         groups[i].index = i;
459         groups[i].regBase = cntlr->regBase + (i * cntlr->gpioRegStep);
460         groups[i].exitBase = cntlr->exitBase;
461         if (OsalSpinInit(&groups[i].lock) != HDF_SUCCESS) {
462             for (; i > 0; i--) {
463                 (void)OsalSpinDestroy(&groups[i - 1].lock);
464             }
465             OsalMemFree(groups);
466             return HDF_FAILURE;
467         }
468     }
469     return HDF_SUCCESS;
470 }
471 
ReleaseGpioCntlrMem(struct Mp1xxGpioCntlr * cntlr)472 static void ReleaseGpioCntlrMem(struct Mp1xxGpioCntlr *cntlr)
473 {
474     if (cntlr == NULL) {
475         return;
476     }
477     if (cntlr->groups != NULL) {
478         for (uint16_t i = 0; i < cntlr->groupNum; i++) {
479             (void)OsalSpinDestroy(&cntlr->groups[i].lock);
480         }
481         OsalMemFree(cntlr->groups);
482         cntlr->groups = NULL;
483     }
484 }
485 
486 /* HdfDriverEntry hook function implementations */
GpioDriverBind(struct HdfDeviceObject * device)487 static int32_t GpioDriverBind(struct HdfDeviceObject *device)
488 {
489     (void)device;
490     return HDF_SUCCESS;
491 }
492 
GpioDriverInit(struct HdfDeviceObject * device)493 static int32_t GpioDriverInit(struct HdfDeviceObject *device)
494 {
495     int32_t ret;
496     struct Mp1xxGpioCntlr *stm32gpio = &g_Mp1xxGpioCntlr;
497 
498     dprintf("%s: Enter", __func__);
499     if (device == NULL || device->property == NULL) {
500         HDF_LOGE("%s: device or property NULL!", __func__);
501         return HDF_ERR_INVALID_OBJECT;
502     }
503     // 获取属性数据
504     ret = Mp1xxGpioReadDrs(stm32gpio, device->property);
505     if (ret != HDF_SUCCESS) {
506         HDF_LOGE("%s: get gpio device resource fail:%d", __func__, ret);
507         return ret;
508     }
509 
510     if (stm32gpio->groupNum > GROUP_MAX || stm32gpio->groupNum <= 0 || stm32gpio->bitNum > BIT_MAX ||
511         stm32gpio->bitNum <= 0) {
512         HDF_LOGE("%s: invalid groupNum:%u or bitNum:%u", __func__, stm32gpio->groupNum,
513                  stm32gpio->bitNum);
514         return HDF_ERR_INVALID_PARAM;
515     }
516     // 寄存器地址映射
517     stm32gpio->regBase = OsalIoRemap(stm32gpio->gpioPhyBase, stm32gpio->groupNum * stm32gpio->gpioRegStep);
518     if (stm32gpio->regBase == NULL) {
519         HDF_LOGE("%s: err remap phy:0x%x", __func__, stm32gpio->gpioPhyBase);
520         return HDF_ERR_IO;
521     }
522     /* OsalIoRemap: remap registers */
523     stm32gpio->exitBase = OsalIoRemap(stm32gpio->irqPhyBase, stm32gpio->iqrRegStep);
524     if (stm32gpio->exitBase == NULL) {
525         dprintf("%s: OsalIoRemap fail!", __func__);
526         return -1;
527     }
528 
529     ret = InitGpioCntlrMem(stm32gpio);
530     if (ret != HDF_SUCCESS) {
531         HDF_LOGE("%s: err init cntlr mem:%d", __func__, ret);
532         OsalIoUnmap((void *)stm32gpio->regBase);
533         stm32gpio->regBase = NULL;
534         return ret;
535     }
536     stm32gpio->cntlr.count = stm32gpio->groupNum * stm32gpio->bitNum;
537     stm32gpio->cntlr.priv = (void *)device->property;
538     stm32gpio->cntlr.ops = &g_GpioMethod;
539     ret = GpioCntlrAdd(&stm32gpio->cntlr);
540     if (ret != HDF_SUCCESS) {
541         HDF_LOGE("%s: err add controller: %d", __func__, ret);
542         return ret;
543     }
544     HDF_LOGE("%s: dev service:%s init success!", __func__, HdfDeviceGetServiceName(device));
545     return ret;
546 }
547 
GpioDriverRelease(struct HdfDeviceObject * device)548 static void GpioDriverRelease(struct HdfDeviceObject *device)
549 {
550     struct GpioCntlr *gpioCntlr = NULL;
551     struct Mp1xxGpioCntlr *stm32gpioGpioCntlr = NULL;
552 
553     HDF_LOGD("%s: Enter", __func__);
554     if (device == NULL) {
555         HDF_LOGE("%s: device is null!", __func__);
556         return;
557     }
558 
559     GpioCntlrRemove(gpioCntlr);
560 
561     stm32gpioGpioCntlr = (struct Mp1xxGpioCntlr *)gpioCntlr;
562     ReleaseGpioCntlrMem(stm32gpioGpioCntlr);
563     OsalIoUnmap((void *)stm32gpioGpioCntlr->regBase);
564     stm32gpioGpioCntlr->regBase = NULL;
565 }
566 
567 /* HdfDriverEntry definition */
568 struct HdfDriverEntry g_GpioDriverEntry = {
569     .moduleVersion = 1,
570     .moduleName = "HDF_PLATFORM_GPIO",
571     .Bind = GpioDriverBind,
572     .Init = GpioDriverInit,
573     .Release = GpioDriverRelease,
574 };
575 
576 /* Init HdfDriverEntry */
577 HDF_INIT(g_GpioDriverEntry);