1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
4  *
5  * Authors:
6  *   Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
7  */
8 
9 #include <common.h>
10 #include <dm.h>
11 #include <log.h>
12 #if CONFIG_IS_ENABLED(SANDBOX64)
13 #include <asm/test.h>
14 #endif
15 #include <linux/bitops.h>
16 #include "nvmxip.h"
17 
18 /* LBA Macros */
19 
20 #define DEFAULT_LBA_SHIFT 10 /* 1024 bytes per block */
21 #define DEFAULT_LBA_COUNT 1024 /* block count */
22 
23 #define DEFAULT_LBA_SZ BIT(DEFAULT_LBA_SHIFT)
24 
25 /**
26  * nvmxip_post_bind() - post binding treatments
27  * @dev:	the NVMXIP device
28  *
29  * Create and probe a child block device.
30  *
31  * Return:
32  *
33  * 0 on success. Otherwise, failure
34  */
nvmxip_post_bind(struct udevice * udev)35 static int nvmxip_post_bind(struct udevice *udev)
36 {
37 	int ret;
38 	struct udevice *bdev = NULL;
39 	char bdev_name[NVMXIP_BLKDEV_NAME_SZ + 1];
40 	int devnum;
41 
42 #if CONFIG_IS_ENABLED(SANDBOX64)
43 	sandbox_set_enable_memio(true);
44 #endif
45 
46 	devnum = uclass_id_count(UCLASS_NVMXIP);
47 	snprintf(bdev_name, NVMXIP_BLKDEV_NAME_SZ, "blk#%d", devnum);
48 
49 	ret = blk_create_devicef(udev, NVMXIP_BLKDRV_NAME, bdev_name, UCLASS_NVMXIP,
50 				 devnum, DEFAULT_LBA_SZ,
51 				 DEFAULT_LBA_COUNT, &bdev);
52 	if (ret) {
53 		log_err("[%s]: failure during creation of the block device %s, error %d\n",
54 			udev->name, bdev_name, ret);
55 		return ret;
56 	}
57 
58 	ret = blk_probe_or_unbind(bdev);
59 	if (ret) {
60 		log_err("[%s]: failure during probing the block device %s, error %d\n",
61 			udev->name, bdev_name, ret);
62 		return ret;
63 	}
64 
65 	log_info("[%s]: the block device %s ready for use\n", udev->name, bdev_name);
66 
67 	return 0;
68 }
69 
70 UCLASS_DRIVER(nvmxip) = {
71 	.name	   = "nvmxip",
72 	.id	   = UCLASS_NVMXIP,
73 	.post_bind = nvmxip_post_bind,
74 };
75