xref: /openbmc/u-boot/drivers/nvme/nvme-uclass.c (revision 982388ea)
1*982388eaSZhikang Zhang /*
2*982388eaSZhikang Zhang  * Copyright (C) 2017 NXP Semiconductors
3*982388eaSZhikang Zhang  * Copyright (C) 2017 Bin Meng <bmeng.cn@gmail.com>
4*982388eaSZhikang Zhang  *
5*982388eaSZhikang Zhang  * SPDX-License-Identifier:	GPL-2.0+
6*982388eaSZhikang Zhang  */
7*982388eaSZhikang Zhang 
8*982388eaSZhikang Zhang #include <common.h>
9*982388eaSZhikang Zhang #include <errno.h>
10*982388eaSZhikang Zhang #include <dm.h>
11*982388eaSZhikang Zhang #include <dm/device.h>
12*982388eaSZhikang Zhang #include "nvme.h"
13*982388eaSZhikang Zhang 
14*982388eaSZhikang Zhang static int nvme_info_init(struct uclass *uc)
15*982388eaSZhikang Zhang {
16*982388eaSZhikang Zhang 	struct nvme_info *info = (struct nvme_info *)uc->priv;
17*982388eaSZhikang Zhang 
18*982388eaSZhikang Zhang 	info->ns_num = 0;
19*982388eaSZhikang Zhang 	info->ndev_num = 0;
20*982388eaSZhikang Zhang 	INIT_LIST_HEAD(&info->dev_list);
21*982388eaSZhikang Zhang 	nvme_info = info;
22*982388eaSZhikang Zhang 
23*982388eaSZhikang Zhang 	return 0;
24*982388eaSZhikang Zhang }
25*982388eaSZhikang Zhang 
26*982388eaSZhikang Zhang static int nvme_uclass_post_probe(struct udevice *udev)
27*982388eaSZhikang Zhang {
28*982388eaSZhikang Zhang 	char name[20];
29*982388eaSZhikang Zhang 	char *str;
30*982388eaSZhikang Zhang 	struct udevice *ns_udev;
31*982388eaSZhikang Zhang 	int i, ret;
32*982388eaSZhikang Zhang 	struct nvme_dev *ndev = dev_get_priv(udev);
33*982388eaSZhikang Zhang 
34*982388eaSZhikang Zhang 	/* Create a blk device for each namespace */
35*982388eaSZhikang Zhang 	for (i = 0; i < ndev->nn; i++) {
36*982388eaSZhikang Zhang 		sprintf(name, "nvme-blk#%d", nvme_info->ns_num);
37*982388eaSZhikang Zhang 		str = strdup(name);
38*982388eaSZhikang Zhang 		if (!str)
39*982388eaSZhikang Zhang 			return -ENOMEM;
40*982388eaSZhikang Zhang 
41*982388eaSZhikang Zhang 		/* The real blksz and size will be set by nvme_blk_probe() */
42*982388eaSZhikang Zhang 		ret = blk_create_device(udev, "nvme-blk", str, IF_TYPE_NVME,
43*982388eaSZhikang Zhang 					nvme_info->ns_num++, 512, 0, &ns_udev);
44*982388eaSZhikang Zhang 		if (ret) {
45*982388eaSZhikang Zhang 			free(str);
46*982388eaSZhikang Zhang 			nvme_info->ns_num--;
47*982388eaSZhikang Zhang 
48*982388eaSZhikang Zhang 			return ret;
49*982388eaSZhikang Zhang 		}
50*982388eaSZhikang Zhang 		device_set_name_alloced(ns_udev);
51*982388eaSZhikang Zhang 	}
52*982388eaSZhikang Zhang 
53*982388eaSZhikang Zhang 	return 0;
54*982388eaSZhikang Zhang }
55*982388eaSZhikang Zhang 
56*982388eaSZhikang Zhang UCLASS_DRIVER(nvme) = {
57*982388eaSZhikang Zhang 	.name	= "nvme",
58*982388eaSZhikang Zhang 	.id	= UCLASS_NVME,
59*982388eaSZhikang Zhang 	.init	= nvme_info_init,
60*982388eaSZhikang Zhang 	.post_probe = nvme_uclass_post_probe,
61*982388eaSZhikang Zhang 	.priv_auto_alloc_size = sizeof(struct nvme_info),
62*982388eaSZhikang Zhang };
63