1 /*
2 * sdio_adapter.c
3 *
4 * linux sdio driver implement.
5 *
6 * Copyright (c) 2020-2023 Huawei Device Co., Ltd.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19 #include <linux/mmc/card.h>
20 #include <linux/mmc/core.h>
21 #include <linux/mmc/host.h>
22 #include <linux/mmc/sdio_func.h>
23 #include "device_resource_if.h"
24 #include "mmc_corex.h"
25 #include "mmc_sdio.h"
26
27 #define HDF_LOG_TAG sdio_adapter_c
28
29 #define DATA_LEN_ONE_BYTE 1
30 #define DATA_LEN_TWO_BYTES 2
31 #define DATA_LEN_FOUR_BYTES 4
32 #define MMC_SLOT_NUM 3
33 #define SDIO_RESCAN_WAIT_TIME 40
34
35 struct mmc_host *GetMmcHost(int32_t slot);
36 void SdioRescan(int32_t slot);
37
38 enum SleepTime {
39 MS_10 = 10,
40 MS_50 = 50,
41 };
42
LinuxSdioGetFunc(const struct SdioDevice * dev)43 static struct sdio_func *LinuxSdioGetFunc(const struct SdioDevice *dev)
44 {
45 if (dev == NULL) {
46 HDF_LOGE("LinuxSdioGetFunc: dev is null.");
47 return NULL;
48 }
49 return (struct sdio_func *)dev->sd.mmc.priv;
50 }
51
LinuxSdioIncrAddrReadBytes(struct SdioDevice * dev,uint8_t * data,uint32_t addr,uint32_t size)52 static int32_t LinuxSdioIncrAddrReadBytes(struct SdioDevice *dev,
53 uint8_t *data, uint32_t addr, uint32_t size)
54 {
55 struct sdio_func *func = LinuxSdioGetFunc(dev);
56 int32_t ret = HDF_SUCCESS;
57 uint16_t *output16 = NULL;
58 uint32_t *output32 = NULL;
59
60 if (func == NULL) {
61 HDF_LOGE("LinuxSdioIncrAddrReadBytes: func is NULL.");
62 return HDF_ERR_INVALID_OBJECT;
63 }
64 if ((data == NULL) || (size == 0)) {
65 HDF_LOGE("LinuxSdioIncrAddrReadBytes: data or size is invalid.");
66 return HDF_ERR_INVALID_PARAM;
67 }
68
69 if (size == DATA_LEN_ONE_BYTE) {
70 *data = sdio_readb(func, addr, &ret);
71 return ret;
72 }
73 if (size == DATA_LEN_TWO_BYTES) {
74 output16 = (uint16_t *)data;
75 *output16 = sdio_readw(func, addr, &ret);
76 return ret;
77 }
78 if (size == DATA_LEN_FOUR_BYTES) {
79 output32 = (uint32_t *)data;
80 *output32 = sdio_readl(func, addr, &ret);
81 return ret;
82 }
83 return sdio_memcpy_fromio(func, data, addr, size);
84 }
85
LinuxSdioIncrAddrWriteBytes(struct SdioDevice * dev,uint8_t * data,uint32_t addr,uint32_t size)86 static int32_t LinuxSdioIncrAddrWriteBytes(struct SdioDevice *dev,
87 uint8_t *data, uint32_t addr, uint32_t size)
88 {
89 int32_t ret = HDF_SUCCESS;
90 struct sdio_func *func = LinuxSdioGetFunc(dev);
91
92 if (func == NULL) {
93 HDF_LOGE("LinuxSdioIncrAddrWriteBytes: func is NULL.");
94 return HDF_ERR_INVALID_OBJECT;
95 }
96 if ((data == NULL) || (size == 0)) {
97 HDF_LOGE("LinuxSdioIncrAddrWriteBytes: data or size is invalid.");
98 return HDF_ERR_INVALID_PARAM;
99 }
100
101 if (size == DATA_LEN_ONE_BYTE) {
102 sdio_writeb(func, *data, addr, &ret);
103 return ret;
104 }
105 if (size == DATA_LEN_TWO_BYTES) {
106 sdio_writew(func, *(uint16_t *)data, addr, &ret);
107 return ret;
108 }
109 if (size == DATA_LEN_FOUR_BYTES) {
110 sdio_writel(func, *(uint32_t *)data, addr, &ret);
111 return ret;
112 }
113 return sdio_memcpy_toio(func, addr, data, size);
114 }
115
LinuxSdioFixedAddrReadBytes(struct SdioDevice * dev,uint8_t * data,uint32_t addr,uint32_t size,uint32_t scatterLen)116 static int32_t LinuxSdioFixedAddrReadBytes(struct SdioDevice *dev,
117 uint8_t *data, uint32_t addr, uint32_t size, uint32_t scatterLen)
118 {
119 struct sdio_func *func = LinuxSdioGetFunc(dev);
120
121 if (func == NULL) {
122 HDF_LOGE("LinuxSdioFixedAddrReadBytes: func is NULL.");
123 return HDF_ERR_INVALID_OBJECT;
124 }
125 if ((data == NULL) || (size == 0)) {
126 HDF_LOGE("LinuxSdioFixedAddrReadBytes: data or size is invalid.");
127 return HDF_ERR_INVALID_PARAM;
128 }
129
130 if (scatterLen > 0) {
131 HDF_LOGE("LinuxSdioFixedAddrReadBytes: not support!");
132 return HDF_ERR_NOT_SUPPORT;
133 }
134 return sdio_readsb(func, data, addr, size);
135 }
136
LinuxSdioFixedAddrWriteBytes(struct SdioDevice * dev,uint8_t * data,uint32_t addr,uint32_t size,uint32_t scatterLen)137 static int32_t LinuxSdioFixedAddrWriteBytes(struct SdioDevice *dev,
138 uint8_t *data, uint32_t addr, uint32_t size, uint32_t scatterLen)
139 {
140 struct sdio_func *func = LinuxSdioGetFunc(dev);
141
142 if (func == NULL) {
143 HDF_LOGE("LinuxSdioFixedAddrWriteBytes: func is NULL.");
144 return HDF_ERR_INVALID_OBJECT;
145 }
146 if ((data == NULL) || (size == 0)) {
147 HDF_LOGE("LinuxSdioFixedAddrReadBytes: data or size is invalid.");
148 return HDF_ERR_INVALID_PARAM;
149 }
150
151 if (scatterLen > 0) {
152 HDF_LOGE("LinuxSdioFixedAddrWriteBytes: not support!");
153 return HDF_ERR_NOT_SUPPORT;
154 }
155 return sdio_writesb(func, addr, data, size);
156 }
157
LinuxSdioFunc0ReadBytes(struct SdioDevice * dev,uint8_t * data,uint32_t addr,uint32_t size)158 static int32_t LinuxSdioFunc0ReadBytes(struct SdioDevice *dev,
159 uint8_t *data, uint32_t addr, uint32_t size)
160 {
161 int32_t ret = HDF_SUCCESS;
162 struct sdio_func *func = LinuxSdioGetFunc(dev);
163
164 if (func == NULL) {
165 HDF_LOGE("LinuxSdioFunc0ReadBytes: func is NULL.");
166 return HDF_ERR_INVALID_OBJECT;
167 }
168 if ((data == NULL) || (size == 0)) {
169 HDF_LOGE("LinuxSdioFunc0ReadBytes: data or size is invalid.");
170 return HDF_ERR_INVALID_PARAM;
171 }
172
173 *data = sdio_f0_readb(func, addr, &ret);
174 return ret;
175 }
176
LinuxSdioFunc0WriteBytes(struct SdioDevice * dev,uint8_t * data,uint32_t addr,uint32_t size)177 static int32_t LinuxSdioFunc0WriteBytes(struct SdioDevice *dev,
178 uint8_t *data, uint32_t addr, uint32_t size)
179 {
180 int32_t ret = HDF_SUCCESS;
181 struct sdio_func *func = LinuxSdioGetFunc(dev);
182
183 if (func == NULL) {
184 HDF_LOGE("LinuxSdioFunc0WriteBytes: func is NULL.");
185 return HDF_ERR_INVALID_OBJECT;
186 }
187 if ((data == NULL) || (size == 0)) {
188 HDF_LOGE("LinuxSdioFunc0WriteBytes: data or size is invalid.");
189 return HDF_ERR_INVALID_PARAM;
190 }
191
192 sdio_f0_writeb(func, *data, addr, &ret);
193 return ret;
194 }
195
LinuxSdioSetBlockSize(struct SdioDevice * dev,uint32_t blockSize)196 static int32_t LinuxSdioSetBlockSize(struct SdioDevice *dev, uint32_t blockSize)
197 {
198 struct sdio_func *func = LinuxSdioGetFunc(dev);
199
200 if (func == NULL) {
201 HDF_LOGE("LinuxSdioSetBlockSize, func is NULL.");
202 return HDF_ERR_INVALID_OBJECT;
203 }
204 return sdio_set_block_size(func, blockSize);
205 }
206
LinuxSdioGetCommonInfo(struct SdioDevice * dev,SdioCommonInfo * info,uint32_t infoType)207 static int32_t LinuxSdioGetCommonInfo(struct SdioDevice *dev,
208 SdioCommonInfo *info, uint32_t infoType)
209 {
210 struct sdio_func *func = LinuxSdioGetFunc(dev);
211
212 if (func == NULL) {
213 HDF_LOGE("LinuxSdioGetCommonInfo: func is NULL.");
214 return HDF_ERR_INVALID_OBJECT;
215 }
216 if (info == NULL) {
217 HDF_LOGE("LinuxSdioGetCommonInfo: info is null.");
218 return HDF_ERR_INVALID_PARAM;
219 }
220 if (infoType != SDIO_FUNC_INFO) {
221 HDF_LOGE("LinuxSdioGetCommonInfo: cur type %u is not support.", infoType);
222 return HDF_ERR_NOT_SUPPORT;
223 }
224
225 if (func->card == NULL) {
226 HDF_LOGE("LinuxSdioGetCommonInfo fail, card is null.");
227 return HDF_ERR_INVALID_PARAM;
228 }
229 if (func->card->host == NULL) {
230 HDF_LOGE("LinuxSdioGetCommonInfo fail, host is null.");
231 return HDF_ERR_INVALID_PARAM;
232 }
233 info->funcInfo.enTimeout = func->enable_timeout;
234 info->funcInfo.maxBlockNum = func->card->host->max_blk_count;
235 info->funcInfo.maxBlockSize = func->card->host->max_blk_size;
236 info->funcInfo.maxRequestSize = func->card->host->max_req_size;
237 info->funcInfo.funcNum = func->num;
238 info->funcInfo.irqCap = func->card->host->caps & MMC_CAP_SDIO_IRQ;
239 info->funcInfo.data = func;
240 return HDF_SUCCESS;
241 }
242
LinuxSdioSetCommonInfo(struct SdioDevice * dev,SdioCommonInfo * info,uint32_t infoType)243 static int32_t LinuxSdioSetCommonInfo(struct SdioDevice *dev,
244 SdioCommonInfo *info, uint32_t infoType)
245 {
246 struct sdio_func *func = LinuxSdioGetFunc(dev);
247
248 if (func == NULL) {
249 HDF_LOGE("LinuxSdioSetCommonInfo: func is NULL.");
250 return HDF_ERR_INVALID_OBJECT;
251 }
252 if (info == NULL) {
253 HDF_LOGE("LinuxSdioSetCommonInfo: info is null.");
254 return HDF_ERR_INVALID_PARAM;
255 }
256 if (infoType != SDIO_FUNC_INFO) {
257 HDF_LOGE("LinuxSdioSetCommonInfo: cur type %u is not support.", infoType);
258 return HDF_ERR_NOT_SUPPORT;
259 }
260
261 if (func->card == NULL) {
262 HDF_LOGE("LinuxSdioSetCommonInfo fail, card is null.");
263 return HDF_ERR_INVALID_PARAM;
264 }
265 if (func->card->host == NULL) {
266 HDF_LOGE("LinuxSdioSetCommonInfo fail, host is null.");
267 return HDF_ERR_INVALID_PARAM;
268 }
269 func->enable_timeout = info->funcInfo.enTimeout;
270 func->card->host->max_blk_count = info->funcInfo.maxBlockNum;
271 func->card->host->max_blk_size = info->funcInfo.maxBlockSize;
272 func->card->host->max_req_size = info->funcInfo.maxRequestSize;
273 func->num = info->funcInfo.funcNum;
274 return HDF_SUCCESS;
275 }
276
LinuxSdioFlushData(struct SdioDevice * dev)277 static int32_t LinuxSdioFlushData(struct SdioDevice *dev)
278 {
279 struct sdio_func *func = LinuxSdioGetFunc(dev);
280
281 if (func == NULL) {
282 HDF_LOGE("LinuxSdioFlushData: func is NULL.");
283 return HDF_ERR_INVALID_OBJECT;
284 }
285 if (func->card == NULL) {
286 HDF_LOGE("LinuxSdioFlushData: card is NULL.");
287 return HDF_ERR_INVALID_OBJECT;
288 }
289
290 return mmc_sw_reset(func->card->host);
291 }
292
LinuxSdioClaimHost(struct SdioDevice * dev)293 static int32_t LinuxSdioClaimHost(struct SdioDevice *dev)
294 {
295 struct sdio_func *func = LinuxSdioGetFunc(dev);
296
297 if (func == NULL) {
298 HDF_LOGE("LinuxSdioClaimHost: func is NULL.");
299 return HDF_ERR_INVALID_OBJECT;
300 }
301 sdio_claim_host(func);
302 return HDF_SUCCESS;
303 }
304
LinuxSdioReleaseHost(struct SdioDevice * dev)305 static int32_t LinuxSdioReleaseHost(struct SdioDevice *dev)
306 {
307 struct sdio_func *func = LinuxSdioGetFunc(dev);
308
309 if (func == NULL) {
310 HDF_LOGE("LinuxSdioReleaseHost: func is NULL.");
311 return HDF_ERR_INVALID_OBJECT;
312 }
313 sdio_release_host(func);
314 return HDF_SUCCESS;
315 }
316
LinuxSdioEnableFunc(struct SdioDevice * dev)317 static int32_t LinuxSdioEnableFunc(struct SdioDevice *dev)
318 {
319 struct sdio_func *func = LinuxSdioGetFunc(dev);
320
321 if (func == NULL) {
322 HDF_LOGE("LinuxSdioEnableFunc: func is NULL.");
323 return HDF_ERR_INVALID_OBJECT;
324 }
325 return sdio_enable_func(func);
326 }
327
LinuxSdioDisableFunc(struct SdioDevice * dev)328 static int32_t LinuxSdioDisableFunc(struct SdioDevice *dev)
329 {
330 struct sdio_func *func = LinuxSdioGetFunc(dev);
331
332 if (func == NULL) {
333 HDF_LOGE("LinuxSdioDisableFunc: func is NULL.");
334 return HDF_ERR_INVALID_OBJECT;
335 }
336 return sdio_disable_func(func);
337 }
338
LinuxSdioClaimIrq(struct SdioDevice * dev,SdioIrqHandler * handler)339 static int32_t LinuxSdioClaimIrq(struct SdioDevice *dev, SdioIrqHandler *handler)
340 {
341 struct sdio_func *func = LinuxSdioGetFunc(dev);
342
343 if (func == NULL) {
344 HDF_LOGE("LinuxSdioClaimIrq: func is NULL.");
345 return HDF_ERR_INVALID_OBJECT;
346 }
347 if (handler == NULL) {
348 HDF_LOGE("LinuxSdioClaimIrq: handler is null.");
349 return HDF_ERR_INVALID_PARAM;
350 }
351 return sdio_claim_irq(func, (sdio_irq_handler_t *)handler);
352 }
353
LinuxSdioReleaseIrq(struct SdioDevice * dev)354 static int32_t LinuxSdioReleaseIrq(struct SdioDevice *dev)
355 {
356 struct sdio_func *func = LinuxSdioGetFunc(dev);
357
358 if (func == NULL) {
359 HDF_LOGE("LinuxSdioReleaseIrq: func is NULL.");
360 return HDF_ERR_INVALID_OBJECT;
361 }
362 return sdio_release_irq(func);
363 }
364
LinuxSdioSearchFunc(uint32_t funcNum,uint16_t vendorId,uint16_t deviceId)365 static struct sdio_func *LinuxSdioSearchFunc(uint32_t funcNum, uint16_t vendorId, uint16_t deviceId)
366 {
367 struct mmc_card *card = NULL;
368 struct mmc_host *host = NULL;
369 struct sdio_func *func = NULL;
370 uint32_t i;
371 uint32_t j;
372
373 for (i = 0; i < MMC_SLOT_NUM; i++) {
374 host = GetMmcHost(i);
375 if (host == NULL) {
376 continue;
377 }
378 card = host->card;
379 if (card == NULL) {
380 continue;
381 }
382 for (j = 0; j <= card->sdio_funcs; j++) {
383 func = card->sdio_func[j];
384 if ((func != NULL) &&
385 (func->num == funcNum) &&
386 (func->vendor == vendorId) &&
387 (func->device == deviceId)) {
388 HDF_LOGD("LinuxSdioSearchFunc: find func!");
389 return func;
390 }
391 }
392 }
393
394 HDF_LOGE("LinuxSdioSearchFunc: get sdio func fail!");
395 return NULL;
396 }
397
LinuxSdioFindFunc(struct SdioDevice * dev,struct SdioFunctionConfig * configData)398 static int32_t LinuxSdioFindFunc(struct SdioDevice *dev, struct SdioFunctionConfig *configData)
399 {
400 if (dev == NULL || configData == NULL) {
401 HDF_LOGE("LinuxSdioFindFunc: dev or configData is NULL.");
402 return HDF_ERR_INVALID_OBJECT;
403 }
404
405 dev->sd.mmc.priv = LinuxSdioSearchFunc(configData->funcNr, configData->vendorId, configData->deviceId);
406 if (dev->sd.mmc.priv == NULL) {
407 HDF_LOGE("LinuxSdioFindFunc: LinuxSdioSearchFunc fail.");
408 return HDF_ERR_NOT_SUPPORT;
409 }
410 return HDF_SUCCESS;
411 }
412
413 static struct SdioDeviceOps g_sdioDeviceOps = {
414 .incrAddrReadBytes = LinuxSdioIncrAddrReadBytes,
415 .incrAddrWriteBytes = LinuxSdioIncrAddrWriteBytes,
416 .fixedAddrReadBytes = LinuxSdioFixedAddrReadBytes,
417 .fixedAddrWriteBytes = LinuxSdioFixedAddrWriteBytes,
418 .func0ReadBytes = LinuxSdioFunc0ReadBytes,
419 .func0WriteBytes = LinuxSdioFunc0WriteBytes,
420 .setBlockSize = LinuxSdioSetBlockSize,
421 .getCommonInfo = LinuxSdioGetCommonInfo,
422 .setCommonInfo = LinuxSdioSetCommonInfo,
423 .flushData = LinuxSdioFlushData,
424 .enableFunc = LinuxSdioEnableFunc,
425 .disableFunc = LinuxSdioDisableFunc,
426 .claimIrq = LinuxSdioClaimIrq,
427 .releaseIrq = LinuxSdioReleaseIrq,
428 .findFunc = LinuxSdioFindFunc,
429 .claimHost = LinuxSdioClaimHost,
430 .releaseHost = LinuxSdioReleaseHost,
431 };
432
LinuxSdioRescanFinish(struct MmcCntlr * cntlr)433 static bool LinuxSdioRescanFinish(struct MmcCntlr *cntlr)
434 {
435 struct mmc_host *host = NULL;
436 struct mmc_card *card = NULL;
437
438 host = GetMmcHost(cntlr->index);
439 if (host == NULL) {
440 return false;
441 }
442
443 card = host->card;
444 if (card == NULL) {
445 return false;
446 }
447 if (card->sdio_funcs > 0) {
448 return true;
449 }
450 return false;
451 }
452
LinuxSdioRescan(struct MmcCntlr * cntlr)453 static int32_t LinuxSdioRescan(struct MmcCntlr *cntlr)
454 {
455 bool rescanFinish = false;
456 uint32_t count = 0;
457
458 if (cntlr == NULL) {
459 HDF_LOGE("LinuxSdioRescan: cntlr is NULL.");
460 return HDF_ERR_INVALID_OBJECT;
461 }
462
463 SdioRescan(cntlr->index);
464 while (rescanFinish == false && count < SDIO_RESCAN_WAIT_TIME) {
465 OsalMSleep(MS_50);
466 count++;
467 rescanFinish = LinuxSdioRescanFinish(cntlr);
468 }
469
470 if (rescanFinish == false) {
471 HDF_LOGE("LinuxSdioRescan: fail!");
472 return HDF_FAILURE;
473 }
474
475 OsalMSleep(MS_10);
476 return HDF_SUCCESS;
477 }
478
479 struct MmcCntlrOps g_sdioCntlrOps = {
480 .rescanSdioDev = LinuxSdioRescan,
481 };
482
LinuxSdioDeleteCntlr(struct MmcCntlr * cntlr)483 static void LinuxSdioDeleteCntlr(struct MmcCntlr *cntlr)
484 {
485 if (cntlr == NULL) {
486 return;
487 }
488
489 if (cntlr->curDev != NULL) {
490 MmcDeviceRemove(cntlr->curDev);
491 OsalMemFree(cntlr->curDev);
492 }
493 MmcCntlrRemove(cntlr);
494 OsalMemFree(cntlr);
495 }
496
LinuxSdioCntlrParse(struct MmcCntlr * cntlr,struct HdfDeviceObject * obj)497 static int32_t LinuxSdioCntlrParse(struct MmcCntlr *cntlr, struct HdfDeviceObject *obj)
498 {
499 const struct DeviceResourceNode *node = NULL;
500 struct DeviceResourceIface *drsOps = NULL;
501 int32_t ret;
502
503 if (obj == NULL || cntlr == NULL) {
504 HDF_LOGE("LinuxSdioCntlrParse: input para is NULL.");
505 return HDF_FAILURE;
506 }
507
508 node = obj->property;
509 if (node == NULL) {
510 HDF_LOGE("LinuxSdioCntlrParse: drs node is NULL.");
511 return HDF_FAILURE;
512 }
513 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
514 if (drsOps == NULL || drsOps->GetUint16 == NULL || drsOps->GetUint32 == NULL) {
515 HDF_LOGE("LinuxSdioCntlrParse: invalid drs ops fail!");
516 return HDF_FAILURE;
517 }
518
519 ret = drsOps->GetUint16(node, "hostId", &(cntlr->index), 0);
520 if (ret != HDF_SUCCESS) {
521 HDF_LOGE("LinuxSdioCntlrParse: read hostIndex fail!");
522 return ret;
523 }
524 ret = drsOps->GetUint32(node, "devType", &(cntlr->devType), 0);
525 if (ret != HDF_SUCCESS) {
526 HDF_LOGE("LinuxSdioCntlrParse: read devType fail!");
527 return ret;
528 }
529 HDF_LOGD("LinuxSdioCntlrParse: hostIndex = %d, devType = %d.", cntlr->index, cntlr->devType);
530 return HDF_SUCCESS;
531 }
532
LinuxSdioBind(struct HdfDeviceObject * obj)533 static int32_t LinuxSdioBind(struct HdfDeviceObject *obj)
534 {
535 struct MmcCntlr *cntlr = NULL;
536 int32_t ret;
537
538 if (obj == NULL) {
539 HDF_LOGE("LinuxSdioBind: Fail, obj is NULL.");
540 return HDF_ERR_INVALID_OBJECT;
541 }
542
543 cntlr = (struct MmcCntlr *)OsalMemCalloc(sizeof(struct MmcCntlr));
544 if (cntlr == NULL) {
545 HDF_LOGE("LinuxSdioBind: no mem for MmcCntlr.");
546 return HDF_ERR_MALLOC_FAIL;
547 }
548
549 cntlr->ops = &g_sdioCntlrOps;
550 cntlr->hdfDevObj = obj;
551 obj->service = &cntlr->service;
552 /* init cntlr. */
553 ret = LinuxSdioCntlrParse(cntlr, obj);
554 if (ret != HDF_SUCCESS) {
555 HDF_LOGE("LinuxSdioBind: cntlr parse fail.");
556 goto _ERR;
557 }
558
559 ret = MmcCntlrAdd(cntlr, false);
560 if (ret != HDF_SUCCESS) {
561 HDF_LOGE("LinuxSdioBind: cntlr add fail.");
562 goto _ERR;
563 }
564
565 ret = MmcCntlrAllocDev(cntlr, (enum MmcDevType)cntlr->devType);
566 if (ret != HDF_SUCCESS) {
567 HDF_LOGE("LinuxSdioBind: alloc dev fail.");
568 goto _ERR;
569 }
570 MmcDeviceAddOps(cntlr->curDev, &g_sdioDeviceOps);
571 HDF_LOGD("LinuxSdioBind: Success!");
572 return HDF_SUCCESS;
573
574 _ERR:
575 LinuxSdioDeleteCntlr(cntlr);
576 HDF_LOGE("LinuxSdioBind: Fail!");
577 return HDF_FAILURE;
578 }
579
LinuxSdioInit(struct HdfDeviceObject * obj)580 static int32_t LinuxSdioInit(struct HdfDeviceObject *obj)
581 {
582 (void)obj;
583 HDF_LOGD("LinuxSdioInit: Success!");
584 return HDF_SUCCESS;
585 }
586
LinuxSdioRelease(struct HdfDeviceObject * obj)587 static void LinuxSdioRelease(struct HdfDeviceObject *obj)
588 {
589 if (obj == NULL) {
590 return;
591 }
592 LinuxSdioDeleteCntlr((struct MmcCntlr *)obj->service);
593 }
594
595 struct HdfDriverEntry g_sdioDriverEntry = {
596 .moduleVersion = 1,
597 .Bind = LinuxSdioBind,
598 .Init = LinuxSdioInit,
599 .Release = LinuxSdioRelease,
600 .moduleName = "HDF_PLATFORM_SDIO",
601 };
602 HDF_INIT(g_sdioDriverEntry);
603