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