1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2017
4  * Mario Six,  Guntermann & Drunck GmbH, mario.six@gdsys.cc
5  */
6 
7 #define LOG_CATEGORY UCLASS_SYSINFO
8 
9 #include <dm.h>
10 #include <sysinfo.h>
11 
12 struct sysinfo_priv {
13 	bool detected;
14 };
15 
sysinfo_get(struct udevice ** devp)16 int sysinfo_get(struct udevice **devp)
17 {
18 	int ret = uclass_first_device_err(UCLASS_SYSINFO, devp);
19 
20 	/*
21 	 * There is some very dodgy error handling in gazerbeam,
22 	 * do not return a device on error.
23 	 */
24 	if (ret)
25 		*devp = NULL;
26 	return ret;
27 }
28 
sysinfo_detect(struct udevice * dev)29 int sysinfo_detect(struct udevice *dev)
30 {
31 	int ret;
32 	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
33 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
34 
35 	if (!ops->detect)
36 		return -ENOSYS;
37 
38 	ret = ops->detect(dev);
39 	if (!ret)
40 		priv->detected = true;
41 
42 	return ret;
43 }
44 
sysinfo_get_fit_loadable(struct udevice * dev,int index,const char * type,const char ** strp)45 int sysinfo_get_fit_loadable(struct udevice *dev, int index, const char *type,
46 			     const char **strp)
47 {
48 	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
49 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
50 
51 	if (!priv->detected)
52 		return -EPERM;
53 
54 	if (!ops->get_fit_loadable)
55 		return -ENOSYS;
56 
57 	return ops->get_fit_loadable(dev, index, type, strp);
58 }
59 
sysinfo_get_bool(struct udevice * dev,int id,bool * val)60 int sysinfo_get_bool(struct udevice *dev, int id, bool *val)
61 {
62 	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
63 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
64 
65 	if (!priv->detected)
66 		return -EPERM;
67 
68 	if (!ops->get_bool)
69 		return -ENOSYS;
70 
71 	return ops->get_bool(dev, id, val);
72 }
73 
sysinfo_get_int(struct udevice * dev,int id,int * val)74 int sysinfo_get_int(struct udevice *dev, int id, int *val)
75 {
76 	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
77 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
78 
79 	if (!priv->detected)
80 		return -EPERM;
81 
82 	if (!ops->get_int)
83 		return -ENOSYS;
84 
85 	return ops->get_int(dev, id, val);
86 }
87 
sysinfo_get_str(struct udevice * dev,int id,size_t size,char * val)88 int sysinfo_get_str(struct udevice *dev, int id, size_t size, char *val)
89 {
90 	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
91 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
92 
93 	if (!priv->detected)
94 		return -EPERM;
95 
96 	if (!ops->get_str)
97 		return -ENOSYS;
98 
99 	return ops->get_str(dev, id, size, val);
100 }
101 
sysinfo_get_data(struct udevice * dev,int id,void ** data,size_t * size)102 int sysinfo_get_data(struct udevice *dev, int id, void **data, size_t *size)
103 {
104 	struct sysinfo_priv *priv;
105 	struct sysinfo_ops *ops;
106 
107 	if (!dev)
108 		return -ENOSYS;
109 
110 	priv = dev_get_uclass_priv(dev);
111 	ops = sysinfo_get_ops(dev);
112 
113 	if (!priv->detected)
114 		return -EPERM;
115 
116 	if (!ops->get_data)
117 		return -ENOSYS;
118 
119 	return ops->get_data(dev, id, data, size);
120 }
121 
sysinfo_get_item_count(struct udevice * dev,int id)122 int sysinfo_get_item_count(struct udevice *dev, int id)
123 {
124 	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
125 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
126 
127 	if (!priv->detected)
128 		return -EPERM;
129 
130 	if (!ops->get_item_count)
131 		return -ENOSYS;
132 
133 	return ops->get_item_count(dev, id);
134 }
135 
sysinfo_get_data_by_index(struct udevice * dev,int id,int index,void ** data,size_t * size)136 int sysinfo_get_data_by_index(struct udevice *dev, int id, int index,
137 			      void **data, size_t *size)
138 {
139 	struct sysinfo_priv *priv = dev_get_uclass_priv(dev);
140 	struct sysinfo_ops *ops = sysinfo_get_ops(dev);
141 
142 	if (!priv->detected)
143 		return -EPERM;
144 
145 	if (!ops->get_data_by_index)
146 		return -ENOSYS;
147 
148 	return ops->get_data_by_index(dev, id, index, data, size);
149 }
150 
151 UCLASS_DRIVER(sysinfo) = {
152 	.id		= UCLASS_SYSINFO,
153 	.name		= "sysinfo",
154 	.post_bind	= dm_scan_fdt_dev,
155 	.per_device_auto	= sizeof(bool),
156 };
157